OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Neither the name of Google Inc. nor the names of its | 10 * * Neither the name of Google Inc. nor the names of its |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 m_nodeEventContexts.clear(); | 75 m_nodeEventContexts.clear(); |
76 m_treeScopeEventContexts.clear(); | 76 m_treeScopeEventContexts.clear(); |
77 initialize(); | 77 initialize(); |
78 } | 78 } |
79 | 79 |
80 static inline bool eventPathShouldBeEmptyFor(Node& node, Event* event) | 80 static inline bool eventPathShouldBeEmptyFor(Node& node, Event* event) |
81 { | 81 { |
82 if (node.isPseudoElement() && !node.parentElement()) | 82 if (node.isPseudoElement() && !node.parentElement()) |
83 return true; | 83 return true; |
84 | 84 |
85 // Do not dispatch non-composed events in SVG use trees. | |
86 if (node.isSVGElement()) { | |
87 if (toSVGElement(node).inUseShadowTree() && event && !event->composed()) | |
88 return true; | |
89 } | |
90 | |
91 return false; | 85 return false; |
92 } | 86 } |
93 | 87 |
94 void EventPath::initialize() | 88 void EventPath::initialize() |
95 { | 89 { |
96 if (eventPathShouldBeEmptyFor(*m_node, m_event)) | 90 if (eventPathShouldBeEmptyFor(*m_node, m_event)) |
97 return; | 91 return; |
98 | 92 |
99 calculatePath(); | 93 calculatePath(); |
100 calculateAdjustedTargets(); | 94 calculateAdjustedTargets(); |
101 calculateTreeOrderAndSetNearestAncestorClosedTree(); | 95 calculateTreeOrderAndSetNearestAncestorClosedTree(); |
102 } | 96 } |
103 | 97 |
104 void EventPath::calculatePath() | 98 void EventPath::calculatePath() |
105 { | 99 { |
106 ASSERT(m_node); | 100 ASSERT(m_node); |
107 ASSERT(m_nodeEventContexts.isEmpty()); | 101 ASSERT(m_nodeEventContexts.isEmpty()); |
108 m_node->updateDistribution(); | 102 m_node->updateDistribution(); |
109 | 103 |
110 // For performance and memory usage reasons we want to store the | 104 // For performance and memory usage reasons we want to store the |
111 // path using as few bytes as possible and with as few allocations | 105 // path using as few bytes as possible and with as few allocations |
112 // as possible which is why we gather the data on the stack before | 106 // as possible which is why we gather the data on the stack before |
113 // storing it in a perfectly sized m_nodeEventContexts Vector. | 107 // storing it in a perfectly sized m_nodeEventContexts Vector. |
114 HeapVector<Member<Node>, 64> nodesInPath; | 108 HeapVector<Member<Node>, 64> nodesInPath; |
115 Node* current = m_node; | 109 Node* current = m_node; |
116 | 110 |
117 // Exclude nodes in SVG <use>'s shadow tree from event path. | |
118 // See crbug.com/630870 | |
119 while (current->isSVGElement()) { | |
120 SVGUseElement* correspondingUseElement = toSVGElement(current)->correspo
ndingUseElement(); | |
121 if (!correspondingUseElement) | |
122 break; | |
123 current = correspondingUseElement; | |
124 } | |
125 | |
126 nodesInPath.append(current); | 111 nodesInPath.append(current); |
127 while (current) { | 112 while (current) { |
128 if (m_event && current->keepEventInNode(m_event)) | 113 if (m_event && current->keepEventInNode(m_event)) |
129 break; | 114 break; |
130 HeapVector<Member<InsertionPoint>, 8> insertionPoints; | 115 HeapVector<Member<InsertionPoint>, 8> insertionPoints; |
131 collectDestinationInsertionPoints(*current, insertionPoints); | 116 collectDestinationInsertionPoints(*current, insertionPoints); |
132 if (!insertionPoints.isEmpty()) { | 117 if (!insertionPoints.isEmpty()) { |
133 for (const auto& insertionPoint : insertionPoints) { | 118 for (const auto& insertionPoint : insertionPoints) { |
134 if (insertionPoint->isShadowInsertionPoint()) { | 119 if (insertionPoint->isShadowInsertionPoint()) { |
135 ShadowRoot* containingShadowRoot = insertionPoint->containin
gShadowRoot(); | 120 ShadowRoot* containingShadowRoot = insertionPoint->containin
gShadowRoot(); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 DEFINE_TRACE(EventPath) | 368 DEFINE_TRACE(EventPath) |
384 { | 369 { |
385 visitor->trace(m_nodeEventContexts); | 370 visitor->trace(m_nodeEventContexts); |
386 visitor->trace(m_node); | 371 visitor->trace(m_node); |
387 visitor->trace(m_event); | 372 visitor->trace(m_event); |
388 visitor->trace(m_treeScopeEventContexts); | 373 visitor->trace(m_treeScopeEventContexts); |
389 visitor->trace(m_windowEventContext); | 374 visitor->trace(m_windowEventContext); |
390 } | 375 } |
391 | 376 |
392 } // namespace blink | 377 } // namespace blink |
OLD | NEW |