Changeset 124291 in webkit
- Timestamp:
- Jul 31, 2012, 8:41:50 PM (14 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
dom/EventDispatcher.cpp (modified) (5 diffs)
-
dom/EventDispatcher.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r124290 r124291 1 2012-07-31 Hayato Ito <hayato@chromium.org> 2 3 Refactor EventDispatcher::dispatchEvent() so that we can call each phase (Caputure, Target and Bubbling) of event dispatching separately. 4 https://bugs.webkit.org/show_bug.cgi?id=92621 5 6 Reviewed by Dimitri Glazkov. 7 8 This is one of the required refactorings to support event 9 propagation for seamless iframes. I've removed 'goto' statements 10 from EventDispatcher::dispatchEvent() as a result. 11 12 I've verified that all separated functions are successfully 13 inlined. I could not see any performance regression. The 14 benchmark result is: 15 16 Before this patch: 17 % ./Tools/Scripts/run-perf-tests PerformanceTests/DOM/Events.html 18 Running 1 tests 19 Running DOM/Events.html (1 of 1) 20 RESULT DOM: Events= 243.986607143 ms 21 median= 242.297619048 ms, stdev= 5.74748351315 ms, min= 239.80952381 ms, max= 268.0 ms 22 23 After this patch: 24 % ./Tools/Scripts/run-perf-tests PerformanceTests/DOM/Events.html 25 Running 1 tests 26 Running DOM/Events.html (1 of 1) 27 RESULT DOM: Events= 242.291666667 ms 28 median= 240.452380952 ms, stdev= 5.8718643632 ms, min= 238.214285714 ms, max= 266.5 ms 29 30 No new tests, no behavior change. 31 32 * dom/EventDispatcher.cpp: 33 (WebCore::EventDispatcher::dispatchEvent): 34 (WebCore::EventDispatcher::dispatchEventPreProcess): 35 (WebCore): 36 (WebCore::EventDispatcher::dispatchEventAtCapturing): 37 (WebCore::EventDispatcher::dispatchEventAtTarget): 38 (WebCore::EventDispatcher::dispatchEventAtBubbling): 39 (WebCore::EventDispatcher::dispatchEventPostProcess): 40 (WebCore::EventDispatcher::topEventContext): 41 * dom/EventDispatcher.h: 42 (WebCore): 43 (EventDispatcher): 44 1 45 2012-07-31 Yoshifumi Inoue <yosin@chromium.org> 2 46 -
trunk/Source/WebCore/dom/EventDispatcher.cpp
r124019 r124291 237 237 } 238 238 239 bool EventDispatcher::dispatchEvent(PassRefPtr<Event> event) 240 { 239 bool EventDispatcher::dispatchEvent(PassRefPtr<Event> prpEvent) 240 { 241 RefPtr<Event> event = prpEvent; 241 242 event->setTarget(eventTargetRespectingSVGTargetRules(m_node.get())); 242 243 243 ASSERT(!eventDispatchForbidden()); 244 244 ASSERT(event->target()); 245 245 ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null. 246 247 RefPtr<EventTarget> originalTarget = event->target();248 246 ensureEventAncestors(event.get()); 249 250 WindowEventContext windowContext(event.get(), m_node.get(), topEventContext()); 251 252 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowContext.window(), m_node.get(), m_ancestors); 253 247 WindowEventContext windowEventContext(event.get(), m_node.get(), topEventContext()); 248 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowEventContext.window(), m_node.get(), m_ancestors); 249 250 void* preDispatchEventHandlerResult; 251 if (dispatchEventPreProcess(event, preDispatchEventHandlerResult) == ContinueDispatching) 252 if (dispatchEventAtCapturing(event, windowEventContext) == ContinueDispatching) 253 if (dispatchEventAtTarget(event) == ContinueDispatching) 254 dispatchEventAtBubbling(event, windowEventContext); 255 dispatchEventPostProcess(event, preDispatchEventHandlerResult); 256 257 // Ensure that after event dispatch, the event's target object is the 258 // outermost shadow DOM boundary. 259 event->setTarget(windowEventContext.target()); 260 event->setCurrentTarget(0); 261 InspectorInstrumentation::didDispatchEvent(cookie); 262 263 return !event->defaultPrevented(); 264 } 265 266 inline EventDispatchContinuation EventDispatcher::dispatchEventPreProcess(PassRefPtr<Event> event, void*& preDispatchEventHandlerResult) 267 { 254 268 // Give the target node a chance to do some work before DOM event handlers get a crack. 255 void* data = m_node->preDispatchEventHandler(event.get()); 256 if (m_ancestors.isEmpty() || event->propagationStopped()) 257 goto doneDispatching; 258 269 preDispatchEventHandlerResult = m_node->preDispatchEventHandler(event.get()); 270 return (m_ancestors.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching; 271 } 272 273 inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing(PassRefPtr<Event> event, WindowEventContext& windowEventContext) 274 { 259 275 // Trigger capturing event handlers, starting at the top and working our way down. 260 276 event->setEventPhase(Event::CAPTURING_PHASE); 261 277 262 if (window Context.handleLocalEvents(event.get()) && event->propagationStopped())263 goto doneDispatching;278 if (windowEventContext.handleLocalEvents(event.get()) && event->propagationStopped()) 279 return DoneDispatching; 264 280 265 281 for (size_t i = m_ancestors.size() - 1; i > 0; --i) { … … 273 289 eventContext.handleLocalEvents(event.get()); 274 290 if (event->propagationStopped()) 275 goto doneDispatching; 276 } 277 291 return DoneDispatching; 292 } 293 294 return ContinueDispatching; 295 } 296 297 inline EventDispatchContinuation EventDispatcher::dispatchEventAtTarget(PassRefPtr<Event> event) 298 { 278 299 event->setEventPhase(Event::AT_TARGET); 279 300 m_ancestors[0].handleLocalEvents(event.get()); 280 if (event->propagationStopped()) 281 goto doneDispatching; 282 301 return event->propagationStopped() ? DoneDispatching : ContinueDispatching; 302 } 303 304 inline EventDispatchContinuation EventDispatcher::dispatchEventAtBubbling(PassRefPtr<Event> event, WindowEventContext& windowContext) 305 { 283 306 if (event->bubbles() && !event->cancelBubble()) { 284 307 // Trigger bubbling event handlers, starting at the bottom and working our way up. … … 294 317 eventContext.handleLocalEvents(event.get()); 295 318 if (event->propagationStopped() || event->cancelBubble()) 296 goto doneDispatching;319 return DoneDispatching; 297 320 } 298 321 windowContext.handleLocalEvents(event.get()); 299 322 } 300 301 doneDispatching: 302 event->setTarget(originalTarget.get()); 323 return ContinueDispatching; 324 } 325 326 inline void EventDispatcher::dispatchEventPostProcess(PassRefPtr<Event> event, void* preDispatchEventHandlerResult) 327 { 328 event->setTarget(eventTargetRespectingSVGTargetRules(m_node.get())); 303 329 event->setCurrentTarget(0); 304 330 event->setEventPhase(0); 305 331 306 332 // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler. 307 m_node->postDispatchEventHandler(event.get(), data);333 m_node->postDispatchEventHandler(event.get(), preDispatchEventHandlerResult); 308 334 309 335 // Call default event handlers. While the DOM does have a concept of preventing … … 315 341 ASSERT(!event->defaultPrevented()); 316 342 if (event->defaultHandled()) 317 goto doneWithDefault;343 return; 318 344 // For bubbling events, call default event handlers on the same targets in the 319 345 // same order as the bubbling phase. … … 324 350 ASSERT(!event->defaultPrevented()); 325 351 if (event->defaultHandled()) 326 goto doneWithDefault;352 return; 327 353 } 328 354 } 329 355 } 330 331 doneWithDefault:332 333 // Ensure that after event dispatch, the event's target object is the334 // outermost shadow DOM boundary.335 event->setTarget(windowContext.target());336 event->setCurrentTarget(0);337 InspectorInstrumentation::didDispatchEvent(cookie);338 339 return !event->defaultPrevented();340 356 } 341 357 -
trunk/Source/WebCore/dom/EventDispatcher.h
r124019 r124291 43 43 class ShadowRoot; 44 44 class TreeScope; 45 class WindowEventContext; 45 46 46 47 enum EventDispatchBehavior { 47 48 RetargetEvent, 48 49 StayInsideShadowDOM 50 }; 51 52 enum EventDispatchContinuation { 53 ContinueDispatching, 54 DoneDispatching 49 55 }; 50 56 … … 81 87 const EventContext* topEventContext(); 82 88 89 EventDispatchContinuation dispatchEventPreProcess(PassRefPtr<Event>, void*& preDispatchEventHandlerResult); 90 EventDispatchContinuation dispatchEventAtCapturing(PassRefPtr<Event>, WindowEventContext&); 91 EventDispatchContinuation dispatchEventAtTarget(PassRefPtr<Event>); 92 EventDispatchContinuation dispatchEventAtBubbling(PassRefPtr<Event>, WindowEventContext&); 93 void dispatchEventPostProcess(PassRefPtr<Event>, void* preDispatchEventHandlerResult); 94 83 95 Vector<EventContext> m_ancestors; 84 96 RefPtr<Node> m_node;
Note:
See TracChangeset
for help on using the changeset viewer.