summaryrefslogtreecommitdiffstats
path: root/khtml/xml/dom2_eventsimpl.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /khtml/xml/dom2_eventsimpl.cpp
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'khtml/xml/dom2_eventsimpl.cpp')
-rw-r--r--khtml/xml/dom2_eventsimpl.cpp969
1 files changed, 969 insertions, 0 deletions
diff --git a/khtml/xml/dom2_eventsimpl.cpp b/khtml/xml/dom2_eventsimpl.cpp
new file mode 100644
index 000000000..db8b17b6f
--- /dev/null
+++ b/khtml/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 "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 = QDateTime::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 = QDateTime::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()
+{
+ QDateTime epoch(QDate(1970,1,1),QTime(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,
+ QMouseEvent *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) {
+ QMapIterator<R,L> i( m_rToL.find(r) );
+ if (i != m_rToL.end())
+ return *i;
+ return L();
+ }
+
+ R toRight(L l) {
+ QMapIterator<L,R> i = m_lToR.find(l);
+ if (i != m_lToR.end())
+ return *i;
+ return R();
+ }
+
+private:
+ QMap<L, R> m_lToR;
+ QMap<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, Qt::Key_Next},
+ {KeyEventBaseImpl::DOM_VK_PAGE_UP, Qt::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,
+ QKeyEvent *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 QKeyEvent(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 = 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;
+ QString text;
+ if (m_virtKeyVal)
+ key = virtKeyToQtKey()->toRight(m_virtKeyVal);
+ if (!key) {
+ ascii = m_keyVal; //###?
+ key = m_keyVal;
+ text = QChar(key);
+ }
+
+ //Neuter F keys as well.
+ if (key >= Qt::Key_F1 && key <= Qt::Key_F35)
+ key = Qt::Key_ScrollLock;
+
+ m_keyEvent = new QKeyEvent(id() == KEYUP_EVENT ? QEvent::KeyRelease : QEvent::KeyPress,
+ key, ascii, modifiers, text);
+}
+
+//------------------------------------------------------------------------------
+
+
+static const IDTranslator<QCString, 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, QCString, unsigned, const char*, keyIdentifiersToVirtKeysTable)
+
+/** These are the modifiers we currently support */
+static const IDTranslator<QCString, unsigned, const char*>::Info keyModifiersToCodeTable[] = {
+ {"Alt", Qt::AltButton},
+ {"Control", Qt::ControlButton},
+ {"Shift", Qt::ShiftButton},
+ {"Meta", Qt::MetaButton},
+ {0, 0}
+};
+
+MAKE_TRANSLATOR(keyModifiersToCode, QCString, 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 QString::fromLatin1(id);
+
+ if (unsigned unicode = keyVal())
+ return QString(QChar(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.
+ QStringList mods =
+ QStringList::split(' ',
+ modifiersList.string().stripWhiteSpace().simplifyWhiteSpace());
+
+ unsigned modifiers = 0;
+ for (QStringList::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(QKeyEvent* key, DOM::AbstractViewImpl* view) :
+ KeyEventBaseImpl(key->type() == QEvent::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 QChar((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(QKeyEvent* key, DOM::AbstractViewImpl* view) :
+ KeyEventBaseImpl(KEYPRESS_EVENT, true, true, view, key)
+{
+ m_outputString = 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;
+}
+