1 /**
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *           (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
6  *           (C) 2003 Apple Computer, Inc.
7  *           (C) 2006, 2010 Maksim Orlovich (maksim@kde.org)
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23 
24  */
25 
26 #include "dom2_eventsimpl.h"
27 
28 #include <dom/dom2_views.h>
29 
30 #include "dom_stringimpl.h"
31 #include "dom_nodeimpl.h"
32 #include "dom_docimpl.h"
33 #include "misc/translator.h"
34 #include <rendering/render_layer.h>
35 #include <khtmlview.h>
36 #include <khtml_part.h>
37 
38 #include <QActionEvent>
39 #include "khtml_debug.h"
40 
41 using namespace DOM;
42 using namespace khtml;
43 
handleLocalEvents(EventImpl * evt,bool useCapture)44 void EventTargetImpl::handleLocalEvents(EventImpl *evt, bool useCapture)
45 {
46     if (!m_regdListeners.listeners) {
47         return;
48     }
49 
50     Event ev = evt;
51     // removeEventListener (e.g. called from a JS event listener) might
52     // invalidate the item after the current iterator (which "it" is pointing to).
53     // So we make a copy of the list.
54     QList<RegisteredEventListener> listeners = *m_regdListeners.listeners;
55     QList<RegisteredEventListener>::iterator it;
56     for (it = listeners.begin(); it != listeners.end(); ++it) {
57         //Check whether this got removed... TODO: use Java-style iterators
58         if (!m_regdListeners.stillContainsListener(*it)) {
59             continue;
60         }
61 
62         RegisteredEventListener &current = (*it);
63         if (current.eventName == evt->name() && current.useCapture == useCapture) {
64             current.listener->handleEvent(ev);
65         }
66 
67         // ECMA legacy hack
68         if (current.useCapture == useCapture && evt->id() == EventImpl::CLICK_EVENT) {
69             MouseEventImpl *me = static_cast<MouseEventImpl *>(evt);
70             if (me->button() == 0) {
71                 // To find whether to call onclick or ondblclick, we can't
72                 // * use me->detail(), it's 2 when clicking twice w/o moving, even very slowly
73                 // * use me->qEvent(), it's not available when using initMouseEvent/dispatchEvent
74                 // So we currently store a bool in MouseEventImpl. If anyone needs to trigger
75                 // dblclicks from the DOM API, we'll need a timer here (well in the doc).
76                 if ((!me->isDoubleClick() && current.eventName.id() == EventImpl::KHTML_ECMA_CLICK_EVENT) ||
77                         (me->isDoubleClick() && current.eventName.id() == EventImpl::KHTML_ECMA_DBLCLICK_EVENT)) {
78                     current.listener->handleEvent(ev);
79                 }
80             }
81         }
82     }
83 }
84 
defaultEventHandler(EventImpl *)85 void EventTargetImpl::defaultEventHandler(EventImpl *)
86 {}
87 
eventTargetDocument()88 DocumentImpl *EventTargetImpl::eventTargetDocument()
89 {
90     return nullptr;
91 }
92 
setDocListenerFlag(unsigned flag)93 void EventTargetImpl::setDocListenerFlag(unsigned flag)
94 {
95     DocumentImpl *doc = eventTargetDocument();
96     if (doc) {
97         doc->addListenerType(DocumentImpl::ListenerType(flag));
98     }
99 }
100 
addEventListener(EventName id,EventListener * listener,const bool useCapture)101 void EventTargetImpl::addEventListener(EventName id, EventListener *listener, const bool useCapture)
102 {
103     switch (id.id()) {
104     case EventImpl::DOMSUBTREEMODIFIED_EVENT:
105         setDocListenerFlag(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER);
106         break;
107     case EventImpl::DOMNODEINSERTED_EVENT:
108         setDocListenerFlag(DocumentImpl::DOMNODEINSERTED_LISTENER);
109         break;
110     case EventImpl::DOMNODEREMOVED_EVENT:
111         setDocListenerFlag(DocumentImpl::DOMNODEREMOVED_LISTENER);
112         break;
113     case EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT:
114         setDocListenerFlag(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
115         break;
116     case EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT:
117         setDocListenerFlag(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER);
118         break;
119     case EventImpl::DOMATTRMODIFIED_EVENT:
120         setDocListenerFlag(DocumentImpl::DOMATTRMODIFIED_LISTENER);
121         break;
122     case EventImpl::DOMCHARACTERDATAMODIFIED_EVENT:
123         setDocListenerFlag(DocumentImpl::DOMCHARACTERDATAMODIFIED_LISTENER);
124         break;
125     default:
126         break;
127     }
128 
129     m_regdListeners.addEventListener(id, listener, useCapture);
130 }
131 
removeEventListener(EventName id,EventListener * listener,bool useCapture)132 void EventTargetImpl::removeEventListener(EventName id, EventListener *listener, bool useCapture)
133 {
134     m_regdListeners.removeEventListener(id, listener, useCapture);
135 }
136 
setHTMLEventListener(EventName id,EventListener * listener)137 void EventTargetImpl::setHTMLEventListener(EventName id, EventListener *listener)
138 {
139     m_regdListeners.setHTMLEventListener(id, listener);
140 }
141 
setHTMLEventListener(unsigned id,EventListener * listener)142 void EventTargetImpl::setHTMLEventListener(unsigned id, EventListener *listener)
143 {
144     m_regdListeners.setHTMLEventListener(EventName::fromId(id), listener);
145 }
146 
getHTMLEventListener(EventName id)147 EventListener *EventTargetImpl::getHTMLEventListener(EventName id)
148 {
149     return m_regdListeners.getHTMLEventListener(id);
150 }
151 
getHTMLEventListener(unsigned id)152 EventListener *EventTargetImpl::getHTMLEventListener(unsigned id)
153 {
154     return m_regdListeners.getHTMLEventListener(EventName::fromId(id));
155 }
156 // -----------------------------------------------------------------------------
157 
addEventListener(EventName id,EventListener * listener,const bool useCapture)158 void RegisteredListenerList::addEventListener(EventName id, EventListener *listener, const bool useCapture)
159 {
160     if (!listener) {
161         return;
162     }
163     RegisteredEventListener rl(id, listener, useCapture);
164     if (!listeners) {
165         listeners = new QList<RegisteredEventListener>;
166     }
167 
168     // if this id/listener/useCapture combination is already registered, do nothing.
169     // the DOM2 spec says that "duplicate instances are discarded", and this keeps
170     // the listener order intact.
171     QList<RegisteredEventListener>::iterator it;
172     for (it = listeners->begin(); it != listeners->end(); ++it)
173         if (*it == rl) {
174             return;
175         }
176 
177     listeners->append(rl);
178 }
179 
removeEventListener(EventName id,EventListener * listener,bool useCapture)180 void RegisteredListenerList::removeEventListener(EventName id, EventListener *listener, bool useCapture)
181 {
182     if (!listeners) { // nothing to remove
183         return;
184     }
185 
186     RegisteredEventListener rl(id, listener, useCapture);
187 
188     QList<RegisteredEventListener>::iterator it;
189     for (it = listeners->begin(); it != listeners->end(); ++it)
190         if (*it == rl) {
191             listeners->erase(it);
192             return;
193         }
194 }
195 
isHTMLEventListener(EventListener * listener)196 bool RegisteredListenerList::isHTMLEventListener(EventListener *listener)
197 {
198     return (listener->eventListenerType() == "_khtml_HTMLEventListener");
199 }
200 
setHTMLEventListener(EventName name,EventListener * listener)201 void RegisteredListenerList::setHTMLEventListener(EventName name, EventListener *listener)
202 {
203     if (!listeners) {
204         listeners = new QList<RegisteredEventListener>;
205     }
206 
207     QList<RegisteredEventListener>::iterator it;
208     if (!listener) {
209         for (it = listeners->begin(); it != listeners->end(); ++it) {
210             if ((*it).eventName == name && isHTMLEventListener((*it).listener)) {
211                 listeners->erase(it);
212                 break;
213             }
214         }
215         return;
216     }
217 
218     // if this event already has a registered handler, insert the new one in
219     // place of the old one, to preserve the order.
220     RegisteredEventListener rl(name, listener, false);
221 
222     for (int i = 0; i < listeners->size(); ++i) {
223         const RegisteredEventListener &listener = listeners->at(i);
224         if (listener.eventName == name && isHTMLEventListener(listener.listener)) {
225             listeners->replace(i, rl);
226             return;
227         }
228     }
229 
230     listeners->append(rl);
231 }
232 
getHTMLEventListener(EventName name)233 EventListener *RegisteredListenerList::getHTMLEventListener(EventName name)
234 {
235     if (!listeners) {
236         return nullptr;
237     }
238 
239     QList<RegisteredEventListener>::iterator it;
240     for (it = listeners->begin(); it != listeners->end(); ++it)
241         if ((*it).eventName == name && isHTMLEventListener((*it).listener)) {
242             return (*it).listener;
243         }
244     return nullptr;
245 }
246 
hasEventListener(EventName name)247 bool RegisteredListenerList::hasEventListener(EventName name)
248 {
249     if (!listeners) {
250         return false;
251     }
252 
253     QList<RegisteredEventListener>::iterator it;
254     for (it = listeners->begin(); it != listeners->end(); ++it)
255         if ((*it).eventName == name) {
256             return true;
257         }
258 
259     return false;
260 }
261 
clear()262 void RegisteredListenerList::clear()
263 {
264     delete listeners;
265     listeners = nullptr;
266 }
267 
stillContainsListener(const RegisteredEventListener & listener)268 bool RegisteredListenerList::stillContainsListener(const RegisteredEventListener &listener)
269 {
270     if (!listeners) {
271         return false;
272     }
273     return listeners->contains(listener);
274 }
275 
~RegisteredListenerList()276 RegisteredListenerList::~RegisteredListenerList()
277 {
278     delete listeners; listeners = nullptr;
279 }
280 
281 // -----------------------------------------------------------------------------
282 
EventImpl()283 EventImpl::EventImpl()
284 {
285     m_canBubble = false;
286     m_cancelable = false;
287 
288     m_propagationStopped = false;
289     m_defaultPrevented = false;
290     m_currentTarget = nullptr;
291     m_eventPhase = 0;
292     m_target = nullptr;
293     m_createTime = QDateTime::currentDateTime();
294     m_defaultHandled = false;
295 }
296 
EventImpl(EventId _id,bool canBubbleArg,bool cancelableArg)297 EventImpl::EventImpl(EventId _id, bool canBubbleArg, bool cancelableArg)
298 {
299     m_eventName = EventName::fromId(_id);
300     m_canBubble = canBubbleArg;
301     m_cancelable = cancelableArg;
302 
303     m_propagationStopped = false;
304     m_defaultPrevented = false;
305     m_currentTarget = nullptr;
306     m_eventPhase = 0;
307     m_target = nullptr;
308     m_createTime = QDateTime::currentDateTime();
309     m_defaultHandled = false;
310 }
311 
~EventImpl()312 EventImpl::~EventImpl()
313 {
314     if (m_target) {
315         m_target->deref();
316     }
317 }
318 
setTarget(EventTargetImpl * _target)319 void EventImpl::setTarget(EventTargetImpl *_target)
320 {
321     if (m_target) {
322         m_target->deref();
323     }
324     m_target = _target;
325     if (m_target) {
326         m_target->ref();
327     }
328 }
329 
timeStamp()330 DOMTimeStamp EventImpl::timeStamp()
331 {
332     QDateTime epoch(QDate(1970, 1, 1), QTime(0, 0));
333     // ### kjs does not yet support long long (?) so the value wraps around
334     return epoch.secsTo(m_createTime) * 1000 + m_createTime.time().msec();
335 }
336 
initEvent(const DOMString & eventTypeArg,bool canBubbleArg,bool cancelableArg)337 void EventImpl::initEvent(const DOMString &eventTypeArg, bool canBubbleArg, bool cancelableArg)
338 {
339     // ### ensure this is not called after we have been dispatched (also for subclasses)
340 
341     m_eventName = EventName::fromString(eventTypeArg);
342 
343     m_canBubble = canBubbleArg;
344     m_cancelable = cancelableArg;
345 }
346 
347 khtml::IDTable<EventImpl> *EventImpl::s_idTable;
348 
initIdTable()349 khtml::IDTable<EventImpl> *EventImpl::initIdTable()
350 {
351     s_idTable = new khtml::IDTable<EventImpl>();
352     s_idTable->addStaticMapping(DOMFOCUSIN_EVENT, "DOMFocusIn");
353     s_idTable->addStaticMapping(DOMFOCUSOUT_EVENT, "DOMFocusOut");
354     s_idTable->addStaticMapping(DOMACTIVATE_EVENT, "DOMActivate");
355     s_idTable->addStaticMapping(CLICK_EVENT, "click");
356     s_idTable->addStaticMapping(MOUSEDOWN_EVENT, "mousedown");
357     s_idTable->addStaticMapping(MOUSEUP_EVENT, "mouseup");
358     s_idTable->addStaticMapping(MOUSEOVER_EVENT, "mouseover");
359     s_idTable->addStaticMapping(MOUSEMOVE_EVENT, "mousemove");
360     s_idTable->addStaticMapping(MOUSEOUT_EVENT, "mouseout");
361     s_idTable->addStaticMapping(DOMSUBTREEMODIFIED_EVENT, "DOMSubtreeModified");
362     s_idTable->addStaticMapping(DOMNODEINSERTED_EVENT, "DOMNodeInserted");
363     s_idTable->addStaticMapping(DOMNODEREMOVED_EVENT, "DOMNodeRemoved");
364     s_idTable->addStaticMapping(DOMNODEREMOVEDFROMDOCUMENT_EVENT, "DOMNodeRemovedFromDocument");
365     s_idTable->addStaticMapping(DOMNODEINSERTEDINTODOCUMENT_EVENT, "DOMNodeInsertedIntoDocument");
366     s_idTable->addStaticMapping(DOMATTRMODIFIED_EVENT, "DOMAttrModified");
367     s_idTable->addStaticMapping(DOMCHARACTERDATAMODIFIED_EVENT, "DOMCharacterDataModified");
368     s_idTable->addStaticMapping(LOAD_EVENT, "load");
369     s_idTable->addStaticMapping(UNLOAD_EVENT, "unload");
370     s_idTable->addStaticMapping(ABORT_EVENT, "abort");
371     s_idTable->addStaticMapping(ERROR_EVENT, "error");
372     s_idTable->addStaticMapping(SELECT_EVENT, "select");
373     s_idTable->addStaticMapping(CHANGE_EVENT, "change");
374     s_idTable->addStaticMapping(SUBMIT_EVENT, "submit");
375     s_idTable->addStaticMapping(RESET_EVENT, "reset");
376     s_idTable->addStaticMapping(FOCUS_EVENT, "focus");
377     s_idTable->addStaticMapping(BLUR_EVENT, "blur");
378     s_idTable->addStaticMapping(RESIZE_EVENT, "resize");
379     s_idTable->addStaticMapping(SCROLL_EVENT, "scroll");
380     s_idTable->addStaticMapping(KEYDOWN_EVENT, "keydown");
381     s_idTable->addStaticMapping(KEYUP_EVENT, "keyup");
382     s_idTable->addStaticMapping(KEYPRESS_EVENT, "keypress");
383     //DOM3 ev. suggests textInput, but it's better for compat this way
384     s_idTable->addStaticMapping(HASHCHANGE_EVENT, "hashchange");
385 
386     //khtml extensions
387     s_idTable->addStaticMapping(KHTML_ECMA_DBLCLICK_EVENT, "dblclick");
388     s_idTable->addHiddenMapping(KHTML_ECMA_CLICK_EVENT, "click");
389     s_idTable->addStaticMapping(KHTML_DRAGDROP_EVENT, "khtml_dragdrop");
390     s_idTable->addStaticMapping(KHTML_MOVE_EVENT, "khtml_move");
391     s_idTable->addStaticMapping(KHTML_MOUSEWHEEL_EVENT, "DOMMouseScroll");
392     // adopt the mozilla name for compatibility
393     s_idTable->addStaticMapping(KHTML_CONTENTLOADED_EVENT, "DOMContentLoaded");
394     // idem
395     s_idTable->addStaticMapping(KHTML_READYSTATECHANGE_EVENT, "readystatechange");
396 
397     s_idTable->addStaticMapping(MESSAGE_EVENT, "message");
398 
399     return s_idTable;
400 }
401 
isUIEvent() const402 bool EventImpl::isUIEvent() const
403 {
404     return false;
405 }
406 
isMouseEvent() const407 bool EventImpl::isMouseEvent() const
408 {
409     return false;
410 }
411 
isMutationEvent() const412 bool EventImpl::isMutationEvent() const
413 {
414     return false;
415 }
416 
isTextInputEvent() const417 bool EventImpl::isTextInputEvent() const
418 {
419     return false;
420 }
421 
isKeyboardEvent() const422 bool EventImpl::isKeyboardEvent() const
423 {
424     return false;
425 }
426 
isMessageEvent() const427 bool EventImpl::isMessageEvent() const
428 {
429     return false;
430 }
431 
isHashChangeEvent() const432 bool EventImpl::isHashChangeEvent() const
433 {
434     return false;
435 }
436 
437 // -----------------------------------------------------------------------------
438 
UIEventImpl(EventId _id,bool canBubbleArg,bool cancelableArg,AbstractViewImpl * viewArg,long detailArg)439 UIEventImpl::UIEventImpl(EventId _id, bool canBubbleArg, bool cancelableArg,
440                          AbstractViewImpl *viewArg, long detailArg)
441     : EventImpl(_id, canBubbleArg, cancelableArg)
442 {
443     m_view = viewArg;
444     if (m_view) {
445         m_view->ref();
446     }
447     m_detail = detailArg;
448 }
449 
~UIEventImpl()450 UIEventImpl::~UIEventImpl()
451 {
452     if (m_view) {
453         m_view->deref();
454     }
455 }
456 
initUIEvent(const DOMString & typeArg,bool canBubbleArg,bool cancelableArg,AbstractViewImpl * viewArg,long detailArg)457 void UIEventImpl::initUIEvent(const DOMString &typeArg,
458                               bool canBubbleArg,
459                               bool cancelableArg,
460                               AbstractViewImpl *viewArg,
461                               long detailArg)
462 {
463     EventImpl::initEvent(typeArg, canBubbleArg, cancelableArg);
464 
465     if (viewArg) {
466         viewArg->ref();
467     }
468 
469     if (m_view) {
470         m_view->deref();
471     }
472 
473     m_view = viewArg;
474 
475     m_detail = detailArg;
476 }
477 
isUIEvent() const478 bool UIEventImpl::isUIEvent() const
479 {
480     return true;
481 }
482 
483 // -----------------------------------------------------------------------------
484 
MouseEventImpl()485 MouseEventImpl::MouseEventImpl()
486 {
487     m_screenX = 0;
488     m_screenY = 0;
489     m_clientX = 0;
490     m_clientY = 0;
491     m_pageX = 0;
492     m_pageY = 0;
493     m_ctrlKey = false;
494     m_altKey = false;
495     m_shiftKey = false;
496     m_metaKey = false;
497     m_button = 0;
498     m_relatedTarget = nullptr;
499     m_qevent = nullptr;
500     m_isDoubleClick = false;
501 }
502 
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,Orientation orient)503 MouseEventImpl::MouseEventImpl(EventId _id,
504                                bool canBubbleArg,
505                                bool cancelableArg,
506                                AbstractViewImpl *viewArg,
507                                long detailArg,
508                                long screenXArg,
509                                long screenYArg,
510                                long clientXArg,
511                                long clientYArg,
512                                long pageXArg,
513                                long pageYArg,
514                                bool ctrlKeyArg,
515                                bool altKeyArg,
516                                bool shiftKeyArg,
517                                bool metaKeyArg,
518                                unsigned short buttonArg,
519                                NodeImpl *relatedTargetArg,
520                                QMouseEvent *qe,
521                                bool isDoubleClick,
522                                Orientation orient)
523     : UIEventImpl(_id, canBubbleArg, cancelableArg, viewArg, detailArg)
524 {
525     m_screenX = screenXArg;
526     m_screenY = screenYArg;
527     m_clientX = clientXArg;
528     m_clientY = clientYArg;
529     m_pageX = pageXArg;
530     m_pageY = pageYArg;
531     m_ctrlKey = ctrlKeyArg;
532     m_altKey = altKeyArg;
533     m_shiftKey = shiftKeyArg;
534     m_metaKey = metaKeyArg;
535     m_button = buttonArg;
536     m_relatedTarget = relatedTargetArg;
537     if (m_relatedTarget) {
538         m_relatedTarget->ref();
539     }
540     computeLayerPos();
541     m_qevent = qe;
542     m_isDoubleClick = isDoubleClick;
543     m_orientation = orient;
544 }
545 
~MouseEventImpl()546 MouseEventImpl::~MouseEventImpl()
547 {
548     if (m_relatedTarget) {
549         m_relatedTarget->deref();
550     }
551 }
552 
computeLayerPos()553 void MouseEventImpl::computeLayerPos()
554 {
555     m_layerX = m_pageX;
556     m_layerY = m_pageY;
557 
558     DocumentImpl *doc = view() ? view()->document() : nullptr;
559     if (doc && doc->renderer()) {
560         khtml::RenderObject::NodeInfo renderInfo(true, false);
561         doc->renderer()->layer()->nodeAtPoint(renderInfo, m_pageX, m_pageY);
562 
563         NodeImpl *node = renderInfo.innerNonSharedNode();
564         while (node && !node->renderer()) {
565             node = node->parent();
566         }
567 
568         if (node) {
569             RenderLayer *layer = node->renderer()->enclosingLayer();
570             if (layer) {
571                 layer->updateLayerPosition();
572             }
573 
574             while (layer) {
575                 m_layerX -= layer->xPos();
576                 m_layerY -= layer->yPos();
577                 layer = layer->parent();
578             }
579         }
580     }
581 }
582 
initMouseEvent(const DOMString & typeArg,bool canBubbleArg,bool cancelableArg,AbstractViewImpl * 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,Orientation orient)583 void MouseEventImpl::initMouseEvent(const DOMString &typeArg,
584                                     bool canBubbleArg,
585                                     bool cancelableArg,
586                                     AbstractViewImpl *viewArg,
587                                     long detailArg,
588                                     long screenXArg,
589                                     long screenYArg,
590                                     long clientXArg,
591                                     long clientYArg,
592                                     bool ctrlKeyArg,
593                                     bool altKeyArg,
594                                     bool shiftKeyArg,
595                                     bool metaKeyArg,
596                                     unsigned short buttonArg,
597                                     const Node &relatedTargetArg,
598                                     Orientation orient)
599 {
600     UIEventImpl::initUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg);
601 
602     if (m_relatedTarget) {
603         m_relatedTarget->deref();
604     }
605 
606     m_screenX = screenXArg;
607     m_screenY = screenYArg;
608     m_clientX = clientXArg;
609     m_clientY = clientYArg;
610     m_pageX   = clientXArg;
611     m_pageY   = clientYArg;
612     KHTMLView *v;
613     if (view() && view()->document() && (v = view()->document()->view())) {
614         m_pageX += v->contentsX();
615         m_pageY += v->contentsY();
616     }
617     m_ctrlKey = ctrlKeyArg;
618     m_altKey = altKeyArg;
619     m_shiftKey = shiftKeyArg;
620     m_metaKey = metaKeyArg;
621     m_button = buttonArg;
622     m_relatedTarget = relatedTargetArg.handle();
623     if (m_relatedTarget) {
624         m_relatedTarget->ref();
625     }
626     m_orientation = orient;
627 
628     // ### make this on-demand. it is soo sloooow
629     computeLayerPos();
630     m_qevent = nullptr;
631 }
632 
isMouseEvent() const633 bool MouseEventImpl::isMouseEvent() const
634 {
635     return true;
636 }
637 
638 //---------------------------------------------------------------------------------------------
639 
640 /* Mapping between special Qt keycodes and virtual DOM codes */
641 IDTranslator<unsigned, unsigned, unsigned>::Info virtKeyToQtKeyTable[] = {
642     {KeyEventBaseImpl::DOM_VK_BACK_SPACE, Qt::Key_Backspace},
643     {KeyEventBaseImpl::DOM_VK_ENTER, Qt::Key_Enter},
644     {KeyEventBaseImpl::DOM_VK_ENTER, Qt::Key_Return},
645     {KeyEventBaseImpl::DOM_VK_NUM_LOCK,  Qt::Key_NumLock},
646     {KeyEventBaseImpl::DOM_VK_RIGHT_ALT,    Qt::Key_Alt},
647     {KeyEventBaseImpl::DOM_VK_LEFT_CONTROL, Qt::Key_Control},
648     {KeyEventBaseImpl::DOM_VK_LEFT_SHIFT,   Qt::Key_Shift},
649     {KeyEventBaseImpl::DOM_VK_META,         Qt::Key_Meta},
650     {KeyEventBaseImpl::DOM_VK_CAPS_LOCK,    Qt::Key_CapsLock},
651     {KeyEventBaseImpl::DOM_VK_DELETE,       Qt::Key_Delete},
652     {KeyEventBaseImpl::DOM_VK_INSERT,       Qt::Key_Insert},
653     {KeyEventBaseImpl::DOM_VK_END,          Qt::Key_End},
654     {KeyEventBaseImpl::DOM_VK_ESCAPE,       Qt::Key_Escape},
655     {KeyEventBaseImpl::DOM_VK_HOME,         Qt::Key_Home},
656     {KeyEventBaseImpl::DOM_VK_PAUSE,        Qt::Key_Pause},
657     {KeyEventBaseImpl::DOM_VK_PRINTSCREEN,  Qt::Key_Print},
658     {KeyEventBaseImpl::DOM_VK_SCROLL_LOCK,  Qt::Key_ScrollLock},
659     {KeyEventBaseImpl::DOM_VK_LEFT,         Qt::Key_Left},
660     {KeyEventBaseImpl::DOM_VK_RIGHT,        Qt::Key_Right},
661     {KeyEventBaseImpl::DOM_VK_UP,           Qt::Key_Up},
662     {KeyEventBaseImpl::DOM_VK_DOWN,         Qt::Key_Down},
663     {KeyEventBaseImpl::DOM_VK_PAGE_DOWN,    Qt::Key_PageDown},
664     {KeyEventBaseImpl::DOM_VK_PAGE_UP,      Qt::Key_PageUp},
665     {KeyEventBaseImpl::DOM_VK_F1,           Qt::Key_F1},
666     {KeyEventBaseImpl::DOM_VK_F2,           Qt::Key_F2},
667     {KeyEventBaseImpl::DOM_VK_F3,           Qt::Key_F3},
668     {KeyEventBaseImpl::DOM_VK_F4,           Qt::Key_F4},
669     {KeyEventBaseImpl::DOM_VK_F5,           Qt::Key_F5},
670     {KeyEventBaseImpl::DOM_VK_F6,           Qt::Key_F6},
671     {KeyEventBaseImpl::DOM_VK_F7,           Qt::Key_F7},
672     {KeyEventBaseImpl::DOM_VK_F8,           Qt::Key_F8},
673     {KeyEventBaseImpl::DOM_VK_F9,           Qt::Key_F9},
674     {KeyEventBaseImpl::DOM_VK_F10,          Qt::Key_F10},
675     {KeyEventBaseImpl::DOM_VK_F11,          Qt::Key_F11},
676     {KeyEventBaseImpl::DOM_VK_F12,          Qt::Key_F12},
677     {KeyEventBaseImpl::DOM_VK_F13,          Qt::Key_F13},
678     {KeyEventBaseImpl::DOM_VK_F14,          Qt::Key_F14},
679     {KeyEventBaseImpl::DOM_VK_F15,          Qt::Key_F15},
680     {KeyEventBaseImpl::DOM_VK_F16,          Qt::Key_F16},
681     {KeyEventBaseImpl::DOM_VK_F17,          Qt::Key_F17},
682     {KeyEventBaseImpl::DOM_VK_F18,          Qt::Key_F18},
683     {KeyEventBaseImpl::DOM_VK_F19,          Qt::Key_F19},
684     {KeyEventBaseImpl::DOM_VK_F20,          Qt::Key_F20},
685     {KeyEventBaseImpl::DOM_VK_F21,          Qt::Key_F21},
686     {KeyEventBaseImpl::DOM_VK_F22,          Qt::Key_F22},
687     {KeyEventBaseImpl::DOM_VK_F23,          Qt::Key_F23},
688     {KeyEventBaseImpl::DOM_VK_F24,          Qt::Key_F24},
689     {0,                   0}
690 };
691 
MAKE_TRANSLATOR(virtKeyToQtKey,unsigned,unsigned,unsigned,virtKeyToQtKeyTable)692 MAKE_TRANSLATOR(virtKeyToQtKey, unsigned, unsigned, unsigned, virtKeyToQtKeyTable)
693 
694 KeyEventBaseImpl::KeyEventBaseImpl(EventId id, bool canBubbleArg, bool cancelableArg, AbstractViewImpl *viewArg,
695                                    QKeyEvent *key) :
696     UIEventImpl(id, canBubbleArg, cancelableArg, viewArg, 0)
697 {
698     m_synthetic = false;
699 
700     m_keyEvent = new QKeyEvent(key->type(), key->key(), key->modifiers(), key->text(), key->isAutoRepeat(), key->count());
701 
702     //Here, we need to map Qt's internal info to browser-style info.
703     m_detail = key->count();
704     m_keyVal = 0; // Set below unless virtual...
705     m_virtKeyVal = virtKeyToQtKey()->toLeft(key->key());
706 
707     // m_keyVal should contain the unicode value
708     // of the pressed key if available, including case distinction
709     if (m_virtKeyVal == DOM_VK_UNDEFINED && !key->text().isEmpty()) {
710         // ... unfortunately, this value is useless if ctrl+ or alt+ are used.
711         if (key->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) {
712             // Try to recover the case... Not quite right with caps lock involved, hence proving again its evilness
713             if (key->modifiers() & (Qt::ShiftModifier)) {
714                 m_keyVal = key->key();    // The original is upper case anyway
715             } else {
716                 m_keyVal = QChar(key->key()).toLower().unicode();
717             }
718         } else {
719             m_keyVal = key->text().unicode()[0].unicode();
720         }
721     }
722 
723     // key->state returns enum ButtonState, which is ShiftButton, ControlButton and AltButton or'ed together.
724     m_modifier = key->modifiers();
725 }
726 
~KeyEventBaseImpl()727 KeyEventBaseImpl::~KeyEventBaseImpl()
728 {
729     delete m_keyEvent;
730 }
731 
initKeyBaseEvent(const DOMString & typeArg,bool canBubbleArg,bool cancelableArg,AbstractViewImpl * viewArg,unsigned long keyValArg,unsigned long virtKeyValArg,unsigned long modifiersArg)732 void KeyEventBaseImpl::initKeyBaseEvent(const DOMString &typeArg,
733                                         bool canBubbleArg,
734                                         bool cancelableArg,
735                                         AbstractViewImpl *viewArg,
736                                         unsigned long keyValArg,
737                                         unsigned long virtKeyValArg,
738                                         unsigned long modifiersArg)
739 {
740     m_synthetic = true;
741     delete m_keyEvent;
742     m_keyEvent = nullptr;
743     initUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, 1);
744     m_virtKeyVal = virtKeyValArg;
745     m_keyVal     = keyValArg;
746     m_modifier   = modifiersArg;
747 }
748 
checkModifier(unsigned long modifierArg)749 bool KeyEventBaseImpl::checkModifier(unsigned long modifierArg)
750 {
751     return ((m_modifier & modifierArg) == modifierArg);
752 }
753 
buildQKeyEvent() const754 void KeyEventBaseImpl::buildQKeyEvent() const
755 {
756     delete m_keyEvent;
757 
758     assert(m_synthetic);
759     //IMPORTANT: we ignore modifers on purpose.
760     //this is to prevent a website from synthesizing something
761     //like Ctrl-V or Shift-Insert and stealing contents of the user's clipboard.
762     Qt::KeyboardModifiers modifiers = nullptr;
763 
764     if (m_modifier & Qt::KeypadModifier) {
765         modifiers |= Qt::KeypadModifier;
766     }
767 
768     int key   = 0;
769     QString text;
770     if (m_virtKeyVal) {
771         key = virtKeyToQtKey()->toRight(m_virtKeyVal);
772     }
773     if (!key) {
774         key   = m_keyVal;
775         text  = QChar(key);
776     }
777 
778     //Neuter F keys as well.
779     if (key >= Qt::Key_F1 && key <= Qt::Key_F35) {
780         key = Qt::Key_ScrollLock;
781     }
782 
783     m_keyEvent = new QKeyEvent(id() == KEYUP_EVENT ? QEvent::KeyRelease : QEvent::KeyPress,
784                                key, modifiers, text);
785 }
786 
787 //------------------------------------------------------------------------------
788 
789 static const IDTranslator<QByteArray, unsigned, const char *>::Info keyIdentifiersToVirtKeysTable[] = {
790     {"Alt",         KeyEventBaseImpl::DOM_VK_LEFT_ALT},
791     {"Control",     KeyEventBaseImpl::DOM_VK_LEFT_CONTROL},
792     {"Shift",       KeyEventBaseImpl::DOM_VK_LEFT_SHIFT},
793     {"Meta",        KeyEventBaseImpl::DOM_VK_META},
794     {"\0x08",       KeyEventBaseImpl::DOM_VK_SPACE},           //1-char virt!
795     {"CapsLock",    KeyEventBaseImpl::DOM_VK_CAPS_LOCK},
796     {"\x7F",        KeyEventBaseImpl::DOM_VK_DELETE},          //1-char virt!
797     {"End",         KeyEventBaseImpl::DOM_VK_END},
798     {"Enter",       KeyEventBaseImpl::DOM_VK_ENTER},
799     {"\x1b",        KeyEventBaseImpl::DOM_VK_ESCAPE},          //1-char virt!
800     {"Home",        KeyEventBaseImpl::DOM_VK_HOME},
801     {"NumLock",     KeyEventBaseImpl::DOM_VK_NUM_LOCK},
802     {"Pause",       KeyEventBaseImpl::DOM_VK_PAUSE},
803     {"PrintScreen", KeyEventBaseImpl::DOM_VK_PRINTSCREEN},
804     {"Scroll",   KeyEventBaseImpl::DOM_VK_SCROLL_LOCK},
805     {" ",        KeyEventBaseImpl::DOM_VK_SPACE},               //1-char virt!
806     {"\t",       KeyEventBaseImpl::DOM_VK_TAB},                 //1-char virt!
807     {"Left",     KeyEventBaseImpl::DOM_VK_LEFT},
808     {"Left",     KeyEventBaseImpl::DOM_VK_LEFT},
809     {"Right",    KeyEventBaseImpl::DOM_VK_RIGHT},
810     {"Up",       KeyEventBaseImpl::DOM_VK_UP},
811     {"Down",     KeyEventBaseImpl::DOM_VK_DOWN},
812     {"PageDown", KeyEventBaseImpl::DOM_VK_PAGE_DOWN},
813     {"PageUp", KeyEventBaseImpl::DOM_VK_PAGE_UP},
814     {"F1", KeyEventBaseImpl::DOM_VK_F1},
815     {"F2", KeyEventBaseImpl::DOM_VK_F2},
816     {"F3", KeyEventBaseImpl::DOM_VK_F3},
817     {"F4", KeyEventBaseImpl::DOM_VK_F4},
818     {"F5", KeyEventBaseImpl::DOM_VK_F5},
819     {"F6", KeyEventBaseImpl::DOM_VK_F6},
820     {"F7", KeyEventBaseImpl::DOM_VK_F7},
821     {"F8", KeyEventBaseImpl::DOM_VK_F8},
822     {"F9", KeyEventBaseImpl::DOM_VK_F9},
823     {"F10", KeyEventBaseImpl::DOM_VK_F10},
824     {"F11", KeyEventBaseImpl::DOM_VK_F11},
825     {"F12", KeyEventBaseImpl::DOM_VK_F12},
826     {"F13", KeyEventBaseImpl::DOM_VK_F13},
827     {"F14", KeyEventBaseImpl::DOM_VK_F14},
828     {"F15", KeyEventBaseImpl::DOM_VK_F15},
829     {"F16", KeyEventBaseImpl::DOM_VK_F16},
830     {"F17", KeyEventBaseImpl::DOM_VK_F17},
831     {"F18", KeyEventBaseImpl::DOM_VK_F18},
832     {"F19", KeyEventBaseImpl::DOM_VK_F19},
833     {"F20", KeyEventBaseImpl::DOM_VK_F20},
834     {"F21", KeyEventBaseImpl::DOM_VK_F21},
835     {"F22", KeyEventBaseImpl::DOM_VK_F22},
836     {"F23", KeyEventBaseImpl::DOM_VK_F23},
837     {"F24", KeyEventBaseImpl::DOM_VK_F24},
838     {nullptr, 0}
839 };
840 
841 MAKE_TRANSLATOR(keyIdentifiersToVirtKeys, QByteArray, unsigned, const char *, keyIdentifiersToVirtKeysTable)
842 
843 /** These are the modifiers we currently support */
844 static const IDTranslator<QByteArray, unsigned, const char *>::Info keyModifiersToCodeTable[] = {
845     {"Alt",         Qt::AltModifier},
846     {"Control",     Qt::ControlModifier},
847     {"Shift",       Qt::ShiftModifier},
848     {"Meta",        Qt::MetaModifier},
849     {nullptr,             0}
850 };
851 
MAKE_TRANSLATOR(keyModifiersToCode,QByteArray,unsigned,const char *,keyModifiersToCodeTable)852 MAKE_TRANSLATOR(keyModifiersToCode, QByteArray, unsigned, const char *, keyModifiersToCodeTable)
853 
854 KeyboardEventImpl::KeyboardEventImpl() : m_keyLocation(KeyboardEvent::DOM_KEY_LOCATION_STANDARD)
855 {}
856 
keyIdentifier() const857 DOMString KeyboardEventImpl::keyIdentifier() const
858 {
859     if (unsigned special = virtKeyVal())
860         if (const char *id = keyIdentifiersToVirtKeys()->toLeft(special)) {
861             return QString::fromLatin1(id);
862         }
863 
864     if (unsigned unicode = keyVal()) {
865         return QString(QChar(unicode));
866     }
867 
868     return "Unidentified";
869 }
870 
getModifierState(const DOMString & keyIdentifierArg) const871 bool KeyboardEventImpl::getModifierState(const DOMString &keyIdentifierArg) const
872 {
873     unsigned mask = keyModifiersToCode()->toRight(keyIdentifierArg.string().toLatin1());
874     return m_modifier & mask;
875 }
876 
isKeyboardEvent() const877 bool KeyboardEventImpl::isKeyboardEvent() const
878 {
879     return true;
880 }
881 
initKeyboardEvent(const DOMString & typeArg,bool canBubbleArg,bool cancelableArg,AbstractViewImpl * viewArg,const DOMString & keyIdentifierArg,unsigned long keyLocationArg,const DOMString & modifiersList)882 void KeyboardEventImpl::initKeyboardEvent(const DOMString &typeArg,
883         bool canBubbleArg,
884         bool cancelableArg,
885         AbstractViewImpl *viewArg,
886         const DOMString &keyIdentifierArg,
887         unsigned long keyLocationArg,
888         const DOMString &modifiersList)
889 {
890     unsigned keyVal     = 0;
891     unsigned virtKeyVal = 0;
892 
893     m_keyLocation = keyLocationArg;
894 
895     //Figure out the code information from the key identifier.
896     if (keyIdentifierArg.length() == 1) {
897         //Likely to be normal unicode id, unless it's one of the few
898         //special values.
899         unsigned short code = keyIdentifierArg.unicode()[0].unicode();
900         if (code > 0x20 && code != 0x7F) {
901             keyVal = code;
902         }
903     }
904 
905     if (!keyVal) { //One of special keys, likely.
906         virtKeyVal = keyIdentifiersToVirtKeys()->toRight(keyIdentifierArg.string().toLatin1());
907     }
908 
909     //Process modifier list.
910     const QStringList mods = modifiersList.string().trimmed().simplified().split(' ');
911 
912     unsigned modifiers = 0;
913     for (QStringList::ConstIterator i = mods.begin(); i != mods.end(); ++i)
914         if (unsigned mask = keyModifiersToCode()->toRight((*i).toLatin1())) {
915             modifiers |= mask;
916         }
917 
918     initKeyBaseEvent(typeArg, canBubbleArg, cancelableArg, viewArg,
919                      keyVal, virtKeyVal, modifiers);
920 }
921 
KeyboardEventImpl(QKeyEvent * key,DOM::AbstractViewImpl * view)922 KeyboardEventImpl::KeyboardEventImpl(QKeyEvent *key, DOM::AbstractViewImpl *view) :
923     KeyEventBaseImpl(key->type() == QEvent::KeyRelease ? KEYUP_EVENT : KEYDOWN_EVENT, true, true, view, key)
924 {
925     if (key->modifiers() & Qt::KeypadModifier) {
926         m_keyLocation = KeyboardEvent::DOM_KEY_LOCATION_NUMPAD;
927     } else {
928         //It's generally standard, but for the modifiers,
929         //it should be left/right, so guess left.
930         m_keyLocation = KeyboardEvent::DOM_KEY_LOCATION_STANDARD;
931         switch (m_virtKeyVal) {
932         case DOM_VK_LEFT_ALT:
933         case DOM_VK_LEFT_SHIFT:
934         case DOM_VK_LEFT_CONTROL:
935         case DOM_VK_META:
936             m_keyLocation = KeyboardEvent::DOM_KEY_LOCATION_LEFT;
937         }
938     }
939 }
940 
keyCode() const941 int KeyboardEventImpl::keyCode() const
942 {
943     //Keycode on key events always identifies the -key- and not the input,
944     //so e.g. 'a' will get 'A'
945     if (m_virtKeyVal != DOM_VK_UNDEFINED) {
946         return m_virtKeyVal;
947     } else {
948         unsigned char code = QChar((unsigned short)m_keyVal).toUpper().unicode();
949         // Some codes we get from Qt are things like ( which conflict with
950         // browser scancodes. Remap them to what's on their keycaps in a US
951         // layout.
952         if (virtKeyToQtKey()->hasLeft(code)) {
953             switch (code) {
954             case '!': return '1';
955             case '@': return '2';
956             case '#': return '3';
957             case '$': return '4';
958             case '%': return '5';
959             case '^': return '6';
960             case '&': return '7';
961             case '*': return '8';
962             case '(': return '9';
963             case ')': return '0';
964             default:
965                 qCWarning(KHTML_LOG) << "Don't know how resolve conflict of code:" << code
966                            << " with a virtKey";
967             }
968         }
969         return code;
970     }
971 }
972 
charCode() const973 int KeyboardEventImpl::charCode() const
974 {
975     //IE doesn't support charCode at all, and mozilla returns 0
976     //on key events. So return 0 here
977     return 0;
978 }
979 
980 // -----------------------------------------------------------------------------
TextEventImpl()981 TextEventImpl::TextEventImpl()
982 {}
983 
isTextInputEvent() const984 bool TextEventImpl::isTextInputEvent() const
985 {
986     return true;
987 }
988 
TextEventImpl(QKeyEvent * key,DOM::AbstractViewImpl * view)989 TextEventImpl::TextEventImpl(QKeyEvent *key, DOM::AbstractViewImpl *view) :
990     KeyEventBaseImpl(KEYPRESS_EVENT, true, true, view, key)
991 {
992     m_outputString = key->text();
993 }
994 
initTextEvent(const DOMString & typeArg,bool canBubbleArg,bool cancelableArg,AbstractViewImpl * viewArg,const DOMString & text)995 void TextEventImpl::initTextEvent(const DOMString &typeArg,
996                                   bool canBubbleArg,
997                                   bool cancelableArg,
998                                   AbstractViewImpl *viewArg,
999                                   const DOMString &text)
1000 {
1001     m_outputString = text;
1002 
1003     //See whether we can get a key out of this.
1004     unsigned keyCode = 0;
1005     if (text.length() == 1) {
1006         keyCode = text.unicode()[0].unicode();
1007     }
1008     initKeyBaseEvent(typeArg, canBubbleArg, cancelableArg, viewArg,
1009                      keyCode, 0, 0);
1010 }
1011 
keyCode() const1012 int TextEventImpl::keyCode() const
1013 {
1014     //Mozilla returns 0 here unless this is a non-unicode key.
1015     //IE stuffs everything here, and so we try to match it..
1016     if (m_keyVal) {
1017         return m_keyVal;
1018     }
1019     return m_virtKeyVal;
1020 }
1021 
charCode() const1022 int TextEventImpl::charCode() const
1023 {
1024     //On text events, in Mozilla charCode is 0 for non-unicode keys,
1025     //and the unicode key otherwise... IE doesn't support this.
1026     if (m_virtKeyVal) {
1027         return 0;
1028     }
1029     return m_keyVal;
1030 }
1031 
1032 // -----------------------------------------------------------------------------
MutationEventImpl()1033 MutationEventImpl::MutationEventImpl()
1034 {
1035     m_relatedNode = nullptr;
1036     m_prevValue = nullptr;
1037     m_newValue = nullptr;
1038     m_attrName = nullptr;
1039     m_attrChange = 0;
1040 }
1041 
MutationEventImpl(EventId _id,bool canBubbleArg,bool cancelableArg,const Node & relatedNodeArg,const DOMString & prevValueArg,const DOMString & newValueArg,const DOMString & attrNameArg,unsigned short attrChangeArg)1042 MutationEventImpl::MutationEventImpl(EventId _id,
1043                                      bool canBubbleArg,
1044                                      bool cancelableArg,
1045                                      const Node &relatedNodeArg,
1046                                      const DOMString &prevValueArg,
1047                                      const DOMString &newValueArg,
1048                                      const DOMString &attrNameArg,
1049                                      unsigned short attrChangeArg)
1050     : EventImpl(_id, canBubbleArg, cancelableArg)
1051 {
1052     m_relatedNode = relatedNodeArg.handle();
1053     if (m_relatedNode) {
1054         m_relatedNode->ref();
1055     }
1056     m_prevValue = prevValueArg.implementation();
1057     if (m_prevValue) {
1058         m_prevValue->ref();
1059     }
1060     m_newValue = newValueArg.implementation();
1061     if (m_newValue) {
1062         m_newValue->ref();
1063     }
1064     m_attrName = attrNameArg.implementation();
1065     if (m_attrName) {
1066         m_attrName->ref();
1067     }
1068     m_attrChange = attrChangeArg;
1069 }
1070 
~MutationEventImpl()1071 MutationEventImpl::~MutationEventImpl()
1072 {
1073     if (m_relatedNode) {
1074         m_relatedNode->deref();
1075     }
1076     if (m_prevValue) {
1077         m_prevValue->deref();
1078     }
1079     if (m_newValue) {
1080         m_newValue->deref();
1081     }
1082     if (m_attrName) {
1083         m_attrName->deref();
1084     }
1085 }
1086 
initMutationEvent(const DOMString & typeArg,bool canBubbleArg,bool cancelableArg,const Node & relatedNodeArg,const DOMString & prevValueArg,const DOMString & newValueArg,const DOMString & attrNameArg,unsigned short attrChangeArg)1087 void MutationEventImpl::initMutationEvent(const DOMString &typeArg,
1088         bool canBubbleArg,
1089         bool cancelableArg,
1090         const Node &relatedNodeArg,
1091         const DOMString &prevValueArg,
1092         const DOMString &newValueArg,
1093         const DOMString &attrNameArg,
1094         unsigned short attrChangeArg)
1095 {
1096     EventImpl::initEvent(typeArg, canBubbleArg, cancelableArg);
1097 
1098     if (m_relatedNode) {
1099         m_relatedNode->deref();
1100     }
1101     if (m_prevValue) {
1102         m_prevValue->deref();
1103     }
1104     if (m_newValue) {
1105         m_newValue->deref();
1106     }
1107     if (m_attrName) {
1108         m_attrName->deref();
1109     }
1110 
1111     m_relatedNode = relatedNodeArg.handle();
1112     if (m_relatedNode) {
1113         m_relatedNode->ref();
1114     }
1115     m_prevValue = prevValueArg.implementation();
1116     if (m_prevValue) {
1117         m_prevValue->ref();
1118     }
1119     m_newValue = newValueArg.implementation();
1120     if (m_newValue) {
1121         m_newValue->ref();
1122     }
1123     m_attrName = attrNameArg.implementation();
1124     if (m_newValue) {
1125         m_newValue->ref();
1126     }
1127     m_attrChange = attrChangeArg;
1128 }
1129 
isMutationEvent() const1130 bool MutationEventImpl::isMutationEvent() const
1131 {
1132     return true;
1133 }
1134 
1135 // -----------------------------------------------------------------------------
1136 
MessageEventImpl()1137 MessageEventImpl::MessageEventImpl()
1138 {}
1139 
isMessageEvent() const1140 bool MessageEventImpl::isMessageEvent() const
1141 {
1142     return true;
1143 }
1144 
initMessageEvent(const DOMString & typeArg,bool canBubbleArg,bool cancelableArg,const RefPtr<Data> & dataArg,const DOMString & originArg,const DOMString & lastEventIdArg,KHTMLPart * sourceArg)1145 void MessageEventImpl::initMessageEvent(const DOMString &typeArg,
1146                                         bool  canBubbleArg,
1147                                         bool  cancelableArg,
1148                                         const RefPtr<Data> &dataArg,
1149                                         const DOMString &originArg,
1150                                         const DOMString &lastEventIdArg,
1151                                         KHTMLPart *sourceArg)
1152 {
1153     EventImpl::initEvent(typeArg, canBubbleArg, cancelableArg);
1154     m_data   = dataArg;
1155     m_origin = originArg;
1156     m_lastEventId = lastEventIdArg;
1157     m_source      = sourceArg;
1158 }
1159 
1160 // -----------------------------------------------------------------------------
1161 
HashChangeEventImpl()1162 HashChangeEventImpl::HashChangeEventImpl()
1163 {
1164 }
1165 
isHashChangeEvent() const1166 bool HashChangeEventImpl::isHashChangeEvent() const
1167 {
1168     return true;
1169 }
1170 
initHashChangeEvent(const DOMString & eventTypeArg,bool canBubbleArg,bool cancelableArg,const DOMString & oldUrl,const DOMString & newUrl)1171 void HashChangeEventImpl::initHashChangeEvent(const DOMString &eventTypeArg, bool canBubbleArg, bool cancelableArg, const DOMString &oldUrl, const DOMString &newUrl)
1172 {
1173     EventImpl::initEvent(eventTypeArg, canBubbleArg, cancelableArg);
1174     m_oldUrl = oldUrl;
1175     m_newUrl = newUrl;
1176 }
1177