summaryrefslogtreecommitdiff
path: root/Source/WebCore/mathml/MathMLElement.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/mathml/MathMLElement.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/mathml/MathMLElement.cpp')
-rw-r--r--Source/WebCore/mathml/MathMLElement.cpp210
1 files changed, 198 insertions, 12 deletions
diff --git a/Source/WebCore/mathml/MathMLElement.cpp b/Source/WebCore/mathml/MathMLElement.cpp
index 6b57617e9..b6cf328f7 100644
--- a/Source/WebCore/mathml/MathMLElement.cpp
+++ b/Source/WebCore/mathml/MathMLElement.cpp
@@ -31,22 +31,166 @@
#include "MathMLElement.h"
+#include "ElementIterator.h"
+#include "HTMLElement.h"
+#include "HTMLMapElement.h"
+#include "HTMLNames.h"
#include "MathMLNames.h"
-#include "RenderObject.h"
+#include "MathMLSelectElement.h"
#include "RenderTableCell.h"
+#include "SVGElement.h"
+#include "SVGNames.h"
namespace WebCore {
using namespace MathMLNames;
-MathMLElement::MathMLElement(const QualifiedName& tagName, Document* document)
- : StyledElement(tagName, document, CreateStyledElement)
+MathMLElement::MathMLElement(const QualifiedName& tagName, Document& document)
+ : StyledElement(tagName, document, CreateMathMLElement)
{
}
-PassRefPtr<MathMLElement> MathMLElement::create(const QualifiedName& tagName, Document* document)
+Ref<MathMLElement> MathMLElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(new MathMLElement(tagName, document));
+ return adoptRef(*new MathMLElement(tagName, document));
+}
+
+bool MathMLElement::isPresentationMathML() const
+{
+ 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);
+}
+
+bool MathMLElement::isPhrasingContent(const Node& node) const
+{
+ // Phrasing content is described in the HTML 5 specification:
+ // http://www.w3.org/TR/html5/dom.html#phrasing-content.
+
+ if (!node.isElementNode())
+ return node.isTextNode();
+
+ if (is<MathMLElement>(node)) {
+ auto& mathmlElement = downcast<MathMLElement>(node);
+ return is<MathMLMathElement>(mathmlElement);
+ }
+
+ if (is<SVGElement>(node)) {
+ auto& svgElement = downcast<SVGElement>(node);
+ return is<SVGSVGElement>(svgElement);
+ }
+
+ if (is<HTMLElement>(node)) {
+ // FIXME: add the <data> and <time> tags when they are implemented.
+ auto& htmlElement = downcast<HTMLElement>(node);
+ return htmlElement.hasTagName(HTMLNames::aTag)
+ || htmlElement.hasTagName(HTMLNames::abbrTag)
+ || (htmlElement.hasTagName(HTMLNames::areaTag) && ancestorsOfType<HTMLMapElement>(htmlElement).first())
+ || htmlElement.hasTagName(HTMLNames::audioTag)
+ || htmlElement.hasTagName(HTMLNames::bTag)
+ || htmlElement.hasTagName(HTMLNames::bdiTag)
+ || htmlElement.hasTagName(HTMLNames::bdoTag)
+ || htmlElement.hasTagName(HTMLNames::brTag)
+ || htmlElement.hasTagName(HTMLNames::buttonTag)
+ || htmlElement.hasTagName(HTMLNames::canvasTag)
+ || htmlElement.hasTagName(HTMLNames::citeTag)
+ || htmlElement.hasTagName(HTMLNames::codeTag)
+ || htmlElement.hasTagName(HTMLNames::datalistTag)
+ || htmlElement.hasTagName(HTMLNames::delTag)
+ || htmlElement.hasTagName(HTMLNames::dfnTag)
+ || htmlElement.hasTagName(HTMLNames::emTag)
+ || htmlElement.hasTagName(HTMLNames::embedTag)
+ || htmlElement.hasTagName(HTMLNames::iTag)
+ || htmlElement.hasTagName(HTMLNames::iframeTag)
+ || htmlElement.hasTagName(HTMLNames::imgTag)
+ || htmlElement.hasTagName(HTMLNames::inputTag)
+ || htmlElement.hasTagName(HTMLNames::insTag)
+ || htmlElement.hasTagName(HTMLNames::kbdTag)
+ || htmlElement.hasTagName(HTMLNames::keygenTag)
+ || htmlElement.hasTagName(HTMLNames::labelTag)
+ || htmlElement.hasTagName(HTMLNames::mapTag)
+ || htmlElement.hasTagName(HTMLNames::markTag)
+ || htmlElement.hasTagName(HTMLNames::meterTag)
+ || htmlElement.hasTagName(HTMLNames::noscriptTag)
+ || htmlElement.hasTagName(HTMLNames::objectTag)
+ || htmlElement.hasTagName(HTMLNames::outputTag)
+ || htmlElement.hasTagName(HTMLNames::progressTag)
+ || htmlElement.hasTagName(HTMLNames::qTag)
+ || htmlElement.hasTagName(HTMLNames::rubyTag)
+ || htmlElement.hasTagName(HTMLNames::sTag)
+ || htmlElement.hasTagName(HTMLNames::sampTag)
+ || htmlElement.hasTagName(HTMLNames::scriptTag)
+ || htmlElement.hasTagName(HTMLNames::selectTag)
+ || htmlElement.hasTagName(HTMLNames::smallTag)
+ || htmlElement.hasTagName(HTMLNames::spanTag)
+ || htmlElement.hasTagName(HTMLNames::strongTag)
+ || htmlElement.hasTagName(HTMLNames::subTag)
+ || htmlElement.hasTagName(HTMLNames::supTag)
+ || htmlElement.hasTagName(HTMLNames::templateTag)
+ || htmlElement.hasTagName(HTMLNames::textareaTag)
+ || htmlElement.hasTagName(HTMLNames::uTag)
+ || htmlElement.hasTagName(HTMLNames::varTag)
+ || htmlElement.hasTagName(HTMLNames::videoTag)
+ || htmlElement.hasTagName(HTMLNames::wbrTag);
+ }
+
+ return false;
+}
+
+bool MathMLElement::isFlowContent(const Node& node) const
+{
+ // Flow content is described in the HTML 5 specification:
+ // http://www.w3.org/TR/html5/dom.html#flow-content
+
+ if (isPhrasingContent(node))
+ return true;
+
+ if (!is<HTMLElement>(node))
+ return false;
+
+ auto& htmlElement = downcast<HTMLElement>(node);
+ // FIXME add the <dialog> tag when it is implemented.
+ return htmlElement.hasTagName(HTMLNames::addressTag)
+ || htmlElement.hasTagName(HTMLNames::articleTag)
+ || htmlElement.hasTagName(HTMLNames::asideTag)
+ || htmlElement.hasTagName(HTMLNames::blockquoteTag)
+ || htmlElement.hasTagName(HTMLNames::detailsTag)
+ || htmlElement.hasTagName(HTMLNames::divTag)
+ || htmlElement.hasTagName(HTMLNames::dlTag)
+ || htmlElement.hasTagName(HTMLNames::fieldsetTag)
+ || htmlElement.hasTagName(HTMLNames::figureTag)
+ || htmlElement.hasTagName(HTMLNames::footerTag)
+ || htmlElement.hasTagName(HTMLNames::formTag)
+ || htmlElement.hasTagName(HTMLNames::h1Tag)
+ || htmlElement.hasTagName(HTMLNames::h2Tag)
+ || htmlElement.hasTagName(HTMLNames::h3Tag)
+ || htmlElement.hasTagName(HTMLNames::h4Tag)
+ || htmlElement.hasTagName(HTMLNames::h5Tag)
+ || htmlElement.hasTagName(HTMLNames::h6Tag)
+ || htmlElement.hasTagName(HTMLNames::headerTag)
+ || htmlElement.hasTagName(HTMLNames::hrTag)
+ || htmlElement.hasTagName(HTMLNames::mainTag)
+ || htmlElement.hasTagName(HTMLNames::navTag)
+ || htmlElement.hasTagName(HTMLNames::olTag)
+ || htmlElement.hasTagName(HTMLNames::pTag)
+ || htmlElement.hasTagName(HTMLNames::preTag)
+ || htmlElement.hasTagName(HTMLNames::sectionTag)
+ || (htmlElement.hasTagName(HTMLNames::styleTag) && htmlElement.hasAttribute("scoped"))
+ || htmlElement.hasTagName(HTMLNames::tableTag)
+ || htmlElement.hasTagName(HTMLNames::ulTag);
}
int MathMLElement::colSpan() const
@@ -68,23 +212,23 @@ int MathMLElement::rowSpan() const
void MathMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == rowspanAttr) {
- if (renderer() && renderer()->isTableCell() && hasTagName(mtdTag))
- toRenderTableCell(renderer())->colSpanOrRowSpanChanged();
+ 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);
}
bool MathMLElement::isPresentationAttribute(const QualifiedName& name) const
{
- if (name == mathbackgroundAttr || name == mathsizeAttr || name == mathcolorAttr || name == fontsizeAttr || name == backgroundAttr || name == colorAttr || name == fontstyleAttr || name == fontweightAttr || name == fontfamilyAttr)
+ if (name == backgroundAttr || name == colorAttr || name == dirAttr || name == fontfamilyAttr || name == fontsizeAttr || name == fontstyleAttr || name == fontweightAttr || name == mathbackgroundAttr || name == mathcolorAttr || name == mathsizeAttr)
return true;
return StyledElement::isPresentationAttribute(name);
}
-void MathMLElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
+void MathMLElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
{
if (name == mathbackgroundAttr)
addPropertyToPresentationAttributeStyle(style, CSSPropertyBackgroundColor, value);
@@ -107,13 +251,55 @@ void MathMLElement::collectStyleForPresentationAttribute(const QualifiedName& na
addPropertyToPresentationAttributeStyle(style, CSSPropertyFontWeight, value);
else if (name == fontfamilyAttr)
addPropertyToPresentationAttributeStyle(style, CSSPropertyFontFamily, value);
- else {
+ else if (name == dirAttr) {
+ if (hasTagName(mathTag) || hasTagName(mrowTag) || hasTagName(mstyleTag) || isMathMLToken())
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyDirection, value);
+ } else {
ASSERT(!isPresentationAttribute(name));
StyledElement::collectStyleForPresentationAttribute(name, value
, style);
}
}
+bool MathMLElement::childShouldCreateRenderer(const Node& child) const
+{
+ if (hasTagName(annotation_xmlTag)) {
+ const AtomicString& value = fastGetAttribute(MathMLNames::encodingAttr);
+
+ // See annotation-xml.model.mathml, annotation-xml.model.svg and annotation-xml.model.xhtml in the HTML5 RelaxNG schema.
+
+ if (is<MathMLElement>(child) && (MathMLSelectElement::isMathMLEncoding(value) || MathMLSelectElement::isHTMLEncoding(value))) {
+ auto& mathmlElement = downcast<MathMLElement>(child);
+ return is<MathMLMathElement>(mathmlElement);
+ }
+
+ if (is<SVGElement>(child) && (MathMLSelectElement::isSVGEncoding(value) || MathMLSelectElement::isHTMLEncoding(value))) {
+ auto& svgElement = downcast<SVGElement>(child);
+ return is<SVGSVGElement>(svgElement);
+ }
+
+ if (is<HTMLElement>(child) && MathMLSelectElement::isHTMLEncoding(value)) {
+ auto& htmlElement = downcast<HTMLElement>(child);
+ return is<HTMLHtmlElement>(htmlElement) || (isFlowContent(htmlElement) && StyledElement::childShouldCreateRenderer(child));
+ }
+
+ return false;
+ }
+
+ // In general, only MathML children are allowed. Text nodes are only visible in token MathML elements.
+ return is<MathMLElement>(child);
+}
+
+void MathMLElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason)
+{
+ if (isSemanticAnnotation() && (name == MathMLNames::srcAttr || name == MathMLNames::encodingAttr)) {
+ Element* parent = parentElement();
+ if (is<MathMLElement>(parent) && parent->hasTagName(semanticsTag))
+ downcast<MathMLElement>(*parent).updateSelectedChild();
+ }
+ StyledElement::attributeChanged(name, oldValue, newValue, reason);
+}
+
}
#endif // ENABLE(MATHML)