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 "EventDispatcher.h" 29#include "EventNames.h" 30#include "EventHandler.h" 31#include "Frame.h" 32#include "PlatformKeyboardEvent.h" 33#include "Settings.h" 34 35namespace WebCore { 36 37static inline const AtomicString& eventTypeForKeyboardEventType(PlatformKeyboardEvent::Type type) 38{ 39 switch (type) { 40 case PlatformKeyboardEvent::KeyUp: 41 return eventNames().keyupEvent; 42 case PlatformKeyboardEvent::RawKeyDown: 43 return eventNames().keydownEvent; 44 case PlatformKeyboardEvent::Char: 45 return eventNames().keypressEvent; 46 case PlatformKeyboardEvent::KeyDown: 47 // The caller should disambiguate the combined event into RawKeyDown or Char events. 48 break; 49 } 50 ASSERT_NOT_REACHED(); 51 return eventNames().keydownEvent; 52} 53 54KeyboardEvent::KeyboardEvent() 55 : m_keyEvent(0) 56 , m_keyLocation(DOM_KEY_LOCATION_STANDARD) 57 , m_altGraphKey(false) 58{ 59} 60 61KeyboardEvent::KeyboardEvent(const PlatformKeyboardEvent& key, AbstractView* view) 62 : UIEventWithKeyState(eventTypeForKeyboardEventType(key.type()), 63 true, true, view, 0, key.ctrlKey(), key.altKey(), key.shiftKey(), key.metaKey()) 64 , m_keyEvent(new PlatformKeyboardEvent(key)) 65 , m_keyIdentifier(key.keyIdentifier()) 66 , m_keyLocation(key.isKeypad() ? DOM_KEY_LOCATION_NUMPAD : DOM_KEY_LOCATION_STANDARD) // FIXME: differentiate right/left, too 67 , m_altGraphKey(false) 68{ 69} 70 71KeyboardEvent::KeyboardEvent(const AtomicString& eventType, bool canBubble, bool cancelable, AbstractView *view, 72 const String &keyIdentifier, unsigned keyLocation, 73 bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) 74 : UIEventWithKeyState(eventType, canBubble, cancelable, view, 0, ctrlKey, altKey, shiftKey, metaKey) 75 , m_keyEvent(0) 76 , m_keyIdentifier(keyIdentifier) 77 , m_keyLocation(keyLocation) 78 , m_altGraphKey(altGraphKey) 79{ 80} 81 82KeyboardEvent::~KeyboardEvent() 83{ 84} 85 86void KeyboardEvent::initKeyboardEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view, 87 const String &keyIdentifier, unsigned keyLocation, 88 bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) 89{ 90 if (dispatched()) 91 return; 92 93 initUIEvent(type, canBubble, cancelable, view, 0); 94 95 m_keyIdentifier = keyIdentifier; 96 m_keyLocation = keyLocation; 97 m_ctrlKey = ctrlKey; 98 m_shiftKey = shiftKey; 99 m_altKey = altKey; 100 m_metaKey = metaKey; 101 m_altGraphKey = altGraphKey; 102} 103 104bool KeyboardEvent::getModifierState(const String& keyIdentifier) const 105{ 106 if (keyIdentifier == "Control") 107 return ctrlKey(); 108 if (keyIdentifier == "Shift") 109 return shiftKey(); 110 if (keyIdentifier == "Alt") 111 return altKey(); 112 if (keyIdentifier == "Meta") 113 return metaKey(); 114 return false; 115} 116 117int KeyboardEvent::keyCode() const 118{ 119 // IE: virtual key code for keyup/keydown, character code for keypress 120 // Firefox: virtual key code for keyup/keydown, zero for keypress 121 // We match IE. 122 if (!m_keyEvent) 123 return 0; 124 if (type() == eventNames().keydownEvent || type() == eventNames().keyupEvent) 125 return m_keyEvent->windowsVirtualKeyCode(); 126 return charCode(); 127} 128 129int KeyboardEvent::charCode() const 130{ 131 // IE: not supported 132 // Firefox: 0 for keydown/keyup events, character code for keypress 133 // We match Firefox, unless in backward compatibility mode, where we always return the character code. 134 bool backwardCompatibilityMode = false; 135 if (view() && view()->frame()) 136 backwardCompatibilityMode = view()->frame()->eventHandler()->needsKeyboardEventDisambiguationQuirks(); 137 138 if (!m_keyEvent || (type() != eventNames().keypressEvent && !backwardCompatibilityMode)) 139 return 0; 140 String text = m_keyEvent->text(); 141 return static_cast<int>(text.characterStartingAt(0)); 142} 143 144bool KeyboardEvent::isKeyboardEvent() const 145{ 146 return true; 147} 148 149int KeyboardEvent::which() const 150{ 151 // Netscape's "which" returns a virtual key code for keydown and keyup, and a character code for keypress. 152 // That's exactly what IE's "keyCode" returns. So they are the same for keyboard events. 153 return keyCode(); 154} 155 156KeyboardEvent* findKeyboardEvent(Event* event) 157{ 158 for (Event* e = event; e; e = e->underlyingEvent()) 159 if (e->isKeyboardEvent()) 160 return static_cast<KeyboardEvent*>(e); 161 return 0; 162} 163 164KeyboardEventDispatchMediator::KeyboardEventDispatchMediator(PassRefPtr<KeyboardEvent> event) 165 : EventDispatchMediator(event) 166{ 167} 168 169bool KeyboardEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const 170{ 171 // Make sure not to return true if we already took default action while handling the event. 172 return EventDispatchMediator::dispatchEvent(dispatcher) && !event()->defaultHandled(); 173} 174 175} // namespace WebCore 176