Title: [132735] trunk
Revision
132735
Author
[email protected]
Date
2012-10-27 11:18:34 -0700 (Sat, 27 Oct 2012)

Log Message

[MathML] Improve some addChild methods
https://bugs.webkit.org/show_bug.cgi?id=98791

Reviewed by Eric Seidel.

Source/WebCore:

MathML addChild methods need to handle any anonymous renderers correctly. Actually, most MathML elements have a fixed
number of children, so conformant _javascript_ won't be doing arbitrary addChild and removeChild calls. However, we don't
want any assertions to fail, and we do want addChild to work correctly when beforeChild == 0, to build up the original
renderer, and then replaceChild at least should work correctly after that. We therefore clean up these routines before
giving them to the chromium fuzzers.

It's best to build the anonymous wrappers just once initially if possible, so empty wrappers aren't left in the render
tree after later removeChild calls.

Test: mathml/presentation/dynamic.html added for mfrac and msqrt. There are already tests for dynamically changing
msub/sup elements, in mathml/presentation/m*-changed.xhtml.

* rendering/mathml/RenderMathMLFraction.cpp:
(WebCore::RenderMathMLFraction::addChild):
    - The two wrappers are built initially. Also, the old RenderMathMLBlock::addChild(row, beforeChild); doesn't really
      work because beforeChild is buried inside a wrapper. This new routine allows the numerator and denominator to be
      added initially, and then later replaced with replaceChild. It's not clear whether e.g. a plain removeChild of a
      numerator should move the remaining child from the denominator to the numerator or not, so we ignore that for now.
* rendering/mathml/RenderMathMLRoot.cpp:
(WebCore::RenderMathMLRoot::addChild):
    - A bit of bullet-proofing for the fuzzers.
* rendering/mathml/RenderMathMLSubSup.cpp:
(WebCore::RenderMathMLSubSup::addChild):
    - Like RenderMathMLFraction::addChild, we create the wrappers once initially, and then fill them dynamically.

LayoutTests:

* mathml/presentation/dynamic-expected.html: Added.
* mathml/presentation/dynamic.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (132734 => 132735)


--- trunk/LayoutTests/ChangeLog	2012-10-27 18:17:30 UTC (rev 132734)
+++ trunk/LayoutTests/ChangeLog	2012-10-27 18:18:34 UTC (rev 132735)
@@ -1,3 +1,13 @@
+2012-10-27  David Barton  <[email protected]>
+
+        [MathML] Improve some addChild methods
+        https://bugs.webkit.org/show_bug.cgi?id=98791
+
+        Reviewed by Eric Seidel.
+
+        * mathml/presentation/dynamic-expected.html: Added.
+        * mathml/presentation/dynamic.html: Added.
+
 2012-10-27  Balazs Kelemen  <[email protected]>
 
         Unreviewed gardening.

Added: trunk/LayoutTests/mathml/presentation/dynamic-expected.html (0 => 132735)


--- trunk/LayoutTests/mathml/presentation/dynamic-expected.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/dynamic-expected.html	2012-10-27 18:18:34 UTC (rev 132735)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+
+<math>
+    <mfrac id="mfrac"><mn>5</mn><mn>4</mn></mfrac>
+    
+    <msqrt id="msqrt"><mn>6</mn><mi>b</mi><mn>7</mn></msqrt>
+</math>

Added: trunk/LayoutTests/mathml/presentation/dynamic.html (0 => 132735)


--- trunk/LayoutTests/mathml/presentation/dynamic.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/dynamic.html	2012-10-27 18:18:34 UTC (rev 132735)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+
+<math>
+    <mfrac id="mfrac"><mn>1</mn><mn>2</mn></mfrac>
+    
+    <msqrt id="msqrt"><mi>a</mi><mi>b</mi><mi>c</mi></msqrt>
+    
+    <mn id="mn4">4</mn>
+    <mn id="mn5">5</mn>
+    <mn id="mn6">6</mn>
+    <mn id="mn7">7</mn>
+</math>
+
+<script>
+    document.body.offsetTop;
+    
+    var mfrac = document.getElementById("mfrac");
+    mfrac.replaceChild(document.getElementById("mn4"), mfrac.lastChild);
+    mfrac.replaceChild(document.getElementById("mn5"), mfrac.firstChild);
+    
+    var msqrt = document.getElementById("msqrt");
+    msqrt.replaceChild(document.getElementById("mn6"), msqrt.firstChild);
+    msqrt.replaceChild(document.getElementById("mn7"), msqrt.lastChild);
+</script>

Modified: trunk/Source/WebCore/ChangeLog (132734 => 132735)


--- trunk/Source/WebCore/ChangeLog	2012-10-27 18:17:30 UTC (rev 132734)
+++ trunk/Source/WebCore/ChangeLog	2012-10-27 18:18:34 UTC (rev 132735)
@@ -1,3 +1,35 @@
+2012-10-27  David Barton  <[email protected]>
+
+        [MathML] Improve some addChild methods
+        https://bugs.webkit.org/show_bug.cgi?id=98791
+
+        Reviewed by Eric Seidel.
+
+        MathML addChild methods need to handle any anonymous renderers correctly. Actually, most MathML elements have a fixed
+        number of children, so conformant _javascript_ won't be doing arbitrary addChild and removeChild calls. However, we don't
+        want any assertions to fail, and we do want addChild to work correctly when beforeChild == 0, to build up the original
+        renderer, and then replaceChild at least should work correctly after that. We therefore clean up these routines before
+        giving them to the chromium fuzzers.
+        
+        It's best to build the anonymous wrappers just once initially if possible, so empty wrappers aren't left in the render
+        tree after later removeChild calls.
+
+        Test: mathml/presentation/dynamic.html added for mfrac and msqrt. There are already tests for dynamically changing
+        msub/sup elements, in mathml/presentation/m*-changed.xhtml.
+
+        * rendering/mathml/RenderMathMLFraction.cpp:
+        (WebCore::RenderMathMLFraction::addChild):
+            - The two wrappers are built initially. Also, the old RenderMathMLBlock::addChild(row, beforeChild); doesn't really
+              work because beforeChild is buried inside a wrapper. This new routine allows the numerator and denominator to be
+              added initially, and then later replaced with replaceChild. It's not clear whether e.g. a plain removeChild of a
+              numerator should move the remaining child from the denominator to the numerator or not, so we ignore that for now.
+        * rendering/mathml/RenderMathMLRoot.cpp:
+        (WebCore::RenderMathMLRoot::addChild):
+            - A bit of bullet-proofing for the fuzzers.
+        * rendering/mathml/RenderMathMLSubSup.cpp:
+        (WebCore::RenderMathMLSubSup::addChild):
+            - Like RenderMathMLFraction::addChild, we create the wrappers once initially, and then fill them dynamically.
+
 2012-10-27  Levi Weintraub  <[email protected]>
 
         Background images can incorrectly repeat with sub-pixel layout

Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp (132734 => 132735)


--- trunk/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp	2012-10-27 18:17:30 UTC (rev 132734)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp	2012-10-27 18:18:34 UTC (rev 132735)
@@ -86,14 +86,23 @@
     lastChild()->style()->setPaddingTop(Length(static_cast<int>(m_lineThickness), Fixed));
 }
 
-void RenderMathMLFraction::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderMathMLFraction::addChild(RenderObject* child, RenderObject* /* beforeChild */)
 {
-    RenderMathMLBlock* row = createAnonymousMathMLBlock();
+    if (isEmpty()) {
+        RenderMathMLBlock* numeratorWrapper = createAnonymousMathMLBlock();
+        RenderMathMLBlock::addChild(numeratorWrapper);
+        fixChildStyle(numeratorWrapper);
+        
+        RenderMathMLBlock* denominatorWrapper = createAnonymousMathMLBlock();
+        RenderMathMLBlock::addChild(denominatorWrapper);
+        fixChildStyle(denominatorWrapper);
+    }
     
-    RenderMathMLBlock::addChild(row, beforeChild);
-    row->addChild(child);
+    if (firstChild()->isEmpty())
+        firstChild()->addChild(child);
+    else
+        lastChild()->addChild(child);
     
-    fixChildStyle(row);
     updateFromElement();
 }
 

Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp (132734 => 132735)


--- trunk/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp	2012-10-27 18:17:30 UTC (rev 132734)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp	2012-10-27 18:18:34 UTC (rev 132735)
@@ -82,7 +82,7 @@
     if (newChild->style()->position() == AbsolutePosition)
         RenderMathMLBlock::addChild(newChild);
     else
-        firstChild()->addChild(newChild, beforeChild && beforeChild->style()->position() != AbsolutePosition ? beforeChild : 0);
+        firstChild()->addChild(newChild, beforeChild && beforeChild->parent() == firstChild() ? beforeChild : 0);
 }
 
 RenderBoxModelObject* RenderMathMLRoot::index() const

Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp (132734 => 132735)


--- trunk/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp	2012-10-27 18:17:30 UTC (rev 132734)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp	2012-10-27 18:18:34 UTC (rev 132735)
@@ -71,26 +71,22 @@
     scriptsStyle->setFontSize(static_cast<int>(0.75 * style()->fontSize()));
 }
 
-// FIXME: Handle arbitrary addChild/removeChild correctly throughout MathML, e.g. add/remove/add a base child here.
+// FIXME: Handle arbitrary addChild/removeChild correctly throughout MathML.
 void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild)
 {
-    // Note: The RenderMathMLBlock only allows element children to be added.
-    Element* childElement = toElement(child->node());
-
-    if (childElement && !childElement->previousElementSibling()) {
-        // Position 1 is always the base of the msub/msup/msubsup.
+    if (isEmpty()) {
         RenderMathMLBlock* baseWrapper = createAnonymousMathMLBlock();
-        RenderMathMLBlock::addChild(baseWrapper, firstChild());
-        baseWrapper->addChild(child);
-            
-        // Make sure we have a script block for rendering.
-        if (!m_scripts) {
-            m_scripts = createAnonymousMathMLBlock();
-            fixScriptsStyle();
-            RenderMathMLBlock::addChild(m_scripts, beforeChild);
-        }
-    } else
-        m_scripts->addChild(child, beforeChild ? m_scripts->firstChild() : 0);
+        RenderMathMLBlock::addChild(baseWrapper);
+        
+        m_scripts = createAnonymousMathMLBlock();
+        RenderMathMLBlock::addChild(m_scripts);
+        fixScriptsStyle();
+    }
+    
+    if (firstChild()->isEmpty())
+        firstChild()->addChild(child);
+    else
+        m_scripts->addChild(child, beforeChild && beforeChild->parent() == m_scripts ? beforeChild : 0);
 }
 
 void RenderMathMLSubSup::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to