Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: Source/core/events/EventPath.cpp

Issue 108723007: Introduce TreeScopeEventContext (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rename SharedEventContext to TreeScopeEventContext Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/events/EventPath.h ('k') | Source/core/events/EventRetargeter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "config.h" 27 #include "config.h"
28 #include "core/events/EventPath.h" 28 #include "core/events/EventPath.h"
29 29
30 #include "EventNames.h" 30 #include "EventNames.h"
31 #include "RuntimeEnabledFeatures.h" 31 #include "RuntimeEnabledFeatures.h"
32 #include "SVGNames.h" 32 #include "SVGNames.h"
33 #include "core/dom/FullscreenElementStack.h" 33 #include "core/dom/FullscreenElementStack.h"
34 #include "core/dom/shadow/ElementShadow.h" 34 #include "core/dom/Touch.h"
35 #include "core/dom/TouchList.h"
35 #include "core/dom/shadow/InsertionPoint.h" 36 #include "core/dom/shadow/InsertionPoint.h"
36 #include "core/dom/shadow/ShadowRoot.h" 37 #include "core/dom/shadow/ShadowRoot.h"
37 #include "core/html/shadow/HTMLShadowElement.h" 38 #include "core/events/FocusEvent.h"
39 #include "core/events/MouseEvent.h"
40 #include "core/events/TouchEvent.h"
38 #include "core/svg/SVGElementInstance.h" 41 #include "core/svg/SVGElementInstance.h"
39 #include "core/svg/SVGUseElement.h" 42 #include "core/svg/SVGUseElement.h"
40 43
41 namespace WebCore { 44 namespace WebCore {
42 45
43 Node* EventPath::parent(Node* node) 46 Node* EventPath::parent(Node* node)
44 { 47 {
45 EventPath eventPath(node); 48 EventPath eventPath(node);
46 return eventPath.size() > 1 ? eventPath[1].node() : 0; 49 return eventPath.size() > 1 ? eventPath[1].node() : 0;
47 } 50 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 , m_event(0) 119 , m_event(0)
117 { 120 {
118 resetWith(node); 121 resetWith(node);
119 } 122 }
120 123
121 void EventPath::resetWith(Node* node) 124 void EventPath::resetWith(Node* node)
122 { 125 {
123 ASSERT(node); 126 ASSERT(node);
124 m_node = node; 127 m_node = node;
125 m_eventContexts.clear(); 128 m_eventContexts.clear();
129 m_sharedEventContexts.clear();
126 calculatePath(); 130 calculatePath();
127 calculateAdjustedTargets(); 131 calculateAdjustedTargets();
128 calculateAdjustedEventPathForEachNode(); 132 calculateAdjustedEventPath();
129 } 133 }
130 134
131 void EventPath::addEventContext(Node* node) 135 void EventPath::addEventContext(Node* node)
132 { 136 {
133 m_eventContexts.append(EventContext(node, eventTargetRespectingTargetRules(n ode))); 137 m_eventContexts.append(EventContext(node, eventTargetRespectingTargetRules(n ode)));
134 } 138 }
135 139
136 void EventPath::calculatePath() 140 void EventPath::calculatePath()
137 { 141 {
138 ASSERT(m_node); 142 ASSERT(m_node);
(...skipping 27 matching lines...) Expand all
166 current = current->shadowHost(); 170 current = current->shadowHost();
167 addEventContext(current); 171 addEventContext(current);
168 } else { 172 } else {
169 current = current->parentNode(); 173 current = current->parentNode();
170 if (current) 174 if (current)
171 addEventContext(current); 175 addEventContext(current);
172 } 176 }
173 } 177 }
174 } 178 }
175 179
176 void EventPath::calculateAdjustedEventPathForEachNode() 180 void EventPath::calculateAdjustedEventPath()
177 { 181 {
178 if (!RuntimeEnabledFeatures::shadowDOMEnabled()) 182 if (!RuntimeEnabledFeatures::shadowDOMEnabled())
179 return; 183 return;
180 TreeScope* lastScope = 0; 184 for (size_t i = 0; i < m_sharedEventContexts.size(); ++i) {
181 for (size_t i = 0; i < size(); ++i) { 185 TreeScopeEventContext* sharedEventContext = m_sharedEventContexts[i].get ();
182 TreeScope* currentScope = &at(i).node()->treeScope();
183 if (currentScope == lastScope) {
184 // Fast path.
185 at(i).setEventPath(at(i - 1).eventPath());
186 continue;
187 }
188 lastScope = currentScope;
189 Vector<RefPtr<Node> > nodes; 186 Vector<RefPtr<Node> > nodes;
190 nodes.reserveInitialCapacity(size()); 187 nodes.reserveInitialCapacity(size());
191 for (size_t j = 0; j < size(); ++j) { 188 for (size_t i = 0; i < size(); ++i) {
192 if (at(j).node()->treeScope().isInclusiveAncestorOf(*currentScope)) 189 if (at(i).node()->treeScope().isInclusiveAncestorOf(sharedEventConte xt->treeScope()))
193 nodes.append(at(j).node()); 190 nodes.append(at(i).node());
194 } 191 }
195 at(i).adoptEventPath(nodes); 192 sharedEventContext->adoptEventPath(nodes);
196 } 193 }
197 } 194 }
198 195
199 #ifndef NDEBUG 196 #ifndef NDEBUG
200 static inline bool movedFromOlderToYounger(const TreeScope& lastTreeScope, const TreeScope& currentTreeScope) 197 static inline bool movedFromOlderToYounger(const TreeScope& lastTreeScope, const TreeScope& currentTreeScope)
201 { 198 {
202 Node* rootNode = lastTreeScope.rootNode(); 199 Node* rootNode = lastTreeScope.rootNode();
203 return rootNode->isShadowRoot() && toShadowRoot(rootNode)->youngerShadowRoot () == currentTreeScope.rootNode(); 200 return rootNode->isShadowRoot() && toShadowRoot(rootNode)->youngerShadowRoot () == currentTreeScope.rootNode();
204 } 201 }
205 202
(...skipping 13 matching lines...) Expand all
219 { 216 {
220 return currentTreeScope.parentTreeScope() == &lastTreeScope; 217 return currentTreeScope.parentTreeScope() == &lastTreeScope;
221 } 218 }
222 219
223 void EventPath::calculateAdjustedTargets() 220 void EventPath::calculateAdjustedTargets()
224 { 221 {
225 Vector<Node*, 32> targetStack; 222 Vector<Node*, 32> targetStack;
226 const TreeScope* lastTreeScope = 0; 223 const TreeScope* lastTreeScope = 0;
227 bool isSVGElement = at(0).node()->isSVGElement(); 224 bool isSVGElement = at(0).node()->isSVGElement();
228 225
226 typedef HashMap<const TreeScope*, RefPtr<TreeScopeEventContext> > SharedEven tContextMap;
227 SharedEventContextMap sharedEventContextMap;
228 TreeScopeEventContext* lastSharedEventContext = 0;
229
229 for (size_t i = 0; i < size(); ++i) { 230 for (size_t i = 0; i < size(); ++i) {
230 Node* current = at(i).node(); 231 Node* current = at(i).node();
231 const TreeScope& currentTreeScope = current->treeScope(); 232 TreeScope& currentTreeScope = current->treeScope();
232 if (targetStack.isEmpty()) { 233 if (targetStack.isEmpty()) {
233 targetStack.append(current); 234 targetStack.append(current);
234 } else if (*lastTreeScope != currentTreeScope && !isSVGElement) { 235 } else if (lastTreeScope != &currentTreeScope && !isSVGElement) {
235 if (movedFromParentToChild(*lastTreeScope, currentTreeScope)) { 236 if (movedFromParentToChild(*lastTreeScope, currentTreeScope)) {
236 targetStack.append(targetStack.last()); 237 targetStack.append(targetStack.last());
237 } else if (movedFromChildToParent(*lastTreeScope, currentTreeScope)) { 238 } else if (movedFromChildToParent(*lastTreeScope, currentTreeScope)) {
238 ASSERT(!targetStack.isEmpty()); 239 ASSERT(!targetStack.isEmpty());
239 targetStack.removeLast(); 240 targetStack.removeLast();
240 if (targetStack.isEmpty()) 241 if (targetStack.isEmpty())
241 targetStack.append(current); 242 targetStack.append(current);
242 } else { 243 } else {
243 ASSERT(movedFromYoungerToOlder(*lastTreeScope, currentTreeScope) || movedFromOlderToYounger(*lastTreeScope, currentTreeScope)); 244 ASSERT(movedFromYoungerToOlder(*lastTreeScope, currentTreeScope) || movedFromOlderToYounger(*lastTreeScope, currentTreeScope));
244 ASSERT(!targetStack.isEmpty()); 245 ASSERT(!targetStack.isEmpty());
245 targetStack.removeLast(); 246 targetStack.removeLast();
246 if (targetStack.isEmpty()) 247 if (targetStack.isEmpty())
247 targetStack.append(current); 248 targetStack.append(current);
248 else 249 else
249 targetStack.append(targetStack.last()); 250 targetStack.append(targetStack.last());
250 } 251 }
251 } 252 }
252 at(i).setTarget(eventTargetRespectingTargetRules(targetStack.last())); 253 if (lastTreeScope != &currentTreeScope) {
254 SharedEventContextMap::AddResult addResult = sharedEventContextMap.a dd(&currentTreeScope, TreeScopeEventContext::create(currentTreeScope));
255 lastSharedEventContext = addResult.iterator->value.get();
256 if (addResult.isNewEntry)
257 lastSharedEventContext->setTarget(eventTargetRespectingTargetRul es(targetStack.last()));
258 }
259 at(i).setSharedEventContext(lastSharedEventContext);
253 lastTreeScope = &currentTreeScope; 260 lastTreeScope = &currentTreeScope;
254 } 261 }
262 m_sharedEventContexts.appendRange(sharedEventContextMap.values().begin(), sh aredEventContextMap.values().end());
263 }
264
265 void EventPath::buildRelatedNodeMap(const Node* relatedNode, RelatedTargetMap& r elatedTargetMap)
266 {
267 TreeScope* lastTreeScope = 0;
268 EventPath eventPath(const_cast<Node*>(relatedNode));
269 for (size_t i = 0; i < eventPath.size(); ++i) {
270 TreeScope* treeScope = &eventPath[i].node()->treeScope();
271 if (treeScope != lastTreeScope)
272 relatedTargetMap.add(treeScope, eventPath[i].target());
273 lastTreeScope = treeScope;
274 }
255 } 275 }
256 276
277 EventTarget* EventPath::findRelatedNode(TreeScope* scope, RelatedTargetMap& rela tedTargetMap)
278 {
279 Vector<TreeScope*, 32> parentTreeScopes;
280 EventTarget* relatedNode = 0;
281 while (scope) {
282 parentTreeScopes.append(scope);
283 RelatedTargetMap::const_iterator found = relatedTargetMap.find(scope);
284 if (found != relatedTargetMap.end()) {
285 relatedNode = found->value;
286 break;
287 }
288 scope = scope->parentTreeScope();
289 }
290 for (Vector<TreeScope*, 32>::iterator iter = parentTreeScopes.begin(); iter < parentTreeScopes.end(); ++iter)
291 relatedTargetMap.add(*iter, relatedNode);
292 return relatedNode;
293 }
294
295 void EventPath::adjustForRelatedTarget(Node* target, EventTarget* relatedTarget)
296 {
297 if (!target)
298 return;
299 if (!relatedTarget)
300 return;
301 Node* relatedNode = relatedTarget->toNode();
302 if (!relatedNode)
303 return;
304 RelatedTargetMap relatedNodeMap;
305 buildRelatedNodeMap(relatedNode, relatedNodeMap);
306
307 for (size_t i = 0; i < m_sharedEventContexts.size(); ++i) {
308 TreeScopeEventContext* sharedEventContext = m_sharedEventContexts[i].get ();
309 sharedEventContext->setRelatedTarget(findRelatedNode(&sharedEventContext ->treeScope(), relatedNodeMap));
310 }
311
312 shrinkIfNeeded(target, relatedTarget);
313 }
314
315 void EventPath::shrinkIfNeeded(const Node* target, const EventTarget* relatedTar get)
316 {
317 // Synthetic mouse events can have a relatedTarget which is identical to the target.
318 bool targetIsIdenticalToToRelatedTarget = (target == relatedTarget);
319
320 for (size_t i = 0; i < size(); ++i) {
321 if (targetIsIdenticalToToRelatedTarget) {
322 if (target->treeScope().rootNode() == at(i).node()) {
323 shrink(i + 1);
324 break;
325 }
326 } else if (at(i).target() == at(i).relatedTarget()) {
327 // Event dispatching should be stopped here.
328 shrink(i);
329 break;
330 }
331 }
332 }
333
334 void EventPath::adjustForTouchEvent(Node* node, TouchEvent& touchEvent)
335 {
336 Vector<TouchList*> adjustedTouches;
337 Vector<TouchList*> adjustedTargetTouches;
338 Vector<TouchList*> adjustedChangedTouches;
339 Vector<TreeScope*> treeScopes;
340
341 for (size_t i = 0; i < m_sharedEventContexts.size(); ++i) {
342 TouchEventContext* touchEventContext = m_sharedEventContexts[i]->ensureT ouchEventContext();
343 adjustedTouches.append(&touchEventContext->touches());
344 adjustedTargetTouches.append(&touchEventContext->targetTouches());
345 adjustedChangedTouches.append(&touchEventContext->changedTouches());
346 treeScopes.append(&m_sharedEventContexts[i]->treeScope());
347 }
348
349 adjustTouchList(node, touchEvent.touches(), adjustedTouches, treeScopes);
350 adjustTouchList(node, touchEvent.targetTouches(), adjustedTargetTouches, tre eScopes);
351 adjustTouchList(node, touchEvent.changedTouches(), adjustedChangedTouches, t reeScopes);
352
353 #ifndef NDEBUG
354 for (size_t i = 0; i < m_sharedEventContexts.size(); ++i) {
355 TreeScope& treeScope = m_sharedEventContexts[i]->treeScope();
356 TouchEventContext* touchEventContext = m_sharedEventContexts[i]->touchEv entContext();
357 checkReachability(treeScope, touchEventContext->touches());
358 checkReachability(treeScope, touchEventContext->targetTouches());
359 checkReachability(treeScope, touchEventContext->changedTouches());
360 }
361 #endif
362 }
363
364 void EventPath::adjustTouchList(const Node* node, const TouchList* touchList, Ve ctor<TouchList*> adjustedTouchList, const Vector<TreeScope*>& treeScopes)
365 {
366 if (!touchList)
367 return;
368 for (size_t i = 0; i < touchList->length(); ++i) {
369 const Touch& touch = *touchList->item(i);
370 RelatedTargetMap relatedNodeMap;
371 buildRelatedNodeMap(touch.target()->toNode(), relatedNodeMap);
372 for (size_t j = 0; j < treeScopes.size(); ++j) {
373 adjustedTouchList[j]->append(touch.cloneWithNewTarget(findRelatedNod e(treeScopes[j], relatedNodeMap)));
374 }
375 }
376 }
377
378 #ifndef NDEBUG
379 void EventPath::checkReachability(TreeScope& treeScope, TouchList& touchList)
380 {
381 for (size_t i = 0; i < touchList.length(); ++i)
382 ASSERT(touchList.item(i)->target()->toNode()->treeScope().isInclusiveAnc estorOf(treeScope));
383 }
384 #endif
385
257 } // namespace 386 } // namespace
OLDNEW
« no previous file with comments | « Source/core/events/EventPath.h ('k') | Source/core/events/EventRetargeter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698