Move parsing of subscriptshift and superscriptshift from rendering to element classes
authorfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jul 2016 05:42:46 +0000 (05:42 +0000)
committerfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jul 2016 05:42:46 +0000 (05:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=159622

Patch by Frederic Wang <fwang@igalia.com> on 2016-07-18
Reviewed by Darin Adler.

We introduce a new MathMLScriptsElement that is used for elements msub, msup, msubsup and
mmultiscripts in order to create RenderMathMLScripts and parse and expose the values of the
subscriptshift and superscriptshift attributes. This is one more step toward moving MathML
attribute parsing to the DOM (bug 156536).

No new tests, rendering is unchanged.

* CMakeLists.txt: Add MathMLScriptsElement files.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* mathml/MathMLAllInOne.cpp: Ditto.
* mathml/MathMLInlineContainerElement.cpp: Remove handling of scripts.
(WebCore::MathMLInlineContainerElement::createElementRenderer): Deleted.
* mathml/MathMLScriptsElement.cpp: Added. New class to handle scripted elements supporting
parsing for the subscriptshift and superscriptshift MathML lengths.
(WebCore::MathMLScriptsElement::MathMLScriptsElement):
(WebCore::MathMLScriptsElement::create):
(WebCore::MathMLScriptsElement::subscriptShift): Expose the cached length for the shift,
parsing the attribute again if necessary.
(WebCore::MathMLScriptsElement::superscriptShift): Ditto.
(WebCore::MathMLScriptsElement::parseAttribute): Mark attributes dirty.
(WebCore::MathMLScriptsElement::createElementRenderer): Create RenderMathMLScripts.
* mathml/MathMLScriptsElement.h: Ditto.
* mathml/mathtags.in: Map msub, msup, msubsup and mmultiscripts to MathMLScriptsElement.
* rendering/mathml/RenderMathMLScripts.cpp:
(WebCore::RenderMathMLScripts::scriptsElement): Helper function to cast the node to a
MathMLScriptsElement.
(WebCore::RenderMathMLScripts::getScriptMetricsAndLayoutIfNeeded): Resolve the attributes
using the functions from the MathMLScriptsElement class.
* rendering/mathml/RenderMathMLScripts.h: Declare scriptsElement.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203396 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/mathml/MathMLAllInOne.cpp
Source/WebCore/mathml/MathMLInlineContainerElement.cpp
Source/WebCore/mathml/MathMLScriptsElement.cpp [new file with mode: 0644]
Source/WebCore/mathml/MathMLScriptsElement.h [new file with mode: 0644]
Source/WebCore/mathml/mathtags.in
Source/WebCore/rendering/mathml/RenderMathMLScripts.cpp
Source/WebCore/rendering/mathml/RenderMathMLScripts.h

index 3472c1b..3d75661 100644 (file)
@@ -1991,6 +1991,7 @@ set(WebCore_SOURCES
     mathml/MathMLMencloseElement.cpp
     mathml/MathMLOperatorDictionary.cpp
     mathml/MathMLPaddedElement.cpp
+    mathml/MathMLScriptsElement.cpp
     mathml/MathMLSelectElement.cpp
     mathml/MathMLSpaceElement.cpp
     mathml/MathMLTextElement.cpp
index d2fedd7..9af7e7f 100644 (file)
@@ -1,5 +1,42 @@
 2016-07-18  Frederic Wang  <fwang@igalia.com>
 
+        Move parsing of subscriptshift and superscriptshift from rendering to element classes
+        https://bugs.webkit.org/show_bug.cgi?id=159622
+
+        Reviewed by Darin Adler.
+
+        We introduce a new MathMLScriptsElement that is used for elements msub, msup, msubsup and
+        mmultiscripts in order to create RenderMathMLScripts and parse and expose the values of the
+        subscriptshift and superscriptshift attributes. This is one more step toward moving MathML
+        attribute parsing to the DOM (bug 156536).
+
+        No new tests, rendering is unchanged.
+
+        * CMakeLists.txt: Add MathMLScriptsElement files.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * mathml/MathMLAllInOne.cpp: Ditto.
+        * mathml/MathMLInlineContainerElement.cpp: Remove handling of scripts.
+        (WebCore::MathMLInlineContainerElement::createElementRenderer): Deleted.
+        * mathml/MathMLScriptsElement.cpp: Added. New class to handle scripted elements supporting
+        parsing for the subscriptshift and superscriptshift MathML lengths.
+        (WebCore::MathMLScriptsElement::MathMLScriptsElement):
+        (WebCore::MathMLScriptsElement::create):
+        (WebCore::MathMLScriptsElement::subscriptShift): Expose the cached length for the shift,
+        parsing the attribute again if necessary.
+        (WebCore::MathMLScriptsElement::superscriptShift): Ditto.
+        (WebCore::MathMLScriptsElement::parseAttribute): Mark attributes dirty.
+        (WebCore::MathMLScriptsElement::createElementRenderer): Create RenderMathMLScripts.
+        * mathml/MathMLScriptsElement.h: Ditto.
+        * mathml/mathtags.in: Map msub, msup, msubsup and mmultiscripts to MathMLScriptsElement.
+        * rendering/mathml/RenderMathMLScripts.cpp:
+        (WebCore::RenderMathMLScripts::scriptsElement): Helper function to cast the node to a
+        MathMLScriptsElement.
+        (WebCore::RenderMathMLScripts::getScriptMetricsAndLayoutIfNeeded): Resolve the attributes
+        using the functions from the MathMLScriptsElement class.
+        * rendering/mathml/RenderMathMLScripts.h: Declare scriptsElement.
+
+2016-07-18  Frederic Wang  <fwang@igalia.com>
+
         Do not store gap and shift parameters on RenderMathMLFraction
         https://bugs.webkit.org/show_bug.cgi?id=159876
 
index 0feece1..2d82be2 100644 (file)
                B57CB52D182A3EED0079A647 /* InlineElementBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B57CB52C182A3EED0079A647 /* InlineElementBox.cpp */; };
                B57CB52E182A3EFC0079A647 /* InlineElementBox.h in Headers */ = {isa = PBXBuildFile; fileRef = B57CB52B182A37F60079A647 /* InlineElementBox.h */; };
                B595FF471824CEE300FF51CD /* RenderIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = B595FF461824CEE300FF51CD /* RenderIterator.h */; };
+               B59CA390CED66C3255F72B48 /* MathMLScriptsElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59CA59AF170D8FAA5B8C9AD /* MathMLScriptsElement.cpp */; };
                B59CA390CED66C3255F72C59 /* MathMLPaddedElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59CA59AF170D8FAA5B8CABE /* MathMLPaddedElement.cpp */; };
                B59DD699119029E5007E9684 /* JSDatabaseCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B59DD697119029E5007E9684 /* JSDatabaseCallback.h */; };
                B59DD69A119029E5007E9684 /* JSDatabaseCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59DD698119029E5007E9684 /* JSDatabaseCallback.cpp */; };
                B57CB52B182A37F60079A647 /* InlineElementBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineElementBox.h; sourceTree = "<group>"; };
                B57CB52C182A3EED0079A647 /* InlineElementBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineElementBox.cpp; sourceTree = "<group>"; };
                B595FF461824CEE300FF51CD /* RenderIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderIterator.h; sourceTree = "<group>"; };
+               B59CA59AF170D8FAA5B8C9AD /* MathMLScriptsElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLScriptsElement.cpp; sourceTree = "<group>"; };
+               B59CA849D41E6F65D81197AB /* MathMLScriptsElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLScriptsElement.h; sourceTree = "<group>"; };
                B59CA59AF170D8FAA5B8CABE /* MathMLPaddedElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLPaddedElement.cpp; sourceTree = "<group>"; };
                B59CA849D41E6F65D81198BC /* MathMLPaddedElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLPaddedElement.h; sourceTree = "<group>"; };
                B59DD697119029E5007E9684 /* JSDatabaseCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDatabaseCallback.h; sourceTree = "<group>"; };
                                CE6D89294C7AACE0AD89B3DD /* MathMLMencloseElement.h */,
                                D4F72C653A64807A83E76FB8 /* MathMLOperatorDictionary.cpp */,
                                DF7E9A294C7AACE0AD89B3DD /* MathMLOperatorDictionary.h */,
+                               B59CA59AF170D8FAA5B8C9AD /* MathMLScriptsElement.cpp */,
+                               B59CA849D41E6F65D81197AB /* MathMLScriptsElement.h */,
                                B59CA59AF170D8FAA5B8CABE /* MathMLPaddedElement.cpp */,
                                B59CA849D41E6F65D81198BC /* MathMLPaddedElement.h */,
                                F75A059AF170D8FAA5B8CABE /* MathMLSelectElement.cpp */,
                                16EA24CEEAB2A60534218ACF /* MathMLOperatorDictionary.cpp in Sources */,
                                FABE72FE1059C21100D999DD /* MathMLNames.cpp in Sources */,
                                439176DF12DA25E17BAF80A2 /* MathMLStyle.cpp in Sources */,
+                               B59CA390CED66C3255F72B48 /* MathMLScriptsElement.cpp in Sources */,
                                B59CA390CED66C3255F72C59 /* MathMLPaddedElement.cpp in Sources */,
                                FED48390CED66C3255F72C59 /* MathMLSelectElement.cpp in Sources */,
                                4FA65A6B1108ABED002615E0 /* MathMLSpaceElement.cpp in Sources */,
index 9268bb4..735330c 100644 (file)
@@ -32,6 +32,7 @@
 #include "MathMLMencloseElement.cpp"
 #include "MathMLOperatorDictionary.cpp"
 #include "MathMLPaddedElement.cpp"
+#include "MathMLScriptsElement.cpp"
 #include "MathMLSelectElement.cpp"
 #include "MathMLTextElement.cpp"
 
index 54dcc35..36219d2 100644 (file)
@@ -36,7 +36,6 @@
 #include "RenderMathMLMenclose.h"
 #include "RenderMathMLRoot.h"
 #include "RenderMathMLRow.h"
-#include "RenderMathMLScripts.h"
 #include "RenderMathMLUnderOver.h"
 
 namespace WebCore {
@@ -66,8 +65,6 @@ RenderPtr<RenderElement> MathMLInlineContainerElement::createElementRenderer(Ren
 {
     if (hasTagName(annotation_xmlTag) || hasTagName(merrorTag) || hasTagName(mphantomTag) || hasTagName(mrowTag) || hasTagName(mstyleTag))
         return createRenderer<RenderMathMLRow>(*this, WTFMove(style));
-    if (hasTagName(msubTag) || hasTagName(msupTag) || hasTagName(msubsupTag) || hasTagName(mmultiscriptsTag))
-        return createRenderer<RenderMathMLScripts>(*this, WTFMove(style));
     if (hasTagName(moverTag) || hasTagName(munderTag) || hasTagName(munderoverTag))
         return createRenderer<RenderMathMLUnderOver>(*this, WTFMove(style));
     if (hasTagName(msqrtTag) || hasTagName(mrootTag))
diff --git a/Source/WebCore/mathml/MathMLScriptsElement.cpp b/Source/WebCore/mathml/MathMLScriptsElement.cpp
new file mode 100644 (file)
index 0000000..e0bf486
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Igalia S.L. 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+#include "MathMLScriptsElement.h"
+
+#include "RenderMathMLScripts.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+inline MathMLScriptsElement::MathMLScriptsElement(const QualifiedName& tagName, Document& document)
+    : MathMLInlineContainerElement(tagName, document)
+{
+}
+
+Ref<MathMLScriptsElement> MathMLScriptsElement::create(const QualifiedName& tagName, Document& document)
+{
+    return adoptRef(*new MathMLScriptsElement(tagName, document));
+}
+
+const MathMLElement::Length& MathMLScriptsElement::subscriptShift()
+{
+    return cachedMathMLLength(subscriptshiftAttr, m_subscriptShift);
+}
+
+const MathMLElement::Length& MathMLScriptsElement::superscriptShift()
+{
+    return cachedMathMLLength(superscriptshiftAttr, m_superscriptShift);
+}
+
+void MathMLScriptsElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+    if (name == subscriptshiftAttr)
+        m_subscriptShift.dirty = true;
+    else if (name == superscriptshiftAttr)
+        m_superscriptShift.dirty = true;
+
+    MathMLElement::parseAttribute(name, value);
+}
+
+RenderPtr<RenderElement> MathMLScriptsElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
+{
+    ASSERT(hasTagName(msubTag) || hasTagName(msupTag) || hasTagName(msubsupTag) || hasTagName(mmultiscriptsTag));
+    return createRenderer<RenderMathMLScripts>(*this, WTFMove(style));
+}
+
+}
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/MathMLScriptsElement.h b/Source/WebCore/mathml/MathMLScriptsElement.h
new file mode 100644 (file)
index 0000000..75e17c9
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Igalia S.L. 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+#pragma once
+
+#if ENABLE(MATHML)
+#include "MathMLInlineContainerElement.h"
+
+namespace WebCore {
+
+class MathMLScriptsElement final : public MathMLInlineContainerElement {
+public:
+    static Ref<MathMLScriptsElement> create(const QualifiedName& tagName, Document&);
+    const Length& subscriptShift();
+    const Length& superscriptShift();
+
+private:
+    MathMLScriptsElement(const QualifiedName& tagName, Document&);
+    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
+    void parseAttribute(const QualifiedName&, const AtomicString&) final;
+
+    Length m_subscriptShift;
+    Length m_superscriptShift;
+};
+
+}
+
+#endif // ENABLE(MATHML)
index 82c8eac..d992ce4 100644 (file)
@@ -9,7 +9,7 @@ maction interfaceName=MathMLSelectElement
 math
 mfrac interfaceName=MathMLFractionElement
 mfenced interfaceName=MathMLInlineContainerElement
-msubsup interfaceName=MathMLInlineContainerElement
+msubsup interfaceName=MathMLScriptsElement
 merror interfaceName=MathMLInlineContainerElement
 mpadded interfaceName=MathMLPaddedElement
 mphantom interfaceName=MathMLInlineContainerElement
@@ -26,12 +26,12 @@ mo interfaceName=MathMLTextElement
 mtext interfaceName=MathMLTextElement
 ms interfaceName=MathMLTextElement
 mspace interfaceName=MathMLSpaceElement
-msub interfaceName=MathMLInlineContainerElement
-msup interfaceName=MathMLInlineContainerElement
+msub interfaceName=MathMLScriptsElement
+msup interfaceName=MathMLScriptsElement
 mtable interfaceName=MathMLInlineContainerElement
 mtr interfaceName=MathMLElement
 mtd interfaceName=MathMLElement
-mmultiscripts interfaceName=MathMLInlineContainerElement
+mmultiscripts interfaceName=MathMLScriptsElement
 mprescripts interfaceName=MathMLInlineContainerElement
 menclose interfaceName=MathMLMencloseElement
 none interfaceName=MathMLInlineContainerElement
index da122f6..13fbfd4 100644 (file)
@@ -32,6 +32,7 @@
 #include "RenderMathMLScripts.h"
 
 #include "MathMLElement.h"
+#include "MathMLScriptsElement.h"
 #include "RenderMathMLOperator.h"
 
 namespace WebCore {
@@ -65,6 +66,12 @@ RenderMathMLScripts::RenderMathMLScripts(Element& element, RenderStyle&& style)
     }
 }
 
+MathMLScriptsElement& RenderMathMLScripts::scriptsElement() const
+{
+    ASSERT(!isRenderMathMLUnderOver());
+    return static_cast<MathMLScriptsElement&>(nodeForNonAnonymous());
+}
+
 RenderMathMLOperator* RenderMathMLScripts::unembellishedOperator()
 {
     auto base = firstChildBox();
@@ -251,16 +258,18 @@ void RenderMathMLScripts::getScriptMetricsAndLayoutIfNeeded(RenderBox* base, Ren
     if (m_scriptType == Sub || m_scriptType == SubSup || m_scriptType == Multiscripts || m_scriptType == Under || m_scriptType == UnderOver) {
         minSubScriptShift = std::max(subscriptShiftDown, baseDescent + subscriptBaselineDropMin);
         if (!isRenderMathMLUnderOver()) {
-            LayoutUnit specifiedMinSubShift = 0;
-            parseMathMLLength(element()->attributeWithoutSynchronization(MathMLNames::subscriptshiftAttr), specifiedMinSubShift, &style(), false);
+            // It is not clear how to interpret the default shift and it is not available yet anyway.
+            // Hence we just pass 0 as the default value used by toUserUnits.
+            LayoutUnit specifiedMinSubShift = toUserUnits(scriptsElement().subscriptShift(), style(), 0);
             minSubScriptShift = std::max(minSubScriptShift, specifiedMinSubShift);
         }
     }
     if (m_scriptType == Super || m_scriptType == SubSup || m_scriptType == Multiscripts  || m_scriptType == Over || m_scriptType == UnderOver) {
         minSupScriptShift = std::max(superscriptShiftUp, baseAscent - superScriptBaselineDropMax);
         if (!isRenderMathMLUnderOver()) {
-            LayoutUnit specifiedMinSupShift = 0;
-            parseMathMLLength(element()->attributeWithoutSynchronization(MathMLNames::superscriptshiftAttr), specifiedMinSupShift, &style(), false);
+            // It is not clear how to interpret the default shift and it is not available yet anyway.
+            // Hence we just pass 0 as the default value used by toUserUnits.
+            LayoutUnit specifiedMinSupShift = toUserUnits(scriptsElement().superscriptShift(), style(), 0);
             minSupScriptShift = std::max(minSupScriptShift, specifiedMinSupShift);
         }
     }
index 8856ec6..5503c7a 100644 (file)
@@ -32,6 +32,9 @@
 #include "RenderMathMLBlock.h"
 
 namespace WebCore {
+
+class MathMLScriptsElement;
+
 // Render a base with scripts.
 class RenderMathMLScripts : public RenderMathMLBlock {
 public:
@@ -48,6 +51,7 @@ protected:
     ScriptsType m_scriptType;
 
 private:
+    MathMLScriptsElement& scriptsElement() const;
     Optional<int> firstLineBaseline() const final;
     bool getBaseAndScripts(RenderBox*& base, RenderBox*& firstPostScript, RenderBox*& firstPreScript);
     LayoutUnit spaceAfterScript();