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  *
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_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 /* TODO:
00036  * The catch all (...) clauses below shouldn't be necessary.
00037  * But they helped to view for example www.faz.net in an stable manner.
00038  * Those unknown exceptions should be treated as severe bugs and be fixed.
00039  *
00040  * these may be CSS exceptions - need to check - pmk
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     // ### translate code into readable string ?
00051     // ### oh, and s/QString/i18n or I18N_NOOP (the code in kjs uses I18N_NOOP... but where is it translated ?)
00052     //     and where does it appear to the user ?
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   // pity there's no way to distinguish between these in JS code
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 = ( // mouse events
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       // keyboard events
00199       id == DOM::EventImpl::KHTML_KEYDOWN_EVENT || id == DOM::EventImpl::KHTML_KEYPRESS_EVENT ||
00200       id == DOM::EventImpl::KHTML_KEYUP_EVENT ||
00201       // other accepted events
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 // no event
00208   {
00209     if ( m_inlineCode && !m_timerCallback )
00210     {
00211       // This is the <a href="javascript:window.open('...')> case -> we let it through
00212       return true;
00213       kdDebug(6070) << "Window.open, smart policy, no event, inline code -> ok" << endl;
00214     }
00215     else // This is the <script>window.open(...)</script> case or a timer callback -> block it
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     // everything else will be 'invalid'
00291     break;
00292   }
00293   return res;
00294 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:16:37 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001