summaryrefslogtreecommitdiffstats
path: root/ksvg/ecma/ksvg_ecma.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ksvg/ecma/ksvg_ecma.cpp')
-rw-r--r--ksvg/ecma/ksvg_ecma.cpp336
1 files changed, 336 insertions, 0 deletions
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