Index: Source/core/events/EventTarget.cpp |
=================================================================== |
--- Source/core/events/EventTarget.cpp (revision 159156) |
+++ Source/core/events/EventTarget.cpp (working copy) |
@@ -1,366 +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 Apple Inc. All rights reserved. |
- * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
- * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions |
- * are met: |
- * 1. Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * 2. Redistributions in binary form must reproduce the above copyright |
- * notice, this list of conditions and the following disclaimer in the |
- * documentation and/or other materials provided with the distribution. |
- * |
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- * |
- */ |
- |
-#include "config.h" |
-#include "core/events/EventTarget.h" |
- |
-#include "RuntimeEnabledFeatures.h" |
-#include "bindings/v8/DOMWrapperWorld.h" |
-#include "bindings/v8/ExceptionState.h" |
-#include "bindings/v8/ScriptController.h" |
-#include "core/events/Event.h" |
-#include "core/dom/ExceptionCode.h" |
-#include "core/inspector/InspectorInstrumentation.h" |
-#include "core/page/DOMWindow.h" |
-#include "wtf/StdLibExtras.h" |
-#include "wtf/Vector.h" |
- |
-using namespace WTF; |
- |
-namespace WebCore { |
- |
-EventTargetData::EventTargetData() |
-{ |
-} |
- |
-EventTargetData::~EventTargetData() |
-{ |
-} |
- |
-EventTarget::~EventTarget() |
-{ |
-} |
- |
-Node* EventTarget::toNode() |
-{ |
- return 0; |
-} |
- |
-DOMWindow* EventTarget::toDOMWindow() |
-{ |
- return 0; |
-} |
- |
-MessagePort* EventTarget::toMessagePort() |
-{ |
- return 0; |
-} |
- |
-inline DOMWindow* EventTarget::executingWindow() |
-{ |
- if (ScriptExecutionContext* context = scriptExecutionContext()) |
- return context->executingWindow(); |
- return 0; |
-} |
- |
-bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) |
-{ |
- EventTargetData* d = ensureEventTargetData(); |
- return d->eventListenerMap.add(eventType, listener, useCapture); |
-} |
- |
-bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) |
-{ |
- EventTargetData* d = eventTargetData(); |
- if (!d) |
- return false; |
- |
- size_t indexOfRemovedListener; |
- |
- if (!d->eventListenerMap.remove(eventType, listener, useCapture, indexOfRemovedListener)) |
- return false; |
- |
- // Notify firing events planning to invoke the listener at 'index' that |
- // they have one less listener to invoke. |
- if (!d->firingEventIterators) |
- return true; |
- for (size_t i = 0; i < d->firingEventIterators->size(); ++i) { |
- FiringEventIterator& firingIterator = d->firingEventIterators->at(i); |
- if (eventType != firingIterator.eventType) |
- continue; |
- |
- if (indexOfRemovedListener >= firingIterator.end) |
- continue; |
- |
- --firingIterator.end; |
- if (indexOfRemovedListener <= firingIterator.iterator) |
- --firingIterator.iterator; |
- } |
- |
- return true; |
-} |
- |
-bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) |
-{ |
- clearAttributeEventListener(eventType, isolatedWorld); |
- if (!listener) |
- return false; |
- return addEventListener(eventType, listener, false); |
-} |
- |
-EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld) |
-{ |
- const EventListenerVector& entry = getEventListeners(eventType); |
- for (size_t i = 0; i < entry.size(); ++i) { |
- EventListener* listener = entry[i].listener.get(); |
- if (listener->isAttribute()) { |
- DOMWrapperWorld* listenerWorld = listener->world(); |
- // Worker listener |
- if (!listenerWorld) { |
- ASSERT(!isolatedWorld); |
- return listener; |
- } |
- if (listenerWorld->isMainWorld() && !isolatedWorld) |
- return listener; |
- if (listenerWorld == isolatedWorld) |
- return listener; |
- } |
- } |
- return 0; |
-} |
- |
-bool EventTarget::clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld) |
-{ |
- EventListener* listener = getAttributeEventListener(eventType, isolatedWorld); |
- if (!listener) |
- return false; |
- return removeEventListener(eventType, listener, false); |
-} |
- |
-bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionState& es) |
-{ |
- if (!event || event->type().isEmpty() || event->isBeingDispatched()) { |
- es.throwDOMException(InvalidStateError); |
- return false; |
- } |
- |
- if (!scriptExecutionContext()) |
- return false; |
- |
- return dispatchEvent(event); |
-} |
- |
-bool EventTarget::dispatchEvent(PassRefPtr<Event> event) |
-{ |
- event->setTarget(this); |
- event->setCurrentTarget(this); |
- event->setEventPhase(Event::AT_TARGET); |
- bool defaultPrevented = fireEventListeners(event.get()); |
- event->setEventPhase(0); |
- return defaultPrevented; |
-} |
- |
-void EventTarget::uncaughtExceptionInEventHandler() |
-{ |
-} |
- |
-static AtomicString legacyType(const Event* event) |
-{ |
- if (event->type() == eventNames().transitionendEvent) |
- return eventNames().webkitTransitionEndEvent; |
- |
- if (event->type() == eventNames().animationstartEvent) |
- return eventNames().webkitAnimationStartEvent; |
- |
- if (event->type() == eventNames().animationendEvent) |
- return eventNames().webkitAnimationEndEvent; |
- |
- if (event->type() == eventNames().animationiterationEvent) |
- return eventNames().webkitAnimationIterationEvent; |
- |
- if (event->type() == eventNames().wheelEvent) |
- return eventNames().mousewheelEvent; |
- |
- return emptyString(); |
-} |
- |
-void EventTarget::countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector* listenersVector, EventListenerVector* legacyListenersVector) |
-{ |
- UseCounter::Feature unprefixedFeature; |
- UseCounter::Feature prefixedFeature; |
- UseCounter::Feature prefixedAndUnprefixedFeature; |
- bool shouldCount = false; |
- |
- if (legacyTypeName == eventNames().webkitTransitionEndEvent) { |
- prefixedFeature = UseCounter::PrefixedTransitionEndEvent; |
- unprefixedFeature = UseCounter::UnprefixedTransitionEndEvent; |
- prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedTransitionEndEvent; |
- shouldCount = true; |
- } else if (legacyTypeName == eventNames().webkitAnimationEndEvent) { |
- prefixedFeature = UseCounter::PrefixedAnimationEndEvent; |
- unprefixedFeature = UseCounter::UnprefixedAnimationEndEvent; |
- prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationEndEvent; |
- shouldCount = true; |
- } else if (legacyTypeName == eventNames().webkitAnimationStartEvent) { |
- prefixedFeature = UseCounter::PrefixedAnimationStartEvent; |
- unprefixedFeature = UseCounter::UnprefixedAnimationStartEvent; |
- prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationStartEvent; |
- shouldCount = true; |
- } else if (legacyTypeName == eventNames().webkitAnimationIterationEvent) { |
- prefixedFeature = UseCounter::PrefixedAnimationIterationEvent; |
- unprefixedFeature = UseCounter::UnprefixedAnimationIterationEvent; |
- prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationIterationEvent; |
- shouldCount = true; |
- } |
- |
- if (shouldCount) { |
- if (DOMWindow* executingWindow = this->executingWindow()) { |
- if (legacyListenersVector) { |
- if (listenersVector) |
- UseCounter::count(executingWindow, prefixedAndUnprefixedFeature); |
- else |
- UseCounter::count(executingWindow, prefixedFeature); |
- } else if (listenersVector) { |
- UseCounter::count(executingWindow, unprefixedFeature); |
- } |
- } |
- } |
-} |
- |
-bool EventTarget::fireEventListeners(Event* event) |
-{ |
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); |
- ASSERT(event && !event->type().isEmpty()); |
- |
- EventTargetData* d = eventTargetData(); |
- if (!d) |
- return true; |
- |
- EventListenerVector* legacyListenersVector = 0; |
- AtomicString legacyTypeName = legacyType(event); |
- if (!legacyTypeName.isEmpty()) |
- legacyListenersVector = d->eventListenerMap.find(legacyTypeName); |
- |
- EventListenerVector* listenersVector = d->eventListenerMap.find(event->type()); |
- if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && (event->type() == eventNames().animationiterationEvent || event->type() == eventNames().animationendEvent |
- || event->type() == eventNames().animationstartEvent)) |
- listenersVector = 0; |
- |
- if (listenersVector) { |
- fireEventListeners(event, d, *listenersVector); |
- } else if (legacyListenersVector) { |
- AtomicString unprefixedTypeName = event->type(); |
- event->setType(legacyTypeName); |
- fireEventListeners(event, d, *legacyListenersVector); |
- event->setType(unprefixedTypeName); |
- } |
- |
- countLegacyEvents(legacyTypeName, listenersVector, legacyListenersVector); |
- return !event->defaultPrevented(); |
-} |
- |
-void EventTarget::fireEventListeners(Event* event, EventTargetData* d, EventListenerVector& entry) |
-{ |
- RefPtr<EventTarget> protect = this; |
- |
- // Fire all listeners registered for this event. Don't fire listeners removed |
- // during event dispatch. Also, don't fire event listeners added during event |
- // dispatch. Conveniently, all new event listeners will be added after or at |
- // index |size|, so iterating up to (but not including) |size| naturally excludes |
- // new event listeners. |
- |
- if (event->type() == eventNames().beforeunloadEvent) { |
- if (DOMWindow* executingWindow = this->executingWindow()) { |
- if (executingWindow->top()) |
- UseCounter::count(executingWindow, UseCounter::SubFrameBeforeUnloadFired); |
- } |
- } |
- |
- bool userEventWasHandled = false; |
- size_t i = 0; |
- size_t size = entry.size(); |
- if (!d->firingEventIterators) |
- d->firingEventIterators = adoptPtr(new FiringEventIteratorVector); |
- d->firingEventIterators->append(FiringEventIterator(event->type(), i, size)); |
- for ( ; i < size; ++i) { |
- RegisteredEventListener& registeredListener = entry[i]; |
- if (event->eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture) |
- continue; |
- if (event->eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture) |
- continue; |
- |
- // If stopImmediatePropagation has been called, we just break out immediately, without |
- // handling any more events on this target. |
- if (event->immediatePropagationStopped()) |
- break; |
- |
- ScriptExecutionContext* context = scriptExecutionContext(); |
- if (!context) |
- break; |
- |
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willHandleEvent(context, event); |
- // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling |
- // event listeners, even though that violates some versions of the DOM spec. |
- registeredListener.listener->handleEvent(context, event); |
- if (!userEventWasHandled && ScriptController::processingUserGesture()) |
- userEventWasHandled = true; |
- InspectorInstrumentation::didHandleEvent(cookie); |
- } |
- d->firingEventIterators->removeLast(); |
- if (userEventWasHandled) { |
- if (ScriptExecutionContext* context = scriptExecutionContext()) |
- context->userEventWasHandled(); |
- } |
-} |
- |
-const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType) |
-{ |
- DEFINE_STATIC_LOCAL(EventListenerVector, emptyVector, ()); |
- |
- EventTargetData* d = eventTargetData(); |
- if (!d) |
- return emptyVector; |
- |
- EventListenerVector* listenerVector = d->eventListenerMap.find(eventType); |
- if (!listenerVector) |
- return emptyVector; |
- |
- return *listenerVector; |
-} |
- |
-void EventTarget::removeAllEventListeners() |
-{ |
- EventTargetData* d = eventTargetData(); |
- if (!d) |
- return; |
- d->eventListenerMap.clear(); |
- |
- // Notify firing events planning to invoke the listener at 'index' that |
- // they have one less listener to invoke. |
- if (d->firingEventIterators) { |
- for (size_t i = 0; i < d->firingEventIterators->size(); ++i) { |
- d->firingEventIterators->at(i).iterator = 0; |
- d->firingEventIterators->at(i).end = 0; |
- } |
- } |
-} |
- |
-} // namespace WebCore |