[Shadow DOM] Add Reified DOM Tree traversal internal APIs.
authorhayato@chromium.org <hayato@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Mar 2012 06:44:15 +0000 (06:44 +0000)
committerhayato@chromium.org <hayato@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Mar 2012 06:44:15 +0000 (06:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=79197

Reviewed by Dimitri Glazkov.

Add internal APIs which can be used to traverse Reified DOM tree, which is
a result of node distribution algorithm explained in Shadow DOM spec.
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html

Every public functions defined in ReifiedTreeTraversal are static
functions and are named in a similar way to ones defined in WebCore::Node class.
The only difference is that ReifiedTreeTraversal APIs consider shadow
hosts and also traverse nodes is Shadow DOM subtrees, crossing shadow's upper and lower boundary
transparently.

There is no actual client which uses these APIs. Follow-up patches for FocusNavigation
and EventDispatcher will use the APIs so that they can traverse node in reified tree order.

.:

* Source/autotools/symbols.filter:

Source/WebCore:

Test: fast/dom/shadow/reified-tree-traversal.html

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.exp.in:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* dom/ReifiedTreeTraversal.cpp: Added.
(WebCore):
(WebCore::isShadowHost):
(WebCore::shadowTreeFor):
(WebCore::shadowTreeOfParent):
(WebCore::ReifiedTreeTraversal::firstChild):
(WebCore::ReifiedTreeTraversal::lastChild):
(WebCore::ReifiedTreeTraversal::lastChildWithoutCrossingUpperBoundary):
(WebCore::ReifiedTreeTraversal::traverseChild):
(WebCore::ReifiedTreeTraversal::traverseLightChildren):
(WebCore::ReifiedTreeTraversal::traverseNode):
(WebCore::ReifiedTreeTraversal::nextSibling):
(WebCore::ReifiedTreeTraversal::previousSibling):
(WebCore::ReifiedTreeTraversal::traverseSiblingOrBackToInsertionPoint):
(WebCore::ReifiedTreeTraversal::traverseSiblingInCurrentTree):
(WebCore::ReifiedTreeTraversal::traverseSiblingOrBackToYoungerShadowRoot):
(WebCore::ReifiedTreeTraversal::escapeFallbackContentElement):
(WebCore::ReifiedTreeTraversal::traverseNodeEscapingFallbackContents):
(WebCore::ReifiedTreeTraversal::parentNode):
(WebCore::ReifiedTreeTraversal::parentNodeWithoutCrossingUpperBoundary):
(WebCore::ReifiedTreeTraversal::parentNodeOrBackToInsertionPoint):
(WebCore::ReifiedTreeTraversal::parentNodeInCurrentTree):
(WebCore::ReifiedTreeTraversal::parentNodeBackToYoungerShadowRootOrHost):
(WebCore::ReifiedTreeTraversal::adjustedParentNode):
(WebCore::ReifiedTreeTraversal::traverseNextNode):
(WebCore::ReifiedTreeTraversal::traverseNextNodeWithoutCrossingUpperBoundary):
(WebCore::ReifiedTreeTraversal::traversePreviousNode):
(WebCore::ReifiedTreeTraversal::traversePreviousNodeWithoutCrossingUpperBoundary):
* dom/ReifiedTreeTraversal.h: Added.
(WebCore):
(ReifiedTreeTraversal):
* dom/ShadowTree.cpp:
(WebCore::ShadowTree::insertionPointFor):
(WebCore::ShadowTree::selectionFor):
(WebCore):
* dom/ShadowTree.h:
(WebCore):
(ShadowTree):
* html/shadow/HTMLContentSelector.cpp:
(WebCore::HTMLContentSelector::findFor):
* html/shadow/HTMLContentSelector.h:
(HTMLContentSelectionSet):
(WebCore::HTMLContentSelectionSet::find):
(HTMLContentSelector):
* html/shadow/InsertionPoint.h:
(WebCore::isInsertionPoint):
(WebCore::toInsertionPoint):
(WebCore):
* testing/Internals.cpp:
(WebCore::Internals::nextSiblingInReifiedTree):
(WebCore):
(WebCore::Internals::firstChildInReifiedTree):
(WebCore::Internals::lastChildInReifiedTree):
(WebCore::Internals::traverseNextNodeInReifiedTree):
(WebCore::Internals::traversePreviousNodeInReifiedTree):
* testing/Internals.h:
(Internals):
* testing/Internals.idl:

Source/WebKit2:

* win/WebKit2.def:
* win/WebKit2CFLite.def:

LayoutTests:

* fast/dom/shadow/reified-tree-traversal-expected.txt: Added.
* fast/dom/shadow/reified-tree-traversal.html: Added.
* platform/efl/Skipped:
* platform/qt/Skipped:
* platform/win/Skipped:
* platform/wincairo/Skipped:
* platform/wk2/Skipped:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@112055 268f45cc-cd09-0410-ab3c-d52691b4dbfc

31 files changed:
ChangeLog
LayoutTests/ChangeLog
LayoutTests/fast/dom/shadow/reified-tree-traversal-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/shadow/reified-tree-traversal.html [new file with mode: 0644]
LayoutTests/platform/efl/Skipped
LayoutTests/platform/qt/Skipped
LayoutTests/platform/win/Skipped
LayoutTests/platform/wincairo/Skipped
LayoutTests/platform/wk2/Skipped
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/ReifiedTreeTraversal.cpp [new file with mode: 0644]
Source/WebCore/dom/ReifiedTreeTraversal.h [new file with mode: 0644]
Source/WebCore/dom/ShadowTree.cpp
Source/WebCore/dom/ShadowTree.h
Source/WebCore/html/shadow/HTMLContentSelector.cpp
Source/WebCore/html/shadow/HTMLContentSelector.h
Source/WebCore/html/shadow/InsertionPoint.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit2/ChangeLog
Source/WebKit2/win/WebKit2.def
Source/WebKit2/win/WebKit2CFLite.def
Source/autotools/symbols.filter

index 47dfd4720b74637613c7745ba2e68b3630794b4b..a8cbe2b7382f36fc2d63628d29fb1de99bbf937b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2012-03-25  Hayato Ito  <hayato@chromium.org>
+
+        [Shadow DOM] Add Reified DOM Tree traversal internal APIs.
+        https://bugs.webkit.org/show_bug.cgi?id=79197
+
+        Reviewed by Dimitri Glazkov.
+
+        Add internal APIs which can be used to traverse Reified DOM tree, which is
+        a result of node distribution algorithm explained in Shadow DOM spec.
+        https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html
+
+        Every public functions defined in ReifiedTreeTraversal are static
+        functions and are named in a similar way to ones defined in WebCore::Node class.
+        The only difference is that ReifiedTreeTraversal APIs consider shadow
+        hosts and also traverse nodes is Shadow DOM subtrees, crossing shadow's upper and lower boundary
+        transparently.
+
+        There is no actual client which uses these APIs. Follow-up patches for FocusNavigation
+        and EventDispatcher will use the APIs so that they can traverse node in reified tree order.
+
+        * Source/autotools/symbols.filter:
+
 2012-03-25  Kevin Ollivier  <kevino@theolliviers.com>
 
         [wx] Unreviewed build fix. Move WTF to its own static lib build.
index 060680d79298227ad5e50ababd02310442276772..88a9d680028e648745b2bdc5c324dd47e7a18340 100644 (file)
@@ -1,3 +1,31 @@
+2012-03-25  Hayato Ito  <hayato@chromium.org>
+
+        [Shadow DOM] Add Reified DOM Tree traversal internal APIs.
+        https://bugs.webkit.org/show_bug.cgi?id=79197
+
+        Reviewed by Dimitri Glazkov.
+
+        Add internal APIs which can be used to traverse Reified DOM tree, which is
+        a result of node distribution algorithm explained in Shadow DOM spec.
+        https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html
+
+        Every public functions defined in ReifiedTreeTraversal are static
+        functions and are named in a similar way to ones defined in WebCore::Node class.
+        The only difference is that ReifiedTreeTraversal APIs consider shadow
+        hosts and also traverse nodes is Shadow DOM subtrees, crossing shadow's upper and lower boundary
+        transparently.
+
+        There is no actual client which uses these APIs. Follow-up patches for FocusNavigation
+        and EventDispatcher will use the APIs so that they can traverse node in reified tree order.
+
+        * fast/dom/shadow/reified-tree-traversal-expected.txt: Added.
+        * fast/dom/shadow/reified-tree-traversal.html: Added.
+        * platform/efl/Skipped:
+        * platform/qt/Skipped:
+        * platform/win/Skipped:
+        * platform/wincairo/Skipped:
+        * platform/wk2/Skipped:
+
 2012-03-25  Csaba Osztrogonác  <ossy@webkit.org>
 
         [Qt] unexpected result in fast/js/large-expressions.html
diff --git a/LayoutTests/fast/dom/shadow/reified-tree-traversal-expected.txt b/LayoutTests/fast/dom/shadow/reified-tree-traversal-expected.txt
new file mode 100644 (file)
index 0000000..00424e7
--- /dev/null
@@ -0,0 +1,156 @@
+Tests for Reified DOM Tree Traversal APIs. Can only run within DRT
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+ShadowRoot should be used.
+Reified Tree:
+DIV     id=a
+       DIV      id=b
+
+Traverse in forward.
+DIV     id=a
+DIV     id=b
+Traverse in backward.
+DIV     id=b
+DIV     id=a
+
+A content element should select light children
+Reified Tree:
+DIV     id=a
+       DIV      id=b
+       DIV      id=c
+       DIV      id=d
+
+Traverse in forward.
+DIV     id=a
+DIV     id=b
+DIV     id=c
+DIV     id=d
+Traverse in backward.
+DIV     id=d
+DIV     id=c
+DIV     id=b
+DIV     id=a
+
+Test for content element selector.
+Reified Tree:
+DIV     id=a
+       DIV      id=b
+
+Traverse in forward.
+DIV     id=a
+Traverse in backward.
+DIV     id=a
+
+Light children should be selected only at once.
+Reified Tree:
+DIV     id=a
+       DIV      id=b
+
+Traverse in forward.
+DIV     id=a
+DIV     id=b
+Traverse in backward.
+DIV     id=e
+DIV     id=d
+DIV     id=c
+DIV     id=a
+
+A content element can have fallback elements.
+Reified Tree:
+DIV     id=a
+       DIV      id=b
+       DIV      id=f1
+       DIV      id=f2
+
+Traverse in forward.
+DIV     id=a
+DIV     id=b
+DIV     id=f1
+DIV     id=f2
+Traverse in backward.
+DIV     id=f2
+DIV     id=f1
+DIV     id=b
+DIV     id=a
+
+Fallback elements should not be used if  element selects any elements.
+Reified Tree:
+DIV     id=a
+       DIV      id=b
+       DIV      id=f1
+       DIV      id=f2
+
+Traverse in forward.
+DIV     id=a
+DIV     id=b
+DIV     id=f1
+DIV     id=f2
+Traverse in backward.
+DIV     id=f2
+DIV     id=f1
+DIV     id=b
+DIV     id=a
+
+Test for Nested ShadowRoots.
+Reified Tree:
+DIV     id=a
+       DIV      id=b
+               DIV      id=c
+               DIV      id=e
+               DIV      id=d
+       DIV      id=f
+       DIV      id=h
+       DIV      id=i
+       DIV      id=g
+
+Traverse in forward.
+DIV     id=a
+DIV     id=b
+DIV     id=c
+DIV     id=e
+DIV     id=d
+DIV     id=f
+DIV     id=h
+DIV     id=i
+DIV     id=g
+Traverse in backward.
+DIV     id=g
+DIV     id=i
+DIV     id=h
+DIV     id=f
+DIV     id=d
+DIV     id=e
+DIV     id=c
+DIV     id=b
+DIV     id=a
+
+Test for Multiple ShadowRoots.
+Reified Tree:
+DIV     id=a
+       DIV      id=d
+       DIV      id=b
+       DIV      id=f
+       DIV      id=c
+       DIV      id=e
+
+Traverse in forward.
+DIV     id=a
+DIV     id=d
+DIV     id=b
+DIV     id=f
+DIV     id=c
+DIV     id=e
+Traverse in backward.
+DIV     id=e
+DIV     id=c
+DIV     id=f
+DIV     id=b
+DIV     id=d
+DIV     id=a
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/shadow/reified-tree-traversal.html b/LayoutTests/fast/dom/shadow/reified-tree-traversal.html
new file mode 100644 (file)
index 0000000..978aeec
--- /dev/null
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/shadow-dom.js"></script>
+</head>
+<body>
+<div id="console"></div>
+<script>
+description("Tests for Reified DOM Tree Traversal APIs. Can only run within DRT");
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function dumpNode(node)
+{
+    var output = node.nodeName + "\t";
+    if (node.id)
+        output += ' id=' + node.id;
+    if (node.className)
+        output += ' class=' + node.className;
+    return output;
+}
+
+function dumpReifiedTree(node, indent)
+{
+    indent = indent || "";
+    var output = indent + dumpNode(node) + "\n";
+    var child;
+    for (child = internals.firstChildInReifiedTree(node); child; child = internals.nextSiblingInReifiedTree(child))
+         output += dumpReifiedTree(child, indent + "\t");
+    return output;
+}
+
+function lastNodeInReifiedTree(root)
+{
+    var lastNode = root;
+    while (internals.lastChildInReifiedTree(lastNode))
+        lastNode = internals.lastChildInReifiedTree(lastNode);
+    return lastNode;
+}
+
+function showReifiedTreeByTraversingInFoward(root)
+{
+    var node = root;
+    var last = lastNodeInReifiedTree(root);
+    while (node) {
+        debug(dumpNode(node));
+        if (node == last)
+            break;
+        node = internals.traverseNextNodeInReifiedTree(node);
+    }
+}
+
+function showReifiedTreeByTraversingInBackward(root)
+{
+    var node = lastNodeInReifiedTree(root);
+    while (node) {
+        debug(dumpNode(node));
+        if (node == root)
+            break;
+        node = internals.traversePreviousNodeInReifiedTree(node);
+    }
+}
+
+function showReifiedTree(node)
+{
+    document.body.appendChild(node);
+    document.body.offsetLeft;
+
+    debug('Reified Tree:');
+    debug(dumpReifiedTree(node));
+
+    debug('Traverse in forward.');
+    showReifiedTreeByTraversingInFoward(node);
+
+    debug('Traverse in backward.');
+    showReifiedTreeByTraversingInBackward(node);
+
+    debug('');
+}
+
+debug('ShadowRoot should be used.');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'})),
+              createDOM('div', {'id': 'c'})));
+
+debug('A content element should select light children');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'}),
+                               createDOM('content')),
+              createDOM('div', {'id': 'c'}),
+              createDOM('div', {'id': 'd'})));
+
+debug('Test for content element selector.');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'}),
+                               createDOM('content', {'select': '.d'})),
+              createDOM('div', {'id': 'c'}),
+              createDOM('div', {'id': 'd'}),
+              createDOM('div', {'id': 'e'})));
+
+debug('Light children should be selected only at once.');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'}),
+                               createDOM('content', {'select': '.d'}),
+                               createDOM('content')),
+              createDOM('div', {'id': 'c'}),
+              createDOM('div', {'id': 'd'}),
+              createDOM('div', {'id': 'e'})));
+
+debug('A content element can have fallback elements.');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'}),
+                               createDOM('content', {'select': '.z'},
+                                         createDOM('div', {'id': 'f1'}),
+                                         createDOM('div', {'id': 'f2'}))),
+              createDOM('div', {'id': 'c'})));
+
+debug('Fallback elements should not be used if <content> element selects any elements.');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'}),
+                               createDOM('content', {'select': '.c'},
+                                         createDOM('div', {'id': 'f1'}),
+                                         createDOM('div', {'id': 'f2'}))),
+              createDOM('div', {'id': 'c'})));
+
+debug('Test for Nested ShadowRoots.');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'},
+                                         createShadowRoot(createDOM('div', {'id': 'c'}),
+                                                          createDOM('content'),
+                                                          createDOM('div', {'id': 'd'})),
+                                         createDOM('div', {'id': 'e'})),
+                               createDOM('div', {'id': 'f'}),
+                               createDOM('content'),
+                               createDOM('div', {'id': 'g'})),
+              createDOM('div', {'id': 'h'}),
+              createDOM('div', {'id': 'i'})));
+
+debug('Test for Multiple ShadowRoots.');
+showReifiedTree(
+    createDOM('div', {'id': 'a'},
+              createShadowRoot(createDOM('div', {'id': 'b'}),
+                               createDOM('content'),
+                               createDOM('div', {'id': 'c'})),
+              createShadowRoot(createDOM('div', {'id': 'd'}),
+                               createDOM('shadow'),
+                               createDOM('div', {'id': 'e'})),
+              createDOM('div', {'id': 'f'})));
+
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
index b15ea2d27b5d10a9348598957089532f4336f1c2..4bc1735a8bce24669efe43dc4280c69254930085 100644 (file)
@@ -1886,6 +1886,7 @@ fast/dom/shadow/content-element-outside-shadow-style.html
 fast/dom/shadow/content-element-in-media-element.html
 fast/dom/shadow/content-element-in-meter-element.html
 fast/dom/shadow/get-element-by-id-in-shadow-root.html
+fast/dom/shadow/reified-tree-traversal.html
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-attached.html
index 87be8e5ae8b7b34a5d15ebac212b62be522f2519..a746cbd8e51240f353a31f95701c165086a6fdcc 100644 (file)
@@ -174,6 +174,7 @@ fast/dom/shadow/iframe-shadow.html
 fast/dom/shadow/multiple-shadowroot.html
 fast/dom/shadow/multiple-shadowroot-rendering.html
 fast/dom/shadow/multiple-shadowroot-adopt.html
+fast/dom/shadow/reified-tree-traversal.html
 fast/dom/shadow/shadow-boundary-events.html
 fast/dom/shadow/shadow-content-crash.html
 fast/dom/shadow/shadow-disable.html
index 2477f1e69243999c3905b94ab4b99a8797291e7b..1ed96f9c5cabaa3f1f56c22902776e39d7a6b228 100644 (file)
@@ -1469,6 +1469,7 @@ fast/dom/shadow/content-element-outside-shadow-style.html
 fast/dom/shadow/content-element-in-media-element.html
 fast/dom/shadow/content-element-in-meter-element.html
 fast/dom/shadow/get-element-by-id-in-shadow-root.html
+fast/dom/shadow/reified-tree-traversal.html
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-activeElement.html
index aef7982a565d64a2ed5ce1d01f9e3243205f4138..c1935c8bda10fbc2dc6fea34af12d360215d3c6e 100644 (file)
@@ -1979,6 +1979,7 @@ fast/dom/shadow/content-element-outside-shadow.html
 fast/dom/shadow/content-element-in-media-element.html
 fast/dom/shadow/content-element-in-meter-element.html
 fast/dom/shadow/get-element-by-id-in-shadow-root.html
+fast/dom/shadow/reified-tree-traversal.html
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-activeElement.html
index 89c657668eb7aa2b532ed78fb466a6660da2fa57..0b54cf10fae055ecb5927e7b4062ef247262285f 100644 (file)
@@ -1085,6 +1085,7 @@ fast/dom/shadow/content-element-outside-shadow.html
 fast/dom/shadow/content-element-outside-shadow-style.html
 fast/dom/shadow/content-element-in-media-element.html
 fast/dom/shadow/content-element-in-meter-element.html
+fast/dom/shadow/reified-tree-traversal.html
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-activeElement.html
index a8485836cd18826a7f75cac045f81eb3912ebfa5..5f977f8b641045e047d4546d38c2f03a73905f35 100644 (file)
@@ -615,6 +615,7 @@ SET(WebCore_SOURCES
     dom/Range.cpp
     dom/RangeException.cpp
     dom/RegisteredEventListener.cpp
+    dom/ReifiedTreeTraversal.cpp
     dom/ScopedEventQueue.cpp
     dom/ScriptableDocumentParser.cpp
     dom/ScriptElement.cpp
index b1339dd531122890925f227f641bcbb13bda635b..e247af5be9aa314bf1d80a85c0e2e6e10adcb48f 100644 (file)
@@ -1,3 +1,91 @@
+2012-03-25  Hayato Ito  <hayato@chromium.org>
+
+        [Shadow DOM] Add Reified DOM Tree traversal internal APIs.
+        https://bugs.webkit.org/show_bug.cgi?id=79197
+
+        Reviewed by Dimitri Glazkov.
+
+        Add internal APIs which can be used to traverse Reified DOM tree, which is
+        a result of node distribution algorithm explained in Shadow DOM spec.
+        https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html
+
+        Every public functions defined in ReifiedTreeTraversal are static
+        functions and are named in a similar way to ones defined in WebCore::Node class.
+        The only difference is that ReifiedTreeTraversal APIs consider shadow
+        hosts and also traverse nodes is Shadow DOM subtrees, crossing shadow's upper and lower boundary
+        transparently.
+
+        There is no actual client which uses these APIs. Follow-up patches for FocusNavigation
+        and EventDispatcher will use the APIs so that they can traverse node in reified tree order.
+
+        Test: fast/dom/shadow/reified-tree-traversal.html
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.exp.in:
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/ReifiedTreeTraversal.cpp: Added.
+        (WebCore):
+        (WebCore::isShadowHost):
+        (WebCore::shadowTreeFor):
+        (WebCore::shadowTreeOfParent):
+        (WebCore::ReifiedTreeTraversal::firstChild):
+        (WebCore::ReifiedTreeTraversal::lastChild):
+        (WebCore::ReifiedTreeTraversal::lastChildWithoutCrossingUpperBoundary):
+        (WebCore::ReifiedTreeTraversal::traverseChild):
+        (WebCore::ReifiedTreeTraversal::traverseLightChildren):
+        (WebCore::ReifiedTreeTraversal::traverseNode):
+        (WebCore::ReifiedTreeTraversal::nextSibling):
+        (WebCore::ReifiedTreeTraversal::previousSibling):
+        (WebCore::ReifiedTreeTraversal::traverseSiblingOrBackToInsertionPoint):
+        (WebCore::ReifiedTreeTraversal::traverseSiblingInCurrentTree):
+        (WebCore::ReifiedTreeTraversal::traverseSiblingOrBackToYoungerShadowRoot):
+        (WebCore::ReifiedTreeTraversal::escapeFallbackContentElement):
+        (WebCore::ReifiedTreeTraversal::traverseNodeEscapingFallbackContents):
+        (WebCore::ReifiedTreeTraversal::parentNode):
+        (WebCore::ReifiedTreeTraversal::parentNodeWithoutCrossingUpperBoundary):
+        (WebCore::ReifiedTreeTraversal::parentNodeOrBackToInsertionPoint):
+        (WebCore::ReifiedTreeTraversal::parentNodeInCurrentTree):
+        (WebCore::ReifiedTreeTraversal::parentNodeBackToYoungerShadowRootOrHost):
+        (WebCore::ReifiedTreeTraversal::adjustedParentNode):
+        (WebCore::ReifiedTreeTraversal::traverseNextNode):
+        (WebCore::ReifiedTreeTraversal::traverseNextNodeWithoutCrossingUpperBoundary):
+        (WebCore::ReifiedTreeTraversal::traversePreviousNode):
+        (WebCore::ReifiedTreeTraversal::traversePreviousNodeWithoutCrossingUpperBoundary):
+        * dom/ReifiedTreeTraversal.h: Added.
+        (WebCore):
+        (ReifiedTreeTraversal):
+        * dom/ShadowTree.cpp:
+        (WebCore::ShadowTree::insertionPointFor):
+        (WebCore::ShadowTree::selectionFor):
+        (WebCore):
+        * dom/ShadowTree.h:
+        (WebCore):
+        (ShadowTree):
+        * html/shadow/HTMLContentSelector.cpp:
+        (WebCore::HTMLContentSelector::findFor):
+        * html/shadow/HTMLContentSelector.h:
+        (HTMLContentSelectionSet):
+        (WebCore::HTMLContentSelectionSet::find):
+        (HTMLContentSelector):
+        * html/shadow/InsertionPoint.h:
+        (WebCore::isInsertionPoint):
+        (WebCore::toInsertionPoint):
+        (WebCore):
+        * testing/Internals.cpp:
+        (WebCore::Internals::nextSiblingInReifiedTree):
+        (WebCore):
+        (WebCore::Internals::firstChildInReifiedTree):
+        (WebCore::Internals::lastChildInReifiedTree):
+        (WebCore::Internals::traverseNextNodeInReifiedTree):
+        (WebCore::Internals::traversePreviousNodeInReifiedTree):
+        * testing/Internals.h:
+        (Internals):
+        * testing/Internals.idl:
+
 2012-03-25  Nikita Vasilyev  <me@elv1s.ru>
 
         Web Inspector: Indenting fully selected line should not indent the line next to it
index fd88feda687db9d625adaa93c54befb57ff18460..51a134677b6790946877c4c3e2a2a8acad48e785 100644 (file)
@@ -1919,6 +1919,8 @@ webcore_sources += \
        Source/WebCore/dom/RawDataDocumentParser.h \
        Source/WebCore/dom/RegisteredEventListener.cpp \
        Source/WebCore/dom/RegisteredEventListener.h \
+       Source/WebCore/dom/ReifiedTreeTraversal.cpp \
+       Source/WebCore/dom/ReifiedTreeTraversal.h \
        Source/WebCore/dom/RenderedDocumentMarker.h \
        Source/WebCore/dom/ScopedEventQueue.cpp \
        Source/WebCore/dom/ScopedEventQueue.h \
index 83d3d331bcd1ec12d48d633f2558c5abdfae61dc..2cf36fb074a684236197cdebd1a8497495954322 100644 (file)
@@ -592,6 +592,7 @@ SOURCES += \
     dom/RangeException.cpp \
     dom/RawDataDocumentParser.h \
     dom/RegisteredEventListener.cpp \
+    dom/ReifiedTreeTraversal.cpp \
     dom/ScopedEventQueue.cpp \
     dom/ScriptedAnimationController.cpp \
     dom/ScriptableDocumentParser.cpp \
@@ -1721,6 +1722,7 @@ HEADERS += \
     dom/QualifiedName.h \
     dom/Range.h \
     dom/RegisteredEventListener.h \
+    dom/ReifiedTreeTraversal.h \
     dom/RenderedDocumentMarker.h \
     dom/ScriptedAnimationController.h \
     dom/ScriptElement.h \
index 721ac4c389720583a5bbe3864fd0971e0efee585..0c426f7e0c17f6329278ff1bdddd5af37845c729 100644 (file)
@@ -607,6 +607,11 @@ __ZN7WebCore20NodeRenderingContextC1EPNS_4NodeE
 __ZN7WebCore20NodeRenderingContextD1Ev
 __ZN7WebCore20PlatformEventFactory24createPlatformMouseEventEP7NSEventP6NSView
 __ZN7WebCore20PlatformEventFactory27createPlatformKeyboardEventEP7NSEvent
+__ZN7WebCore20ReifiedTreeTraversal11nextSiblingEPKNS_4NodeE
+__ZN7WebCore20ReifiedTreeTraversal20traversePreviousNodeEPKNS_4NodeE
+__ZN7WebCore20ReifiedTreeTraversal9lastChildEPKNS_4NodeE
+__ZN7WebCore20ReifiedTreeTraversal16traverseNextNodeEPKNS_4NodeE
+__ZN7WebCore20ReifiedTreeTraversal10firstChildEPKNS_4NodeE
 __ZN7WebCore20RenderEmbeddedObject30setShowsCrashedPluginIndicatorEv
 __ZN7WebCore20ResourceResponseBase11setMimeTypeERKN3WTF6StringE
 __ZN7WebCore20ResourceResponseBase17setHTTPStatusCodeEi
index 8eed71fc3d1a18d11ad2c73ef4cfae32ecf557f0..3d2ef7960d8cfbc9622d4fd71f3a7459a831b9f4 100644 (file)
             'dom/Range.h',
             'dom/RangeBoundaryPoint.h',
             'dom/RegisteredEventListener.h',
+            'dom/ReifiedTreeTraversal.h',
             'dom/RenderedDocumentMarker.h',
             'dom/ScriptExecutionContext.h',
             'dom/ScriptRunner.h',
             'dom/RangeException.h',
             'dom/RawDataDocumentParser.h',
             'dom/RegisteredEventListener.cpp',
+            'dom/ReifiedTreeTraversal.cpp',
+            'dom/ReifiedTreeTraversal.h',
             'dom/RequestAnimationFrameCallback.h',
             'dom/ScopedEventQueue.cpp',
             'dom/ScopedEventQueue.h',
index 13766f2ed27d32614f912502256611ac65e4dfed..08ee78015bbeecadafe2cb88a9ee8e4364125b51 100755 (executable)
                                RelativePath="..\dom\RangeException.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\dom\ReifiedTreeTraversal.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\dom\ReifiedTreeTraversal.h"
+                               >
+                       </File>
                        <File
                                RelativePath="..\dom\RegisteredEventListener.cpp"
                                >
index 64007376d73a6a5215b8909f654f9115c9320554..bee8ea611aad9dc76c4489f7420c9f993452ab39 100644 (file)
                49FFBF1D11C8550E006A7118 /* GraphicsContext3DMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 49FFBF1C11C8550E006A7118 /* GraphicsContext3DMac.mm */; };
                49FFBF3F11C93EE3006A7118 /* WebGLLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49FFBF3D11C93EE3006A7118 /* WebGLLayer.h */; };
                49FFBF4011C93EE3006A7118 /* WebGLLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 49FFBF3E11C93EE3006A7118 /* WebGLLayer.mm */; };
+               4A013D291512FD7700E1E613 /* ReifiedTreeTraversal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A013D271512FD7700E1E613 /* ReifiedTreeTraversal.cpp */; };
+               4A013D2A1512FD7700E1E613 /* ReifiedTreeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A013D281512FD7700E1E613 /* ReifiedTreeTraversal.h */; };
                4A0DA2FE129B241900AB61E1 /* FormAssociatedElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A0DA2FC129B241900AB61E1 /* FormAssociatedElement.cpp */; };
                4A0DA2FF129B241900AB61E1 /* FormAssociatedElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A0DA2FD129B241900AB61E1 /* FormAssociatedElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4A1E719014E101E400626F9D /* JSHTMLContentElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A1E718E14E101E400626F9D /* JSHTMLContentElement.cpp */; };
                49FFBF1C11C8550E006A7118 /* GraphicsContext3DMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GraphicsContext3DMac.mm; sourceTree = "<group>"; };
                49FFBF3D11C93EE3006A7118 /* WebGLLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLLayer.h; sourceTree = "<group>"; };
                49FFBF3E11C93EE3006A7118 /* WebGLLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebGLLayer.mm; sourceTree = "<group>"; };
+               4A013D271512FD7700E1E613 /* ReifiedTreeTraversal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReifiedTreeTraversal.cpp; sourceTree = "<group>"; };
+               4A013D281512FD7700E1E613 /* ReifiedTreeTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReifiedTreeTraversal.h; sourceTree = "<group>"; };
                4A0DA2FC129B241900AB61E1 /* FormAssociatedElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormAssociatedElement.cpp; sourceTree = "<group>"; };
                4A0DA2FD129B241900AB61E1 /* FormAssociatedElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormAssociatedElement.h; sourceTree = "<group>"; };
                4A1E718E14E101E400626F9D /* JSHTMLContentElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLContentElement.cpp; sourceTree = "<group>"; };
                                A84D827B11D333ED00972990 /* RawDataDocumentParser.h */,
                                85031B350A44EFC700F992E0 /* RegisteredEventListener.cpp */,
                                85031B360A44EFC700F992E0 /* RegisteredEventListener.h */,
+                               4A013D271512FD7700E1E613 /* ReifiedTreeTraversal.cpp */,
+                               4A013D281512FD7700E1E613 /* ReifiedTreeTraversal.h */,
                                A76E5F7E135E0DCF00A69837 /* RenderedDocumentMarker.h */,
                                4998AEC413F9D0EA0090B1AA /* RequestAnimationFrameCallback.h */,
                                4998AEC513F9D0EA0090B1AA /* RequestAnimationFrameCallback.idl */,
                                BCAB418213E356E800D8AAF3 /* Region.h in Headers */,
                                85031B4C0A44EFC700F992E0 /* RegisteredEventListener.h in Headers */,
                                B2C3DA2D0D006C1D00EF6F26 /* RegularExpression.h in Headers */,
+                               4A013D2A1512FD7700E1E613 /* ReifiedTreeTraversal.h in Headers */,
                                93309E01099E64920056E581 /* RemoveCSSPropertyCommand.h in Headers */,
                                D06C0D8F0CFD11460065F43F /* RemoveFormatCommand.h in Headers */,
                                93309E05099E64920056E581 /* RemoveNodeCommand.h in Headers */,
                                BCAB418113E356E800D8AAF3 /* Region.cpp in Sources */,
                                85031B4B0A44EFC700F992E0 /* RegisteredEventListener.cpp in Sources */,
                                B2C3DA2C0D006C1D00EF6F26 /* RegularExpression.cpp in Sources */,
+                               4A013D291512FD7700E1E613 /* ReifiedTreeTraversal.cpp in Sources */,
                                93309E00099E64920056E581 /* RemoveCSSPropertyCommand.cpp in Sources */,
                                D06C0D900CFD11460065F43F /* RemoveFormatCommand.cpp in Sources */,
                                93309E04099E64920056E581 /* RemoveNodeCommand.cpp in Sources */,
diff --git a/Source/WebCore/dom/ReifiedTreeTraversal.cpp b/Source/WebCore/dom/ReifiedTreeTraversal.cpp
new file mode 100644 (file)
index 0000000..3c54354
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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 "ReifiedTreeTraversal.h"
+
+#include "Element.h"
+#include "HTMLContentSelector.h"
+#include "InsertionPoint.h"
+#include "ShadowTree.h"
+
+namespace WebCore {
+
+static inline bool isShadowHost(const Node* node)
+{
+    return node && node->isElementNode() && toElement(node)->hasShadowRoot();
+}
+
+static inline ShadowTree* shadowTreeFor(const Node* node)
+{
+    if (node && node->isElementNode())
+        return toElement(node)->shadowTree();
+    return 0;
+}
+
+static inline ShadowTree* shadowTreeOfParent(const Node* node)
+{
+    if (node && node->parentNode())
+        return shadowTreeFor(node->parentNode());
+    return 0;
+}
+
+Node* ReifiedTreeTraversal::firstChild(const Node* node)
+{
+    ASSERT(node);
+    Node* child = traverseChild(node, ReifiedTreeTraversalDirectionForward);
+    ASSERT(!child || !child->isShadowRoot());
+    return child;
+}
+
+Node* ReifiedTreeTraversal::lastChild(const Node* node)
+{
+    ASSERT(node);
+    Node* child = traverseChild(node, ReifiedTreeTraversalDirectionBackward);
+    ASSERT(!child || !child->isShadowRoot());
+    return child;
+}
+
+Node* ReifiedTreeTraversal::lastChildWithoutCrossingUpperBoundary(const Node* node)
+{
+    ASSERT(node);
+    Node* child = traverseLightChildren(node, ReifiedTreeTraversalDirectionBackward);
+    ASSERT(!child || !child->isShadowRoot());
+    return child;
+}
+
+Node* ReifiedTreeTraversal::traverseChild(const Node* node, ReifiedTreeTraversalDirection direction)
+{
+    ASSERT(node);
+    // FIXME: Add an assertion once InsertionPoint have isActive() function.
+    // https://bugs.webkit.org/show_bug.cgi?id=82010
+    // ASSERT(!isInsertionPoint(node) || !toInsertionPoint(node)->isActive());
+    ASSERT(!node->isShadowRoot());
+    ShadowTree* shadowTree = shadowTreeFor(node);
+    if (shadowTree && shadowTree->hasShadowRoot())
+        return traverseLightChildren(shadowTree->youngestShadowRoot(), direction);
+    return traverseLightChildren(node, direction);
+}
+
+Node* ReifiedTreeTraversal::traverseLightChildren(const Node* node, ReifiedTreeTraversalDirection direction)
+{
+    ASSERT(node);
+    if (Node* child = (direction == ReifiedTreeTraversalDirectionForward ? node->firstChild() : node->lastChild()))
+        return traverseNode(child, direction);
+    return 0;
+}
+
+Node* ReifiedTreeTraversal::traverseNode(const Node* node, ReifiedTreeTraversalDirection direction)
+{
+    ASSERT(node);
+    if (isInsertionPoint(node)) {
+        const HTMLContentSelectionList* selectionList = toInsertionPoint(node)->selections();
+        if (HTMLContentSelection* selection = (direction == ReifiedTreeTraversalDirectionForward ? selectionList->first() : selectionList->last()))
+            return traverseNode(selection->node(), direction);
+        return traverseLightChildren(node, direction);
+    }
+    return const_cast<Node*>(node);
+}
+
+Node* ReifiedTreeTraversal::nextSibling(const Node* node)
+{
+    ASSERT(node);
+    ASSERT(!node->isShadowRoot());
+    Node* next = traverseSiblingOrBackToInsertionPoint(node, ReifiedTreeTraversalDirectionForward);
+    ASSERT(!next || !next->isShadowRoot());
+    return next;
+}
+
+Node* ReifiedTreeTraversal::previousSibling(const Node* node)
+{
+    ASSERT(node);
+    ASSERT(!node->isShadowRoot());
+    Node* next = traverseSiblingOrBackToInsertionPoint(node, ReifiedTreeTraversalDirectionBackward);
+    ASSERT(!next || !next->isShadowRoot());
+    return next;
+}
+
+Node* ReifiedTreeTraversal::traverseSiblingOrBackToInsertionPoint(const Node* node, ReifiedTreeTraversalDirection direction)
+{
+    ASSERT(node);
+    ShadowTree* shadowTree = shadowTreeOfParent(node);
+    if (!shadowTree)
+        return traverseSiblingInCurrentTree(node, direction);
+    HTMLContentSelection* selection = shadowTree->selectionFor(node);
+    if (!selection)
+        return traverseSiblingInCurrentTree(node, direction);
+    if (HTMLContentSelection* nextSelection = (direction == ReifiedTreeTraversalDirectionForward ? selection->next() : selection->previous()))
+        return traverseNode(nextSelection->node(), direction);
+    return traverseSiblingOrBackToInsertionPoint(selection->insertionPoint(), direction);
+}
+
+Node* ReifiedTreeTraversal::traverseSiblingInCurrentTree(const Node* node, ReifiedTreeTraversalDirection direction)
+{
+    ASSERT(node);
+    if (Node* next = (direction == ReifiedTreeTraversalDirectionForward ? node->nextSibling() : node->previousSibling()))
+        return traverseNode(next, direction);
+    if (Node* next = traverseSiblingOrBackToYoungerShadowRoot(node, direction))
+        return next;
+    return escapeFallbackContentElement(node, direction);
+}
+
+Node* ReifiedTreeTraversal::traverseSiblingOrBackToYoungerShadowRoot(const Node* node, ReifiedTreeTraversalDirection direction)
+{
+    ASSERT(node);
+    if (node->parentNode() && node->parentNode()->isShadowRoot()) {
+        ShadowRoot* parentShadowRoot = toShadowRoot(node->parentNode());
+        if (!parentShadowRoot->isYoungest()) {
+            InsertionPoint* assignedInsertionPoint = parentShadowRoot->assignedTo();
+            ASSERT(assignedInsertionPoint);
+            return traverseSiblingInCurrentTree(assignedInsertionPoint, direction);
+        }
+    }
+    return 0;
+}
+
+Node* ReifiedTreeTraversal::escapeFallbackContentElement(const Node* node, ReifiedTreeTraversalDirection direction)
+{
+    ASSERT(node);
+    if (node->parentNode() && isInsertionPoint(node->parentNode()))
+        return traverseSiblingOrBackToInsertionPoint(node->parentNode(), direction);
+    return 0;
+}
+
+Node* ReifiedTreeTraversal::traverseNodeEscapingFallbackContents(const Node* node, CrossedUpperBoundary& crossed)
+{
+    ASSERT(node);
+    if (isInsertionPoint(node))
+        return parentNodeOrBackToInsertionPoint(node, crossed);
+    crossed = NotCrossed;
+    return const_cast<Node*>(node);
+}
+
+Node* ReifiedTreeTraversal::parentNode(const Node* node, CrossedUpperBoundary& crossed)
+{
+    ASSERT(node);
+    ASSERT(!node->isShadowRoot());
+    crossed = NotCrossed;
+    // FIXME: Add an assertion once InsertionPoint have isActive() function.
+    // https://bugs.webkit.org/show_bug.cgi?id=82010
+    // ASSERT(!isInsertionPoint(node) || !toInsertionPoint(node)->isActive());
+    return parentNodeOrBackToInsertionPoint(node, crossed);
+}
+
+Node* ReifiedTreeTraversal::parentNode(const Node* node)
+{
+    CrossedUpperBoundary crossed;
+    Node* parent = parentNode(node, crossed);
+    UNUSED_PARAM(crossed);
+    return parent;
+}
+
+Node* ReifiedTreeTraversal::parentNodeWithoutCrossingUpperBoundary(const Node* node)
+{
+    ASSERT(node);
+    ASSERT(!node->isShadowRoot());
+    // FIXME: Add an assertion once InsertionPoint have isActive() function.
+    // https://bugs.webkit.org/show_bug.cgi?id=82010
+    // ASSERT(!isInsertionPoint(node) || !toInsertionPoint(node)->isActive());
+    CrossedUpperBoundary crossed;
+    Node* parent = parentNodeOrBackToInsertionPoint(node, crossed);
+    if (crossed == Crossed)
+        return 0;
+    return parent;
+}
+
+Node* ReifiedTreeTraversal::parentNodeOrBackToInsertionPoint(const Node* node, CrossedUpperBoundary& crossed)
+{
+    ASSERT(crossed == NotCrossed);
+    if (ShadowTree* shadowTree = shadowTreeOfParent(node)) {
+        if (HTMLContentSelection* selection = shadowTree->selectionFor(node))
+            return parentNodeOrBackToInsertionPoint(selection->insertionPoint(), crossed);
+    }
+    return parentNodeInCurrentTree(node, crossed);
+}
+
+Node* ReifiedTreeTraversal::parentNodeInCurrentTree(const Node* node, CrossedUpperBoundary& crossed)
+{
+    ASSERT(crossed == NotCrossed);
+    if (Node* parent = node->parentNode()) {
+        if (parent->isShadowRoot())
+            return parentNodeBackToYoungerShadowRootOrHost(toShadowRoot(parent), crossed);
+        return traverseNodeEscapingFallbackContents(parent, crossed);
+    }
+    return 0;
+}
+
+Node* ReifiedTreeTraversal::parentNodeBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, CrossedUpperBoundary& crossed)
+{
+    ASSERT(shadowRoot);
+    ASSERT(crossed == NotCrossed);
+    if (shadowRoot->isYoungest()) {
+        crossed = Crossed;
+        return shadowRoot->host();
+    }
+    InsertionPoint* assignedInsertionPoint = shadowRoot->assignedTo();
+    ASSERT(assignedInsertionPoint);
+    return parentNodeOrBackToInsertionPoint(assignedInsertionPoint, crossed);
+}
+
+Node* ReifiedTreeTraversal::adjustedParentNode(const Node* node)
+{
+    if (ShadowTree* shadowTree = shadowTreeOfParent(node)) {
+        if (HTMLContentSelection* selection = shadowTree->selectionFor(node))
+            return selection->insertionPoint();
+    }
+    if (node->isShadowRoot()) {
+        const ShadowRoot* shadowRoot = toShadowRoot(node);
+        if (!shadowRoot->isYoungest()) {
+            InsertionPoint* assignedInsertionPoint = shadowRoot->assignedTo();
+            ASSERT(assignedInsertionPoint);
+            return assignedInsertionPoint;
+        }
+        return shadowRoot->host();
+    }
+    return node->parentNode();
+}
+
+Node* ReifiedTreeTraversal::traverseNextNode(const Node* node)
+{
+    if (Node* next = firstChild(node))
+        return next;
+    if (Node* next = nextSibling(node))
+        return next;
+    const Node* n = node;
+    while (n && !nextSibling(n))
+        n = parentNode(n);
+    if (n)
+        return nextSibling(n);
+    return 0;
+}
+
+Node* ReifiedTreeTraversal::traverseNextNodeWithoutCrossingUpperBoundary(const Node* node)
+{
+    if (!isShadowHost(node)) {
+        if (Node* next = traverseLightChildren(node, ReifiedTreeTraversalDirectionForward))
+            return next;
+    }
+    if (Node* next = nextSibling(node))
+        return next;
+    const Node* n = node;
+    while (n && !nextSibling(n))
+        n = parentNodeWithoutCrossingUpperBoundary(n);
+    if (n)
+        return nextSibling(n);
+    return 0;
+}
+
+Node* ReifiedTreeTraversal::traversePreviousNode(const Node* node)
+{
+    if (Node* n = previousSibling(node)) {
+        while (Node* child = ReifiedTreeTraversal::lastChild(n))
+            n = child;
+        return n;
+    }
+    return parentNode(node);
+}
+
+Node* ReifiedTreeTraversal::traversePreviousNodeWithoutCrossingUpperBoundary(const Node* node)
+{
+    if (Node* n = previousSibling(node)) {
+        while (!isShadowHost(n)) {
+            if (Node* child = ReifiedTreeTraversal::traverseLightChildren(n, ReifiedTreeTraversalDirectionBackward))
+                n = child;
+            else
+                break;
+        }
+        return n;
+    }
+    return parentNodeWithoutCrossingUpperBoundary(node);
+}
+
+} // namespace
diff --git a/Source/WebCore/dom/ReifiedTreeTraversal.h b/Source/WebCore/dom/ReifiedTreeTraversal.h
new file mode 100644 (file)
index 0000000..2119373
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER 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.
+ */
+
+#ifndef ReifiedTreeTraversal_h
+#define ReifiedTreeTraversal_h
+
+namespace WebCore {
+
+class Node;
+class ShadowRoot;
+
+enum ReifiedTreeTraversalDirection {
+    ReifiedTreeTraversalDirectionForward,
+    ReifiedTreeTraversalDirectionBackward
+};
+
+// FIXME: Make some functions inline to optimise the performance.
+// https://bugs.webkit.org/show_bug.cgi?id=82019
+class ReifiedTreeTraversal {
+public:
+    enum CrossedUpperBoundary {
+        NotCrossed,
+        Crossed,
+    };
+
+    static Node* firstChild(const Node*);
+    static Node* lastChild(const Node*);
+    static Node* lastChildWithoutCrossingUpperBoundary(const Node*);
+
+    static Node* nextSibling(const Node*);
+    static Node* previousSibling(const Node*);
+
+    static Node* parentNode(const Node*, CrossedUpperBoundary&);
+    static Node* parentNode(const Node*);
+    static Node* parentNodeWithoutCrossingUpperBoundary(const Node*);
+
+    static Node* traverseNextNode(const Node*);
+    static Node* traversePreviousNode(const Node*);
+
+    // FIXME: An 'adjusted' is not good name for general use case. Rename this.
+    // https://bugs.webkit.org/show_bug.cgi?id=82022
+    // This may return ShadowRoot or InsertionPoint.
+    static Node* adjustedParentNode(const Node*);
+
+    static Node* traverseNextNodeWithoutCrossingUpperBoundary(const Node*);
+    static Node* traversePreviousNodeWithoutCrossingUpperBoundary(const Node*);
+
+private:
+    static Node* traverseChild(const Node*, ReifiedTreeTraversalDirection);
+    static Node* traverseNode(const Node*, ReifiedTreeTraversalDirection);
+    static Node* traverseLightChildren(const Node*, ReifiedTreeTraversalDirection);
+
+    static Node* traverseSiblingOrBackToInsertionPoint(const Node*, ReifiedTreeTraversalDirection);
+    static Node* traverseSiblingInCurrentTree(const Node*, ReifiedTreeTraversalDirection);
+
+    static Node* traverseSiblingOrBackToYoungerShadowRoot(const Node*, ReifiedTreeTraversalDirection);
+    static Node* escapeFallbackContentElement(const Node*, ReifiedTreeTraversalDirection);
+
+    static Node* traverseNodeEscapingFallbackContents(const Node*, CrossedUpperBoundary&);
+
+    static Node* parentNodeOrBackToInsertionPoint(const Node*, CrossedUpperBoundary&);
+    static Node* parentNodeInCurrentTree(const Node*, CrossedUpperBoundary&);
+    static Node* parentNodeBackToYoungerShadowRootOrHost(const ShadowRoot*, CrossedUpperBoundary&);
+};
+
+} // namespace
+
+#endif
index 1bae3bea7e9ea0ab9eb6246aef2de080c6acc3df..6fbe7295d63a3981aa5e80d24cc003e77ac86a68 100644 (file)
@@ -204,7 +204,7 @@ void ShadowTree::detachHost(Element* host)
     host->detachAsNode();
 }
 
-InsertionPoint* ShadowTree::insertionPointFor(Node* node) const
+InsertionPoint* ShadowTree::insertionPointFor(const Node* node) const
 {
     ASSERT(node && node->parentNode());
 
@@ -221,6 +221,11 @@ InsertionPoint* ShadowTree::insertionPointFor(Node* node) const
     return found->insertionPoint();
 }
 
+HTMLContentSelection* ShadowTree::selectionFor(const Node* node) const
+{
+    return m_selector.findFor(node);
+}
+
 void ShadowTree::reattach()
 {
     detach();
index 57222183a26317442f8907feee92cca3678d2726..e9c2ccadb0ccf7cd1550f40d32089af0f73628a3 100644 (file)
@@ -41,6 +41,7 @@ class Node;
 class Element;
 class InsertionPoint;
 class TreeScope;
+class HTMLContentSelection;
 
 class ShadowTree {
 public:
@@ -79,7 +80,8 @@ public:
     void reattachHostChildrenAndShadow();
     void hostChildrenChanged();
 
-    InsertionPoint* insertionPointFor(Node*) const;
+    InsertionPoint* insertionPointFor(const Node*) const;
+    HTMLContentSelection* selectionFor(const Node*) const;
 
     HTMLContentSelector& selector();
     const HTMLContentSelector& selector() const;
index 8b62d56a773db30db6d318af73bdd1c0f8dbb467..31e4194ec5a37de0394c03f8e838e65bb45874c4 100644 (file)
@@ -138,7 +138,7 @@ void HTMLContentSelector::unselect(HTMLContentSelectionList* list)
     list->clear();
 }
 
-HTMLContentSelection* HTMLContentSelector::findFor(Node* key) const
+HTMLContentSelection* HTMLContentSelector::findFor(const Node* key) const
 {
     return m_selectionSet.find(key);
 }
index e01180500bad123423a17588a81932f180f14c53..bcfbddbbd8827385a7c9afc11c24f6feca6e3629 100644 (file)
@@ -98,7 +98,7 @@ public:
     void add(HTMLContentSelection* value) { m_set.add(value); }
     void remove(HTMLContentSelection* value) { m_set.remove(value); }
     bool isEmpty() const { return m_set.isEmpty(); }
-    HTMLContentSelection* find(Node* key) const;
+    HTMLContentSelection* find(const Node* key) const;
 
 private:
     struct Translator {
@@ -118,9 +118,9 @@ private:
     PointerSet m_set;
 };
 
-inline HTMLContentSelection* HTMLContentSelectionSet::find(Node* key) const
+inline HTMLContentSelection* HTMLContentSelectionSet::find(const Node* key) const
 {
-    PointerSet::iterator found = m_set.find<Node*, HTMLContentSelectionSet::Translator>(key);
+    PointerSet::iterator found = m_set.find<const Node*, HTMLContentSelectionSet::Translator>(key);
     return found != m_set.end() ? *found : 0;
 }
 
@@ -132,7 +132,7 @@ public:
 
     void select(InsertionPoint*, HTMLContentSelectionList*);
     void unselect(HTMLContentSelectionList*);
-    HTMLContentSelection* findFor(Node* key) const;
+    HTMLContentSelection* findFor(const Node* key) const;
 
     void willSelect();
     bool isSelecting() const;
index b5282cddc27482cec33535ddbeb68c70f55884bc..74b1a200c4d9e2b1278054c447af4011d46d48b0 100644 (file)
@@ -71,7 +71,7 @@ private:
     HTMLContentSelectionList m_selections;
 };
 
-inline bool isInsertionPoint(Node* node)
+inline bool isInsertionPoint(const Node* node)
 {
     if (!node)
         return true;
@@ -88,6 +88,12 @@ inline InsertionPoint* toInsertionPoint(Node* node)
     return static_cast<InsertionPoint*>(node);
 }
 
+inline const InsertionPoint* toInsertionPoint(const Node* node)
+{
+    ASSERT(isInsertionPoint(node));
+    return static_cast<const InsertionPoint*>(node);
+}
+
 inline bool isShadowBoundary(Node* node)
 {
     if (!isInsertionPoint(node))
index 6f2ee33a7ab68f26fd107197e818766af19f5067..f2f109804240767d252a5968547e612356699629 100644 (file)
@@ -50,6 +50,7 @@
 #include "NodeRenderingContext.h"
 #include "Page.h"
 #include "Range.h"
+#include "ReifiedTreeTraversal.h"
 #include "RenderObject.h"
 #include "RenderTreeAsText.h"
 #include "Settings.h"
@@ -181,6 +182,51 @@ bool Internals::attached(Node* node, ExceptionCode& ec)
     return node->attached();
 }
 
+Node* Internals::nextSiblingInReifiedTree(Node* node, ExceptionCode& ec)
+{
+    if (!node) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+    return ReifiedTreeTraversal::nextSibling(node);
+}
+
+Node* Internals::firstChildInReifiedTree(Node* node, ExceptionCode& ec)
+{
+    if (!node) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+    return ReifiedTreeTraversal::firstChild(node);
+}
+
+Node* Internals::lastChildInReifiedTree(Node* node, ExceptionCode& ec)
+{
+    if (!node) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+    return ReifiedTreeTraversal::lastChild(node);
+}
+
+Node* Internals::traverseNextNodeInReifiedTree(Node* node, ExceptionCode& ec)
+{
+    if (!node) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+    return ReifiedTreeTraversal::traverseNextNode(node);
+}
+
+Node* Internals::traversePreviousNodeInReifiedTree(Node* node, ExceptionCode& ec)
+{
+    if (!node) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+    return ReifiedTreeTraversal::traversePreviousNode(node);
+}
+
 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
 {
     if (!element) {
index 75ed7e26e99d9f8a301229c80ffb7ee05de94de1..a0613ac217b83eb9f813efa9087713d00cf8a3b8 100644 (file)
@@ -84,6 +84,12 @@ public:
 
     bool attached(Node*, ExceptionCode&);
 
+    Node* nextSiblingInReifiedTree(Node*, ExceptionCode&);
+    Node* firstChildInReifiedTree(Node*, ExceptionCode&);
+    Node* lastChildInReifiedTree(Node*, ExceptionCode&);
+    Node* traverseNextNodeInReifiedTree(Node*, ExceptionCode&);
+    Node* traversePreviousNodeInReifiedTree(Node*, ExceptionCode&);
+
 #if ENABLE(INPUT_COLOR)
     void selectColorInColorChooser(Element*, const String& colorValue);
 #endif
index f2200ffc4b159a0768ffdfaf602fc70f49875034..95fe9dc558d400e225e24735c29d760f08ba4897 100644 (file)
@@ -55,6 +55,12 @@ module window {
         Element getElementByIdInShadowRoot(in Node shadowRoot, in DOMString id) raises(DOMException);
         boolean isValidContentSelect(in Element contentElement) raises(DOMException);
 
+        Node nextSiblingInReifiedTree(in Node node) raises(DOMException);
+        Node firstChildInReifiedTree(in Node node) raises(DOMException);
+        Node lastChildInReifiedTree(in Node node) raises(DOMException);
+        Node traverseNextNodeInReifiedTree(in Node node) raises(DOMException);
+        Node traversePreviousNodeInReifiedTree(in Node node) raises(DOMException);
+
         boolean attached(in Node node) raises(DOMException);
 
 #if defined(ENABLE_INPUT_COLOR) && ENABLE_INPUT_COLOR
index 2d698ae37db1f9a7be35808043e8ae345acef56d..7f841a9d8c1e1ca5c043d064e3588ac4f8f7aa68 100644 (file)
@@ -1,3 +1,26 @@
+2012-03-25  Hayato Ito  <hayato@chromium.org>
+
+        [Shadow DOM] Add Reified DOM Tree traversal internal APIs.
+        https://bugs.webkit.org/show_bug.cgi?id=79197
+
+        Reviewed by Dimitri Glazkov.
+
+        Add internal APIs which can be used to traverse Reified DOM tree, which is
+        a result of node distribution algorithm explained in Shadow DOM spec.
+        https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html
+
+        Every public functions defined in ReifiedTreeTraversal are static
+        functions and are named in a similar way to ones defined in WebCore::Node class.
+        The only difference is that ReifiedTreeTraversal APIs consider shadow
+        hosts and also traverse nodes is Shadow DOM subtrees, crossing shadow's upper and lower boundary
+        transparently.
+
+        There is no actual client which uses these APIs. Follow-up patches for FocusNavigation
+        and EventDispatcher will use the APIs so that they can traverse node in reified tree order.
+
+        * win/WebKit2.def:
+        * win/WebKit2CFLite.def:
+
 2012-03-25  Alexander Færøy  <alexander.faeroy@nokia.com>
 
         Unreviewed build fix for QtWebKit on Mac OS X.
index e2c8f6dfadd74224bff52b8c92e8f544601feb54..ada88379bd950aa599d0a4d1094f2fd03490c3d4 100644 (file)
@@ -168,6 +168,7 @@ EXPORTS
         ?equalIgnoringCase@WTF@@YA_NPAVStringImpl@1@PBE@Z
         ?externalRepresentation@WebCore@@YA?AVString@WTF@@PAVElement@1@I@Z
         ?find@StringImpl@WTF@@QAEIPAV12@I@Z
+        ?firstChild@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?frameDestroyed@FrameDestructionObserver@WebCore@@UAEXXZ
         ?fromUTF8WithLatin1Fallback@String@WTF@@SA?AV12@PBEI@Z
         ?getCachedDOMStructure@WebCore@@YAPAVStructure@JSC@@PAVJSDOMGlobalObject@1@PBUClassInfo@3@@Z
@@ -180,7 +181,9 @@ EXPORTS
         ?isPreloaded@CachedResourceLoader@WebCore@@QBE_NABVString@WTF@@@Z
         ?jsStringSlowCase@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@AAV?$HashMap@PAVStringImpl@WTF@@V?$Weak@VJSString@JSC@@@JSC@@UStringHash@2@U?$HashTraits@PAVStringImpl@WTF@@@2@U?$HashTraits@V?$Weak@VJSString@JSC@@@JSC@@@2@@WTF@@PAVStringImpl@6@@Z
         ?lastChangeWasUserEdit@HTMLTextFormControlElement@WebCore@@QBE_NXZ
+        ?lastChild@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?markersFor@DocumentMarkerController@WebCore@@QAE?AV?$Vector@PAVDocumentMarker@WebCore@@$0A@@WTF@@PAVNode@2@VMarkerTypes@DocumentMarker@2@@Z
+        ?nextSibling@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?number@String@WTF@@SA?AV12@I@Z
         ?number@String@WTF@@SA?AV12@H@Z
         ?observeFrame@FrameDestructionObserver@WebCore@@IAEXPAVFrame@2@@Z
@@ -227,6 +230,8 @@ EXPORTS
         ?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVRange@1@@Z
         ?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVNodeList@1@@Z
         ?toRange@WebCore@@YAPAVRange@1@VJSValue@JSC@@@Z
+        ?traverseNextNode@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
+        ?traversePreviousNode@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?updateLayoutIgnorePendingStylesheets@Document@WebCore@@QAEXXZ
         ?userPreferredLanguages@WebCore@@YA?AV?$Vector@VString@WTF@@$0A@@WTF@@XZ
         ?utf8@String@WTF@@QBE?AVCString@2@_N@Z
index 81a43a20ec0326fd60d14774963382c071947617..9ee2ee1718ff0a56cf9f1b5690c3d27fd5de34aa 100644 (file)
@@ -161,6 +161,7 @@ EXPORTS
         ?equalIgnoringCase@WTF@@YA_NPAVStringImpl@1@PBE@Z
         ?externalRepresentation@WebCore@@YA?AVString@WTF@@PAVElement@1@I@Z
         ?find@StringImpl@WTF@@QAEIPAV12@I@Z
+        ?firstChild@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?frameDestroyed@FrameDestructionObserver@WebCore@@UAEXXZ
         ?fromUTF8WithLatin1Fallback@String@WTF@@SA?AV12@PBEI@Z
         ?getCachedDOMStructure@WebCore@@YAPAVStructure@JSC@@PAVJSDOMGlobalObject@1@PBUClassInfo@3@@Z
@@ -173,11 +174,13 @@ EXPORTS
         ?isPreloaded@CachedResourceLoader@WebCore@@QBE_NABVString@WTF@@@Z
         ?jsStringSlowCase@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@AAV?$HashMap@PAVStringImpl@WTF@@V?$Weak@VJSString@JSC@@@JSC@@UStringHash@2@U?$HashTraits@PAVStringImpl@WTF@@@2@U?$HashTraits@V?$Weak@VJSString@JSC@@@JSC@@@2@@WTF@@PAVStringImpl@6@@Z
         ?lastChangeWasUserEdit@HTMLTextFormControlElement@WebCore@@QBE_NXZ
+        ?lastChild@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?markersFor@DocumentMarkerController@WebCore@@QAE?AV?$Vector@PAVDocumentMarker@WebCore@@$0A@@WTF@@PAVNode@2@VMarkerTypes@DocumentMarker@2@@Z
         ?number@String@WTF@@SA?AV12@I@Z
         ?number@String@WTF@@SA?AV12@H@Z
         ?observeFrame@FrameDestructionObserver@WebCore@@IAEXPAVFrame@2@@Z
         ?overrideUserPreferredLanguages@WebCore@@YAXABV?$Vector@VString@WTF@@$0A@@WTF@@@Z
+        ?nextSibling@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?numberOfScopedHTMLStyleChildren@Node@WebCore@@QBEIXZ
         ?page@Document@WebCore@@QBEPAVPage@2@XZ
         ?paintControlTints@FrameView@WebCore@@AAEXXZ
@@ -220,6 +223,8 @@ EXPORTS
         ?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVRange@1@@Z
         ?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVNodeList@1@@Z
         ?toRange@WebCore@@YAPAVRange@1@VJSValue@JSC@@@Z
+        ?traverseNextNode@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
+        ?traversePreviousNode@ReifiedTreeTraversal@WebCore@@SAPAVNode@2@PBV32@@Z
         ?updateLayoutIgnorePendingStylesheets@Document@WebCore@@QAEXXZ
         ?userPreferredLanguages@WebCore@@YA?AV?$Vector@VString@WTF@@$0A@@WTF@@XZ
         ?utf8@String@WTF@@QBE?AVCString@2@_N@Z
index ac7b00cded17fe9b19f582e71374f02c74b1624a..5320e8b34d003a610c3b9f07f8e4157e6c088e75 100644 (file)
@@ -64,6 +64,11 @@ _ZN7WebCore18HTMLContentElement6createEPNS_8DocumentE;
 _ZN7WebCore19InspectorController39setResourcesDataSizeLimitsFromInternalsEii;
 _ZN7WebCore20NodeRenderingContextC1EPNS_4NodeE;
 _ZN7WebCore20NodeRenderingContextD1Ev;
+_ZN7WebCore20ReifiedTreeTraversal11nextSiblingEPKNS_4NodeE;
+_ZN7WebCore20ReifiedTreeTraversal20traversePreviousNodeEPKNS_4NodeE;
+_ZN7WebCore20ReifiedTreeTraversal9lastChildEPKNS_4NodeE;
+_ZN7WebCore20ReifiedTreeTraversal16traverseNextNodeEPKNS_4NodeE;
+_ZN7WebCore20ReifiedTreeTraversal10firstChildEPKNS_4NodeE;
 _ZN7WebCore21getCachedDOMStructureEPNS_17JSDOMGlobalObjectEPKN3JSC9ClassInfoE;
 _ZN7WebCore22externalRepresentationEPNS_7ElementEj;
 _ZN7WebCore22userPreferredLanguagesEv;