summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/EventTarget.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/EventTarget.h')
-rw-r--r--Source/WebCore/dom/EventTarget.h329
1 files changed, 133 insertions, 196 deletions
diff --git a/Source/WebCore/dom/EventTarget.h b/Source/WebCore/dom/EventTarget.h
index e6d6b29cc..892d4b812 100644
--- a/Source/WebCore/dom/EventTarget.h
+++ b/Source/WebCore/dom/EventTarget.h
@@ -2,7 +2,7 @@
* 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
*
@@ -15,227 +15,164 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
- *
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef EventTarget_h
-#define EventTarget_h
+#pragma once
#include "EventListenerMap.h"
-#include "EventNames.h"
#include "EventTargetInterfaces.h"
+#include "ExceptionOr.h"
+#include "ScriptWrappable.h"
+#include <memory>
#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/text/AtomicStringHash.h>
+#include <wtf/Variant.h>
namespace WebCore {
- class AudioNode;
- class AudioContext;
- class AudioTrackList;
- class DedicatedWorkerGlobalScope;
- class DOMApplicationCache;
- class DOMWindow;
- class Event;
- class EventListener;
- class EventSource;
- class FileReader;
- class FileWriter;
- class IDBDatabase;
- class IDBRequest;
- class IDBTransaction;
- class ScriptProcessorNode;
- class MediaController;
- class MediaStream;
- class MessagePort;
- class Node;
- class Notification;
- class SVGElementInstance;
- class ScriptExecutionContext;
- class SharedWorker;
- class SharedWorkerGlobalScope;
- class TextTrack;
- class TextTrackCue;
- class VideoTrackList;
- class WebSocket;
- class WebKitNamedFlow;
- class Worker;
- class XMLHttpRequest;
- class XMLHttpRequestUpload;
-
- typedef int ExceptionCode;
-
- struct FiringEventIterator {
- FiringEventIterator(const AtomicString& eventType, size_t& iterator, size_t& size)
- : eventType(eventType)
- , iterator(iterator)
- , size(size)
- {
- }
-
- const AtomicString& eventType;
- size_t& iterator;
- size_t& size;
- };
- typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
+class DOMWindow;
+class DOMWrapperWorld;
+class Node;
- struct EventTargetData {
- WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED;
- public:
- EventTargetData();
- ~EventTargetData();
+struct EventTargetData {
+ WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED;
+public:
+ EventTargetData() = default;
+ EventListenerMap eventListenerMap;
+ bool isFiringEventListeners { false };
+};
- EventListenerMap eventListenerMap;
- OwnPtr<FiringEventIteratorVector> firingEventIterators;
- };
+enum EventTargetInterface {
- enum EventTargetInterface {
+#define DOM_EVENT_INTERFACE_DECLARE(name) name##EventTargetInterfaceType,
+DOM_EVENT_TARGET_INTERFACES_FOR_EACH(DOM_EVENT_INTERFACE_DECLARE)
+#undef DOM_EVENT_INTERFACE_DECLARE
- #define DOM_EVENT_INTERFACE_DECLARE(name) name##EventTargetInterfaceType,
- DOM_EVENT_TARGET_INTERFACES_FOR_EACH(DOM_EVENT_INTERFACE_DECLARE)
- #undef DOM_EVENT_INTERFACE_DECLARE
+};
- };
+class EventTarget : public ScriptWrappable {
+public:
+ void ref() { refEventTarget(); }
+ void deref() { derefEventTarget(); }
+
+ virtual EventTargetInterface eventTargetInterface() const = 0;
+ virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
- class EventTarget {
- public:
- void ref() { refEventTarget(); }
- void deref() { derefEventTarget(); }
-
- virtual EventTargetInterface eventTargetInterface() const = 0;
- virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
-
- virtual Node* toNode();
- virtual DOMWindow* toDOMWindow();
- virtual bool isMessagePort() const;
-
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
- virtual void removeAllEventListeners();
- virtual bool dispatchEvent(PassRefPtr<Event>);
- bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); // DOM API
- virtual void uncaughtExceptionInEventHandler();
-
- // Used for legacy "onEvent" attribute APIs.
- bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
- bool clearAttributeEventListener(const AtomicString& eventType);
- EventListener* getAttributeEventListener(const AtomicString& eventType);
-
- bool hasEventListeners() const;
- bool hasEventListeners(const AtomicString& eventType);
- bool hasCapturingEventListeners(const AtomicString& eventType);
- const EventListenerVector& getEventListeners(const AtomicString& eventType);
-
- bool fireEventListeners(Event*);
- bool isFiringEventListeners();
-
- void visitJSEventListeners(JSC::SlotVisitor&);
- void invalidateJSEventListeners(JSC::JSObject*);
-
- protected:
- virtual ~EventTarget();
-
- virtual EventTargetData* eventTargetData() = 0;
- virtual EventTargetData& ensureEventTargetData() = 0;
-
- private:
- virtual void refEventTarget() = 0;
- virtual void derefEventTarget() = 0;
-
- void fireEventListeners(Event*, EventTargetData*, EventListenerVector&);
- void setupLegacyTypeObserverIfNeeded(const AtomicString& legacyTypeName, bool hasLegacyTypeListeners, bool hasNewTypeListeners);
-
- friend class EventListenerIterator;
+ virtual Node* toNode();
+ virtual DOMWindow* toDOMWindow();
+ virtual bool isMessagePort() const;
+
+ struct ListenerOptions {
+ ListenerOptions(bool capture = false)
+ : capture(capture)
+ { }
+
+ bool capture;
};
- class EventTargetWithInlineData : public EventTarget {
- protected:
- virtual EventTargetData* eventTargetData() override final { return &m_eventTargetData; }
- virtual EventTargetData& ensureEventTargetData() override final { return m_eventTargetData; }
- private:
- EventTargetData m_eventTargetData;
+ struct AddEventListenerOptions : ListenerOptions {
+ AddEventListenerOptions(bool capture = false, bool passive = false, bool once = false)
+ : ListenerOptions(capture)
+ , passive(passive)
+ , once(once)
+ { }
+
+ bool passive;
+ bool once;
};
- // FIXME: These macros should be split into separate DEFINE and DECLARE
- // macros to avoid causing so many header includes.
- #define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
- EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
- void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
-
- #define DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \
- virtual EventListener* on##attribute(); \
- virtual void setOn##attribute(PassRefPtr<EventListener> listener); \
-
- #define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(type, attribute) \
- EventListener* type::on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
- void type::setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
-
- #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
- EventListener* on##attribute() { return document().getWindowAttributeEventListener(eventNames().attribute##Event); } \
- void setOn##attribute(PassRefPtr<EventListener> listener) { document().setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \
-
- #define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
- EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \
- void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \
-
- #define DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
- EventListener* on##attribute(); \
- void setOn##attribute(PassRefPtr<EventListener> listener);
-
- #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(type, recipient, attribute) \
- EventListener* type::on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \
- void type::setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); }
-
- inline void EventTarget::visitJSEventListeners(JSC::SlotVisitor& visitor)
- {
- EventListenerIterator iterator(this);
- while (EventListener* listener = iterator.nextListener())
- listener->visitJSFunction(visitor);
- }
-
- inline bool EventTarget::isFiringEventListeners()
- {
- EventTargetData* d = eventTargetData();
- if (!d)
- return false;
- return d->firingEventIterators && !d->firingEventIterators->isEmpty();
- }
-
- inline bool EventTarget::hasEventListeners() const
- {
- EventTargetData* d = const_cast<EventTarget*>(this)->eventTargetData();
- if (!d)
- return false;
- return !d->eventListenerMap.isEmpty();
- }
-
- inline bool EventTarget::hasEventListeners(const AtomicString& eventType)
- {
- EventTargetData* d = eventTargetData();
- if (!d)
- return false;
- return d->eventListenerMap.contains(eventType);
- }
-
- inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventType)
- {
- EventTargetData* d = eventTargetData();
- if (!d)
- return false;
- return d->eventListenerMap.containsCapturing(eventType);
- }
+ using AddEventListenerOptionsOrBoolean = Variant<AddEventListenerOptions, bool>;
+ WEBCORE_EXPORT void addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, AddEventListenerOptionsOrBoolean&&);
+ using ListenerOptionsOrBoolean = Variant<ListenerOptions, bool>;
+ WEBCORE_EXPORT void removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, ListenerOptionsOrBoolean&&);
+ WEBCORE_EXPORT ExceptionOr<bool> dispatchEventForBindings(Event&);
+
+ virtual bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions& = { });
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&);
+
+ virtual void removeAllEventListeners();
+ virtual bool dispatchEvent(Event&);
+ virtual void uncaughtExceptionInEventHandler();
+
+ // Used for legacy "onevent" attributes.
+ bool setAttributeEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, DOMWrapperWorld&);
+ EventListener* attributeEventListener(const AtomicString& eventType, DOMWrapperWorld&);
+
+ bool hasEventListeners() const;
+ bool hasEventListeners(const AtomicString& eventType) const;
+ bool hasCapturingEventListeners(const AtomicString& eventType);
+ bool hasActiveEventListeners(const AtomicString& eventType) const;
+ const EventListenerVector& eventListeners(const AtomicString& eventType);
+
+ bool fireEventListeners(Event&);
+ bool isFiringEventListeners() const;
+
+ void visitJSEventListeners(JSC::SlotVisitor&);
+ void invalidateJSEventListeners(JSC::JSObject*);
+
+protected:
+ virtual ~EventTarget() = default;
+
+ virtual EventTargetData* eventTargetData() = 0;
+ virtual EventTargetData* eventTargetDataConcurrently() = 0;
+ virtual EventTargetData& ensureEventTargetData() = 0;
+ const EventTargetData* eventTargetData() const;
+
+private:
+ virtual void refEventTarget() = 0;
+ virtual void derefEventTarget() = 0;
+
+ void fireEventListeners(Event&, EventListenerVector);
+
+ friend class EventListenerIterator;
+};
+
+class EventTargetWithInlineData : public EventTarget {
+protected:
+ EventTargetData* eventTargetData() final { return &m_eventTargetData; }
+ EventTargetData* eventTargetDataConcurrently() final { return &m_eventTargetData; }
+ EventTargetData& ensureEventTargetData() final { return m_eventTargetData; }
+private:
+ EventTargetData m_eventTargetData;
+};
+
+inline const EventTargetData* EventTarget::eventTargetData() const
+{
+ return const_cast<EventTarget*>(this)->eventTargetData();
+}
+
+inline bool EventTarget::isFiringEventListeners() const
+{
+ auto* data = eventTargetData();
+ return data && data->isFiringEventListeners;
+}
+
+inline bool EventTarget::hasEventListeners() const
+{
+ auto* data = eventTargetData();
+ return data && !data->eventListenerMap.isEmpty();
+}
+
+inline bool EventTarget::hasEventListeners(const AtomicString& eventType) const
+{
+ auto* data = eventTargetData();
+ return data && data->eventListenerMap.contains(eventType);
+}
+
+inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventType)
+{
+ auto* data = eventTargetData();
+ return data && data->eventListenerMap.containsCapturing(eventType);
+}
} // namespace WebCore
-
-#endif // EventTarget_h