khtml Library API Documentation

kjs_binding.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 1999-2003 Harri Porten (porten@kde.org)
00005  *  Copyright (C) 2001-2003 David Faure (faure@kde.org)
00006  *  Copyright (C) 2003 Apple Computer, Inc.
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Library General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2 of the License, or (at your option) any later version.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Library General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Library General Public
00019  *  License along with this library; if not, write to the Free Software
00020  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 #include "kjs_binding.h"
00024 #include "kjs_dom.h"
00025 
00026 #include "dom/dom_exception.h"
00027 #include "dom/dom2_range.h"
00028 #include "xml/dom2_eventsimpl.h"
00029 
00030 #include <kdebug.h>
00031 
00032 #include <assert.h>
00033 
00034 using namespace KJS;
00035 
00036 /* TODO:
00037  * The catch all (...) clauses below shouldn't be necessary.
00038  * But they helped to view for example www.faz.net in an stable manner.
00039  * Those unknown exceptions should be treated as severe bugs and be fixed.
00040  *
00041  * these may be CSS exceptions - need to check - pmk
00042  */
00043 
00044 Value DOMObject::get(ExecState *exec, const Identifier &p) const
00045 {
00046   Value result;
00047   try {
00048     result = tryGet(exec,p);
00049   }
00050   catch (DOM::DOMException e) {
00051     // ### translate code into readable string ?
00052     // ### oh, and s/QString/i18n or I18N_NOOP (the code in kjs uses I18N_NOOP... but where is it translated ?)
00053     //     and where does it appear to the user ?
00054     Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
00055     exec->setException( err );
00056     result = Undefined();
00057   }
00058   catch (...) {
00059     kdError(6070) << "Unknown exception in DOMObject::get()" << endl;
00060     result = String("Unknown exception");
00061   }
00062 
00063   return result;
00064 }
00065 
00066 void DOMObject::put(ExecState *exec, const Identifier &propertyName,
00067                     const Value &value, int attr)
00068 {
00069   try {
00070     tryPut(exec, propertyName, value, attr);
00071   }
00072   catch (DOM::DOMException e) {
00073     Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
00074     exec->setException(err);
00075   }
00076   catch (...) {
00077     kdError(6070) << "Unknown exception in DOMObject::put()" << endl;
00078   }
00079 }
00080 
00081 UString DOMObject::toString(ExecState *) const
00082 {
00083   return "[object " + className() + "]";
00084 }
00085 
00086 Value DOMFunction::get(ExecState *exec, const Identifier &propertyName) const
00087 {
00088   Value result;
00089   try {
00090     result = tryGet(exec, propertyName);
00091   }
00092   catch (DOM::DOMException e) {
00093     result = Undefined();
00094     Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
00095     exec->setException(err);
00096   }
00097   catch (...) {
00098     kdError(6070) << "Unknown exception in DOMFunction::get()" << endl;
00099     result = String("Unknown exception");
00100   }
00101 
00102   return result;
00103 }
00104 
00105 Value DOMFunction::call(ExecState *exec, Object &thisObj, const List &args)
00106 {
00107   Value val;
00108   try {
00109     val = tryCall(exec, thisObj, args);
00110   }
00111   // pity there's no way to distinguish between these in JS code
00112   // ### Look into setting prototypes of these & the use of instanceof so the exception
00113   // type can be determined. See what other browsers do.
00114   catch (DOM::DOMException e) {
00115     Object err = Error::create(exec, GeneralError, QString("DOM Exception %1").arg(e.code).local8Bit());
00116     err.put(exec, "code", Number(e.code));
00117     exec->setException(err);
00118   }
00119   catch (DOM::RangeException e) {
00120     Object err = Error::create(exec, GeneralError, QString("DOM Range Exception %1").arg(e.code).local8Bit());
00121     err.put(exec, "code", Number(e.code));
00122     exec->setException(err);
00123   }
00124   catch (DOM::CSSException e) {
00125     Object err = Error::create(exec, GeneralError, QString("CSS Exception %1").arg(e.code).local8Bit());
00126     err.put(exec, "code", Number(e.code));
00127     exec->setException(err);
00128   }
00129   catch (DOM::EventException e) {
00130     Object err = Error::create(exec, GeneralError, QString("DOM Event Exception %1").arg(e.code).local8Bit());
00131     err.put(exec, "code", Number(e.code));
00132     exec->setException(err);
00133   }
00134   catch (...) {
00135     kdError(6070) << "Unknown exception in DOMFunction::call()" << endl;
00136     Object err = Error::create(exec, GeneralError, "Unknown exception");
00137     exec->setException(err);
00138   }
00139   return val;
00140 }
00141 
00142 typedef QPtrList<ScriptInterpreter> InterpreterList;
00143 static InterpreterList *interpreterList;
00144 
00145 ScriptInterpreter::ScriptInterpreter( const Object &global, KHTMLPart* part )
00146   : Interpreter( global ), m_part( part ), m_domObjects(1021),
00147     m_evt( 0L ), m_inlineCode(false), m_timerCallback(false)
00148 {
00149 #ifdef KJS_VERBOSE
00150   kdDebug(6070) << "ScriptInterpreter::ScriptInterpreter " << this << " for part=" << m_part << endl;
00151 #endif
00152   if ( !interpreterList )
00153     interpreterList = new InterpreterList;
00154   interpreterList->append( this );
00155 }
00156 
00157 ScriptInterpreter::~ScriptInterpreter()
00158 {
00159 #ifdef KJS_VERBOSE
00160   kdDebug(6070) << "ScriptInterpreter::~ScriptInterpreter " << this << " for part=" << m_part << endl;
00161 #endif
00162   assert( interpreterList && interpreterList->contains( this ) );
00163   interpreterList->remove( this );
00164   if ( interpreterList->isEmpty() ) {
00165     delete interpreterList;
00166     interpreterList = 0;
00167   }
00168 }
00169 
00170 void ScriptInterpreter::forgetDOMObject( void* objectHandle )
00171 {
00172   if( !interpreterList ) return;
00173 
00174   QPtrListIterator<ScriptInterpreter> it( *interpreterList );
00175   while ( it.current() ) {
00176     (*it)->deleteDOMObject( objectHandle );
00177     ++it;
00178   }
00179 }
00180 
00181 void ScriptInterpreter::mark()
00182 {
00183   Interpreter::mark();
00184 #ifdef KJS_VERBOSE
00185   kdDebug(6070) << "ScriptInterpreter::mark " << this << " marking " << m_domObjects.count() << " DOM objects" << endl;
00186 #endif
00187   QPtrDictIterator<DOMObject> it( m_domObjects );
00188   for( ; it.current(); ++it )
00189     it.current()->mark();
00190 }
00191 
00192 bool ScriptInterpreter::isWindowOpenAllowed() const
00193 {
00194   if ( m_evt )
00195   {
00196     int id = m_evt->handle()->id();
00197     bool eventOk = ( // mouse events
00198       id == DOM::EventImpl::CLICK_EVENT ||
00199       id == DOM::EventImpl::MOUSEUP_EVENT || id == DOM::EventImpl::MOUSEDOWN_EVENT ||
00200       id == DOM::EventImpl::KHTML_ECMA_CLICK_EVENT || id == DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT ||
00201       // keyboard events
00202       id == DOM::EventImpl::KEYDOWN_EVENT || id == DOM::EventImpl::KHTML_KEYPRESS_EVENT ||
00203       id == DOM::EventImpl::KEYUP_EVENT ||
00204       // other accepted events
00205       id == DOM::EventImpl::SELECT_EVENT || id == DOM::EventImpl::CHANGE_EVENT ||
00206       id == DOM::EventImpl::SUBMIT_EVENT );
00207     kdDebug(6070) << "Window.open, smart policy: id=" << id << " eventOk=" << eventOk << endl;
00208     if (eventOk)
00209       return true;
00210   } else // no event
00211   {
00212     if ( m_inlineCode && !m_timerCallback )
00213     {
00214       // This is the <a href="javascript:window.open('...')> case -> we let it through
00215       return true;
00216       kdDebug(6070) << "Window.open, smart policy, no event, inline code -> ok" << endl;
00217     }
00218     else // This is the <script>window.open(...)</script> case or a timer callback -> block it
00219       kdDebug(6070) << "Window.open, smart policy, no event, <script> tag -> refused" << endl;
00220   }
00221   return false;
00222 }
00223 
00224 
00225 UString::UString(const QString &d)
00226 {
00227   unsigned int len = d.length();
00228   UChar *dat = new UChar[len];
00229   memcpy(dat, d.unicode(), len * sizeof(UChar));
00230   rep = UString::Rep::create(dat, len);
00231 }
00232 
00233 UString::UString(const DOM::DOMString &d)
00234 {
00235   if (d.isNull()) {
00236     attach(&Rep::null);
00237     return;
00238   }
00239 
00240   unsigned int len = d.length();
00241   UChar *dat = new UChar[len];
00242   memcpy(dat, d.unicode(), len * sizeof(UChar));
00243   rep = UString::Rep::create(dat, len);
00244 }
00245 
00246 DOM::DOMString UString::string() const
00247 {
00248   return DOM::DOMString((QChar*) data(), size());
00249 }
00250 
00251 QString UString::qstring() const
00252 {
00253   return QString((QChar*) data(), size());
00254 }
00255 
00256 QConstString UString::qconststring() const
00257 {
00258   return QConstString((QChar*) data(), size());
00259 }
00260 
00261 DOM::DOMString Identifier::string() const
00262 {
00263   return DOM::DOMString((QChar*) data(), size());
00264 }
00265 
00266 QString Identifier::qstring() const
00267 {
00268   return QString((QChar*) data(), size());
00269 }
00270 
00271 DOM::Node KJS::toNode(const Value& val)
00272 {
00273   Object obj = Object::dynamicCast(val);
00274   if (obj.isNull() || !obj.inherits(&DOMNode::info))
00275     return DOM::Node();
00276 
00277   const DOMNode *dobj = static_cast<const DOMNode*>(obj.imp());
00278   return dobj->toNode();
00279 }
00280 
00281 Value KJS::getString(DOM::DOMString s)
00282 {
00283   if (s.isNull())
00284     return Null();
00285   else
00286     return String(s);
00287 }
00288 
00289 QVariant KJS::ValueToVariant(ExecState* exec, const Value &val) {
00290   QVariant res;
00291   switch (val.type()) {
00292   case BooleanType:
00293     res = QVariant(val.toBoolean(exec), 0);
00294     break;
00295   case NumberType:
00296     res = QVariant(val.toNumber(exec));
00297     break;
00298   case StringType:
00299     res = QVariant(val.toString(exec).qstring());
00300     break;
00301   default:
00302     // everything else will be 'invalid'
00303     break;
00304   }
00305   return res;
00306 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Apr 21 18:45:05 2004 by doxygen 1.3.6-20040222 written by Dimitri van Heesch, © 1997-2003