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 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "core/dom/TreeScope.h" | 33 #include "core/dom/TreeScope.h" |
34 #include "core/dom/shadow/ShadowRoot.h" | 34 #include "core/dom/shadow/ShadowRoot.h" |
35 #include "wtf/PassRefPtr.h" | 35 #include "wtf/PassRefPtr.h" |
36 #include "wtf/RefPtr.h" | 36 #include "wtf/RefPtr.h" |
37 #include "wtf/Vector.h" | 37 #include "wtf/Vector.h" |
38 | 38 |
39 namespace WebCore { | 39 namespace WebCore { |
40 | 40 |
41 static inline bool inTheSameScope(ShadowRoot* shadowRoot, EventTarget* target) | 41 static inline bool inTheSameScope(ShadowRoot* shadowRoot, EventTarget* target) |
42 { | 42 { |
43 return target->toNode() && target->toNode()->treeScope().rootNode() == shado
wRoot; | 43 return target->toNode() && target->toNode()->treeScope()->rootNode() == shad
owRoot; |
44 } | 44 } |
45 | 45 |
46 static inline EventDispatchBehavior determineDispatchBehavior(Event* event, Shad
owRoot* shadowRoot, EventTarget* target) | 46 static inline EventDispatchBehavior determineDispatchBehavior(Event* event, Shad
owRoot* shadowRoot, EventTarget* target) |
47 { | 47 { |
48 // Video-only full screen is a mode where we use the shadow DOM as an implem
entation | 48 // Video-only full screen is a mode where we use the shadow DOM as an implem
entation |
49 // detail that should not be detectable by the web content. | 49 // detail that should not be detectable by the web content. |
50 if (Element* element = FullscreenElementStack::currentFullScreenElementFrom(
&target->toNode()->document())) { | 50 if (Element* element = FullscreenElementStack::currentFullScreenElementFrom(
&target->toNode()->document())) { |
51 // FIXME: We assume that if the full screen element is a media element t
hat it's | 51 // FIXME: We assume that if the full screen element is a media element t
hat it's |
52 // the video-only full screen. Both here and elsewhere. But that is prob
ably wrong. | 52 // the video-only full screen. Both here and elsewhere. But that is prob
ably wrong. |
53 if (element->isMediaElement() && shadowRoot && shadowRoot->host() == ele
ment) | 53 if (element->isMediaElement() && shadowRoot && shadowRoot->host() == ele
ment) |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 void EventRetargeter::calculateAdjustedEventPathForEachNode(EventPath& eventPath
) | 116 void EventRetargeter::calculateAdjustedEventPathForEachNode(EventPath& eventPath
) |
117 { | 117 { |
118 if (!RuntimeEnabledFeatures::shadowDOMEnabled()) | 118 if (!RuntimeEnabledFeatures::shadowDOMEnabled()) |
119 return; | 119 return; |
120 TreeScope* lastScope = 0; | 120 TreeScope* lastScope = 0; |
121 size_t eventPathSize = eventPath.size(); | 121 size_t eventPathSize = eventPath.size(); |
122 for (size_t i = 0; i < eventPathSize; ++i) { | 122 for (size_t i = 0; i < eventPathSize; ++i) { |
123 TreeScope* currentScope = &eventPath[i]->node()->treeScope(); | 123 NonNullPtr<TreeScope> currentScope = eventPath[i]->node()->treeScope(); |
124 if (currentScope == lastScope) { | 124 if (currentScope == lastScope) { |
125 // Fast path. | 125 // Fast path. |
126 eventPath[i]->setEventPath(eventPath[i - 1]->eventPath()); | 126 eventPath[i]->setEventPath(eventPath[i - 1]->eventPath()); |
127 continue; | 127 continue; |
128 } | 128 } |
129 lastScope = currentScope; | 129 lastScope = currentScope.get(); |
130 Vector<RefPtr<Node> > nodes; | 130 Vector<RefPtr<Node> > nodes; |
131 for (size_t j = 0; j < eventPathSize; ++j) { | 131 for (size_t j = 0; j < eventPathSize; ++j) { |
132 Node* node = eventPath[j]->node(); | 132 Node* node = eventPath[j]->node(); |
133 if (node->treeScope().isInclusiveAncestorOf(*currentScope)) | 133 if (node->treeScope()->isInclusiveAncestorOf(currentScope)) |
134 nodes.append(node); | 134 nodes.append(node); |
135 } | 135 } |
136 eventPath[i]->adoptEventPath(nodes); | 136 eventPath[i]->adoptEventPath(nodes); |
137 } | 137 } |
138 } | 138 } |
139 | 139 |
140 void EventRetargeter::adjustForMouseEvent(Node* node, MouseEvent& mouseEvent) | 140 void EventRetargeter::adjustForMouseEvent(Node* node, MouseEvent& mouseEvent) |
141 { | 141 { |
142 adjustForRelatedTarget(node, mouseEvent.relatedTarget(), mouseEvent.eventPat
h()); | 142 adjustForRelatedTarget(node, mouseEvent.relatedTarget(), mouseEvent.eventPat
h()); |
143 } | 143 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 { | 208 { |
209 RelatedNodeMap relatedNodeMap; | 209 RelatedNodeMap relatedNodeMap; |
210 buildRelatedNodeMap(relatedNode, relatedNodeMap); | 210 buildRelatedNodeMap(relatedNode, relatedNodeMap); |
211 | 211 |
212 // Synthetic mouse events can have a relatedTarget which is identical to the
target. | 212 // Synthetic mouse events can have a relatedTarget which is identical to the
target. |
213 bool targetIsIdenticalToToRelatedTarget = (node == relatedNode); | 213 bool targetIsIdenticalToToRelatedTarget = (node == relatedNode); |
214 | 214 |
215 TreeScope* lastTreeScope = 0; | 215 TreeScope* lastTreeScope = 0; |
216 Node* adjustedNode = 0; | 216 Node* adjustedNode = 0; |
217 for (EventPath::const_iterator iter = eventPath.begin(); iter < eventPath.en
d(); ++iter) { | 217 for (EventPath::const_iterator iter = eventPath.begin(); iter < eventPath.en
d(); ++iter) { |
218 TreeScope* scope = &(*iter)->node()->treeScope(); | 218 NonNullPtr<TreeScope> scope = (*iter)->node()->treeScope(); |
219 if (scope == lastTreeScope) { | 219 if (scope == lastTreeScope) { |
220 // Re-use the previous adjustedRelatedTarget if treeScope does not c
hange. Just for the performance optimization. | 220 // Re-use the previous adjustedRelatedTarget if treeScope does not c
hange. Just for the performance optimization. |
221 adjustedNodes.append(adjustedNode); | 221 adjustedNodes.append(adjustedNode); |
222 } else { | 222 } else { |
223 adjustedNode = findRelatedNode(scope, relatedNodeMap); | 223 adjustedNode = findRelatedNode(scope.get(), relatedNodeMap); |
224 adjustedNodes.append(adjustedNode); | 224 adjustedNodes.append(adjustedNode); |
225 } | 225 } |
226 lastTreeScope = scope; | 226 lastTreeScope = scope.get(); |
227 if (eventWithRelatedTargetDispatchBehavior == DoesNotStopAtBoundary) | 227 if (eventWithRelatedTargetDispatchBehavior == DoesNotStopAtBoundary) |
228 continue; | 228 continue; |
229 if (targetIsIdenticalToToRelatedTarget) { | 229 if (targetIsIdenticalToToRelatedTarget) { |
230 if (node->treeScope().rootNode() == (*iter)->node()) { | 230 if (node->treeScope()->rootNode() == (*iter)->node()) { |
231 eventPath.shrink(iter + 1 - eventPath.begin()); | 231 eventPath.shrink(iter + 1 - eventPath.begin()); |
232 break; | 232 break; |
233 } | 233 } |
234 } else if ((*iter)->target() == adjustedNode) { | 234 } else if ((*iter)->target() == adjustedNode) { |
235 // Event dispatching should be stopped here. | 235 // Event dispatching should be stopped here. |
236 eventPath.shrink(iter - eventPath.begin()); | 236 eventPath.shrink(iter - eventPath.begin()); |
237 adjustedNodes.shrink(adjustedNodes.size() - 1); | 237 adjustedNodes.shrink(adjustedNodes.size() - 1); |
238 break; | 238 break; |
239 } | 239 } |
240 } | 240 } |
241 } | 241 } |
242 | 242 |
243 void EventRetargeter::buildRelatedNodeMap(const Node* relatedNode, RelatedNodeMa
p& relatedNodeMap) | 243 void EventRetargeter::buildRelatedNodeMap(const Node* relatedNode, RelatedNodeMa
p& relatedNodeMap) |
244 { | 244 { |
245 Vector<Node*, 32> relatedNodeStack; | 245 Vector<Node*, 32> relatedNodeStack; |
246 TreeScope* lastTreeScope = 0; | 246 TreeScope* lastTreeScope = 0; |
247 for (EventPathWalker walker(relatedNode); walker.node(); walker.moveToParent
()) { | 247 for (EventPathWalker walker(relatedNode); walker.node(); walker.moveToParent
()) { |
248 Node* node = walker.node(); | 248 Node* node = walker.node(); |
249 if (relatedNodeStack.isEmpty()) | 249 if (relatedNodeStack.isEmpty()) |
250 relatedNodeStack.append(node); | 250 relatedNodeStack.append(node); |
251 else if (walker.isVisitingInsertionPointInReprojection()) | 251 else if (walker.isVisitingInsertionPointInReprojection()) |
252 relatedNodeStack.append(relatedNodeStack.last()); | 252 relatedNodeStack.append(relatedNodeStack.last()); |
253 TreeScope* scope = &node->treeScope(); | 253 NonNullPtr<TreeScope> scope = node->treeScope(); |
254 // Skips adding a node to the map if treeScope does not change. Just for
the performance optimization. | 254 // Skips adding a node to the map if treeScope does not change. Just for
the performance optimization. |
255 if (scope != lastTreeScope) | 255 if (scope != lastTreeScope) |
256 relatedNodeMap.add(scope, relatedNodeStack.last()); | 256 relatedNodeMap.add(scope.get(), relatedNodeStack.last()); |
257 lastTreeScope = scope; | 257 lastTreeScope = scope.get(); |
258 if (node->isShadowRoot()) { | 258 if (node->isShadowRoot()) { |
259 ASSERT(!relatedNodeStack.isEmpty()); | 259 ASSERT(!relatedNodeStack.isEmpty()); |
260 relatedNodeStack.removeLast(); | 260 relatedNodeStack.removeLast(); |
261 } | 261 } |
262 } | 262 } |
263 } | 263 } |
264 | 264 |
265 Node* EventRetargeter::findRelatedNode(TreeScope* scope, RelatedNodeMap& related
NodeMap) | 265 Node* EventRetargeter::findRelatedNode(TreeScope* scope, RelatedNodeMap& related
NodeMap) |
266 { | 266 { |
267 Vector<TreeScope*, 32> parentTreeScopes; | 267 Vector<TreeScope*, 32> parentTreeScopes; |
268 Node* relatedNode = 0; | 268 Node* relatedNode = 0; |
269 while (scope) { | 269 while (scope) { |
270 parentTreeScopes.append(scope); | 270 parentTreeScopes.append(scope); |
271 RelatedNodeMap::const_iterator found = relatedNodeMap.find(scope); | 271 RelatedNodeMap::const_iterator found = relatedNodeMap.find(scope); |
272 if (found != relatedNodeMap.end()) { | 272 if (found != relatedNodeMap.end()) { |
273 relatedNode = found->value; | 273 relatedNode = found->value; |
274 break; | 274 break; |
275 } | 275 } |
276 scope = scope->parentTreeScope(); | 276 scope = scope->parentTreeScope(); |
277 } | 277 } |
278 for (Vector<TreeScope*, 32>::iterator iter = parentTreeScopes.begin(); iter
< parentTreeScopes.end(); ++iter) | 278 for (Vector<TreeScope*, 32>::iterator iter = parentTreeScopes.begin(); iter
< parentTreeScopes.end(); ++iter) |
279 relatedNodeMap.add(*iter, relatedNode); | 279 relatedNodeMap.add(*iter, relatedNode); |
280 return relatedNode; | 280 return relatedNode; |
281 } | 281 } |
282 | 282 |
283 } | 283 } |
OLD | NEW |