diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/mathml/MathMLElement.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-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.cpp | 210 |
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) |