<!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>[208661] 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/208661">208661</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2016-11-12 19:08:52 -0800 (Sat, 12 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>RenderObject::flowThreadState should follow containing block instead of parent.
https://bugs.webkit.org/show_bug.cgi?id=164629

Reviewed by Simon Fraser.

Currently every descendant of a region/multicolumn container is considered to be part of the
flowthread including out-of-flow renderers. They all have the InsideFlowThread flag set.
However since out-of-flow renderers are not really part of the flowthread layout context,
whenever the layout code actually checks for their flowthread containers, we return nullptr and
try to handle this seemingly defective state gracefully (that is, flag indicates &quot;inside the flow thread&quot; state,
but there's no flow tread container).

This patch fixes this confused state by setting the RenderObject::flowThreadState flag based on
the containing block's state instead of the parent's.

Not testable, since we seem to manage out-of-flow elements just fine even
when they have the InsideFlowThread flag set.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::styleDidChange):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::setStyle):
(WebCore::RenderElement::adjustFlowThreadStateIncludingDescendants): This is an iterative DFS pre-order traversal so
we set the flow state first on containers.
* rendering/RenderElement.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::computedFlowThreadState):
(WebCore::RenderObject::initializeFlowThreadStateOnInsertion):
* rendering/RenderObject.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockcpp">trunk/Source/WebCore/rendering/RenderBlock.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementcpp">trunk/Source/WebCore/rendering/RenderElement.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementh">trunk/Source/WebCore/rendering/RenderElement.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderObjectcpp">trunk/Source/WebCore/rendering/RenderObject.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderObjecth">trunk/Source/WebCore/rendering/RenderObject.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208660 => 208661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-13 02:43:37 UTC (rev 208660)
+++ trunk/Source/WebCore/ChangeLog        2016-11-13 03:08:52 UTC (rev 208661)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2016-11-12  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        RenderObject::flowThreadState should follow containing block instead of parent.
+        https://bugs.webkit.org/show_bug.cgi?id=164629
+
+        Reviewed by Simon Fraser.
+
+        Currently every descendant of a region/multicolumn container is considered to be part of the
+        flowthread including out-of-flow renderers. They all have the InsideFlowThread flag set.
+        However since out-of-flow renderers are not really part of the flowthread layout context,
+        whenever the layout code actually checks for their flowthread containers, we return nullptr and
+        try to handle this seemingly defective state gracefully (that is, flag indicates &quot;inside the flow thread&quot; state,
+        but there's no flow tread container).

+        This patch fixes this confused state by setting the RenderObject::flowThreadState flag based on
+        the containing block's state instead of the parent's.
+
+        Not testable, since we seem to manage out-of-flow elements just fine even
+        when they have the InsideFlowThread flag set. 
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::styleDidChange):
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::setStyle):
+        (WebCore::RenderElement::adjustFlowThreadStateIncludingDescendants): This is an iterative DFS pre-order traversal so
+        we set the flow state first on containers.
+        * rendering/RenderElement.h:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::computedFlowThreadState):
+        (WebCore::RenderObject::initializeFlowThreadStateOnInsertion):
+        * rendering/RenderObject.h:
+
</ins><span class="cx"> 2016-11-12  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         document.currentScript should be null when running a script inside a shadow tree
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (208660 => 208661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlock.cpp        2016-11-13 02:43:37 UTC (rev 208660)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp        2016-11-13 03:08:52 UTC (rev 208661)
</span><span class="lines">@@ -427,7 +427,7 @@
</span><span class="cx">     RenderBox::styleDidChange(diff, oldStyle);
</span><span class="cx"> 
</span><span class="cx">     if (hadTransform != hasTransform())
</span><del>-        resetFlowThreadContainingBlockAndChildInfoIncludingDescendants();
</del><ins>+        adjustFlowThreadStateOnContainingBlockChangeIfNeeded();
</ins><span class="cx"> 
</span><span class="cx">     auto&amp; newStyle = style();
</span><span class="cx">     if (!isAnonymousBlock()) {
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (208660 => 208661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.cpp        2016-11-13 02:43:37 UTC (rev 208660)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp        2016-11-13 03:08:52 UTC (rev 208661)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> #include &quot;RenderChildIterator.h&quot;
</span><span class="cx"> #include &quot;RenderCounter.h&quot;
</span><span class="cx"> #include &quot;RenderDeprecatedFlexibleBox.h&quot;
</span><ins>+#include &quot;RenderDescendantIterator.h&quot;
</ins><span class="cx"> #include &quot;RenderFlexibleBox.h&quot;
</span><span class="cx"> #include &quot;RenderImage.h&quot;
</span><span class="cx"> #include &quot;RenderImageResourceStyleImage.h&quot;
</span><span class="lines">@@ -411,8 +412,8 @@
</span><span class="cx"> 
</span><span class="cx">     // Make sure we invalidate the containing block cache for flows when the contianing block context changes
</span><span class="cx">     // so that styleDidChange can safely use RenderBlock::locateFlowThreadContainingBlock()
</span><del>-    if (is&lt;RenderBlock&gt;(*this) &amp;&amp; oldStyle.position() != m_style.position())
-        downcast&lt;RenderBlock&gt;(*this).resetFlowThreadContainingBlockAndChildInfoIncludingDescendants();
</del><ins>+    if (oldStyle.position() != m_style.position())
+        adjustFlowThreadStateOnContainingBlockChangeIfNeeded();
</ins><span class="cx"> 
</span><span class="cx">     styleDidChange(diff, &amp;oldStyle);
</span><span class="cx"> 
</span><span class="lines">@@ -2185,6 +2186,21 @@
</span><span class="cx">     return (frame().settings().shouldRespectImageOrientation() &amp;&amp; is&lt;HTMLImageElement&gt;(element())) ? RespectImageOrientation : DoNotRespectImageOrientation;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RenderElement::adjustFlowThreadStateOnContainingBlockChangeIfNeeded()
+{
+    if (flowThreadState() == NotInsideFlowThread)
+        return;
+
+    // Invalidate the containing block caches.
+    if (is&lt;RenderBlock&gt;(*this))
+        downcast&lt;RenderBlock&gt;(*this).resetFlowThreadContainingBlockAndChildInfoIncludingDescendants();
+    
+    // Adjust the flow tread state on the subtree.
+    setFlowThreadState(RenderObject::computedFlowThreadState(*this));
+    for (auto&amp; descendant : descendantsOfType&lt;RenderObject&gt;(*this))
+        descendant.setFlowThreadState(RenderObject::computedFlowThreadState(descendant));
+}
+
</ins><span class="cx"> void RenderElement::removeFromRenderFlowThread()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(flowThreadState() != NotInsideFlowThread);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.h (208660 => 208661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.h        2016-11-13 02:43:37 UTC (rev 208660)
+++ trunk/Source/WebCore/rendering/RenderElement.h        2016-11-13 03:08:52 UTC (rev 208661)
</span><span class="lines">@@ -281,6 +281,7 @@
</span><span class="cx">     void updateOutlineAutoAncestor(bool hasOutlineAuto);
</span><span class="cx"> 
</span><span class="cx">     void removeFromRenderFlowThreadIncludingDescendants(bool shouldUpdateState);
</span><ins>+    void adjustFlowThreadStateOnContainingBlockChangeIfNeeded();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     RenderElement(ContainerNode&amp;, RenderStyle&amp;&amp;, BaseTypeFlags);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (208660 => 208661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderObject.cpp        2016-11-13 02:43:37 UTC (rev 208660)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp        2016-11-13 03:08:52 UTC (rev 208661)
</span><span class="lines">@@ -177,18 +177,36 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RenderObject::FlowThreadState RenderObject::computedFlowThreadState(const RenderObject&amp; renderer)
+{
+    if (!renderer.parent())
+        return renderer.flowThreadState();
+
+    auto inheritedFlowState = RenderObject::NotInsideFlowThread;
+    if (is&lt;RenderText&gt;(renderer))
+        inheritedFlowState = renderer.parent()-&gt;flowThreadState();
+    else if (auto* containingBlock = renderer.containingBlock())
+        inheritedFlowState = containingBlock-&gt;flowThreadState();
+    else {
+        // Splitting lines or doing continuation, so just keep the current state.
+        inheritedFlowState = renderer.flowThreadState();
+    }
+    return inheritedFlowState;
+}
+
</ins><span class="cx"> void RenderObject::initializeFlowThreadStateOnInsertion()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(parent());
</span><span class="cx"> 
</span><del>-    if (flowThreadState() == parent()-&gt;flowThreadState())
-        return;
-
</del><span class="cx">     // A RenderFlowThread is always considered to be inside itself, so it never has to change its state in response to parent changes.
</span><span class="cx">     if (isRenderFlowThread())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    setFlowThreadStateIncludingDescendants(parent()-&gt;flowThreadState());
</del><ins>+    auto computedState = computedFlowThreadState(*this);
+    if (flowThreadState() == computedState)
+        return;
+
+    setFlowThreadStateIncludingDescendants(computedState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RenderObject::resetFlowThreadStateOnRemoval()
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderObject.h (208660 => 208661)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderObject.h        2016-11-13 02:43:37 UTC (rev 208660)
+++ trunk/Source/WebCore/rendering/RenderObject.h        2016-11-13 03:08:52 UTC (rev 208661)
</span><span class="lines">@@ -820,6 +820,7 @@
</span><span class="cx"> 
</span><span class="cx">     void initializeFlowThreadStateOnInsertion();
</span><span class="cx">     void resetFlowThreadStateOnRemoval();
</span><ins>+    static FlowThreadState computedFlowThreadState(const RenderObject&amp;);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx"> #ifndef NDEBUG
</span></span></pre>
</div>
</div>

</body>
</html>