<!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>[190983] 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/190983">190983</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2015-10-13 06:12:25 -0700 (Tue, 13 Oct 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Implement iterator for traversing composed DOM
https://bugs.webkit.org/show_bug.cgi?id=149997
Reviewed by Ryosuke Niwa.
Source/WebCore:
ComposedTreeIterator traverses the DOM in composed tree order. This means it enters
shadow trees and follows slots created by Shadow DOM API correctly.
auto children = composedTreeChildren(containerNode);
for (auto& composedChild : children)
...
auto descendants = composedTreeDescendants(containerNode);
for (auto& composedDescendant : descendants)
...
* WebCore.xcodeproj/project.pbxproj:
* dom/ComposedTreeIterator.cpp: Added.
(WebCore::ComposedTreeIterator::initializeShadowStack):
(WebCore::ComposedTreeIterator::traverseNextInShadowTree):
(WebCore::ComposedTreeIterator::traverseNextSiblingSlot):
(WebCore::ComposedTreeIterator::traversePreviousSiblingSlot):
(WebCore::ComposedTreeIterator::traverseParentInShadowTree):
* dom/ComposedTreeIterator.h: Added.
(WebCore::ComposedTreeIterator::operator*):
(WebCore::ComposedTreeIterator::operator->):
(WebCore::ComposedTreeIterator::operator==):
(WebCore::ComposedTreeIterator::operator!=):
(WebCore::ComposedTreeIterator::ShadowContext::ShadowContext):
(WebCore::ComposedTreeIterator::ComposedTreeIterator):
(WebCore::ComposedTreeIterator::traverseNext):
(WebCore::ComposedTreeIterator::traverseNextSibling):
(WebCore::ComposedTreeIterator::traversePreviousSibling):
(WebCore::ComposedTreeIterator::traverseParent):
(WebCore::ComposedTreeChildAdapter::Iterator::Iterator):
(WebCore::ComposedTreeChildAdapter::Iterator::operator++):
(WebCore::ComposedTreeChildAdapter::Iterator::operator--):
(WebCore::ComposedTreeChildAdapter::ComposedTreeChildAdapter):
(WebCore::ComposedTreeChildAdapter::begin):
(WebCore::ComposedTreeChildAdapter::end):
(WebCore::ComposedTreeChildAdapter::at):
(WebCore::composedTreeChildren):
* dom/NodeRenderingTraversal.cpp:
(WebCore::NodeRenderingTraversal::parentSlow):
(WebCore::NodeRenderingTraversal::nextInScope):
(WebCore::NodeRenderingTraversal::firstChildSlow): Deleted.
(WebCore::NodeRenderingTraversal::nextSiblingSlow): Deleted.
(WebCore::NodeRenderingTraversal::previousSiblingSlow): Deleted.
* dom/NodeRenderingTraversal.h:
(WebCore::NodeRenderingTraversal::parent):
(WebCore::NodeRenderingTraversal::firstChild): Deleted.
(WebCore::NodeRenderingTraversal::nextSibling): Deleted.
(WebCore::NodeRenderingTraversal::previousSibling): Deleted.
* style/RenderTreePosition.cpp:
(WebCore::RenderTreePosition::computeNextSibling):
Restore the full assert.
(WebCore::RenderTreePosition::invalidateNextSibling):
(WebCore::RenderTreePosition::previousSiblingRenderer):
(WebCore::RenderTreePosition::nextSiblingRenderer):
Make these member functions.
Use the iterator. This is fixes some bugs and allows enabling a test case.
* style/RenderTreePosition.h:
* style/StyleResolveTree.cpp:
(WebCore::Style::textRendererIsNeeded):
LayoutTests:
* TestExpectations:
Re-enable fast/html/details-replace-text.html which is fixed by this change.
* fast/forms/select-listbox-focus-displaynone-expected.txt:
* fast/repaint/text-in-relative-positioned-inline-expected.txt:
* fullscreen/full-screen-fixed-pos-parent-expected.txt:
* platform/mac-mavericks/fast/html/details-open2-expected.txt:
* platform/mac/fast/html/details-add-child-2-expected.txt:
* platform/mac/fast/html/details-open2-expected.txt:
Non-visual whitespace changes.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsfastformsselectlistboxfocusdisplaynoneexpectedtxt">trunk/LayoutTests/fast/forms/select-listbox-focus-displaynone-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastrepainttextinrelativepositionedinlineexpectedtxt">trunk/LayoutTests/fast/repaint/text-in-relative-positioned-inline-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfullscreenfullscreenfixedposparentexpectedtxt">trunk/LayoutTests/fullscreen/full-screen-fixed-pos-parent-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacfasthtmldetailsaddchild2expectedtxt">trunk/LayoutTests/platform/mac/fast/html/details-add-child-2-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacfasthtmldetailsopen2expectedtxt">trunk/LayoutTests/platform/mac/fast/html/details-open2-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacmavericksfasthtmldetailsopen2expectedtxt">trunk/LayoutTests/platform/mac-mavericks/fast/html/details-open2-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomDOMAllInOnecpp">trunk/Source/WebCore/dom/DOMAllInOne.cpp</a></li>
<li><a href="#trunkSourceWebCoredomNodeRenderingTraversalcpp">trunk/Source/WebCore/dom/NodeRenderingTraversal.cpp</a></li>
<li><a href="#trunkSourceWebCoredomNodeRenderingTraversalh">trunk/Source/WebCore/dom/NodeRenderingTraversal.h</a></li>
<li><a href="#trunkSourceWebCorestyleRenderTreePositioncpp">trunk/Source/WebCore/style/RenderTreePosition.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleRenderTreePositionh">trunk/Source/WebCore/style/RenderTreePosition.h</a></li>
<li><a href="#trunkSourceWebCorestyleStyleResolveTreecpp">trunk/Source/WebCore/style/StyleResolveTree.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoredomComposedTreeIteratorcpp">trunk/Source/WebCore/dom/ComposedTreeIterator.cpp</a></li>
<li><a href="#trunkSourceWebCoredomComposedTreeIteratorh">trunk/Source/WebCore/dom/ComposedTreeIterator.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/ChangeLog        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2015-10-12 Antti Koivisto <antti@apple.com>
+
+ Implement iterator for traversing composed DOM
+ https://bugs.webkit.org/show_bug.cgi?id=149997
+
+ Reviewed by Ryosuke Niwa.
+
+ * TestExpectations:
+
+ Re-enable fast/html/details-replace-text.html which is fixed by this change.
+
+ * fast/forms/select-listbox-focus-displaynone-expected.txt:
+ * fast/repaint/text-in-relative-positioned-inline-expected.txt:
+ * fullscreen/full-screen-fixed-pos-parent-expected.txt:
+ * platform/mac-mavericks/fast/html/details-open2-expected.txt:
+ * platform/mac/fast/html/details-add-child-2-expected.txt:
+ * platform/mac/fast/html/details-open2-expected.txt:
+
+ Non-visual whitespace changes.
+
</ins><span class="cx"> 2015-10-12 Zalan Bujtas <zalan@apple.com>
</span><span class="cx">
</span><span class="cx"> [Win] Update anonymous table results for Windows port.
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/TestExpectations        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -672,7 +672,6 @@
</span><span class="cx"> webkit.org/b/149082 http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-overridesexpires.html [ Pass Failure ]
</span><span class="cx">
</span><span class="cx"> webkit.org/b/148695 fast/shadow-dom [ Failure ImageOnlyFailure ]
</span><del>-webkit.org/b/149997 fast/html/details-replace-text.html [ Failure ]
</del><span class="cx">
</span><span class="cx"> # Marks as flaky (see also https://bugs.webkit.org/show_bug.cgi?id=132388)
</span><span class="cx">
</span></span></pre></div>
<a id="trunkLayoutTestsfastformsselectlistboxfocusdisplaynoneexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/forms/select-listbox-focus-displaynone-expected.txt (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/forms/select-listbox-focus-displaynone-expected.txt        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/fast/forms/select-listbox-focus-displaynone-expected.txt        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -1 +1 @@
</span><del>- PASS
</del><ins>+ PASS
</ins></span></pre></div>
<a id="trunkLayoutTestsfastrepainttextinrelativepositionedinlineexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/repaint/text-in-relative-positioned-inline-expected.txt (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/repaint/text-in-relative-positioned-inline-expected.txt        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/fast/repaint/text-in-relative-positioned-inline-expected.txt        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -4,5 +4,4 @@
</span><span class="cx"> RenderBlock {HTML} at (0,0) size 800x600
</span><span class="cx"> RenderBody {BODY} at (8,8) size 784x584
</span><span class="cx"> RenderBlock {DIV} at (100,0) size 684x100
</span><del>- RenderText {#text} at (0,0) size 0x0
</del><span class="cx"> RenderBlock {DIV} at (0,0) size 100x100 [bgcolor=#008000]
</span></span></pre></div>
<a id="trunkLayoutTestsfullscreenfullscreenfixedposparentexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fullscreen/full-screen-fixed-pos-parent-expected.txt (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fullscreen/full-screen-fixed-pos-parent-expected.txt        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/fullscreen/full-screen-fixed-pos-parent-expected.txt        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -1,2 +1 @@
</span><span class="cx">
</span><del>-
</del></span></pre></div>
<a id="trunkLayoutTestsplatformmacfasthtmldetailsaddchild2expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/html/details-add-child-2-expected.txt (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/html/details-add-child-2-expected.txt        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/platform/mac/fast/html/details-add-child-2-expected.txt        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -12,3 +12,5 @@
</span><span class="cx"> RenderInline {B} at (0,0) size 144x18
</span><span class="cx"> RenderText {#text} at (0,0) size 144x18
</span><span class="cx"> text run at (0,0) width 144: "should have bold test"
</span><ins>+ RenderText {#text} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 0x0
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacfasthtmldetailsopen2expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/html/details-open2-expected.txt (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/html/details-open2-expected.txt        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/platform/mac/fast/html/details-open2-expected.txt        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -10,5 +10,7 @@
</span><span class="cx"> text run at (16,0) width 61: "summary"
</span><span class="cx"> RenderBlock (anonymous) at (0,18) size 784x23
</span><span class="cx"> RenderTextControl {INPUT} at (2,2) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
</span><ins>+ RenderText {#text} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 0x0
</ins><span class="cx"> layer at (13,31) size 130x13
</span><span class="cx"> RenderBlock {DIV} at (3,3) size 131x13
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacmavericksfasthtmldetailsopen2expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-mavericks/fast/html/details-open2-expected.txt (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-mavericks/fast/html/details-open2-expected.txt        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/platform/mac-mavericks/fast/html/details-open2-expected.txt        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -10,5 +10,7 @@
</span><span class="cx"> text run at (16,0) width 61: "summary"
</span><span class="cx"> RenderBlock (anonymous) at (0,18) size 784x23
</span><span class="cx"> RenderTextControl {INPUT} at (2,2) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
</span><ins>+ RenderText {#text} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 0x0
</ins><span class="cx"> layer at (13,31) size 139x13
</span><span class="cx"> RenderBlock {DIV} at (3,3) size 140x13
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/CMakeLists.txt        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -1412,6 +1412,7 @@
</span><span class="cx"> dom/ClipboardEvent.cpp
</span><span class="cx"> dom/CollectionIndexCache.cpp
</span><span class="cx"> dom/Comment.cpp
</span><ins>+ dom/ComposedTreeIterator.cpp
</ins><span class="cx"> dom/CompositionEvent.cpp
</span><span class="cx"> dom/ContainerNode.cpp
</span><span class="cx"> dom/ContainerNodeAlgorithms.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/ChangeLog        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -1,3 +1,74 @@
</span><ins>+2015-10-12 Antti Koivisto <antti@apple.com>
+
+ Implement iterator for traversing composed DOM
+ https://bugs.webkit.org/show_bug.cgi?id=149997
+
+ Reviewed by Ryosuke Niwa.
+
+ ComposedTreeIterator traverses the DOM in composed tree order. This means it enters
+ shadow trees and follows slots created by Shadow DOM API correctly.
+
+ auto children = composedTreeChildren(containerNode);
+ for (auto& composedChild : children)
+ ...
+
+ auto descendants = composedTreeDescendants(containerNode);
+ for (auto& composedDescendant : descendants)
+ ...
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/ComposedTreeIterator.cpp: Added.
+ (WebCore::ComposedTreeIterator::initializeShadowStack):
+ (WebCore::ComposedTreeIterator::traverseNextInShadowTree):
+ (WebCore::ComposedTreeIterator::traverseNextSiblingSlot):
+ (WebCore::ComposedTreeIterator::traversePreviousSiblingSlot):
+ (WebCore::ComposedTreeIterator::traverseParentInShadowTree):
+ * dom/ComposedTreeIterator.h: Added.
+ (WebCore::ComposedTreeIterator::operator*):
+ (WebCore::ComposedTreeIterator::operator->):
+ (WebCore::ComposedTreeIterator::operator==):
+ (WebCore::ComposedTreeIterator::operator!=):
+ (WebCore::ComposedTreeIterator::ShadowContext::ShadowContext):
+ (WebCore::ComposedTreeIterator::ComposedTreeIterator):
+ (WebCore::ComposedTreeIterator::traverseNext):
+ (WebCore::ComposedTreeIterator::traverseNextSibling):
+ (WebCore::ComposedTreeIterator::traversePreviousSibling):
+ (WebCore::ComposedTreeIterator::traverseParent):
+ (WebCore::ComposedTreeChildAdapter::Iterator::Iterator):
+ (WebCore::ComposedTreeChildAdapter::Iterator::operator++):
+ (WebCore::ComposedTreeChildAdapter::Iterator::operator--):
+ (WebCore::ComposedTreeChildAdapter::ComposedTreeChildAdapter):
+ (WebCore::ComposedTreeChildAdapter::begin):
+ (WebCore::ComposedTreeChildAdapter::end):
+ (WebCore::ComposedTreeChildAdapter::at):
+ (WebCore::composedTreeChildren):
+ * dom/NodeRenderingTraversal.cpp:
+ (WebCore::NodeRenderingTraversal::parentSlow):
+ (WebCore::NodeRenderingTraversal::nextInScope):
+ (WebCore::NodeRenderingTraversal::firstChildSlow): Deleted.
+ (WebCore::NodeRenderingTraversal::nextSiblingSlow): Deleted.
+ (WebCore::NodeRenderingTraversal::previousSiblingSlow): Deleted.
+ * dom/NodeRenderingTraversal.h:
+ (WebCore::NodeRenderingTraversal::parent):
+ (WebCore::NodeRenderingTraversal::firstChild): Deleted.
+ (WebCore::NodeRenderingTraversal::nextSibling): Deleted.
+ (WebCore::NodeRenderingTraversal::previousSibling): Deleted.
+ * style/RenderTreePosition.cpp:
+ (WebCore::RenderTreePosition::computeNextSibling):
+
+ Restore the full assert.
+
+ (WebCore::RenderTreePosition::invalidateNextSibling):
+ (WebCore::RenderTreePosition::previousSiblingRenderer):
+ (WebCore::RenderTreePosition::nextSiblingRenderer):
+
+ Make these member functions.
+ Use the iterator. This is fixes some bugs and allows enabling a test case.
+
+ * style/RenderTreePosition.h:
+ * style/StyleResolveTree.cpp:
+ (WebCore::Style::textRendererIsNeeded):
+
</ins><span class="cx"> 2015-10-13 ChangSeok Oh <changseok.oh@collabora.com>
</span><span class="cx">
</span><span class="cx"> [GTK] Use GUniquePtr for GtkIconInfo
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-<?xml version="1.0" encoding="utf-8"?>
</del><ins>+<?xml version="1.0" encoding="utf-8"?>
</ins><span class="cx"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</span><span class="cx"> <ItemGroup Label="ProjectConfigurations">
</span><span class="cx"> <ProjectConfiguration Include="DebugSuffix|Win32">
</span><span class="lines">@@ -13705,6 +13705,20 @@
</span><span class="cx"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
</span><span class="cx"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
</span><span class="cx"> </ClCompile>
</span><ins>+ <ClCompile Include="..\dom\ComposedTreeIterator.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
+ </ClCompile>
</ins><span class="cx"> <ClCompile Include="..\dom\CompositionEvent.cpp">
</span><span class="cx"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</span><span class="cx"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</span><span class="lines">@@ -21949,6 +21963,7 @@
</span><span class="cx"> <ClInclude Include="..\dom\ClipboardEvent.h" />
</span><span class="cx"> <ClInclude Include="..\dom\CollectionIndexCache.h" />
</span><span class="cx"> <ClInclude Include="..\dom\Comment.h" />
</span><ins>+ <ClInclude Include="..\dom\ComposedTreeIterator.h" />
</ins><span class="cx"> <ClInclude Include="..\dom\CompositionEvent.h" />
</span><span class="cx"> <ClInclude Include="..\dom\ContainerNode.h" />
</span><span class="cx"> <ClInclude Include="..\dom\ContextDestructionObserver.h" />
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -6422,6 +6422,8 @@
</span><span class="cx">                 E44B4BB3141650D7002B1D8B /* SelectorChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44B4BB1141650D7002B1D8B /* SelectorChecker.cpp */; };
</span><span class="cx">                 E44B4BB4141650D7002B1D8B /* SelectorChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = E44B4BB2141650D7002B1D8B /* SelectorChecker.h */; };
</span><span class="cx">                 E44EE3A817577EBD00EEE8CF /* FontGenericFamilies.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44EE3A617576E5500EEE8CF /* FontGenericFamilies.cpp */; };
</span><ins>+                E44FA1851BCA6B5A0091B6EF /* ComposedTreeIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E44FA1841BCA6B5A0091B6EF /* ComposedTreeIterator.h */; settings = {ASSET_TAGS = (); }; };
+                E44FA1871BCA91560091B6EF /* ComposedTreeIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44FA1861BCA91560091B6EF /* ComposedTreeIterator.cpp */; settings = {ASSET_TAGS = (); }; };
</ins><span class="cx">                 E45322AB140CE267005A0F92 /* SelectorQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45322A9140CE267005A0F92 /* SelectorQuery.cpp */; };
</span><span class="cx">                 E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = E45322AA140CE267005A0F92 /* SelectorQuery.h */; };
</span><span class="cx">                 E453901D0EAFCACA003695C8 /* MIMETypeRegistryIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = E45390180EAFCACA003695C8 /* MIMETypeRegistryIOS.mm */; };
</span><span class="lines">@@ -14240,6 +14242,8 @@
</span><span class="cx">                 E44B4BB2141650D7002B1D8B /* SelectorChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorChecker.h; sourceTree = "<group>"; };
</span><span class="cx">                 E44EE3A617576E5500EEE8CF /* FontGenericFamilies.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FontGenericFamilies.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 E44EE3A717576E5500EEE8CF /* FontGenericFamilies.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontGenericFamilies.h; sourceTree = "<group>"; };
</span><ins>+                E44FA1841BCA6B5A0091B6EF /* ComposedTreeIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComposedTreeIterator.h; sourceTree = "<group>"; };
+                E44FA1861BCA91560091B6EF /* ComposedTreeIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComposedTreeIterator.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 E45322A9140CE267005A0F92 /* SelectorQuery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectorQuery.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 E45322AA140CE267005A0F92 /* SelectorQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorQuery.h; sourceTree = "<group>"; };
</span><span class="cx">                 E45390180EAFCACA003695C8 /* MIMETypeRegistryIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MIMETypeRegistryIOS.mm; sourceTree = "<group>"; };
</span><span class="lines">@@ -23525,6 +23529,8 @@
</span><span class="cx">                                 6550B697099DF0270090D781 /* Comment.cpp */,
</span><span class="cx">                                 6550B698099DF0270090D781 /* Comment.h */,
</span><span class="cx">                                 85089CC70A98C22600A275AA /* Comment.idl */,
</span><ins>+                                E44FA1861BCA91560091B6EF /* ComposedTreeIterator.cpp */,
+                                E44FA1841BCA6B5A0091B6EF /* ComposedTreeIterator.h */,
</ins><span class="cx">                                 79F2F59E1091939A000D87CB /* CompositionEvent.cpp */,
</span><span class="cx">                                 79F2F59F1091939A000D87CB /* CompositionEvent.h */,
</span><span class="cx">                                 79F2F5A01091939A000D87CB /* CompositionEvent.idl */,
</span><span class="lines">@@ -26123,6 +26129,7 @@
</span><span class="cx">                                 B27B28260CEF0C0700D39D54 /* JSSVGFontElement.h in Headers */,
</span><span class="cx">                                 A83B79050CCAFF15000B0825 /* JSSVGFontFaceElement.h in Headers */,
</span><span class="cx">                                 A83B79000CCAFF15000B0825 /* JSSVGFontFaceFormatElement.h in Headers */,
</span><ins>+                                E44FA1851BCA6B5A0091B6EF /* ComposedTreeIterator.h in Headers */,
</ins><span class="cx">                                 A83B79020CCAFF15000B0825 /* JSSVGFontFaceNameElement.h in Headers */,
</span><span class="cx">                                 A83B78FE0CCAFF15000B0825 /* JSSVGFontFaceSrcElement.h in Headers */,
</span><span class="cx">                                 A83B78FC0CCAFF15000B0825 /* JSSVGFontFaceUriElement.h in Headers */,
</span><span class="lines">@@ -29980,6 +29987,7 @@
</span><span class="cx">                                 517A63C41B74318B00E7DCDC /* KeyedEncoderCF.cpp in Sources */,
</span><span class="cx">                                 A513B3D8114B166A001C429B /* KeyEventCocoa.mm in Sources */,
</span><span class="cx">                                 2655413A1489811C000DFC5D /* KeyEventIOS.mm in Sources */,
</span><ins>+                                E44FA1871BCA91560091B6EF /* ComposedTreeIterator.cpp in Sources */,
</ins><span class="cx">                                 935C477009AC4D7300A6AAB4 /* KeyEventMac.mm in Sources */,
</span><span class="cx">                                 316FE1190E6E1DA700BF6088 /* KeyframeAnimation.cpp in Sources */,
</span><span class="cx">                                 BC5EBA100E823E4700B25965 /* KeyframeList.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoredomComposedTreeIteratorcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/dom/ComposedTreeIterator.cpp (0 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ComposedTreeIterator.cpp         (rev 0)
+++ trunk/Source/WebCore/dom/ComposedTreeIterator.cpp        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -0,0 +1,192 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ComposedTreeIterator.h"
+
+#include "HTMLSlotElement.h"
+
+namespace WebCore {
+
+void ComposedTreeIterator::initializeShadowStack()
+{
+ // This code sets up the iterator for arbitrary node/root pair. It is not needed in common cases
+ // or completes fast because node and root are close (like in composedTreeChildren(*parent).at(node) case).
+ auto* node = m_current;
+ while (node != &m_root) {
+ auto* parent = node->parentNode();
+ if (!parent) {
+ m_current = nullptr;
+ return;
+ }
+ if (is<ShadowRoot>(*parent)) {
+ auto& shadowRoot = downcast<ShadowRoot>(*parent);
+ if (m_shadowStack.isEmpty() || m_shadowStack.last().host != shadowRoot.host())
+ m_shadowStack.append(shadowRoot.host());
+ node = shadowRoot.host();
+ continue;
+ }
+ if (auto* shadowRoot = parent->shadowRoot()) {
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ m_shadowStack.append(shadowRoot->host());
+ auto* assignedSlot = shadowRoot->findAssignedSlot(*node);
+ if (assignedSlot) {
+ size_t index = assignedSlot->assignedNodes()->find(node);
+ ASSERT(index != notFound);
+
+ m_shadowStack.last().currentSlot = assignedSlot;
+ m_shadowStack.last().currentSlotNodeIndex = index;
+ node = assignedSlot;
+ continue;
+ }
+ // The node is not part of the composed tree.
+#else
+ m_current = nullptr;
+ return;
+#endif
+ }
+ node = parent;
+ }
+ m_shadowStack.reverse();
+}
+
+void ComposedTreeIterator::traverseNextInShadowTree()
+{
+ ASSERT(!m_shadowStack.isEmpty());
+
+ auto* shadowContext = &m_shadowStack.last();
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ if (is<HTMLSlotElement>(*m_current) && !shadowContext->currentSlot) {
+ auto& slot = downcast<HTMLSlotElement>(*m_current);
+ if (auto* assignedNodes = slot.assignedNodes()) {
+ shadowContext->currentSlot = &slot;
+ shadowContext->currentSlotNodeIndex = 0;
+ m_current = assignedNodes->at(0);
+ return;
+ }
+ }
+#endif
+
+ m_current = NodeTraversal::next(*m_current, shadowContext->host);
+
+ while (!m_current) {
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ if (auto* slot = shadowContext->currentSlot) {
+ bool nextNodeInSameSlot = ++shadowContext->currentSlotNodeIndex < slot->assignedNodes()->size();
+ if (nextNodeInSameSlot) {
+ m_current = slot->assignedNodes()->at(shadowContext->currentSlotNodeIndex);
+ return;
+ }
+ m_current = NodeTraversal::nextSkippingChildren(*slot, shadowContext->host);
+ shadowContext->currentSlot = nullptr;
+ continue;
+ }
+#endif
+ auto& previousHost = *shadowContext->host;
+ m_shadowStack.removeLast();
+
+ if (m_shadowStack.isEmpty()) {
+ m_current = NodeTraversal::nextSkippingChildren(previousHost, &m_root);
+ return;
+ }
+ shadowContext = &m_shadowStack.last();
+ m_current = NodeTraversal::nextSkippingChildren(previousHost, shadowContext->host);
+ }
+}
+
+void ComposedTreeIterator::traverseParentInShadowTree()
+{
+ ASSERT(!m_shadowStack.isEmpty());
+
+ auto& shadowContext = m_shadowStack.last();
+
+ auto* parent = m_current->parentNode();
+ if (is<ShadowRoot>(parent)) {
+ ASSERT(shadowContext.host == downcast<ShadowRoot>(*parent).host());
+
+ m_current = shadowContext.host;
+ m_shadowStack.removeLast();
+ return;
+ }
+ if (parent->shadowRoot()) {
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ ASSERT(shadowContext.host == parent);
+
+ auto* slot = shadowContext.currentSlot;
+ ASSERT(slot->assignedNodes()->at(shadowContext.currentSlotNodeIndex) == m_current);
+
+ m_current = slot;
+ shadowContext.currentSlot = nullptr;
+ return;
+#else
+ m_current = nullptr;
+ return;
+#endif
+ }
+ m_current = parent;
+}
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+void ComposedTreeIterator::traverseNextSiblingSlot()
+{
+ ASSERT(m_current->parentNode()->shadowRoot());
+ ASSERT(!m_shadowStack.isEmpty());
+ ASSERT(m_shadowStack.last().host == m_current->parentNode());
+
+ auto& shadowContext = m_shadowStack.last();
+
+ if (!shadowContext.currentSlot) {
+ m_current = nullptr;
+ return;
+ }
+ auto* slotNodes = shadowContext.currentSlot->assignedNodes();
+ ASSERT(slotNodes->at(shadowContext.currentSlotNodeIndex) == m_current);
+
+ bool nextNodeInSameSlot = ++shadowContext.currentSlotNodeIndex < slotNodes->size();
+ m_current = nextNodeInSameSlot ? slotNodes->at(shadowContext.currentSlotNodeIndex) : nullptr;
+}
+
+void ComposedTreeIterator::traversePreviousSiblingSlot()
+{
+ ASSERT(m_current->parentNode()->shadowRoot());
+ ASSERT(!m_shadowStack.isEmpty());
+ ASSERT(m_shadowStack.last().host == m_current->parentNode());
+
+ auto& shadowContext = m_shadowStack.last();
+
+ if (!shadowContext.currentSlot) {
+ m_current = nullptr;
+ return;
+ }
+ auto* slotNodes = shadowContext.currentSlot->assignedNodes();
+ ASSERT(slotNodes->at(shadowContext.currentSlotNodeIndex) == m_current);
+
+ bool previousNodeInSameSlot = shadowContext.currentSlotNodeIndex > 0;
+ m_current = previousNodeInSameSlot ? slotNodes->at(--shadowContext.currentSlotNodeIndex) : nullptr;
+}
+#endif
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoredomComposedTreeIteratorh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/dom/ComposedTreeIterator.h (0 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ComposedTreeIterator.h         (rev 0)
+++ trunk/Source/WebCore/dom/ComposedTreeIterator.h        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -0,0 +1,204 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "HTMLSlotElement.h"
+#include "NodeTraversal.h"
+#include "ShadowRoot.h"
+
+#ifndef ComposedTreeIterator_h
+#define ComposedTreeIterator_h
+
+namespace WebCore {
+
+class HTMLSlotElement;
+
+class ComposedTreeIterator {
+public:
+ ComposedTreeIterator(ContainerNode& root);
+ ComposedTreeIterator(ContainerNode& root, Node& current);
+
+ Node& operator*() { return *m_current; }
+ Node* operator->() { return m_current; }
+
+ bool operator==(const ComposedTreeIterator& other) const { return m_current == other.m_current; }
+ bool operator!=(const ComposedTreeIterator& other) const { return m_current != other.m_current; }
+
+ ComposedTreeIterator& operator++() { return traverseNextSibling(); }
+
+ ComposedTreeIterator& traverseNext();
+ ComposedTreeIterator& traverseNextSibling();
+ ComposedTreeIterator& traversePreviousSibling();
+ ComposedTreeIterator& traverseParent();
+
+private:
+ void initializeShadowStack();
+ void traverseNextInShadowTree();
+ void traverseParentInShadowTree();
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ void traverseNextSiblingSlot();
+ void traversePreviousSiblingSlot();
+#endif
+
+ ContainerNode& m_root;
+ Node* m_current { 0 };
+
+ struct ShadowContext {
+ ShadowContext(Element* host)
+ : host(host)
+ { }
+
+ Element* host;
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ HTMLSlotElement* currentSlot { nullptr };
+ unsigned currentSlotNodeIndex { 0 };
+#endif
+ };
+ Vector<ShadowContext, 4> m_shadowStack;
+};
+
+inline ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root)
+ : m_root(root)
+{
+ ASSERT(!is<ShadowRoot>(m_root));
+}
+
+inline ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root, Node& current)
+ : m_root(root)
+ , m_current(&current)
+{
+ ASSERT(!is<ShadowRoot>(m_root));
+ ASSERT(!is<ShadowRoot>(m_current));
+
+ bool mayNeedShadowStack = m_root.shadowRoot() || (m_current != &m_root && current.parentNode() != &m_root);
+ if (mayNeedShadowStack)
+ initializeShadowStack();
+}
+
+inline ComposedTreeIterator& ComposedTreeIterator::traverseNext()
+{
+ if (auto* shadowRoot = m_current->shadowRoot()) {
+ m_shadowStack.append(shadowRoot->host());
+ m_current = shadowRoot;
+ }
+
+ if (m_shadowStack.isEmpty())
+ m_current = NodeTraversal::next(*m_current, &m_root);
+ else
+ traverseNextInShadowTree();
+
+ return *this;
+}
+
+inline ComposedTreeIterator& ComposedTreeIterator::traverseNextSibling()
+{
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ bool isAssignedToSlot = !m_shadowStack.isEmpty() && m_current->parentNode()->shadowRoot();
+ if (isAssignedToSlot) {
+ traverseNextSiblingSlot();
+ return *this;
+ }
+#endif
+ m_current = m_current->nextSibling();
+ return *this;
+}
+
+inline ComposedTreeIterator& ComposedTreeIterator::traversePreviousSibling()
+{
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ bool isAssignedToSlot = !m_shadowStack.isEmpty() && m_current->parentNode()->shadowRoot();
+ if (isAssignedToSlot) {
+ traversePreviousSiblingSlot();
+ return *this;
+ }
+#endif
+ m_current = m_current->previousSibling();
+ return *this;
+}
+
+inline ComposedTreeIterator& ComposedTreeIterator::traverseParent()
+{
+ if (m_shadowStack.isEmpty())
+ m_current = m_current->parentNode();
+ else
+ traverseParentInShadowTree();
+
+ return *this;
+}
+
+class ComposedTreeDescendantAdapter {
+public:
+ ComposedTreeDescendantAdapter(ContainerNode& parent)
+ : m_parent(parent)
+ { }
+
+ ComposedTreeIterator begin() { return ComposedTreeIterator(m_parent, m_parent).traverseNext(); }
+ ComposedTreeIterator end() { return ComposedTreeIterator(m_parent); }
+ ComposedTreeIterator at(const Node& child) { return ComposedTreeIterator(m_parent, const_cast<Node&>(child)); }
+
+private:
+ ContainerNode& m_parent;
+};
+
+class ComposedTreeChildAdapter {
+public:
+ class Iterator : public ComposedTreeIterator {
+ public:
+ Iterator(ContainerNode& root)
+ : ComposedTreeIterator(root)
+ { }
+ Iterator(ContainerNode& root, Node& current)
+ : ComposedTreeIterator(root, current)
+ { }
+
+ Iterator& operator++() { return static_cast<Iterator&>(traverseNextSibling()); }
+ Iterator& operator--() { return static_cast<Iterator&>(traversePreviousSibling()); }
+ };
+
+ ComposedTreeChildAdapter(ContainerNode& parent)
+ : m_parent(parent)
+ { }
+
+ Iterator begin() { return static_cast<Iterator&>(Iterator(m_parent, m_parent).traverseNext()); }
+ Iterator end() { return Iterator(m_parent); }
+ Iterator at(const Node& child) { return Iterator(m_parent, const_cast<Node&>(child)); }
+
+private:
+ ContainerNode& m_parent;
+};
+
+// FIXME: We should have const versions too.
+inline ComposedTreeDescendantAdapter composedTreeDescendants(ContainerNode& parent)
+{
+ return ComposedTreeDescendantAdapter(parent);
+}
+
+inline ComposedTreeChildAdapter composedTreeChildren(ContainerNode& parent)
+{
+ return ComposedTreeChildAdapter(parent);
+}
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoredomDOMAllInOnecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/DOMAllInOne.cpp (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/DOMAllInOne.cpp        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/dom/DOMAllInOne.cpp        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> #include "ClipboardEvent.cpp"
</span><span class="cx"> #include "CollectionIndexCache.cpp"
</span><span class="cx"> #include "Comment.cpp"
</span><ins>+#include "ComposedTreeIterator.cpp"
</ins><span class="cx"> #include "CompositionEvent.cpp"
</span><span class="cx"> #include "ContainerNode.cpp"
</span><span class="cx"> #include "ContainerNodeAlgorithms.cpp"
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeRenderingTraversalcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/NodeRenderingTraversal.cpp (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/NodeRenderingTraversal.cpp        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/dom/NodeRenderingTraversal.cpp        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -95,27 +95,6 @@
</span><span class="cx"> return traverseParent(node, CrossShadowRoot);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-Node* firstChildSlow(const Node* node)
-{
- ASSERT(!node->isShadowRoot());
-
- return traverseFirstChild(node, DontCrossShadowRoot);
-}
-
-Node* nextSiblingSlow(const Node* node)
-{
- ASSERT(!node->isShadowRoot());
-
- return traverseNextSibling(node);
-}
-
-Node* previousSiblingSlow(const Node* node)
-{
- ASSERT(!node->isShadowRoot());
-
- return traversePreviousSibling(node);
-}
-
</del><span class="cx"> Node* nextInScope(const Node* node)
</span><span class="cx"> {
</span><span class="cx"> if (Node* next = traverseFirstChild(node, DontCrossShadowRoot))
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeRenderingTraversalh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/NodeRenderingTraversal.h (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/NodeRenderingTraversal.h        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/dom/NodeRenderingTraversal.h        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -35,9 +35,6 @@
</span><span class="cx"> namespace NodeRenderingTraversal {
</span><span class="cx">
</span><span class="cx"> ContainerNode* parent(const Node*);
</span><del>-Node* firstChild(const Node*);
-Node* nextSibling(const Node*);
-Node* previousSibling(const Node*);
</del><span class="cx">
</span><span class="cx"> Node* nextInScope(const Node*);
</span><span class="cx"> Node* previousInScope(const Node*);
</span><span class="lines">@@ -45,9 +42,6 @@
</span><span class="cx"> Node* lastChildInScope(const Node*);
</span><span class="cx">
</span><span class="cx"> ContainerNode* parentSlow(const Node*);
</span><del>-Node* firstChildSlow(const Node*);
-Node* nextSiblingSlow(const Node*);
-Node* previousSiblingSlow(const Node*);
</del><span class="cx">
</span><span class="cx"> inline ContainerNode* parent(const Node* node)
</span><span class="cx"> {
</span><span class="lines">@@ -59,38 +53,8 @@
</span><span class="cx"> return node->parentNodeGuaranteedHostFree();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline Node* firstChild(const Node* node)
-{
- ASSERT(!node->isPseudoElement());
- if (node->needsNodeRenderingTraversalSlowPath())
- return firstChildSlow(node);
-
- ASSERT(nextSiblingSlow(node) == node->nextSibling());
- return node->firstChild();
</del><span class="cx"> }
</span><span class="cx">
</span><del>-inline Node* nextSibling(const Node* node)
-{
- ASSERT(!node->isPseudoElement());
- if (node->needsNodeRenderingTraversalSlowPath())
- return nextSiblingSlow(node);
-
- ASSERT(nextSiblingSlow(node) == node->nextSibling());
- return node->nextSibling();
-}
-
-inline Node* previousSibling(const Node* node)
-{
- ASSERT(!node->isPseudoElement());
- if (node->needsNodeRenderingTraversalSlowPath())
- return previousSiblingSlow(node);
-
- ASSERT(previousSiblingSlow(node) == node->previousSibling());
- return node->previousSibling();
-}
-
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorestyleRenderTreePositioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/RenderTreePosition.cpp (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/RenderTreePosition.cpp        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/style/RenderTreePosition.cpp        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "RenderTreePosition.h"
</span><span class="cx">
</span><ins>+#include "ComposedTreeIterator.h"
</ins><span class="cx"> #include "NodeRenderingTraversal.h"
</span><span class="cx"> #include "PseudoElement.h"
</span><span class="cx"> #include "RenderObject.h"
</span><span class="lines">@@ -40,14 +41,11 @@
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx"> const unsigned oNSquaredAvoidanceLimit = 20;
</span><span class="cx"> bool skipAssert = m_parent.isRenderView() || ++m_assertionLimitCounter > oNSquaredAvoidanceLimit;
</span><del>- // FIXME: Traversal needs to know about slots and this needs be removed.
- skipAssert = skipAssert || (node.parentElement() && node.parentElement()->shadowRoot());
-
- ASSERT(skipAssert || nextSiblingRenderer(node, m_parent) == m_nextSibling);
</del><ins>+ ASSERT(skipAssert || nextSiblingRenderer(node) == m_nextSibling);
</ins><span class="cx"> #endif
</span><span class="cx"> return;
</span><span class="cx"> }
</span><del>- m_nextSibling = nextSiblingRenderer(node, m_parent);
</del><ins>+ m_nextSibling = nextSiblingRenderer(node);
</ins><span class="cx"> m_hasValidNextSibling = true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -59,35 +57,41 @@
</span><span class="cx"> m_hasValidNextSibling = false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-RenderObject* RenderTreePosition::previousSiblingRenderer(const Text& textNode)
</del><ins>+RenderObject* RenderTreePosition::previousSiblingRenderer(const Text& textNode) const
</ins><span class="cx"> {
</span><span class="cx"> if (textNode.renderer())
</span><span class="cx"> return textNode.renderer()->previousSibling();
</span><del>- for (Node* sibling = NodeRenderingTraversal::previousSibling(&textNode); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
- RenderObject* renderer = sibling->renderer();
</del><ins>+
+ auto* parentElement = m_parent.element();
+
+ auto composedChildren = composedTreeChildren(*parentElement);
+ for (auto it = composedChildren.at(textNode), end = composedChildren.end(); it != end; --it) {
+ RenderObject* renderer = it->renderer();
</ins><span class="cx"> if (renderer && !RenderTreePosition::isRendererReparented(*renderer))
</span><span class="cx"> return renderer;
</span><span class="cx"> }
</span><del>- if (auto* parent = textNode.parentElement()) {
- if (auto* before = parent->beforePseudoElement())
- return before->renderer();
- }
</del><ins>+ if (auto* before = parentElement->beforePseudoElement())
+ return before->renderer();
</ins><span class="cx"> return nullptr;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-RenderObject* RenderTreePosition::nextSiblingRenderer(const Node& node, const RenderElement& parentRenderer)
</del><ins>+RenderObject* RenderTreePosition::nextSiblingRenderer(const Node& node) const
</ins><span class="cx"> {
</span><del>- if (!parentRenderer.element())
</del><ins>+ auto* parentElement = m_parent.element();
+ if (!parentElement)
</ins><span class="cx"> return nullptr;
</span><span class="cx"> if (node.isAfterPseudoElement())
</span><span class="cx"> return nullptr;
</span><del>- Node* sibling = node.isBeforePseudoElement() ? NodeRenderingTraversal::firstChild(parentRenderer.element()) : NodeRenderingTraversal::nextSibling(&node);
- for (; sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
- RenderObject* renderer = sibling->renderer();
</del><ins>+
+ auto composedChildren = composedTreeChildren(*parentElement);
+
+ auto it = node.isBeforePseudoElement() ? composedChildren.begin() : composedChildren.at(node);
+ for (auto end = composedChildren.end(); it != end; ++it) {
+ RenderObject* renderer = it->renderer();
</ins><span class="cx"> if (renderer && !isRendererReparented(*renderer))
</span><span class="cx"> return renderer;
</span><span class="cx"> }
</span><del>- if (PseudoElement* after = parentRenderer.element()->afterPseudoElement())
</del><ins>+ if (PseudoElement* after = parentElement->afterPseudoElement())
</ins><span class="cx"> return after->renderer();
</span><span class="cx"> return nullptr;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorestyleRenderTreePositionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/RenderTreePosition.h (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/RenderTreePosition.h        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/style/RenderTreePosition.h        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -61,8 +61,8 @@
</span><span class="cx"> void computeNextSibling(const Node&);
</span><span class="cx"> void invalidateNextSibling(const RenderObject&);
</span><span class="cx">
</span><del>- static RenderObject* previousSiblingRenderer(const Text&);
- static RenderObject* nextSiblingRenderer(const Node&, const RenderElement& parentRenderer);
</del><ins>+ RenderObject* previousSiblingRenderer(const Text&) const;
+ RenderObject* nextSiblingRenderer(const Node&) const;
</ins><span class="cx"> static bool isRendererReparented(const RenderObject&);
</span><span class="cx">
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (190982 => 190983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveTree.cpp        2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp        2015-10-13 13:12:25 UTC (rev 190983)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include "AnimationController.h"
</span><span class="cx"> #include "AuthorStyleSheets.h"
</span><span class="cx"> #include "CSSFontSelector.h"
</span><ins>+#include "ComposedTreeIterator.h"
</ins><span class="cx"> #include "ElementIterator.h"
</span><span class="cx"> #include "ElementRareData.h"
</span><span class="cx"> #include "FlowThreadController.h"
</span><span class="lines">@@ -262,7 +263,7 @@
</span><span class="cx"> if (parentRenderer.style().preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
</span><span class="cx"> return true;
</span><span class="cx">
</span><del>- RenderObject* previousRenderer = RenderTreePosition::previousSiblingRenderer(textNode);
</del><ins>+ RenderObject* previousRenderer = renderTreePosition.previousSiblingRenderer(textNode);
</ins><span class="cx"> if (previousRenderer && previousRenderer->isBR()) // <span><br/> <br/></span>
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="lines">@@ -277,7 +278,7 @@
</span><span class="cx"> RenderObject* first = parentRenderer.firstChild();
</span><span class="cx"> while (first && first->isFloatingOrOutOfFlowPositioned())
</span><span class="cx"> first = first->nextSibling();
</span><del>- RenderObject* nextRenderer = RenderTreePosition::nextSiblingRenderer(textNode, parentRenderer);
</del><ins>+ RenderObject* nextRenderer = renderTreePosition.nextSiblingRenderer(textNode);
</ins><span class="cx"> if (!first || nextRenderer == first) {
</span><span class="cx"> // Whitespace at the start of a block just goes away. Don't even make a render object for this text.
</span><span class="cx"> return false;
</span></span></pre>
</div>
</div>
</body>
</html>