<!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>[191204] trunk</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/191204">191204</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2015-10-16 13:50:22 -0700 (Fri, 16 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Computed style should work correctly with slotted elements that have display:none
https://bugs.webkit.org/show_bug.cgi?id=150237

Reviewed by Andreas Kling.

Source/WebCore:

If an element has display:none we don't normally retain or even compute its style (as it is not rendered).
If getComputedStyle is invoked for such element we resolve the style (along with any ancestors) and cache
it separately to rare data. This path needs to work with slotted elements in shadow trees.

This patch also make computedStyle() iterative rather than recursive.

Test: fast/shadow-dom/computed-style-display-none.html

* dom/Document.cpp:
(WebCore::Document::styleForElementIgnoringPendingStylesheets):

    Pass in the parent style instead of invoking computedStyle() recursively.

* dom/Document.h:
* dom/Element.cpp:
(WebCore::beforeOrAfterPseudoElement):
(WebCore::Element::existingComputedStyle):
(WebCore::Element::resolveComputedStyle):

    Iterative resolve function that uses composed tree iterator.

(WebCore::Element::computedStyle):

    Factor into helpers.

* dom/Element.h:
* dom/Node.cpp:
(WebCore::Node::computedStyle):

    Use the composed tree iterator.

LayoutTests:

* editing/style/apply-style-atomic-expected.txt:

    Rebase.

* fast/css/getComputedStyle/getComputedStyle-with-pseudo-element-expected.txt:
* fast/css/getComputedStyle/getComputedStyle-with-pseudo-element.html:

    We now also compute style of display:none pseudo elements correctly.
    This is a progression and matches other browsers.

* fast/shadow-dom/computed-style-display-none-expected.txt: Added.
* fast/shadow-dom/computed-style-display-none.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestseditingstyleapplystyleatomicexpectedtxt">trunk/LayoutTests/editing/style/apply-style-atomic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcssgetComputedStylegetComputedStylewithpseudoelementexpectedtxt">trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcssgetComputedStylegetComputedStylewithpseudoelementhtml">trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</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="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCoredomNodecpp">trunk/Source/WebCore/dom/Node.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastshadowdomcomputedstyledisplaynoneexpectedtxt">trunk/LayoutTests/fast/shadow-dom/computed-style-display-none-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastshadowdomcomputedstyledisplaynonehtml">trunk/LayoutTests/fast/shadow-dom/computed-style-display-none.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/LayoutTests/ChangeLog        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2015-10-16  Antti Koivisto  &lt;antti@apple.com&gt;
+
+        Computed style should work correctly with slotted elements that have display:none
+        https://bugs.webkit.org/show_bug.cgi?id=150237
+
+        Reviewed by Andreas Kling.
+
+        * editing/style/apply-style-atomic-expected.txt:
+
+            Rebase.
+
+        * fast/css/getComputedStyle/getComputedStyle-with-pseudo-element-expected.txt:
+        * fast/css/getComputedStyle/getComputedStyle-with-pseudo-element.html:
+
+            We now also compute style of display:none pseudo elements correctly.
+            This is a progression and matches other browsers.
+
+        * fast/shadow-dom/computed-style-display-none-expected.txt: Added.
+        * fast/shadow-dom/computed-style-display-none.html: Added.
+
</ins><span class="cx"> 2015-10-16  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Update initial-letter results for iOS port.
</span></span></pre></div>
<a id="trunkLayoutTestseditingstyleapplystyleatomicexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/editing/style/apply-style-atomic-expected.txt (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/style/apply-style-atomic-expected.txt        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/LayoutTests/editing/style/apply-style-atomic-expected.txt        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -2,19 +2,18 @@
</span><span class="cx"> | &lt;a&gt;
</span><span class="cx"> |   href=&quot;a&quot;
</span><span class="cx"> |   &quot;&lt;#selection-anchor&gt;1&quot;
</span><del>-|   &lt;progress&gt;
-|     &lt;a&gt;
-|       style=&quot;&quot;
-|       &quot;2&quot;
-|     &lt;shadow:root&gt;
</del><ins>+| &lt;progress&gt;
+|   &lt;a&gt;
+|     style=&quot;&quot;
+|     &quot;2&quot;
+|   &lt;shadow:root&gt;
+|     &lt;div&gt;
+|       pseudo=&quot;-webkit-progress-inner-element&quot;
+|       shadow:pseudoId=&quot;-webkit-progress-inner-element&quot;
</ins><span class="cx"> |       &lt;div&gt;
</span><del>-|         pseudo=&quot;-webkit-progress-inner-element&quot;
-|         shadow:pseudoId=&quot;-webkit-progress-inner-element&quot;
</del><ins>+|         pseudo=&quot;-webkit-progress-bar&quot;
+|         shadow:pseudoId=&quot;-webkit-progress-bar&quot;
</ins><span class="cx"> |         &lt;div&gt;
</span><del>-|           pseudo=&quot;-webkit-progress-bar&quot;
-|           shadow:pseudoId=&quot;-webkit-progress-bar&quot;
-|           &lt;div&gt;
-|             pseudo=&quot;-webkit-progress-value&quot;
-|             style=&quot;width: -100%;&quot;
-|             shadow:pseudoId=&quot;-webkit-progress-value&quot;
-|   &lt;#selection-focus&gt;
</del><ins>+|           pseudo=&quot;-webkit-progress-value&quot;
+|           style=&quot;width: -100%;&quot;
+|           shadow:pseudoId=&quot;-webkit-progress-value&quot;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcssgetComputedStylegetComputedStylewithpseudoelementexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element-expected.txt (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element-expected.txt        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element-expected.txt        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -51,10 +51,10 @@
</span><span class="cx"> PASS Expected '0px' for padding in the computed style for element with id testBeforeAfterInline and pseudo-element :before and got '0px'
</span><span class="cx"> PASS Expected '0px' for margin in the computed style for element with id testBeforeAfterInline and pseudo-element :after and got '0px'
</span><span class="cx"> PASS Expected '10px 20px 30px 40px' for padding in the computed style for element with id testBeforeAfterInline and pseudo-element :after and got '10px 20px 30px 40px'
</span><del>-PASS Expected '' for width in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :after and got ''
-PASS Expected '' for height in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :after and got ''
-PASS Expected '' for width in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :before and got ''
-PASS Expected '' for height in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :before and got ''
</del><ins>+PASS Expected '100px' for width in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :after and got '100px'
+PASS Expected '100px' for height in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :after and got '100px'
+PASS Expected '100px' for width in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :before and got '100px'
+PASS Expected '100px' for height in the computed style for element with id testBeforeAfterDisplayNone and pseudo-element :before and got '100px'
</ins><span class="cx"> PASS Expected 'rgb(165, 42, 42)' for color in the computed style for element with id testNoPseudoElement and pseudo-element null and got 'rgb(165, 42, 42)'
</span><span class="cx"> PASS Expected 'rgb(165, 42, 42)' for color in the computed style for element with id testNoPseudoElement and pseudo-element :first-line and got 'rgb(165, 42, 42)'
</span><span class="cx"> PASS Expected 'rgb(165, 42, 42)' for color in the computed style for element with id testNoPseudoElement and pseudo-element :first-letter and got 'rgb(165, 42, 42)'
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssgetComputedStylegetComputedStylewithpseudoelementhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element.html (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element.html        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/LayoutTests/fast/css/getComputedStyle/getComputedStyle-with-pseudo-element.html        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -168,10 +168,10 @@
</span><span class="cx">         { 'elementId' : 'testBeforeAfterInline', 'pseudoElement' : ':before', 'property' : 'padding', 'expectedValue' : '0px' },
</span><span class="cx">         { 'elementId' : 'testBeforeAfterInline', 'pseudoElement' : ':after', 'property' : 'margin', 'expectedValue' : '0px' },
</span><span class="cx">         { 'elementId' : 'testBeforeAfterInline', 'pseudoElement' : ':after', 'property' : 'padding', 'expectedValue' : '10px 20px 30px 40px' },
</span><del>-        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':after', 'property' : 'width', 'expectedValue' : '' },
-        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':after', 'property' : 'height', 'expectedValue' : '' },
-        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':before', 'property' : 'width', 'expectedValue' : '' },
-        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':before', 'property' : 'height', 'expectedValue' : '' },
</del><ins>+        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':after', 'property' : 'width', 'expectedValue' : '100px' },
+        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':after', 'property' : 'height', 'expectedValue' : '100px' },
+        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':before', 'property' : 'width', 'expectedValue' : '100px' },
+        { 'elementId' : 'testBeforeAfterDisplayNone', 'pseudoElement' : ':before', 'property' : 'height', 'expectedValue' : '100px' },
</ins><span class="cx">         { 'elementId' : 'testNoPseudoElement', 'pseudoElement' : null, 'property' : 'color', 'expectedValue' : 'rgb(165, 42, 42)' },
</span><span class="cx">         { 'elementId' : 'testNoPseudoElement', 'pseudoElement' : ':first-line', 'property' : 'color', 'expectedValue' : 'rgb(165, 42, 42)' },
</span><span class="cx">         { 'elementId' : 'testNoPseudoElement', 'pseudoElement' : ':first-letter', 'property' : 'color', 'expectedValue' : 'rgb(165, 42, 42)' },
</span></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomcomputedstyledisplaynoneexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shadow-dom/computed-style-display-none-expected.txt (0 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/computed-style-display-none-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/computed-style-display-none-expected.txt        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Ensure tha slotted elements with display:none inherit their style via shadow tree
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS getComputedStyle(hostChild).color is &quot;rgb(0, 128, 0)&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomcomputedstyledisplaynonehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shadow-dom/computed-style-display-none.html (0 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/computed-style-display-none.html                                (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/computed-style-display-none.html        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;meta charset=&quot;utf-8&quot;&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;style&gt;
+my-host { display: none; color: red; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;my-host&gt;&lt;my-host-child&gt;&lt;/my-host-child&gt;&lt;/my-host&gt;
+&lt;script&gt;
+description(&quot;Ensure tha slotted elements with display:none inherit their style via shadow tree&quot;);
+
+var host = document.querySelector(&quot;my-host&quot;);
+var shadowRoot = host.attachShadow({ mode: &quot;closed&quot;});
+shadowRoot.innerHTML = &quot;&lt;style&gt;div { color: green }&lt;/style&gt;&lt;div&gt;&lt;slot&gt;&lt;/slot&gt;&lt;/div&gt;&quot;;
+
+hostChild = document.querySelector(&quot;my-host-child&quot;);
+shouldBeEqualToString(&quot;getComputedStyle(hostChild).color&quot;, &quot;rgb(0, 128, 0)&quot;);
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/Source/WebCore/ChangeLog        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -1,3 +1,41 @@
</span><ins>+2015-10-16  Antti Koivisto  &lt;antti@apple.com&gt;
+
+        Computed style should work correctly with slotted elements that have display:none
+        https://bugs.webkit.org/show_bug.cgi?id=150237
+
+        Reviewed by Andreas Kling.
+
+        If an element has display:none we don't normally retain or even compute its style (as it is not rendered).
+        If getComputedStyle is invoked for such element we resolve the style (along with any ancestors) and cache
+        it separately to rare data. This path needs to work with slotted elements in shadow trees.
+
+        This patch also make computedStyle() iterative rather than recursive.
+
+        Test: fast/shadow-dom/computed-style-display-none.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::styleForElementIgnoringPendingStylesheets):
+
+            Pass in the parent style instead of invoking computedStyle() recursively.
+
+        * dom/Document.h:
+        * dom/Element.cpp:
+        (WebCore::beforeOrAfterPseudoElement):
+        (WebCore::Element::existingComputedStyle):
+        (WebCore::Element::resolveComputedStyle):
+
+            Iterative resolve function that uses composed tree iterator.
+
+        (WebCore::Element::computedStyle):
+
+            Factor into helpers.
+
+        * dom/Element.h:
+        * dom/Node.cpp:
+        (WebCore::Node::computedStyle):
+
+            Use the composed tree iterator.
+
</ins><span class="cx"> 2015-10-16  David Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ASSERT in imported/blink/fast/block/float/overhanging-float-crashes-when-sibling-becomes-formatting-context.html
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/Source/WebCore/dom/Document.cpp        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -1954,15 +1954,15 @@
</span><span class="cx">     m_ignorePendingStylesheets = oldIgnore;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;RenderStyle&gt; Document::styleForElementIgnoringPendingStylesheets(Element* element)
</del><ins>+Ref&lt;RenderStyle&gt; Document::styleForElementIgnoringPendingStylesheets(Element&amp; element, RenderStyle* parentStyle)
</ins><span class="cx"> {
</span><del>-    ASSERT_ARG(element, &amp;element-&gt;document() == this);
</del><ins>+    ASSERT(&amp;element.document() == this);
</ins><span class="cx"> 
</span><span class="cx">     // On iOS request delegates called during styleForElement may result in re-entering WebKit and killing the style resolver.
</span><span class="cx">     ResourceLoadScheduler::Suspender suspender(*platformStrategies()-&gt;loaderStrategy()-&gt;resourceLoadScheduler());
</span><span class="cx"> 
</span><span class="cx">     TemporaryChange&lt;bool&gt; change(m_ignorePendingStylesheets, true);
</span><del>-    return ensureStyleResolver().styleForElement(element, element-&gt;parentNode() ? element-&gt;parentNode()-&gt;computedStyle() : nullptr);
</del><ins>+    return element.resolveStyle(parentStyle);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool Document::updateLayoutIfDimensionsOutOfDate(Element&amp; element, DimensionsCheck dimensionsCheck)
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/Source/WebCore/dom/Document.h        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -570,7 +570,7 @@
</span><span class="cx">     };
</span><span class="cx">     WEBCORE_EXPORT void updateLayoutIgnorePendingStylesheets(RunPostLayoutTasks = RunPostLayoutTasks::Asynchronously);
</span><span class="cx"> 
</span><del>-    Ref&lt;RenderStyle&gt; styleForElementIgnoringPendingStylesheets(Element*);
</del><ins>+    Ref&lt;RenderStyle&gt; styleForElementIgnoringPendingStylesheets(Element&amp;, RenderStyle* parentStyle);
</ins><span class="cx"> 
</span><span class="cx">     // Returns true if page box (margin boxes and page borders) is visible.
</span><span class="cx">     WEBCORE_EXPORT bool isPageBoxVisible(int pageIndex);
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/Source/WebCore/dom/Element.cpp        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;ChromeClient.h&quot;
</span><span class="cx"> #include &quot;ClientRect.h&quot;
</span><span class="cx"> #include &quot;ClientRectList.h&quot;
</span><ins>+#include &quot;ComposedTreeAncestorIterator.h&quot;
</ins><span class="cx"> #include &quot;ContainerNodeAlgorithms.h&quot;
</span><span class="cx"> #include &quot;DOMTokenList.h&quot;
</span><span class="cx"> #include &quot;Dictionary.h&quot;
</span><span class="lines">@@ -2434,44 +2435,79 @@
</span><span class="cx">     ensureElementRareData().setMinimumSizeForResizing(size);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static PseudoElement* beforeOrAfterPseudoElement(Element* host, PseudoId pseudoElementSpecifier)
</del><ins>+static PseudoElement* beforeOrAfterPseudoElement(Element&amp; host, PseudoId pseudoElementSpecifier)
</ins><span class="cx"> {
</span><span class="cx">     switch (pseudoElementSpecifier) {
</span><span class="cx">     case BEFORE:
</span><del>-        return host-&gt;beforePseudoElement();
</del><ins>+        return host.beforePseudoElement();
</ins><span class="cx">     case AFTER:
</span><del>-        return host-&gt;afterPseudoElement();
</del><ins>+        return host.afterPseudoElement();
</ins><span class="cx">     default:
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RenderStyle* Element::existingComputedStyle()
+{
+    if (RenderStyle* renderTreeStyle = renderStyle())
+        return renderTreeStyle;
+
+    if (hasRareData())
+        return elementRareData()-&gt;computedStyle();
+
+    return nullptr;
+}
+
+RenderStyle&amp; Element::resolveComputedStyle()
+{
+    ASSERT(inDocument());
+    ASSERT(!existingComputedStyle());
+
+    Deque&lt;Element*, 32&gt; elementsRequiringComputedStyle({ this });
+    RenderStyle* previousStyle = nullptr;
+
+    // Collect ancestors until we find one that has style.
+    auto composedAncestors = composedTreeAncestors(*this);
+    for (auto&amp; ancestor : composedAncestors) {
+        if (!is&lt;Element&gt;(ancestor))
+            break;
+        auto&amp; ancestorElement = downcast&lt;Element&gt;(ancestor);
+        elementsRequiringComputedStyle.prepend(&amp;ancestorElement);
+        if (auto* existingStyle = ancestorElement.existingComputedStyle()) {
+            previousStyle = existingStyle;
+            break;
+        }
+    }
+
+    // Resolve and cache styles starting from the most distant ancestor.
+    for (auto* element : elementsRequiringComputedStyle) {
+        auto style = document().styleForElementIgnoringPendingStylesheets(*element, previousStyle);
+        previousStyle = style.ptr();
+        ElementRareData&amp; rareData = element-&gt;ensureElementRareData();
+        rareData.setComputedStyle(WTF::move(style));
+    }
+
+    return *previousStyle;
+}
+
</ins><span class="cx"> RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
</span><span class="cx"> {
</span><del>-    if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(this, pseudoElementSpecifier))
</del><ins>+    if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(*this, pseudoElementSpecifier))
</ins><span class="cx">         return pseudoElement-&gt;computedStyle();
</span><span class="cx"> 
</span><del>-    // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
-    // properties, which are only known by the renderer because it did the layout, will be correct and so that the
-    // values returned for the &quot;:selection&quot; pseudo-element will be correct.
-    if (RenderStyle* usedStyle = renderStyle()) {
-        if (pseudoElementSpecifier) {
-            RenderStyle* cachedPseudoStyle = usedStyle-&gt;getCachedPseudoStyle(pseudoElementSpecifier);
-            return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
-        }
-        return usedStyle;
</del><ins>+    auto* style = existingComputedStyle();
+    if (!style) {
+        if (!inDocument())
+            return nullptr;
+        style = &amp;resolveComputedStyle();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!inDocument()) {
-        // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
-        // document tree and figure out when to destroy the computed style for such elements.
-        return nullptr;
</del><ins>+    if (pseudoElementSpecifier) {
+        if (auto* cachedPseudoStyle = style-&gt;getCachedPseudoStyle(pseudoElementSpecifier))
+            style = cachedPseudoStyle;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ElementRareData&amp; data = ensureElementRareData();
-    if (!data.computedStyle())
-        data.setComputedStyle(document().styleForElementIgnoringPendingStylesheets(this));
-    return pseudoElementSpecifier ? data.computedStyle()-&gt;getCachedPseudoStyle(pseudoElementSpecifier) : data.computedStyle();
</del><ins>+    return style;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Element::setStyleAffectedByEmpty()
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/Source/WebCore/dom/Element.h        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -573,6 +573,9 @@
</span><span class="cx"> 
</span><span class="cx">     void removeShadowRoot();
</span><span class="cx"> 
</span><ins>+    RenderStyle* existingComputedStyle();
+    RenderStyle&amp; resolveComputedStyle();
+
</ins><span class="cx">     bool rareDataStyleAffectedByEmpty() const;
</span><span class="cx">     bool rareDataChildrenAffectedByHover() const;
</span><span class="cx">     bool rareDataChildrenAffectedByActive() const;
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.cpp (191203 => 191204)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.cpp        2015-10-16 20:46:32 UTC (rev 191203)
+++ trunk/Source/WebCore/dom/Node.cpp        2015-10-16 20:50:22 UTC (rev 191204)
</span><span class="lines">@@ -1006,11 +1006,10 @@
</span><span class="cx"> 
</span><span class="cx"> RenderStyle* Node::computedStyle(PseudoId pseudoElementSpecifier)
</span><span class="cx"> {
</span><del>-    for (Node* node = this; node; node = node-&gt;parentOrShadowHostNode()) {
-        if (is&lt;Element&gt;(*node))
-            return downcast&lt;Element&gt;(*node).computedStyle(pseudoElementSpecifier);
-    }
-    return nullptr;
</del><ins>+    auto* composedParent = composedTreeAncestors(*this).first();
+    if (!composedParent)
+        return nullptr;
+    return composedParent-&gt;computedStyle(pseudoElementSpecifier);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> int Node::maxCharacterOffset() const
</span></span></pre>
</div>
</div>

</body>
</html>