Changeset 121079 in webkit


Ignore:
Timestamp:
Jun 22, 2012 5:31:02 PM (12 years ago)
Author:
hayato@chromium.org
Message:

[Shadow] ShadowRoot.activeElement should use the result of re-targeting algorithm.
https://bugs.webkit.org/show_bug.cgi?id=89763

Reviewed by Dimitri Glazkov.

Source/WebCore:

Use the result of the re-targeting algorithm in calculating
shadow root's activeElement so that ShadowRoot.activeElement returns
a focused distributed node correctly as the algorithm says.

The spec is:
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#active-element

Tests: fast/dom/shadow/shadow-root-activeElement.html

  • dom/EventDispatcher.cpp:

(WebCore):
(WebCore::EventRelatedTargetAdjuster::adjust):
(WebCore::EventDispatcher::ensureEventAncestors):

  • dom/TreeScope.cpp:

(WebCore::TreeScope::focusedNode):

  • html/shadow/InsertionPoint.h:

(WebCore::InsertionPoint::contains):

LayoutTests:

  • fast/dom/shadow/shadow-root-activeElement-expected.txt:
  • fast/dom/shadow/shadow-root-activeElement.html:
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r121077 r121079  
     12012-06-22  Hayato Ito  <hayato@chromium.org>
     2
     3        [Shadow] ShadowRoot.activeElement should use the result of re-targeting algorithm.
     4        https://bugs.webkit.org/show_bug.cgi?id=89763
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        * fast/dom/shadow/shadow-root-activeElement-expected.txt:
     9        * fast/dom/shadow/shadow-root-activeElement.html:
     10
    1112012-06-22  Kenneth Russell  <kbr@google.com>
    212
  • trunk/LayoutTests/fast/dom/shadow/shadow-root-activeElement-expected.txt

    r110810 r121079  
    44
    55
    6 
    7 PASS shadowRoot.activeElement is defined.
    8 PASS shadowRootInside.activeElement is defined.
    9 PASS childInBody.focus();document.activeElement is childInBody
    10 PASS childInBody.focus();shadowRoot.activeElement is null
    11 PASS childInBody.focus();shadowRootInside.activeElement is null
    12 PASS childInTreeOne.focus();document.activeElement is shadowHost
    13 PASS childInTreeOne.focus();shadowRoot.activeElement is childInTreeOne
    14 PASS childInTreeOne.focus();shadowRootInside.activeElement is null
    15 PASS childInTreeTwo.focus();document.activeElement is shadowHost
    16 PASS childInTreeTwo.focus();shadowRoot.activeElement is shadowHostInside
    17 PASS childInTreeTwo.focus();shadowRootInside.activeElement is childInTreeTwo
    18 childInTreeTwo.blur();
     6PASS shadowRoot1.activeElement is defined.
     7PASS shadowRoot2.activeElement is defined.
     8PASS nodeInDocument.focus(); document.activeElement is nodeInDocument
     9PASS nodeInDocument.focus(); shadowRoot1.activeElement is null
     10PASS nodeInDocument.focus(); shadowRoot2.activeElement is null
     11PASS distributedLightChild.focus(); document.activeElement is distributedLightChild
     12PASS distributedLightChild.focus(); shadowRoot1.activeElement is distributedLightChild
     13PASS distributedLightChild.focus(); shadowRoot2.activeElement is null
     14PASS childInShadowRoot1.focus(); document.activeElement is shadowHost1
     15PASS childInShadowRoot1.focus(); shadowRoot1.activeElement is childInShadowRoot1
     16PASS childInShadowRoot1.focus(); shadowRoot2.activeElement is null
     17PASS childInShadowRoot2.focus(); document.activeElement is shadowHost1
     18PASS childInShadowRoot2.focus(); shadowRoot1.activeElement is shadowHost2
     19PASS childInShadowRoot2.focus(); shadowRoot2.activeElement is childInShadowRoot2
     20childInShadowRoot2.blur();
    1921PASS document.activeElement is document.body
    20 PASS shadowRoot.activeElement is null
    21 PASS shadowRootInside.activeElement is null
     22PASS shadowRoot1.activeElement is null
     23PASS shadowRoot2.activeElement is null
    2224PASS successfullyParsed is true
    2325
  • trunk/LayoutTests/fast/dom/shadow/shadow-root-activeElement.html

    r120792 r121079  
    33<head>
    44<script src="../../js/resources/js-test-pre.js"></script>
     5<script src="resources/shadow-dom.js"></script>
    56</head>
    67<body>
    7 <div id="console">
     8<div id="console"></div>
     9<div id="sandbox">
    810</div>
    911<script>
     
    1618    testRunner.dumpAsText();
    1719
    18 var childInBody = document.createElement("p");
    19 childInBody.tabIndex = "1";
    20 document.body.appendChild(childInBody);
     20document.getElementById('sandbox').appendChild(
     21    createDOM('div', {},
     22              createDOM('div', {'id': 'node-in-document', 'tabindex': 1}),
     23              createDOM('div', {'id': 'shadow-host-1'},
     24                        createShadowRoot(
     25                            createDOM('div', {'id': 'shadow-host-2'},
     26                                      createShadowRoot(
     27                                          createDOM('div', {'id': 'child-in-shadow-root-2', 'tabindex': 1}))),
     28                            createDOM('div', {'id': 'child-in-shadow-root-1', 'tabindex': 1}),
     29                            createDOM('content', {'select': '#distributed-light-child'})),
     30                        createDOM('div', {'id': 'distributed-light-child', 'tabindex': 1}))));
    2131
    22 // First ShodowHost
    23 var shadowHost = document.createElement("div");
    24 document.body.appendChild(shadowHost);
    25 var shadowRoot = new WebKitShadowRoot(shadowHost);
     32var shadowHost1 = getNodeInShadowTreeStack('shadow-host-1');
     33var shadowHost2 = getNodeInShadowTreeStack('shadow-host-1/shadow-host-2');
     34var shadowRoot1 = getNodeInShadowTreeStack('shadow-host-1/');
     35var shadowRoot2 = getNodeInShadowTreeStack('shadow-host-1/shadow-host-2/');
    2636
    27 // Second ShadowHost
    28 shadowHostInside = document.createElement("div");
    29 shadowRoot.appendChild(shadowHostInside);
    30 var shadowRootInside = new WebKitShadowRoot(shadowHostInside);
     37var nodeInDocument = document.getElementById('node-in-document');
     38var distributedLightChild = document.getElementById('distributed-light-child');
     39var childInShadowRoot1 = getNodeInShadowTreeStack('shadow-host-1/child-in-shadow-root-1');
     40var childInShadowRoot2 = getNodeInShadowTreeStack('shadow-host-1/shadow-host-2/child-in-shadow-root-2');
    3141
    32 // Add a child inside first Shadow host
    33 var childInTreeOne = document.createElement("p");
    34 childInTreeOne.setAttribute("id", "childInTreeOne");
    35 childInTreeOne.tabIndex = "1";
    36 shadowRoot.appendChild(childInTreeOne);
     42shouldBeDefined("shadowRoot1.activeElement");
     43shouldBeDefined("shadowRoot2.activeElement");
    3744
    38 // Add a child inside second shadow host
    39 var childInTreeTwo = document.createElement("p");
    40 childInTreeTwo.setAttribute("id", "childInTreeTwo");
    41 childInTreeTwo.tabIndex = "1";
    42 shadowRootInside.appendChild(childInTreeTwo);
     45shouldBe("nodeInDocument.focus(); document.activeElement", "nodeInDocument");
     46shouldBe("nodeInDocument.focus(); shadowRoot1.activeElement", "null");
     47shouldBe("nodeInDocument.focus(); shadowRoot2.activeElement", "null");
    4348
    44 shouldBeDefined("shadowRoot.activeElement");
    45 shouldBeDefined("shadowRootInside.activeElement");
     49shouldBe("distributedLightChild.focus(); document.activeElement", "distributedLightChild");
     50shouldBe("distributedLightChild.focus(); shadowRoot1.activeElement", "distributedLightChild");
     51shouldBe("distributedLightChild.focus(); shadowRoot2.activeElement", "null");
    4652
    47 shouldBe("childInBody.focus();document.activeElement", "childInBody");
    48 shouldBe("childInBody.focus();shadowRoot.activeElement", "null");
    49 shouldBe("childInBody.focus();shadowRootInside.activeElement", "null");
     53shouldBe("childInShadowRoot1.focus(); document.activeElement", "shadowHost1");
     54shouldBe("childInShadowRoot1.focus(); shadowRoot1.activeElement", "childInShadowRoot1");
     55shouldBe("childInShadowRoot1.focus(); shadowRoot2.activeElement", "null");
    5056
    51 shouldBe("childInTreeOne.focus();document.activeElement", "shadowHost");
    52 shouldBe("childInTreeOne.focus();shadowRoot.activeElement", "childInTreeOne");
    53 shouldBe("childInTreeOne.focus();shadowRootInside.activeElement", "null");
     57shouldBe("childInShadowRoot2.focus(); document.activeElement", "shadowHost1");
     58shouldBe("childInShadowRoot2.focus(); shadowRoot1.activeElement", "shadowHost2");
     59shouldBe("childInShadowRoot2.focus(); shadowRoot2.activeElement", "childInShadowRoot2");
    5460
    55 shouldBe("childInTreeTwo.focus();document.activeElement", "shadowHost");
    56 shouldBe("childInTreeTwo.focus();shadowRoot.activeElement", "shadowHostInside");
    57 shouldBe("childInTreeTwo.focus();shadowRootInside.activeElement", "childInTreeTwo");
    58 
    59 evalAndLog("childInTreeTwo.blur();");
     61evalAndLog("childInShadowRoot2.blur();");
    6062shouldBe("document.activeElement", "document.body");
    61 shouldBe("shadowRoot.activeElement", "null");
    62 shouldBe("shadowRootInside.activeElement", "null");
     63shouldBe("shadowRoot1.activeElement", "null");
     64shouldBe("shadowRoot2.activeElement", "null");
    6365
    6466var successfullyParsed = true;
  • trunk/Source/WebCore/ChangeLog

    r121076 r121079  
     12012-06-22  Hayato Ito  <hayato@chromium.org>
     2
     3        [Shadow] ShadowRoot.activeElement should use the result of re-targeting algorithm.
     4        https://bugs.webkit.org/show_bug.cgi?id=89763
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        Use the result of the re-targeting algorithm in calculating
     9        shadow root's activeElement so that ShadowRoot.activeElement returns
     10        a focused distributed node correctly as the algorithm says.
     11
     12        The spec is:
     13        https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#active-element
     14
     15        Tests: fast/dom/shadow/shadow-root-activeElement.html
     16
     17        * dom/EventDispatcher.cpp:
     18        (WebCore):
     19        (WebCore::EventRelatedTargetAdjuster::adjust):
     20        (WebCore::EventDispatcher::ensureEventAncestors):
     21        * dom/TreeScope.cpp:
     22        (WebCore::TreeScope::focusedNode):
     23        * html/shadow/InsertionPoint.h:
     24        (WebCore::InsertionPoint::contains):
     25
    1262012-06-22  James Robinson  <jamesr@chromium.org>
    227
  • trunk/Source/WebCore/dom/EventDispatcher.cpp

    r121040 r121079  
    5252static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;
    5353
    54 static inline bool isAssignedTo(const Node* node, const InsertionPoint* insertionPoint)
    55 {
    56     ASSERT(insertionPoint);
    57     return node && (insertionPoint->contains(node) || (node->isShadowRoot() && toShadowRoot(node)->assignedTo() == insertionPoint));
    58 }
    59 
    6054EventRelatedTargetAdjuster::EventRelatedTargetAdjuster(PassRefPtr<Node> node, PassRefPtr<Node> relatedTarget)
    6155    : m_node(node)
     
    7569        if (relatedTargetStack.isEmpty())
    7670            relatedTargetStack.append(node);
    77         else if (isInsertionPoint(node) && isAssignedTo(lastNode, toInsertionPoint(node)))
     71        else if (isInsertionPoint(node) && toInsertionPoint(node)->contains(lastNode))
    7872            relatedTargetStack.append(relatedTargetStack.last());
    7973        TreeScope* scope = node->treeScope();
     
    227221        if (targetStack.isEmpty())
    228222            targetStack.append(eventTargetRespectingSVGTargetRules(node));
    229         else if (isInsertionPoint(node) && isAssignedTo(last, toInsertionPoint(node)))
     223        else if (isInsertionPoint(node) && toInsertionPoint(node)->contains(last))
    230224            targetStack.append(targetStack.last());
    231225        m_ancestors.append(EventContext(node, eventTargetRespectingSVGTargetRules(node), targetStack.last()));
  • trunk/Source/WebCore/dom/TreeScope.cpp

    r120168 r121079  
    2727#include "TreeScope.h"
    2828
     29#include "ComposedShadowTreeWalker.h"
    2930#include "ContainerNode.h"
    3031#include "ContextFeatures.h"
     
    3940#include "HTMLMapElement.h"
    4041#include "HTMLNames.h"
     42#include "InsertionPoint.h"
    4143#include "Page.h"
    4244#include "ShadowRoot.h"
     
    225227    if (!node)
    226228        return 0;
    227 
    228     TreeScope* treeScope = node->treeScope();
    229 
    230     while (treeScope != this && treeScope != document) {
    231         node = toShadowRoot(treeScope->rootNode())->host();
    232         treeScope = node->treeScope();
    233     }
    234     if (this != treeScope)
    235         return 0;
    236 
    237     return node;
     229    Vector<Node*> targetStack;
     230    Node* last = 0;
     231    for (ComposedShadowTreeParentWalker walker(node); walker.get(); walker.parentIncludingInsertionPointAndShadowRoot()) {
     232        Node* node = walker.get();
     233        if (targetStack.isEmpty())
     234            targetStack.append(node);
     235        else if (isInsertionPoint(node) && toInsertionPoint(node)->contains(last))
     236            targetStack.append(targetStack.last());
     237        if (node == rootNode())
     238            return targetStack.last();
     239        last = node;
     240        if (node->isShadowRoot()) {
     241            ASSERT(!targetStack.isEmpty());
     242            targetStack.removeLast();
     243        }
     244    }
     245    return 0;
    238246}
    239247
  • trunk/Source/WebCore/html/shadow/InsertionPoint.h

    r120754 r121079  
    3535#include "HTMLElement.h"
    3636#include "HTMLNames.h"
     37#include "ShadowRoot.h"
    3738#include <wtf/Forward.h>
    3839
     
    5859
    5960    size_t indexOf(Node* node) const { return m_distribution.find(node); }
    60     bool contains(const Node* node) const { return m_distribution.contains(const_cast<Node*>(node)); }
     61    bool contains(const Node* node) const { return m_distribution.contains(const_cast<Node*>(node)) || (node->isShadowRoot() && toShadowRoot(node)->assignedTo() == this); }
    6162    size_t size() const { return m_distribution.size(); }
    6263    Node* at(size_t index)  const { return m_distribution.at(index).get(); }
Note: See TracChangeset for help on using the changeset viewer.