| Index: Source/core/events/EventDispatcher.cpp
|
| ===================================================================
|
| --- Source/core/events/EventDispatcher.cpp (revision 159156)
|
| +++ Source/core/events/EventDispatcher.cpp (working copy)
|
| @@ -1,227 +0,0 @@
|
| -/*
|
| - * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
|
| - * (C) 1999 Antti Koivisto (koivisto@kde.org)
|
| - * (C) 2001 Dirk Mueller (mueller@kde.org)
|
| - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
|
| - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
|
| - * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
|
| - * Copyright (C) 2011 Google Inc. All rights reserved.
|
| - *
|
| - * This library is free software; you can redistribute it and/or
|
| - * modify it under the terms of the GNU Library General Public
|
| - * License as published by the Free Software Foundation; either
|
| - * version 2 of the License, or (at your option) any later version.
|
| - *
|
| - * This library is distributed in the hope that it will be useful,
|
| - * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| - * Library General Public License for more details.
|
| - *
|
| - * You should have received a copy of the GNU Library General Public License
|
| - * along with this library; see the file COPYING.LIB. If not, write to
|
| - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
| - * Boston, MA 02110-1301, USA.
|
| - */
|
| -
|
| -#include "config.h"
|
| -#include "core/events/EventDispatcher.h"
|
| -
|
| -#include "core/dom/ContainerNode.h"
|
| -#include "core/events/EventContext.h"
|
| -#include "core/events/EventDispatchMediator.h"
|
| -#include "core/events/EventRetargeter.h"
|
| -#include "core/events/MouseEvent.h"
|
| -#include "core/events/ScopedEventQueue.h"
|
| -#include "core/events/WindowEventContext.h"
|
| -#include "core/inspector/InspectorInstrumentation.h"
|
| -#include "core/page/FrameView.h"
|
| -#include "wtf/RefPtr.h"
|
| -
|
| -namespace WebCore {
|
| -
|
| -static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;
|
| -
|
| -bool EventDispatcher::dispatchEvent(Node* node, PassRefPtr<EventDispatchMediator> mediator)
|
| -{
|
| - ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
|
| - if (!mediator->event())
|
| - return true;
|
| - EventDispatcher dispatcher(node, mediator->event());
|
| - return mediator->dispatchEvent(&dispatcher);
|
| -}
|
| -
|
| -EventDispatcher::EventDispatcher(Node* node, PassRefPtr<Event> event)
|
| - : m_node(node)
|
| - , m_event(event)
|
| -#ifndef NDEBUG
|
| - , m_eventDispatched(false)
|
| -#endif
|
| -{
|
| - ASSERT(node);
|
| - ASSERT(m_event.get());
|
| - ASSERT(!m_event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
|
| - m_view = node->document().view();
|
| - EventRetargeter::ensureEventPath(m_node.get(), m_event.get());
|
| -}
|
| -
|
| -void EventDispatcher::dispatchScopedEvent(Node* node, PassRefPtr<EventDispatchMediator> mediator)
|
| -{
|
| - // We need to set the target here because it can go away by the time we actually fire the event.
|
| - mediator->event()->setTarget(EventRetargeter::eventTargetRespectingTargetRules(node));
|
| - ScopedEventQueue::instance()->enqueueEventDispatchMediator(mediator);
|
| -}
|
| -
|
| -void EventDispatcher::dispatchSimulatedClick(Node* node, Event* underlyingEvent, SimulatedClickMouseEventOptions mouseEventOptions, SimulatedClickVisualOptions visualOptions)
|
| -{
|
| - if (isDisabledFormControl(node))
|
| - return;
|
| -
|
| - if (!gNodesDispatchingSimulatedClicks)
|
| - gNodesDispatchingSimulatedClicks = new HashSet<Node*>;
|
| - else if (gNodesDispatchingSimulatedClicks->contains(node))
|
| - return;
|
| -
|
| - gNodesDispatchingSimulatedClicks->add(node);
|
| -
|
| - if (mouseEventOptions == SendMouseOverUpDownEvents)
|
| - EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mouseoverEvent, node->document().defaultView(), underlyingEvent)).dispatch();
|
| -
|
| - if (mouseEventOptions != SendNoEvents)
|
| - EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mousedownEvent, node->document().defaultView(), underlyingEvent)).dispatch();
|
| - node->setActive(true, visualOptions == ShowPressedLook);
|
| - if (mouseEventOptions != SendNoEvents)
|
| - EventDispatcher(node, SimulatedMouseEvent::create(eventNames().mouseupEvent, node->document().defaultView(), underlyingEvent)).dispatch();
|
| - node->setActive(false);
|
| -
|
| - // always send click
|
| - EventDispatcher(node, SimulatedMouseEvent::create(eventNames().clickEvent, node->document().defaultView(), underlyingEvent)).dispatch();
|
| -
|
| - gNodesDispatchingSimulatedClicks->remove(node);
|
| -}
|
| -
|
| -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_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);
|
| -
|
| - return !m_event->defaultPrevented();
|
| -}
|
| -
|
| -inline EventDispatchContinuation EventDispatcher::dispatchEventPreProcess(void*& preDispatchEventHandlerResult)
|
| -{
|
| - // Give the target node a chance to do some work before DOM event handlers get a crack.
|
| - preDispatchEventHandlerResult = m_node->preDispatchEventHandler(m_event.get());
|
| - return (m_event->eventPath().isEmpty() || m_event->propagationStopped()) ? DoneDispatching : ContinueDispatching;
|
| -}
|
| -
|
| -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::dispatchEventAtTarget()
|
| -{
|
| - m_event->setEventPhase(Event::AT_TARGET);
|
| - m_event->eventPath()[0]->handleLocalEvents(m_event.get());
|
| - return m_event->propagationStopped() ? DoneDispatching : 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 void EventDispatcher::dispatchEventPostProcess(void* preDispatchEventHandlerResult)
|
| -{
|
| - m_event->setTarget(EventRetargeter::eventTargetRespectingTargetRules(m_node.get()));
|
| - m_event->setCurrentTarget(0);
|
| - m_event->setEventPhase(0);
|
| -
|
| - // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler.
|
| - m_node->postDispatchEventHandler(m_event.get(), preDispatchEventHandlerResult);
|
| -
|
| - // 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 (!m_event->defaultPrevented() && !m_event->defaultHandled()) {
|
| - // Non-bubbling events call only one default event handler, the one for the target.
|
| - m_node->willCallDefaultEventHandler(*m_event);
|
| - m_node->defaultEventHandler(m_event.get());
|
| - ASSERT(!m_event->defaultPrevented());
|
| - if (m_event->defaultHandled())
|
| - return;
|
| - // For bubbling events, call default event handlers on the same targets in the
|
| - // same order as the bubbling phase.
|
| - if (m_event->bubbles()) {
|
| - size_t size = m_event->eventPath().size();
|
| - for (size_t i = 1; i < size; ++i) {
|
| - m_event->eventPath()[i]->node()->willCallDefaultEventHandler(*m_event);
|
| - m_event->eventPath()[i]->node()->defaultEventHandler(m_event.get());
|
| - ASSERT(!m_event->defaultPrevented());
|
| - if (m_event->defaultHandled())
|
| - return;
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -const EventContext* EventDispatcher::topEventContext()
|
| -{
|
| - return m_event->eventPath().isEmpty() ? 0 : m_event->eventPath().last().get();
|
| -}
|
| -
|
| -}
|
|
|