⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 211139 in webkit


Ignore:
Timestamp:
Jan 25, 2017, 1:11:52 AM (10 years ago)
Author:
rniwa@webkit.org
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/JavaScriptCore:

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:
Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r211133 r211139  
     12017-01-25  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        collectMatchingElementsInFlatTree should not find elements inside an user agent shadow tree
     4        https://bugs.webkit.org/show_bug.cgi?id=167409
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Added matchingElementInFlatTree as a common identifier since it's required in the bindings code.
     9
     10        * runtime/CommonIdentifiers.h:
     11
    1122017-01-24  Joseph Pecoraro  <pecoraro@apple.com>
    213
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r211133 r211139  
    281281    macro(webkit) \
    282282    macro(collectMatchingElementsInFlatTree) \
     283    macro(matchingElementInFlatTree) \
    283284    macro(webkitIDBCursor) \
    284285    macro(webkitIDBDatabase) \
  • trunk/Source/WebCore/ChangeLog

    r211137 r211139  
     12017-01-25  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        collectMatchingElementsInFlatTree should not find elements inside an user agent shadow tree
     4        https://bugs.webkit.org/show_bug.cgi?id=167409
     5
     6        Reviewed by Antti Koivisto.
     7
     8        The bug was caused by collectMatchingElementsInFlatTree including elements inside an user agent shadow tree
     9        even though it shouldn't. Fixed the bug by checking that condition.
     10
     11        Also added matchingElementInFlatTree to find the first element matching a selector as opposed to all,
     12        again, only exposed in a world which forces all shadow trees to be accessible.
     13
     14        * page/DOMWindow.cpp:
     15        (WebCore::selectorQueryInFrame):
     16        (WebCore::DOMWindow::collectMatchingElementsInFlatTree):
     17        (WebCore::DOMWindow::matchingElementInFlatTree):
     18        * page/DOMWindow.h:
     19        * page/DOMWindow.idl:
     20
    1212017-01-24  Alex Christensen  <achristensen@webkit.org>
    222
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r211036 r211139  
    624624}
    625625
    626 ExceptionOr<Ref<NodeList>> DOMWindow::collectMatchingElementsInFlatTree(Node& scope, const String& selectors)
    627 {
    628     if (!m_frame)
     626static ExceptionOr<SelectorQuery&> selectorQueryInFrame(Frame* frame, const String& selectors)
     627{
     628    if (!frame)
    629629        return Exception { NOT_SUPPORTED_ERR };
    630630
    631     Document* document = m_frame->document();
     631    Document* document = frame->document();
    632632    if (!document)
    633633        return Exception { NOT_SUPPORTED_ERR };
    634634
    635     auto queryOrException = document->selectorQueryForString(selectors);
     635    return document->selectorQueryForString(selectors);
     636}
     637
     638ExceptionOr<Ref<NodeList>> DOMWindow::collectMatchingElementsInFlatTree(Node& scope, const String& selectors)
     639{
     640    auto queryOrException = selectorQueryInFrame(m_frame, selectors);
    636641    if (queryOrException.hasException())
    637642        return queryOrException.releaseException();
     
    644649    Vector<Ref<Element>> result;
    645650    for (auto& node : composedTreeDescendants(downcast<ContainerNode>(scope))) {
    646         if (is<Element>(node) && query.matches(downcast<Element>(node)))
     651        if (is<Element>(node) && query.matches(downcast<Element>(node)) && !node.isInUserAgentShadowTree())
    647652            result.append(downcast<Element>(node));
    648653    }
    649654
    650655    return Ref<NodeList> { StaticElementList::create(WTFMove(result)) };
     656}
     657
     658ExceptionOr<RefPtr<Element>> DOMWindow::matchingElementInFlatTree(Node& scope, const String& selectors)
     659{
     660    auto queryOrException = selectorQueryInFrame(m_frame, selectors);
     661    if (queryOrException.hasException())
     662        return queryOrException.releaseException();
     663
     664    if (!is<ContainerNode>(scope))
     665        return RefPtr<Element> { nullptr };
     666
     667    SelectorQuery& query = queryOrException.releaseReturnValue();
     668
     669    for (auto& node : composedTreeDescendants(downcast<ContainerNode>(scope))) {
     670        if (is<Element>(node) && query.matches(downcast<Element>(node)) && !node.isInUserAgentShadowTree())
     671            return &downcast<Element>(node);
     672    }
     673
     674    return RefPtr<Element> { nullptr };
    651675}
    652676
  • trunk/Source/WebCore/page/DOMWindow.h

    r211033 r211139  
    279279
    280280    ExceptionOr<Ref<NodeList>> collectMatchingElementsInFlatTree(Node&, const String& selectors);
     281    ExceptionOr<RefPtr<Element>> matchingElementInFlatTree(Node&, const String& selectors);
    281282
    282283#if ENABLE(ORIENTATION_EVENTS)
  • trunk/Source/WebCore/page/DOMWindow.idl

    r210797 r211139  
    178178    [MayThrowException, EnabledForWorld=shadowRootIsAlwaysOpen]
    179179    NodeList collectMatchingElementsInFlatTree(Node scope, DOMString selectors);
     180    [MayThrowException, EnabledForWorld=shadowRootIsAlwaysOpen]
     181    Element? matchingElementInFlatTree(Node scope, DOMString selectors);
    180182
    181183    // Event handlers unique to Element and DOMWindow.
  • trunk/Tools/ChangeLog

    r211138 r211139  
     12017-01-25  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        collectMatchingElementsInFlatTree should not find elements inside an user agent shadow tree
     4        https://bugs.webkit.org/show_bug.cgi?id=167409
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Added a test case for collectMatchingElementsInFlatTree not finding elements inside an user agent shadow tree
     9        as well as tests for the newly added matchingElementInFlatTree.
     10
     11        * TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp:
     12        (TestWebKitAPI::runJavaScriptAlert):
     13        * TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp:
     14        (TestWebKitAPI::InjectedBundleMakeAllShadowRootOpenTest::initialize):
     15        * TestWebKitAPI/Tests/WebKit2/closed-shadow-tree-test.html:
     16
    1172017-01-24  Carlos Garcia Campos  <cgarcia@igalia.com>
    218
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp

    r208878 r211139  
    5151        break;
    5252    case 3:
    53         EXPECT_WK_STREQ("PASS: query method exists", alertText);
     53        EXPECT_WK_STREQ("PASS: collectMatchingElementsInFlatTree exists", alertText);
    5454        break;
    5555    case 4:
    56         EXPECT_WK_STREQ("PASS: query method was not present in the normal world", alertText);
     56        EXPECT_WK_STREQ("PASS: collectMatchingElementsInFlatTree was not present in the normal world", alertText);
    5757        break;
    5858    case 5:
     
    6161    case 6:
    6262        EXPECT_WK_STREQ("Found:2,3,4", alertText);
     63        break;
     64    case 7:
     65        EXPECT_WK_STREQ("PASS: matchingElementInFlatTree exists", alertText);
     66        break;
     67    case 8:
     68        EXPECT_WK_STREQ("PASS: matchingElementInFlatTree was not present in the normal world", alertText);
     69        break;
     70    case 9:
     71        EXPECT_WK_STREQ("Found:1", alertText);
     72        break;
     73    case 10:
     74        EXPECT_WK_STREQ("Found:2", alertText);
     75        break;
     76    case 11:
     77        EXPECT_WK_STREQ("Found:0 divs", alertText);
     78        break;
     79    case 12:
     80        EXPECT_WK_STREQ("Found:false", alertText);
    6381        done = true;
    6482        break;
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen_Bundle.cpp

    r208878 r211139  
    6161            "    alert(document.querySelector('shadow-host').shadowRoot ? 'PASS: shadowRoot created by normal world' : 'FAIL');\n"
    6262            // Test 3
    63             "    alert(window[queryMethodName] ? 'PASS: query method exists' : 'FAIL');\n"
     63            "    alert(window[queryMethodName] ? `PASS: ${queryMethodName} exists` : `FAIL: ${queryMethodName} does not exist`);\n"
    6464            // Test 4
    65             "    document.dispatchEvent(new Event('testnormalworld'));\n"
     65            "    document.dispatchEvent(new CustomEvent('testnormalworld', {detail: queryMethodName}));\n"
    6666            // Test 5
    6767            "    const queryMethod = window[queryMethodName];\n"
     
    7272            "    queryResult = Array.from(queryMethod(innerHost, 'span'));\n"
    7373            "    alert('Found:' + queryResult.map((span) => span.textContent).join(','));\n"
     74            // Test 7
     75            "    alert(window.matchingElementInFlatTree ? `PASS: matchingElementInFlatTree exists` : `FAIL: matchingElementInFlatTree does not exist`);\n"
     76            // Test 8
     77            "    document.dispatchEvent(new CustomEvent('testnormalworld', {detail: 'matchingElementInFlatTree'}));\n"
     78            // Test 9
     79            "    queryResult = window.matchingElementInFlatTree(document, 'span');\n"
     80            "    alert('Found:' + (queryResult ? queryResult.textContent : 'null'));\n"
     81            // Test 10
     82            "    queryResult = window.matchingElementInFlatTree(innerHost, 'span');\n"
     83            "    alert('Found:' + (queryResult ? queryResult.textContent : 'null'));\n"
     84            // Test 11
     85            "    alert(`Found:${queryMethod(document, 'div').length} divs`);\n"
     86            // Test 12
     87            "    queryResult = window.matchingElementInFlatTree(document, 'div');\n"
     88            "    alert(`Found:${!!queryResult}`);\n"
    7489            "}\n"));
    7590        WKBundleAddUserScript(bundle, pageGroup, world, source.get(), 0, 0, 0, kWKInjectAtDocumentStart, kWKInjectInAllFrames);
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2/closed-shadow-tree-test.html

    r208878 r211139  
    33<body>
    44<shadow-host><span>5</span><span slot="bar">2</span></shadow-host>
     5<input type="text">
    56<script>
    67const shadowRoot = document.querySelector('shadow-host').attachShadow({mode: 'closed'});
     
    1920    <span>4</span>`;
    2021
    21 document.addEventListener('testnormalworld', function () {
    22     alert(window.collectMatchingElementsInFlatTree ?
    23         'FAIL' : 'PASS: query method was not present in the normal world');
     22document.addEventListener('testnormalworld', function (event) {
     23    alert(window[event.detail] ? `FAIL: ${event.detail} was present in the normal world` : `PASS: ${event.detail} was not present in the normal world`);
    2424});
    2525
Note: See TracChangeset for help on using the changeset viewer.