00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kjs_binding.h"
00022 #include "kjs_dom.h"
00023
00024 #include "dom/dom_exception.h"
00025 #include "dom/dom2_range.h"
00026 #include "xml/dom2_eventsimpl.h"
00027
00028 #include <kdebug.h>
00029
00030 #include <assert.h>
00031
00032 using namespace KJS;
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 Value DOMObject::get(ExecState *exec, const UString &p) const
00043 {
00044 Value result;
00045 try {
00046 result = tryGet(exec,p);
00047 }
00048 catch (DOM::DOMException e) {
00049
00050
00051
00052 Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
00053 exec->setException( err );
00054 result = Undefined();
00055 }
00056 catch (...) {
00057 kdError(6070) << "Unknown exception in DOMObject::get()" << endl;
00058 result = String("Unknown exception");
00059 }
00060
00061 return result;
00062 }
00063
00064 void DOMObject::put(ExecState *exec, const UString &propertyName,
00065 const Value &value, int attr)
00066 {
00067 try {
00068 tryPut(exec, propertyName, value, attr);
00069 }
00070 catch (DOM::DOMException e) {
00071 Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
00072 exec->setException(err);
00073 }
00074 catch (...) {
00075 kdError(6070) << "Unknown exception in DOMObject::put()" << endl;
00076 }
00077 }
00078
00079 UString DOMObject::toString(ExecState *) const
00080 {
00081 return "[object " + className() + "]";
00082 }
00083
00084 Value DOMFunction::get(ExecState *exec, const UString &propertyName) const
00085 {
00086 Value result;
00087 try {
00088 result = tryGet(exec, propertyName);
00089 }
00090 catch (DOM::DOMException e) {
00091 result = Undefined();
00092 Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
00093 exec->setException(err);
00094 }
00095 catch (...) {
00096 kdError(6070) << "Unknown exception in DOMFunction::get()" << endl;
00097 result = String("Unknown exception");
00098 }
00099
00100 return result;
00101 }
00102
00103 Value DOMFunction::call(ExecState *exec, Object &thisObj, const List &args)
00104 {
00105 Value val;
00106 try {
00107 val = tryCall(exec, thisObj, args);
00108 }
00109
00110 catch (DOM::DOMException e) {
00111 Object err = Error::create(exec, GeneralError, QString("DOM Exception %1").arg(e.code).local8Bit());
00112 err.put(exec, "code", Number(e.code));
00113 exec->setException(err);
00114 }
00115 catch (DOM::RangeException e) {
00116 Object err = Error::create(exec, GeneralError, QString("DOM Range Exception %1").arg(e.code).local8Bit());
00117 err.put(exec, "code", Number(e.code));
00118 exec->setException(err);
00119 }
00120 catch (DOM::CSSException e) {
00121 Object err = Error::create(exec, GeneralError, QString("CSS Exception %1").arg(e.code).local8Bit());
00122 err.put(exec, "code", Number(e.code));
00123 exec->setException(err);
00124 }
00125 catch (DOM::EventException e) {
00126 Object err = Error::create(exec, GeneralError, QString("DOM Event Exception %1").arg(e.code).local8Bit());
00127 err.put(exec, "code", Number(e.code));
00128 exec->setException(err);
00129 }
00130 catch (...) {
00131 kdError(6070) << "Unknown exception in DOMFunction::call()" << endl;
00132 Object err = Error::create(exec, GeneralError, "Unknown exception");
00133 exec->setException(err);
00134 }
00135 return val;
00136 }
00137
00138 typedef QPtrList<ScriptInterpreter> InterpreterList;
00139 static InterpreterList *interpreterList;
00140
00141 ScriptInterpreter::ScriptInterpreter( const Object &global, KHTMLPart* part )
00142 : Interpreter( global ), m_part( part ), m_domObjects(1021),
00143 m_evt( 0L ), m_inlineCode(false), m_timerCallback(false)
00144 {
00145 #ifdef KJS_VERBOSE
00146 kdDebug(6070) << "ScriptInterpreter::ScriptInterpreter " << this << " for part=" << m_part << endl;
00147 #endif
00148 if ( !interpreterList )
00149 interpreterList = new InterpreterList;
00150 interpreterList->append( this );
00151 }
00152
00153 ScriptInterpreter::~ScriptInterpreter()
00154 {
00155 #ifdef KJS_VERBOSE
00156 kdDebug(6070) << "ScriptInterpreter::~ScriptInterpreter " << this << " for part=" << m_part << endl;
00157 #endif
00158 assert( interpreterList && interpreterList->contains( this ) );
00159 interpreterList->remove( this );
00160 if ( interpreterList->isEmpty() ) {
00161 delete interpreterList;
00162 interpreterList = 0;
00163 }
00164 }
00165
00166 void ScriptInterpreter::forgetDOMObject( void* objectHandle )
00167 {
00168 if( !interpreterList ) return;
00169
00170 QPtrListIterator<ScriptInterpreter> it( *interpreterList );
00171 while ( it.current() ) {
00172 (*it)->deleteDOMObject( objectHandle );
00173 ++it;
00174 }
00175 }
00176
00177 void ScriptInterpreter::mark()
00178 {
00179 Interpreter::mark();
00180 #ifdef KJS_VERBOSE
00181 kdDebug(6070) << "ScriptInterpreter::mark marking " << m_domObjects.count() << " DOM objects" << endl;
00182 #endif
00183 QPtrDictIterator<DOMObject> it( m_domObjects );
00184 for( ; it.current(); ++it )
00185 it.current()->mark();
00186 }
00187
00188 bool ScriptInterpreter::isWindowOpenAllowed() const
00189 {
00190 if ( m_evt )
00191 {
00192 int id = m_evt->handle()->id();
00193 bool eventOk = (
00194 id == DOM::EventImpl::KHTML_ECMA_CLICK_EVENT || id == DOM::EventImpl::MOUSEDOWN_EVENT ||
00195 id == DOM::EventImpl::MOUSEUP_EVENT || id == DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT ||
00196
00197 id == DOM::EventImpl::KHTML_KEYDOWN_EVENT || id == DOM::EventImpl::KHTML_KEYPRESS_EVENT ||
00198 id == DOM::EventImpl::KHTML_KEYUP_EVENT ||
00199
00200 id == DOM::EventImpl::SELECT_EVENT || id == DOM::EventImpl::CHANGE_EVENT ||
00201 id == DOM::EventImpl::SUBMIT_EVENT );
00202 kdDebug(6070) << "Window.open, smart policy: id=" << id << " eventOk=" << eventOk << endl;
00203 if (eventOk)
00204 return true;
00205 } else
00206 {
00207 if ( m_inlineCode && !m_timerCallback )
00208 {
00209
00210 return true;
00211 kdDebug(6070) << "Window.open, smart policy, no event, inline code -> ok" << endl;
00212 }
00213 else
00214 kdDebug(6070) << "Window.open, smart policy, no event, <script> tag -> refused" << endl;
00215 }
00216 return false;
00217 }
00218
00220
00221 UString::UString(const QString &d)
00222 {
00223 unsigned int len = d.length();
00224 UChar *dat = new UChar[len];
00225 memcpy(dat, d.unicode(), len * sizeof(UChar));
00226 rep = UString::Rep::create(dat, len);
00227 }
00228
00229 UString::UString(const DOM::DOMString &d)
00230 {
00231 if (d.isNull()) {
00232 attach(&Rep::null);
00233 return;
00234 }
00235
00236 unsigned int len = d.length();
00237 UChar *dat = new UChar[len];
00238 memcpy(dat, d.unicode(), len * sizeof(UChar));
00239 rep = UString::Rep::create(dat, len);
00240 }
00241
00242 DOM::DOMString UString::string() const
00243 {
00244 return DOM::DOMString((QChar*) data(), size());
00245 }
00246
00247 QString UString::qstring() const
00248 {
00249 return QString((QChar*) data(), size());
00250 }
00251
00252 QConstString UString::qconststring() const
00253 {
00254 return QConstString((QChar*) data(), size());
00255 }
00256
00257 DOM::Node KJS::toNode(const Value& val)
00258 {
00259 Object obj = Object::dynamicCast(val);
00260 if (obj.isNull() || !obj.inherits(&DOMNode::info))
00261 return DOM::Node();
00262
00263 const DOMNode *dobj = static_cast<const DOMNode*>(obj.imp());
00264 return dobj->toNode();
00265 }
00266
00267 Value KJS::getString(DOM::DOMString s)
00268 {
00269 if (s.isNull())
00270 return Null();
00271 else
00272 return String(s);
00273 }
00274
00275 QVariant KJS::ValueToVariant(ExecState* exec, const Value &val) {
00276 QVariant res;
00277 switch (val.type()) {
00278 case BooleanType:
00279 res = QVariant(val.toBoolean(exec), 0);
00280 break;
00281 case NumberType:
00282 res = QVariant(val.toNumber(exec));
00283 break;
00284 case StringType:
00285 res = QVariant(val.toString(exec).qstring());
00286 break;
00287 default:
00288
00289 break;
00290 }
00291 return res;
00292 }