1 /** 2 * Copyright (C) 2001 Peter Kelly (pmk (at) post.com) 3 * Copyright (C) 2001 Tobias Anton (anton (at) stud.fbi.fh-darmstadt.de) 4 * Copyright (C) 2006 Samuel Weinig (sam.weinig (at) 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()) 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 164