You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/khtml/xml/dom2_eventsimpl.cpp

970 lines
29 KiB

/**
* This file is part of the DOM implementation for KDE.
*
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
* (C) 2003 Apple Computer, Inc.
* (C) 2006 Maksim Orlovich (maksim@kde.org)
*
* 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 "dom/dom2_views.h"
#include "xml/dom2_eventsimpl.h"
#include "xml/dom_stringimpl.h"
#include "xml/dom_nodeimpl.h"
#include "xml/dom_docimpl.h"
#include "rendering/render_layer.h"
#include "khtmlview.h"
#include <kdebug.h>
using namespace DOM;
using namespace khtml;
EventImpl::EventImpl()
{
m_type = 0;
m_canBubble = false;
m_cancelable = false;
m_propagationStopped = false;
m_defaultPrevented = false;
m_id = UNKNOWN_EVENT;
m_currentTarget = 0;
m_eventPhase = 0;
m_target = 0;
m_createTime = TQDateTime::currentDateTime();
m_defaultHandled = false;
}
EventImpl::EventImpl(EventId _id, bool canBubbleArg, bool cancelableArg)
{
DOMString t = EventImpl::idToType(_id);
m_type = t.implementation();
if (m_type)
m_type->ref();
m_canBubble = canBubbleArg;
m_cancelable = cancelableArg;
m_propagationStopped = false;
m_defaultPrevented = false;
m_id = _id;
m_currentTarget = 0;
m_eventPhase = 0;
m_target = 0;
m_createTime = TQDateTime::currentDateTime();
m_defaultHandled = false;
}
EventImpl::~EventImpl()
{
if (m_type)
m_type->deref();
if (m_target)
m_target->deref();
}
void EventImpl::setTarget(NodeImpl *_target)
{
if (m_target)
m_target->deref();
m_target = _target;
if (m_target)
m_target->ref();
}
DOMTimeStamp EventImpl::timeStamp()
{
TQDateTime epoch(TQDate(1970,1,1),TQTime(0,0));
// ### kjs does not yet support long long (?) so the value wraps around
return epoch.secsTo(m_createTime)*1000+m_createTime.time().msec();
}
void EventImpl::initEvent(const DOMString &eventTypeArg, bool canBubbleArg, bool cancelableArg)
{
// ### ensure this is not called after we have been dispatched (also for subclasses)
if (m_type)
m_type->deref();
m_type = eventTypeArg.implementation();
if (m_type)
m_type->ref();
m_id = typeToId(eventTypeArg);
m_canBubble = canBubbleArg;
m_cancelable = cancelableArg;
}
EventImpl::EventId EventImpl::typeToId(DOMString type)
{
if (type == "DOMFocusIn")
return DOMFOCUSIN_EVENT;
else if (type == "DOMFocusOut")
return DOMFOCUSOUT_EVENT;
else if (type == "DOMActivate")
return DOMACTIVATE_EVENT;
else if (type == "click")
return CLICK_EVENT;
else if (type == "mousedown")
return MOUSEDOWN_EVENT;
else if (type == "mouseup")
return MOUSEUP_EVENT;
else if (type == "mouseover")
return MOUSEOVER_EVENT;
else if (type == "mousemove")
return MOUSEMOVE_EVENT;
else if (type == "mouseout")
return MOUSEOUT_EVENT;
else if (type == "DOMSubtreeModified")
return DOMSUBTREEMODIFIED_EVENT;
else if (type == "DOMNodeInserted")
return DOMNODEINSERTED_EVENT;
else if (type == "DOMNodeRemoved")
return DOMNODEREMOVED_EVENT;
else if (type == "DOMNodeRemovedFromDocument")
return DOMNODEREMOVEDFROMDOCUMENT_EVENT;
else if (type == "DOMNodeInsertedIntoDocument")
return DOMNODEINSERTEDINTODOCUMENT_EVENT;
else if (type == "DOMAttrModified")
return DOMATTRMODIFIED_EVENT;
else if (type == "DOMCharacterDataModified")
return DOMCHARACTERDATAMODIFIED_EVENT;
else if (type == "load")
return LOAD_EVENT;
else if (type == "unload")
return UNLOAD_EVENT;
else if (type == "abort")
return ABORT_EVENT;
else if (type == "error")
return ERROR_EVENT;
else if (type == "select")
return SELECT_EVENT;
else if (type == "change")
return CHANGE_EVENT;
else if (type == "submit")
return SUBMIT_EVENT;
else if (type == "reset")
return RESET_EVENT;
else if (type == "focus")
return FOCUS_EVENT;
else if (type == "blur")
return BLUR_EVENT;
else if (type == "resize")
return RESIZE_EVENT;
else if (type == "scroll")
return SCROLL_EVENT;
else if ( type == "keydown" )
return KEYDOWN_EVENT;
else if ( type == "keyup" )
return KEYUP_EVENT;
else if ( type == "textInput" )
return KEYPRESS_EVENT;
else if ( type == "keypress" )
return KEYPRESS_EVENT;
else if ( type == "readystatechange" )
return KHTML_READYSTATECHANGE_EVENT;
else if ( type == "dblclick" )
return KHTML_ECMA_DBLCLICK_EVENT;
// ignore: KHTML_CLICK_EVENT
return UNKNOWN_EVENT;
}
DOMString EventImpl::idToType(EventImpl::EventId id)
{
switch (id) {
case DOMFOCUSIN_EVENT:
return "DOMFocusIn";
case DOMFOCUSOUT_EVENT:
return "DOMFocusOut";
case DOMACTIVATE_EVENT:
return "DOMActivate";
case CLICK_EVENT:
return "click";
case MOUSEDOWN_EVENT:
return "mousedown";
case MOUSEUP_EVENT:
return "mouseup";
case MOUSEOVER_EVENT:
return "mouseover";
case MOUSEMOVE_EVENT:
return "mousemove";
case MOUSEOUT_EVENT:
return "mouseout";
case DOMSUBTREEMODIFIED_EVENT:
return "DOMSubtreeModified";
case DOMNODEINSERTED_EVENT:
return "DOMNodeInserted";
case DOMNODEREMOVED_EVENT:
return "DOMNodeRemoved";
case DOMNODEREMOVEDFROMDOCUMENT_EVENT:
return "DOMNodeRemovedFromDocument";
case DOMNODEINSERTEDINTODOCUMENT_EVENT:
return "DOMNodeInsertedIntoDocument";
case DOMATTRMODIFIED_EVENT:
return "DOMAttrModified";
case DOMCHARACTERDATAMODIFIED_EVENT:
return "DOMCharacterDataModified";
case LOAD_EVENT:
return "load";
case UNLOAD_EVENT:
return "unload";
case ABORT_EVENT:
return "abort";
case ERROR_EVENT:
return "error";
case SELECT_EVENT:
return "select";
case CHANGE_EVENT:
return "change";
case SUBMIT_EVENT:
return "submit";
case RESET_EVENT:
return "reset";
case FOCUS_EVENT:
return "focus";
case BLUR_EVENT:
return "blur";
case RESIZE_EVENT:
return "resize";
case SCROLL_EVENT:
return "scroll";
case KEYDOWN_EVENT:
return "keydown";
case KEYUP_EVENT:
return "keyup";
case KEYPRESS_EVENT:
return "keypress"; //DOM3 ev. suggests textInput, but it's better for compat this way
//khtml extensions
case KHTML_ECMA_DBLCLICK_EVENT:
return "dblclick";
case KHTML_ECMA_CLICK_EVENT:
return "click";
case KHTML_DRAGDROP_EVENT:
return "khtml_dragdrop";
case KHTML_MOVE_EVENT:
return "khtml_move";
case KHTML_READYSTATECHANGE_EVENT:
return "readystatechange";
default:
return DOMString();
break;
}
}
bool EventImpl::isUIEvent() const
{
return false;
}
bool EventImpl::isMouseEvent() const
{
return false;
}
bool EventImpl::isMutationEvent() const
{
return false;
}
bool EventImpl::isTextInputEvent() const
{
return false;
}
bool EventImpl::isKeyboardEvent() const
{
return false;
}
// -----------------------------------------------------------------------------
UIEventImpl::UIEventImpl(EventId _id, bool canBubbleArg, bool cancelableArg,
AbstractViewImpl *viewArg, long detailArg)
: EventImpl(_id,canBubbleArg,cancelableArg)
{
m_view = viewArg;
if (m_view)
m_view->ref();
m_detail = detailArg;
}
UIEventImpl::~UIEventImpl()
{
if (m_view)
m_view->deref();
}
void UIEventImpl::initUIEvent(const DOMString &typeArg,
bool canBubbleArg,
bool cancelableArg,
const AbstractView &viewArg,
long detailArg)
{
EventImpl::initEvent(typeArg,canBubbleArg,cancelableArg);
if (m_view)
m_view->deref();
m_view = viewArg.handle();
if (m_view)
m_view->ref();
m_detail = detailArg;
}
bool UIEventImpl::isUIEvent() const
{
return true;
}
// -----------------------------------------------------------------------------
MouseEventImpl::MouseEventImpl()
{
m_screenX = 0;
m_screenY = 0;
m_clientX = 0;
m_clientY = 0;
m_pageX = 0;
m_pageY = 0;
m_ctrlKey = false;
m_altKey = false;
m_shiftKey = false;
m_metaKey = false;
m_button = 0;
m_relatedTarget = 0;
m_qevent = 0;
m_isDoubleClick = false;
}
MouseEventImpl::MouseEventImpl(EventId _id,
bool canBubbleArg,
bool cancelableArg,
AbstractViewImpl *viewArg,
long detailArg,
long screenXArg,
long screenYArg,
long clientXArg,
long clientYArg,
long pageXArg,
long pageYArg,
bool ctrlKeyArg,
bool altKeyArg,
bool shiftKeyArg,
bool metaKeyArg,
unsigned short buttonArg,
NodeImpl *relatedTargetArg,
TQMouseEvent *qe,
bool isDoubleClick)
: UIEventImpl(_id,canBubbleArg,cancelableArg,viewArg,detailArg)
{
m_screenX = screenXArg;
m_screenY = screenYArg;
m_clientX = clientXArg;
m_clientY = clientYArg;
m_pageX = pageXArg;
m_pageY = pageYArg;
m_ctrlKey = ctrlKeyArg;
m_altKey = altKeyArg;
m_shiftKey = shiftKeyArg;
m_metaKey = metaKeyArg;
m_button = buttonArg;
m_relatedTarget = relatedTargetArg;
if (m_relatedTarget)
m_relatedTarget->ref();
computeLayerPos();
m_qevent = qe;
m_isDoubleClick = isDoubleClick;
}
MouseEventImpl::~MouseEventImpl()
{
if (m_relatedTarget)
m_relatedTarget->deref();
}
void MouseEventImpl::computeLayerPos()
{
m_layerX = m_pageX;
m_layerY = m_pageY;
DocumentImpl* doc = view() ? view()->document() : 0;
if (doc) {
khtml::RenderObject::NodeInfo renderInfo(true, false);
doc->renderer()->layer()->nodeAtPoint(renderInfo, m_pageX, m_pageY);
NodeImpl *node = renderInfo.innerNonSharedNode();
while (node && !node->renderer())
node = node->parent();
if (node) {
node->renderer()->enclosingLayer()->updateLayerPosition();
for (RenderLayer* layer = node->renderer()->enclosingLayer(); layer;
layer = layer->parent()) {
m_layerX -= layer->xPos();
m_layerY -= layer->yPos();
}
}
}
}
void MouseEventImpl::initMouseEvent(const DOMString &typeArg,
bool canBubbleArg,
bool cancelableArg,
const AbstractView &viewArg,
long detailArg,
long screenXArg,
long screenYArg,
long clientXArg,
long clientYArg,
bool ctrlKeyArg,
bool altKeyArg,
bool shiftKeyArg,
bool metaKeyArg,
unsigned short buttonArg,
const Node &relatedTargetArg)
{
UIEventImpl::initUIEvent(typeArg,canBubbleArg,cancelableArg,viewArg,detailArg);
if (m_relatedTarget)
m_relatedTarget->deref();
m_screenX = screenXArg;
m_screenY = screenYArg;
m_clientX = clientXArg;
m_clientY = clientYArg;
m_pageX = clientXArg;
m_pageY = clientYArg;
KHTMLView* v;
if ( view() && view()->document() && ( v = view()->document()->view() ) ) {
m_pageX += v->contentsX();
m_pageY += v->contentsY();
}
m_ctrlKey = ctrlKeyArg;
m_altKey = altKeyArg;
m_shiftKey = shiftKeyArg;
m_metaKey = metaKeyArg;
m_button = buttonArg;
m_relatedTarget = relatedTargetArg.handle();
if (m_relatedTarget)
m_relatedTarget->ref();
// ### make this on-demand. its soo sloooow
computeLayerPos();
m_qevent = 0;
}
bool MouseEventImpl::isMouseEvent() const
{
return true;
}
//---------------------------------------------------------------------------------------------
/* This class is used to do remapping between different encodings reasonably compactly */
template<typename L, typename R, typename MemL>
class IDTranslator
{
public:
struct Info {
MemL l;
R r;
};
IDTranslator(const Info* table) {
for (const Info* cursor = table; cursor->l; ++cursor) {
m_lToR.insert(cursor->l, cursor->r);
m_rToL.insert(cursor->r, cursor->l);
}
}
L toLeft(R r) {
TQMapIterator<R,L> i( m_rToL.find(r) );
if (i != m_rToL.end())
return *i;
return L();
}
R toRight(L l) {
TQMapIterator<L,R> i = m_lToR.find(l);
if (i != m_lToR.end())
return *i;
return R();
}
private:
TQMap<L, R> m_lToR;
TQMap<R, L> m_rToL;
};
#define MAKE_TRANSLATOR(name,L,R,MR,table) static IDTranslator<L,R,MR>* s_##name; \
static IDTranslator<L,R,MR>* name() { if (!s_##name) s_##name = new IDTranslator<L,R,MR>(table); \
return s_##name; }
//---------------------------------------------------------------------------------------------
/* Mapping between special Qt keycodes and virtual DOM codes */
IDTranslator<unsigned, unsigned, unsigned>::Info virtKeyToQtKeyTable[] =
{
{KeyEventBaseImpl::DOM_VK_BACK_SPACE, Qt::Key_Backspace},
{KeyEventBaseImpl::DOM_VK_ENTER, Qt::Key_Enter},
{KeyEventBaseImpl::DOM_VK_ENTER, Qt::Key_Return},
{KeyEventBaseImpl::DOM_VK_NUM_LOCK, Qt::Key_NumLock},
{KeyEventBaseImpl::DOM_VK_RIGHT_ALT, Qt::Key_Alt},
{KeyEventBaseImpl::DOM_VK_LEFT_CONTROL, Qt::Key_Control},
{KeyEventBaseImpl::DOM_VK_LEFT_SHIFT, Qt::Key_Shift},
{KeyEventBaseImpl::DOM_VK_META, Qt::Key_Meta},
{KeyEventBaseImpl::DOM_VK_CAPS_LOCK, Qt::Key_CapsLock},
{KeyEventBaseImpl::DOM_VK_DELETE, Qt::Key_Delete},
{KeyEventBaseImpl::DOM_VK_END, Qt::Key_End},
{KeyEventBaseImpl::DOM_VK_ESCAPE, Qt::Key_Escape},
{KeyEventBaseImpl::DOM_VK_HOME, Qt::Key_Home},
{KeyEventBaseImpl::DOM_VK_PAUSE, Qt::Key_Pause},
{KeyEventBaseImpl::DOM_VK_PRINTSCREEN, Qt::Key_Print},
{KeyEventBaseImpl::DOM_VK_SCROLL_LOCK, Qt::Key_ScrollLock},
{KeyEventBaseImpl::DOM_VK_LEFT, Qt::Key_Left},
{KeyEventBaseImpl::DOM_VK_RIGHT, Qt::Key_Right},
{KeyEventBaseImpl::DOM_VK_UP, Qt::Key_Up},
{KeyEventBaseImpl::DOM_VK_DOWN, Qt::Key_Down},
{KeyEventBaseImpl::DOM_VK_PAGE_DOWN, TQt::Key_Next},
{KeyEventBaseImpl::DOM_VK_PAGE_UP, TQt::Key_Prior},
{KeyEventBaseImpl::DOM_VK_F1, Qt::Key_F1},
{KeyEventBaseImpl::DOM_VK_F2, Qt::Key_F2},
{KeyEventBaseImpl::DOM_VK_F3, Qt::Key_F3},
{KeyEventBaseImpl::DOM_VK_F4, Qt::Key_F4},
{KeyEventBaseImpl::DOM_VK_F5, Qt::Key_F5},
{KeyEventBaseImpl::DOM_VK_F6, Qt::Key_F6},
{KeyEventBaseImpl::DOM_VK_F7, Qt::Key_F7},
{KeyEventBaseImpl::DOM_VK_F8, Qt::Key_F8},
{KeyEventBaseImpl::DOM_VK_F9, Qt::Key_F9},
{KeyEventBaseImpl::DOM_VK_F10, Qt::Key_F10},
{KeyEventBaseImpl::DOM_VK_F11, Qt::Key_F11},
{KeyEventBaseImpl::DOM_VK_F12, Qt::Key_F12},
{KeyEventBaseImpl::DOM_VK_F13, Qt::Key_F13},
{KeyEventBaseImpl::DOM_VK_F14, Qt::Key_F14},
{KeyEventBaseImpl::DOM_VK_F15, Qt::Key_F15},
{KeyEventBaseImpl::DOM_VK_F16, Qt::Key_F16},
{KeyEventBaseImpl::DOM_VK_F17, Qt::Key_F17},
{KeyEventBaseImpl::DOM_VK_F18, Qt::Key_F18},
{KeyEventBaseImpl::DOM_VK_F19, Qt::Key_F19},
{KeyEventBaseImpl::DOM_VK_F20, Qt::Key_F20},
{KeyEventBaseImpl::DOM_VK_F21, Qt::Key_F21},
{KeyEventBaseImpl::DOM_VK_F22, Qt::Key_F22},
{KeyEventBaseImpl::DOM_VK_F23, Qt::Key_F23},
{KeyEventBaseImpl::DOM_VK_F24, Qt::Key_F24},
{0, 0}
};
MAKE_TRANSLATOR(virtKeyToQtKey, unsigned, unsigned, unsigned, virtKeyToQtKeyTable)
KeyEventBaseImpl::KeyEventBaseImpl(EventId id, bool canBubbleArg, bool cancelableArg, AbstractViewImpl *viewArg,
TQKeyEvent *key) :
UIEventImpl(id, canBubbleArg, cancelableArg, viewArg, 0)
{
m_synthetic = false;
//Here, we need to map Qt's internal info to browser-style info.
m_keyEvent = new TQKeyEvent(key->type(), key->key(), key->ascii(), key->state(), key->text(), key->isAutoRepeat(), key->count() );
m_detail = key->count();
m_keyVal = key->ascii();
m_virtKeyVal = virtKeyToQtKey()->toLeft(key->key());
// m_keyVal should contain the unicode value
// of the pressed key if available.
if (m_virtKeyVal == DOM_VK_UNDEFINED && !key->text().isEmpty())
m_keyVal = TQString(key->text()).unicode()[0];
// key->state returns enum ButtonState, which is ShiftButton, ControlButton and AltButton or'ed together.
m_modifier = key->state();
}
KeyEventBaseImpl::~KeyEventBaseImpl()
{
delete m_keyEvent;
}
void KeyEventBaseImpl::initKeyBaseEvent(const DOMString &typeArg,
bool canBubbleArg,
bool cancelableArg,
const AbstractView &viewArg,
unsigned long keyValArg,
unsigned long virtKeyValArg,
unsigned long modifiersArg)
{
m_synthetic = true;
delete m_keyEvent;
m_keyEvent = 0;
initUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, 1);
m_virtKeyVal = virtKeyValArg;
m_keyVal = keyValArg;
m_modifier = modifiersArg;
}
bool KeyEventBaseImpl::checkModifier(unsigned long modifierArg)
{
return ((m_modifier & modifierArg) == modifierArg);
}
void KeyEventBaseImpl::initModifier(unsigned long modifierArg,
bool valueArg)
{
if (valueArg)
m_modifier |= modifierArg;
else
m_modifier &= (modifierArg ^ 0xFFFFFFFF);
}
void KeyEventBaseImpl::buildQKeyEvent() const
{
delete m_keyEvent;
assert(m_synthetic);
//IMPORTANT: we ignore modifers on purpose.
//this is to prevent a website from synthesizing something
//like Ctrl-V or Shift-Insert and stealing contents of the user's clipboard.
unsigned modifiers = 0;
int key = 0;
int ascii = 0;
TQString text;
if (m_virtKeyVal)
key = virtKeyToQtKey()->toRight(m_virtKeyVal);
if (!key) {
ascii = m_keyVal; //###?
key = m_keyVal;
text = TQChar(key);
}
//Neuter F keys as well.
if (key >= Qt::Key_F1 && key <= Qt::Key_F35)
key = Qt::Key_ScrollLock;
m_keyEvent = new TQKeyEvent(id() == KEYUP_EVENT ? TQEvent::KeyRelease : TQEvent::KeyPress,
key, ascii, modifiers, text);
}
//------------------------------------------------------------------------------
static const IDTranslator<TQCString, unsigned, const char*>::Info keyIdentifiersToVirtKeysTable[] = {
{"Alt", KeyEventBaseImpl::DOM_VK_LEFT_ALT},
{"Control", KeyEventBaseImpl::DOM_VK_LEFT_CONTROL},
{"Shift", KeyEventBaseImpl::DOM_VK_LEFT_SHIFT},
{"Meta", KeyEventBaseImpl::DOM_VK_META},
{"\0x08", KeyEventBaseImpl::DOM_VK_SPACE}, //1-char virt!
{"CapsLock", KeyEventBaseImpl::DOM_VK_CAPS_LOCK},
{"\x7F", KeyEventBaseImpl::DOM_VK_DELETE}, //1-char virt!
{"End", KeyEventBaseImpl::DOM_VK_END},
{"Enter", KeyEventBaseImpl::DOM_VK_ENTER},
{"\x1b", KeyEventBaseImpl::DOM_VK_ESCAPE}, //1-char virt!
{"Home", KeyEventBaseImpl::DOM_VK_HOME},
{"NumLock", KeyEventBaseImpl::DOM_VK_NUM_LOCK},
{"Pause", KeyEventBaseImpl::DOM_VK_PAUSE},
{"PrintScreen", KeyEventBaseImpl::DOM_VK_PRINTSCREEN},
{"Scroll", KeyEventBaseImpl::DOM_VK_SCROLL_LOCK},
{" ", KeyEventBaseImpl::DOM_VK_SPACE}, //1-char virt!
{"\t", KeyEventBaseImpl::DOM_VK_TAB}, //1-char virt!
{"Left", KeyEventBaseImpl::DOM_VK_LEFT},
{"Left", KeyEventBaseImpl::DOM_VK_LEFT},
{"Right", KeyEventBaseImpl::DOM_VK_RIGHT},
{"Up", KeyEventBaseImpl::DOM_VK_UP},
{"Down", KeyEventBaseImpl::DOM_VK_DOWN},
{"PageDown", KeyEventBaseImpl::DOM_VK_PAGE_DOWN},
{"PageUp", KeyEventBaseImpl::DOM_VK_PAGE_UP},
{"F1", KeyEventBaseImpl::DOM_VK_F1},
{"F2", KeyEventBaseImpl::DOM_VK_F2},
{"F3", KeyEventBaseImpl::DOM_VK_F3},
{"F4", KeyEventBaseImpl::DOM_VK_F4},
{"F5", KeyEventBaseImpl::DOM_VK_F5},
{"F6", KeyEventBaseImpl::DOM_VK_F6},
{"F7", KeyEventBaseImpl::DOM_VK_F7},
{"F8", KeyEventBaseImpl::DOM_VK_F8},
{"F9", KeyEventBaseImpl::DOM_VK_F9},
{"F10", KeyEventBaseImpl::DOM_VK_F10},
{"F11", KeyEventBaseImpl::DOM_VK_F11},
{"F12", KeyEventBaseImpl::DOM_VK_F12},
{"F13", KeyEventBaseImpl::DOM_VK_F13},
{"F14", KeyEventBaseImpl::DOM_VK_F14},
{"F15", KeyEventBaseImpl::DOM_VK_F15},
{"F16", KeyEventBaseImpl::DOM_VK_F16},
{"F17", KeyEventBaseImpl::DOM_VK_F17},
{"F18", KeyEventBaseImpl::DOM_VK_F18},
{"F19", KeyEventBaseImpl::DOM_VK_F19},
{"F20", KeyEventBaseImpl::DOM_VK_F20},
{"F21", KeyEventBaseImpl::DOM_VK_F21},
{"F22", KeyEventBaseImpl::DOM_VK_F22},
{"F23", KeyEventBaseImpl::DOM_VK_F23},
{"F24", KeyEventBaseImpl::DOM_VK_F24},
{0, 0}
};
MAKE_TRANSLATOR(keyIdentifiersToVirtKeys, TQCString, unsigned, const char*, keyIdentifiersToVirtKeysTable)
/** These are the modifiers we currently support */
static const IDTranslator<TQCString, unsigned, const char*>::Info keyModifiersToCodeTable[] = {
{"Alt", TQt::AltButton},
{"Control", TQt::ControlButton},
{"Shift", TQt::ShiftButton},
{"Meta", TQt::MetaButton},
{0, 0}
};
MAKE_TRANSLATOR(keyModifiersToCode, TQCString, unsigned, const char*, keyModifiersToCodeTable)
KeyboardEventImpl::KeyboardEventImpl() : m_keyLocation(DOM_KEY_LOCATION_STANDARD)
{}
DOMString KeyboardEventImpl::keyIdentifier() const
{
if (unsigned special = virtKeyVal())
if (const char* id = keyIdentifiersToVirtKeys()->toLeft(special))
return TQString::fromLatin1(id);
if (unsigned unicode = keyVal())
return TQString(TQChar(unicode));
return "Unidentified";
}
bool KeyboardEventImpl::getModifierState (const DOMString& keyIdentifierArg) const
{
unsigned mask = keyModifiersToCode()->toRight(keyIdentifierArg.string().latin1());
return m_modifier & mask;
}
bool KeyboardEventImpl::isKeyboardEvent() const
{
return true;
}
void KeyboardEventImpl::initKeyboardEvent(const DOMString &typeArg,
bool canBubbleArg,
bool cancelableArg,
const AbstractView &viewArg,
const DOMString &keyIdentifierArg,
unsigned long keyLocationArg,
const DOMString& modifiersList)
{
unsigned keyVal = 0;
unsigned virtKeyVal = 0;
m_keyLocation = keyLocationArg;
//Figure out the code information from the key identifier.
if (keyIdentifierArg.length() == 1) {
//Likely to be normal unicode id, unless it's one of the few
//special values.
unsigned short code = keyIdentifierArg.unicode()[0];
if (code > 0x20 && code != 0x7F)
keyVal = code;
}
if (!keyVal) //One of special keys, likely.
virtKeyVal = keyIdentifiersToVirtKeys()->toRight(keyIdentifierArg.string().latin1());
//Process modifier list.
TQStringList mods =
TQStringList::split(' ',
modifiersList.string().stripWhiteSpace().simplifyWhiteSpace());
unsigned modifiers = 0;
for (TQStringList::Iterator i = mods.begin(); i != mods.end(); ++i)
if (unsigned mask = keyModifiersToCode()->toRight((*i).latin1()))
modifiers |= mask;
initKeyBaseEvent(typeArg, canBubbleArg, cancelableArg, viewArg,
keyVal, virtKeyVal, modifiers);
}
KeyboardEventImpl::KeyboardEventImpl(TQKeyEvent* key, DOM::AbstractViewImpl* view) :
KeyEventBaseImpl(key->type() == TQEvent::KeyRelease ? KEYUP_EVENT : KEYDOWN_EVENT, true, true, view, key)
{
//Try to put something reasonable in location...
//we don't know direction, so guess left
m_keyLocation = DOM_KEY_LOCATION_STANDARD;
switch (m_virtKeyVal) {
case DOM_VK_LEFT_ALT:
case DOM_VK_LEFT_SHIFT:
case DOM_VK_LEFT_CONTROL:
case DOM_VK_META:
m_keyLocation = DOM_KEY_LOCATION_LEFT;
}
}
int KeyboardEventImpl::keyCode() const
{
//Keycode on key events always identifies the -key- and not the input,
//so e.g. 'a' will get 'A'
if (m_virtKeyVal != DOM_VK_UNDEFINED)
return m_virtKeyVal;
else
return TQChar((unsigned short)m_keyVal).upper().unicode();
}
int KeyboardEventImpl::charCode() const
{
//IE doesn't support charCode at all, and mozilla returns 0
//on key events. So return 0 here
return 0;
}
// -----------------------------------------------------------------------------
TextEventImpl::TextEventImpl()
{}
bool TextEventImpl::isTextInputEvent() const
{
return true;
}
TextEventImpl::TextEventImpl(TQKeyEvent* key, DOM::AbstractViewImpl* view) :
KeyEventBaseImpl(KEYPRESS_EVENT, true, true, view, key)
{
m_outputString = TQString(key->text());
}
void TextEventImpl::initTextEvent(const DOMString &typeArg,
bool canBubbleArg,
bool cancelableArg,
const AbstractView &viewArg,
const DOMString& text)
{
m_outputString = text;
//See whether we can get a key out of this.
unsigned keyCode = 0;
if (text.length() == 1)
keyCode = text.unicode()[0].unicode();
initKeyBaseEvent(typeArg, canBubbleArg, cancelableArg, viewArg,
keyCode, 0, 0);
}
int TextEventImpl::keyCode() const
{
//Mozilla returns 0 here unless this is a non-unicode key.
//IE stuffs everything here, and so we try to match it..
if (m_keyVal)
return m_keyVal;
return m_virtKeyVal;
}
int TextEventImpl::charCode() const
{
//On text events, in Mozilla charCode is 0 for non-unicode keys,
//and the unicode key otherwise... IE doesn't support this.
if (m_virtKeyVal)
return 0;
return m_keyVal;
}
// -----------------------------------------------------------------------------
MutationEventImpl::MutationEventImpl()
{
m_relatedNode = 0;
m_prevValue = 0;
m_newValue = 0;
m_attrName = 0;
m_attrChange = 0;
}
MutationEventImpl::MutationEventImpl(EventId _id,
bool canBubbleArg,
bool cancelableArg,
const Node &relatedNodeArg,
const DOMString &prevValueArg,
const DOMString &newValueArg,
const DOMString &attrNameArg,
unsigned short attrChangeArg)
: EventImpl(_id,canBubbleArg,cancelableArg)
{
m_relatedNode = relatedNodeArg.handle();
if (m_relatedNode)
m_relatedNode->ref();
m_prevValue = prevValueArg.implementation();
if (m_prevValue)
m_prevValue->ref();
m_newValue = newValueArg.implementation();
if (m_newValue)
m_newValue->ref();
m_attrName = attrNameArg.implementation();
if (m_attrName)
m_attrName->ref();
m_attrChange = attrChangeArg;
}
MutationEventImpl::~MutationEventImpl()
{
if (m_relatedNode)
m_relatedNode->deref();
if (m_prevValue)
m_prevValue->deref();
if (m_newValue)
m_newValue->deref();
if (m_attrName)
m_attrName->deref();
}
void MutationEventImpl::initMutationEvent(const DOMString &typeArg,
bool canBubbleArg,
bool cancelableArg,
const Node &relatedNodeArg,
const DOMString &prevValueArg,
const DOMString &newValueArg,
const DOMString &attrNameArg,
unsigned short attrChangeArg)
{
EventImpl::initEvent(typeArg,canBubbleArg,cancelableArg);
if (m_relatedNode)
m_relatedNode->deref();
if (m_prevValue)
m_prevValue->deref();
if (m_newValue)
m_newValue->deref();
if (m_attrName)
m_attrName->deref();
m_relatedNode = relatedNodeArg.handle();
if (m_relatedNode)
m_relatedNode->ref();
m_prevValue = prevValueArg.implementation();
if (m_prevValue)
m_prevValue->ref();
m_newValue = newValueArg.implementation();
if (m_newValue)
m_newValue->ref();
m_attrName = attrNameArg.implementation();
if (m_newValue)
m_newValue->ref();
m_attrChange = attrChangeArg;
}
bool MutationEventImpl::isMutationEvent() const
{
return true;
}