00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _KJS_BINDING_H_
00023 #define _KJS_BINDING_H_
00024
00025 #include <kjs/interpreter.h>
00026 #include <kjs/function_object.h>
00027
00028 #include <dom/dom_node.h>
00029 #include <qvariant.h>
00030 #include <qptrdict.h>
00031 #include <kurl.h>
00032 #include <kjs/lookup.h>
00033
00034 namespace KParts {
00035 class ReadOnlyPart;
00036 class LiveConnectExtension;
00037 }
00038
00039 namespace khtml {
00040 class ChildFrame;
00041 }
00042
00043 namespace KJS {
00044
00050 class DOMObject : public ObjectImp {
00051 public:
00052 DOMObject(const Object &proto) : ObjectImp(proto) {}
00053 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00054 virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const
00055 { return ObjectImp::get(exec, propertyName); }
00056
00057 virtual void put(ExecState *exec, const Identifier &propertyName,
00058 const Value &value, int attr = None);
00059 virtual void tryPut(ExecState *exec, const Identifier &propertyName,
00060 const Value& value, int attr = None);
00061
00062 virtual UString toString(ExecState *exec) const;
00063 };
00064
00070 class DOMFunction : public InternalFunctionImp {
00071 public:
00072 DOMFunction(ExecState* exec) : InternalFunctionImp(
00073 static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
00074 ) {}
00075 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00076 virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const
00077 { return ObjectImp::get(exec, propertyName); }
00078
00079 virtual bool implementsCall() const { return true; }
00080 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00081
00082 virtual Value tryCall(ExecState *exec, Object &thisObj, const List&args)
00083 { return ObjectImp::call(exec, thisObj, args); }
00084 virtual bool toBoolean(ExecState *) const { return true; }
00085 };
00086
00092 class KDE_EXPORT ScriptInterpreter : public Interpreter
00093 {
00094 public:
00095 ScriptInterpreter( const Object &global, khtml::ChildFrame* frame );
00096 virtual ~ScriptInterpreter();
00097
00098 DOMObject* getDOMObject( void* objectHandle ) const {
00099 return m_domObjects[objectHandle];
00100 }
00101 void putDOMObject( void* objectHandle, DOMObject* obj ) {
00102 m_domObjects.insert( objectHandle, obj );
00103 }
00104 void customizedDOMObject( DOMObject* obj ) {
00105 m_customizedDomObjects.replace( obj, this );
00106 }
00107 bool deleteDOMObject( void* objectHandle ) {
00108 DOMObject* obj = m_domObjects.take( objectHandle );
00109 if (obj) {
00110 m_customizedDomObjects.remove( obj );
00111 return true;
00112 }
00113 else
00114 return false;
00115 }
00116 void clear() {
00117 m_customizedDomObjects.clear();
00118 m_domObjects.clear();
00119 }
00123 static void forgetDOMObject( void* objectHandle );
00124
00128 virtual void mark();
00129 KParts::ReadOnlyPart* part() const;
00130
00131 virtual int rtti() { return 1; }
00132
00136 void setCurrentEvent( DOM::Event *evt ) { m_evt = evt; }
00137 void setInlineCode( bool inlineCode ) { m_inlineCode = inlineCode; }
00138 void setProcessingTimerCallback( bool timerCallback ) { m_timerCallback = timerCallback; }
00142 bool isWindowOpenAllowed() const;
00143
00144 private:
00145 khtml::ChildFrame* m_frame;
00146 QPtrDict<DOMObject> m_domObjects;
00147 QPtrDict<void> m_customizedDomObjects;
00148
00149 DOM::Event *m_evt;
00150 bool m_inlineCode;
00151 bool m_timerCallback;
00152 };
00156 template<class DOMObj, class KJSDOMObj>
00157 inline Value cacheDOMObject(ExecState *exec, DOMObj domObj)
00158 {
00159 DOMObject *ret;
00160 if (domObj.isNull())
00161 return Null();
00162 ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
00163 if ((ret = interp->getDOMObject(domObj.handle())))
00164 return Value(ret);
00165 else {
00166 ret = new KJSDOMObj(exec, domObj);
00167 interp->putDOMObject(domObj.handle(),ret);
00168 return Value(ret);
00169 }
00170 }
00171
00175 DOM::Node toNode(const Value&);
00179 Value getString(DOM::DOMString s);
00180
00184 QVariant ValueToVariant(ExecState* exec, const Value& val);
00185
00190 template <class FuncImp, class ThisImp, class ParentImp>
00191 inline Value DOMObjectLookupGet(ExecState *exec, const Identifier &propertyName,
00192 const HashTable* table, const ThisImp* thisObj)
00193 {
00194 const HashEntry* entry = Lookup::findEntry(table, propertyName);
00195
00196 if (!entry)
00197 return thisObj->ParentImp::tryGet(exec, propertyName);
00198
00199 if (entry->attr & Function) {
00200 return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
00201 }
00202 return thisObj->getValueProperty(exec, entry->value);
00203 }
00204
00209 template <class ThisImp, class ParentImp>
00210 inline Value DOMObjectLookupGetValue(ExecState *exec, const Identifier &propertyName,
00211 const HashTable* table, const ThisImp* thisObj)
00212 {
00213 const HashEntry* entry = Lookup::findEntry(table, propertyName);
00214
00215 if (!entry)
00216 return thisObj->ParentImp::tryGet(exec, propertyName);
00217
00218 if (entry->attr & Function)
00219 fprintf(stderr, "Function bit set! Shouldn't happen in lookupValue!\n" );
00220 return thisObj->getValueProperty(exec, entry->value);
00221 }
00222
00227 template <class ThisImp, class ParentImp>
00228 inline void DOMObjectLookupPut(ExecState *exec, const Identifier &propertyName,
00229 const Value& value, int attr,
00230 const HashTable* table, ThisImp* thisObj)
00231 {
00232 const HashEntry* entry = Lookup::findEntry(table, propertyName);
00233
00234 if (!entry)
00235 thisObj->ParentImp::tryPut(exec, propertyName, value, attr);
00236 else if (entry->attr & Function)
00237 thisObj->ObjectImp::put(exec, propertyName, value, attr);
00238 else if (entry->attr & ReadOnly)
00239 #ifdef KJS_VERBOSE
00240 fprintf(stderr,"WARNING: Attempt to change value of readonly property '%s'\n",propertyName.ascii());
00241 #else
00242 ;
00243 #endif
00244 else
00245 thisObj->putValueProperty(exec, entry->value, value, attr);
00246 }
00247
00248
00249 #define IMPLEMENT_PROTOFUNC_DOM(ClassFunc) \
00250 namespace KJS { \
00251 class ClassFunc : public DOMFunction { \
00252 public: \
00253 ClassFunc(ExecState *exec, int i, int len) \
00254 : DOMFunction( exec ), id(i) { \
00255 Value protect(this); \
00256 put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum); \
00257 } \
00258 \
00259 virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args); \
00260 private: \
00261 int id; \
00262 }; \
00263 }
00264
00265 Value getLiveConnectValue(KParts::LiveConnectExtension *lc, const QString & name, const int type, const QString & value, int id);
00266
00267
00268
00269
00270
00271 #define DEFINE_PSEUDO_CONSTRUCTOR(ClassName) \
00272 class ClassName : public DOMObject { \
00273 public: \
00274 ClassName(ExecState *); \
00275 virtual const ClassInfo* classInfo() const { return &info; } \
00276 static const ClassInfo info; \
00277 static Object self(ExecState *exec); \
00278 };
00279
00280 #define IMPLEMENT_PSEUDO_CONSTRUCTOR_IMP(Class,ClassName,ProtoClass,ParentProto) \
00281 const ClassInfo Class::info = { ClassName, 0, 0, 0 }; \
00282 Class::Class(ExecState* exec): DOMObject(ParentProto) {\
00283 Object proto = ProtoClass::self(exec); \
00284 putDirect(prototypePropertyName, proto.imp(), DontDelete|ReadOnly); \
00285 }\
00286 Object Class::self(ExecState *exec) { \
00287 return Object(cacheGlobalObject<Class>(exec, "[[" ClassName ".constructor]]")); \
00288 }
00289
00290 #define IMPLEMENT_PSEUDO_CONSTRUCTOR(Class,ClassName,ProtoClass) \
00291 IMPLEMENT_PSEUDO_CONSTRUCTOR_IMP(Class,ClassName,ProtoClass,exec->lexicalInterpreter()->builtinObjectPrototype())
00292
00293 #define IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(Class,ClassName,ProtoClass,ParentProtoClass) \
00294 IMPLEMENT_PSEUDO_CONSTRUCTOR_IMP(Class,ClassName,ProtoClass,ParentProtoClass::self(exec))
00295
00296
00297 #define CREATE_CONSTANT_TABLE(Class,ClassName) \
00298 class Class : public DOMObject { \
00299 public: \
00300 Class(ExecState *exec): DOMObject(exec->interpreter()->builtinObjectPrototype()) {} \
00301 virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const { \
00302 return DOMObjectLookupGetValue<Class, DOMObject>(exec, propertyName, &Class##Table, this);\
00303 } \
00304 Value getValueProperty(ExecState * , int token) const { \
00305 \
00306 return Number((unsigned int)token); \
00307 } \
00308 virtual const ClassInfo* classInfo() const { return &info; } \
00309 static const ClassInfo info; \
00310 static Object self(ExecState *exec) { \
00311 return Object(cacheGlobalObject<Class>(exec, "[[" ClassName ".constant_table]]")); \
00312 } \
00313 }; \
00314 const ClassInfo Class::info = { ClassName, 0, &Class##Table, 0 };
00315
00316 }
00317
00318 #endif