Move WebCore into Source
[WebKit-https.git] / Source / WebCore / dom / KeyboardEvent.cpp
1 /**
2  * Copyright (C) 2001 Peter Kelly (pmk@post.com)
3  * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
4  * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
5  * Copyright (C) 2003, 2005, 2006, 2007 Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include "config.h"
24 #include "KeyboardEvent.h"
25
26 #include "Document.h"
27 #include "DOMWindow.h"
28 #include "EventNames.h"
29 #include "EventHandler.h"
30 #include "Frame.h"
31 #include "PlatformKeyboardEvent.h"
32 #include "Settings.h"
33
34 namespace WebCore {
35
36 static inline const AtomicString& eventTypeForKeyboardEventType(PlatformKeyboardEvent::Type type)
37 {
38     switch (type) {
39         case PlatformKeyboardEvent::KeyUp:
40             return eventNames().keyupEvent;
41         case PlatformKeyboardEvent::RawKeyDown:
42             return eventNames().keydownEvent;
43         case PlatformKeyboardEvent::Char:
44             return eventNames().keypressEvent;
45         case PlatformKeyboardEvent::KeyDown:
46             // The caller should disambiguate the combined event into RawKeyDown or Char events.
47             break;
48     }
49     ASSERT_NOT_REACHED();
50     return eventNames().keydownEvent;
51 }
52
53 KeyboardEvent::KeyboardEvent()
54     : m_keyEvent(0)
55     , m_keyLocation(DOM_KEY_LOCATION_STANDARD)
56     , m_altGraphKey(false)
57 {
58 }
59
60 KeyboardEvent::KeyboardEvent(const PlatformKeyboardEvent& key, AbstractView* view)
61     : UIEventWithKeyState(eventTypeForKeyboardEventType(key.type()),
62                           true, true, view, 0, key.ctrlKey(), key.altKey(), key.shiftKey(), key.metaKey())
63     , m_keyEvent(new PlatformKeyboardEvent(key))
64     , m_keyIdentifier(key.keyIdentifier())
65     , m_keyLocation(key.isKeypad() ? DOM_KEY_LOCATION_NUMPAD : DOM_KEY_LOCATION_STANDARD) // FIXME: differentiate right/left, too
66     , m_altGraphKey(false)
67 {
68 }
69
70 KeyboardEvent::KeyboardEvent(const AtomicString& eventType, bool canBubble, bool cancelable, AbstractView *view,
71                              const String &keyIdentifier,  unsigned keyLocation,
72                              bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey)
73     : UIEventWithKeyState(eventType, canBubble, cancelable, view, 0, ctrlKey, altKey, shiftKey, metaKey)
74     , m_keyEvent(0)
75     , m_keyIdentifier(keyIdentifier)
76     , m_keyLocation(keyLocation)
77     , m_altGraphKey(altGraphKey)
78 {
79 }
80
81 KeyboardEvent::~KeyboardEvent()
82 {
83 }
84
85 void KeyboardEvent::initKeyboardEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view,
86                                       const String &keyIdentifier, unsigned keyLocation,
87                                       bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey)
88 {
89     if (dispatched())
90         return;
91
92     initUIEvent(type, canBubble, cancelable, view, 0);
93
94     m_keyIdentifier = keyIdentifier;
95     m_keyLocation = keyLocation;
96     m_ctrlKey = ctrlKey;
97     m_shiftKey = shiftKey;
98     m_altKey = altKey;
99     m_metaKey = metaKey;
100     m_altGraphKey = altGraphKey;
101 }
102
103 bool KeyboardEvent::getModifierState(const String& keyIdentifier) const
104 {
105     if (keyIdentifier == "Control")
106         return ctrlKey();
107     if (keyIdentifier == "Shift")
108         return shiftKey();
109     if (keyIdentifier == "Alt")
110         return altKey();
111     if (keyIdentifier == "Meta")
112         return metaKey();
113     return false;
114 }
115
116 int KeyboardEvent::keyCode() const
117 {
118     // IE: virtual key code for keyup/keydown, character code for keypress
119     // Firefox: virtual key code for keyup/keydown, zero for keypress
120     // We match IE.
121     if (!m_keyEvent)
122         return 0;
123     if (type() == eventNames().keydownEvent || type() == eventNames().keyupEvent)
124         return m_keyEvent->windowsVirtualKeyCode();
125     return charCode();
126 }
127
128 int KeyboardEvent::charCode() const
129 {
130     // IE: not supported
131     // Firefox: 0 for keydown/keyup events, character code for keypress
132     // We match Firefox, unless in backward compatibility mode, where we always return the character code.
133     bool backwardCompatibilityMode = false;
134     if (view() && view()->frame())
135         backwardCompatibilityMode = view()->frame()->eventHandler()->needsKeyboardEventDisambiguationQuirks();
136
137     if (!m_keyEvent || (type() != eventNames().keypressEvent && !backwardCompatibilityMode))
138         return 0;
139     String text = m_keyEvent->text();
140     return static_cast<int>(text.characterStartingAt(0));
141 }
142
143 bool KeyboardEvent::isKeyboardEvent() const
144 {
145     return true;
146 }
147
148 int KeyboardEvent::which() const
149 {
150     // Netscape's "which" returns a virtual key code for keydown and keyup, and a character code for keypress.
151     // That's exactly what IE's "keyCode" returns. So they are the same for keyboard events.
152     return keyCode();
153 }
154
155 KeyboardEvent* findKeyboardEvent(Event* event)
156 {
157     for (Event* e = event; e; e = e->underlyingEvent())
158         if (e->isKeyboardEvent())
159             return static_cast<KeyboardEvent*>(e);
160     return 0;
161 }
162
163 } // namespace WebCore