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-2001 Harri Porten (porten@kde.org)
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Library General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Library General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Library General Public
00017  *  License along with this library; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 /* TODO:
00035  * The catch all (...) clauses below shouldn't be necessary.
00036  * But they helped to view for example www.faz.net in an stable manner.
00037  * Those unknown exceptions should be treated as severe bugs and be fixed.
00038  *
00039  * these may be CSS exceptions - need to check - pmk
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     // ### translate code into readable string ?
00050     // ### oh, and s/QString/i18n or I18N_NOOP (the code in kjs uses I18N_NOOP... but where is it translated ?)
00051     //     and where does it appear to the user ?
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   // pity there's no way to distinguish between these in JS code
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 = ( // mouse events
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       // keyboard events
00197       id == DOM::EventImpl::KHTML_KEYDOWN_EVENT || id == DOM::EventImpl::KHTML_KEYPRESS_EVENT ||
00198       id == DOM::EventImpl::KHTML_KEYUP_EVENT ||
00199       // other accepted events
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 // no event
00206   {
00207     if ( m_inlineCode && !m_timerCallback )
00208     {
00209       // This is the <a href="javascript:window.open('...')> case -> we let it through
00210       return true;
00211       kdDebug(6070) << "Window.open, smart policy, no event, inline code -> ok" << endl;
00212     }
00213     else // This is the <script>window.open(...)</script> case or a timer callback -> block it
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     // everything else will be 'invalid'
00289     break;
00290   }
00291   return res;
00292 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:22:40 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001