summaryrefslogtreecommitdiff
path: root/Source/WebCore/mathml/MathMLElement.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/mathml/MathMLElement.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/mathml/MathMLElement.cpp')
-rw-r--r--Source/WebCore/mathml/MathMLElement.cpp156
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);
}
}