Implement an internal style property for displaystyle.
authorfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Jul 2016 05:40:20 +0000 (05:40 +0000)
committerfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Jul 2016 05:40:20 +0000 (05:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133845

Patch by Frederic Wang <fwang@igalia.com> on 2016-07-07
Reviewed by Brent Fulgham.

Source/WebCore:

Tests: mathml/opentype/large-operators-displaystyle-dynamic.html
       mathml/opentype/large-operators-displaystyle.html

This is based on a patch by Alejandro G. Castro <alex@igalia.com>

* CMakeLists.txt: Add MathMLStyle to the build system.
* WebCore.xcodeproj/project.pbxproj: ditto.
* mathml/MathMLInlineContainerElement.cpp:
(WebCore::MathMLInlineContainerElement::parseAttribute): Resolve the mathml style when the
displaystyle attribute changes on the mtable or mstyle elements.
* mathml/MathMLInlineContainerElement.h: Define parseAttribute.
* mathml/MathMLMathElement.cpp:
(WebCore::MathMLMathElement::MathMLMathElement): Indicate that we have custom style.
(WebCore::MathMLMathElement::parseAttribute): Resolve the mathml style when the display or
displaystyle attributes change on the math element.
(WebCore::MathMLMathElement::didAttachRenderers): Resolve the mathml style when one
renderer is attached.
* mathml/MathMLMathElement.h: Declare parseAttribute and didAttachRenderers.
* mathml/mathattrs.in: Declare the display and displaystyle attributes.
* rendering/mathml/MathMLStyle.cpp: Added.
(WebCore::MathMLStyle::MathMLStyle): New class to handle custom MathML style.
(WebCore::MathMLStyle::create):
(WebCore::MathMLStyle::setDisplayStyle): Helper function to take the displaystyle from
the specified rendered.
(WebCore::MathMLStyle::resolveMathMLStyleTree): Helper function to resolve the custom
MathML style in renderer subtree.
(WebCore::MathMLStyle::getMathMLParentNode): Helper function to get a MathML ancestor of
the specified renderer.
(WebCore::MathMLStyle::updateStyleIfNeeded): Helper function to update the style of the
specified renderer if needed.
(WebCore::MathMLStyle::resolveMathMLStyle): Resolve the MathML style of a given renderer.
For displaystyle, we inherit the value of the parent except for the cases mentioned in the
MathML recommendation.
* rendering/mathml/MathMLStyle.h: New class header for custom MathML style.
Only displaystyle is supported for now.
* rendering/mathml/RenderMathMLBlock.cpp: Add a member and getter for custom MathML style.
(WebCore::RenderMathMLBlock::RenderMathMLBlock):
* rendering/mathml/RenderMathMLBlock.h: ditto.
(WebCore::RenderMathMLBlock::mathMLStyle):
* rendering/mathml/RenderMathMLMath.h: Add definition to use the syntax is<RenderMathMLMath>.
* rendering/mathml/RenderMathMLOperator.h:
(WebCore::RenderMathMLOperator::isLargeOperatorInDisplayStyle): Do not rerturn true when
the operator is not in displaystyle.
* rendering/mathml/RenderMathMLRoot.h: Make updateStyle public, so that it can be called
by MathMLStyle::updateStyleIfNeeded.
* rendering/mathml/RenderMathMLUnderOver.h: Add definition to use the syntax
is<RenderMathMLUnderOver>.

LayoutTests:

This is based on a patch by Alejandro G. Castro <alex@igalia.com>

Add two new tests to verify that the displaystyle property is correctly inherited
on various MathML elements.
large-operators-displaystyle verifies that large operators are only drawn bigger when
the displaystyle is true.
large-operators-displaystyle-dynamic verifies the same displaystyle is calculated when
the display and displaystyle attributes are changed dynamically.

* mathml/opentype/large-operators-displaystyle-dynamic-expected.html: Added.
* mathml/opentype/large-operators-displaystyle-dynamic.html: Added.
* mathml/opentype/large-operators-displaystyle-expected.txt: Added.
* imported/mathml-in-html5/fonts/math/largeop-displayoperatorminheight5000.woff: Added.
* imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1.html: Added.
* imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1-expected.txt: Added.

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

23 files changed:
LayoutTests/ChangeLog
LayoutTests/imported/mathml-in-html5/fonts/math/largeop-displayoperatorminheight5000.woff [new file with mode: 0644]
LayoutTests/imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1-expected.txt [new file with mode: 0644]
LayoutTests/imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1.html [new file with mode: 0644]
LayoutTests/mathml/opentype/large-operators-displaystyle-dynamic-expected.html [new file with mode: 0644]
LayoutTests/mathml/opentype/large-operators-displaystyle-dynamic.html [new file with mode: 0644]
LayoutTests/platform/ios-simulator/mathml/opentype/large-operators-displaystyle-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/mathml/opentype/large-operators-displaystyle-expected.txt [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/mathml/MathMLInlineContainerElement.cpp
Source/WebCore/mathml/MathMLInlineContainerElement.h
Source/WebCore/mathml/MathMLMathElement.cpp
Source/WebCore/mathml/MathMLMathElement.h
Source/WebCore/mathml/mathattrs.in
Source/WebCore/rendering/mathml/MathMLStyle.cpp [new file with mode: 0644]
Source/WebCore/rendering/mathml/MathMLStyle.h [new file with mode: 0644]
Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
Source/WebCore/rendering/mathml/RenderMathMLBlock.h
Source/WebCore/rendering/mathml/RenderMathMLOperator.h
Source/WebCore/rendering/mathml/RenderMathMLRoot.h
Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h

index 2d75450..4bb5234 100644 (file)
@@ -1,5 +1,28 @@
 2016-07-07  Frederic Wang  <fwang@igalia.com>
 
+        Implement an internal style property for displaystyle.
+        https://bugs.webkit.org/show_bug.cgi?id=133845
+
+        Reviewed by Brent Fulgham.
+
+        This is based on a patch by Alejandro G. Castro <alex@igalia.com>
+
+        Add two new tests to verify that the displaystyle property is correctly inherited
+        on various MathML elements.
+        large-operators-displaystyle verifies that large operators are only drawn bigger when
+        the displaystyle is true.
+        large-operators-displaystyle-dynamic verifies the same displaystyle is calculated when
+        the display and displaystyle attributes are changed dynamically.
+
+        * mathml/opentype/large-operators-displaystyle-dynamic-expected.html: Added.
+        * mathml/opentype/large-operators-displaystyle-dynamic.html: Added.
+        * mathml/opentype/large-operators-displaystyle-expected.txt: Added.
+        * imported/mathml-in-html5/fonts/math/largeop-displayoperatorminheight5000.woff: Added.
+        * imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1.html: Added.
+        * imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1-expected.txt: Added.
+
+2016-07-07  Frederic Wang  <fwang@igalia.com>
+
         Rebaseline some MathML tests on Windows after r202934
 
         Unreviewed test gardening.
diff --git a/LayoutTests/imported/mathml-in-html5/fonts/math/largeop-displayoperatorminheight5000.woff b/LayoutTests/imported/mathml-in-html5/fonts/math/largeop-displayoperatorminheight5000.woff
new file mode 100644 (file)
index 0000000..da3f1a3
Binary files /dev/null and b/LayoutTests/imported/mathml-in-html5/fonts/math/largeop-displayoperatorminheight5000.woff differ
diff --git a/LayoutTests/imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1-expected.txt b/LayoutTests/imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1-expected.txt
new file mode 100644 (file)
index 0000000..9c549a9
--- /dev/null
@@ -0,0 +1,56 @@
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+  ⫿   ⫿   ⫿  
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+⫿
+
+PASS math element 
+PASS mstyle element 
+PASS mtable element 
+PASS mfrac element 
+PASS mroot element 
+PASS msub element 
+PASS msup element 
+PASS msubsup element 
+PASS munder element 
+PASS mover element 
+PASS munderover element 
+
diff --git a/LayoutTests/imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1.html b/LayoutTests/imported/mathml-in-html5/mathml/relations/css-styling/displaystyle-1.html
new file mode 100644 (file)
index 0000000..63bf13c
--- /dev/null
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>displaystyle</title>
+<link rel="help" href="http://www.mathml-association.org/MathMLinHTML5/S2.html#SS3.SSS1">
+<meta name="assert" content="Verify that the correct inheritance of the displaystyle value by measuring the size of large operators.">
+<style>
+  @font-face {
+    font-family: TestFont;
+    src: url("../../../fonts/math/largeop-displayoperatorminheight5000.woff");
+  }
+  math  {
+    font-family: TestFont;
+    font-size: 10px;
+  }
+</style>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script>
+  setup({ explicit_done: true });
+  var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000
+  var epsilon = 5;
+  function verify_displaystyle(element, displaystyle, description) {
+    if (typeof element === "string")
+      element = document.getElementById(element);
+    var elementSize = element.getBoundingClientRect().height;
+    if (displaystyle)
+      assert_approx_equals(elementSize, 5000 * emToPx, epsilon, description);
+    else
+      assert_approx_equals(elementSize, 1000 * emToPx, epsilon, description);
+  }
+
+  window.addEventListener("load", function() {
+    document.fonts.ready.then(function() {
+      window.setTimeout(runTests, 250);
+    });
+  });
+
+  function runTests() {
+    test(function() {
+      verify_displaystyle("math_default", false, "default");
+      verify_displaystyle("math_inline", false, "explicit display inline");
+      verify_displaystyle("math_block", true, "explicit display block");
+      verify_displaystyle("math_false", false, "explicit displaystyle false");
+      verify_displaystyle("math_true", true, "explicit displaystyle true");
+    }, "math element");
+    test(function() {
+      verify_displaystyle("mstyle_false", false, "explicit displaystyle false");
+      verify_displaystyle("mstyle_true", true, "explicit displaystyle true");
+    }, "mstyle element");
+    test(function() {
+      verify_displaystyle("mtable_default", false, "default");
+      verify_displaystyle("mtable_false", false, "explicit displaystyle false");
+      verify_displaystyle("mtable_true", true, "explicit displaystyle true");
+    }, "mtable element");
+    test(function() {
+      verify_displaystyle("mfrac_numerator", false, "numerator");
+      verify_displaystyle("mfrac_denominator", false, "denominator");
+    }, "mfrac element");
+    test(function() {
+      verify_displaystyle("mroot_base", true, "base");
+      verify_displaystyle("mroot_index", false, "index");
+    }, "mroot element");
+    test(function() {
+      verify_displaystyle("msub_base", true, "base");
+      verify_displaystyle("msub_subscript", false, "subscript");
+    }, "msub element");
+    test(function() {
+      verify_displaystyle("msup_base", true, "base");
+      verify_displaystyle("msup_supscript", false, "supscript");
+    }, "msup element");
+    test(function() {
+      verify_displaystyle("msubsup_base", true, "base");
+      verify_displaystyle("msubsup_subscript", false, "subscript");
+      verify_displaystyle("msubsup_supscript", false, "supscript");
+    }, "msubsup element");
+    test(function() {
+      verify_displaystyle("munder_base", true, "base");
+      verify_displaystyle("munder_underscript", false, "underscript");
+    }, "munder element");
+    test(function() {
+      verify_displaystyle("mover_base", true, "base");
+      verify_displaystyle("mover_overscript", false, "overscript");
+    }, "mover element");
+    test(function() {
+      verify_displaystyle("munderover_base", true, "base");
+      verify_displaystyle("munderover_underscript", false, "underscript");
+      verify_displaystyle("munderover_overscript", false, "overscript");
+    }, "munderover element");
+    done();
+  }
+</script>
+</head>
+<body>
+  <math><mo id="math_default">&#x2AFF;</mo></math>
+  <math display="inline"><mo id="math_inline">&#x2AFF;</mo></math>
+  <math display="block"><mo id="math_block">&#x2AFF;</mo></math>
+  <math displaystyle="false"><mo id="math_false">&#x2AFF;</mo></math>
+  <math displaystyle="true"><mo id="math_true">&#x2AFF;</mo></math>
+  <math><mstyle displaystyle="false"><mo id="mstyle_false">&#x2AFF;</mo></mstyle></math>
+  <math><mstyle displaystyle="true"><mo id="mstyle_true">&#x2AFF;</mo></mstyle></math>
+  <math displaystyle="true"><mtable><mtr><mtd><mo id="mtable_default">&#x2AFF;</mo></mtd></mtr></mtable></math>
+  <math><mtable displaystyle="true"><mtr><mtd><mo id="mtable_true">&#x2AFF;</mo></mtd></mtr></mtable></math>
+  <math displaystyle="true"><mtable displaystyle="false"><mtr><mtd><mo id="mtable_false">&#x2AFF;</mo></mtd></mtr></mtable></math>
+  <math displaystyle="true"><mfrac><mo id="mfrac_numerator">&#x2AFF;</mo><mo id="mfrac_denominator">&#x2AFF;</mo></mfrac></math>
+  <math displaystyle="true"><mroot><mo id="mroot_base">&#x2AFF;</mo><mo id="mroot_index">&#x2AFF;</mo></mroot></math>
+  <math displaystyle="true"><msub><mo id="msub_base">&#x2AFF;</mo><mo id="msub_subscript">&#x2AFF;</mo></msub></math>
+  <math displaystyle="true"><msup><mo id="msup_base">&#x2AFF;</mo><mo id="msup_supscript">&#x2AFF;</mo></msup></math>
+  <math displaystyle="true"><msubsup><mo id="msubsup_base">&#x2AFF;</mo><mo id="msubsup_subscript">&#x2AFF;</mo><mo id="msubsup_supscript">&#x2AFF;</mo></msubsup></math>
+  <math displaystyle="true"><mmultiscripts><mo id="mmultiscripts_base">&#x2AFF;</mo><mo id="mmultiscripts_subscript">&#x2AFF;</mo><mo id="mmultiscripts_supscript">&#x2AFF;</mo><mprescripts/><mo id="mmultiscripts_presubscript">&#x2AFF;</mo><mo id="mmultiscripts_presupscript">&#x2AFF;</mo></mmultiscripts></math>
+  <math displaystyle="true"><munder><mo id="munder_base">&#x2AFF;</mo><mo id="munder_underscript">&#x2AFF;</mo></munder></math>
+  <math displaystyle="true"><mover><mo id="mover_base">&#x2AFF;</mo><mo id="mover_overscript">&#x2AFF;</mo></mover></math>
+  <math displaystyle="true"><munderover><mo id="munderover_base">&#x2AFF;</mo><mo id="munderover_underscript">&#x2AFF;</mo><mo id="munderover_overscript">&#x2AFF;</mo></munderover></math>
+</body>
+</html>
diff --git a/LayoutTests/mathml/opentype/large-operators-displaystyle-dynamic-expected.html b/LayoutTests/mathml/opentype/large-operators-displaystyle-dynamic-expected.html
new file mode 100644 (file)
index 0000000..dc80365
--- /dev/null
@@ -0,0 +1,39 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Open Type MATH - large operators - displaystyle</title>
+    <meta charset="utf-8"/>
+    <style type="text/css">
+      @font-face {
+        font-family: stretchy;
+        src: url("stretchy.woff");
+      }
+      div.largeop_test * {
+        font-family: stretchy;
+        font-size: 10px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="largeop_test">
+      <math display="inline"><mo>&#x2A1B;</mo></math>
+      <math display="block"><mo>&#x2A1B;</mo></math>
+      <math displaystyle="false"><mo>&#x2A1B;</mo></math>
+      <math displaystyle="true"><mo>&#x2A1B;</mo></math>
+      <math><mstyle displaystyle="false"><mo>&#x2A1B;</mo></mstyle></math>
+      <math><mstyle displaystyle="true"><mo>&#x2A1B;</mo></mstyle></math>
+      <math displaystyle="true"><mtable><mtr><mtd><mo>&#x2A1B;</mo></mtd></mtr></mtable></math>
+      <math><mtable displaystyle="true"><mtr><mtd><mo>&#x2A1B;</mo></mtd></mtr></mtable></math>
+      <math displaystyle="true"><mtable displaystyle="false"><mtr><mtd><mo>&#x2A1B;</mo></mtd></mtr></mtable></math>
+      <math displaystyle="true"><mfrac><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mfrac></math>
+      <math displaystyle="true"><mroot><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mroot></math>
+      <math displaystyle="true"><msub><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></msub></math>
+      <math displaystyle="true"><msup><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></msup></math>
+      <math displaystyle="true"><msubsup><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></msubsup></math>
+      <math displaystyle="true"><mmultiscripts><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mprescripts/><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mmultiscripts></math>
+      <math displaystyle="true"><munder><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></munder></math>
+      <math displaystyle="true"><mover><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mover></math>
+      <math displaystyle="true"><munderover><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></munderover></math>
+    </div>
+  </body>
+</html>
diff --git a/LayoutTests/mathml/opentype/large-operators-displaystyle-dynamic.html b/LayoutTests/mathml/opentype/large-operators-displaystyle-dynamic.html
new file mode 100644 (file)
index 0000000..29e230e
--- /dev/null
@@ -0,0 +1,63 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Open Type MATH - large operators - displaystyle</title>
+    <meta charset="utf-8"/>
+    <style type="text/css">
+      @font-face {
+        font-family: stretchy;
+        src: url("stretchy.woff");
+      }
+      div.largeop_test * {
+        font-family: stretchy;
+        font-size: 10px;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="largeop_test">
+      <math class="update" display="block"><mo>&#x2A1B;</mo></math>
+      <math class="update" display="inline"><mo>&#x2A1B;</mo></math>
+      <math class="update" displaystyle="true"><mo>&#x2A1B;</mo></math>
+      <math class="update" displaystyle="false"><mo>&#x2A1B;</mo></math>
+      <math class="update"><mstyle class="update" displaystyle="true"><mo>&#x2A1B;</mo></mstyle></math>
+      <math class="update"><mstyle class="update" displaystyle="false"><mo>&#x2A1B;</mo></mstyle></math>
+      <math class="update" displaystyle="false"><mtable><mtr><mtd><mo>&#x2A1B;</mo></mtd></mtr></mtable></math>
+      <math class="update"><mtable class="update" displaystyle="false"><mtr><mtd><mo>&#x2A1B;</mo></mtd></mtr></mtable></math>
+      <math class="update" displaystyle="false"><mtable class="update" displaystyle="true"><mtr><mtd><mo>&#x2A1B;</mo></mtd></mtr></mtable></math>
+      <math class="update" displaystyle="false"><mfrac><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mfrac></math>
+      <math class="update" displaystyle="false"><mroot><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mroot></math>
+      <math class="update" displaystyle="false"><msub><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></msub></math>
+      <math class="update" displaystyle="false"><msup><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></msup></math>
+      <math class="update" displaystyle="false"><msubsup><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></msubsup></math>
+      <math class="update" displaystyle="false"><mmultiscripts><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mprescripts/><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mmultiscripts></math>
+      <math class="update" displaystyle="false"><munder><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></munder></math>
+      <math class="update" displaystyle="false"><mover><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></mover></math>
+      <math class="update" displaystyle="false"><munderover><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo><mo>&#x2A1B;</mo></munderover></math>
+    </div>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        function updatePageAfterRendering()
+        {
+            setTimeout(function()
+                {
+                    // Switch the value of display/displaystyle attributes.
+                    var mathmlElements = document.getElementsByClassName("update");
+                    for (var i = 0; i < mathmlElements.length; i++) {
+                        var e = mathmlElements[i];
+                        if (e.hasAttribute("displaystyle"))
+                          e.setAttribute("displaystyle", e.getAttribute("displaystyle") == "true" ? "false" : "true");
+                        if (e.hasAttribute("display"))
+                          e.setAttribute("display", e.getAttribute("display") == "block" ? "inline" : "block");
+                    }
+                    if (window.testRunner)
+                      testRunner.notifyDone();
+                }, 50);
+        }
+
+        addEventListener('load', updatePageAfterRendering, false);
+    </script>
+  </body>
+</html>
diff --git a/LayoutTests/platform/ios-simulator/mathml/opentype/large-operators-displaystyle-expected.txt b/LayoutTests/platform/ios-simulator/mathml/opentype/large-operators-displaystyle-expected.txt
new file mode 100644 (file)
index 0000000..cd2c340
--- /dev/null
@@ -0,0 +1,55 @@
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+  ⨛   ⨛   ⨛  
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+
+PASS math element 
+PASS mstyle element 
+PASS mtable element 
+PASS mfrac element 
+PASS mroot element 
+PASS msub element 
+PASS msup element 
+PASS msubsup element 
+PASS munder element 
+PASS mover element 
+PASS munderover element 
+
diff --git a/LayoutTests/platform/mac/mathml/opentype/large-operators-displaystyle-expected.txt b/LayoutTests/platform/mac/mathml/opentype/large-operators-displaystyle-expected.txt
new file mode 100644 (file)
index 0000000..cd2c340
--- /dev/null
@@ -0,0 +1,55 @@
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+  ⨛   ⨛   ⨛  
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+⨛
+
+PASS math element 
+PASS mstyle element 
+PASS mtable element 
+PASS mfrac element 
+PASS mroot element 
+PASS msub element 
+PASS msup element 
+PASS msubsup element 
+PASS munder element 
+PASS mover element 
+PASS munderover element 
+
index 22ec73a..0c32772 100644 (file)
@@ -2523,6 +2523,7 @@ set(WebCore_SOURCES
     rendering/line/TrailingObjects.cpp
 
     rendering/mathml/MathMLOperatorDictionary.cpp
+    rendering/mathml/MathMLStyle.cpp
     rendering/mathml/MathOperator.cpp
     rendering/mathml/RenderMathMLBlock.cpp
     rendering/mathml/RenderMathMLFenced.cpp
index 1e4a77b..3b44b12 100644 (file)
@@ -1,3 +1,58 @@
+2016-07-07  Frederic Wang  <fwang@igalia.com>
+
+        Implement an internal style property for displaystyle.
+        https://bugs.webkit.org/show_bug.cgi?id=133845
+
+        Reviewed by Brent Fulgham.
+
+        Tests: mathml/opentype/large-operators-displaystyle-dynamic.html
+               mathml/opentype/large-operators-displaystyle.html
+
+        This is based on a patch by Alejandro G. Castro <alex@igalia.com>
+
+        * CMakeLists.txt: Add MathMLStyle to the build system.
+        * WebCore.xcodeproj/project.pbxproj: ditto.
+        * mathml/MathMLInlineContainerElement.cpp:
+        (WebCore::MathMLInlineContainerElement::parseAttribute): Resolve the mathml style when the
+        displaystyle attribute changes on the mtable or mstyle elements.
+        * mathml/MathMLInlineContainerElement.h: Define parseAttribute.
+        * mathml/MathMLMathElement.cpp:
+        (WebCore::MathMLMathElement::MathMLMathElement): Indicate that we have custom style.
+        (WebCore::MathMLMathElement::parseAttribute): Resolve the mathml style when the display or
+        displaystyle attributes change on the math element.
+        (WebCore::MathMLMathElement::didAttachRenderers): Resolve the mathml style when one
+        renderer is attached.
+        * mathml/MathMLMathElement.h: Declare parseAttribute and didAttachRenderers.
+        * mathml/mathattrs.in: Declare the display and displaystyle attributes.
+        * rendering/mathml/MathMLStyle.cpp: Added.
+        (WebCore::MathMLStyle::MathMLStyle): New class to handle custom MathML style.
+        (WebCore::MathMLStyle::create):
+        (WebCore::MathMLStyle::setDisplayStyle): Helper function to take the displaystyle from
+        the specified rendered.
+        (WebCore::MathMLStyle::resolveMathMLStyleTree): Helper function to resolve the custom
+        MathML style in renderer subtree.
+        (WebCore::MathMLStyle::getMathMLParentNode): Helper function to get a MathML ancestor of
+        the specified renderer.
+        (WebCore::MathMLStyle::updateStyleIfNeeded): Helper function to update the style of the
+        specified renderer if needed.
+        (WebCore::MathMLStyle::resolveMathMLStyle): Resolve the MathML style of a given renderer.
+        For displaystyle, we inherit the value of the parent except for the cases mentioned in the
+        MathML recommendation.
+        * rendering/mathml/MathMLStyle.h: New class header for custom MathML style.
+        Only displaystyle is supported for now.
+        * rendering/mathml/RenderMathMLBlock.cpp: Add a member and getter for custom MathML style.
+        (WebCore::RenderMathMLBlock::RenderMathMLBlock):
+        * rendering/mathml/RenderMathMLBlock.h: ditto.
+        (WebCore::RenderMathMLBlock::mathMLStyle):
+        * rendering/mathml/RenderMathMLMath.h: Add definition to use the syntax is<RenderMathMLMath>.
+        * rendering/mathml/RenderMathMLOperator.h:
+        (WebCore::RenderMathMLOperator::isLargeOperatorInDisplayStyle): Do not rerturn true when
+        the operator is not in displaystyle.
+        * rendering/mathml/RenderMathMLRoot.h: Make updateStyle public, so that it can be called
+        by MathMLStyle::updateStyleIfNeeded.
+        * rendering/mathml/RenderMathMLUnderOver.h: Add definition to use the syntax
+        is<RenderMathMLUnderOver>.
+
 2016-07-07  Ryosuke Niwa  <rniwa@webkit.org>
 
         Replace scoped flag in Event by composed flag
index e400e96..36439f0 100644 (file)
                439046DD12DA25E800AF80A2 /* RenderMathMLMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439046C912DA25E800AF80A2 /* RenderMathMLMath.cpp */; };
                439046DE12DA25E800AF80A2 /* RenderMathMLMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 439046CA12DA25E800AF80A2 /* RenderMathMLMath.h */; };
                439046DF12DA25E17BAF80A2 /* MathMLOperatorDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439046CB12DA25E17BAF80A2 /* MathMLOperatorDictionary.cpp */; };
+               439176DF12DA25E17BAF80A2 /* MathMLStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439176CB12DA25E17BAF80A2 /* MathMLStyle.cpp */; };
                439046DF12DA25E800AF80A2 /* RenderMathMLOperator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439046CB12DA25E800AF80A2 /* RenderMathMLOperator.cpp */; };
                439046E012DA25E17BAF80A2 /* MathMLOperatorDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 439046CC12DA25E17BAF80A2 /* MathMLOperatorDictionary.h */; };
+               439176E012DA25E17BAF80A2 /* MathMLStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 439176CC12DA25E17BAF80A2 /* MathMLStyle.h */; };
                439046E012DA25E800AF80A2 /* RenderMathMLOperator.h in Headers */ = {isa = PBXBuildFile; fileRef = 439046CC12DA25E800AF80A2 /* RenderMathMLOperator.h */; };
                439046E112DA25E800AF80A2 /* RenderMathMLRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439046CD12DA25E800AF80A2 /* RenderMathMLRoot.cpp */; };
                439046E212DA25E800AF80A2 /* RenderMathMLRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = 439046CE12DA25E800AF80A2 /* RenderMathMLRoot.h */; };
                439046C912DA25E800AF80A2 /* RenderMathMLMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMathMLMath.cpp; sourceTree = "<group>"; };
                439046CA12DA25E800AF80A2 /* RenderMathMLMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMathMLMath.h; sourceTree = "<group>"; };
                439046CB12DA25E17BAF80A2 /* MathMLOperatorDictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLOperatorDictionary.cpp; sourceTree = "<group>"; };
+               439176CB12DA25E17BAF80A2 /* MathMLStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLStyle.cpp; sourceTree = "<group>"; };
                439046CB12DA25E800AF80A2 /* RenderMathMLOperator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMathMLOperator.cpp; sourceTree = "<group>"; };
                439046CC12DA25E17BAF80A2 /* MathMLOperatorDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLOperatorDictionary.h; sourceTree = "<group>"; };
+               439176CC12DA25E17BAF80A2 /* MathMLStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLStyle.h; sourceTree = "<group>"; };
                439046CC12DA25E800AF80A2 /* RenderMathMLOperator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMathMLOperator.h; sourceTree = "<group>"; };
                439046CD12DA25E800AF80A2 /* RenderMathMLRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMathMLRoot.cpp; sourceTree = "<group>"; };
                439046CE12DA25E800AF80A2 /* RenderMathMLRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMathMLRoot.h; sourceTree = "<group>"; };
                                439046CC12DA25E17BAF80A2 /* MathMLOperatorDictionary.h */,
                                439046D512DA25E812AF80AC /* MathOperator.cpp */,
                                439046D612DA25E812AF80AC /* MathOperator.h */,
+                               439176CB12DA25E17BAF80A2 /* MathMLStyle.cpp */,
+                               439176CC12DA25E17BAF80A2 /* MathMLStyle.h */,
                                439046C312DA25E800AF80A2 /* RenderMathMLBlock.cpp */,
                                439046C412DA25E800AF80A2 /* RenderMathMLBlock.h */,
                                439046C512DA25E800AF80A2 /* RenderMathMLFenced.cpp */,
                                FABE72F91059C1EB00D999DD /* MathMLMathElement.h in Headers */,
                                44A28AAF12DFB8BF00AE923B /* MathMLNames.h in Headers */,
                                439046E012DA25E17BAF80A2 /* MathMLOperatorDictionary.h in Headers */,
+                               439176E012DA25E17BAF80A2 /* MathMLStyle.h in Headers */,
                                FA654A6C1108ABED002615E0 /* MathMLTextElement.h in Headers */,
                                439046EA12DA25E812AF80AC /* MathOperator.h in Headers */,
                                49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */,
                                05D913CEEAB2A60534218ACF /* MathMLMencloseElement.cpp in Sources */,
                                FABE72FE1059C21100D999DD /* MathMLNames.cpp in Sources */,
                                439046DF12DA25E17BAF80A2 /* MathMLOperatorDictionary.cpp in Sources */,
+                               439176DF12DA25E17BAF80A2 /* MathMLStyle.cpp in Sources */,
                                FED48390CED66C3255F72C59 /* MathMLSelectElement.cpp in Sources */,
                                FA654A6B1108ABED002615E0 /* MathMLTextElement.cpp in Sources */,
                                439046E912DA25E812AF80AC /* MathOperator.cpp in Sources */,
index 6f60f2a..3577128 100644 (file)
@@ -83,6 +83,14 @@ RenderPtr<RenderElement> MathMLInlineContainerElement::createElementRenderer(Ren
     return createRenderer<RenderMathMLBlock>(*this, WTFMove(style));
 }
 
+void MathMLInlineContainerElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+    if (name == displaystyleAttr && (hasTagName(mstyleTag) || hasTagName(mtableTag)) && renderer())
+        MathMLStyle::resolveMathMLStyleTree(renderer());
+
+    MathMLElement::parseAttribute(name, value);
+}
+
 }
 
 #endif // ENABLE(MATHML)
index 509bba5..a5895ef 100644 (file)
@@ -41,6 +41,7 @@ public:
 protected:
     MathMLInlineContainerElement(const QualifiedName& tagName, Document&);
     void childrenChanged(const ChildChange&) override;
+    void parseAttribute(const QualifiedName&, const AtomicString&) override;
 
 private:
     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
index 63652d3..944c687 100644 (file)
 #if ENABLE(MATHML)
 
 #include "MathMLMathElement.h"
+
+#include "MathMLNames.h"
 #include "RenderMathMLMath.h"
 
 namespace WebCore {
 
+using namespace MathMLNames;
+
 inline MathMLMathElement::MathMLMathElement(const QualifiedName& tagName, Document& document)
     : MathMLInlineContainerElement(tagName, document)
 {
+    setHasCustomStyleResolveCallbacks();
 }
 
 Ref<MathMLMathElement> MathMLMathElement::create(const QualifiedName& tagName, Document& document)
@@ -48,6 +53,21 @@ RenderPtr<RenderElement> MathMLMathElement::createElementRenderer(RenderStyle&&
     return createRenderer<RenderMathMLMath>(*this, WTFMove(style));
 }
 
+void MathMLMathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+    if ((name == displaystyleAttr || name == displayAttr) && hasTagName(mathTag) && renderer())
+        MathMLStyle::resolveMathMLStyleTree(renderer());
+
+    MathMLInlineContainerElement::parseAttribute(name, value);
+}
+
+void MathMLMathElement::didAttachRenderers()
+{
+    MathMLInlineContainerElement::didAttachRenderers();
+
+    MathMLStyle::resolveMathMLStyleTree(renderer());
+}
+
 }
 
 #endif // ENABLE(MATHML)
index 76046de..92f1802 100644 (file)
@@ -36,8 +36,12 @@ class MathMLMathElement : public MathMLInlineContainerElement {
 public:
     static Ref<MathMLMathElement> create(const QualifiedName& tagName, Document&);
 
+protected:
+    void didAttachRenderers() final;
+
 private:
     MathMLMathElement(const QualifiedName& tagName, Document&);
+    void parseAttribute(const QualifiedName&, const AtomicString&) final;
 
     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
 };
index 077e79c..0d31d49 100644 (file)
@@ -14,6 +14,8 @@ definitionURL
 denomalign
 depth
 dir
+display
+displaystyle
 encoding
 fence
 fontfamily
diff --git a/Source/WebCore/rendering/mathml/MathMLStyle.cpp b/Source/WebCore/rendering/mathml/MathMLStyle.cpp
new file mode 100644 (file)
index 0000000..a6c7d10
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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 "MathMLStyle.h"
+
+#include "MathMLElement.h"
+#include "MathMLNames.h"
+#include "RenderMathMLBlock.h"
+#include "RenderMathMLFraction.h"
+#include "RenderMathMLMath.h"
+#include "RenderMathMLRoot.h"
+#include "RenderMathMLScripts.h"
+#include "RenderMathMLToken.h"
+#include "RenderMathMLUnderOver.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+Ref<MathMLStyle> MathMLStyle::create()
+{
+    return adoptRef(*new MathMLStyle());
+}
+
+void MathMLStyle::setDisplayStyle(RenderObject* renderer)
+{
+    if (!renderer)
+        return;
+
+    // FIXME: Should we make RenderMathMLTable derive from RenderMathMLBlock in order to simplify this?
+    if (is<RenderMathMLTable>(renderer))
+        m_displayStyle = downcast<RenderMathMLTable>(renderer)->mathMLStyle()->displayStyle();
+    else if (is<RenderMathMLBlock>(renderer))
+        m_displayStyle = downcast<RenderMathMLBlock>(renderer)->mathMLStyle()->displayStyle();
+}
+
+void MathMLStyle::resolveMathMLStyleTree(RenderObject* renderer)
+{
+    for (auto* child = renderer; child; child = child->nextInPreOrder(renderer)) {
+        // FIXME: Should we make RenderMathMLTable derive from RenderMathMLBlock in order to simplify this?
+        if (is<RenderMathMLTable>(child))
+            downcast<RenderMathMLTable>(child)->mathMLStyle()->resolveMathMLStyle(child);
+        else if (is<RenderMathMLBlock>(child))
+            downcast<RenderMathMLBlock>(child)->mathMLStyle()->resolveMathMLStyle(child);
+    }
+}
+
+RenderObject* MathMLStyle::getMathMLParentNode(RenderObject* renderer)
+{
+    auto* parentRenderer = renderer->parent();
+
+    while (parentRenderer && !(is<RenderMathMLTable>(parentRenderer) || is<RenderMathMLBlock>(parentRenderer)))
+        parentRenderer = parentRenderer->parent();
+
+    return parentRenderer;
+}
+
+void MathMLStyle::updateStyleIfNeeded(RenderObject* renderer, bool oldDisplayStyle)
+{
+    if (oldDisplayStyle != m_displayStyle) {
+        if (is<RenderMathMLToken>(renderer))
+            downcast<RenderMathMLToken>(renderer)->updateTokenContent();
+        else if (is<RenderMathMLRoot>(renderer))
+            downcast<RenderMathMLRoot>(renderer)->updateStyle();
+    }
+}
+
+void MathMLStyle::resolveMathMLStyle(RenderObject* renderer)
+{
+    ASSERT(renderer);
+
+    bool oldDisplayStyle = m_displayStyle;
+
+    // For anonymous renderers, we just inherit the style from our parent.
+    if (renderer->isAnonymous()) {
+        setDisplayStyle(getMathMLParentNode(renderer));
+        updateStyleIfNeeded(renderer, oldDisplayStyle);
+        return;
+    }
+
+    if (is<RenderMathMLMath>(renderer))
+        m_displayStyle = downcast<RenderElement>(renderer)->element()->fastGetAttribute(displayAttr) == "block"; // The default displaystyle of the <math> element depends on its display attribute.
+    else if (is<RenderMathMLTable>(renderer))
+        m_displayStyle = false; // The default displaystyle of <mtable> is false.
+    else if (auto* parentRenderer = getMathMLParentNode(renderer)) {
+        setDisplayStyle(parentRenderer); // The default displaystyle is inherited from our parent.
+        if (is<RenderMathMLFraction>(parentRenderer))
+            m_displayStyle = false; // <mfrac> sets displaystyle to false within its numerator and denominator.
+        else if ((is<RenderMathMLRoot>(parentRenderer) && !parentRenderer->isRenderMathMLSquareRoot()) || is<RenderMathMLScripts>(parentRenderer) || is<RenderMathMLUnderOver>(parentRenderer)) {
+            // <mroot>, <msub>, <msup>, <msubsup>, <mmultiscripts>, <munder>, <mover> and <munderover> elements set displaystyle to false within their scripts.
+            auto* base = downcast<RenderBox>(parentRenderer)->firstChildBox();
+            if (renderer != base)
+                m_displayStyle = false;
+        }
+    }
+
+    // The displaystyle attribute on the <math>, <mtable> or <mstyle> elements override the default behavior.
+    const auto* element = downcast<RenderElement>(renderer)->element();
+    const QualifiedName& tagName = element->tagQName();
+    if (tagName == mathTag || tagName == mtableTag || tagName == mstyleTag) {
+        // We only modify the value of displaystyle if there is an explicit and valid attribute.
+        const AtomicString& attributeValue = element->fastGetAttribute(displaystyleAttr);
+        if (attributeValue == "true")
+            m_displayStyle = true;
+        else if (attributeValue == "false")
+            m_displayStyle = false;
+    }
+
+    updateStyleIfNeeded(renderer, oldDisplayStyle);
+}
+
+}
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/rendering/mathml/MathMLStyle.h b/Source/WebCore/rendering/mathml/MathMLStyle.h
new file mode 100644 (file)
index 0000000..996f3d4
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#ifndef MathMLStyle_h
+#define MathMLStyle_h
+#pragma once
+
+#if ENABLE(MATHML)
+
+#include "Element.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class MathMLStyle: public RefCounted<MathMLStyle> {
+public:
+    MathMLStyle() { }
+    static Ref<MathMLStyle> create();
+
+    bool displayStyle() const { return m_displayStyle; }
+    void setDisplayStyle(bool displayStyle) { m_displayStyle = displayStyle; }
+
+    void resolveMathMLStyle(RenderObject*);
+    static void resolveMathMLStyleTree(RenderObject*);
+
+private:
+    bool isDisplayStyleAlwaysFalse(RenderObject*);
+    void setDisplayStyle(RenderObject*);
+    RenderObject* getMathMLParentNode(RenderObject*);
+    void updateStyleIfNeeded(RenderObject*, bool);
+
+    bool m_displayStyle = false;
+};
+
+}
+
+#endif // ENABLE(MATHML)
+#endif // MathMLStyle_h
index b3188a8..0c51a30 100644 (file)
@@ -46,12 +46,14 @@ using namespace MathMLNames;
 
 RenderMathMLBlock::RenderMathMLBlock(Element& container, RenderStyle&& style)
     : RenderBlock(container, WTFMove(style), 0)
+    , m_mathMLStyle(MathMLStyle::create())
 {
     setChildrenInline(false); // All of our children must be block-level.
 }
 
 RenderMathMLBlock::RenderMathMLBlock(Document& document, RenderStyle&& style)
     : RenderBlock(document, WTFMove(style), 0)
+    , m_mathMLStyle(MathMLStyle::create())
 {
     setChildrenInline(false); // All of our children must be block-level.
 }
index 6e249ae..e1dd971 100644 (file)
@@ -29,6 +29,7 @@
 
 #if ENABLE(MATHML)
 
+#include "MathMLStyle.h"
 #include "RenderBlock.h"
 #include "RenderTable.h"
 #include "StyleInheritedData.h"
@@ -45,6 +46,8 @@ public:
     RenderMathMLBlock(Document&, RenderStyle&&);
     virtual ~RenderMathMLBlock();
 
+    MathMLStyle* mathMLStyle() const { return const_cast<MathMLStyle*>(&m_mathMLStyle.get()); }
+
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
 
     // MathML defines an "embellished operator" as roughly an <mo> that may have subscripts,
@@ -80,20 +83,27 @@ private:
     bool avoidsFloats() const final { return true; }
     bool canDropAnonymousBlockChild() const final { return false; }
     void layoutItems(bool relayoutChildren);
+
+    Ref<MathMLStyle> m_mathMLStyle;
 };
 
 class RenderMathMLTable final : public RenderTable {
 public:
     explicit RenderMathMLTable(Element& element, RenderStyle&& style)
         : RenderTable(element, WTFMove(style))
+        , m_mathMLStyle(MathMLStyle::create())
     {
     }
 
     Optional<int> firstLineBaseline() const override;
 
+    MathMLStyle* mathMLStyle() const { return const_cast<MathMLStyle*>(&m_mathMLStyle.get()); }
+
 private:
     bool isRenderMathMLTable() const override { return true; }
     const char* renderName() const override { return "RenderMathMLTable"; }
+
+    Ref<MathMLStyle> m_mathMLStyle;
 };
 
 // Parsing functions for MathML Length values
index a6b2a33..bb2b0b8 100644 (file)
@@ -49,8 +49,7 @@ public:
     void resetStretchSize();
 
     bool hasOperatorFlag(MathMLOperatorDictionary::Flag flag) const { return m_operatorFlags & flag; }
-    // FIXME: The displaystyle property is not implemented (https://bugs.webkit.org/show_bug.cgi?id=118737).
-    bool isLargeOperatorInDisplayStyle() const { return !hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && hasOperatorFlag(MathMLOperatorDictionary::LargeOp); }
+    bool isLargeOperatorInDisplayStyle() const { return !hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && hasOperatorFlag(MathMLOperatorDictionary::LargeOp) && mathMLStyle()->displayStyle(); }
     bool isVertical() const { return m_isVertical; }
     LayoutUnit italicCorrection() const { return m_mathOperator.italicCorrection(); }
 
index 7302f9f..0b1adea 100644 (file)
@@ -49,6 +49,7 @@ public:
 
     void computePreferredLogicalWidths() final;
     void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) final;
+    void updateStyle();
 
 protected:
     void paint(PaintInfo&, const LayoutPoint&) final;
@@ -59,7 +60,6 @@ private:
     RenderBox& getIndex() const;
     bool isRenderMathMLRoot() const final { return true; }
     const char* renderName() const final { return "RenderMathMLRoot"; }
-    void updateStyle();
 
     MathOperator m_radicalOperator;
     LayoutUnit m_verticalGap;
index 22dec8d..846e1bb 100644 (file)
@@ -61,6 +61,8 @@ private:
 
 }
 
+SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderMathMLUnderOver, isRenderMathMLUnderOver())
+
 #endif // ENABLE(MATHML)
 
 #endif // RenderMathMLUnderOver_h