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 34namespace WebCore { 35 36static 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 53KeyboardEvent::KeyboardEvent() 54 : m_keyEvent(0) 55 , m_keyLocation(DOM_KEY_LOCATION_STANDARD) 56 , m_altGraphKey(false) 57{ 58} 59 60KeyboardEvent::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 70KeyboardEvent::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 81KeyboardEvent::~KeyboardEvent() 82{ 83} 84 85void 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 103bool 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 116int 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 128int 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 143bool KeyboardEvent::isKeyboardEvent() const 144{ 145 return true; 146} 147 148int 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 155KeyboardEvent* 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