khtml Library API Documentation

kjs_events.cpp

00001 // -*- c-basic-offset: 2 -*- 00002 /* 00003 * This file is part of the KDE libraries 00004 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 00005 * Copyright (C) 2003 Apple Computer, Inc. 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Library General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Library General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Library General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 */ 00021 00022 #include "kjs_window.h" 00023 #include "kjs_events.h" 00024 #include "kjs_events.lut.h" 00025 #include "kjs_views.h" 00026 #include "kjs_proxy.h" 00027 #include "xml/dom_nodeimpl.h" 00028 #include "xml/dom_docimpl.h" 00029 #include "xml/dom2_eventsimpl.h" 00030 #include "rendering/render_object.h" 00031 #include "xml/dom2_eventsimpl.h" 00032 #include "khtml_part.h" 00033 00034 #include <kdebug.h> 00035 00036 using namespace KJS; 00037 using namespace DOM; 00038 00039 // ------------------------------------------------------------------------- 00040 00041 JSEventListener::JSEventListener(Object _listener, ObjectImp *_compareListenerImp, const Object &_win, bool _html) 00042 : listener( _listener ), compareListenerImp( _compareListenerImp ), html( _html ), win( _win ) 00043 { 00044 //fprintf(stderr,"JSEventListener::JSEventListener this=%p listener=%p\n",this,listener.imp()); 00045 if (compareListenerImp) { 00046 static_cast<Window*>(win.imp())->jsEventListeners.insert(compareListenerImp, this); 00047 } 00048 } 00049 00050 JSEventListener::~JSEventListener() 00051 { 00052 if (compareListenerImp) { 00053 static_cast<Window*>(win.imp())->jsEventListeners.remove(compareListenerImp); 00054 } 00055 //fprintf(stderr,"JSEventListener::~JSEventListener this=%p listener=%p\n",this,listener.imp()); 00056 } 00057 00058 void JSEventListener::handleEvent(DOM::Event &evt) 00059 { 00060 #ifdef KJS_DEBUGGER 00061 if (KJSDebugWin::debugWindow() && KJSDebugWin::debugWindow()->inSession()) 00062 return; 00063 #endif 00064 KHTMLPart *part = static_cast<Window*>(win.imp())->part(); 00065 KJSProxy *proxy = 0L; 00066 if (part) 00067 proxy = part->jScript(); 00068 00069 if (proxy && listener.implementsCall()) { 00070 ref(); 00071 00072 KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); 00073 ExecState *exec = interpreter->globalExec(); 00074 00075 List args; 00076 args.append(getDOMEvent(exec,evt)); 00077 00078 // Set "this" to the event's current target 00079 Object thisObj = Object::dynamicCast(getDOMNode(exec,evt.currentTarget())); 00080 ScopeChain oldScope = listener.scope(); 00081 if ( thisObj.isValid() ) { 00082 ScopeChain scope = oldScope; 00083 // Add the event's target element to the scope 00084 // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope) 00085 static_cast<DOMNode*>(thisObj.imp())->pushEventHandlerScope(exec, scope); 00086 listener.setScope( scope ); 00087 } 00088 else { 00089 if ( m_hackThisObj.isValid() ) { // special hack for Image 00090 thisObj = m_hackThisObj; 00091 } 00092 else 00093 { 00094 // Window events (window.onload/window.onresize etc.) must have 'this' set to the window. 00095 // DocumentImpl::defaultEventHandler sets currentTarget to 0 to mean 'window'. 00096 thisObj = win; 00097 } 00098 } 00099 00100 Window *window = static_cast<Window*>(win.imp()); 00101 // Set the event we're handling in the Window object 00102 window->setCurrentEvent( &evt ); 00103 // ... and in the interpreter 00104 interpreter->setCurrentEvent( &evt ); 00105 00106 KJSCPUGuard guard; 00107 guard.start(); 00108 Value retval = listener.call(exec, thisObj, args); 00109 guard.stop(); 00110 00111 listener.setScope( oldScope ); 00112 00113 window->setCurrentEvent( 0 ); 00114 interpreter->setCurrentEvent( 0 ); 00115 if ( exec->hadException() ) 00116 exec->clearException(); 00117 else if (html) 00118 { 00119 QVariant ret = ValueToVariant(exec, retval); 00120 if (ret.type() == QVariant::Bool && ret.toBool() == false) 00121 evt.preventDefault(); 00122 } 00123 window->afterScriptExecution(); 00124 deref(); 00125 } 00126 } 00127 00128 DOM::DOMString JSEventListener::eventListenerType() 00129 { 00130 if (html) 00131 return "_khtml_HTMLEventListener"; 00132 else 00133 return "_khtml_JSEventListener"; 00134 } 00135 00136 Object JSEventListener::listenerObj() const 00137 { 00138 return listener; 00139 } 00140 00141 JSLazyEventListener::JSLazyEventListener(const QString &_code, const QString &_name, const Object &_win, bool _html) 00142 : JSEventListener(Object(), 0, _win, _html), 00143 code(_code), name(_name), 00144 parsed(false) 00145 { 00146 } 00147 00148 JSLazyEventListener::~JSLazyEventListener() 00149 { 00150 if (!listener.isNull() && listener.imp()) { 00151 static_cast<Window*>(win.imp())->jsEventListeners.remove(listener.imp()); 00152 } 00153 } 00154 00155 void JSLazyEventListener::handleEvent(DOM::Event &evt) 00156 { 00157 parseCode(); 00158 if (!listener.isNull()) { 00159 JSEventListener::handleEvent(evt); 00160 } 00161 } 00162 00163 00164 Object JSLazyEventListener::listenerObj() const 00165 { 00166 parseCode(); 00167 return listener; 00168 } 00169 00170 void JSLazyEventListener::parseCode() const 00171 { 00172 if (!parsed) { 00173 KHTMLPart *part = static_cast<Window*>(win.imp())->part(); 00174 KJSProxy *proxy = 0L; 00175 if (part) 00176 proxy = part->jScript(); 00177 00178 if (proxy) { 00179 KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); 00180 ExecState *exec = interpreter->globalExec(); 00181 00182 //KJS::Constructor constr(KJS::Global::current().get("Function").imp()); 00183 KJS::Object constr = interpreter->builtinFunction(); 00184 KJS::List args; 00185 00186 static KJS::String eventString("event"); 00187 00188 args.append(eventString); 00189 args.append(KJS::String(code)); 00190 listener = constr.construct(exec, args); // ### is globalExec ok ? 00191 00192 if ( exec->hadException() ) { 00193 exec->clearException(); 00194 00195 // failed to parse, so let's just make this listener a no-op 00196 listener = Object(); 00197 } else if (!listener.inherits(&DeclaredFunctionImp::info)) { 00198 listener = Object();// Error creating function 00199 } else { 00200 DeclaredFunctionImp *declFunc = static_cast<DeclaredFunctionImp*>(listener.imp()); 00201 declFunc->setName(Identifier(name)); 00202 } 00203 } 00204 00205 // no more need to keep the unparsed code around 00206 code = QString(); 00207 00208 if (!listener.isNull() && listener.imp()) { 00209 static_cast<Window*>(win.imp())->jsEventListeners.insert(listener.imp(), 00210 (KJS::JSEventListener *)(this)); 00211 } 00212 00213 parsed = true; 00214 } 00215 } 00216 00217 // ------------------------------------------------------------------------- 00218 00219 const ClassInfo EventConstructor::info = { "EventConstructor", 0, &EventConstructorTable, 0 }; 00220 /* 00221 @begin EventConstructorTable 3 00222 CAPTURING_PHASE DOM::Event::CAPTURING_PHASE DontDelete|ReadOnly 00223 AT_TARGET DOM::Event::AT_TARGET DontDelete|ReadOnly 00224 BUBBLING_PHASE DOM::Event::BUBBLING_PHASE DontDelete|ReadOnly 00225 # Reverse-engineered from Netscape 00226 MOUSEDOWN 1 DontDelete|ReadOnly 00227 MOUSEUP 2 DontDelete|ReadOnly 00228 MOUSEOVER 4 DontDelete|ReadOnly 00229 MOUSEOUT 8 DontDelete|ReadOnly 00230 MOUSEMOVE 16 DontDelete|ReadOnly 00231 MOUSEDRAG 32 DontDelete|ReadOnly 00232 CLICK 64 DontDelete|ReadOnly 00233 DBLCLICK 128 DontDelete|ReadOnly 00234 KEYDOWN 256 DontDelete|ReadOnly 00235 KEYUP 512 DontDelete|ReadOnly 00236 KEYPRESS 1024 DontDelete|ReadOnly 00237 DRAGDROP 2048 DontDelete|ReadOnly 00238 FOCUS 4096 DontDelete|ReadOnly 00239 BLUR 8192 DontDelete|ReadOnly 00240 SELECT 16384 DontDelete|ReadOnly 00241 CHANGE 32768 DontDelete|ReadOnly 00242 @end 00243 */ 00244 00245 EventConstructor::EventConstructor(ExecState *exec) 00246 : DOMObject(exec->interpreter()->builtinObjectPrototype()) 00247 { 00248 } 00249 00250 Value EventConstructor::tryGet(ExecState *exec, const Identifier &p) const 00251 { 00252 return DOMObjectLookupGetValue<EventConstructor, DOMObject>(exec,p,&EventConstructorTable,this); 00253 } 00254 00255 Value EventConstructor::getValueProperty(ExecState *, int token) const 00256 { 00257 // We use the token as the value to return directly 00258 return Number(token); 00259 } 00260 00261 Value KJS::getEventConstructor(ExecState *exec) 00262 { 00263 return cacheGlobalObject<EventConstructor>(exec, "[[event.constructor]]"); 00264 } 00265 00266 // ------------------------------------------------------------------------- 00267 00268 const ClassInfo DOMEvent::info = { "Event", 0, &DOMEventTable, 0 }; 00269 /* 00270 @begin DOMEventTable 7 00271 type DOMEvent::Type DontDelete|ReadOnly 00272 target DOMEvent::Target DontDelete|ReadOnly 00273 currentTarget DOMEvent::CurrentTarget DontDelete|ReadOnly 00274 srcElement DOMEvent::SrcElement DontDelete|ReadOnly 00275 eventPhase DOMEvent::EventPhase DontDelete|ReadOnly 00276 bubbles DOMEvent::Bubbles DontDelete|ReadOnly 00277 cancelable DOMEvent::Cancelable DontDelete|ReadOnly 00278 timeStamp DOMEvent::TimeStamp DontDelete|ReadOnly 00279 returnValue DOMEvent::ReturnValue DontDelete 00280 cancelBubble DOMEvent::CancelBubble DontDelete 00281 @end 00282 @begin DOMEventProtoTable 3 00283 stopPropagation DOMEvent::StopPropagation DontDelete|Function 0 00284 preventDefault DOMEvent::PreventDefault DontDelete|Function 0 00285 initEvent DOMEvent::InitEvent DontDelete|Function 3 00286 @end 00287 */ 00288 DEFINE_PROTOTYPE("DOMEvent", DOMEventProto) 00289 IMPLEMENT_PROTOFUNC_DOM(DOMEventProtoFunc) 00290 IMPLEMENT_PROTOTYPE(DOMEventProto, DOMEventProtoFunc) 00291 00292 DOMEvent::DOMEvent(ExecState *exec, DOM::Event e) 00293 : DOMObject(DOMEventProto::self(exec)), event(e) { } 00294 00295 DOMEvent::DOMEvent(const Object &proto, DOM::Event e) 00296 : DOMObject(proto), event(e) { } 00297 00298 DOMEvent::~DOMEvent() 00299 { 00300 ScriptInterpreter::forgetDOMObject(event.handle()); 00301 } 00302 00303 Value DOMEvent::tryGet(ExecState *exec, const Identifier &p) const 00304 { 00305 #ifdef KJS_VERBOSE 00306 kdDebug() << "KJS::DOMEvent::tryGet " << p.qstring() << endl; 00307 #endif 00308 return DOMObjectLookupGetValue<DOMEvent,DOMObject>(exec, p, &DOMEventTable, this ); 00309 } 00310 00311 Value DOMEvent::getValueProperty(ExecState *exec, int token) const 00312 { 00313 switch (token) { 00314 case Type: 00315 return String(event.type()); 00316 case Target: 00317 case SrcElement: /*MSIE extension - "the object that fired the event"*/ 00318 return getDOMNode(exec,event.target()); 00319 case CurrentTarget: 00320 return getDOMNode(exec,event.currentTarget()); 00321 case EventPhase: 00322 return Number((unsigned int)event.eventPhase()); 00323 case Bubbles: 00324 return Boolean(event.bubbles()); 00325 case Cancelable: 00326 return Boolean(event.cancelable()); 00327 case TimeStamp: 00328 return Number((long unsigned int)event.timeStamp()); // ### long long ? 00329 case ReturnValue: // MSIE extension 00330 return Boolean(event.handle()->defaultPrevented()); 00331 case CancelBubble: // MSIE extension 00332 return Boolean(event.handle()->propagationStopped()); 00333 default: 00334 kdDebug(6070) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token << endl; 00335 return Value(); 00336 } 00337 } 00338 00339 Value DOMEvent::defaultValue(ExecState *exec, KJS::Type hint) const 00340 { 00341 if (event.handle()->id() == EventImpl::ERROR_EVENT && !event.handle()->message().isNull()) { 00342 return String(event.handle()->message()); 00343 } 00344 else 00345 return DOMObject::defaultValue(exec,hint); 00346 } 00347 00348 void DOMEvent::tryPut(ExecState *exec, const Identifier &propertyName, 00349 const Value& value, int attr) 00350 { 00351 DOMObjectLookupPut<DOMEvent, DOMObject>(exec, propertyName, value, attr, 00352 &DOMEventTable, this); 00353 } 00354 00355 void DOMEvent::putValueProperty(ExecState *exec, int token, const Value& value, int) 00356 { 00357 switch (token) { 00358 case ReturnValue: // MSIE equivalent for "preventDefault" (but with a way to reset it) 00359 // returnValue=false means "default action of the event on the source object is canceled", 00360 // which means preventDefault(true). Hence the '!'. 00361 event.handle()->preventDefault(!value.toBoolean(exec)); 00362 break; 00363 case CancelBubble: // MSIE equivalent for "stopPropagation" (but with a way to reset it) 00364 event.handle()->stopPropagation(value.toBoolean(exec)); 00365 break; 00366 default: 00367 break; 00368 } 00369 } 00370 00371 Value DOMEventProtoFunc::tryCall(ExecState *exec, Object & thisObj, const List &args) 00372 { 00373 KJS_CHECK_THIS( KJS::DOMEvent, thisObj ); 00374 DOM::Event event = static_cast<DOMEvent *>( thisObj.imp() )->toEvent(); 00375 switch (id) { 00376 case DOMEvent::StopPropagation: 00377 event.stopPropagation(); 00378 return Undefined(); 00379 case DOMEvent::PreventDefault: 00380 event.preventDefault(); 00381 return Undefined(); 00382 case DOMEvent::InitEvent: 00383 event.initEvent(args[0].toString(exec).string(),args[1].toBoolean(exec),args[2].toBoolean(exec)); 00384 return Undefined(); 00385 }; 00386 return Undefined(); 00387 } 00388 00389 Value KJS::getDOMEvent(ExecState *exec, DOM::Event e) 00390 { 00391 DOM::EventImpl *ei = e.handle(); 00392 if (!ei) 00393 return Null(); 00394 ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter()); 00395 DOMObject *ret = interp->getDOMObject(ei); 00396 if (!ret) { 00397 if (ei->isTextEvent()) 00398 ret = new DOMTextEvent(exec, e); 00399 else if (ei->isMouseEvent()) 00400 ret = new DOMMouseEvent(exec, e); 00401 else if (ei->isUIEvent()) 00402 ret = new DOMUIEvent(exec, e); 00403 else if (ei->isMutationEvent()) 00404 ret = new DOMMutationEvent(exec, e); 00405 else 00406 ret = new DOMEvent(exec, e); 00407 00408 interp->putDOMObject(ei, ret); 00409 } 00410 00411 return Value(ret); 00412 } 00413 00414 DOM::Event KJS::toEvent(const Value& val) 00415 { 00416 Object obj = Object::dynamicCast(val); 00417 if (obj.isNull() || !obj.inherits(&DOMEvent::info)) 00418 return DOM::Event(); 00419 00420 const DOMEvent *dobj = static_cast<const DOMEvent*>(obj.imp()); 00421 return dobj->toEvent(); 00422 } 00423 00424 // ------------------------------------------------------------------------- 00425 00426 00427 const ClassInfo EventExceptionConstructor::info = { "EventExceptionConstructor", 0, &EventExceptionConstructorTable, 0 }; 00428 /* 00429 @begin EventExceptionConstructorTable 1 00430 UNSPECIFIED_EVENT_TYPE_ERR DOM::EventException::UNSPECIFIED_EVENT_TYPE_ERR DontDelete|ReadOnly 00431 @end 00432 */ 00433 EventExceptionConstructor::EventExceptionConstructor(ExecState *exec) 00434 : DOMObject(exec->interpreter()->builtinObjectPrototype()) 00435 { 00436 } 00437 00438 Value EventExceptionConstructor::tryGet(ExecState *exec, const Identifier &p) const 00439 { 00440 return DOMObjectLookupGetValue<EventExceptionConstructor, DOMObject>(exec,p,&EventExceptionConstructorTable,this); 00441 } 00442 00443 Value EventExceptionConstructor::getValueProperty(ExecState *, int token) const 00444 { 00445 // We use the token as the value to return directly 00446 return Number(token); 00447 } 00448 00449 Value KJS::getEventExceptionConstructor(ExecState *exec) 00450 { 00451 return cacheGlobalObject<EventExceptionConstructor>(exec, "[[eventException.constructor]]"); 00452 } 00453 00454 // ------------------------------------------------------------------------- 00455 00456 const ClassInfo DOMUIEvent::info = { "UIEvent", &DOMEvent::info, &DOMUIEventTable, 0 }; 00457 /* 00458 @begin DOMUIEventTable 7 00459 view DOMUIEvent::View DontDelete|ReadOnly 00460 detail DOMUIEvent::Detail DontDelete|ReadOnly 00461 keyCode DOMUIEvent::KeyCode DontDelete|ReadOnly 00462 layerX DOMUIEvent::LayerX DontDelete|ReadOnly 00463 layerY DOMUIEvent::LayerY DontDelete|ReadOnly 00464 pageX DOMUIEvent::PageX DontDelete|ReadOnly 00465 pageY DOMUIEvent::PageY DontDelete|ReadOnly 00466 which DOMUIEvent::Which DontDelete|ReadOnly 00467 @end 00468 @begin DOMUIEventProtoTable 1 00469 initUIEvent DOMUIEvent::InitUIEvent DontDelete|Function 5 00470 @end 00471 */ 00472 DEFINE_PROTOTYPE("DOMUIEvent",DOMUIEventProto) 00473 IMPLEMENT_PROTOFUNC_DOM(DOMUIEventProtoFunc) 00474 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMUIEventProto,DOMUIEventProtoFunc,DOMEventProto) 00475 00476 DOMUIEvent::DOMUIEvent(ExecState *exec, DOM::UIEvent ue) : 00477 DOMEvent(DOMUIEventProto::self(exec), ue) {} 00478 00479 DOMUIEvent::DOMUIEvent(const Object &proto, DOM::UIEvent ue) : 00480 DOMEvent(proto, ue) {} 00481 00482 DOMUIEvent::~DOMUIEvent() 00483 { 00484 } 00485 00486 Value DOMUIEvent::tryGet(ExecState *exec, const Identifier &p) const 00487 { 00488 return DOMObjectLookupGetValue<DOMUIEvent,DOMEvent>(exec,p,&DOMUIEventTable,this); 00489 } 00490 00491 Value DOMUIEvent::getValueProperty(ExecState *exec, int token) const 00492 { 00493 switch (token) { 00494 case View: 00495 return getDOMAbstractView(exec,static_cast<DOM::UIEvent>(event).view()); 00496 case Detail: 00497 return Number(static_cast<DOM::UIEvent>(event).detail()); 00498 case KeyCode: 00499 // IE-compatibility 00500 return Number(static_cast<DOM::UIEvent>(event).keyCode()); 00501 case LayerX: 00502 // NS-compatibility 00503 return Number(static_cast<DOM::UIEvent>(event).layerX()); 00504 case LayerY: 00505 // NS-compatibility 00506 return Number(static_cast<DOM::UIEvent>(event).layerY()); 00507 case PageX: 00508 // NS-compatibility 00509 return Number(static_cast<DOM::UIEvent>(event).pageX()); 00510 case PageY: 00511 // NS-compatibility 00512 return Number(static_cast<DOM::UIEvent>(event).pageY()); 00513 case Which: 00514 // NS-compatibility 00515 return Number(static_cast<DOM::UIEvent>(event).which()); 00516 default: 00517 kdDebug(6070) << "WARNING: Unhandled token in DOMUIEvent::getValueProperty : " << token << endl; 00518 return Undefined(); 00519 } 00520 } 00521 00522 Value DOMUIEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) 00523 { 00524 KJS_CHECK_THIS( KJS::DOMUIEvent, thisObj ); 00525 DOM::UIEvent uiEvent = static_cast<DOMUIEvent *>(thisObj.imp())->toUIEvent(); 00526 switch (id) { 00527 case DOMUIEvent::InitUIEvent: { 00528 DOM::AbstractView v = toAbstractView(args[3]); 00529 static_cast<DOM::UIEvent>(uiEvent).initUIEvent(args[0].toString(exec).string(), 00530 args[1].toBoolean(exec), 00531 args[2].toBoolean(exec), 00532 v, 00533 args[4].toInteger(exec)); 00534 } 00535 return Undefined(); 00536 } 00537 return Undefined(); 00538 } 00539 00540 // ------------------------------------------------------------------------- 00541 00542 const ClassInfo DOMMouseEvent::info = { "MouseEvent", &DOMUIEvent::info, &DOMMouseEventTable, 0 }; 00543 00544 /* 00545 @begin DOMMouseEventTable 2 00546 screenX DOMMouseEvent::ScreenX DontDelete|ReadOnly 00547 screenY DOMMouseEvent::ScreenY DontDelete|ReadOnly 00548 clientX DOMMouseEvent::ClientX DontDelete|ReadOnly 00549 x DOMMouseEvent::X DontDelete|ReadOnly 00550 clientY DOMMouseEvent::ClientY DontDelete|ReadOnly 00551 y DOMMouseEvent::Y DontDelete|ReadOnly 00552 offsetX DOMMouseEvent::OffsetX DontDelete|ReadOnly 00553 offsetY DOMMouseEvent::OffsetY DontDelete|ReadOnly 00554 ctrlKey DOMMouseEvent::CtrlKey DontDelete|ReadOnly 00555 shiftKey DOMMouseEvent::ShiftKey DontDelete|ReadOnly 00556 altKey DOMMouseEvent::AltKey DontDelete|ReadOnly 00557 metaKey DOMMouseEvent::MetaKey DontDelete|ReadOnly 00558 button DOMMouseEvent::Button DontDelete|ReadOnly 00559 relatedTarget DOMMouseEvent::RelatedTarget DontDelete|ReadOnly 00560 fromElement DOMMouseEvent::FromElement DontDelete|ReadOnly 00561 toElement DOMMouseEvent::ToElement DontDelete|ReadOnly 00562 @end 00563 @begin DOMMouseEventProtoTable 1 00564 initMouseEvent DOMMouseEvent::InitMouseEvent DontDelete|Function 15 00565 @end 00566 */ 00567 DEFINE_PROTOTYPE("DOMMouseEvent",DOMMouseEventProto) 00568 IMPLEMENT_PROTOFUNC_DOM(DOMMouseEventProtoFunc) 00569 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMMouseEventProto,DOMMouseEventProtoFunc,DOMUIEventProto) 00570 00571 DOMMouseEvent::DOMMouseEvent(ExecState *exec, DOM::MouseEvent me) : 00572 DOMUIEvent(DOMMouseEventProto::self(exec), me) {} 00573 00574 DOMMouseEvent::~DOMMouseEvent() 00575 { 00576 } 00577 00578 Value DOMMouseEvent::tryGet(ExecState *exec, const Identifier &p) const 00579 { 00580 #ifdef KJS_VERBOSE 00581 kdDebug(6070) << "DOMMouseEvent::tryGet " << p.qstring() << endl; 00582 #endif 00583 return DOMObjectLookupGetValue<DOMMouseEvent,DOMUIEvent>(exec,p,&DOMMouseEventTable,this); 00584 } 00585 00586 Value DOMMouseEvent::getValueProperty(ExecState *exec, int token) const 00587 { 00588 switch (token) { 00589 case ScreenX: 00590 return Number(static_cast<DOM::MouseEvent>(event).screenX()); 00591 case ScreenY: 00592 return Number(static_cast<DOM::MouseEvent>(event).screenY()); 00593 case ClientX: 00594 case X: 00595 return Number(static_cast<DOM::MouseEvent>(event).clientX()); 00596 case ClientY: 00597 case Y: 00598 return Number(static_cast<DOM::MouseEvent>(event).clientY()); 00599 case OffsetX: 00600 case OffsetY: // MSIE extension 00601 { 00602 DOM::Node node = event.target(); 00603 node.handle()->getDocument()->updateRendering(); 00604 khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L; 00605 int x = static_cast<DOM::MouseEvent>(event).clientX(); 00606 int y = static_cast<DOM::MouseEvent>(event).clientY(); 00607 if ( rend ) { 00608 int xPos, yPos; 00609 if ( rend->absolutePosition( xPos, yPos ) ) { 00610 kdDebug() << "DOMMouseEvent::getValueProperty rend=" << rend << " xPos=" << xPos << " yPos=" << yPos << endl; 00611 x -= xPos; 00612 y -= yPos; 00613 } 00614 } 00615 return Number( token == OffsetX ? x : y ); 00616 } 00617 case CtrlKey: 00618 return Boolean(static_cast<DOM::MouseEvent>(event).ctrlKey()); 00619 case ShiftKey: 00620 return Boolean(static_cast<DOM::MouseEvent>(event).shiftKey()); 00621 case AltKey: 00622 return Boolean(static_cast<DOM::MouseEvent>(event).altKey()); 00623 case MetaKey: 00624 return Boolean(static_cast<DOM::MouseEvent>(event).metaKey()); 00625 case Button: 00626 { 00627 // Tricky. The DOM (and khtml) use 0 for LMB, 1 for MMB and 2 for RMB 00628 // but MSIE uses 1=LMB, 2=RMB, 4=MMB, as a bitfield 00629 int domButton = static_cast<DOM::MouseEvent>(event).button(); 00630 int button = domButton==0 ? 1 : domButton==1 ? 4 : domButton==2 ? 2 : 0; 00631 return Number( (unsigned int)button ); 00632 } 00633 case ToElement: 00634 // MSIE extension - "the object toward which the user is moving the mouse pointer" 00635 if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT) 00636 return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).relatedTarget()); 00637 return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).target()); 00638 case FromElement: 00639 // MSIE extension - "object from which activation 00640 // or the mouse pointer is exiting during the event" (huh?) 00641 if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT) 00642 return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).target()); 00643 /* fall through */ 00644 case RelatedTarget: 00645 return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).relatedTarget()); 00646 default: 00647 kdDebug(6070) << "WARNING: Unhandled token in DOMMouseEvent::getValueProperty : " << token << endl; 00648 return Value(); 00649 } 00650 } 00651 00652 Value DOMMouseEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) 00653 { 00654 KJS_CHECK_THIS( KJS::DOMMouseEvent, thisObj ); 00655 DOM::MouseEvent mouseEvent = static_cast<DOMMouseEvent *>(thisObj.imp())->toMouseEvent(); 00656 switch (id) { 00657 case DOMMouseEvent::InitMouseEvent: 00658 mouseEvent.initMouseEvent(args[0].toString(exec).string(), // typeArg 00659 args[1].toBoolean(exec), // canBubbleArg 00660 args[2].toBoolean(exec), // cancelableArg 00661 toAbstractView(args[3]), // viewArg 00662 args[4].toInteger(exec), // detailArg 00663 args[5].toInteger(exec), // screenXArg 00664 args[6].toInteger(exec), // screenYArg 00665 args[7].toInteger(exec), // clientXArg 00666 args[8].toInteger(exec), // clientYArg 00667 args[9].toBoolean(exec), // ctrlKeyArg 00668 args[10].toBoolean(exec), // altKeyArg 00669 args[11].toBoolean(exec), // shiftKeyArg 00670 args[12].toBoolean(exec), // metaKeyArg 00671 args[13].toInteger(exec), // buttonArg 00672 toNode(args[14])); // relatedTargetArg 00673 return Undefined(); 00674 } 00675 return Undefined(); 00676 } 00677 00678 // ------------------------------------------------------------------------- 00679 00680 const ClassInfo DOMTextEvent::info = { "TextEvent", &DOMUIEvent::info, &DOMTextEventTable, 0 }; 00681 00682 /* 00683 @begin DOMTextEventTable 2 00684 keyVal DOMTextEvent::Key DontDelete|ReadOnly 00685 virtKeyVal DOMTextEvent::VirtKey DontDelete|ReadOnly 00686 outputString DOMTextEvent::OutputString DontDelete|ReadOnly 00687 inputGenerated DOMTextEvent::InputGenerated DontDelete|ReadOnly 00688 numPad DOMTextEvent::NumPad DontDelete|ReadOnly 00689 @end 00690 @begin DOMTextEventProtoTable 1 00691 initTextEvent DOMTextEvent::InitTextEvent DontDelete|Function 10 00692 # Missing: initTextEventNS, initModifier 00693 @end 00694 */ 00695 DEFINE_PROTOTYPE("DOMTextEvent",DOMTextEventProto) 00696 IMPLEMENT_PROTOFUNC_DOM(DOMTextEventProtoFunc) 00697 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMTextEventProto,DOMTextEventProtoFunc,DOMUIEventProto) 00698 00699 DOMTextEvent::DOMTextEvent(ExecState *exec, DOM::TextEvent ke) : 00700 DOMUIEvent(DOMTextEventProto::self(exec), ke) {} 00701 00702 DOMTextEvent::~DOMTextEvent() 00703 { 00704 } 00705 00706 Value DOMTextEvent::tryGet(ExecState *exec, const Identifier &p) const 00707 { 00708 #ifdef KJS_VERBOSE 00709 kdDebug(6070) << "DOMTextEvent::tryGet " << p.qstring() << endl; 00710 #endif 00711 return DOMObjectLookupGetValue<DOMTextEvent,DOMUIEvent>(exec,p,&DOMTextEventTable,this); 00712 } 00713 00714 Value DOMTextEvent::getValueProperty(ExecState *, int token) const 00715 { 00716 switch (token) { 00717 case Key: 00718 return Number(static_cast<DOM::TextEvent>(event).keyVal()); 00719 case VirtKey: 00720 return Number(static_cast<DOM::TextEvent>(event).virtKeyVal()); 00721 case OutputString: 00722 return String(static_cast<DOM::TextEvent>(event).outputString()); 00723 case InputGenerated: 00724 return Boolean(static_cast<DOM::TextEvent>(event).inputGenerated()); 00725 case NumPad: 00726 return Boolean(static_cast<DOM::TextEvent>(event).numPad()); 00727 default: 00728 kdDebug(6070) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token << endl; 00729 return Value(); 00730 } 00731 } 00732 00733 Value DOMTextEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) 00734 { 00735 KJS_CHECK_THIS( KJS::DOMTextEvent, thisObj ); 00736 DOM::TextEvent keyEvent = static_cast<DOMTextEvent *>(thisObj.imp())->toTextEvent(); 00737 switch (id) { 00738 case DOMTextEvent::InitTextEvent: 00739 keyEvent.initTextEvent(args[0].toString(exec).string(), // typeArg 00740 args[1].toBoolean(exec), // canBubbleArg 00741 args[2].toBoolean(exec), // cancelableArg 00742 toAbstractView(args[3]), // viewArg 00743 args[4].toInteger(exec), // detailArg 00744 args[5].toString(exec).string(), // outputStringArg 00745 args[6].toInteger(exec), // keyValArg 00746 args[7].toInteger(exec), // virtKeyValArg 00747 args[8].toBoolean(exec), // inputGeneratedArg 00748 args[9].toBoolean(exec));// numPadArg 00749 00750 return Undefined(); 00751 } 00752 return Undefined(); 00753 } 00754 00755 // ------------------------------------------------------------------------- 00756 00757 const ClassInfo MutationEventConstructor::info = { "MutationEventConstructor", 0, &MutationEventConstructorTable, 0 }; 00758 /* 00759 @begin MutationEventConstructorTable 3 00760 MODIFICATION DOM::MutationEvent::MODIFICATION DontDelete|ReadOnly 00761 ADDITION DOM::MutationEvent::ADDITION DontDelete|ReadOnly 00762 REMOVAL DOM::MutationEvent::REMOVAL DontDelete|ReadOnly 00763 @end 00764 */ 00765 MutationEventConstructor::MutationEventConstructor(ExecState* exec) 00766 : DOMObject(exec->interpreter()->builtinObjectPrototype()) 00767 { 00768 } 00769 00770 Value MutationEventConstructor::tryGet(ExecState *exec, const Identifier &p) const 00771 { 00772 return DOMObjectLookupGetValue<MutationEventConstructor,DOMObject>(exec,p,&MutationEventConstructorTable,this); 00773 } 00774 00775 Value MutationEventConstructor::getValueProperty(ExecState *, int token) const 00776 { 00777 // We use the token as the value to return directly 00778 return Number(token); 00779 } 00780 00781 Value KJS::getMutationEventConstructor(ExecState *exec) 00782 { 00783 return cacheGlobalObject<MutationEventConstructor>(exec, "[[mutationEvent.constructor]]"); 00784 } 00785 00786 // ------------------------------------------------------------------------- 00787 00788 const ClassInfo DOMMutationEvent::info = { "MutationEvent", &DOMEvent::info, &DOMMutationEventTable, 0 }; 00789 /* 00790 @begin DOMMutationEventTable 5 00791 relatedNode DOMMutationEvent::RelatedNode DontDelete|ReadOnly 00792 prevValue DOMMutationEvent::PrevValue DontDelete|ReadOnly 00793 newValue DOMMutationEvent::NewValue DontDelete|ReadOnly 00794 attrName DOMMutationEvent::AttrName DontDelete|ReadOnly 00795 attrChange DOMMutationEvent::AttrChange DontDelete|ReadOnly 00796 @end 00797 @begin DOMMutationEventProtoTable 1 00798 initMutationEvent DOMMutationEvent::InitMutationEvent DontDelete|Function 8 00799 @end 00800 */ 00801 DEFINE_PROTOTYPE("DOMMutationEvent",DOMMutationEventProto) 00802 IMPLEMENT_PROTOFUNC_DOM(DOMMutationEventProtoFunc) 00803 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMMutationEventProto,DOMMutationEventProtoFunc,DOMEventProto) 00804 00805 DOMMutationEvent::DOMMutationEvent(ExecState *exec, DOM::MutationEvent me) : 00806 DOMEvent(DOMMutationEventProto::self(exec), me) {} 00807 00808 DOMMutationEvent::~DOMMutationEvent() 00809 { 00810 } 00811 00812 Value DOMMutationEvent::tryGet(ExecState *exec, const Identifier &p) const 00813 { 00814 return DOMObjectLookupGetValue<DOMMutationEvent,DOMEvent>(exec,p,&DOMMutationEventTable,this); 00815 } 00816 00817 Value DOMMutationEvent::getValueProperty(ExecState *exec, int token) const 00818 { 00819 switch (token) { 00820 case RelatedNode: 00821 return getDOMNode(exec,static_cast<DOM::MutationEvent>(event).relatedNode()); 00822 case PrevValue: 00823 return String(static_cast<DOM::MutationEvent>(event).prevValue()); 00824 case NewValue: 00825 return String(static_cast<DOM::MutationEvent>(event).newValue()); 00826 case AttrName: 00827 return String(static_cast<DOM::MutationEvent>(event).attrName()); 00828 case AttrChange: 00829 return Number((unsigned int)static_cast<DOM::MutationEvent>(event).attrChange()); 00830 default: 00831 kdDebug(6070) << "WARNING: Unhandled token in DOMMutationEvent::getValueProperty : " << token << endl; 00832 return Value(); 00833 } 00834 } 00835 00836 Value DOMMutationEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) 00837 { 00838 KJS_CHECK_THIS( KJS::DOMMutationEvent, thisObj ); 00839 DOM::MutationEvent mutationEvent = static_cast<DOMMutationEvent *>(thisObj.imp())->toMutationEvent(); 00840 switch (id) { 00841 case DOMMutationEvent::InitMutationEvent: 00842 mutationEvent.initMutationEvent(args[0].toString(exec).string(), // typeArg, 00843 args[1].toBoolean(exec), // canBubbleArg 00844 args[2].toBoolean(exec), // cancelableArg 00845 toNode(args[3]), // relatedNodeArg 00846 args[4].toString(exec).string(), // prevValueArg 00847 args[5].toString(exec).string(), // newValueArg 00848 args[6].toString(exec).string(), // attrNameArg 00849 args[7].toInteger(exec)); // attrChangeArg 00850 return Undefined(); 00851 } 00852 return Undefined(); 00853 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:44:56 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003