• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KJS-API

kjsprototype.cpp

Go to the documentation of this file.
00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 2008 Harri Porten (porten@kde.org)
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  *  Boston, MA 02110-1301, USA.
00019  *
00020  */
00021 
00022 #include "kjsprototype.h"
00023 #include "kjsinterpreter.h"
00024 #include "kjsarguments.h"
00025 #include "kjsprivate.h"
00026 
00027 #include "kjs/object.h"
00028 #include "kjs/context.h"
00029 #include "kjs/interpreter.h"
00030 
00031 #include <QMap>
00032 
00033 using namespace KJS;
00034 
00035 class KJSCustomProperty
00036 {
00037 public:
00038     KJSCustomProperty(KJSPrototype::PropertyGetter g,
00039                       KJSPrototype::PropertySetter s)
00040         : getter(g), setter(s)
00041     {
00042     }
00043 
00044     JSValue* read(ExecState* exec, void* object);
00045     void write(ExecState* exec, void* object, JSValue* value);
00046 
00047 private:
00048     KJSPrototype::PropertyGetter getter;
00049     KJSPrototype::PropertySetter setter;
00050 };
00051 
00052 class CustomObject : public JSObject {
00053 public:
00054     CustomObject(JSValue* proto, void* v)
00055         : JSObject(proto),
00056           iv(v)
00057     {
00058     }
00059 
00060     void put(ExecState* exec, const Identifier& id,
00061              JSValue *value, int attr = None);
00062 
00063     void* internalValue() { return iv; }
00064 
00065     // rtti
00066     static const ClassInfo info;
00067     const ClassInfo* classInfo() const { return &info; }
00068 
00069 private:
00070     void* iv;
00071 };
00072 
00073 const ClassInfo CustomObject::info = { "CustomObject", 0, 0, 0 };
00074 
00075 class KJSCustomFunction : public JSObject {
00076 public:
00077     KJSCustomFunction(ExecState* exec, KJSPrototype::FunctionCall f)
00078         : callback(f)
00079     {
00080         setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
00081     }
00082 
00083     JSValue* callAsFunction(ExecState* exec, JSObject* thisObj,
00084                             const List &args);
00085     bool implementsCall() const { return true; }
00086 
00087 private:
00088     KJSPrototype::FunctionCall callback;
00089 };
00090 
00091 JSValue* KJSCustomFunction::callAsFunction(ExecState* exec, JSObject* thisObj,
00092                                            const List &args)
00093 {
00094     // FIXME: does not protect against mixing custom objects
00095     KJS_CHECK_THIS(CustomObject, thisObj);
00096 
00097     CustomObject* co = static_cast<CustomObject*>(thisObj);
00098     void* thisValue = co->internalValue();
00099 
00100     KJSContext ctx(EXECSTATE_HANDLE(exec));
00101     KJSArguments a(LIST_HANDLE(&args));
00102     KJSObject res = (*callback)(&ctx, thisValue, a);
00103     return JSVALUE(&res);
00104 }
00105 
00106 JSValue* KJSCustomProperty::read(ExecState* exec, void* object)
00107 {
00108     assert(getter);
00109     
00110     KJSContext ctx(EXECSTATE_HANDLE(exec));
00111     KJSObject res = (*getter)(&ctx, object);
00112     return JSVALUE(&res);
00113 }
00114 
00115 void KJSCustomProperty::write(ExecState* exec, void* object, JSValue* value)
00116 {
00117     KJSContext ctx(EXECSTATE_HANDLE(exec));
00118 
00119     if (setter) {
00120         KJSObject vo(JSVALUE_HANDLE(value));
00121         (*setter)(&ctx, object, vo);
00122     } else {
00123         JSObject *e = Error::create(exec, GeneralError,
00124                                     "Property is read-only");
00125         exec->setException(e);
00126     }
00127 }
00128 
00129 static JSValue* getPropertyValue(ExecState* exec, JSObject *originalObject,
00130                                  const Identifier&, const PropertySlot& sl)
00131 {
00132     CustomObject* o = static_cast<CustomObject*>(originalObject);
00133     KJSCustomProperty* p =
00134         reinterpret_cast<KJSCustomProperty*>(sl.customValue());
00135 
00136     return p->read(exec, o->internalValue());
00137 }
00138 
00139 // FIXME: or use Identifier?
00140 // FIXME: use values
00141 typedef QMap<UString, KJSCustomProperty*> CustomPropertyMap;
00142 
00143 class CustomPrototype : public JSObject {
00144 public:
00145     CustomPrototype()
00146     {
00147     }
00148     ~CustomPrototype()
00149     {
00150         qDeleteAll(properties);
00151     }
00152 
00153     bool getOwnPropertySlot(ExecState *exec, const Identifier& id,
00154                             PropertySlot& sl)
00155     {
00156         CustomPropertyMap::iterator it = properties.find(id.ustring());
00157         if (it == properties.end())
00158             return JSObject::getOwnPropertySlot(exec, id, sl);
00159         
00160         sl.setCustomValue(0, *it, getPropertyValue);
00161 
00162         return true;
00163     }
00164 
00165     void registerProperty(const QString& name,
00166                           KJSPrototype::PropertyGetter g,
00167                           KJSPrototype::PropertySetter s)
00168     {
00169         properties.insert(toUString(name), new KJSCustomProperty(g, s));
00170     }
00171 
00172     void registerFunction(ExecState* exec,
00173                           const QString& name, KJSPrototype::FunctionCall f)
00174     {
00175         putDirect(toIdentifier(name), new KJSCustomFunction(exec, f));
00176     }
00177 
00178     bool setProperty(ExecState* exec, CustomObject* obj,
00179                      const Identifier& id, JSValue* value)
00180     {
00181         CustomPropertyMap::iterator it = properties.find(id.ustring());
00182         if (it == properties.end())
00183             return false;
00184 
00185         (*it)->write(exec, obj->internalValue(), value);
00186         
00187         return true;
00188     }
00189 
00190 private:
00191     CustomPropertyMap properties;
00192 };
00193 
00194 void CustomObject::put(ExecState* exec, const Identifier& id,
00195                        JSValue* value, int attr)
00196 {
00197     CustomPrototype* p = static_cast<CustomPrototype*>(prototype());
00198 
00199     if (!p->setProperty(exec, this, id, value))
00200         JSObject::put(exec, id, value, attr);
00201 }
00202 
00203 KJSPrototype::KJSPrototype()
00204 {
00205     CustomPrototype* p = new CustomPrototype;
00206     gcProtect(p);
00207 
00208     hnd = PROTOTYPE_HANDLE(p);
00209 }
00210 
00211 KJSPrototype::~KJSPrototype()
00212 {
00213     gcUnprotect(PROTOTYPE(this));
00214 }
00215 
00216 void KJSPrototype::defineConstant(const QString& name, double value)
00217 {
00218     CustomPrototype* p = PROTOTYPE(this);
00219 
00220     p->putDirect(toIdentifier(name), jsNumber(value),
00221                  DontEnum|DontDelete|ReadOnly);
00222 }
00223 
00224 void KJSPrototype::defineConstant(const QString& name, const QString& value)
00225 {
00226     CustomPrototype* p = PROTOTYPE(this);
00227 
00228     p->putDirect(toIdentifier(name), jsString(toUString(value)),
00229                  DontEnum|DontDelete|ReadOnly);
00230 }
00231 
00232 void KJSPrototype::defineConstant(const QString& name, const KJSObject& value)
00233 {
00234     CustomPrototype* p = PROTOTYPE(this);
00235 
00236     p->putDirect(toIdentifier(name), JSVALUE(&value),
00237                  DontEnum|DontDelete|ReadOnly);
00238 }
00239 
00240 KJSObject KJSPrototype::constructObject(KJSContext* ctx, void *internalValue)
00241 {
00242     CustomPrototype* p = PROTOTYPE(this);
00243 
00244     if (ctx && !p->prototype()) {
00245         ExecState* exec = EXECSTATE(ctx);
00246         KJS::Interpreter* i = exec->lexicalInterpreter();
00247         JSObject* objectProto = i->builtinObjectPrototype();
00248         p->setPrototype(objectProto);
00249     }
00250 
00251     CustomObject* newObj = new CustomObject(p, internalValue);
00252     return KJSObject(JSVALUE_HANDLE(newObj));
00253 }
00254 
00255 KJSGlobalObject KJSPrototype::constructGlobalObject(void *internalValue)
00256 {
00257     CustomPrototype* p = PROTOTYPE(this);
00258 
00259     CustomObject* newObj = new CustomObject(p, internalValue);
00260     return KJSGlobalObject(JSVALUE_HANDLE(newObj));
00261 }
00262 
00263 void KJSPrototype::defineProperty(KJSContext* ctx,
00264                                   const QString& name,
00265                                   PropertyGetter getter,
00266                                   PropertySetter setter)
00267 {
00268     assert(getter);
00269 
00270     CustomPrototype* p = PROTOTYPE(this);
00271 
00272     p->registerProperty(name, getter, setter);
00273 }
00274 
00275 void KJSPrototype::defineFunction(KJSContext* ctx,
00276                                   const QString& name, FunctionCall callback)
00277 {
00278     assert(callback);
00279 
00280     CustomPrototype* p = PROTOTYPE(this);
00281     ExecState* exec = EXECSTATE(ctx);
00282 
00283     p->registerFunction(exec, name, callback);
00284 }
00285 
00286 

KJS-API

Skip menu "KJS-API"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal