static void dispatchEventInDOM(Event& event, const EventPath& path, WindowEventContext& windowEventContext) { // Trigger capturing event handlers, starting at the top and working our way down. event.setEventPhase(Event::CAPTURING_PHASE); // We don't dispatch load events to the window. This quirk was originally // added because Mozilla doesn't propagate load events to the window object. bool shouldFireEventAtWindow = event.type() != eventNames().loadEvent; if (shouldFireEventAtWindow && windowEventContext.handleLocalEvents(event) && event.propagationStopped()) return; for (size_t i = path.size() - 1; i > 0; --i) { const EventContext& eventContext = path.contextAt(i); if (eventContext.currentTargetSameAsTarget()) continue; eventContext.handleLocalEvents(event); if (event.propagationStopped()) return; } event.setEventPhase(Event::AT_TARGET); path.contextAt(0).handleLocalEvents(event); if (event.propagationStopped()) return; // Trigger bubbling event handlers, starting at the bottom and working our way up. size_t size = path.size(); for (size_t i = 1; i < size; ++i) { const EventContext& eventContext = path.contextAt(i); if (eventContext.currentTargetSameAsTarget()) event.setEventPhase(Event::AT_TARGET); else if (event.bubbles() && !event.cancelBubble()) event.setEventPhase(Event::BUBBLING_PHASE); else continue; eventContext.handleLocalEvents(event); if (event.propagationStopped()) return; } if (event.bubbles() && !event.cancelBubble()) { event.setEventPhase(Event::BUBBLING_PHASE); if (shouldFireEventAtWindow) windowEventContext.handleLocalEvents(event); } }
inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing(WindowEventContext& windowEventContext) { // Trigger capturing event handlers, starting at the top and working our way down. m_event->setEventPhase(Event::CAPTURING_PHASE); if (windowEventContext.handleLocalEvents(m_event.get()) && m_event->propagationStopped()) return DoneDispatching; for (size_t i = m_event->eventPath().size() - 1; i > 0; --i) { const EventContext& eventContext = *m_event->eventPath()[i]; if (eventContext.currentTargetSameAsTarget()) continue; eventContext.handleLocalEvents(m_event.get()); if (m_event->propagationStopped()) return DoneDispatching; } return ContinueDispatching; }
inline EventDispatchContinuation EventDispatcher::dispatchEventAtBubbling(WindowEventContext& windowContext) { if (m_event->bubbles() && !m_event->cancelBubble()) { // Trigger bubbling event handlers, starting at the bottom and working our way up. m_event->setEventPhase(Event::BUBBLING_PHASE); size_t size = m_eventPath.size(); for (size_t i = 1; i < size; ++i) { const EventContext& eventContext = *m_eventPath[i]; if (eventContext.currentTargetSameAsTarget()) continue; else m_event->setEventPhase(Event::BUBBLING_PHASE); eventContext.handleLocalEvents(m_event.get()); if (m_event->propagationStopped() || m_event->cancelBubble()) return DoneDispatching; } windowContext.handleLocalEvents(m_event.get()); } return ContinueDispatching; }
inline EventDispatchContinuation EventDispatcher::dispatchEventAtBubbling(PassRefPtr<Event> event, WindowEventContext& windowContext) { if (event->bubbles() && !event->cancelBubble()) { // Trigger bubbling event handlers, starting at the bottom and working our way up. event->setEventPhase(Event::BUBBLING_PHASE); size_t size = m_ancestors.size(); for (size_t i = 1; i < size; ++i) { const EventContext& eventContext = m_ancestors[i]; if (eventContext.currentTargetSameAsTarget()) event->setEventPhase(Event::AT_TARGET); else event->setEventPhase(Event::BUBBLING_PHASE); eventContext.handleLocalEvents(event.get()); if (event->propagationStopped() || event->cancelBubble()) return DoneDispatching; } windowContext.handleLocalEvents(event.get()); } return ContinueDispatching; }
inline void EventDispatcher::dispatchEventAtBubbling(WindowEventContext& windowContext) { // Trigger bubbling event handlers, starting at the bottom and working our way up. size_t size = m_event->eventPath().size(); for (size_t i = 1; i < size; ++i) { const EventContext& eventContext = *m_event->eventPath()[i]; if (eventContext.currentTargetSameAsTarget()) m_event->setEventPhase(Event::AT_TARGET); else if (m_event->bubbles() && !m_event->cancelBubble()) m_event->setEventPhase(Event::BUBBLING_PHASE); else continue; eventContext.handleLocalEvents(m_event.get()); if (m_event->propagationStopped()) return; } if (m_event->bubbles() && !m_event->cancelBubble()) { m_event->setEventPhase(Event::BUBBLING_PHASE); windowContext.handleLocalEvents(m_event.get()); } }
inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing(PassRefPtr<Event> event, WindowEventContext& windowEventContext) { // Trigger capturing event handlers, starting at the top and working our way down. event->setEventPhase(Event::CAPTURING_PHASE); if (windowEventContext.handleLocalEvents(event.get()) && event->propagationStopped()) return DoneDispatching; for (size_t i = m_ancestors.size() - 1; i > 0; --i) { const EventContext& eventContext = m_ancestors[i]; if (eventContext.currentTargetSameAsTarget()) { if (event->bubbles()) continue; event->setEventPhase(Event::AT_TARGET); } else event->setEventPhase(Event::CAPTURING_PHASE); eventContext.handleLocalEvents(event.get()); if (event->propagationStopped()) return DoneDispatching; } return ContinueDispatching; }