1 /*
2 * This file is part of the KDE libraries
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003 Apple Computer, Inc.
5 * Copyright (C) 2006, 2009, 2010 Maksim Orlovich (maksim@kde.org)
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "kjs_events.h"
23 #include "kjs_events.lut.h"
24
25 #include "kjs_data.h"
26 #include "kjs_window.h"
27 #include "kjs_views.h"
28 #include "kjs_proxy.h"
29 #include <xml/dom_nodeimpl.h>
30 #include <xml/dom_docimpl.h>
31 #include <xml/dom2_eventsimpl.h>
32 #include <rendering/render_object.h>
33 #include <rendering/render_canvas.h>
34 #include <khtml_part.h>
35 #ifdef KJS_DEBUGGER
36 #include "debugger/debugwindow.h"
37 #endif
38 #include "khtml_debug.h"
39 #include <kjs/scriptfunction.h>
40 #include <kjs/function_object.h>
41
42 using namespace KJS;
43 using namespace KJSDebugger;
44 using namespace DOM;
45
46 // -------------------------------------------------------------------------
47
JSEventListener(JSObject * _listener,JSObject * _compareListenerImp,JSObject * _win,bool _html)48 JSEventListener::JSEventListener(JSObject *_listener, JSObject *_compareListenerImp, JSObject *_win, bool _html)
49 : listener(_listener), compareListenerImp(_compareListenerImp), html(_html), win(_win)
50 {
51 //fprintf(stderr,"JSEventListener::JSEventListener this=%p listener=%p\n",this,listener.imp());
52 if (compareListenerImp) {
53 static_cast<Window *>(win.get())->jsEventListeners.insert(QPair<void *, bool>(compareListenerImp.get(), html), this);
54 }
55 }
56
~JSEventListener()57 JSEventListener::~JSEventListener()
58 {
59 if (compareListenerImp) {
60 static_cast<Window *>(win.get())->jsEventListeners.remove(QPair<void *, bool>(compareListenerImp.get(), html));
61 }
62 //fprintf(stderr,"JSEventListener::~JSEventListener this=%p listener=%p\n",this,listener.imp());
63 }
64
handleEvent(DOM::Event & evt)65 void JSEventListener::handleEvent(DOM::Event &evt)
66 {
67 KHTMLPart *part = qobject_cast<KHTMLPart *>(static_cast<Window *>(win.get())->part());
68 KJSProxy *proxy = nullptr;
69 if (part) {
70 proxy = part->jScript();
71 }
72
73 if (proxy && listener && listener->implementsCall()) {
74 #ifdef KJS_DEBUGGER
75 //### This is the wrong place to do this --- we need
76 // a more global/general stategy to prevent unwanted event loop recursion issues.
77 if (proxy->debugEnabled() && DebugWindow::window()->inSession()) {
78 return;
79 }
80 #endif
81 ref();
82
83 KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter());
84 ExecState *exec = interpreter->globalExec();
85
86 List args;
87 args.append(getDOMEvent(exec, evt.handle()));
88
89 JSObject *thisObj = nullptr;
90 // Check whether handler is a function or an object with handleEvent method
91 if (listener == compareListenerImp) {
92 // Set "this" to the event's current target
93 thisObj = getEventTarget(exec, evt.handle()->currentTarget())->getObject();
94 } else {
95 thisObj = compareListenerImp;
96 }
97
98 if (!thisObj) {
99 // ### can this still happen? eventTarget should be window on Window events now.
100 thisObj = win;
101 }
102
103 Window *window = static_cast<Window *>(win.get());
104 // Set the event we're handling in the Window object
105 window->setCurrentEvent(evt.handle());
106 // ... and in the interpreter
107 interpreter->setCurrentEvent(&evt);
108
109 interpreter->startCPUGuard();
110 JSValue *retval = listener->call(exec, thisObj, args);
111 interpreter->stopCPUGuard();
112
113 window->setCurrentEvent(nullptr);
114 interpreter->setCurrentEvent(nullptr);
115 if (exec->hadException()) {
116 exec->clearException();
117 } else if (html) {
118 QVariant ret = ValueToVariant(exec, retval);
119 if (ret.type() == QVariant::Bool && ret.toBool() == false) {
120 evt.preventDefault();
121 }
122 }
123 window->afterScriptExecution();
124 deref();
125 }
126 }
127
eventListenerType()128 DOM::DOMString JSEventListener::eventListenerType()
129 {
130 if (html) {
131 return "_khtml_HTMLEventListener";
132 } else {
133 return "_khtml_JSEventListener";
134 }
135 }
136
listenerObj() const137 JSObject *JSEventListener::listenerObj() const
138 {
139 return listener;
140 }
141
JSLazyEventListener(const QString & _code,const QString & _url,int _lineNum,const QString & _name,JSObject * _win,DOM::NodeImpl * _originalNode,bool _svg)142 JSLazyEventListener::JSLazyEventListener(const QString &_code, const QString &_url, int _lineNum,
143 const QString &_name, JSObject *_win, DOM::NodeImpl *_originalNode, bool _svg)
144 : JSEventListener(nullptr, nullptr, _win, true), code(_code), url(_url), lineNum(_lineNum),
145 name(_name), parsed(false), svg(_svg)
146 {
147 // We don't retain the original node, because we assume it
148 // will stay alive as long as this handler object is around
149 // and we need to avoid a reference cycle. If JS transfers
150 // this handler to another node, parseCode will be called and
151 // then originalNode is no longer needed.
152
153 originalNode = _originalNode;
154 }
155
~JSLazyEventListener()156 JSLazyEventListener::~JSLazyEventListener()
157 {
158 }
159
handleEvent(DOM::Event & evt)160 void JSLazyEventListener::handleEvent(DOM::Event &evt)
161 {
162 parseCode();
163 if (listener) {
164 JSEventListener::handleEvent(evt);
165 }
166 }
167
listenerObj() const168 JSObject *JSLazyEventListener::listenerObj() const
169 {
170 parseCode();
171 return listener;
172 }
173
parseCode() const174 void JSLazyEventListener::parseCode() const
175 {
176 if (!parsed) {
177 KHTMLPart *part = qobject_cast<KHTMLPart *>(static_cast<Window *>(win.get())->part());
178 KJSProxy *proxy = nullptr;
179 if (part) {
180 proxy = part->jScript();
181 }
182
183 if (proxy) {
184 KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter());
185 ExecState *exec = interpreter->globalExec();
186
187 //KJS::Constructor constr(KJS::Global::current().get("Function").imp());
188 KJS::FunctionObjectImp *constr = static_cast<KJS::FunctionObjectImp *>(interpreter->builtinFunction());
189 KJS::List args;
190
191 if (svg) {
192 args.append(jsString("evt"));
193 } else {
194 args.append(jsString("event"));
195 }
196
197 args.append(jsString(code));
198 listener = constr->construct(exec, args,
199 Identifier(UString(name)), url, lineNum); // ### is globalExec ok ?
200 compareListenerImp = listener;
201
202 if (exec->hadException()) {
203 exec->clearException();
204
205 // failed to parse, so let's just make this listener a no-op
206 listener = nullptr;
207 } else if (!listener->inherits(&DeclaredFunctionImp::info)) {
208 listener = nullptr;// Error creating function
209 } else {
210 DeclaredFunctionImp *declFunc = static_cast<DeclaredFunctionImp *>(listener.get());
211
212 if (originalNode) {
213 // Add the event's home element to the scope
214 // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope)
215 ScopeChain scope = declFunc->scope();
216
217 JSObject *thisObj = getDOMNode(exec, originalNode)->getObject();
218
219 if (thisObj) {
220 static_cast<DOMNode *>(thisObj)->pushEventHandlerScope(exec, scope);
221 declFunc->setScope(scope);
222 }
223 }
224 }
225 }
226
227 // no more need to keep the unparsed code around
228 code.clear();
229
230 if (listener) {
231 static_cast<Window *>(win.get())->jsEventListeners.insert(QPair<void *, bool>(compareListenerImp.get(), true),
232 (KJS::JSEventListener *)(this));
233 }
234
235 parsed = true;
236 }
237 }
238
239 // -------------------------------------------------------------------------
240
241 const ClassInfo DOMEvent::info = { "Event", nullptr, &DOMEventTable, nullptr };
242 /*
243 @begin DOMEventTable 7
244 type DOMEvent::Type DontDelete|ReadOnly
245 target DOMEvent::Target DontDelete|ReadOnly
246 currentTarget DOMEvent::CurrentTarget DontDelete|ReadOnly
247 srcElement DOMEvent::SrcElement DontDelete|ReadOnly
248 eventPhase DOMEvent::EventPhase DontDelete|ReadOnly
249 bubbles DOMEvent::Bubbles DontDelete|ReadOnly
250 cancelable DOMEvent::Cancelable DontDelete|ReadOnly
251 timeStamp DOMEvent::TimeStamp DontDelete|ReadOnly
252 returnValue DOMEvent::ReturnValue DontDelete
253 cancelBubble DOMEvent::CancelBubble DontDelete
254 @end
255 @begin DOMEventProtoTable 3
256 stopPropagation DOMEvent::StopPropagation DontDelete|Function 0
257 preventDefault DOMEvent::PreventDefault DontDelete|Function 0
258 initEvent DOMEvent::InitEvent DontDelete|Function 3
259 @end
260 */
261 KJS_DEFINE_PROTOTYPE(DOMEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMEventProtoFunc)262 KJS_IMPLEMENT_PROTOFUNC(DOMEventProtoFunc)
263 KJS_IMPLEMENT_PROTOTYPE("DOMEvent", DOMEventProto, DOMEventProtoFunc, ObjectPrototype)
264
265 DOMEvent::DOMEvent(ExecState *exec, DOM::EventImpl *e)
266 : m_impl(e)
267 {
268 setPrototype(DOMEventProto::self(exec));
269 }
270
DOMEvent(JSObject * proto,DOM::EventImpl * e)271 DOMEvent::DOMEvent(JSObject *proto, DOM::EventImpl *e):
272 m_impl(e)
273 {
274 setPrototype(proto);
275 }
276
~DOMEvent()277 DOMEvent::~DOMEvent()
278 {
279 ScriptInterpreter::forgetDOMObject(m_impl.get());
280 }
281
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)282 bool DOMEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
283 {
284 #ifdef KJS_VERBOSE
285 qCDebug(KHTML_LOG) << "KJS::DOMEvent::getOwnPropertySlot " << propertyName.qstring();
286 #endif
287
288 return getStaticValueSlot<DOMEvent, DOMObject>(exec, &DOMEventTable, this, propertyName, slot);
289 }
290
getValueProperty(ExecState * exec,int token) const291 JSValue *DOMEvent::getValueProperty(ExecState *exec, int token) const
292 {
293 DOM::EventImpl &event = *impl();
294 switch (token) {
295 case Type:
296 return jsString(event.type());
297 case Target:
298 case SrcElement: /*MSIE extension - "the object that fired the event"*/
299 return getEventTarget(exec, event.target());
300 case CurrentTarget:
301 return getEventTarget(exec, event.currentTarget());
302 case EventPhase:
303 return jsNumber((unsigned int)event.eventPhase());
304 case Bubbles:
305 return jsBoolean(event.bubbles());
306 case Cancelable:
307 return jsBoolean(event.cancelable());
308 case TimeStamp:
309 return jsNumber((long unsigned int)event.timeStamp()); // ### long long ?
310 case ReturnValue: // MSIE extension
311 // return false == cancel, so this returns the -opposite- of defaultPrevented
312 return jsBoolean(!event.defaultPrevented());
313 case CancelBubble: // MSIE extension
314 return jsBoolean(event.propagationStopped());
315 default:
316 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token;
317 return nullptr;
318 }
319 }
320
defaultValue(ExecState * exec,KJS::JSType hint) const321 JSValue *DOMEvent::defaultValue(ExecState *exec, KJS::JSType hint) const
322 {
323 if (m_impl->id() == EventImpl::ERROR_EVENT && !m_impl->message().isNull()) {
324 return jsString(m_impl->message());
325 } else {
326 return DOMObject::defaultValue(exec, hint);
327 }
328 }
329
put(ExecState * exec,const Identifier & propertyName,JSValue * value,int attr)330 void DOMEvent::put(ExecState *exec, const Identifier &propertyName,
331 JSValue *value, int attr)
332 {
333 lookupPut<DOMEvent, DOMObject>(exec, propertyName, value, attr,
334 &DOMEventTable, this);
335 }
336
putValueProperty(ExecState * exec,int token,JSValue * value,int)337 void DOMEvent::putValueProperty(ExecState *exec, int token, JSValue *value, int)
338 {
339 switch (token) {
340 case ReturnValue: // MSIE equivalent for "preventDefault" (but with a way to reset it)
341 // returnValue=false means "default action of the event on the source object is canceled",
342 // which means preventDefault(true). Hence the '!'.
343 m_impl->preventDefault(!value->toBoolean(exec));
344 break;
345 case CancelBubble: // MSIE equivalent for "stopPropagation" (but with a way to reset it)
346 m_impl->stopPropagation(value->toBoolean(exec));
347 break;
348 default:
349 break;
350 }
351 }
352
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)353 JSValue *DOMEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
354 {
355 KJS_CHECK_THIS(KJS::DOMEvent, thisObj);
356 DOM::EventImpl &event = *static_cast<DOMEvent *>(thisObj)->impl();
357 switch (id) {
358 case DOMEvent::StopPropagation:
359 event.stopPropagation(true);
360 return jsUndefined();
361 case DOMEvent::PreventDefault:
362 event.preventDefault(true);
363 return jsUndefined();
364 case DOMEvent::InitEvent:
365 event.initEvent(args[0]->toString(exec).domString(), args[1]->toBoolean(exec), args[2]->toBoolean(exec));
366 return jsUndefined();
367 };
368 return jsUndefined();
369 }
370
getDOMEvent(ExecState * exec,DOM::EventImpl * ei)371 JSValue *KJS::getDOMEvent(ExecState *exec, DOM::EventImpl *ei)
372 {
373 if (!ei) {
374 return jsNull();
375 }
376 ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
377 DOMObject *ret = interp->getDOMObject(ei);
378 if (!ret) {
379 if (ei->isTextInputEvent()) {
380 ret = new DOMTextEvent(exec, static_cast<DOM::TextEventImpl *>(ei));
381 } else if (ei->isKeyboardEvent()) {
382 ret = new DOMKeyboardEvent(exec, static_cast<DOM::KeyboardEventImpl *>(ei));
383 } else if (ei->isMouseEvent()) {
384 ret = new DOMMouseEvent(exec, static_cast<DOM::MouseEventImpl *>(ei));
385 } else if (ei->isUIEvent()) {
386 ret = new DOMUIEvent(exec, static_cast<DOM::UIEventImpl *>(ei));
387 } else if (ei->isMutationEvent()) {
388 ret = new DOMMutationEvent(exec, static_cast<DOM::MutationEventImpl *>(ei));
389 } else if (ei->isMessageEvent()) {
390 ret = new DOMMessageEvent(exec, static_cast<DOM::MessageEventImpl *>(ei));
391 } else if (ei->isHashChangeEvent()) {
392 ret = new DOMHashChangeEvent(exec, static_cast<DOM::HashChangeEventImpl *>(ei));
393 } else {
394 ret = new DOMEvent(exec, ei);
395 }
396
397 interp->putDOMObject(ei, ret);
398 }
399
400 return ret;
401 }
402
toEvent(JSValue * val)403 DOM::EventImpl *KJS::toEvent(JSValue *val)
404 {
405 JSObject *obj = val->getObject();
406 if (!obj || !obj->inherits(&DOMEvent::info)) {
407 return nullptr;
408 }
409
410 const DOMEvent *dobj = static_cast<const DOMEvent *>(obj);
411 return dobj->impl();
412 }
413
414 // -------------------------------------------------------------------------
415 /*
416 @begin EventConstantsTable 23
417 CAPTURING_PHASE DOM::Event::CAPTURING_PHASE DontDelete|ReadOnly
418 AT_TARGET DOM::Event::AT_TARGET DontDelete|ReadOnly
419 BUBBLING_PHASE DOM::Event::BUBBLING_PHASE DontDelete|ReadOnly
420 # Reverse-engineered from Netscape
421 MOUSEDOWN 1 DontDelete|ReadOnly
422 MOUSEUP 2 DontDelete|ReadOnly
423 MOUSEOVER 4 DontDelete|ReadOnly
424 MOUSEOUT 8 DontDelete|ReadOnly
425 MOUSEMOVE 16 DontDelete|ReadOnly
426 MOUSEDRAG 32 DontDelete|ReadOnly
427 CLICK 64 DontDelete|ReadOnly
428 DBLCLICK 128 DontDelete|ReadOnly
429 KEYDOWN 256 DontDelete|ReadOnly
430 KEYUP 512 DontDelete|ReadOnly
431 KEYPRESS 1024 DontDelete|ReadOnly
432 DRAGDROP 2048 DontDelete|ReadOnly
433 FOCUS 4096 DontDelete|ReadOnly
434 BLUR 8192 DontDelete|ReadOnly
435 SELECT 16384 DontDelete|ReadOnly
436 CHANGE 32768 DontDelete|ReadOnly
437 @end
438 */
439 DEFINE_CONSTANT_TABLE(EventConstants)
440 IMPLEMENT_CONSTANT_TABLE(EventConstants, "EventConstants")
441
442 IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(EventConstructor, "EventConstructor", DOMEventProto, EventConstants)
443 // -------------------------------------------------------------------------
444
445 const ClassInfo EventExceptionConstructor::info = { "EventExceptionConstructor", nullptr, &EventExceptionConstructorTable, nullptr };
446 /*
447 @begin EventExceptionConstructorTable 1
448 UNSPECIFIED_EVENT_TYPE_ERR DOM::EventException::UNSPECIFIED_EVENT_TYPE_ERR DontDelete|ReadOnly
449 @end
450 */
EventExceptionConstructor(ExecState * exec)451 EventExceptionConstructor::EventExceptionConstructor(ExecState *exec)
452 : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype())
453 {
454 }
455
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)456 bool EventExceptionConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
457 {
458 return getStaticValueSlot<EventExceptionConstructor, DOMObject>(exec, &EventExceptionConstructorTable, this, propertyName, slot);
459 }
460
getValueProperty(ExecState *,int token) const461 JSValue *EventExceptionConstructor::getValueProperty(ExecState *, int token) const
462 {
463 // We use the token as the value to return directly
464 return jsNumber(token);
465 }
466
getEventExceptionConstructor(ExecState * exec)467 JSValue *KJS::getEventExceptionConstructor(ExecState *exec)
468 {
469 return cacheGlobalObject<EventExceptionConstructor>(exec, "[[eventException.constructor]]");
470 }
471
472 // -------------------------------------------------------------------------
473
474 const ClassInfo DOMUIEvent::info = { "UIEvent", &DOMEvent::info, &DOMUIEventTable, nullptr };
475 /*
476 @begin DOMUIEventTable 7
477 view DOMUIEvent::View DontDelete|ReadOnly
478 detail DOMUIEvent::Detail DontDelete|ReadOnly
479 keyCode DOMUIEvent::KeyCode DontDelete|ReadOnly
480 charCode DOMUIEvent::CharCode DontDelete|ReadOnly
481 layerX DOMUIEvent::LayerX DontDelete|ReadOnly
482 layerY DOMUIEvent::LayerY DontDelete|ReadOnly
483 pageX DOMUIEvent::PageX DontDelete|ReadOnly
484 pageY DOMUIEvent::PageY DontDelete|ReadOnly
485 which DOMUIEvent::Which DontDelete|ReadOnly
486 @end
487 @begin DOMUIEventProtoTable 1
488 initUIEvent DOMUIEvent::InitUIEvent DontDelete|Function 5
489 @end
490 */
491 KJS_DEFINE_PROTOTYPE(DOMUIEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMUIEventProtoFunc)492 KJS_IMPLEMENT_PROTOFUNC(DOMUIEventProtoFunc)
493 KJS_IMPLEMENT_PROTOTYPE("DOMUIEvent", DOMUIEventProto, DOMUIEventProtoFunc, DOMEventProto)
494
495 DOMUIEvent::DOMUIEvent(ExecState *exec, DOM::UIEventImpl *ue) :
496 DOMEvent(DOMUIEventProto::self(exec), ue) {}
497
DOMUIEvent(JSObject * proto,DOM::UIEventImpl * ue)498 DOMUIEvent::DOMUIEvent(JSObject *proto, DOM::UIEventImpl *ue) :
499 DOMEvent(proto, ue) {}
500
~DOMUIEvent()501 DOMUIEvent::~DOMUIEvent()
502 {
503 }
504
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)505 bool DOMUIEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
506 {
507 return getStaticValueSlot<DOMUIEvent, DOMEvent>(exec, &DOMUIEventTable, this, propertyName, slot);
508 }
509
getValueProperty(ExecState * exec,int token) const510 JSValue *DOMUIEvent::getValueProperty(ExecState *exec, int token) const
511 {
512 DOM::UIEventImpl &event = *impl();
513 switch (token) {
514 case View:
515 return getDOMAbstractView(exec, event.view());
516 case Detail:
517 return jsNumber(event.detail());
518 case KeyCode:
519 // IE-compatibility
520 return jsNumber(event.keyCode());
521 case CharCode:
522 // IE-compatibility
523 return jsNumber(event.charCode());
524 case LayerX:
525 // NS-compatibility
526 return jsNumber(event.layerX());
527 case LayerY:
528 // NS-compatibility
529 return jsNumber(event.layerY());
530 case PageX:
531 // NS-compatibility
532 return jsNumber(event.pageX());
533 case PageY:
534 // NS-compatibility
535 return jsNumber(event.pageY());
536 case Which:
537 // NS-compatibility
538 return jsNumber(event.which());
539 default:
540 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMUIEvent::getValueProperty : " << token;
541 return jsUndefined();
542 }
543 }
544
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)545 JSValue *DOMUIEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
546 {
547 KJS_CHECK_THIS(KJS::DOMUIEvent, thisObj);
548 DOM::UIEventImpl &uiEvent = *static_cast<DOMUIEvent *>(thisObj)->impl();
549 switch (id) {
550 case DOMUIEvent::InitUIEvent: {
551 DOM::AbstractViewImpl *v = toAbstractView(args[3]);
552 uiEvent.initUIEvent(args[0]->toString(exec).domString(),
553 args[1]->toBoolean(exec),
554 args[2]->toBoolean(exec),
555 v,
556 args[4]->toInteger(exec));
557 }
558 return jsUndefined();
559 }
560 return jsUndefined();
561 }
562
563 // -------------------------------------------------------------------------
564
565 const ClassInfo DOMMouseEvent::info = { "MouseEvent", &DOMUIEvent::info, &DOMMouseEventTable, nullptr };
566
567 /*
568 @begin DOMMouseEventTable 2
569 screenX DOMMouseEvent::ScreenX DontDelete|ReadOnly
570 screenY DOMMouseEvent::ScreenY DontDelete|ReadOnly
571 clientX DOMMouseEvent::ClientX DontDelete|ReadOnly
572 x DOMMouseEvent::X DontDelete|ReadOnly
573 clientY DOMMouseEvent::ClientY DontDelete|ReadOnly
574 y DOMMouseEvent::Y DontDelete|ReadOnly
575 offsetX DOMMouseEvent::OffsetX DontDelete|ReadOnly
576 offsetY DOMMouseEvent::OffsetY DontDelete|ReadOnly
577 ctrlKey DOMMouseEvent::CtrlKey DontDelete|ReadOnly
578 shiftKey DOMMouseEvent::ShiftKey DontDelete|ReadOnly
579 altKey DOMMouseEvent::AltKey DontDelete|ReadOnly
580 metaKey DOMMouseEvent::MetaKey DontDelete|ReadOnly
581 button DOMMouseEvent::Button DontDelete|ReadOnly
582 relatedTarget DOMMouseEvent::RelatedTarget DontDelete|ReadOnly
583 fromElement DOMMouseEvent::FromElement DontDelete|ReadOnly
584 toElement DOMMouseEvent::ToElement DontDelete|ReadOnly
585 @end
586 @begin DOMMouseEventProtoTable 1
587 initMouseEvent DOMMouseEvent::InitMouseEvent DontDelete|Function 15
588 @end
589 */
590 KJS_DEFINE_PROTOTYPE(DOMMouseEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMMouseEventProtoFunc)591 KJS_IMPLEMENT_PROTOFUNC(DOMMouseEventProtoFunc)
592 KJS_IMPLEMENT_PROTOTYPE("DOMMouseEvent", DOMMouseEventProto, DOMMouseEventProtoFunc, DOMUIEventProto)
593
594 DOMMouseEvent::DOMMouseEvent(ExecState *exec, DOM::MouseEventImpl *me) :
595 DOMUIEvent(DOMMouseEventProto::self(exec), me) {}
596
~DOMMouseEvent()597 DOMMouseEvent::~DOMMouseEvent()
598 {
599 }
600
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)601 bool DOMMouseEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
602 {
603 #ifdef KJS_VERBOSE
604 qCDebug(KHTML_LOG) << "DOMMouseEvent::getOwnPropertySlot " << propertyName.qstring();
605 #endif
606
607 return getStaticValueSlot<DOMMouseEvent, DOMUIEvent>(exec, &DOMMouseEventTable, this, propertyName, slot);
608 }
609
getValueProperty(ExecState * exec,int token) const610 JSValue *DOMMouseEvent::getValueProperty(ExecState *exec, int token) const
611 {
612 DOM::MouseEventImpl &event = *impl();
613 switch (token) {
614 case ScreenX:
615 return jsNumber(event.screenX());
616 case ScreenY:
617 return jsNumber(event.screenY());
618 case ClientX:
619 case X:
620 return jsNumber(event.clientX());
621 case ClientY:
622 case Y:
623 return jsNumber(event.clientY());
624 case OffsetX:
625 case OffsetY: { // MSIE extension
626 if (event.target()->eventTargetType() != EventTargetImpl::DOM_NODE) {
627 return jsUndefined();
628 }
629
630 DOM::Node node = static_cast<NodeImpl *>(event.target());
631 khtml::RenderObject *rend = nullptr;
632 if (node.handle()) {
633 node.handle()->document()->updateRendering();
634 rend = node.handle()->renderer();
635 }
636 int x = event.clientX();
637 int y = event.clientY();
638 if (rend) {
639 int xPos, yPos;
640 if (rend->absolutePosition(xPos, yPos)) {
641 //qCDebug(KHTML_LOG) << "DOMMouseEvent::getValueProperty rend=" << rend << " xPos=" << xPos << " yPos=" << yPos;
642 x -= xPos;
643 y -= yPos;
644 }
645 if (rend->canvas()) {
646 int cYPos, cXPos;
647 rend->canvas()->absolutePosition(cXPos, cYPos, true);
648 x += cXPos;
649 y += cYPos;
650 }
651 }
652 return jsNumber(token == OffsetX ? x : y);
653 }
654 case CtrlKey:
655 return jsBoolean(event.ctrlKey());
656 case ShiftKey:
657 return jsBoolean(event.shiftKey());
658 case AltKey:
659 return jsBoolean(event.altKey());
660 case MetaKey:
661 return jsBoolean(event.metaKey());
662 case Button: {
663 if (exec->dynamicInterpreter()->compatMode() == Interpreter::IECompat) {
664 // Tricky. The DOM (and khtml) use 0 for LMB, 1 for MMB and 2 for RMB
665 // but MSIE uses 1=LMB, 2=RMB, 4=MMB, as a bitfield
666 int domButton = event.button();
667 int button = domButton == 0 ? 1 : domButton == 1 ? 4 : domButton == 2 ? 2 : 0;
668 return jsNumber((unsigned int)button);
669 }
670 return jsNumber(event.button());
671 }
672 case ToElement:
673 // MSIE extension - "the object toward which the user is moving the mouse pointer"
674 if (event.id() == DOM::EventImpl::MOUSEOUT_EVENT) {
675 return getEventTarget(exec, event.relatedTarget());
676 }
677 return getEventTarget(exec, event.target());
678 case FromElement:
679 // MSIE extension - "object from which activation
680 // or the mouse pointer is exiting during the event" (huh?)
681 if (event.id() == DOM::EventImpl::MOUSEOUT_EVENT) {
682 return getEventTarget(exec, event.target());
683 }
684 /* fall through */
685 case RelatedTarget:
686 return getEventTarget(exec, event.relatedTarget());
687 default:
688 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMMouseEvent::getValueProperty : " << token;
689 return nullptr;
690 }
691 }
692
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)693 JSValue *DOMMouseEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
694 {
695 KJS_CHECK_THIS(KJS::DOMMouseEvent, thisObj);
696 DOM::MouseEventImpl &mouseEvent = *static_cast<DOMMouseEvent *>(thisObj)->impl();
697 switch (id) {
698 case DOMMouseEvent::InitMouseEvent:
699 mouseEvent.initMouseEvent(args[0]->toString(exec).domString(), // typeArg
700 args[1]->toBoolean(exec), // canBubbleArg
701 args[2]->toBoolean(exec), // cancelableArg
702 toAbstractView(args[3]), // viewArg
703 args[4]->toInteger(exec), // detailArg
704 args[5]->toInteger(exec), // screenXArg
705 args[6]->toInteger(exec), // screenYArg
706 args[7]->toInteger(exec), // clientXArg
707 args[8]->toInteger(exec), // clientYArg
708 args[9]->toBoolean(exec), // ctrlKeyArg
709 args[10]->toBoolean(exec), // altKeyArg
710 args[11]->toBoolean(exec), // shiftKeyArg
711 args[12]->toBoolean(exec), // metaKeyArg
712 args[13]->toInteger(exec), // buttonArg
713 toNode(args[14])); // relatedTargetArg
714 return jsUndefined();
715 }
716 return jsUndefined();
717 }
718
719 // -------------------------------------------------------------------------
720
721 const ClassInfo DOMKeyEventBase::info = { "KeyEventBase", &DOMUIEvent::info, &DOMKeyEventBaseTable, nullptr };
722
723 /*
724 @begin DOMKeyEventBaseTable 5
725 keyVal DOMKeyEventBase::Key DontDelete|ReadOnly
726 virtKeyVal DOMKeyEventBase::VirtKey DontDelete|ReadOnly
727 ctrlKey DOMKeyEventBase::CtrlKey DontDelete|ReadOnly
728 altKey DOMKeyEventBase::AltKey DontDelete|ReadOnly
729 shiftKey DOMKeyEventBase::ShiftKey DontDelete|ReadOnly
730 metaKey DOMKeyEventBase::MetaKey DontDelete|ReadOnly
731 @end
732 */
733
DOMKeyEventBase(JSObject * proto,DOM::KeyEventBaseImpl * ke)734 DOMKeyEventBase::DOMKeyEventBase(JSObject *proto, DOM::KeyEventBaseImpl *ke) :
735 DOMUIEvent(proto, ke) {}
736
~DOMKeyEventBase()737 DOMKeyEventBase::~DOMKeyEventBase()
738 {}
739
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)740 bool DOMKeyEventBase::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
741 {
742 #ifdef KJS_VERBOSE
743 qCDebug(KHTML_LOG) << "DOMKeyEventBase::getOwnPropertySlot " << propertyName.qstring();
744 #endif
745 return getStaticValueSlot<DOMKeyEventBase, DOMUIEvent>(exec, &DOMKeyEventBaseTable, this, propertyName, slot);
746 }
747
getValueProperty(ExecState *,int token) const748 JSValue *DOMKeyEventBase::getValueProperty(ExecState *, int token) const
749 {
750 DOM::KeyEventBaseImpl *tevent = impl();
751 switch (token) {
752 case Key:
753 return jsNumber(tevent->keyVal());
754 case VirtKey:
755 return jsNumber(tevent->virtKeyVal());
756 // these modifier attributes actually belong into a KeyboardEvent interface,
757 // but we want them on "keypress" as well.
758 case CtrlKey:
759 return jsBoolean(tevent->ctrlKey());
760 case ShiftKey:
761 return jsBoolean(tevent->shiftKey());
762 case AltKey:
763 return jsBoolean(tevent->altKey());
764 case MetaKey:
765 return jsBoolean(tevent->metaKey());
766 default:
767 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMKeyEventBase::getValueProperty : " << token;
768 return jsUndefined();
769 }
770 }
771
772 // -------------------------------------------------------------------------
773 const ClassInfo DOMTextEvent::info = { "TextEvent", &DOMKeyEventBase::info, &DOMTextEventTable, nullptr };
774
775 /*
776 @begin DOMTextEventTable 1
777 data DOMTextEvent::Data DontDelete|ReadOnly
778 @end
779 @begin DOMTextEventProtoTable 1
780 initTextEvent DOMTextEvent::InitTextEvent DontDelete|Function 5
781 # Missing: initTextEventNS
782 @end
783 */
784 KJS_DEFINE_PROTOTYPE(DOMTextEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMTextEventProtoFunc)785 KJS_IMPLEMENT_PROTOFUNC(DOMTextEventProtoFunc)
786 KJS_IMPLEMENT_PROTOTYPE("DOMTextEvent", DOMTextEventProto, DOMTextEventProtoFunc, DOMUIEventProto) //Note: no proto in KeyBase
787
788 DOMTextEvent::DOMTextEvent(ExecState *exec, DOM::TextEventImpl *ke) :
789 DOMKeyEventBase(DOMTextEventProto::self(exec), ke) {}
790
~DOMTextEvent()791 DOMTextEvent::~DOMTextEvent()
792 {
793 }
794
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)795 bool DOMTextEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
796 {
797 #ifdef KJS_VERBOSE
798 qCDebug(KHTML_LOG) << "DOMTextEvent::getOwnPropertySlot " << propertyName.qstring();
799 #endif
800 return getStaticValueSlot<DOMTextEvent, DOMKeyEventBase>(exec, &DOMTextEventTable, this, propertyName, slot);
801 }
802
getValueProperty(ExecState *,int token) const803 JSValue *DOMTextEvent::getValueProperty(ExecState *, int token) const
804 {
805 DOM::TextEventImpl &tevent = *impl();
806 switch (token) {
807 case Data:
808 return jsString(tevent.data());
809 default:
810 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token;
811 return jsUndefined();
812 }
813 }
814
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)815 JSValue *DOMTextEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
816 {
817 KJS_CHECK_THIS(KJS::DOMTextEvent, thisObj);
818 DOM::TextEventImpl &keyEvent = *static_cast<DOMTextEvent *>(thisObj)->impl();
819 switch (id) {
820 case DOMTextEvent::InitTextEvent:
821
822 keyEvent.initTextEvent(args[0]->toString(exec).domString(), // typeArg
823 args[1]->toBoolean(exec), // canBubbleArg
824 args[2]->toBoolean(exec), // cancelableArg
825 toAbstractView(args[3]), // viewArg
826 args[4]->toString(exec).domString()); // dataArg
827 return jsUndefined();
828 }
829 return jsUndefined();
830 }
831 // -------------------------------------------------------------------------
832 const ClassInfo DOMKeyboardEvent::info = { "KeyboardEvent", &DOMKeyEventBase::info, &DOMKeyboardEventTable, nullptr };
833
834 /*
835 @begin DOMKeyboardEventTable 2
836 keyIdentifier DOMKeyboardEvent::KeyIdentifier DontDelete|ReadOnly
837 keyLocation DOMKeyboardEvent::KeyLocation DontDelete|ReadOnly
838 @end
839 @begin DOMKeyboardEventProtoTable 2
840 initKeyboardEvent DOMKeyboardEvent::InitKeyboardEvent DontDelete|Function 7
841 getModifierState DOMKeyboardEvent::GetModifierState DontDelete|Function 1
842 @end
843 */
844 KJS_DEFINE_PROTOTYPE(DOMKeyboardEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMKeyboardEventProtoFunc)845 KJS_IMPLEMENT_PROTOFUNC(DOMKeyboardEventProtoFunc)
846 KJS_IMPLEMENT_PROTOTYPE("DOMKeyboardEvent", DOMKeyboardEventProto, DOMKeyboardEventProtoFunc, DOMUIEventProto) //Note: no proto in KeyBase
847
848 DOMKeyboardEvent::DOMKeyboardEvent(ExecState *exec, DOM::KeyboardEventImpl *ke) :
849 DOMKeyEventBase(DOMKeyboardEventProto::self(exec), ke) {}
850
~DOMKeyboardEvent()851 DOMKeyboardEvent::~DOMKeyboardEvent()
852 {
853 }
854
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)855 bool DOMKeyboardEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
856 {
857 #ifdef KJS_VERBOSE
858 qCDebug(KHTML_LOG) << "DOMKeyboardEvent::getOwnPropertySlot " << propertyName.qstring();
859 #endif
860 return getStaticValueSlot<DOMKeyboardEvent, DOMKeyEventBase>(exec, &DOMKeyboardEventTable, this, propertyName, slot);
861 }
862
getValueProperty(ExecState *,int token) const863 JSValue *DOMKeyboardEvent::getValueProperty(ExecState *, int token) const
864 {
865 DOM::KeyboardEventImpl *tevent = impl();
866 switch (token) {
867 case KeyIdentifier:
868 return jsString(tevent->keyIdentifier());
869 case KeyLocation:
870 return jsNumber(tevent->keyLocation());
871 default:
872 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMKeyboardEvent::getValueProperty : " << token;
873 return jsUndefined();
874 }
875 }
876
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)877 JSValue *DOMKeyboardEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
878 {
879 KJS_CHECK_THIS(KJS::DOMKeyboardEvent, thisObj);
880 DOM::KeyboardEventImpl *keyEvent = static_cast<DOMKeyboardEvent *>(thisObj)->impl();
881 switch (id) {
882 case DOMKeyboardEvent::InitKeyboardEvent:
883 keyEvent->initKeyboardEvent(args[0]->toString(exec).domString(), // typeArg
884 args[1]->toBoolean(exec), // canBubbleArg
885 args[2]->toBoolean(exec), // cancelableArg
886 toAbstractView(args[3]), // viewArg
887 args[4]->toString(exec).domString(), // keyIdentifierArg
888 args[5]->toInteger(exec), // keyLocationArg
889 args[6]->toString(exec).domString()); //modifiersList
890 break;
891 case DOMKeyboardEvent::GetModifierState:
892 return jsBoolean(keyEvent->getModifierState(args[0]->toString(exec).domString()));
893 }
894 return jsUndefined();
895 }
896
897 // -------------------------------------------------------------------------
898 const ClassInfo KeyboardEventConstructor::info = { "KeyboardEventConstructor", nullptr, &KeyboardEventConstructorTable, nullptr };
899 /*
900 @begin KeyboardEventConstructorTable 4
901 DOM_KEY_LOCATION_STANDARD DOM::KeyboardEvent::DOM_KEY_LOCATION_STANDARD DontDelete|ReadOnly
902 DOM_KEY_LOCATION_LEFT DOM::KeyboardEvent::DOM_KEY_LOCATION_LEFT DontDelete|ReadOnly
903 DOM_KEY_LOCATION_RIGHT DOM::KeyboardEvent::DOM_KEY_LOCATION_RIGHT DontDelete|ReadOnly
904 DOM_KEY_LOCATION_NUMPAD DOM::KeyboardEvent::DOM_KEY_LOCATION_NUMPAD DontDelete|ReadOnly
905 @end
906 */
KeyboardEventConstructor(ExecState * exec)907 KeyboardEventConstructor::KeyboardEventConstructor(ExecState *exec)
908 : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype())
909 {}
910
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)911 bool KeyboardEventConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
912 {
913 #ifdef KJS_VERBOSE
914 qCDebug(KHTML_LOG) << "DOMKeyboardEvent::getOwnPropertySlot " << propertyName.qstring();
915 #endif
916 return getStaticValueSlot<KeyboardEventConstructor, DOMObject>(exec, &KeyboardEventConstructorTable, this, propertyName, slot);
917 }
918
getValueProperty(ExecState *,int token) const919 JSValue *KeyboardEventConstructor::getValueProperty(ExecState *, int token) const
920 {
921 // We use the token as the value to return directly
922 return jsNumber(token);
923 }
924
getKeyboardEventConstructor(ExecState * exec)925 JSValue *KJS::getKeyboardEventConstructor(ExecState *exec)
926 {
927 return cacheGlobalObject<KeyboardEventConstructor>(exec, "[[keyboardEvent.constructor]]");
928 }
929
930 // -------------------------------------------------------------------------
931 const ClassInfo MutationEventConstructor::info = { "MutationEventConstructor", nullptr, &MutationEventConstructorTable, nullptr };
932 /*
933 @begin MutationEventConstructorTable 3
934 MODIFICATION DOM::MutationEvent::MODIFICATION DontDelete|ReadOnly
935 ADDITION DOM::MutationEvent::ADDITION DontDelete|ReadOnly
936 REMOVAL DOM::MutationEvent::REMOVAL DontDelete|ReadOnly
937 @end
938 */
MutationEventConstructor(ExecState * exec)939 MutationEventConstructor::MutationEventConstructor(ExecState *exec)
940 : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype())
941 {
942 }
943
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)944 bool MutationEventConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
945 {
946 return getStaticValueSlot<MutationEventConstructor, DOMObject>(exec, &MutationEventConstructorTable, this, propertyName, slot);
947 }
948
getValueProperty(ExecState *,int token) const949 JSValue *MutationEventConstructor::getValueProperty(ExecState *, int token) const
950 {
951 // We use the token as the value to return directly
952 return jsNumber(token);
953 }
954
getMutationEventConstructor(ExecState * exec)955 JSValue *KJS::getMutationEventConstructor(ExecState *exec)
956 {
957 return cacheGlobalObject<MutationEventConstructor>(exec, "[[mutationEvent.constructor]]");
958 }
959
960 // -------------------------------------------------------------------------
961
962 const ClassInfo DOMMutationEvent::info = { "MutationEvent", &DOMEvent::info, &DOMMutationEventTable, nullptr };
963 /*
964 @begin DOMMutationEventTable 5
965 relatedNode DOMMutationEvent::RelatedNode DontDelete|ReadOnly
966 prevValue DOMMutationEvent::PrevValue DontDelete|ReadOnly
967 newValue DOMMutationEvent::NewValue DontDelete|ReadOnly
968 attrName DOMMutationEvent::AttrName DontDelete|ReadOnly
969 attrChange DOMMutationEvent::AttrChange DontDelete|ReadOnly
970 @end
971 @begin DOMMutationEventProtoTable 1
972 initMutationEvent DOMMutationEvent::InitMutationEvent DontDelete|Function 8
973 @end
974 */
975 KJS_DEFINE_PROTOTYPE(DOMMutationEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMMutationEventProtoFunc)976 KJS_IMPLEMENT_PROTOFUNC(DOMMutationEventProtoFunc)
977 KJS_IMPLEMENT_PROTOTYPE("DOMMutationEvent", DOMMutationEventProto, DOMMutationEventProtoFunc, DOMEventProto)
978
979 DOMMutationEvent::DOMMutationEvent(ExecState *exec, DOM::MutationEventImpl *me) :
980 DOMEvent(DOMMutationEventProto::self(exec), me) {}
981
~DOMMutationEvent()982 DOMMutationEvent::~DOMMutationEvent()
983 {
984 }
985
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)986 bool DOMMutationEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
987 {
988 return getStaticValueSlot<DOMMutationEvent, DOMEvent>(exec, &DOMMutationEventTable, this, propertyName, slot);
989 }
990
getValueProperty(ExecState * exec,int token) const991 JSValue *DOMMutationEvent::getValueProperty(ExecState *exec, int token) const
992 {
993 DOM::MutationEventImpl &event = *impl();
994 switch (token) {
995 case RelatedNode: {
996 DOM::Node relatedNode = event.relatedNode();
997 return getDOMNode(exec, relatedNode.handle());
998 }
999 case PrevValue:
1000 return jsString(event.prevValue());
1001 case NewValue:
1002 return jsString(event.newValue());
1003 case AttrName:
1004 return jsString(event.attrName());
1005 case AttrChange:
1006 return jsNumber((unsigned int)event.attrChange());
1007 default:
1008 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMMutationEvent::getValueProperty : " << token;
1009 return nullptr;
1010 }
1011 }
1012
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)1013 JSValue *DOMMutationEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
1014 {
1015 KJS_CHECK_THIS(KJS::DOMMutationEvent, thisObj);
1016 DOM::MutationEventImpl &mutationEvent = *static_cast<DOMMutationEvent *>(thisObj)->impl();
1017 switch (id) {
1018 case DOMMutationEvent::InitMutationEvent:
1019 mutationEvent.initMutationEvent(args[0]->toString(exec).domString(), // typeArg,
1020 args[1]->toBoolean(exec), // canBubbleArg
1021 args[2]->toBoolean(exec), // cancelableArg
1022 toNode(args[3]), // relatedNodeArg
1023 args[4]->toString(exec).domString(), // prevValueArg
1024 args[5]->toString(exec).domString(), // newValueArg
1025 args[6]->toString(exec).domString(), // attrNameArg
1026 args[7]->toInteger(exec)); // attrChangeArg
1027 return jsUndefined();
1028 }
1029 return jsUndefined();
1030 }
1031 // -------------------------------------------------------------------------
1032
1033 const ClassInfo DOMMessageEvent::info = { "MessageEvent", &DOMEvent::info, &DOMMessageEventTable, nullptr };
1034 /*
1035 @begin DOMMessageEventTable 5
1036 data DOMMessageEvent::Data DontDelete|ReadOnly
1037 origin DOMMessageEvent::Origin DontDelete|ReadOnly
1038 source DOMMessageEvent::Source DontDelete|ReadOnly
1039 lastEventId DOMMessageEvent::LastEventId DontDelete|ReadOnly
1040 @end
1041 @begin DOMMessageEventProtoTable 1
1042 initMessageEvent DOMMessageEvent::InitMessageEvent DontDelete|Function 7
1043 @end
1044 */
1045 KJS_DEFINE_PROTOTYPE(DOMMessageEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMMessageEventProtoFunc)1046 KJS_IMPLEMENT_PROTOFUNC(DOMMessageEventProtoFunc)
1047 KJS_IMPLEMENT_PROTOTYPE("DOMMessageEvent", DOMMessageEventProto, DOMMessageEventProtoFunc, DOMEventProto)
1048 IMPLEMENT_PSEUDO_CONSTRUCTOR(MessageEventPseudoCtor, "DOMMessageEvent", DOMMessageEventProto)
1049
1050 DOMMessageEvent::DOMMessageEvent(ExecState *exec, DOM::MessageEventImpl *me) :
1051 DOMEvent(DOMMessageEventProto::self(exec), me) {}
1052
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)1053 bool DOMMessageEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
1054 {
1055 return getStaticValueSlot<DOMMessageEvent, DOMEvent>(exec, &DOMMessageEventTable, this, propertyName, slot);
1056 }
1057
getValueProperty(ExecState * exec,int token) const1058 JSValue *DOMMessageEvent::getValueProperty(ExecState *exec, int token) const
1059 {
1060 DOM::MessageEventImpl &event = *impl();
1061 switch (token) {
1062 case Data:
1063 return getMessageEventData(exec, event.data().get());
1064 case Origin:
1065 return jsString(event.origin());
1066 case LastEventId:
1067 return jsString(event.lastEventId());
1068 case Source:
1069 if (KHTMLPart *p = event.source()) {
1070 return Window::retrieve(p);
1071 } else {
1072 return jsNull();
1073 }
1074 default:
1075 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMMessageEvent::getValueProperty : " << token;
1076 return nullptr;
1077 }
1078 }
1079
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)1080 JSValue *DOMMessageEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
1081 {
1082 KJS_CHECK_THIS(KJS::DOMMessageEvent, thisObj);
1083 DOM::MessageEventImpl &messageEvent = *static_cast<DOMMessageEvent *>(thisObj)->impl();
1084 switch (id) {
1085 case DOMMessageEvent::InitMessageEvent: {
1086 JSObject *sourceObj = args[3]->getObject();
1087
1088 Window *sourceWin = nullptr;
1089 if (sourceObj && sourceObj->inherits(&Window::info)) {
1090 sourceWin = static_cast<Window *>(sourceObj);
1091 }
1092
1093 KHTMLPart *part = nullptr;
1094 if (sourceWin) {
1095 part = qobject_cast<KHTMLPart *>(sourceWin->part());
1096 }
1097
1098 if (!part) {
1099 setDOMException(exec, DOM::DOMException::TYPE_MISMATCH_ERR);
1100 return jsUndefined();
1101 }
1102
1103 messageEvent.initMessageEvent(args[0]->toString(exec).domString(), // typeArg,
1104 args[1]->toBoolean(exec), // canBubbleArg
1105 args[2]->toBoolean(exec), // cancelableArg
1106 encapsulateMessageEventData(
1107 exec, exec->dynamicInterpreter(), args[3]), // dataArg
1108 args[4]->toString(exec).domString(), // originArg
1109 args[5]->toString(exec).domString(), // lastEventIdArg
1110 part); // sourceArg
1111 return jsUndefined();
1112 }
1113 }
1114 return jsUndefined();
1115 }
1116
1117 // -------------------------------------------------------------------------
1118
1119 const ClassInfo DOMHashChangeEvent::info = { "HashChangeEvent", &DOMEvent::info, &DOMHashChangeEventTable, nullptr };
1120 /*
1121 @begin DOMHashChangeEventTable 2
1122 oldURL DOMHashChangeEvent::OldUrl DontDelete|ReadOnly
1123 newURL DOMHashChangeEvent::NewUrl DontDelete|ReadOnly
1124 @end
1125 @begin DOMHashChangeEventProtoTable 1
1126 initHashChangeEvent DOMHashChangeEvent::InitHashChangeEvent DontDelete|Function 5
1127 @end
1128 */
1129 KJS_DEFINE_PROTOTYPE(DOMHashChangeEventProto)
KJS_IMPLEMENT_PROTOFUNC(DOMHashChangeEventProtoFunc)1130 KJS_IMPLEMENT_PROTOFUNC(DOMHashChangeEventProtoFunc)
1131 KJS_IMPLEMENT_PROTOTYPE("DOMHashChangeEvent", DOMHashChangeEventProto, DOMHashChangeEventProtoFunc, DOMEventProto)
1132 IMPLEMENT_PSEUDO_CONSTRUCTOR(HashChangeEventPseudoCtor, "DOMHashChangeEvent", DOMHashChangeEventProto)
1133
1134 DOMHashChangeEvent::DOMHashChangeEvent(ExecState *exec, HashChangeEventImpl *me) :
1135 DOMEvent(DOMHashChangeEventProto::self(exec), me)
1136 {}
1137
getOwnPropertySlot(ExecState * exec,const Identifier & propertyName,PropertySlot & slot)1138 bool DOMHashChangeEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
1139 {
1140 return getStaticValueSlot<DOMHashChangeEvent, DOMEvent>(exec, &DOMHashChangeEventTable, this, propertyName, slot);
1141 }
1142
getValueProperty(ExecState *,int token) const1143 JSValue *DOMHashChangeEvent::getValueProperty(ExecState * /*exec*/, int token) const
1144 {
1145 DOM::HashChangeEventImpl &event = *impl();
1146 switch (token) {
1147 case NewUrl:
1148 return jsString(event.newUrl());
1149 case OldUrl:
1150 return jsString(event.oldUrl());
1151 default:
1152 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMHashChangeEvent::getValueProperty : " << token;
1153 return jsUndefined();
1154 }
1155 }
1156
callAsFunction(ExecState * exec,JSObject * thisObj,const List & args)1157 JSValue *DOMHashChangeEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
1158 {
1159 KJS_CHECK_THIS(KJS::DOMHashChangeEvent, thisObj);
1160 DOM::HashChangeEventImpl &hashChangeEvent = *static_cast<DOMHashChangeEvent *>(thisObj)->impl();
1161 switch (id) {
1162 case DOMHashChangeEvent::InitHashChangeEvent: {
1163 hashChangeEvent.initHashChangeEvent(args[0]->toString(exec).domString(), // typeArg,
1164 args[1]->toBoolean(exec), // canBubbleArg
1165 args[2]->toBoolean(exec), // cancelableArg
1166 args[3]->toString(exec).domString(), // oldURL
1167 args[4]->toString(exec).domString()); // newURL
1168 return jsUndefined();
1169 }
1170 }
1171 return jsUndefined();
1172 }
1173