📄 kjs_events.cpp
字号:
// -*- c-basic-offset: 2 -*-/* * This file is part of the KDE libraries * Copyright (C) 2001 Peter Kelly (pmk@post.com) * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "khtml_part.h"#include "kjs_window.h"#include "kjs_events.h"#include "kjs_events.lut.h"#include "kjs_views.h"#include "kjs_proxy.h"#include "xml/dom_nodeimpl.h"#include "xml/dom_docimpl.h"#include "xml/dom2_eventsimpl.h"#include "rendering/render_object.h"#include "misc/loader.h"#include <kdebug.h>using namespace KJS;using DOM::KeyboardEvent;using DOM::EventImpl;// -------------------------------------------------------------------------JSEventListener::JSEventListener(Object _listener, const Object &_win, bool _html){ listener = _listener; //fprintf(stderr,"JSEventListener::JSEventListener this=%p listener=%p\n",this,listener.imp()); html = _html; win = _win; if (_listener.imp()) { static_cast<Window*>(win.imp())->jsEventListeners.insert(_listener.imp(), this); }}JSEventListener::~JSEventListener(){ if (listener.imp()) { static_cast<Window*>(win.imp())->jsEventListeners.remove(listener.imp()); } //fprintf(stderr,"JSEventListener::~JSEventListener this=%p listener=%p\n",this,listener.imp());}void JSEventListener::handleEvent(DOM::Event &evt, bool isWindowEvent){#ifdef KJS_DEBUGGER if (KJSDebugWin::instance() && KJSDebugWin::instance()->inSession()) return;#endif KHTMLPart *part = static_cast<Window*>(win.imp())->part(); KJSProxy *proxy = 0; if (part) proxy = KJSProxy::proxy( part ); if (proxy && listener.implementsCall()) { ref(); KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); ExecState *exec = interpreter->globalExec(); List args; args.append(getDOMEvent(exec,evt)); // Add the event's target element to the scope // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope) ScopeChain oldScope = listener.scope(); Object thisObj; if (isWindowEvent) { thisObj = win; } else { KJS::Interpreter::lock(); thisObj = Object::dynamicCast(getDOMNode(exec,evt.currentTarget())); KJS::Interpreter::unlock(); if ( !thisObj.isNull() ) { ScopeChain scope = oldScope; KJS::Interpreter::lock(); static_cast<DOMNode*>(thisObj.imp())->pushEventHandlerScope(exec, scope); KJS::Interpreter::unlock(); listener.setScope( scope ); } } Window *window = static_cast<Window*>(win.imp()); // Set the event we're handling in the Window object window->setCurrentEvent( &evt ); // ... and in the interpreter interpreter->setCurrentEvent( &evt ); KJS::Interpreter::lock(); Value retval = listener.call(exec, thisObj, args); KJS::Interpreter::unlock(); listener.setScope( oldScope ); window->setCurrentEvent( 0 ); interpreter->setCurrentEvent( 0 );#if APPLE_CHANGES if ( exec->hadException() ) { KJS::Interpreter::lock(); char *message = exec->exception().toObject(exec).get(exec, messagePropertyName).toString(exec).ascii(); int lineNumber = exec->exception().toObject(exec).get(exec, "line").toInt32(exec); UString sourceURL = exec->exception().toObject(exec).get(exec, "sourceURL").toString(exec); KJS::Interpreter::unlock(); if (Interpreter::shouldPrintExceptions()) { printf("(event handler):%s\n", message); } KWQ(part)->addMessageToConsole(message, lineNumber, sourceURL.qstring()); exec->clearException(); }#else if ( exec->hadException() ) exec->clearException();#endif else if (html) { QVariant ret = ValueToVariant(exec, retval); if (ret.type() == QVariant::Bool && ret.toBool() == false) evt.preventDefault(); } DOM::DocumentImpl::updateDocumentsRendering(); deref(); }}DOM::DOMString JSEventListener::eventListenerType(){ if (html) return "_khtml_HTMLEventListener"; else return "_khtml_JSEventListener";}Object JSEventListener::listenerObj() const{ return listener; }JSLazyEventListener::JSLazyEventListener(QString _code, const Object &_win, bool _html) : JSEventListener(Object(), _win, _html), code(_code), parsed(false){}void JSLazyEventListener::handleEvent(DOM::Event &evt, bool isWindowEvent){ parseCode(); if (!listener.isNull()) { JSEventListener::handleEvent(evt, isWindowEvent); }}Object JSLazyEventListener::listenerObj() const{ parseCode(); return listener;}void JSLazyEventListener::parseCode() const{ if (!parsed) { KHTMLPart *part = static_cast<Window*>(win.imp())->part(); KJSProxy *proxy = 0L; if (part) proxy = KJSProxy::proxy( part ); if (proxy) { KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter()); ExecState *exec = interpreter->globalExec(); KJS::Interpreter::lock(); //KJS::Constructor constr(KJS::Global::current().get("Function").imp()); KJS::Object constr = interpreter->builtinFunction(); KJS::List args; static ProtectedValue eventString = KJS::String("event"); args.append(eventString); args.append(KJS::String(code)); listener = constr.construct(exec, args); // ### is globalExec ok ? KJS::Interpreter::unlock(); if ( exec->hadException() ) { exec->clearException(); // failed to parse, so let's just make this listener a no-op listener = Object(); } } // no more need to keep the unparsed code around code = QString(); if (!listener.isNull()) { static_cast<Window*>(win.imp())->jsEventListeners.insert(listener.imp(), (KJS::JSEventListener *)(this)); } parsed = true; }}Value KJS::getNodeEventListener(DOM::Node n, int eventId){ DOM::EventListener *listener = n.handle()->getHTMLEventListener(eventId); JSEventListener *jsListener = static_cast<JSEventListener*>(listener); if ( jsListener && jsListener->listenerObjImp() ) return jsListener->listenerObj(); else return Null();}// -------------------------------------------------------------------------const ClassInfo EventConstructor::info = { "EventConstructor", 0, &EventConstructorTable, 0 };/*@begin EventConstructorTable 3 CAPTURING_PHASE DOM::Event::CAPTURING_PHASE DontDelete|ReadOnly AT_TARGET DOM::Event::AT_TARGET DontDelete|ReadOnly BUBBLING_PHASE DOM::Event::BUBBLING_PHASE DontDelete|ReadOnly# Reverse-engineered from Netscape MOUSEDOWN 1 DontDelete|ReadOnly MOUSEUP 2 DontDelete|ReadOnly MOUSEOVER 4 DontDelete|ReadOnly MOUSEOUT 8 DontDelete|ReadOnly MOUSEMOVE 16 DontDelete|ReadOnly MOUSEDRAG 32 DontDelete|ReadOnly CLICK 64 DontDelete|ReadOnly DBLCLICK 128 DontDelete|ReadOnly KEYDOWN 256 DontDelete|ReadOnly KEYUP 512 DontDelete|ReadOnly KEYPRESS 1024 DontDelete|ReadOnly DRAGDROP 2048 DontDelete|ReadOnly FOCUS 4096 DontDelete|ReadOnly BLUR 8192 DontDelete|ReadOnly SELECT 16384 DontDelete|ReadOnly CHANGE 32768 DontDelete|ReadOnly@end*/Value EventConstructor::tryGet(ExecState *exec, const Identifier &p) const{ return DOMObjectLookupGetValue<EventConstructor, DOMObject>(exec,p,&EventConstructorTable,this);}Value EventConstructor::getValueProperty(ExecState *, int token) const{ // We use the token as the value to return directly return Number(token);}Value KJS::getEventConstructor(ExecState *exec){ return cacheGlobalObject<EventConstructor>(exec, "[[event.constructor]]");}// -------------------------------------------------------------------------const ClassInfo DOMEvent::info = { "Event", 0, &DOMEventTable, 0 };/*@begin DOMEventTable 12 type DOMEvent::Type DontDelete|ReadOnly target DOMEvent::Target DontDelete|ReadOnly currentTarget DOMEvent::CurrentTarget DontDelete|ReadOnly srcElement DOMEvent::SrcElement DontDelete|ReadOnly eventPhase DOMEvent::EventPhase DontDelete|ReadOnly bubbles DOMEvent::Bubbles DontDelete|ReadOnly cancelable DOMEvent::Cancelable DontDelete|ReadOnly timeStamp DOMEvent::TimeStamp DontDelete|ReadOnly returnValue DOMEvent::ReturnValue DontDelete cancelBubble DOMEvent::CancelBubble DontDelete dataTransfer DOMMouseEvent::DataTransfer DontDelete|ReadOnly clipboardData DOMEvent::ClipboardData DontDelete|ReadOnly@end@begin DOMEventProtoTable 3 stopPropagation DOMEvent::StopPropagation DontDelete|Function 0 preventDefault DOMEvent::PreventDefault DontDelete|Function 0 initEvent DOMEvent::InitEvent DontDelete|Function 3@end*/DEFINE_PROTOTYPE("DOMEvent", DOMEventProto)IMPLEMENT_PROTOFUNC(DOMEventProtoFunc)IMPLEMENT_PROTOTYPE(DOMEventProto, DOMEventProtoFunc)DOMEvent::DOMEvent(ExecState *exec, DOM::Event e) : DOMObject(DOMEventProto::self(exec)), event(e), clipboard(0) { }DOMEvent::~DOMEvent(){ ScriptInterpreter::forgetDOMObject(event.handle());}// pass marks through to JS objects we hold during garbage collectionvoid DOMMouseEvent::mark(){ ObjectImp::mark(); if (clipboard && !clipboard->marked()) clipboard->mark();}Value DOMEvent::tryGet(ExecState *exec, const Identifier &p) const{#ifdef KJS_VERBOSE kdDebug() << "KJS::DOMEvent::tryGet " << p.qstring() << endl;#endif return DOMObjectLookupGetValue<DOMEvent,DOMObject>(exec, p, &DOMEventTable, this );}Value DOMEvent::getValueProperty(ExecState *exec, int token) const{ switch (token) { case Type: return String(event.type()); case Target: case SrcElement: /*MSIE extension - "the object that fired the event"*/ return getDOMNode(exec,event.target()); case CurrentTarget: return getDOMNode(exec,event.currentTarget()); case EventPhase: return Number((unsigned int)event.eventPhase()); case Bubbles: return Boolean(event.bubbles()); case CancelBubble: return Boolean(event.getCancelBubble()); case ReturnValue: return Boolean(!event.defaultPrevented()); case Cancelable: return Boolean(event.cancelable()); case TimeStamp: return Number((long unsigned int)event.timeStamp()); // ### long long ? case ClipboardData: { DOM::EventImpl *ei = event.handle(); if (ei->isClipboardEvent()) { DOM::ClipboardEventImpl *impl = static_cast<DOM::ClipboardEventImpl *>(event.handle()); if (!clipboard) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -