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