<!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>[201534] 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/201534">201534</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2016-05-31 15:51:01 -0700 (Tue, 31 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Clean up / modernize iOS text autosizing code
https://bugs.webkit.org/show_bug.cgi?id=158217

Reviewed by Darin Adler.

Clean up / modernize iOS text autosizing code.

I think iOS text autosizing code is too intrusive inside the RenderStyle
class but I have not updated this part of the code yet to limit patch
size. This patch focuses on the TextAutoSizing.* and text autosizing
code in the Document class.

* WebCore.xcodeproj/project.pbxproj:
* dom/Document.cpp:
(WebCore::TextAutoSizingTraits::constructDeletedValue): Deleted.
(WebCore::TextAutoSizingTraits::isDeletedValue): Deleted.
Move TextAutoSizingTraits to the TextAutoSizing header to
promote reuse and make the text autosizing code a little less
intrusive.

(WebCore::Document::addAutoSizingNode):
- Drop local 'key' variable as it is only used once.
- Use std::make_unique&lt;&gt; to construct the TextAutoSizingValue
  as it is no longer ref-counted.

(WebCore::Document::validateAutoSizingNodes):
Iterate over the textAutosizedNodes HashMap only once instead
of twice. TextAutoSizingValue::adjustTextNodeSizes() was updated
to return an enum class so we know from that value if we can
remove the value from the HashSet or not, without having to rely
on TextAutoSizingValue::numNodes(), which I removed in this
patch.

(WebCore::Document::clearAutoSizingNodes):
Updated the TextAutoSizingValue destructor to call reset() so
we don't have to explicitly call reset() on each value before
clearing the textAutosizedNodes HashMap.

* dom/Document.h:
- Move TextAutoSizingTraits to the TextAutosizing header.
- Rename resetAutosizingNodes() to clearAutoSizingNodes() as
  the method now only clears the textAutosizedNodes HashMap
  and reset() is now an implementation detail for
  TextAutoSizingValue.

* rendering/RenderElement.cpp:
(WebCore::RenderElement::resetTextAutosizing):
Call clearAutoSizingNodes() as it was renamed.

* rendering/TextAutoSizing.cpp:
(WebCore::TextAutoSizingKey::TextAutoSizingKey):
- Use value of -1 for std::unique_ptr m_style member for distinguishing
a HashTable deleted value, instead of having an extra m_isDeleted
data member for this purpose.
- Take RenderStyle parameter by reference and drop the null check as the
  call site can never pass nullptr.

(WebCore::TextAutoSizingValue::addTextNode):
- Rename addNode() to addTextNode() for clarity.

(WebCore::TextAutoSizingValue::~TextAutoSizingValue):
Update destructor to call reset() so that the Document does not have to
call it explicitly and can instead just clear the HashMap, which will
destroy the TextAutoSizingValue objects.

(WebCore::TextAutoSizingValue::reset):
Rename text to renderer for clarity.

* rendering/TextAutoSizing.h:
- Make TextAutoSizingValue as fast allocated.
- Update TextAutoSizingValue to no longer be refcounted as ownership is never
  shared. The Document owns those.
- Drop the factory function for TextAutoSizingValue and make the constructor
  public now that the class is no longer refcounted.
- Make reset() method private now that it is called from the destructor and
  the Document is no longer expected to explicitly call it.
- Update adjustTextNodeSizes() to return a StillHasNodes enum class and the
  Document can rely on the determine if it can drop the TextAutoSizingValue
  from its HashMap (and therefore destroy the object).
- Drop numNodes() method as it is no longer needed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockFlowcpp">trunk/Source/WebCore/rendering/RenderBlockFlow.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementcpp">trunk/Source/WebCore/rendering/RenderElement.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingTextAutoSizingcpp">trunk/Source/WebCore/rendering/TextAutoSizing.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingTextAutoSizingh">trunk/Source/WebCore/rendering/TextAutoSizing.h</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleRenderStylecpp">trunk/Source/WebCore/rendering/style/RenderStyle.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleRenderStyleh">trunk/Source/WebCore/rendering/style/RenderStyle.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/ChangeLog        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -1,3 +1,87 @@
</span><ins>+2016-05-31  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Clean up / modernize iOS text autosizing code
+        https://bugs.webkit.org/show_bug.cgi?id=158217
+
+        Reviewed by Darin Adler.
+
+        Clean up / modernize iOS text autosizing code.
+
+        I think iOS text autosizing code is too intrusive inside the RenderStyle
+        class but I have not updated this part of the code yet to limit patch
+        size. This patch focuses on the TextAutoSizing.* and text autosizing
+        code in the Document class.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/Document.cpp:
+        (WebCore::TextAutoSizingTraits::constructDeletedValue): Deleted.
+        (WebCore::TextAutoSizingTraits::isDeletedValue): Deleted.
+        Move TextAutoSizingTraits to the TextAutoSizing header to
+        promote reuse and make the text autosizing code a little less
+        intrusive.
+
+        (WebCore::Document::addAutoSizingNode):
+        - Drop local 'key' variable as it is only used once.
+        - Use std::make_unique&lt;&gt; to construct the TextAutoSizingValue
+          as it is no longer ref-counted.
+
+        (WebCore::Document::validateAutoSizingNodes):
+        Iterate over the textAutosizedNodes HashMap only once instead
+        of twice. TextAutoSizingValue::adjustTextNodeSizes() was updated
+        to return an enum class so we know from that value if we can
+        remove the value from the HashSet or not, without having to rely
+        on TextAutoSizingValue::numNodes(), which I removed in this
+        patch.
+
+        (WebCore::Document::clearAutoSizingNodes):
+        Updated the TextAutoSizingValue destructor to call reset() so
+        we don't have to explicitly call reset() on each value before
+        clearing the textAutosizedNodes HashMap.
+
+        * dom/Document.h:
+        - Move TextAutoSizingTraits to the TextAutosizing header.
+        - Rename resetAutosizingNodes() to clearAutoSizingNodes() as
+          the method now only clears the textAutosizedNodes HashMap
+          and reset() is now an implementation detail for
+          TextAutoSizingValue.
+
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::resetTextAutosizing):
+        Call clearAutoSizingNodes() as it was renamed.
+
+        * rendering/TextAutoSizing.cpp:
+        (WebCore::TextAutoSizingKey::TextAutoSizingKey):
+        - Use value of -1 for std::unique_ptr m_style member for distinguishing
+        a HashTable deleted value, instead of having an extra m_isDeleted
+        data member for this purpose.
+        - Take RenderStyle parameter by reference and drop the null check as the
+          call site can never pass nullptr.
+
+        (WebCore::TextAutoSizingValue::addTextNode):
+        - Rename addNode() to addTextNode() for clarity.
+
+        (WebCore::TextAutoSizingValue::~TextAutoSizingValue):
+        Update destructor to call reset() so that the Document does not have to
+        call it explicitly and can instead just clear the HashMap, which will
+        destroy the TextAutoSizingValue objects.
+
+        (WebCore::TextAutoSizingValue::reset):
+        Rename text to renderer for clarity.
+
+        * rendering/TextAutoSizing.h:
+        - Make TextAutoSizingValue as fast allocated.
+        - Update TextAutoSizingValue to no longer be refcounted as ownership is never
+          shared. The Document owns those.
+        - Drop the factory function for TextAutoSizingValue and make the constructor
+          public now that the class is no longer refcounted.
+        - Make reset() method private now that it is called from the destructor and
+          the Document is no longer expected to explicitly call it.
+        - Update adjustTextNodeSizes() to return a StillHasNodes enum class and the
+          Document can rely on the determine if it can drop the TextAutoSizingValue
+          from its HashMap (and therefore destroy the object).
+        - Drop numNodes() method as it is no longer needed.
+
+
</ins><span class="cx"> 2016-05-31  Dave Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(r201040): Repainting of moving overflow:hidden objects is broken.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -474,7 +474,7 @@
</span><span class="cx">                 0F54DCE11880F901003EEDBB /* DOMGestureEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F54DCDE1880F901003EEDBB /* DOMGestureEvent.mm */; };
</span><span class="cx">                 0F54DCE21880F901003EEDBB /* DOMGestureEventInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F54DCDF1880F901003EEDBB /* DOMGestureEventInternal.h */; };
</span><span class="cx">                 0F54DCE51881051D003EEDBB /* TextAutoSizing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F54DCE31881051D003EEDBB /* TextAutoSizing.cpp */; };
</span><del>-                0F54DCE61881051D003EEDBB /* TextAutoSizing.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F54DCE41881051D003EEDBB /* TextAutoSizing.h */; };
</del><ins>+                0F54DCE61881051D003EEDBB /* TextAutoSizing.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F54DCE41881051D003EEDBB /* TextAutoSizing.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F54DD081881D5F5003EEDBB /* Touch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F54DD051881D5F5003EEDBB /* Touch.h */; };
</span><span class="cx">                 0F54DD091881D5F5003EEDBB /* TouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F54DD061881D5F5003EEDBB /* TouchEvent.h */; };
</span><span class="cx">                 0F54DD0A1881D5F5003EEDBB /* TouchList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F54DD071881D5F5003EEDBB /* TouchList.h */; };
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/dom/Document.cpp        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -223,10 +223,6 @@
</span><span class="cx"> #include &quot;GestureEvent.h&quot;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if ENABLE(IOS_TEXT_AUTOSIZING)
-#include &quot;TextAutoSizing.h&quot;
-#endif
-
</del><span class="cx"> #if ENABLE(MATHML)
</span><span class="cx"> #include &quot;MathMLElement.h&quot;
</span><span class="cx"> #include &quot;MathMLElementFactory.h&quot;
</span><span class="lines">@@ -425,18 +421,6 @@
</span><span class="cx"> 
</span><span class="cx"> uint64_t Document::s_globalTreeVersion = 0;
</span><span class="cx"> 
</span><del>-#if ENABLE(IOS_TEXT_AUTOSIZING)
-void TextAutoSizingTraits::constructDeletedValue(TextAutoSizingKey&amp; slot)
-{
-    new (&amp;slot) TextAutoSizingKey(TextAutoSizingKey::Deleted);
-}
-
-bool TextAutoSizingTraits::isDeletedValue(const TextAutoSizingKey&amp; value)
-{
-    return value.isDeleted();
-}
-#endif
-
</del><span class="cx"> HashSet&lt;Document*&gt;&amp; Document::allDocuments()
</span><span class="cx"> {
</span><span class="cx">     static NeverDestroyed&lt;HashSet&lt;Document*&gt;&gt; documents;
</span><span class="lines">@@ -5298,35 +5282,24 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(IOS_TEXT_AUTOSIZING)
</span><span class="cx"> 
</span><del>-void Document::addAutoSizingNode(Text&amp; node, float candidateSize)
</del><ins>+void Document::addAutoSizedNode(Text&amp; node, float candidateSize)
</ins><span class="cx"> {
</span><del>-    LOG(TextAutosizing, &quot; addAutoSizingNode %p candidateSize=%f&quot;, &amp;node, candidateSize);
-
-    TextAutoSizingKey key(&amp;node.renderer()-&gt;style());
-    auto addResult = m_textAutoSizedNodes.ensure(WTFMove(key), [] {
-        return TextAutoSizingValue::create();
-    });
-    addResult.iterator-&gt;value-&gt;addNode(node, candidateSize);
</del><ins>+    LOG(TextAutosizing, &quot; addAutoSizedNode %p candidateSize=%f&quot;, &amp;node, candidateSize);
+    auto addResult = m_textAutoSizedNodes.add&lt;TextAutoSizingHashTranslator&gt;(node.renderer()-&gt;style(), nullptr);
+    if (addResult.isNewEntry)
+        addResult.iterator-&gt;value = std::make_unique&lt;TextAutoSizingValue&gt;();
+    addResult.iterator-&gt;value-&gt;addTextNode(node, candidateSize);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Document::validateAutoSizingNodes()
</del><ins>+void Document::updateAutoSizedNodes()
</ins><span class="cx"> {
</span><del>-    Vector&lt;TextAutoSizingKey&gt; nodesForRemoval;
-    for (auto&amp; keyValuePair : m_textAutoSizedNodes) {
-        TextAutoSizingValue* value = keyValuePair.value.get();
-        // Update all the nodes in the collection to reflect the new
-        // candidate size.
-        value-&gt;adjustNodeSizes();
-    }
</del><span class="cx">     m_textAutoSizedNodes.removeIf([](auto&amp; keyAndValue) {
</span><del>-        return !keyAndValue.value-&gt;numNodes();
</del><ins>+        return keyAndValue.value-&gt;adjustTextNodeSizes() == TextAutoSizingValue::StillHasNodes::No;
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-void Document::resetAutoSizingNodes()
</del><ins>+void Document::clearAutoSizedNodes()
</ins><span class="cx"> {
</span><del>-    for (auto&amp; value : m_textAutoSizedNodes.values())
-        value-&gt;reset();
</del><span class="cx">     m_textAutoSizedNodes.clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/dom/Document.h        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> #include &quot;StringWithDirection.h&quot;
</span><span class="cx"> #include &quot;StyleChange.h&quot;
</span><span class="cx"> #include &quot;Supplementable.h&quot;
</span><ins>+#include &quot;TextAutoSizing.h&quot;
</ins><span class="cx"> #include &quot;TextResourceDecoder.h&quot;
</span><span class="cx"> #include &quot;Timer.h&quot;
</span><span class="cx"> #include &quot;TreeScope.h&quot;
</span><span class="lines">@@ -212,12 +213,6 @@
</span><span class="cx"> struct TextAutoSizingHash;
</span><span class="cx"> class TextAutoSizingKey;
</span><span class="cx"> class TextAutoSizingValue;
</span><del>-
-struct TextAutoSizingTraits : WTF::GenericHashTraits&lt;TextAutoSizingKey&gt; {
-    static const bool emptyValueIsZero = true;
-    static void constructDeletedValue(TextAutoSizingKey&amp; slot);
-    static bool isDeletedValue(const TextAutoSizingKey&amp; value);
-};
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_SESSION)
</span><span class="lines">@@ -1694,12 +1689,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(IOS_TEXT_AUTOSIZING)
</span><span class="cx"> public:
</span><del>-    void addAutoSizingNode(Text&amp;, float size);
-    void validateAutoSizingNodes();
-    void resetAutoSizingNodes();
</del><ins>+    void addAutoSizedNode(Text&amp;, float size);
+    void updateAutoSizedNodes();
+    void clearAutoSizedNodes();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    typedef HashMap&lt;TextAutoSizingKey, RefPtr&lt;TextAutoSizingValue&gt;, TextAutoSizingHash, TextAutoSizingTraits&gt; TextAutoSizingMap;
</del><ins>+    using TextAutoSizingMap = HashMap&lt;TextAutoSizingKey, std::unique_ptr&lt;TextAutoSizingValue&gt;, TextAutoSizingHash, TextAutoSizingTraits&gt;;
</ins><span class="cx">     TextAutoSizingMap m_textAutoSizedNodes;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockFlowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -3817,7 +3817,7 @@
</span><span class="cx">             float lineTextMultiplier = lineCount == ONE_LINE ? oneLineTextMultiplier(specifiedSize) : textMultiplier(specifiedSize);
</span><span class="cx">             float candidateNewSize = roundf(std::min(minFontSize, specifiedSize * lineTextMultiplier));
</span><span class="cx">             if (candidateNewSize &gt; specifiedSize &amp;&amp; candidateNewSize != fontDescription.computedSize() &amp;&amp; text.textNode() &amp;&amp; oldStyle.textSizeAdjust().isAuto())
</span><del>-                document().addAutoSizingNode(*text.textNode(), candidateNewSize);
</del><ins>+                document().addAutoSizedNode(*text.textNode(), candidateNewSize);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         descendant = RenderObjectTraversal::nextSkippingChildren(text, this);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.cpp        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -2214,7 +2214,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Remove style from auto-sizing table that are no longer valid.
</span><del>-    document-&gt;validateAutoSizingNodes();
</del><ins>+    document-&gt;updateAutoSizedNodes();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderElement::resetTextAutosizing()
</span><span class="lines">@@ -2225,7 +2225,7 @@
</span><span class="cx"> 
</span><span class="cx">     LOG(TextAutosizing, &quot;RenderElement::resetTextAutosizing()&quot;);
</span><span class="cx"> 
</span><del>-    document-&gt;resetAutoSizingNodes();
</del><ins>+    document-&gt;clearAutoSizedNodes();
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;int&gt; depthStack;
</span><span class="cx">     int currentDepth = 0;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingTextAutoSizingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/TextAutoSizing.cpp (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/TextAutoSizing.cpp        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/rendering/TextAutoSizing.cpp        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -48,79 +48,71 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TextAutoSizingKey::TextAutoSizingKey(DeletedTag)
</span><del>-    : m_isDeleted(true)
</del><span class="cx"> {
</span><ins>+    HashTraits&lt;std::unique_ptr&lt;RenderStyle&gt;&gt;::constructDeletedValue(m_style);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-TextAutoSizingKey::TextAutoSizingKey(const RenderStyle* style)
-    : m_style(style ? RenderStyle::clonePtr(*style) : nullptr)
</del><ins>+TextAutoSizingKey::TextAutoSizingKey(const RenderStyle&amp; style, unsigned hash)
+    : m_style(RenderStyle::clonePtr(style)) // FIXME: This seems very inefficient.
+    , m_hash(hash)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-int TextAutoSizingValue::numNodes() const
</del><ins>+void TextAutoSizingValue::addTextNode(Text&amp; node, float size)
</ins><span class="cx"> {
</span><del>-    return m_autoSizedNodes.size();
-}
-
-void TextAutoSizingValue::addNode(Text&amp; node, float size)
-{
</del><span class="cx">     node.renderer()-&gt;setCandidateComputedTextSize(size);
</span><span class="cx">     m_autoSizedNodes.add(&amp;node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#define MAX_SCALE_INCREASE 1.7f
</del><ins>+static const float maxScaleIncrease = 1.7f;
</ins><span class="cx"> 
</span><del>-bool TextAutoSizingValue::adjustNodeSizes()
</del><ins>+auto TextAutoSizingValue::adjustTextNodeSizes() -&gt; StillHasNodes
</ins><span class="cx"> {
</span><del>-    bool didRemoveObjects = false;
-
-    // Remove stale nodes.  Nodes may have had their renderers detached.  We'll
-    // also need to remove the style from the documents m_textAutoSizedNodes
-    // collection.  Return true indicates we need to do that removal.
</del><ins>+    // Remove stale nodes. Nodes may have had their renderers detached. We'll also need to remove the style from the documents m_textAutoSizedNodes
+    // collection. Return true indicates we need to do that removal.
</ins><span class="cx">     Vector&lt;Text*&gt; nodesForRemoval;
</span><del>-    for (auto&amp; node : m_autoSizedNodes) {
-        auto* text = node-&gt;renderer();
-        if (!text || !text-&gt;style().textSizeAdjust().isAuto() || !text-&gt;candidateComputedTextSize()) {
-            nodesForRemoval.append(node.get());
-            didRemoveObjects = true;
-        }
</del><ins>+    for (auto&amp; textNode : m_autoSizedNodes) {
+        auto* renderer = textNode-&gt;renderer();
+        if (!renderer || !renderer-&gt;style().textSizeAdjust().isAuto() || !renderer-&gt;candidateComputedTextSize())
+            nodesForRemoval.append(textNode.get());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (auto&amp; node : nodesForRemoval)
</span><span class="cx">         m_autoSizedNodes.remove(node);
</span><span class="cx"> 
</span><del>-    // If we only have one piece of text with the style on the page don't
-    // adjust it's size.
</del><ins>+    StillHasNodes stillHasNodes = m_autoSizedNodes.isEmpty() ? StillHasNodes::No : StillHasNodes::Yes;
+
+    // If we only have one piece of text with the style on the page don't adjust it's size.
</ins><span class="cx">     if (m_autoSizedNodes.size() &lt;= 1)
</span><del>-        return didRemoveObjects;
</del><ins>+        return stillHasNodes;
</ins><span class="cx"> 
</span><del>-    // Compute average size
</del><ins>+    // Compute average size.
</ins><span class="cx">     float cumulativeSize = 0;
</span><span class="cx">     for (auto&amp; node : m_autoSizedNodes)
</span><span class="cx">         cumulativeSize += node-&gt;renderer()-&gt;candidateComputedTextSize();
</span><span class="cx"> 
</span><del>-    float averageSize = roundf(cumulativeSize / m_autoSizedNodes.size());
</del><ins>+    float averageSize = std::round(cumulativeSize / m_autoSizedNodes.size());
</ins><span class="cx"> 
</span><del>-    // Adjust sizes
</del><ins>+    // Adjust sizes.
</ins><span class="cx">     bool firstPass = true;
</span><span class="cx">     for (auto&amp; node : m_autoSizedNodes) {
</span><del>-        auto* text = node-&gt;renderer();
-        if (!text || text-&gt;style().fontDescription().computedSize() == averageSize)
</del><ins>+        auto&amp; renderer = *node-&gt;renderer();
+        if (renderer.style().fontDescription().computedSize() == averageSize)
</ins><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        float specifiedSize = text-&gt;style().fontDescription().specifiedSize();
</del><ins>+        float specifiedSize = renderer.style().fontDescription().specifiedSize();
</ins><span class="cx">         float scaleChange = averageSize / specifiedSize;
</span><del>-        if (scaleChange &gt; MAX_SCALE_INCREASE &amp;&amp; firstPass) {
</del><ins>+        if (scaleChange &gt; maxScaleIncrease &amp;&amp; firstPass) {
</ins><span class="cx">             firstPass = false;
</span><del>-            averageSize = roundf(specifiedSize * MAX_SCALE_INCREASE);
</del><ins>+            averageSize = std::round(specifiedSize * maxScaleIncrease);
</ins><span class="cx">             scaleChange = averageSize / specifiedSize;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         LOG(TextAutosizing, &quot;  adjust node size %p firstPass=%d averageSize=%f scaleChange=%f&quot;, node.get(), firstPass, averageSize, scaleChange);
</span><span class="cx"> 
</span><del>-        auto* parentRenderer = text-&gt;parent();
</del><ins>+        auto* parentRenderer = renderer.parent();
</ins><span class="cx"> 
</span><del>-        auto style = cloneRenderStyleWithState(text-&gt;style());
</del><ins>+        auto style = cloneRenderStyleWithState(renderer.style());
</ins><span class="cx">         auto fontDescription = style.fontDescription();
</span><span class="cx">         fontDescription.setComputedSize(averageSize);
</span><span class="cx">         style.setFontDescription(fontDescription);
</span><span class="lines">@@ -161,26 +153,31 @@
</span><span class="cx">         parentRenderer-&gt;setStyle(WTFMove(newParentStyle));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return didRemoveObjects;
</del><ins>+    return stillHasNodes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TextAutoSizingValue::~TextAutoSizingValue()
+{
+    reset();
+}
+
</ins><span class="cx"> void TextAutoSizingValue::reset()
</span><span class="cx"> {
</span><span class="cx">     for (auto&amp; node : m_autoSizedNodes) {
</span><del>-        auto* text = node-&gt;renderer();
-        if (!text)
</del><ins>+        auto* renderer = node-&gt;renderer();
+        if (!renderer)
</ins><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        auto* parentRenderer = text-&gt;parent();
</del><ins>+        auto* parentRenderer = renderer-&gt;parent();
</ins><span class="cx">         if (!parentRenderer)
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         // Reset the font size back to the original specified size
</span><del>-        auto fontDescription = text-&gt;style().fontDescription();
</del><ins>+        auto fontDescription = renderer-&gt;style().fontDescription();
</ins><span class="cx">         float originalSize = fontDescription.specifiedSize();
</span><span class="cx">         if (fontDescription.computedSize() != originalSize) {
</span><span class="cx">             fontDescription.setComputedSize(originalSize);
</span><del>-            auto style = cloneRenderStyleWithState(text-&gt;style());
</del><ins>+            auto style = cloneRenderStyleWithState(renderer-&gt;style());
</ins><span class="cx">             style.setFontDescription(fontDescription);
</span><span class="cx">             style.fontCascade().update(&amp;node-&gt;document().fontSelector());
</span><span class="cx">             parentRenderer-&gt;setStyle(WTFMove(style));
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingTextAutoSizingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/TextAutoSizing.h (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/TextAutoSizing.h        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/rendering/TextAutoSizing.h        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -23,8 +23,7 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#ifndef TextAutoSizing_h
-#define TextAutoSizing_h
</del><ins>+#pragma once
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(IOS_TEXT_AUTOSIZING)
</span><span class="cx"> 
</span><span class="lines">@@ -38,22 +37,23 @@
</span><span class="cx"> class Document;
</span><span class="cx"> class Text;
</span><span class="cx"> 
</span><ins>+// FIXME: We can probably get rid of this class entirely and use std::unique_ptr&lt;RenderStyle&gt; as key
+// as long as we use the right hash traits.
</ins><span class="cx"> class TextAutoSizingKey {
</span><span class="cx"> public:
</span><span class="cx">     TextAutoSizingKey() = default;
</span><span class="cx">     enum DeletedTag { Deleted };
</span><span class="cx">     explicit TextAutoSizingKey(DeletedTag);
</span><del>-    explicit TextAutoSizingKey(const RenderStyle*);
-    TextAutoSizingKey(TextAutoSizingKey&amp;&amp;) = default;
</del><ins>+    TextAutoSizingKey(const RenderStyle&amp;, unsigned hash);
</ins><span class="cx"> 
</span><del>-    TextAutoSizingKey&amp; operator=(TextAutoSizingKey&amp;&amp;) = default;
</del><ins>+    const RenderStyle* style() const { ASSERT(!isDeleted()); return m_style.get(); }
+    bool isDeleted() const { return HashTraits&lt;std::unique_ptr&lt;RenderStyle&gt;&gt;::isDeletedValue(m_style); }
</ins><span class="cx"> 
</span><del>-    const RenderStyle* style() const { return m_style.get(); }
-    inline bool isDeleted() const { return m_isDeleted; }
</del><ins>+    unsigned hash() const { return m_hash; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     std::unique_ptr&lt;RenderStyle&gt; m_style;
</span><del>-    bool m_isDeleted { false };
</del><ins>+    unsigned m_hash { 0 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline bool operator==(const TextAutoSizingKey&amp; a, const TextAutoSizingKey&amp; b)
</span><span class="lines">@@ -62,33 +62,63 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!a.style() || !b.style())
</span><span class="cx">         return a.style() == b.style();
</span><del>-    return a.style()-&gt;equalForTextAutosizing(b.style());
</del><ins>+    return a.style()-&gt;equalForTextAutosizing(*b.style());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> struct TextAutoSizingHash {
</span><del>-    static unsigned hash(const TextAutoSizingKey&amp; key) { return key.style()-&gt;hashForTextAutosizing(); }
</del><ins>+    static unsigned hash(const TextAutoSizingKey&amp; key) { return key.hash(); }
</ins><span class="cx">     static bool equal(const TextAutoSizingKey&amp; a, const TextAutoSizingKey&amp; b) { return a == b; }
</span><span class="cx">     static const bool safeToCompareToEmptyOrDeleted = true;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class TextAutoSizingValue : public RefCounted&lt;TextAutoSizingValue&gt; {
-public:
-    static Ref&lt;TextAutoSizingValue&gt; create()
</del><ins>+struct TextAutoSizingTraits : WTF::GenericHashTraits&lt;TextAutoSizingKey&gt; {
+    static const bool emptyValueIsZero = true;
+    static void constructDeletedValue(TextAutoSizingKey&amp; slot)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new TextAutoSizingValue);
</del><ins>+        new (NotNull, &amp;slot) TextAutoSizingKey(TextAutoSizingKey::Deleted);
</ins><span class="cx">     }
</span><ins>+    static bool isDeletedValue(const TextAutoSizingKey&amp; value)
+    {
+        return value.isDeleted();
+    }
+};
</ins><span class="cx"> 
</span><del>-    void addNode(Text&amp;, float size);
-    bool adjustNodeSizes();
-    int numNodes() const;
</del><ins>+struct TextAutoSizingHashTranslator {
+    static unsigned hash(const RenderStyle&amp; style)
+    {
+        return style.hashForTextAutosizing();
+    }
+
+    static bool equal(const TextAutoSizingKey&amp; key, const RenderStyle&amp; style)
+    {
+        if (key.isDeleted() || !key.style())
+            return false;
+        return key.style()-&gt;equalForTextAutosizing(style);
+    }
+
+    static void translate(TextAutoSizingKey&amp; key, const RenderStyle&amp; style, unsigned hash)
+    {
+        key = { style, hash };
+    }
+};
+
+class TextAutoSizingValue {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    TextAutoSizingValue() = default;
+    ~TextAutoSizingValue();
+
+    void addTextNode(Text&amp;, float size);
+
+    enum class StillHasNodes { No, Yes };
+    StillHasNodes adjustTextNodeSizes();
+
+private:
</ins><span class="cx">     void reset();
</span><del>-private:
-    TextAutoSizingValue() { }
</del><ins>+
</ins><span class="cx">     HashSet&lt;RefPtr&lt;Text&gt;&gt; m_autoSizedNodes;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(IOS_TEXT_AUTOSIZING)
</span><del>-
-#endif // TextAutoSizing_h
</del></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleRenderStylecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -411,26 +411,26 @@
</span><span class="cx">     return hash;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool RenderStyle::equalForTextAutosizing(const RenderStyle* other) const
</del><ins>+bool RenderStyle::equalForTextAutosizing(const RenderStyle&amp; other) const
</ins><span class="cx"> {
</span><del>-    return rareNonInheritedData-&gt;m_appearance == other-&gt;rareNonInheritedData-&gt;m_appearance
-        &amp;&amp; rareNonInheritedData-&gt;marginBeforeCollapse == other-&gt;rareNonInheritedData-&gt;marginBeforeCollapse
-        &amp;&amp; rareNonInheritedData-&gt;marginAfterCollapse == other-&gt;rareNonInheritedData-&gt;marginAfterCollapse
-        &amp;&amp; rareNonInheritedData-&gt;lineClamp == other-&gt;rareNonInheritedData-&gt;lineClamp
-        &amp;&amp; rareInheritedData-&gt;textSizeAdjust == other-&gt;rareInheritedData-&gt;textSizeAdjust
-        &amp;&amp; rareInheritedData-&gt;overflowWrap == other-&gt;rareInheritedData-&gt;overflowWrap
-        &amp;&amp; rareInheritedData-&gt;nbspMode == other-&gt;rareInheritedData-&gt;nbspMode
-        &amp;&amp; rareInheritedData-&gt;lineBreak == other-&gt;rareInheritedData-&gt;lineBreak
-        &amp;&amp; rareInheritedData-&gt;textSecurity == other-&gt;rareInheritedData-&gt;textSecurity
-        &amp;&amp; inherited-&gt;specifiedLineHeight == other-&gt;inherited-&gt;specifiedLineHeight
-        &amp;&amp; inherited-&gt;fontCascade.equalForTextAutoSizing(other-&gt;inherited-&gt;fontCascade)
-        &amp;&amp; inherited-&gt;horizontal_border_spacing == other-&gt;inherited-&gt;horizontal_border_spacing
-        &amp;&amp; inherited-&gt;vertical_border_spacing == other-&gt;inherited-&gt;vertical_border_spacing
-        &amp;&amp; inherited_flags._box_direction == other-&gt;inherited_flags._box_direction
-        &amp;&amp; inherited_flags.m_rtlOrdering == other-&gt;inherited_flags.m_rtlOrdering
-        &amp;&amp; noninherited_flags.position() == other-&gt;noninherited_flags.position()
-        &amp;&amp; noninherited_flags.floating() == other-&gt;noninherited_flags.floating()
-        &amp;&amp; rareNonInheritedData-&gt;textOverflow == other-&gt;rareNonInheritedData-&gt;textOverflow;
</del><ins>+    return rareNonInheritedData-&gt;m_appearance == other.rareNonInheritedData-&gt;m_appearance
+        &amp;&amp; rareNonInheritedData-&gt;marginBeforeCollapse == other.rareNonInheritedData-&gt;marginBeforeCollapse
+        &amp;&amp; rareNonInheritedData-&gt;marginAfterCollapse == other.rareNonInheritedData-&gt;marginAfterCollapse
+        &amp;&amp; rareNonInheritedData-&gt;lineClamp == other.rareNonInheritedData-&gt;lineClamp
+        &amp;&amp; rareInheritedData-&gt;textSizeAdjust == other.rareInheritedData-&gt;textSizeAdjust
+        &amp;&amp; rareInheritedData-&gt;overflowWrap == other.rareInheritedData-&gt;overflowWrap
+        &amp;&amp; rareInheritedData-&gt;nbspMode == other.rareInheritedData-&gt;nbspMode
+        &amp;&amp; rareInheritedData-&gt;lineBreak == other.rareInheritedData-&gt;lineBreak
+        &amp;&amp; rareInheritedData-&gt;textSecurity == other.rareInheritedData-&gt;textSecurity
+        &amp;&amp; inherited-&gt;specifiedLineHeight == other.inherited-&gt;specifiedLineHeight
+        &amp;&amp; inherited-&gt;fontCascade.equalForTextAutoSizing(other.inherited-&gt;fontCascade)
+        &amp;&amp; inherited-&gt;horizontal_border_spacing == other.inherited-&gt;horizontal_border_spacing
+        &amp;&amp; inherited-&gt;vertical_border_spacing == other.inherited-&gt;vertical_border_spacing
+        &amp;&amp; inherited_flags._box_direction == other.inherited_flags._box_direction
+        &amp;&amp; inherited_flags.m_rtlOrdering == other.inherited_flags.m_rtlOrdering
+        &amp;&amp; noninherited_flags.position() == other.noninherited_flags.position()
+        &amp;&amp; noninherited_flags.floating() == other.noninherited_flags.floating()
+        &amp;&amp; rareNonInheritedData-&gt;textOverflow == other.rareNonInheritedData-&gt;textOverflow;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(IOS_TEXT_AUTOSIZING)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleRenderStyleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (201533 => 201534)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/RenderStyle.h        2016-05-31 22:44:31 UTC (rev 201533)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h        2016-05-31 22:51:01 UTC (rev 201534)
</span><span class="lines">@@ -1862,7 +1862,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(IOS_TEXT_AUTOSIZING)
</span><span class="cx">     uint32_t hashForTextAutosizing() const;
</span><del>-    bool equalForTextAutosizing(const RenderStyle *other) const;
</del><ins>+    bool equalForTextAutosizing(const RenderStyle&amp;) const;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     StyleDifference diff(const RenderStyle&amp;, unsigned&amp; changedContextSensitiveProperties) const;
</span></span></pre>
</div>
</div>

</body>
</html>