diff options
| author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-05-24 08:28:08 +0000 |
|---|---|---|
| committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-05-24 08:28:08 +0000 |
| commit | a4e969f4965059196ca948db781e52f7cfebf19e (patch) | |
| tree | 6ca352808c8fdc52006a0f33f6ae3c593b23867d /Source/WebCore/mathml | |
| parent | 41386e9cb918eed93b3f13648cbef387e371e451 (diff) | |
| download | WebKitGtk-tarball-a4e969f4965059196ca948db781e52f7cfebf19e.tar.gz | |
webkitgtk-2.12.3webkitgtk-2.12.3
Diffstat (limited to 'Source/WebCore/mathml')
| -rw-r--r-- | Source/WebCore/mathml/MathMLAllInOne.cpp | 34 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLElement.cpp | 192 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLElement.h | 28 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLInlineContainerElement.cpp | 78 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLInlineContainerElement.h | 5 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLMathElement.cpp | 16 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLMathElement.h | 5 | ||||
| -rw-r--r--[-rwxr-xr-x] | Source/WebCore/mathml/MathMLMencloseElement.cpp | 22 | ||||
| -rw-r--r--[-rwxr-xr-x] | Source/WebCore/mathml/MathMLMencloseElement.h | 13 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLSelectElement.cpp | 73 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLSelectElement.h | 11 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLTextElement.cpp | 54 | ||||
| -rw-r--r-- | Source/WebCore/mathml/MathMLTextElement.h | 7 | ||||
| -rw-r--r-- | Source/WebCore/mathml/mathattrs.in | 11 | ||||
| -rw-r--r-- | Source/WebCore/mathml/mathtags.in | 2 |
15 files changed, 409 insertions, 142 deletions
diff --git a/Source/WebCore/mathml/MathMLAllInOne.cpp b/Source/WebCore/mathml/MathMLAllInOne.cpp new file mode 100644 index 000000000..77a778900 --- /dev/null +++ b/Source/WebCore/mathml/MathMLAllInOne.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build. + +#include "MathMLElement.cpp" +#include "MathMLInlineContainerElement.cpp" +#include "MathMLMathElement.cpp" +#include "MathMLMencloseElement.cpp" +#include "MathMLSelectElement.cpp" +#include "MathMLTextElement.cpp" + diff --git a/Source/WebCore/mathml/MathMLElement.cpp b/Source/WebCore/mathml/MathMLElement.cpp index 240179251..b6cf328f7 100644 --- a/Source/WebCore/mathml/MathMLElement.cpp +++ b/Source/WebCore/mathml/MathMLElement.cpp @@ -31,8 +31,15 @@ #include "MathMLElement.h" +#include "ElementIterator.h" +#include "HTMLElement.h" +#include "HTMLMapElement.h" +#include "HTMLNames.h" #include "MathMLNames.h" +#include "MathMLSelectElement.h" #include "RenderTableCell.h" +#include "SVGElement.h" +#include "SVGNames.h" namespace WebCore { @@ -43,14 +50,147 @@ MathMLElement::MathMLElement(const QualifiedName& tagName, Document& document) { } -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); + 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 @@ -72,11 +212,11 @@ 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); } @@ -123,23 +263,41 @@ 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); + 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; + } - // Only create renderers for MathML elements or text. MathML prohibits non-MathML markup inside a <math> element. - return child.isTextNode() || child.isMathMLElement(); + // 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& newValue, AttributeModificationReason reason) +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 (parent && parent->isMathMLElement() && parent->hasTagName(semanticsTag)) - toMathMLElement(parent)->updateSelectedChild(); + if (is<MathMLElement>(parent) && parent->hasTagName(semanticsTag)) + downcast<MathMLElement>(*parent).updateSelectedChild(); } - StyledElement::attributeChanged(name, newValue, reason); + StyledElement::attributeChanged(name, oldValue, newValue, reason); } } diff --git a/Source/WebCore/mathml/MathMLElement.h b/Source/WebCore/mathml/MathMLElement.h index 02f14a263..ca91ad007 100644 --- a/Source/WebCore/mathml/MathMLElement.h +++ b/Source/WebCore/mathml/MathMLElement.h @@ -37,7 +37,7 @@ namespace WebCore { class MathMLElement : public StyledElement { public: - static PassRefPtr<MathMLElement> create(const QualifiedName& tagName, Document&); + static Ref<MathMLElement> create(const QualifiedName& tagName, Document&); int colSpan() const; int rowSpan() const; @@ -54,26 +54,38 @@ public: virtual bool isPresentationMathML() const; + bool hasTagName(const MathMLQualifiedName& name) const { return hasLocalName(name.localName()); } + protected: MathMLElement(const QualifiedName& tagName, Document&); virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; virtual bool childShouldCreateRenderer(const Node&) const override; - virtual void attributeChanged(const QualifiedName&, const AtomicString& newValue, AttributeModificationReason) override; + virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason) override; virtual bool isPresentationAttribute(const QualifiedName&) const override; virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; -private: - virtual void updateSelectedChild() { }; -}; + bool isPhrasingContent(const Node&) const; + bool isFlowContent(const Node&) const; -void isMathMLElement(const MathMLElement&); // Catch unnecessary runtime check of type known at compile time. -inline bool isMathMLElement(const Node& node) { return node.isMathMLElement(); } -NODE_TYPE_CASTS(MathMLElement) +private: + virtual void updateSelectedChild() { } +}; +inline bool Node::hasTagName(const MathMLQualifiedName& name) const +{ + return isMathMLElement() && downcast<MathMLElement>(*this).hasTagName(name); } +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MathMLElement) + static bool isType(const WebCore::Node& node) { return node.isMathMLElement(); } +SPECIALIZE_TYPE_TRAITS_END() + +#include "MathMLElementTypeHelpers.h" + #endif // ENABLE(MATHML) #endif // MathMLElement_h diff --git a/Source/WebCore/mathml/MathMLInlineContainerElement.cpp b/Source/WebCore/mathml/MathMLInlineContainerElement.cpp index edc809cd1..8011b5e54 100644 --- a/Source/WebCore/mathml/MathMLInlineContainerElement.cpp +++ b/Source/WebCore/mathml/MathMLInlineContainerElement.cpp @@ -50,43 +50,57 @@ MathMLInlineContainerElement::MathMLInlineContainerElement(const QualifiedName& { } -PassRefPtr<MathMLInlineContainerElement> MathMLInlineContainerElement::create(const QualifiedName& tagName, Document& document) +Ref<MathMLInlineContainerElement> MathMLInlineContainerElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new MathMLInlineContainerElement(tagName, document)); + return adoptRef(*new MathMLInlineContainerElement(tagName, document)); } -RenderPtr<RenderElement> MathMLInlineContainerElement::createElementRenderer(PassRef<RenderStyle> style) +void MathMLInlineContainerElement::childrenChanged(const ChildChange& change) { - if (hasLocalName(annotation_xmlTag)) - return createRenderer<RenderMathMLRow>(*this, std::move(style)); - if (hasLocalName(merrorTag) || hasLocalName(mphantomTag) || hasLocalName(mrowTag) || hasLocalName(mstyleTag)) - return createRenderer<RenderMathMLRow>(*this, std::move(style)); - if (hasLocalName(msubTag)) - return createRenderer<RenderMathMLScripts>(*this, std::move(style)); - if (hasLocalName(msupTag)) - return createRenderer<RenderMathMLScripts>(*this, std::move(style)); - if (hasLocalName(msubsupTag)) - return createRenderer<RenderMathMLScripts>(*this, std::move(style)); - if (hasLocalName(mmultiscriptsTag)) - return createRenderer<RenderMathMLScripts>(*this, std::move(style)); - if (hasLocalName(moverTag)) - return createRenderer<RenderMathMLUnderOver>(*this, std::move(style)); - if (hasLocalName(munderTag)) - return createRenderer<RenderMathMLUnderOver>(*this, std::move(style)); - if (hasLocalName(munderoverTag)) - return createRenderer<RenderMathMLUnderOver>(*this, std::move(style)); - if (hasLocalName(mfracTag)) - return createRenderer<RenderMathMLFraction>(*this, std::move(style)); - if (hasLocalName(msqrtTag)) - return createRenderer<RenderMathMLSquareRoot>(*this, std::move(style)); - if (hasLocalName(mrootTag)) - return createRenderer<RenderMathMLRoot>(*this, std::move(style)); - if (hasLocalName(mfencedTag)) - return createRenderer<RenderMathMLFenced>(*this, std::move(style)); - if (hasLocalName(mtableTag)) - return createRenderer<RenderMathMLTable>(*this, std::move(style)); + if (renderer()) { + if (is<RenderMathMLRow>(*renderer())) + downcast<RenderMathMLRow>(*renderer()).updateOperatorProperties(); + else if (hasTagName(mathTag) || hasTagName(msqrtTag)) { + auto* childRenderer = renderer()->firstChild(); + if (is<RenderMathMLRow>(childRenderer)) + downcast<RenderMathMLRow>(*childRenderer).updateOperatorProperties(); + } + } + MathMLElement::childrenChanged(change); +} + +RenderPtr<RenderElement> MathMLInlineContainerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&) +{ + if (hasTagName(annotation_xmlTag)) + return createRenderer<RenderMathMLRow>(*this, WTFMove(style)); + if (hasTagName(merrorTag) || hasTagName(mphantomTag) || hasTagName(mrowTag) || hasTagName(mstyleTag)) + return createRenderer<RenderMathMLRow>(*this, WTFMove(style)); + if (hasTagName(msubTag)) + return createRenderer<RenderMathMLScripts>(*this, WTFMove(style)); + if (hasTagName(msupTag)) + return createRenderer<RenderMathMLScripts>(*this, WTFMove(style)); + if (hasTagName(msubsupTag)) + return createRenderer<RenderMathMLScripts>(*this, WTFMove(style)); + if (hasTagName(mmultiscriptsTag)) + return createRenderer<RenderMathMLScripts>(*this, WTFMove(style)); + if (hasTagName(moverTag)) + return createRenderer<RenderMathMLUnderOver>(*this, WTFMove(style)); + if (hasTagName(munderTag)) + return createRenderer<RenderMathMLUnderOver>(*this, WTFMove(style)); + if (hasTagName(munderoverTag)) + return createRenderer<RenderMathMLUnderOver>(*this, WTFMove(style)); + if (hasTagName(mfracTag)) + return createRenderer<RenderMathMLFraction>(*this, WTFMove(style)); + if (hasTagName(msqrtTag)) + return createRenderer<RenderMathMLSquareRoot>(*this, WTFMove(style)); + if (hasTagName(mrootTag)) + return createRenderer<RenderMathMLRoot>(*this, WTFMove(style)); + if (hasTagName(mfencedTag)) + return createRenderer<RenderMathMLFenced>(*this, WTFMove(style)); + if (hasTagName(mtableTag)) + return createRenderer<RenderMathMLTable>(*this, WTFMove(style)); - return createRenderer<RenderMathMLBlock>(*this, std::move(style)); + return createRenderer<RenderMathMLBlock>(*this, WTFMove(style)); } } diff --git a/Source/WebCore/mathml/MathMLInlineContainerElement.h b/Source/WebCore/mathml/MathMLInlineContainerElement.h index eb7b3d615..81e1ee53f 100644 --- a/Source/WebCore/mathml/MathMLInlineContainerElement.h +++ b/Source/WebCore/mathml/MathMLInlineContainerElement.h @@ -34,15 +34,16 @@ namespace WebCore { class MathMLInlineContainerElement : public MathMLElement { public: - static PassRefPtr<MathMLInlineContainerElement> create(const QualifiedName& tagName, Document&); + static Ref<MathMLInlineContainerElement> create(const QualifiedName& tagName, Document&); virtual bool isPresentationMathML() const override { return true; } protected: MathMLInlineContainerElement(const QualifiedName& tagName, Document&); + virtual void childrenChanged(const ChildChange&) override; private: - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override; }; } diff --git a/Source/WebCore/mathml/MathMLMathElement.cpp b/Source/WebCore/mathml/MathMLMathElement.cpp index 6f2f389ba..31036c502 100644 --- a/Source/WebCore/mathml/MathMLMathElement.cpp +++ b/Source/WebCore/mathml/MathMLMathElement.cpp @@ -38,22 +38,14 @@ inline MathMLMathElement::MathMLMathElement(const QualifiedName& tagName, Docume { } -PassRefPtr<MathMLMathElement> MathMLMathElement::create(const QualifiedName& tagName, Document& document) +Ref<MathMLMathElement> MathMLMathElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new MathMLMathElement(tagName, document)); + return adoptRef(*new MathMLMathElement(tagName, document)); } -Node::InsertionNotificationRequest MathMLMathElement::insertedInto(ContainerNode& insertionPoint) +RenderPtr<RenderElement> MathMLMathElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&) { - // There are sibling rules in the MathML default style. - if (insertionPoint.inDocument()) - document().styleSheetCollection().setUsesSiblingRulesOverride(true); - return MathMLInlineContainerElement::insertedInto(insertionPoint); -} - -RenderPtr<RenderElement> MathMLMathElement::createElementRenderer(PassRef<RenderStyle> style) -{ - return createRenderer<RenderMathMLMath>(*this, std::move(style)); + return createRenderer<RenderMathMLMath>(*this, WTFMove(style)); } } diff --git a/Source/WebCore/mathml/MathMLMathElement.h b/Source/WebCore/mathml/MathMLMathElement.h index 23873e922..04ec69cbd 100644 --- a/Source/WebCore/mathml/MathMLMathElement.h +++ b/Source/WebCore/mathml/MathMLMathElement.h @@ -34,13 +34,12 @@ namespace WebCore { class MathMLMathElement : public MathMLInlineContainerElement { public: - static PassRefPtr<MathMLMathElement> create(const QualifiedName& tagName, Document&); + static Ref<MathMLMathElement> create(const QualifiedName& tagName, Document&); private: MathMLMathElement(const QualifiedName& tagName, Document&); - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override; }; } diff --git a/Source/WebCore/mathml/MathMLMencloseElement.cpp b/Source/WebCore/mathml/MathMLMencloseElement.cpp index 4013d887d..3612ccb33 100755..100644 --- a/Source/WebCore/mathml/MathMLMencloseElement.cpp +++ b/Source/WebCore/mathml/MathMLMencloseElement.cpp @@ -45,14 +45,14 @@ MathMLMencloseElement::MathMLMencloseElement(const QualifiedName& tagName, Docum { } -PassRefPtr<MathMLMencloseElement> MathMLMencloseElement::create(const QualifiedName& tagName, Document& document) +Ref<MathMLMencloseElement> MathMLMencloseElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new MathMLMencloseElement(tagName, document)); + return adoptRef(*new MathMLMencloseElement(tagName, document)); } -RenderPtr<RenderElement> MathMLMencloseElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> MathMLMencloseElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&) { - return createRenderer<RenderMathMLMenclose>(*this, std::move(style)); + return createRenderer<RenderMathMLMenclose>(*this, WTFMove(style)); } bool MathMLMencloseElement::isPresentationAttribute(const QualifiedName& name) const @@ -78,7 +78,7 @@ void MathMLMencloseElement::collectStyleForPresentationAttribute(const Qualified if (val.isEmpty()) return; if (name == MathMLNames::notationAttr) { - val.split(" ", m_notationValues); + val.split(' ', m_notationValues); size_t notationValueSize = m_notationValues.size(); for (size_t i = 0; i < notationValueSize; i++) { if (m_notationValues[i] == "top" || m_notationValues[i] == "longdiv") { @@ -129,15 +129,13 @@ void MathMLMencloseElement::collectStyleForPresentationAttribute(const Qualified String MathMLMencloseElement::longDivLeftPadding() const { StringBuilder padding; - float fontSize = 0; - String closingBrace = ")"; - TextRun run(closingBrace.impl(), closingBrace.length()); + String closingBrace(")", String::ConstructFromLiteral); + TextRun run(closingBrace); Node* node = parentNode(); if (node && node->renderer()) { - const Font& font = node->renderer()->style().font(); - fontSize = font.width(run); - padding.append(String::number(fontSize)); - padding.append("px"); + const FontCascade& font = node->renderer()->style().fontCascade(); + padding.appendNumber(font.width(run)); + padding.appendLiteral("px"); } return padding.toString(); } diff --git a/Source/WebCore/mathml/MathMLMencloseElement.h b/Source/WebCore/mathml/MathMLMencloseElement.h index 3c0ee9095..5f442c394 100755..100644 --- a/Source/WebCore/mathml/MathMLMencloseElement.h +++ b/Source/WebCore/mathml/MathMLMencloseElement.h @@ -33,28 +33,23 @@ namespace WebCore { class MathMLMencloseElement final: public MathMLInlineContainerElement { public: - static PassRefPtr<MathMLMencloseElement> create(const QualifiedName& tagName, Document&); + static Ref<MathMLMencloseElement> create(const QualifiedName& tagName, Document&); const Vector<String>& notationValues() const { return m_notationValues; } bool isRadical() const { return m_isRadicalValue; } + String longDivLeftPadding() const; + bool isDefaultLongDiv() const { return !hasAttribute(MathMLNames::notationAttr); } private: MathMLMencloseElement(const QualifiedName&, Document&); - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override; virtual bool isPresentationAttribute(const QualifiedName&) const override; virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; virtual void finishParsingChildren() override; - String longDivLeftPadding() const; Vector<String> m_notationValues; bool m_isRadicalValue; }; -inline MathMLMencloseElement* toMathMLMencloseElement(Node* node) -{ - ASSERT_WITH_SECURITY_IMPLICATION(!node || (node->isElementNode() && toElement(node)->hasTagName(MathMLNames::mencloseTag))); - return static_cast<MathMLMencloseElement*>(node); -} - } #endif // ENABLE(MATHML) diff --git a/Source/WebCore/mathml/MathMLSelectElement.cpp b/Source/WebCore/mathml/MathMLSelectElement.cpp index a22d584bd..1226a36d4 100644 --- a/Source/WebCore/mathml/MathMLSelectElement.cpp +++ b/Source/WebCore/mathml/MathMLSelectElement.cpp @@ -29,8 +29,13 @@ #if ENABLE(MATHML) #include "Event.h" +#include "HTMLElement.h" +#include "HTMLNames.h" #include "MathMLNames.h" #include "RenderMathMLRow.h" +#include "SVGElement.h" +#include "SVGNames.h" +#include "StyleTreeResolver.h" namespace WebCore { @@ -42,14 +47,37 @@ MathMLSelectElement::MathMLSelectElement(const QualifiedName& tagName, Document& { } -PassRefPtr<MathMLSelectElement> MathMLSelectElement::create(const QualifiedName& tagName, Document& document) +Ref<MathMLSelectElement> MathMLSelectElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new MathMLSelectElement(tagName, document)); + return adoptRef(*new MathMLSelectElement(tagName, document)); } -RenderPtr<RenderElement> MathMLSelectElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> MathMLSelectElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&) { - return createRenderer<RenderMathMLRow>(*this, std::move(style)); + return createRenderer<RenderMathMLRow>(*this, WTFMove(style)); +} + +// We recognize the following values for the encoding attribute of the <semantics> element: +// +// - "MathML-Presentation", which is mentioned in the MathML 3 recommendation. +// - "SVG1.1" which is mentioned in the W3C note. +// http://www.w3.org/Math/Documents/Notes/graphics.xml +// - Other MIME Content-Types for MathML, SVG and HTML. +// +// We exclude "application/mathml+xml" which is ambiguous about whether it is Presentation or Content MathML. Authors must use a more explicit encoding value. +bool MathMLSelectElement::isMathMLEncoding(const AtomicString& value) +{ + return value == "application/mathml-presentation+xml" || value == "MathML-Presentation"; +} + +bool MathMLSelectElement::isSVGEncoding(const AtomicString& value) +{ + return value == "image/svg+xml" || value == "SVG1.1"; +} + +bool MathMLSelectElement::isHTMLEncoding(const AtomicString& value) +{ + return value == "application/xhtml+xml" || value == "text/html"; } bool MathMLSelectElement::childShouldCreateRenderer(const Node& child) const @@ -69,17 +97,17 @@ void MathMLSelectElement::childrenChanged(const ChildChange& change) MathMLInlineContainerElement::childrenChanged(change); } -void MathMLSelectElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason) +void MathMLSelectElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason) { - if (hasLocalName(mactionTag) && (name == MathMLNames::actiontypeAttr || name == MathMLNames::selectionAttr)) + if (hasTagName(mactionTag) && (name == MathMLNames::actiontypeAttr || name == MathMLNames::selectionAttr)) updateSelectedChild(); - MathMLInlineContainerElement::attributeChanged(name, newValue, reason); + MathMLInlineContainerElement::attributeChanged(name, oldValue, newValue, reason); } int MathMLSelectElement::getSelectedActionChildAndIndex(Element*& selectedChild) { - ASSERT(hasLocalName(mactionTag)); + ASSERT(hasTagName(mactionTag)); // We "round up or down to the closest allowable value" of the selection attribute, as suggested by the MathML specification. selectedChild = firstElementChild(); @@ -100,7 +128,7 @@ int MathMLSelectElement::getSelectedActionChildAndIndex(Element*& selectedChild) Element* MathMLSelectElement::getSelectedActionChild() { - ASSERT(hasLocalName(mactionTag)); + ASSERT(hasTagName(mactionTag)); Element* child = firstElementChild(); if (!child) @@ -124,26 +152,26 @@ Element* MathMLSelectElement::getSelectedActionChild() Element* MathMLSelectElement::getSelectedSemanticsChild() { - ASSERT(hasLocalName(semanticsTag)); + ASSERT(hasTagName(semanticsTag)); Element* child = firstElementChild(); if (!child) - return child; + return nullptr; - if (!child->isMathMLElement() || !toMathMLElement(child)->isPresentationMathML()) { + if (!is<MathMLElement>(*child) || !downcast<MathMLElement>(*child).isPresentationMathML()) { // The first child is not a presentation MathML element. Hence we move to the second child and start searching an annotation child that could be displayed. child = child->nextElementSibling(); - } else if (!toMathMLElement(child)->isSemanticAnnotation()) { + } else if (!downcast<MathMLElement>(*child).isSemanticAnnotation()) { // The first child is a presentation MathML but not an annotation, so we can just display it. return child; } // Otherwise, the first child is an <annotation> or <annotation-xml> element. This is invalid, but some people use this syntax so we take care of this case too and start the search from this first child. for ( ; child; child = child->nextElementSibling()) { - if (!child->isMathMLElement()) + if (!is<MathMLElement>(*child)) continue; - if (child->hasLocalName(MathMLNames::annotationTag)) { + if (child->hasTagName(MathMLNames::annotationTag)) { // If the <annotation> element has an src attribute then it is a reference to arbitrary binary data and it is not clear whether we can display it. Hence we just ignore the annotation. if (child->hasAttribute(MathMLNames::srcAttr)) continue; @@ -151,20 +179,13 @@ Element* MathMLSelectElement::getSelectedSemanticsChild() return child; } - if (child->hasLocalName(MathMLNames::annotation_xmlTag)) { + if (child->hasTagName(MathMLNames::annotation_xmlTag)) { // If the <annotation-xml> element has an src attribute then it is a reference to arbitrary binary data and it is not clear whether we can display it. Hence we just ignore the annotation. if (child->hasAttribute(MathMLNames::srcAttr)) continue; - // If the <annotation-xml> element has an encoding attribute describing presentation MathML, SVG or HTML we assume the content can be displayed and we stop here. We recognize the following encoding values: - // - // - "MathML-Presentation", which is mentioned in the MathML 3 recommendation. - // - "SVG1.1" which is mentioned in the W3C note. - // http://www.w3.org/Math/Documents/Notes/graphics.xml - // - Other MIME Content-Types for SVG and HTML. - // - // We exclude "application/mathml+xml" which is ambiguous about whether it is Presentation or Content MathML. Authors must use a more explicit encoding value. + // If the <annotation-xml> element has an encoding attribute describing presentation MathML, SVG or HTML we assume the content can be displayed and we stop here. const AtomicString& value = child->fastGetAttribute(MathMLNames::encodingAttr); - if (value == "application/mathml-presentation+xml" || value == "MathML-Presentation" || value == "image/svg+xml" || value == "SVG1.1" || value == "application/xhtml+xml" || value == "text/html") + if (isMathMLEncoding(value) || isSVGEncoding(value) || isHTMLEncoding(value)) return child; } } @@ -175,7 +196,7 @@ Element* MathMLSelectElement::getSelectedSemanticsChild() void MathMLSelectElement::updateSelectedChild() { - Element* newSelectedChild = hasLocalName(mactionTag) ? getSelectedActionChild() : getSelectedSemanticsChild(); + Element* newSelectedChild = hasTagName(mactionTag) ? getSelectedActionChild() : getSelectedSemanticsChild(); if (m_selectedChild == newSelectedChild) return; diff --git a/Source/WebCore/mathml/MathMLSelectElement.h b/Source/WebCore/mathml/MathMLSelectElement.h index 30f3ecc60..38ed70c9c 100644 --- a/Source/WebCore/mathml/MathMLSelectElement.h +++ b/Source/WebCore/mathml/MathMLSelectElement.h @@ -33,17 +33,20 @@ namespace WebCore { class MathMLSelectElement final : public MathMLInlineContainerElement { public: - static PassRefPtr<MathMLSelectElement> create(const QualifiedName& tagName, Document&); + static Ref<MathMLSelectElement> create(const QualifiedName& tagName, Document&); + static bool isMathMLEncoding(const AtomicString& value); + static bool isSVGEncoding(const AtomicString& value); + static bool isHTMLEncoding(const AtomicString& value); private: MathMLSelectElement(const QualifiedName& tagName, Document&); - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override; virtual bool childShouldCreateRenderer(const Node&) const override; virtual void finishParsingChildren() override; virtual void childrenChanged(const ChildChange&) override; - virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) override; + virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly) override; virtual void defaultEventHandler(Event*) override; virtual bool willRespondToMouseClickEvents() override; @@ -53,7 +56,7 @@ private: Element* getSelectedSemanticsChild(); void updateSelectedChild() override; - Element* m_selectedChild; + RefPtr<Element> m_selectedChild; }; } diff --git a/Source/WebCore/mathml/MathMLTextElement.cpp b/Source/WebCore/mathml/MathMLTextElement.cpp index 4f17b6c10..0a587c8fb 100644 --- a/Source/WebCore/mathml/MathMLTextElement.cpp +++ b/Source/WebCore/mathml/MathMLTextElement.cpp @@ -33,6 +33,7 @@ #include "MathMLNames.h" #include "RenderMathMLOperator.h" #include "RenderMathMLSpace.h" +#include "RenderMathMLToken.h" namespace WebCore { @@ -44,38 +45,65 @@ inline MathMLTextElement::MathMLTextElement(const QualifiedName& tagName, Docume setHasCustomStyleResolveCallbacks(); } -PassRefPtr<MathMLTextElement> MathMLTextElement::create(const QualifiedName& tagName, Document& document) +Ref<MathMLTextElement> MathMLTextElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new MathMLTextElement(tagName, document)); + return adoptRef(*new MathMLTextElement(tagName, document)); } void MathMLTextElement::didAttachRenderers() { MathMLElement::didAttachRenderers(); - if (renderer()) - renderer()->updateFromElement(); + if (is<RenderMathMLToken>(renderer())) + downcast<RenderMathMLToken>(*renderer()).updateTokenContent(); } void MathMLTextElement::childrenChanged(const ChildChange& change) { MathMLElement::childrenChanged(change); - if (renderer()) - renderer()->updateFromElement(); + if (is<RenderMathMLToken>(renderer())) + downcast<RenderMathMLToken>(*renderer()).updateTokenContent(); } -RenderPtr<RenderElement> MathMLTextElement::createElementRenderer(PassRef<RenderStyle> style) +void MathMLTextElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (hasLocalName(MathMLNames::moTag)) - return createRenderer<RenderMathMLOperator>(*this, std::move(style)); - if (hasLocalName(MathMLNames::mspaceTag)) - return createRenderer<RenderMathMLSpace>(*this, std::move(style)); + if (name == stretchyAttr) { + if (is<RenderMathMLOperator>(renderer())) + downcast<RenderMathMLOperator>(*renderer()).setOperatorFlagAndScheduleLayoutIfNeeded(MathMLOperatorDictionary::Stretchy, value); + return; + } - return MathMLElement::createElementRenderer(std::move(style)); + MathMLElement::parseAttribute(name, value); +} + +RenderPtr<RenderElement> MathMLTextElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition& insertionPosition) +{ + if (hasTagName(MathMLNames::moTag)) + return createRenderer<RenderMathMLOperator>(*this, WTFMove(style)); + if (hasTagName(MathMLNames::mspaceTag)) + return createRenderer<RenderMathMLSpace>(*this, WTFMove(style)); + if (hasTagName(MathMLNames::annotationTag)) + return MathMLElement::createElementRenderer(WTFMove(style), insertionPosition); + + ASSERT(hasTagName(MathMLNames::miTag) || hasTagName(MathMLNames::mnTag) || hasTagName(MathMLNames::msTag) || hasTagName(MathMLNames::mtextTag)); + + // FIXME: why do we have to set the alignment here ? It seems needed to make the + // style-changed.htmt test to pass, since mathml renders expect Stretch as default. + style.get().setAlignItemsPosition(ItemPositionStretch); + + return createRenderer<RenderMathMLToken>(*this, WTFMove(style)); } bool MathMLTextElement::childShouldCreateRenderer(const Node& child) const { - return child.isTextNode(); + if (hasTagName(MathMLNames::mspaceTag)) + return false; + + // FIXME: phrasing content should be accepted in <mo> elements too (https://bugs.webkit.org/show_bug.cgi?id=130245). + if (hasTagName(MathMLNames::annotationTag) || hasTagName(MathMLNames::moTag)) + return child.isTextNode(); + + // The HTML specification defines <mi>, <mo>, <mn>, <ms> and <mtext> as insertion points. + return isPhrasingContent(child) && StyledElement::childShouldCreateRenderer(child); } } diff --git a/Source/WebCore/mathml/MathMLTextElement.h b/Source/WebCore/mathml/MathMLTextElement.h index 4135155d6..1d5f57858 100644 --- a/Source/WebCore/mathml/MathMLTextElement.h +++ b/Source/WebCore/mathml/MathMLTextElement.h @@ -32,9 +32,9 @@ namespace WebCore { -class MathMLTextElement : public MathMLElement { +class MathMLTextElement final : public MathMLElement { public: - static PassRefPtr<MathMLTextElement> create(const QualifiedName& tagName, Document&); + static Ref<MathMLTextElement> create(const QualifiedName& tagName, Document&); virtual void didAttachRenderers() override; virtual bool isPresentationMathML() const override { return true; } @@ -42,10 +42,11 @@ public: private: MathMLTextElement(const QualifiedName& tagName, Document&); - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override; virtual bool childShouldCreateRenderer(const Node&) const override; virtual void childrenChanged(const ChildChange&) override; + virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; }; } diff --git a/Source/WebCore/mathml/mathattrs.in b/Source/WebCore/mathml/mathattrs.in index abfdbb5bb..077e79c78 100644 --- a/Source/WebCore/mathml/mathattrs.in +++ b/Source/WebCore/mathml/mathattrs.in @@ -3,6 +3,7 @@ namespaceURI="http://www.w3.org/1998/Math/MathML" guardFactoryWith="ENABLE(MATHML)" attrsNullNamespace +accent actiontype alttext background @@ -14,24 +15,34 @@ denomalign depth dir encoding +fence fontfamily fontsize fontstyle fontweight +form height +largeop linethickness +lspace mathbackground mathcolor mathsize mathvariant +maxsize +minsize +movablelimits notation numalign open rowspan +rspace +separator selection separators src stretchy +symmetric subscriptshift superscriptshift width diff --git a/Source/WebCore/mathml/mathtags.in b/Source/WebCore/mathml/mathtags.in index 7cce6d72e..5d081d1d2 100644 --- a/Source/WebCore/mathml/mathtags.in +++ b/Source/WebCore/mathml/mathtags.in @@ -23,6 +23,7 @@ mi interfaceName=MathMLTextElement mn interfaceName=MathMLTextElement mo interfaceName=MathMLTextElement mtext interfaceName=MathMLTextElement +ms interfaceName=MathMLTextElement mspace interfaceName=MathMLTextElement msub interfaceName=MathMLInlineContainerElement msup interfaceName=MathMLInlineContainerElement @@ -41,7 +42,6 @@ mglyph interfaceName=MathMLElement mlabeledtr interfaceName=MathMLElement mlongdiv interfaceName=MathMLElement mpadded interfaceName=MathMLElement -ms interfaceName=MathMLElement mscarries interfaceName=MathMLElement mscarry interfaceName=MathMLElement msgroup interfaceName=MathMLElement |
