KHtml

kjs_events.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2001 Peter Kelly ([email protected])
4  * Copyright (C) 2003 Apple Computer, Inc.
5  * Copyright (C) 2006, 2009, 2010 Maksim Orlovich ([email protected])
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 
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 
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 
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 
128 DOM::DOMString JSEventListener::eventListenerType()
129 {
130  if (html) {
131  return "_khtml_HTMLEventListener";
132  } else {
133  return "_khtml_JSEventListener";
134  }
135 }
136 
137 JSObject *JSEventListener::listenerObj() const
138 {
139  return listener;
140 }
141 
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 
156 JSLazyEventListener::~JSLazyEventListener()
157 {
158 }
159 
160 void JSLazyEventListener::handleEvent(DOM::Event &evt)
161 {
162  parseCode();
163  if (listener) {
164  JSEventListener::handleEvent(evt);
165  }
166 }
167 
168 JSObject *JSLazyEventListener::listenerObj() const
169 {
170  parseCode();
171  return listener;
172 }
173 
174 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)
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 
271 DOMEvent::DOMEvent(JSObject *proto, DOM::EventImpl *e):
272  m_impl(e)
273 {
274  setPrototype(proto);
275 }
276 
277 DOMEvent::~DOMEvent()
278 {
279  ScriptInterpreter::forgetDOMObject(m_impl.get());
280 }
281 
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 
291 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 
321 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 
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 
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 
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 
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 
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 */
451 EventExceptionConstructor::EventExceptionConstructor(ExecState *exec)
452  : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype())
453 {
454 }
455 
456 bool EventExceptionConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
457 {
458  return getStaticValueSlot<EventExceptionConstructor, DOMObject>(exec, &EventExceptionConstructorTable, this, propertyName, slot);
459 }
460 
461 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 
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)
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 
498 DOMUIEvent::DOMUIEvent(JSObject *proto, DOM::UIEventImpl *ue) :
499  DOMEvent(proto, ue) {}
500 
501 DOMUIEvent::~DOMUIEvent()
502 {
503 }
504 
505 bool DOMUIEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
506 {
507  return getStaticValueSlot<DOMUIEvent, DOMEvent>(exec, &DOMUIEventTable, this, propertyName, slot);
508 }
509 
510 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 
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)
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 
597 DOMMouseEvent::~DOMMouseEvent()
598 {
599 }
600 
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 
610 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 
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 
734 DOMKeyEventBase::DOMKeyEventBase(JSObject *proto, DOM::KeyEventBaseImpl *ke) :
735  DOMUIEvent(proto, ke) {}
736 
737 DOMKeyEventBase::~DOMKeyEventBase()
738 {}
739 
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 
748 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)
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 
791 DOMTextEvent::~DOMTextEvent()
792 {
793 }
794 
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 
803 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 
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)
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 
851 DOMKeyboardEvent::~DOMKeyboardEvent()
852 {
853 }
854 
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 
863 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 
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 */
907 KeyboardEventConstructor::KeyboardEventConstructor(ExecState *exec)
908  : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype())
909 {}
910 
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 
919 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 
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 */
939 MutationEventConstructor::MutationEventConstructor(ExecState *exec)
940  : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype())
941 {
942 }
943 
944 bool MutationEventConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
945 {
946  return getStaticValueSlot<MutationEventConstructor, DOMObject>(exec, &MutationEventConstructorTable, this, propertyName, slot);
947 }
948 
949 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 
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)
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 
982 DOMMutationEvent::~DOMMutationEvent()
983 {
984 }
985 
986 bool DOMMutationEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
987 {
988  return getStaticValueSlot<DOMMutationEvent, DOMEvent>(exec, &DOMMutationEventTable, this, propertyName, slot);
989 }
990 
991 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 
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)
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 
1053 bool DOMMessageEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
1054 {
1055  return getStaticValueSlot<DOMMessageEvent, DOMEvent>(exec, &DOMMessageEventTable, this, propertyName, slot);
1056 }
1057 
1058 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 
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)
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 
1138 bool DOMHashChangeEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
1139 {
1140  return getStaticValueSlot<DOMHashChangeEvent, DOMEvent>(exec, &DOMHashChangeEventTable, this, propertyName, slot);
1141 }
1142 
1143 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 
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 }
KJS_EXTERNAL_EXPORT QString qstring() const
The Node interface is the primary datatype for the entire Document Object Model.
Definition: dom_node.h:278
virtual ExecState * globalExec()
QString name(const QVariant &location)
Base class for all objects in this binding.
Definition: kjs_binding.h:78
Interpreter * dynamicInterpreter() const
KJOBWIDGETS_EXPORT QWidget * window(KJob *job)
void append(JSValue *val)
Proxy class serving as interface when being dlopen&#39;ed.
Definition: kjs_proxy.h:61
This class is khtml&#39;s main class.
Definition: khtml_part.h:208
void ref()
We inherit from Interpreter, to save a pointer to the HTML part that the interpreter runs for...
Definition: kjs_binding.h:96
void deref()
EventImpl * handle() const
void preventDefault()
If an event is cancelable, the preventDefault method is used to signify that the event is to be cance...
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
bool hadException() const
void setCurrentEvent(DOM::Event *evt)
Set the event that is triggering the execution of a script, if any.
Definition: kjs_binding.h:145
JSObject * builtinFunction() const
This library provides a full-featured HTML parser and widget.
Introduced in DOM Level 2.
Definition: dom2_events.h:116
char * toString(const T &value)
void clearException()
void keyEvent(QTest::KeyAction action, QWindow *window, char ascii, Qt::KeyboardModifiers modifier, int delay)
Base Class for all rendering tree objects.
JSObject * builtinObjectPrototype() const
bool toBool() const const
QVariant::Type type() const const
NodeImpl * handle() const
Definition: dom_node.h:936
Window
Definition: kjs_window.h:393
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:47:57 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.