00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _KJS_BINDING_H_
00022 #define _KJS_BINDING_H_
00023
00024 #include <kjs/interpreter.h>
00025 #include <dom/dom_node.h>
00026 #include <qvariant.h>
00027 #include <qptrdict.h>
00028 #include <kurl.h>
00029 #include <kjs/lookup.h>
00030
00031 class KHTMLPart;
00032
00033 namespace KJS {
00034
00040 class DOMObject : public ObjectImp {
00041 public:
00042 DOMObject(const Object &proto) : ObjectImp(proto) {}
00043 virtual Value get(ExecState *exec, const UString &propertyName) const;
00044 virtual Value tryGet(ExecState *exec, const UString &propertyName) const
00045 { return ObjectImp::get(exec, propertyName); }
00046
00047 virtual void put(ExecState *exec, const UString &propertyName,
00048 const Value &value, int attr = None);
00049 virtual void tryPut(ExecState *exec, const UString &propertyName,
00050 const Value& value, int attr = None)
00051 { ObjectImp::put(exec,propertyName,value,attr); }
00052
00053 virtual UString toString(ExecState *exec) const;
00054 };
00055
00061 class DOMFunction : public ObjectImp {
00062 public:
00063 DOMFunction() : ObjectImp( ) {}
00064 virtual Value get(ExecState *exec, const UString &propertyName) const;
00065 virtual Value tryGet(ExecState *exec, const UString &propertyName) const
00066 { return ObjectImp::get(exec, propertyName); }
00067
00068 virtual bool implementsCall() const { return true; }
00069 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00070
00071 virtual Value tryCall(ExecState *exec, Object &thisObj, const List&args)
00072 { return ObjectImp::call(exec, thisObj, args); }
00073 virtual bool toBoolean(ExecState *) const { return true; }
00074 virtual Value toPrimitive(ExecState *exec, Type) const { return String(toString(exec)); }
00075 virtual UString toString(ExecState *) const { return UString("[function]"); }
00076 };
00077
00083 class ScriptInterpreter : public Interpreter
00084 {
00085 public:
00086 ScriptInterpreter( const Object &global, KHTMLPart* part );
00087 virtual ~ScriptInterpreter();
00088
00089 DOMObject* getDOMObject( void* objectHandle ) const {
00090 return m_domObjects[objectHandle];
00091 }
00092 void putDOMObject( void* objectHandle, DOMObject* obj ) {
00093 m_domObjects.insert( objectHandle, obj );
00094 }
00095 bool deleteDOMObject( void* objectHandle ) {
00096 return m_domObjects.remove( objectHandle );
00097 }
00098 void clear() {
00099 m_domObjects.clear();
00100 }
00104 static void forgetDOMObject( void* objectHandle );
00105
00109 virtual void mark();
00110 KHTMLPart* part() const { return m_part; }
00111
00112 virtual int rtti() { return 1; }
00113
00117 void setCurrentEvent( DOM::Event *evt ) { m_evt = evt; }
00118 void setInlineCode( bool inlineCode ) { m_inlineCode = inlineCode; }
00119 void setProcessingTimerCallback( bool timerCallback ) { m_timerCallback = timerCallback; }
00123 bool isWindowOpenAllowed() const;
00124
00125 private:
00126 KHTMLPart* m_part;
00127 QPtrDict<DOMObject> m_domObjects;
00128 DOM::Event *m_evt;
00129 bool m_inlineCode;
00130 bool m_timerCallback;
00131 };
00135 template<class DOMObj, class KJSDOMObj>
00136 inline Value cacheDOMObject(ExecState *exec, DOMObj domObj)
00137 {
00138 DOMObject *ret;
00139 if (domObj.isNull())
00140 return Null();
00141 ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
00142 if ((ret = interp->getDOMObject(domObj.handle())))
00143 return Value(ret);
00144 else {
00145 ret = new KJSDOMObj(exec, domObj);
00146 interp->putDOMObject(domObj.handle(),ret);
00147 return Value(ret);
00148 }
00149 }
00150
00154 DOM::Node toNode(const Value&);
00158 Value getString(DOM::DOMString s);
00159
00163 QVariant ValueToVariant(ExecState* exec, const Value& val);
00164
00169 template <class FuncImp, class ThisImp, class ParentImp>
00170 inline Value DOMObjectLookupGet(ExecState *exec, const UString &propertyName,
00171 const HashTable* table, const ThisImp* thisObj)
00172 {
00173 const HashEntry* entry = Lookup::findEntry(table, propertyName);
00174
00175 if (!entry)
00176 return thisObj->ParentImp::tryGet(exec, propertyName);
00177
00178 if (entry->attr & Function)
00179 return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
00180 return thisObj->getValueProperty(exec, entry->value);
00181 }
00182
00187 template <class ThisImp, class ParentImp>
00188 inline Value DOMObjectLookupGetValue(ExecState *exec, const UString &propertyName,
00189 const HashTable* table, const ThisImp* thisObj)
00190 {
00191 const HashEntry* entry = Lookup::findEntry(table, propertyName);
00192
00193 if (!entry)
00194 return thisObj->ParentImp::tryGet(exec, propertyName);
00195
00196 if (entry->attr & Function)
00197 fprintf(stderr, "Function bit set! Shouldn't happen in lookupValue!\n" );
00198 return thisObj->getValueProperty(exec, entry->value);
00199 }
00200
00205 template <class ThisImp, class ParentImp>
00206 inline void DOMObjectLookupPut(ExecState *exec, const UString &propertyName,
00207 const Value& value, int attr,
00208 const HashTable* table, ThisImp* thisObj)
00209 {
00210 const HashEntry* entry = Lookup::findEntry(table, propertyName);
00211
00212 if (!entry)
00213 thisObj->ParentImp::tryPut(exec, propertyName, value, attr);
00214 else if (entry->attr & Function)
00215 thisObj->ObjectImp::put(exec, propertyName, value, attr);
00216 else if (entry->attr & ReadOnly)
00217 #ifdef KJS_VERBOSE
00218 fprintf(stderr,"Attempt to change value of readonly property '%s'\n",propertyName.ascii());
00219 #else
00220 ;
00221 #endif
00222 else
00223 thisObj->putValueProperty(exec, entry->value, value, attr);
00224 }
00225
00226
00227 #define IMPLEMENT_PROTOFUNC_DOM(ClassFunc) \
00228 namespace KJS { \
00229 class ClassFunc : public DOMFunction { \
00230 public: \
00231 ClassFunc(ExecState *exec, int i, int len) \
00232 : DOMFunction( ), id(i) { \
00233 Value protect(this); \
00234 put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum); \
00235 } \
00236 \
00237 virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args); \
00238 private: \
00239 int id; \
00240 }; \
00241 }
00242
00243 }
00244
00245 #endif