Title: [190983] trunk
Revision
190983
Author
[email protected]
Date
2015-10-13 06:12:25 -0700 (Tue, 13 Oct 2015)

Log Message

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.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (190982 => 190983)


--- trunk/LayoutTests/ChangeLog	2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/ChangeLog	2015-10-13 13:12:25 UTC (rev 190983)
@@ -1,3 +1,23 @@
+2015-10-12  Antti Koivisto  <[email protected]>
+
+        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.
+
 2015-10-12  Zalan Bujtas  <[email protected]>
 
         [Win] Update anonymous table results for Windows port. 

Modified: trunk/LayoutTests/TestExpectations (190982 => 190983)


--- trunk/LayoutTests/TestExpectations	2015-10-13 13:05:37 UTC (rev 190982)
+++ trunk/LayoutTests/TestExpectations	2015-10-13 13:12:25 UTC (rev 190983)
@@ -672,7 +672,6 @@
 webkit.org/b/149082 http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-overridesexpires.html [ Pass Failure ]
 
 webkit.org/b/148695 fast/shadow-dom [ Failure ImageOnlyFailure ]
-webkit.org/b/149997 fast/html/details-replace-text.html [ Failure ]
 
 # Marks as flaky (see also https://bugs.webkit.org/show_bug.cgi?id=132388)
 

Modified: trunk/LayoutTests/fast/forms/select-listbox-focus-displaynone-expected.txt (190982 => 190983)


--- 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)
@@ -1 +1 @@
-  PASS
+ PASS

Modified: trunk/LayoutTests/fast/repaint/text-in-relative-positioned-inline-expected.txt (190982 => 190983)


--- 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)
@@ -4,5 +4,4 @@
   RenderBlock {HTML} at (0,0) size 800x600
     RenderBody {BODY} at (8,8) size 784x584
       RenderBlock {DIV} at (100,0) size 684x100
-        RenderText {#text} at (0,0) size 0x0
       RenderBlock {DIV} at (0,0) size 100x100 [bgcolor=#008000]

Modified: trunk/LayoutTests/fullscreen/full-screen-fixed-pos-parent-expected.txt (190982 => 190983)


--- 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)
@@ -1,2 +1 @@
 
-

Modified: trunk/LayoutTests/platform/mac/fast/html/details-add-child-2-expected.txt (190982 => 190983)


--- 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)
@@ -12,3 +12,5 @@
           RenderInline {B} at (0,0) size 144x18
             RenderText {#text} at (0,0) size 144x18
               text run at (0,0) width 144: "should have bold test"
+          RenderText {#text} at (0,0) size 0x0
+          RenderText {#text} at (0,0) size 0x0

Modified: trunk/LayoutTests/platform/mac/fast/html/details-open2-expected.txt (190982 => 190983)


--- 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)
@@ -10,5 +10,7 @@
             text run at (16,0) width 61: "summary"
         RenderBlock (anonymous) at (0,18) size 784x23
           RenderTextControl {INPUT} at (2,2) size 137x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderText {#text} at (0,0) size 0x0
+          RenderText {#text} at (0,0) size 0x0
 layer at (13,31) size 130x13
   RenderBlock {DIV} at (3,3) size 131x13

Modified: trunk/LayoutTests/platform/mac-mavericks/fast/html/details-open2-expected.txt (190982 => 190983)


--- 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)
@@ -10,5 +10,7 @@
             text run at (16,0) width 61: "summary"
         RenderBlock (anonymous) at (0,18) size 784x23
           RenderTextControl {INPUT} at (2,2) size 146x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+          RenderText {#text} at (0,0) size 0x0
+          RenderText {#text} at (0,0) size 0x0
 layer at (13,31) size 139x13
   RenderBlock {DIV} at (3,3) size 140x13

Modified: trunk/Source/WebCore/CMakeLists.txt (190982 => 190983)


--- 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)
@@ -1412,6 +1412,7 @@
     dom/ClipboardEvent.cpp
     dom/CollectionIndexCache.cpp
     dom/Comment.cpp
+    dom/ComposedTreeIterator.cpp
     dom/CompositionEvent.cpp
     dom/ContainerNode.cpp
     dom/ContainerNodeAlgorithms.cpp

Modified: trunk/Source/WebCore/ChangeLog (190982 => 190983)


--- 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)
@@ -1,3 +1,74 @@
+2015-10-12  Antti Koivisto  <[email protected]>
+
+        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):
+
 2015-10-13  ChangSeok Oh  <[email protected]>
 
         [GTK] Use GUniquePtr for GtkIconInfo

Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (190982 => 190983)


--- 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)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="DebugSuffix|Win32">
@@ -13705,6 +13705,20 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <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>
     <ClCompile Include="..\dom\CompositionEvent.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -21949,6 +21963,7 @@
     <ClInclude Include="..\dom\ClipboardEvent.h" />
     <ClInclude Include="..\dom\CollectionIndexCache.h" />
     <ClInclude Include="..\dom\Comment.h" />
+    <ClInclude Include="..\dom\ComposedTreeIterator.h" />
     <ClInclude Include="..\dom\CompositionEvent.h" />
     <ClInclude Include="..\dom\ContainerNode.h" />
     <ClInclude Include="..\dom\ContextDestructionObserver.h" />

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (190982 => 190983)


--- 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)
@@ -6422,6 +6422,8 @@
 		E44B4BB3141650D7002B1D8B /* SelectorChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44B4BB1141650D7002B1D8B /* SelectorChecker.cpp */; };
 		E44B4BB4141650D7002B1D8B /* SelectorChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = E44B4BB2141650D7002B1D8B /* SelectorChecker.h */; };
 		E44EE3A817577EBD00EEE8CF /* FontGenericFamilies.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44EE3A617576E5500EEE8CF /* FontGenericFamilies.cpp */; };
+		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 = (); }; };
 		E45322AB140CE267005A0F92 /* SelectorQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45322A9140CE267005A0F92 /* SelectorQuery.cpp */; };
 		E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = E45322AA140CE267005A0F92 /* SelectorQuery.h */; };
 		E453901D0EAFCACA003695C8 /* MIMETypeRegistryIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = E45390180EAFCACA003695C8 /* MIMETypeRegistryIOS.mm */; };
@@ -14240,6 +14242,8 @@
 		E44B4BB2141650D7002B1D8B /* SelectorChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorChecker.h; sourceTree = "<group>"; };
 		E44EE3A617576E5500EEE8CF /* FontGenericFamilies.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FontGenericFamilies.cpp; sourceTree = "<group>"; };
 		E44EE3A717576E5500EEE8CF /* FontGenericFamilies.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontGenericFamilies.h; sourceTree = "<group>"; };
+		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>"; };
 		E45322A9140CE267005A0F92 /* SelectorQuery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectorQuery.cpp; sourceTree = "<group>"; };
 		E45322AA140CE267005A0F92 /* SelectorQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorQuery.h; sourceTree = "<group>"; };
 		E45390180EAFCACA003695C8 /* MIMETypeRegistryIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MIMETypeRegistryIOS.mm; sourceTree = "<group>"; };
@@ -23525,6 +23529,8 @@
 				6550B697099DF0270090D781 /* Comment.cpp */,
 				6550B698099DF0270090D781 /* Comment.h */,
 				85089CC70A98C22600A275AA /* Comment.idl */,
+				E44FA1861BCA91560091B6EF /* ComposedTreeIterator.cpp */,
+				E44FA1841BCA6B5A0091B6EF /* ComposedTreeIterator.h */,
 				79F2F59E1091939A000D87CB /* CompositionEvent.cpp */,
 				79F2F59F1091939A000D87CB /* CompositionEvent.h */,
 				79F2F5A01091939A000D87CB /* CompositionEvent.idl */,
@@ -26123,6 +26129,7 @@
 				B27B28260CEF0C0700D39D54 /* JSSVGFontElement.h in Headers */,
 				A83B79050CCAFF15000B0825 /* JSSVGFontFaceElement.h in Headers */,
 				A83B79000CCAFF15000B0825 /* JSSVGFontFaceFormatElement.h in Headers */,
+				E44FA1851BCA6B5A0091B6EF /* ComposedTreeIterator.h in Headers */,
 				A83B79020CCAFF15000B0825 /* JSSVGFontFaceNameElement.h in Headers */,
 				A83B78FE0CCAFF15000B0825 /* JSSVGFontFaceSrcElement.h in Headers */,
 				A83B78FC0CCAFF15000B0825 /* JSSVGFontFaceUriElement.h in Headers */,
@@ -29980,6 +29987,7 @@
 				517A63C41B74318B00E7DCDC /* KeyedEncoderCF.cpp in Sources */,
 				A513B3D8114B166A001C429B /* KeyEventCocoa.mm in Sources */,
 				2655413A1489811C000DFC5D /* KeyEventIOS.mm in Sources */,
+				E44FA1871BCA91560091B6EF /* ComposedTreeIterator.cpp in Sources */,
 				935C477009AC4D7300A6AAB4 /* KeyEventMac.mm in Sources */,
 				316FE1190E6E1DA700BF6088 /* KeyframeAnimation.cpp in Sources */,
 				BC5EBA100E823E4700B25965 /* KeyframeList.cpp in Sources */,

Added: trunk/Source/WebCore/dom/ComposedTreeIterator.cpp (0 => 190983)


--- trunk/Source/WebCore/dom/ComposedTreeIterator.cpp	                        (rev 0)
+++ trunk/Source/WebCore/dom/ComposedTreeIterator.cpp	2015-10-13 13:12:25 UTC (rev 190983)
@@ -0,0 +1,192 @@
+/*
+ * 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
+
+}

Added: trunk/Source/WebCore/dom/ComposedTreeIterator.h (0 => 190983)


--- trunk/Source/WebCore/dom/ComposedTreeIterator.h	                        (rev 0)
+++ trunk/Source/WebCore/dom/ComposedTreeIterator.h	2015-10-13 13:12:25 UTC (rev 190983)
@@ -0,0 +1,204 @@
+/*
+ * 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

Modified: trunk/Source/WebCore/dom/DOMAllInOne.cpp (190982 => 190983)


--- 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)
@@ -42,6 +42,7 @@
 #include "ClipboardEvent.cpp"
 #include "CollectionIndexCache.cpp"
 #include "Comment.cpp"
+#include "ComposedTreeIterator.cpp"
 #include "CompositionEvent.cpp"
 #include "ContainerNode.cpp"
 #include "ContainerNodeAlgorithms.cpp"

Modified: trunk/Source/WebCore/dom/NodeRenderingTraversal.cpp (190982 => 190983)


--- 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)
@@ -95,27 +95,6 @@
     return traverseParent(node, CrossShadowRoot);
 }
 
-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);
-}
-
 Node* nextInScope(const Node* node)
 {
     if (Node* next = traverseFirstChild(node, DontCrossShadowRoot))

Modified: trunk/Source/WebCore/dom/NodeRenderingTraversal.h (190982 => 190983)


--- 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)
@@ -35,9 +35,6 @@
 namespace NodeRenderingTraversal {
 
 ContainerNode* parent(const Node*);
-Node* firstChild(const Node*);
-Node* nextSibling(const Node*);
-Node* previousSibling(const Node*);
 
 Node* nextInScope(const Node*);
 Node* previousInScope(const Node*);
@@ -45,9 +42,6 @@
 Node* lastChildInScope(const Node*);
 
 ContainerNode* parentSlow(const Node*);
-Node* firstChildSlow(const Node*);
-Node* nextSiblingSlow(const Node*);
-Node* previousSiblingSlow(const Node*);
 
 inline ContainerNode* parent(const Node* node)
 {
@@ -59,38 +53,8 @@
     return node->parentNodeGuaranteedHostFree();
 }
 
-inline Node* firstChild(const Node* node)
-{
-    ASSERT(!node->isPseudoElement());
-    if (node->needsNodeRenderingTraversalSlowPath())
-        return firstChildSlow(node);
-
-    ASSERT(nextSiblingSlow(node) == node->nextSibling());
-    return node->firstChild();
 }
 
-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();
-}
-
-}
-
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/style/RenderTreePosition.cpp (190982 => 190983)


--- 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)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "RenderTreePosition.h"
 
+#include "ComposedTreeIterator.h"
 #include "NodeRenderingTraversal.h"
 #include "PseudoElement.h"
 #include "RenderObject.h"
@@ -40,14 +41,11 @@
 #if !ASSERT_DISABLED
         const unsigned _oNSquaredAvoidanceLimit_ = 20;
         bool skipAssert = m_parent.isRenderView() || ++m_assertionLimitCounter > oNSquaredAvoidanceLimit;
-        // 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);
+        ASSERT(skipAssert || nextSiblingRenderer(node) == m_nextSibling);
 #endif
         return;
     }
-    m_nextSibling = nextSiblingRenderer(node, m_parent);
+    m_nextSibling = nextSiblingRenderer(node);
     m_hasValidNextSibling = true;
 }
 
@@ -59,35 +57,41 @@
         m_hasValidNextSibling = false;
 }
 
-RenderObject* RenderTreePosition::previousSiblingRenderer(const Text& textNode)
+RenderObject* RenderTreePosition::previousSiblingRenderer(const Text& textNode) const
 {
     if (textNode.renderer())
         return textNode.renderer()->previousSibling();
-    for (Node* sibling = NodeRenderingTraversal::previousSibling(&textNode); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
-        RenderObject* renderer = sibling->renderer();
+
+    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();
         if (renderer && !RenderTreePosition::isRendererReparented(*renderer))
             return renderer;
     }
-    if (auto* parent = textNode.parentElement()) {
-        if (auto* before = parent->beforePseudoElement())
-            return before->renderer();
-    }
+    if (auto* before = parentElement->beforePseudoElement())
+        return before->renderer();
     return nullptr;
 }
 
-RenderObject* RenderTreePosition::nextSiblingRenderer(const Node& node, const RenderElement& parentRenderer)
+RenderObject* RenderTreePosition::nextSiblingRenderer(const Node& node) const
 {
-    if (!parentRenderer.element())
+    auto* parentElement = m_parent.element();
+    if (!parentElement)
         return nullptr;
     if (node.isAfterPseudoElement())
         return nullptr;
-    Node* sibling = node.isBeforePseudoElement() ? NodeRenderingTraversal::firstChild(parentRenderer.element()) : NodeRenderingTraversal::nextSibling(&node);
-    for (; sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
-        RenderObject* renderer = sibling->renderer();
+
+    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();
         if (renderer && !isRendererReparented(*renderer))
             return renderer;
     }
-    if (PseudoElement* after = parentRenderer.element()->afterPseudoElement())
+    if (PseudoElement* after = parentElement->afterPseudoElement())
         return after->renderer();
     return nullptr;
 }

Modified: trunk/Source/WebCore/style/RenderTreePosition.h (190982 => 190983)


--- 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)
@@ -61,8 +61,8 @@
     void computeNextSibling(const Node&);
     void invalidateNextSibling(const RenderObject&);
 
-    static RenderObject* previousSiblingRenderer(const Text&);
-    static RenderObject* nextSiblingRenderer(const Node&, const RenderElement& parentRenderer);
+    RenderObject* previousSiblingRenderer(const Text&) const;
+    RenderObject* nextSiblingRenderer(const Node&) const;
     static bool isRendererReparented(const RenderObject&);
 
 private:

Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (190982 => 190983)


--- 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)
@@ -30,6 +30,7 @@
 #include "AnimationController.h"
 #include "AuthorStyleSheets.h"
 #include "CSSFontSelector.h"
+#include "ComposedTreeIterator.h"
 #include "ElementIterator.h"
 #include "ElementRareData.h"
 #include "FlowThreadController.h"
@@ -262,7 +263,7 @@
     if (parentRenderer.style().preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
         return true;
 
-    RenderObject* previousRenderer = RenderTreePosition::previousSiblingRenderer(textNode);
+    RenderObject* previousRenderer = renderTreePosition.previousSiblingRenderer(textNode);
     if (previousRenderer && previousRenderer->isBR()) // <span><br/> <br/></span>
         return false;
         
@@ -277,7 +278,7 @@
         RenderObject* first = parentRenderer.firstChild();
         while (first && first->isFloatingOrOutOfFlowPositioned())
             first = first->nextSibling();
-        RenderObject* nextRenderer = RenderTreePosition::nextSiblingRenderer(textNode, parentRenderer);
+        RenderObject* nextRenderer = renderTreePosition.nextSiblingRenderer(textNode);
         if (!first || nextRenderer == first) {
             // Whitespace at the start of a block just goes away. Don't even make a render object for this text.
             return false;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to