diff options
Diffstat (limited to 'tdehtml/xml/dom2_eventsimpl.cpp')
-rw-r--r-- | tdehtml/xml/dom2_eventsimpl.cpp | 969 |
1 files changed, 969 insertions, 0 deletions
diff --git a/tdehtml/xml/dom2_eventsimpl.cpp b/tdehtml/xml/dom2_eventsimpl.cpp new file mode 100644 index 000000000..c0bb10f9a --- /dev/null +++ b/tdehtml/xml/dom2_eventsimpl.cpp @@ -0,0 +1,969 @@ +/** + * 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 "tdehtmlview.h" + +#include <kdebug.h> + +using namespace DOM; +using namespace tdehtml; + +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 + + //tdehtml extensions + case KHTML_ECMA_DBLCLICK_EVENT: + return "dblclick"; + case KHTML_ECMA_CLICK_EVENT: + return "click"; + case KHTML_DRAGDROP_EVENT: + return "tdehtml_dragdrop"; + case KHTML_MOVE_EVENT: + return "tdehtml_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) { + tdehtml::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; +} + |