Title: [211139] trunk
Revision
211139
Author
[email protected]
Date
2017-01-25 01:11:52 -0800 (Wed, 25 Jan 2017)

Log Message

collectMatchingElementsInFlatTree should not find elements inside an user agent shadow tree
https://bugs.webkit.org/show_bug.cgi?id=167409

Reviewed by Antti Koivisto.

Source/_javascript_Core:

Added matchingElementInFlatTree as a common identifier since it's required in the bindings code.

* runtime/CommonIdentifiers.h:

Source/WebCore:

The bug was caused by collectMatchingElementsInFlatTree including elements inside an user agent shadow tree
even though it shouldn't. Fixed the bug by checking that condition.

Also added matchingElementInFlatTree to find the first element matching a selector as opposed to all,
again, only exposed in a world which forces all shadow trees to be accessible.

* page/DOMWindow.cpp:
(WebCore::selectorQueryInFrame):
(WebCore::DOMWindow::collectMatchingElementsInFlatTree):
(WebCore::DOMWindow::matchingElementInFlatTree):
* page/DOMWindow.h:
* page/DOMWindow.idl:

Tools:

Added a test case for collectMatchingElementsInFlatTree not finding elements inside an user agent shadow tree
as well as tests for the newly added matchingElementInFlatTree.

* TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp:
(TestWebKitAPI::runJavaScriptAlert):
* TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp:
(TestWebKitAPI::InjectedBundleMakeAllShadowRootOpenTest::initialize):
* TestWebKitAPI/Tests/WebKit2/closed-shadow-tree-test.html:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (211138 => 211139)


--- trunk/Source/_javascript_Core/ChangeLog	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-01-25 09:11:52 UTC (rev 211139)
@@ -1,3 +1,14 @@
+2017-01-25  Ryosuke Niwa  <[email protected]>
+
+        collectMatchingElementsInFlatTree should not find elements inside an user agent shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=167409
+
+        Reviewed by Antti Koivisto.
+
+        Added matchingElementInFlatTree as a common identifier since it's required in the bindings code.
+
+        * runtime/CommonIdentifiers.h:
+
 2017-01-24  Joseph Pecoraro  <[email protected]>
 
         Fold USER_TIMING into WEB_TIMING and make it a RuntimeEnabledFeature

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (211138 => 211139)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2017-01-25 09:11:52 UTC (rev 211139)
@@ -280,6 +280,7 @@
     macro(valueOf) \
     macro(webkit) \
     macro(collectMatchingElementsInFlatTree) \
+    macro(matchingElementInFlatTree) \
     macro(webkitIDBCursor) \
     macro(webkitIDBDatabase) \
     macro(webkitIDBFactory) \

Modified: trunk/Source/WebCore/ChangeLog (211138 => 211139)


--- trunk/Source/WebCore/ChangeLog	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Source/WebCore/ChangeLog	2017-01-25 09:11:52 UTC (rev 211139)
@@ -1,3 +1,23 @@
+2017-01-25  Ryosuke Niwa  <[email protected]>
+
+        collectMatchingElementsInFlatTree should not find elements inside an user agent shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=167409
+
+        Reviewed by Antti Koivisto.
+
+        The bug was caused by collectMatchingElementsInFlatTree including elements inside an user agent shadow tree
+        even though it shouldn't. Fixed the bug by checking that condition.
+
+        Also added matchingElementInFlatTree to find the first element matching a selector as opposed to all,
+        again, only exposed in a world which forces all shadow trees to be accessible.
+
+        * page/DOMWindow.cpp:
+        (WebCore::selectorQueryInFrame):
+        (WebCore::DOMWindow::collectMatchingElementsInFlatTree):
+        (WebCore::DOMWindow::matchingElementInFlatTree):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl:
+
 2017-01-24  Alex Christensen  <[email protected]>
 
         REGRESSION (r208902): URLWithUserTypedString returns nil with file URLs

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (211138 => 211139)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2017-01-25 09:11:52 UTC (rev 211139)
@@ -623,16 +623,21 @@
     return *m_customElementRegistry;
 }
 
-ExceptionOr<Ref<NodeList>> DOMWindow::collectMatchingElementsInFlatTree(Node& scope, const String& selectors)
+static ExceptionOr<SelectorQuery&> selectorQueryInFrame(Frame* frame, const String& selectors)
 {
-    if (!m_frame)
+    if (!frame)
         return Exception { NOT_SUPPORTED_ERR };
 
-    Document* document = m_frame->document();
+    Document* document = frame->document();
     if (!document)
         return Exception { NOT_SUPPORTED_ERR };
 
-    auto queryOrException = document->selectorQueryForString(selectors);
+    return document->selectorQueryForString(selectors);
+}
+
+ExceptionOr<Ref<NodeList>> DOMWindow::collectMatchingElementsInFlatTree(Node& scope, const String& selectors)
+{
+    auto queryOrException = selectorQueryInFrame(m_frame, selectors);
     if (queryOrException.hasException())
         return queryOrException.releaseException();
 
@@ -643,7 +648,7 @@
 
     Vector<Ref<Element>> result;
     for (auto& node : composedTreeDescendants(downcast<ContainerNode>(scope))) {
-        if (is<Element>(node) && query.matches(downcast<Element>(node)))
+        if (is<Element>(node) && query.matches(downcast<Element>(node)) && !node.isInUserAgentShadowTree())
             result.append(downcast<Element>(node));
     }
 
@@ -650,6 +655,25 @@
     return Ref<NodeList> { StaticElementList::create(WTFMove(result)) };
 }
 
+ExceptionOr<RefPtr<Element>> DOMWindow::matchingElementInFlatTree(Node& scope, const String& selectors)
+{
+    auto queryOrException = selectorQueryInFrame(m_frame, selectors);
+    if (queryOrException.hasException())
+        return queryOrException.releaseException();
+
+    if (!is<ContainerNode>(scope))
+        return RefPtr<Element> { nullptr };
+
+    SelectorQuery& query = queryOrException.releaseReturnValue();
+
+    for (auto& node : composedTreeDescendants(downcast<ContainerNode>(scope))) {
+        if (is<Element>(node) && query.matches(downcast<Element>(node)) && !node.isInUserAgentShadowTree())
+            return &downcast<Element>(node);
+    }
+
+    return RefPtr<Element> { nullptr };
+}
+
 #if ENABLE(ORIENTATION_EVENTS)
 
 int DOMWindow::orientation() const

Modified: trunk/Source/WebCore/page/DOMWindow.h (211138 => 211139)


--- trunk/Source/WebCore/page/DOMWindow.h	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Source/WebCore/page/DOMWindow.h	2017-01-25 09:11:52 UTC (rev 211139)
@@ -278,6 +278,7 @@
     CustomElementRegistry& ensureCustomElementRegistry();
 
     ExceptionOr<Ref<NodeList>> collectMatchingElementsInFlatTree(Node&, const String& selectors);
+    ExceptionOr<RefPtr<Element>> matchingElementInFlatTree(Node&, const String& selectors);
 
 #if ENABLE(ORIENTATION_EVENTS)
     // This is the interface orientation in degrees. Some examples are:

Modified: trunk/Source/WebCore/page/DOMWindow.idl (211138 => 211139)


--- trunk/Source/WebCore/page/DOMWindow.idl	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Source/WebCore/page/DOMWindow.idl	2017-01-25 09:11:52 UTC (rev 211139)
@@ -177,6 +177,8 @@
 
     [MayThrowException, EnabledForWorld=shadowRootIsAlwaysOpen]
     NodeList collectMatchingElementsInFlatTree(Node scope, DOMString selectors);
+    [MayThrowException, EnabledForWorld=shadowRootIsAlwaysOpen]
+    Element? matchingElementInFlatTree(Node scope, DOMString selectors);
 
     // Event handlers unique to Element and DOMWindow.
     // FIXME: Should these be exposed on Document as well (and therefore moved to GlobalEventHandlers.idl)?

Modified: trunk/Tools/ChangeLog (211138 => 211139)


--- trunk/Tools/ChangeLog	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Tools/ChangeLog	2017-01-25 09:11:52 UTC (rev 211139)
@@ -1,3 +1,19 @@
+2017-01-25  Ryosuke Niwa  <[email protected]>
+
+        collectMatchingElementsInFlatTree should not find elements inside an user agent shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=167409
+
+        Reviewed by Antti Koivisto.
+
+        Added a test case for collectMatchingElementsInFlatTree not finding elements inside an user agent shadow tree
+        as well as tests for the newly added matchingElementInFlatTree.
+
+        * TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp:
+        (TestWebKitAPI::runJavaScriptAlert):
+        * TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp:
+        (TestWebKitAPI::InjectedBundleMakeAllShadowRootOpenTest::initialize):
+        * TestWebKitAPI/Tests/WebKit2/closed-shadow-tree-test.html:
+
 2017-01-24  Carlos Garcia Campos  <[email protected]>
 
         [GTK] Add API to create ephemeral web views and deprecate the private browsing setting

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp (211138 => 211139)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp	2017-01-25 09:11:52 UTC (rev 211139)
@@ -50,10 +50,10 @@
         EXPECT_WK_STREQ("PASS: shadowRoot created by normal world", alertText);
         break;
     case 3:
-        EXPECT_WK_STREQ("PASS: query method exists", alertText);
+        EXPECT_WK_STREQ("PASS: collectMatchingElementsInFlatTree exists", alertText);
         break;
     case 4:
-        EXPECT_WK_STREQ("PASS: query method was not present in the normal world", alertText);
+        EXPECT_WK_STREQ("PASS: collectMatchingElementsInFlatTree was not present in the normal world", alertText);
         break;
     case 5:
         EXPECT_WK_STREQ("Found:1,2,3,4,5,6", alertText);
@@ -60,6 +60,24 @@
         break;
     case 6:
         EXPECT_WK_STREQ("Found:2,3,4", alertText);
+        break;
+    case 7:
+        EXPECT_WK_STREQ("PASS: matchingElementInFlatTree exists", alertText);
+        break;
+    case 8:
+        EXPECT_WK_STREQ("PASS: matchingElementInFlatTree was not present in the normal world", alertText);
+        break;
+    case 9:
+        EXPECT_WK_STREQ("Found:1", alertText);
+        break;
+    case 10:
+        EXPECT_WK_STREQ("Found:2", alertText);
+        break;
+    case 11:
+        EXPECT_WK_STREQ("Found:0 divs", alertText);
+        break;
+    case 12:
+        EXPECT_WK_STREQ("Found:false", alertText);
         done = true;
         break;
     }

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp (211138 => 211139)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp	2017-01-25 09:11:52 UTC (rev 211139)
@@ -60,9 +60,9 @@
             // Test 2
             "    alert(document.querySelector('shadow-host').shadowRoot ? 'PASS: shadowRoot created by normal world' : 'FAIL');\n"
             // Test 3
-            "    alert(window[queryMethodName] ? 'PASS: query method exists' : 'FAIL');\n"
+            "    alert(window[queryMethodName] ? `PASS: ${queryMethodName} exists` : `FAIL: ${queryMethodName} does not exist`);\n"
             // Test 4
-            "    document.dispatchEvent(new Event('testnormalworld'));\n"
+            "    document.dispatchEvent(new CustomEvent('testnormalworld', {detail: queryMethodName}));\n"
             // Test 5
             "    const queryMethod = window[queryMethodName];\n"
             "    let queryResult = Array.from(queryMethod(document, 'span'));\n"
@@ -71,6 +71,21 @@
             "    const innerHost = queryMethod(document, 'inner-host')[0];\n"
             "    queryResult = Array.from(queryMethod(innerHost, 'span'));\n"
             "    alert('Found:' + queryResult.map((span) => span.textContent).join(','));\n"
+            // Test 7
+            "    alert(window.matchingElementInFlatTree ? `PASS: matchingElementInFlatTree exists` : `FAIL: matchingElementInFlatTree does not exist`);\n"
+            // Test 8
+            "    document.dispatchEvent(new CustomEvent('testnormalworld', {detail: 'matchingElementInFlatTree'}));\n"
+            // Test 9
+            "    queryResult = window.matchingElementInFlatTree(document, 'span');\n"
+            "    alert('Found:' + (queryResult ? queryResult.textContent : 'null'));\n"
+            // Test 10
+            "    queryResult = window.matchingElementInFlatTree(innerHost, 'span');\n"
+            "    alert('Found:' + (queryResult ? queryResult.textContent : 'null'));\n"
+            // Test 11
+            "    alert(`Found:${queryMethod(document, 'div').length} divs`);\n"
+            // Test 12
+            "    queryResult = window.matchingElementInFlatTree(document, 'div');\n"
+            "    alert(`Found:${!!queryResult}`);\n"
             "}\n"));
         WKBundleAddUserScript(bundle, pageGroup, world, source.get(), 0, 0, 0, kWKInjectAtDocumentStart, kWKInjectInAllFrames);
     }

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2/closed-shadow-tree-test.html (211138 => 211139)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/closed-shadow-tree-test.html	2017-01-25 08:01:08 UTC (rev 211138)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/closed-shadow-tree-test.html	2017-01-25 09:11:52 UTC (rev 211139)
@@ -2,6 +2,7 @@
 <html>
 <body>
 <shadow-host><span>5</span><span slot="bar">2</span></shadow-host>
+<input type="text">
 <script>
 const shadowRoot = document.querySelector('shadow-host').attachShadow({mode: 'closed'});
 shadowRoot.innerHTML = `
@@ -18,9 +19,8 @@
     <slot name="foo"></slot>
     <span>4</span>`;
 
-document.addEventListener('testnormalworld', function () {
-    alert(window.collectMatchingElementsInFlatTree ?
-        'FAIL' : 'PASS: query method was not present in the normal world');
+document.addEventListener('testnormalworld', function (event) {
+    alert(window[event.detail] ? `FAIL: ${event.detail} was present in the normal world` : `PASS: ${event.detail} was not present in the normal world`);
 });
 
 </script>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to