Index: Source/core/events/TreeScopeEventContext.cpp |
diff --git a/Source/core/events/TreeScopeEventContext.cpp b/Source/core/events/TreeScopeEventContext.cpp |
index 22a8cacb23a3b54757233f7eefefd745981e005d..ee5a34f633e112599887f8c342bfdccc938995a1 100644 |
--- a/Source/core/events/TreeScopeEventContext.cpp |
+++ b/Source/core/events/TreeScopeEventContext.cpp |
@@ -34,6 +34,29 @@ |
namespace blink { |
+bool TreeScopeEventContext::isUnclosedTreeOf(const TreeScopeEventContext& other) |
+{ |
+ // Exclude closed nodes if necessary. |
+ // If a node is in a closed shadow root, or in a tree whose ancestor has a closed shadow root, |
+ // it should not be visible to nodes above the closed shadow root. |
+ |
+ // (1) If |this| is an ancestor of |other| in tree-of-trees, include it. |
+ if (isInclusiveAncestorOf(other)) |
+ return true; |
+ |
+ // (2) If no closed shadow root in ancestors of this, include it. |
+ if (!containingClosedShadowTree()) |
+ return true; |
+ |
+ // (3) If |this| is descendent of |other|, exclude if any closed shadow root in between. |
+ if (isDescendantOf(other)) |
+ return !containingClosedShadowTree()->isDescendantOf(other); |
+ |
+ // (4) |this| and |other| must be in exclusive branches. |
+ ASSERT(other.isExclusivePartOf(*this)); |
+ return false; |
+} |
+ |
WillBeHeapVector<RefPtrWillBeMember<EventTarget>>& TreeScopeEventContext::ensureEventPath(EventPath& path) |
{ |
if (m_eventPath) |
@@ -42,11 +65,9 @@ WillBeHeapVector<RefPtrWillBeMember<EventTarget>>& TreeScopeEventContext::ensure |
m_eventPath = adoptPtrWillBeNoop(new WillBeHeapVector<RefPtrWillBeMember<EventTarget>>()); |
LocalDOMWindow* window = path.windowEventContext().window(); |
m_eventPath->reserveCapacity(path.size() + (window ? 1 : 0)); |
+ |
for (size_t i = 0; i < path.size(); ++i) { |
- Node& rootNode = path[i].treeScopeEventContext().rootNode(); |
- if (rootNode.isShadowRoot() && (toShadowRoot(rootNode).type() == ShadowRootType::OpenByDefault || toShadowRoot(rootNode).type() == ShadowRootType::Open)) |
- m_eventPath->append(path[i].node()); |
- else if (path[i].treeScopeEventContext().isInclusiveAncestorOf(*this)) |
+ if (path[i].treeScopeEventContext().isUnclosedTreeOf(*this)) |
m_eventPath->append(path[i].node()); |
} |
if (window) |
@@ -69,6 +90,7 @@ PassRefPtrWillBeRawPtr<TreeScopeEventContext> TreeScopeEventContext::create(Tree |
TreeScopeEventContext::TreeScopeEventContext(TreeScope& treeScope) |
: m_treeScope(treeScope) |
, m_rootNode(treeScope.rootNode()) |
+ , m_containingClosedShadowTree(nullptr) |
, m_preOrder(-1) |
, m_postOrder(-1) |
{ |
@@ -84,18 +106,21 @@ DEFINE_TRACE(TreeScopeEventContext) |
visitor->trace(m_relatedTarget); |
visitor->trace(m_eventPath); |
visitor->trace(m_touchEventContext); |
+ visitor->trace(m_containingClosedShadowTree); |
#if ENABLE(OILPAN) |
visitor->trace(m_children); |
#endif |
} |
-int TreeScopeEventContext::calculatePrePostOrderNumber(int orderNumber) |
+int TreeScopeEventContext::calculateTreeOrderAndSetNearestAncestorClosedTree(int orderNumber, TreeScopeEventContext* nearestAncestorClosedTreeScopeEventContext) |
{ |
m_preOrder = orderNumber; |
+ m_containingClosedShadowTree = (rootNode().isShadowRoot() && !toShadowRoot(rootNode()).isOpen()) ? this : nearestAncestorClosedTreeScopeEventContext; |
for (size_t i = 0; i < m_children.size(); ++i) |
- orderNumber = m_children[i]->calculatePrePostOrderNumber(orderNumber + 1); |
+ orderNumber = m_children[i]->calculateTreeOrderAndSetNearestAncestorClosedTree(orderNumber + 1, containingClosedShadowTree()); |
m_postOrder = orderNumber + 1; |
+ |
return orderNumber + 1; |
} |
-} |
+} // namespace blink |