summaryrefslogtreecommitdiffstats
path: root/ksvg/ecma
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit47d455dd55be855e4cc691c32f687f723d9247ee (patch)
tree52e236aaa2576bdb3840ebede26619692fed6d7d /ksvg/ecma
downloadtdegraphics-47d455dd55be855e4cc691c32f687f723d9247ee.tar.gz
tdegraphics-47d455dd55be855e4cc691c32f687f723d9247ee.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegraphics@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksvg/ecma')
-rw-r--r--ksvg/ecma/Makefile.am7
-rw-r--r--ksvg/ecma/ksvg_bridge.h103
-rw-r--r--ksvg/ecma/ksvg_cacheimpl.h65
-rw-r--r--ksvg/ecma/ksvg_ecma.cpp336
-rw-r--r--ksvg/ecma/ksvg_ecma.h114
-rw-r--r--ksvg/ecma/ksvg_ecmaeventlistener.cpp99
-rw-r--r--ksvg/ecma/ksvg_ecmaeventlistener.h54
-rw-r--r--ksvg/ecma/ksvg_helper.cpp68
-rw-r--r--ksvg/ecma/ksvg_lookup.h318
-rw-r--r--ksvg/ecma/ksvg_scriptinterpreter.cpp92
-rw-r--r--ksvg/ecma/ksvg_scriptinterpreter.h71
-rw-r--r--ksvg/ecma/ksvg_window.cpp578
-rw-r--r--ksvg/ecma/ksvg_window.h122
13 files changed, 2027 insertions, 0 deletions
diff --git a/ksvg/ecma/Makefile.am b/ksvg/ecma/Makefile.am
new file mode 100644
index 00000000..b3eea2b5
--- /dev/null
+++ b/ksvg/ecma/Makefile.am
@@ -0,0 +1,7 @@
+INCLUDES = $(FREETYPE_CFLAGS) -I$(top_srcdir)/ksvg/dom -I$(top_srcdir)/ksvg/impl -I$(top_srcdir)/ksvg/core -I$(top_srcdir)/ksvg/data -I$(top_srcdir)/ksvg/impl/libs/libtext2path/src $(all_includes)
+METASOURCES = AUTO
+KDE_CXXFLAGS = $(USE_EXCEPTIONS)
+
+noinst_LTLIBRARIES = libksvgecma.la
+
+libksvgecma_la_SOURCES = ksvg_scriptinterpreter.cpp ksvg_ecma.cpp ksvg_helper.cpp ksvg_ecmaeventlistener.cpp ksvg_window.cpp
diff --git a/ksvg/ecma/ksvg_bridge.h b/ksvg/ecma/ksvg_bridge.h
new file mode 100644
index 00000000..784dea15
--- /dev/null
+++ b/ksvg/ecma/ksvg_bridge.h
@@ -0,0 +1,103 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSVGBridge_H
+#define KSVGBridge_H
+
+#include <kdebug.h>
+
+#include <kjs/object.h>
+#include <kjs/lookup.h>
+#include <kjs/interpreter.h> // for ExecState
+
+namespace KJS
+{
+ class Value;
+ class UString;
+ class ExecState;
+}
+
+// Base class for all bridges
+// The T class must provide prototype(exec), get and hasProperty
+// and have a static s_classInfo object
+template<class T>
+class KSVGBridge : public KJS::ObjectImp
+{
+public:
+ KSVGBridge(KJS::ExecState *exec, T *impl) : KJS::ObjectImp(impl->prototype(exec)), m_impl(impl) { }
+
+ T *impl() const { return m_impl; }
+
+ virtual KJS::Value get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const
+ {
+ kdDebug(26004) << "KSVGBridge::get(), " << propertyName.qstring() << " Name: " << classInfo()->className << " Object: " << m_impl << endl;
+
+ // Look for standard properties (e.g. those in the hashtables)
+ KJS::Value val = m_impl->get(exec, propertyName, this);
+
+ if(val.type() != KJS::UndefinedType)
+ return val;
+
+ // Not found -> forward to ObjectImp.
+ val = KJS::ObjectImp::get(exec, propertyName);
+ if(val.type() == KJS::UndefinedType)
+ kdDebug(26004) << "WARNING: " << propertyName.qstring() << " not found in... Name: " << classInfo()->className << " Object: " << m_impl << " on line : " << exec->context().curStmtFirstLine() << endl;
+ return val;
+ }
+
+ virtual bool hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const
+ {
+ kdDebug(26004) << "KSVGBridge::hasProperty(), " << propertyName.qstring() << " Name: " << classInfo()->className << " Object: " << m_impl << endl;
+
+ if(m_impl->hasProperty(exec, propertyName))
+ return true;
+
+ return KJS::ObjectImp::hasProperty(exec, propertyName);
+ }
+
+ virtual const KJS::ClassInfo *classInfo() const { return &T::s_classInfo; }
+
+protected:
+ T *m_impl;
+};
+
+// Base class for readwrite bridges
+// T must also implement put (use KSVG_PUT in the header file)
+template<class T>
+class KSVGRWBridge : public KSVGBridge<T>
+{
+public:
+ KSVGRWBridge(KJS::ExecState *exec, T *impl) : KSVGBridge<T>(exec, impl) { }
+
+ virtual void put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value &value, int attr)
+ {
+// if(!(attr & KJS::Internal))
+// kdDebug(26004) << "KSVGBridge::put(), " << propertyName.qstring() << " Name: " << classInfo()->className << " Object: " << m_impl << endl;
+
+ // Try to see if we know this property (and need to take special action)
+ if(this->m_impl->put(exec, propertyName, value, attr))
+ return;
+
+ // We don't -> set property in ObjectImp.
+ KJS::ObjectImp::put(exec, propertyName, value, attr);
+ }
+};
+
+#endif
diff --git a/ksvg/ecma/ksvg_cacheimpl.h b/ksvg/ecma/ksvg_cacheimpl.h
new file mode 100644
index 00000000..1140f1b4
--- /dev/null
+++ b/ksvg/ecma/ksvg_cacheimpl.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSVGCacheImpl_H
+#define KSVGCacheImpl_H
+
+#include "ksvg_scriptinterpreter.h"
+
+// Lookup or create JS object around an existing "DOM Object"
+template<class DOMObj, class KJSDOMObj>
+inline KJS::Value cacheDOMObject(KJS::ExecState *exec, DOMObj *domObj)
+{
+ KJS::ObjectImp *ret;
+ if(!domObj)
+ return KJS::Null();
+
+ KSVGScriptInterpreter *interp = static_cast<KSVGScriptInterpreter *>(exec->interpreter());
+ if((ret = interp->getDOMObject(domObj)))
+ return KJS::Value(ret);
+ else
+ {
+ ret = new KJSDOMObj(exec, domObj);
+ interp->putDOMObject(domObj, ret);
+ return KJS::Value(ret);
+ }
+}
+
+// Lookup or create singleton Impl object, and return a unique bridge object for it.
+// (Very much like KJS::cacheGlobalObject, which is for a singleton ObjectImp)
+// This one is mostly used for Constructor objects.
+template <class ClassCtor>
+inline KJS::Object cacheGlobalBridge(KJS::ExecState *exec, const KJS::Identifier &propertyName)
+{
+ KJS::ValueImp *obj = static_cast<KJS::ObjectImp*>(exec->interpreter()->globalObject().imp())->getDirect(propertyName);
+ if(obj)
+ return KJS::Object::dynamicCast(KJS::Value(obj));
+ else
+ {
+ ClassCtor* ctor = new ClassCtor(exec); // create the ClassCtor instance
+ KJS::Object newObject(new KSVGBridge<ClassCtor>(exec, ctor)); // create the bridge around it
+ exec->interpreter()->globalObject().put(exec, propertyName, newObject, KJS::Internal);
+ return newObject;
+ }
+}
+
+#endif
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_ecma.cpp b/ksvg/ecma/ksvg_ecma.cpp
new file mode 100644
index 00000000..a2aed6ce
--- /dev/null
+++ b/ksvg/ecma/ksvg_ecma.cpp
@@ -0,0 +1,336 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <kdebug.h>
+
+#include <qvariant.h>
+
+#include <dom/dom2_events.h>
+
+#include "SVGEcma.h"
+
+#include "SVGDocumentImpl.h"
+
+#include "ksvg_ecma.h"
+#include "ksvg_window.h"
+#include "ksvg_scriptinterpreter.h"
+#include "ksvg_ecmaeventlistener.h"
+
+#include "KSVGLoader.h"
+
+using namespace KSVG;
+using namespace KJS;
+
+class AsyncStatus : public ObjectImp
+{
+public:
+ AsyncStatus() : ObjectImp() { }
+
+ virtual bool implementsCall() const { return true; }
+ virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+};
+
+Value AsyncStatus::call(ExecState *exec, Object &, const List &args)
+{
+ kdDebug(26004) << "[AsyncStatus] " << args[0].toString(exec).ascii() << endl;
+
+ if(args[0].toString(exec) == "success")
+ return Number(1);
+ else
+ return Undefined();
+}
+
+KSVGEcma::KSVGEcma(SVGDocumentImpl *doc) : m_doc(doc)
+{
+ m_init = false;
+ m_hasListeners = false;
+
+ m_window = 0;
+ m_interpreter = 0;
+
+ m_ecmaEventListeners.setAutoDelete(true);
+}
+
+KSVGEcma::~KSVGEcma()
+{
+ // We are 0 soon so event listeners may NOT call us
+ QPtrListIterator<KSVGEcmaEventListener> it(m_ecmaEventListeners);
+ for(; it.current(); ++it)
+ it.current()->forbidRemove();
+
+ if(m_interpreter)
+ delete m_interpreter;
+}
+
+bool KSVGEcma::initialized()
+{
+ return m_init;
+}
+
+void KSVGEcma::setup()
+{
+ if(m_init)
+ return;
+
+ m_init = true;
+
+ // Create handler for js calls
+ m_window = new KSVG::Window(m_doc);
+ Object globalObject(m_window);
+
+ // Create code interpreter
+ m_interpreter = new KSVGScriptInterpreter(globalObject, m_doc);
+
+ // Set object prototype for global object
+ m_window->setPrototype(m_interpreter->builtinObjectPrototype());
+
+ // Create bridge for document. Could be done on demand now, though
+ KSVGBridge<SVGDocumentImpl> *documentRequest = new KSVGBridge<SVGDocumentImpl>(m_interpreter->globalExec(), m_doc);
+ documentRequest->ref();
+
+ m_interpreter->putDOMObject(m_doc->handle(), documentRequest);
+}
+
+Completion KSVGEcma::evaluate(const UString &code, const Value &thisV)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KSVGEcma::evaluate " << code.qstring() << endl;
+#endif
+
+ return m_interpreter->evaluate(code, thisV);
+}
+
+Object KSVGEcma::globalObject()
+{
+ return m_interpreter->globalObject();
+}
+
+ExecState *KSVGEcma::globalExec()
+{
+ return m_interpreter->globalExec();
+}
+
+SVGEventListener *KSVGEcma::createEventListener(DOM::DOMString type)
+{
+ QPtrListIterator<KSVGEcmaEventListener> it(m_ecmaEventListeners);
+
+ for(; it.current(); ++it)
+ {
+ if(it.current()->type() == type.string())
+ return static_cast<SVGEventListener *>(it.current());
+ }
+
+ setup();
+
+ Object constr = m_interpreter->builtinFunction();
+
+ List args;
+ args.append(String("event"));
+ args.append(String(type.string()));
+
+ Object obj = constr.construct(m_interpreter->globalExec(), args);
+
+ // Note that the KSVGEcmaEventListener constructor adds itself to the m_ecmaEventListeners list
+ KSVGEcmaEventListener *event = new KSVGEcmaEventListener(obj, type.string(), this);
+ event->ref();
+
+ // addEventListener() is called by KSVGEcmaListeners ctor, so it's
+ // safe to check to count of the eventListeners list (Niko)
+ if(m_ecmaEventListeners.count() > 0)
+ m_hasListeners = true;
+
+ return event;
+}
+
+QString KSVGEcma::valueOfEventListener(SVGEventListener *listener) const
+{
+ KSVGEcmaEventListener *event = static_cast<KSVGEcmaEventListener *>(listener);
+ if(!event)
+ return QString::null;
+
+ return event->type();
+}
+
+void KSVGEcma::addEventListener(KSVGEcmaEventListener *listener)
+{
+ m_ecmaEventListeners.append(listener);
+}
+
+void KSVGEcma::removeEventListener(KSVGEcmaEventListener *listener)
+{
+ m_ecmaEventListeners.take(m_ecmaEventListeners.find(listener));
+
+ if(m_ecmaEventListeners.count() == 0)
+ m_hasListeners = false;
+}
+
+bool KSVGEcma::hasEventListeners()
+{
+ return m_hasListeners;
+}
+
+void KSVGEcma::finishedWithEvent(SVGEventImpl *event)
+{
+ KSVGScriptInterpreter *interpreter = static_cast<KSVGScriptInterpreter *>(globalExec()->interpreter());
+ interpreter->removeDOMObject(event);
+}
+
+Value KSVGEcma::getUrl(ExecState *exec, ::KURL url)
+{
+ Object *status = new Object(new AsyncStatus());
+
+ // FIXME: Security issue, allows local testing of getURL(), REMOVE BEFORE RELEASE! (Niko)
+ QString svgDocument = KSVGLoader::getUrl(url, true);
+ if(svgDocument.length() > 0)
+ {
+ status->put(exec, Identifier("success"), Boolean(true));
+ status->put(exec, Identifier("content"), String(svgDocument));
+ }
+ else
+ {
+ status->put(exec, Identifier("success"), Boolean(false));
+ status->put(exec, Identifier("content"), String(""));
+ }
+
+ return Value(*status);
+}
+
+void KSVGEcma::postUrl(ExecState *exec, ::KURL url, const QString &data, const QString &mimeType, const QString &contentEncoding, Object &callBackFunction)
+{
+ Object *status = new Object(new AsyncStatus());
+ status->put(exec, Identifier("content"), String(""));
+ status->put(exec, Identifier("success"), Boolean(false));
+
+ QByteArray byteArray;
+ QDataStream ds(byteArray, IO_WriteOnly);
+ ds << data;
+
+ // Support gzip compression
+ if(contentEncoding == "gzip" || contentEncoding == "deflate")
+ byteArray = qCompress(byteArray);
+
+ KSVGLoader *loader = new KSVGLoader();
+ loader->postUrl(url, byteArray, mimeType, exec, callBackFunction, *status);
+ delete loader;
+}
+
+// Helpers
+Value KSVG::getDOMNode(ExecState *exec, DOM::Node n)
+{
+ ObjectImp *ret = 0;
+ if(n.isNull())
+ return Null();
+
+ KSVGScriptInterpreter *interpreter = static_cast<KSVGScriptInterpreter *>(exec->interpreter());
+
+ ObjectImp *request = interpreter->getDOMObject(n.handle());
+ if(request)
+ return Value(request);
+
+ SVGElementImpl *elem = 0;
+
+ switch(n.nodeType())
+ {
+ case DOM::Node::ELEMENT_NODE:
+ elem = interpreter->document()->getElementFromHandle(n.handle());
+ if(!elem)
+ {
+ // Lookup different document, if possible
+ SVGDocumentImpl *different = interpreter->document()->getDocumentFromHandle(n.ownerDocument().handle());
+
+ if(!different)
+ return Null();
+
+ elem = different->getElementFromHandle(n.handle());
+
+ if(!elem)
+ return Null();
+ }
+
+ // The generated bridge() function does not ref the ret itself
+ ret = elem->bridge(exec);
+ ret->ref();
+ break;
+ case DOM::Node::TEXT_NODE:
+ ret = new KSVGRWBridge<SVGDOMTextBridge>(exec, new SVGDOMTextBridge(n));
+ ret->ref();
+ break;
+ default:
+ ret = new KSVGBridge<SVGDOMNodeBridge>(exec, new SVGDOMNodeBridge(n));
+ ret->ref();
+ break;
+ }
+
+ interpreter->putDOMObject(n.handle(), ret);
+
+ return Value(ret);
+}
+
+Value KSVG::getDOMEvent(ExecState *exec, SVGEventImpl *e)
+{
+ return e->cache(exec);
+}
+
+Value KSVG::getString(DOM::DOMString s)
+{
+ if(s.isNull())
+ return Null();
+ else
+ return String(s);
+}
+
+DOM::Node KSVG::toNode(const Value &val)
+{
+ Object obj = Object::dynamicCast(val);
+ if(obj.isNull())
+ return DOM::Node();
+
+ SVGDOMNodeBridge *bridge = toNodeBridge(static_cast<ObjectImp *>(obj.imp()));
+
+ if(bridge)
+ return bridge->impl();
+
+ return DOM::Node();
+}
+
+QVariant KSVG::valueToVariant(ExecState *exec, const Value &val)
+{
+ QVariant res;
+
+ switch(val.type())
+ {
+ case BooleanType:
+ res = QVariant(val.toBoolean(exec), 0);
+ break;
+ case NumberType:
+ res = QVariant(val.toNumber(exec));
+ break;
+ case StringType:
+ res = QVariant(val.toString(exec).qstring());
+ break;
+ default:
+ // everything else will be 'invalid'
+ break;
+ }
+
+ return res;
+}
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_ecma.h b/ksvg/ecma/ksvg_ecma.h
new file mode 100644
index 00000000..7c236454
--- /dev/null
+++ b/ksvg/ecma/ksvg_ecma.h
@@ -0,0 +1,114 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSVGEcma_H
+#define KSVGEcma_H
+
+#include <qptrlist.h>
+
+#include "ksvg_bridge.h"
+
+namespace DOM
+{
+ class Node;
+ class DOMString;
+}
+
+namespace KJS
+{
+ class Value;
+ class Object;
+ class UString;
+ class ExecState;
+ class Completion;
+}
+
+namespace KSVG
+{
+ class Window;
+ class SVGEventImpl;
+ class SVGDocumentImpl;
+ class SVGEventListener;
+ class SVGDOMNodeBridge;
+}
+
+class QVariant;
+
+class KSVGEcmaEventListener;
+class KSVGScriptInterpreter;
+
+typedef KSVGBridge<KSVG::SVGEventImpl> KSVGEcmaEvent;
+
+// Helpers
+namespace KSVG
+{
+ KJS::Value getDOMNode(KJS::ExecState *, DOM::Node);
+ KJS::Value getDOMEvent(KJS::ExecState *, KSVG::SVGEventImpl *);
+ KJS::Value getString(DOM::DOMString);
+
+ QVariant valueToVariant(KJS::ExecState *, const KJS::Value &);
+
+ DOM::Node toNode(const KJS::Value &);
+
+ // This one is part of generateddata.cpp
+ SVGDOMNodeBridge *toNodeBridge(const KJS::ObjectImp *);
+}
+
+class KSVGEcma
+{
+public:
+ KSVGEcma(KSVG::SVGDocumentImpl *doc);
+ ~KSVGEcma();
+
+ void setup();
+ bool initialized();
+
+ KJS::Completion evaluate(const KJS::UString &code, const KJS::Value &thisV);
+
+ KJS::Object globalObject();
+ KJS::ExecState *globalExec();
+
+ KSVGScriptInterpreter *interpreter() { return m_interpreter; }
+
+ KSVG::SVGEventListener *createEventListener(DOM::DOMString type);
+ QString valueOfEventListener(KSVG::SVGEventListener *listener) const;
+ void addEventListener(KSVGEcmaEventListener *listener);
+ void removeEventListener(KSVGEcmaEventListener *listener);
+ bool hasEventListeners();
+
+ void finishedWithEvent(KSVG::SVGEventImpl *event);
+
+ KJS::Value getUrl(KJS::ExecState *exec, ::KURL url);
+ void postUrl(KJS::ExecState *exec, ::KURL url, const QString &data, const QString &mimeType, const QString &contentEncoding, KJS::Object &callBackFunction);
+
+private:
+ bool m_init, m_hasListeners;
+
+ KSVG::SVGDocumentImpl *m_doc;
+
+ KSVG::Window *m_window;
+ KSVGScriptInterpreter *m_interpreter;
+ QPtrList<KSVGEcmaEventListener> m_ecmaEventListeners;
+
+};
+
+#endif
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_ecmaeventlistener.cpp b/ksvg/ecma/ksvg_ecmaeventlistener.cpp
new file mode 100644
index 00000000..4b59f924
--- /dev/null
+++ b/ksvg/ecma/ksvg_ecmaeventlistener.cpp
@@ -0,0 +1,99 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <kdebug.h>
+
+#include <qvariant.h>
+
+#include "SVGDocumentImpl.h"
+#include "SVGSVGElementImpl.h"
+
+#include "ksvg_ecma.h"
+#include "ksvg_scriptinterpreter.h"
+#include "ksvg_ecmaeventlistener.h"
+
+using namespace KSVG;
+using namespace KJS;
+
+KSVGEcmaEventListener::KSVGEcmaEventListener(KJS::Object _listener, QString _type, KSVGEcma *_ecma) : SVGEventListener()
+{
+ m_listener = _listener;
+ m_remove = true;
+ m_type = _type;
+ m_ecma = _ecma;
+
+ m_ecma->addEventListener(this);
+}
+
+KSVGEcmaEventListener::~KSVGEcmaEventListener()
+{
+ if(m_remove)
+ m_ecma->removeEventListener(this);
+}
+
+void KSVGEcmaEventListener::forbidRemove()
+{
+ m_remove = false;
+}
+
+void KSVGEcmaEventListener::handleEvent(SVGEventImpl *evt)
+{
+ if(m_ecma && m_listener.implementsCall())
+ {
+ KSVGScriptInterpreter *interpreter = m_ecma->interpreter();
+ ExecState *exec = m_ecma->globalExec();
+
+ // Append 'evt'
+ List args;
+ args.append(getDOMEvent(exec, evt));
+
+ // Set current event
+ interpreter->setCurrentEvent(evt);
+
+ // Call it!
+ Object thisObj = Object::dynamicCast(getDOMNode(exec, *evt->currentTarget()));
+ Value retval = m_listener.call(exec, thisObj, args);
+
+ interpreter->setCurrentEvent(0);
+
+ if(exec->hadException())
+ {
+ exec->clearException();
+
+ // onerror support
+ SVGSVGElementImpl *rootElement = static_cast<KSVGScriptInterpreter *>(exec->interpreter())->document()->rootElement();
+ if(rootElement)
+ rootElement->dispatchEvent(SVGEvent::ERROR_EVENT, true, false);
+ }
+ else
+ {
+ QVariant ret = valueToVariant(exec, retval);
+ if(ret.type() == QVariant::Bool && ret.toBool() == false)
+ evt->preventDefault();
+ }
+ }
+}
+
+DOM::DOMString KSVGEcmaEventListener::eventListenerType()
+{
+ return "KSVGEcmaEventListener - " + m_type;
+}
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_ecmaeventlistener.h b/ksvg/ecma/ksvg_ecmaeventlistener.h
new file mode 100644
index 00000000..16ebe3bc
--- /dev/null
+++ b/ksvg/ecma/ksvg_ecmaeventlistener.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSVGEcmaEventListener_H
+#define KSVGEcmaEventListener_H
+
+#include "SVGEventImpl.h"
+
+namespace KJS
+{
+ class Object;
+}
+
+class KSVGEcmaEventListener : public KSVG::SVGEventListener
+{
+public:
+ KSVGEcmaEventListener(KJS::Object _listener, QString _type, KSVGEcma *_ecma);
+ virtual ~KSVGEcmaEventListener();
+
+ virtual void handleEvent(KSVG::SVGEventImpl *evt);
+ virtual DOM::DOMString eventListenerType();
+
+ QString type() { return m_type; }
+
+ void forbidRemove();
+
+private:
+ KSVGEcma *m_ecma;
+ QString m_type;
+ bool m_remove;
+
+ KJS::Object m_listener;
+};
+
+#endif
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_helper.cpp b/ksvg/ecma/ksvg_helper.cpp
new file mode 100644
index 00000000..597f9a06
--- /dev/null
+++ b/ksvg/ecma/ksvg_helper.cpp
@@ -0,0 +1,68 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <kjs/ustring.h>
+#include <kjs/identifier.h>
+
+#include <dom/dom_string.h>
+
+KJS::UString::UString(const DOM::DOMString &d)
+{
+ if(d.isNull())
+ {
+ attach(&Rep::null);
+ return;
+ }
+
+ unsigned int len = d.length();
+ KJS::UChar *dat = new UChar[len];
+ memcpy(dat, d.unicode(), len * sizeof(UChar));
+ rep = KJS::UString::Rep::create(dat, len);
+}
+
+KJS::UString::UString(const QString &d)
+{
+ unsigned int len = d.length();
+ KJS::UChar *dat = new UChar[len];
+ memcpy(dat, d.unicode(), len * sizeof(UChar));
+ rep = KJS::UString::Rep::create(dat, len);
+}
+
+QString KJS::UString::qstring() const
+{
+ return QString(reinterpret_cast<QChar *>(const_cast<KJS::UChar *>(data())), size());
+}
+
+DOM::DOMString KJS::UString::string() const
+{
+ return DOM::DOMString(reinterpret_cast<QChar *>(const_cast<KJS::UChar *>(data())), size());
+}
+
+DOM::DOMString KJS::Identifier::string() const
+{
+ return DOM::DOMString((QChar*) data(), size());
+}
+
+QString KJS::Identifier::qstring() const
+{
+ return QString((QChar*) data(), size());
+}
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_lookup.h b/ksvg/ecma/ksvg_lookup.h
new file mode 100644
index 00000000..11c41462
--- /dev/null
+++ b/ksvg/ecma/ksvg_lookup.h
@@ -0,0 +1,318 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSVG_LOOKUP_H
+#define KSVG_LOOKUP_H
+
+#include <kjs/object.h>
+#include <kjs/lookup.h>
+#include <kjs/interpreter.h> // for ExecState
+
+#include "ksvg_bridge.h"
+#include "ksvg_scriptinterpreter.h"
+
+#define KSVG_GET_COMMON \
+public: \
+ \
+ /* The standard hasProperty call, auto-generated. Looks in hashtable, forwards to parents. */ \
+ bool hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
+ \
+ /* get() method, called by KSVGBridge::get */ \
+ KJS::Value get(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::ObjectImp* bridge) const; \
+ \
+ /* Called by lookupGet(). Auto-generated. Forwards to the parent which has the given property. */ \
+ KJS::Value getInParents(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::ObjectImp* bridge) const; \
+ \
+ KJS::Object prototype(KJS::ExecState *exec) const;\
+ \
+ static const KJS::ClassInfo s_classInfo; \
+ \
+ static const struct KJS::HashTable s_hashTable; \
+ \
+ int m_attrFlags;
+
+// For classes with properties to read, and a hashtable.
+#define KSVG_GET \
+ KSVG_GET_COMMON \
+ KJS::Value cache(KJS::ExecState *exec) const;
+
+// Same thing, for base classes (kalyptus helps finding them)
+// The difference is that cache() is virtual
+#define KSVG_BASECLASS_GET \
+ KSVG_GET_COMMON \
+ virtual KJS::Value cache(KJS::ExecState *exec) const;
+
+// For classes without properties, but with a parent class to forward to
+#define KSVG_FORWARDGET \
+public: \
+ \
+ bool hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
+ \
+ /* will have the code for getInParents */ \
+ KJS::Value get(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::ObjectImp* bridge) const; \
+ \
+ KJS::Object prototype(KJS::ExecState *exec) const;\
+ \
+ static const KJS::ClassInfo s_classInfo; \
+ \
+ KJS::Value cache(KJS::ExecState *exec) const;
+
+// For read-write classes only, i.e. those which support put()
+#define KSVG_PUT \
+ \
+ /* put() method, called by KSVGBridge::put */ \
+ bool put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value &value, int attr); \
+ \
+ /* Called by lookupPut. Auto-generated. Looks in hashtable, forwards to parents. */ \
+ bool putInParents(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value &value, int attr);
+
+// For classes which inherit a read-write class, but have no readwrite property themselves
+#define KSVG_FORWARDPUT \
+ \
+ /* put() method, called by KSVGBridge::put */ \
+ bool put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value &value, int attr);
+
+// For classes which need to be accessable with getElementById -> elements
+#define KSVG_NO_TAG_BRIDGE \
+public: \
+ KJS::ObjectImp *bridge(KJS::ExecState *) const { return 0; }
+
+#define KSVG_BRIDGE \
+public: \
+ KJS::ObjectImp *bridge(KJS::ExecState *) const; \
+ virtual DOM::DOMString tagName() const { return s_tagName; } \
+ static const DOM::DOMString s_tagName;
+
+// Fast setting of default values, if the token is known
+// Note: this is actually misnamed it should be KSVG_SET_DEFAULT_ATTRIBUTE
+#define KSVG_SET_ALT_ATTRIBUTE(Token, Name) putValueProperty(ownerDoc()->ecmaEngine()->globalExec(), Token, String(Name), Internal);
+
+// Check if attribute has not been parsed, if the token is known
+#define KSVG_TOKEN_NOT_PARSED_ELEMENT(Token, Element) (~Element->m_attrFlags & (1 << Token))
+#define KSVG_TOKEN_NOT_PARSED(Token) KSVG_TOKEN_NOT_PARSED_ELEMENT(Token, this)
+
+// Checks if the interpreter is in attribute "getting" mode
+#define KSVG_CHECK_ATTRIBUTE bool attributeMode = static_cast<KSVGScriptInterpreter *>(exec->interpreter())->attributeGetMode();
+
+// Sets the class specific flags to a ZERO value
+#define KSVG_EMPTY_FLAGS m_attrFlags = 0;
+
+// to be used in generatedata.cpp
+// GET p1=exec, p2=propertyName, p3=bridge
+// PUT p1=exec, p2=propertyName, p3=value, p4=attr
+#define GET_METHOD_ARGS KJS::ExecState *p1, const KJS::Identifier &p2, const KJS::ObjectImp *p3
+#define PUT_METHOD_ARGS KJS::ExecState *p1, const KJS::Identifier &p2, const KJS::Value &p3, int p4
+
+namespace KSVG
+{
+ /**
+ * Helper method for property lookups
+ *
+ * This method does it all (looking in the hashtable, checking for function
+ * overrides, creating the function or retrieving from cache, calling
+ * getValueProperty in case of a non-function property, forwarding to parent[s] if
+ * unknown property).
+ *
+ * Template arguments:
+ * @param FuncImp the class which implements this object's functions
+ * @param ThisImp the class of "this". It must implement the getValueProperty(exec,token) method,
+ * for non-function properties, and the getInParents() method (auto-generated).
+ *
+ * Method arguments:
+ * @param exec execution state, as usual
+ * @param propertyName the property we're looking for
+ * @param table the static hashtable for this class
+ * @param thisObj "this"
+ */
+ template<class FuncImp, class ThisImp>
+ inline KJS::Value lookupGet(KJS::ExecState *exec,
+ const KJS::Identifier &propertyName,
+ const KJS::HashTable *table,
+ const ThisImp *thisObj, // the 'impl' object
+ const KJS::ObjectImp *bridge)
+ {
+ const KJS::HashEntry *entry = KJS::Lookup::findEntry(table, propertyName);
+
+ if(!entry) // not found, forward to parents
+ return thisObj->getInParents(exec, propertyName, bridge);
+
+ if(entry->attr & KJS::Function)
+ return KJS::lookupOrCreateFunction<FuncImp>(exec, propertyName,
+ const_cast<KJS::ObjectImp *>(bridge),
+ entry->value, entry->params, entry->attr);
+
+ return thisObj->getValueProperty(exec, entry->value);
+ }
+
+ /**
+ * Simplified version of lookupGet in case there are no functions, only "values".
+ * Using this instead of lookupGet removes the need for a FuncImp class.
+ */
+ template <class ThisImp>
+ inline KJS::Value lookupGetValue(KJS::ExecState *exec,
+ const KJS::Identifier &propertyName,
+ const KJS::HashTable *table,
+ const ThisImp *thisObj, // the 'impl' object
+ const KJS::ObjectImp *bridge)
+ {
+ const KJS::HashEntry *entry = KJS::Lookup::findEntry(table, propertyName);
+
+ if(!entry) // not found, forward to parents
+ return thisObj->getInParents(exec, propertyName, bridge);
+
+ if(entry->attr & KJS::Function)
+ kdError(26004) << "Function bit set! Shouldn't happen in lookupGetValue! propertyName was " << propertyName.qstring() << endl;
+
+ return thisObj->getValueProperty(exec, entry->value);
+ }
+
+ /**
+ * This one is for "put".
+ * Lookup hash entry for property to be set, and set the value.
+ * The "this" class must implement putValueProperty.
+ * If it returns false, put() will return false, and KSVGRequest will set a dynamic property in ObjectImp
+ */
+ template <class ThisImp>
+ inline bool lookupPut(KJS::ExecState *exec,
+ const KJS::Identifier &propertyName,
+ const KJS::Value &value,
+ int attr,
+ const KJS::HashTable *table,
+ ThisImp *thisObj)
+ {
+ const KJS::HashEntry *entry = KJS::Lookup::findEntry(table, propertyName);
+
+ if(!entry) // not found, forward to parents
+ return thisObj->putInParents(exec, propertyName, value, attr);
+ else if(entry->attr & KJS::Function) // Function: put as override property
+ return false;
+ else if(entry->attr & KJS::ReadOnly && !(attr & KJS::Internal)) // readonly! Can't put!
+ {
+#ifdef KJS_VERBOSE
+ kdWarning(26004) <<" Attempt to change value of readonly property '" << propertyName.qstring() << "'" << endl;
+#endif
+ return true; // "we did it" -> don't put override property
+ }
+ else
+ {
+ if(static_cast<KSVGScriptInterpreter *>(exec->interpreter())->attributeSetMode())
+ thisObj->m_attrFlags |= (1 << entry->value);
+
+ thisObj->putValueProperty(exec, entry->value, value, attr);
+ return true;
+ }
+ }
+}
+
+// Same as kjs' DEFINE_PROTOTYPE, but with a pointer to the hashtable too, and no ClassName here
+// The ClassProto ctor(exec) must be public, so we can use KJS::cacheGlobalObject... (Niko)
+#define KSVG_DEFINE_PROTOTYPE(ClassProto) \
+ namespace KSVG { \
+ class ClassProto : public KJS::ObjectImp { \
+ public: \
+ static KJS::Object self(KJS::ExecState *exec); \
+ ClassProto( KJS::ExecState *exec ) \
+ : KJS::ObjectImp( exec->interpreter()->builtinObjectPrototype() ) {} \
+ virtual const KJS::ClassInfo *classInfo() const { return &info; } \
+ static const KJS::ClassInfo info; \
+ KJS::Value get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
+ bool hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
+ \
+ static const struct KJS::HashTable s_hashTable; \
+ }; \
+ }
+
+// same as IMPLEMENT_PROTOTYPE but in the KSVG namespace, and with ClassName here
+// so that KSVG_DEFINE_PROTOTYPE can be put in a header file ('info' defined here)
+#define KSVG_IMPLEMENT_PROTOTYPE(ClassName,ClassProto,ClassFunc) \
+ KJS::Value KSVG::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
+ { \
+ return lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &s_hashTable, this ); \
+ } \
+ bool KSVG::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
+ { /*stupid but we need this to have a common macro for the declaration*/ \
+ return KJS::ObjectImp::hasProperty(exec, propertyName); \
+ } \
+ KJS::Object KSVG::ClassProto::self(KJS::ExecState *exec) \
+ { \
+ return KJS::cacheGlobalObject<ClassProto>( exec, "[[" ClassName ".prototype]]" ); \
+ } \
+ const KJS::ClassInfo ClassProto::info = { ClassName, 0, &s_hashTable, 0 }; \
+
+// same as KSVG_IMPLEMENT_PROTOTYPE but with a parent class to forward calls to
+// Not used within KSVG up to now - each class does a self proto lookup in generateddata.cpp
+#define KSVG_IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassName,ClassProto,ClassFunc,ParentProto) \
+ KJS::Value KSVG::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
+ { \
+ KJS::Value val = lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &s_hashTable, this ); \
+ if ( val.type() != UndefinedType ) return val; \
+ /* Not found -> forward request to "parent" prototype */ \
+ return ParentProto::self(exec).get( exec, propertyName ); \
+ } \
+ bool KSVG::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
+ { \
+ if (KJS::ObjectImp::hasProperty(exec, propertyName)) \
+ return true; \
+ return ParentProto::self(exec).hasProperty(exec, propertyName); \
+ } \
+ KJS::Object KSVG::ClassProto::self(KJS::ExecState *exec) \
+ { \
+ return KJS::cacheGlobalObject<ClassProto>( exec, "[[" ClassName ".prototype]]" ); \
+ } \
+ const KJS::ClassInfo ClassProto::info = { ClassName, 0, &s_hashTable, 0 }; \
+
+#define KSVG_IMPLEMENT_PROTOFUNC(ClassFunc,Class) \
+ namespace KSVG { \
+ class ClassFunc : public KJS::ObjectImp { \
+ public: \
+ ClassFunc(KJS::ExecState *exec, int i, int len) \
+ : KJS::ObjectImp( /*proto? */ ), id(i) { \
+ KJS::Value protect(this); \
+ put(exec,"length",KJS::Number(len),KJS::DontDelete|KJS::ReadOnly|KJS::DontEnum); \
+ } \
+ /** Used by call() to check the type of thisObj. Generated code */ \
+ Class * cast(const KJS::ObjectImp* bridge) const; \
+ \
+ virtual bool implementsCall() const { return true; } \
+ /** You need to implement that one */ \
+ virtual KJS::Value call(KJS::ExecState *exec, KJS::Object &thisObj, const KJS::List &args); \
+ private: \
+ int id; \
+ }; \
+ }
+
+// To be used when casting the type of an argument
+#define KSVG_CHECK(ClassName, theObj) \
+ ClassName* obj = cast(static_cast<KJS::ObjectImp*>(theObj.imp())); \
+ if (!obj) { \
+ kdDebug(26004) << k_funcinfo << " Wrong object type: expected " << ClassName::s_classInfo.className << " got " << thisObj.classInfo()->className << endl; \
+ Object err = Error::create(exec,TypeError); \
+ exec->setException(err); \
+ return err; \
+ }
+
+// To be used in all call() implementations!
+// Can't use if (!thisObj.inherits(&ClassName::s_classInfo) since we don't
+// use the (single-parent) inheritance of ClassInfo...
+#define KSVG_CHECK_THIS(ClassName) KSVG_CHECK(ClassName, thisObj)
+
+#endif
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_scriptinterpreter.cpp b/ksvg/ecma/ksvg_scriptinterpreter.cpp
new file mode 100644
index 00000000..b5b9e6dd
--- /dev/null
+++ b/ksvg/ecma/ksvg_scriptinterpreter.cpp
@@ -0,0 +1,92 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "SVGEventImpl.h"
+#include "SVGDocumentImpl.h"
+#include "ksvg_scriptinterpreter.h"
+
+using namespace KSVG;
+using namespace KJS;
+
+KSVGScriptInterpreter::KSVGScriptInterpreter(const Object &global, SVGDocumentImpl *doc) : Interpreter(global), m_document(doc)
+{
+ m_evt = 0;
+
+ m_attributeGetMode = false;
+ m_attributeSetMode = false;
+}
+
+KSVGScriptInterpreter::~KSVGScriptInterpreter()
+{
+ if(m_evt)
+ m_evt->deref();
+}
+
+SVGDocumentImpl *KSVGScriptInterpreter::document()
+{
+ return m_document;
+}
+
+KSVG::SVGEventImpl *KSVGScriptInterpreter::currentEvent()
+{
+ return m_evt;
+}
+
+void KSVGScriptInterpreter::setCurrentEvent(KSVG::SVGEventImpl *evt)
+{
+ m_evt = evt;
+}
+
+KJS::ObjectImp *KSVGScriptInterpreter::getDOMObject(void *objectHandle) const
+{
+ return m_domObjects[objectHandle];
+}
+
+void KSVGScriptInterpreter::putDOMObject(void *objectHandle, KJS::ObjectImp *obj)
+{
+ m_domObjects.insert(objectHandle, obj);
+}
+
+void KSVGScriptInterpreter::removeDOMObject(void *objectHandle)
+{
+ m_domObjects.take(objectHandle);
+}
+
+bool KSVGScriptInterpreter::attributeGetMode()
+{
+ return m_attributeGetMode;
+}
+
+bool KSVGScriptInterpreter::attributeSetMode()
+{
+ return m_attributeSetMode;
+}
+
+void KSVGScriptInterpreter::setAttributeGetMode(bool temp)
+{
+ m_attributeGetMode = temp;
+}
+
+void KSVGScriptInterpreter::setAttributeSetMode(bool temp)
+{
+ m_attributeSetMode = temp;
+}
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_scriptinterpreter.h b/ksvg/ecma/ksvg_scriptinterpreter.h
new file mode 100644
index 00000000..ed7c6af8
--- /dev/null
+++ b/ksvg/ecma/ksvg_scriptinterpreter.h
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2002-2003 KSVG Team
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSVGScriptInterpreter_H
+#define KSVGScriptInterpreter_H
+
+#include <qptrdict.h>
+
+namespace KJS
+{
+ class Value;
+ class Object;
+ class Interpreter;
+}
+
+namespace KSVG
+{
+ class SVGEventImpl;
+ class SVGDocumentImpl;
+}
+
+class KSVGScriptInterpreter : public KJS::Interpreter
+{
+public:
+ KSVGScriptInterpreter(const KJS::Object &global, KSVG::SVGDocumentImpl *doc);
+ virtual ~KSVGScriptInterpreter();
+
+ KSVG::SVGDocumentImpl *document();
+
+ KJS::ObjectImp *getDOMObject(void *objectHandle) const;
+ void putDOMObject(void *objectHandle, KJS::ObjectImp *obj);
+ void removeDOMObject(void *objectHandle);
+
+ KSVG::SVGEventImpl *currentEvent();
+ void setCurrentEvent(KSVG::SVGEventImpl *evt);
+
+ bool attributeGetMode();
+ void setAttributeGetMode(bool temp);
+
+ bool attributeSetMode();
+ void setAttributeSetMode(bool temp);
+
+private:
+ KSVG::SVGDocumentImpl *m_document;
+ KSVG::SVGEventImpl *m_evt;
+
+ bool m_attributeGetMode, m_attributeSetMode;
+
+ QPtrDict<KJS::ObjectImp> m_domObjects;
+};
+
+#endif
+
+// vim:ts=4:noet
diff --git a/ksvg/ecma/ksvg_window.cpp b/ksvg/ecma/ksvg_window.cpp
new file mode 100644
index 00000000..d4c04de3
--- /dev/null
+++ b/ksvg/ecma/ksvg_window.cpp
@@ -0,0 +1,578 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 David Faure <faure@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "ksvg_window.moc"
+#include "ksvg_lookup.h"
+#include "ksvg_ecma.h"
+#include "ksvg_bridge.h"
+#include "ksvg_scriptinterpreter.h"
+#include <SVGEventImpl.h>
+#include <SVGDocumentImpl.h>
+#include <KSVGCanvas.h>
+#include <SVGWindowImpl.h>
+// for js constants
+#include <SVGTransformImpl.h>
+#include <SVGLengthImpl.h>
+#include <SVGAngleImpl.h>
+#include <SVGColorImpl.h>
+#include <SVGPreserveAspectRatioImpl.h>
+#include <SVGTextContentElementImpl.h>
+#include <SVGPathSegImpl.h>
+#include <SVGGradientElementImpl.h>
+#include <SVGMarkerElementImpl.h>
+#include <SVGTextPathElementImpl.h>
+#include <SVGPaintImpl.h>
+#include <SVGZoomAndPanImpl.h>
+
+#include <kparts/part.h>
+#include <assert.h>
+#include <kdebug.h>
+#include <qstylesheet.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kinputdialog.h>
+
+using namespace KSVG;
+
+#include "ksvg_window.lut.h"
+
+// Spec on http://www.protocol7.com/svg-wiki/ow.asp?AdobeSVGViewerWindow
+
+/*
+@namespace KSVG
+@begin KSVG::Window::s_hashTable 34
+ closed KSVG::Window::_Closed DontDelete|ReadOnly
+ window KSVG::Window::_Window DontDelete|ReadOnly
+ evt KSVG::Window::_Evt DontDelete|ReadOnly
+ document KSVG::Window::_Document DontDelete|ReadOnly
+ svgDocument KSVG::Window::_Document DontDelete|ReadOnly
+ innerWidth KSVG::Window::_InnerWidth DontDelete|ReadOnly
+ innerHeight KSVG::Window::_InnerHeight DontDelete|ReadOnly
+ setTimeout KSVG::Window::_SetTimeout DontDelete|Function 2
+ clearTimeout KSVG::Window::_ClearTimeout DontDelete|Function 1
+ setInterval KSVG::Window::_SetInterval DontDelete|Function 2
+ clearInterval KSVG::Window::_ClearInterval DontDelete|Function 1
+ navigator KSVG::Window::_Navigator DontDelete|ReadOnly
+ printNode KSVG::Window::_PrintNode DontDelete|Function 1
+
+# todo navigator, status/defaultstatus, like in KJS::Window (khtml)
+# todo close
+# todo instancename
+# todo setsrc, getsrc, reload, focus, blur, browsereval, findinstancebyname
+
+# "Constructors" (usually repositories for constants)
+ SVGTransform KSVG::Window::_SVGTransform DontDelete|ReadOnly
+ SVGLength KSVG::Window::_SVGLength DontDelete|ReadOnly
+ SVGAngle KSVG::Window::_SVGAngle DontDelete|ReadOnly
+ SVGPreserveAspectRatio KSVG::Window::_SVGPreserveAspectRatio DontDelete|ReadOnly
+ SVGPathSeg KSVG::Window::_SVGPathSeg DontDelete|ReadOnly
+ SVGGradientElement KSVG::Window::_SVGGradientElement DontDelete|ReadOnly
+ SVGMarkerElement KSVG::Window::_SVGMarkerElement DontDelete|ReadOnly
+ SVGTextPathElement KSVG::Window::_SVGTextPathElement DontDelete|ReadOnly
+ SVGPaint KSVG::Window::_SVGPaint DontDelete|ReadOnly
+ SVGTextContentElement KSVG::Window::_SVGTextContentElement DontDelete|ReadOnly
+ SVGZoomAndPan KSVG::Window::_SVGZoomAndPan DontDelete|ReadOnly
+ SVGColor KSVG::Window::_SVGColor DontDelete|ReadOnly
+
+# Functions
+ alert KSVG::Window::_Alert DontDelete|Function 1
+ prompt KSVG::Window::_Prompt DontDelete|Function 2
+ confirm KSVG::Window::_Confirm DontDelete|Function 1
+ debug KSVG::Window::_Debug DontDelete|Function 1
+ success KSVG::Window::_Success DontDelete|Function 1
+ getSVGViewerVersion KSVG::Window::_GetSVGViewerVersion DontDelete|Function 0
+ getURL KSVG::Window::_GetURL DontDelete|Function 2
+ postURL KSVG::Window::_PostURL DontDelete|Function 5
+ parseXML KSVG::Window::_ParseXML DontDelete|Function 1
+@end
+*/
+
+KSVG_IMPLEMENT_PROTOFUNC(WindowFunc, Window)
+
+const ClassInfo KSVG::Window::s_classInfo = { "Window", 0, &s_hashTable, 0 };
+
+KSVG::Window::Window(KSVG::SVGDocumentImpl *p) : ObjectImp(), m_doc(p)
+{
+ winq = new WindowQObject(this);
+}
+
+KSVG::Window::~Window()
+{
+ delete winq;
+}
+
+KSVG::Window *KSVG::Window::retrieveActive(ExecState *exec)
+{
+ ValueImp *imp = exec->interpreter()->globalObject().imp();
+ assert(imp);
+ return static_cast<KSVG::Window*>(imp);
+}
+
+bool KSVG::Window::hasProperty(ExecState *, const Identifier &) const
+{
+ return true; // See KJS::KSVG::Window::hasProperty
+}
+
+Value KSVG::Window::get(ExecState *exec, const Identifier &p) const
+{
+ kdDebug(26004) << "KSVG::Window (" << this << ")::get " << p.qstring() << endl;
+
+ if(p == "closed")
+ return Boolean(m_doc.isNull());
+
+ // we don't want any operations on a closed window
+ if(m_doc.isNull())
+ return Undefined();
+
+ // Look for overrides first
+ Value val = ObjectImp::get(exec, p);
+ if(!val.isA(UndefinedType))
+ return isSafeScript(exec) ? val : Undefined();
+
+ // Not the right way in the long run. Should use retrieve(m_doc)...
+ KSVGScriptInterpreter* interpreter = static_cast<KSVGScriptInterpreter *>(exec->interpreter());
+
+ const HashEntry *entry = Lookup::findEntry(&KSVG::Window::s_hashTable, p);
+ if(entry)
+ {
+ switch(entry->value)
+ {
+ case _Document:
+ // special case, KSVGEcma::setup created it, so we don't need to do it
+ return Value(interpreter->getDOMObject(m_doc->handle()));
+ case _Window:
+ return Value(const_cast<Window *>(this));
+ case _Evt:
+ {
+ KSVG::SVGEventImpl *evt = interpreter->currentEvent();
+ if(evt)
+ return getDOMEvent(exec, evt);
+ else
+ return Undefined();
+ }
+ case _InnerWidth:
+ return Number(m_doc->canvas()->width());
+ case _InnerHeight:
+ return Number(m_doc->canvas()->height());
+ case _SetTimeout:
+ case _ClearTimeout:
+ case _SetInterval:
+ case _ClearInterval:
+ case _PrintNode:
+ {
+ if(isSafeScript(exec))
+ return lookupOrCreateFunction<WindowFunc>(exec, p, this, entry->value, entry->params, entry->attr);
+ else
+ return Undefined();
+ }
+ case _Alert:
+ case _Confirm:
+ case _Debug:
+ case _Success:
+ case _GetSVGViewerVersion:
+ case _GetURL:
+ case _PostURL:
+ case _ParseXML:
+ case _Prompt:
+ return lookupOrCreateFunction<WindowFunc>(exec, p, this, entry->value, entry->params, entry->attr);
+ case _SVGTransform:
+ return getSVGTransformImplConstructor(exec);
+ case _SVGLength:
+ return getSVGLengthImplConstructor(exec);
+ case _SVGAngle:
+ return getSVGAngleImplConstructor(exec);
+ case _SVGColor:
+ return getSVGColorImplConstructor(exec);
+ case _SVGPreserveAspectRatio:
+ return getSVGPreserveAspectRatioImplConstructor(exec);
+ case _SVGPathSeg:
+ return getSVGPathSegImplConstructor(exec);
+ case _SVGGradientElement:
+ return getSVGGradientElementImplConstructor(exec);
+ case _SVGMarkerElement:
+ return getSVGMarkerElementImplConstructor(exec);
+ case _SVGTextPathElement:
+ return getSVGTextPathElementImplConstructor(exec);
+ case _SVGPaint:
+ return getSVGPaintImplConstructor(exec);
+ case _SVGTextContentElement:
+ return getSVGTextContentElementImplConstructor(exec);
+ case _SVGZoomAndPan:
+ return getSVGZoomAndPanImplConstructor(exec);
+ }
+ }
+
+ // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
+ // But it can also mean something isn't loaded or implemented...
+ kdDebug(26004) << "KSVG::Window::get property not found: " << p.qstring() << endl;
+
+ return Undefined();
+}
+
+void KSVG::Window::put(ExecState* exec, const Identifier &propertyName, const Value &value, int attr)
+{
+ // Called by an internal KJS call (e.g. InterpreterImp's constructor) ?
+ // If yes, save time and jump directly to ObjectImp.
+ if((attr != None && attr != DontDelete)
+ // Same thing if we have a local override (e.g. "var location")
+ || (ObjectImp::getDirect(propertyName) && isSafeScript(exec)))
+ {
+ ObjectImp::put( exec, propertyName, value, attr );
+ return;
+ }
+
+ const HashEntry *entry = Lookup::findEntry(&KSVG::Window::s_hashTable, propertyName);
+ if(entry)
+ {
+#ifdef KJS_VERBOSE
+ kdDebug(26004) << "Window(" << this << ")::put " << propertyName.qstring() << endl;
+#endif
+ //switch(entry->value)
+ //{
+ // ...
+ //}
+ }
+
+ if(isSafeScript(exec))
+ ObjectImp::put(exec, propertyName, value, attr);
+}
+
+bool KSVG::Window::isSafeScript(ExecState *exec) const
+{
+ if(m_doc.isNull()) // part deleted ? can't grant access
+ {
+ kdDebug(26004) << "KSVG::Window::isSafeScript: accessing deleted part !" << endl;
+ return false;
+ }
+
+ KSVG::SVGDocumentImpl *activePart = static_cast<KSVGScriptInterpreter *>(exec->interpreter())->document();
+
+ if(!activePart)
+ {
+ kdDebug(26004) << "KSVG::Window::isSafeScript: current interpreter's part is 0L!" << endl;
+ return false;
+ }
+
+ if(activePart == m_doc) // Not calling from another frame, no problem.
+ return true;
+
+ return false;
+}
+
+void KSVG::Window::clear(ExecState *exec)
+{
+ kdDebug(26004) << "KSVG::Window::clear " << this << endl;
+ delete winq;
+ winq = new WindowQObject(this);;
+
+ // Get rid of everything, those user vars could hold references to DOM nodes
+ deleteAllProperties(exec);
+
+ // Really delete those properties, so that the DOM nodes get deref'ed
+ // KJS::Collector::collect();
+
+ // Now recreate a working global object for the next URL that will use us
+ Interpreter *interpreter = exec->interpreter();
+ interpreter->initGlobalObject();
+}
+
+Value WindowFunc::call(ExecState *exec, Object &thisObj, const List &args)
+{
+ if(!thisObj.inherits(&KSVG::Window::s_classInfo))
+ {
+ Object err = Error::create(exec, TypeError);
+ exec->setException(err);
+ return err;
+ }
+
+ Window *window = static_cast<Window *>(thisObj.imp());
+ Value v = args[0];
+ UString s = v.toString(exec);
+ QString str = s.qstring();
+
+ switch(id)
+ {
+ case KSVG::Window::_Alert:
+ SVGWindowImpl::alert(DOM::DOMString(str), "Javascript");
+ return Undefined();
+ case KSVG::Window::_Confirm:
+ return Boolean(SVGWindowImpl::confirm(DOM::DOMString(str), "Javascript"));
+ case KSVG::Window::_Debug:
+ kdDebug(26004) << "[Debug] " << str << endl;
+ return Undefined();
+ case KSVG::Window::_Success:
+ //if(args[0].toString(exec) == "success") // ? Did you really mean that ?
+ return Number(1);
+ //return Undefined();
+ case KSVG::Window::_GetSVGViewerVersion:
+ return String("0.1"); // I cant really find a central place for the version nr, so... (Rob)
+ case KSVG::Window::_ClearTimeout:
+ case KSVG::Window::_ClearInterval:
+ (const_cast<Window *>(window))->clearTimeout(v.toInt32(exec));
+ return Undefined();
+ case KSVG::Window::_PrintNode:
+ return String(const_cast<Window *>(window)->doc()->window()->printNode(toNode(args[0])));
+ case KSVG::Window::_GetURL:
+ {
+ KURL url((const_cast<Window *>(window))->doc()->baseUrl(), args[0].toString(exec).qstring());
+ Value asyncStatus = (const_cast<Window *>(window))->doc()->ecmaEngine()->getUrl(exec, url);
+ Object callBackFunction = Object::dynamicCast(args[1]);
+ List callBackArgs;
+
+ callBackArgs.append(asyncStatus);
+ callBackFunction.call(exec, callBackFunction, callBackArgs);
+
+ return Undefined();
+ }
+ case KSVG::Window::_PostURL:
+ {
+ KURL url((const_cast<Window *>(window))->doc()->baseUrl(), args[0].toString(exec).qstring());
+ QString data = args[1].toString(exec).qstring();
+ QString mimeType = args[3].toString(exec).qstring();
+ QString contentEncoding = args[4].toString(exec).qstring();
+ Object callBackFunction = Object::dynamicCast(args[2]);
+
+ (const_cast<Window *>(window))->doc()->ecmaEngine()->postUrl(exec, url, data, mimeType, contentEncoding, callBackFunction);
+
+ return Undefined();
+ };
+ case KSVG::Window::_ParseXML:
+ {
+ SVGDocumentImpl *doc = new SVGDocumentImpl();
+ doc->ref();
+ doc->attach(0);
+
+ // So we can find it later...
+ (const_cast<Window *>(window))->doc()->addToDocumentDict(doc->handle(), doc);
+
+ // Also add the current doc to the new doc!
+ SVGDocumentImpl *curDoc = (const_cast<Window *>(window))->doc();
+ doc->addToDocumentDict(curDoc->handle(), curDoc);
+
+ QXmlInputSource *svgFragment = new QXmlInputSource();
+ svgFragment->setData(args[0].toString(exec).qstring());
+
+ doc->parseSVG(svgFragment, true);
+
+ DOM::DocumentFragment fragment = doc->createDocumentFragment();
+ DOM::Node node = doc->firstChild();
+ for(; !node.isNull(); node = node.nextSibling())
+ fragment.appendChild(node);
+
+
+// fragment = *doc; // Should copy the nodes into here...
+
+ return (new SVGDOMDocumentFragmentBridge(fragment))->cache(exec);
+ }
+ case KSVG::Window::_Prompt:
+ {
+ // mop: from khtml. do we need that?
+ // part->xmlDocImpl()->updateRendering();
+ bool ok;
+ QString str2;
+ if (args.size() >= 2)
+ str2 = KInputDialog::getText(i18n("Prompt"),
+ QStyleSheet::convertFromPlainText(str),
+ args[1].toString(exec).qstring(), &ok);
+ else
+ str2 = KInputDialog::getText(i18n("Prompt"),
+ QStyleSheet::convertFromPlainText(str),
+ QString::null, &ok);
+ if ( ok )
+ return String(str2);
+ else
+ return Null();
+ }
+ case KSVG::Window::_SetInterval:
+ if(args.size() >= 2 && v.isA(StringType))
+ {
+ int i = args[1].toInt32(exec);
+ int r = (const_cast<Window *>(window))->installTimeout(s, i, false);
+ return Number(r);
+ }
+ else if(args.size() >= 2 && !Object::dynamicCast(v).isNull() && Object::dynamicCast(v).implementsCall())
+ {
+ Value func = args[0];
+ int i = args[1].toInt32(exec);
+ int r = (const_cast<Window *>(window))->installTimeout(s, i, false);
+ return Number(r);
+ }
+ else
+ return Undefined();
+ case KSVG::Window::_SetTimeout:
+ if (args.size() == 2 && v.isA(StringType))
+ {
+ int i = args[1].toInt32(exec);
+ int r = (const_cast<Window *>(window))->installTimeout(s, i, true /*single shot*/);
+ return Number(r);
+ }
+ else if(args.size() >= 2 && v.isA(ObjectType) && Object::dynamicCast(v).implementsCall())
+ {
+ Value func = args[0];
+ int i = args[1].toInt32(exec);
+ int r = (const_cast<Window *>(window))->installTimeout(s, i, false);
+ return Number(r);
+ }
+ else
+ return Undefined();
+ }
+
+ return Undefined();
+}
+
+int KSVG::Window::installTimeout(const UString &handler, int t, bool singleShot)
+{
+ return winq->installTimeout(handler, t, singleShot);
+}
+
+void KSVG::Window::clearTimeout(int timerId)
+{
+ winq->clearTimeout(timerId);
+}
+
+////////////////////// ScheduledAction ////////////////////////
+
+ScheduledAction::ScheduledAction(Object _func, List _args, bool _singleShot)
+{
+ func = _func;
+ args = _args;
+ isFunction = true;
+ singleShot = _singleShot;
+}
+
+ScheduledAction::ScheduledAction(QString _code, bool _singleShot)
+{
+ code = _code;
+ isFunction = false;
+ singleShot = _singleShot;
+}
+
+ScheduledAction::~ScheduledAction()
+{
+}
+
+void ScheduledAction::execute(Window *window)
+{
+ Q_ASSERT(window->doc());
+
+ KSVGScriptInterpreter *interpreter = window->doc()->ecmaEngine()->interpreter();
+ if(isFunction)
+ {
+ if(func.implementsCall())
+ {
+ ExecState *exec = interpreter->globalExec();
+ Q_ASSERT(window == interpreter->globalObject().imp());
+ Object obj(window);
+ func.call(exec, obj, args); // note that call() creates its own execution state for the func call
+ }
+ }
+ else
+ {
+ interpreter->evaluate(code);
+ window->doc()->rerender();
+ }
+}
+
+////////////////////// WindowQObject ////////////////////////
+
+WindowQObject::WindowQObject(Window *w) : parent(w)
+{
+}
+
+WindowQObject::~WindowQObject()
+{
+ parentDestroyed(); // reuse same code
+}
+
+void WindowQObject::parentDestroyed()
+{
+ killTimers();
+
+ QMapIterator<int, ScheduledAction *> it;
+ for(it = scheduledActions.begin(); it != scheduledActions.end(); ++it)
+ {
+ ScheduledAction *action = *it;
+ delete action;
+ }
+
+ scheduledActions.clear();
+}
+
+int WindowQObject::installTimeout(const UString &handler, int t, bool singleShot)
+{
+ int id = startTimer(t);
+ ScheduledAction *action = new ScheduledAction(handler.qstring(), singleShot);
+ scheduledActions.insert(id, action);
+ return id;
+}
+
+int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
+{
+ Object objFunc = Object::dynamicCast(func);
+ int id = startTimer(t);
+ scheduledActions.insert(id, new ScheduledAction(objFunc, args, singleShot));
+ return id;
+}
+
+void WindowQObject::clearTimeout(int timerId, bool delAction)
+{
+ killTimer(timerId);
+
+ if(delAction)
+ {
+ QMapIterator<int, ScheduledAction *> it = scheduledActions.find(timerId);
+ if(it != scheduledActions.end())
+ {
+ ScheduledAction *action = *it;
+ scheduledActions.remove(it);
+ delete action;
+ }
+ }
+}
+
+void WindowQObject::timerEvent(QTimerEvent *e)
+{
+ QMapIterator<int, ScheduledAction *> it = scheduledActions.find(e->timerId());
+ if(it != scheduledActions.end())
+ {
+ ScheduledAction *action = *it;
+ bool singleShot = action->singleShot;
+
+ // remove single shots installed by setTimeout()
+ if(singleShot)
+ {
+ clearTimeout(e->timerId(), false);
+ scheduledActions.remove(it);
+ }
+
+ if(parent->doc())
+ action->execute(parent);
+
+ // It is important to test singleShot and not action->singleShot here - the
+ // action could have been deleted already if not single shot and if the
+ // JS code called by execute() calls clearTimeout().
+ if(singleShot)
+ delete action;
+ }
+ else
+ kdWarning(6070) << "WindowQObject::timerEvent this=" << this << " timer " << e->timerId() << " not found (" << scheduledActions.count() << " actions in map)" << endl;
+}
+
+void WindowQObject::timeoutClose()
+{
+}
diff --git a/ksvg/ecma/ksvg_window.h b/ksvg/ecma/ksvg_window.h
new file mode 100644
index 00000000..28c9699e
--- /dev/null
+++ b/ksvg/ecma/ksvg_window.h
@@ -0,0 +1,122 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 David Faure <faure@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSVG_WINDOW_H
+#define KSVG_WINDOW_H
+
+#include <kjs/object.h>
+#include <qguardedptr.h>
+
+namespace KSVG {
+
+class SVGDocumentImpl;
+class WindowQObject;
+
+// This is currently a fork of khtml's Window object, simplified.
+// However in the long run it could become a base class for it.
+// Author: David Faure <faure@kde.org>
+class Window : public KJS::ObjectImp {
+ friend class WindowFunc;
+ friend class WindowQObject;
+ friend class ScheduledAction;
+public:
+ Window(KSVG::SVGDocumentImpl *p);
+ ~Window();
+
+ virtual KJS::Value get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const;
+ virtual void put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value &value, int attr = KJS::None);
+ virtual bool hasProperty(KJS::ExecState * /*exec*/, const KJS::Identifier &/*p*/) const;
+
+ /**
+ * Returns and registers a window object. In case there's already a Window
+ * for the specified part p this will be returned in order to have unique
+ * bindings.
+ */
+ //static KJS::Value retrieve(KSVG::SVGDocumentImpl *p);
+ /**
+ * Returns the Window object for a given part
+ */
+ //static Window *retrieveWindow(KSVG::SVGDocumentImpl *p);
+ /**
+ * returns a pointer to the Window object this javascript interpreting instance
+ * was called from.
+ */
+ static Window *retrieveActive(KJS::ExecState *exec);
+
+ QGuardedPtr<KSVG::SVGDocumentImpl> doc() const { return m_doc; }
+
+ int installTimeout(const KJS::UString &handler, int t, bool singleShot);
+ void clearTimeout(int timerId);
+
+ bool isSafeScript(KJS::ExecState *exec) const;
+ void clear( KJS::ExecState *exec );
+
+ enum {
+ // Properties
+ _Closed, _Window, _Document, _Evt, _InnerWidth, _InnerHeight,
+ _SVGTransform, _SVGLength, _SVGAngle, _SVGColor, _SVGPreserveAspectRatio, _SVGGradientElement,
+ _SVGPathSeg, _SVGTextContentElement, _SVGPaint, _SVGZoomAndPan, _SVGMarkerElement, _SVGTextPathElement,
+ _SetInterval, _ClearInterval, _SetTimeout, _ClearTimeout, _Navigator, _PrintNode,
+ // Functions
+ _Alert, _Confirm, _Debug, _Success, _GetSVGViewerVersion, _GetURL, _PostURL, _ParseXML, _Prompt
+ };
+
+ virtual const KJS::ClassInfo* classInfo() const { return &s_classInfo; }
+ static const KJS::ClassInfo s_classInfo;
+ static const struct KJS::HashTable s_hashTable;
+
+private:
+ WindowQObject *winq;
+ QGuardedPtr<KSVG::SVGDocumentImpl> m_doc;
+};
+
+class ScheduledAction {
+public:
+ ScheduledAction(KJS::Object _func, KJS::List _args, bool _singleShot);
+ ScheduledAction(QString _code, bool _singleShot);
+ ~ScheduledAction();
+ void execute(Window *window);
+ KJS::Object func;
+ KJS::List args;
+ QString code;
+ bool isFunction;
+ bool singleShot;
+};
+
+class WindowQObject : public QObject {
+ Q_OBJECT
+public:
+ WindowQObject(Window *w);
+ ~WindowQObject();
+ int installTimeout(const KJS::UString &handler, int t, bool singleShot);
+ int installTimeout(const KJS::Value &func, KJS::List args, int t, bool singleShot);
+ void clearTimeout(int timerId, bool delAction = true);
+public slots:
+ void timeoutClose();
+protected slots:
+ void parentDestroyed();
+protected:
+ void timerEvent(QTimerEvent *e);
+private:
+ Window *parent;
+ //KHTMLPart *part; // not guarded, may be dangling
+ QMap<int, ScheduledAction*> scheduledActions;
+};
+
+}
+#endif // KSVG_WINDOW_H