diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/mathml/MathMLElement.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/mathml/MathMLElement.cpp')
-rw-r--r-- | Source/WebCore/mathml/MathMLElement.cpp | 156 |
1 files changed, 120 insertions, 36 deletions
diff --git a/Source/WebCore/mathml/MathMLElement.cpp b/Source/WebCore/mathml/MathMLElement.cpp index 42fe25d8a..128b41508 100644 --- a/Source/WebCore/mathml/MathMLElement.cpp +++ b/Source/WebCore/mathml/MathMLElement.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. * Copyright (C) 2010 Apple Inc. All rights reserved. * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved. + * Copyright (C) 2016 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,57 +27,61 @@ */ #include "config.h" +#include "MathMLElement.h" #if ENABLE(MATHML) -#include "MathMLElement.h" - +#include "EventHandler.h" +#include "HTMLAnchorElement.h" +#include "HTMLParserIdioms.h" #include "MathMLNames.h" +#include "MouseEvent.h" #include "RenderTableCell.h" namespace WebCore { - + using namespace MathMLNames; - + MathMLElement::MathMLElement(const QualifiedName& tagName, Document& document) : StyledElement(tagName, document, CreateMathMLElement) { } - -PassRefPtr<MathMLElement> MathMLElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new MathMLElement(tagName, document)); -} -bool MathMLElement::isPresentationMathML() const +Ref<MathMLElement> MathMLElement::create(const QualifiedName& tagName, Document& document) { - return hasTagName(MathMLNames::mtrTag) || hasTagName(MathMLNames::mtdTag) || hasTagName(MathMLNames::maligngroupTag) || hasTagName(MathMLNames::malignmarkTag) || hasTagName(MathMLNames::mencloseTag) || hasTagName(MathMLNames::mglyphTag) || hasTagName(MathMLNames::mlabeledtrTag) || hasTagName(MathMLNames::mlongdivTag) || hasTagName(MathMLNames::mpaddedTag) || hasTagName(MathMLNames::msTag) || hasTagName(MathMLNames::mscarriesTag) || hasTagName(MathMLNames::mscarryTag) || hasTagName(MathMLNames::msgroupTag) || hasTagName(MathMLNames::mslineTag) || hasTagName(MathMLNames::msrowTag) || hasTagName(MathMLNames::mstackTag); + return adoptRef(*new MathMLElement(tagName, document)); } -int MathMLElement::colSpan() const +unsigned MathMLElement::colSpan() const { if (!hasTagName(mtdTag)) - return 1; - const AtomicString& colSpanValue = fastGetAttribute(columnspanAttr); - return std::max(1, colSpanValue.toInt()); + return 1u; + auto& colSpanValue = attributeWithoutSynchronization(columnspanAttr); + return std::max(1u, limitToOnlyHTMLNonNegative(colSpanValue, 1u)); } -int MathMLElement::rowSpan() const +unsigned MathMLElement::rowSpan() const { if (!hasTagName(mtdTag)) - return 1; - const AtomicString& rowSpanValue = fastGetAttribute(rowspanAttr); - return std::max(1, rowSpanValue.toInt()); + return 1u; + auto& rowSpanValue = attributeWithoutSynchronization(rowspanAttr); + static const unsigned maxRowspan = 8190; // This constant comes from HTMLTableCellElement. + return std::max(1u, std::min(limitToOnlyHTMLNonNegative(rowSpanValue, 1u), maxRowspan)); } void MathMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (name == rowspanAttr) { - if (renderer() && renderer()->isTableCell() && hasTagName(mtdTag)) - toRenderTableCell(renderer())->colSpanOrRowSpanChanged(); + if (name == hrefAttr) { + bool wasLink = isLink(); + setIsLink(!value.isNull() && !shouldProhibitLinks(this)); + if (wasLink != isLink()) + invalidateStyleForSubtree(); + } else if (name == rowspanAttr) { + if (is<RenderTableCell>(renderer()) && hasTagName(mtdTag)) + downcast<RenderTableCell>(*renderer()).colSpanOrRowSpanChanged(); } else if (name == columnspanAttr) { - if (renderer() && renderer()->isTableCell() && hasTagName(mtdTag)) - toRenderTableCell(renderer())->colSpanOrRowSpanChanged(); + if (is<RenderTableCell>(renderer()) && hasTagName(mtdTag)) + downcast<RenderTableCell>(renderer())->colSpanOrRowSpanChanged(); } else StyledElement::parseAttribute(name, value); } @@ -123,23 +128,102 @@ void MathMLElement::collectStyleForPresentationAttribute(const QualifiedName& na bool MathMLElement::childShouldCreateRenderer(const Node& child) const { - if (hasTagName(annotationTag)) - return child.isTextNode(); - if (hasTagName(annotation_xmlTag)) - return StyledElement::childShouldCreateRenderer(child); + // In general, only MathML children are allowed. Text nodes are only visible in token MathML elements. + return is<MathMLElement>(child); +} + +bool MathMLElement::willRespondToMouseClickEvents() +{ + return isLink() || StyledElement::willRespondToMouseClickEvents(); +} + +void MathMLElement::defaultEventHandler(Event& event) +{ + if (isLink()) { + if (focused() && isEnterKeyKeydownEvent(event)) { + event.setDefaultHandled(); + dispatchSimulatedClick(&event); + return; + } + if (MouseEvent::canTriggerActivationBehavior(event)) { + auto& href = attributeWithoutSynchronization(hrefAttr); + const auto& url = stripLeadingAndTrailingHTMLSpaces(href); + event.setDefaultHandled(); + if (auto* frame = document().frame()) + frame->loader().urlSelected(document().completeURL(url), "_self", &event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate()); + return; + } + } + + StyledElement::defaultEventHandler(event); +} + +bool MathMLElement::canStartSelection() const +{ + if (!isLink()) + return StyledElement::canStartSelection(); + + return hasEditableStyle(); +} + +bool MathMLElement::isFocusable() const +{ + if (renderer() && renderer()->absoluteClippedOverflowRect().isEmpty()) + return false; + + return StyledElement::isFocusable(); +} + +bool MathMLElement::isKeyboardFocusable(KeyboardEvent& event) const +{ + if (isFocusable() && StyledElement::supportsFocus()) + return StyledElement::isKeyboardFocusable(event); + + if (isLink()) + return document().frame()->eventHandler().tabsToLinks(event); + + return StyledElement::isKeyboardFocusable(event); +} + +bool MathMLElement::isMouseFocusable() const +{ + // Links are focusable by default, but only allow links with tabindex or contenteditable to be mouse focusable. + // https://bugs.webkit.org/show_bug.cgi?id=26856 + if (isLink()) + return StyledElement::supportsFocus(); + + return StyledElement::isMouseFocusable(); +} + +bool MathMLElement::isURLAttribute(const Attribute& attribute) const +{ + return attribute.name().localName() == hrefAttr || StyledElement::isURLAttribute(attribute); +} - // Only create renderers for MathML elements or text. MathML prohibits non-MathML markup inside a <math> element. - return child.isTextNode() || child.isMathMLElement(); +bool MathMLElement::supportsFocus() const +{ + if (hasEditableStyle()) + return StyledElement::supportsFocus(); + // If not a link we should still be able to focus the element if it has tabIndex. + return isLink() || StyledElement::supportsFocus(); +} + +int MathMLElement::tabIndex() const +{ + // Skip the supportsFocus check in StyledElement. + return Element::tabIndex(); } -void MathMLElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason) +StringView MathMLElement::stripLeadingAndTrailingWhitespace(const StringView& stringView) { - if (isSemanticAnnotation() && (name == MathMLNames::srcAttr || name == MathMLNames::encodingAttr)) { - Element* parent = parentElement(); - if (parent && parent->isMathMLElement() && parent->hasTagName(semanticsTag)) - toMathMLElement(parent)->updateSelectedChild(); + unsigned start = 0, stringLength = stringView.length(); + while (stringLength > 0 && isHTMLSpace(stringView[start])) { + start++; + stringLength--; } - StyledElement::attributeChanged(name, oldValue, newValue, reason); + while (stringLength > 0 && isHTMLSpace(stringView[start + stringLength - 1])) + stringLength--; + return stringView.substring(start, stringLength); } } |