Home | History | Annotate | Download | only in dom
      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