blob: c11b3bd83336b08688f82ca4ec09a6033c710da8 [file] [log] [blame]
/**
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
* Copyright (C) 2003, 2005, 2006, 2007 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "core/events/KeyboardEvent.h"
#include "bindings/core/v8/DOMWrapperWorld.h"
#include "bindings/core/v8/ScriptState.h"
#include "platform/PlatformKeyboardEvent.h"
#include "platform/WindowsKeyboardCodes.h"
#include "wtf/PtrUtil.h"
namespace blink {
static inline const AtomicString& eventTypeForKeyboardEventType(PlatformEvent::EventType type)
{
switch (type) {
case PlatformEvent::KeyUp:
return EventTypeNames::keyup;
case PlatformEvent::RawKeyDown:
return EventTypeNames::keydown;
case PlatformEvent::Char:
return EventTypeNames::keypress;
case PlatformEvent::KeyDown:
// The caller should disambiguate the combined event into RawKeyDown or Char events.
break;
default:
break;
}
ASSERT_NOT_REACHED();
return EventTypeNames::keydown;
}
static inline KeyboardEvent::KeyLocationCode keyLocationCode(const PlatformKeyboardEvent& key)
{
if (key.isKeypad())
return KeyboardEvent::DOM_KEY_LOCATION_NUMPAD;
if (key.getModifiers() & PlatformEvent::IsLeft)
return KeyboardEvent::DOM_KEY_LOCATION_LEFT;
if (key.getModifiers() & PlatformEvent::IsRight)
return KeyboardEvent::DOM_KEY_LOCATION_RIGHT;
return KeyboardEvent::DOM_KEY_LOCATION_STANDARD;
}
KeyboardEvent* KeyboardEvent::create(ScriptState* scriptState, const AtomicString& type, const KeyboardEventInit& initializer)
{
if (scriptState->world().isIsolatedWorld())
UIEventWithKeyState::didCreateEventInIsolatedWorld(initializer.ctrlKey(), initializer.altKey(), initializer.shiftKey(), initializer.metaKey());
return new KeyboardEvent(type, initializer);
}
KeyboardEvent::KeyboardEvent()
: m_location(DOM_KEY_LOCATION_STANDARD)
{
}
KeyboardEvent::KeyboardEvent(const PlatformKeyboardEvent& key, AbstractView* view)
: UIEventWithKeyState(eventTypeForKeyboardEventType(key.type()), true, true, view, 0, key.getModifiers(), key.timestamp(), InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities())
, m_keyEvent(wrapUnique(new PlatformKeyboardEvent(key)))
, m_code(key.code())
, m_key(key.key())
, m_location(keyLocationCode(key))
{
initLocationModifiers(m_location);
}
KeyboardEvent::KeyboardEvent(const AtomicString& eventType, const KeyboardEventInit& initializer)
: UIEventWithKeyState(eventType, initializer)
, m_code(initializer.code())
, m_key(initializer.key())
, m_location(initializer.location())
{
if (initializer.repeat())
m_modifiers |= PlatformEvent::IsAutoRepeat;
initLocationModifiers(initializer.location());
}
KeyboardEvent::KeyboardEvent(const AtomicString& eventType, bool canBubble, bool cancelable, AbstractView* view,
const String& code, const String& key, unsigned location, PlatformEvent::Modifiers modifiers,
double plaformTimeStamp)
: UIEventWithKeyState(eventType, canBubble, cancelable, view, 0, modifiers, plaformTimeStamp, InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities())
, m_code(code)
, m_key(key)
, m_location(location)
{
initLocationModifiers(location);
}
KeyboardEvent::~KeyboardEvent()
{
}
void KeyboardEvent::initKeyboardEvent(ScriptState* scriptState, const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view,
const String& keyIdentifier, unsigned location, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
if (isBeingDispatched())
return;
if (scriptState->world().isIsolatedWorld())
UIEventWithKeyState::didCreateEventInIsolatedWorld(ctrlKey, altKey, shiftKey, metaKey);
initUIEvent(type, canBubble, cancelable, view, 0);
m_location = location;
initModifiers(ctrlKey, altKey, shiftKey, metaKey);
initLocationModifiers(location);
}
int KeyboardEvent::keyCode() const
{
// IE: virtual key code for keyup/keydown, character code for keypress
// Firefox: virtual key code for keyup/keydown, zero for keypress
// We match IE.
if (!m_keyEvent)
return 0;
#if OS(ANDROID)
// FIXME: Check to see if this applies to other OS.
// If the key event belongs to IME composition then propagate to JS.
if (m_keyEvent->nativeVirtualKeyCode() == 0xE5) // VKEY_PROCESSKEY
return m_keyEvent->nativeVirtualKeyCode();
#endif
if (type() == EventTypeNames::keydown || type() == EventTypeNames::keyup)
return m_keyEvent->windowsVirtualKeyCode();
return charCode();
}
int KeyboardEvent::charCode() const
{
// IE: not supported
// Firefox: 0 for keydown/keyup events, character code for keypress
// We match Firefox
if (!m_keyEvent || (type() != EventTypeNames::keypress))
return 0;
String text = m_keyEvent->text();
return static_cast<int>(text.characterStartingAt(0));
}
const AtomicString& KeyboardEvent::interfaceName() const
{
return EventNames::KeyboardEvent;
}
bool KeyboardEvent::isKeyboardEvent() const
{
return true;
}
int KeyboardEvent::which() const
{
// Netscape's "which" returns a virtual key code for keydown and keyup, and a character code for keypress.
// That's exactly what IE's "keyCode" returns. So they are the same for keyboard events.
return keyCode();
}
void KeyboardEvent::initLocationModifiers(unsigned location)
{
switch (location) {
case KeyboardEvent::DOM_KEY_LOCATION_NUMPAD:
m_modifiers |= PlatformEvent::IsKeyPad;
break;
case KeyboardEvent::DOM_KEY_LOCATION_LEFT:
m_modifiers |= PlatformEvent::IsLeft;
break;
case KeyboardEvent::DOM_KEY_LOCATION_RIGHT:
m_modifiers |= PlatformEvent::IsRight;
break;
}
}
DEFINE_TRACE(KeyboardEvent)
{
UIEventWithKeyState::trace(visitor);
}
} // namespace blink