<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[204075] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/204075">204075</a></dd>
<dt>Author</dt> <dd>fred.wang@free.fr</dd>
<dt>Date</dt> <dd>2016-08-03 00:00:38 -0700 (Wed, 03 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Move determination of operator direction into DOM class and reduce relayout
https://bugs.webkit.org/show_bug.cgi?id=160339

Patch by Frederic Wang &lt;fwang@igalia.com&gt; on 2016-08-02
Reviewed by Darin Adler.

We move the determination of operator direction into MathMLOperatorElement. We also simplify
a bit RenderMathMLFencedOperator so that the update of operator properties are done
immediately in updateOperatorContent and the resolution of to LayoutUnit is implemented
in leadingSpace, trailingSpace, minSize and maxSize. After that, setOperatorProperties is no
longer necessary and we can remove many calls that used to update operator properties and
force relayout.

No new tests, already covered by existing tests.

* mathml/MathMLInlineContainerElement.cpp:
(WebCore::MathMLInlineContainerElement::childrenChanged): No need to call updateOperatorProperties.
* mathml/MathMLOperatorElement.cpp: Change names from &quot;text&quot; to &quot;char&quot;.
(WebCore::MathMLOperatorElement::parseOperatorChar): Parse character and isVertical in this function.
(WebCore::MathMLOperatorElement::operatorChar):
(WebCore::MathMLOperatorElement::childrenChanged):
(WebCore::MathMLOperatorElement::computeDictionaryProperty): Call operatorChar().character.
(WebCore::MathMLOperatorElement::parseOperatorText): Deleted.
(WebCore::MathMLOperatorElement::operatorText): Deleted.
* mathml/MathMLOperatorElement.h: Use a new structure to hold both the character and direction
and change names from &quot;text&quot; to &quot;char&quot;.
* rendering/mathml/RenderMathMLFencedOperator.cpp:
(WebCore::RenderMathMLFencedOperator::updateOperatorContent): Update both the character and
direction using MathMLOperatorElement::parseOperatorChar. Then set the boolean properties
and leading/trailing space using the operator dictionary. minsize and maxsize are constant
so we do not need to set them any more.
(WebCore::RenderMathMLFencedOperator::leadingSpace): Resolve the spacing read from the
dictionary to LayoutUnit. Note that it can never be negative.
(WebCore::RenderMathMLFencedOperator::trailingSpace): Ditto.
(WebCore::RenderMathMLFencedOperator::RenderMathMLFencedOperator): Deleted.
(WebCore::RenderMathMLFencedOperator::setOperatorProperties): Deleted.
* rendering/mathml/RenderMathMLFencedOperator.h: We use the new OperatorChar structure for
accessors and members. We make minSize and maxSize just return the default values and delete
the corresponding members. Finally, leading and trailing space are now stored as unsigned
short in MathUnit.
* rendering/mathml/RenderMathMLOperator.cpp:
(WebCore::RenderMathMLOperator::textContent): Use the new OperatorChar structure.
(WebCore::RenderMathMLOperator::isVertical): Helper function forwarding to MathMLOperatorElement.
(WebCore::RenderMathMLOperator::stretchTo): Use isVertical() and remove setOperatorProperties().
(WebCore::RenderMathMLOperator::resetStretchSize): Ditto.
(WebCore::RenderMathMLOperator::updateMathOperator): Rename rebuildTokenContent as this is
now really only used to update MathOperator and hence replace the condition on
useMathOperator() with an ASSERT.
(WebCore::RenderMathMLOperator::updateTokenContent): Call updateMathOperator instead of
rebuildTokenContent.
(WebCore::RenderMathMLOperator::verticalStretchedOperatorShift): We use isVertical().
(WebCore::RenderMathMLOperator::paint): Ditto.
(WebCore::RenderMathMLOperator::setOperatorProperties): Deleted. This is no longer needed.
(WebCore::RenderMathMLOperator::computePreferredLogicalWidths): Deleted.
(WebCore::RenderMathMLOperator::rebuildTokenContent): Deleted. Renamed updateMathOperator.
(WebCore::RenderMathMLOperator::styleDidChange): No need to call updateOperatorProperties.
(WebCore::RenderMathMLOperator::updateOperatorProperties): Ditto..
* rendering/mathml/RenderMathMLOperator.h: Update some declaration and remove m_isVertical.
(WebCore::RenderMathMLOperator::isVertical): Deleted.
* rendering/mathml/RenderMathMLRow.cpp:
(WebCore::RenderMathMLRow::updateOperatorProperties): Deleted. This is no longer needed.
* rendering/mathml/RenderMathMLRow.h: Ditto.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoremathmlMathMLInlineContainerElementcpp">trunk/Source/WebCore/mathml/MathMLInlineContainerElement.cpp</a></li>
<li><a href="#trunkSourceWebCoremathmlMathMLOperatorElementcpp">trunk/Source/WebCore/mathml/MathMLOperatorElement.cpp</a></li>
<li><a href="#trunkSourceWebCoremathmlMathMLOperatorElementh">trunk/Source/WebCore/mathml/MathMLOperatorElement.h</a></li>
<li><a href="#trunkSourceWebCorerenderingmathmlRenderMathMLFencedOperatorcpp">trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingmathmlRenderMathMLFencedOperatorh">trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.h</a></li>
<li><a href="#trunkSourceWebCorerenderingmathmlRenderMathMLOperatorcpp">trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingmathmlRenderMathMLOperatorh">trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h</a></li>
<li><a href="#trunkSourceWebCorerenderingmathmlRenderMathMLRowcpp">trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingmathmlRenderMathMLRowh">trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/ChangeLog        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -1,3 +1,67 @@
</span><ins>+2016-08-02  Frederic Wang  &lt;fwang@igalia.com&gt;
+
+        Move determination of operator direction into DOM class and reduce relayout
+        https://bugs.webkit.org/show_bug.cgi?id=160339
+
+        Reviewed by Darin Adler.
+
+        We move the determination of operator direction into MathMLOperatorElement. We also simplify
+        a bit RenderMathMLFencedOperator so that the update of operator properties are done
+        immediately in updateOperatorContent and the resolution of to LayoutUnit is implemented
+        in leadingSpace, trailingSpace, minSize and maxSize. After that, setOperatorProperties is no
+        longer necessary and we can remove many calls that used to update operator properties and
+        force relayout.
+
+        No new tests, already covered by existing tests.
+
+        * mathml/MathMLInlineContainerElement.cpp:
+        (WebCore::MathMLInlineContainerElement::childrenChanged): No need to call updateOperatorProperties.
+        * mathml/MathMLOperatorElement.cpp: Change names from &quot;text&quot; to &quot;char&quot;.
+        (WebCore::MathMLOperatorElement::parseOperatorChar): Parse character and isVertical in this function.
+        (WebCore::MathMLOperatorElement::operatorChar):
+        (WebCore::MathMLOperatorElement::childrenChanged):
+        (WebCore::MathMLOperatorElement::computeDictionaryProperty): Call operatorChar().character.
+        (WebCore::MathMLOperatorElement::parseOperatorText): Deleted.
+        (WebCore::MathMLOperatorElement::operatorText): Deleted.
+        * mathml/MathMLOperatorElement.h: Use a new structure to hold both the character and direction
+        and change names from &quot;text&quot; to &quot;char&quot;.
+        * rendering/mathml/RenderMathMLFencedOperator.cpp:
+        (WebCore::RenderMathMLFencedOperator::updateOperatorContent): Update both the character and
+        direction using MathMLOperatorElement::parseOperatorChar. Then set the boolean properties
+        and leading/trailing space using the operator dictionary. minsize and maxsize are constant
+        so we do not need to set them any more.
+        (WebCore::RenderMathMLFencedOperator::leadingSpace): Resolve the spacing read from the
+        dictionary to LayoutUnit. Note that it can never be negative.
+        (WebCore::RenderMathMLFencedOperator::trailingSpace): Ditto.
+        (WebCore::RenderMathMLFencedOperator::RenderMathMLFencedOperator): Deleted.
+        (WebCore::RenderMathMLFencedOperator::setOperatorProperties): Deleted.
+        * rendering/mathml/RenderMathMLFencedOperator.h: We use the new OperatorChar structure for
+        accessors and members. We make minSize and maxSize just return the default values and delete
+        the corresponding members. Finally, leading and trailing space are now stored as unsigned
+        short in MathUnit.
+        * rendering/mathml/RenderMathMLOperator.cpp:
+        (WebCore::RenderMathMLOperator::textContent): Use the new OperatorChar structure.
+        (WebCore::RenderMathMLOperator::isVertical): Helper function forwarding to MathMLOperatorElement.
+        (WebCore::RenderMathMLOperator::stretchTo): Use isVertical() and remove setOperatorProperties().
+        (WebCore::RenderMathMLOperator::resetStretchSize): Ditto.
+        (WebCore::RenderMathMLOperator::updateMathOperator): Rename rebuildTokenContent as this is
+        now really only used to update MathOperator and hence replace the condition on
+        useMathOperator() with an ASSERT.
+        (WebCore::RenderMathMLOperator::updateTokenContent): Call updateMathOperator instead of
+        rebuildTokenContent.
+        (WebCore::RenderMathMLOperator::verticalStretchedOperatorShift): We use isVertical().
+        (WebCore::RenderMathMLOperator::paint): Ditto.
+        (WebCore::RenderMathMLOperator::setOperatorProperties): Deleted. This is no longer needed.
+        (WebCore::RenderMathMLOperator::computePreferredLogicalWidths): Deleted.
+        (WebCore::RenderMathMLOperator::rebuildTokenContent): Deleted. Renamed updateMathOperator.
+        (WebCore::RenderMathMLOperator::styleDidChange): No need to call updateOperatorProperties.
+        (WebCore::RenderMathMLOperator::updateOperatorProperties): Ditto..
+        * rendering/mathml/RenderMathMLOperator.h: Update some declaration and remove m_isVertical.
+        (WebCore::RenderMathMLOperator::isVertical): Deleted.
+        * rendering/mathml/RenderMathMLRow.cpp:
+        (WebCore::RenderMathMLRow::updateOperatorProperties): Deleted. This is no longer needed.
+        * rendering/mathml/RenderMathMLRow.h: Ditto.
+
</ins><span class="cx"> 2016-08-02  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Drop custom bindings code for HTMLSelectElement.remove()
</span></span></pre></div>
<a id="trunkSourceWebCoremathmlMathMLInlineContainerElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/mathml/MathMLInlineContainerElement.cpp (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/mathml/MathMLInlineContainerElement.cpp        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/mathml/MathMLInlineContainerElement.cpp        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -60,10 +60,6 @@
</span><span class="cx">             static_cast&lt;MathMLOperatorElement*&gt;(child)-&gt;setOperatorFormDirty();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: Parsing of operator properties should be done in the element classes rather than in the renderer classes.
-    // See https://webkit.org/b/156537
-    if (renderer() &amp;&amp; is&lt;RenderMathMLRow&gt;(*renderer()))
-        downcast&lt;RenderMathMLRow&gt;(*renderer()).updateOperatorProperties();
</del><span class="cx">     MathMLElement::childrenChanged(change);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoremathmlMathMLOperatorElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/mathml/MathMLOperatorElement.cpp (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/mathml/MathMLOperatorElement.cpp        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/mathml/MathMLOperatorElement.cpp        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -47,8 +47,10 @@
</span><span class="cx">     return adoptRef(*new MathMLOperatorElement(tagName, document));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-UChar MathMLOperatorElement::parseOperatorText(const String&amp; string)
</del><ins>+MathMLOperatorElement::OperatorChar MathMLOperatorElement::parseOperatorChar(const String&amp; string)
</ins><span class="cx"> {
</span><ins>+    OperatorChar operatorChar;
+
</ins><span class="cx">     // We collapse the whitespace and replace the hyphens by minus signs.
</span><span class="cx">     AtomicString textContent = string.stripWhiteSpace().simplifyWhiteSpace().replace(hyphenMinus, minusSign).impl();
</span><span class="cx"> 
</span><span class="lines">@@ -56,14 +58,16 @@
</span><span class="cx">     // FIXME: This is a really inefficient way to extract a character from a string (https://webkit.org/b/160241#c7).
</span><span class="cx">     // FIXME: This does not handle surrogate pairs (https://webkit.org/b/122296).
</span><span class="cx">     // FIXME: This does not handle &lt;mo&gt; operators with multiple characters (https://webkit.org/b/124828).
</span><del>-    return textContent.length() == 1 ? textContent[0] : 0;
</del><ins>+    operatorChar.character = textContent.length() == 1 ? textContent[0] : 0;
+    operatorChar.isVertical = MathMLOperatorDictionary::isVertical(operatorChar.character);
+    return operatorChar;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-UChar MathMLOperatorElement::operatorText()
</del><ins>+const MathMLOperatorElement::OperatorChar&amp; MathMLOperatorElement::operatorChar()
</ins><span class="cx"> {
</span><del>-    if (!m_operatorText)
-        m_operatorText = parseOperatorText(textContent());
-    return m_operatorText.value();
</del><ins>+    if (!m_operatorChar)
+        m_operatorChar = parseOperatorChar(textContent());
+    return m_operatorChar.value();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> MathMLOperatorElement::DictionaryProperty MathMLOperatorElement::computeDictionaryProperty()
</span><span class="lines">@@ -91,7 +95,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // We then try and find an entry in the operator dictionary to override the default values.
</span><del>-    if (auto entry = search(operatorText(), dictionaryProperty.form, explicitForm)) {
</del><ins>+    if (auto entry = search(operatorChar().character, dictionaryProperty.form, explicitForm)) {
</ins><span class="cx">         dictionaryProperty.form = static_cast&lt;MathMLOperatorDictionary::Form&gt;(entry.value().form);
</span><span class="cx">         dictionaryProperty.leadingSpaceInMathUnit = entry.value().lspace;
</span><span class="cx">         dictionaryProperty.trailingSpaceInMathUnit = entry.value().rspace;
</span><span class="lines">@@ -212,7 +216,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MathMLOperatorElement::childrenChanged(const ChildChange&amp; change)
</span><span class="cx"> {
</span><del>-    m_operatorText = Nullopt;
</del><ins>+    m_operatorChar = Nullopt;
</ins><span class="cx">     m_dictionaryProperty = Nullopt;
</span><span class="cx">     m_properties.dirtyFlags = MathMLOperatorDictionary::allFlags;
</span><span class="cx">     MathMLTextElement::childrenChanged(change);
</span></span></pre></div>
<a id="trunkSourceWebCoremathmlMathMLOperatorElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/mathml/MathMLOperatorElement.h (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/mathml/MathMLOperatorElement.h        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/mathml/MathMLOperatorElement.h        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -34,8 +34,12 @@
</span><span class="cx"> class MathMLOperatorElement final : public MathMLTextElement {
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;MathMLOperatorElement&gt; create(const QualifiedName&amp; tagName, Document&amp;);
</span><del>-    static UChar parseOperatorText(const String&amp;);
-    UChar operatorText();
</del><ins>+    struct OperatorChar {
+        UChar character { 0 };
+        bool isVertical { true };
+    };
+    static OperatorChar parseOperatorChar(const String&amp;);
+    const OperatorChar&amp; operatorChar();
</ins><span class="cx">     void setOperatorFormDirty() { m_dictionaryProperty = Nullopt; }
</span><span class="cx">     MathMLOperatorDictionary::Form form() { return dictionaryProperty().form; }
</span><span class="cx">     bool hasProperty(MathMLOperatorDictionary::Flag);
</span><span class="lines">@@ -52,7 +56,7 @@
</span><span class="cx">     void childrenChanged(const ChildChange&amp;) final;
</span><span class="cx">     void parseAttribute(const QualifiedName&amp;, const AtomicString&amp;) final;
</span><span class="cx"> 
</span><del>-    Optional&lt;UChar&gt; m_operatorText;
</del><ins>+    Optional&lt;OperatorChar&gt; m_operatorChar;
</ins><span class="cx"> 
</span><span class="cx">     struct DictionaryProperty {
</span><span class="cx">         MathMLOperatorDictionary::Form form;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingmathmlRenderMathMLFencedOperatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.cpp (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.cpp        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.cpp        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -42,46 +42,41 @@
</span><span class="cx">     , m_operatorFlags(flags)
</span><span class="cx"> {
</span><span class="cx">     updateOperatorContent(operatorString);
</span><del>-
-    // maxsize always has the default value &quot;infinity&quot; value for mfenced operators.
-    m_maxSize = intMaxForLayoutUnit;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderMathMLFencedOperator::updateOperatorContent(const String&amp; operatorString)
</span><span class="cx"> {
</span><del>-    m_textContent = MathMLOperatorElement::parseOperatorText(operatorString);
-    rebuildTokenContent();
</del><ins>+    m_operatorChar = MathMLOperatorElement::parseOperatorChar(operatorString);
+
+    // We try and read spacing and boolean properties from the operator dictionary.
+    // However we preserve the Fence and Separator properties specified in the constructor.
+    if (auto entry = search(m_operatorChar.character, m_operatorForm, true)) {
+        m_leadingSpaceInMathUnit = entry.value().lspace;
+        m_trailingSpaceInMathUnit = entry.value().rspace;
+        m_operatorFlags = (m_operatorFlags &amp; (MathMLOperatorDictionary::Fence | MathMLOperatorDictionary::Separator)) | entry.value().flags;
+    } else {
+        m_operatorFlags &amp;= MathMLOperatorDictionary::Fence | MathMLOperatorDictionary::Separator; // Flags are disabled by default.
+        m_leadingSpaceInMathUnit = 5; // Default spacing is thickmathspace.
+        m_trailingSpaceInMathUnit = 5; // Default spacing is thickmathspace.
+    }
+
+    updateMathOperator();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderMathMLFencedOperator::setOperatorProperties()
</del><ins>+LayoutUnit RenderMathMLFencedOperator::leadingSpace() const
</ins><span class="cx"> {
</span><del>-    // We determine the stretch direction (default is vertical).
-    m_isVertical = MathMLOperatorDictionary::isVertical(m_textContent);
-
-    // Resets all but the Fence and Separator properties.
-    m_operatorFlags &amp;= MathMLOperatorDictionary::Fence | MathMLOperatorDictionary::Separator;
-
-    // minsize always has the default value &quot;1em&quot; value for mfenced operators.
-    m_minSize = style().fontCascade().size();
-
-    // Default spacing is thickmathspace.
</del><span class="cx">     MathMLElement::Length leadingSpace;
</span><span class="cx">     leadingSpace.type = MathMLElement::LengthType::MathUnit;
</span><del>-    leadingSpace.value = 5;
-    MathMLElement::Length trailingSpace = leadingSpace;
</del><ins>+    leadingSpace.value = static_cast&lt;float&gt;(m_leadingSpaceInMathUnit);
+    return toUserUnits(leadingSpace, style(), 0);
+}
</ins><span class="cx"> 
</span><del>-    if (auto entry = search(m_textContent, m_operatorForm, true)) {
-        // We use the space specified in the operator dictionary.
-        leadingSpace.value = static_cast&lt;float&gt;(entry.value().lspace);
-        trailingSpace.value = static_cast&lt;float&gt;(entry.value().rspace);
-
-        // We use the dictionary but preserve the Fence and Separator properties.
-        m_operatorFlags = (m_operatorFlags &amp; (MathMLOperatorDictionary::Fence | MathMLOperatorDictionary::Separator)) | entry.value().flags;
-    }
-
-    // Resolve the leading and trailing spaces.
-    m_leadingSpace = toUserUnits(leadingSpace, style(), 0);
-    m_trailingSpace = toUserUnits(trailingSpace, style(), 0);
</del><ins>+LayoutUnit RenderMathMLFencedOperator::trailingSpace() const
+{
+    MathMLElement::Length trailingSpace;
+    trailingSpace.type = MathMLElement::LengthType::MathUnit;
+    trailingSpace.value = static_cast&lt;float&gt;(m_trailingSpaceInMathUnit);
+    return toUserUnits(trailingSpace, style(), 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingmathmlRenderMathMLFencedOperatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.h (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.h        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.h        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #if ENABLE(MATHML)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;MathMLOperatorDictionary.h&quot;
</span><ins>+#include &quot;MathMLOperatorElement.h&quot;
</ins><span class="cx"> #include &quot;RenderMathMLOperator.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -39,22 +40,25 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     bool isRenderMathMLFencedOperator() const final { return true; }
</span><del>-    void setOperatorProperties() final;
-    UChar textContent() const final { return m_textContent; }
-    LayoutUnit leadingSpace() const final { return m_leadingSpace; }
-    LayoutUnit trailingSpace() const final { return m_trailingSpace; }
-    LayoutUnit minSize() const final { return m_minSize; }
-    LayoutUnit maxSize() const final { return m_maxSize; }
</del><ins>+    bool isVertical() const final { return m_operatorChar.isVertical; }
+    UChar textContent() const final { return m_operatorChar.character; }
+    LayoutUnit leadingSpace() const final;
+    LayoutUnit trailingSpace() const final;
+
+    // minsize always has the default value &quot;1em&quot;.
+    LayoutUnit minSize() const final { return style().fontCascade().size(); }
+
+    // maxsize always has the default value &quot;infinity&quot;.
+    LayoutUnit maxSize() const final { return intMaxForLayoutUnit; }
+
</ins><span class="cx">     bool hasOperatorFlag(MathMLOperatorDictionary::Flag flag) const final { return m_operatorFlags &amp; flag; }
</span><span class="cx"> 
</span><span class="cx">     // We always use the MathOperator class for anonymous mfenced operators, since they do not have text content in the DOM.
</span><span class="cx">     bool useMathOperator() const final { return true; }
</span><span class="cx"> 
</span><del>-    UChar m_textContent { 0 };
-    LayoutUnit m_leadingSpace;
-    LayoutUnit m_trailingSpace;
-    LayoutUnit m_minSize;
-    LayoutUnit m_maxSize;
</del><ins>+    MathMLOperatorElement::OperatorChar m_operatorChar;
+    unsigned short m_leadingSpaceInMathUnit;
+    unsigned short m_trailingSpaceInMathUnit;
</ins><span class="cx">     MathMLOperatorDictionary::Form m_operatorForm;
</span><span class="cx">     unsigned short m_operatorFlags;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingmathmlRenderMathMLOperatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx"> 
</span><span class="cx"> UChar RenderMathMLOperator::textContent() const
</span><span class="cx"> {
</span><del>-    return element().operatorText();
</del><ins>+    return element().operatorChar().character;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RenderMathMLOperator::isInvisibleOperator() const
</span><span class="lines">@@ -110,24 +110,23 @@
</span><span class="cx">     return std::max&lt;LayoutUnit&gt;(0, maxSize);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderMathMLOperator::setOperatorProperties()
</del><ins>+bool RenderMathMLOperator::isVertical() const
</ins><span class="cx"> {
</span><del>-    // We determine the stretch direction (default is vertical).
-    m_isVertical = MathMLOperatorDictionary::isVertical(textContent());
</del><ins>+    return element().operatorChar().isVertical;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> void RenderMathMLOperator::stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(hasOperatorFlag(MathMLOperatorDictionary::Stretchy));
</span><del>-    ASSERT(m_isVertical);
</del><ins>+    ASSERT(isVertical());
</ins><span class="cx"> 
</span><del>-    if (!m_isVertical || (heightAboveBaseline == m_stretchHeightAboveBaseline &amp;&amp; depthBelowBaseline == m_stretchDepthBelowBaseline))
</del><ins>+    if (!isVertical() || (heightAboveBaseline == m_stretchHeightAboveBaseline &amp;&amp; depthBelowBaseline == m_stretchDepthBelowBaseline))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_stretchHeightAboveBaseline = heightAboveBaseline;
</span><span class="cx">     m_stretchDepthBelowBaseline = depthBelowBaseline;
</span><span class="cx"> 
</span><del>-    setOperatorProperties();
</del><span class="cx">     if (hasOperatorFlag(MathMLOperatorDictionary::Symmetric)) {
</span><span class="cx">         // We make the operator stretch symmetrically above and below the axis.
</span><span class="cx">         LayoutUnit axis = mathAxisHeight();
</span><span class="lines">@@ -160,22 +159,20 @@
</span><span class="cx"> void RenderMathMLOperator::stretchTo(LayoutUnit width)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(hasOperatorFlag(MathMLOperatorDictionary::Stretchy));
</span><del>-    ASSERT(!m_isVertical);
</del><ins>+    ASSERT(!isVertical());
</ins><span class="cx"> 
</span><del>-    if (m_isVertical || m_stretchWidth == width)
</del><ins>+    if (isVertical() || m_stretchWidth == width)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_stretchWidth = width;
</span><span class="cx">     m_mathOperator.stretchTo(style(), width);
</span><span class="cx"> 
</span><del>-    setOperatorProperties();
-
</del><span class="cx">     setLogicalHeight(m_mathOperator.ascent() + m_mathOperator.descent());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderMathMLOperator::resetStretchSize()
</span><span class="cx"> {
</span><del>-    if (m_isVertical) {
</del><ins>+    if (isVertical()) {
</ins><span class="cx">         m_stretchHeightAboveBaseline = 0;
</span><span class="cx">         m_stretchDepthBelowBaseline = 0;
</span><span class="cx">     } else
</span><span class="lines">@@ -188,7 +185,6 @@
</span><span class="cx"> 
</span><span class="cx">     LayoutUnit preferredWidth = 0;
</span><span class="cx"> 
</span><del>-    setOperatorProperties();
</del><span class="cx">     if (!useMathOperator()) {
</span><span class="cx">         RenderMathMLToken::computePreferredLogicalWidths();
</span><span class="cx">         preferredWidth = m_maxPreferredLogicalWidth;
</span><span class="lines">@@ -243,22 +239,17 @@
</span><span class="cx">     clearNeedsLayout();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderMathMLOperator::rebuildTokenContent()
</del><ins>+void RenderMathMLOperator::updateMathOperator()
</ins><span class="cx"> {
</span><del>-    setOperatorProperties();
-
-    if (useMathOperator()) {
-        MathOperator::Type type;
-        if (!shouldAllowStretching())
-            type = MathOperator::Type::NormalOperator;
-        else if (isLargeOperatorInDisplayStyle())
-            type = MathOperator::Type::DisplayOperator;
-        else
-            type = m_isVertical ? MathOperator::Type::VerticalOperator : MathOperator::Type::HorizontalOperator;
-        m_mathOperator.setOperator(style(), textContent(), type);
-    }
-
-    setNeedsLayoutAndPrefWidthsRecalc();
</del><ins>+    ASSERT(useMathOperator());
+    MathOperator::Type type;
+    if (!shouldAllowStretching())
+        type = MathOperator::Type::NormalOperator;
+    else if (isLargeOperatorInDisplayStyle())
+        type = MathOperator::Type::DisplayOperator;
+    else
+        type = isVertical() ? MathOperator::Type::VerticalOperator : MathOperator::Type::HorizontalOperator;
+    m_mathOperator.setOperator(style(), textContent(), type);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderMathMLOperator::updateTokenContent()
</span><span class="lines">@@ -265,7 +256,8 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!isAnonymous());
</span><span class="cx">     RenderMathMLToken::updateTokenContent();
</span><del>-    rebuildTokenContent();
</del><ins>+    if (useMathOperator())
+        updateMathOperator();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderMathMLOperator::updateFromElement()
</span><span class="lines">@@ -273,12 +265,6 @@
</span><span class="cx">     updateTokenContent();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderMathMLOperator::updateOperatorProperties()
-{
-    setOperatorProperties();
-    setNeedsLayoutAndPrefWidthsRecalc();
-}
-
</del><span class="cx"> bool RenderMathMLOperator::shouldAllowStretching() const
</span><span class="cx"> {
</span><span class="cx">     return textContent() &amp;&amp; (hasOperatorFlag(MathMLOperatorDictionary::Stretchy) || isLargeOperatorInDisplayStyle());
</span><span class="lines">@@ -296,12 +282,11 @@
</span><span class="cx"> {
</span><span class="cx">     RenderMathMLBlock::styleDidChange(diff, oldStyle);
</span><span class="cx">     m_mathOperator.reset(style());
</span><del>-    updateOperatorProperties();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LayoutUnit RenderMathMLOperator::verticalStretchedOperatorShift() const
</span><span class="cx"> {
</span><del>-    if (!m_isVertical || !stretchSize())
</del><ins>+    if (!isVertical() || !stretchSize())
</ins><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="cx">     return (m_stretchDepthBelowBaseline - m_stretchHeightAboveBaseline - m_mathOperator.descent() + m_mathOperator.ascent()) / 2;
</span><span class="lines">@@ -324,7 +309,7 @@
</span><span class="cx">     operatorTopLeft.move(style().isLeftToRightDirection() ? leadingSpace() : trailingSpace(), 0);
</span><span class="cx"> 
</span><span class="cx">     // Center horizontal operators.
</span><del>-    if (!m_isVertical)
</del><ins>+    if (!isVertical())
</ins><span class="cx">         operatorTopLeft.move(-(m_mathOperator.width() - width()) / 2, 0);
</span><span class="cx"> 
</span><span class="cx">     m_mathOperator.paint(style(), info, operatorTopLeft);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingmathmlRenderMathMLOperatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -44,23 +44,21 @@
</span><span class="cx"> 
</span><span class="cx">     void stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline);
</span><span class="cx">     void stretchTo(LayoutUnit width);
</span><del>-    LayoutUnit stretchSize() const { return m_isVertical ? m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline : m_stretchWidth; }
</del><ins>+    LayoutUnit stretchSize() const { return isVertical() ? m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline : m_stretchWidth; }
</ins><span class="cx">     void resetStretchSize();
</span><span class="cx"> 
</span><span class="cx">     virtual bool hasOperatorFlag(MathMLOperatorDictionary::Flag) const;
</span><span class="cx">     bool isLargeOperatorInDisplayStyle() const { return !hasOperatorFlag(MathMLOperatorDictionary::Stretchy) &amp;&amp; hasOperatorFlag(MathMLOperatorDictionary::LargeOp) &amp;&amp; mathMLStyle()-&gt;displayStyle(); }
</span><span class="cx">     bool shouldMoveLimits() const { return hasOperatorFlag(MathMLOperatorDictionary::MovableLimits) &amp;&amp; !mathMLStyle()-&gt;displayStyle(); }
</span><del>-    bool isVertical() const { return m_isVertical; }
</del><ins>+    virtual bool isVertical() const;
</ins><span class="cx">     LayoutUnit italicCorrection() const { return m_mathOperator.italicCorrection(); }
</span><span class="cx"> 
</span><span class="cx">     void updateTokenContent() final;
</span><del>-    void updateOperatorProperties();
</del><span class="cx">     void updateFromElement() final;
</span><span class="cx">     virtual UChar textContent() const;
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    void rebuildTokenContent();
-    virtual void setOperatorProperties();
</del><ins>+    virtual void updateMathOperator();
</ins><span class="cx">     virtual LayoutUnit leadingSpace() const;
</span><span class="cx">     virtual LayoutUnit trailingSpace() const;
</span><span class="cx">     virtual LayoutUnit minSize() const;
</span><span class="lines">@@ -67,8 +65,6 @@
</span><span class="cx">     virtual LayoutUnit maxSize() const;
</span><span class="cx">     virtual bool useMathOperator() const;
</span><span class="cx"> 
</span><del>-    bool m_isVertical { true };
-
</del><span class="cx"> private:
</span><span class="cx">     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
</span><span class="cx">     void computePreferredLogicalWidths() final;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingmathmlRenderMathMLRowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -44,18 +44,6 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderMathMLRow::updateOperatorProperties()
-{
-    for (auto* child = firstChildBox(); child; child = child-&gt;nextSiblingBox()) {
-        if (is&lt;RenderMathMLBlock&gt;(*child)) {
-            if (auto* renderOperator = downcast&lt;RenderMathMLBlock&gt;(*child).unembellishedOperator())
-                renderOperator-&gt;updateOperatorProperties();
-        }
-    }
-    setNeedsLayoutAndPrefWidthsRecalc();
-}
-
-
</del><span class="cx"> Optional&lt;int&gt; RenderMathMLRow::firstLineBaseline() const
</span><span class="cx"> {
</span><span class="cx">     auto* baselineChild = firstChildBox();
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingmathmlRenderMathMLRowh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.h (204074 => 204075)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.h        2016-08-03 06:35:08 UTC (rev 204074)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.h        2016-08-03 07:00:38 UTC (rev 204075)
</span><span class="lines">@@ -36,8 +36,6 @@
</span><span class="cx"> public:
</span><span class="cx">     RenderMathMLRow(Element&amp;, RenderStyle&amp;&amp;);
</span><span class="cx"> 
</span><del>-    void updateOperatorProperties();
-
</del><span class="cx"> protected:
</span><span class="cx">     void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
</span><span class="cx">     Optional&lt;int&gt; firstLineBaseline() const override;
</span></span></pre>
</div>
</div>

</body>
</html>