Make all ScriptWrappable IsoHeap-ed
[WebKit-https.git] / Source / WebCore / dom / Event.h
index 0ad7913..1bc7255 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2001 Peter Kelly (pmk@post.com)
  * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
  * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2017 Apple 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
  *
  */
 
-#ifndef Event_h
-#define Event_h
+#pragma once
 
-#include "Clipboard.h"
-#include "DOMTimeStamp.h"
-#include <wtf/RefCounted.h>
-#include <wtf/text/AtomicString.h>
+#include "DOMHighResTimeStamp.h"
+#include "EventInit.h"
+#include "EventInterfaces.h"
+#include "ExceptionOr.h"
+#include "ScriptWrappable.h"
+#include <wtf/MonotonicTime.h>
+#include <wtf/TypeCasts.h>
+#include <wtf/text/AtomString.h>
 
 namespace WebCore {
 
-    class EventTarget;
-    class EventDispatcher;
-
-    struct EventInit {
-        EventInit();
-        
-        bool bubbles;
-        bool cancelable;
+class EventPath;
+class EventTarget;
+class ScriptExecutionContext;
+
+class Event : public ScriptWrappable, public RefCounted<Event> {
+    WTF_MAKE_ISO_ALLOCATED(Event);
+public:
+    enum class IsTrusted : uint8_t { No, Yes };
+    enum class CanBubble : uint8_t { No, Yes };
+    enum class IsCancelable : uint8_t { No, Yes };
+    enum class IsComposed : uint8_t { No, Yes };
+
+    enum PhaseType : uint8_t {
+        NONE = 0,
+        CAPTURING_PHASE = 1,
+        AT_TARGET = 2,
+        BUBBLING_PHASE = 3
     };
 
-    class Event : public RefCounted<Event> {
-    public:
-        enum PhaseType { 
-            CAPTURING_PHASE     = 1, 
-            AT_TARGET           = 2,
-            BUBBLING_PHASE      = 3 
-        };
-
-        enum EventType {
-            MOUSEDOWN           = 1,
-            MOUSEUP             = 2,
-            MOUSEOVER           = 4,
-            MOUSEOUT            = 8,
-            MOUSEMOVE           = 16,
-            MOUSEDRAG           = 32,
-            CLICK               = 64,
-            DBLCLICK            = 128,
-            KEYDOWN             = 256,
-            KEYUP               = 512,
-            KEYPRESS            = 1024,
-            DRAGDROP            = 2048,
-            FOCUS               = 4096,
-            BLUR                = 8192,
-            SELECT              = 16384,
-            CHANGE              = 32768
-        };
-
-        static PassRefPtr<Event> create()
-        {
-            return adoptRef(new Event);
-        }
-        static PassRefPtr<Event> create(const AtomicString& type, bool canBubble, bool cancelable)
-        {
-            return adoptRef(new Event(type, canBubble, cancelable));
-        }
-
-        static PassRefPtr<Event> create(const AtomicString& type, const EventInit& initializer)
-        {
-            return adoptRef(new Event(type, initializer));
-        }
-
-        virtual ~Event();
-
-        void initEvent(const AtomicString& type, bool canBubble, bool cancelable);
-
-        const AtomicString& type() const { return m_type; }
-        
-        EventTarget* target() const { return m_target.get(); }
-        void setTarget(PassRefPtr<EventTarget>);
-
-        EventTarget* currentTarget() const { return m_currentTarget; }
-        void setCurrentTarget(EventTarget* currentTarget) { m_currentTarget = currentTarget; }
-
-        unsigned short eventPhase() const { return m_eventPhase; }
-        void setEventPhase(unsigned short eventPhase) { m_eventPhase = eventPhase; }
-
-        bool bubbles() const { return m_canBubble; }
-        bool cancelable() const { return m_cancelable; }
-        DOMTimeStamp timeStamp() const { return m_createTime; }
-
-        void stopPropagation() { m_propagationStopped = true; }
-        void stopImmediatePropagation() { m_immediatePropagationStopped = true; }
-        
-        // IE Extensions
-        EventTarget* srcElement() const { return target(); } // MSIE extension - "the object that fired the event"
-
-        bool returnValue() const { return !defaultPrevented(); }
-        void setReturnValue(bool returnValue) { setDefaultPrevented(!returnValue); }
-
-        Clipboard* clipboardData() const { return isClipboardEvent() ? clipboard() : 0; }
-
-        virtual bool isCustomEvent() const;
-        virtual bool isUIEvent() const;
-        virtual bool isMouseEvent() const;
-        virtual bool isMutationEvent() const;
-        virtual bool isKeyboardEvent() const;
-        virtual bool isTextEvent() const;
-        virtual bool isCompositionEvent() const;
-        virtual bool isDragEvent() const; // a subset of mouse events
-        virtual bool isClipboardEvent() const;
-        virtual bool isMessageEvent() const;
-        virtual bool isWheelEvent() const;
-        virtual bool isBeforeTextInsertedEvent() const;
-        virtual bool isOverflowEvent() const;
-        virtual bool isPageTransitionEvent() const;
-        virtual bool isPopStateEvent() const;
-        virtual bool isProgressEvent() const;
-        virtual bool isXMLHttpRequestProgressEvent() const;
-        virtual bool isWebKitAnimationEvent() const;
-        virtual bool isWebKitTransitionEvent() const;
-        virtual bool isBeforeLoadEvent() const;
-        virtual bool isHashChangeEvent() const;
-#if ENABLE(SVG)
-        virtual bool isSVGZoomEvent() const;
-#endif
-#if ENABLE(DOM_STORAGE)
-        virtual bool isStorageEvent() const;
-#endif
-#if ENABLE(INDEXED_DATABASE)
-        virtual bool isIDBVersionChangeEvent() const;
-#endif
-#if ENABLE(WEB_AUDIO)
-        virtual bool isAudioProcessingEvent() const;
-        virtual bool isOfflineAudioCompletionEvent() const;
-#endif
-        virtual bool isErrorEvent() const;
-#if ENABLE(TOUCH_EVENTS)
-        virtual bool isTouchEvent() const;
-#endif
-#if ENABLE(DEVICE_ORIENTATION)
-        virtual bool isDeviceMotionEvent() const;
-        virtual bool isDeviceOrientationEvent() const;
-#endif
-#if ENABLE(INPUT_SPEECH)
-        virtual bool isSpeechInputEvent() const;
-#endif
-#if ENABLE(WEB_SOCKETS)
-        virtual bool isCloseEvent() const;
-#endif
-#if ENABLE(MEDIA_STREAM)
-        virtual bool isMediaStreamEvent() const;
-#endif
-#if ENABLE(WEBGL)
-        virtual bool isWebGLContextEvent() const;
-#endif
-
-        bool propagationStopped() const { return m_propagationStopped || m_immediatePropagationStopped; }
-        bool immediatePropagationStopped() const { return m_immediatePropagationStopped; }
-
-        bool defaultPrevented() const { return m_defaultPrevented; }
-        void preventDefault() { if (m_cancelable) m_defaultPrevented = true; }
-        void setDefaultPrevented(bool defaultPrevented) { m_defaultPrevented = defaultPrevented; }
-
-        bool defaultHandled() const { return m_defaultHandled; }
-        void setDefaultHandled() { m_defaultHandled = true; }
-
-        bool cancelBubble() const { return m_cancelBubble; }
-        void setCancelBubble(bool cancel) { m_cancelBubble = cancel; }
-
-        Event* underlyingEvent() const { return m_underlyingEvent.get(); }
-        void setUnderlyingEvent(PassRefPtr<Event>);
-
-        virtual bool storesResultAsString() const;
-        virtual void storeResult(const String&);
-
-        virtual Clipboard* clipboard() const { return 0; }
-
-        bool isBeingDispatched() const { return eventPhase(); }
-
-    protected:
-        Event();
-        Event(const AtomicString& type, bool canBubble, bool cancelable);
-        Event(const AtomicString& type, const EventInit&);
-
-        virtual void receivedTarget();
-        bool dispatched() const { return m_target; }
-
-    private:
-        AtomicString m_type;
-        bool m_canBubble;
-        bool m_cancelable;
-
-        bool m_propagationStopped;
-        bool m_immediatePropagationStopped;
-        bool m_defaultPrevented;
-        bool m_defaultHandled;
-        bool m_cancelBubble;
-
-        unsigned short m_eventPhase;
-        EventTarget* m_currentTarget;
-        RefPtr<EventTarget> m_target;
-        DOMTimeStamp m_createTime;
-
-        RefPtr<Event> m_underlyingEvent;
-    };
+    WEBCORE_EXPORT static Ref<Event> create(const AtomString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No);
+    static Ref<Event> createForBindings();
+    static Ref<Event> create(const AtomString& type, const EventInit&, IsTrusted = IsTrusted::No);
+
+    virtual ~Event();
+
+    WEBCORE_EXPORT void initEvent(const AtomString& type, bool canBubble, bool cancelable);
+
+    bool isInitialized() const { return m_isInitialized; }
+
+    const AtomString& type() const { return m_type; }
+    void setType(const AtomString& type) { m_type = type; }
+    
+    EventTarget* target() const { return m_target.get(); }
+    void setTarget(RefPtr<EventTarget>&&);
+
+    EventTarget* currentTarget() const { return m_currentTarget.get(); }
+    void setCurrentTarget(EventTarget*);
+
+    unsigned short eventPhase() const { return m_eventPhase; }
+    void setEventPhase(PhaseType phase) { m_eventPhase = phase; }
+
+    bool bubbles() const { return m_canBubble; }
+    bool cancelable() const { return m_cancelable; }
+    bool composed() const { return m_composed; }
+
+    DOMHighResTimeStamp timeStampForBindings(ScriptExecutionContext&) const;
+    MonotonicTime timeStamp() const { return m_createTime; }
+
+    void setEventPath(const EventPath& path) { m_eventPath = &path; }
+    Vector<EventTarget*> composedPath() const;
+
+    void stopPropagation() { m_propagationStopped = true; }
+    void stopImmediatePropagation() { m_immediatePropagationStopped = true; }
+
+    bool isTrusted() const { return m_isTrusted; }
+    void setUntrusted() { m_isTrusted = false; }
+
+    bool legacyReturnValue() const { return !m_wasCanceled; }
+    void setLegacyReturnValue(bool);
+
+    virtual EventInterface eventInterface() const { return EventInterfaceType; }
+
+    virtual bool isBeforeTextInsertedEvent() const { return false; }
+    virtual bool isBeforeUnloadEvent() const { return false; }
+    virtual bool isClipboardEvent() const { return false; }
+    virtual bool isCompositionEvent() const { return false; }
+    virtual bool isErrorEvent() const { return false; }
+    virtual bool isFocusEvent() const { return false; }
+    virtual bool isInputEvent() const { return false; }
+    virtual bool isKeyboardEvent() const { return false; }
+    virtual bool isMouseEvent() const { return false; }
+    virtual bool isPointerEvent() const { return false; }
+    virtual bool isTextEvent() const { return false; }
+    virtual bool isTouchEvent() const { return false; }
+    virtual bool isUIEvent() const { return false; }
+    virtual bool isVersionChangeEvent() const { return false; }
+    virtual bool isWheelEvent() const { return false; }
+
+    bool propagationStopped() const { return m_propagationStopped || m_immediatePropagationStopped; }
+    bool immediatePropagationStopped() const { return m_immediatePropagationStopped; }
+
+    void resetBeforeDispatch();
+    void resetAfterDispatch();
+
+    bool defaultPrevented() const { return m_wasCanceled; }
+    void preventDefault();
+
+    bool defaultHandled() const { return m_defaultHandled; }
+    void setDefaultHandled() { m_defaultHandled = true; }
+
+    bool isDefaultEventHandlerIgnored() const { return m_isDefaultEventHandlerIgnored; }
+    void setIsDefaultEventHandlerIgnored() { m_isDefaultEventHandlerIgnored = true; }
+
+    void setInPassiveListener(bool value) { m_isExecutingPassiveEventListener = value; }
+
+    bool cancelBubble() const { return propagationStopped(); }
+    void setCancelBubble(bool);
+
+    Event* underlyingEvent() const { return m_underlyingEvent.get(); }
+    void setUnderlyingEvent(Event*);
+
+    // Returns true if the dispatch flag is set.
+    // https://dom.spec.whatwg.org/#dispatch-flag
+    bool isBeingDispatched() const { return eventPhase(); }
+
+    virtual EventTarget* relatedTarget() const { return nullptr; }
+    virtual void setRelatedTarget(EventTarget&) { }
+
+protected:
+    explicit Event(IsTrusted = IsTrusted::No);
+    Event(const AtomString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No);
+    Event(const AtomString& type, CanBubble, IsCancelable, IsComposed, MonotonicTime timestamp, IsTrusted isTrusted = IsTrusted::Yes);
+    Event(const AtomString& type, const EventInit&, IsTrusted);
+
+    virtual void receivedTarget() { }
+
+private:
+    explicit Event(MonotonicTime createTime, const AtomString& type, IsTrusted, CanBubble, IsCancelable, IsComposed);
+
+    void setCanceledFlagIfPossible();
+
+    unsigned m_isInitialized : 1;
+    unsigned m_canBubble : 1;
+    unsigned m_cancelable : 1;
+    unsigned m_composed : 1;
+
+    unsigned m_propagationStopped : 1;
+    unsigned m_immediatePropagationStopped : 1;
+    unsigned m_wasCanceled : 1;
+    unsigned m_defaultHandled : 1;
+    unsigned m_isDefaultEventHandlerIgnored : 1;
+    unsigned m_isTrusted : 1;
+    unsigned m_isExecutingPassiveEventListener : 1;
+
+    unsigned m_eventPhase : 2;
+
+    AtomString m_type;
+
+    RefPtr<EventTarget> m_currentTarget;
+    const EventPath* m_eventPath { nullptr };
+    RefPtr<EventTarget> m_target;
+    MonotonicTime m_createTime;
+
+    RefPtr<Event> m_underlyingEvent;
+};
+
+inline void Event::preventDefault()
+{
+    setCanceledFlagIfPossible();
+}
+
+inline void Event::setLegacyReturnValue(bool returnValue)
+{
+    if (!returnValue)
+        setCanceledFlagIfPossible();
+}
+
+// https://dom.spec.whatwg.org/#set-the-canceled-flag
+inline void Event::setCanceledFlagIfPossible()
+{
+    if (m_cancelable && !m_isExecutingPassiveEventListener)
+        m_wasCanceled = true;
+    // FIXME: Specification suggests we log something to the console when preventDefault is called but
+    // doesn't do anything because the event is not cancelable or is executing passive event listeners.
+}
+
+inline void Event::setCancelBubble(bool cancel)
+{
+    if (cancel)
+        m_propagationStopped = true;
+}
 
 } // namespace WebCore
 
-#endif // Event_h
+#define SPECIALIZE_TYPE_TRAITS_EVENT(ToValueTypeName) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
+    static bool isType(const WebCore::Event& event) { return event.is##ToValueTypeName(); } \
+SPECIALIZE_TYPE_TRAITS_END()