Make all ScriptWrappable IsoHeap-ed
[WebKit-https.git] / Source / WebCore / dom / KeyboardEvent.cpp
index 54cd983..0f294fc 100644 (file)
@@ -1,8 +1,8 @@
-/**
+/*
  * 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, 2005, 2006, 2007, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2018 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
 #include "config.h"
 #include "KeyboardEvent.h"
 
-#include "Document.h"
 #include "DOMWindow.h"
-#include "EventDispatcher.h"
-#include "EventNames.h"
+#include "Document.h"
+#include "Editor.h"
 #include "EventHandler.h"
+#include "EventNames.h"
 #include "Frame.h"
 #include "PlatformKeyboardEvent.h"
-#include "Settings.h"
 #include "WindowsKeyboardCodes.h"
+#include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
 
-static inline const AtomicString& eventTypeForKeyboardEventType(PlatformEvent::Type type)
+WTF_MAKE_ISO_ALLOCATED_IMPL(KeyboardEvent);
+
+static inline const AtomString& eventTypeForKeyboardEventType(PlatformEvent::Type type)
 {
     switch (type) {
         case PlatformEvent::KeyUp:
@@ -74,123 +76,155 @@ static inline int windowsVirtualKeyCodeWithoutLocation(int keycode)
 static inline KeyboardEvent::KeyLocationCode keyLocationCode(const PlatformKeyboardEvent& key)
 {
     if (key.isKeypad())
-        return KeyboardEvent::DOMKeyLocationNumpad;
+        return KeyboardEvent::DOM_KEY_LOCATION_NUMPAD;
 
     switch (key.windowsVirtualKeyCode()) {
     case VK_LCONTROL:
     case VK_LSHIFT:
     case VK_LMENU:
     case VK_LWIN:
-        return KeyboardEvent::DOMKeyLocationLeft;
+        return KeyboardEvent::DOM_KEY_LOCATION_LEFT;
     case VK_RCONTROL:
     case VK_RSHIFT:
     case VK_RMENU:
     case VK_RWIN:
-        return KeyboardEvent::DOMKeyLocationRight;
+        return KeyboardEvent::DOM_KEY_LOCATION_RIGHT;
     default:
-        return KeyboardEvent::DOMKeyLocationStandard;
+        return KeyboardEvent::DOM_KEY_LOCATION_STANDARD;
     }
 }
 
-KeyboardEventInit::KeyboardEventInit()
-    : location(0)
-    , ctrlKey(false)
-    , altKey(false)
-    , shiftKey(false)
-    , metaKey(false)
-{
-}
+inline KeyboardEvent::KeyboardEvent() = default;
 
-KeyboardEvent::KeyboardEvent()
-    : m_location(DOMKeyLocationStandard)
-    , m_altGraphKey(false)
+inline KeyboardEvent::KeyboardEvent(const PlatformKeyboardEvent& key, RefPtr<WindowProxy>&& view)
+    : UIEventWithKeyState(eventTypeForKeyboardEventType(key.type()), CanBubble::Yes, IsCancelable::Yes, IsComposed::Yes,
+        key.timestamp().approximateMonotonicTime(), view.copyRef(), 0, key.modifiers(), IsTrusted::Yes)
+    , m_underlyingPlatformEvent(makeUnique<PlatformKeyboardEvent>(key))
+#if ENABLE(KEYBOARD_KEY_ATTRIBUTE)
+    , m_key(key.key())
+#endif
+#if ENABLE(KEYBOARD_CODE_ATTRIBUTE)
+    , m_code(key.code())
+#endif
+    , m_keyIdentifier(key.keyIdentifier())
+    , m_location(keyLocationCode(key))
+    , m_repeat(key.isAutoRepeat())
+    , m_isComposing(view && is<DOMWindow>(view->window()) && downcast<DOMWindow>(*view->window()).frame() && downcast<DOMWindow>(*view->window()).frame()->editor().hasComposition())
+#if USE(APPKIT) || USE(UIKIT_KEYBOARD_ADDITIONS)
+    , m_handledByInputMethod(key.handledByInputMethod())
+#endif
+#if USE(APPKIT)
+    , m_keypressCommands(key.commands())
+#endif
+{
+}
+
+inline KeyboardEvent::KeyboardEvent(const AtomString& eventType, const Init& initializer)
+    : UIEventWithKeyState(eventType, initializer)
+#if ENABLE(KEYBOARD_KEY_ATTRIBUTE)
+    , m_key(initializer.key)
+#endif
+#if ENABLE(KEYBOARD_CODE_ATTRIBUTE)
+    , m_code(initializer.code)
+#endif
+    , m_keyIdentifier(initializer.keyIdentifier)
+    , m_location(initializer.keyLocation ? *initializer.keyLocation : initializer.location)
+    , m_repeat(initializer.repeat)
+    , m_isComposing(initializer.isComposing)
+    , m_charCode(initializer.charCode)
+    , m_keyCode(initializer.keyCode)
+    , m_which(initializer.which)
 {
 }
 
-KeyboardEvent::KeyboardEvent(const PlatformKeyboardEvent& key, AbstractView* view)
-    : UIEventWithKeyState(eventTypeForKeyboardEventType(key.type()),
-                          true, true, key.timestamp(), view, 0, key.ctrlKey(), key.altKey(), key.shiftKey(), key.metaKey())
-    , m_keyEvent(adoptPtr(new PlatformKeyboardEvent(key)))
-    , m_keyIdentifier(key.keyIdentifier())
-    , m_location(keyLocationCode(key))
-    , m_altGraphKey(false)
+KeyboardEvent::~KeyboardEvent() = default;
+
+Ref<KeyboardEvent> KeyboardEvent::create(const PlatformKeyboardEvent& platformEvent, RefPtr<WindowProxy>&& view)
 {
+    return adoptRef(*new KeyboardEvent(platformEvent, WTFMove(view)));
 }
 
-KeyboardEvent::KeyboardEvent(const AtomicString& eventType, const KeyboardEventInit& initializer)
-    : UIEventWithKeyState(eventType, initializer.bubbles, initializer.cancelable, initializer.view, initializer.detail, initializer.ctrlKey, initializer.altKey, initializer.shiftKey, initializer.metaKey)
-    , m_keyIdentifier(initializer.keyIdentifier)
-    , m_location(initializer.location)
-    , m_altGraphKey(false)
+Ref<KeyboardEvent> KeyboardEvent::createForBindings()
 {
+    return adoptRef(*new KeyboardEvent);
 }
 
-KeyboardEvent::~KeyboardEvent()
+Ref<KeyboardEvent> KeyboardEvent::create(const AtomString& type, const Init& initializer)
 {
+    return adoptRef(*new KeyboardEvent(type, initializer));
 }
 
-void KeyboardEvent::initKeyboardEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view,
-                                      const String &keyIdentifier, unsigned location,
-                                      bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey)
+void KeyboardEvent::initKeyboardEvent(const AtomString& type, bool canBubble, bool cancelable, RefPtr<WindowProxy>&& view,
+    const String& keyIdentifier, unsigned location, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey)
 {
-    if (dispatched())
+    if (isBeingDispatched())
         return;
 
-    initUIEvent(type, canBubble, cancelable, view, 0);
+    initUIEvent(type, canBubble, cancelable, WTFMove(view), 0);
 
     m_keyIdentifier = keyIdentifier;
     m_location = location;
-    m_ctrlKey = ctrlKey;
-    m_shiftKey = shiftKey;
-    m_altKey = altKey;
-    m_metaKey = metaKey;
-    m_altGraphKey = altGraphKey;
-}
 
-bool KeyboardEvent::getModifierState(const String& keyIdentifier) const
-{
-    if (keyIdentifier == "Control")
-        return ctrlKey();
-    if (keyIdentifier == "Shift")
-        return shiftKey();
-    if (keyIdentifier == "Alt")
-        return altKey();
-    if (keyIdentifier == "Meta")
-        return metaKey();
-    return false;
+    setModifierKeys(ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
+
+    m_charCode = WTF::nullopt;
+    m_isComposing = false;
+    m_keyCode = WTF::nullopt;
+    m_repeat = false;
+    m_underlyingPlatformEvent = nullptr;
+    m_which = WTF::nullopt;
+
+#if ENABLE(KEYBOARD_CODE_ATTRIBUTE)
+    m_code = { };
+#endif
+
+#if ENABLE(KEYBOARD_KEY_ATTRIBUTE)
+    m_key = { };
+#endif
+
+#if PLATFORM(COCOA)
+    m_handledByInputMethod = false;
+    m_keypressCommands = { };
+#endif
 }
 
 int KeyboardEvent::keyCode() const
 {
+    if (m_keyCode)
+        return m_keyCode.value();
+
     // IE: virtual key code for keyup/keydown, character code for keypress
     // Firefox: virtual key code for keyup/keydown, zero for keypress
     // We match IE.
-    if (!m_keyEvent)
+    if (!m_underlyingPlatformEvent)
         return 0;
     if (type() == eventNames().keydownEvent || type() == eventNames().keyupEvent)
-        return windowsVirtualKeyCodeWithoutLocation(m_keyEvent->windowsVirtualKeyCode());
+        return windowsVirtualKeyCodeWithoutLocation(m_underlyingPlatformEvent->windowsVirtualKeyCode());
 
     return charCode();
 }
 
 int KeyboardEvent::charCode() const
 {
+    if (m_charCode)
+        return m_charCode.value();
+
     // IE: not supported
     // Firefox: 0 for keydown/keyup events, character code for keypress
     // We match Firefox, unless in backward compatibility mode, where we always return the character code.
     bool backwardCompatibilityMode = false;
-    if (view() && view()->frame())
-        backwardCompatibilityMode = view()->frame()->eventHandler()->needsKeyboardEventDisambiguationQuirks();
+    auto* window = view() ? view()->window() : nullptr;
+    if (is<DOMWindow>(window) && downcast<DOMWindow>(*window).frame())
+        backwardCompatibilityMode = downcast<DOMWindow>(*window).frame()->eventHandler().needsKeyboardEventDisambiguationQuirks();
 
-    if (!m_keyEvent || (type() != eventNames().keypressEvent && !backwardCompatibilityMode))
+    if (!m_underlyingPlatformEvent || (type() != eventNames().keypressEvent && !backwardCompatibilityMode))
         return 0;
-    String text = m_keyEvent->text();
-    return static_cast<int>(text.characterStartingAt(0));
+    return m_underlyingPlatformEvent->text().characterStartingAt(0);
 }
 
-const AtomicString& KeyboardEvent::interfaceName() const
+EventInterface KeyboardEvent::eventInterface() const
 {
-    return eventNames().interfaceForKeyboardEvent;
+    return KeyboardEventInterfaceType;
 }
 
 bool KeyboardEvent::isKeyboardEvent() const
@@ -202,31 +236,9 @@ int KeyboardEvent::which() const
 {
     // Netscape's "which" returns a virtual key code for keydown and keyup, and a character code for keypress.
     // That's exactly what IE's "keyCode" returns. So they are the same for keyboard events.
+    if (m_which)
+        return m_which.value();
     return keyCode();
 }
 
-KeyboardEvent* findKeyboardEvent(Event* event)
-{
-    for (Event* e = event; e; e = e->underlyingEvent())
-        if (e->isKeyboardEvent())
-            return static_cast<KeyboardEvent*>(e);
-    return 0;
-}
-
-PassRefPtr<KeyboardEventDispatchMediator> KeyboardEventDispatchMediator::create(PassRefPtr<KeyboardEvent> event)
-{
-    return adoptRef(new KeyboardEventDispatchMediator(event));
-}
-
-KeyboardEventDispatchMediator::KeyboardEventDispatchMediator(PassRefPtr<KeyboardEvent> event)
-    : EventDispatchMediator(event)
-{
-}
-
-bool KeyboardEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
-{
-    // Make sure not to return true if we already took default action while handling the event.
-    return EventDispatchMediator::dispatchEvent(dispatcher) && !event()->defaultHandled();
-}
-
 } // namespace WebCore