Make all ScriptWrappable IsoHeap-ed
[WebKit-https.git] / Source / WebCore / dom / Event.h
index 74f855a..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, 2013 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 "DOMTimeStamp.h"
+#include "DOMHighResTimeStamp.h"
+#include "EventInit.h"
 #include "EventInterfaces.h"
+#include "ExceptionOr.h"
 #include "ScriptWrappable.h"
-#include <wtf/HashMap.h>
-#include <wtf/ListHashSet.h>
-#include <wtf/RefCounted.h>
+#include <wtf/MonotonicTime.h>
 #include <wtf/TypeCasts.h>
-#include <wtf/text/AtomicString.h>
+#include <wtf/text/AtomString.h>
 
 namespace WebCore {
 
-class DataTransfer;
+class EventPath;
 class EventTarget;
-class HTMLIFrameElement;
-
-struct EventInit {
-    EventInit();
-    EventInit(bool bubbles, bool cancelable);
-
-    bool bubbles;
-    bool cancelable;
-};
-
-enum EventInterface {
-
-#define DOM_EVENT_INTERFACE_DECLARE(name) name##InterfaceType,
-DOM_EVENT_INTERFACES_FOR_EACH(DOM_EVENT_INTERFACE_DECLARE)
-#undef DOM_EVENT_INTERFACE_DECLARE
-
-};
+class ScriptExecutionContext;
 
 class Event : public ScriptWrappable, public RefCounted<Event> {
+    WTF_MAKE_ISO_ALLOCATED(Event);
 public:
-    enum PhaseType { 
-        NONE                = 0,
-        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
+    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
     };
 
-    static Ref<Event> create()
-    {
-        return adoptRef(*new Event);
-    }
-    static Ref<Event> create(const AtomicString& type, bool canBubble, bool cancelable)
-    {
-        return adoptRef(*new Event(type, canBubble, cancelable));
-    }
-
-    static Ref<Event> create(const AtomicString& type, const EventInit& initializer)
-    {
-        return adoptRef(*new Event(type, initializer));
-    }
+    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();
 
-    void initEvent(const AtomicString& type, bool canBubble, bool cancelable);
+    WEBCORE_EXPORT void initEvent(const AtomString& type, bool canBubble, bool cancelable);
+
     bool isInitialized() const { return m_isInitialized; }
 
-    const AtomicString& type() const { return m_type; }
-    void setType(const AtomicString& type) { m_type = type; }
+    const AtomString& type() const { return m_type; }
+    void setType(const AtomString& type) { m_type = type; }
     
     EventTarget* target() const { return m_target.get(); }
-    void setTarget(PassRefPtr<EventTarget>);
+    void setTarget(RefPtr<EventTarget>&&);
 
-    EventTarget* currentTarget() const { return m_currentTarget; }
-    void setCurrentTarget(EventTarget* currentTarget) { m_currentTarget = currentTarget; }
+    EventTarget* currentTarget() const { return m_currentTarget.get(); }
+    void setCurrentTarget(EventTarget*);
 
     unsigned short eventPhase() const { return m_eventPhase; }
-    void setEventPhase(unsigned short eventPhase) { m_eventPhase = eventPhase; }
+    void setEventPhase(PhaseType phase) { m_eventPhase = phase; }
 
     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 legacyReturnValue() const { return !defaultPrevented(); }
-    void setLegacyReturnValue(bool returnValue) { setDefaultPrevented(!returnValue); }
-
-    DataTransfer* clipboardData() const { return isClipboardEvent() ? internalDataTransfer() : 0; }
+    bool composed() const { return m_composed; }
 
-    virtual EventInterface eventInterface() const;
+    DOMHighResTimeStamp timeStampForBindings(ScriptExecutionContext&) const;
+    MonotonicTime timeStamp() const { return m_createTime; }
 
-    // These events are general classes of events.
-    virtual bool isUIEvent() const;
-    virtual bool isMouseEvent() const;
-    virtual bool isFocusEvent() const;
-    virtual bool isKeyboardEvent() const;
-    virtual bool isTouchEvent() const;
+    void setEventPath(const EventPath& path) { m_eventPath = &path; }
+    Vector<EventTarget*> composedPath() const;
 
-    // Drag events are a subset of mouse events.
-    virtual bool isDragEvent() const;
-
-    // These events lack a DOM interface.
-    virtual bool isClipboardEvent() const;
-    virtual bool isBeforeTextInsertedEvent() const;
-
-    virtual bool isBeforeUnloadEvent() const;
+    void stopPropagation() { m_propagationStopped = true; }
+    void stopImmediatePropagation() { m_immediatePropagationStopped = true; }
 
-    virtual bool isErrorEvent() const;
-    virtual bool isTextEvent() const;
-    virtual bool isWheelEvent() const;
+    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; }
 
-    bool defaultPrevented() const { return m_defaultPrevented; }
-    void preventDefault()
-    {
-        if (m_cancelable)
-            m_defaultPrevented = true;
-    }
-    void setDefaultPrevented(bool defaultPrevented) { m_defaultPrevented = defaultPrevented; }
+    void resetBeforeDispatch();
+    void resetAfterDispatch();
+
+    bool defaultPrevented() const { return m_wasCanceled; }
+    void preventDefault();
 
     bool defaultHandled() const { return m_defaultHandled; }
     void setDefaultHandled() { m_defaultHandled = true; }
 
-    bool cancelBubble() const { return m_cancelBubble; }
-    void setCancelBubble(bool cancel) { m_cancelBubble = cancel; }
+    bool isDefaultEventHandlerIgnored() const { return m_isDefaultEventHandlerIgnored; }
+    void setIsDefaultEventHandlerIgnored() { m_isDefaultEventHandlerIgnored = true; }
 
-    Event* underlyingEvent() const { return m_underlyingEvent.get(); }
-    void setUnderlyingEvent(PassRefPtr<Event>);
+    void setInPassiveListener(bool value) { m_isExecutingPassiveEventListener = value; }
 
-    virtual DataTransfer* internalDataTransfer() const { return 0; }
+    bool cancelBubble() const { return propagationStopped(); }
+    void setCancelBubble(bool);
 
-    bool isBeingDispatched() const { return eventPhase(); }
+    Event* underlyingEvent() const { return m_underlyingEvent.get(); }
+    void setUnderlyingEvent(Event*);
 
-    virtual PassRefPtr<Event> cloneFor(HTMLIFrameElement*) const;
+    // 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:
-    Event();
-    WEBCORE_EXPORT Event(const AtomicString& type, bool canBubble, bool cancelable);
-    Event(const AtomicString& type, bool canBubble, bool cancelable, double timestamp);
-    Event(const AtomicString& type, const EventInit&);
+    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();
-    bool dispatched() const { return m_target; }
+    virtual void receivedTarget() { }
 
 private:
-    bool m_isInitialized { false };
-    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;
+    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;
-    DOMTimeStamp m_createTime;
+    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
 
 #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()
-
-#endif // Event_h