File indexing completed on 2023-09-24 04:06:10
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 0004 * Copyright (C) 2003 Apple Computer, Inc. 0005 * Copyright (C) 2006, 2009, 2010 Maksim Orlovich (maksim@kde.org) 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Library General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Library General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Library General Public 0018 * License along with this library; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0020 */ 0021 0022 #include "kjs_events.h" 0023 #include "kjs_events.lut.h" 0024 0025 #include "kjs_data.h" 0026 #include "kjs_window.h" 0027 #include "kjs_views.h" 0028 #include "kjs_proxy.h" 0029 #include <xml/dom_nodeimpl.h> 0030 #include <xml/dom_docimpl.h> 0031 #include <xml/dom2_eventsimpl.h> 0032 #include <rendering/render_object.h> 0033 #include <rendering/render_canvas.h> 0034 #include <khtml_part.h> 0035 #ifdef KJS_DEBUGGER 0036 #include "debugger/debugwindow.h" 0037 #endif 0038 #include "khtml_debug.h" 0039 #include <kjs/scriptfunction.h> 0040 #include <kjs/function_object.h> 0041 0042 using namespace KJS; 0043 using namespace KJSDebugger; 0044 using namespace DOM; 0045 0046 // ------------------------------------------------------------------------- 0047 0048 JSEventListener::JSEventListener(JSObject *_listener, JSObject *_compareListenerImp, JSObject *_win, bool _html) 0049 : listener(_listener), compareListenerImp(_compareListenerImp), html(_html), win(_win) 0050 { 0051 //fprintf(stderr,"JSEventListener::JSEventListener this=%p listener=%p\n",this,listener.imp()); 0052 if (compareListenerImp) { 0053 static_cast<Window *>(win.get())->jsEventListeners.insert(QPair<void *, bool>(compareListenerImp.get(), html), this); 0054 } 0055 } 0056 0057 JSEventListener::~JSEventListener() 0058 { 0059 if (compareListenerImp) { 0060 static_cast<Window *>(win.get())->jsEventListeners.remove(QPair<void *, bool>(compareListenerImp.get(), html)); 0061 } 0062 //fprintf(stderr,"JSEventListener::~JSEventListener this=%p listener=%p\n",this,listener.imp()); 0063 } 0064 0065 void JSEventListener::handleEvent(DOM::Event &evt) 0066 { 0067 KHTMLPart *part = qobject_cast<KHTMLPart *>(static_cast<Window *>(win.get())->part()); 0068 KJSProxy *proxy = nullptr; 0069 if (part) { 0070 proxy = part->jScript(); 0071 } 0072 0073 if (proxy && listener && listener->implementsCall()) { 0074 #ifdef KJS_DEBUGGER 0075 //### This is the wrong place to do this --- we need 0076 // a more global/general stategy to prevent unwanted event loop recursion issues. 0077 if (proxy->debugEnabled() && DebugWindow::window()->inSession()) { 0078 return; 0079 } 0080 #endif 0081 ref(); 0082 0083 KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); 0084 ExecState *exec = interpreter->globalExec(); 0085 0086 List args; 0087 args.append(getDOMEvent(exec, evt.handle())); 0088 0089 JSObject *thisObj = nullptr; 0090 // Check whether handler is a function or an object with handleEvent method 0091 if (listener == compareListenerImp) { 0092 // Set "this" to the event's current target 0093 thisObj = getEventTarget(exec, evt.handle()->currentTarget())->getObject(); 0094 } else { 0095 thisObj = compareListenerImp; 0096 } 0097 0098 if (!thisObj) { 0099 // ### can this still happen? eventTarget should be window on Window events now. 0100 thisObj = win; 0101 } 0102 0103 Window *window = static_cast<Window *>(win.get()); 0104 // Set the event we're handling in the Window object 0105 window->setCurrentEvent(evt.handle()); 0106 // ... and in the interpreter 0107 interpreter->setCurrentEvent(&evt); 0108 0109 interpreter->startCPUGuard(); 0110 JSValue *retval = listener->call(exec, thisObj, args); 0111 interpreter->stopCPUGuard(); 0112 0113 window->setCurrentEvent(nullptr); 0114 interpreter->setCurrentEvent(nullptr); 0115 if (exec->hadException()) { 0116 exec->clearException(); 0117 } else if (html) { 0118 QVariant ret = ValueToVariant(exec, retval); 0119 if (ret.type() == QVariant::Bool && ret.toBool() == false) { 0120 evt.preventDefault(); 0121 } 0122 } 0123 window->afterScriptExecution(); 0124 deref(); 0125 } 0126 } 0127 0128 DOM::DOMString JSEventListener::eventListenerType() 0129 { 0130 if (html) { 0131 return "_khtml_HTMLEventListener"; 0132 } else { 0133 return "_khtml_JSEventListener"; 0134 } 0135 } 0136 0137 JSObject *JSEventListener::listenerObj() const 0138 { 0139 return listener; 0140 } 0141 0142 JSLazyEventListener::JSLazyEventListener(const QString &_code, const QString &_url, int _lineNum, 0143 const QString &_name, JSObject *_win, DOM::NodeImpl *_originalNode, bool _svg) 0144 : JSEventListener(nullptr, nullptr, _win, true), code(_code), url(_url), lineNum(_lineNum), 0145 name(_name), parsed(false), svg(_svg) 0146 { 0147 // We don't retain the original node, because we assume it 0148 // will stay alive as long as this handler object is around 0149 // and we need to avoid a reference cycle. If JS transfers 0150 // this handler to another node, parseCode will be called and 0151 // then originalNode is no longer needed. 0152 0153 originalNode = _originalNode; 0154 } 0155 0156 JSLazyEventListener::~JSLazyEventListener() 0157 { 0158 } 0159 0160 void JSLazyEventListener::handleEvent(DOM::Event &evt) 0161 { 0162 parseCode(); 0163 if (listener) { 0164 JSEventListener::handleEvent(evt); 0165 } 0166 } 0167 0168 JSObject *JSLazyEventListener::listenerObj() const 0169 { 0170 parseCode(); 0171 return listener; 0172 } 0173 0174 void JSLazyEventListener::parseCode() const 0175 { 0176 if (!parsed) { 0177 KHTMLPart *part = qobject_cast<KHTMLPart *>(static_cast<Window *>(win.get())->part()); 0178 KJSProxy *proxy = nullptr; 0179 if (part) { 0180 proxy = part->jScript(); 0181 } 0182 0183 if (proxy) { 0184 KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); 0185 ExecState *exec = interpreter->globalExec(); 0186 0187 //KJS::Constructor constr(KJS::Global::current().get("Function").imp()); 0188 KJS::FunctionObjectImp *constr = static_cast<KJS::FunctionObjectImp *>(interpreter->builtinFunction()); 0189 KJS::List args; 0190 0191 if (svg) { 0192 args.append(jsString("evt")); 0193 } else { 0194 args.append(jsString("event")); 0195 } 0196 0197 args.append(jsString(code)); 0198 listener = constr->construct(exec, args, 0199 Identifier(UString(name)), url, lineNum); // ### is globalExec ok ? 0200 compareListenerImp = listener; 0201 0202 if (exec->hadException()) { 0203 exec->clearException(); 0204 0205 // failed to parse, so let's just make this listener a no-op 0206 listener = nullptr; 0207 } else if (!listener->inherits(&DeclaredFunctionImp::info)) { 0208 listener = nullptr;// Error creating function 0209 } else { 0210 DeclaredFunctionImp *declFunc = static_cast<DeclaredFunctionImp *>(listener.get()); 0211 0212 if (originalNode) { 0213 // Add the event's home element to the scope 0214 // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope) 0215 ScopeChain scope = declFunc->scope(); 0216 0217 JSObject *thisObj = getDOMNode(exec, originalNode)->getObject(); 0218 0219 if (thisObj) { 0220 static_cast<DOMNode *>(thisObj)->pushEventHandlerScope(exec, scope); 0221 declFunc->setScope(scope); 0222 } 0223 } 0224 } 0225 } 0226 0227 // no more need to keep the unparsed code around 0228 code.clear(); 0229 0230 if (listener) { 0231 static_cast<Window *>(win.get())->jsEventListeners.insert(QPair<void *, bool>(compareListenerImp.get(), true), 0232 (KJS::JSEventListener *)(this)); 0233 } 0234 0235 parsed = true; 0236 } 0237 } 0238 0239 // ------------------------------------------------------------------------- 0240 0241 const ClassInfo DOMEvent::info = { "Event", nullptr, &DOMEventTable, nullptr }; 0242 /* 0243 @begin DOMEventTable 7 0244 type DOMEvent::Type DontDelete|ReadOnly 0245 target DOMEvent::Target DontDelete|ReadOnly 0246 currentTarget DOMEvent::CurrentTarget DontDelete|ReadOnly 0247 srcElement DOMEvent::SrcElement DontDelete|ReadOnly 0248 eventPhase DOMEvent::EventPhase DontDelete|ReadOnly 0249 bubbles DOMEvent::Bubbles DontDelete|ReadOnly 0250 cancelable DOMEvent::Cancelable DontDelete|ReadOnly 0251 timeStamp DOMEvent::TimeStamp DontDelete|ReadOnly 0252 returnValue DOMEvent::ReturnValue DontDelete 0253 cancelBubble DOMEvent::CancelBubble DontDelete 0254 @end 0255 @begin DOMEventProtoTable 3 0256 stopPropagation DOMEvent::StopPropagation DontDelete|Function 0 0257 preventDefault DOMEvent::PreventDefault DontDelete|Function 0 0258 initEvent DOMEvent::InitEvent DontDelete|Function 3 0259 @end 0260 */ 0261 KJS_DEFINE_PROTOTYPE(DOMEventProto) 0262 KJS_IMPLEMENT_PROTOFUNC(DOMEventProtoFunc) 0263 KJS_IMPLEMENT_PROTOTYPE("DOMEvent", DOMEventProto, DOMEventProtoFunc, ObjectPrototype) 0264 0265 DOMEvent::DOMEvent(ExecState *exec, DOM::EventImpl *e) 0266 : m_impl(e) 0267 { 0268 setPrototype(DOMEventProto::self(exec)); 0269 } 0270 0271 DOMEvent::DOMEvent(JSObject *proto, DOM::EventImpl *e): 0272 m_impl(e) 0273 { 0274 setPrototype(proto); 0275 } 0276 0277 DOMEvent::~DOMEvent() 0278 { 0279 ScriptInterpreter::forgetDOMObject(m_impl.get()); 0280 } 0281 0282 bool DOMEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0283 { 0284 #ifdef KJS_VERBOSE 0285 qCDebug(KHTML_LOG) << "KJS::DOMEvent::getOwnPropertySlot " << propertyName.qstring(); 0286 #endif 0287 0288 return getStaticValueSlot<DOMEvent, DOMObject>(exec, &DOMEventTable, this, propertyName, slot); 0289 } 0290 0291 JSValue *DOMEvent::getValueProperty(ExecState *exec, int token) const 0292 { 0293 DOM::EventImpl &event = *impl(); 0294 switch (token) { 0295 case Type: 0296 return jsString(event.type()); 0297 case Target: 0298 case SrcElement: /*MSIE extension - "the object that fired the event"*/ 0299 return getEventTarget(exec, event.target()); 0300 case CurrentTarget: 0301 return getEventTarget(exec, event.currentTarget()); 0302 case EventPhase: 0303 return jsNumber((unsigned int)event.eventPhase()); 0304 case Bubbles: 0305 return jsBoolean(event.bubbles()); 0306 case Cancelable: 0307 return jsBoolean(event.cancelable()); 0308 case TimeStamp: 0309 return jsNumber((long unsigned int)event.timeStamp()); // ### long long ? 0310 case ReturnValue: // MSIE extension 0311 // return false == cancel, so this returns the -opposite- of defaultPrevented 0312 return jsBoolean(!event.defaultPrevented()); 0313 case CancelBubble: // MSIE extension 0314 return jsBoolean(event.propagationStopped()); 0315 default: 0316 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token; 0317 return nullptr; 0318 } 0319 } 0320 0321 JSValue *DOMEvent::defaultValue(ExecState *exec, KJS::JSType hint) const 0322 { 0323 if (m_impl->id() == EventImpl::ERROR_EVENT && !m_impl->message().isNull()) { 0324 return jsString(m_impl->message()); 0325 } else { 0326 return DOMObject::defaultValue(exec, hint); 0327 } 0328 } 0329 0330 void DOMEvent::put(ExecState *exec, const Identifier &propertyName, 0331 JSValue *value, int attr) 0332 { 0333 lookupPut<DOMEvent, DOMObject>(exec, propertyName, value, attr, 0334 &DOMEventTable, this); 0335 } 0336 0337 void DOMEvent::putValueProperty(ExecState *exec, int token, JSValue *value, int) 0338 { 0339 switch (token) { 0340 case ReturnValue: // MSIE equivalent for "preventDefault" (but with a way to reset it) 0341 // returnValue=false means "default action of the event on the source object is canceled", 0342 // which means preventDefault(true). Hence the '!'. 0343 m_impl->preventDefault(!value->toBoolean(exec)); 0344 break; 0345 case CancelBubble: // MSIE equivalent for "stopPropagation" (but with a way to reset it) 0346 m_impl->stopPropagation(value->toBoolean(exec)); 0347 break; 0348 default: 0349 break; 0350 } 0351 } 0352 0353 JSValue *DOMEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0354 { 0355 KJS_CHECK_THIS(KJS::DOMEvent, thisObj); 0356 DOM::EventImpl &event = *static_cast<DOMEvent *>(thisObj)->impl(); 0357 switch (id) { 0358 case DOMEvent::StopPropagation: 0359 event.stopPropagation(true); 0360 return jsUndefined(); 0361 case DOMEvent::PreventDefault: 0362 event.preventDefault(true); 0363 return jsUndefined(); 0364 case DOMEvent::InitEvent: 0365 event.initEvent(args[0]->toString(exec).domString(), args[1]->toBoolean(exec), args[2]->toBoolean(exec)); 0366 return jsUndefined(); 0367 }; 0368 return jsUndefined(); 0369 } 0370 0371 JSValue *KJS::getDOMEvent(ExecState *exec, DOM::EventImpl *ei) 0372 { 0373 if (!ei) { 0374 return jsNull(); 0375 } 0376 ScriptInterpreter *interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter()); 0377 DOMObject *ret = interp->getDOMObject(ei); 0378 if (!ret) { 0379 if (ei->isTextInputEvent()) { 0380 ret = new DOMTextEvent(exec, static_cast<DOM::TextEventImpl *>(ei)); 0381 } else if (ei->isKeyboardEvent()) { 0382 ret = new DOMKeyboardEvent(exec, static_cast<DOM::KeyboardEventImpl *>(ei)); 0383 } else if (ei->isMouseEvent()) { 0384 ret = new DOMMouseEvent(exec, static_cast<DOM::MouseEventImpl *>(ei)); 0385 } else if (ei->isUIEvent()) { 0386 ret = new DOMUIEvent(exec, static_cast<DOM::UIEventImpl *>(ei)); 0387 } else if (ei->isMutationEvent()) { 0388 ret = new DOMMutationEvent(exec, static_cast<DOM::MutationEventImpl *>(ei)); 0389 } else if (ei->isMessageEvent()) { 0390 ret = new DOMMessageEvent(exec, static_cast<DOM::MessageEventImpl *>(ei)); 0391 } else if (ei->isHashChangeEvent()) { 0392 ret = new DOMHashChangeEvent(exec, static_cast<DOM::HashChangeEventImpl *>(ei)); 0393 } else { 0394 ret = new DOMEvent(exec, ei); 0395 } 0396 0397 interp->putDOMObject(ei, ret); 0398 } 0399 0400 return ret; 0401 } 0402 0403 DOM::EventImpl *KJS::toEvent(JSValue *val) 0404 { 0405 JSObject *obj = val->getObject(); 0406 if (!obj || !obj->inherits(&DOMEvent::info)) { 0407 return nullptr; 0408 } 0409 0410 const DOMEvent *dobj = static_cast<const DOMEvent *>(obj); 0411 return dobj->impl(); 0412 } 0413 0414 // ------------------------------------------------------------------------- 0415 /* 0416 @begin EventConstantsTable 23 0417 CAPTURING_PHASE DOM::Event::CAPTURING_PHASE DontDelete|ReadOnly 0418 AT_TARGET DOM::Event::AT_TARGET DontDelete|ReadOnly 0419 BUBBLING_PHASE DOM::Event::BUBBLING_PHASE DontDelete|ReadOnly 0420 # Reverse-engineered from Netscape 0421 MOUSEDOWN 1 DontDelete|ReadOnly 0422 MOUSEUP 2 DontDelete|ReadOnly 0423 MOUSEOVER 4 DontDelete|ReadOnly 0424 MOUSEOUT 8 DontDelete|ReadOnly 0425 MOUSEMOVE 16 DontDelete|ReadOnly 0426 MOUSEDRAG 32 DontDelete|ReadOnly 0427 CLICK 64 DontDelete|ReadOnly 0428 DBLCLICK 128 DontDelete|ReadOnly 0429 KEYDOWN 256 DontDelete|ReadOnly 0430 KEYUP 512 DontDelete|ReadOnly 0431 KEYPRESS 1024 DontDelete|ReadOnly 0432 DRAGDROP 2048 DontDelete|ReadOnly 0433 FOCUS 4096 DontDelete|ReadOnly 0434 BLUR 8192 DontDelete|ReadOnly 0435 SELECT 16384 DontDelete|ReadOnly 0436 CHANGE 32768 DontDelete|ReadOnly 0437 @end 0438 */ 0439 DEFINE_CONSTANT_TABLE(EventConstants) 0440 IMPLEMENT_CONSTANT_TABLE(EventConstants, "EventConstants") 0441 0442 IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(EventConstructor, "EventConstructor", DOMEventProto, EventConstants) 0443 // ------------------------------------------------------------------------- 0444 0445 const ClassInfo EventExceptionConstructor::info = { "EventExceptionConstructor", nullptr, &EventExceptionConstructorTable, nullptr }; 0446 /* 0447 @begin EventExceptionConstructorTable 1 0448 UNSPECIFIED_EVENT_TYPE_ERR DOM::EventException::UNSPECIFIED_EVENT_TYPE_ERR DontDelete|ReadOnly 0449 @end 0450 */ 0451 EventExceptionConstructor::EventExceptionConstructor(ExecState *exec) 0452 : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype()) 0453 { 0454 } 0455 0456 bool EventExceptionConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0457 { 0458 return getStaticValueSlot<EventExceptionConstructor, DOMObject>(exec, &EventExceptionConstructorTable, this, propertyName, slot); 0459 } 0460 0461 JSValue *EventExceptionConstructor::getValueProperty(ExecState *, int token) const 0462 { 0463 // We use the token as the value to return directly 0464 return jsNumber(token); 0465 } 0466 0467 JSValue *KJS::getEventExceptionConstructor(ExecState *exec) 0468 { 0469 return cacheGlobalObject<EventExceptionConstructor>(exec, "[[eventException.constructor]]"); 0470 } 0471 0472 // ------------------------------------------------------------------------- 0473 0474 const ClassInfo DOMUIEvent::info = { "UIEvent", &DOMEvent::info, &DOMUIEventTable, nullptr }; 0475 /* 0476 @begin DOMUIEventTable 7 0477 view DOMUIEvent::View DontDelete|ReadOnly 0478 detail DOMUIEvent::Detail DontDelete|ReadOnly 0479 keyCode DOMUIEvent::KeyCode DontDelete|ReadOnly 0480 charCode DOMUIEvent::CharCode DontDelete|ReadOnly 0481 layerX DOMUIEvent::LayerX DontDelete|ReadOnly 0482 layerY DOMUIEvent::LayerY DontDelete|ReadOnly 0483 pageX DOMUIEvent::PageX DontDelete|ReadOnly 0484 pageY DOMUIEvent::PageY DontDelete|ReadOnly 0485 which DOMUIEvent::Which DontDelete|ReadOnly 0486 @end 0487 @begin DOMUIEventProtoTable 1 0488 initUIEvent DOMUIEvent::InitUIEvent DontDelete|Function 5 0489 @end 0490 */ 0491 KJS_DEFINE_PROTOTYPE(DOMUIEventProto) 0492 KJS_IMPLEMENT_PROTOFUNC(DOMUIEventProtoFunc) 0493 KJS_IMPLEMENT_PROTOTYPE("DOMUIEvent", DOMUIEventProto, DOMUIEventProtoFunc, DOMEventProto) 0494 0495 DOMUIEvent::DOMUIEvent(ExecState *exec, DOM::UIEventImpl *ue) : 0496 DOMEvent(DOMUIEventProto::self(exec), ue) {} 0497 0498 DOMUIEvent::DOMUIEvent(JSObject *proto, DOM::UIEventImpl *ue) : 0499 DOMEvent(proto, ue) {} 0500 0501 DOMUIEvent::~DOMUIEvent() 0502 { 0503 } 0504 0505 bool DOMUIEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0506 { 0507 return getStaticValueSlot<DOMUIEvent, DOMEvent>(exec, &DOMUIEventTable, this, propertyName, slot); 0508 } 0509 0510 JSValue *DOMUIEvent::getValueProperty(ExecState *exec, int token) const 0511 { 0512 DOM::UIEventImpl &event = *impl(); 0513 switch (token) { 0514 case View: 0515 return getDOMAbstractView(exec, event.view()); 0516 case Detail: 0517 return jsNumber(event.detail()); 0518 case KeyCode: 0519 // IE-compatibility 0520 return jsNumber(event.keyCode()); 0521 case CharCode: 0522 // IE-compatibility 0523 return jsNumber(event.charCode()); 0524 case LayerX: 0525 // NS-compatibility 0526 return jsNumber(event.layerX()); 0527 case LayerY: 0528 // NS-compatibility 0529 return jsNumber(event.layerY()); 0530 case PageX: 0531 // NS-compatibility 0532 return jsNumber(event.pageX()); 0533 case PageY: 0534 // NS-compatibility 0535 return jsNumber(event.pageY()); 0536 case Which: 0537 // NS-compatibility 0538 return jsNumber(event.which()); 0539 default: 0540 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMUIEvent::getValueProperty : " << token; 0541 return jsUndefined(); 0542 } 0543 } 0544 0545 JSValue *DOMUIEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0546 { 0547 KJS_CHECK_THIS(KJS::DOMUIEvent, thisObj); 0548 DOM::UIEventImpl &uiEvent = *static_cast<DOMUIEvent *>(thisObj)->impl(); 0549 switch (id) { 0550 case DOMUIEvent::InitUIEvent: { 0551 DOM::AbstractViewImpl *v = toAbstractView(args[3]); 0552 uiEvent.initUIEvent(args[0]->toString(exec).domString(), 0553 args[1]->toBoolean(exec), 0554 args[2]->toBoolean(exec), 0555 v, 0556 args[4]->toInteger(exec)); 0557 } 0558 return jsUndefined(); 0559 } 0560 return jsUndefined(); 0561 } 0562 0563 // ------------------------------------------------------------------------- 0564 0565 const ClassInfo DOMMouseEvent::info = { "MouseEvent", &DOMUIEvent::info, &DOMMouseEventTable, nullptr }; 0566 0567 /* 0568 @begin DOMMouseEventTable 2 0569 screenX DOMMouseEvent::ScreenX DontDelete|ReadOnly 0570 screenY DOMMouseEvent::ScreenY DontDelete|ReadOnly 0571 clientX DOMMouseEvent::ClientX DontDelete|ReadOnly 0572 x DOMMouseEvent::X DontDelete|ReadOnly 0573 clientY DOMMouseEvent::ClientY DontDelete|ReadOnly 0574 y DOMMouseEvent::Y DontDelete|ReadOnly 0575 offsetX DOMMouseEvent::OffsetX DontDelete|ReadOnly 0576 offsetY DOMMouseEvent::OffsetY DontDelete|ReadOnly 0577 ctrlKey DOMMouseEvent::CtrlKey DontDelete|ReadOnly 0578 shiftKey DOMMouseEvent::ShiftKey DontDelete|ReadOnly 0579 altKey DOMMouseEvent::AltKey DontDelete|ReadOnly 0580 metaKey DOMMouseEvent::MetaKey DontDelete|ReadOnly 0581 button DOMMouseEvent::Button DontDelete|ReadOnly 0582 relatedTarget DOMMouseEvent::RelatedTarget DontDelete|ReadOnly 0583 fromElement DOMMouseEvent::FromElement DontDelete|ReadOnly 0584 toElement DOMMouseEvent::ToElement DontDelete|ReadOnly 0585 @end 0586 @begin DOMMouseEventProtoTable 1 0587 initMouseEvent DOMMouseEvent::InitMouseEvent DontDelete|Function 15 0588 @end 0589 */ 0590 KJS_DEFINE_PROTOTYPE(DOMMouseEventProto) 0591 KJS_IMPLEMENT_PROTOFUNC(DOMMouseEventProtoFunc) 0592 KJS_IMPLEMENT_PROTOTYPE("DOMMouseEvent", DOMMouseEventProto, DOMMouseEventProtoFunc, DOMUIEventProto) 0593 0594 DOMMouseEvent::DOMMouseEvent(ExecState *exec, DOM::MouseEventImpl *me) : 0595 DOMUIEvent(DOMMouseEventProto::self(exec), me) {} 0596 0597 DOMMouseEvent::~DOMMouseEvent() 0598 { 0599 } 0600 0601 bool DOMMouseEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0602 { 0603 #ifdef KJS_VERBOSE 0604 qCDebug(KHTML_LOG) << "DOMMouseEvent::getOwnPropertySlot " << propertyName.qstring(); 0605 #endif 0606 0607 return getStaticValueSlot<DOMMouseEvent, DOMUIEvent>(exec, &DOMMouseEventTable, this, propertyName, slot); 0608 } 0609 0610 JSValue *DOMMouseEvent::getValueProperty(ExecState *exec, int token) const 0611 { 0612 DOM::MouseEventImpl &event = *impl(); 0613 switch (token) { 0614 case ScreenX: 0615 return jsNumber(event.screenX()); 0616 case ScreenY: 0617 return jsNumber(event.screenY()); 0618 case ClientX: 0619 case X: 0620 return jsNumber(event.clientX()); 0621 case ClientY: 0622 case Y: 0623 return jsNumber(event.clientY()); 0624 case OffsetX: 0625 case OffsetY: { // MSIE extension 0626 if (event.target()->eventTargetType() != EventTargetImpl::DOM_NODE) { 0627 return jsUndefined(); 0628 } 0629 0630 DOM::Node node = static_cast<NodeImpl *>(event.target()); 0631 khtml::RenderObject *rend = nullptr; 0632 if (node.handle()) { 0633 node.handle()->document()->updateRendering(); 0634 rend = node.handle()->renderer(); 0635 } 0636 int x = event.clientX(); 0637 int y = event.clientY(); 0638 if (rend) { 0639 int xPos, yPos; 0640 if (rend->absolutePosition(xPos, yPos)) { 0641 //qCDebug(KHTML_LOG) << "DOMMouseEvent::getValueProperty rend=" << rend << " xPos=" << xPos << " yPos=" << yPos; 0642 x -= xPos; 0643 y -= yPos; 0644 } 0645 if (rend->canvas()) { 0646 int cYPos, cXPos; 0647 rend->canvas()->absolutePosition(cXPos, cYPos, true); 0648 x += cXPos; 0649 y += cYPos; 0650 } 0651 } 0652 return jsNumber(token == OffsetX ? x : y); 0653 } 0654 case CtrlKey: 0655 return jsBoolean(event.ctrlKey()); 0656 case ShiftKey: 0657 return jsBoolean(event.shiftKey()); 0658 case AltKey: 0659 return jsBoolean(event.altKey()); 0660 case MetaKey: 0661 return jsBoolean(event.metaKey()); 0662 case Button: { 0663 if (exec->dynamicInterpreter()->compatMode() == Interpreter::IECompat) { 0664 // Tricky. The DOM (and khtml) use 0 for LMB, 1 for MMB and 2 for RMB 0665 // but MSIE uses 1=LMB, 2=RMB, 4=MMB, as a bitfield 0666 int domButton = event.button(); 0667 int button = domButton == 0 ? 1 : domButton == 1 ? 4 : domButton == 2 ? 2 : 0; 0668 return jsNumber((unsigned int)button); 0669 } 0670 return jsNumber(event.button()); 0671 } 0672 case ToElement: 0673 // MSIE extension - "the object toward which the user is moving the mouse pointer" 0674 if (event.id() == DOM::EventImpl::MOUSEOUT_EVENT) { 0675 return getEventTarget(exec, event.relatedTarget()); 0676 } 0677 return getEventTarget(exec, event.target()); 0678 case FromElement: 0679 // MSIE extension - "object from which activation 0680 // or the mouse pointer is exiting during the event" (huh?) 0681 if (event.id() == DOM::EventImpl::MOUSEOUT_EVENT) { 0682 return getEventTarget(exec, event.target()); 0683 } 0684 /* fall through */ 0685 case RelatedTarget: 0686 return getEventTarget(exec, event.relatedTarget()); 0687 default: 0688 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMMouseEvent::getValueProperty : " << token; 0689 return nullptr; 0690 } 0691 } 0692 0693 JSValue *DOMMouseEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0694 { 0695 KJS_CHECK_THIS(KJS::DOMMouseEvent, thisObj); 0696 DOM::MouseEventImpl &mouseEvent = *static_cast<DOMMouseEvent *>(thisObj)->impl(); 0697 switch (id) { 0698 case DOMMouseEvent::InitMouseEvent: 0699 mouseEvent.initMouseEvent(args[0]->toString(exec).domString(), // typeArg 0700 args[1]->toBoolean(exec), // canBubbleArg 0701 args[2]->toBoolean(exec), // cancelableArg 0702 toAbstractView(args[3]), // viewArg 0703 args[4]->toInteger(exec), // detailArg 0704 args[5]->toInteger(exec), // screenXArg 0705 args[6]->toInteger(exec), // screenYArg 0706 args[7]->toInteger(exec), // clientXArg 0707 args[8]->toInteger(exec), // clientYArg 0708 args[9]->toBoolean(exec), // ctrlKeyArg 0709 args[10]->toBoolean(exec), // altKeyArg 0710 args[11]->toBoolean(exec), // shiftKeyArg 0711 args[12]->toBoolean(exec), // metaKeyArg 0712 args[13]->toInteger(exec), // buttonArg 0713 toNode(args[14])); // relatedTargetArg 0714 return jsUndefined(); 0715 } 0716 return jsUndefined(); 0717 } 0718 0719 // ------------------------------------------------------------------------- 0720 0721 const ClassInfo DOMKeyEventBase::info = { "KeyEventBase", &DOMUIEvent::info, &DOMKeyEventBaseTable, nullptr }; 0722 0723 /* 0724 @begin DOMKeyEventBaseTable 5 0725 keyVal DOMKeyEventBase::Key DontDelete|ReadOnly 0726 virtKeyVal DOMKeyEventBase::VirtKey DontDelete|ReadOnly 0727 ctrlKey DOMKeyEventBase::CtrlKey DontDelete|ReadOnly 0728 altKey DOMKeyEventBase::AltKey DontDelete|ReadOnly 0729 shiftKey DOMKeyEventBase::ShiftKey DontDelete|ReadOnly 0730 metaKey DOMKeyEventBase::MetaKey DontDelete|ReadOnly 0731 @end 0732 */ 0733 0734 DOMKeyEventBase::DOMKeyEventBase(JSObject *proto, DOM::KeyEventBaseImpl *ke) : 0735 DOMUIEvent(proto, ke) {} 0736 0737 DOMKeyEventBase::~DOMKeyEventBase() 0738 {} 0739 0740 bool DOMKeyEventBase::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0741 { 0742 #ifdef KJS_VERBOSE 0743 qCDebug(KHTML_LOG) << "DOMKeyEventBase::getOwnPropertySlot " << propertyName.qstring(); 0744 #endif 0745 return getStaticValueSlot<DOMKeyEventBase, DOMUIEvent>(exec, &DOMKeyEventBaseTable, this, propertyName, slot); 0746 } 0747 0748 JSValue *DOMKeyEventBase::getValueProperty(ExecState *, int token) const 0749 { 0750 DOM::KeyEventBaseImpl *tevent = impl(); 0751 switch (token) { 0752 case Key: 0753 return jsNumber(tevent->keyVal()); 0754 case VirtKey: 0755 return jsNumber(tevent->virtKeyVal()); 0756 // these modifier attributes actually belong into a KeyboardEvent interface, 0757 // but we want them on "keypress" as well. 0758 case CtrlKey: 0759 return jsBoolean(tevent->ctrlKey()); 0760 case ShiftKey: 0761 return jsBoolean(tevent->shiftKey()); 0762 case AltKey: 0763 return jsBoolean(tevent->altKey()); 0764 case MetaKey: 0765 return jsBoolean(tevent->metaKey()); 0766 default: 0767 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMKeyEventBase::getValueProperty : " << token; 0768 return jsUndefined(); 0769 } 0770 } 0771 0772 // ------------------------------------------------------------------------- 0773 const ClassInfo DOMTextEvent::info = { "TextEvent", &DOMKeyEventBase::info, &DOMTextEventTable, nullptr }; 0774 0775 /* 0776 @begin DOMTextEventTable 1 0777 data DOMTextEvent::Data DontDelete|ReadOnly 0778 @end 0779 @begin DOMTextEventProtoTable 1 0780 initTextEvent DOMTextEvent::InitTextEvent DontDelete|Function 5 0781 # Missing: initTextEventNS 0782 @end 0783 */ 0784 KJS_DEFINE_PROTOTYPE(DOMTextEventProto) 0785 KJS_IMPLEMENT_PROTOFUNC(DOMTextEventProtoFunc) 0786 KJS_IMPLEMENT_PROTOTYPE("DOMTextEvent", DOMTextEventProto, DOMTextEventProtoFunc, DOMUIEventProto) //Note: no proto in KeyBase 0787 0788 DOMTextEvent::DOMTextEvent(ExecState *exec, DOM::TextEventImpl *ke) : 0789 DOMKeyEventBase(DOMTextEventProto::self(exec), ke) {} 0790 0791 DOMTextEvent::~DOMTextEvent() 0792 { 0793 } 0794 0795 bool DOMTextEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0796 { 0797 #ifdef KJS_VERBOSE 0798 qCDebug(KHTML_LOG) << "DOMTextEvent::getOwnPropertySlot " << propertyName.qstring(); 0799 #endif 0800 return getStaticValueSlot<DOMTextEvent, DOMKeyEventBase>(exec, &DOMTextEventTable, this, propertyName, slot); 0801 } 0802 0803 JSValue *DOMTextEvent::getValueProperty(ExecState *, int token) const 0804 { 0805 DOM::TextEventImpl &tevent = *impl(); 0806 switch (token) { 0807 case Data: 0808 return jsString(tevent.data()); 0809 default: 0810 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token; 0811 return jsUndefined(); 0812 } 0813 } 0814 0815 JSValue *DOMTextEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0816 { 0817 KJS_CHECK_THIS(KJS::DOMTextEvent, thisObj); 0818 DOM::TextEventImpl &keyEvent = *static_cast<DOMTextEvent *>(thisObj)->impl(); 0819 switch (id) { 0820 case DOMTextEvent::InitTextEvent: 0821 0822 keyEvent.initTextEvent(args[0]->toString(exec).domString(), // typeArg 0823 args[1]->toBoolean(exec), // canBubbleArg 0824 args[2]->toBoolean(exec), // cancelableArg 0825 toAbstractView(args[3]), // viewArg 0826 args[4]->toString(exec).domString()); // dataArg 0827 return jsUndefined(); 0828 } 0829 return jsUndefined(); 0830 } 0831 // ------------------------------------------------------------------------- 0832 const ClassInfo DOMKeyboardEvent::info = { "KeyboardEvent", &DOMKeyEventBase::info, &DOMKeyboardEventTable, nullptr }; 0833 0834 /* 0835 @begin DOMKeyboardEventTable 2 0836 keyIdentifier DOMKeyboardEvent::KeyIdentifier DontDelete|ReadOnly 0837 keyLocation DOMKeyboardEvent::KeyLocation DontDelete|ReadOnly 0838 @end 0839 @begin DOMKeyboardEventProtoTable 2 0840 initKeyboardEvent DOMKeyboardEvent::InitKeyboardEvent DontDelete|Function 7 0841 getModifierState DOMKeyboardEvent::GetModifierState DontDelete|Function 1 0842 @end 0843 */ 0844 KJS_DEFINE_PROTOTYPE(DOMKeyboardEventProto) 0845 KJS_IMPLEMENT_PROTOFUNC(DOMKeyboardEventProtoFunc) 0846 KJS_IMPLEMENT_PROTOTYPE("DOMKeyboardEvent", DOMKeyboardEventProto, DOMKeyboardEventProtoFunc, DOMUIEventProto) //Note: no proto in KeyBase 0847 0848 DOMKeyboardEvent::DOMKeyboardEvent(ExecState *exec, DOM::KeyboardEventImpl *ke) : 0849 DOMKeyEventBase(DOMKeyboardEventProto::self(exec), ke) {} 0850 0851 DOMKeyboardEvent::~DOMKeyboardEvent() 0852 { 0853 } 0854 0855 bool DOMKeyboardEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0856 { 0857 #ifdef KJS_VERBOSE 0858 qCDebug(KHTML_LOG) << "DOMKeyboardEvent::getOwnPropertySlot " << propertyName.qstring(); 0859 #endif 0860 return getStaticValueSlot<DOMKeyboardEvent, DOMKeyEventBase>(exec, &DOMKeyboardEventTable, this, propertyName, slot); 0861 } 0862 0863 JSValue *DOMKeyboardEvent::getValueProperty(ExecState *, int token) const 0864 { 0865 DOM::KeyboardEventImpl *tevent = impl(); 0866 switch (token) { 0867 case KeyIdentifier: 0868 return jsString(tevent->keyIdentifier()); 0869 case KeyLocation: 0870 return jsNumber(tevent->keyLocation()); 0871 default: 0872 // qCDebug(KHTML_LOG) << "WARNING: Unhandled token in DOMKeyboardEvent::getValueProperty : " << token; 0873 return jsUndefined(); 0874 } 0875 } 0876 0877 JSValue *DOMKeyboardEventProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0878 { 0879 KJS_CHECK_THIS(KJS::DOMKeyboardEvent, thisObj); 0880 DOM::KeyboardEventImpl *keyEvent = static_cast<DOMKeyboardEvent *>(thisObj)->impl(); 0881 switch (id) { 0882 case DOMKeyboardEvent::InitKeyboardEvent: 0883 keyEvent->initKeyboardEvent(args[0]->toString(exec).domString(), // typeArg 0884 args[1]->toBoolean(exec), // canBubbleArg 0885 args[2]->toBoolean(exec), // cancelableArg 0886 toAbstractView(args[3]), // viewArg 0887 args[4]->toString(exec).domString(), // keyIdentifierArg 0888 args[5]->toInteger(exec), // keyLocationArg 0889 args[6]->toString(exec).domString()); //modifiersList 0890 break; 0891 case DOMKeyboardEvent::GetModifierState: 0892 return jsBoolean(keyEvent->getModifierState(args[0]->toString(exec).domString())); 0893 } 0894 return jsUndefined(); 0895 } 0896 0897 // ------------------------------------------------------------------------- 0898 const ClassInfo KeyboardEventConstructor::info = { "KeyboardEventConstructor", nullptr, &KeyboardEventConstructorTable, nullptr }; 0899 /* 0900 @begin KeyboardEventConstructorTable 4 0901 DOM_KEY_LOCATION_STANDARD DOM::KeyboardEvent::DOM_KEY_LOCATION_STANDARD DontDelete|ReadOnly 0902 DOM_KEY_LOCATION_LEFT DOM::KeyboardEvent::DOM_KEY_LOCATION_LEFT DontDelete|ReadOnly 0903 DOM_KEY_LOCATION_RIGHT DOM::KeyboardEvent::DOM_KEY_LOCATION_RIGHT DontDelete|ReadOnly 0904 DOM_KEY_LOCATION_NUMPAD DOM::KeyboardEvent::DOM_KEY_LOCATION_NUMPAD DontDelete|ReadOnly 0905 @end 0906 */ 0907 KeyboardEventConstructor::KeyboardEventConstructor(ExecState *exec) 0908 : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype()) 0909 {} 0910 0911 bool KeyboardEventConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0912 { 0913 #ifdef KJS_VERBOSE 0914 qCDebug(KHTML_LOG) << "DOMKeyboardEvent::getOwnPropertySlot " << propertyName.qstring(); 0915 #endif 0916 return getStaticValueSlot<KeyboardEventConstructor, DOMObject>(exec, &KeyboardEventConstructorTable, this, propertyName, slot); 0917 } 0918 0919 JSValue *KeyboardEventConstructor::getValueProperty(ExecState *, int token) const 0920 { 0921 // We use the token as the value to return directly 0922 return jsNumber(token); 0923 } 0924 0925 JSValue *KJS::getKeyboardEventConstructor(ExecState *exec) 0926 { 0927 return cacheGlobalObject<KeyboardEventConstructor>(exec, "[[keyboardEvent.constructor]]"); 0928 } 0929 0930 // ------------------------------------------------------------------------- 0931 const ClassInfo MutationEventConstructor::info = { "MutationEventConstructor", nullptr, &MutationEventConstructorTable, nullptr }; 0932 /* 0933 @begin MutationEventConstructorTable 3 0934 MODIFICATION DOM::MutationEvent::MODIFICATION DontDelete|ReadOnly 0935 ADDITION DOM::MutationEvent::ADDITION DontDelete|ReadOnly 0936 REMOVAL DOM::MutationEvent::REMOVAL DontDelete|ReadOnly 0937 @end 0938 */ 0939 MutationEventConstructor::MutationEventConstructor(ExecState *exec) 0940 : DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype()) 0941 { 0942 } 0943 0944 bool MutationEventConstructor::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0945 { 0946 return getStaticValueSlot<MutationEventConstructor, DOMObject>(exec, &MutationEventConstructorTable, this, propertyName, slot); 0947 } 0948 0949 JSValue *MutationEventConstructor::getValueProperty(ExecState *, int token) const 0950 { 0951 // We use the token as the value to return directly 0952 return jsNumber(token); 0953 } 0954 0955 JSValue *KJS::getMutationEventConstructor(ExecState *exec) 0956 { 0957 return cacheGlobalObject<MutationEventConstructor>(exec, "[[mutationEvent.constructor]]"); 0958 } 0959 0960 // ------------------------------------------------------------------------- 0961 0962 const ClassInfo DOMMutationEvent::info = { "MutationEvent", &DOMEvent::info, &DOMMutationEventTable, nullptr }; 0963 /* 0964 @begin DOMMutationEventTable 5 0965 relatedNode DOMMutationEvent::RelatedNode DontDelete|ReadOnly 0966 prevValue DOMMutationEvent::PrevValue DontDelete|ReadOnly 0967 newValue DOMMutationEvent::NewValue DontDelete|ReadOnly 0968 attrName DOMMutationEvent::AttrName DontDelete|ReadOnly 0969 attrChange DOMMutationEvent::AttrChange DontDelete|ReadOnly 0970 @end 0971 @begin DOMMutationEventProtoTable 1 0972 initMutationEvent DOMMutationEvent::InitMutationEvent DontDelete|Function 8 0973 @end 0974 */ 0975 KJS_DEFINE_PROTOTYPE(DOMMutationEventProto) 0976 KJS_IMPLEMENT_PROTOFUNC(DOMMutationEventProtoFunc) 0977 KJS_IMPLEMENT_PROTOTYPE("DOMMutationEvent", DOMMutationEventProto, DOMMutationEventProtoFunc, DOMEventProto) 0978 0979 DOMMutationEvent::DOMMutationEvent(ExecState *exec, DOM::MutationEventImpl *me) : 0980 DOMEvent(DOMMutationEventProto::self(exec), me) {} 0981 0982 DOMMutationEvent::~DOMMutationEvent() 0983 { 0984 } 0985 0986 bool DOMMutationEvent::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0987 { 0988 return getStaticValueSlot<DOMMutationEvent, DOMEvent>(exec, &DOMMutationEventTable, this, propertyName, slot); 0989 } 0990 0991 JSValue *DOMMutationEvent::getValueProperty(ExecState *exec, int token) const 0992 { 0993 DOM::MutationEventImpl &event = *impl(); 0994 switch (token) { 0995 case RelatedNode: { 0996 DOM::Node relatedNode = event.relatedNode(); 0997 return getDOMNode(exec, relatedNode.handle()); 0998 } 0999 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 }