Пример #1
0
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;
}
Пример #2
0
bool EventDispatcher::dispatchEvent(PassRefPtr<Event> event)
{
    event->setTarget(eventTargetRespectingSVGTargetRules(m_node.get()));

    ASSERT(!eventDispatchForbidden());
    ASSERT(event->target());
    ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.

    RefPtr<EventTarget> originalTarget = event->target();
    ensureEventAncestors(event.get());

    WindowEventContext windowContext(event.get(), m_node.get(), topEventContext());

    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowContext.window(), m_node.get(), m_ancestors);

    // Give the target node a chance to do some work before DOM event handlers get a crack.
    void* data = m_node->preDispatchEventHandler(event.get());
    if (m_ancestors.isEmpty() || m_shouldPreventDispatch || event->propagationStopped())
        goto doneDispatching;

    // Trigger capturing event handlers, starting at the top and working our way down.
    event->setEventPhase(Event::CAPTURING_PHASE);

    if (windowContext.handleLocalEvents(event.get()) && event->propagationStopped())
        goto 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())
            goto doneDispatching;
    }

    event->setEventPhase(Event::AT_TARGET);
    event->setTarget(originalTarget.get());
    event->setCurrentTarget(eventTargetRespectingSVGTargetRules(m_node.get()));
    m_ancestors[0].handleLocalEvents(event.get());
    if (event->propagationStopped())
        goto doneDispatching;

    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())
                goto doneDispatching;
        }
        windowContext.handleLocalEvents(event.get());
    }

doneDispatching:
    event->setTarget(originalTarget.get());
    event->setCurrentTarget(0);
    event->setEventPhase(0);

    // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler.
    m_node->postDispatchEventHandler(event.get(), data);

    // 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()) {
        // Non-bubbling events call only one default event handler, the one for the target.
        m_node->defaultEventHandler(event.get());
        ASSERT(!event->defaultPrevented());
        if (event->defaultHandled())
            goto doneWithDefault;
        // For bubbling events, call default event handlers on the same targets in the
        // same order as the bubbling phase.
        if (event->bubbles()) {
            size_t size = m_ancestors.size();
            for (size_t i = 1; i < size; ++i) {
                m_ancestors[i].node()->defaultEventHandler(event.get());
                ASSERT(!event->defaultPrevented());
                if (event->defaultHandled())
                    goto doneWithDefault;
            }
        }
    }

doneWithDefault:

    // Ensure that after event dispatch, the event's target object is the
    // outermost shadow DOM boundary.
    event->setTarget(windowContext.target());
    event->setCurrentTarget(0);
    InspectorInstrumentation::didDispatchEvent(cookie);

    return !event->defaultPrevented();
}