bool EventDispatcher::dispatch() { #ifndef NDEBUG ASSERT(!m_eventDispatched); m_eventDispatched = true; #endif ChildNodesLazySnapshot::takeChildNodesLazySnapshot(); m_event->setTarget(EventRetargeter::eventTargetRespectingTargetRules(m_node.get())); ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); ASSERT(m_event->target()); WindowEventContext windowEventContext(m_event.get(), m_node.get(), topEventContext()); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *m_event, windowEventContext.window(), m_node.get(), m_eventPath); void* preDispatchEventHandlerResult; if (dispatchEventPreProcess(preDispatchEventHandlerResult) == ContinueDispatching) if (dispatchEventAtCapturing(windowEventContext) == ContinueDispatching) if (dispatchEventAtTarget() == ContinueDispatching) dispatchEventAtBubbling(windowEventContext); dispatchEventPostProcess(preDispatchEventHandlerResult); // Ensure that after event dispatch, the event's target object is the // outermost shadow DOM boundary. m_event->setTarget(windowEventContext.target()); m_event->setCurrentTarget(0); InspectorInstrumentation::didDispatchEvent(cookie); return !m_event->defaultPrevented(); }
bool EventDispatcher::dispatchEvent(PassRefPtr<Event> prpEvent) { #ifndef NDEBUG ASSERT(!m_eventDispatched); m_eventDispatched = true; #endif RefPtr<Event> event = prpEvent; ChildNodesLazySnapshot::takeChildNodesLazySnapshot(); event->setTarget(eventTargetRespectingTargetRules(m_node.get())); ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); ASSERT(event->target()); ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null. ensureEventAncestors(event.get()); WindowEventContext windowEventContext(event.get(), m_node.get(), topEventContext()); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowEventContext.window(), m_node.get(), m_ancestors); void* preDispatchEventHandlerResult; if (dispatchEventPreProcess(event, preDispatchEventHandlerResult) == ContinueDispatching) if (dispatchEventAtCapturing(event, windowEventContext) == ContinueDispatching) if (dispatchEventAtTarget(event) == ContinueDispatching) dispatchEventAtBubbling(event, windowEventContext); dispatchEventPostProcess(event, preDispatchEventHandlerResult); // Ensure that after event dispatch, the event's target object is the // outermost shadow DOM boundary. event->setTarget(windowEventContext.target()); event->setCurrentTarget(0); InspectorInstrumentation::didDispatchEvent(cookie); return !event->defaultPrevented(); }
bool EventDispatcher::dispatch() { TRACE_EVENT0("webkit", "EventDispatcher::dispatch"); #ifndef NDEBUG ASSERT(!m_eventDispatched); m_eventDispatched = true; #endif ChildNodesLazySnapshot::takeChildNodesLazySnapshot(); m_event->setTarget(EventPath::eventTargetRespectingTargetRules(m_node.get())); ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); ASSERT(m_event->target()); WindowEventContext windowEventContext(m_event.get(), m_node.get(), topNodeEventContext()); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch", "type", m_event->type().ascii()); // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing. InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(&m_node->document(), *m_event, windowEventContext.window(), m_node.get(), m_event->eventPath()); void* preDispatchEventHandlerResult; if (dispatchEventPreProcess(preDispatchEventHandlerResult) == ContinueDispatching) if (dispatchEventAtCapturing(windowEventContext) == ContinueDispatching) if (dispatchEventAtTarget() == ContinueDispatching) dispatchEventAtBubbling(windowEventContext); dispatchEventPostProcess(preDispatchEventHandlerResult); // Ensure that after event dispatch, the event's target object is the // outermost shadow DOM boundary. m_event->setTarget(windowEventContext.target()); m_event->setCurrentTarget(0); InspectorInstrumentation::didDispatchEvent(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data()); return !m_event->defaultPrevented(); }
bool EventDispatcher::dispatchEvent(Node* origin, PassRefPtr<Event> prpEvent) { ASSERT_WITH_SECURITY_IMPLICATION(!NoEventDispatchAssertion::isEventDispatchForbidden()); if (!prpEvent) return true; ASSERT(origin); RefPtr<Node> node(origin); RefPtr<Event> event(prpEvent); RefPtr<FrameView> view = node->document().view(); EventPath eventPath(*node, *event); if (EventTarget* relatedTarget = event->relatedTarget()) eventPath.setRelatedTarget(*node, *relatedTarget); #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) if (is<TouchEvent>(*event)) { if (!eventPath.updateTouchLists(downcast<TouchEvent>(*event))) return true; } #endif ChildNodesLazySnapshot::takeChildNodesLazySnapshot(); EventTarget* target = eventTargetRespectingTargetRules(*node); event->setTarget(target); if (!event->target()) return true; ASSERT_WITH_SECURITY_IMPLICATION(!NoEventDispatchAssertion::isEventDispatchForbidden()); WindowEventContext windowEventContext(node.get(), eventPath.lastContextIfExists()); InputElementClickState clickHandlingState; if (is<HTMLInputElement>(*node)) downcast<HTMLInputElement>(*node).willDispatchEvent(*event, clickHandlingState); if (!event->propagationStopped() && !eventPath.isEmpty()) dispatchEventInDOM(*event, eventPath, windowEventContext); event->setTarget(eventTargetRespectingTargetRules(*node)); event->setCurrentTarget(nullptr); event->setEventPhase(0); if (clickHandlingState.stateful) downcast<HTMLInputElement>(*node).didDispatchClickEvent(*event, clickHandlingState); // Call default event handlers. While the DOM does have a concept of preventing // default handling, the detail of which handlers are called is an internal // implementation detail and not part of the DOM. if (!event->defaultPrevented() && !event->defaultHandled()) callDefaultEventHandlersInTheBubblingOrder(*event, eventPath); // Ensure that after event dispatch, the event's target object is the // outermost shadow DOM boundary. event->setTarget(windowEventContext.target()); event->setCurrentTarget(0); return !event->defaultPrevented(); }