• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KJS-API

  • kjs
  • api
kjsprototype.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 2008 Harri Porten (porten@kde.org)
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#include "kjsprototype.h"
23#include "kjsinterpreter.h"
24#include "kjsarguments.h"
25#include "kjsprivate.h"
26
27#include "kjs/object.h"
28#include "kjs/JSVariableObject.h"
29#include "kjs/context.h"
30#include "kjs/interpreter.h"
31
32#include <QMap>
33
34using namespace KJS;
35
36class KJSCustomProperty
37{
38public:
39 KJSCustomProperty(KJSPrototype::PropertyGetter g,
40 KJSPrototype::PropertySetter s)
41 : getter(g), setter(s)
42 {
43 }
44
45 JSValue* read(ExecState* exec, void* object);
46 void write(ExecState* exec, void* object, JSValue* value);
47
48private:
49 KJSPrototype::PropertyGetter getter;
50 KJSPrototype::PropertySetter setter;
51};
52
53class CustomObjectInfo {
54public:
55 CustomObjectInfo(void* v): iv(v) {}
56 virtual ~CustomObjectInfo() {}
57 void* internalValue() { return iv; }
58protected:
59 void* iv;
60};
61
62template<class Base>
63class CustomObject : public Base, public CustomObjectInfo {
64public:
65 CustomObject(JSValue* proto, void* v)
66 : Base(proto),
67 CustomObjectInfo(v)
68 {}
69
70 using Base::put;
71 void put(ExecState* exec, const Identifier& id,
72 JSValue *value, int attr = None);
73
74
75 // rtti
76 static const ClassInfo info;
77 const ClassInfo* classInfo() const { return &info; }
78};
79
80template<>
81const ClassInfo CustomObject<JSObject>::info = { "CustomObject", 0, 0, 0 };
82
83template<>
84const ClassInfo CustomObject<JSGlobalObject>::info = { "CustomGlobalObject", 0, 0, 0 };
85
86class KJSCustomFunction : public JSObject {
87public:
88 KJSCustomFunction(ExecState* exec, KJSPrototype::FunctionCall f)
89 : callback(f)
90 {
91 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
92 }
93
94 JSValue* callAsFunction(ExecState* exec, JSObject* thisObj,
95 const List &args);
96 bool implementsCall() const { return true; }
97
98private:
99 KJSPrototype::FunctionCall callback;
100};
101
102JSValue* KJSCustomFunction::callAsFunction(ExecState* exec, JSObject* thisObj,
103 const List &args)
104{
105 // FIXME: does not protect against mixing custom objects
106 CustomObjectInfo* inf = dynamic_cast<CustomObjectInfo*>(thisObj);
107
108 if (!inf) {
109 const char* errMsg = "Attempt at calling a function with an invalid receiver";
110 KJS::JSObject *err = KJS::Error::create(exec, KJS::TypeError, errMsg);
111 exec->setException(err);
112 return err;
113 }
114
115 void* thisValue = inf->internalValue();
116
117 KJSContext ctx(EXECSTATE_HANDLE(exec));
118 KJSArguments a(LIST_HANDLE(&args));
119 KJSObject res = (*callback)(&ctx, thisValue, a);
120 return JSVALUE(&res);
121}
122
123JSValue* KJSCustomProperty::read(ExecState* exec, void* object)
124{
125 assert(getter);
126
127 KJSContext ctx(EXECSTATE_HANDLE(exec));
128 KJSObject res = (*getter)(&ctx, object);
129 return JSVALUE(&res);
130}
131
132void KJSCustomProperty::write(ExecState* exec, void* object, JSValue* value)
133{
134 KJSContext ctx(EXECSTATE_HANDLE(exec));
135
136 if (setter) {
137 KJSObject vo(JSVALUE_HANDLE(value));
138 (*setter)(&ctx, object, vo);
139 } else {
140 JSObject *e = Error::create(exec, GeneralError,
141 "Property is read-only");
142 exec->setException(e);
143 }
144}
145
146static JSValue* getPropertyValue(ExecState* exec, JSObject *originalObject,
147 const Identifier&, const PropertySlot& sl)
148{
149 CustomObjectInfo* inf = dynamic_cast<CustomObjectInfo*>(originalObject);
150 if (!inf)
151 return jsUndefined();
152
153 KJSCustomProperty* p =
154 reinterpret_cast<KJSCustomProperty*>(sl.customValue());
155
156 return p->read(exec, inf->internalValue());
157}
158
159// FIXME: or use Identifier?
160// FIXME: use values
161typedef QMap<UString, KJSCustomProperty*> CustomPropertyMap;
162
163class CustomPrototype : public JSObject {
164public:
165 CustomPrototype()
166 {
167 }
168 ~CustomPrototype()
169 {
170 qDeleteAll(properties);
171 }
172
173 using KJS::JSObject::getOwnPropertySlot;
174 bool getOwnPropertySlot(ExecState *exec, const Identifier& id,
175 PropertySlot& sl)
176 {
177 CustomPropertyMap::iterator it = properties.find(id.ustring());
178 if (it == properties.end())
179 return JSObject::getOwnPropertySlot(exec, id, sl);
180
181 sl.setCustomValue(0, *it, getPropertyValue);
182
183 return true;
184 }
185
186 void registerProperty(const QString& name,
187 KJSPrototype::PropertyGetter g,
188 KJSPrototype::PropertySetter s)
189 {
190 properties.insert(toUString(name), new KJSCustomProperty(g, s));
191 }
192
193 void registerFunction(ExecState* exec,
194 const QString& name, KJSPrototype::FunctionCall f)
195 {
196 putDirect(toIdentifier(name), new KJSCustomFunction(exec, f));
197 }
198
199 template<typename Base>
200 bool setProperty(ExecState* exec, CustomObject<Base>* obj,
201 const Identifier& id, JSValue* value)
202 {
203 CustomPropertyMap::iterator it = properties.find(id.ustring());
204 if (it == properties.end())
205 return false;
206
207 (*it)->write(exec, obj->internalValue(), value);
208
209 return true;
210 }
211
212private:
213 CustomPropertyMap properties;
214};
215
216template<class Base>
217void CustomObject<Base>::put(ExecState* exec, const Identifier& id,
218 JSValue* value, int attr)
219{
220 CustomPrototype* p = static_cast<CustomPrototype*>(this->prototype());
221
222 if (!p->setProperty(exec, this, id, value))
223 Base::put(exec, id, value, attr);
224}
225
226KJSPrototype::KJSPrototype()
227{
228 CustomPrototype* p = new CustomPrototype;
229 gcProtect(p);
230
231 hnd = PROTOTYPE_HANDLE(p);
232}
233
234KJSPrototype::~KJSPrototype()
235{
236 gcUnprotect(PROTOTYPE(this));
237}
238
239void KJSPrototype::defineConstant(const QString& name, double value)
240{
241 CustomPrototype* p = PROTOTYPE(this);
242
243 p->putDirect(toIdentifier(name), jsNumber(value),
244 DontEnum|DontDelete|ReadOnly);
245}
246
247void KJSPrototype::defineConstant(const QString& name, const QString& value)
248{
249 CustomPrototype* p = PROTOTYPE(this);
250
251 p->putDirect(toIdentifier(name), jsString(toUString(value)),
252 DontEnum|DontDelete|ReadOnly);
253}
254
255void KJSPrototype::defineConstant(const QString& name, const KJSObject& value)
256{
257 CustomPrototype* p = PROTOTYPE(this);
258
259 p->putDirect(toIdentifier(name), JSVALUE(&value),
260 DontEnum|DontDelete|ReadOnly);
261}
262
263KJSObject KJSPrototype::constructObject(KJSContext* ctx, void *internalValue)
264{
265 CustomPrototype* p = PROTOTYPE(this);
266
267 if (ctx && !p->prototype()) {
268 ExecState* exec = EXECSTATE(ctx);
269 KJS::Interpreter* i = exec->lexicalInterpreter();
270 JSObject* objectProto = i->builtinObjectPrototype();
271 p->setPrototype(objectProto);
272 }
273
274 CustomObject<JSObject>* newObj = new CustomObject<JSObject>(p, internalValue);
275 return KJSObject(JSVALUE_HANDLE(newObj));
276}
277
278KJSGlobalObject KJSPrototype::constructGlobalObject(void *internalValue)
279{
280 CustomPrototype* p = PROTOTYPE(this);
281
282 CustomObject<JSGlobalObject>* newObj = new CustomObject<JSGlobalObject>(p, internalValue);
283 return KJSGlobalObject(JSVALUE_HANDLE(newObj));
284}
285
286void KJSPrototype::defineProperty(KJSContext* ctx,
287 const QString& name,
288 PropertyGetter getter,
289 PropertySetter setter)
290{
291 Q_UNUSED(ctx);
292 assert(getter);
293
294 CustomPrototype* p = PROTOTYPE(this);
295
296 p->registerProperty(name, getter, setter);
297}
298
299void KJSPrototype::defineFunction(KJSContext* ctx,
300 const QString& name, FunctionCall callback)
301{
302 assert(callback);
303
304 CustomPrototype* p = PROTOTYPE(this);
305 ExecState* exec = EXECSTATE(ctx);
306
307 p->registerFunction(exec, name, callback);
308}
309
310
311// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
KJSArguments
A class representing a list of JavaScript arguments.
Definition: kjsarguments.h:37
KJSContext
A class representing a JavaScript execution context.
Definition: kjscontext.h:40
KJSGlobalObject
A class representing a global object of an execution environment.
Definition: kjsobject.h:281
KJSObject
A class representing a JavaScript value.
Definition: kjsobject.h:49
KJSPrototype::constructObject
KJSObject constructObject(KJSContext *ctx, void *internalValue=0)
Construct an object with this prototype and the specified internal value.
Definition: kjsprototype.cpp:263
KJSPrototype::defineProperty
void defineProperty(KJSContext *ctx, const QString &name, PropertyGetter getter, PropertySetter setter=0)
Defines a property of this prototype with C++ callback functions for getting and setting the property...
Definition: kjsprototype.cpp:286
KJSPrototype::PropertySetter
void(* PropertySetter)(KJSContext *context, void *object, KJSObject value)
Function signature for a property setter function.
Definition: kjsprototype.h:75
KJSPrototype::KJSPrototype
KJSPrototype()
Constructs a prototype object with its own prototype property set to the Object prototype.
Definition: kjsprototype.cpp:226
KJSPrototype::FunctionCall
KJSObject(* FunctionCall)(KJSContext *context, void *object, const KJSArguments &arguments)
Signature for function call callback function.
Definition: kjsprototype.h:92
KJSPrototype::PropertyGetter
KJSObject(* PropertyGetter)(KJSContext *context, void *object)
Function signature for a property getter function.
Definition: kjsprototype.h:70
KJSPrototype::defineConstant
void defineConstant(const QString &name, double value)
Add a read-only numerical property to this object.
Definition: kjsprototype.cpp:239
KJSPrototype::~KJSPrototype
~KJSPrototype()
Destructs this prototype object.
Definition: kjsprototype.cpp:234
KJSPrototype::constructGlobalObject
KJSGlobalObject constructGlobalObject(void *internalValue=0)
Similar to constructObject() but specialized on the construction of global objects.
Definition: kjsprototype.cpp:278
KJSPrototype::defineFunction
void defineFunction(KJSContext *ctx, const QString &name, FunctionCall callback)
Define a function.
Definition: kjsprototype.cpp:299
kjsarguments.h
kjsinterpreter.h
kjsprivate.h
LIST_HANDLE
#define LIST_HANDLE(l)
Definition: kjsprivate.h:42
PROTOTYPE_HANDLE
#define PROTOTYPE_HANDLE(p)
Definition: kjsprivate.h:39
PROTOTYPE
#define PROTOTYPE(h)
Definition: kjsprivate.h:40
JSVALUE_HANDLE
#define JSVALUE_HANDLE(v)
Definition: kjsprivate.h:30
EXECSTATE_HANDLE
#define EXECSTATE_HANDLE(c)
Definition: kjsprivate.h:33
toIdentifier
static KJS::Identifier toIdentifier(const QString &s)
Definition: kjsprivate.h:53
toUString
static KJS::UString toUString(const QString &s)
Definition: kjsprivate.h:45
EXECSTATE
#define EXECSTATE(ctx)
Definition: kjsprivate.h:34
JSVALUE
#define JSVALUE(h)
Definition: kjsprivate.h:31
getPropertyValue
static JSValue * getPropertyValue(ExecState *exec, JSObject *originalObject, const Identifier &, const PropertySlot &sl)
Definition: kjsprototype.cpp:146
CustomPropertyMap
QMap< UString, KJSCustomProperty * > CustomPropertyMap
Definition: kjsprototype.cpp:161
kjsprototype.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KJS-API

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

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal