00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kjsembed.h"
00023 #include "binding_support.h"
00024
00025 #include "qobject_binding.h"
00026 #include "variant_binding.h"
00027 #include "static_binding.h"
00028
00029 #include "iosupport.h"
00030 #include "quiloader_binding.h"
00031 #ifdef KJSEMBED_FORMBUILDER_BINDING
00032 #include "qformbuilder_binding.h"
00033 #endif
00034 #include "qpainter_binding.h"
00035 #include "qwidget_binding.h"
00036 #include "qaction_binding.h"
00037 #include "qlayout_binding.h"
00038 #include "svg_binding.h"
00039 #include "filedialog_binding.h"
00040 #include "settings.h"
00041 #include "fileio.h"
00042 #include "color.h"
00043 #include "rect.h"
00044 #include "size.h"
00045 #include "point.h"
00046 #include "image.h"
00047 #include "pixmap.h"
00048 #include "brush.h"
00049 #include "pen.h"
00050 #include "font.h"
00051 #include "dom.h"
00052 #include "url.h"
00053 #include "application.h"
00054
00055 #include "builtins.h"
00056
00057 #include <kjs/interpreter.h>
00058 #include <kjs/completion.h>
00059
00060 #include <QtCore/QFile>
00061 #include <QtCore/QTextStream>
00062 #include <QtCore/QObject>
00063
00064 #include <QtCore/QDebug>
00065
00066
00073 namespace KJS {
00074 #ifndef QTONLY_WEBKIT
00075 UString::UString( const QString &d )
00076 {
00077 uint len = d.length();
00078 UChar *dat = static_cast<UChar*>(fastMalloc(sizeof(UChar)*len));
00079 memcpy( dat, d.unicode(), len * sizeof(UChar) );
00080 m_rep = UString::Rep::create(dat, len);
00081 }
00082
00083 QString UString::qstring() const
00084 {
00085 return QString((QChar*) data(), size());
00086 }
00087
00088 QString Identifier::qstring() const
00089 {
00090 return QString((QChar*) data(), size());
00091 }
00092 #endif
00093 }
00094
00095 namespace KJSEmbed {
00096
00097 class EnginePrivate {
00098 public:
00099 EnginePrivate ( )
00100 {
00101 m_interpreter = new KJS::Interpreter( );
00102 m_interpreter->initGlobalObject();
00103 m_interpreter->ref();
00104 }
00105 ~EnginePrivate()
00106 {
00107 m_interpreter->deref();
00108 }
00109 KJS::Interpreter *m_interpreter;
00110 KJS::Completion m_currentResult;
00111 bool m_bindingsEnabled;
00112 };
00113
00114 void setup( KJS::ExecState *exec, KJS::JSObject *parent )
00115 {
00116 StaticBinding::publish( exec, parent, IoFactory::methods() );
00117 StaticBinding::publish( exec, parent, FileDialog::methods() );
00118 StaticBinding::publish( exec, parent, BuiltinsFactory::methods() );
00119 StaticConstructor::add( exec, parent, FileIO::constructor() );
00120 StaticConstructor::add( exec, parent, DomNode::constructor() );
00121 StaticConstructor::add( exec, parent, DomDocument::constructor() );
00122 StaticConstructor::add( exec, parent, DomElement::constructor() );
00123 StaticConstructor::add( exec, parent, DomAttr::constructor() );
00124 StaticConstructor::add( exec, parent, DomDocumentType::constructor() );
00125 StaticConstructor::add( exec, parent, DomNodeList::constructor() );
00126 StaticConstructor::add( exec, parent, DomNamedNodeMap::constructor() );
00127 StaticConstructor::add( exec, parent, DomText::constructor() );
00128 StaticConstructor::add( exec, parent, Url::constructor() );
00129 StaticConstructor::add( exec, parent, SettingsBinding::constructor() );
00130 StaticConstructor::add( exec, parent, CoreApplicationBinding::constructor() );
00131 StaticConstructor::add( exec, parent, Point::constructor() );
00132 StaticConstructor::add( exec, parent, Size::constructor() );
00133 StaticConstructor::add( exec, parent, Rect::constructor() );
00134 StaticConstructor::add( exec, parent, Color::constructor() );
00135
00136
00137 QApplication* app = ::qobject_cast<QApplication*>(QCoreApplication::instance());
00138 if (app && (app->type() != QApplication::Tty))
00139 {
00140
00141
00142 #ifdef KJSEMBED_FORMBUILDER_BINDING
00143 StaticConstructor::add( exec, parent, FormBuilder::constructor() );
00144 #endif
00145 StaticConstructor::add( exec, parent, UiLoaderBinding::constructor() );
00146 StaticConstructor::add( exec, parent, QWidgetBinding::constructor() );
00147 StaticConstructor::add( exec, parent, Layout::constructor() );
00148 StaticConstructor::add( exec, parent, Action::constructor() );
00149 StaticConstructor::add( exec, parent, ActionGroup::constructor() );
00150 StaticConstructor::add( exec, parent, Font::constructor() );
00151 StaticConstructor::add( exec, parent, Pen::constructor() );
00152 StaticConstructor::add( exec, parent, Brush::constructor() );
00153 StaticConstructor::add( exec, parent, Image::constructor() );
00154 StaticConstructor::add( exec, parent, Pixmap::constructor() );
00155 StaticConstructor::add( exec, parent, Painter::constructor() );
00156 StaticConstructor::add( exec, parent, SvgRenderer::constructor() );
00157 StaticConstructor::add( exec, parent, SvgWidget::constructor() );
00158 StaticConstructor::add( exec, parent, ApplicationBinding::constructor() );
00159 }
00160 }
00161
00162 Engine::Engine( bool enableBindings )
00163 {
00164 dptr = new EnginePrivate( );
00165 if ( enableBindings )
00166 setup( dptr->m_interpreter->globalExec(), dptr->m_interpreter->globalObject() );
00167 dptr->m_bindingsEnabled = enableBindings;
00168 }
00169
00170 Engine::~Engine()
00171 {
00172 delete dptr;
00173 }
00174
00175 bool Engine::isBindingsEnabled() const
00176 {
00177 return dptr->m_bindingsEnabled;
00178 }
00179
00180 KJS::JSObject *Engine::addObject( QObject *obj, KJS::JSObject *parent, const KJS::UString &name ) const
00181 {
00182 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00183 KJS::JSObject *returnObject = KJSEmbed::createQObject(exec , obj, KJSEmbed::ObjectBinding::CPPOwned );
00184 KJS::Identifier jsName( !name.isEmpty() ? name : toUString(obj->objectName()) );
00185
00186 parent->putDirect(jsName, returnObject, KJS::DontDelete|KJS::ReadOnly );
00187 return returnObject;
00188 }
00189
00190 KJS::JSObject *Engine::addObject( QObject *obj, const KJS::UString &name ) const
00191 {
00192 return addObject( obj, dptr->m_interpreter->globalObject(), name );
00193 }
00194
00195 KJS::Completion Engine::completion() const
00196 {
00197 return dptr->m_currentResult;
00198 }
00199
00200 KJS::Interpreter *Engine::interpreter() const
00201 {
00202 return dptr->m_interpreter;
00203 }
00204
00205 KJS::Completion Engine::runFile( KJS::Interpreter *interpreter, const KJS::UString &fileName )
00206 {
00207
00208 KJS::UString code;
00209 QFile file( toQString(fileName) );
00210 if( file.open( QFile::ReadOnly ) )
00211 {
00212 QTextStream ts( &file );
00213
00214 QString line;
00215 while( !ts.atEnd() )
00216 {
00217 line = ts.readLine();
00218 if( line[0] != '#' ) code += toUString(line + '\n');
00219 }
00220 file.close();
00221 }
00222 else
00223 {
00224 code = "println('Could not open file.');";
00225 qWarning() << "Could not open file " << toQString(fileName);
00226 }
00227
00228
00229
00230 return interpreter->evaluate( fileName, 0, code, 0 );
00231 }
00232
00233 Engine::ExitStatus Engine::runFile( const KJS::UString &fileName )
00234 {
00235 dptr->m_currentResult = runFile( dptr->m_interpreter, fileName );
00236
00237 if( dptr->m_currentResult.complType() == KJS::Normal )
00238 return Engine::Success;
00239 else if ( dptr->m_currentResult.complType() == KJS::ReturnValue)
00240 return Engine::Success;
00241 else
00242 return Engine::Failure;
00243 }
00244
00245 Engine::ExitStatus Engine::execute( const KJS::UString &code )
00246 {
00247 dptr->m_currentResult = dptr->m_interpreter->evaluate(KJS::UString(""), 0, code, 0);
00248 if( dptr->m_currentResult.complType() == KJS::Normal )
00249 return Engine::Success;
00250 else if ( dptr->m_currentResult.complType() == KJS::ReturnValue)
00251 return Engine::Success;
00252 else
00253 return Engine::Failure;
00254 }
00255
00256 KJS::JSObject *Engine::construct( const KJS::UString &className, const KJS::List &args ) const
00257 {
00258 KJS::JSObject *global = dptr->m_interpreter->globalObject();
00259 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00260 return StaticConstructor::construct( exec, global, className, args );
00261 }
00262
00263 KJS::JSValue *Engine::callMethod( const KJS::UString &methodName, const KJS::List &args )
00264 {
00265 KJS::JSObject *global = dptr->m_interpreter->globalObject();
00266 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00267
00268 KJS::Identifier id = KJS::Identifier( KJS::UString( methodName ) );
00269 KJS::JSObject *fun = global->get( exec, id )->toObject( exec );
00270 KJS::JSValue *retValue;
00271
00272 if ( !fun->implementsCall() ) {
00273 QString msg = i18n( "%1 is not a function and cannot be called.", toQString(methodName) );
00274 return throwError( exec, KJS::TypeError, msg );
00275 }
00276
00277 retValue = fun->call( exec, global, args );
00278
00279 if( exec->hadException() )
00280 return exec->exception();
00281
00282 return retValue;
00283 }
00284
00285 KJS::JSValue *Engine::callMethod( KJS::JSObject *parent,
00286 const KJS::UString &methodName, const KJS::List &args )
00287 {
00288 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00289
00290 KJS::Identifier id = KJS::Identifier( methodName);
00291 KJS::JSObject *fun = parent->get( exec, id )->toObject( exec );
00292 KJS::JSValue *retValue;
00293
00294 if ( !fun->implementsCall() ) {
00295 QString msg = i18n( "%1 is not a function and cannot be called.", toQString(methodName) );
00296 return throwError( exec, KJS::TypeError, msg );
00297 }
00298
00299 retValue = fun->call( exec, parent, args );
00300
00301 if( exec->hadException() )
00302 return exec->exception();
00303
00304 return retValue;
00305 }
00306
00307
00308 }
00309
00310