summaryrefslogtreecommitdiffstats
path: root/khtml/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
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /khtml/ecma
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.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/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'khtml/ecma')
-rw-r--r--khtml/ecma/AUTHORS4
-rw-r--r--khtml/ecma/Makefile.am90
-rw-r--r--khtml/ecma/README21
-rw-r--r--khtml/ecma/THANKS9
-rw-r--r--khtml/ecma/TODO12
-rw-r--r--khtml/ecma/domparser.cpp112
-rw-r--r--khtml/ecma/domparser.h58
-rw-r--r--khtml/ecma/jsk.html113
-rw-r--r--khtml/ecma/kjs_binding.cpp467
-rw-r--r--khtml/ecma/kjs_binding.h409
-rw-r--r--khtml/ecma/kjs_css.cpp1302
-rw-r--r--khtml/ecma/kjs_css.h304
-rw-r--r--khtml/ecma/kjs_debugwin.cpp1139
-rw-r--r--khtml/ecma/kjs_debugwin.h285
-rw-r--r--khtml/ecma/kjs_dom.cpp1849
-rw-r--r--khtml/ecma/kjs_dom.h299
-rw-r--r--khtml/ecma/kjs_events.cpp993
-rw-r--r--khtml/ecma/kjs_events.h250
-rw-r--r--khtml/ecma/kjs_html.cpp3946
-rw-r--r--khtml/ecma/kjs_html.h294
-rw-r--r--khtml/ecma/kjs_mozilla.cpp94
-rw-r--r--khtml/ecma/kjs_mozilla.h44
-rw-r--r--khtml/ecma/kjs_navigator.cpp670
-rw-r--r--khtml/ecma/kjs_navigator.h53
-rw-r--r--khtml/ecma/kjs_proxy.cpp411
-rw-r--r--khtml/ecma/kjs_proxy.h91
-rw-r--r--khtml/ecma/kjs_range.cpp233
-rw-r--r--khtml/ecma/kjs_range.h71
-rw-r--r--khtml/ecma/kjs_traversal.cpp327
-rw-r--r--khtml/ecma/kjs_traversal.h108
-rw-r--r--khtml/ecma/kjs_views.cpp91
-rw-r--r--khtml/ecma/kjs_views.h53
-rw-r--r--khtml/ecma/kjs_window.cpp2935
-rw-r--r--khtml/ecma/kjs_window.h309
-rw-r--r--khtml/ecma/testecma.cpp67
-rw-r--r--khtml/ecma/xmlhttprequest.cpp810
-rw-r--r--khtml/ecma/xmlhttprequest.h142
-rw-r--r--khtml/ecma/xmlserializer.cpp109
-rw-r--r--khtml/ecma/xmlserializer.h54
39 files changed, 18628 insertions, 0 deletions
diff --git a/khtml/ecma/AUTHORS b/khtml/ecma/AUTHORS
new file mode 100644
index 000000000..2a129330d
--- /dev/null
+++ b/khtml/ecma/AUTHORS
@@ -0,0 +1,4 @@
+Harri Porten <porten@kde.org>
+Peter Kelly <pmk@post.com>
+Dirk Mueller <mueller@kde.org>
+Daniel Molkentin <molkentin@kde.org>
diff --git a/khtml/ecma/Makefile.am b/khtml/ecma/Makefile.am
new file mode 100644
index 000000000..c88b51d33
--- /dev/null
+++ b/khtml/ecma/Makefile.am
@@ -0,0 +1,90 @@
+# This file is part of the KDE libraries
+# Copyright (C) 1999 Harri Porten (porten@kde.org)
+
+# 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.
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/kio -I$(top_srcdir)/kio/bookmarks -I$(top_srcdir)/khtml -I$(top_srcdir)/khtml/java -I$(top_srcdir)/kwallet/client -I$(top_srcdir)/kutils -I$(top_builddir)/kjs $(all_includes)
+
+KDE_CXXFLAGS = $(USE_EXCEPTIONS)
+
+noinst_LTLIBRARIES = libkjs_html.la
+
+noinst_HEADERS = kjs_html.h kjs_dom.h kjs_window.h kjs_navigator.h \
+ kjs_binding.h kjs_proxy.h kjs_css.h kjs_range.h \
+ kjs_traversal.h kjs_events.h kjs_views.h kjs_debugwin.h
+
+libkjs_html_la_SOURCES = kjs_binding.cpp kjs_dom.cpp kjs_html.cpp kjs_window.cpp \
+ kjs_navigator.cpp kjs_proxy.cpp \
+ kjs_css.cpp kjs_range.cpp kjs_traversal.cpp kjs_events.cpp \
+ kjs_views.cpp kjs_debugwin.cpp kjs_mozilla.cpp xmlhttprequest.cpp \
+ xmlserializer.cpp domparser.cpp
+#libkjs_html_la_LDFLAGS = -module -avoid-version $(all_libraries)
+libkjs_html_la_LIBADD = $(top_builddir)/kjs/libkjs.la # ../libkhtml.la
+libkjs_html_la_METASOURCES = AUTO
+
+LUT_FILES = kjs_dom.lut.h kjs_html.lut.h kjs_css.lut.h kjs_events.lut.h kjs_navigator.lut.h \
+ kjs_mozilla.lut.h kjs_range.lut.h kjs_traversal.lut.h kjs_views.lut.h kjs_window.lut.h
+
+CREATE_HASH_TABLE = $(top_srcdir)/kjs/create_hash_table
+
+kjs_dom.lut.h : $(srcdir)/kjs_dom.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_dom.cpp > $@
+kjs_dom.lo: kjs_dom.lut.h
+kjs_html.lut.h : $(srcdir)/kjs_html.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_html.cpp > $@
+kjs_html.lo: kjs_html.lut.h
+kjs_css.lut.h : $(srcdir)/kjs_css.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_css.cpp > $@
+kjs_css.lo: kjs_css.lut.h
+kjs_events.lut.h : $(srcdir)/kjs_events.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_events.cpp > $@
+kjs_events.lo: kjs_events.lut.h
+kjs_navigator.lut.h : $(srcdir)/kjs_navigator.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_navigator.cpp > $@
+kjs_navigator.lo: kjs_navigator.lut.h
+kjs_mozilla.lut.h : $(srcdir)/kjs_mozilla.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_mozilla.cpp > $@
+kjs_mozilla.lo: kjs_mozilla.lut.h
+kjs_range.lut.h : $(srcdir)/kjs_range.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_range.cpp > $@
+kjs_range.lo: kjs_range.lut.h
+kjs_traversal.lut.h : $(srcdir)/kjs_traversal.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_traversal.cpp > $@
+kjs_traversal.lo: kjs_traversal.lut.h
+kjs_views.lut.h : $(srcdir)/kjs_views.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_views.cpp > $@
+kjs_views.lo: kjs_views.lut.h
+kjs_window.lut.h : $(srcdir)/kjs_window.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/kjs_window.cpp > $@
+kjs_window.lo: kjs_window.lut.h
+xmlhttprequest.lut.h : $(srcdir)/xmlhttprequest.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/xmlhttprequest.cpp > $@
+xmlhttprequest.lo: xmlhttprequest.lut.h
+xmlserializer.lut.h : $(srcdir)/xmlserializer.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/xmlserializer.cpp > $@
+xmlserializer.lo: xmlserializer.lut.h
+domparser.lut.h : $(srcdir)/domparser.cpp $(CREATE_HASH_TABLE)
+ $(PERL) $(CREATE_HASH_TABLE) $(srcdir)/domparser.cpp > $@
+domparser.lo: domparser.lut.h
+
+
+CLEANFILES = $(LUT_FILES)
+
+# interactive test program
+#check_PROGRAMS = testecma
+#testecma_SOURCES = testecma.cpp
+#testecma_LDADD = ../libkhtml.la $(top_builddir)/kjs/libkjs.la
+
diff --git a/khtml/ecma/README b/khtml/ecma/README
new file mode 100644
index 000000000..4c341699a
--- /dev/null
+++ b/khtml/ecma/README
@@ -0,0 +1,21 @@
+This module contains the ECMAScript a.k.a. JavaScript language bindings for
+the KHTML Part.
+
+The module is loaded into KHTML's address space on demand.
+
+To test the non-HTML DOM functions you may compile a little interactive
+interpreter called 'testecma' with 'make check' (see testecma.cpp for
+further details).
+
+Harri Porten <porten@kde.org>
+
+========================================================================
+Appendix A: Web sites with useful tests
+
+http://oucsace.cs.ohiou.edu/~ywang/JavaScript
+http://www.xs4all.nl/~ppk/js/index.html?version5.html
+
+Appendix B: References for HTML JavaScript bindings
+
+http://msdn.microsoft.com/workshop/author/dhtml/reference/objects.asp
+http://docs.sun.com/source/816-6408-10/
diff --git a/khtml/ecma/THANKS b/khtml/ecma/THANKS
new file mode 100644
index 000000000..b21dce741
--- /dev/null
+++ b/khtml/ecma/THANKS
@@ -0,0 +1,9 @@
+Vadim Plessky <lucy-ples@mtu-net.ru> for dissecting an endless number
+of bug reports and therefore taking quite some load of our shoulders.
+
+Ferdinand Gassauer <f.gassauer@aon.at> for numerous useful bug reports
+and keeping track of them later.
+
+David Faure <faure@kde.org> for taking some time off from Konqueror
+and making a lotto site working fixing bugs along the way.
+
diff --git a/khtml/ecma/TODO b/khtml/ecma/TODO
new file mode 100644
index 000000000..16a7152c5
--- /dev/null
+++ b/khtml/ecma/TODO
@@ -0,0 +1,12 @@
+Has to be done
+==============
+- frame[] correct search and sorting order (DONE ?)
+- optional error message output
+- change KParts::WindowArgs && friends
+ that we can detect if a locationbar is on/or not
+
+Could be done
+=============
+- Make the graphical debugger useable
+- Improve internal structures to give a really useful
+ output on errors (i.e. improve backtrance capabilities)
diff --git a/khtml/ecma/domparser.cpp b/khtml/ecma/domparser.cpp
new file mode 100644
index 000000000..63a9dce36
--- /dev/null
+++ b/khtml/ecma/domparser.cpp
@@ -0,0 +1,112 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2005 Anders Carlsson (andersca@mac.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "domparser.h"
+#include "domparser.lut.h"
+
+#include "kjs_dom.h"
+#include "kjs_window.h"
+#include "xml/dom_nodeimpl.h"
+#include "xml/dom_docimpl.h"
+
+#include "html/html_documentimpl.h"
+
+using DOM::DocumentImpl;
+
+////////////////////// DOMParser Object ////////////////////////
+
+/* Source for DOMParserProtoTable.
+@begin DOMParserProtoTable 1
+ parseFromString DOMParser::ParseFromString DontDelete|Function 2
+@end
+*/
+
+
+namespace KJS {
+
+KJS_DEFINE_PROTOTYPE(DOMParserProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMParserProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMParser", DOMParserProto, DOMParserProtoFunc)
+
+
+DOMParserConstructorImp::DOMParserConstructorImp(ExecState *, DOM::DocumentImpl *d)
+ : doc(d)
+{
+}
+
+bool DOMParserConstructorImp::implementsConstruct() const
+{
+ return true;
+}
+
+Object DOMParserConstructorImp::construct(ExecState *exec, const List &)
+{
+ return Object(new DOMParser(exec, doc.get()));
+}
+
+const ClassInfo DOMParser::info = { "DOMParser", 0, 0 /* &DOMParserTable*/, 0 };
+
+
+DOMParser::DOMParser(ExecState *exec, DOM::DocumentImpl *d)
+ : DOMObject(DOMParserProto::self(exec)), doc(d)
+{
+// setPrototype(DOMParserProto::self(exec));
+}
+
+
+Value DOMParserProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ if (!thisObj.inherits(&DOMParser::info)) {
+ Object err = Error::create(exec,TypeError);
+ exec->setException(err);
+ return err;
+ }
+
+ DOMParser *parser = static_cast<DOMParser *>(thisObj.imp());
+
+ switch (id) {
+ case DOMParser::ParseFromString:
+ {
+ if (args.size() != 2) {
+ return Undefined();
+ }
+
+ QString str = args[0].toString(exec).qstring();
+ QString contentType = args[1].toString(exec).qstring().stripWhiteSpace();
+
+ if (contentType == "text/xml" || contentType == "application/xml" || contentType == "application/xhtml+xml") {
+ DocumentImpl *docImpl = parser->doc->implementation()->createDocument();
+
+ docImpl->open();
+ docImpl->write(str);
+ docImpl->finishParsing();
+ docImpl->close();
+
+ return getDOMNode(exec, docImpl);
+ }
+ }
+ }
+
+ return Undefined();
+}
+
+} // end namespace
+
+
diff --git a/khtml/ecma/domparser.h b/khtml/ecma/domparser.h
new file mode 100644
index 000000000..233872602
--- /dev/null
+++ b/khtml/ecma/domparser.h
@@ -0,0 +1,58 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2005 Anders Carlsson (andersca@mac.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef DOMPARSER_H
+#define DOMPARSER_H
+
+#include <qguardedptr.h>
+#include <kjs/object.h>
+#include <kjs/interpreter.h>
+#include <misc/shared.h>
+
+#include "kjs_dom.h"
+
+namespace KJS {
+
+ class DOMParserConstructorImp : public ObjectImp {
+ public:
+ DOMParserConstructorImp(ExecState *, DOM::DocumentImpl *d);
+ virtual bool implementsConstruct() const;
+ virtual Object construct(ExecState *exec, const List &args);
+private:
+ khtml::SharedPtr<DOM::DocumentImpl> doc;
+ };
+
+ class DOMParser : public DOMObject {
+ public:
+ DOMParser(ExecState *, DOM::DocumentImpl *d);
+ virtual bool toBoolean(ExecState *) const { return true; }
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { ParseFromString };
+
+ private:
+ QGuardedPtr<DOM::DocumentImpl> doc;
+
+ friend class DOMParserProtoFunc;
+ };
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/jsk.html b/khtml/ecma/jsk.html
new file mode 100644
index 000000000..917c083e8
--- /dev/null
+++ b/khtml/ecma/jsk.html
@@ -0,0 +1,113 @@
+<html>
+<!--
+Javascript Konsole (c) 2001 Till Krech <till@snafu.de>
+Dieser Code unterliegt den Bedingungen der Gnu Public License Version 2.
+-->
+<head>
+<title>Javascript Konsole</title>
+<style type="text/css">
+code {
+ color:#444488;
+}
+em {
+ font-weight: bold;
+}
+</style>
+<script language="JavaScript">
+
+function do_eval() {
+ var fo = document.forms.fo;
+ fo.restyp.value = "";
+ fo.field.value = "";
+ var fo = document.fo;
+ var expr = fo.zeile.value;
+ var result = eval(expr);
+ fo.restyp.value = typeof(result);
+ var tuedel = "";
+ if (typeof(result) == "string") {
+ tuedel = '"';
+ }
+ fo.field.value = tuedel + result + tuedel;
+}
+
+function do_properties() {
+ var fo = document.forms.fo;
+ fo.restyp.value = "";
+ fo.field.value = "";
+ var fo = document.fo;
+ var expr = fo.zeile.value;
+ var result = eval(expr);
+ var i;
+ fo.restyp.value = typeof(result);
+ var fieldvalue = "";
+ if (typeof(result) != "undefined") {
+ for (i in result) {
+ var tuedel = "";
+ var propval = result[i];
+ if (typeof(propval) == "string") {
+ tuedel = '"';
+ }
+ fieldvalue +=
+ i
+ + " [" + typeof(propval) + "] = "
+ + tuedel + propval + tuedel + "\n";
+ }
+ fo.field.value = fieldvalue;
+ }
+}
+
+
+</script>
+</head>
+<body bgcolor="#dddddd">
+<h1>JavaScript Konsole</h1>
+<form name="fo">
+<table bgcolor="#cccccc" cellspacing="1" cellpadding="8">
+ <tr bgcolor="#ffeeee"><th height="40" align="right">Expression</th><td><input name="zeile" type="text" size="60"></td></tr>
+ <tr bgcolor="#eeeeee"><th align="right">Result Type</th><td><input name="restyp" readonly type="text" size="60"></td></tr>
+ <tr bgcolor="#eeeeee"><th align="right">Result(s)</th><td><textarea readonly name="field" rows="10" cols="60"></textarea></td></tr>
+<tr bgcolor="#ffeeee"><td>&nbsp;</td><td>
+ <input type="button" value="list properties" onclick="do_properties()">
+ <input type="button" value="evaluate" onclick="do_eval()">
+ <input type="reset" value="clear fields"
+</td></tr>
+</table>
+</form>
+<h2>Explanation</h2>
+<h3>Operation</h3>
+<blockquote>
+When <em>evaluate</em> is pressed, the given expression is evaluated and the result is displayed in the result(s) field.
+In case of <em>list properties</em> being pressed, the result of the expression is taken as an object
+and the objects properties are displayed with their type and value in the the result(s) field.
+</blockquote>
+<h3>Expression</h3>
+<blockquote>
+Expression must be a valid javascript expression, e.g.<br><code>window</code>
+<br>or<br><code>document.body.innerHTML</code><br>or<br>
+<code>"Today: " + (new Date()).toString()</code><br>
+or<br>
+<code>"Cablecar".match(/ab.*c/)</code>
+<br>It is also possible to assign a value,
+e.g.<br><code>document.getElementsByTagName('H1').item(0).innerText="Hello World"</code><br>
+You may execute these examples by pasting them into the expression field.
+</blockquote>
+<h3>Result Type</h3>
+<blockquote>
+The type of the result of the given expression.
+</blockquote>
+<h3>Result(s)</h3>
+<blockquote>
+The result of the expression is implicitly converted to a primitive type by the javascript interpreter,
+if <em>evaluate</em> was pressed. When <em>list properties</em> was pressed, a <code>for (var i in obj)</code> loop
+is executed to list the properties. These object properties are in turn evaluated and their types and values
+are displayed.
+</blockquote>
+<p>
+<a href="mailto:till@snafu.de?subject=JavaScript%20Konsole">Till Krech</a>
+</p>
+<p>
+<br>
+</p>
+
+</body>
+</html>
diff --git a/khtml/ecma/kjs_binding.cpp b/khtml/ecma/kjs_binding.cpp
new file mode 100644
index 000000000..295d8c5e9
--- /dev/null
+++ b/khtml/ecma/kjs_binding.cpp
@@ -0,0 +1,467 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2003 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001-2003 David Faure (faure@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "kjs_binding.h"
+#include "kjs_dom.h"
+
+#include "dom/dom_exception.h"
+#include "dom/dom2_range.h"
+#include "xml/dom2_eventsimpl.h"
+#include "khtmlpart_p.h"
+
+#include <kdebug.h>
+#include <kparts/browserextension.h>
+
+#include <assert.h>
+
+using namespace KJS;
+
+/* TODO:
+ * The catch all (...) clauses below shouldn't be necessary.
+ * But they helped to view for example www.faz.net in an stable manner.
+ * Those unknown exceptions should be treated as severe bugs and be fixed.
+ *
+ * these may be CSS exceptions - need to check - pmk
+ */
+
+Value DOMObject::get(ExecState *exec, const Identifier &p) const
+{
+ Value result;
+ try {
+ result = tryGet(exec,p);
+ }
+ catch (DOM::DOMException e) {
+ // ### translate code into readable string ?
+ // ### oh, and s/QString/i18n or I18N_NOOP (the code in kjs uses I18N_NOOP... but where is it translated ?)
+ // and where does it appear to the user ?
+ Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
+ exec->setException( err );
+ result = Undefined();
+ }
+ catch (...) {
+ kdError(6070) << "Unknown exception in DOMObject::get()" << endl;
+ result = String("Unknown exception");
+ }
+
+ return result;
+}
+
+void DOMObject::put(ExecState *exec, const Identifier &propertyName,
+ const Value &value, int attr)
+{
+ try {
+ tryPut(exec, propertyName, value, attr);
+ }
+ catch (DOM::DOMException e) {
+ Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
+ exec->setException(err);
+ }
+ catch (...) {
+ kdError(6070) << "Unknown exception in DOMObject::put()" << endl;
+ }
+}
+
+void DOMObject::tryPut(ExecState *exec, const Identifier &propertyName,
+ const Value& value, int attr)
+{
+ static_cast<ScriptInterpreter*>(exec->dynamicInterpreter())->customizedDOMObject(this);
+ ObjectImp::put(exec,propertyName,value,attr);
+}
+
+UString DOMObject::toString(ExecState *) const
+{
+ return "[object " + className() + "]";
+}
+
+Boolean DOMObject::hasInstance(ExecState *exec, const Value &value)
+{
+ if (value.type() != ObjectType)
+ return Boolean(false);
+
+ Value prot = get(exec,prototypePropertyName);
+ if (prot.type() != ObjectType && prot.type() != NullType) {
+ Object err = Error::create(exec, TypeError, "Invalid prototype encountered "
+ "in instanceof operation.");
+ exec->setException(err);
+ return Boolean(false);
+ }
+
+ Object v = Object(static_cast<ObjectImp*>(value.imp()));
+ while ((v = Object::dynamicCast(v.prototype())).imp()) {
+ if (v.imp() == prot.imp())
+ return Boolean(true);
+ }
+ return Boolean(false);
+}
+
+
+Value DOMFunction::get(ExecState *exec, const Identifier &propertyName) const
+{
+ try {
+ return tryGet(exec, propertyName);
+ }
+ catch (DOM::DOMException e) {
+ Object err = Error::create(exec, GeneralError, QString("DOM exception %1").arg(e.code).local8Bit());
+ exec->setException(err);
+ return Undefined();
+ }
+ catch (...) {
+ kdError(6070) << "Unknown exception in DOMFunction::get()" << endl;
+ return String("Unknown exception");
+ }
+}
+
+Value DOMFunction::call(ExecState *exec, Object &thisObj, const List &args)
+{
+ try {
+ return tryCall(exec, thisObj, args);
+ }
+ // pity there's no way to distinguish between these in JS code
+ // ### Look into setting prototypes of these & the use of instanceof so the exception
+ // type can be determined. See what other browsers do.
+ catch (DOM::DOMException e) {
+ Object err = Error::create(exec, GeneralError, QString("DOM Exception %1").arg(e.code).local8Bit());
+ err.put(exec, "code", Number(e.code));
+ exec->setException(err);
+ return Undefined();
+ }
+ catch (DOM::RangeException e) {
+ Object err = Error::create(exec, GeneralError, QString("DOM Range Exception %1").arg(e.code).local8Bit());
+ err.put(exec, "code", Number(e.code));
+ exec->setException(err);
+ return Undefined();
+ }
+ catch (DOM::CSSException e) {
+ Object err = Error::create(exec, GeneralError, QString("CSS Exception %1").arg(e.code).local8Bit());
+ err.put(exec, "code", Number(e.code));
+ exec->setException(err);
+ return Undefined();
+ }
+ catch (DOM::EventException e) {
+ Object err = Error::create(exec, GeneralError, QString("DOM Event Exception %1").arg(e.code).local8Bit());
+ err.put(exec, "code", Number(e.code));
+ exec->setException(err);
+ return Undefined();
+ }
+ catch (...) {
+ kdError(6070) << "Unknown exception in DOMFunction::call()" << endl;
+ Object err = Error::create(exec, GeneralError, "Unknown exception");
+ exec->setException(err);
+ return Undefined();
+ }
+}
+
+typedef QPtrList<ScriptInterpreter> InterpreterList;
+static InterpreterList *interpreterList;
+
+ScriptInterpreter::ScriptInterpreter( const Object &global, khtml::ChildFrame* frame )
+ : Interpreter( global ), m_frame( frame ), m_domObjects(1021),
+ m_evt( 0L ), m_inlineCode(false), m_timerCallback(false)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "ScriptInterpreter::ScriptInterpreter " << this << " for part=" << m_frame << endl;
+#endif
+ if ( !interpreterList )
+ interpreterList = new InterpreterList;
+ interpreterList->append( this );
+}
+
+ScriptInterpreter::~ScriptInterpreter()
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "ScriptInterpreter::~ScriptInterpreter " << this << " for part=" << m_frame << endl;
+#endif
+ assert( interpreterList && interpreterList->contains( this ) );
+ interpreterList->remove( this );
+ if ( interpreterList->isEmpty() ) {
+ delete interpreterList;
+ interpreterList = 0;
+ }
+}
+
+void ScriptInterpreter::forgetDOMObject( void* objectHandle )
+{
+ if( !interpreterList ) return;
+
+ QPtrListIterator<ScriptInterpreter> it( *interpreterList );
+ while ( it.current() ) {
+ (*it)->deleteDOMObject( objectHandle );
+ ++it;
+ }
+}
+
+void ScriptInterpreter::mark()
+{
+ Interpreter::mark();
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "ScriptInterpreter::mark " << this << " marking " << m_customizedDomObjects.count() << " DOM objects" << endl;
+#endif
+ QPtrDictIterator<void> it( m_customizedDomObjects );
+ for( ; it.current(); ++it )
+ static_cast<DOMObject*>(it.currentKey())->mark();
+}
+
+KParts::ReadOnlyPart* ScriptInterpreter::part() const {
+ return m_frame->m_part;
+}
+
+bool ScriptInterpreter::isWindowOpenAllowed() const
+{
+ if ( m_evt )
+ {
+ int id = m_evt->handle()->id();
+ bool eventOk = ( // mouse events
+ id == DOM::EventImpl::CLICK_EVENT ||
+ id == DOM::EventImpl::MOUSEUP_EVENT || id == DOM::EventImpl::MOUSEDOWN_EVENT ||
+ id == DOM::EventImpl::KHTML_ECMA_CLICK_EVENT || id == DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT ||
+ // keyboard events
+ id == DOM::EventImpl::KEYDOWN_EVENT || id == DOM::EventImpl::KEYPRESS_EVENT ||
+ id == DOM::EventImpl::KEYUP_EVENT ||
+ // other accepted events
+ id == DOM::EventImpl::SELECT_EVENT || id == DOM::EventImpl::CHANGE_EVENT ||
+ id == DOM::EventImpl::SUBMIT_EVENT );
+ kdDebug(6070) << "Window.open, smart policy: id=" << id << " eventOk=" << eventOk << endl;
+ if (eventOk)
+ return true;
+ } else // no event
+ {
+ if ( m_inlineCode && !m_timerCallback )
+ {
+ // This is the <a href="javascript:window.open('...')> case -> we let it through
+ return true;
+ kdDebug(6070) << "Window.open, smart policy, no event, inline code -> ok" << endl;
+ }
+ else // This is the <script>window.open(...)</script> case or a timer callback -> block it
+ kdDebug(6070) << "Window.open, smart policy, no event, <script> tag -> refused" << endl;
+ }
+ return false;
+}
+
+
+UString::UString(const QString &d)
+{
+ unsigned int len = d.length();
+ UChar *dat = new UChar[len];
+ memcpy(dat, d.unicode(), len * sizeof(UChar));
+ rep = UString::Rep::create(dat, len);
+}
+
+UString::UString(const DOM::DOMString &d)
+{
+ if (d.isNull()) {
+ // we do a conversion here as null DOMStrings shouldn't cross
+ // the boundary to kjs. They should either be empty strings
+ // or explicitly converted to KJS::Null via getString().
+ attach(&Rep::empty);
+ return;
+ }
+
+ unsigned int len = d.length();
+ UChar *dat = new UChar[len];
+ memcpy(dat, d.unicode(), len * sizeof(UChar));
+ rep = UString::Rep::create(dat, len);
+}
+
+DOM::DOMString UString::string() const
+{
+ return DOM::DOMString((QChar*) data(), size());
+}
+
+QString UString::qstring() const
+{
+ return QString((QChar*) data(), size());
+}
+
+QConstString UString::qconststring() const
+{
+ return QConstString((QChar*) data(), size());
+}
+
+DOM::DOMString Identifier::string() const
+{
+ return DOM::DOMString((QChar*) data(), size());
+}
+
+QString Identifier::qstring() const
+{
+ return QString((QChar*) data(), size());
+}
+
+DOM::Node KJS::toNode(const Value& val)
+{
+ Object obj = Object::dynamicCast(val);
+ if (!obj.isValid() || !obj.inherits(&DOMNode::info))
+ return DOM::Node();
+
+ const DOMNode *dobj = static_cast<const DOMNode*>(obj.imp());
+ return dobj->toNode();
+}
+
+Value KJS::getString(DOM::DOMString s)
+{
+ if (s.isNull())
+ return Null();
+ else
+ return String(s);
+}
+
+QVariant KJS::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;
+}
+
+class EmbedLiveConnect : public ObjectImp
+{
+ friend Value KJS::getLiveConnectValue(KParts::LiveConnectExtension *lc, const QString & name, const int type, const QString & value, int id);
+ EmbedLiveConnect(KParts::LiveConnectExtension *lc, UString n, KParts::LiveConnectExtension::Type t, int id);
+public:
+ ~EmbedLiveConnect();
+
+ virtual Value get(ExecState *, const Identifier & prop) const;
+ virtual void put(ExecState * exec, const Identifier &prop, const Value & value, int=None);
+ virtual Value call(ExecState * exec, Object &, const List &args);
+ virtual bool implementsCall() const;
+ virtual bool toBoolean(ExecState *) const;
+ virtual Value toPrimitive(ExecState *exec, Type) const;
+ virtual UString toString(ExecState *) const;
+
+private:
+ EmbedLiveConnect(const EmbedLiveConnect &);
+ QGuardedPtr<KParts::LiveConnectExtension> m_liveconnect;
+ UString name;
+ KParts::LiveConnectExtension::Type objtype;
+ unsigned long objid;
+};
+
+Value KJS::getLiveConnectValue(KParts::LiveConnectExtension *lc, const QString & name, const int type, const QString & value, int id)
+{
+ KParts::LiveConnectExtension::Type t=(KParts::LiveConnectExtension::Type)type;
+ switch(t) {
+ case KParts::LiveConnectExtension::TypeBool: {
+ bool ok;
+ int i = value.toInt(&ok);
+ if (ok)
+ return Boolean(i);
+ return Boolean(!strcasecmp(value.latin1(), "true"));
+ }
+ case KParts::LiveConnectExtension::TypeObject:
+ case KParts::LiveConnectExtension::TypeFunction:
+ return Value(new EmbedLiveConnect(lc, name, t, id));
+ case KParts::LiveConnectExtension::TypeNumber: {
+ bool ok;
+ int i = value.toInt(&ok);
+ if (ok)
+ return Number(i);
+ else
+ return Number(value.toDouble(&ok));
+ }
+ case KParts::LiveConnectExtension::TypeString:
+ return String(value);
+ case KParts::LiveConnectExtension::TypeVoid:
+ default:
+ return Undefined();
+ }
+}
+
+/* only with gcc > 3.4 KDE_NO_EXPORT */
+EmbedLiveConnect::EmbedLiveConnect(KParts::LiveConnectExtension *lc, UString n, KParts::LiveConnectExtension::Type t, int id)
+ : m_liveconnect (lc), name(n), objtype(t), objid(id)
+{}
+
+/* only with gcc > 3.4 KDE_NO_EXPORT */
+EmbedLiveConnect::~EmbedLiveConnect() {
+ if (m_liveconnect)
+ m_liveconnect->unregister(objid);
+}
+
+KDE_NO_EXPORT
+Value EmbedLiveConnect::get(ExecState *, const Identifier & prop) const
+{
+ if (m_liveconnect) {
+ KParts::LiveConnectExtension::Type rettype;
+ QString retval;
+ unsigned long retobjid;
+ if (m_liveconnect->get(objid, prop.qstring(), rettype, retobjid, retval))
+ return getLiveConnectValue(m_liveconnect, prop.qstring(), rettype, retval, retobjid);
+ }
+ return Undefined();
+}
+
+KDE_NO_EXPORT
+void EmbedLiveConnect::put(ExecState * exec, const Identifier &prop, const Value & value, int)
+{
+ if (m_liveconnect)
+ m_liveconnect->put(objid, prop.qstring(), value.toString(exec).qstring());
+}
+
+KDE_NO_EXPORT
+bool EmbedLiveConnect::implementsCall() const {
+ return objtype == KParts::LiveConnectExtension::TypeFunction;
+}
+
+KDE_NO_EXPORT
+Value EmbedLiveConnect::call(ExecState *exec, Object&, const List &args)
+{
+ if (m_liveconnect) {
+ QStringList qargs;
+ for (ListIterator i = args.begin(); i != args.end(); ++i)
+ qargs.append((*i).toString(exec).qstring());
+ KParts::LiveConnectExtension::Type rtype;
+ QString rval;
+ unsigned long robjid;
+ if (m_liveconnect->call(objid, name.qstring(), qargs, rtype, robjid, rval))
+ return getLiveConnectValue(m_liveconnect, name.qstring(), rtype, rval, robjid);
+ }
+ return Undefined();
+}
+
+KDE_NO_EXPORT
+bool EmbedLiveConnect::toBoolean(ExecState *) const {
+ return true;
+}
+
+KDE_NO_EXPORT
+Value EmbedLiveConnect::toPrimitive(ExecState *exec, Type) const {
+ return String(toString(exec));
+}
+
+KDE_NO_EXPORT
+UString EmbedLiveConnect::toString(ExecState *) const {
+ QString str;
+ const char *type = objtype == KParts::LiveConnectExtension::TypeFunction ? "Function" : "Object";
+ str.sprintf("[object %s ref=%d]", type, (int) objid);
+ return UString(str);
+}
diff --git a/khtml/ecma/kjs_binding.h b/khtml/ecma/kjs_binding.h
new file mode 100644
index 000000000..4b49e866b
--- /dev/null
+++ b/khtml/ecma/kjs_binding.h
@@ -0,0 +1,409 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_BINDING_H_
+#define _KJS_BINDING_H_
+
+#include <kjs/interpreter.h>
+#include <kjs/function_object.h> /// for FunctionPrototypeImp
+
+#include <dom/dom_node.h>
+#include <qvariant.h>
+#include <qptrdict.h>
+#include <kurl.h>
+#include <kjs/lookup.h>
+
+namespace KParts {
+ class ReadOnlyPart;
+ class LiveConnectExtension;
+}
+
+namespace khtml {
+ class ChildFrame;
+}
+
+namespace KJS {
+
+ /**
+ * Base class for all objects in this binding - get() and put() run
+ * tryGet() and tryPut() respectively, and catch exceptions if they
+ * occur.
+ */
+ class DOMObject : public ObjectImp {
+ public:
+ DOMObject(const Object &proto) : ObjectImp(proto) {}
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const
+ { return ObjectImp::get(exec, propertyName); }
+ virtual bool implementsHasInstance() const { return true; }
+ virtual Boolean hasInstance(ExecState *exec, const Value &value);
+ virtual void put(ExecState *exec, const Identifier &propertyName,
+ const Value &value, int attr = None);
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName,
+ const Value& value, int attr = None);
+
+ virtual UString toString(ExecState *exec) const;
+ };
+
+ /**
+ * Base class for all functions in this binding - get() and call() run
+ * tryGet() and tryCall() respectively, and catch exceptions if they
+ * occur.
+ */
+ class DOMFunction : public InternalFunctionImp {
+ public:
+ DOMFunction(ExecState* exec) : InternalFunctionImp(
+ static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+ ) {}
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const
+ { return ObjectImp::get(exec, propertyName); }
+
+ virtual bool implementsCall() const { return true; }
+ virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
+ virtual Value tryCall(ExecState *exec, Object &thisObj, const List&args)
+ { return ObjectImp::call(exec, thisObj, args); }
+ virtual bool toBoolean(ExecState *) const { return true; }
+ };
+
+ /**
+ * We inherit from Interpreter, to save a pointer to the HTML part
+ * that the interpreter runs for.
+ * The interpreter also stores the DOM object - >KJS::DOMObject cache.
+ */
+ class KDE_EXPORT ScriptInterpreter : public Interpreter
+ {
+ public:
+ ScriptInterpreter( const Object &global, khtml::ChildFrame* frame );
+ virtual ~ScriptInterpreter();
+
+ DOMObject* getDOMObject( void* objectHandle ) const {
+ return m_domObjects[objectHandle];
+ }
+ void putDOMObject( void* objectHandle, DOMObject* obj ) {
+ m_domObjects.insert( objectHandle, obj );
+ }
+ void customizedDOMObject( DOMObject* obj ) {
+ m_customizedDomObjects.replace( obj, this );
+ }
+ bool deleteDOMObject( void* objectHandle ) {
+ DOMObject* obj = m_domObjects.take( objectHandle );
+ if (obj) {
+ m_customizedDomObjects.remove( obj );
+ return true;
+ }
+ else
+ return false;
+ }
+ void clear() {
+ m_customizedDomObjects.clear();
+ m_domObjects.clear();
+ }
+ /**
+ * Static method. Makes all interpreters forget about the object
+ */
+ static void forgetDOMObject( void* objectHandle );
+
+ /**
+ * Mark objects in the DOMObject cache.
+ */
+ virtual void mark();
+ KParts::ReadOnlyPart* part() const;
+
+ virtual int rtti() { return 1; }
+
+ /**
+ * Set the event that is triggering the execution of a script, if any
+ */
+ void setCurrentEvent( DOM::Event *evt ) { m_evt = evt; }
+ void setInlineCode( bool inlineCode ) { m_inlineCode = inlineCode; }
+ void setProcessingTimerCallback( bool timerCallback ) { m_timerCallback = timerCallback; }
+ /**
+ * "Smart" window.open policy
+ */
+ bool isWindowOpenAllowed() const;
+
+ private:
+ khtml::ChildFrame* m_frame;
+ QPtrDict<DOMObject> m_domObjects;
+ QPtrDict<void> m_customizedDomObjects; //Objects which had custom properties set,
+ //and should not be GC'd. key is DOMObject*
+ DOM::Event *m_evt;
+ bool m_inlineCode;
+ bool m_timerCallback;
+ };
+ /**
+ * Retrieve from cache, or create, a KJS object around a DOM object
+ */
+ template<class DOMObj, class KJSDOMObj>
+ inline Value cacheDOMObject(ExecState *exec, DOMObj domObj)
+ {
+ DOMObject *ret;
+ if (domObj.isNull())
+ return Null();
+ ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+ if ((ret = interp->getDOMObject(domObj.handle())))
+ return Value(ret);
+ else {
+ ret = new KJSDOMObj(exec, domObj);
+ interp->putDOMObject(domObj.handle(),ret);
+ return Value(ret);
+ }
+ }
+
+ /**
+ * Convert an object to a Node. Returns a null Node if not possible.
+ */
+ DOM::Node toNode(const Value&);
+ /**
+ * Get a String object, or Null() if s is null
+ */
+ Value getString(DOM::DOMString s);
+
+ /**
+ * Convery a KJS value into a QVariant
+ */
+ QVariant ValueToVariant(ExecState* exec, const Value& val);
+
+ /**
+ * We need a modified version of lookupGet because
+ * we call tryGet instead of get, in DOMObjects.
+ */
+ template <class FuncImp, class ThisImp, class ParentImp>
+ inline Value DOMObjectLookupGet(ExecState *exec, const Identifier &propertyName,
+ const HashTable* table, const ThisImp* thisObj)
+ {
+ const HashEntry* entry = Lookup::findEntry(table, propertyName);
+
+ if (!entry) // not found, forward to parent
+ return thisObj->ParentImp::tryGet(exec, propertyName);
+
+ if (entry->attr & Function) {
+ return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
+ }
+ return thisObj->getValueProperty(exec, entry->value);
+ }
+
+ /**
+ * Simplified version of DOMObjectLookupGet in case there are no
+ * functions, only "values".
+ */
+ template <class ThisImp, class ParentImp>
+ inline Value DOMObjectLookupGetValue(ExecState *exec, const Identifier &propertyName,
+ const HashTable* table, const ThisImp* thisObj)
+ {
+ const HashEntry* entry = Lookup::findEntry(table, propertyName);
+
+ if (!entry) // not found, forward to parent
+ return thisObj->ParentImp::tryGet(exec, propertyName);
+
+ if (entry->attr & Function)
+ fprintf(stderr, "Function bit set! Shouldn't happen in lookupValue!\n" );
+ return thisObj->getValueProperty(exec, entry->value);
+ }
+
+ /**
+ * We need a modified version of lookupPut because
+ * we call tryPut instead of put, in DOMObjects.
+ */
+ template <class ThisImp, class ParentImp>
+ inline void DOMObjectLookupPut(ExecState *exec, const Identifier &propertyName,
+ const Value& value, int attr,
+ const HashTable* table, ThisImp* thisObj)
+ {
+ const HashEntry* entry = Lookup::findEntry(table, propertyName);
+
+ if (!entry) // not found: forward to parent
+ thisObj->ParentImp::tryPut(exec, propertyName, value, attr);
+ else if (entry->attr & Function) // function: put as override property
+ thisObj->ObjectImp::put(exec, propertyName, value, attr);
+ else if (entry->attr & ReadOnly) // readonly! Can't put!
+#ifdef KJS_VERBOSE
+ fprintf(stderr,"WARNING: Attempt to change value of readonly property '%s'\n",propertyName.ascii());
+#else
+ ; // do nothing
+#endif
+ else
+ thisObj->putValueProperty(exec, entry->value, value, attr);
+ }
+
+// Versions of prototype functions that properly support instanceof,
+// and are compatible with trunk.
+#define KJS_DEFINE_PROTOTYPE_IMP(ClassProto,ProtoCode) \
+ class ClassProto : public ObjectImp { \
+ friend Object cacheGlobalObject<ClassProto>(ExecState *exec, const Identifier &propertyName); \
+ public: \
+ static Object self(ExecState *exec); \
+ virtual const ClassInfo *classInfo() const { return &info; } \
+ static const ClassInfo info; \
+ Value get(ExecState *exec, const Identifier &propertyName) const; \
+ protected: \
+ ClassProto( ExecState *exec ) \
+ : ObjectImp( ProtoCode ) {} \
+ \
+ static Identifier* s_name; \
+ static Identifier* name(); \
+ };
+
+#define KJS_DEFINE_PROTOTYPE(ClassProto) \
+ KJS_DEFINE_PROTOTYPE_IMP(ClassProto, exec->interpreter()->builtinObjectPrototype())
+
+#define KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(ClassProto, ClassProtoProto) \
+ KJS_DEFINE_PROTOTYPE_IMP(ClassProto, ClassProtoProto::self(exec))
+
+#define KJS_EMPTY_PROTOTYPE_IMP(ClassName, ClassProto, ProtoCode) \
+ class ClassProto : public ObjectImp { \
+ friend Object cacheGlobalObject<ClassProto>(ExecState *exec, const Identifier &propertyName); \
+ public: \
+ static Object self(ExecState *exec) { \
+ return cacheGlobalObject<ClassProto>(exec, *name()); \
+ } \
+ virtual const ClassInfo *classInfo() const { return &info; } \
+ static const ClassInfo info; \
+ protected: \
+ ClassProto( ExecState *exec ) \
+ : ObjectImp( ProtoCode ) {} \
+ \
+ static Identifier* s_name; \
+ static Identifier* name() { \
+ if (!s_name) s_name = new Identifier("[[" ClassName ".prototype]]"); \
+ return s_name; \
+ }\
+ }; \
+ Identifier* ClassProto::s_name = 0; \
+ const ClassInfo ClassProto::info = { ClassName, 0, 0, 0 };
+
+#define KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE(ClassName, ClassProto, ClassProtoProto) \
+ KJS_EMPTY_PROTOTYPE_IMP(ClassName, ClassProto, ClassProtoProto::self(exec))
+
+//### this doesn't implement hasProperty, but stuff in lookup.h didn't
+//either (just did the forward)
+#define KJS_IMPLEMENT_PROTOTYPE(ClassName, ClassProto, ClassFunc) \
+ const ClassInfo ClassProto::info = { ClassName, 0, &ClassProto##Table, 0 }; \
+ Identifier* ClassProto::s_name = 0; \
+ Object ClassProto::self(ExecState *exec) \
+ { \
+ return cacheGlobalObject<ClassProto>(exec, *name()); \
+ } \
+ Value ClassProto::get(ExecState *exec, const Identifier &propertyName) const \
+ { \
+ /*fprintf( stderr, "%sProto::get(%s) [in macro, no parent]\n", info.className, propertyName.ascii());*/ \
+ return lookupGetFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
+ } \
+ Identifier* ClassProto::name() \
+ { \
+ if (!s_name) s_name = new Identifier("[[" ClassName ".prototype]]"); \
+ return s_name; \
+ }
+
+ // Modified version of IMPLEMENT_PROTOFUNC, to use DOMFunction and tryCall
+#define IMPLEMENT_PROTOFUNC_DOM(ClassFunc) \
+ class ClassFunc : public DOMFunction { \
+ public: \
+ ClassFunc(ExecState *exec, int i, int len) \
+ : DOMFunction( exec ), id(i) { \
+ Value protect(this); \
+ put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum); \
+ } \
+ /** You need to implement that one */ \
+ virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args); \
+ private: \
+ int id; \
+ };
+
+ Value getLiveConnectValue(KParts::LiveConnectExtension *lc, const QString & name, const int type, const QString & value, int id);
+
+
+// This is used to create pseudo-constructor objects, like Mozillaish
+// Element, HTMLDocument, etc., which do not act like real constructors,
+// but do have the prototype property pointing to prototype of "instances"
+#define DEFINE_PSEUDO_CONSTRUCTOR(ClassName) \
+ class ClassName : public DOMObject { \
+ public: \
+ ClassName(ExecState *); \
+ virtual const ClassInfo* classInfo() const { return &info; } \
+ static const ClassInfo info; \
+ static Object self(ExecState *exec); \
+ };
+
+#define IMPLEMENT_PSEUDO_CONSTRUCTOR_IMP(Class,ClassName,ProtoClass,ParentProto) \
+ const ClassInfo Class::info = { ClassName, 0, 0, 0 }; \
+ Class::Class(ExecState* exec): DOMObject(ParentProto) {\
+ Object proto = ProtoClass::self(exec); \
+ putDirect(prototypePropertyName, proto.imp(), DontDelete|ReadOnly); \
+ }\
+ Object Class::self(ExecState *exec) { \
+ return Object(cacheGlobalObject<Class>(exec, "[[" ClassName ".constructor]]")); \
+ }
+
+#define IMPLEMENT_PSEUDO_CONSTRUCTOR(Class,ClassName,ProtoClass) \
+ IMPLEMENT_PSEUDO_CONSTRUCTOR_IMP(Class,ClassName,ProtoClass,exec->lexicalInterpreter()->builtinObjectPrototype())
+
+#define IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(Class,ClassName,ProtoClass,ParentProtoClass) \
+ IMPLEMENT_PSEUDO_CONSTRUCTOR_IMP(Class,ClassName,ProtoClass,ParentProtoClass::self(exec))
+
+// This declares a constant table, which merely maps everything in its
+// table to its token value. Can be used as a prototype
+#define DEFINE_CONSTANT_TABLE(Class) \
+ class Class : public DOMObject { \
+ public: \
+ Class(ExecState *exec): DOMObject(exec->lexicalInterpreter()->builtinObjectPrototype()) {} \
+ \
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;\
+ Value getValueProperty(ExecState * /*exec*/, int token) const; \
+ virtual const ClassInfo* classInfo() const { return &info; } \
+ static const ClassInfo info; \
+ static Object self(ExecState *exec);\
+ static Identifier* s_name; \
+ static Identifier* name(); \
+ };
+
+// Emits an implementation of a constant table
+#define IMPLEMENT_CONSTANT_TABLE(Class,ClassName) \
+ Value Class::tryGet(ExecState *exec, const Identifier &propertyName) const { \
+ return DOMObjectLookupGetValue<Class, DOMObject>(exec, propertyName, &Class##Table, this);\
+ } \
+ Value Class::getValueProperty(ExecState * /*exec*/, int token) const { \
+ /* We use the token as the value to return directly*/ \
+ return Number((unsigned int)token); \
+ } \
+ Object Class::self(ExecState *exec) { \
+ return cacheGlobalObject<Class>(exec, *name()); \
+ } \
+ Identifier* Class::s_name = 0; \
+ Identifier* Class::name() { \
+ if (!s_name) s_name = new Identifier("[[" ClassName ".constant_table]]"); \
+ return s_name; \
+ } \
+ const ClassInfo Class::info = { ClassName, 0, &Class##Table, 0 };
+
+
+// Hide some of the stuff in lookup.h..
+#undef PUBLIC_DEFINE_PROTOTYPE
+#undef DEFINE_PROTOTYPE
+#undef IMPLEMENT_PROTOTYPE
+#undef PUBLIC_IMPLEMENT_PROTOTYPE
+#undef IMPLEMENT_PROTOTYPE_WITH_PARENT
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_css.cpp b/khtml/ecma/kjs_css.cpp
new file mode 100644
index 000000000..167809046
--- /dev/null
+++ b/khtml/ecma/kjs_css.cpp
@@ -0,0 +1,1302 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "kjs_css.h"
+#include "kjs_css.lut.h"
+
+#include <dom/html_head.h> // for HTMLStyleElement
+
+#include <css/css_base.h>
+#include "kjs_dom.h"
+
+
+#include <kdebug.h>
+
+namespace KJS {
+
+static QString cssPropertyName( const Identifier &p, bool& hadPixelPrefix )
+{
+ QString prop = p.qstring();
+ int i = prop.length();
+ while ( --i ) {
+ char c = prop[i].latin1();
+ if ( c >= 'A' && c <= 'Z' )
+ prop.insert( i, '-' );
+ }
+
+ prop = prop.lower();
+ hadPixelPrefix = false;
+
+ if (prop.startsWith("css-")) {
+ prop = prop.mid(4);
+ } else if (prop.startsWith("pixel-")) {
+ prop = prop.mid(6);
+ hadPixelPrefix = true;
+ } else if (prop.startsWith("pos-")) {
+ prop = prop.mid(4);
+ hadPixelPrefix = true;
+ }
+
+ return prop;
+}
+
+/*
+@begin DOMCSSStyleDeclarationProtoTable 7
+ getPropertyValue DOMCSSStyleDeclaration::GetPropertyValue DontDelete|Function 1
+ getPropertyCSSValue DOMCSSStyleDeclaration::GetPropertyCSSValue DontDelete|Function 1
+ removeProperty DOMCSSStyleDeclaration::RemoveProperty DontDelete|Function 1
+ getPropertyPriority DOMCSSStyleDeclaration::GetPropertyPriority DontDelete|Function 1
+ setProperty DOMCSSStyleDeclaration::SetProperty DontDelete|Function 3
+ item DOMCSSStyleDeclaration::Item DontDelete|Function 1
+# IE names for it (#36063)
+ getAttribute DOMCSSStyleDeclaration::GetPropertyValue DontDelete|Function 1
+ removeAttribute DOMCSSStyleDeclaration::RemoveProperty DontDelete|Function 1
+ setAttribute DOMCSSStyleDeclaration::SetProperty DontDelete|Function 3
+@end
+@begin DOMCSSStyleDeclarationTable 3
+ cssText DOMCSSStyleDeclaration::CssText DontDelete
+ length DOMCSSStyleDeclaration::Length DontDelete|ReadOnly
+ parentRule DOMCSSStyleDeclaration::ParentRule DontDelete|ReadOnly
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMCSSStyleDeclarationProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMCSSStyleDeclarationProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleDeclaration", DOMCSSStyleDeclarationProto, DOMCSSStyleDeclarationProtoFunc)
+
+IMPLEMENT_PSEUDO_CONSTRUCTOR(CSSStyleDeclarationPseudoCtor, "DOMCSSStyleDeclaration",DOMCSSStyleDeclarationProto)
+
+const ClassInfo DOMCSSStyleDeclaration::info = { "CSSStyleDeclaration", 0, &DOMCSSStyleDeclarationTable, 0 };
+
+DOMCSSStyleDeclaration::DOMCSSStyleDeclaration(ExecState *exec, const DOM::CSSStyleDeclaration& s)
+ : DOMObject(DOMCSSStyleDeclarationProto::self(exec)), styleDecl(s)
+{ }
+
+DOMCSSStyleDeclaration::~DOMCSSStyleDeclaration()
+{
+ ScriptInterpreter::forgetDOMObject(styleDecl.handle());
+}
+
+bool DOMCSSStyleDeclaration::hasProperty(ExecState *exec, const Identifier &p) const
+{
+ bool hadPixelPrefix;
+ QString cssprop = cssPropertyName(p, hadPixelPrefix);
+ if (DOM::getPropertyID(cssprop.latin1(), cssprop.length()))
+ return true;
+
+ return ObjectImp::hasProperty(exec, p);
+}
+
+Value DOMCSSStyleDeclaration::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMCSSStyleDeclaration::tryGet " << propertyName.qstring() << endl;
+#endif
+ const HashEntry* entry = Lookup::findEntry(&DOMCSSStyleDeclarationTable, propertyName);
+ if (entry)
+ switch (entry->value) {
+ case CssText:
+ return String(styleDecl.cssText());
+ case Length:
+ return Number(styleDecl.length());
+ case ParentRule:
+ return getDOMCSSRule(exec,styleDecl.parentRule());
+ default:
+ break;
+ }
+
+ // Look in the prototype (for functions) before assuming it's a name
+ Object proto = Object::dynamicCast(prototype());
+ if (proto.isValid() && proto.hasProperty(exec,propertyName))
+ return proto.get(exec,propertyName);
+
+ bool ok;
+ long unsigned int u = propertyName.toULong(&ok);
+ if (ok)
+ return String(DOM::CSSStyleDeclaration(styleDecl).item(u));
+
+ // pixelTop returns "CSS Top" as number value in unit pixels
+ // posTop returns "CSS top" as number value in unit pixels _if_ its a
+ // positioned element. if it is not a positioned element, return 0
+ // from MSIE documentation ### IMPLEMENT THAT (Dirk)
+ bool asNumber;
+ QString p = cssPropertyName(propertyName, asNumber);
+
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMCSSStyleDeclaration: converting to css property name: " << p << ( asNumber ? "px" : "" ) << endl;
+#endif
+
+ if (asNumber) {
+ DOM::CSSValue v = styleDecl.getPropertyCSSValue(p);
+ if ( !v.isNull() && v.cssValueType() == DOM::CSSValue::CSS_PRIMITIVE_VALUE)
+ return Number(static_cast<DOM::CSSPrimitiveValue>(v).getFloatValue(DOM::CSSPrimitiveValue::CSS_PX));
+ }
+
+ DOM::DOMString str = const_cast<DOM::CSSStyleDeclaration &>( styleDecl ).getPropertyValue(p);
+ if (!str.isNull())
+ return String(str);
+
+ // see if we know this css property, return empty then
+ if (DOM::getPropertyID(p.latin1(), p.length()))
+ return String(DOM::DOMString(""));
+
+ return DOMObject::tryGet(exec, propertyName);
+}
+
+
+void DOMCSSStyleDeclaration::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr )
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMCSSStyleDeclaration::tryPut " << propertyName.qstring() << endl;
+#endif
+ if (propertyName == "cssText") {
+ styleDecl.setCssText(value.toString(exec).string());
+ }
+ else {
+ bool pxSuffix;
+ QString prop = cssPropertyName(propertyName, pxSuffix);
+ QString propvalue = value.toString(exec).qstring();
+
+ if (pxSuffix)
+ propvalue += "px";
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMCSSStyleDeclaration: prop=" << prop << " propvalue=" << propvalue << endl;
+#endif
+ // Look whether the property is known.d In that case add it as a CSS property.
+ if (DOM::getPropertyID(prop.latin1(), prop.length())) {
+ if (propvalue.isEmpty())
+ styleDecl.removeProperty(prop);
+ else {
+ int important = propvalue.find("!important", 0, false);
+ if (important == -1)
+ styleDecl.setProperty(prop, DOM::DOMString(propvalue), "");
+ else
+ styleDecl.setProperty(prop, DOM::DOMString(propvalue.left(important - 1)), "important");
+ }
+ }
+ else
+ // otherwise add it as a JS property
+ DOMObject::tryPut( exec, propertyName, value, attr );
+ }
+}
+
+Value DOMCSSStyleDeclarationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMCSSStyleDeclaration, thisObj );
+ DOM::CSSStyleDeclaration styleDecl = static_cast<DOMCSSStyleDeclaration *>(thisObj.imp())->toStyleDecl();
+ String str = args[0].toString(exec);
+ DOM::DOMString s = str.value().string();
+
+ switch (id) {
+ case DOMCSSStyleDeclaration::GetPropertyValue:
+ return String(styleDecl.getPropertyValue(s));
+ case DOMCSSStyleDeclaration::GetPropertyCSSValue:
+ return getDOMCSSValue(exec,styleDecl.getPropertyCSSValue(s));
+ case DOMCSSStyleDeclaration::RemoveProperty:
+ return String(styleDecl.removeProperty(s));
+ case DOMCSSStyleDeclaration::GetPropertyPriority:
+ return String(styleDecl.getPropertyPriority(s));
+ case DOMCSSStyleDeclaration::SetProperty:
+ styleDecl.setProperty(args[0].toString(exec).string(),
+ args[1].toString(exec).string(),
+ args[2].toString(exec).string());
+ return Undefined();
+ case DOMCSSStyleDeclaration::Item:
+ return String(styleDecl.item(args[0].toInteger(exec)));
+ default:
+ return Undefined();
+ }
+}
+
+Value getDOMCSSStyleDeclaration(ExecState *exec, const DOM::CSSStyleDeclaration& s)
+{
+ return cacheDOMObject<DOM::CSSStyleDeclaration, KJS::DOMCSSStyleDeclaration>(exec, s);
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMStyleSheet::info = { "StyleSheet", 0, &DOMStyleSheetTable, 0 };
+/*
+@begin DOMStyleSheetTable 7
+ type DOMStyleSheet::Type DontDelete|ReadOnly
+ disabled DOMStyleSheet::Disabled DontDelete
+ ownerNode DOMStyleSheet::OwnerNode DontDelete|ReadOnly
+ parentStyleSheet DOMStyleSheet::ParentStyleSheet DontDelete|ReadOnly
+ href DOMStyleSheet::Href DontDelete|ReadOnly
+ title DOMStyleSheet::Title DontDelete|ReadOnly
+ media DOMStyleSheet::Media DontDelete|ReadOnly
+@end
+*/
+
+DOMStyleSheet::DOMStyleSheet(ExecState* exec, const DOM::StyleSheet& ss)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), styleSheet(ss)
+{
+}
+
+DOMStyleSheet::~DOMStyleSheet()
+{
+ ScriptInterpreter::forgetDOMObject(styleSheet.handle());
+}
+
+Value DOMStyleSheet::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ return DOMObjectLookupGetValue<DOMStyleSheet,DOMObject>(exec,propertyName,&DOMStyleSheetTable,this);
+}
+
+Value DOMStyleSheet::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Type:
+ return String(styleSheet.type());
+ case Disabled:
+ return Boolean(styleSheet.disabled());
+ case OwnerNode:
+ return getDOMNode(exec,styleSheet.ownerNode());
+ case ParentStyleSheet:
+ return getDOMStyleSheet(exec,styleSheet.parentStyleSheet());
+ case Href:
+ return String(styleSheet.href());
+ case Title:
+ return String(styleSheet.title());
+ case Media:
+ return getDOMMediaList(exec, styleSheet.media());
+ }
+ return Value();
+}
+
+void DOMStyleSheet::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+ if (propertyName == "disabled") {
+ styleSheet.setDisabled(value.toBoolean(exec));
+ }
+ else
+ DOMObject::tryPut(exec, propertyName, value, attr);
+}
+
+Value getDOMStyleSheet(ExecState *exec, const DOM::StyleSheet& ss)
+{
+ DOMObject *ret;
+ if (ss.isNull())
+ return Null();
+ ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+ if ((ret = interp->getDOMObject(ss.handle())))
+ return Value(ret);
+ else {
+ if (ss.isCSSStyleSheet()) {
+ DOM::CSSStyleSheet cs;
+ cs = ss;
+ ret = new DOMCSSStyleSheet(exec,cs);
+ }
+ else
+ ret = new DOMStyleSheet(exec,ss);
+ interp->putDOMObject(ss.handle(),ret);
+ return Value(ret);
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMStyleSheetList::info = { "StyleSheetList", 0, &DOMStyleSheetListTable, 0 };
+
+/*
+@begin DOMStyleSheetListTable 2
+ length DOMStyleSheetList::Length DontDelete|ReadOnly
+ item DOMStyleSheetList::Item DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(DOMStyleSheetListFunc) // not really a proto, but doesn't matter
+
+DOMStyleSheetList::DOMStyleSheetList(ExecState *exec, const DOM::StyleSheetList& ssl, const DOM::Document& doc)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), styleSheetList(ssl), m_doc(doc)
+{
+}
+
+DOMStyleSheetList::~DOMStyleSheetList()
+{
+ ScriptInterpreter::forgetDOMObject(styleSheetList.handle());
+}
+
+Value DOMStyleSheetList::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMStyleSheetList::tryGet " << p.qstring() << endl;
+#endif
+ if (p == lengthPropertyName)
+ return Number(styleSheetList.length());
+ else if (p == "item")
+ return lookupOrCreateFunction<DOMStyleSheetListFunc>(exec,p,this,DOMStyleSheetList::Item,1,DontDelete|Function);
+
+ // Retrieve stylesheet by index
+ bool ok;
+ long unsigned int u = p.toULong(&ok);
+ if (ok)
+ return getDOMStyleSheet(exec, DOM::StyleSheetList(styleSheetList).item(u));
+
+ // IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
+ // (this is consistent with all the other collections)
+#if 0
+ // Bad implementation because DOM::StyleSheet doesn't inherit DOM::Node
+ // so we can't use DOMNamedNodesCollection.....
+ // We could duplicate it for stylesheets though - worth it ?
+ // Other problem of this implementation: it doesn't look for the ID attribute!
+ DOM::NameNodeListImpl namedList( m_doc.documentElement().handle(), p.string() );
+ int len = namedList.length();
+ if ( len ) {
+ QValueList<DOM::Node> styleSheets;
+ for ( int i = 0 ; i < len ; ++i ) {
+ DOM::HTMLStyleElement elem = DOM::Node(namedList.item(i));
+ if (!elem.isNull())
+ styleSheets.append(elem.sheet());
+ }
+ if ( styleSheets.count() == 1 ) // single result
+ return getDOMStyleSheet(exec, styleSheets[0]);
+ else if ( styleSheets.count() > 1 ) {
+ return new DOMNamedItemsCollection(exec,styleSheets);
+ }
+ }
+#endif
+ // ### Bad implementation because returns a single element (are IDs always unique?)
+ // and doesn't look for name attribute (see implementation above).
+ // But unicity of stylesheet ids is good practice anyway ;)
+ DOM::DOMString pstr = p.string();
+ DOM::HTMLStyleElement styleElem = m_doc.getElementById( pstr );
+ if (!styleElem.isNull())
+ return getDOMStyleSheet(exec, styleElem.sheet());
+
+ return DOMObject::tryGet(exec, p);
+}
+
+Value KJS::DOMStyleSheetList::call(ExecState *exec, Object &thisObj, const List &args)
+{
+ // This code duplication is necessary, DOMStyleSheetList isn't a DOMFunction
+ Value val;
+ try {
+ val = tryCall(exec, thisObj, args);
+ }
+ // pity there's no way to distinguish between these in JS code
+ catch (...) {
+ Object err = Error::create(exec, GeneralError, "Exception from DOMStyleSheetList");
+ exec->setException(err);
+ }
+ return val;
+}
+
+Value DOMStyleSheetList::tryCall(ExecState *exec, Object & /*thisObj*/, const List &args)
+{
+ if (args.size() == 1) {
+ // support for styleSheets(<index>) and styleSheets(<name>)
+ return tryGet( exec, Identifier(args[0].toString(exec)) );
+ }
+ return Undefined();
+}
+
+Value getDOMStyleSheetList(ExecState *exec, const DOM::StyleSheetList& ssl, const DOM::Document& doc)
+{
+ // Can't use the cacheDOMObject macro because of the doc argument
+ DOMObject *ret;
+ if (ssl.isNull())
+ return Null();
+ ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+ if ((ret = interp->getDOMObject(ssl.handle())))
+ return Value(ret);
+ else {
+ ret = new DOMStyleSheetList(exec, ssl, doc);
+ interp->putDOMObject(ssl.handle(),ret);
+ return Value(ret);
+ }
+}
+
+Value DOMStyleSheetListFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMStyleSheetList, thisObj );
+ DOM::StyleSheetList styleSheetList = static_cast<DOMStyleSheetList *>(thisObj.imp())->toStyleSheetList();
+ if (id == DOMStyleSheetList::Item)
+ return getDOMStyleSheet(exec, styleSheetList.item(args[0].toInteger(exec)));
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMMediaList::info = { "MediaList", 0, &DOMMediaListTable, 0 };
+
+/*
+@begin DOMMediaListTable 2
+ mediaText DOMMediaList::MediaText DontDelete|ReadOnly
+ length DOMMediaList::Length DontDelete|ReadOnly
+@end
+@begin DOMMediaListProtoTable 3
+ item DOMMediaList::Item DontDelete|Function 1
+ deleteMedium DOMMediaList::DeleteMedium DontDelete|Function 1
+ appendMedium DOMMediaList::AppendMedium DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMMediaListProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMMediaListProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMMediaList", DOMMediaListProto, DOMMediaListProtoFunc)
+
+DOMMediaList::DOMMediaList(ExecState *exec, const DOM::MediaList& ml)
+ : DOMObject(DOMMediaListProto::self(exec)), mediaList(ml) { }
+
+DOMMediaList::~DOMMediaList()
+{
+ ScriptInterpreter::forgetDOMObject(mediaList.handle());
+}
+
+Value DOMMediaList::tryGet(ExecState *exec, const Identifier &p) const
+{
+ if (p == "mediaText")
+ return String(mediaList.mediaText());
+ else if (p == lengthPropertyName)
+ return Number(mediaList.length());
+
+ bool ok;
+ long unsigned int u = p.toULong(&ok);
+ if (ok)
+ return String(mediaList.item(u));
+
+ return DOMObject::tryGet(exec, p);
+}
+
+void DOMMediaList::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+ if (propertyName == "mediaText")
+ mediaList.setMediaText(value.toString(exec).string());
+ else
+ DOMObject::tryPut(exec, propertyName, value, attr);
+}
+
+Value getDOMMediaList(ExecState *exec, const DOM::MediaList& ml)
+{
+ return cacheDOMObject<DOM::MediaList, KJS::DOMMediaList>(exec, ml);
+}
+
+Value KJS::DOMMediaListProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMMediaList, thisObj );
+ DOM::MediaList mediaList = static_cast<DOMMediaList *>(thisObj.imp())->toMediaList();
+ switch (id) {
+ case DOMMediaList::Item:
+ return String(mediaList.item(args[0].toInteger(exec)));
+ case DOMMediaList::DeleteMedium:
+ mediaList.deleteMedium(args[0].toString(exec).string());
+ return Undefined();
+ case DOMMediaList::AppendMedium:
+ mediaList.appendMedium(args[0].toString(exec).string());
+ return Undefined();
+ default:
+ return Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMCSSStyleSheet::info = { "CSSStyleSheet", 0, &DOMCSSStyleSheetTable, 0 };
+
+/*
+@begin DOMCSSStyleSheetTable 2
+ ownerRule DOMCSSStyleSheet::OwnerRule DontDelete|ReadOnly
+ cssRules DOMCSSStyleSheet::CssRules DontDelete|ReadOnly
+# MSIE extension
+ rules DOMCSSStyleSheet::Rules DontDelete|ReadOnly
+@end
+@begin DOMCSSStyleSheetProtoTable 2
+ insertRule DOMCSSStyleSheet::InsertRule DontDelete|Function 2
+ deleteRule DOMCSSStyleSheet::DeleteRule DontDelete|Function 1
+# IE extensions
+ addRule DOMCSSStyleSheet::AddRule DontDelete|Function 3
+ removeRule DOMCSSStyleSheet::RemoveRule DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMCSSStyleSheetProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMCSSStyleSheetProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleSheet",DOMCSSStyleSheetProto,DOMCSSStyleSheetProtoFunc) // warning, use _WITH_PARENT if DOMStyleSheet gets a proto
+
+DOMCSSStyleSheet::DOMCSSStyleSheet(ExecState *exec, const DOM::CSSStyleSheet& ss)
+ : DOMStyleSheet(DOMCSSStyleSheetProto::self(exec),ss) { }
+
+DOMCSSStyleSheet::~DOMCSSStyleSheet()
+{
+}
+
+Value DOMCSSStyleSheet::tryGet(ExecState *exec, const Identifier &p) const
+{
+ DOM::CSSStyleSheet cssStyleSheet = static_cast<DOM::CSSStyleSheet>(styleSheet);
+ if (p == "ownerRule")
+ return getDOMCSSRule(exec,cssStyleSheet.ownerRule());
+ else if (p == "cssRules" || p == "rules" /* MSIE extension */)
+ return getDOMCSSRuleList(exec,cssStyleSheet.cssRules());
+ return DOMStyleSheet::tryGet(exec,p);
+}
+
+Value DOMCSSStyleSheetProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMCSSStyleSheet, thisObj );
+ DOM::CSSStyleSheet styleSheet = static_cast<DOMCSSStyleSheet *>(thisObj.imp())->toCSSStyleSheet();
+
+ switch (id) {
+ case DOMCSSStyleSheet::InsertRule:
+ return Number(styleSheet.insertRule(args[0].toString(exec).string(),(long unsigned int)args[1].toInteger(exec)));
+ case DOMCSSStyleSheet::DeleteRule:
+ styleSheet.deleteRule(args[0].toInteger(exec));
+ return Undefined();
+ // IE extensions
+ case DOMCSSStyleSheet::AddRule: {
+ //Unpassed/-1 means append. Since insertRule is picky (throws exceptions)
+ //we adjust it to the desired length
+ unsigned long index = args[2].toInteger(exec);
+ unsigned long length = styleSheet.cssRules().length();
+ if (args[2].type() == UndefinedType) index = length;
+ if (index > length) index = length;
+ DOM::DOMString str = args[0].toString(exec).string() + " { " + args[1].toString(exec).string() + " } ";
+ return Number(styleSheet.insertRule(str,index));
+ }
+ case DOMCSSStyleSheet::RemoveRule: {
+ int index = args.size() > 0 ? args[0].toInteger(exec) : 0 /*first one*/;
+ styleSheet.deleteRule(index);
+ return Undefined();
+ }
+ default:
+ return Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMCSSRuleList::info = { "CSSRuleList", 0, &DOMCSSRuleListTable, 0 };
+/*
+@begin DOMCSSRuleListTable 3
+ length DOMCSSRuleList::Length DontDelete|ReadOnly
+ item DOMCSSRuleList::Item DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(DOMCSSRuleListFunc) // not really a proto, but doesn't matter
+
+DOMCSSRuleList::DOMCSSRuleList(ExecState* exec, const DOM::CSSRuleList& rl)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), cssRuleList(rl)
+{
+}
+
+DOMCSSRuleList::~DOMCSSRuleList()
+{
+ ScriptInterpreter::forgetDOMObject(cssRuleList.handle());
+}
+
+Value DOMCSSRuleList::tryGet(ExecState *exec, const Identifier &p) const
+{
+ Value result;
+ if (p == lengthPropertyName)
+ return Number(cssRuleList.length());
+ else if (p == "item")
+ return lookupOrCreateFunction<DOMCSSRuleListFunc>(exec,p,this,DOMCSSRuleList::Item,1,DontDelete|Function);
+
+ bool ok;
+ long unsigned int u = p.toULong(&ok);
+ if (ok)
+ return getDOMCSSRule(exec,DOM::CSSRuleList(cssRuleList).item(u));
+
+ return DOMObject::tryGet(exec,p);
+}
+
+Value DOMCSSRuleListFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMCSSRuleList, thisObj );
+ DOM::CSSRuleList cssRuleList = static_cast<DOMCSSRuleList *>(thisObj.imp())->toCSSRuleList();
+ switch (id) {
+ case DOMCSSRuleList::Item:
+ return getDOMCSSRule(exec,cssRuleList.item(args[0].toInteger(exec)));
+ default:
+ return Undefined();
+ }
+}
+
+Value getDOMCSSRuleList(ExecState *exec, const DOM::CSSRuleList& rl)
+{
+ return cacheDOMObject<DOM::CSSRuleList, KJS::DOMCSSRuleList>(exec, rl);
+}
+
+// -------------------------------------------------------------------------
+
+IMPLEMENT_PROTOFUNC_DOM(DOMCSSRuleFunc) // Not a proto, but doesn't matter
+
+DOMCSSRule::DOMCSSRule(ExecState* exec, const DOM::CSSRule& r)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), cssRule(r)
+{
+}
+
+DOMCSSRule::~DOMCSSRule()
+{
+ ScriptInterpreter::forgetDOMObject(cssRule.handle());
+}
+
+const ClassInfo DOMCSSRule::info = { "CSSRule", 0, &DOMCSSRuleTable, 0 };
+const ClassInfo DOMCSSRule::style_info = { "CSSStyleRule", &DOMCSSRule::info, &DOMCSSStyleRuleTable, 0 };
+const ClassInfo DOMCSSRule::media_info = { "CSSMediaRule", &DOMCSSRule::info, &DOMCSSMediaRuleTable, 0 };
+const ClassInfo DOMCSSRule::fontface_info = { "CSSFontFaceRule", &DOMCSSRule::info, &DOMCSSFontFaceRuleTable, 0 };
+const ClassInfo DOMCSSRule::page_info = { "CSSPageRule", &DOMCSSRule::info, &DOMCSSPageRuleTable, 0 };
+const ClassInfo DOMCSSRule::import_info = { "CSSImportRule", &DOMCSSRule::info, &DOMCSSImportRuleTable, 0 };
+const ClassInfo DOMCSSRule::charset_info = { "CSSCharsetRule", &DOMCSSRule::info, &DOMCSSCharsetRuleTable, 0 };
+
+const ClassInfo* DOMCSSRule::classInfo() const
+{
+ switch (cssRule.type()) {
+ case DOM::CSSRule::STYLE_RULE:
+ return &style_info;
+ case DOM::CSSRule::MEDIA_RULE:
+ return &media_info;
+ case DOM::CSSRule::FONT_FACE_RULE:
+ return &fontface_info;
+ case DOM::CSSRule::PAGE_RULE:
+ return &page_info;
+ case DOM::CSSRule::IMPORT_RULE:
+ return &import_info;
+ case DOM::CSSRule::CHARSET_RULE:
+ return &charset_info;
+ case DOM::CSSRule::UNKNOWN_RULE:
+ default:
+ return &info;
+ }
+}
+/*
+@begin DOMCSSRuleTable 4
+ type DOMCSSRule::Type DontDelete|ReadOnly
+ cssText DOMCSSRule::CssText DontDelete|ReadOnly
+ parentStyleSheet DOMCSSRule::ParentStyleSheet DontDelete|ReadOnly
+ parentRule DOMCSSRule::ParentRule DontDelete|ReadOnly
+@end
+@begin DOMCSSStyleRuleTable 2
+ selectorText DOMCSSRule::Style_SelectorText DontDelete
+ style DOMCSSRule::Style_Style DontDelete|ReadOnly
+@end
+@begin DOMCSSMediaRuleTable 4
+ media DOMCSSRule::Media_Media DontDelete|ReadOnly
+ cssRules DOMCSSRule::Media_CssRules DontDelete|ReadOnly
+ insertRule DOMCSSRule::Media_InsertRule DontDelete|Function 2
+ deleteRule DOMCSSRule::Media_DeleteRule DontDelete|Function 1
+@end
+@begin DOMCSSFontFaceRuleTable 1
+ style DOMCSSRule::FontFace_Style DontDelete|ReadOnly
+@end
+@begin DOMCSSPageRuleTable 2
+ selectorText DOMCSSRule::Page_SelectorText DontDelete
+ style DOMCSSRule::Page_Style DontDelete|ReadOnly
+@end
+@begin DOMCSSImportRuleTable 3
+ href DOMCSSRule::Import_Href DontDelete|ReadOnly
+ media DOMCSSRule::Import_Media DontDelete|ReadOnly
+ styleSheet DOMCSSRule::Import_StyleSheet DontDelete|ReadOnly
+@end
+@begin DOMCSSCharsetRuleTable 1
+ encoding DOMCSSRule::Charset_Encoding DontDelete
+@end
+*/
+Value DOMCSSRule::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMCSSRule::tryGet " << propertyName.qstring() << endl;
+#endif
+ const HashTable* table = classInfo()->propHashTable; // get the right hashtable
+ const HashEntry* entry = Lookup::findEntry(table, propertyName);
+ if (entry) {
+ if (entry->attr & Function)
+ return lookupOrCreateFunction<DOMCSSRuleFunc>(exec, propertyName, this, entry->value, entry->params, entry->attr);
+ return getValueProperty(exec, entry->value);
+ }
+
+ // Base CSSRule stuff or parent class forward, as usual
+ return DOMObjectLookupGet<DOMCSSRuleFunc, DOMCSSRule, DOMObject>(exec, propertyName, &DOMCSSRuleTable, this);
+}
+
+Value DOMCSSRule::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Type:
+ return Number(cssRule.type());
+ case CssText:
+ return String(cssRule.cssText());
+ case ParentStyleSheet:
+ return getDOMStyleSheet(exec,cssRule.parentStyleSheet());
+ case ParentRule:
+ return getDOMCSSRule(exec,cssRule.parentRule());
+
+ // for DOM::CSSRule::STYLE_RULE:
+ case Style_SelectorText:
+ return String(static_cast<DOM::CSSStyleRule>(cssRule).selectorText());
+ case Style_Style:
+ return getDOMCSSStyleDeclaration(exec,static_cast<DOM::CSSStyleRule>(cssRule).style());
+
+ // for DOM::CSSRule::MEDIA_RULE:
+ case Media_Media:
+ return getDOMMediaList(exec,static_cast<DOM::CSSMediaRule>(cssRule).media());
+ case Media_CssRules:
+ return getDOMCSSRuleList(exec,static_cast<DOM::CSSMediaRule>(cssRule).cssRules());
+
+ // for DOM::CSSRule::FONT_FACE_RULE:
+ case FontFace_Style:
+ return getDOMCSSStyleDeclaration(exec,static_cast<DOM::CSSFontFaceRule>(cssRule).style());
+
+ // for DOM::CSSRule::PAGE_RULE:
+ case Page_SelectorText:
+ return String(static_cast<DOM::CSSPageRule>(cssRule).selectorText());
+ case Page_Style:
+ return getDOMCSSStyleDeclaration(exec,static_cast<DOM::CSSPageRule>(cssRule).style());
+
+ // for DOM::CSSRule::IMPORT_RULE:
+ case Import_Href:
+ return String(static_cast<DOM::CSSImportRule>(cssRule).href());
+ case Import_Media:
+ return getDOMMediaList(exec,static_cast<DOM::CSSImportRule>(cssRule).media());
+ case Import_StyleSheet:
+ return getDOMStyleSheet(exec,static_cast<DOM::CSSImportRule>(cssRule).styleSheet());
+
+ // for DOM::CSSRule::CHARSET_RULE:
+ case Charset_Encoding:
+ return String(static_cast<DOM::CSSCharsetRule>(cssRule).encoding());
+
+ default:
+ kdDebug(6070) << "WARNING: DOMCSSRule::getValueProperty unhandled token " << token << endl;
+ }
+ return Undefined();
+}
+
+void DOMCSSRule::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+ const HashTable* table = classInfo()->propHashTable; // get the right hashtable
+ const HashEntry* entry = Lookup::findEntry(table, propertyName);
+ if (entry) {
+ if (entry->attr & Function) // function: put as override property
+ {
+ ObjectImp::put(exec, propertyName, value, attr);
+ return;
+ }
+ else if ((entry->attr & ReadOnly) == 0) // let DOMObjectLookupPut print the warning if not
+ {
+ putValueProperty(exec, entry->value, value, attr);
+ return;
+ }
+ }
+ DOMObjectLookupPut<DOMCSSRule, DOMObject>(exec, propertyName, value, attr, &DOMCSSRuleTable, this);
+}
+
+void DOMCSSRule::putValueProperty(ExecState *exec, int token, const Value& value, int)
+{
+ switch (token) {
+ // for DOM::CSSRule::STYLE_RULE:
+ case Style_SelectorText:
+ static_cast<DOM::CSSStyleRule>(cssRule).setSelectorText(value.toString(exec).string());
+ return;
+
+ // for DOM::CSSRule::PAGE_RULE:
+ case Page_SelectorText:
+ static_cast<DOM::CSSPageRule>(cssRule).setSelectorText(value.toString(exec).string());
+ return;
+
+ // for DOM::CSSRule::CHARSET_RULE:
+ case Charset_Encoding:
+ static_cast<DOM::CSSCharsetRule>(cssRule).setEncoding(value.toString(exec).string());
+ return;
+
+ default:
+ kdDebug(6070) << "WARNING: DOMCSSRule::putValueProperty unhandled token " << token << endl;
+ }
+}
+
+Value DOMCSSRuleFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMCSSRule, thisObj );
+ DOM::CSSRule cssRule = static_cast<DOMCSSRule *>(thisObj.imp())->toCSSRule();
+
+ if (cssRule.type() == DOM::CSSRule::MEDIA_RULE) {
+ DOM::CSSMediaRule rule = static_cast<DOM::CSSMediaRule>(cssRule);
+ if (id == DOMCSSRule::Media_InsertRule)
+ return Number(rule.insertRule(args[0].toString(exec).string(),args[1].toInteger(exec)));
+ else if (id == DOMCSSRule::Media_DeleteRule)
+ rule.deleteRule(args[0].toInteger(exec));
+ }
+
+ return Undefined();
+}
+
+Value getDOMCSSRule(ExecState *exec, const DOM::CSSRule& r)
+{
+ return cacheDOMObject<DOM::CSSRule, KJS::DOMCSSRule>(exec, r);
+}
+
+// -------------------------------------------------------------------------
+
+
+DOM::CSSRule toCSSRule(const Value& val)
+{
+ Object obj = Object::dynamicCast(val);
+ if (!obj.isValid() || !obj.inherits(&DOMCSSRule::info))
+ return DOM::CSSRule();
+
+ const DOMCSSRule *dobj = static_cast<const DOMCSSRule*>(obj.imp());
+ return dobj->toCSSRule();
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo CSSRuleConstructor::info = { "CSSRuleConstructor", 0, &CSSRuleConstructorTable, 0 };
+/*
+@begin CSSRuleConstructorTable 7
+ UNKNOWN_RULE CSSRuleConstructor::UNKNOWN_RULE DontDelete|ReadOnly
+ STYLE_RULE CSSRuleConstructor::STYLE_RULE DontDelete|ReadOnly
+ CHARSET_RULE CSSRuleConstructor::CHARSET_RULE DontDelete|ReadOnly
+ IMPORT_RULE CSSRuleConstructor::IMPORT_RULE DontDelete|ReadOnly
+ MEDIA_RULE CSSRuleConstructor::MEDIA_RULE DontDelete|ReadOnly
+ FONT_FACE_RULE CSSRuleConstructor::FONT_FACE_RULE DontDelete|ReadOnly
+ PAGE_RULE CSSRuleConstructor::PAGE_RULE DontDelete|ReadOnly
+@end
+*/
+
+CSSRuleConstructor::CSSRuleConstructor(ExecState *exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype())
+{
+}
+
+Value CSSRuleConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<CSSRuleConstructor,DOMObject>(exec,p,&CSSRuleConstructorTable,this);
+}
+
+Value CSSRuleConstructor::getValueProperty(ExecState *, int token) const
+{
+ switch (token) {
+ case UNKNOWN_RULE:
+ return Number(DOM::CSSRule::UNKNOWN_RULE);
+ case STYLE_RULE:
+ return Number(DOM::CSSRule::STYLE_RULE);
+ case CHARSET_RULE:
+ return Number(DOM::CSSRule::CHARSET_RULE);
+ case IMPORT_RULE:
+ return Number(DOM::CSSRule::IMPORT_RULE);
+ case MEDIA_RULE:
+ return Number(DOM::CSSRule::MEDIA_RULE);
+ case FONT_FACE_RULE:
+ return Number(DOM::CSSRule::FONT_FACE_RULE);
+ case PAGE_RULE:
+ return Number(DOM::CSSRule::PAGE_RULE);
+ }
+ return Value();
+}
+
+Value getCSSRuleConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<CSSRuleConstructor>( exec, "[[cssRule.constructor]]" );
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMCSSValue::info = { "CSSValue", 0, &DOMCSSValueTable, 0 };
+
+/*
+@begin DOMCSSValueTable 2
+ cssText DOMCSSValue::CssText DontDelete|ReadOnly
+ cssValueType DOMCSSValue::CssValueType DontDelete|ReadOnly
+@end
+*/
+
+DOMCSSValue::DOMCSSValue(ExecState* exec, const DOM::CSSValue& val)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), cssValue(val)
+{
+}
+
+DOMCSSValue::~DOMCSSValue()
+{
+ ScriptInterpreter::forgetDOMObject(cssValue.handle());
+}
+
+Value DOMCSSValue::tryGet(ExecState *exec, const Identifier &p) const
+{
+ if (p == "cssText")
+ return String(cssValue.cssText());
+ else if (p == "cssValueType")
+ return Number(cssValue.cssValueType());
+ return DOMObject::tryGet(exec,p);
+}
+
+void DOMCSSValue::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+ if (propertyName == "cssText")
+ cssValue.setCssText(value.toString(exec).string());
+ else
+ DOMObject::tryPut(exec, propertyName, value, attr);
+}
+
+Value getDOMCSSValue(ExecState *exec, const DOM::CSSValue& v)
+{
+ DOMObject *ret;
+ if (v.isNull())
+ return Null();
+ ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+ if ((ret = interp->getDOMObject(v.handle())))
+ return Value(ret);
+ else {
+ if (v.isCSSValueList())
+ ret = new DOMCSSValueList(exec,v);
+ else if (v.isCSSPrimitiveValue())
+ ret = new DOMCSSPrimitiveValue(exec,v);
+ else
+ ret = new DOMCSSValue(exec,v);
+ interp->putDOMObject(v.handle(),ret);
+ return Value(ret);
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo CSSValueConstructor::info = { "CSSValueConstructor", 0, &CSSValueConstructorTable, 0 };
+/*
+@begin CSSValueConstructorTable 5
+ CSS_INHERIT CSSValueConstructor::CSS_INHERIT DontDelete|ReadOnly
+ CSS_PRIMITIVE_VALUE CSSValueConstructor::CSS_PRIMITIVE_VALUE DontDelete|ReadOnly
+ CSS_VALUE_LIST CSSValueConstructor::CSS_VALUE_LIST DontDelete|ReadOnly
+ CSS_CUSTOM CSSValueConstructor::CSS_CUSTOM DontDelete|ReadOnly
+@end
+*/
+
+CSSValueConstructor::CSSValueConstructor(ExecState *exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype())
+{
+}
+
+Value CSSValueConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<CSSValueConstructor,DOMObject>(exec,p,&CSSValueConstructorTable,this);
+}
+
+Value CSSValueConstructor::getValueProperty(ExecState *, int token) const
+{
+ switch (token) {
+ case CSS_INHERIT:
+ return Number(DOM::CSSValue::CSS_INHERIT);
+ case CSS_PRIMITIVE_VALUE:
+ return Number(DOM::CSSValue::CSS_PRIMITIVE_VALUE);
+ case CSS_VALUE_LIST:
+ return Number(DOM::CSSValue::CSS_VALUE_LIST);
+ case CSS_CUSTOM:
+ return Number(DOM::CSSValue::CSS_CUSTOM);
+ }
+ return Value();
+}
+
+Value getCSSValueConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<CSSValueConstructor>( exec, "[[cssValue.constructor]]" );
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMCSSPrimitiveValue::info = { "CSSPrimitiveValue", 0, &DOMCSSPrimitiveValueTable, 0 };
+/*
+@begin DOMCSSPrimitiveValueTable 1
+ primitiveType DOMCSSPrimitiveValue::PrimitiveType DontDelete|ReadOnly
+@end
+@begin DOMCSSPrimitiveValueProtoTable 3
+ setFloatValue DOMCSSPrimitiveValue::SetFloatValue DontDelete|Function 2
+ getFloatValue DOMCSSPrimitiveValue::GetFloatValue DontDelete|Function 1
+ setStringValue DOMCSSPrimitiveValue::SetStringValue DontDelete|Function 2
+ getStringValue DOMCSSPrimitiveValue::GetStringValue DontDelete|Function 0
+ getCounterValue DOMCSSPrimitiveValue::GetCounterValue DontDelete|Function 0
+ getRectValue DOMCSSPrimitiveValue::GetRectValue DontDelete|Function 0
+ getRGBColorValue DOMCSSPrimitiveValue::GetRGBColorValue DontDelete|Function 0
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMCSSPrimitiveValueProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMCSSPrimitiveValueProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMCSSPrimitiveValue",DOMCSSPrimitiveValueProto,DOMCSSPrimitiveValueProtoFunc)
+
+DOMCSSPrimitiveValue::DOMCSSPrimitiveValue(ExecState *exec, const DOM::CSSPrimitiveValue& v)
+ : DOMCSSValue(DOMCSSPrimitiveValueProto::self(exec), v) { }
+
+Value DOMCSSPrimitiveValue::tryGet(ExecState *exec, const Identifier &p) const
+{
+ if (p=="primitiveType")
+ return Number(static_cast<DOM::CSSPrimitiveValue>(cssValue).primitiveType());
+ return DOMObject::tryGet(exec,p);
+}
+
+Value DOMCSSPrimitiveValueProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMCSSPrimitiveValue, thisObj );
+ DOM::CSSPrimitiveValue val = static_cast<DOMCSSPrimitiveValue *>(thisObj.imp())->toCSSPrimitiveValue();
+ switch (id) {
+ case DOMCSSPrimitiveValue::SetFloatValue:
+ val.setFloatValue(args[0].toInteger(exec),args[1].toNumber(exec));
+ return Undefined();
+ case DOMCSSPrimitiveValue::GetFloatValue:
+ return Number(val.getFloatValue(args[0].toInteger(exec)));
+ case DOMCSSPrimitiveValue::SetStringValue:
+ val.setStringValue(args[0].toInteger(exec),args[1].toString(exec).string());
+ return Undefined();
+ case DOMCSSPrimitiveValue::GetStringValue:
+ return String(val.getStringValue());
+ case DOMCSSPrimitiveValue::GetCounterValue:
+ return getDOMCounter(exec,val.getCounterValue());
+ case DOMCSSPrimitiveValue::GetRectValue:
+ return getDOMRect(exec,val.getRectValue());
+ case DOMCSSPrimitiveValue::GetRGBColorValue:
+ return getDOMRGBColor(exec,val.getRGBColorValue());
+ default:
+ return Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo CSSPrimitiveValueConstructor::info = { "CSSPrimitiveValueConstructor", 0, &CSSPrimitiveValueConstructorTable, 0 };
+
+/*
+@begin CSSPrimitiveValueConstructorTable 27
+ CSS_UNKNOWN DOM::CSSPrimitiveValue::CSS_UNKNOWN DontDelete|ReadOnly
+ CSS_NUMBER DOM::CSSPrimitiveValue::CSS_NUMBER DontDelete|ReadOnly
+ CSS_PERCENTAGE DOM::CSSPrimitiveValue::CSS_PERCENTAGE DontDelete|ReadOnly
+ CSS_EMS DOM::CSSPrimitiveValue::CSS_EMS DontDelete|ReadOnly
+ CSS_EXS DOM::CSSPrimitiveValue::CSS_EXS DontDelete|ReadOnly
+ CSS_PX DOM::CSSPrimitiveValue::CSS_PX DontDelete|ReadOnly
+ CSS_CM DOM::CSSPrimitiveValue::CSS_CM DontDelete|ReadOnly
+ CSS_MM DOM::CSSPrimitiveValue::CSS_MM DontDelete|ReadOnly
+ CSS_IN DOM::CSSPrimitiveValue::CSS_IN DontDelete|ReadOnly
+ CSS_PT DOM::CSSPrimitiveValue::CSS_PT DontDelete|ReadOnly
+ CSS_PC DOM::CSSPrimitiveValue::CSS_PC DontDelete|ReadOnly
+ CSS_DEG DOM::CSSPrimitiveValue::CSS_DEG DontDelete|ReadOnly
+ CSS_RAD DOM::CSSPrimitiveValue::CSS_RAD DontDelete|ReadOnly
+ CSS_GRAD DOM::CSSPrimitiveValue::CSS_GRAD DontDelete|ReadOnly
+ CSS_MS DOM::CSSPrimitiveValue::CSS_MS DontDelete|ReadOnly
+ CSS_S DOM::CSSPrimitiveValue::CSS_S DontDelete|ReadOnly
+ CSS_HZ DOM::CSSPrimitiveValue::CSS_HZ DontDelete|ReadOnly
+ CSS_KHZ DOM::CSSPrimitiveValue::CSS_KHZ DontDelete|ReadOnly
+ CSS_DIMENSION DOM::CSSPrimitiveValue::CSS_DIMENSION DontDelete|ReadOnly
+ CSS_STRING DOM::CSSPrimitiveValue::CSS_STRING DontDelete|ReadOnly
+ CSS_URI DOM::CSSPrimitiveValue::CSS_URI DontDelete|ReadOnly
+ CSS_IDENT DOM::CSSPrimitiveValue::CSS_IDENT DontDelete|ReadOnly
+ CSS_ATTR DOM::CSSPrimitiveValue::CSS_ATTR DontDelete|ReadOnly
+ CSS_COUNTER DOM::CSSPrimitiveValue::CSS_COUNTER DontDelete|ReadOnly
+ CSS_RECT DOM::CSSPrimitiveValue::CSS_RECT DontDelete|ReadOnly
+ CSS_RGBCOLOR DOM::CSSPrimitiveValue::CSS_RGBCOLOR DontDelete|ReadOnly
+@end
+*/
+
+Value CSSPrimitiveValueConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<CSSPrimitiveValueConstructor,CSSValueConstructor>(exec,p,&CSSPrimitiveValueConstructorTable,this);
+}
+
+Value CSSPrimitiveValueConstructor::getValueProperty(ExecState *, int token) const
+{
+ // We use the token as the value to return directly
+ return Number(token);
+}
+
+Value getCSSPrimitiveValueConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<CSSPrimitiveValueConstructor>( exec, "[[cssPrimitiveValue.constructor]]" );
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMCSSValueList::info = { "CSSValueList", 0, &DOMCSSValueListTable, 0 };
+
+/*
+@begin DOMCSSValueListTable 3
+ length DOMCSSValueList::Length DontDelete|ReadOnly
+ item DOMCSSValueList::Item DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(DOMCSSValueListFunc) // not really a proto, but doesn't matter
+
+DOMCSSValueList::DOMCSSValueList(ExecState *exec, const DOM::CSSValueList& v)
+ : DOMCSSValue(exec, v) { }
+
+Value DOMCSSValueList::tryGet(ExecState *exec, const Identifier &p) const
+{
+ Value result;
+ DOM::CSSValueList valueList = static_cast<DOM::CSSValueList>(cssValue);
+
+ if (p == lengthPropertyName)
+ return Number(valueList.length());
+ else if (p == "item")
+ return lookupOrCreateFunction<DOMCSSValueListFunc>(exec,p,this,DOMCSSValueList::Item,1,DontDelete|Function);
+
+ bool ok;
+ long unsigned int u = p.toULong(&ok);
+ if (ok)
+ return getDOMCSSValue(exec,valueList.item(u));
+
+ return DOMCSSValue::tryGet(exec,p);
+}
+
+Value DOMCSSValueListFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMCSSValueList, thisObj );
+ DOM::CSSValueList valueList = static_cast<DOMCSSValueList *>(thisObj.imp())->toValueList();
+ switch (id) {
+ case DOMCSSValueList::Item:
+ return getDOMCSSValue(exec,valueList.item(args[0].toInteger(exec)));
+ default:
+ return Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMRGBColor::info = { "RGBColor", 0, &DOMRGBColorTable, 0 };
+
+/*
+@begin DOMRGBColorTable 3
+ red DOMRGBColor::Red DontDelete|ReadOnly
+ green DOMRGBColor::Green DontDelete|ReadOnly
+ blue DOMRGBColor::Blue DontDelete|ReadOnly
+@end
+*/
+
+DOMRGBColor::DOMRGBColor(ExecState* exec, const DOM::RGBColor& c)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), rgbColor(c)
+{
+}
+
+DOMRGBColor::~DOMRGBColor()
+{
+ //rgbColors.remove(rgbColor.handle());
+}
+
+Value DOMRGBColor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMRGBColor,DOMObject>(exec, p,
+ &DOMRGBColorTable,
+ this);
+}
+
+Value DOMRGBColor::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Red:
+ return getDOMCSSValue(exec, rgbColor.red());
+ case Green:
+ return getDOMCSSValue(exec, rgbColor.green());
+ case Blue:
+ return getDOMCSSValue(exec, rgbColor.blue());
+ default:
+ return Value();
+ }
+}
+
+Value getDOMRGBColor(ExecState *exec, const DOM::RGBColor& c)
+{
+ // ### implement equals for RGBColor since they're not refcounted objects
+ return Value(new DOMRGBColor(exec, c));
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMRect::info = { "Rect", 0, &DOMRectTable, 0 };
+/*
+@begin DOMRectTable 4
+ top DOMRect::Top DontDelete|ReadOnly
+ right DOMRect::Right DontDelete|ReadOnly
+ bottom DOMRect::Bottom DontDelete|ReadOnly
+ left DOMRect::Left DontDelete|ReadOnly
+@end
+*/
+
+DOMRect::DOMRect(ExecState *exec, const DOM::Rect& r)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), rect(r)
+{
+}
+
+DOMRect::~DOMRect()
+{
+ ScriptInterpreter::forgetDOMObject(rect.handle());
+}
+
+Value DOMRect::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMRect,DOMObject>(exec, p,
+ &DOMRectTable, this);
+}
+
+Value DOMRect::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Top:
+ return getDOMCSSValue(exec, rect.top());
+ case Right:
+ return getDOMCSSValue(exec, rect.right());
+ case Bottom:
+ return getDOMCSSValue(exec, rect.bottom());
+ case Left:
+ return getDOMCSSValue(exec, rect.left());
+ default:
+ return Value();
+ }
+}
+
+Value getDOMRect(ExecState *exec, const DOM::Rect& r)
+{
+ return cacheDOMObject<DOM::Rect, KJS::DOMRect>(exec, r);
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMCounter::info = { "Counter", 0, &DOMCounterTable, 0 };
+/*
+@begin DOMCounterTable 3
+ identifier DOMCounter::identifier DontDelete|ReadOnly
+ listStyle DOMCounter::listStyle DontDelete|ReadOnly
+ separator DOMCounter::separator DontDelete|ReadOnly
+@end
+*/
+DOMCounter::DOMCounter(ExecState *exec, const DOM::Counter& c)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), counter(c)
+{
+}
+
+DOMCounter::~DOMCounter()
+{
+ ScriptInterpreter::forgetDOMObject(counter.handle());
+}
+
+Value DOMCounter::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMCounter,DOMObject>(exec, p,
+ &DOMCounterTable, this);
+}
+
+Value DOMCounter::getValueProperty(ExecState *, int token) const
+{
+ switch (token) {
+ case identifier:
+ return String(counter.identifier());
+ case listStyle:
+ return String(counter.listStyle());
+ case separator:
+ return String(counter.separator());
+ default:
+ return Value();
+ }
+}
+
+Value getDOMCounter(ExecState *exec, const DOM::Counter& c)
+{
+ return cacheDOMObject<DOM::Counter, KJS::DOMCounter>(exec, c);
+}
+
+} //namespace KJS
diff --git a/khtml/ecma/kjs_css.h b/khtml/ecma/kjs_css.h
new file mode 100644
index 000000000..2b7d14712
--- /dev/null
+++ b/khtml/ecma/kjs_css.h
@@ -0,0 +1,304 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_CSS_H_
+#define _KJS_CSS_H_
+
+#include <dom/dom_node.h>
+#include <dom/dom_doc.h>
+#include <kjs/object.h>
+#include <dom/css_value.h>
+#include <dom/css_stylesheet.h>
+#include <dom/css_rule.h>
+#include "kjs_binding.h"
+
+namespace KJS {
+
+ class DOMCSSStyleDeclaration : public DOMObject {
+ public:
+ DOMCSSStyleDeclaration(ExecState *exec, const DOM::CSSStyleDeclaration& s);
+ virtual ~DOMCSSStyleDeclaration();
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo *classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { CssText, Length, ParentRule,
+ GetPropertyValue, GetPropertyCSSValue, RemoveProperty, GetPropertyPriority,
+ SetProperty, Item };
+ DOM::CSSStyleDeclaration toStyleDecl() const { return styleDecl; }
+ protected:
+ DOM::CSSStyleDeclaration styleDecl;
+ };
+
+ DEFINE_PSEUDO_CONSTRUCTOR(CSSStyleDeclarationPseudoCtor)
+
+ Value getDOMCSSStyleDeclaration(ExecState *exec, const DOM::CSSStyleDeclaration& n);
+
+ class DOMStyleSheet : public DOMObject {
+ public:
+ // Build a DOMStyleSheet
+ DOMStyleSheet(ExecState *, const DOM::StyleSheet& ss);
+ // Constructor for inherited classes
+ DOMStyleSheet(const Object& proto, const DOM::StyleSheet& ss) : DOMObject(proto), styleSheet(ss) { }
+ virtual ~DOMStyleSheet();
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ virtual bool toBoolean(ExecState *) const { return true; }
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Type, Disabled, OwnerNode, ParentStyleSheet, Href, Title, Media };
+ protected:
+ DOM::StyleSheet styleSheet;
+ };
+
+ Value getDOMStyleSheet(ExecState *exec, const DOM::StyleSheet& ss);
+
+ class DOMStyleSheetList : public DOMObject {
+ public:
+ DOMStyleSheetList(ExecState *, const DOM::StyleSheetList& ssl, const DOM::Document& doc);
+ virtual ~DOMStyleSheetList();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+ Value tryCall(ExecState *exec, Object &thisObj, const List &args);
+ virtual bool implementsCall() const { return true; }
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ virtual bool toBoolean(ExecState* ) const { return true; }
+ static const ClassInfo info;
+ DOM::StyleSheetList toStyleSheetList() const { return styleSheetList; }
+ enum { Item, Length };
+ private:
+ DOM::StyleSheetList styleSheetList;
+ DOM::Document m_doc;
+ };
+
+ // The document is only used for get-stylesheet-by-name (make optional if necessary)
+ Value getDOMStyleSheetList(ExecState *exec, const DOM::StyleSheetList& ss, const DOM::Document& doc);
+
+ class DOMMediaList : public DOMObject {
+ public:
+ DOMMediaList(ExecState *, const DOM::MediaList& ml);
+ virtual ~DOMMediaList();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ virtual bool toBoolean(ExecState* ) const { return true; }
+ static const ClassInfo info;
+ enum { MediaText, Length,
+ Item, DeleteMedium, AppendMedium };
+ DOM::MediaList toMediaList() const { return mediaList; }
+ private:
+ DOM::MediaList mediaList;
+ };
+
+ Value getDOMMediaList(ExecState *exec, const DOM::MediaList& ss);
+
+ class DOMCSSStyleSheet : public DOMStyleSheet {
+ public:
+ DOMCSSStyleSheet(ExecState *exec, const DOM::CSSStyleSheet& ss);
+ virtual ~DOMCSSStyleSheet();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { OwnerRule, CssRules, Rules,
+ InsertRule, DeleteRule, AddRule, RemoveRule };
+ DOM::CSSStyleSheet toCSSStyleSheet() const { return static_cast<DOM::CSSStyleSheet>(styleSheet); }
+ };
+
+ class DOMCSSRuleList : public DOMObject {
+ public:
+ DOMCSSRuleList(ExecState *, const DOM::CSSRuleList& rl);
+ virtual ~DOMCSSRuleList();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Item, Length };
+ DOM::CSSRuleList toCSSRuleList() const { return cssRuleList; }
+ protected:
+ DOM::CSSRuleList cssRuleList;
+ };
+
+ Value getDOMCSSRuleList(ExecState *exec, const DOM::CSSRuleList& rl);
+
+ class DOMCSSRule : public DOMObject {
+ public:
+ DOMCSSRule(ExecState *, const DOM::CSSRule& r);
+ virtual ~DOMCSSRule();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ void putValueProperty(ExecState *exec, int token, const Value& value, int attr);
+ virtual const ClassInfo* classInfo() const;
+ static const ClassInfo info;
+ static const ClassInfo style_info, media_info, fontface_info, page_info, import_info, charset_info;
+ enum { ParentStyleSheet, Type, CssText, ParentRule,
+ Style_SelectorText, Style_Style,
+ Media_Media, Media_InsertRule, Media_DeleteRule, Media_CssRules,
+ FontFace_Style, Page_SelectorText, Page_Style,
+ Import_Href, Import_Media, Import_StyleSheet, Charset_Encoding };
+ DOM::CSSRule toCSSRule() const { return cssRule; }
+ protected:
+ DOM::CSSRule cssRule;
+ };
+
+ Value getDOMCSSRule(ExecState *exec, const DOM::CSSRule& r);
+
+ /**
+ * Convert an object to a CSSRule. Returns a null CSSRule if not possible.
+ */
+ DOM::CSSRule toCSSRule(const Value&);
+
+ // Constructor for CSSRule - currently only used for some global values
+ class CSSRuleConstructor : public DOMObject {
+ public:
+ CSSRuleConstructor(ExecState *);
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { UNKNOWN_RULE, STYLE_RULE, CHARSET_RULE, IMPORT_RULE, MEDIA_RULE, FONT_FACE_RULE, PAGE_RULE };
+ };
+
+ Value getCSSRuleConstructor(ExecState *exec);
+
+ class DOMCSSValue : public DOMObject {
+ public:
+ DOMCSSValue(ExecState *, const DOM::CSSValue& v);
+ DOMCSSValue(const Object& proto, const DOM::CSSValue& v) : DOMObject(proto), cssValue(v) { }
+ virtual ~DOMCSSValue();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { CssText, CssValueType };
+ protected:
+ DOM::CSSValue cssValue;
+ };
+
+ Value getDOMCSSValue(ExecState *exec, const DOM::CSSValue& v);
+
+ // Constructor for CSSValue - currently only used for some global values
+ class CSSValueConstructor : public DOMObject {
+ public:
+ CSSValueConstructor(ExecState *exec);
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { CSS_VALUE_LIST, CSS_PRIMITIVE_VALUE, CSS_CUSTOM, CSS_INHERIT };
+ };
+
+ Value getCSSValueConstructor(ExecState *exec);
+
+ class DOMCSSPrimitiveValue : public DOMCSSValue {
+ public:
+ DOMCSSPrimitiveValue(ExecState *exec, const DOM::CSSPrimitiveValue& v);
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ DOM::CSSPrimitiveValue toCSSPrimitiveValue() const { return static_cast<DOM::CSSPrimitiveValue>(cssValue); }
+ enum { PrimitiveType, SetFloatValue, GetFloatValue, SetStringValue, GetStringValue,
+ GetCounterValue, GetRectValue, GetRGBColorValue };
+ };
+
+ // Constructor for CSSPrimitiveValue - currently only used for some global values
+ class CSSPrimitiveValueConstructor : public CSSValueConstructor {
+ public:
+ CSSPrimitiveValueConstructor(ExecState *exec) : CSSValueConstructor(exec) { }
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ Value getCSSPrimitiveValueConstructor(ExecState *exec);
+
+ class DOMCSSValueList : public DOMCSSValue {
+ public:
+ DOMCSSValueList(ExecState *exec, const DOM::CSSValueList& v);
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Item, Length };
+ DOM::CSSValueList toValueList() const { return static_cast<DOM::CSSValueList>(cssValue); }
+ };
+
+ class DOMRGBColor : public DOMObject {
+ public:
+ DOMRGBColor(ExecState*, const DOM::RGBColor& c);
+ ~DOMRGBColor();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Red, Green, Blue };
+ protected:
+ DOM::RGBColor rgbColor;
+ };
+
+ Value getDOMRGBColor(ExecState *exec, const DOM::RGBColor& c);
+
+ class DOMRect : public DOMObject {
+ public:
+ DOMRect(ExecState *, const DOM::Rect& r);
+ ~DOMRect();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Top, Right, Bottom, Left };
+ protected:
+ DOM::Rect rect;
+ };
+
+ Value getDOMRect(ExecState *exec, const DOM::Rect& r);
+
+ class DOMCounter : public DOMObject {
+ public:
+ DOMCounter(ExecState *, const DOM::Counter& c);
+ ~DOMCounter();
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { identifier, listStyle, separator };
+ protected:
+ DOM::Counter counter;
+ };
+
+ Value getDOMCounter(ExecState *exec, const DOM::Counter& c);
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_debugwin.cpp b/khtml/ecma/kjs_debugwin.cpp
new file mode 100644
index 000000000..13a12ce5f
--- /dev/null
+++ b/khtml/ecma/kjs_debugwin.cpp
@@ -0,0 +1,1139 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001,2003 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "kjs_debugwin.h"
+#include "kjs_proxy.h"
+
+#ifdef KJS_DEBUGGER
+
+#include <assert.h>
+#include <stdlib.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qtextedit.h>
+#include <qlistbox.h>
+#include <qmultilineedit.h>
+#include <qapplication.h>
+#include <qsplitter.h>
+#include <qcombobox.h>
+#include <qbitmap.h>
+#include <qwidgetlist.h>
+#include <qlabel.h>
+#include <qdatastream.h>
+#include <qcstring.h>
+#include <qpainter.h>
+#include <qscrollbar.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <kmessagebox.h>
+#include <kguiitem.h>
+#include <kpopupmenu.h>
+#include <kmenubar.h>
+#include <kaction.h>
+#include <kactioncollection.h>
+#include <kglobalsettings.h>
+#include <kshortcut.h>
+#include <kconfig.h>
+#include <kconfigbase.h>
+#include <kapplication.h>
+#include <dcop/dcopclient.h>
+#include <kstringhandler.h>
+
+#include "kjs_dom.h"
+#include "kjs_binding.h"
+#include "khtml_part.h"
+#include "khtmlview.h"
+#include "khtml_pagecache.h"
+#include "khtml_settings.h"
+#include "khtml_factory.h"
+#include "misc/decoder.h"
+#include <kjs/ustring.h>
+#include <kjs/object.h>
+#include <kjs/function.h>
+#include <kjs/interpreter.h>
+
+using namespace KJS;
+using namespace khtml;
+
+SourceDisplay::SourceDisplay(KJSDebugWin *debugWin, QWidget *parent, const char *name)
+ : QScrollView(parent,name), m_currentLine(-1), m_sourceFile(0), m_debugWin(debugWin),
+ m_font(KGlobalSettings::fixedFont())
+{
+ verticalScrollBar()->setLineStep(QFontMetrics(m_font).height());
+ viewport()->setBackgroundMode(Qt::NoBackground);
+ m_breakpointIcon = KGlobal::iconLoader()->loadIcon("stop",KIcon::Small);
+}
+
+SourceDisplay::~SourceDisplay()
+{
+ if (m_sourceFile) {
+ m_sourceFile->deref();
+ m_sourceFile = 0L;
+ }
+}
+
+void SourceDisplay::setSource(SourceFile *sourceFile)
+{
+ if ( sourceFile )
+ sourceFile->ref();
+ if (m_sourceFile)
+ m_sourceFile->deref();
+ m_sourceFile = sourceFile;
+ if ( m_sourceFile )
+ m_sourceFile->ref();
+
+ if (!m_sourceFile || !m_debugWin->isVisible()) {
+ return;
+ }
+
+ QString code = sourceFile->getCode();
+ const QChar *chars = code.unicode();
+ uint len = code.length();
+ QChar newLine('\n');
+ QChar cr('\r');
+ QChar tab('\t');
+ QString tabstr(" ");
+ QString line;
+ m_lines.clear();
+ int width = 0;
+ QFontMetrics metrics(m_font);
+
+ for (uint pos = 0; pos < len; pos++) {
+ QChar c = chars[pos];
+ if (c == cr) {
+ if (pos < len-1 && chars[pos+1] == newLine)
+ continue;
+ else
+ c = newLine;
+ }
+ if (c == newLine) {
+ m_lines.append(line);
+ int lineWidth = metrics.width(line);
+ if (lineWidth > width)
+ width = lineWidth;
+ line = "";
+ }
+ else if (c == tab) {
+ line += tabstr;
+ }
+ else {
+ line += c;
+ }
+ }
+ if (line.length()) {
+ m_lines.append(line);
+ int lineWidth = metrics.width(line);
+ if (lineWidth > width)
+ width = lineWidth;
+ }
+
+ int linenoDisplayWidth = metrics.width("888888");
+ resizeContents(linenoDisplayWidth+4+width,metrics.height()*m_lines.count());
+ update();
+ sourceFile->deref();
+}
+
+void SourceDisplay::setCurrentLine(int lineno, bool doCenter)
+{
+ m_currentLine = lineno;
+
+ if (doCenter && m_currentLine >= 0) {
+ QFontMetrics metrics(m_font);
+ int height = metrics.height();
+ center(0,height*m_currentLine+height/2);
+ }
+
+ updateContents();
+}
+
+void SourceDisplay::contentsMousePressEvent(QMouseEvent *e)
+{
+ QScrollView::mouseDoubleClickEvent(e);
+ QFontMetrics metrics(m_font);
+ int lineno = e->y()/metrics.height();
+ emit lineDoubleClicked(lineno+1); // line numbers start from 1
+}
+
+void SourceDisplay::showEvent(QShowEvent *)
+{
+ setSource(m_sourceFile);
+}
+
+void SourceDisplay::drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph)
+{
+ if (!m_sourceFile) {
+ p->fillRect(clipx,clipy,clipw,cliph,palette().active().base());
+ return;
+ }
+
+ QFontMetrics metrics(m_font);
+ int height = metrics.height();
+
+ int bottom = clipy + cliph;
+ int right = clipx + clipw;
+
+ int firstLine = clipy/height-1;
+ if (firstLine < 0)
+ firstLine = 0;
+ int lastLine = bottom/height+2;
+ if (lastLine > (int)m_lines.count())
+ lastLine = m_lines.count();
+
+ p->setFont(m_font);
+
+ int linenoWidth = metrics.width("888888");
+
+ for (int lineno = firstLine; lineno <= lastLine; lineno++) {
+ QString linenoStr = QString().sprintf("%d",lineno+1);
+
+
+ p->fillRect(0,height*lineno,linenoWidth,height,palette().active().mid());
+
+ p->setPen(palette().active().text());
+ p->drawText(0,height*lineno,linenoWidth,height,Qt::AlignRight,linenoStr);
+
+ QColor bgColor;
+ QColor textColor;
+
+ if (lineno == m_currentLine) {
+ bgColor = palette().active().highlight();
+ textColor = palette().active().highlightedText();
+ }
+ else if (m_debugWin->haveBreakpoint(m_sourceFile,lineno+1,lineno+1)) {
+ bgColor = palette().active().text();
+ textColor = palette().active().base();
+ p->drawPixmap(2,height*lineno+height/2-m_breakpointIcon.height()/2,m_breakpointIcon);
+ }
+ else {
+ bgColor = palette().active().base();
+ textColor = palette().active().text();
+ }
+
+ p->fillRect(linenoWidth,height*lineno,right-linenoWidth,height,bgColor);
+ p->setPen(textColor);
+ p->drawText(linenoWidth+4,height*lineno,contentsWidth()-linenoWidth-4,height,
+ Qt::AlignLeft,m_lines[lineno]);
+ }
+
+ int remainingTop = height*(lastLine+1);
+ p->fillRect(0,remainingTop,linenoWidth,bottom-remainingTop,palette().active().mid());
+
+ p->fillRect(linenoWidth,remainingTop,
+ right-linenoWidth,bottom-remainingTop,palette().active().base());
+}
+
+//-------------------------------------------------------------------------
+
+KJSDebugWin * KJSDebugWin::kjs_html_debugger = 0;
+
+QString SourceFile::getCode()
+{
+ if (interpreter) {
+ KHTMLPart *part = ::qt_cast<KHTMLPart*>(static_cast<ScriptInterpreter*>(interpreter)->part());
+ if (part && url == part->url().url() && KHTMLPageCache::self()->isValid(part->cacheId())) {
+ Decoder *decoder = part->createDecoder();
+ QByteArray data;
+ QDataStream stream(data,IO_WriteOnly);
+ KHTMLPageCache::self()->saveData(part->cacheId(),&stream);
+ QString str;
+ if (data.size() == 0)
+ str = "";
+ else
+ str = decoder->decode(data.data(),data.size()) + decoder->flush();
+ delete decoder;
+ return str;
+ }
+ }
+
+ return code;
+}
+
+//-------------------------------------------------------------------------
+
+SourceFragment::SourceFragment(int sid, int bl, int el, SourceFile *sf)
+{
+ sourceId = sid;
+ baseLine = bl;
+ errorLine = el;
+ sourceFile = sf;
+ sourceFile->ref();
+}
+
+SourceFragment::~SourceFragment()
+{
+ sourceFile->deref();
+ sourceFile = 0L;
+}
+
+//-------------------------------------------------------------------------
+
+KJSErrorDialog::KJSErrorDialog(QWidget *parent, const QString& errorMessage, bool showDebug)
+ : KDialogBase(parent,0,true,i18n("JavaScript Error"),
+ showDebug ? KDialogBase::Ok|KDialogBase::User1 : KDialogBase::Ok,
+ KDialogBase::Ok,false,KGuiItem("&Debug","gear"))
+{
+ QWidget *page = new QWidget(this);
+ setMainWidget(page);
+
+ QLabel *iconLabel = new QLabel("",page);
+ iconLabel->setPixmap(KGlobal::iconLoader()->loadIcon("messagebox_critical",
+ KIcon::NoGroup,KIcon::SizeMedium,
+ KIcon::DefaultState,0,true));
+
+ QWidget *contents = new QWidget(page);
+ QLabel *label = new QLabel(errorMessage,contents);
+ m_dontShowAgainCb = new QCheckBox(i18n("&Do not show this message again"),contents);
+
+ QVBoxLayout *vl = new QVBoxLayout(contents,0,spacingHint());
+ vl->addWidget(label);
+ vl->addWidget(m_dontShowAgainCb);
+
+ QHBoxLayout *topLayout = new QHBoxLayout(page,0,spacingHint());
+ topLayout->addWidget(iconLabel);
+ topLayout->addWidget(contents);
+ topLayout->addStretch(10);
+
+ m_debugSelected = false;
+}
+
+KJSErrorDialog::~KJSErrorDialog()
+{
+}
+
+void KJSErrorDialog::slotUser1()
+{
+ m_debugSelected = true;
+ close();
+}
+
+//-------------------------------------------------------------------------
+EvalMultiLineEdit::EvalMultiLineEdit(QWidget *parent)
+ : QMultiLineEdit(parent) {
+}
+
+void EvalMultiLineEdit::keyPressEvent(QKeyEvent * e)
+{
+ if (e->key() == Qt::Key_Return) {
+ if (hasSelectedText()) {
+ m_code = selectedText();
+ } else {
+ int para, index;
+ getCursorPosition(&para, &index);
+ m_code = text(para);
+ }
+ end();
+ }
+ QMultiLineEdit::keyPressEvent(e);
+}
+//-------------------------------------------------------------------------
+KJSDebugWin::KJSDebugWin(QWidget *parent, const char *name)
+ : KMainWindow(parent, name, WType_TopLevel), KInstance("kjs_debugger")
+{
+ m_breakpoints = 0;
+ m_breakpointCount = 0;
+
+ m_curSourceFile = 0;
+ m_mode = Continue;
+ m_nextSourceUrl = "";
+ m_nextSourceBaseLine = 1;
+ m_execs = 0;
+ m_execsCount = 0;
+ m_execsAlloc = 0;
+ m_steppingDepth = 0;
+
+ m_stopIcon = KGlobal::iconLoader()->loadIcon("stop",KIcon::Small);
+ m_emptyIcon = QPixmap(m_stopIcon.width(),m_stopIcon.height());
+ QBitmap emptyMask(m_stopIcon.width(),m_stopIcon.height(),true);
+ m_emptyIcon.setMask(emptyMask);
+
+ setCaption(i18n("JavaScript Debugger"));
+
+ QWidget *mainWidget = new QWidget(this);
+ setCentralWidget(mainWidget);
+
+ QVBoxLayout *vl = new QVBoxLayout(mainWidget,5);
+
+ // frame list & code
+ QSplitter *hsplitter = new QSplitter(Qt::Vertical,mainWidget);
+ QSplitter *vsplitter = new QSplitter(hsplitter);
+ QFont font(KGlobalSettings::fixedFont());
+
+ QWidget *contextContainer = new QWidget(vsplitter);
+
+ QLabel *contextLabel = new QLabel(i18n("Call stack"),contextContainer);
+ QWidget *contextListContainer = new QWidget(contextContainer);
+ m_contextList = new QListBox(contextListContainer);
+ m_contextList->setMinimumSize(100,200);
+ connect(m_contextList,SIGNAL(highlighted(int)),this,SLOT(slotShowFrame(int)));
+
+ QHBoxLayout *clistLayout = new QHBoxLayout(contextListContainer);
+ clistLayout->addWidget(m_contextList);
+ clistLayout->addSpacing(KDialog::spacingHint());
+
+ QVBoxLayout *contextLayout = new QVBoxLayout(contextContainer);
+ contextLayout->addWidget(contextLabel);
+ contextLayout->addSpacing(KDialog::spacingHint());
+ contextLayout->addWidget(contextListContainer);
+
+ // source selection & display
+ QWidget *sourceSelDisplay = new QWidget(vsplitter);
+ QVBoxLayout *ssdvl = new QVBoxLayout(sourceSelDisplay);
+
+ m_sourceSel = new QComboBox(toolBar());
+ connect(m_sourceSel,SIGNAL(activated(int)),this,SLOT(slotSourceSelected(int)));
+
+ m_sourceDisplay = new SourceDisplay(this,sourceSelDisplay);
+ ssdvl->addWidget(m_sourceDisplay);
+ connect(m_sourceDisplay,SIGNAL(lineDoubleClicked(int)),SLOT(slotToggleBreakpoint(int)));
+
+ QValueList<int> vsplitSizes;
+ vsplitSizes.insert(vsplitSizes.end(),120);
+ vsplitSizes.insert(vsplitSizes.end(),480);
+ vsplitter->setSizes(vsplitSizes);
+
+ // evaluate
+
+ QWidget *evalContainer = new QWidget(hsplitter);
+
+ QLabel *evalLabel = new QLabel(i18n("JavaScript console"),evalContainer);
+ m_evalEdit = new EvalMultiLineEdit(evalContainer);
+ m_evalEdit->setWordWrap(QMultiLineEdit::NoWrap);
+ m_evalEdit->setFont(font);
+ connect(m_evalEdit,SIGNAL(returnPressed()),SLOT(slotEval()));
+ m_evalDepth = 0;
+
+ QVBoxLayout *evalLayout = new QVBoxLayout(evalContainer);
+ evalLayout->addSpacing(KDialog::spacingHint());
+ evalLayout->addWidget(evalLabel);
+ evalLayout->addSpacing(KDialog::spacingHint());
+ evalLayout->addWidget(m_evalEdit);
+
+ QValueList<int> hsplitSizes;
+ hsplitSizes.insert(hsplitSizes.end(),400);
+ hsplitSizes.insert(hsplitSizes.end(),200);
+ hsplitter->setSizes(hsplitSizes);
+
+ vl->addWidget(hsplitter);
+
+ // actions
+ KPopupMenu *debugMenu = new KPopupMenu(this);
+ menuBar()->insertItem("&Debug",debugMenu);
+
+ m_actionCollection = new KActionCollection(this);
+ m_actionCollection->setInstance(this);
+
+ // Venkman use F12, KDevelop F10
+ KShortcut scNext = KShortcut(KKeySequence(KKey(Qt::Key_F12)));
+ scNext.append(KKeySequence(KKey(Qt::Key_F10)));
+ m_nextAction = new KAction(i18n("Next breakpoint","&Next"),"dbgnext",scNext,this,SLOT(slotNext()),
+ m_actionCollection,"next");
+ m_stepAction = new KAction(i18n("&Step"),"dbgstep",KShortcut(Qt::Key_F11),this,SLOT(slotStep()),
+ m_actionCollection,"step");
+ // Venkman use F5, Kdevelop F9
+ KShortcut scCont = KShortcut(KKeySequence(KKey(Qt::Key_F5)));
+ scCont.append(KKeySequence(KKey(Qt::Key_F9)));
+ m_continueAction = new KAction(i18n("&Continue"),"dbgrun",scCont,this,SLOT(slotContinue()),
+ m_actionCollection,"cont");
+ m_stopAction = new KAction(i18n("St&op"),"stop",KShortcut(Qt::Key_F4),this,SLOT(slotStop()),
+ m_actionCollection,"stop");
+ m_breakAction = new KAction(i18n("&Break at Next Statement"),"dbgrunto",KShortcut(Qt::Key_F8),this,SLOT(slotBreakNext()),
+ m_actionCollection,"breaknext");
+
+
+ m_nextAction->setToolTip(i18n("Next breakpoint","Next"));
+ m_stepAction->setToolTip(i18n("Step"));
+ m_continueAction->setToolTip(i18n("Continue"));
+ m_stopAction->setToolTip(i18n("Stop"));
+ m_breakAction->setToolTip("Break at next Statement");
+
+ m_nextAction->setEnabled(false);
+ m_stepAction->setEnabled(false);
+ m_continueAction->setEnabled(false);
+ m_stopAction->setEnabled(false);
+ m_breakAction->setEnabled(true);
+
+ m_nextAction->plug(debugMenu);
+ m_stepAction->plug(debugMenu);
+ m_continueAction->plug(debugMenu);
+// m_stopAction->plug(debugMenu); ### disabled until DebuggerImp::stop() works reliably
+ m_breakAction->plug(debugMenu);
+
+ m_nextAction->plug(toolBar());
+ m_stepAction->plug(toolBar());
+ m_continueAction->plug(toolBar());
+// m_stopAction->plug(toolBar()); ###
+ m_breakAction->plug(toolBar());
+
+ toolBar()->insertWidget(1,300,m_sourceSel);
+ toolBar()->setItemAutoSized(1);
+
+ updateContextList();
+ setMinimumSize(300,200);
+ resize(600,450);
+
+}
+
+KJSDebugWin::~KJSDebugWin()
+{
+ free(m_breakpoints);
+ free(m_execs);
+}
+
+KJSDebugWin *KJSDebugWin::createInstance()
+{
+ assert(!kjs_html_debugger);
+ kjs_html_debugger = new KJSDebugWin();
+ return kjs_html_debugger;
+}
+
+void KJSDebugWin::destroyInstance()
+{
+ assert(kjs_html_debugger);
+ kjs_html_debugger->hide();
+ delete kjs_html_debugger;
+}
+
+void KJSDebugWin::slotNext()
+{
+ m_mode = Next;
+ leaveSession();
+}
+
+void KJSDebugWin::slotStep()
+{
+ m_mode = Step;
+ leaveSession();
+}
+
+void KJSDebugWin::slotContinue()
+{
+ m_mode = Continue;
+ leaveSession();
+}
+
+void KJSDebugWin::slotStop()
+{
+ m_mode = Stop;
+ while (!m_execStates.isEmpty())
+ leaveSession();
+}
+
+void KJSDebugWin::slotBreakNext()
+{
+ m_mode = Step;
+}
+
+void KJSDebugWin::slotToggleBreakpoint(int lineno)
+{
+ if (m_sourceSel->currentItem() < 0)
+ return;
+
+ SourceFile *sourceFile = m_sourceSelFiles.at(m_sourceSel->currentItem());
+
+ // Find the source fragment containing the selected line (if any)
+ int sourceId = -1;
+ int highestBaseLine = -1;
+ QMap<int,SourceFragment*>::Iterator it;
+
+ for (it = m_sourceFragments.begin(); it != m_sourceFragments.end(); ++it) {
+ SourceFragment *sourceFragment = it.data();
+ if (sourceFragment &&
+ sourceFragment->sourceFile == sourceFile &&
+ sourceFragment->baseLine <= lineno &&
+ sourceFragment->baseLine > highestBaseLine) {
+
+ sourceId = sourceFragment->sourceId;
+ highestBaseLine = sourceFragment->baseLine;
+ }
+ }
+
+ if (sourceId < 0)
+ return;
+
+ // Update the source code display with the appropriate icon
+ int fragmentLineno = lineno-highestBaseLine+1;
+ if (!setBreakpoint(sourceId,fragmentLineno)) // was already set
+ deleteBreakpoint(sourceId,fragmentLineno);
+
+ m_sourceDisplay->updateContents();
+}
+
+void KJSDebugWin::slotShowFrame(int frameno)
+{
+ if (frameno < 0 || frameno >= m_execsCount)
+ return;
+
+ Context ctx = m_execs[frameno]->context();
+ setSourceLine(ctx.sourceId(),ctx.curStmtFirstLine());
+}
+
+void KJSDebugWin::slotSourceSelected(int sourceSelIndex)
+{
+ // A source file has been selected from the drop-down list - display the file
+ if (sourceSelIndex < 0 || sourceSelIndex >= (int)m_sourceSel->count())
+ return;
+ SourceFile *sourceFile = m_sourceSelFiles.at(sourceSelIndex);
+ displaySourceFile(sourceFile,true);
+
+ // If the currently selected context is in the current source file, then hilight
+ // the line it's on.
+ if (m_contextList->currentItem() >= 0) {
+ Context ctx = m_execs[m_contextList->currentItem()]->context();
+ if (m_sourceFragments[ctx.sourceId()]->sourceFile == m_sourceSelFiles.at(sourceSelIndex))
+ setSourceLine(ctx.sourceId(),ctx.curStmtFirstLine());
+ }
+}
+
+void KJSDebugWin::slotEval()
+{
+ // Work out which execution state to use. If we're currently in a debugging session,
+ // use the current context - otherwise, use the global execution state from the interpreter
+ // corresponding to the currently displayed source file.
+ ExecState *exec;
+ Object thisobj;
+ if (m_execStates.isEmpty()) {
+ if (m_sourceSel->currentItem() < 0)
+ return;
+ SourceFile *sourceFile = m_sourceSelFiles.at(m_sourceSel->currentItem());
+ if (!sourceFile->interpreter)
+ return;
+ exec = sourceFile->interpreter->globalExec();
+ thisobj = exec->interpreter()->globalObject();
+ }
+ else {
+ exec = m_execStates.top();
+ thisobj = exec->context().thisValue();
+ }
+
+ // Evaluate the js code from m_evalEdit
+ UString code(m_evalEdit->code());
+ QString msg;
+
+ KJSCPUGuard guard;
+ guard.start();
+
+ Interpreter *interp = exec->interpreter();
+
+ Object obj = Object::dynamicCast(interp->globalObject().get(exec, "eval"));
+ List args;
+ args.append(String(code));
+
+ m_evalDepth++;
+ Value retval = obj.call(exec, thisobj, args);
+ m_evalDepth--;
+ guard.stop();
+
+ // Print the return value or exception message to the console
+ if (exec->hadException()) {
+ Value exc = exec->exception();
+ exec->clearException();
+ msg = "Exception: " + exc.toString(interp->globalExec()).qstring();
+ }
+ else {
+ msg = retval.toString(interp->globalExec()).qstring();
+ }
+
+ m_evalEdit->insert(msg+"\n");
+ updateContextList();
+}
+
+void KJSDebugWin::closeEvent(QCloseEvent *e)
+{
+ while (!m_execStates.isEmpty()) // ### not sure if this will work
+ leaveSession();
+ return QWidget::closeEvent(e);
+}
+
+bool KJSDebugWin::eventFilter(QObject *o, QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::Destroy:
+ case QEvent::Close:
+ case QEvent::Quit:
+ while (o->parent())
+ o = o->parent();
+ if (o == this)
+ return QWidget::eventFilter(o,e);
+ else
+ return true;
+ break;
+ default:
+ return QWidget::eventFilter(o,e);
+ }
+}
+
+void KJSDebugWin::disableOtherWindows()
+{
+ QWidgetList *widgets = QApplication::allWidgets();
+ QWidgetListIt it(*widgets);
+ for (; it.current(); ++it)
+ it.current()->installEventFilter(this);
+}
+
+void KJSDebugWin::enableOtherWindows()
+{
+ QWidgetList *widgets = QApplication::allWidgets();
+ QWidgetListIt it(*widgets);
+ for (; it.current(); ++it)
+ it.current()->removeEventFilter(this);
+}
+
+bool KJSDebugWin::sourceParsed(KJS::ExecState *exec, int sourceId,
+ const KJS::UString &source, int errorLine)
+{
+ // Work out which source file this fragment is in
+ SourceFile *sourceFile = 0;
+ if (!m_nextSourceUrl.isEmpty())
+ sourceFile = getSourceFile(exec->interpreter(),m_nextSourceUrl);
+
+ int index;
+ if (!sourceFile) {
+ index = m_sourceSel->count();
+ if (!m_nextSourceUrl.isEmpty()) {
+
+ QString code = source.qstring();
+ KParts::ReadOnlyPart *part = static_cast<ScriptInterpreter*>(exec->interpreter())->part();
+ if (m_nextSourceUrl == part->url().url()) {
+ // Only store the code here if it's not from the part's html page... in that
+ // case we can get it from KHTMLPageCache
+ code = QString::null;
+ }
+
+ sourceFile = new SourceFile(m_nextSourceUrl,code,exec->interpreter());
+ setSourceFile(exec->interpreter(),m_nextSourceUrl,sourceFile);
+ m_sourceSelFiles.append(sourceFile);
+ m_sourceSel->insertItem(m_nextSourceUrl);
+ }
+ else {
+ // Sourced passed from somewhere else (possibly an eval call)... we don't know the url,
+ // but we still know the interpreter
+ sourceFile = new SourceFile("(unknown)",source.qstring(),exec->interpreter());
+ m_sourceSelFiles.append(sourceFile);
+ m_sourceSel->insertItem(QString::number(index) += "-???");
+ }
+ }
+ else {
+ // Ensure that each source file to be displayed is associated with
+ // an appropriate interpreter
+ if (!sourceFile->interpreter)
+ sourceFile->interpreter = exec->interpreter();
+ for (index = 0; index < m_sourceSel->count(); index++) {
+ if (m_sourceSelFiles.at(index) == sourceFile)
+ break;
+ }
+ assert(index < m_sourceSel->count());
+ }
+
+ SourceFragment *sf = new SourceFragment(sourceId,m_nextSourceBaseLine,errorLine,sourceFile);
+ m_sourceFragments[sourceId] = sf;
+
+ if (m_sourceSel->currentItem() < 0)
+ m_sourceSel->setCurrentItem(index);
+
+ if (m_sourceSel->currentItem() == index) {
+ displaySourceFile(sourceFile,true);
+ }
+
+ m_nextSourceBaseLine = 1;
+ m_nextSourceUrl = "";
+
+ return (m_mode != Stop);
+}
+
+bool KJSDebugWin::sourceUnused(KJS::ExecState *exec, int sourceId)
+{
+ // Verify that there aren't any contexts on the stack using the given sourceId
+ // This should never be the case because this function is only called when
+ // the interpreter has deleted all Node objects for the source.
+ for (int e = 0; e < m_execsCount; e++)
+ assert(m_execs[e]->context().sourceId() != sourceId);
+
+ // Now remove the fragment (and the SourceFile, if it was the last fragment in that file)
+ SourceFragment *fragment = m_sourceFragments[sourceId];
+ if (fragment) {
+ m_sourceFragments.erase(sourceId);
+
+ SourceFile *sourceFile = fragment->sourceFile;
+ if (sourceFile->hasOneRef()) {
+ for (int i = 0; i < m_sourceSel->count(); i++) {
+ if (m_sourceSelFiles.at(i) == sourceFile) {
+ m_sourceSel->removeItem(i);
+ m_sourceSelFiles.remove(i);
+ break;
+ }
+ }
+ removeSourceFile(exec->interpreter(),sourceFile->url);
+ }
+ delete fragment;
+ }
+
+ return (m_mode != Stop);
+}
+
+bool KJSDebugWin::exception(ExecState *exec, const Value &value, bool inTryCatch)
+{
+ assert(value.isValid());
+
+ // Ignore exceptions that will be caught by the script
+ if (inTryCatch)
+ return true;
+
+ KParts::ReadOnlyPart *part = static_cast<ScriptInterpreter*>(exec->interpreter())->part();
+ KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart*>(part);
+ if (khtmlpart && !khtmlpart->settings()->isJavaScriptErrorReportingEnabled())
+ return true;
+
+ QWidget *dlgParent = (m_evalDepth == 0) ? (QWidget*)part->widget() : (QWidget*)this;
+
+ QString exceptionMsg = value.toString(exec).qstring();
+
+ // Syntax errors are a special case. For these we want to display the url & lineno,
+ // which isn't included in the exception messeage. So we work it out from the values
+ // passed to sourceParsed()
+ Object valueObj = Object::dynamicCast(value);
+ Object syntaxError = exec->interpreter()->builtinSyntaxError();
+ if (valueObj.isValid() && valueObj.get(exec,"constructor").imp() == syntaxError.imp()) {
+ Value sidValue = valueObj.get(exec,"sid");
+ if (sidValue.isA(NumberType)) { // sid is not set for Function() constructor
+ int sourceId = (int)sidValue.toNumber(exec);
+ assert(m_sourceFragments[sourceId]);
+ exceptionMsg = i18n("Parse error at %1 line %2")
+ .arg(m_sourceFragments[sourceId]->sourceFile->url)
+ .arg(m_sourceFragments[sourceId]->baseLine+m_sourceFragments[sourceId]->errorLine-1);
+ }
+ }
+
+ bool dontShowAgain = false;
+ if (m_execsCount == 0) {
+ // An exception occurred and we're not currently executing any code... this can
+ // happen in some cases e.g. a parse error, or native code accessing funcitons like
+ // Object::put()
+ QString msg = i18n("An error occurred while attempting to run a script on this page.\n\n%1")
+ .arg(exceptionMsg);
+ KJSErrorDialog dlg(dlgParent,msg,false);
+ dlg.exec();
+ dontShowAgain = dlg.dontShowAgain();
+ }
+ else {
+ Context ctx = m_execs[m_execsCount-1]->context();
+ SourceFragment *sourceFragment = m_sourceFragments[ctx.sourceId()];
+ QString msg = i18n("An error occurred while attempting to run a script on this page.\n\n%1 line %2:\n%3")
+ .arg(KStringHandler::rsqueeze( sourceFragment->sourceFile->url,80),
+ QString::number( sourceFragment->baseLine+ctx.curStmtFirstLine()-1),
+ exceptionMsg);
+
+ KJSErrorDialog dlg(dlgParent,msg,true);
+ dlg.exec();
+ dontShowAgain = dlg.dontShowAgain();
+
+ if (dlg.debugSelected()) {
+ m_mode = Next;
+ m_steppingDepth = m_execsCount-1;
+ enterSession(exec);
+ }
+ }
+
+ if (dontShowAgain) {
+ KConfig *config = kapp->config();
+ KConfigGroupSaver saver(config,QString::fromLatin1("Java/JavaScript Settings"));
+ config->writeEntry("ReportJavaScriptErrors",QVariant(false,0));
+ config->sync();
+ QByteArray data;
+ kapp->dcopClient()->send( "konqueror*", "KonquerorIface", "reparseConfiguration()", data );
+ }
+
+ return (m_mode != Stop);
+}
+
+bool KJSDebugWin::atStatement(KJS::ExecState *exec)
+{
+ assert(m_execsCount > 0);
+ assert(m_execs[m_execsCount-1] == exec);
+ checkBreak(exec);
+ return (m_mode != Stop);
+}
+
+bool KJSDebugWin::enterContext(ExecState *exec)
+{
+ if (m_execsCount >= m_execsAlloc) {
+ m_execsAlloc += 10;
+ m_execs = (ExecState**)realloc(m_execs,m_execsAlloc*sizeof(ExecState*));
+ }
+ m_execs[m_execsCount++] = exec;
+
+ if (m_mode == Step)
+ m_steppingDepth = m_execsCount-1;
+
+ checkBreak(exec);
+ return (m_mode != Stop);
+}
+
+bool KJSDebugWin::exitContext(ExecState *exec, const Completion &/*completion*/)
+{
+ assert(m_execsCount > 0);
+ assert(m_execs[m_execsCount-1] == exec);
+
+ checkBreak(exec);
+
+ m_execsCount--;
+ if (m_steppingDepth > m_execsCount-1)
+ m_steppingDepth = m_execsCount-1;
+ if (m_execsCount == 0)
+ updateContextList();
+
+ return (m_mode != Stop);
+}
+
+void KJSDebugWin::displaySourceFile(SourceFile *sourceFile, bool forceRefresh)
+{
+ if (m_curSourceFile == sourceFile && !forceRefresh)
+ return;
+ sourceFile->ref();
+ m_sourceDisplay->setSource(sourceFile);
+ if (m_curSourceFile)
+ m_curSourceFile->deref();
+ m_curSourceFile = sourceFile;
+}
+
+void KJSDebugWin::setSourceLine(int sourceId, int lineno)
+{
+ SourceFragment *source = m_sourceFragments[sourceId];
+ if (!source)
+ return;
+
+ SourceFile *sourceFile = source->sourceFile;
+ if (m_curSourceFile != source->sourceFile) {
+ for (int i = 0; i < m_sourceSel->count(); i++)
+ if (m_sourceSelFiles.at(i) == sourceFile)
+ m_sourceSel->setCurrentItem(i);
+ displaySourceFile(sourceFile,false);
+ }
+ m_sourceDisplay->setCurrentLine(source->baseLine+lineno-2);
+}
+
+void KJSDebugWin::setNextSourceInfo(QString url, int baseLine)
+{
+ m_nextSourceUrl = url;
+ m_nextSourceBaseLine = baseLine;
+}
+
+void KJSDebugWin::sourceChanged(Interpreter *interpreter, QString url)
+{
+ SourceFile *sourceFile = getSourceFile(interpreter,url);
+ if (sourceFile && m_curSourceFile == sourceFile)
+ displaySourceFile(sourceFile,true);
+}
+
+void KJSDebugWin::clearInterpreter(Interpreter *interpreter)
+{
+ QMap<int,SourceFragment*>::Iterator it;
+
+ for (it = m_sourceFragments.begin(); it != m_sourceFragments.end(); ++it)
+ if (it.data() && it.data()->sourceFile->interpreter == interpreter)
+ it.data()->sourceFile->interpreter = 0;
+}
+
+SourceFile *KJSDebugWin::getSourceFile(Interpreter *interpreter, QString url)
+{
+ QString key = QString("%1|%2").arg((long)interpreter).arg(url);
+ return m_sourceFiles[key];
+}
+
+void KJSDebugWin::setSourceFile(Interpreter *interpreter, QString url, SourceFile *sourceFile)
+{
+ QString key = QString("%1|%2").arg((long)interpreter).arg(url);
+ sourceFile->ref();
+ if (SourceFile* oldFile = m_sourceFiles[key])
+ oldFile->deref();
+ m_sourceFiles[key] = sourceFile;
+}
+
+void KJSDebugWin::removeSourceFile(Interpreter *interpreter, QString url)
+{
+ QString key = QString("%1|%2").arg((long)interpreter).arg(url);
+ if (SourceFile* oldFile = m_sourceFiles[key])
+ oldFile->deref();
+ m_sourceFiles.remove(key);
+}
+
+void KJSDebugWin::checkBreak(ExecState *exec)
+{
+ if (m_breakpointCount > 0) {
+ Context ctx = m_execs[m_execsCount-1]->context();
+ if (haveBreakpoint(ctx.sourceId(),ctx.curStmtFirstLine(),ctx.curStmtLastLine())) {
+ m_mode = Next;
+ m_steppingDepth = m_execsCount-1;
+ }
+ }
+
+ if ((m_mode == Step || m_mode == Next) && m_steppingDepth == m_execsCount-1)
+ enterSession(exec);
+}
+
+void KJSDebugWin::enterSession(ExecState *exec)
+{
+ // This "enters" a new debugging session, i.e. enables usage of the debugging window
+ // It re-enters the qt event loop here, allowing execution of other parts of the
+ // program to continue while the script is stopped. We have to be a bit careful here,
+ // i.e. make sure the user can't quit the app, and disable other event handlers which
+ // could interfere with the debugging session.
+ if (!isVisible())
+ show();
+
+ m_mode = Continue;
+
+ if (m_execStates.isEmpty()) {
+ disableOtherWindows();
+ m_nextAction->setEnabled(true);
+ m_stepAction->setEnabled(true);
+ m_continueAction->setEnabled(true);
+ m_stopAction->setEnabled(true);
+ m_breakAction->setEnabled(false);
+ }
+ m_execStates.push(exec);
+
+ updateContextList();
+
+ qApp->enter_loop(); // won't return until leaveSession() is called
+}
+
+void KJSDebugWin::leaveSession()
+{
+ // Disables debugging for this window and returns to execute the rest of the script
+ // (or aborts execution, if the user pressed stop). When this returns, the program
+ // will exit the qt event loop, i.e. return to whatever processing was being done
+ // before the debugger was stopped.
+ assert(!m_execStates.isEmpty());
+
+ m_execStates.pop();
+
+ if (m_execStates.isEmpty()) {
+ m_nextAction->setEnabled(false);
+ m_stepAction->setEnabled(false);
+ m_continueAction->setEnabled(false);
+ m_stopAction->setEnabled(false);
+ m_breakAction->setEnabled(true);
+ m_sourceDisplay->setCurrentLine(-1);
+ enableOtherWindows();
+ }
+
+ qApp->exit_loop();
+}
+
+void KJSDebugWin::updateContextList()
+{
+ disconnect(m_contextList,SIGNAL(highlighted(int)),this,SLOT(slotShowFrame(int)));
+
+ m_contextList->clear();
+ for (int i = 0; i < m_execsCount; i++)
+ m_contextList->insertItem(contextStr(m_execs[i]->context()));
+
+ if (m_execsCount > 0) {
+ m_contextList->setSelected(m_execsCount-1, true);
+ Context ctx = m_execs[m_execsCount-1]->context();
+ setSourceLine(ctx.sourceId(),ctx.curStmtFirstLine());
+ }
+
+ connect(m_contextList,SIGNAL(highlighted(int)),this,SLOT(slotShowFrame(int)));
+}
+
+QString KJSDebugWin::contextStr(const Context &ctx)
+{
+ QString str = "";
+ SourceFragment *sourceFragment = m_sourceFragments[ctx.sourceId()];
+ QString url = sourceFragment->sourceFile->url;
+ int fileLineno = sourceFragment->baseLine+ctx.curStmtFirstLine()-1;
+
+ switch (ctx.codeType()) {
+ case GlobalCode:
+ str = QString("Global code at %1:%2").arg(url).arg(fileLineno);
+ break;
+ case EvalCode:
+ str = QString("Eval code at %1:%2").arg(url).arg(fileLineno);
+ break;
+ case FunctionCode:
+ if (!ctx.functionName().isNull())
+ str = QString("%1() at %2:%3").arg(ctx.functionName().qstring()).arg(url).arg(fileLineno);
+ else
+ str = QString("Anonymous function at %1:%2").arg(url).arg(fileLineno);
+ break;
+ }
+
+ return str;
+}
+
+bool KJSDebugWin::setBreakpoint(int sourceId, int lineno)
+{
+ if (haveBreakpoint(sourceId,lineno,lineno))
+ return false;
+
+ m_breakpointCount++;
+ m_breakpoints = static_cast<Breakpoint*>(realloc(m_breakpoints,
+ m_breakpointCount*sizeof(Breakpoint)));
+ m_breakpoints[m_breakpointCount-1].sourceId = sourceId;
+ m_breakpoints[m_breakpointCount-1].lineno = lineno;
+
+ return true;
+}
+
+bool KJSDebugWin::deleteBreakpoint(int sourceId, int lineno)
+{
+ for (int i = 0; i < m_breakpointCount; i++) {
+ if (m_breakpoints[i].sourceId == sourceId && m_breakpoints[i].lineno == lineno) {
+
+ memmove(m_breakpoints+i,m_breakpoints+i+1,(m_breakpointCount-i-1)*sizeof(Breakpoint));
+ m_breakpointCount--;
+ m_breakpoints = static_cast<Breakpoint*>(realloc(m_breakpoints,
+ m_breakpointCount*sizeof(Breakpoint)));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool KJSDebugWin::haveBreakpoint(SourceFile *sourceFile, int line0, int line1)
+{
+ for (int i = 0; i < m_breakpointCount; i++) {
+ int sourceId = m_breakpoints[i].sourceId;
+ int lineno = m_breakpoints[i].lineno;
+ if (m_sourceFragments.contains(sourceId) &&
+ m_sourceFragments[sourceId]->sourceFile == sourceFile) {
+ int absLineno = m_sourceFragments[sourceId]->baseLine+lineno-1;
+ if (absLineno >= line0 && absLineno <= line1)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#include "kjs_debugwin.moc"
+
+#endif // KJS_DEBUGGER
diff --git a/khtml/ecma/kjs_debugwin.h b/khtml/ecma/kjs_debugwin.h
new file mode 100644
index 000000000..5a2ce2f1f
--- /dev/null
+++ b/khtml/ecma/kjs_debugwin.h
@@ -0,0 +1,285 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001,2003 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_DEBUGGER_H_
+#define _KJS_DEBUGGER_H_
+
+#include <qglobal.h>
+
+#define KJS_DEBUGGER
+
+#ifdef KJS_DEBUGGER
+
+#include <qwidget.h>
+#include <qmultilineedit.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+#include <qptrstack.h>
+#include <qcheckbox.h>
+#include <kdialogbase.h>
+#include <kmainwindow.h>
+#include <qscrollview.h>
+
+#include <kjs/debugger.h>
+
+#include "dom/dom_misc.h"
+
+class QListBox;
+class QComboBox;
+class KActionCollection;
+class KAction;
+
+namespace KJS {
+ class FunctionImp;
+ class List;
+ class Interpreter;
+ class KJSDebugWin;
+
+ class SourceFile : public DOM::DomShared
+ {
+ public:
+ SourceFile(QString u, QString c, Interpreter *interp)
+ : url(u), code(c), interpreter(interp) {}
+ QString getCode();
+ QString url;
+ QString code;
+ Interpreter *interpreter;
+ };
+
+ /**
+ * @internal
+ *
+ * When kjs parses some code, it generates a source code fragment (or just "source").
+ * This is referenced by its source id in future calls to functions such as atLine()
+ * and callEvent(). We keep a record of all source fragments parsed in order to display
+ * then to the user.
+ *
+ * For .js files, the source fragment will be the entire file. For js code included
+ * in html files, however, there may be multiple source fragments within the one file
+ * (e.g. multiple SCRIPT tags or onclick="..." attributes)
+ *
+ * In the case where a single file has multiple source fragments, the source objects
+ * for these fragments will all point to the same SourceFile for their code.
+ */
+ class SourceFragment
+ {
+ public:
+ SourceFragment(int sid, int bl, int el, SourceFile *sf);
+ ~SourceFragment();
+
+ int sourceId;
+ int baseLine;
+ int errorLine;
+ SourceFile *sourceFile;
+ private:
+ SourceFragment(const SourceFragment& other);
+ SourceFragment& operator = (const SourceFragment& other);
+ };
+
+ class KJSErrorDialog : public KDialogBase {
+ Q_OBJECT
+ public:
+ KJSErrorDialog(QWidget *parent, const QString& errorMessage, bool showDebug);
+ virtual ~KJSErrorDialog();
+
+ bool debugSelected() const { return m_debugSelected; }
+ bool dontShowAgain() const { return m_dontShowAgainCb->isChecked(); }
+
+ protected slots:
+ virtual void slotUser1();
+
+ private:
+ QCheckBox *m_dontShowAgainCb;
+ bool m_debugSelected;
+ };
+
+ class EvalMultiLineEdit : public QMultiLineEdit {
+ Q_OBJECT
+ public:
+ EvalMultiLineEdit(QWidget *parent);
+ const QString & code() const { return m_code; }
+ protected:
+ void keyPressEvent(QKeyEvent * e);
+ private:
+ QString m_code;
+ };
+
+ class SourceDisplay : public QScrollView {
+ Q_OBJECT
+ public:
+ SourceDisplay(KJSDebugWin *debugWin, QWidget *parent, const char *name = 0);
+ ~SourceDisplay();
+
+ void setSource(SourceFile *sourceFile);
+ void setCurrentLine(int lineno, bool doCenter = true);
+
+ signals:
+ void lineDoubleClicked(int lineno);
+
+ protected:
+ virtual void contentsMousePressEvent(QMouseEvent *e);
+ virtual void showEvent(QShowEvent *);
+ virtual void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph);
+
+ QString m_source;
+ int m_currentLine;
+ SourceFile *m_sourceFile;
+ QStringList m_lines;
+
+ KJSDebugWin *m_debugWin;
+ QFont m_font;
+ QPixmap m_breakpointIcon;
+ };
+
+ /**
+ * @internal
+ *
+ * KJSDebugWin represents the debugger window that is visible to the user. It contains
+ * a stack frame list, a code viewer and a source fragment selector, plus buttons
+ * to control execution including next, step and continue.
+ *
+ * There is only one debug window per program. This can be obtained by calling #instance
+ */
+ class KJSDebugWin : public KMainWindow, public Debugger, public KInstance
+ {
+ Q_OBJECT
+ friend class SourceDisplay;
+ public:
+ KJSDebugWin(QWidget *parent=0, const char *name=0);
+ virtual ~KJSDebugWin();
+
+ static KJSDebugWin *createInstance();
+ static void destroyInstance();
+ static KJSDebugWin *debugWindow() { return kjs_html_debugger; }
+
+ enum Mode { Disabled = 0, // No break on any statements
+ Next = 1, // Will break on next statement in current context
+ Step = 2, // Will break on next statement in current or deeper context
+ Continue = 3, // Will continue until next breakpoint
+ Stop = 4 // The script will stop execution completely,
+ // as soon as possible
+ };
+
+ void setSourceLine(int sourceId, int lineno);
+ void setNextSourceInfo(QString url, int baseLine);
+ void sourceChanged(Interpreter *interpreter, QString url);
+ bool inSession() const { return !m_execStates.isEmpty(); }
+ void setMode(Mode m) { m_mode = m; }
+ void clearInterpreter(Interpreter *interpreter);
+ ExecState *getExecState() const { return m_execStates.top(); }
+
+ // functions overridden from KJS:Debugger
+ bool sourceParsed(ExecState *exec, int sourceId,
+ const UString &source, int errorLine);
+ bool sourceUnused(ExecState * exec, int sourceId);
+ bool exception(ExecState *exec, const Value &value, bool inTryCatch);
+ bool atStatement(ExecState *exec);
+ bool enterContext(ExecState *exec);
+ bool exitContext(ExecState *exec, const Completion &completion);
+
+ public slots:
+ void slotNext();
+ void slotStep();
+ void slotContinue();
+ void slotStop();
+ void slotBreakNext();
+ void slotToggleBreakpoint(int lineno);
+ void slotShowFrame(int frameno);
+ void slotSourceSelected(int sourceSelIndex);
+ void slotEval();
+
+ protected:
+
+ void closeEvent(QCloseEvent *e);
+ bool eventFilter(QObject *obj, QEvent *evt);
+ void disableOtherWindows();
+ void enableOtherWindows();
+
+ private:
+
+ SourceFile *getSourceFile(Interpreter *interpreter, QString url);
+ void setSourceFile(Interpreter *interpreter, QString url, SourceFile *sourceFile);
+ void removeSourceFile(Interpreter *interpreter, QString url);
+
+ void checkBreak(ExecState *exec);
+ void enterSession(ExecState *exec);
+ void leaveSession();
+ void displaySourceFile(SourceFile *sourceFile, bool forceRefresh);
+ void updateContextList();
+
+ QString contextStr(const Context &ctx);
+
+ struct Breakpoint {
+ int sourceId;
+ int lineno;
+ };
+ Breakpoint *m_breakpoints;
+ int m_breakpointCount;
+ bool setBreakpoint(int sourceId, int lineno);
+ bool deleteBreakpoint(int sourceId, int lineno);
+ bool haveBreakpoint(SourceFile *sourceFile, int line0, int line1);
+ bool haveBreakpoint(int sourceId, int line0, int line1) const {
+ for (int i = 0; i < m_breakpointCount; i++) {
+ if (m_breakpoints[i].sourceId == sourceId &&
+ m_breakpoints[i].lineno >= line0 &&
+ m_breakpoints[i].lineno <= line1)
+ return true;
+ }
+ return false;
+ }
+
+ SourceFile *m_curSourceFile;
+ Mode m_mode;
+ QString m_nextSourceUrl;
+ int m_nextSourceBaseLine;
+ QPtrStack<ExecState> m_execStates;
+ ExecState **m_execs;
+ int m_execsCount;
+ int m_execsAlloc;
+ int m_steppingDepth;
+
+ QMap<QString,SourceFile*> m_sourceFiles; /* maps url->SourceFile */
+ QMap<int,SourceFragment*> m_sourceFragments; /* maps SourceId->SourceFragment */
+ QPtrList<SourceFile> m_sourceSelFiles; /* maps combobox index->SourceFile */
+
+ KActionCollection *m_actionCollection;
+ QPixmap m_stopIcon;
+ QPixmap m_emptyIcon;
+ SourceDisplay *m_sourceDisplay;
+ QListBox *m_contextList;
+
+ KAction *m_stepAction;
+ KAction *m_nextAction;
+ KAction *m_continueAction;
+ KAction *m_stopAction;
+ KAction *m_breakAction;
+
+ QComboBox *m_sourceSel;
+ EvalMultiLineEdit *m_evalEdit;
+ int m_evalDepth;
+
+ static KJSDebugWin *kjs_html_debugger;
+ };
+
+} // namespace
+
+#endif // KJS_DEBUGGER
+
+#endif // _KJS_DEBUGGER_H_
diff --git a/khtml/ecma/kjs_dom.cpp b/khtml/ecma/kjs_dom.cpp
new file mode 100644
index 000000000..74a90a9d2
--- /dev/null
+++ b/khtml/ecma/kjs_dom.cpp
@@ -0,0 +1,1849 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <khtmlview.h>
+#include "xml/dom2_eventsimpl.h"
+#include "rendering/render_canvas.h"
+#include "rendering/render_layer.h"
+#include "xml/dom_nodeimpl.h"
+#include "xml/dom_docimpl.h"
+#include "misc/htmltags.h" // ID_*
+#include "misc/htmlattrs.h" // ATTR_*
+#include "html/html_baseimpl.h"
+#include <kdebug.h>
+#include <khtml_part.h>
+
+#include "kjs_dom.h"
+#include "kjs_html.h"
+#include "kjs_css.h"
+#include "kjs_range.h"
+#include "kjs_traversal.h"
+#include "kjs_events.h"
+#include "kjs_views.h"
+#include "kjs_window.h"
+#include "dom/dom_exception.h"
+#include "kjs_dom.lut.h"
+#include "khtmlpart_p.h"
+
+namespace KJS {
+
+// -------------------------------------------------------------------------
+/* Source for DOMNodeConstantsTable.
+@begin DOMNodeConstantsTable 11
+ ELEMENT_NODE DOM::Node::ELEMENT_NODE DontDelete|ReadOnly
+ ATTRIBUTE_NODE DOM::Node::ATTRIBUTE_NODE DontDelete|ReadOnly
+ TEXT_NODE DOM::Node::TEXT_NODE DontDelete|ReadOnly
+ CDATA_SECTION_NODE DOM::Node::CDATA_SECTION_NODE DontDelete|ReadOnly
+ ENTITY_REFERENCE_NODE DOM::Node::ENTITY_REFERENCE_NODE DontDelete|ReadOnly
+ ENTITY_NODE DOM::Node::ENTITY_NODE DontDelete|ReadOnly
+ PROCESSING_INSTRUCTION_NODE DOM::Node::PROCESSING_INSTRUCTION_NODE DontDelete|ReadOnly
+ COMMENT_NODE DOM::Node::COMMENT_NODE DontDelete|ReadOnly
+ DOCUMENT_NODE DOM::Node::DOCUMENT_NODE DontDelete|ReadOnly
+ DOCUMENT_TYPE_NODE DOM::Node::DOCUMENT_TYPE_NODE DontDelete|ReadOnly
+ DOCUMENT_FRAGMENT_NODE DOM::Node::DOCUMENT_FRAGMENT_NODE DontDelete|ReadOnly
+ NOTATION_NODE DOM::Node::NOTATION_NODE DontDelete|ReadOnly
+@end
+*/
+IMPLEMENT_CONSTANT_TABLE(DOMNodeConstants,"DOMNodeConstants")
+// -------------------------------------------------------------------------
+/* Source for DOMNodeProtoTable.
+@begin DOMNodeProtoTable 13
+ insertBefore DOMNode::InsertBefore DontDelete|Function 2
+ replaceChild DOMNode::ReplaceChild DontDelete|Function 2
+ removeChild DOMNode::RemoveChild DontDelete|Function 1
+ appendChild DOMNode::AppendChild DontDelete|Function 1
+ hasAttributes DOMNode::HasAttributes DontDelete|Function 0
+ hasChildNodes DOMNode::HasChildNodes DontDelete|Function 0
+ cloneNode DOMNode::CloneNode DontDelete|Function 1
+# DOM2
+ normalize DOMNode::Normalize DontDelete|Function 0
+ isSupported DOMNode::IsSupported DontDelete|Function 2
+# from the EventTarget interface
+ addEventListener DOMNode::AddEventListener DontDelete|Function 3
+ removeEventListener DOMNode::RemoveEventListener DontDelete|Function 3
+ dispatchEvent DOMNode::DispatchEvent DontDelete|Function 1
+# IE extensions
+ contains DOMNode::Contains DontDelete|Function 1
+ insertAdjacentHTML DOMNode::InsertAdjacentHTML DontDelete|Function 2
+# "DOM level 0" (from Gecko DOM reference; also in WinIE)
+ item DOMNode::Item DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(DOMNodeProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMNode", DOMNodeProto, DOMNodeProtoFunc)
+
+const ClassInfo DOMNode::info = { "Node", 0, &DOMNodeTable, 0 };
+
+DOMNode::DOMNode(ExecState *exec, const DOM::Node& n)
+ : DOMObject(DOMNodeProto::self(exec)), node(n)
+{
+}
+
+DOMNode::DOMNode(const Object& proto, const DOM::Node& n)
+ : DOMObject(proto), node(n)
+{
+}
+
+DOMNode::~DOMNode()
+{
+ ScriptInterpreter::forgetDOMObject(node.handle());
+}
+
+bool DOMNode::toBoolean(ExecState *) const
+{
+ return !node.isNull();
+}
+
+/* Source for DOMNodeTable.
+@begin DOMNodeTable 53
+ nodeName DOMNode::NodeName DontDelete|ReadOnly
+ nodeValue DOMNode::NodeValue DontDelete
+ nodeType DOMNode::NodeType DontDelete|ReadOnly
+ parentNode DOMNode::ParentNode DontDelete|ReadOnly
+ parentElement DOMNode::ParentElement DontDelete|ReadOnly
+ childNodes DOMNode::ChildNodes DontDelete|ReadOnly
+ firstChild DOMNode::FirstChild DontDelete|ReadOnly
+ lastChild DOMNode::LastChild DontDelete|ReadOnly
+ previousSibling DOMNode::PreviousSibling DontDelete|ReadOnly
+ nextSibling DOMNode::NextSibling DontDelete|ReadOnly
+ attributes DOMNode::Attributes DontDelete|ReadOnly
+ namespaceURI DOMNode::NamespaceURI DontDelete|ReadOnly
+# DOM2
+ prefix DOMNode::Prefix DontDelete
+ localName DOMNode::LocalName DontDelete|ReadOnly
+ ownerDocument DOMNode::OwnerDocument DontDelete|ReadOnly
+# DOM3
+ textContent DOMNode::TextContent DontDelete
+# Event handlers
+# IE also has: onactivate, onbefore*, oncontextmenu, oncontrolselect, oncut,
+# ondeactivate, ondrag*, ondrop, onfocusin, onfocusout, onhelp, onmousewheel,
+# onmove*, onpaste, onpropertychange, onreadystatechange, onresizeend/start,
+# onselectionchange, onstop
+ onabort DOMNode::OnAbort DontDelete
+ onblur DOMNode::OnBlur DontDelete
+ onchange DOMNode::OnChange DontDelete
+ onclick DOMNode::OnClick DontDelete
+ ondblclick DOMNode::OnDblClick DontDelete
+ ondragdrop DOMNode::OnDragDrop DontDelete
+ onerror DOMNode::OnError DontDelete
+ onfocus DOMNode::OnFocus DontDelete
+ onkeydown DOMNode::OnKeyDown DontDelete
+ onkeypress DOMNode::OnKeyPress DontDelete
+ onkeyup DOMNode::OnKeyUp DontDelete
+ onload DOMNode::OnLoad DontDelete
+ onmousedown DOMNode::OnMouseDown DontDelete
+ onmousemove DOMNode::OnMouseMove DontDelete
+ onmouseout DOMNode::OnMouseOut DontDelete
+ onmouseover DOMNode::OnMouseOver DontDelete
+ onmouseup DOMNode::OnMouseUp DontDelete
+ onmove DOMNode::OnMove DontDelete
+ onreset DOMNode::OnReset DontDelete
+ onresize DOMNode::OnResize DontDelete
+ onselect DOMNode::OnSelect DontDelete
+ onsubmit DOMNode::OnSubmit DontDelete
+ onunload DOMNode::OnUnload DontDelete
+# IE extensions
+ offsetLeft DOMNode::OffsetLeft DontDelete|ReadOnly
+ offsetTop DOMNode::OffsetTop DontDelete|ReadOnly
+ offsetWidth DOMNode::OffsetWidth DontDelete|ReadOnly
+ offsetHeight DOMNode::OffsetHeight DontDelete|ReadOnly
+ offsetParent DOMNode::OffsetParent DontDelete|ReadOnly
+ clientWidth DOMNode::ClientWidth DontDelete|ReadOnly
+ clientHeight DOMNode::ClientHeight DontDelete|ReadOnly
+ scrollLeft DOMNode::ScrollLeft DontDelete
+ scrollTop DOMNode::ScrollTop DontDelete
+ scrollWidth DOMNode::ScrollWidth DontDelete|ReadOnly
+ scrollHeight DOMNode::ScrollHeight DontDelete|ReadOnly
+ sourceIndex DOMNode::SourceIndex DontDelete|ReadOnly
+@end
+*/
+Value DOMNode::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMNode::tryGet " << propertyName.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this);
+}
+
+static khtml::RenderObject* handleBodyRootQuirk(const DOM::Node& node, khtml::RenderObject* rend, int token)
+{
+ //This emulates the quirks of various height/width properties on the viewport and root. Note that it
+ //is (mostly) IE-compatible in quirks, and mozilla-compatible in strict.
+ if (!rend) return 0;
+
+ bool quirksMode = rend->style() && rend->style()->htmlHacks();
+
+ //There are a couple quirks here. One is that in quirks mode body is always forwarded to root...
+ //This is relevant for even the scrollTop/scrollLeft type properties.
+ if (quirksMode && node.handle()->id() == ID_BODY) {
+ while (rend->parent() && !rend->isRoot())
+ rend = rend->parent();
+ }
+
+ //Also, some properties of the root are really done in terms of the viewport.
+ //These are {offset/client}{Height/Width}. The offset versions do it only in
+ //quirks mode, the client always.
+ if (!rend->isRoot()) return rend; //Don't care about non-root things here!
+ bool needViewport = false;
+
+ switch (token) {
+ case DOMNode::OffsetHeight:
+ case DOMNode::OffsetWidth:
+ needViewport = quirksMode;
+ break;
+ case DOMNode::ClientHeight:
+ case DOMNode::ClientWidth:
+ needViewport = true;
+ break;
+ }
+
+ if (needViewport) {
+ //Scan up to find the new target
+ while (rend->parent())
+ rend = rend->parent();
+ }
+ return rend;
+}
+
+Value DOMNode::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case NodeName:
+ return String(node.nodeName());
+ case NodeValue:
+ return getString(node.nodeValue()); // initially null, per domts/level1/core/hc_documentcreateelement.html
+ case NodeType:
+ return Number((unsigned int)node.nodeType());
+ case ParentNode:
+ return getDOMNode(exec,node.parentNode());
+ case ParentElement: // IE only apparently
+ return getDOMNode(exec,node.parentNode());
+ case ChildNodes:
+ return getDOMNodeList(exec,node.childNodes());
+ case FirstChild:
+ return getDOMNode(exec,node.firstChild());
+ case LastChild:
+ return getDOMNode(exec,node.lastChild());
+ case PreviousSibling:
+ return getDOMNode(exec,node.previousSibling());
+ case NextSibling:
+ return getDOMNode(exec,node.nextSibling());
+ case Attributes:
+ return getDOMNamedNodeMap(exec,node.attributes());
+ case NamespaceURI:
+ return getString(node.namespaceURI()); // Moz returns null if not set (dom/namespaces.html)
+ case Prefix:
+ return getString(node.prefix()); // Moz returns null if not set (dom/namespaces.html)
+ case TextContent:
+ return getString(node.textContent()); //DOM3 says return null, but I really should test mozilla..
+ case LocalName:
+ return getString(node.localName()); // Moz returns null if not set (dom/namespaces.html)
+ case OwnerDocument:
+ return getDOMNode(exec,node.ownerDocument());
+ case OnAbort:
+ return getListener(DOM::EventImpl::ABORT_EVENT);
+ case OnBlur:
+ return getListener(DOM::EventImpl::BLUR_EVENT);
+ case OnChange:
+ return getListener(DOM::EventImpl::CHANGE_EVENT);
+ case OnClick:
+ return getListener(DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
+ case OnDblClick:
+ return getListener(DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
+ case OnDragDrop:
+ return getListener(DOM::EventImpl::KHTML_DRAGDROP_EVENT);
+ case OnError:
+ return getListener(DOM::EventImpl::ERROR_EVENT);
+ case OnFocus:
+ return getListener(DOM::EventImpl::FOCUS_EVENT);
+ case OnKeyDown:
+ return getListener(DOM::EventImpl::KEYDOWN_EVENT);
+ case OnKeyPress:
+ return getListener(DOM::EventImpl::KEYPRESS_EVENT);
+ case OnKeyUp:
+ return getListener(DOM::EventImpl::KEYUP_EVENT);
+ case OnLoad:
+ return getListener(DOM::EventImpl::LOAD_EVENT);
+ case OnMouseDown:
+ return getListener(DOM::EventImpl::MOUSEDOWN_EVENT);
+ case OnMouseMove:
+ return getListener(DOM::EventImpl::MOUSEMOVE_EVENT);
+ case OnMouseOut:
+ return getListener(DOM::EventImpl::MOUSEOUT_EVENT);
+ case OnMouseOver:
+ return getListener(DOM::EventImpl::MOUSEOVER_EVENT);
+ case OnMouseUp:
+ return getListener(DOM::EventImpl::MOUSEUP_EVENT);
+ case OnMove:
+ return getListener(DOM::EventImpl::KHTML_MOVE_EVENT);
+ case OnReset:
+ return getListener(DOM::EventImpl::RESET_EVENT);
+ case OnResize:
+ return getListener(DOM::EventImpl::RESIZE_EVENT);
+ case OnSelect:
+ return getListener(DOM::EventImpl::SELECT_EVENT);
+ case OnSubmit:
+ return getListener(DOM::EventImpl::SUBMIT_EVENT);
+ case OnUnload:
+ return getListener(DOM::EventImpl::UNLOAD_EVENT);
+ case SourceIndex: {
+ // Retrieves the ordinal position of the object, in source order, as the object
+ // appears in the document's all collection
+ // i.e. document.all[n.sourceIndex] == n
+ DOM::Document doc = node.ownerDocument();
+ if (doc.isHTMLDocument()) {
+ DOM::HTMLCollection all = static_cast<DOM::HTMLDocument>(doc).all();
+ unsigned long i = 0;
+ DOM::Node n = all.firstItem();
+ for ( ; !n.isNull() && n != node; n = all.nextItem() )
+ ++i;
+ Q_ASSERT( !n.isNull() ); // node not in document.all !?
+ return Number(i);
+ }
+ }
+ default:
+ // no DOM standard, found in IE only
+
+ // Make sure our layout is up to date before we allow a query on these attributes.
+ DOM::DocumentImpl* docimpl = node.handle()->getDocument();
+ if (docimpl) {
+ docimpl->updateLayout();
+ }
+
+ khtml::RenderObject *rend = node.handle()->renderer();
+
+ //In quirks mode, may need to forward if to body.
+ rend = handleBodyRootQuirk(node, rend, token);
+
+ switch (token) {
+ case OffsetLeft:
+ return rend ? static_cast<Value>( Number( rend->offsetLeft() ) ) : Undefined();
+ case OffsetTop:
+ return rend ? static_cast<Value>( Number( rend->offsetTop() ) ) : Undefined();
+ case OffsetWidth:
+ return rend ? static_cast<Value>( Number( rend->offsetWidth() ) ) : Undefined();
+ case OffsetHeight:
+ return rend ? static_cast<Value>( Number( rend->offsetHeight() ) ) : Undefined();
+ case OffsetParent:
+ {
+ khtml::RenderObject* par = rend ? rend->offsetParent() : 0;
+ return getDOMNode( exec, par ? par->element() : 0 );
+ }
+ case ClientWidth:
+ return rend ? static_cast<Value>( Number( rend->clientWidth() ) ) : Undefined();
+ case ClientHeight:
+ return rend ? static_cast<Value>( Number( rend->clientHeight() ) ) : Undefined();
+ case ScrollWidth:
+ return rend ? static_cast<Value>( Number(rend->scrollWidth()) ) : Undefined();
+ case ScrollHeight:
+ return rend ? static_cast<Value>( Number(rend->scrollHeight()) ) : Undefined();
+ case ScrollLeft:
+ if (rend && rend->layer()) {
+ if (rend->isRoot() && !rend->style()->hidesOverflow())
+ return Number( node.ownerDocument().view() ? node.ownerDocument().view()->contentsX() : 0);
+ return Number( rend->layer()->scrollXOffset() );
+ }
+ return Number( 0 );
+ case ScrollTop:
+ if (rend && rend->layer()) {
+ if (rend->isRoot() && !rend->style()->hidesOverflow())
+ return Number( node.ownerDocument().view() ? node.ownerDocument().view()->contentsY() : 0);
+ return Number( rend->layer()->scrollYOffset() );
+ }
+ return Number( 0 );
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMNode::getValueProperty : " << token << endl;
+ break;
+ }
+ }
+ return Undefined();
+}
+
+
+void DOMNode::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMNode::tryPut " << propertyName.qstring() << endl;
+#endif
+ DOMObjectLookupPut<DOMNode,DOMObject>(exec, propertyName, value, attr,
+ &DOMNodeTable, this );
+}
+
+void DOMNode::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
+{
+ switch (token) {
+ case NodeValue:
+ node.setNodeValue(value.toString(exec).string());
+ break;
+ case Prefix:
+ node.setPrefix(value.toString(exec).string());
+ break;
+ case TextContent:
+ node.setTextContent(value.toString(exec).string());
+ break;
+ case OnAbort:
+ setListener(exec,DOM::EventImpl::ABORT_EVENT,value);
+ break;
+ case OnBlur:
+ setListener(exec,DOM::EventImpl::BLUR_EVENT,value);
+ break;
+ case OnChange:
+ setListener(exec,DOM::EventImpl::CHANGE_EVENT,value);
+ break;
+ case OnClick:
+ setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
+ break;
+ case OnDblClick:
+ setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
+ break;
+ case OnDragDrop:
+ setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
+ break;
+ case OnError:
+ setListener(exec,DOM::EventImpl::ERROR_EVENT,value);
+ break;
+ case OnFocus:
+ setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
+ break;
+ case OnKeyDown:
+ setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
+ break;
+ case OnKeyPress:
+ setListener(exec,DOM::EventImpl::KEYPRESS_EVENT,value);
+ break;
+ case OnKeyUp:
+ setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
+ break;
+ case OnLoad:
+ setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
+ break;
+ case OnMouseDown:
+ setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
+ break;
+ case OnMouseMove:
+ setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
+ break;
+ case OnMouseOut:
+ setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
+ break;
+ case OnMouseOver:
+ setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
+ break;
+ case OnMouseUp:
+ setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
+ break;
+ case OnMove:
+ setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
+ break;
+ case OnReset:
+ setListener(exec,DOM::EventImpl::RESET_EVENT,value);
+ break;
+ case OnResize:
+ setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
+ break;
+ case OnSelect:
+ setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
+ break;
+ case OnSubmit:
+ setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
+ break;
+ case OnUnload:
+ setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
+ break;
+ default:
+ // Make sure our layout is up to date
+ DOM::DocumentImpl* docimpl = node.handle()->getDocument();
+ if (docimpl)
+ docimpl->updateLayout();
+
+ khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
+
+ //In quirks mode, may need to forward.
+ rend = handleBodyRootQuirk(node, rend, token);
+
+ switch (token) {
+ case ScrollLeft:
+ if (rend && rend->layer()) {
+ if (rend->style()->hidesOverflow())
+ rend->layer()->scrollToXOffset(value.toInt32(exec));
+ else if (rend->isRoot()) {
+ QScrollView* sview = node.ownerDocument().view();
+ if (sview)
+ sview->setContentsPos(value.toInt32(exec), sview->contentsY());
+ }
+ }
+ break;
+ case ScrollTop:
+ if (rend && rend->layer()) {
+ if (rend->style()->hidesOverflow())
+ rend->layer()->scrollToYOffset(value.toInt32(exec));
+ else if (rend->isRoot()) {
+ QScrollView* sview = node.ownerDocument().view();
+ if (sview)
+ sview->setContentsPos(sview->contentsX(), value.toInt32(exec));
+ }
+ }
+ break;
+ default:
+ kdDebug(6070) << "WARNING: DOMNode::putValueProperty unhandled token " << token << endl;
+ }
+ }
+}
+
+Value DOMNode::toPrimitive(ExecState *exec, Type /*preferred*/) const
+{
+ if (node.isNull())
+ return Null();
+
+ return String(toString(exec));
+}
+
+UString DOMNode::toString(ExecState *) const
+{
+ if (node.isNull())
+ return "null";
+ UString s;
+
+ DOM::Element e = node;
+ if ( !e.isNull() ) {
+ s = e.nodeName().string();
+ } else
+ s = className(); // fallback
+
+ return "[object " + s + "]";
+}
+
+void DOMNode::setListener(ExecState *exec, int eventId, const Value& func) const
+{
+ node.handle()->setHTMLEventListener(eventId,Window::retrieveActive(exec)->getJSEventListener(func,true));
+}
+
+Value DOMNode::getListener(int eventId) const
+{
+ DOM::EventListener *listener = node.handle()->getHTMLEventListener(eventId);
+ JSEventListener *jsListener = static_cast<JSEventListener*>(listener);
+ if ( jsListener && jsListener->listenerObjImp() )
+ return jsListener->listenerObj();
+ else
+ return Null();
+}
+
+void DOMNode::pushEventHandlerScope(ExecState *, ScopeChain &) const
+{
+}
+
+Value DOMNodeProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( DOMNode, thisObj );
+ DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
+ switch (id) {
+ case DOMNode::HasAttributes:
+ return Boolean(node.hasAttributes());
+ case DOMNode::HasChildNodes:
+ return Boolean(node.hasChildNodes());
+ case DOMNode::CloneNode:
+ return getDOMNode(exec,node.cloneNode(args[0].toBoolean(exec)));
+ case DOMNode::Normalize:
+ node.normalize();
+ return Undefined();
+ case DOMNode::IsSupported:
+ return Boolean(node.isSupported(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMNode::AddEventListener: {
+ JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
+ node.addEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
+ return Undefined();
+ }
+ case DOMNode::RemoveEventListener: {
+ JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
+ node.removeEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
+ return Undefined();
+ }
+ case DOMNode::DispatchEvent:
+ return Boolean(node.dispatchEvent(toEvent(args[0])));
+ case DOMNode::AppendChild:
+ return getDOMNode(exec,node.appendChild(toNode(args[0])));
+ case DOMNode::RemoveChild:
+ return getDOMNode(exec,node.removeChild(toNode(args[0])));
+ case DOMNode::InsertBefore:
+ return getDOMNode(exec,node.insertBefore(toNode(args[0]), toNode(args[1])));
+ case DOMNode::ReplaceChild:
+ return getDOMNode(exec,node.replaceChild(toNode(args[0]), toNode(args[1])));
+ case DOMNode::Contains:
+ {
+ DOM::Node other = toNode(args[0]);
+ if (!other.isNull() && node.nodeType()==DOM::Node::ELEMENT_NODE)
+ {
+ DOM::NodeBaseImpl *impl = static_cast<DOM::NodeBaseImpl *>(node.handle());
+ bool retval = other.handle()->isAncestor(impl);
+ return Boolean(retval);
+ }
+ return Undefined();
+ }
+ case DOMNode::InsertAdjacentHTML:
+ {
+ // see http://www.faqts.com/knowledge_base/view.phtml/aid/5756
+ // and http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/insertAdjacentHTML.asp
+ Range range = node.ownerDocument().createRange();
+
+ range.setStartBefore(node);
+
+ DocumentFragment docFrag = range.createContextualFragment(args[1].toString(exec).string());
+
+ DOMString where = args[0].toString(exec).string();
+
+ if (where == "beforeBegin" || where == "BeforeBegin")
+ node.parentNode().insertBefore(docFrag, node);
+ else if (where == "afterBegin" || where == "AfterBegin")
+ node.insertBefore(docFrag, node.firstChild());
+ else if (where == "beforeEnd" || where == "BeforeEnd")
+ return getDOMNode(exec, node.appendChild(docFrag));
+ else if (where == "afterEnd" || where == "AfterEnd")
+ if (!node.nextSibling().isNull())
+ node.parentNode().insertBefore(docFrag, node.nextSibling());
+ else
+ node.parentNode().appendChild(docFrag);
+
+ return Undefined();
+ }
+ case DOMNode::Item:
+ return getDOMNode(exec, node.childNodes().item(static_cast<unsigned long>(args[0].toNumber(exec))));
+ }
+
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+/*
+@begin DOMNodeListProtoTable 2
+ item DOMNodeList::Item DontDelete|Function 1
+# IE extension (IE treats DOMNodeList like an HTMLCollection)
+ namedItem DOMNodeList::NamedItem DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMNodeListProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMNodeListProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMNodeList", DOMNodeListProto, DOMNodeListProtoFunc)
+
+
+const ClassInfo DOMNodeList::info = { "NodeList", 0, 0, 0 };
+
+DOMNodeList::DOMNodeList(ExecState *exec, const DOM::NodeList& l)
+ : DOMObject(DOMNodeListProto::self(exec)), list(l) { }
+
+DOMNodeList::~DOMNodeList()
+{
+ ScriptInterpreter::forgetDOMObject(list.handle());
+}
+
+// We have to implement hasProperty since we don't use a hashtable for 'length'
+// ## this breaks "for (..in..)" though.
+bool DOMNodeList::hasProperty(ExecState *exec, const Identifier &p) const
+{
+ if (p == lengthPropertyName)
+ return true;
+
+ if (ObjectImp::hasProperty(exec, p))
+ return true;
+
+ bool ok;
+ unsigned long pos = p.toULong(&ok);
+ if (ok && pos < list.length())
+ return true;
+
+ // ## missing: accept p if item id...
+ return false;
+}
+
+Value DOMNodeList::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMNodeList::tryGet " << p.ascii() << endl;
+#endif
+ if (p == lengthPropertyName)
+ return Number(list.length());
+
+ // Look in the prototype (for functions) before assuming it's an item's name
+ Object proto = Object::dynamicCast(prototype());
+ if (proto.isValid() && proto.hasProperty(exec,p))
+ return proto.get(exec,p);
+
+ Value result;
+
+ // array index ?
+ bool ok;
+ long unsigned int idx = p.toULong(&ok);
+ if (ok)
+ result = getDOMNode(exec,list.item(idx));
+ else {
+ // Find by ID
+ DOM::HTMLElement e;
+ unsigned long l = list.length();
+ bool found = false;
+
+ for ( unsigned long i = 0; i < l; i++ )
+ if ( ( e = list.item( i ) ).id() == p.string() ) {
+ result = getDOMNode(exec, list.item( i ) );
+ found = true;
+ break;
+ }
+
+ if ( !found )
+ result = ObjectImp::get(exec, p);
+ }
+
+ return result;
+}
+
+ReferenceList DOMNodeList::propList(ExecState *exec, bool recursive)
+{
+ ReferenceList properties = ObjectImp::propList(exec,recursive);
+
+ for (unsigned i = 0; i < list.length(); ++i) {
+ if (!ObjectImp::hasProperty(exec,Identifier::from(i))) {
+ properties.append(Reference(this, i));
+ }
+ }
+
+ if (!ObjectImp::hasProperty(exec, lengthPropertyName))
+ properties.append(Reference(this, lengthPropertyName));
+
+ return properties;
+}
+
+// Need to support both get and call, so that list[0] and list(0) work.
+Value DOMNodeList::call(ExecState *exec, Object &thisObj, const List &args)
+{
+ // This code duplication is necessary, DOMNodeList isn't a DOMFunction
+ Value val;
+ try {
+ val = tryCall(exec, thisObj, args);
+ }
+ // pity there's no way to distinguish between these in JS code
+ catch (...) {
+ Object err = Error::create(exec, GeneralError, "Exception from DOMNodeList");
+ exec->setException(err);
+ }
+ return val;
+}
+
+Value DOMNodeList::tryCall(ExecState *exec, Object &, const List &args)
+{
+ // Do not use thisObj here. See HTMLCollection.
+ UString s = args[0].toString(exec);
+
+ // index-based lookup?
+ bool ok;
+ unsigned int u = s.toULong(&ok);
+ if (ok)
+ return getDOMNode(exec,list.item(u));
+
+ // try lookup by name
+ // ### NodeList::namedItem() would be cool to have
+ // ### do we need to support the same two arg overload as in HTMLCollection?
+ Value result = tryGet(exec, Identifier(s));
+
+ if (result.isValid())
+ return result;
+
+ return Undefined();
+}
+
+// Not a prototype class currently, but should probably be converted to one
+Value DOMNodeListProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMNodeList, thisObj );
+ DOM::NodeList list = static_cast<DOMNodeList *>(thisObj.imp())->nodeList();
+ switch (id) {
+ case KJS::DOMNodeList::Item:
+ return getDOMNode(exec, list.item(args[0].toInt32(exec)));
+ case KJS::DOMNodeList::NamedItem:
+ {
+ // Not a real namedItem implementation like the one HTMLCollection has.
+ // This is only an IE extension...
+ DOM::HTMLElement e;
+ unsigned long len = list.length();
+ DOM::DOMString s = args[0].toString(exec).string();
+
+ for ( unsigned long i = 0; i < len; i++ )
+ {
+ e = list.item( i );
+ if ( !e.isNull() && (
+ e.id() == s || static_cast<ElementImpl *>(e.handle())->getAttribute(ATTR_NAME) == s )
+ )
+ {
+ return getDOMNode(exec, e );
+ }
+ }
+ return Null(); // see HTMLCollection::NamedItem implementation
+ }
+ default:
+ return Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+//### FIXME: link to the node prototype.
+const ClassInfo DOMAttr::info = { "Attr", &DOMNode::info, &DOMAttrTable, 0 };
+
+/* Source for DOMAttrTable.
+@begin DOMAttrTable 5
+ name DOMAttr::Name DontDelete|ReadOnly
+ specified DOMAttr::Specified DontDelete|ReadOnly
+ value DOMAttr::ValueProperty DontDelete
+ ownerElement DOMAttr::OwnerElement DontDelete|ReadOnly
+@end
+*/
+Value DOMAttr::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMAttr::tryGet " << propertyName.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMAttr,DOMNode>(exec, propertyName,
+ &DOMAttrTable, this );
+}
+
+Value DOMAttr::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Name:
+ return String(static_cast<DOM::Attr>(node).name());
+ case Specified:
+ return Boolean(static_cast<DOM::Attr>(node).specified());
+ case ValueProperty:
+ return String(static_cast<DOM::Attr>(node).value());
+ case OwnerElement: // DOM2
+ return getDOMNode(exec,static_cast<DOM::Attr>(node).ownerElement());
+ }
+ return Value(); // not reached
+}
+
+void DOMAttr::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMAttr::tryPut " << propertyName.qstring() << endl;
+#endif
+ DOMObjectLookupPut<DOMAttr,DOMNode>(exec, propertyName, value, attr,
+ &DOMAttrTable, this );
+}
+
+void DOMAttr::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
+{
+ switch (token) {
+ case ValueProperty:
+ static_cast<DOM::Attr>(node).setValue(value.toString(exec).string());
+ return;
+ default:
+ kdDebug(6070) << "WARNING: DOMAttr::putValueProperty unhandled token " << token << endl;
+ }
+}
+
+// -------------------------------------------------------------------------
+
+/* Source for DOMDocumentProtoTable.
+@begin DOMDocumentProtoTable 23
+ createElement DOMDocument::CreateElement DontDelete|Function 1
+ createDocumentFragment DOMDocument::CreateDocumentFragment DontDelete|Function 1
+ createTextNode DOMDocument::CreateTextNode DontDelete|Function 1
+ createComment DOMDocument::CreateComment DontDelete|Function 1
+ createCDATASection DOMDocument::CreateCDATASection DontDelete|Function 1
+ createProcessingInstruction DOMDocument::CreateProcessingInstruction DontDelete|Function 1
+ createAttribute DOMDocument::CreateAttribute DontDelete|Function 1
+ createEntityReference DOMDocument::CreateEntityReference DontDelete|Function 1
+ getElementsByTagName DOMDocument::GetElementsByTagName DontDelete|Function 1
+ importNode DOMDocument::ImportNode DontDelete|Function 2
+ createElementNS DOMDocument::CreateElementNS DontDelete|Function 2
+ createAttributeNS DOMDocument::CreateAttributeNS DontDelete|Function 2
+ getElementsByTagNameNS DOMDocument::GetElementsByTagNameNS DontDelete|Function 2
+ getElementById DOMDocument::GetElementById DontDelete|Function 1
+ createRange DOMDocument::CreateRange DontDelete|Function 0
+ createNodeIterator DOMDocument::CreateNodeIterator DontDelete|Function 3
+ createTreeWalker DOMDocument::CreateTreeWalker DontDelete|Function 4
+ createEvent DOMDocument::CreateEvent DontDelete|Function 1
+ getOverrideStyle DOMDocument::GetOverrideStyle DontDelete|Function 2
+ abort DOMDocument::Abort DontDelete|Function 0
+ load DOMDocument::Load DontDelete|Function 1
+ loadXML DOMDocument::LoadXML DontDelete|Function 2
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(DOMDocumentProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMDocument", DOMDocumentProto, DOMDocumentProtoFunc)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(DocumentPseudoCtor, "Document", DOMDocumentProto)
+
+const ClassInfo DOMDocument::info = { "Document", &DOMNode::info, &DOMDocumentTable, 0 };
+
+/* Source for DOMDocumentTable.
+@begin DOMDocumentTable 4
+ doctype DOMDocument::DocType DontDelete|ReadOnly
+ implementation DOMDocument::Implementation DontDelete|ReadOnly
+ characterSet DOMDocument::CharacterSet DontDelete|ReadOnly
+ documentElement DOMDocument::DocumentElement DontDelete|ReadOnly
+ styleSheets DOMDocument::StyleSheets DontDelete|ReadOnly
+ preferredStylesheetSet DOMDocument::PreferredStylesheetSet DontDelete|ReadOnly
+ selectedStylesheetSet DOMDocument::SelectedStylesheetSet DontDelete
+ readyState DOMDocument::ReadyState DontDelete|ReadOnly
+ defaultView DOMDocument::DefaultView DontDelete|ReadOnly
+ async DOMDocument::Async DontDelete
+@end
+*/
+
+DOMDocument::DOMDocument(ExecState *exec, const DOM::Document& d)
+ : DOMNode(DOMDocumentProto::self(exec), d) { }
+
+DOMDocument::DOMDocument(const Object& proto, const DOM::Document& d)
+ : DOMNode(proto, d) { }
+
+DOMDocument::~DOMDocument()
+{
+ ScriptInterpreter::forgetDOMObject(node.handle());
+}
+
+Value DOMDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMDocument::tryGet " << propertyName.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMDocument, DOMNode>(
+ exec, propertyName, &DOMDocumentTable, this);
+}
+
+Value DOMDocument::getValueProperty(ExecState *exec, int token) const
+{
+ DOM::Document doc = static_cast<DOM::Document>(node);
+
+ switch(token) {
+ case DocType:
+ return getDOMNode(exec,doc.doctype());
+ case Implementation:
+ return getDOMDOMImplementation(exec,doc.implementation());
+ case DocumentElement:
+ return getDOMNode(exec,doc.documentElement());
+ case CharacterSet: {
+ DOM::DocumentImpl* docImpl = static_cast<DOM::DocumentImpl*>(doc.handle());
+ if (docImpl->part())
+ return String(docImpl->part()->encoding());
+ else
+ return Undefined();
+ }
+ case StyleSheets:
+ //kdDebug() << "DOMDocument::StyleSheets, returning " << doc.styleSheets().length() << " stylesheets" << endl;
+ return getDOMStyleSheetList(exec, doc.styleSheets(), doc);
+ case DOMDocument::DefaultView: // DOM2
+ {
+ KHTMLView *view = node.handle()->getDocument()->view();
+ if (view)
+ return Window::retrieve(view->part());
+ return getDOMAbstractView(exec, doc.defaultView());
+ }
+ case PreferredStylesheetSet:
+ return String(doc.preferredStylesheetSet());
+ case SelectedStylesheetSet:
+ return String(doc.selectedStylesheetSet());
+ case ReadyState:
+ {
+ DOM::DocumentImpl* docimpl = node.handle()->getDocument();
+ if ( docimpl && docimpl->view() )
+ {
+ KHTMLPart* part = docimpl->view()->part();
+ if ( part ) {
+ if (part->d->m_bComplete) return String("complete");
+ if (docimpl->parsing()) return String("loading");
+ return String("loaded");
+ // What does the interactive value mean ?
+ // Missing support for "uninitialized"
+ }
+ }
+ return Undefined();
+ }
+ case Async:
+ return Boolean(doc.async());
+ default:
+ kdDebug(6070) << "WARNING: DOMDocument::getValueProperty unhandled token " << token << endl;
+ return Value();
+ }
+}
+
+void DOMDocument::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMDocument::tryPut " << propertyName.qstring() << endl;
+#endif
+ DOMObjectLookupPut<DOMDocument,DOMNode>(exec, propertyName, value, attr, &DOMDocumentTable, this );
+}
+
+void DOMDocument::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
+{
+ DOM::Document doc = static_cast<DOM::Document>(node);
+ switch (token) {
+ case SelectedStylesheetSet: {
+ doc.setSelectedStylesheetSet(value.toString(exec).string());
+ break;
+ }
+ case Async: {
+ doc.setAsync(value.toBoolean(exec));
+ break;
+ }
+ }
+}
+
+Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMDocument, thisObj );
+ DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
+ DOM::Document doc = static_cast<DOM::Document>(node);
+ String str = args[0].toString(exec);
+ DOM::DOMString s = str.value().string();
+
+ switch(id) {
+ case DOMDocument::CreateElement:
+ return getDOMNode(exec,doc.createElement(s));
+ case DOMDocument::CreateDocumentFragment:
+ return getDOMNode(exec,doc.createDocumentFragment());
+ case DOMDocument::CreateTextNode:
+ return getDOMNode(exec,doc.createTextNode(s));
+ case DOMDocument::CreateComment:
+ return getDOMNode(exec,doc.createComment(s));
+ case DOMDocument::CreateCDATASection:
+ return getDOMNode(exec,doc.createCDATASection(s)); /* TODO: okay ? */
+ case DOMDocument::CreateProcessingInstruction:
+ return getDOMNode(exec,doc.createProcessingInstruction(args[0].toString(exec).string(),
+ args[1].toString(exec).string()));
+ case DOMDocument::CreateAttribute:
+ return getDOMNode(exec,doc.createAttribute(s));
+ case DOMDocument::CreateEntityReference:
+ return getDOMNode(exec,doc.createEntityReference(args[0].toString(exec).string()));
+ case DOMDocument::GetElementsByTagName:
+ return getDOMNodeList(exec,doc.getElementsByTagName(s));
+ case DOMDocument::ImportNode: // DOM2
+ return getDOMNode(exec,doc.importNode(toNode(args[0]), args[1].toBoolean(exec)));
+ case DOMDocument::CreateElementNS: // DOM2
+ return getDOMNode(exec,doc.createElementNS(args[0].toString(exec).string(), args[1].toString(exec).string()));
+ case DOMDocument::CreateAttributeNS: // DOM2
+ return getDOMNode(exec,doc.createAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMDocument::GetElementsByTagNameNS: // DOM2
+ return getDOMNodeList(exec,doc.getElementsByTagNameNS(args[0].toString(exec).string(),
+ args[1].toString(exec).string()));
+ case DOMDocument::GetElementById:
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMDocument::GetElementById looking for " << args[0].toString(exec).string() << endl;
+#endif
+ return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
+ case DOMDocument::CreateRange:
+ return getDOMRange(exec,doc.createRange());
+ case DOMDocument::CreateNodeIterator:
+ if (args[2].isA(NullType)) {
+ DOM::NodeFilter filter;
+ return getDOMNodeIterator(exec,
+ doc.createNodeIterator(toNode(args[0]),
+ (long unsigned int)(args[1].toNumber(exec)),
+ filter,args[3].toBoolean(exec)));
+ }
+ else {
+ Object obj = Object::dynamicCast(args[2]);
+ if (obj.isValid())
+ {
+ DOM::CustomNodeFilter *customFilter = new JSNodeFilter(obj);
+ DOM::NodeFilter filter = DOM::NodeFilter::createCustom(customFilter);
+ return getDOMNodeIterator(exec,
+ doc.createNodeIterator(
+ toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
+ filter,args[3].toBoolean(exec)));
+ }// else?
+ }
+ case DOMDocument::CreateTreeWalker:
+ return getDOMTreeWalker(exec,doc.createTreeWalker(toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
+ toNodeFilter(args[2]),args[3].toBoolean(exec)));
+ case DOMDocument::CreateEvent:
+ return getDOMEvent(exec,doc.createEvent(s));
+ case DOMDocument::GetOverrideStyle: {
+ DOM::Node arg0 = toNode(args[0]);
+ if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
+ return Undefined(); // throw exception?
+ else
+ return getDOMCSSStyleDeclaration(exec,doc.getOverrideStyle(static_cast<DOM::Element>(arg0),args[1].toString(exec).string()));
+ }
+ case DOMDocument::Abort:
+ doc.abort();
+ break;
+ case DOMDocument::Load: {
+ Window* active = Window::retrieveActive(exec);
+ // Complete the URL using the "active part" (running interpreter). We do this for the security
+ // check and to make sure we load exactly the same url as we have verified to be safe
+ KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(active->part());
+ if (khtmlpart) {
+ // Security: only allow documents to be loaded from the same host
+ QString dstUrl = khtmlpart->htmlDocument().completeURL(s).string();
+ KParts::ReadOnlyPart *part = static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part();
+ if (part->url().host() == KURL(dstUrl).host()) {
+ kdDebug(6070) << "JavaScript: access granted for document.load() of " << dstUrl << endl;
+ doc.load(dstUrl);
+ }
+ else {
+ kdDebug(6070) << "JavaScript: access denied for document.load() of " << dstUrl << endl;
+ }
+ }
+ break;
+ }
+ case DOMDocument::LoadXML:
+ doc.loadXML(s);
+ break;
+ default:
+ break;
+ }
+
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+/* Source for DOMElementProtoTable.
+@begin DOMElementProtoTable 17
+ getAttribute DOMElement::GetAttribute DontDelete|Function 1
+ setAttribute DOMElement::SetAttribute DontDelete|Function 2
+ removeAttribute DOMElement::RemoveAttribute DontDelete|Function 1
+ getAttributeNode DOMElement::GetAttributeNode DontDelete|Function 1
+ setAttributeNode DOMElement::SetAttributeNode DontDelete|Function 2
+ removeAttributeNode DOMElement::RemoveAttributeNode DontDelete|Function 1
+ getElementsByTagName DOMElement::GetElementsByTagName DontDelete|Function 1
+ hasAttribute DOMElement::HasAttribute DontDelete|Function 1
+ getAttributeNS DOMElement::GetAttributeNS DontDelete|Function 2
+ setAttributeNS DOMElement::SetAttributeNS DontDelete|Function 3
+ removeAttributeNS DOMElement::RemoveAttributeNS DontDelete|Function 2
+ getAttributeNodeNS DOMElement::GetAttributeNodeNS DontDelete|Function 2
+ setAttributeNodeNS DOMElement::SetAttributeNodeNS DontDelete|Function 1
+ getElementsByTagNameNS DOMElement::GetElementsByTagNameNS DontDelete|Function 2
+ hasAttributeNS DOMElement::HasAttributeNS DontDelete|Function 2
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(DOMElementProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMElement", DOMElementProto, DOMElementProtoFunc)
+
+IMPLEMENT_PSEUDO_CONSTRUCTOR(ElementPseudoCtor, "Element", DOMElementProto)
+
+const ClassInfo DOMElement::info = { "Element", &DOMNode::info, &DOMElementTable, 0 };
+/* Source for DOMElementTable.
+@begin DOMElementTable 3
+ tagName DOMElement::TagName DontDelete|ReadOnly
+ style DOMElement::Style DontDelete|ReadOnly
+@end
+*/
+DOMElement::DOMElement(ExecState *exec, const DOM::Element& e)
+ : DOMNode(DOMElementProto::self(exec), e) { }
+
+DOMElement::DOMElement(const Object& proto, const DOM::Element& e)
+ : DOMNode(proto, e) { }
+
+Value DOMElement::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMElement::tryGet " << propertyName.qstring() << endl;
+#endif
+ DOM::Element element = static_cast<DOM::Element>(node);
+
+ const HashEntry* entry = Lookup::findEntry(&DOMElementTable, propertyName);
+ if (entry)
+ {
+ switch( entry->value ) {
+ case TagName:
+ return String(element.tagName());
+ case Style:
+ return getDOMCSSStyleDeclaration(exec,element.style());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMElement::tryGet : " << entry->value << endl;
+ break;
+ }
+ }
+ // We have to check in DOMNode before giving access to attributes, otherwise
+ // onload="..." would make onload return the string (attribute value) instead of
+ // the listener object (function).
+ if (DOMNode::hasProperty(exec, propertyName))
+ return DOMNode::tryGet(exec, propertyName);
+
+ DOM::DOMString attr = element.getAttribute( propertyName.string() );
+ // Give access to attributes
+ if ( !attr.isNull() )
+ return String( attr );
+
+ return Undefined();
+}
+
+Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMNode, thisObj ); // node should be enough here, given the cast
+ DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
+ DOM::Element element = static_cast<DOM::Element>(node);
+
+ switch(id) {
+ case DOMElement::GetAttribute:
+ /** In theory, we should not return null here, as per DOM. In practice, that
+ breaks websites
+ */
+ return getString(element.getAttribute(args[0].toString(exec).string()));
+ case DOMElement::SetAttribute:
+ element.setAttribute(args[0].toString(exec).string(),args[1].toString(exec).string());
+ return Undefined();
+ case DOMElement::RemoveAttribute:
+ element.removeAttribute(args[0].toString(exec).string());
+ return Undefined();
+ case DOMElement::GetAttributeNode:
+ return getDOMNode(exec,element.getAttributeNode(args[0].toString(exec).string()));
+ case DOMElement::SetAttributeNode:
+ return getDOMNode(exec,element.setAttributeNode(KJS::toNode(args[0])));
+ case DOMElement::RemoveAttributeNode:
+ return getDOMNode(exec,element.removeAttributeNode(KJS::toNode(args[0])));
+ case DOMElement::GetElementsByTagName:
+ return getDOMNodeList(exec,element.getElementsByTagName(args[0].toString(exec).string()));
+ case DOMElement::HasAttribute: // DOM2
+ return Boolean(element.hasAttribute(args[0].toString(exec).string()));
+ case DOMElement::GetAttributeNS: // DOM2
+ return String(element.getAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMElement::SetAttributeNS: // DOM2
+ element.setAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string());
+ return Undefined();
+ case DOMElement::RemoveAttributeNS: // DOM2
+ element.removeAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string());
+ return Undefined();
+ case DOMElement::GetAttributeNodeNS: // DOM2
+ return getDOMNode(exec,element.getAttributeNodeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMElement::SetAttributeNodeNS: // DOM2
+ return getDOMNode(exec,element.setAttributeNodeNS(KJS::toNode(args[0])));
+ case DOMElement::GetElementsByTagNameNS: // DOM2
+ return getDOMNodeList(exec,element.getElementsByTagNameNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMElement::HasAttributeNS: // DOM2
+ return Boolean(element.hasAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ default:
+ return Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+/* Source for DOMDOMImplementationProtoTable.
+@begin DOMDOMImplementationProtoTable 5
+ hasFeature DOMDOMImplementation::HasFeature DontDelete|Function 2
+ createCSSStyleSheet DOMDOMImplementation::CreateCSSStyleSheet DontDelete|Function 2
+# DOM2
+ createDocumentType DOMDOMImplementation::CreateDocumentType DontDelete|Function 3
+ createDocument DOMDOMImplementation::CreateDocument DontDelete|Function 3
+ createHTMLDocument DOMDOMImplementation::CreateHTMLDocument DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMDOMImplementationProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMDOMImplementationProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMImplementation", DOMDOMImplementationProto, DOMDOMImplementationProtoFunc)
+
+const ClassInfo DOMDOMImplementation::info = { "DOMImplementation", 0, 0, 0 };
+
+DOMDOMImplementation::DOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
+ : DOMObject(DOMDOMImplementationProto::self(exec)), implementation(i) { }
+
+DOMDOMImplementation::~DOMDOMImplementation()
+{
+ ScriptInterpreter::forgetDOMObject(implementation.handle());
+}
+
+Value DOMDOMImplementationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMDOMImplementation, thisObj );
+ DOM::DOMImplementation implementation = static_cast<DOMDOMImplementation *>( thisObj.imp() )->toImplementation();
+
+ switch(id) {
+ case DOMDOMImplementation::HasFeature:
+ return Boolean(implementation.hasFeature(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMDOMImplementation::CreateDocumentType: // DOM2
+ return getDOMNode(exec,implementation.createDocumentType(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string()));
+ case DOMDOMImplementation::CreateDocument: { // DOM2
+ // Initially set the URL to document of the creator... this is so that it resides in the same
+ // host/domain for security checks. The URL will be updated if Document.load() is called.
+ KHTMLPart *part = ::qt_cast<KHTMLPart*>(static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part());
+ if (part) {
+ Document doc = implementation.createDocument(args[0].toString(exec).string(),args[1].toString(exec).string(),toNode(args[2]));
+ KURL url = static_cast<DocumentImpl*>(part->document().handle())->URL();
+ static_cast<DocumentImpl*>(doc.handle())->setURL(url.url());
+ return getDOMNode(exec,doc);
+ }
+ break;
+ }
+ case DOMDOMImplementation::CreateCSSStyleSheet: // DOM2
+ return getDOMStyleSheet(exec,implementation.createCSSStyleSheet(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMDOMImplementation::CreateHTMLDocument: // DOM2-HTML
+ return getDOMNode(exec, implementation.createHTMLDocument(args[0].toString(exec).string()));
+ default:
+ break;
+ }
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMDocumentType::info = { "DocumentType", &DOMNode::info, &DOMDocumentTypeTable, 0 };
+
+/* Source for DOMDocumentTypeTable.
+@begin DOMDocumentTypeTable 6
+ name DOMDocumentType::Name DontDelete|ReadOnly
+ entities DOMDocumentType::Entities DontDelete|ReadOnly
+ notations DOMDocumentType::Notations DontDelete|ReadOnly
+# DOM2
+ publicId DOMDocumentType::PublicId DontDelete|ReadOnly
+ systemId DOMDocumentType::SystemId DontDelete|ReadOnly
+ internalSubset DOMDocumentType::InternalSubset DontDelete|ReadOnly
+@end
+*/
+DOMDocumentType::DOMDocumentType(ExecState *exec, const DOM::DocumentType& dt)
+ : DOMNode( /*### no proto yet*/exec, dt ) { }
+
+Value DOMDocumentType::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMDocumentType::tryGet " << propertyName.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this);
+}
+
+Value DOMDocumentType::getValueProperty(ExecState *exec, int token) const
+{
+ DOM::DocumentType type = static_cast<DOM::DocumentType>(node);
+ switch (token) {
+ case Name:
+ return String(type.name());
+ case Entities:
+ return getDOMNamedNodeMap(exec,type.entities());
+ case Notations:
+ return getDOMNamedNodeMap(exec,type.notations());
+ case PublicId: // DOM2
+ return String(type.publicId());
+ case SystemId: // DOM2
+ return String(type.systemId());
+ case InternalSubset: // DOM2
+ return getString(type.internalSubset()); // can be null, see domts/level2/core/internalSubset01.html
+ default:
+ kdDebug(6070) << "WARNING: DOMDocumentType::getValueProperty unhandled token " << token << endl;
+ return Value();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+/* Source for DOMNamedNodeMapProtoTable.
+@begin DOMNamedNodeMapProtoTable 7
+ getNamedItem DOMNamedNodeMap::GetNamedItem DontDelete|Function 1
+ setNamedItem DOMNamedNodeMap::SetNamedItem DontDelete|Function 1
+ removeNamedItem DOMNamedNodeMap::RemoveNamedItem DontDelete|Function 1
+ item DOMNamedNodeMap::Item DontDelete|Function 1
+# DOM2
+ getNamedItemNS DOMNamedNodeMap::GetNamedItemNS DontDelete|Function 2
+ setNamedItemNS DOMNamedNodeMap::SetNamedItemNS DontDelete|Function 1
+ removeNamedItemNS DOMNamedNodeMap::RemoveNamedItemNS DontDelete|Function 2
+@end
+@begin DOMNamedNodeMapTable 7
+ length DOMNamedNodeMap::Length DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMNamedNodeMapProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMNamedNodeMapProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("NamedNodeMap", DOMNamedNodeMapProto, DOMNamedNodeMapProtoFunc)
+
+const ClassInfo DOMNamedNodeMap::info = { "NamedNodeMap", 0, &DOMNamedNodeMapTable, 0 };
+
+DOMNamedNodeMap::DOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
+ : DOMObject(DOMNamedNodeMapProto::self(exec)), map(m) { }
+
+DOMNamedNodeMap::~DOMNamedNodeMap()
+{
+ ScriptInterpreter::forgetDOMObject(map.handle());
+}
+
+bool DOMNamedNodeMap::hasProperty(ExecState *exec, const Identifier &p) const
+{
+ // ## missing? array index
+ return DOMObject::hasProperty(exec, p);
+}
+
+Value DOMNamedNodeMap::tryGet(ExecState* exec, const Identifier &p) const
+{
+ if (p == lengthPropertyName)
+ return Number(map.length());
+
+ // array index ?
+ bool ok;
+ long unsigned int idx = p.toULong(&ok);
+ if (ok)
+ return getDOMNode(exec,map.item(idx));
+
+ // Anything else (including functions, defined in the prototype)
+ return DOMObject::tryGet(exec, p);
+}
+
+Value DOMNamedNodeMapProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMNamedNodeMap, thisObj );
+ DOM::NamedNodeMap map = static_cast<DOMNamedNodeMap *>(thisObj.imp())->toMap();
+
+ switch(id) {
+ case DOMNamedNodeMap::GetNamedItem:
+ return getDOMNode(exec, map.getNamedItem(args[0].toString(exec).string()));
+ case DOMNamedNodeMap::SetNamedItem:
+ return getDOMNode(exec, map.setNamedItem(KJS::toNode(args[0])));
+ case DOMNamedNodeMap::RemoveNamedItem:
+ return getDOMNode(exec, map.removeNamedItem(args[0].toString(exec).string()));
+ case DOMNamedNodeMap::Item:
+ return getDOMNode(exec, map.item(args[0].toInt32(exec)));
+ case DOMNamedNodeMap::GetNamedItemNS: // DOM2
+ return getDOMNode(exec, map.getNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ case DOMNamedNodeMap::SetNamedItemNS: // DOM2
+ return getDOMNode(exec, map.setNamedItemNS(toNode(args[0])));
+ case DOMNamedNodeMap::RemoveNamedItemNS: // DOM2
+ return getDOMNode(exec, map.removeNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
+ default:
+ break;
+ }
+
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+//### FIXME: proto
+const ClassInfo DOMProcessingInstruction::info = { "ProcessingInstruction", &DOMNode::info, &DOMProcessingInstructionTable, 0 };
+
+/* Source for DOMProcessingInstructionTable.
+@begin DOMProcessingInstructionTable 3
+ target DOMProcessingInstruction::Target DontDelete|ReadOnly
+ data DOMProcessingInstruction::Data DontDelete
+ sheet DOMProcessingInstruction::Sheet DontDelete|ReadOnly
+@end
+*/
+Value DOMProcessingInstruction::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ return DOMObjectLookupGetValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this);
+}
+
+Value DOMProcessingInstruction::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Target:
+ return String(static_cast<DOM::ProcessingInstruction>(node).target());
+ case Data:
+ return String(static_cast<DOM::ProcessingInstruction>(node).data());
+ case Sheet:
+ return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
+ default:
+ kdDebug(6070) << "WARNING: DOMProcessingInstruction::getValueProperty unhandled token " << token << endl;
+ return Value();
+ }
+}
+
+void DOMProcessingInstruction::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+ // Not worth using the hashtable for this one ;)
+ if (propertyName == "data")
+ static_cast<DOM::ProcessingInstruction>(node).setData(value.toString(exec).string());
+ else
+ DOMNode::tryPut(exec, propertyName,value,attr);
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMNotation::info = { "Notation", &DOMNode::info, &DOMNotationTable, 0 };
+
+/* Source for DOMNotationTable.
+@begin DOMNotationTable 2
+ publicId DOMNotation::PublicId DontDelete|ReadOnly
+ systemId DOMNotation::SystemId DontDelete|ReadOnly
+@end
+*/
+Value DOMNotation::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ return DOMObjectLookupGetValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this);
+}
+
+Value DOMNotation::getValueProperty(ExecState *, int token) const
+{
+ switch (token) {
+ case PublicId:
+ return String(static_cast<DOM::Notation>(node).publicId());
+ case SystemId:
+ return String(static_cast<DOM::Notation>(node).systemId());
+ default:
+ kdDebug(6070) << "WARNING: DOMNotation::getValueProperty unhandled token " << token << endl;
+ return Value();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMEntity::info = { "Entity", &DOMNode::info, 0, 0 };
+
+/* Source for DOMEntityTable.
+@begin DOMEntityTable 2
+ publicId DOMEntity::PublicId DontDelete|ReadOnly
+ systemId DOMEntity::SystemId DontDelete|ReadOnly
+ notationName DOMEntity::NotationName DontDelete|ReadOnly
+@end
+*/
+Value DOMEntity::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ return DOMObjectLookupGetValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this);
+}
+
+Value DOMEntity::getValueProperty(ExecState *, int token) const
+{
+ switch (token) {
+ case PublicId:
+ return String(static_cast<DOM::Entity>(node).publicId());
+ case SystemId:
+ return String(static_cast<DOM::Entity>(node).systemId());
+ case NotationName:
+ return String(static_cast<DOM::Entity>(node).notationName());
+ default:
+ kdDebug(6070) << "WARNING: DOMEntity::getValueProperty unhandled token " << token << endl;
+ return Value();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+bool checkNodeSecurity(ExecState *exec, const DOM::Node& n)
+{
+ // Check to see if the currently executing interpreter is allowed to access the specified node
+ if (n.isNull())
+ return true;
+ KHTMLView *view = n.handle()->getDocument()->view();
+ Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
+ if ( !win || !win->isSafeScript(exec) )
+ return false;
+ return true;
+}
+
+Value getDOMNode(ExecState *exec, const DOM::Node& n)
+{
+ DOMObject *ret = 0;
+ if (n.isNull())
+ return Null();
+ ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+ if ((ret = interp->getDOMObject(n.handle())))
+ return Value(ret);
+
+ switch (n.nodeType()) {
+ case DOM::Node::ELEMENT_NODE:
+ if (static_cast<DOM::Element>(n).isHTMLElement())
+ ret = new HTMLElement(exec, static_cast<DOM::HTMLElement>(n));
+ else
+ ret = new DOMElement(exec, static_cast<DOM::Element>(n));
+ break;
+ case DOM::Node::ATTRIBUTE_NODE:
+ ret = new DOMAttr(exec, static_cast<DOM::Attr>(n));
+ break;
+ case DOM::Node::TEXT_NODE:
+ case DOM::Node::CDATA_SECTION_NODE:
+ ret = new DOMText(exec, static_cast<DOM::Text>(n));
+ break;
+ case DOM::Node::ENTITY_REFERENCE_NODE:
+ ret = new DOMNode(exec, n);
+ break;
+ case DOM::Node::ENTITY_NODE:
+ ret = new DOMEntity(exec, static_cast<DOM::Entity>(n));
+ break;
+ case DOM::Node::PROCESSING_INSTRUCTION_NODE:
+ ret = new DOMProcessingInstruction(exec, static_cast<DOM::ProcessingInstruction>(n));
+ break;
+ case DOM::Node::COMMENT_NODE:
+ ret = new DOMCharacterData(exec, static_cast<DOM::CharacterData>(n));
+ break;
+ case DOM::Node::DOCUMENT_NODE:
+ if (static_cast<DOM::Document>(n).isHTMLDocument())
+ ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
+ else
+ ret = new DOMDocument(exec, static_cast<DOM::Document>(n));
+ break;
+ case DOM::Node::DOCUMENT_TYPE_NODE:
+ ret = new DOMDocumentType(exec, static_cast<DOM::DocumentType>(n));
+ break;
+ case DOM::Node::DOCUMENT_FRAGMENT_NODE:
+ ret = new DOMNode(exec, n);
+ break;
+ case DOM::Node::NOTATION_NODE:
+ ret = new DOMNotation(exec, static_cast<DOM::Notation>(n));
+ break;
+ default:
+ ret = new DOMNode(exec, n);
+ }
+ interp->putDOMObject(n.handle(),ret);
+
+ return Value(ret);
+}
+
+Value getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
+{
+ return Value(cacheDOMObject<DOM::NamedNodeMap, KJS::DOMNamedNodeMap>(exec, m));
+}
+
+Value getDOMNodeList(ExecState *exec, const DOM::NodeList& l)
+{
+ return Value(cacheDOMObject<DOM::NodeList, KJS::DOMNodeList>(exec, l));
+}
+
+Value getDOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
+{
+ return Value(cacheDOMObject<DOM::DOMImplementation, KJS::DOMDOMImplementation>(exec, i));
+}
+
+// -------------------------------------------------------------------------
+IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(NodeConstructor, "NodeConstructor", DOMNodeProto, DOMNodeConstants)
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMExceptionConstructor::info = { "DOMExceptionConstructor", 0, 0, 0 };
+
+/* Source for DOMExceptionConstructorTable.
+@begin DOMExceptionConstructorTable 15
+ INDEX_SIZE_ERR DOM::DOMException::INDEX_SIZE_ERR DontDelete|ReadOnly
+ DOMSTRING_SIZE_ERR DOM::DOMException::DOMSTRING_SIZE_ERR DontDelete|ReadOnly
+ HIERARCHY_REQUEST_ERR DOM::DOMException::HIERARCHY_REQUEST_ERR DontDelete|ReadOnly
+ WRONG_DOCUMENT_ERR DOM::DOMException::WRONG_DOCUMENT_ERR DontDelete|ReadOnly
+ INVALID_CHARACTER_ERR DOM::DOMException::INVALID_CHARACTER_ERR DontDelete|ReadOnly
+ NO_DATA_ALLOWED_ERR DOM::DOMException::NO_DATA_ALLOWED_ERR DontDelete|ReadOnly
+ NO_MODIFICATION_ALLOWED_ERR DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR DontDelete|ReadOnly
+ NOT_FOUND_ERR DOM::DOMException::NOT_FOUND_ERR DontDelete|ReadOnly
+ NOT_SUPPORTED_ERR DOM::DOMException::NOT_SUPPORTED_ERR DontDelete|ReadOnly
+ INUSE_ATTRIBUTE_ERR DOM::DOMException::INUSE_ATTRIBUTE_ERR DontDelete|ReadOnly
+ INVALID_STATE_ERR DOM::DOMException::INVALID_STATE_ERR DontDelete|ReadOnly
+ SYNTAX_ERR DOM::DOMException::SYNTAX_ERR DontDelete|ReadOnly
+ INVALID_MODIFICATION_ERR DOM::DOMException::INVALID_MODIFICATION_ERR DontDelete|ReadOnly
+ NAMESPACE_ERR DOM::DOMException::NAMESPACE_ERR DontDelete|ReadOnly
+ INVALID_ACCESS_ERR DOM::DOMException::INVALID_ACCESS_ERR DontDelete|ReadOnly
+@end
+*/
+
+DOMExceptionConstructor::DOMExceptionConstructor(ExecState* exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype())
+{
+}
+
+Value DOMExceptionConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ return DOMObjectLookupGetValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this);
+}
+
+Value DOMExceptionConstructor::getValueProperty(ExecState *, int token) const
+{
+ // We use the token as the value to return directly
+ return Number((unsigned int)token);
+#if 0
+ switch (token) {
+ case INDEX_SIZE_ERR:
+ return Number((unsigned int)DOM::DOMException::INDEX_SIZE_ERR);
+ case DOMSTRING_SIZE_ERR:
+ return Number((unsigned int)DOM::DOMException::DOMSTRING_SIZE_ERR);
+ case HIERARCHY_REQUEST_ERR:
+ return Number((unsigned int)DOM::DOMException::HIERARCHY_REQUEST_ERR);
+ case WRONG_DOCUMENT_ERR:
+ return Number((unsigned int)DOM::DOMException::WRONG_DOCUMENT_ERR);
+ case INVALID_CHARACTER_ERR:
+ return Number((unsigned int)DOM::DOMException::INVALID_CHARACTER_ERR);
+ case NO_DATA_ALLOWED_ERR:
+ return Number((unsigned int)DOM::DOMException::NO_DATA_ALLOWED_ERR);
+ case NO_MODIFICATION_ALLOWED_ERR:
+ return Number((unsigned int)DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR);
+ case NOT_FOUND_ERR:
+ return Number((unsigned int)DOM::DOMException::NOT_FOUND_ERR);
+ case NOT_SUPPORTED_ERR:
+ return Number((unsigned int)DOM::DOMException::NOT_SUPPORTED_ERR);
+ case INUSE_ATTRIBUTE_ERR:
+ return Number((unsigned int)DOM::DOMException::INUSE_ATTRIBUTE_ERR);
+ case INVALID_STATE_ERR:
+ return Number((unsigned int)DOM::DOMException::INVALID_STATE_ERR);
+ case SYNTAX_ERR:
+ return Number((unsigned int)DOM::DOMException::SYNTAX_ERR);
+ case INVALID_MODIFICATION_ERR:
+ return Number((unsigned int)DOM::DOMException::INVALID_MODIFICATION_ERR);
+ case NAMESPACE_ERR:
+ return Number((unsigned int)DOM::DOMException::NAMESPACE_ERR);
+ case INVALID_ACCESS_ERR:
+ return Number((unsigned int)DOM::DOMException::INVALID_ACCESS_ERR);
+ default:
+ kdDebug(6070) << "WARNING: DOMExceptionConstructor::getValueProperty unhandled token " << token << endl;
+ return Value();
+ }
+#endif
+}
+
+Object getDOMExceptionConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<DOMExceptionConstructor>(exec, "[[DOMException.constructor]]");
+}
+
+// -------------------------------------------------------------------------
+
+/* Source for DOMNamedNodesCollection.
+@begin DOMNamedNodesCollectionTable 1
+ length KJS::DOMNamedNodesCollection::Length DontDelete|ReadOnly
+@end
+*/
+const ClassInfo KJS::DOMNamedNodesCollection::info = { "DOMNamedNodesCollection", 0, &DOMNamedNodesCollectionTable, 0 };
+
+// Such a collection is usually very short-lived, it only exists
+// for constructs like document.forms.<name>[1],
+// so it shouldn't be a problem that it's storing all the nodes (with the same name). (David)
+DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *exec, const QValueList<DOM::Node>& nodes )
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()),
+ m_nodes(nodes)
+{
+ // Maybe we should ref (and deref in the dtor) the nodes, though ?
+}
+
+Value DOMNamedNodesCollection::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ kdDebug(6070) << k_funcinfo << propertyName.ascii() << endl;
+ if (propertyName == lengthPropertyName)
+ return Number(m_nodes.count());
+ // index?
+ bool ok;
+ unsigned int u = propertyName.toULong(&ok);
+ if (ok && u < m_nodes.count()) {
+ DOM::Node node = m_nodes[u];
+ return getDOMNode(exec,node);
+ }
+ return DOMObject::tryGet(exec,propertyName);
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMCharacterData::info = { "CharacterImp",
+ &DOMNode::info, &DOMCharacterDataTable, 0 };
+/*
+@begin DOMCharacterDataTable 2
+ data DOMCharacterData::Data DontDelete
+ length DOMCharacterData::Length DontDelete|ReadOnly
+@end
+@begin DOMCharacterDataProtoTable 7
+ substringData DOMCharacterData::SubstringData DontDelete|Function 2
+ appendData DOMCharacterData::AppendData DontDelete|Function 1
+ insertData DOMCharacterData::InsertData DontDelete|Function 2
+ deleteData DOMCharacterData::DeleteData DontDelete|Function 2
+ replaceData DOMCharacterData::ReplaceData DontDelete|Function 2
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMCharacterDataProto, DOMNodeProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMCharacterDataProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMCharacterData", DOMCharacterDataProto, DOMCharacterDataProtoFunc)
+
+DOMCharacterData::DOMCharacterData(ExecState *exec, const DOM::CharacterData& d)
+ : DOMNode(DOMCharacterDataProto::self(exec), d) {}
+
+DOMCharacterData::DOMCharacterData(const Object& proto, const DOM::CharacterData& d)
+ : DOMNode(proto, d) {}
+
+Value DOMCharacterData::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070)<<"DOMCharacterData::tryGet "<<p.string().string()<<endl;
+#endif
+ return DOMObjectLookupGetValue<DOMCharacterData,DOMNode>(exec,p,&DOMCharacterDataTable,this);
+}
+
+Value DOMCharacterData::getValueProperty(ExecState *, int token) const
+{
+ DOM::CharacterData data = static_cast<DOM::CharacterData>(node);
+ switch (token) {
+ case Data:
+ return String(data.data());
+ case Length:
+ return Number(data.length());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMCharacterData::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+void DOMCharacterData::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+ if (propertyName == "data")
+ static_cast<DOM::CharacterData>(node).setData(value.toString(exec).string());
+ else
+ DOMNode::tryPut(exec, propertyName,value,attr);
+}
+
+Value DOMCharacterDataProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMCharacterData, thisObj );
+ DOM::CharacterData data = static_cast<DOMCharacterData *>(thisObj.imp())->toData();
+ switch(id) {
+ case DOMCharacterData::SubstringData:
+ return String(data.substringData(args[0].toInteger(exec),args[1].toInteger(exec)));
+ case DOMCharacterData::AppendData:
+ data.appendData(args[0].toString(exec).string());
+ return Undefined();
+ break;
+ case DOMCharacterData::InsertData:
+ data.insertData(args[0].toInteger(exec),args[1].toString(exec).string());
+ return Undefined();
+ break;
+ case DOMCharacterData::DeleteData:
+ data.deleteData(args[0].toInteger(exec),args[1].toInteger(exec));
+ return Undefined();
+ break;
+ case DOMCharacterData::ReplaceData:
+ data.replaceData(args[0].toInteger(exec),args[1].toInteger(exec),args[2].toString(exec).string());
+ return Undefined();
+ default:
+ break;
+ }
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMText::info = { "Text",
+ &DOMCharacterData::info, 0, 0 };
+/*
+@begin DOMTextProtoTable 1
+ splitText DOMText::SplitText DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMTextProto, DOMCharacterDataProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMTextProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMText", DOMTextProto, DOMTextProtoFunc)
+
+DOMText::DOMText(ExecState *exec, const DOM::Text& t)
+ : DOMCharacterData(DOMTextProto::self(exec), t) { }
+
+Value DOMText::tryGet(ExecState *exec, const Identifier &p) const
+{
+ if (p.isEmpty())
+ return Undefined(); // ### TODO
+ else
+ return DOMCharacterData::tryGet(exec, p);
+}
+
+Value DOMTextProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMText, thisObj );
+ DOM::Text text = static_cast<DOMText *>(thisObj.imp())->toText();
+ switch(id) {
+ case DOMText::SplitText:
+ return getDOMNode(exec,text.splitText(args[0].toInteger(exec)));
+ default:
+ break;
+ }
+ return Undefined();
+}
+
+}
diff --git a/khtml/ecma/kjs_dom.h b/khtml/ecma/kjs_dom.h
new file mode 100644
index 000000000..e6b593fdb
--- /dev/null
+++ b/khtml/ecma/kjs_dom.h
@@ -0,0 +1,299 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_DOM_H_
+#define _KJS_DOM_H_
+
+#include "dom/dom_node.h"
+#include "dom/dom_doc.h"
+#include "dom/dom_element.h"
+#include "dom/dom_xml.h"
+
+#include "ecma/kjs_binding.h"
+
+
+namespace KJS {
+
+ class DOMNode : public DOMObject {
+ public:
+ // Build a DOMNode
+ DOMNode(ExecState *exec, const DOM::Node& n);
+ // Constructor for inherited classes
+ DOMNode(const Object& proto, const DOM::Node& n);
+ ~DOMNode();
+ virtual bool toBoolean(ExecState *) const;
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ void putValueProperty(ExecState *exec, int token, const Value& value, int attr);
+ virtual DOM::Node toNode() const { return node; }
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+
+ virtual Value toPrimitive(ExecState *exec, Type preferred = UndefinedType) const;
+ virtual UString toString(ExecState *exec) const;
+ void setListener(ExecState *exec, int eventId, const Value& func) const;
+ Value getListener(int eventId) const;
+ virtual void pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const;
+
+ enum { NodeName, NodeValue, NodeType, ParentNode, ParentElement,
+ ChildNodes, FirstChild, LastChild, PreviousSibling, NextSibling, Item,
+ Attributes, NamespaceURI, Prefix, LocalName, OwnerDocument, InsertBefore,
+ ReplaceChild, RemoveChild, AppendChild, HasAttributes, HasChildNodes,
+ CloneNode, Normalize, IsSupported, AddEventListener, RemoveEventListener,
+ DispatchEvent, Contains, InsertAdjacentHTML,
+ OnAbort, OnBlur, OnChange, OnClick, OnDblClick, OnDragDrop, OnError,
+ OnFocus, OnKeyDown, OnKeyPress, OnKeyUp, OnLoad, OnMouseDown,
+ OnMouseMove, OnMouseOut, OnMouseOver, OnMouseUp, OnMove, OnReset,
+ OnResize, OnSelect, OnSubmit, OnUnload,
+ OffsetLeft, OffsetTop, OffsetWidth, OffsetHeight, OffsetParent,
+ ClientWidth, ClientHeight, ScrollLeft, ScrollTop,
+ ScrollWidth, ScrollHeight, SourceIndex, TextContent };
+
+ protected:
+ DOM::Node node;
+ };
+
+ DEFINE_CONSTANT_TABLE(DOMNodeConstants)
+ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMNodeProto, DOMNodeConstants)
+ DEFINE_PSEUDO_CONSTRUCTOR(NodeConstructor)
+
+ class DOMNodeList : public DOMObject {
+ public:
+ DOMNodeList(ExecState *, const DOM::NodeList& l);
+ ~DOMNodeList();
+ virtual bool hasProperty(ExecState *exec, const Identifier &p) const;
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ virtual Value call(ExecState *exec, Object &thisObj, const List&args);
+ virtual Value tryCall(ExecState *exec, Object &thisObj, const List&args);
+ virtual bool implementsCall() const { return true; }
+ virtual ReferenceList propList(ExecState *exec, bool recursive);
+
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ virtual bool toBoolean(ExecState *) const { return true; }
+ static const ClassInfo info;
+ DOM::NodeList nodeList() const { return list; }
+ enum { Item, NamedItem };
+ private:
+ DOM::NodeList list;
+ };
+
+ class DOMDocument : public DOMNode {
+ public:
+ // Build a DOMDocument
+ DOMDocument(ExecState *exec, const DOM::Document& d);
+ // Constructor for inherited classes
+ DOMDocument(const Object& proto, const DOM::Document& d);
+ virtual ~DOMDocument();
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ void putValueProperty(ExecState *exec, int token, const Value& value, int attr);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { DocType, Implementation, DocumentElement, CharacterSet,
+ // Functions
+ CreateElement, CreateDocumentFragment, CreateTextNode, CreateComment,
+ CreateCDATASection, CreateProcessingInstruction, CreateAttribute,
+ CreateEntityReference, GetElementsByTagName, ImportNode, CreateElementNS,
+ CreateAttributeNS, GetElementsByTagNameNS, GetElementById,
+ CreateRange, CreateNodeIterator, CreateTreeWalker, DefaultView,
+ CreateEvent, StyleSheets, GetOverrideStyle, Abort, Load, LoadXML,
+ PreferredStylesheetSet, SelectedStylesheetSet, ReadyState, Async };
+ };
+
+ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMDocumentProto, DOMNodeProto)
+
+ DEFINE_PSEUDO_CONSTRUCTOR(DocumentPseudoCtor)
+
+ class DOMAttr : public DOMNode {
+ public:
+ DOMAttr(ExecState *exec, const DOM::Attr& a) : DOMNode(exec, a) { }
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ Value getValueProperty(ExecState *exec, int token) const;
+ void putValueProperty(ExecState *exec, int token, const Value& value, int attr);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Name, Specified, ValueProperty, OwnerElement };
+ };
+
+ class DOMElement : public DOMNode {
+ public:
+ // Build a DOMElement
+ DOMElement(ExecState *exec, const DOM::Element& e);
+ // Constructor for inherited classes
+ DOMElement(const Object& proto, const DOM::Element& e);
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { TagName, Style,
+ GetAttribute, SetAttribute, RemoveAttribute, GetAttributeNode,
+ SetAttributeNode, RemoveAttributeNode, GetElementsByTagName,
+ GetAttributeNS, SetAttributeNS, RemoveAttributeNS, GetAttributeNodeNS,
+ SetAttributeNodeNS, GetElementsByTagNameNS, HasAttribute, HasAttributeNS };
+ };
+
+ KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMElementProto, DOMNodeProto)
+ DEFINE_PSEUDO_CONSTRUCTOR(ElementPseudoCtor)
+
+ class DOMDOMImplementation : public DOMObject {
+ public:
+ // Build a DOMDOMImplementation
+ DOMDOMImplementation(ExecState *, const DOM::DOMImplementation& i);
+ ~DOMDOMImplementation();
+ // no put - all functions
+ virtual const ClassInfo* classInfo() const { return &info; }
+ virtual bool toBoolean(ExecState *) const { return true; }
+ static const ClassInfo info;
+ enum { HasFeature, CreateDocumentType, CreateDocument, CreateCSSStyleSheet, CreateHTMLDocument };
+ DOM::DOMImplementation toImplementation() const { return implementation; }
+ private:
+ DOM::DOMImplementation implementation;
+ };
+
+ class DOMDocumentType : public DOMNode {
+ public:
+ // Build a DOMDocumentType
+ DOMDocumentType(ExecState *exec, const DOM::DocumentType& dt);
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Name, Entities, Notations, PublicId, SystemId, InternalSubset };
+ };
+
+ class DOMNamedNodeMap : public DOMObject {
+ public:
+ DOMNamedNodeMap(ExecState *, const DOM::NamedNodeMap& m);
+ ~DOMNamedNodeMap();
+ virtual bool hasProperty(ExecState *exec, const Identifier &p) const;
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ virtual bool toBoolean(ExecState *) const { return true; }
+ static const ClassInfo info;
+ enum { GetNamedItem, SetNamedItem, RemoveNamedItem, Item, Length,
+ GetNamedItemNS, SetNamedItemNS, RemoveNamedItemNS };
+ DOM::NamedNodeMap toMap() const { return map; }
+ private:
+ DOM::NamedNodeMap map;
+ };
+
+ class DOMProcessingInstruction : public DOMNode {
+ public:
+ DOMProcessingInstruction(ExecState *exec, const DOM::ProcessingInstruction& pi) : DOMNode(exec, pi) { }
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Target, Data, Sheet };
+ };
+
+ class DOMNotation : public DOMNode {
+ public:
+ DOMNotation(ExecState *exec, const DOM::Notation& n) : DOMNode(exec, n) { }
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { PublicId, SystemId };
+ };
+
+ class DOMEntity : public DOMNode {
+ public:
+ DOMEntity(ExecState *exec, const DOM::Entity& e) : DOMNode(exec, e) { }
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { PublicId, SystemId, NotationName };
+ };
+
+ // Constructor for DOMException - constructor stuff not implemented yet
+ class DOMExceptionConstructor : public DOMObject {
+ public:
+ DOMExceptionConstructor(ExecState *);
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ bool checkNodeSecurity(ExecState *exec, const DOM::Node& n);
+ KDE_EXPORT Value getDOMNode(ExecState *exec, const DOM::Node& n);
+ Value getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m);
+ Value getDOMNodeList(ExecState *exec, const DOM::NodeList& l);
+ Value getDOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i);
+ Object getDOMExceptionConstructor(ExecState *exec);
+
+ // Internal class, used for the collection return by e.g. document.forms.myinput
+ // when multiple nodes have the same name.
+ class DOMNamedNodesCollection : public DOMObject {
+ public:
+ DOMNamedNodesCollection(ExecState *exec, const QValueList<DOM::Node>& nodes );
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ const QValueList<DOM::Node>& nodes() const { return m_nodes; }
+ enum { Length };
+ private:
+ QValueList<DOM::Node> m_nodes;
+ };
+
+ class DOMCharacterData : public DOMNode {
+ public:
+ // Build a DOMCharacterData
+ DOMCharacterData(ExecState *exec, const DOM::CharacterData& d);
+ // Constructor for inherited classes
+ DOMCharacterData(const Object& proto, const DOM::CharacterData& d);
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ DOM::CharacterData toData() const { return static_cast<DOM::CharacterData>(node); }
+ enum { Data, Length,
+ SubstringData, AppendData, InsertData, DeleteData, ReplaceData };
+ };
+
+ class DOMText : public DOMCharacterData {
+ public:
+ DOMText(ExecState *exec, const DOM::Text& t);
+ virtual Value tryGet(ExecState *exec,const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *, int token) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ DOM::Text toText() const { return static_cast<DOM::Text>(node); }
+ enum { SplitText };
+ };
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_events.cpp b/khtml/ecma/kjs_events.cpp
new file mode 100644
index 000000000..8ebda7193
--- /dev/null
+++ b/khtml/ecma/kjs_events.cpp
@@ -0,0 +1,993 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "kjs_window.h"
+#include "kjs_events.h"
+#include "kjs_events.lut.h"
+#include "kjs_views.h"
+#include "kjs_proxy.h"
+#include "xml/dom_nodeimpl.h"
+#include "xml/dom_docimpl.h"
+#include "xml/dom2_eventsimpl.h"
+#include "rendering/render_object.h"
+#include "rendering/render_canvas.h"
+#include "xml/dom2_eventsimpl.h"
+#include "khtml_part.h"
+
+#include <kdebug.h>
+
+using namespace DOM;
+
+namespace KJS {
+
+// -------------------------------------------------------------------------
+
+JSEventListener::JSEventListener(Object _listener, ObjectImp *_compareListenerImp, const Object &_win, bool _html)
+ : listener( _listener ), compareListenerImp( _compareListenerImp ), html( _html ), win( _win )
+{
+ //fprintf(stderr,"JSEventListener::JSEventListener this=%p listener=%p\n",this,listener.imp());
+ if (compareListenerImp) {
+ static_cast<Window*>(win.imp())->jsEventListeners.insert(compareListenerImp, this);
+ }
+}
+
+JSEventListener::~JSEventListener()
+{
+ if (compareListenerImp) {
+ static_cast<Window*>(win.imp())->jsEventListeners.remove(compareListenerImp);
+ }
+ //fprintf(stderr,"JSEventListener::~JSEventListener this=%p listener=%p\n",this,listener.imp());
+}
+
+void JSEventListener::handleEvent(DOM::Event &evt)
+{
+#ifdef KJS_DEBUGGER
+ if (KJSDebugWin::debugWindow() && KJSDebugWin::debugWindow()->inSession())
+ return;
+#endif
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(static_cast<Window*>(win.imp())->part());
+ KJSProxy *proxy = 0L;
+ if (part)
+ proxy = part->jScript();
+
+ if (proxy && listener.isValid() && listener.implementsCall()) {
+ ref();
+
+ KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter());
+ ExecState *exec = interpreter->globalExec();
+
+ List args;
+ args.append(getDOMEvent(exec,evt));
+
+ // Set "this" to the event's current target
+ Object thisObj = Object::dynamicCast(getDOMNode(exec,evt.currentTarget()));
+ if ( !thisObj.isValid() ) {
+ // Window events (window.onload/window.onresize etc.) must have 'this' set to the window.
+ // DocumentImpl::defaultEventHandler sets currentTarget to 0 to mean 'window'.
+ thisObj = win;
+ }
+
+ Window *window = static_cast<Window*>(win.imp());
+ // Set the event we're handling in the Window object
+ window->setCurrentEvent( &evt );
+ // ... and in the interpreter
+ interpreter->setCurrentEvent( &evt );
+
+ KJSCPUGuard guard;
+ guard.start();
+ Value retval = listener.call(exec, thisObj, args);
+ guard.stop();
+
+ window->setCurrentEvent( 0 );
+ interpreter->setCurrentEvent( 0 );
+ if ( exec->hadException() )
+ exec->clearException();
+ else if (html)
+ {
+ QVariant ret = ValueToVariant(exec, retval);
+ if (ret.type() == QVariant::Bool && ret.toBool() == false)
+ evt.preventDefault();
+ }
+ window->afterScriptExecution();
+ deref();
+ }
+}
+
+DOM::DOMString JSEventListener::eventListenerType()
+{
+ if (html)
+ return "_khtml_HTMLEventListener";
+ else
+ return "_khtml_JSEventListener";
+}
+
+Object JSEventListener::listenerObj() const
+{
+ return listener;
+}
+
+JSLazyEventListener::JSLazyEventListener(const QString &_code, const QString &_name, const Object &_win, DOM::NodeImpl* _originalNode)
+ : JSEventListener(Object(), 0, _win, true),
+ code(_code), name(_name),
+ parsed(false)
+{
+ // We don't retain the original node, because we assume it
+ // will stay alive as long as this handler object is around
+ // and we need to avoid a reference cycle. If JS transfers
+ // this handler to another node, parseCode will be called and
+ // then originalNode is no longer needed.
+
+ originalNode = _originalNode;
+}
+
+JSLazyEventListener::~JSLazyEventListener()
+{
+ if (listener.isValid()) {
+ static_cast<Window*>(win.imp())->jsEventListeners.remove(listener.imp());
+ }
+}
+
+void JSLazyEventListener::handleEvent(DOM::Event &evt)
+{
+ parseCode();
+ if (listener.isValid()) {
+ JSEventListener::handleEvent(evt);
+ }
+}
+
+
+Object JSLazyEventListener::listenerObj() const
+{
+ parseCode();
+ return listener;
+}
+
+void JSLazyEventListener::parseCode() const
+{
+ if (!parsed) {
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(static_cast<Window*>(win.imp())->part());
+ KJSProxy *proxy = 0L;
+ if (part)
+ proxy = part->jScript();
+
+ if (proxy) {
+ KJS::ScriptInterpreter *interpreter = static_cast<KJS::ScriptInterpreter *>(proxy->interpreter());
+ ExecState *exec = interpreter->globalExec();
+
+ //KJS::Constructor constr(KJS::Global::current().get("Function").imp());
+ KJS::Object constr = interpreter->builtinFunction();
+ KJS::List args;
+
+ static KJS::String eventString("event");
+
+ args.append(eventString);
+ args.append(KJS::String(code));
+ listener = constr.construct(exec, args); // ### is globalExec ok ?
+
+ if (exec->hadException()) {
+ exec->clearException();
+
+ // failed to parse, so let's just make this listener a no-op
+ listener = Object();
+ } else if (!listener.inherits(&DeclaredFunctionImp::info)) {
+ listener = Object();// Error creating function
+ } else {
+ DeclaredFunctionImp *declFunc = static_cast<DeclaredFunctionImp*>(listener.imp());
+ declFunc->setName(Identifier(name));
+
+ if (originalNode)
+ {
+ // Add the event's home element to the scope
+ // (and the document, and the form - see KJS::HTMLElement::eventHandlerScope)
+ ScopeChain scope = listener.scope();
+
+ Object thisObj = Object::dynamicCast(getDOMNode(exec, originalNode));
+
+ if (thisObj.isValid()) {
+ static_cast<DOMNode*>(thisObj.imp())->pushEventHandlerScope(exec, scope);
+
+ listener.setScope(scope);
+ }
+ }
+ }
+ }
+
+ // no more need to keep the unparsed code around
+ code = QString();
+
+ if (listener.isValid()) {
+ static_cast<Window*>(win.imp())->jsEventListeners.insert(listener.imp(),
+ (KJS::JSEventListener *)(this));
+ }
+
+ parsed = true;
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMEvent::info = { "Event", 0, &DOMEventTable, 0 };
+/*
+@begin DOMEventTable 7
+ type DOMEvent::Type DontDelete|ReadOnly
+ target DOMEvent::Target DontDelete|ReadOnly
+ currentTarget DOMEvent::CurrentTarget DontDelete|ReadOnly
+ srcElement DOMEvent::SrcElement DontDelete|ReadOnly
+ eventPhase DOMEvent::EventPhase DontDelete|ReadOnly
+ bubbles DOMEvent::Bubbles DontDelete|ReadOnly
+ cancelable DOMEvent::Cancelable DontDelete|ReadOnly
+ timeStamp DOMEvent::TimeStamp DontDelete|ReadOnly
+ returnValue DOMEvent::ReturnValue DontDelete
+ cancelBubble DOMEvent::CancelBubble DontDelete
+@end
+@begin DOMEventProtoTable 3
+ stopPropagation DOMEvent::StopPropagation DontDelete|Function 0
+ preventDefault DOMEvent::PreventDefault DontDelete|Function 0
+ initEvent DOMEvent::InitEvent DontDelete|Function 3
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMEventProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMEventProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMEvent", DOMEventProto, DOMEventProtoFunc)
+
+DOMEvent::DOMEvent(ExecState *exec, DOM::Event e)
+ : DOMObject(DOMEventProto::self(exec)), event(e) { }
+
+DOMEvent::DOMEvent(const Object &proto, DOM::Event e)
+ : DOMObject(proto), event(e) { }
+
+DOMEvent::~DOMEvent()
+{
+ ScriptInterpreter::forgetDOMObject(event.handle());
+}
+
+Value DOMEvent::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug() << "KJS::DOMEvent::tryGet " << p.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMEvent,DOMObject>(exec, p, &DOMEventTable, this );
+}
+
+Value DOMEvent::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Type:
+ return String(event.type());
+ case Target:
+ case SrcElement: /*MSIE extension - "the object that fired the event"*/
+ return getDOMNode(exec,event.target());
+ case CurrentTarget:
+ return getDOMNode(exec,event.currentTarget());
+ case EventPhase:
+ return Number((unsigned int)event.eventPhase());
+ case Bubbles:
+ return Boolean(event.bubbles());
+ case Cancelable:
+ return Boolean(event.cancelable());
+ case TimeStamp:
+ return Number((long unsigned int)event.timeStamp()); // ### long long ?
+ case ReturnValue: // MSIE extension
+ // return false == cancel, so this returns the -opposite- of defaultPrevented
+ return Boolean(!event.handle()->defaultPrevented());
+ case CancelBubble: // MSIE extension
+ return Boolean(event.handle()->propagationStopped());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+Value DOMEvent::defaultValue(ExecState *exec, KJS::Type hint) const
+{
+ if (event.handle()->id() == EventImpl::ERROR_EVENT && !event.handle()->message().isNull()) {
+ return String(event.handle()->message());
+ }
+ else
+ return DOMObject::defaultValue(exec,hint);
+}
+
+void DOMEvent::tryPut(ExecState *exec, const Identifier &propertyName,
+ const Value& value, int attr)
+{
+ DOMObjectLookupPut<DOMEvent, DOMObject>(exec, propertyName, value, attr,
+ &DOMEventTable, this);
+}
+
+void DOMEvent::putValueProperty(ExecState *exec, int token, const Value& value, int)
+{
+ switch (token) {
+ case ReturnValue: // MSIE equivalent for "preventDefault" (but with a way to reset it)
+ // returnValue=false means "default action of the event on the source object is canceled",
+ // which means preventDefault(true). Hence the '!'.
+ event.handle()->preventDefault(!value.toBoolean(exec));
+ break;
+ case CancelBubble: // MSIE equivalent for "stopPropagation" (but with a way to reset it)
+ event.handle()->stopPropagation(value.toBoolean(exec));
+ break;
+ default:
+ break;
+ }
+}
+
+Value DOMEventProtoFunc::tryCall(ExecState *exec, Object & thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMEvent, thisObj );
+ DOM::Event event = static_cast<DOMEvent *>( thisObj.imp() )->toEvent();
+ switch (id) {
+ case DOMEvent::StopPropagation:
+ event.stopPropagation();
+ return Undefined();
+ case DOMEvent::PreventDefault:
+ event.preventDefault();
+ return Undefined();
+ case DOMEvent::InitEvent:
+ event.initEvent(args[0].toString(exec).string(),args[1].toBoolean(exec),args[2].toBoolean(exec));
+ return Undefined();
+ };
+ return Undefined();
+}
+
+Value getDOMEvent(ExecState *exec, DOM::Event e)
+{
+ DOM::EventImpl *ei = e.handle();
+ if (!ei)
+ return Null();
+ ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+ DOMObject *ret = interp->getDOMObject(ei);
+ if (!ret) {
+ if (ei->isTextInputEvent())
+ ret = new DOMTextEvent(exec, e);
+ else if (ei->isKeyboardEvent())
+ ret = new DOMKeyboardEvent(exec, e);
+ else if (ei->isMouseEvent())
+ ret = new DOMMouseEvent(exec, e);
+ else if (ei->isUIEvent())
+ ret = new DOMUIEvent(exec, e);
+ else if (ei->isMutationEvent())
+ ret = new DOMMutationEvent(exec, e);
+ else
+ ret = new DOMEvent(exec, e);
+
+ interp->putDOMObject(ei, ret);
+ }
+
+ return Value(ret);
+}
+
+DOM::Event toEvent(const Value& val)
+{
+ Object obj = Object::dynamicCast(val);
+ if (!obj.isValid() || !obj.inherits(&DOMEvent::info))
+ return DOM::Event();
+
+ const DOMEvent *dobj = static_cast<const DOMEvent*>(obj.imp());
+ return dobj->toEvent();
+}
+
+// -------------------------------------------------------------------------
+/*
+@begin EventConstantsTable 23
+ CAPTURING_PHASE DOM::Event::CAPTURING_PHASE DontDelete|ReadOnly
+ AT_TARGET DOM::Event::AT_TARGET DontDelete|ReadOnly
+ BUBBLING_PHASE DOM::Event::BUBBLING_PHASE DontDelete|ReadOnly
+# Reverse-engineered from Netscape
+ MOUSEDOWN 1 DontDelete|ReadOnly
+ MOUSEUP 2 DontDelete|ReadOnly
+ MOUSEOVER 4 DontDelete|ReadOnly
+ MOUSEOUT 8 DontDelete|ReadOnly
+ MOUSEMOVE 16 DontDelete|ReadOnly
+ MOUSEDRAG 32 DontDelete|ReadOnly
+ CLICK 64 DontDelete|ReadOnly
+ DBLCLICK 128 DontDelete|ReadOnly
+ KEYDOWN 256 DontDelete|ReadOnly
+ KEYUP 512 DontDelete|ReadOnly
+ KEYPRESS 1024 DontDelete|ReadOnly
+ DRAGDROP 2048 DontDelete|ReadOnly
+ FOCUS 4096 DontDelete|ReadOnly
+ BLUR 8192 DontDelete|ReadOnly
+ SELECT 16384 DontDelete|ReadOnly
+ CHANGE 32768 DontDelete|ReadOnly
+@end
+*/
+DEFINE_CONSTANT_TABLE(EventConstants)
+IMPLEMENT_CONSTANT_TABLE(EventConstants, "EventConstants")
+
+IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(EventConstructor, "EventConstructor", DOMEventProto, EventConstants)
+// -------------------------------------------------------------------------
+
+
+const ClassInfo EventExceptionConstructor::info = { "EventExceptionConstructor", 0, &EventExceptionConstructorTable, 0 };
+/*
+@begin EventExceptionConstructorTable 1
+ UNSPECIFIED_EVENT_TYPE_ERR DOM::EventException::UNSPECIFIED_EVENT_TYPE_ERR DontDelete|ReadOnly
+@end
+*/
+EventExceptionConstructor::EventExceptionConstructor(ExecState *exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype())
+{
+}
+
+Value EventExceptionConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<EventExceptionConstructor, DOMObject>(exec,p,&EventExceptionConstructorTable,this);
+}
+
+Value EventExceptionConstructor::getValueProperty(ExecState *, int token) const
+{
+ // We use the token as the value to return directly
+ return Number(token);
+}
+
+Value getEventExceptionConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<EventExceptionConstructor>(exec, "[[eventException.constructor]]");
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMUIEvent::info = { "UIEvent", &DOMEvent::info, &DOMUIEventTable, 0 };
+/*
+@begin DOMUIEventTable 7
+ view DOMUIEvent::View DontDelete|ReadOnly
+ detail DOMUIEvent::Detail DontDelete|ReadOnly
+ keyCode DOMUIEvent::KeyCode DontDelete|ReadOnly
+ charCode DOMUIEvent::CharCode DontDelete|ReadOnly
+ layerX DOMUIEvent::LayerX DontDelete|ReadOnly
+ layerY DOMUIEvent::LayerY DontDelete|ReadOnly
+ pageX DOMUIEvent::PageX DontDelete|ReadOnly
+ pageY DOMUIEvent::PageY DontDelete|ReadOnly
+ which DOMUIEvent::Which DontDelete|ReadOnly
+@end
+@begin DOMUIEventProtoTable 1
+ initUIEvent DOMUIEvent::InitUIEvent DontDelete|Function 5
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMUIEventProto, DOMEventProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMUIEventProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMUIEvent", DOMUIEventProto, DOMUIEventProtoFunc)
+
+DOMUIEvent::DOMUIEvent(ExecState *exec, DOM::UIEvent ue) :
+ DOMEvent(DOMUIEventProto::self(exec), ue) {}
+
+DOMUIEvent::DOMUIEvent(const Object &proto, DOM::UIEvent ue) :
+ DOMEvent(proto, ue) {}
+
+DOMUIEvent::~DOMUIEvent()
+{
+}
+
+Value DOMUIEvent::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMUIEvent,DOMEvent>(exec,p,&DOMUIEventTable,this);
+}
+
+Value DOMUIEvent::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case View:
+ return getDOMAbstractView(exec,static_cast<DOM::UIEvent>(event).view());
+ case Detail:
+ return Number(static_cast<DOM::UIEvent>(event).detail());
+ case KeyCode:
+ // IE-compatibility
+ return Number(static_cast<DOM::UIEvent>(event).keyCode());
+ case CharCode:
+ // IE-compatibility
+ return Number(static_cast<DOM::UIEvent>(event).charCode());
+ case LayerX:
+ // NS-compatibility
+ return Number(static_cast<DOM::UIEvent>(event).layerX());
+ case LayerY:
+ // NS-compatibility
+ return Number(static_cast<DOM::UIEvent>(event).layerY());
+ case PageX:
+ // NS-compatibility
+ return Number(static_cast<DOM::UIEvent>(event).pageX());
+ case PageY:
+ // NS-compatibility
+ return Number(static_cast<DOM::UIEvent>(event).pageY());
+ case Which:
+ // NS-compatibility
+ return Number(static_cast<DOM::UIEvent>(event).which());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMUIEvent::getValueProperty : " << token << endl;
+ return Undefined();
+ }
+}
+
+Value DOMUIEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMUIEvent, thisObj );
+ DOM::UIEvent uiEvent = static_cast<DOMUIEvent *>(thisObj.imp())->toUIEvent();
+ switch (id) {
+ case DOMUIEvent::InitUIEvent: {
+ DOM::AbstractView v = toAbstractView(args[3]);
+ static_cast<DOM::UIEvent>(uiEvent).initUIEvent(args[0].toString(exec).string(),
+ args[1].toBoolean(exec),
+ args[2].toBoolean(exec),
+ v,
+ args[4].toInteger(exec));
+ }
+ return Undefined();
+ }
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMMouseEvent::info = { "MouseEvent", &DOMUIEvent::info, &DOMMouseEventTable, 0 };
+
+/*
+@begin DOMMouseEventTable 2
+ screenX DOMMouseEvent::ScreenX DontDelete|ReadOnly
+ screenY DOMMouseEvent::ScreenY DontDelete|ReadOnly
+ clientX DOMMouseEvent::ClientX DontDelete|ReadOnly
+ x DOMMouseEvent::X DontDelete|ReadOnly
+ clientY DOMMouseEvent::ClientY DontDelete|ReadOnly
+ y DOMMouseEvent::Y DontDelete|ReadOnly
+ offsetX DOMMouseEvent::OffsetX DontDelete|ReadOnly
+ offsetY DOMMouseEvent::OffsetY DontDelete|ReadOnly
+ ctrlKey DOMMouseEvent::CtrlKey DontDelete|ReadOnly
+ shiftKey DOMMouseEvent::ShiftKey DontDelete|ReadOnly
+ altKey DOMMouseEvent::AltKey DontDelete|ReadOnly
+ metaKey DOMMouseEvent::MetaKey DontDelete|ReadOnly
+ button DOMMouseEvent::Button DontDelete|ReadOnly
+ relatedTarget DOMMouseEvent::RelatedTarget DontDelete|ReadOnly
+ fromElement DOMMouseEvent::FromElement DontDelete|ReadOnly
+ toElement DOMMouseEvent::ToElement DontDelete|ReadOnly
+@end
+@begin DOMMouseEventProtoTable 1
+ initMouseEvent DOMMouseEvent::InitMouseEvent DontDelete|Function 15
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMMouseEventProto, DOMUIEventProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMMouseEventProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMMouseEvent", DOMMouseEventProto, DOMMouseEventProtoFunc)
+
+DOMMouseEvent::DOMMouseEvent(ExecState *exec, DOM::MouseEvent me) :
+ DOMUIEvent(DOMMouseEventProto::self(exec), me) {}
+
+DOMMouseEvent::~DOMMouseEvent()
+{
+}
+
+Value DOMMouseEvent::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMMouseEvent::tryGet " << p.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMMouseEvent,DOMUIEvent>(exec,p,&DOMMouseEventTable,this);
+}
+
+Value DOMMouseEvent::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case ScreenX:
+ return Number(static_cast<DOM::MouseEvent>(event).screenX());
+ case ScreenY:
+ return Number(static_cast<DOM::MouseEvent>(event).screenY());
+ case ClientX:
+ case X:
+ return Number(static_cast<DOM::MouseEvent>(event).clientX());
+ case ClientY:
+ case Y:
+ return Number(static_cast<DOM::MouseEvent>(event).clientY());
+ case OffsetX:
+ case OffsetY: // MSIE extension
+ {
+ DOM::Node node = event.target();
+ khtml::RenderObject *rend = 0;
+ if (node.handle()) {
+ node.handle()->getDocument()->updateRendering();
+ rend = node.handle()->renderer();
+ }
+ int x = static_cast<DOM::MouseEvent>(event).clientX();
+ int y = static_cast<DOM::MouseEvent>(event).clientY();
+ if ( rend ) {
+ int xPos, yPos;
+ if ( rend->absolutePosition( xPos, yPos ) ) {
+ //kdDebug() << "DOMMouseEvent::getValueProperty rend=" << rend << " xPos=" << xPos << " yPos=" << yPos << endl;
+ x -= xPos;
+ y -= yPos;
+ }
+ if ( rend->canvas() ) {
+ int cYPos, cXPos;
+ rend->canvas()->absolutePosition( cXPos, cYPos, true );
+ x += cXPos;
+ y += cYPos;
+ }
+ }
+ return Number( token == OffsetX ? x : y );
+ }
+ case CtrlKey:
+ return Boolean(static_cast<DOM::MouseEvent>(event).ctrlKey());
+ case ShiftKey:
+ return Boolean(static_cast<DOM::MouseEvent>(event).shiftKey());
+ case AltKey:
+ return Boolean(static_cast<DOM::MouseEvent>(event).altKey());
+ case MetaKey:
+ return Boolean(static_cast<DOM::MouseEvent>(event).metaKey());
+ case Button:
+ {
+ if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat ) {
+ return Number(static_cast<DOM::MouseEvent>(event).button());
+ }
+ // Tricky. The DOM (and khtml) use 0 for LMB, 1 for MMB and 2 for RMB
+ // but MSIE uses 1=LMB, 2=RMB, 4=MMB, as a bitfield
+ int domButton = static_cast<DOM::MouseEvent>(event).button();
+ int button = domButton==0 ? 1 : domButton==1 ? 4 : domButton==2 ? 2 : 0;
+ return Number( (unsigned int)button );
+ }
+ case ToElement:
+ // MSIE extension - "the object toward which the user is moving the mouse pointer"
+ if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT)
+ return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).relatedTarget());
+ return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).target());
+ case FromElement:
+ // MSIE extension - "object from which activation
+ // or the mouse pointer is exiting during the event" (huh?)
+ if (event.handle()->id() == DOM::EventImpl::MOUSEOUT_EVENT)
+ return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).target());
+ /* fall through */
+ case RelatedTarget:
+ return getDOMNode(exec,static_cast<DOM::MouseEvent>(event).relatedTarget());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMMouseEvent::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+Value DOMMouseEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMMouseEvent, thisObj );
+ DOM::MouseEvent mouseEvent = static_cast<DOMMouseEvent *>(thisObj.imp())->toMouseEvent();
+ switch (id) {
+ case DOMMouseEvent::InitMouseEvent:
+ mouseEvent.initMouseEvent(args[0].toString(exec).string(), // typeArg
+ args[1].toBoolean(exec), // canBubbleArg
+ args[2].toBoolean(exec), // cancelableArg
+ toAbstractView(args[3]), // viewArg
+ args[4].toInteger(exec), // detailArg
+ args[5].toInteger(exec), // screenXArg
+ args[6].toInteger(exec), // screenYArg
+ args[7].toInteger(exec), // clientXArg
+ args[8].toInteger(exec), // clientYArg
+ args[9].toBoolean(exec), // ctrlKeyArg
+ args[10].toBoolean(exec), // altKeyArg
+ args[11].toBoolean(exec), // shiftKeyArg
+ args[12].toBoolean(exec), // metaKeyArg
+ args[13].toInteger(exec), // buttonArg
+ toNode(args[14])); // relatedTargetArg
+ return Undefined();
+ }
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMKeyEventBase::info = { "KeyEventBase", &DOMUIEvent::info, &DOMKeyEventBaseTable, 0 };
+
+/*
+@begin DOMKeyEventBaseTable 5
+ keyVal DOMKeyEventBase::Key DontDelete|ReadOnly
+ virtKeyVal DOMKeyEventBase::VirtKey DontDelete|ReadOnly
+ ctrlKey DOMKeyEventBase::CtrlKey DontDelete|ReadOnly
+ altKey DOMKeyEventBase::AltKey DontDelete|ReadOnly
+ shiftKey DOMKeyEventBase::ShiftKey DontDelete|ReadOnly
+ altKey DOMKeyEventBase::AltKey DontDelete|ReadOnly
+@end
+*/
+
+DOMKeyEventBase::DOMKeyEventBase(const Object &proto, DOM::TextEvent ke) :
+ DOMUIEvent(proto, ke) {}
+
+DOMKeyEventBase::~DOMKeyEventBase()
+{}
+
+Value DOMKeyEventBase::tryGet(ExecState *exec,const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMKeyEventBase::tryGet " << p.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMKeyEventBase,DOMUIEvent>(exec,p,&DOMKeyEventBaseTable,this);
+}
+
+Value DOMKeyEventBase::getValueProperty(ExecState *, int token) const
+{
+ DOM::KeyEventBaseImpl* tevent = impl();
+ switch (token) {
+ case Key:
+ return Number(tevent->keyVal());
+ case VirtKey:
+ return Number(tevent->virtKeyVal());
+ // these modifier attributes actually belong into a KeyboardEvent interface,
+ // but we want them on "keypress" as well.
+ case CtrlKey:
+ return Boolean(tevent->ctrlKey());
+ case ShiftKey:
+ return Boolean(tevent->shiftKey());
+ case AltKey:
+ return Boolean(tevent->altKey());
+ case MetaKey:
+ return Boolean(tevent->metaKey());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token << endl;
+ return KJS::Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+const ClassInfo DOMTextEvent::info = { "TextEvent", &DOMKeyEventBase::info, &DOMTextEventTable, 0 };
+
+/*
+@begin DOMTextEventTable 1
+ data DOMTextEvent::Data DontDelete|ReadOnly
+@end
+@begin DOMTextEventProtoTable 1
+ initTextEvent DOMTextEvent::InitTextEvent DontDelete|Function 5
+ # Missing: initTextEventNS
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMTextEventProto, DOMUIEventProto) //Note: no proto in KeyBase
+IMPLEMENT_PROTOFUNC_DOM(DOMTextEventProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMTextEvent", DOMTextEventProto, DOMTextEventProtoFunc)
+
+DOMTextEvent::DOMTextEvent(ExecState *exec, DOM::TextEvent ke) :
+ DOMKeyEventBase(DOMTextEventProto::self(exec), ke) {}
+
+DOMTextEvent::~DOMTextEvent()
+{
+}
+
+Value DOMTextEvent::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMTextEvent::tryGet " << p.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMTextEvent,DOMKeyEventBase>(exec,p,&DOMTextEventTable,this);
+}
+
+Value DOMTextEvent::getValueProperty(ExecState *, int token) const
+{
+ DOM::TextEventImpl* tevent = impl();
+ switch (token) {
+ case Data:
+ return String(tevent->data());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMTextEvent::getValueProperty : " << token << endl;
+ return KJS::Undefined();
+ }
+}
+
+Value DOMTextEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMTextEvent, thisObj );
+ DOM::TextEventImpl* keyEvent = static_cast<DOMTextEvent *>(thisObj.imp())->impl();
+ switch (id) {
+ case DOMTextEvent::InitTextEvent:
+ keyEvent->initTextEvent(args[0].toString(exec).string(), // typeArg
+ args[1].toBoolean(exec), // canBubbleArg
+ args[2].toBoolean(exec), // cancelableArg
+ toAbstractView(args[3]), // viewArg
+ args[4].toString(exec).string()); // dataArg
+
+ return Undefined();
+ }
+ return Undefined();
+}
+// -------------------------------------------------------------------------
+const ClassInfo DOMKeyboardEvent::info = { "KeyboardEvent", &DOMKeyEventBase::info, &DOMKeyboardEventTable, 0 };
+
+/*
+@begin DOMKeyboardEventTable 2
+ keyIdentifier DOMKeyboardEvent::KeyIdentifier DontDelete|ReadOnly
+ keyLocation DOMKeyboardEvent::KeyLocation DontDelete|ReadOnly
+@end
+@begin DOMKeyboardEventProtoTable 2
+ initKeyboardEvent DOMKeyboardEvent::InitKeyboardEvent DontDelete|Function 7
+ getModifierState DOMKeyboardEvent::GetModifierState DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMKeyboardEventProto, DOMUIEventProto) //Note: no proto in KeyBase
+IMPLEMENT_PROTOFUNC_DOM(DOMKeyboardEventProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMKeyboardEvent", DOMKeyboardEventProto, DOMKeyboardEventProtoFunc)
+
+DOMKeyboardEvent::DOMKeyboardEvent(ExecState *exec, DOM::TextEvent ke) :
+ DOMKeyEventBase(DOMKeyboardEventProto::self(exec), ke) {}
+
+DOMKeyboardEvent::~DOMKeyboardEvent()
+{
+}
+
+Value DOMKeyboardEvent::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "DOMKeyboardEvent::tryGet " << p.qstring() << endl;
+#endif
+ return DOMObjectLookupGetValue<DOMKeyboardEvent,DOMKeyEventBase>(exec,p,&DOMKeyboardEventTable,this);
+}
+
+Value DOMKeyboardEvent::getValueProperty(ExecState *, int token) const
+{
+ DOM::KeyboardEventImpl* tevent = impl();
+ switch (token) {
+ case KeyIdentifier:
+ return String(tevent->keyIdentifier());
+ case KeyLocation:
+ return Number(tevent->keyLocation());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMKeyboardEvent::getValueProperty : " << token << endl;
+ return KJS::Undefined();
+ }
+}
+
+Value DOMKeyboardEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMKeyboardEvent, thisObj );
+ DOM::KeyboardEventImpl* keyEvent = static_cast<DOMKeyboardEvent *>(thisObj.imp())->impl();
+ switch (id) {
+ case DOMKeyboardEvent::InitKeyboardEvent:
+ keyEvent->initKeyboardEvent(args[0].toString(exec).string(), // typeArg
+ args[1].toBoolean(exec), // canBubbleArg
+ args[2].toBoolean(exec), // cancelableArg
+ toAbstractView(args[3]), // viewArg
+ args[4].toString(exec).string(), // keyIdentifierArg
+ args[5].toInteger(exec), // keyLocationArg
+ args[6].toString(exec).string()); //modifiersList
+ break;
+ case DOMKeyboardEvent::GetModifierState:
+ return Boolean(keyEvent->getModifierState(args[0].toString(exec).string()));
+ }
+ return Undefined();
+}
+
+// -------------------------------------------------------------------------
+const ClassInfo KeyboardEventConstructor::info = { "KeyboardEventConstructor", 0, &KeyboardEventConstructorTable, 0 };
+/*
+@begin KeyboardEventConstructorTable 4
+ DOM_KEY_LOCATION_STANDARD DOM::KeyboardEventImpl::DOM_KEY_LOCATION_STANDARD DontDelete|ReadOnly
+ DOM_KEY_LOCATION_LEFT DOM::KeyboardEventImpl::DOM_KEY_LOCATION_LEFT DontDelete|ReadOnly
+ DOM_KEY_LOCATION_RIGHT DOM::KeyboardEventImpl::DOM_KEY_LOCATION_RIGHT DontDelete|ReadOnly
+ DOM_KEY_LOCATION_NUMPAD DOM::KeyboardEventImpl::DOM_KEY_LOCATION_NUMPAD DontDelete|ReadOnly
+@end
+*/
+KeyboardEventConstructor::KeyboardEventConstructor(ExecState* exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype())
+{}
+
+Value KeyboardEventConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<KeyboardEventConstructor,DOMObject>(exec,p,&KeyboardEventConstructorTable,this);
+}
+
+Value KeyboardEventConstructor::getValueProperty(ExecState *, int token) const
+{
+ // We use the token as the value to return directly
+ return Number(token);
+}
+
+Value getKeyboardEventConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<KeyboardEventConstructor>(exec, "[[keyboardEvent.constructor]]");
+}
+
+
+// -------------------------------------------------------------------------
+const ClassInfo MutationEventConstructor::info = { "MutationEventConstructor", 0, &MutationEventConstructorTable, 0 };
+/*
+@begin MutationEventConstructorTable 3
+ MODIFICATION DOM::MutationEvent::MODIFICATION DontDelete|ReadOnly
+ ADDITION DOM::MutationEvent::ADDITION DontDelete|ReadOnly
+ REMOVAL DOM::MutationEvent::REMOVAL DontDelete|ReadOnly
+@end
+*/
+MutationEventConstructor::MutationEventConstructor(ExecState* exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype())
+{
+}
+
+Value MutationEventConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<MutationEventConstructor,DOMObject>(exec,p,&MutationEventConstructorTable,this);
+}
+
+Value MutationEventConstructor::getValueProperty(ExecState *, int token) const
+{
+ // We use the token as the value to return directly
+ return Number(token);
+}
+
+Value getMutationEventConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<MutationEventConstructor>(exec, "[[mutationEvent.constructor]]");
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMMutationEvent::info = { "MutationEvent", &DOMEvent::info, &DOMMutationEventTable, 0 };
+/*
+@begin DOMMutationEventTable 5
+ relatedNode DOMMutationEvent::RelatedNode DontDelete|ReadOnly
+ prevValue DOMMutationEvent::PrevValue DontDelete|ReadOnly
+ newValue DOMMutationEvent::NewValue DontDelete|ReadOnly
+ attrName DOMMutationEvent::AttrName DontDelete|ReadOnly
+ attrChange DOMMutationEvent::AttrChange DontDelete|ReadOnly
+@end
+@begin DOMMutationEventProtoTable 1
+ initMutationEvent DOMMutationEvent::InitMutationEvent DontDelete|Function 8
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMMutationEventProto, DOMEventProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMMutationEventProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMMutationEvent", DOMMutationEventProto, DOMMutationEventProtoFunc)
+
+DOMMutationEvent::DOMMutationEvent(ExecState *exec, DOM::MutationEvent me) :
+ DOMEvent(DOMMutationEventProto::self(exec), me) {}
+
+DOMMutationEvent::~DOMMutationEvent()
+{
+}
+
+Value DOMMutationEvent::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMMutationEvent,DOMEvent>(exec,p,&DOMMutationEventTable,this);
+}
+
+Value DOMMutationEvent::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case RelatedNode:
+ return getDOMNode(exec,static_cast<DOM::MutationEvent>(event).relatedNode());
+ case PrevValue:
+ return String(static_cast<DOM::MutationEvent>(event).prevValue());
+ case NewValue:
+ return String(static_cast<DOM::MutationEvent>(event).newValue());
+ case AttrName:
+ return String(static_cast<DOM::MutationEvent>(event).attrName());
+ case AttrChange:
+ return Number((unsigned int)static_cast<DOM::MutationEvent>(event).attrChange());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMMutationEvent::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+Value DOMMutationEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMMutationEvent, thisObj );
+ DOM::MutationEvent mutationEvent = static_cast<DOMMutationEvent *>(thisObj.imp())->toMutationEvent();
+ switch (id) {
+ case DOMMutationEvent::InitMutationEvent:
+ mutationEvent.initMutationEvent(args[0].toString(exec).string(), // typeArg,
+ args[1].toBoolean(exec), // canBubbleArg
+ args[2].toBoolean(exec), // cancelableArg
+ toNode(args[3]), // relatedNodeArg
+ args[4].toString(exec).string(), // prevValueArg
+ args[5].toString(exec).string(), // newValueArg
+ args[6].toString(exec).string(), // attrNameArg
+ args[7].toInteger(exec)); // attrChangeArg
+ return Undefined();
+ }
+ return Undefined();
+}
+
+} //namespace KJS
diff --git a/khtml/ecma/kjs_events.h b/khtml/ecma/kjs_events.h
new file mode 100644
index 000000000..9fedfe594
--- /dev/null
+++ b/khtml/ecma/kjs_events.h
@@ -0,0 +1,250 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_EVENTS_H_
+#define _KJS_EVENTS_H_
+
+#include "ecma/kjs_dom.h"
+#include "dom/dom2_events.h"
+#include "dom/dom_misc.h"
+#include "xml/dom2_eventsimpl.h"
+
+namespace KJS {
+
+ class Window;
+
+ class JSEventListener : public DOM::EventListener {
+ public:
+ /**
+ * @param _listener the function object, that will be called when the event is emitted
+ * @param _compareListenerImp Compare Listener implementation.
+ * @param _win Window object, for memory management and caching.
+ * @param _html \c true if it is HTML.
+ * Never create a JSEventListener directly, use Window::getJSEventListener.
+ */
+ JSEventListener(Object _listener, ObjectImp *_compareListenerImp, const Object &_win, bool _html = false);
+ virtual ~JSEventListener();
+ virtual void handleEvent(DOM::Event &evt);
+ virtual DOM::DOMString eventListenerType();
+ // Return the KJS function object executed when this event is emitted
+ virtual Object listenerObj() const;
+ ObjectImp *listenerObjImp() const { return listenerObj().imp(); }
+ // for Window::clear(). This is a bad hack though. The JSEventListener might not get deleted
+ // if it was added to a DOM node in another frame (#61467). But calling removeEventListener on
+ // all nodes we're listening to is quite difficult.
+ void clear() { listener = Object(); }
+ bool isHTMLEventListener() const { return html; }
+
+ protected:
+ mutable Object listener;
+ // Storing a different ObjectImp ptr is needed to support addEventListener(.. [Object] ..) calls
+ // In the real-life case (where a 'function' is passed to addEventListener) we can directly call
+ // the 'listener' object and can cache the 'listener.imp()'. If the event listener should be removed
+ // the implementation will call removeEventListener(.. [Function] ..), and we can lookup the event
+ // listener by the passed function's imp() ptr.
+ // In the only dom-approved way (passing an Object to add/removeEventListener), the 'listener'
+ // variable stores the function object 'passedListener.handleEvent'. But we need to cache
+ // the imp() ptr of the 'passedListener' function _object_, as the implementation will
+ // call removeEventListener(.. [Object ..] on removal, and now we can successfully lookup
+ // the correct event listener, as well as the 'listener.handleEvent' function, we need to call.
+ mutable ObjectImp *compareListenerImp;
+ bool html;
+ Object win;
+ };
+
+ class JSLazyEventListener : public JSEventListener {
+ public:
+ JSLazyEventListener(const QString &_code, const QString &_name, const Object &_win, DOM::NodeImpl* node);
+ ~JSLazyEventListener();
+ virtual void handleEvent(DOM::Event &evt);
+ Object listenerObj() const;
+ private:
+ void parseCode() const;
+
+ mutable QString code;
+ mutable QString name;
+ mutable bool parsed;
+ DOM::NodeImpl *originalNode;
+ };
+
+ // Constructor for Event - currently only used for some global vars
+ DEFINE_PSEUDO_CONSTRUCTOR(EventConstructor)
+
+ class DOMEvent : public DOMObject {
+ public:
+ // Build a DOMEvent
+ DOMEvent(ExecState *exec, DOM::Event e);
+ // Constructor for inherited classes
+ DOMEvent(const Object &proto, DOM::Event e);
+ ~DOMEvent();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName,
+ const Value& value, int attr = None);
+ virtual Value defaultValue(ExecState *exec, KJS::Type hint) const;
+ void putValueProperty(ExecState *exec, int token, const Value& value, int);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Type, Target, CurrentTarget, EventPhase, Bubbles,
+ Cancelable, TimeStamp, StopPropagation, PreventDefault, InitEvent,
+ // MS IE equivalents
+ SrcElement, ReturnValue, CancelBubble };
+ DOM::Event toEvent() const { return event; }
+ protected:
+ DOM::Event event;
+ };
+
+ Value getDOMEvent(ExecState *exec, DOM::Event e);
+
+ /**
+ * Convert an object to an Event. Returns a null Event if not possible.
+ */
+ DOM::Event toEvent(const Value&);
+
+ // Constructor object EventException
+ class EventExceptionConstructor : public DOMObject {
+ public:
+ EventExceptionConstructor(ExecState *);
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ Value getEventExceptionConstructor(ExecState *exec);
+
+ class DOMUIEvent : public DOMEvent {
+ public:
+ // Build a DOMUIEvent
+ DOMUIEvent(ExecState *exec, DOM::UIEvent ue);
+ // Constructor for inherited classes
+ DOMUIEvent(const Object &proto, DOM::UIEvent ue);
+ ~DOMUIEvent();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { View, Detail, KeyCode, CharCode, LayerX, LayerY, PageX, PageY, Which, InitUIEvent };
+ DOM::UIEvent toUIEvent() const { return static_cast<DOM::UIEvent>(event); }
+ };
+
+ class DOMMouseEvent : public DOMUIEvent {
+ public:
+ DOMMouseEvent(ExecState *exec, DOM::MouseEvent me);
+ ~DOMMouseEvent();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { ScreenX, ScreenY, ClientX, X, ClientY, Y, OffsetX, OffsetY,
+ CtrlKey, ShiftKey, AltKey,
+ MetaKey, Button, RelatedTarget, FromElement, ToElement,
+ InitMouseEvent
+ };
+ DOM::MouseEvent toMouseEvent() const { return static_cast<DOM::MouseEvent>(event); }
+ };
+
+ class DOMKeyEventBase : public DOMUIEvent {
+ public:
+ DOMKeyEventBase(const Object &proto, DOM::TextEvent ke);
+ ~DOMKeyEventBase();
+
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Key, VirtKey, CtrlKey, ShiftKey, AltKey, MetaKey };
+ DOM::KeyEventBaseImpl* impl() const { return static_cast<DOM::KeyEventBaseImpl*>(event.handle()); }
+ };
+
+ class DOMTextEvent : public DOMKeyEventBase {
+ public:
+ DOMTextEvent(ExecState *exec, DOM::TextEvent ke);
+ ~DOMTextEvent();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum {Data, InitTextEvent};
+ DOM::TextEventImpl* impl() const { return static_cast<DOM::TextEventImpl*>(event.handle()); }
+ };
+
+ class DOMKeyboardEvent : public DOMKeyEventBase {
+ public:
+ DOMKeyboardEvent(ExecState *exec, DOM::TextEvent ke);
+ ~DOMKeyboardEvent();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum {KeyIdentifier, KeyLocation, GetModifierState, InitKeyboardEvent};
+ DOM::KeyboardEventImpl* impl() const { return static_cast<DOM::KeyboardEventImpl*>(event.handle()); }
+ };
+
+ // Constructor object KeyboardEvent
+ class KeyboardEventConstructor : public DOMObject {
+ public:
+ KeyboardEventConstructor(ExecState *);
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ Value getKeyboardEventConstructor(ExecState *exec);
+
+ // Constructor object MutationEvent
+ class MutationEventConstructor : public DOMObject {
+ public:
+ MutationEventConstructor(ExecState *);
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ Value getMutationEventConstructor(ExecState *exec);
+
+ class DOMMutationEvent : public DOMEvent {
+ public:
+ DOMMutationEvent(ExecState *exec, DOM::MutationEvent me);
+ ~DOMMutationEvent();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { AttrChange, RelatedNode, AttrName, PrevValue, NewValue,
+ InitMutationEvent };
+ DOM::MutationEvent toMutationEvent() const { return static_cast<DOM::MutationEvent>(event); }
+ };
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_html.cpp b/khtml/ecma/kjs_html.cpp
new file mode 100644
index 000000000..94f89079f
--- /dev/null
+++ b/khtml/ecma/kjs_html.cpp
@@ -0,0 +1,3946 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001-2003 David Faure (faure@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "misc/loader.h"
+#include "dom/html_block.h"
+#include "dom/html_head.h"
+#include "dom/html_image.h"
+#include "dom/html_inline.h"
+#include "dom/html_list.h"
+#include "dom/html_table.h"
+#include "dom/html_object.h"
+#include "dom/dom_exception.h"
+
+// ### HACK
+#include "html/html_baseimpl.h"
+#include "html/html_documentimpl.h"
+#include "html/html_formimpl.h"
+#include "html/html_imageimpl.h"
+#include "html/html_miscimpl.h"
+#include "xml/dom2_eventsimpl.h"
+
+#include <kparts/browserextension.h>
+
+#include "khtml_part.h"
+#include "khtmlview.h"
+
+#include "ecma/kjs_css.h"
+#include "ecma/kjs_events.h"
+#include "ecma/kjs_html.h"
+#include "ecma/kjs_window.h"
+#include "kjs_html.lut.h"
+
+#include "misc/htmltags.h"
+#include "misc/htmlattrs.h"
+#include "rendering/render_object.h"
+#include "rendering/render_canvas.h"
+#include "rendering/render_frames.h"
+#include "rendering/render_layer.h"
+
+#include "kmessagebox.h"
+#include <kstringhandler.h>
+#include <klocale.h>
+
+#include <kdebug.h>
+
+namespace KJS {
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLDocumentProto, DOMDocumentProto)
+IMPLEMENT_PROTOFUNC_DOM(HTMLDocFunction)
+KJS_IMPLEMENT_PROTOTYPE("HTMLDocument", HTMLDocumentProto, HTMLDocFunction)
+
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDocumentPseudoCtor, "HTMLDocument", HTMLDocumentProto)
+
+/* Source for HTMLDocumentProtoTable.
+@begin HTMLDocumentProtoTable 11
+ clear HTMLDocument::Clear DontDelete|Function 0
+ open HTMLDocument::Open DontDelete|Function 0
+ close HTMLDocument::Close DontDelete|Function 0
+ write HTMLDocument::Write DontDelete|Function 1
+ writeln HTMLDocument::WriteLn DontDelete|Function 1
+ getElementsByName HTMLDocument::GetElementsByName DontDelete|Function 1
+ getSelection HTMLDocument::GetSelection DontDelete|Function 1
+ captureEvents HTMLDocument::CaptureEvents DontDelete|Function 0
+ releaseEvents HTMLDocument::ReleaseEvents DontDelete|Function 0
+@end
+*/
+
+
+Value KJS::HTMLDocFunction::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( HTMLDocument, thisObj );
+
+ DOM::HTMLDocument doc = static_cast<KJS::HTMLDocument *>(thisObj.imp())->toDocument();
+
+ switch (id) {
+ case HTMLDocument::Clear: // even IE doesn't support that one...
+ //doc.clear(); // TODO
+ return Undefined();
+ case HTMLDocument::Open:
+ if (args.size() >= 3) // IE extension for document.open: it means window.open if it has 3 args or more
+ {
+ KHTMLView *view = static_cast<DOM::DocumentImpl*>(doc.handle())->view();
+ if ( view && view->part() ) {
+ Window* win = Window::retrieveWindow(view->part());
+ if( win ) {
+ win->openWindow(exec, args);
+ }
+ }
+ }
+
+ doc.open();
+ return Undefined();
+ case HTMLDocument::Close:
+ // see khtmltests/ecma/tokenizer-script-recursion.html
+ doc.close();
+ return Undefined();
+ case HTMLDocument::Write:
+ case HTMLDocument::WriteLn: {
+ // DOM only specifies single string argument, but NS & IE allow multiple
+ // or no arguments
+ UString str = "";
+ for (int i = 0; i < args.size(); i++)
+ str += args[i].toString(exec);
+ if (id == HTMLDocument::WriteLn)
+ str += "\n";
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "document.write: " << str.string().string() << endl;
+#endif
+ doc.write(str.string());
+ return Undefined();
+ }
+ case HTMLDocument::GetElementsByName:
+ return getDOMNodeList(exec,doc.getElementsByName(args[0].toString(exec).string()));
+ case HTMLDocument::GetSelection: {
+ // NS4 and Mozilla specific. IE uses document.selection.createRange()
+ // http://docs.sun.com/source/816-6408-10/document.htm#1195981
+ KHTMLView *view = static_cast<DOM::DocumentImpl*>(doc.handle())->view();
+ if ( view && view->part() )
+ return String(view->part()->selectedText());
+ else
+ return Undefined();
+ }
+ case HTMLDocument::CaptureEvents:
+ case HTMLDocument::ReleaseEvents:
+ // Do nothing for now. These are NS-specific legacy calls.
+ break;
+ }
+
+ return Undefined();
+}
+
+const ClassInfo KJS::HTMLDocument::info =
+ { "HTMLDocument", &DOMDocument::info, &HTMLDocumentTable, 0 };
+/* Source for HTMLDocumentTable.
+@begin HTMLDocumentTable 31
+ title HTMLDocument::Title DontDelete
+ referrer HTMLDocument::Referrer DontDelete|ReadOnly
+ domain HTMLDocument::Domain DontDelete
+ URL HTMLDocument::URL DontDelete|ReadOnly
+ body HTMLDocument::Body DontDelete
+ location HTMLDocument::Location DontDelete
+ cookie HTMLDocument::Cookie DontDelete
+ images HTMLDocument::Images DontDelete|ReadOnly
+ applets HTMLDocument::Applets DontDelete|ReadOnly
+ links HTMLDocument::Links DontDelete|ReadOnly
+ forms HTMLDocument::Forms DontDelete|ReadOnly
+ anchors HTMLDocument::Anchors DontDelete|ReadOnly
+ scripts HTMLDocument::Scripts DontDelete|ReadOnly
+ all HTMLDocument::All DontDelete|ReadOnly
+ bgColor HTMLDocument::BgColor DontDelete
+ fgColor HTMLDocument::FgColor DontDelete
+ alinkColor HTMLDocument::AlinkColor DontDelete
+ linkColor HTMLDocument::LinkColor DontDelete
+ vlinkColor HTMLDocument::VlinkColor DontDelete
+ lastModified HTMLDocument::LastModified DontDelete|ReadOnly
+ height HTMLDocument::Height DontDelete|ReadOnly
+ width HTMLDocument::Width DontDelete|ReadOnly
+ dir HTMLDocument::Dir DontDelete
+ compatMode HTMLDocument::CompatMode DontDelete|ReadOnly
+#IE extension
+ frames HTMLDocument::Frames DontDelete|ReadOnly
+#NS4 extension
+ layers HTMLDocument::Layers DontDelete|ReadOnly
+#potentially obsolete array properties
+# plugins
+# tags
+#potentially obsolete properties
+# embeds
+# ids
+@end
+*/
+
+KJS::HTMLDocument::HTMLDocument(ExecState *exec, const DOM::HTMLDocument& d)
+ : DOMDocument(HTMLDocumentProto::self(exec), d) { }
+
+bool KJS::HTMLDocument::hasProperty(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ //kdDebug(6070) << "KJS::HTMLDocument::hasProperty " << p.qstring() << endl;
+#endif
+ DOM::HTMLDocument doc = static_cast<DOM::HTMLDocument>(node);
+ DOM::DocumentImpl* docImpl = static_cast<DOM::DocumentImpl*>(doc.handle());
+ KHTMLView *view = docImpl->view();
+ Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
+ if ( !win || !win->isSafeScript(exec) )
+ return false;
+
+
+ if ( docImpl->underDocNamedCache().contains( p.qstring() ) )
+ return true;
+
+ if ( view && view->part() )
+ {
+ KHTMLPart *kp = view->part()->findFrame( p.qstring() );
+ if (kp)
+ return true;
+ }
+
+ return DOMDocument::hasProperty(exec, p);
+}
+
+Value KJS::HTMLDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLDocument::tryGet " << propertyName.qstring() << endl;
+#endif
+
+ DOM::HTMLDocument doc = static_cast<DOM::HTMLDocument>(node);
+ DOM::DocumentImpl* docImpl = static_cast<DOM::DocumentImpl*>(doc.handle());
+ KHTMLView *view = docImpl->view();
+
+ Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
+ if ( !win || !win->isSafeScript(exec) )
+ return Undefined();
+
+ //Check for images, forms, objects, etc.
+ ElementMappingCache::ItemInfo* info = docImpl->underDocNamedCache().get(propertyName.qstring());
+ if (info) {
+ //May be a false positive, but we can try to avoid doing it the hard way in
+ //simpler cases. The trickiness here is that the cache is kept under both
+ //name and id, but we sometimes ignore id for IE compat
+ DOM::DOMString propertyDOMString = propertyName.string();
+
+ if (info->nd && DOM::HTMLMappedNameCollectionImpl::matchesName(info->nd,
+ HTMLCollectionImpl::DOCUMENT_NAMED_ITEMS, propertyDOMString)) {
+ return getDOMNode(exec, info->nd);
+ } else {
+ //Can't tell it just like that, so better go through collection and count stuff. This is the slow path...
+ DOM::HTMLMappedNameCollection coll(docImpl, HTMLCollectionImpl::DOCUMENT_NAMED_ITEMS, propertyDOMString);
+
+ if (coll.length() == 1) {
+ DOM::Node node = coll.firstItem();
+ return getDOMNode(exec, node);
+ } else if (coll.length() > 1) {
+ return getHTMLCollection(exec, coll);
+ }
+ }
+ }
+
+ // Check for frames/iframes with name==propertyName
+ if ( view && view->part() )
+ {
+ // ###### TODO return a collection in case several frames have the same name
+ // (IE does that). Hard to do with findFrame :}
+ KHTMLPart *kp = view->part()->findFrame( propertyName.qstring() );
+ if (kp)
+ return Window::retrieve(kp);
+ }
+
+ const HashEntry* entry = Lookup::findEntry(&HTMLDocumentTable, propertyName);
+ if (entry) {
+ switch (entry->value) {
+ case Title:
+ return String(doc.title());
+ case Referrer:
+ return String(doc.referrer());
+ case Domain:
+ return String(doc.domain());
+ case URL:
+ return String(doc.URL());
+ case Body:
+ return getDOMNode(exec,doc.body());
+ case Location:
+ if (win)
+ return Value(win->location());
+ else
+ return Undefined();
+ case Cookie:
+ return String(doc.cookie());
+ case Images:
+ return getHTMLCollection(exec,doc.images());
+ case Applets:
+ return getHTMLCollection(exec,doc.applets());
+ case Links:
+ return getHTMLCollection(exec,doc.links());
+ case Forms:
+ return getHTMLCollection(exec,doc.forms());
+ case Layers:
+ // ### Should not be hidden when we emulate Netscape4
+ return getHTMLCollection(exec,doc.layers(), true);
+ case Anchors:
+ return getHTMLCollection(exec,doc.anchors());
+ case Scripts:
+ return getHTMLCollection(exec,doc.scripts());
+ case All:
+ // Disable document.all when we try to be Netscape-compatible
+ if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat )
+ return Undefined();
+ else
+ if ( exec->interpreter()->compatMode() == Interpreter::IECompat )
+ return getHTMLCollection(exec,doc.all());
+ else // enabled but hidden
+ return getHTMLCollection(exec,doc.all(), true);
+ case CompatMode:
+ return String(static_cast<HTMLDocumentImpl *>(doc.handle())->parseMode()
+ == DocumentImpl::Compat ? "BackCompat" : "CSS1Compat");
+ }
+ }
+ // Look for overrides
+ ValueImp * val = ObjectImp::getDirect(propertyName);
+ if (val)
+ return Value(val);
+
+ DOM::HTMLBodyElement body = doc.body();
+ if (entry) {
+ switch (entry->value) {
+ case BgColor:
+ return String(body.bgColor());
+ case FgColor:
+ return String(body.text());
+ case AlinkColor:
+ return String(body.aLink());
+ case LinkColor:
+ return String(body.link());
+ case VlinkColor:
+ return String(body.vLink());
+ case LastModified:
+ return String(doc.lastModified());
+ case Height: // NS-only, not available in IE
+ return Number(view ? view->contentsHeight() : 0);
+ case Width: // NS-only, not available in IE
+ return Number(view ? view->contentsWidth() : 0);
+ case Dir:
+ return String(body.dir());
+ case Frames:
+ if ( win )
+ return Value(win->frames(exec));
+ else
+ return Undefined();
+ }
+ }
+ return DOMDocument::tryGet(exec, propertyName);
+}
+
+void KJS::HTMLDocument::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLDocument::tryPut " << propertyName.qstring() << endl;
+#endif
+ KHTMLView *view = static_cast<DOM::DocumentImpl*>(node.handle())->view();
+
+ Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
+ if ( !win || !win->isSafeScript(exec) )
+ return;
+
+ DOMObjectLookupPut<HTMLDocument, DOMDocument>( exec, propertyName, value, attr, &HTMLDocumentTable, this );
+}
+
+void KJS::HTMLDocument::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
+{
+ DOM::HTMLDocument doc = static_cast<DOM::HTMLDocument>(node);
+
+ DOM::HTMLBodyElement body = doc.body();
+ DOM::DOMString val = value.toString(exec).string();
+
+ switch (token) {
+ case Title:
+ if (doc.title() != val) doc.setTitle(val);
+ break;
+ case Body: {
+ DOMNode *node = new DOMNode(exec, KJS::toNode(value));
+ // This is required to avoid leaking the node.
+ Value nodeValue(node);
+ doc.setBody(node->toNode());
+ break;
+ }
+ case Domain: { // not part of the DOM
+ DOM::HTMLDocumentImpl* docimpl = static_cast<DOM::HTMLDocumentImpl*>(doc.handle());
+ if (docimpl)
+ docimpl->setDomain(val);
+ break;
+ }
+ case Cookie:
+ doc.setCookie(val);
+ break;
+ case Location:
+ {
+ KHTMLView *view = static_cast<DOM::DocumentImpl*>(doc.handle())->view();
+ if ( view )
+ Window::retrieveWindow(view->part())->goURL(exec, value.toString(exec).qstring(), false /*don't lock history*/);
+ break;
+ }
+ case BgColor:
+ if (body.bgColor() != val) body.setBgColor(val);
+ break;
+ case FgColor:
+ if (body.text() != val) body.setText(val);
+ break;
+ case AlinkColor:
+ if (body.aLink() != val) body.setALink(val);
+ break;
+ case LinkColor:
+ if (body.link() != val) body.setLink(val);
+ break;
+ case VlinkColor:
+ if (body.vLink() != val) body.setVLink(val);
+ break;
+ case Dir:
+ body.setDir(val);
+ break;
+ default:
+ kdDebug(6070) << "WARNING: HTMLDocument::putValueProperty unhandled token " << token << endl;
+ }
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo KJS::HTMLElement::info = { "HTMLElement", &DOMElement::info, &HTMLElementTable, 0 };
+const ClassInfo KJS::HTMLElement::html_info = { "HTMLHtmlElement", &KJS::HTMLElement::info, &HTMLHtmlElementTable, 0 };
+const ClassInfo KJS::HTMLElement::head_info = { "HTMLHeadElement", &KJS::HTMLElement::info, &HTMLHeadElementTable, 0 };
+const ClassInfo KJS::HTMLElement::link_info = { "HTMLLinkElement", &KJS::HTMLElement::info, &HTMLLinkElementTable, 0 };
+const ClassInfo KJS::HTMLElement::title_info = { "HTMLTitleElement", &KJS::HTMLElement::info, &HTMLTitleElementTable, 0 };
+const ClassInfo KJS::HTMLElement::meta_info = { "HTMLMetaElement", &KJS::HTMLElement::info, &HTMLMetaElementTable, 0 };
+const ClassInfo KJS::HTMLElement::base_info = { "HTMLBaseElement", &KJS::HTMLElement::info, &HTMLBaseElementTable, 0 };
+const ClassInfo KJS::HTMLElement::isIndex_info = { "HTMLIsIndexElement", &KJS::HTMLElement::info, &HTMLIsIndexElementTable, 0 };
+const ClassInfo KJS::HTMLElement::style_info = { "HTMLStyleElement", &KJS::HTMLElement::info, &HTMLStyleElementTable, 0 };
+const ClassInfo KJS::HTMLElement::body_info = { "HTMLBodyElement", &KJS::HTMLElement::info, &HTMLBodyElementTable, 0 };
+const ClassInfo KJS::HTMLElement::form_info = { "HTMLFormElement", &KJS::HTMLElement::info, &HTMLFormElementTable, 0 };
+const ClassInfo KJS::HTMLElement::select_info = { "HTMLSelectElement", &KJS::HTMLElement::info, &HTMLSelectElementTable, 0 };
+const ClassInfo KJS::HTMLElement::optGroup_info = { "HTMLOptGroupElement", &KJS::HTMLElement::info, &HTMLOptGroupElementTable, 0 };
+const ClassInfo KJS::HTMLElement::option_info = { "HTMLOptionElement", &KJS::HTMLElement::info, &HTMLOptionElementTable, 0 };
+const ClassInfo KJS::HTMLElement::input_info = { "HTMLInputElement", &KJS::HTMLElement::info, &HTMLInputElementTable, 0 };
+const ClassInfo KJS::HTMLElement::textArea_info = { "HTMLTextAreaElement", &KJS::HTMLElement::info, &HTMLTextAreaElementTable, 0 };
+const ClassInfo KJS::HTMLElement::button_info = { "HTMLButtonElement", &KJS::HTMLElement::info, &HTMLButtonElementTable, 0 };
+const ClassInfo KJS::HTMLElement::label_info = { "HTMLLabelElement", &KJS::HTMLElement::info, &HTMLLabelElementTable, 0 };
+const ClassInfo KJS::HTMLElement::fieldSet_info = { "HTMLFieldSetElement", &KJS::HTMLElement::info, &HTMLFieldSetElementTable, 0 };
+const ClassInfo KJS::HTMLElement::legend_info = { "HTMLLegendElement", &KJS::HTMLElement::info, &HTMLLegendElementTable, 0 };
+const ClassInfo KJS::HTMLElement::ul_info = { "HTMLUListElement", &KJS::HTMLElement::info, &HTMLUListElementTable, 0 };
+const ClassInfo KJS::HTMLElement::ol_info = { "HTMLOListElement", &KJS::HTMLElement::info, &HTMLOListElementTable, 0 };
+const ClassInfo KJS::HTMLElement::dl_info = { "HTMLDListElement", &KJS::HTMLElement::info, &HTMLDListElementTable, 0 };
+const ClassInfo KJS::HTMLElement::dir_info = { "HTMLDirectoryElement", &KJS::HTMLElement::info, &HTMLDirectoryElementTable, 0 };
+const ClassInfo KJS::HTMLElement::menu_info = { "HTMLMenuElement", &KJS::HTMLElement::info, &HTMLMenuElementTable, 0 };
+const ClassInfo KJS::HTMLElement::li_info = { "HTMLLIElement", &KJS::HTMLElement::info, &HTMLLIElementTable, 0 };
+const ClassInfo KJS::HTMLElement::div_info = { "HTMLDivElement", &KJS::HTMLElement::info, &HTMLDivElementTable, 0 };
+const ClassInfo KJS::HTMLElement::p_info = { "HTMLParagraphElement", &KJS::HTMLElement::info, &HTMLParagraphElementTable, 0 };
+const ClassInfo KJS::HTMLElement::heading_info = { "HTMLHeadingElement", &KJS::HTMLElement::info, &HTMLHeadingElementTable, 0 };
+const ClassInfo KJS::HTMLElement::blockQuote_info = { "HTMLBlockQuoteElement", &KJS::HTMLElement::info, &HTMLBlockQuoteElementTable, 0 };
+const ClassInfo KJS::HTMLElement::q_info = { "HTMLQuoteElement", &KJS::HTMLElement::info, &HTMLQuoteElementTable, 0 };
+const ClassInfo KJS::HTMLElement::pre_info = { "HTMLPreElement", &KJS::HTMLElement::info, &HTMLPreElementTable, 0 };
+const ClassInfo KJS::HTMLElement::br_info = { "HTMLBRElement", &KJS::HTMLElement::info, &HTMLBRElementTable, 0 };
+const ClassInfo KJS::HTMLElement::baseFont_info = { "HTMLBaseFontElement", &KJS::HTMLElement::info, &HTMLBaseFontElementTable, 0 };
+const ClassInfo KJS::HTMLElement::font_info = { "HTMLFontElement", &KJS::HTMLElement::info, &HTMLFontElementTable, 0 };
+const ClassInfo KJS::HTMLElement::hr_info = { "HTMLHRElement", &KJS::HTMLElement::info, &HTMLHRElementTable, 0 };
+const ClassInfo KJS::HTMLElement::mod_info = { "HTMLModElement", &KJS::HTMLElement::info, &HTMLModElementTable, 0 };
+const ClassInfo KJS::HTMLElement::a_info = { "HTMLAnchorElement", &KJS::HTMLElement::info, &HTMLAnchorElementTable, 0 };
+const ClassInfo KJS::HTMLElement::img_info = { "HTMLImageElement", &KJS::HTMLElement::info, &HTMLImageElementTable, 0 };
+const ClassInfo KJS::HTMLElement::object_info = { "HTMLObjectElement", &KJS::HTMLElement::info, &HTMLObjectElementTable, 0 };
+const ClassInfo KJS::HTMLElement::param_info = { "HTMLParamElement", &KJS::HTMLElement::info, &HTMLParamElementTable, 0 };
+const ClassInfo KJS::HTMLElement::applet_info = { "HTMLAppletElement", &KJS::HTMLElement::info, &HTMLAppletElementTable, 0 };
+const ClassInfo KJS::HTMLElement::map_info = { "HTMLMapElement", &KJS::HTMLElement::info, &HTMLMapElementTable, 0 };
+const ClassInfo KJS::HTMLElement::area_info = { "HTMLAreaElement", &KJS::HTMLElement::info, &HTMLAreaElementTable, 0 };
+const ClassInfo KJS::HTMLElement::script_info = { "HTMLScriptElement", &KJS::HTMLElement::info, &HTMLScriptElementTable, 0 };
+const ClassInfo KJS::HTMLElement::table_info = { "HTMLTableElement", &KJS::HTMLElement::info, &HTMLTableElementTable, 0 };
+const ClassInfo KJS::HTMLElement::caption_info = { "HTMLTableCaptionElement", &KJS::HTMLElement::info, &HTMLTableCaptionElementTable, 0 };
+const ClassInfo KJS::HTMLElement::col_info = { "HTMLTableColElement", &KJS::HTMLElement::info, &HTMLTableColElementTable, 0 };
+const ClassInfo KJS::HTMLElement::tablesection_info = { "HTMLTableSectionElement", &KJS::HTMLElement::info, &HTMLTableSectionElementTable, 0 };
+const ClassInfo KJS::HTMLElement::tr_info = { "HTMLTableRowElement", &KJS::HTMLElement::info, &HTMLTableRowElementTable, 0 };
+const ClassInfo KJS::HTMLElement::tablecell_info = { "HTMLTableCellElement", &KJS::HTMLElement::info, &HTMLTableCellElementTable, 0 };
+const ClassInfo KJS::HTMLElement::frameSet_info = { "HTMLFrameSetElement", &KJS::HTMLElement::info, &HTMLFrameSetElementTable, 0 };
+const ClassInfo KJS::HTMLElement::frame_info = { "HTMLFrameElement", &KJS::HTMLElement::info, &HTMLFrameElementTable, 0 };
+const ClassInfo KJS::HTMLElement::iFrame_info = { "HTMLIFrameElement", &KJS::HTMLElement::info, &HTMLIFrameElementTable, 0 };
+const ClassInfo KJS::HTMLElement::marquee_info = { "HTMLMarqueeElement", &KJS::HTMLElement::info, 0, 0 };
+const ClassInfo KJS::HTMLElement::layer_info = { "HTMLLayerElement", &KJS::HTMLElement::info, &HTMLLayerElementTable, 0 };
+
+static Object prototypeForID(ExecState* exec, DOM::NodeImpl::Id id);
+
+KJS::HTMLElement::HTMLElement(ExecState *exec, const DOM::HTMLElement& e) :
+ DOMElement(prototypeForID(exec, e.elementId()), e) { }
+
+const ClassInfo* KJS::HTMLElement::classInfo() const
+{
+ DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
+ switch (element.elementId()) {
+ case ID_HTML:
+ return &html_info;
+ case ID_HEAD:
+ return &head_info;
+ case ID_LINK:
+ return &link_info;
+ case ID_TITLE:
+ return &title_info;
+ case ID_META:
+ return &meta_info;
+ case ID_BASE:
+ return &base_info;
+ case ID_ISINDEX:
+ return &isIndex_info;
+ case ID_STYLE:
+ return &style_info;
+ case ID_BODY:
+ return &body_info;
+ case ID_FORM:
+ return &form_info;
+ case ID_SELECT:
+ return &select_info;
+ case ID_OPTGROUP:
+ return &optGroup_info;
+ case ID_OPTION:
+ return &option_info;
+ case ID_INPUT:
+ return &input_info;
+ case ID_TEXTAREA:
+ return &textArea_info;
+ case ID_BUTTON:
+ return &button_info;
+ case ID_LABEL:
+ return &label_info;
+ case ID_FIELDSET:
+ return &fieldSet_info;
+ case ID_LEGEND:
+ return &legend_info;
+ case ID_UL:
+ return &ul_info;
+ case ID_OL:
+ return &ol_info;
+ case ID_DL:
+ return &dl_info;
+ case ID_DIR:
+ return &dir_info;
+ case ID_MENU:
+ return &menu_info;
+ case ID_LI:
+ return &li_info;
+ case ID_DIV:
+ return &div_info;
+ case ID_P:
+ return &p_info;
+ case ID_H1:
+ case ID_H2:
+ case ID_H3:
+ case ID_H4:
+ case ID_H5:
+ case ID_H6:
+ return &heading_info;
+ case ID_BLOCKQUOTE:
+ return &blockQuote_info;
+ case ID_Q:
+ return &q_info;
+ case ID_PRE:
+ return &pre_info;
+ case ID_BR:
+ return &br_info;
+ case ID_BASEFONT:
+ return &baseFont_info;
+ case ID_FONT:
+ return &font_info;
+ case ID_HR:
+ return &hr_info;
+ case ID_INS:
+ case ID_DEL:
+ return &mod_info;
+ case ID_A:
+ return &a_info;
+ case ID_IMG:
+ return &img_info;
+ case ID_OBJECT:
+ return &object_info;
+ case ID_PARAM:
+ return &param_info;
+ case ID_APPLET:
+ return &applet_info;
+ case ID_MAP:
+ return &map_info;
+ case ID_AREA:
+ return &area_info;
+ case ID_SCRIPT:
+ return &script_info;
+ case ID_TABLE:
+ return &table_info;
+ case ID_CAPTION:
+ return &caption_info;
+ case ID_COL:
+ case ID_COLGROUP:
+ return &col_info;
+ case ID_THEAD:
+ case ID_TBODY:
+ case ID_TFOOT:
+ return &tablesection_info;
+ case ID_TR:
+ return &tr_info;
+ case ID_TH:
+ case ID_TD:
+ return &tablecell_info;
+ case ID_FRAMESET:
+ return &frameSet_info;
+ case ID_FRAME:
+ return &frame_info;
+ case ID_IFRAME:
+ return &iFrame_info;
+ case ID_MARQUEE:
+ return &marquee_info;
+ case ID_LAYER:
+ return &layer_info;
+ default:
+ return &info;
+ }
+}
+/*
+@begin HTMLElementTable 11
+ id KJS::HTMLElement::ElementId DontDelete
+ title KJS::HTMLElement::ElementTitle DontDelete
+ lang KJS::HTMLElement::ElementLang DontDelete
+ dir KJS::HTMLElement::ElementDir DontDelete
+### isn't this "class" in the HTML spec?
+ className KJS::HTMLElement::ElementClassName DontDelete
+ innerHTML KJS::HTMLElement::ElementInnerHTML DontDelete
+ innerText KJS::HTMLElement::ElementInnerText DontDelete
+ document KJS::HTMLElement::ElementDocument DontDelete|ReadOnly
+# IE extension
+ children KJS::HTMLElement::ElementChildren DontDelete|ReadOnly
+ all KJS::HTMLElement::ElementAll DontDelete|ReadOnly
+@end
+@begin HTMLElementProtoTable 1
+ scrollIntoView KJS::HTMLElement::ElementScrollIntoView DontDelete|Function 0
+@end
+@begin HTMLHtmlElementTable 1
+ version KJS::HTMLElement::HtmlVersion DontDelete
+@end
+@begin HTMLHeadElementTable 1
+ profile KJS::HTMLElement::HeadProfile DontDelete
+@end
+@begin HTMLLinkElementTable 11
+ disabled KJS::HTMLElement::LinkDisabled DontDelete
+ charset KJS::HTMLElement::LinkCharset DontDelete
+ href KJS::HTMLElement::LinkHref DontDelete
+ hreflang KJS::HTMLElement::LinkHrefLang DontDelete
+ media KJS::HTMLElement::LinkMedia DontDelete
+ rel KJS::HTMLElement::LinkRel DontDelete
+ rev KJS::HTMLElement::LinkRev DontDelete
+ target KJS::HTMLElement::LinkTarget DontDelete
+ type KJS::HTMLElement::LinkType DontDelete
+ sheet KJS::HTMLElement::LinkSheet DontDelete|ReadOnly
+@end
+@begin HTMLTitleElementTable 1
+ text KJS::HTMLElement::TitleText DontDelete
+@end
+@begin HTMLMetaElementTable 4
+ content KJS::HTMLElement::MetaContent DontDelete
+ httpEquiv KJS::HTMLElement::MetaHttpEquiv DontDelete
+ name KJS::HTMLElement::MetaName DontDelete
+ scheme KJS::HTMLElement::MetaScheme DontDelete
+@end
+@begin HTMLBaseElementTable 2
+ href KJS::HTMLElement::BaseHref DontDelete
+ target KJS::HTMLElement::BaseTarget DontDelete
+@end
+@begin HTMLIsIndexElementTable 2
+ form KJS::HTMLElement::IsIndexForm DontDelete|ReadOnly
+ prompt KJS::HTMLElement::IsIndexPrompt DontDelete
+@end
+@begin HTMLStyleElementTable 4
+ disabled KJS::HTMLElement::StyleDisabled DontDelete
+ media KJS::HTMLElement::StyleMedia DontDelete
+ type KJS::HTMLElement::StyleType DontDelete
+ sheet KJS::HTMLElement::StyleSheet DontDelete|ReadOnly
+@end
+@begin HTMLBodyElementTable 8
+ aLink KJS::HTMLElement::BodyALink DontDelete
+ background KJS::HTMLElement::BodyBackground DontDelete
+ bgColor KJS::HTMLElement::BodyBgColor DontDelete
+ link KJS::HTMLElement::BodyLink DontDelete
+ text KJS::HTMLElement::BodyText DontDelete
+ vLink KJS::HTMLElement::BodyVLink DontDelete
+# IE extension
+ onload KJS::HTMLElement::BodyOnLoad DontDelete
+@end
+@begin HTMLBodyElementProtoTable 2
+# Mozilla'ish extension. Ideally we would want to support this on all elements.
+# Not hard, but not an immediate need.
+ focus KJS::HTMLElement::BodyFocus DontDelete|Function 0
+@end
+@begin HTMLFormElementTable 11
+# Also supported, by name/index
+ elements KJS::HTMLElement::FormElements DontDelete|ReadOnly
+ length KJS::HTMLElement::FormLength DontDelete|ReadOnly
+ name KJS::HTMLElement::FormName DontDelete
+ acceptCharset KJS::HTMLElement::FormAcceptCharset DontDelete
+ action KJS::HTMLElement::FormAction DontDelete
+ encoding KJS::HTMLElement::FormEncType DontDelete
+ enctype KJS::HTMLElement::FormEncType DontDelete
+ method KJS::HTMLElement::FormMethod DontDelete
+ target KJS::HTMLElement::FormTarget DontDelete
+@end
+@begin HTMLFormElementProtoTable 2
+ submit KJS::HTMLElement::FormSubmit DontDelete|Function 0
+ reset KJS::HTMLElement::FormReset DontDelete|Function 0
+@end
+@begin HTMLSelectElementTable 11
+# Also supported, by index
+ type KJS::HTMLElement::SelectType DontDelete|ReadOnly
+ selectedIndex KJS::HTMLElement::SelectSelectedIndex DontDelete
+ value KJS::HTMLElement::SelectValue DontDelete
+ length KJS::HTMLElement::SelectLength DontDelete
+ form KJS::HTMLElement::SelectForm DontDelete|ReadOnly
+ options KJS::HTMLElement::SelectOptions DontDelete|ReadOnly
+ disabled KJS::HTMLElement::SelectDisabled DontDelete
+ multiple KJS::HTMLElement::SelectMultiple DontDelete
+ name KJS::HTMLElement::SelectName DontDelete
+ size KJS::HTMLElement::SelectSize DontDelete
+ tabIndex KJS::HTMLElement::SelectTabIndex DontDelete
+@end
+@begin HTMLSelectElementProtoTable 4
+ add KJS::HTMLElement::SelectAdd DontDelete|Function 2
+ remove KJS::HTMLElement::SelectRemove DontDelete|Function 1
+ blur KJS::HTMLElement::SelectBlur DontDelete|Function 0
+ focus KJS::HTMLElement::SelectFocus DontDelete|Function 0
+@end
+@begin HTMLOptGroupElementTable 2
+ disabled KJS::HTMLElement::OptGroupDisabled DontDelete
+ label KJS::HTMLElement::OptGroupLabel DontDelete
+@end
+@begin HTMLOptionElementTable 8
+ form KJS::HTMLElement::OptionForm DontDelete|ReadOnly
+ defaultSelected KJS::HTMLElement::OptionDefaultSelected DontDelete
+ text KJS::HTMLElement::OptionText DontDelete
+ index KJS::HTMLElement::OptionIndex DontDelete|ReadOnly
+ disabled KJS::HTMLElement::OptionDisabled DontDelete
+ label KJS::HTMLElement::OptionLabel DontDelete
+ selected KJS::HTMLElement::OptionSelected DontDelete
+ value KJS::HTMLElement::OptionValue DontDelete
+@end
+@begin HTMLInputElementTable 25
+ defaultValue KJS::HTMLElement::InputDefaultValue DontDelete
+ defaultChecked KJS::HTMLElement::InputDefaultChecked DontDelete
+ form KJS::HTMLElement::InputForm DontDelete|ReadOnly
+ accept KJS::HTMLElement::InputAccept DontDelete
+ accessKey KJS::HTMLElement::InputAccessKey DontDelete
+ align KJS::HTMLElement::InputAlign DontDelete
+ alt KJS::HTMLElement::InputAlt DontDelete
+ checked KJS::HTMLElement::InputChecked DontDelete
+ indeterminate KJS::HTMLElement::InputIndeterminate DontDelete
+ status KJS::HTMLElement::InputChecked DontDelete
+ disabled KJS::HTMLElement::InputDisabled DontDelete
+ maxLength KJS::HTMLElement::InputMaxLength DontDelete
+ name KJS::HTMLElement::InputName DontDelete
+ readOnly KJS::HTMLElement::InputReadOnly DontDelete
+ size KJS::HTMLElement::InputSize DontDelete
+ src KJS::HTMLElement::InputSrc DontDelete
+ tabIndex KJS::HTMLElement::InputTabIndex DontDelete
+ type KJS::HTMLElement::InputType DontDelete
+ useMap KJS::HTMLElement::InputUseMap DontDelete
+ value KJS::HTMLElement::InputValue DontDelete
+ selectionStart KJS::HTMLElement::InputSelectionStart DontDelete
+ selectionEnd KJS::HTMLElement::InputSelectionEnd DontDelete
+@end
+@begin HTMLInputElementProtoTable 5
+ blur KJS::HTMLElement::InputBlur DontDelete|Function 0
+ focus KJS::HTMLElement::InputFocus DontDelete|Function 0
+ select KJS::HTMLElement::InputSelect DontDelete|Function 0
+ click KJS::HTMLElement::InputClick DontDelete|Function 0
+ setSelectionRange KJS::HTMLElement::InputSetSelectionRange DontDelete|Function 2
+@end
+@begin HTMLTextAreaElementTable 13
+ defaultValue KJS::HTMLElement::TextAreaDefaultValue DontDelete
+ form KJS::HTMLElement::TextAreaForm DontDelete|ReadOnly
+ accessKey KJS::HTMLElement::TextAreaAccessKey DontDelete
+ cols KJS::HTMLElement::TextAreaCols DontDelete
+ disabled KJS::HTMLElement::TextAreaDisabled DontDelete
+ name KJS::HTMLElement::TextAreaName DontDelete
+ readOnly KJS::HTMLElement::TextAreaReadOnly DontDelete
+ rows KJS::HTMLElement::TextAreaRows DontDelete
+ tabIndex KJS::HTMLElement::TextAreaTabIndex DontDelete
+ type KJS::HTMLElement::TextAreaType DontDelete|ReadOnly
+ value KJS::HTMLElement::TextAreaValue DontDelete
+ selectionStart KJS::HTMLElement::TextAreaSelectionStart DontDelete
+ selectionEnd KJS::HTMLElement::TextAreaSelectionEnd DontDelete
+ textLength KJS::HTMLElement::TextAreaTextLength DontDelete|ReadOnly
+@end
+@begin HTMLTextAreaElementProtoTable 4
+ blur KJS::HTMLElement::TextAreaBlur DontDelete|Function 0
+ focus KJS::HTMLElement::TextAreaFocus DontDelete|Function 0
+ select KJS::HTMLElement::TextAreaSelect DontDelete|Function 0
+ setSelectionRange KJS::HTMLElement::TextAreaSetSelectionRange DontDelete|Function 2
+@end
+@begin HTMLButtonElementTable 9
+ form KJS::HTMLElement::ButtonForm DontDelete|ReadOnly
+ accessKey KJS::HTMLElement::ButtonAccessKey DontDelete
+ disabled KJS::HTMLElement::ButtonDisabled DontDelete
+ name KJS::HTMLElement::ButtonName DontDelete
+ tabIndex KJS::HTMLElement::ButtonTabIndex DontDelete
+ type KJS::HTMLElement::ButtonType DontDelete|ReadOnly
+ value KJS::HTMLElement::ButtonValue DontDelete
+@end
+@begin HTMLButtonElementProtoTable 2
+ blur KJS::HTMLElement::ButtonBlur DontDelete|Function 0
+ focus KJS::HTMLElement::ButtonFocus DontDelete|Function 0
+@end
+@begin HTMLLabelElementTable 3
+ form KJS::HTMLElement::LabelForm DontDelete|ReadOnly
+ accessKey KJS::HTMLElement::LabelAccessKey DontDelete
+ htmlFor KJS::HTMLElement::LabelHtmlFor DontDelete
+@end
+@begin HTMLFieldSetElementTable 1
+ form KJS::HTMLElement::FieldSetForm DontDelete|ReadOnly
+@end
+@begin HTMLLegendElementTable 3
+ form KJS::HTMLElement::LegendForm DontDelete|ReadOnly
+ accessKey KJS::HTMLElement::LegendAccessKey DontDelete
+ align KJS::HTMLElement::LegendAlign DontDelete
+@end
+@begin HTMLUListElementTable 2
+ compact KJS::HTMLElement::UListCompact DontDelete
+ type KJS::HTMLElement::UListType DontDelete
+@end
+@begin HTMLOListElementTable 3
+ compact KJS::HTMLElement::OListCompact DontDelete
+ start KJS::HTMLElement::OListStart DontDelete
+ type KJS::HTMLElement::OListType DontDelete
+@end
+@begin HTMLDListElementTable 1
+ compact KJS::HTMLElement::DListCompact DontDelete
+@end
+@begin HTMLDirectoryElementTable 1
+ compact KJS::HTMLElement::DirectoryCompact DontDelete
+@end
+@begin HTMLMenuElementTable 1
+ compact KJS::HTMLElement::MenuCompact DontDelete
+@end
+@begin HTMLLIElementTable 2
+ type KJS::HTMLElement::LIType DontDelete
+ value KJS::HTMLElement::LIValue DontDelete
+@end
+@begin HTMLDivElementTable 1
+ align KJS::HTMLElement::DivAlign DontDelete
+@end
+@begin HTMLParagraphElementTable 1
+ align KJS::HTMLElement::ParagraphAlign DontDelete
+@end
+@begin HTMLHeadingElementTable 1
+ align KJS::HTMLElement::HeadingAlign DontDelete
+@end
+@begin HTMLBlockQuoteElementTable 1
+ cite KJS::HTMLElement::BlockQuoteCite DontDelete
+@end
+@begin HTMLQuoteElementTable 1
+ cite KJS::HTMLElement::QuoteCite DontDelete
+@end
+@begin HTMLPreElementTable 1
+ width KJS::HTMLElement::PreWidth DontDelete
+@end
+@begin HTMLBRElementTable 1
+ clear KJS::HTMLElement::BRClear DontDelete
+@end
+@begin HTMLBaseFontElementTable 3
+ color KJS::HTMLElement::BaseFontColor DontDelete
+ face KJS::HTMLElement::BaseFontFace DontDelete
+ size KJS::HTMLElement::BaseFontSize DontDelete
+@end
+@begin HTMLFontElementTable 3
+ color KJS::HTMLElement::FontColor DontDelete
+ face KJS::HTMLElement::FontFace DontDelete
+ size KJS::HTMLElement::FontSize DontDelete
+@end
+@begin HTMLHRElementTable 4
+ align KJS::HTMLElement::HRAlign DontDelete
+ noShade KJS::HTMLElement::HRNoShade DontDelete
+ size KJS::HTMLElement::HRSize DontDelete
+ width KJS::HTMLElement::HRWidth DontDelete
+@end
+@begin HTMLModElementTable 2
+ cite KJS::HTMLElement::ModCite DontDelete
+ dateTime KJS::HTMLElement::ModDateTime DontDelete
+@end
+@begin HTMLAnchorElementTable 23
+ accessKey KJS::HTMLElement::AnchorAccessKey DontDelete
+ charset KJS::HTMLElement::AnchorCharset DontDelete
+ coords KJS::HTMLElement::AnchorCoords DontDelete
+ href KJS::HTMLElement::AnchorHref DontDelete
+ hreflang KJS::HTMLElement::AnchorHrefLang DontDelete
+ hash KJS::HTMLElement::AnchorHash DontDelete|ReadOnly
+ host KJS::HTMLElement::AnchorHost DontDelete|ReadOnly
+ hostname KJS::HTMLElement::AnchorHostname DontDelete|ReadOnly
+ name KJS::HTMLElement::AnchorName DontDelete
+ pathname KJS::HTMLElement::AnchorPathName DontDelete|ReadOnly
+ port KJS::HTMLElement::AnchorPort DontDelete|ReadOnly
+ protocol KJS::HTMLElement::AnchorProtocol DontDelete|ReadOnly
+ rel KJS::HTMLElement::AnchorRel DontDelete
+ rev KJS::HTMLElement::AnchorRev DontDelete
+ search KJS::HTMLElement::AnchorSearch DontDelete
+ shape KJS::HTMLElement::AnchorShape DontDelete
+ tabIndex KJS::HTMLElement::AnchorTabIndex DontDelete
+ target KJS::HTMLElement::AnchorTarget DontDelete
+ text KJS::HTMLElement::AnchorText DontDelete|ReadOnly
+ type KJS::HTMLElement::AnchorType DontDelete
+@end
+@begin HTMLAnchorElementProtoTable 3
+ blur KJS::HTMLElement::AnchorBlur DontDelete|Function 0
+ focus KJS::HTMLElement::AnchorFocus DontDelete|Function 0
+ click KJS::HTMLElement::AnchorClick DontDelete|Function 0
+@end
+@begin HTMLImageElementTable 15
+ name KJS::HTMLElement::ImageName DontDelete
+ align KJS::HTMLElement::ImageAlign DontDelete
+ alt KJS::HTMLElement::ImageAlt DontDelete
+ border KJS::HTMLElement::ImageBorder DontDelete
+ complete KJS::HTMLElement::ImageComplete DontDelete|ReadOnly
+ height KJS::HTMLElement::ImageHeight DontDelete
+ hspace KJS::HTMLElement::ImageHspace DontDelete
+ isMap KJS::HTMLElement::ImageIsMap DontDelete
+ longDesc KJS::HTMLElement::ImageLongDesc DontDelete
+ src KJS::HTMLElement::ImageSrc DontDelete
+ useMap KJS::HTMLElement::ImageUseMap DontDelete
+ vspace KJS::HTMLElement::ImageVspace DontDelete
+ width KJS::HTMLElement::ImageWidth DontDelete
+ x KJS::HTMLElement::ImageX DontDelete|ReadOnly
+ y KJS::HTMLElement::ImageY DontDelete|ReadOnly
+@end
+@begin HTMLObjectElementTable 20
+ form KJS::HTMLElement::ObjectForm DontDelete|ReadOnly
+ code KJS::HTMLElement::ObjectCode DontDelete
+ align KJS::HTMLElement::ObjectAlign DontDelete
+ archive KJS::HTMLElement::ObjectArchive DontDelete
+ border KJS::HTMLElement::ObjectBorder DontDelete
+ codeBase KJS::HTMLElement::ObjectCodeBase DontDelete
+ codeType KJS::HTMLElement::ObjectCodeType DontDelete
+ contentDocument KJS::HTMLElement::ObjectContentDocument DontDelete|ReadOnly
+ data KJS::HTMLElement::ObjectData DontDelete
+ declare KJS::HTMLElement::ObjectDeclare DontDelete
+ height KJS::HTMLElement::ObjectHeight DontDelete
+ hspace KJS::HTMLElement::ObjectHspace DontDelete
+ name KJS::HTMLElement::ObjectName DontDelete
+ standby KJS::HTMLElement::ObjectStandby DontDelete
+ tabIndex KJS::HTMLElement::ObjectTabIndex DontDelete
+ type KJS::HTMLElement::ObjectType DontDelete
+ useMap KJS::HTMLElement::ObjectUseMap DontDelete
+ vspace KJS::HTMLElement::ObjectVspace DontDelete
+ width KJS::HTMLElement::ObjectWidth DontDelete
+@end
+@begin HTMLParamElementTable 4
+ name KJS::HTMLElement::ParamName DontDelete
+ type KJS::HTMLElement::ParamType DontDelete
+ value KJS::HTMLElement::ParamValue DontDelete
+ valueType KJS::HTMLElement::ParamValueType DontDelete
+@end
+@begin HTMLAppletElementTable 11
+ align KJS::HTMLElement::AppletAlign DontDelete
+ alt KJS::HTMLElement::AppletAlt DontDelete
+ archive KJS::HTMLElement::AppletArchive DontDelete
+ code KJS::HTMLElement::AppletCode DontDelete
+ codeBase KJS::HTMLElement::AppletCodeBase DontDelete
+ height KJS::HTMLElement::AppletHeight DontDelete
+ hspace KJS::HTMLElement::AppletHspace DontDelete
+ name KJS::HTMLElement::AppletName DontDelete
+ object KJS::HTMLElement::AppletObject DontDelete
+ vspace KJS::HTMLElement::AppletVspace DontDelete
+ width KJS::HTMLElement::AppletWidth DontDelete
+@end
+@begin HTMLMapElementTable 2
+ areas KJS::HTMLElement::MapAreas DontDelete|ReadOnly
+ name KJS::HTMLElement::MapName DontDelete
+@end
+@begin HTMLAreaElementTable 15
+ accessKey KJS::HTMLElement::AreaAccessKey DontDelete
+ alt KJS::HTMLElement::AreaAlt DontDelete
+ coords KJS::HTMLElement::AreaCoords DontDelete
+ href KJS::HTMLElement::AreaHref DontDelete
+ hash KJS::HTMLElement::AreaHash DontDelete|ReadOnly
+ host KJS::HTMLElement::AreaHost DontDelete|ReadOnly
+ hostname KJS::HTMLElement::AreaHostName DontDelete|ReadOnly
+ pathname KJS::HTMLElement::AreaPathName DontDelete|ReadOnly
+ port KJS::HTMLElement::AreaPort DontDelete|ReadOnly
+ protocol KJS::HTMLElement::AreaProtocol DontDelete|ReadOnly
+ search KJS::HTMLElement::AreaSearch DontDelete|ReadOnly
+ noHref KJS::HTMLElement::AreaNoHref DontDelete
+ shape KJS::HTMLElement::AreaShape DontDelete
+ tabIndex KJS::HTMLElement::AreaTabIndex DontDelete
+ target KJS::HTMLElement::AreaTarget DontDelete
+@end
+@begin HTMLScriptElementTable 7
+ text KJS::HTMLElement::ScriptText DontDelete
+ htmlFor KJS::HTMLElement::ScriptHtmlFor DontDelete
+ event KJS::HTMLElement::ScriptEvent DontDelete
+ charset KJS::HTMLElement::ScriptCharset DontDelete
+ defer KJS::HTMLElement::ScriptDefer DontDelete
+ src KJS::HTMLElement::ScriptSrc DontDelete
+ type KJS::HTMLElement::ScriptType DontDelete
+@end
+@begin HTMLTableElementTable 23
+ caption KJS::HTMLElement::TableCaption DontDelete
+ tHead KJS::HTMLElement::TableTHead DontDelete
+ tFoot KJS::HTMLElement::TableTFoot DontDelete
+ rows KJS::HTMLElement::TableRows DontDelete|ReadOnly
+ tBodies KJS::HTMLElement::TableTBodies DontDelete|ReadOnly
+ align KJS::HTMLElement::TableAlign DontDelete
+ bgColor KJS::HTMLElement::TableBgColor DontDelete
+ border KJS::HTMLElement::TableBorder DontDelete
+ cellPadding KJS::HTMLElement::TableCellPadding DontDelete
+ cellSpacing KJS::HTMLElement::TableCellSpacing DontDelete
+ frame KJS::HTMLElement::TableFrame DontDelete
+ rules KJS::HTMLElement::TableRules DontDelete
+ summary KJS::HTMLElement::TableSummary DontDelete
+ width KJS::HTMLElement::TableWidth DontDelete
+@end
+@begin HTMLTableElementProtoTable 8
+ createTHead KJS::HTMLElement::TableCreateTHead DontDelete|Function 0
+ deleteTHead KJS::HTMLElement::TableDeleteTHead DontDelete|Function 0
+ createTFoot KJS::HTMLElement::TableCreateTFoot DontDelete|Function 0
+ deleteTFoot KJS::HTMLElement::TableDeleteTFoot DontDelete|Function 0
+ createCaption KJS::HTMLElement::TableCreateCaption DontDelete|Function 0
+ deleteCaption KJS::HTMLElement::TableDeleteCaption DontDelete|Function 0
+ insertRow KJS::HTMLElement::TableInsertRow DontDelete|Function 1
+ deleteRow KJS::HTMLElement::TableDeleteRow DontDelete|Function 1
+@end
+@begin HTMLTableCaptionElementTable 1
+ align KJS::HTMLElement::TableCaptionAlign DontDelete
+@end
+@begin HTMLTableColElementTable 7
+ align KJS::HTMLElement::TableColAlign DontDelete
+ ch KJS::HTMLElement::TableColCh DontDelete
+ chOff KJS::HTMLElement::TableColChOff DontDelete
+ span KJS::HTMLElement::TableColSpan DontDelete
+ vAlign KJS::HTMLElement::TableColVAlign DontDelete
+ width KJS::HTMLElement::TableColWidth DontDelete
+@end
+@begin HTMLTableSectionElementTable 7
+ align KJS::HTMLElement::TableSectionAlign DontDelete
+ ch KJS::HTMLElement::TableSectionCh DontDelete
+ chOff KJS::HTMLElement::TableSectionChOff DontDelete
+ vAlign KJS::HTMLElement::TableSectionVAlign DontDelete
+ rows KJS::HTMLElement::TableSectionRows DontDelete|ReadOnly
+@end
+@begin HTMLTableSectionElementProtoTable 2
+ insertRow KJS::HTMLElement::TableSectionInsertRow DontDelete|Function 1
+ deleteRow KJS::HTMLElement::TableSectionDeleteRow DontDelete|Function 1
+@end
+@begin HTMLTableRowElementTable 11
+ rowIndex KJS::HTMLElement::TableRowRowIndex DontDelete|ReadOnly
+ sectionRowIndex KJS::HTMLElement::TableRowSectionRowIndex DontDelete|ReadOnly
+ cells KJS::HTMLElement::TableRowCells DontDelete|ReadOnly
+ align KJS::HTMLElement::TableRowAlign DontDelete
+ bgColor KJS::HTMLElement::TableRowBgColor DontDelete
+ ch KJS::HTMLElement::TableRowCh DontDelete
+ chOff KJS::HTMLElement::TableRowChOff DontDelete
+ vAlign KJS::HTMLElement::TableRowVAlign DontDelete
+@end
+@begin HTMLTableRowElementProtoTable 2
+ insertCell KJS::HTMLElement::TableRowInsertCell DontDelete|Function 1
+ deleteCell KJS::HTMLElement::TableRowDeleteCell DontDelete|Function 1
+@end
+@begin HTMLTableCellElementTable 15
+ cellIndex KJS::HTMLElement::TableCellCellIndex DontDelete|ReadOnly
+ abbr KJS::HTMLElement::TableCellAbbr DontDelete
+ align KJS::HTMLElement::TableCellAlign DontDelete
+ axis KJS::HTMLElement::TableCellAxis DontDelete
+ bgColor KJS::HTMLElement::TableCellBgColor DontDelete
+ ch KJS::HTMLElement::TableCellCh DontDelete
+ chOff KJS::HTMLElement::TableCellChOff DontDelete
+ colSpan KJS::HTMLElement::TableCellColSpan DontDelete
+ headers KJS::HTMLElement::TableCellHeaders DontDelete
+ height KJS::HTMLElement::TableCellHeight DontDelete
+ noWrap KJS::HTMLElement::TableCellNoWrap DontDelete
+ rowSpan KJS::HTMLElement::TableCellRowSpan DontDelete
+ scope KJS::HTMLElement::TableCellScope DontDelete
+ vAlign KJS::HTMLElement::TableCellVAlign DontDelete
+ width KJS::HTMLElement::TableCellWidth DontDelete
+@end
+@begin HTMLFrameSetElementTable 2
+ cols KJS::HTMLElement::FrameSetCols DontDelete
+ rows KJS::HTMLElement::FrameSetRows DontDelete
+@end
+@begin HTMLLayerElementTable 6
+ top KJS::HTMLElement::LayerTop DontDelete
+ left KJS::HTMLElement::LayerLeft DontDelete
+ visibility KJS::HTMLElement::LayerVisibility DontDelete
+ bgColor KJS::HTMLElement::LayerBgColor DontDelete
+ document KJS::HTMLElement::LayerDocument DontDelete|ReadOnly
+ clip KJS::HTMLElement::LayerClip DontDelete|ReadOnly
+ layers KJS::HTMLElement::LayerLayers DontDelete|ReadOnly
+@end
+@begin HTMLFrameElementTable 13
+ contentDocument KJS::HTMLElement::FrameContentDocument DontDelete|ReadOnly
+ contentWindow KJS::HTMLElement::FrameContentWindow DontDelete|ReadOnly
+ frameBorder KJS::HTMLElement::FrameFrameBorder DontDelete
+ longDesc KJS::HTMLElement::FrameLongDesc DontDelete
+ marginHeight KJS::HTMLElement::FrameMarginHeight DontDelete
+ marginWidth KJS::HTMLElement::FrameMarginWidth DontDelete
+ name KJS::HTMLElement::FrameName DontDelete
+ noResize KJS::HTMLElement::FrameNoResize DontDelete
+ scrolling KJS::HTMLElement::FrameScrolling DontDelete
+ src KJS::HTMLElement::FrameSrc DontDelete
+ location KJS::HTMLElement::FrameLocation DontDelete
+# IE extension
+ width KJS::HTMLElement::FrameWidth DontDelete|ReadOnly
+ height KJS::HTMLElement::FrameHeight DontDelete|ReadOnly
+@end
+@begin HTMLIFrameElementTable 12
+ align KJS::HTMLElement::IFrameAlign DontDelete
+ contentDocument KJS::HTMLElement::IFrameContentDocument DontDelete|ReadOnly
+ contentWindow KJS::HTMLElement::IFrameContentWindow DontDelete|ReadOnly
+ frameBorder KJS::HTMLElement::IFrameFrameBorder DontDelete
+ height KJS::HTMLElement::IFrameHeight DontDelete
+ longDesc KJS::HTMLElement::IFrameLongDesc DontDelete
+ marginHeight KJS::HTMLElement::IFrameMarginHeight DontDelete
+ marginWidth KJS::HTMLElement::IFrameMarginWidth DontDelete
+ name KJS::HTMLElement::IFrameName DontDelete
+ scrolling KJS::HTMLElement::IFrameScrolling DontDelete
+ src KJS::HTMLElement::IFrameSrc DontDelete
+ width KJS::HTMLElement::IFrameWidth DontDelete
+@end
+
+@begin HTMLMarqueeElementProtoTable 2
+ start KJS::HTMLElement::MarqueeStart DontDelete|Function 0
+ stop KJS::HTMLElement::MarqueeStop DontDelete|Function 0
+@end
+
+*/
+
+static KParts::LiveConnectExtension *getLiveConnectExtension(const DOM::HTMLElement & element)
+{
+ DOM::HTMLDocument doc = element.ownerDocument();
+ KHTMLView *view = static_cast<DOM::DocumentImpl*>(doc.handle())->view();
+ if (view && element.handle())
+ return view->part()->liveConnectExtension(static_cast<khtml::RenderPart*>(element.handle()->renderer()));
+ return 0L;
+}
+
+Value KJS::HTMLElement::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLElement::tryGet " << propertyName.qstring() << " thisTag=" << element.tagName().string() << endl;
+#endif
+ // First look at dynamic properties
+ switch (element.elementId()) {
+ case ID_FORM: {
+ DOM::HTMLFormElement form = element;
+ // Check if we're retrieving an element (by index or by name)
+ bool ok;
+ uint u = propertyName.toULong(&ok);
+
+ if (ok)
+ return getDOMNode(exec,form.elements().item(u));
+ KJS::HTMLCollection coll(exec, form.elements());
+ Value namedItems = coll.getNamedItems(exec, propertyName);
+ if (namedItems.type() != UndefinedType)
+ return namedItems;
+ }
+ break;
+ case ID_SELECT: {
+ DOM::HTMLSelectElement select = element;
+ bool ok;
+ uint u = propertyName.toULong(&ok);
+ if (ok)
+ return getDOMNode(exec,select.options().item(u)); // not specified by DOM(?) but supported in netscape/IE
+ }
+ break;
+ case ID_APPLET:
+ case ID_OBJECT:
+ case ID_EMBED: {
+ KParts::LiveConnectExtension *lc = getLiveConnectExtension(element);
+ QString rvalue;
+ KParts::LiveConnectExtension::Type rtype;
+ unsigned long robjid;
+ if (lc && lc->get(0, propertyName.qstring(), rtype, robjid, rvalue))
+ return getLiveConnectValue(lc, propertyName.qstring(), rtype, rvalue, robjid);
+ }
+ break;
+ default:
+ break;
+ }
+
+ const HashTable* table = classInfo()->propHashTable; // get the right hashtable
+ const HashEntry* entry = table ? Lookup::findEntry(table, propertyName) : 0;
+ if (entry) {
+ if (entry->attr & Function)
+ return lookupOrCreateFunction<KJS::HTMLElementFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
+ return getValueProperty(exec, entry->value);
+ }
+
+ // Base HTMLElement stuff or parent class forward, as usual
+ return DOMObjectLookupGet<KJS::HTMLElementFunction, KJS::HTMLElement, DOMElement>(exec, propertyName, &KJS::HTMLElementTable, this);
+}
+
+Value KJS::HTMLElement::getValueProperty(ExecState *exec, int token) const
+{
+ DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
+ switch (element.elementId()) {
+ case ID_HTML: {
+ DOM::HTMLHtmlElement html = element;
+ if (token == HtmlVersion) return String(html.version());
+ }
+ break;
+ case ID_HEAD: {
+ DOM::HTMLHeadElement head = element;
+ if (token == HeadProfile) return String(head.profile());
+ }
+ break;
+ case ID_LINK: {
+ DOM::HTMLLinkElement link = element;
+ switch (token) {
+ case LinkDisabled: return Boolean(link.disabled());
+ case LinkCharset: return String(link.charset());
+ case LinkHref: return String(link.href());
+ case LinkHrefLang: return String(link.hreflang());
+ case LinkMedia: return String(link.media());
+ case LinkRel: return String(link.rel());
+ case LinkRev: return String(link.rev());
+ case LinkTarget: return String(link.target());
+ case LinkType: return String(link.type());
+ case LinkSheet: return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
+ }
+ }
+ break;
+ case ID_TITLE: {
+ DOM::HTMLTitleElement title = element;
+ switch (token) {
+ case TitleText: return String(title.text());
+ }
+ }
+ break;
+ case ID_META: {
+ DOM::HTMLMetaElement meta = element;
+ switch (token) {
+ case MetaContent: return String(meta.content());
+ case MetaHttpEquiv: return String(meta.httpEquiv());
+ case MetaName: return String(meta.name());
+ case MetaScheme: return String(meta.scheme());
+ }
+ }
+ break;
+ case ID_BASE: {
+ DOM::HTMLBaseElement base = element;
+ switch (token) {
+ case BaseHref: return String(base.href());
+ case BaseTarget: return String(base.target());
+ }
+ }
+ break;
+ case ID_ISINDEX: {
+ DOM::HTMLIsIndexElement isindex = element;
+ switch (token) {
+ case IsIndexForm: return getDOMNode(exec,isindex.form()); // type HTMLFormElement
+ case IsIndexPrompt: return String(isindex.prompt());
+ }
+ }
+ break;
+ case ID_STYLE: {
+ DOM::HTMLStyleElement style = element;
+ switch (token) {
+ case StyleDisabled: return Boolean(style.disabled());
+ case StyleMedia: return String(style.media());
+ case StyleType: return String(style.type());
+ case StyleSheet: return getDOMStyleSheet(exec,style.sheet());
+ }
+ }
+ break;
+ case ID_BODY: {
+ DOM::HTMLBodyElement body = element;
+ switch (token) {
+ case BodyALink: return String(body.aLink());
+ case BodyBackground: return String(body.background());
+ case BodyBgColor: return String(body.bgColor());
+ case BodyLink: return String(body.link());
+ case BodyText: return String(body.text());
+ case BodyVLink: return String(body.vLink());
+ case BodyOnLoad: {
+ DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl *>(node.ownerDocument().handle());
+ if (!doc || !checkNodeSecurity(exec, node))
+ return Undefined();
+ DOMNode* kjsDocNode = new DOMNode(exec, doc);
+ // Need to create a Value wrapper to avoid leaking the KJS::DOMNode
+ Value nodeValue(kjsDocNode);
+ return kjsDocNode->getListener( DOM::EventImpl::LOAD_EVENT );
+ }
+ }
+ }
+ break;
+
+ case ID_FORM: {
+ DOM::HTMLFormElement form = element;
+ switch (token) {
+ case FormElements: return getHTMLCollection(exec,form.elements());
+ case FormLength: return Number(form.length());
+ case FormName: return String(form.name()); // NOT getString (IE gives empty string)
+ case FormAcceptCharset: return String(form.acceptCharset());
+ case FormAction: return String(form.action());
+ case FormEncType: return String(form.enctype());
+ case FormMethod: return String(form.method());
+ case FormTarget: return String(form.target());
+ }
+ }
+ break;
+ case ID_SELECT: {
+ DOM::HTMLSelectElement select = element;
+ switch (token) {
+ case SelectType: return String(select.type());
+ case SelectSelectedIndex: return Number(select.selectedIndex());
+ case SelectValue: return String(select.value());
+ case SelectLength: return Number(select.length());
+ case SelectForm: return getDOMNode(exec,select.form()); // type HTMLFormElement
+ case SelectOptions: return getSelectHTMLCollection(exec, select.options(), select); // type HTMLCollection
+ case SelectDisabled: return Boolean(select.disabled());
+ case SelectMultiple: return Boolean(select.multiple());
+ case SelectName: return String(select.name());
+ case SelectSize: return Number(select.size());
+ case SelectTabIndex: return Number(select.tabIndex());
+ }
+ }
+ break;
+ case ID_OPTGROUP: {
+ DOM::HTMLOptGroupElement optgroup = element;
+ switch (token) {
+ case OptGroupDisabled: return Boolean(optgroup.disabled());
+ case OptGroupLabel: return String(optgroup.label());
+ }
+ }
+ break;
+ case ID_OPTION: {
+ DOM::HTMLOptionElement option = element;
+ switch (token) {
+ case OptionForm: return getDOMNode(exec,option.form()); // type HTMLFormElement
+ case OptionDefaultSelected: return Boolean(option.defaultSelected());
+ case OptionText: return String(option.text());
+ case OptionIndex: return Number(option.index());
+ case OptionDisabled: return Boolean(option.disabled());
+ case OptionLabel: return String(option.label());
+ case OptionSelected: return Boolean(option.selected());
+ case OptionValue: return String(option.value());
+ }
+ }
+ break;
+ case ID_INPUT: {
+ DOM::HTMLInputElement input = element;
+ switch (token) {
+ case InputDefaultValue: return String(input.defaultValue());
+ case InputDefaultChecked: return Boolean(input.defaultChecked());
+ case InputForm: return getDOMNode(exec,input.form()); // type HTMLFormElement
+ case InputAccept: return String(input.accept());
+ case InputAccessKey: return String(input.accessKey());
+ case InputAlign: return String(input.align());
+ case InputAlt: return String(input.alt());
+ case InputChecked: return Boolean(input.checked());
+ case InputIndeterminate: return Boolean(input.indeterminate());
+ case InputDisabled: return Boolean(input.disabled());
+ case InputMaxLength: return Number(input.maxLength());
+ case InputName: return String(input.name()); // NOT getString (IE gives empty string)
+ case InputReadOnly: return Boolean(input.readOnly());
+ case InputSize: return Number(input.getSize());
+ case InputSrc: return String(input.src());
+ case InputTabIndex: return Number(input.tabIndex());
+ case InputType: return String(input.type());
+ case InputUseMap: return String(input.useMap());
+ case InputValue: return String(input.value());
+ case InputSelectionStart: {
+ long val = input.selectionStart();
+ if (val != -1)
+ return Number(val);
+ else
+ return Undefined();
+ }
+ case InputSelectionEnd: {
+ long val = input.selectionEnd();
+ if (val != -1)
+ return Number(val);
+ else
+ return Undefined();
+ }
+ }
+ }
+ break;
+ case ID_TEXTAREA: {
+ DOM::HTMLTextAreaElement textarea = element;
+ switch (token) {
+ case TextAreaDefaultValue: return String(textarea.defaultValue());
+ case TextAreaForm: return getDOMNode(exec,textarea.form()); // type HTMLFormElement
+ case TextAreaAccessKey: return String(textarea.accessKey());
+ case TextAreaCols: return Number(textarea.cols());
+ case TextAreaDisabled: return Boolean(textarea.disabled());
+ case TextAreaName: return String(textarea.name());
+ case TextAreaReadOnly: return Boolean(textarea.readOnly());
+ case TextAreaRows: return Number(textarea.rows());
+ case TextAreaTabIndex: return Number(textarea.tabIndex());
+ case TextAreaType: return String(textarea.type());
+ case TextAreaValue: return String(textarea.value());
+ case TextAreaSelectionStart: return Number(textarea.selectionStart());
+ case TextAreaSelectionEnd: return Number(textarea.selectionEnd());
+ case TextAreaTextLength: return Number(textarea.textLength());
+ }
+ }
+ break;
+ case ID_BUTTON: {
+ DOM::HTMLButtonElement button = element;
+ switch (token) {
+ case ButtonForm: return getDOMNode(exec,button.form()); // type HTMLFormElement
+ case ButtonAccessKey: return String(button.accessKey());
+ case ButtonDisabled: return Boolean(button.disabled());
+ case ButtonName: return String(button.name());
+ case ButtonTabIndex: return Number(button.tabIndex());
+ case ButtonType: return String(button.type());
+ case ButtonValue: return String(button.value());
+ }
+ }
+ break;
+ case ID_LABEL: {
+ DOM::HTMLLabelElement label = element;
+ switch (token) {
+ case LabelForm: return getDOMNode(exec,label.form()); // type HTMLFormElement
+ case LabelAccessKey: return String(label.accessKey());
+ case LabelHtmlFor: return String(label.htmlFor());
+ }
+ }
+ break;
+ case ID_FIELDSET: {
+ DOM::HTMLFieldSetElement fieldSet = element;
+ switch (token) {
+ case FieldSetForm: return getDOMNode(exec,fieldSet.form()); // type HTMLFormElement
+ }
+ }
+ break;
+ case ID_LEGEND: {
+ DOM::HTMLLegendElement legend = element;
+ switch (token) {
+ case LegendForm: return getDOMNode(exec,legend.form()); // type HTMLFormElement
+ case LegendAccessKey: return String(legend.accessKey());
+ case LegendAlign: return String(legend.align());
+ }
+ }
+ break;
+ case ID_UL: {
+ DOM::HTMLUListElement uList = element;
+ switch (token) {
+ case UListCompact: return Boolean(uList.compact());
+ case UListType: return String(uList.type());
+ }
+ }
+ break;
+ case ID_OL: {
+ DOM::HTMLOListElement oList = element;
+ switch (token) {
+ case OListCompact: return Boolean(oList.compact());
+ case OListStart: return Number(oList.start());
+ case OListType: return String(oList.type());
+ }
+ }
+ break;
+ case ID_DL: {
+ DOM::HTMLDListElement dList = element;
+ switch (token) {
+ case DListCompact: return Boolean(dList.compact());
+ }
+ }
+ break;
+ case ID_DIR: {
+ DOM::HTMLDirectoryElement directory = element;
+ switch (token) {
+ case DirectoryCompact: return Boolean(directory.compact());
+ }
+ }
+ break;
+ case ID_MENU: {
+ DOM::HTMLMenuElement menu = element;
+ switch (token) {
+ case MenuCompact: return Boolean(menu.compact());
+ }
+ }
+ break;
+ case ID_LI: {
+ DOM::HTMLLIElement li = element;
+ switch (token) {
+ case LIType: return String(li.type());
+ case LIValue: return Number(li.value());
+ }
+ }
+ break;
+ case ID_DIV: {
+ DOM::HTMLDivElement div = element;
+ switch (token) {
+ case DivAlign: return String(div.align());
+ }
+ }
+ break;
+ case ID_P: {
+ DOM::HTMLParagraphElement paragraph = element;
+ switch (token) {
+ case ParagraphAlign: return String(paragraph.align());
+ }
+ }
+ break;
+ case ID_H1:
+ case ID_H2:
+ case ID_H3:
+ case ID_H4:
+ case ID_H5:
+ case ID_H6: {
+ DOM::HTMLHeadingElement heading = element;
+ switch (token) {
+ case HeadingAlign: return String(heading.align());
+ }
+ }
+ break;
+ case ID_BLOCKQUOTE: {
+ DOM::HTMLBlockquoteElement blockquote = element;
+ switch (token) {
+ case BlockQuoteCite: return String(blockquote.cite());
+ }
+ }
+ case ID_Q: {
+ DOM::HTMLQuoteElement quote = element;
+ switch (token) {
+ case QuoteCite: return String(quote.cite());
+ }
+ }
+ case ID_PRE: {
+ DOM::HTMLPreElement pre = element;
+ switch (token) {
+ case PreWidth: return Number(pre.width());
+ }
+ }
+ break;
+ case ID_BR: {
+ DOM::HTMLBRElement br = element;
+ switch (token) {
+ case BRClear: return String(br.clear());
+ }
+ }
+ break;
+ case ID_BASEFONT: {
+ DOM::HTMLBaseFontElement baseFont = element;
+ switch (token) {
+ case BaseFontColor: return String(baseFont.color());
+ case BaseFontFace: return String(baseFont.face());
+ case BaseFontSize: return Number(baseFont.getSize());
+ }
+ }
+ break;
+ case ID_FONT: {
+ DOM::HTMLFontElement font = element;
+ switch (token) {
+ case FontColor: return String(font.color());
+ case FontFace: return String(font.face());
+ case FontSize: return String(font.size());
+ }
+ }
+ break;
+ case ID_HR: {
+ DOM::HTMLHRElement hr = element;
+ switch (token) {
+ case HRAlign: return String(hr.align());
+ case HRNoShade: return Boolean(hr.noShade());
+ case HRSize: return String(hr.size());
+ case HRWidth: return String(hr.width());
+ }
+ }
+ break;
+ case ID_INS:
+ case ID_DEL: {
+ DOM::HTMLModElement mod = element;
+ switch (token) {
+ case ModCite: return String(mod.cite());
+ case ModDateTime: return String(mod.dateTime());
+ }
+ }
+ break;
+ case ID_A: {
+ DOM::HTMLAnchorElement anchor = element;
+ switch (token) {
+ case AnchorAccessKey: return String(anchor.accessKey());
+ case AnchorCharset: return String(anchor.charset());
+ case AnchorCoords: return String(anchor.coords());
+ case AnchorHref: return String(anchor.href());
+ case AnchorHrefLang: return String(anchor.hreflang());
+ case AnchorHash: return String('#'+KURL(anchor.href().string()).ref());
+ case AnchorHost: return String(KURL(anchor.href().string()).host());
+ case AnchorHostname: {
+ KURL url(anchor.href().string());
+ kdDebug(6070) << "anchor::hostname uses:" <<url.url()<<endl;
+ if (url.port()==0)
+ return String(url.host());
+ else
+ return String(url.host() + ":" + QString::number(url.port()));
+ }
+ case AnchorPathName: return String(KURL(anchor.href().string()).path());
+ case AnchorPort: return String(QString::number(KURL(anchor.href().string()).port()));
+ case AnchorProtocol: return String(KURL(anchor.href().string()).protocol()+":");
+ case AnchorSearch: { KURL u(anchor.href().string());
+ QString q = u.query();
+ if (q.length() == 1)
+ return String();
+ return String(q); }
+ case AnchorName: return String(anchor.name());
+ case AnchorRel: return String(anchor.rel());
+ case AnchorRev: return String(anchor.rev());
+ case AnchorShape: return String(anchor.shape());
+ case AnchorTabIndex: return Number(anchor.tabIndex());
+ case AnchorTarget: return String(anchor.target());
+ // Not specified in http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/a.asp
+ // Mozilla returns the inner text.
+ case AnchorText: return String(anchor.innerText());
+ case AnchorType: return String(anchor.type());
+ }
+ }
+ break;
+ case ID_IMG: {
+ DOM::HTMLImageElement image = element;
+ switch (token) {
+ case ImageName: return String(image.name()); // NOT getString (IE gives empty string)
+ case ImageAlign: return String(image.align());
+ case ImageAlt: return String(image.alt());
+ case ImageBorder: return String(image.getBorder());
+ case ImageComplete: return Boolean(static_cast<DOM::HTMLImageElementImpl*>( image.handle() )->complete());
+ case ImageHeight: return Number(image.height());
+ case ImageHspace: return Number(image.hspace());
+ case ImageIsMap: return Boolean(image.isMap());
+ case ImageLongDesc: return String(image.longDesc());
+ case ImageSrc: return String(image.src());
+ case ImageUseMap: return String(image.useMap());
+ case ImageVspace: return Number(image.vspace());
+ case ImageWidth: return Number(image.width());
+ case ImageX: return Number(image.x());
+ case ImageY: return Number(image.y());
+ }
+ }
+ break;
+ case ID_OBJECT: {
+ DOM::HTMLObjectElement object = element;
+ switch (token) {
+ case ObjectForm: return getDOMNode(exec,object.form()); // type HTMLFormElement
+ case ObjectCode: return String(object.code());
+ case ObjectAlign: return String(object.align());
+ case ObjectArchive: return String(object.archive());
+ case ObjectBorder: return String(object.border());
+ case ObjectCodeBase: return String(object.codeBase());
+ case ObjectCodeType: return String(object.codeType());
+ case ObjectContentDocument: return checkNodeSecurity(exec,object.contentDocument()) ?
+ getDOMNode(exec, object.contentDocument()) : Undefined();
+ case ObjectData: return String(object.data());
+ case ObjectDeclare: return Boolean(object.declare());
+ case ObjectHeight: return String(object.height());
+ case ObjectHspace: return Number(object.getHspace());
+ case ObjectName: return String(object.name());
+ case ObjectStandby: return String(object.standby());
+ case ObjectTabIndex: return Number(object.tabIndex());
+ case ObjectType: return String(object.type());
+ case ObjectUseMap: return String(object.useMap());
+ case ObjectVspace: return Number(object.getVspace());
+ case ObjectWidth: return String(object.width());
+ }
+ }
+ break;
+ case ID_PARAM: {
+ DOM::HTMLParamElement param = element;
+ switch (token) {
+ case ParamName: return String(param.name());
+ case ParamType: return String(param.type());
+ case ParamValue: return String(param.value());
+ case ParamValueType: return String(param.valueType());
+ }
+ }
+ break;
+ case ID_APPLET: {
+ DOM::HTMLAppletElement applet = element;
+ switch (token) {
+ case AppletAlign: return String(applet.align());
+ case AppletAlt: return String(applet.alt());
+ case AppletArchive: return String(applet.archive());
+ case AppletCode: return String(applet.code());
+ case AppletCodeBase: return String(applet.codeBase());
+ case AppletHeight: return String(applet.height());
+ case AppletHspace: return Number(applet.getHspace());
+ case AppletName: return String(applet.name());
+ case AppletObject: return String(applet.object());
+ case AppletVspace: return Number(applet.getVspace());
+ case AppletWidth: return String(applet.width());
+ }
+ }
+ break;
+ case ID_MAP: {
+ DOM::HTMLMapElement map = element;
+ switch (token) {
+ case MapAreas: return getHTMLCollection(exec, map.areas()); // type HTMLCollection
+ case MapName: return String(map.name());
+ }
+ }
+ break;
+ case ID_AREA: {
+ DOM::HTMLAreaElement area = element;
+ switch (token) {
+ case AreaAccessKey: return String(area.accessKey());
+ case AreaAlt: return String(area.alt());
+ case AreaCoords: return String(area.coords());
+ // Group everything that needs href
+ case AreaHref:
+ case AreaHash:
+ case AreaHost:
+ case AreaHostName:
+ case AreaPathName:
+ case AreaPort:
+ case AreaProtocol:
+ case AreaSearch:
+ {
+ DOM::Document doc = area.ownerDocument();
+ DOM::DOMString href = area.href();
+ KURL url;
+ if ( !href.isNull() ) {
+ url = doc.completeURL( href ).string();
+ if ( href.isEmpty() )
+ url.setFileName( QString::null ); // href="" clears the filename (in IE)
+ }
+ switch(token) {
+ case AreaHref:
+ return String(url.url());
+ case AreaHash: return String(url.isEmpty() ? "" : '#'+url.ref());
+ case AreaHost: return String(url.host());
+ case AreaHostName: {
+ if (url.port()==0)
+ return String(url.host());
+ else
+ return String(url.host() + ":" + QString::number(url.port()));
+ }
+ case AreaPathName: {
+ return String(url.path());
+ }
+ case AreaPort: return String(QString::number(url.port()));
+ case AreaProtocol: return String(url.isEmpty() ? "" : url.protocol()+":");
+ case AreaSearch: return String(url.query());
+ }
+ }
+ case AreaNoHref: return Boolean(area.noHref());
+ case AreaShape: return String(area.shape());
+ case AreaTabIndex: return Number(area.tabIndex());
+ case AreaTarget: return String(area.target());
+ }
+ }
+ break;
+ case ID_SCRIPT: {
+ DOM::HTMLScriptElement script = element;
+ switch (token) {
+ case ScriptText: return String(script.text());
+ case ScriptHtmlFor: return String(script.htmlFor());
+ case ScriptEvent: return String(script.event());
+ case ScriptCharset: return String(script.charset());
+ case ScriptDefer: return Boolean(script.defer());
+ case ScriptSrc: return String(script.src());
+ case ScriptType: return String(script.type());
+ }
+ }
+ break;
+ case ID_TABLE: {
+ DOM::HTMLTableElement table = element;
+ switch (token) {
+ case TableCaption: return getDOMNode(exec,table.caption()); // type HTMLTableCaptionElement
+ case TableTHead: return getDOMNode(exec,table.tHead()); // type HTMLTableSectionElement
+ case TableTFoot: return getDOMNode(exec,table.tFoot()); // type HTMLTableSectionElement
+ case TableRows: return getHTMLCollection(exec,table.rows()); // type HTMLCollection
+ case TableTBodies: return getHTMLCollection(exec,table.tBodies()); // type HTMLCollection
+ case TableAlign: return String(table.align());
+ case TableBgColor: return String(table.bgColor());
+ case TableBorder: return String(table.border());
+ case TableCellPadding: return String(table.cellPadding());
+ case TableCellSpacing: return String(table.cellSpacing());
+ case TableFrame: return String(table.frame());
+ case TableRules: return String(table.rules());
+ case TableSummary: return String(table.summary());
+ case TableWidth: return String(table.width());
+ }
+ }
+ break;
+ case ID_CAPTION: {
+ DOM::HTMLTableCaptionElement tableCaption = element;
+ switch (token) {
+ case TableCaptionAlign: return String(tableCaption.align());
+ }
+ }
+ break;
+ case ID_COL:
+ case ID_COLGROUP: {
+ DOM::HTMLTableColElement tableCol = element;
+ switch (token) {
+ case TableColAlign: return String(tableCol.align());
+ case TableColCh: return String(tableCol.ch());
+ case TableColChOff: return String(tableCol.chOff());
+ case TableColSpan: return Number(tableCol.span());
+ case TableColVAlign: return String(tableCol.vAlign());
+ case TableColWidth: return String(tableCol.width());
+ }
+ }
+ break;
+ case ID_THEAD:
+ case ID_TBODY:
+ case ID_TFOOT: {
+ DOM::HTMLTableSectionElement tableSection = element;
+ switch (token) {
+ case TableSectionAlign: return String(tableSection.align());
+ case TableSectionCh: return String(tableSection.ch());
+ case TableSectionChOff: return String(tableSection.chOff());
+ case TableSectionVAlign: return String(tableSection.vAlign());
+ case TableSectionRows: return getHTMLCollection(exec,tableSection.rows()); // type HTMLCollection
+ }
+ }
+ break;
+ case ID_TR: {
+ DOM::HTMLTableRowElement tableRow = element;
+ switch (token) {
+ case TableRowRowIndex: return Number(tableRow.rowIndex());
+ case TableRowSectionRowIndex: return Number(tableRow.sectionRowIndex());
+ case TableRowCells: return getHTMLCollection(exec,tableRow.cells()); // type HTMLCollection
+ case TableRowAlign: return String(tableRow.align());
+ case TableRowBgColor: return String(tableRow.bgColor());
+ case TableRowCh: return String(tableRow.ch());
+ case TableRowChOff: return String(tableRow.chOff());
+ case TableRowVAlign: return String(tableRow.vAlign());
+ }
+ }
+ break;
+ case ID_TH:
+ case ID_TD: {
+ DOM::HTMLTableCellElement tableCell = element;
+ switch (token) {
+ case TableCellCellIndex: return Number(tableCell.cellIndex());
+ case TableCellAbbr: return String(tableCell.abbr());
+ case TableCellAlign: return String(tableCell.align());
+ case TableCellAxis: return String(tableCell.axis());
+ case TableCellBgColor: return String(tableCell.bgColor());
+ case TableCellCh: return String(tableCell.ch());
+ case TableCellChOff: return String(tableCell.chOff());
+ case TableCellColSpan: return Number(tableCell.colSpan());
+ case TableCellHeaders: return String(tableCell.headers());
+ case TableCellHeight: return String(tableCell.height());
+ case TableCellNoWrap: return Boolean(tableCell.noWrap());
+ case TableCellRowSpan: return Number(tableCell.rowSpan());
+ case TableCellScope: return String(tableCell.scope());
+ case TableCellVAlign: return String(tableCell.vAlign());
+ case TableCellWidth: return String(tableCell.width());
+ }
+ }
+ break;
+ case ID_FRAMESET: {
+ DOM::HTMLFrameSetElement frameSet = element;
+ switch (token) {
+ case FrameSetCols: return String(frameSet.cols());
+ case FrameSetRows: return String(frameSet.rows());
+ }
+ }
+ break;
+ case ID_LAYER: {
+ DOM::HTMLLayerElement layerElement = element;
+ switch (token) {
+ case LayerTop: return Number(layerElement.top());
+ case LayerLeft: return Number(layerElement.left());
+ case LayerVisibility: return getString(layerElement.visibility());
+ case LayerBgColor: return getString(layerElement.bgColor());
+ /*case LayerClip: return getLayerClip(exec, layerElement); */
+ case LayerDocument: return Undefined();
+ case LayerLayers: return getHTMLCollection(exec,layerElement.layers());
+ }
+ }
+ break;
+ case ID_FRAME: {
+ DOM::HTMLFrameElement frameElement = element;
+ switch (token) {
+ case FrameContentDocument: return checkNodeSecurity(exec,frameElement.contentDocument()) ?
+ getDOMNode(exec, frameElement.contentDocument()) : Undefined();
+ case FrameContentWindow: {
+ KHTMLPart* part = static_cast<DOM::HTMLFrameElementImpl*>(frameElement.handle())->contentPart();
+ if (part) {
+ Window *w = Window::retrieveWindow(part);
+ if (w)
+ return Value(w);
+ }
+ return Undefined();
+ }
+ case FrameFrameBorder: return String(frameElement.frameBorder());
+ case FrameLongDesc: return String(frameElement.longDesc());
+ case FrameMarginHeight: return String(frameElement.marginHeight());
+ case FrameMarginWidth: return String(frameElement.marginWidth());
+ case FrameName: return String(frameElement.name());
+ case FrameNoResize: return Boolean(frameElement.noResize());
+ case FrameScrolling: return String(frameElement.scrolling());
+ case FrameSrc:
+ case FrameLocation: return String(frameElement.src());
+ // IE only
+ case FrameWidth:
+ case FrameHeight:
+ {
+ frameElement.handle()->getDocument()->updateLayout();
+ khtml::RenderObject* r = frameElement.handle()->renderer();
+ return Number( r ? (token == FrameWidth ? r->width() : r->height()) : 0 );
+ }
+ }
+ }
+ break;
+ case ID_IFRAME: {
+ DOM::HTMLIFrameElement iFrame = element;
+ switch (token) {
+ case IFrameAlign: return String(iFrame.align());
+ case IFrameContentDocument: return checkNodeSecurity(exec,iFrame.contentDocument()) ?
+ getDOMNode(exec, iFrame.contentDocument()) : Undefined();
+ case IFrameContentWindow: {
+ KHTMLPart* part = static_cast<DOM::HTMLIFrameElementImpl*>(iFrame.handle())->contentPart();
+ if (part) {
+ Window *w = Window::retrieveWindow(part);
+ if (w)
+ return Value(w);
+ }
+ return Undefined();
+ }
+ case IFrameFrameBorder: return String(iFrame.frameBorder());
+ case IFrameHeight: return String(iFrame.height());
+ case IFrameLongDesc: return String(iFrame.longDesc());
+ case IFrameMarginHeight: return String(iFrame.marginHeight());
+ case IFrameMarginWidth: return String(iFrame.marginWidth());
+ case IFrameName: return String(iFrame.name());
+ case IFrameScrolling: return String(iFrame.scrolling());
+ case IFrameSrc: return String(iFrame.src());
+ case IFrameWidth: return String(iFrame.width());
+ }
+ break;
+ }
+ } // xemacs (or arnt) could be a bit smarter when it comes to indenting switch()es ;)
+ // its not arnt to blame - its the original Stroustrup style we like :) (Dirk)
+
+ // generic properties
+ switch (token) {
+ case ElementId:
+ return String(element.id()); // String is wrong here. Other browsers return empty string if no id specified.
+ case ElementTitle:
+ return String(element.title());
+ case ElementLang:
+ return String(element.lang());
+ case ElementDir:
+ return String(element.dir());
+ case ElementClassName:
+ return String(element.className());
+ case ElementInnerHTML:
+ return String(element.innerHTML());
+ case ElementInnerText:
+ return String(element.innerText());
+ case ElementDocument:
+ return getDOMNode(exec,element.ownerDocument());
+ case ElementChildren:
+ return getHTMLCollection(exec,element.children());
+ case ElementAll:
+ // Disable element.all when we try to be Netscape-compatible
+ if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat )
+ return Undefined();
+ else
+ if ( exec->interpreter()->compatMode() == Interpreter::IECompat )
+ return getHTMLCollection(exec,element.all());
+ else // Enabled but hidden by default
+ return getHTMLCollection(exec,element.all(), true);
+ // ### what about style? or is this used instead for DOM2 stylesheets?
+ }
+ kdError() << "HTMLElement::getValueProperty unhandled token " << token << endl;
+ return Undefined();
+}
+
+bool KJS::HTMLElement::hasProperty(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ //kdDebug(6070) << "HTMLElement::hasProperty " << propertyName.qstring() << endl;
+#endif
+ DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
+ // First look at dynamic properties - keep this in sync with tryGet
+ switch (element.elementId()) {
+ case ID_FORM: {
+ DOM::HTMLFormElement form = element;
+ // Check if we're retrieving an element (by index or by name)
+ bool ok;
+ uint u = propertyName.toULong(&ok);
+ if (ok && !(form.elements().item(u).isNull()))
+ return true;
+ DOM::Node testnode = form.elements().namedItem(propertyName.string());
+ if (!testnode.isNull())
+ return true;
+ }
+ case ID_SELECT: {
+ DOM::HTMLSelectElement select = element;
+ bool ok;
+ uint u = propertyName.toULong(&ok);
+ if (ok && !(select.options().item(u).isNull()))
+ return true;
+ }
+ default:
+ break;
+ }
+
+ return DOMElement::hasProperty(exec, propertyName);
+}
+
+UString KJS::HTMLElement::toString(ExecState *exec) const
+{
+ if (node.elementId() == ID_A)
+ return UString(static_cast<const DOM::HTMLAnchorElement&>(node).href());
+ else if (node.elementId() == ID_APPLET) {
+ KParts::LiveConnectExtension *lc = getLiveConnectExtension(node);
+ QStringList qargs;
+ QString retvalue;
+ KParts::LiveConnectExtension::Type rettype;
+ unsigned long retobjid;
+ if (lc && lc->call(0, "hashCode", qargs, rettype, retobjid, retvalue)) {
+ QString str("[object APPLET ref=");
+ return UString(str + retvalue + QString("]"));
+ }
+ } else if (node.elementId() == ID_IMG) {
+ DOM::HTMLImageElement image(node);
+ if (!image.alt().isEmpty())
+ return UString(image.alt()) + " " + DOMElement::toString(exec);
+ }
+ return DOMElement::toString(exec);
+}
+
+static void getForm(DOM::HTMLFormElement* form, const DOM::HTMLElement& element)
+{
+ switch (element.elementId()) {
+ case ID_ISINDEX: {
+ DOM::HTMLIsIndexElement isindex = element;
+ *form = isindex.form();
+ break;
+ }
+ case ID_SELECT: {
+ DOM::HTMLSelectElement select = element;
+ *form = select.form();
+ break;
+ }
+ case ID_OPTION: {
+ DOM::HTMLOptionElement option = element;
+ *form = option.form();
+ break;
+ }
+ case ID_INPUT: {
+ DOM::HTMLInputElement input = element;
+ *form = input.form();
+ break;
+ }
+ case ID_TEXTAREA: {
+ DOM::HTMLTextAreaElement textarea = element;
+ *form = textarea.form();
+ break;
+ }
+ case ID_LABEL: {
+ DOM::HTMLLabelElement label = element;
+ *form = label.form();
+ break;
+ }
+ case ID_FIELDSET: {
+ DOM::HTMLFieldSetElement fieldset = element;
+ *form = fieldset.form();
+ break;
+ }
+ case ID_LEGEND: {
+ DOM::HTMLLegendElement legend = element;
+ *form = legend.form();
+ break;
+ }
+ case ID_OBJECT: {
+ DOM::HTMLObjectElement object = element;
+ *form = object.form();
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void KJS::HTMLElement::pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const
+{
+ DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
+
+ // The document is put on first, fall back to searching it only after the element and form.
+ scope.push(static_cast<ObjectImp *>(getDOMNode(exec, element.ownerDocument()).imp()));
+
+ // The form is next, searched before the document, but after the element itself.
+ DOM::HTMLFormElement formElt;
+
+ // First try to obtain the form from the element itself. We do this to deal with
+ // the malformed case where <form>s aren't in our parent chain (e.g., when they were inside
+ // <table> or <tbody>.
+ getForm(&formElt, element);
+ if (!formElt.isNull())
+ scope.push(static_cast<ObjectImp *>(getDOMNode(exec, formElt).imp()));
+ else {
+ DOM::Node form = element.parentNode();
+ while (!form.isNull() && form.elementId() != ID_FORM)
+ form = form.parentNode();
+
+ if (!form.isNull())
+ scope.push(static_cast<ObjectImp *>(getDOMNode(exec, form).imp()));
+ }
+
+ // The element is on top, searched first.
+ scope.push(static_cast<ObjectImp *>(getDOMNode(exec, element).imp()));
+}
+
+HTMLElementFunction::HTMLElementFunction(ExecState *exec, int i, int len)
+ : DOMFunction(exec), id(i)
+{
+ Value protect(this);
+ put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum);
+}
+
+Value KJS::HTMLElementFunction::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( HTMLElement, thisObj );
+
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLElementFunction::tryCall " << endl;
+#endif
+ DOM::HTMLElement element = static_cast<KJS::HTMLElement *>(thisObj.imp())->toElement();
+
+ switch (element.elementId()) {
+ case ID_FORM: {
+ DOM::HTMLFormElement form = element;
+ if (id == KJS::HTMLElement::FormSubmit) {
+
+
+ DOM::HTMLDocument doc = element.ownerDocument();
+ KHTMLView *view = static_cast<DOM::DocumentImpl*>(doc.handle())->view();
+ KHTMLSettings::KJSWindowOpenPolicy policy = KHTMLSettings::KJSWindowOpenAllow;
+ if (view)
+ policy = view->part()->settings()->windowOpenPolicy(view->part()->url().host());
+
+ bool block = false;
+
+ if ( policy != KHTMLSettings::KJSWindowOpenAllow ) {
+ block = true;
+
+ // if this is a form without a target, or a special target, don't block
+ QString trg = form.target().lower().string();
+ if( trg.isEmpty() || trg == "_top" || trg == "_self" ||
+ trg == "_parent")
+ block = false;
+
+ QString caption;
+
+ // if there is a frame with the target name, don't block
+ if ( view && view->part() ) {
+ if (!view->part()->url().host().isEmpty())
+ caption = view->part()->url().host() + " - ";
+ // search all (possibly nested) framesets
+ KHTMLPart *currentPart = view->part()->parentPart();
+ while( currentPart != 0L ) {
+ if( currentPart->frameExists( form.target().string() ) )
+ block = false;
+ currentPart = currentPart->parentPart();
+ }
+ }
+
+ if ( block && policy == KHTMLSettings::KJSWindowOpenAsk && view ) {
+ if (view && view->part())
+ emit view->part()->browserExtension()->requestFocus(view->part());
+ caption += i18n( "Confirmation: JavaScript Popup" );
+ if ( KMessageBox::questionYesNo(view, form.action().isEmpty() ?
+ i18n( "This site is submitting a form which will open up a new browser "
+ "window via JavaScript.\n"
+ "Do you want to allow the form to be submitted?" ) :
+ i18n( "<qt>This site is submitting a form which will open <p>%1</p> in a new browser window via JavaScript.<br />"
+ "Do you want to allow the form to be submitted?</qt>").arg(KStringHandler::csqueeze(form.action().string(), 100)),
+ caption, i18n("Allow"), i18n("Do Not Allow") ) == KMessageBox::Yes )
+ block = false;
+
+ } else if ( block && policy == KHTMLSettings::KJSWindowOpenSmart ) {
+ if( static_cast<KJS::ScriptInterpreter *>(exec->interpreter())->isWindowOpenAllowed() ) {
+ // This submission has been triggered by the user
+ block = false;
+ }
+ }
+ }
+
+ if( !block )
+ form.submit();
+
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::FormReset) {
+ form.reset();
+ return Undefined();
+ }
+ }
+ break;
+ case ID_BODY: {
+ if (id == KJS::HTMLElement::BodyFocus) {
+ // Just blur everything. Not perfect, but good enough for now
+ if (DOM::NodeImpl* impl = element.handle()) {
+ impl->getDocument()->setFocusNode(0);
+ }
+ }
+ }
+ break;
+ case ID_SELECT: {
+ DOM::HTMLSelectElement select = element;
+ if (id == KJS::HTMLElement::SelectAdd) {
+ select.add(KJS::toNode(args[0]),KJS::toNode(args[1]));
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::SelectRemove) {
+ select.remove(int(args[0].toNumber(exec)));
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::SelectBlur) {
+ select.blur();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::SelectFocus) {
+ select.focus();
+ return Undefined();
+ }
+ }
+ break;
+ case ID_INPUT: {
+ DOM::HTMLInputElement input = element;
+ if (id == KJS::HTMLElement::InputBlur) {
+ input.blur();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::InputFocus) {
+ input.focus();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::InputSelect) {
+ input.select();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::InputClick) {
+ input.click();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::InputSetSelectionRange) {
+ input.setSelectionRange(args[0].toNumber(exec), args[1].toNumber(exec));
+ return Undefined();
+ }
+ }
+ break;
+ case ID_BUTTON: {
+ DOM::HTMLButtonElement button = element;
+ if (id == KJS::HTMLElement::ButtonBlur) {
+ button.blur();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::ButtonFocus) {
+ button.focus();
+ return Undefined();
+ }
+ }
+ break;
+ case ID_TEXTAREA: {
+ DOM::HTMLTextAreaElement textarea = element;
+ if (id == KJS::HTMLElement::TextAreaBlur) {
+ textarea.blur();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::TextAreaFocus) {
+ textarea.focus();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::TextAreaSelect) {
+ textarea.select();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::TextAreaSetSelectionRange) {
+ textarea.setSelectionRange(args[0].toNumber(exec), args[1].toNumber(exec));
+ return Undefined();
+ }
+
+ }
+ break;
+ case ID_A: {
+ DOM::HTMLAnchorElement anchor = element;
+ if (id == KJS::HTMLElement::AnchorBlur) {
+ anchor.blur();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::AnchorFocus) {
+ anchor.focus();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::AnchorClick) {
+ static_cast<DOM::HTMLAnchorElementImpl*>(anchor.handle())->click();
+ return Undefined();
+ }
+ }
+ break;
+ case ID_TABLE: {
+ DOM::HTMLTableElement table = element;
+ if (id == KJS::HTMLElement::TableCreateTHead)
+ return getDOMNode(exec,table.createTHead());
+ else if (id == KJS::HTMLElement::TableDeleteTHead) {
+ table.deleteTHead();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::TableCreateTFoot)
+ return getDOMNode(exec,table.createTFoot());
+ else if (id == KJS::HTMLElement::TableDeleteTFoot) {
+ table.deleteTFoot();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::TableCreateCaption)
+ return getDOMNode(exec,table.createCaption());
+ else if (id == KJS::HTMLElement::TableDeleteCaption) {
+ table.deleteCaption();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::TableInsertRow)
+ return getDOMNode(exec,table.insertRow(args[0].toInteger(exec)));
+ else if (id == KJS::HTMLElement::TableDeleteRow) {
+ table.deleteRow(args[0].toInteger(exec));
+ return Undefined();
+ }
+ }
+ break;
+ case ID_THEAD:
+ case ID_TBODY:
+ case ID_TFOOT: {
+ DOM::HTMLTableSectionElement tableSection = element;
+ if (id == KJS::HTMLElement::TableSectionInsertRow)
+ return getDOMNode(exec,tableSection.insertRow(args[0].toInteger(exec)));
+ else if (id == KJS::HTMLElement::TableSectionDeleteRow) {
+ tableSection.deleteRow(args[0].toInteger(exec));
+ return Undefined();
+ }
+ }
+ break;
+ case ID_TR: {
+ DOM::HTMLTableRowElement tableRow = element;
+ if (id == KJS::HTMLElement::TableRowInsertCell)
+ return getDOMNode(exec,tableRow.insertCell(args[0].toInteger(exec)));
+ else if (id == KJS::HTMLElement::TableRowDeleteCell) {
+ tableRow.deleteCell(args[0].toInteger(exec));
+ return Undefined();
+ }
+ break;
+ }
+ case ID_MARQUEE: {
+ if (id == KJS::HTMLElement::MarqueeStart && element.handle()->renderer() &&
+ element.handle()->renderer()->layer() &&
+ element.handle()->renderer()->layer()->marquee()) {
+ element.handle()->renderer()->layer()->marquee()->start();
+ return Undefined();
+ }
+ else if (id == KJS::HTMLElement::MarqueeStop && element.handle()->renderer() &&
+ element.handle()->renderer()->layer() &&
+ element.handle()->renderer()->layer()->marquee()) {
+ element.handle()->renderer()->layer()->marquee()->stop();
+ return Undefined();
+ }
+ break;
+ }
+ }
+
+ if (id == HTMLElement::ElementScrollIntoView) {
+ bool alignToTop = true;
+ if (args.size() > 0)
+ alignToTop = args[0].toBoolean(exec);
+ static_cast<HTMLElementImpl*>(element.handle())->scrollIntoView(alignToTop);
+ return Undefined();
+ }
+
+ return Undefined();
+}
+
+void KJS::HTMLElement::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+#ifdef KJS_VERBOSE
+ DOM::DOMString str = value.isA(NullType) ? DOM::DOMString() : value.toString(exec).string();
+#endif
+ DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLElement::tryPut " << propertyName.qstring()
+ << " thisTag=" << element.tagName().string()
+ << " str=" << str.string() << endl;
+#endif
+ // First look at dynamic properties
+ switch (element.elementId()) {
+ case ID_SELECT: {
+ DOM::HTMLSelectElement select = element;
+ bool ok;
+ /*uint u =*/ propertyName.toULong(&ok);
+ if (ok) {
+ Object coll = Object::dynamicCast( getSelectHTMLCollection(exec, select.options(), select) );
+ if ( coll.isValid() )
+ coll.put(exec,propertyName,value);
+ return;
+ }
+ break;
+ }
+ case ID_APPLET:
+ case ID_OBJECT:
+ case ID_EMBED: {
+ KParts::LiveConnectExtension *lc = getLiveConnectExtension(element);
+ if (lc && lc->put(0, propertyName.qstring(), value.toString(exec).qstring()))
+ return;
+ break;
+ }
+ default:
+ break;
+ }
+
+ const HashTable* table = classInfo()->propHashTable; // get the right hashtable
+ const HashEntry* entry = table ? Lookup::findEntry(table, propertyName) : 0;
+ if (entry) {
+ if (entry->attr & Function) // function: put as override property
+ {
+ ObjectImp::put(exec, propertyName, value, attr);
+ return;
+ }
+ else if ((entry->attr & ReadOnly) == 0) // let DOMObjectLookupPut print the warning if not
+ {
+ putValueProperty(exec, entry->value, value, attr);
+ return;
+ }
+ }
+ DOMObjectLookupPut<KJS::HTMLElement, DOMElement>(exec, propertyName, value, attr, &KJS::HTMLElementTable, this);
+}
+
+void KJS::HTMLElement::putValueProperty(ExecState *exec, int token, const Value& value, int)
+{
+ DOM::DOMString str = value.isA(NullType) ? DOM::DOMString() : value.toString(exec).string();
+ DOMNode *kjsNode = new DOMNode(exec, KJS::toNode(value));
+ // Need to create a Value wrapper to avoid leaking the KJS::DOMNode
+ Value nodeValue(kjsNode);
+ DOM::Node n = kjsNode->toNode();
+ DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLElement::putValueProperty "
+ << " thisTag=" << element.tagName().string()
+ << " token=" << token << endl;
+#endif
+
+ switch (element.elementId()) {
+ case ID_HTML: {
+ DOM::HTMLHtmlElement html = element;
+ switch (token) {
+ case HtmlVersion: { html.setVersion(str); return; }
+ }
+ }
+ break;
+ case ID_HEAD: {
+ DOM::HTMLHeadElement head = element;
+ switch (token) {
+ case HeadProfile: { head.setProfile(str); return; }
+ }
+ }
+ break;
+ case ID_LINK: {
+ DOM::HTMLLinkElement link = element;
+ switch (token) {
+ case LinkDisabled: { link.setDisabled(value.toBoolean(exec)); return; }
+ case LinkCharset: { link.setCharset(str); return; }
+ case LinkHref: { link.setHref(str); return; }
+ case LinkHrefLang: { link.setHreflang(str); return; }
+ case LinkMedia: { link.setMedia(str); return; }
+ case LinkRel: { link.setRel(str); return; }
+ case LinkRev: { link.setRev(str); return; }
+ case LinkTarget: { link.setTarget(str); return; }
+ case LinkType: { link.setType(str); return; }
+ }
+ }
+ break;
+ case ID_TITLE: {
+ DOM::HTMLTitleElement title = element;
+ switch (token) {
+ case TitleText: { title.setText(str); return; }
+ }
+ }
+ break;
+ case ID_META: {
+ DOM::HTMLMetaElement meta = element;
+ switch (token) {
+ case MetaContent: { meta.setContent(str); return; }
+ case MetaHttpEquiv: { meta.setHttpEquiv(str); return; }
+ case MetaName: { meta.setName(str); return; }
+ case MetaScheme: { meta.setScheme(str); return; }
+ }
+ }
+ break;
+ case ID_BASE: {
+ DOM::HTMLBaseElement base = element;
+ switch (token) {
+ case BaseHref: { base.setHref(str); return; }
+ case BaseTarget: { base.setTarget(str); return; }
+ }
+ }
+ break;
+ case ID_ISINDEX: {
+ DOM::HTMLIsIndexElement isindex = element;
+ switch (token) {
+ // read-only: form
+ case IsIndexPrompt: { isindex.setPrompt(str); return; }
+ }
+ }
+ break;
+ case ID_STYLE: {
+ DOM::HTMLStyleElement style = element;
+ switch (token) {
+ case StyleDisabled: { style.setDisabled(value.toBoolean(exec)); return; }
+ case StyleMedia: { style.setMedia(str); return; }
+ case StyleType: { style.setType(str); return; }
+ }
+ }
+ break;
+ case ID_BODY: {
+ DOM::HTMLBodyElement body = element;
+ switch (token) {
+ case BodyALink: { body.setALink(str); return; }
+ case BodyBackground: { body.setBackground(str); return; }
+ case BodyBgColor: { body.setBgColor(str); return; }
+ case BodyLink: { body.setLink(str); return; }
+ case BodyText: { body.setText(str); return; }
+ case BodyVLink: { body.setVLink(str); return; }
+ case BodyOnLoad:
+ DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl *>(node.ownerDocument().handle());
+ if (doc && checkNodeSecurity(exec, node))
+ {
+ DOMNode* kjsDocNode = new DOMNode(exec, doc);
+ // Need to create a Value wrapper to avoid leaking the KJS::DOMNode
+ Value nodeValue(kjsDocNode);
+ kjsDocNode->setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
+ }
+ return;
+ }
+ }
+ break;
+ case ID_FORM: {
+ DOM::HTMLFormElement form = element;
+ switch (token) {
+ // read-only: elements
+ // read-only: length
+ case FormName: { form.setName(str); return; }
+ case FormAcceptCharset: { form.setAcceptCharset(str); return; }
+ case FormAction: { form.setAction(str.string()); return; }
+ case FormEncType: { form.setEnctype(str); return; }
+ case FormMethod: { form.setMethod(str); return; }
+ case FormTarget: { form.setTarget(str); return; }
+ }
+ }
+ break;
+ case ID_SELECT: {
+ DOM::HTMLSelectElement select = element;
+ switch (token) {
+ // read-only: type
+ case SelectSelectedIndex: { select.setSelectedIndex(value.toInteger(exec)); return; }
+ case SelectValue: { select.setValue(str); return; }
+ case SelectLength: { // read-only according to the NS spec, but webpages need it writeable
+ Object coll = Object::dynamicCast( getSelectHTMLCollection(exec, select.options(), select) );
+ if ( coll.isValid() )
+ coll.put(exec,"length",value);
+ return;
+ }
+ // read-only: form
+ // read-only: options
+ case SelectDisabled: { select.setDisabled(value.toBoolean(exec)); return; }
+ case SelectMultiple: { select.setMultiple(value.toBoolean(exec)); return; }
+ case SelectName: { select.setName(str); return; }
+ case SelectSize: { select.setSize(value.toInteger(exec)); return; }
+ case SelectTabIndex: { select.setTabIndex(value.toInteger(exec)); return; }
+ }
+ }
+ break;
+ case ID_OPTGROUP: {
+ DOM::HTMLOptGroupElement optgroup = element;
+ switch (token) {
+ case OptGroupDisabled: { optgroup.setDisabled(value.toBoolean(exec)); return; }
+ case OptGroupLabel: { optgroup.setLabel(str); return; }
+ }
+ }
+ break;
+ case ID_OPTION: {
+ DOM::HTMLOptionElement option = element;
+ switch (token) {
+ // read-only: form
+ case OptionDefaultSelected: { option.setDefaultSelected(value.toBoolean(exec)); return; }
+ // read-only: text <--- According to the DOM, but JavaScript and JScript both allow changes.
+ // So, we'll do it here and not add it to our DOM headers.
+ case OptionText: { DOM::NodeList nl(option.childNodes());
+ for (unsigned int i = 0; i < nl.length(); i++) {
+ if (nl.item(i).nodeType() == DOM::Node::TEXT_NODE) {
+ static_cast<DOM::Text>(nl.item(i)).setData(str);
+ return;
+ }
+ }
+ // No child text node found, creating one
+ DOM::Text t = option.ownerDocument().createTextNode(str);
+ try { option.appendChild(t); }
+ catch(DOM::DOMException& e) {
+ // #### exec->setException ?
+ }
+
+ return;
+ }
+ // read-only: index
+ case OptionDisabled: { option.setDisabled(value.toBoolean(exec)); return; }
+ case OptionLabel: { option.setLabel(str); return; }
+ case OptionSelected: { option.setSelected(value.toBoolean(exec)); return; }
+ case OptionValue: { option.setValue(str); return; }
+ }
+ }
+ break;
+ case ID_INPUT: {
+ DOM::HTMLInputElement input = element;
+ switch (token) {
+ case InputDefaultValue: { input.setDefaultValue(str); return; }
+ case InputDefaultChecked: { input.setDefaultChecked(value.toBoolean(exec)); return; }
+ // read-only: form
+ case InputAccept: { input.setAccept(str); return; }
+ case InputAccessKey: { input.setAccessKey(str); return; }
+ case InputAlign: { input.setAlign(str); return; }
+ case InputAlt: { input.setAlt(str); return; }
+ case InputChecked: { input.setChecked(value.toBoolean(exec)); return; }
+ case InputIndeterminate: { input.setIndeterminate(value.toBoolean(exec)); return; }
+ case InputDisabled: { input.setDisabled(value.toBoolean(exec)); return; }
+ case InputMaxLength: { input.setMaxLength(value.toInteger(exec)); return; }
+ case InputName: { input.setName(str); return; }
+ case InputReadOnly: { input.setReadOnly(value.toBoolean(exec)); return; }
+ case InputSize: { input.setSize(value.toInteger(exec)); return; }
+ case InputSrc: { input.setSrc(str); return; }
+ case InputTabIndex: { input.setTabIndex(value.toInteger(exec)); return; }
+ case InputType: { input.setType(str); return; }
+ case InputUseMap: { input.setUseMap(str); return; }
+ case InputValue: { input.setValue(str); return; }
+ case InputSelectionStart: { input.setSelectionStart(value.toInteger(exec)); return; }
+ case InputSelectionEnd: { input.setSelectionEnd (value.toInteger(exec)); return; }
+ }
+ }
+ break;
+ case ID_TEXTAREA: {
+ DOM::HTMLTextAreaElement textarea = element;
+ switch (token) {
+ case TextAreaDefaultValue: { textarea.setDefaultValue(str); return; }
+ // read-only: form
+ case TextAreaAccessKey: { textarea.setAccessKey(str); return; }
+ case TextAreaCols: { textarea.setCols(value.toInteger(exec)); return; }
+ case TextAreaDisabled: { textarea.setDisabled(value.toBoolean(exec)); return; }
+ case TextAreaName: { textarea.setName(str); return; }
+ case TextAreaReadOnly: { textarea.setReadOnly(value.toBoolean(exec)); return; }
+ case TextAreaRows: { textarea.setRows(value.toInteger(exec)); return; }
+ case TextAreaTabIndex: { textarea.setTabIndex(value.toInteger(exec)); return; }
+ // read-only: type
+ case TextAreaValue: { textarea.setValue(str); return; }
+ case TextAreaSelectionStart: { textarea.setSelectionStart(value.toInteger(exec)); return; }
+ case TextAreaSelectionEnd: { textarea.setSelectionEnd (value.toInteger(exec)); return; }
+ }
+ }
+ break;
+ case ID_BUTTON: {
+ DOM::HTMLButtonElement button = element;
+ switch (token) {
+ // read-only: form
+ case ButtonAccessKey: { button.setAccessKey(str); return; }
+ case ButtonDisabled: { button.setDisabled(value.toBoolean(exec)); return; }
+ case ButtonName: { button.setName(str); return; }
+ case ButtonTabIndex: { button.setTabIndex(value.toInteger(exec)); return; }
+ // read-only: type
+ case ButtonValue: { button.setValue(str); return; }
+ }
+ }
+ break;
+ case ID_LABEL: {
+ DOM::HTMLLabelElement label = element;
+ switch (token) {
+ // read-only: form
+ case LabelAccessKey: { label.setAccessKey(str); return; }
+ case LabelHtmlFor: { label.setHtmlFor(str); return; }
+ }
+ }
+ break;
+// case ID_FIELDSET: {
+// DOM::HTMLFieldSetElement fieldSet = element;
+// // read-only: form
+// }
+// break;
+ case ID_LEGEND: {
+ DOM::HTMLLegendElement legend = element;
+ switch (token) {
+ // read-only: form
+ case LegendAccessKey: { legend.setAccessKey(str); return; }
+ case LegendAlign: { legend.setAlign(str); return; }
+ }
+ }
+ break;
+ case ID_UL: {
+ DOM::HTMLUListElement uList = element;
+ switch (token) {
+ case UListCompact: { uList.setCompact(value.toBoolean(exec)); return; }
+ case UListType: { uList.setType(str); return; }
+ }
+ }
+ break;
+ case ID_OL: {
+ DOM::HTMLOListElement oList = element;
+ switch (token) {
+ case OListCompact: { oList.setCompact(value.toBoolean(exec)); return; }
+ case OListStart: { oList.setStart(value.toInteger(exec)); return; }
+ case OListType: { oList.setType(str); return; }
+ }
+ }
+ break;
+ case ID_DL: {
+ DOM::HTMLDListElement dList = element;
+ switch (token) {
+ case DListCompact: { dList.setCompact(value.toBoolean(exec)); return; }
+ }
+ }
+ break;
+ case ID_DIR: {
+ DOM::HTMLDirectoryElement directory = element;
+ switch (token) {
+ case DirectoryCompact: { directory.setCompact(value.toBoolean(exec)); return; }
+ }
+ }
+ break;
+ case ID_MENU: {
+ DOM::HTMLMenuElement menu = element;
+ switch (token) {
+ case MenuCompact: { menu.setCompact(value.toBoolean(exec)); return; }
+ }
+ }
+ break;
+ case ID_LI: {
+ DOM::HTMLLIElement li = element;
+ switch (token) {
+ case LIType: { li.setType(str); return; }
+ case LIValue: { li.setValue(value.toInteger(exec)); return; }
+ }
+ }
+ break;
+ case ID_DIV: {
+ DOM::HTMLDivElement div = element;
+ switch (token) {
+ case DivAlign: { div.setAlign(str); return; }
+ }
+ }
+ break;
+ case ID_P: {
+ DOM::HTMLParagraphElement paragraph = element;
+ switch (token) {
+ case ParagraphAlign: { paragraph.setAlign(str); return; }
+ }
+ }
+ break;
+ case ID_H1:
+ case ID_H2:
+ case ID_H3:
+ case ID_H4:
+ case ID_H5:
+ case ID_H6: {
+ DOM::HTMLHeadingElement heading = element;
+ switch (token) {
+ case HeadingAlign: { heading.setAlign(str); return; }
+ }
+ }
+ break;
+ case ID_BLOCKQUOTE: {
+ DOM::HTMLBlockquoteElement blockquote = element;
+ switch (token) {
+ case BlockQuoteCite: { blockquote.setCite(str); return; }
+ }
+ }
+ break;
+ case ID_Q: {
+ DOM::HTMLQuoteElement quote = element;
+ switch (token) {
+ case QuoteCite: { quote.setCite(str); return; }
+ }
+ }
+ break;
+ case ID_PRE: {
+ DOM::HTMLPreElement pre = element;
+ switch (token) {
+ case PreWidth: { pre.setWidth(value.toInteger(exec)); return; }
+ }
+ }
+ break;
+ case ID_BR: {
+ DOM::HTMLBRElement br = element;
+ switch (token) {
+ case BRClear: { br.setClear(str); return; }
+ }
+ }
+ break;
+ case ID_BASEFONT: {
+ DOM::HTMLBaseFontElement baseFont = element;
+ switch (token) {
+ case BaseFontColor: { baseFont.setColor(str); return; }
+ case BaseFontFace: { baseFont.setFace(str); return; }
+ case BaseFontSize: { baseFont.setSize(value.toInteger(exec)); return; }
+ }
+ }
+ break;
+ case ID_FONT: {
+ DOM::HTMLFontElement font = element;
+ switch (token) {
+ case FontColor: { font.setColor(str); return; }
+ case FontFace: { font.setFace(str); return; }
+ case FontSize: { font.setSize(str); return; }
+ }
+ }
+ break;
+ case ID_HR: {
+ DOM::HTMLHRElement hr = element;
+ switch (token) {
+ case HRAlign: { hr.setAlign(str); return; }
+ case HRNoShade: { hr.setNoShade(value.toBoolean(exec)); return; }
+ case HRSize: { hr.setSize(str); return; }
+ case HRWidth: { hr.setWidth(str); return; }
+ }
+ }
+ break;
+ case ID_INS:
+ case ID_DEL: {
+ DOM::HTMLModElement mod = element;
+ switch (token) {
+ case ModCite: { mod.setCite(str); return; }
+ case ModDateTime: { mod.setDateTime(str); return; }
+ }
+ }
+ break;
+ case ID_A: {
+ DOM::HTMLAnchorElement anchor = element;
+ switch (token) {
+ case AnchorAccessKey: { anchor.setAccessKey(str); return; }
+ case AnchorCharset: { anchor.setCharset(str); return; }
+ case AnchorCoords: { anchor.setCoords(str); return; }
+ case AnchorHref: { anchor.setHref(str); return; }
+ case AnchorHrefLang: { anchor.setHreflang(str); return; }
+ case AnchorSearch: { KURL href(anchor.href().string());
+ QString q = str.isEmpty() ? QString() : str.string();
+ href.setQuery(q);
+ anchor.setHref(href.url()); return; }
+ case AnchorName: { anchor.setName(str); return; }
+ case AnchorRel: { anchor.setRel(str); return; }
+ case AnchorRev: { anchor.setRev(str); return; }
+ case AnchorShape: { anchor.setShape(str); return; }
+ case AnchorTabIndex: { anchor.setTabIndex(value.toInteger(exec)); return; }
+ case AnchorTarget: { anchor.setTarget(str); return; }
+ case AnchorType: { anchor.setType(str); return; }
+ }
+ }
+ break;
+ case ID_IMG: {
+ DOM::HTMLImageElement image = element;
+ switch (token) {
+ case ImageName: { image.setName(str); return; }
+ case ImageAlign: { image.setAlign(str); return; }
+ case ImageAlt: { image.setAlt(str); return; }
+ case ImageBorder: { image.setBorder(str); return; }
+ case ImageHeight: { image.setHeight(value.toInteger(exec)); return; }
+ case ImageHspace: { image.setHspace(value.toInteger(exec)); return; }
+ case ImageIsMap: { image.setIsMap(value.toBoolean(exec)); return; }
+ case ImageLongDesc: { image.setLongDesc(str); return; }
+ case ImageSrc: { image.setSrc(str); return; }
+ case ImageUseMap: { image.setUseMap(str); return; }
+ case ImageVspace: { image.setVspace(value.toInteger(exec)); return; }
+ case ImageWidth: { image.setWidth(value.toInteger(exec)); return; }
+ }
+ }
+ break;
+ case ID_OBJECT: {
+ DOM::HTMLObjectElement object = element;
+ switch (token) {
+ // read-only: form
+ case ObjectCode: { object.setCode(str); return; }
+ case ObjectAlign: { object.setAlign(str); return; }
+ case ObjectArchive: { object.setArchive(str); return; }
+ case ObjectBorder: { object.setBorder(str); return; }
+ case ObjectCodeBase: { object.setCodeBase(str); return; }
+ case ObjectCodeType: { object.setCodeType(str); return; }
+ // read-only: ObjectContentDocument
+ case ObjectData: { object.setData(str); return; }
+ case ObjectDeclare: { object.setDeclare(value.toBoolean(exec)); return; }
+ case ObjectHeight: { object.setHeight(str); return; }
+ case ObjectHspace: { object.setHspace(value.toInteger(exec)); return; }
+ case ObjectName: { object.setName(str); return; }
+ case ObjectStandby: { object.setStandby(str); return; }
+ case ObjectTabIndex: { object.setTabIndex(value.toInteger(exec)); return; }
+ case ObjectType: { object.setType(str); return; }
+ case ObjectUseMap: { object.setUseMap(str); return; }
+ case ObjectVspace: { object.setVspace(value.toInteger(exec)); return; }
+ case ObjectWidth: { object.setWidth(str); return; }
+ }
+ }
+ break;
+ case ID_PARAM: {
+ DOM::HTMLParamElement param = element;
+ switch (token) {
+ case ParamName: { param.setName(str); return; }
+ case ParamType: { param.setType(str); return; }
+ case ParamValue: { param.setValue(str); return; }
+ case ParamValueType: { param.setValueType(str); return; }
+ }
+ }
+ break;
+ case ID_APPLET: {
+ DOM::HTMLAppletElement applet = element;
+ switch (token) {
+ case AppletAlign: { applet.setAlign(str); return; }
+ case AppletAlt: { applet.setAlt(str); return; }
+ case AppletArchive: { applet.setArchive(str); return; }
+ case AppletCode: { applet.setCode(str); return; }
+ case AppletCodeBase: { applet.setCodeBase(str); return; }
+ case AppletHeight: { applet.setHeight(str); return; }
+ case AppletHspace: { applet.setHspace(value.toInteger(exec)); return; }
+ case AppletName: { applet.setName(str); return; }
+ case AppletObject: { applet.setObject(str); return; }
+ case AppletVspace: { applet.setVspace(value.toInteger(exec)); return; }
+ case AppletWidth: { applet.setWidth(str); return; }
+ }
+ }
+ break;
+ case ID_MAP: {
+ DOM::HTMLMapElement map = element;
+ switch (token) {
+ // read-only: areas
+ case MapName: { map.setName(str); return; }
+ }
+ }
+ break;
+ case ID_AREA: {
+ DOM::HTMLAreaElement area = element;
+ switch (token) {
+ case AreaAccessKey: { area.setAccessKey(str); return; }
+ case AreaAlt: { area.setAlt(str); return; }
+ case AreaCoords: { area.setCoords(str); return; }
+ case AreaHref: { area.setHref(str); return; }
+ case AreaNoHref: { area.setNoHref(value.toBoolean(exec)); return; }
+ case AreaShape: { area.setShape(str); return; }
+ case AreaTabIndex: { area.setTabIndex(value.toInteger(exec)); return; }
+ case AreaTarget: { area.setTarget(str); return; }
+ }
+ }
+ break;
+ case ID_SCRIPT: {
+ DOM::HTMLScriptElement script = element;
+ switch (token) {
+ case ScriptText: { script.setText(str); return; }
+ case ScriptHtmlFor: { script.setHtmlFor(str); return; }
+ case ScriptEvent: { script.setEvent(str); return; }
+ case ScriptCharset: { script.setCharset(str); return; }
+ case ScriptDefer: { script.setDefer(value.toBoolean(exec)); return; }
+ case ScriptSrc: { script.setSrc(str); return; }
+ case ScriptType: { script.setType(str); return; }
+ }
+ }
+ break;
+ case ID_TABLE: {
+ DOM::HTMLTableElement table = element;
+ switch (token) {
+ case TableCaption: { table.setCaption(n); return; } // type HTMLTableCaptionElement
+ case TableTHead: { table.setTHead(n); return; } // type HTMLTableSectionElement
+ case TableTFoot: { table.setTFoot(n); return; } // type HTMLTableSectionElement
+ // read-only: rows
+ // read-only: tbodies
+ case TableAlign: { table.setAlign(str); return; }
+ case TableBgColor: { table.setBgColor(str); return; }
+ case TableBorder: { table.setBorder(str); return; }
+ case TableCellPadding: { table.setCellPadding(str); return; }
+ case TableCellSpacing: { table.setCellSpacing(str); return; }
+ case TableFrame: { table.setFrame(str); return; }
+ case TableRules: { table.setRules(str); return; }
+ case TableSummary: { table.setSummary(str); return; }
+ case TableWidth: { table.setWidth(str); return; }
+ }
+ }
+ break;
+ case ID_CAPTION: {
+ DOM::HTMLTableCaptionElement tableCaption = element;
+ switch (token) {
+ case TableCaptionAlign: { tableCaption.setAlign(str); return; }
+ }
+ }
+ break;
+ case ID_COL:
+ case ID_COLGROUP: {
+ DOM::HTMLTableColElement tableCol = element;
+ switch (token) {
+ case TableColAlign: { tableCol.setAlign(str); return; }
+ case TableColCh: { tableCol.setCh(str); return; }
+ case TableColChOff: { tableCol.setChOff(str); return; }
+ case TableColSpan: { tableCol.setSpan(value.toInteger(exec)); return; }
+ case TableColVAlign: { tableCol.setVAlign(str); return; }
+ case TableColWidth: { tableCol.setWidth(str); return; }
+ }
+ }
+ break;
+ case ID_THEAD:
+ case ID_TBODY:
+ case ID_TFOOT: {
+ DOM::HTMLTableSectionElement tableSection = element;
+ switch (token) {
+ case TableSectionAlign: { tableSection.setAlign(str); return; }
+ case TableSectionCh: { tableSection.setCh(str); return; }
+ case TableSectionChOff: { tableSection.setChOff(str); return; }
+ case TableSectionVAlign: { tableSection.setVAlign(str); return; }
+ // read-only: rows
+ }
+ }
+ break;
+ case ID_TR: {
+ DOM::HTMLTableRowElement tableRow = element;
+ switch (token) {
+ // read-only: rowIndex
+ // read-only: sectionRowIndex
+ // read-only: cells
+ case TableRowAlign: { tableRow.setAlign(str); return; }
+ case TableRowBgColor: { tableRow.setBgColor(str); return; }
+ case TableRowCh: { tableRow.setCh(str); return; }
+ case TableRowChOff: { tableRow.setChOff(str); return; }
+ case TableRowVAlign: { tableRow.setVAlign(str); return; }
+ }
+ }
+ break;
+ case ID_TH:
+ case ID_TD: {
+ DOM::HTMLTableCellElement tableCell = element;
+ switch (token) {
+ // read-only: cellIndex
+ case TableCellAbbr: { tableCell.setAbbr(str); return; }
+ case TableCellAlign: { tableCell.setAlign(str); return; }
+ case TableCellAxis: { tableCell.setAxis(str); return; }
+ case TableCellBgColor: { tableCell.setBgColor(str); return; }
+ case TableCellCh: { tableCell.setCh(str); return; }
+ case TableCellChOff: { tableCell.setChOff(str); return; }
+ case TableCellColSpan: { tableCell.setColSpan(value.toInteger(exec)); return; }
+ case TableCellHeaders: { tableCell.setHeaders(str); return; }
+ case TableCellHeight: { tableCell.setHeight(str); return; }
+ case TableCellNoWrap: { tableCell.setNoWrap(value.toBoolean(exec)); return; }
+ case TableCellRowSpan: { tableCell.setRowSpan(value.toInteger(exec)); return; }
+ case TableCellScope: { tableCell.setScope(str); return; }
+ case TableCellVAlign: { tableCell.setVAlign(str); return; }
+ case TableCellWidth: { tableCell.setWidth(str); return; }
+ }
+ }
+ break;
+ case ID_FRAMESET: {
+ DOM::HTMLFrameSetElement frameSet = element;
+ switch (token) {
+ case FrameSetCols: { frameSet.setCols(str); return; }
+ case FrameSetRows: { frameSet.setRows(str); return; }
+ }
+ }
+ break;
+ case ID_LAYER: {
+ DOM::HTMLLayerElement layerElement = element;
+ switch (token) {
+ case LayerTop: { layerElement.setTop(value.toInteger(exec)); return; }
+ case LayerLeft: { layerElement.setLeft(value.toInteger(exec)); return; }
+ case LayerVisibility: { layerElement.setVisibility(str); return; }
+ case LayerBgColor: { layerElement.setBgColor(str); return; }
+ // read-only: layers, clip
+ }
+ }
+ break;
+ case ID_FRAME: {
+ DOM::HTMLFrameElement frameElement = element;
+ switch (token) {
+ // read-only: FrameContentDocument:
+ case FrameFrameBorder: { frameElement.setFrameBorder(str); return; }
+ case FrameLongDesc: { frameElement.setLongDesc(str); return; }
+ case FrameMarginHeight: { frameElement.setMarginHeight(str); return; }
+ case FrameMarginWidth: { frameElement.setMarginWidth(str); return; }
+ case FrameName: { frameElement.setName(str); return; }
+ case FrameNoResize: { frameElement.setNoResize(value.toBoolean(exec)); return; }
+ case FrameScrolling: { frameElement.setScrolling(str); return; }
+ case FrameSrc: { frameElement.setSrc(str); return; }
+ case FrameLocation: {
+ static_cast<DOM::HTMLFrameElementImpl *>(frameElement.handle())->setLocation(str);
+ return;
+ }
+ }
+ }
+ break;
+ case ID_IFRAME: {
+ DOM::HTMLIFrameElement iFrame = element;
+ switch (token) {
+ case IFrameAlign: { iFrame.setAlign(str); return; }
+ // read-only: IFrameContentDocument
+ case IFrameFrameBorder: { iFrame.setFrameBorder(str); return; }
+ case IFrameHeight: { iFrame.setHeight(str); return; }
+ case IFrameLongDesc: { iFrame.setLongDesc(str); return; }
+ case IFrameMarginHeight: { iFrame.setMarginHeight(str); return; }
+ case IFrameMarginWidth: { iFrame.setMarginWidth(str); return; }
+ case IFrameName: { iFrame.setName(str); return; }
+ case IFrameScrolling: { iFrame.setScrolling(str); return; }
+ case IFrameSrc: { iFrame.setSrc(str); return; }
+ case IFrameWidth: { iFrame.setWidth(str); return; }
+ }
+ break;
+ }
+ }
+
+ // generic properties
+ switch (token) {
+ case ElementId:
+ element.setId(str);
+ return;
+ case ElementTitle:
+ element.setTitle(str);
+ return;
+ case ElementLang:
+ element.setLang(str);
+ return;
+ case ElementDir:
+ element.setDir(str);
+ return;
+ case ElementClassName:
+ element.setClassName(str);
+ return;
+ case ElementInnerHTML:
+ element.setInnerHTML(str);
+ return;
+ case ElementInnerText:
+ element.setInnerText(str);
+ return;
+ default:
+ kdDebug(6070) << "WARNING: KJS::HTMLElement::putValueProperty unhandled token " << token << " thisTag=" << element.tagName().string() << " str=" << str.string() << endl;
+ }
+}
+
+//Prototype mess for this...
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLElementProto, DOMElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLElement", HTMLElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLElementPseudoCtor, "HTMLElement", HTMLElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHtmlElement", HTMLHtmlElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHtmlElementPseudoCtor, "HTMLHtmlElement", HTMLHtmlElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHeadElement", HTMLHeadElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHeadElementPseudoCtor, "HTMLHeadElement", HTMLHeadElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLinkElement", HTMLLinkElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLinkElementPseudoCtor, "HTMLLinkElement", HTMLLinkElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTitleElement", HTMLTitleElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTitleElementPseudoCtor, "HTMLTitleElement", HTMLTitleElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLMetaElement", HTMLMetaElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMetaElementPseudoCtor, "HTMLMetaElement", HTMLMetaElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBaseElement", HTMLBaseElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBaseElementPseudoCtor, "HTMLBaseElement", HTMLBaseElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLIsIndexElement", HTMLIsIndexElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLIsIndexElementPseudoCtor, "HTMLIsIndexElement", HTMLIsIndexElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLStyleElement", HTMLStyleElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLStyleElementPseudoCtor, "HTMLStyleElement", HTMLStyleElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLBodyElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLBodyElement", HTMLBodyElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBodyElementPseudoCtor, "HTMLBodyElement", HTMLBodyElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLFormElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLFormElement", HTMLFormElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFormElementPseudoCtor, "HTMLFormElement", HTMLFormElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLSelectElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLSelectElement", HTMLSelectElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLSelectElementPseudoCtor, "HTMLSelectElement", HTMLSelectElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLOptGroupElement", HTMLOptGroupElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLOptGroupElementPseudoCtor, "HTMLOptGroupElement", HTMLOptGroupElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLOptionElement", HTMLOptionElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLOptionElementPseudoCtor, "HTMLOptionElement", HTMLOptionElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLInputElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLInputElement", HTMLInputElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLInputElementPseudoCtor, "HTMLInputElement", HTMLInputElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLTextAreaElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLTextAreaElement", HTMLTextAreaElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTextAreaElementPseudoCtor, "HTMLTextAreaElement", HTMLTextAreaElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLButtonElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLButtonElement", HTMLButtonElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLButtonElementPseudoCtor, "HTMLButtonElement", HTMLButtonElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLabelElement", HTMLLabelElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLabelElementPseudoCtor, "HTMLLabelElement", HTMLLabelElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFieldSetElement", HTMLFieldSetElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFieldSetElementPseudoCtor, "HTMLFieldSetElement", HTMLFieldSetElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLegendElement", HTMLLegendElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLegendElementPseudoCtor, "HTMLLegendElement", HTMLLegendElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLUListElement", HTMLUListElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLUListElementPseudoCtor, "HTMLUListElement", HTMLUListElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLOListElement", HTMLOListElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLOListElementPseudoCtor, "HTMLOListElement", HTMLOListElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLDListElement", HTMLDListElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDListElementPseudoCtor, "HTMLDListElement", HTMLDListElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLDirectoryElement", HTMLDirectoryElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDirectoryElementPseudoCtor, "HTMLDirectoryElement", HTMLDirectoryElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLMenuElement", HTMLMenuElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMenuElementPseudoCtor, "HTMLMenuElement", HTMLMenuElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLIElement", HTMLLIElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLIElementPseudoCtor, "HTMLLIElement", HTMLLIElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLDivElement", HTMLDivElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLDivElementPseudoCtor, "HTMLDivElement", HTMLDivElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLParagraphElement", HTMLParagraphElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLParagraphElementPseudoCtor, "HTMLParagraphElement", HTMLParagraphElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHeadingElement", HTMLHeadingElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHeadingElementPseudoCtor, "HTMLHeadingElement", HTMLHeadingElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBlockQuoteElement", HTMLBlockQuoteElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBlockQuoteElementPseudoCtor, "HTMLBlockQuoteElement", HTMLBlockQuoteElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLQuoteElement", HTMLQuoteElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLQuoteElementPseudoCtor, "HTMLQuoteElement", HTMLQuoteElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLPreElement", HTMLPreElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLPreElementPseudoCtor, "HTMLPreElement", HTMLPreElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBRElement", HTMLBRElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBRElementPseudoCtor, "HTMLBRElement", HTMLBRElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLBaseFontElement", HTMLBaseFontElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLBaseFontElementPseudoCtor, "HTMLBaseFontElement", HTMLBaseFontElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFontElement", HTMLFontElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFontElementPseudoCtor, "HTMLFontElement", HTMLFontElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLHRElement", HTMLHRElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLHRElementPseudoCtor, "HTMLHRElement", HTMLHRElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLModElement", HTMLModElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLModElementPseudoCtor, "HTMLModElement", HTMLModElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLAnchorElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLAnchorElement", HTMLAnchorElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLAnchorElementPseudoCtor, "HTMLAnchorElement", HTMLAnchorElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLImageElement", HTMLImageElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLImageElementPseudoCtor, "HTMLImageElement", HTMLImageElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLObjectElement", HTMLObjectElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLObjectElementPseudoCtor, "HTMLObjectElement", HTMLObjectElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLParamElement", HTMLParamElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLParamElementPseudoCtor, "HTMLParamElement", HTMLParamElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLAppletElement", HTMLAppletElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLAppletElementPseudoCtor, "HTMLAppletElement", HTMLAppletElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLMapElement", HTMLMapElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMapElementPseudoCtor, "HTMLMapElement", HTMLMapElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLAreaElement", HTMLAreaElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLAreaElementPseudoCtor, "HTMLAreaElement", HTMLAreaElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLScriptElement", HTMLScriptElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLScriptElementPseudoCtor, "HTMLScriptElement", HTMLScriptElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLTableElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLTableElement", HTMLTableElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableElementPseudoCtor, "HTMLTableElement", HTMLTableElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTableCaptionElement", HTMLTableCaptionElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableCaptionElementPseudoCtor, "HTMLTableCaptionElement", HTMLTableCaptionElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTableColElement", HTMLTableColElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableColElementPseudoCtor, "HTMLTableColElement", HTMLTableColElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLTableSectionElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLTableSectionElement", HTMLTableSectionElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableSectionElementPseudoCtor, "HTMLTableSectionElement", HTMLTableSectionElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLTableRowElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLTableRowElement", HTMLTableRowElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableRowElementPseudoCtor, "HTMLTableRowElement", HTMLTableRowElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLTableCellElement", HTMLTableCellElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLTableCellElementPseudoCtor, "HTMLTableCellElement", HTMLTableCellElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFrameSetElement", HTMLFrameSetElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFrameSetElementPseudoCtor, "HTMLFrameSetElement", HTMLFrameSetElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLLayerElement", HTMLLayerElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLLayerElementPseudoCtor, "HTMLLayerElement", HTMLLayerElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLFrameElement", HTMLFrameElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLFrameElementPseudoCtor, "HTMLFrameElement", HTMLFrameElementProto)
+
+KJS_EMPTY_PROTOTYPE_WITH_PROTOTYPE("HTMLIFrameElement", HTMLIFrameElementProto, HTMLElementProto)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLIFrameElementPseudoCtor, "HTMLIFrameElement", HTMLIFrameElementProto)
+
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLMarqueeElementProto, HTMLElementProto)
+KJS_IMPLEMENT_PROTOTYPE("HTMLMarqueeElement", HTMLMarqueeElementProto, HTMLElementFunction)
+IMPLEMENT_PSEUDO_CONSTRUCTOR(HTMLMarqueeElementPseudoCtor, "HTMLMarqueeElement", HTMLMarqueeElementProto)
+
+static Object prototypeForID(ExecState* exec, DOM::NodeImpl::Id id) {
+ switch (id) {
+ case ID_HTML:
+ return HTMLHtmlElementProto::self(exec);
+ case ID_HEAD:
+ return HTMLHeadElementProto::self(exec);
+ case ID_LINK:
+ return HTMLLinkElementProto::self(exec);
+ case ID_TITLE:
+ return HTMLTitleElementProto::self(exec);
+ case ID_META:
+ return HTMLMetaElementProto::self(exec);
+ case ID_BASE:
+ return HTMLBaseElementProto::self(exec);
+ case ID_ISINDEX:
+ return HTMLIsIndexElementProto::self(exec);
+ case ID_STYLE:
+ return HTMLStyleElementProto::self(exec);
+ case ID_BODY:
+ return HTMLBodyElementProto::self(exec);
+ case ID_FORM:
+ return HTMLFormElementProto::self(exec);
+ case ID_SELECT:
+ return HTMLSelectElementProto::self(exec);
+ case ID_OPTGROUP:
+ return HTMLOptGroupElementProto::self(exec);
+ case ID_OPTION:
+ return HTMLOptionElementProto::self(exec);
+ case ID_INPUT:
+ return HTMLInputElementProto::self(exec);
+ case ID_TEXTAREA:
+ return HTMLTextAreaElementProto::self(exec);
+ case ID_BUTTON:
+ return HTMLButtonElementProto::self(exec);
+ case ID_LABEL:
+ return HTMLLabelElementProto::self(exec);
+ case ID_FIELDSET:
+ return HTMLFieldSetElementProto::self(exec);
+ case ID_LEGEND:
+ return HTMLLegendElementProto::self(exec);
+ case ID_UL:
+ return HTMLUListElementProto::self(exec);
+ case ID_OL:
+ return HTMLOListElementProto::self(exec);
+ case ID_DL:
+ return HTMLDListElementProto::self(exec);
+ case ID_DIR:
+ return HTMLDirectoryElementProto::self(exec);
+ case ID_MENU:
+ return HTMLMenuElementProto::self(exec);
+ case ID_LI:
+ return HTMLLIElementProto::self(exec);
+ case ID_DIV:
+ return HTMLDivElementProto::self(exec);
+ case ID_P:
+ return HTMLParagraphElementProto::self(exec);
+ case ID_H1:
+ case ID_H2:
+ case ID_H3:
+ case ID_H4:
+ case ID_H5:
+ case ID_H6:
+ return HTMLHeadingElementProto::self(exec);
+ case ID_BLOCKQUOTE:
+ return HTMLBlockQuoteElementProto::self(exec);
+ case ID_Q:
+ return HTMLQuoteElementProto::self(exec);
+ case ID_PRE:
+ return HTMLPreElementProto::self(exec);
+ case ID_BR:
+ return HTMLBRElementProto::self(exec);
+ case ID_BASEFONT:
+ return HTMLBaseFontElementProto::self(exec);
+ case ID_FONT:
+ return HTMLFontElementProto::self(exec);
+ case ID_HR:
+ return HTMLHRElementProto::self(exec);
+ case ID_INS:
+ case ID_DEL:
+ return HTMLModElementProto::self(exec);
+ case ID_A:
+ return HTMLAnchorElementProto::self(exec);
+ case ID_IMG:
+ return HTMLImageElementProto::self(exec);
+ case ID_OBJECT:
+ return HTMLObjectElementProto::self(exec);
+ case ID_PARAM:
+ return HTMLParamElementProto::self(exec);
+ case ID_APPLET:
+ return HTMLAppletElementProto::self(exec);
+ case ID_MAP:
+ return HTMLMapElementProto::self(exec);
+ case ID_AREA:
+ return HTMLAreaElementProto::self(exec);
+ case ID_SCRIPT:
+ return HTMLScriptElementProto::self(exec);
+ case ID_TABLE:
+ return HTMLTableElementProto::self(exec);
+ case ID_CAPTION:
+ return HTMLTableCaptionElementProto::self(exec);
+ case ID_COL:
+ case ID_COLGROUP:
+ return HTMLTableColElementProto::self(exec);
+ case ID_THEAD:
+ case ID_TBODY:
+ case ID_TFOOT:
+ return HTMLTableSectionElementProto::self(exec);
+ case ID_TR:
+ return HTMLTableRowElementProto::self(exec);
+ case ID_TD:
+ case ID_TH:
+ return HTMLTableCellElementProto::self(exec);
+ case ID_FRAMESET:
+ return HTMLFrameSetElementProto::self(exec);
+ case ID_LAYER:
+ return HTMLLayerElementProto::self(exec);
+ case ID_FRAME:
+ return HTMLFrameElementProto::self(exec);
+ case ID_IFRAME:
+ return HTMLIFrameElementProto::self(exec);
+ case ID_MARQUEE:
+ return HTMLMarqueeElementProto::self(exec);
+ default:
+ return HTMLElementProto::self(exec);
+ }
+}
+
+// -------------------------------------------------------------------------
+/* Source for HTMLCollectionProtoTable.
+@begin HTMLCollectionProtoTable 3
+ item HTMLCollection::Item DontDelete|Function 1
+ namedItem HTMLCollection::NamedItem DontDelete|Function 1
+ tags HTMLCollection::Tags DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE(HTMLCollectionProto)
+IMPLEMENT_PROTOFUNC_DOM(HTMLCollectionProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("HTMLCollection", HTMLCollectionProto,HTMLCollectionProtoFunc)
+
+const ClassInfo KJS::HTMLCollection::info = { "HTMLCollection", 0, 0, 0 };
+
+KJS::HTMLCollection::HTMLCollection(ExecState *exec, const DOM::HTMLCollection& c)
+ : DOMObject(HTMLCollectionProto::self(exec)), collection(c), hidden(false) {}
+
+KJS::HTMLCollection::HTMLCollection(const KJS::Object& proto, const DOM::HTMLCollection& c)
+ : DOMObject(proto), collection(c), hidden(false) {}
+
+KJS::HTMLCollection::~HTMLCollection()
+{
+ ScriptInterpreter::forgetDOMObject(collection.handle());
+}
+
+bool KJS::HTMLCollection::toBoolean(ExecState *) const {
+ return !hidden;
+}
+
+// We have to implement hasProperty since we don't use a hashtable for 'selectedIndex' and 'length',
+// and for indices in "for (..in..)"
+bool KJS::HTMLCollection::hasProperty(ExecState *exec, const Identifier &p) const
+{
+ if (p == lengthPropertyName)
+ return true;
+ if ( collection.handle()->getType() == HTMLCollectionImpl::SELECT_OPTIONS &&
+ ( p == "selectedIndex" || p == "value" ) )
+ return true;
+
+ bool ok;
+ unsigned long pos = p.toULong(&ok);
+ if (ok && pos < collection.length())
+ return true;
+
+ return DOMObject::hasProperty(exec, p);
+}
+
+ReferenceList KJS::HTMLCollection::propList(ExecState *exec, bool recursive)
+{
+ ReferenceList properties = ObjectImp::propList(exec,recursive);
+
+ for (unsigned i = 0; i < collection.length(); ++i) {
+ if (!ObjectImp::hasProperty(exec,Identifier::from(i))) {
+ properties.append(Reference(this, i));
+ }
+ }
+
+ if (!ObjectImp::hasProperty(exec, lengthPropertyName))
+ properties.append(Reference(this, lengthPropertyName));
+
+ return properties;
+}
+
+Value KJS::HTMLCollection::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLCollection::tryGet " << propertyName.ascii() << endl;
+#endif
+ if (propertyName == lengthPropertyName)
+ {
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << " collection length is " << collection.length() << endl;
+#endif
+ return Number(collection.length());
+ }
+
+ if (collection.handle()->getType() == HTMLCollectionImpl::SELECT_OPTIONS) {
+ DOM::HTMLSelectElement parentSelect = collection.base();
+ if ( parentSelect.isNull() )
+ return Undefined();
+ if (propertyName == "selectedIndex") {
+ // NON-STANDARD options.selectedIndex
+ return Number(parentSelect.selectedIndex());
+ } else if ( propertyName == "value" ) {
+ // NON-STANDARD options.value
+ return String(parentSelect.value());
+ }
+ }
+
+ // Look in the prototype (for functions) before assuming it's an item's name
+ Object proto = Object::dynamicCast(prototype());
+ if (proto.isValid() && proto.hasProperty(exec,propertyName))
+ return proto.get(exec,propertyName);
+
+ // name or index ?
+ bool ok;
+ unsigned int u = propertyName.toULong(&ok);
+ if (ok) {
+ if ( u < collection.length() ) {
+ DOM::Node node = collection.item(u);
+ return getDOMNode(exec,node);
+ } else
+ return Undefined();
+ }
+ else
+ return getNamedItems(exec,propertyName);
+}
+
+// HTMLCollections are strange objects, they support both get and call,
+// so that document.forms.item(0) and document.forms(0) both work.
+Value KJS::HTMLCollection::call(ExecState *exec, Object &thisObj, const List &args)
+{
+ // This code duplication is necessary, HTMLCollection isn't a DOMFunction
+ Value val;
+ try {
+ val = tryCall(exec, thisObj, args);
+ }
+ // pity there's no way to distinguish between these in JS code
+ catch (...) {
+ Object err = Error::create(exec, GeneralError, "Exception from HTMLCollection");
+ exec->setException(err);
+ }
+ return val;
+}
+
+Value KJS::HTMLCollection::tryCall(ExecState *exec, Object &, const List &args)
+{
+ // Do not use thisObj here. It can be the HTMLDocument, in the document.forms(i) case.
+ /*if( thisObj.imp() != this )
+ {
+ kdDebug(6070) << "WARNING: thisObj.imp() != this in HTMLCollection::tryCall" << endl;
+ KJS::printInfo(exec,"KJS::HTMLCollection::tryCall thisObj",thisObj,-1);
+ KJS::printInfo(exec,"KJS::HTMLCollection::tryCall this",Value(this),-1);
+ }*/
+ // Also, do we need the TypeError test here ?
+
+ if (args.size() == 1) {
+ // support for document.all(<index>) etc.
+ bool ok;
+ UString s = args[0].toString(exec);
+ unsigned int u = s.toULong(&ok);
+ if (ok) {
+ DOM::Element element = collection.item(u);
+ return getDOMNode(exec,element);
+ }
+ // support for document.images('<name>') etc.
+ return getNamedItems(exec,Identifier(s));
+ }
+ else if (args.size() >= 1) // the second arg, if set, is the index of the item we want
+ {
+ bool ok;
+ UString s = args[0].toString(exec);
+ unsigned int u = args[1].toString(exec).toULong(&ok);
+ if (ok)
+ {
+ DOM::DOMString pstr = s.string();
+ DOM::Node node = collection.namedItem(pstr);
+ while (!node.isNull()) {
+ if (!u)
+ return getDOMNode(exec,node);
+ node = collection.nextNamedItem(pstr);
+ --u;
+ }
+ }
+ }
+ return Undefined();
+}
+
+Value KJS::HTMLCollection::getNamedItems(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLCollection::getNamedItems " << propertyName.ascii() << endl;
+#endif
+
+ DOM::DOMString pstr = propertyName.string();
+
+ QValueList<DOM::NodeImpl*> matches = collection.handle()->namedItems(pstr);
+
+ if (!matches.isEmpty()) {
+ if (matches.size() == 1) {
+ DOM::Node node(matches[0]);
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "returning single node" << endl;
+#endif
+ return getDOMNode(exec,node);
+ }
+ else {
+ // multiple items, return a collection
+ QValueList<DOM::Node> nodes;
+ for (QValueList<DOM::NodeImpl*>::const_iterator i = matches.begin();
+ i != matches.end(); ++i)
+ nodes.append(DOM::Node(*i));
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "returning list of " << nodes.count() << " nodes" << endl;
+#endif
+ return Value(new DOMNamedNodesCollection(exec, nodes));
+ }
+ }
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "not found" << endl;
+#endif
+ return Undefined();
+}
+
+Value KJS::HTMLCollectionProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::HTMLCollection, thisObj );
+ DOM::HTMLCollection coll = static_cast<KJS::HTMLCollection *>(thisObj.imp())->toCollection();
+
+ switch (id) {
+ case KJS::HTMLCollection::Item:
+ {
+ // support for item(<index>) (DOM)
+ bool ok;
+ UString s = args[0].toString(exec);
+ unsigned int u = s.toULong(&ok);
+ if (ok) {
+ return getDOMNode(exec,coll.item(u));
+ }
+ // support for item('<name>') (IE only)
+ kdWarning() << "non-standard HTMLCollection.item('" << s.ascii() << "') called, use namedItem instead" << endl;
+ return getDOMNode(exec,coll.namedItem(s.string()));
+ }
+ case KJS::HTMLCollection::Tags:
+ {
+ DOM::DOMString tagName = args[0].toString(exec).string();
+ DOM::NodeList list;
+ // getElementsByTagName exists in Document and in Element, pick up the right one
+ if ( coll.base().nodeType() == DOM::Node::DOCUMENT_NODE )
+ {
+ DOM::Document doc = coll.base();
+ list = doc.getElementsByTagName(tagName);
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLCollectionProtoFunc::tryCall document.tags(" << tagName.string() << ") -> " << list.length() << " items in node list" << endl;
+#endif
+ } else
+ {
+ DOM::Element e = coll.base();
+ list = e.getElementsByTagName(tagName);
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLCollectionProtoFunc::tryCall element.tags(" << tagName.string() << ") -> " << list.length() << " items in node list" << endl;
+#endif
+ }
+ return getDOMNodeList(exec, list);
+ }
+ case KJS::HTMLCollection::NamedItem:
+ {
+ Value val = static_cast<HTMLCollection *>(thisObj.imp())->getNamedItems(exec, Identifier(args[0].toString(exec)));
+ // Must return null when asking for a named item that isn't in the collection
+ // (DOM2 testsuite, HTMLCollection12 test)
+ if ( val.type() == KJS::UndefinedType )
+ return Null();
+ else
+ return val;
+ }
+ default:
+ return Undefined();
+ }
+}
+
+// -------------------------------------------------------------------------
+/* Source for HTMLSelectCollectionProtoTable.
+@begin HTMLSelectCollectionProtoTable 1
+ add HTMLSelectCollection::Add DontDelete|Function 2
+@end
+*/
+KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(HTMLSelectCollectionProto, HTMLCollectionProto)
+IMPLEMENT_PROTOFUNC_DOM(HTMLSelectCollectionProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("HTMLOptionsCollection", HTMLSelectCollectionProto, HTMLSelectCollectionProtoFunc)
+
+const ClassInfo KJS::HTMLSelectCollection::info = { "HTMLOptionsCollection", &HTMLCollection::info, 0, 0 };
+
+KJS::HTMLSelectCollection::HTMLSelectCollection(ExecState *exec, const DOM::HTMLCollection& c,
+ const DOM::HTMLSelectElement& e)
+ : HTMLCollection(HTMLSelectCollectionProto::self(exec), c), element(e) { }
+
+Value KJS::HTMLSelectCollection::tryGet(ExecState *exec, const Identifier &p) const
+{
+ if (p == "selectedIndex")
+ return Number(element.selectedIndex());
+
+ return HTMLCollection::tryGet(exec, p);
+}
+
+void KJS::HTMLSelectCollection::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "KJS::HTMLSelectCollection::tryPut " << propertyName.qstring() << endl;
+#endif
+ if ( propertyName == "selectedIndex" ) {
+ element.setSelectedIndex( value.toInteger( exec ) );
+ return;
+ }
+ // resize ?
+ else if (propertyName == lengthPropertyName) {
+ unsigned newLen;
+ bool converted = value.toUInt32(newLen);
+
+ if (!converted) {
+ return;
+ }
+
+ long diff = element.length() - newLen;
+
+ if (diff < 0) { // add dummy elements
+ do {
+ element.add(element.ownerDocument().createElement("OPTION"), DOM::HTMLElement());
+ } while (++diff);
+ }
+ else // remove elements
+ while (diff-- > 0)
+ element.remove(newLen + diff);
+
+ return;
+ }
+ // an index ?
+ bool ok;
+ unsigned int u = propertyName.toULong(&ok);
+ if (!ok)
+ return;
+
+ if (value.isA(NullType) || value.isA(UndefinedType)) {
+ // null and undefined delete. others, too ?
+ element.remove(u);
+ return;
+ }
+
+ // is v an option element ?
+ DOM::Node node = KJS::toNode(value);
+ if (node.isNull() || node.elementId() != ID_OPTION)
+ return;
+
+ DOM::HTMLOptionElement option = static_cast<DOM::HTMLOptionElement>(node);
+ if ( option.ownerDocument() != element.ownerDocument() )
+ option = static_cast<DOM::HTMLOptionElement>(element.ownerDocument().importNode(option, true));
+ long diff = long(u) - element.length();
+ DOM::HTMLElement before;
+ // out of array bounds ? first insert empty dummies
+ if (diff > 0) {
+ while (diff--) {
+ element.add(element.ownerDocument().createElement("OPTION"), before);
+ }
+ // replace an existing entry ?
+ } else if (diff < 0) {
+ before = element.options().item(u+1);
+ element.remove(u);
+ }
+ // finally add the new element
+ element.add(option, before);
+}
+
+
+Value KJS::HTMLSelectCollectionProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::HTMLSelectCollection, thisObj );
+ DOM::HTMLSelectElement element = static_cast<KJS::HTMLSelectCollection *>(thisObj.imp())->toElement();
+
+ switch (id) {
+ case KJS::HTMLSelectCollection::Add:
+ {
+ //Non-standard select.options.add.
+ //The first argument is the item, 2nd is offset.
+ //IE and Mozilla are both quite picky here, too...
+ DOM::Node node = KJS::toNode(args[0]);
+ if (node.isNull() || node.elementId() != ID_OPTION) {
+ Object err = Error::create(exec, GeneralError, "Invalid argument to HTMLOptionsCollection::add");
+ exec->setException(err);
+ return Undefined();
+ }
+
+ DOM::HTMLOptionElement option = static_cast<DOM::HTMLOptionElement>(node);
+ if ( option.ownerDocument() != element.ownerDocument() ) //### remove this once auto-adopt works...
+ option = static_cast<DOM::HTMLOptionElement>(element.ownerDocument().importNode(option, true));
+
+ int pos = 0;
+ //By default append, if not specified or null..
+ if (args[1].isA(UndefinedType))
+ pos = element.length();
+ else
+ pos = (int)args[1].toNumber(exec);
+
+ if (pos < 0) {
+ Object err = Error::create(exec, GeneralError, "Invalid index argument to HTMLOptionsCollection::add");
+ exec->setException(err);
+ return Undefined();
+ }
+
+ if (pos >= element.length()) {
+ //Append
+ element.add(option, DOM::Node());
+ } else {
+ //Find what to prepend before..
+ DOM::HTMLSelectElementImpl* impl = static_cast<HTMLSelectElementImpl*>(element.handle());
+ QMemArray<HTMLGenericFormElementImpl*> items = impl->listItems();
+ int dummy;
+ impl->insertBefore(option.handle(), items.at(pos), dummy);
+ }
+ return Undefined();
+ break;
+ }
+ default:
+ break;
+ }
+ return Undefined();
+}
+
+
+////////////////////// Option Object ////////////////////////
+
+OptionConstructorImp::OptionConstructorImp(ExecState *exec, const DOM::Document &d)
+ : ObjectImp(), doc(d)
+{
+ // ## isn't there some redundancy between ObjectImp::_proto and the "prototype" property ?
+ //put(exec,"prototype", ...,DontEnum|DontDelete|ReadOnly);
+
+ // no. of arguments for constructor
+ // ## is 4 correct ? 0 to 4, it seems to be
+ put(exec,lengthPropertyName, Number(4), ReadOnly|DontDelete|DontEnum);
+}
+
+bool OptionConstructorImp::implementsConstruct() const
+{
+ return true;
+}
+
+Object OptionConstructorImp::construct(ExecState *exec, const List &args)
+{
+ DOM::Element el = doc.createElement("OPTION");
+ DOM::HTMLOptionElement opt = static_cast<DOM::HTMLOptionElement>(el);
+ int sz = args.size();
+ DOM::Text t = doc.createTextNode("");
+ try { opt.appendChild(t); }
+ catch(DOM::DOMException& e) {
+ // #### exec->setException ?
+ }
+ if (sz > 0)
+ t.setData(args[0].toString(exec).string()); // set the text
+ if (sz > 1)
+ opt.setValue(args[1].toString(exec).string());
+ if (sz > 2)
+ opt.setDefaultSelected(args[2].toBoolean(exec));
+ if (sz > 3)
+ opt.setSelected(args[3].toBoolean(exec));
+
+ return Object::dynamicCast(getDOMNode(exec,opt));
+}
+
+////////////////////// Image Object ////////////////////////
+
+//Like in other browsers, we merely make a new HTMLImageElement
+//not in tree for this.
+ImageConstructorImp::ImageConstructorImp(ExecState *, const DOM::Document &d)
+ : ObjectImp(), doc(d)
+{
+}
+
+bool ImageConstructorImp::implementsConstruct() const
+{
+ return true;
+}
+
+Object ImageConstructorImp::construct(ExecState *exec, const List &list)
+{
+ bool widthSet = false, heightSet = false;
+ int width = 0, height = 0;
+ if (list.size() > 0) {
+ widthSet = true;
+ Value w = list.at(0);
+ width = w.toInt32(exec);
+ }
+ if (list.size() > 1) {
+ heightSet = true;
+ Value h = list.at(1);
+ height = h.toInt32(exec);
+ }
+
+ HTMLImageElement image(doc.createElement("image"));
+
+ if (widthSet)
+ image.setWidth(width);
+
+ if (heightSet)
+ image.setHeight(height);
+
+ return Object::dynamicCast(getDOMNode(exec,image));
+}
+
+Value getHTMLCollection(ExecState *exec, const DOM::HTMLCollection& c, bool hide)
+{
+ Value coll = cacheDOMObject<DOM::HTMLCollection, KJS::HTMLCollection>(exec, c);
+ if (hide) {
+ KJS::HTMLCollection *impl = static_cast<KJS::HTMLCollection*>(coll.imp());
+ impl->hide();
+ }
+ return coll;
+}
+
+Value getSelectHTMLCollection(ExecState *exec, const DOM::HTMLCollection& c, const DOM::HTMLSelectElement& e)
+{
+ DOMObject *ret;
+ if (c.isNull())
+ return Null();
+ ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+ if ((ret = interp->getDOMObject(c.handle())))
+ return Value(ret);
+ else {
+ ret = new HTMLSelectCollection(exec, c, e);
+ interp->putDOMObject(c.handle(),ret);
+ return Value(ret);
+ }
+}
+
+} //namespace KJS
diff --git a/khtml/ecma/kjs_html.h b/khtml/ecma/kjs_html.h
new file mode 100644
index 000000000..53da38462
--- /dev/null
+++ b/khtml/ecma/kjs_html.h
@@ -0,0 +1,294 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_HTML_H_
+#define _KJS_HTML_H_
+
+#include "dom/html_document.h"
+#include "dom/html_base.h"
+#include "dom/html_misc.h"
+#include "dom/html_form.h"
+#include "misc/loader_client.h"
+
+#include "ecma/kjs_binding.h"
+#include "ecma/kjs_dom.h"
+#include "xml/dom_nodeimpl.h" // for NodeImpl::Id
+
+namespace KJS {
+
+ class HTMLElement;
+
+ class HTMLDocument : public DOMDocument {
+ public:
+ HTMLDocument(ExecState *exec, const DOM::HTMLDocument& d);
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
+ virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Title, Referrer, Domain, URL, Body, Location, Cookie,
+ Images, Applets, Links, Forms, Layers, Anchors, Scripts, All, Clear, Open, Close,
+ Write, WriteLn, GetElementsByName, GetSelection, CaptureEvents, ReleaseEvents,
+ BgColor, FgColor, AlinkColor, LinkColor, VlinkColor, LastModified,
+ Height, Width, Dir, Frames, CompatMode };
+ DOM::Document toDocument() const { return static_cast<DOM::Document>( node ); }
+ };
+
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLDocumentPseudoCtor)
+
+ class HTMLElement : public DOMElement {
+ public:
+ HTMLElement(ExecState *exec, const DOM::HTMLElement& e);
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ void putValueProperty(ExecState *exec, int token, const Value& value, int);
+ virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
+ virtual UString toString(ExecState *exec) const;
+ virtual void pushEventHandlerScope(ExecState *exec, ScopeChain &scope) const;
+ virtual const ClassInfo* classInfo() const;
+ static const ClassInfo info;
+
+ static const ClassInfo html_info, head_info, link_info, title_info,
+ meta_info, base_info, isIndex_info, style_info, body_info, form_info,
+ select_info, optGroup_info, option_info, input_info, textArea_info,
+ button_info, label_info, fieldSet_info, legend_info, ul_info, ol_info,
+ dl_info, dir_info, menu_info, li_info, div_info, p_info, heading_info,
+ blockQuote_info, q_info, pre_info, br_info, baseFont_info, font_info,
+ hr_info, mod_info, a_info, img_info, object_info, param_info,
+ applet_info, map_info, area_info, script_info, table_info,
+ caption_info, col_info, tablesection_info, tr_info,
+ tablecell_info, frameSet_info, frame_info, iFrame_info, marquee_info, layer_info;
+
+ enum { HtmlVersion, HeadProfile, LinkHref, LinkRel, LinkMedia,
+ LinkCharset, LinkDisabled, LinkHrefLang, LinkRev, LinkTarget, LinkType,
+ LinkSheet, TitleText, MetaName, MetaHttpEquiv, MetaContent, MetaScheme,
+ BaseHref, BaseTarget, IsIndexForm, IsIndexPrompt, StyleDisabled,
+ StyleSheet, StyleType, StyleMedia, BodyBackground, BodyVLink, BodyText,
+ BodyLink, BodyALink, BodyBgColor, BodyOnLoad, BodyFocus,
+ FormAction, FormEncType, FormElements, FormLength, FormAcceptCharset,
+ FormReset, FormTarget, FormName, FormMethod, FormSubmit, SelectAdd,
+ SelectTabIndex, SelectValue, SelectSelectedIndex, SelectLength,
+ SelectRemove, SelectForm, SelectBlur, SelectType, SelectOptions,
+ SelectDisabled, SelectMultiple, SelectName, SelectSize, SelectFocus,
+ OptGroupDisabled, OptGroupLabel, OptionIndex, OptionSelected,
+ OptionForm, OptionText, OptionDefaultSelected, OptionDisabled,
+ OptionLabel, OptionValue, InputBlur, InputReadOnly, InputAccept,
+ InputSize, InputDefaultValue, InputTabIndex, InputValue, InputType,
+ InputFocus, InputMaxLength, InputDefaultChecked, InputDisabled,
+ InputChecked, InputIndeterminate, InputForm, InputAccessKey, InputAlign, InputAlt,
+ InputName, InputSrc, InputUseMap, InputSelect, InputClick,
+ InputSelectionStart, InputSelectionEnd, InputSetSelectionRange,
+ TextAreaAccessKey, TextAreaName, TextAreaDefaultValue, TextAreaSelect,
+ TextAreaCols, TextAreaDisabled, TextAreaForm, TextAreaType,
+ TextAreaTabIndex, TextAreaReadOnly, TextAreaRows, TextAreaValue,
+ TextAreaBlur, TextAreaFocus, TextAreaSelectionStart, TextAreaSelectionEnd, TextAreaSetSelectionRange,
+ TextAreaTextLength, ButtonBlur, ButtonFocus, ButtonForm, ButtonTabIndex, ButtonName,
+ ButtonDisabled, ButtonAccessKey, ButtonType, ButtonValue, LabelHtmlFor,
+ LabelForm, LabelAccessKey, FieldSetForm, LegendForm, LegendAccessKey,
+ LegendAlign, UListType, UListCompact, OListStart, OListCompact,
+ OListType, DListCompact, DirectoryCompact, MenuCompact, LIType,
+ LIValue, DivAlign, ParagraphAlign, HeadingAlign, BlockQuoteCite,
+ QuoteCite, PreWidth, BRClear, BaseFontColor, BaseFontSize,
+ BaseFontFace, FontColor, FontSize, FontFace, HRWidth, HRNoShade,
+ HRAlign, HRSize, ModCite, ModDateTime, AnchorShape, AnchorRel,
+ AnchorAccessKey, AnchorCoords, AnchorHref, AnchorProtocol, AnchorHost,
+ AnchorCharset, AnchorHrefLang, AnchorHostname, AnchorType, AnchorFocus,
+ AnchorPort, AnchorPathName, AnchorHash, AnchorSearch, AnchorName,
+ AnchorRev, AnchorTabIndex, AnchorTarget, AnchorText, AnchorBlur, AnchorClick,
+ ImageName, ImageAlign, ImageHspace, ImageVspace, ImageUseMap, ImageAlt,
+ ImageLowSrc, ImageWidth, ImageIsMap, ImageBorder, ImageHeight,
+ ImageLongDesc, ImageSrc, ImageX, ImageY, ImageComplete, ObjectHspace, ObjectHeight, ObjectAlign,
+ ObjectBorder, ObjectCode, ObjectType, ObjectVspace, ObjectArchive,
+ ObjectDeclare, ObjectForm, ObjectCodeBase, ObjectCodeType, ObjectData,
+ ObjectName, ObjectStandby, ObjectTabIndex, ObjectUseMap, ObjectWidth, ObjectContentDocument,
+ ParamName, ParamType, ParamValueType, ParamValue, AppletArchive,
+ AppletAlt, AppletCode, AppletWidth, AppletAlign, AppletCodeBase,
+ AppletName, AppletHeight, AppletHspace, AppletObject, AppletVspace,
+ MapAreas, MapName, AreaHash, AreaHref, AreaTarget, AreaPort, AreaShape,
+ AreaCoords, AreaAlt, AreaAccessKey, AreaNoHref, AreaHost, AreaProtocol,
+ AreaHostName, AreaPathName, AreaSearch, AreaTabIndex, ScriptEvent,
+ ScriptType, ScriptHtmlFor, ScriptText, ScriptSrc, ScriptCharset,
+ ScriptDefer, TableSummary, TableTBodies, TableTHead, TableCellPadding,
+ TableDeleteCaption, TableCreateCaption, TableCaption, TableWidth,
+ TableCreateTFoot, TableAlign, TableTFoot, TableDeleteRow,
+ TableCellSpacing, TableRows, TableBgColor, TableBorder, TableFrame,
+ TableRules, TableCreateTHead, TableDeleteTHead, TableDeleteTFoot,
+ TableInsertRow, TableCaptionAlign, TableColCh, TableColChOff,
+ TableColAlign, TableColSpan, TableColVAlign, TableColWidth,
+ TableSectionCh, TableSectionDeleteRow, TableSectionChOff,
+ TableSectionRows, TableSectionAlign, TableSectionVAlign,
+ TableSectionInsertRow, TableRowSectionRowIndex, TableRowRowIndex,
+ TableRowChOff, TableRowCells, TableRowVAlign, TableRowCh,
+ TableRowAlign, TableRowBgColor, TableRowDeleteCell, TableRowInsertCell,
+ TableCellColSpan, TableCellNoWrap, TableCellAbbr, TableCellHeight,
+ TableCellWidth, TableCellCellIndex, TableCellChOff, TableCellBgColor,
+ TableCellCh, TableCellVAlign, TableCellRowSpan, TableCellHeaders,
+ TableCellAlign, TableCellAxis, TableCellScope, FrameSetCols,
+ FrameSetRows, FrameSrc, FrameLocation, FrameFrameBorder, FrameScrolling,
+ FrameMarginWidth, FrameLongDesc, FrameMarginHeight, FrameName,
+ FrameContentDocument, FrameContentWindow,
+ FrameNoResize, FrameWidth, FrameHeight, IFrameLongDesc, IFrameAlign,
+ IFrameFrameBorder, IFrameSrc, IFrameName, IFrameHeight,
+ IFrameMarginHeight, IFrameMarginWidth, IFrameScrolling, IFrameWidth,
+ IFrameContentDocument, IFrameContentWindow,
+ MarqueeStart, MarqueeStop,
+ LayerTop, LayerLeft, LayerVisibility, LayerBgColor, LayerClip, LayerDocument, LayerLayers,
+ ElementInnerHTML, ElementTitle, ElementId, ElementDir, ElementLang,
+ ElementClassName, ElementInnerText, ElementDocument,
+ ElementChildren, ElementAll, ElementScrollIntoView };
+
+ DOM::HTMLElement toElement() const { return static_cast<DOM::HTMLElement>(node); }
+ };
+
+ class HTMLElementFunction : public DOMFunction {
+ public:
+ HTMLElementFunction(ExecState *exec, int i, int len);
+ virtual Value tryCall(ExecState *exec, Object &thisObj, const List&args);
+ private:
+ int id;
+ };
+
+ class HTMLCollection : public DOMObject {
+ public:
+ HTMLCollection(ExecState *exec, const DOM::HTMLCollection& c);
+ HTMLCollection(const KJS::Object& proto, const DOM::HTMLCollection& c);
+ ~HTMLCollection();
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ virtual Value call(ExecState *exec, Object &thisObj, const List&args);
+ virtual Value tryCall(ExecState *exec, Object &thisObj, const List&args);
+ virtual bool implementsCall() const { return true; }
+ virtual bool toBoolean(ExecState *) const;
+ virtual bool hasProperty(ExecState *exec, const Identifier &p) const;
+ virtual ReferenceList propList(ExecState *exec, bool recursive);
+ enum { Item, NamedItem, Tags };
+ Value getNamedItems(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ DOM::HTMLCollection toCollection() const { return collection; }
+ virtual void hide() { hidden = true; }
+ protected:
+ DOM::HTMLCollection collection;
+ bool hidden;
+ };
+
+ class HTMLSelectCollection : public HTMLCollection {
+ public:
+ enum { Add };
+ HTMLSelectCollection(ExecState *exec, const DOM::HTMLCollection& c, const DOM::HTMLSelectElement& e);
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+
+ DOM::HTMLSelectElement toElement() const { return element; }
+ private:
+ DOM::HTMLSelectElement element;
+ };
+
+ ////////////////////// Option Object ////////////////////////
+
+ class OptionConstructorImp : public ObjectImp {
+ public:
+ OptionConstructorImp(ExecState *exec, const DOM::Document &d);
+ virtual bool implementsConstruct() const;
+ virtual Object construct(ExecState *exec, const List &args);
+ private:
+ DOM::Document doc;
+ };
+
+ ////////////////////// Image Object ////////////////////////
+
+ class ImageConstructorImp : public ObjectImp {
+ public:
+ ImageConstructorImp(ExecState *exec, const DOM::Document &d);
+ virtual bool implementsConstruct() const;
+ virtual Object construct(ExecState *exec, const List &args);
+ private:
+ DOM::Document doc;
+ };
+
+ Value getHTMLCollection(ExecState *exec, const DOM::HTMLCollection& c, bool hide=false);
+ Value getSelectHTMLCollection(ExecState *exec, const DOM::HTMLCollection& c, const DOM::HTMLSelectElement& e);
+
+
+ //All the pseudo constructors..
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLHtmlElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLHeadElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLLinkElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTitleElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLMetaElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLBaseElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLIsIndexElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLStyleElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLBodyElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLFormElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLSelectElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLOptGroupElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLOptionElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLInputElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTextAreaElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLButtonElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLLabelElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLFieldSetElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLLegendElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLUListElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLOListElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLDListElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLDirectoryElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLMenuElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLLIElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLDivElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLParagraphElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLHeadingElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLBlockQuoteElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLQuoteElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLPreElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLBRElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLBaseFontElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLFontElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLHRElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLModElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLAnchorElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLImageElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLObjectElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLParamElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLAppletElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLMapElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLAreaElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLScriptElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTableElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTableCaptionElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTableColElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTableSectionElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTableRowElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLTableCellElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLFrameSetElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLLayerElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLFrameElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLIFrameElementPseudoCtor)
+ DEFINE_PSEUDO_CONSTRUCTOR(HTMLMarqueeElementPseudoCtor)
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_mozilla.cpp b/khtml/ecma/kjs_mozilla.cpp
new file mode 100644
index 000000000..4b1520b9a
--- /dev/null
+++ b/khtml/ecma/kjs_mozilla.cpp
@@ -0,0 +1,94 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2003 George Staikos (staikos@kde.org)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <klocale.h>
+#include <kdebug.h>
+
+#include "kjs_mozilla.h"
+#include "kjs/lookup.h"
+#include "kjs_binding.h"
+#include "khtml_part.h"
+#include "kjs_mozilla.lut.h"
+
+using namespace KJS;
+
+namespace KJS {
+
+const ClassInfo MozillaSidebarExtension::info = { "sidebar", 0, &MozillaSidebarExtensionTable, 0 };
+/*
+@begin MozillaSidebarExtensionTable 1
+ addPanel MozillaSidebarExtension::addPanel DontDelete|Function 0
+@end
+*/
+}
+IMPLEMENT_PROTOFUNC_DOM(MozillaSidebarExtensionFunc)
+
+MozillaSidebarExtension::MozillaSidebarExtension(ExecState *exec, KHTMLPart *p)
+ : ObjectImp(exec->interpreter()->builtinObjectPrototype()), m_part(p) { }
+
+Value MozillaSidebarExtension::get(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "MozillaSidebarExtension::get " << propertyName.ascii() << endl;
+#endif
+ return lookupGet<MozillaSidebarExtensionFunc,MozillaSidebarExtension,ObjectImp>(exec,propertyName,&MozillaSidebarExtensionTable,this);
+}
+
+Value MozillaSidebarExtension::getValueProperty(ExecState *exec, int token) const
+{
+ Q_UNUSED(exec);
+ switch (token) {
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in MozillaSidebarExtension::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+Value MozillaSidebarExtensionFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::MozillaSidebarExtension, thisObj );
+ MozillaSidebarExtension *mse = static_cast<MozillaSidebarExtension*>(thisObj.imp());
+
+ KHTMLPart *part = mse->part();
+ if (!part)
+ return Undefined();
+
+ // addPanel() id == 0
+ KParts::BrowserExtension *ext = part->browserExtension();
+ if (ext) {
+ QString url, name;
+ if (args.size() == 1) { // I've seen this, don't know if it's legal.
+ name = QString::null;
+ url = args[0].toString(exec).qstring();
+ } else if (args.size() == 2 || args.size() == 3) {
+ name = args[0].toString(exec).qstring();
+ url = args[1].toString(exec).qstring();
+ // 2 is the "CURL" which I don't understand and don't think we need.
+ } else {
+ return Boolean(false);
+ }
+ emit ext->addWebSideBar(KURL( url ), name);
+ return Boolean(true);
+ }
+
+ return Undefined();
+}
+
+
diff --git a/khtml/ecma/kjs_mozilla.h b/khtml/ecma/kjs_mozilla.h
new file mode 100644
index 000000000..220094f63
--- /dev/null
+++ b/khtml/ecma/kjs_mozilla.h
@@ -0,0 +1,44 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2003 George Staikos (staikos@kde.org)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_MOZILLA_H_
+#define _KJS_MOZILLA_H_
+
+#include <kjs/object.h>
+
+class KHTMLPart;
+
+namespace KJS {
+
+ class MozillaSidebarExtension : public ObjectImp {
+ public:
+ MozillaSidebarExtension(ExecState *exec, KHTMLPart *p);
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { addPanel };
+ KHTMLPart *part() const { return m_part; }
+ private:
+ KHTMLPart *m_part;
+ };
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_navigator.cpp b/khtml/ecma/kjs_navigator.cpp
new file mode 100644
index 000000000..d962cac36
--- /dev/null
+++ b/khtml/ecma/kjs_navigator.cpp
@@ -0,0 +1,670 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org)
+ * Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <klocale.h>
+
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kdebug.h>
+
+#include <kio/kprotocolmanager.h>
+#include <kio/kmimetype.h>
+#include <kio/kservice.h>
+#include <kio/ktrader.h>
+#include "kjs_navigator.h"
+#include "kjs/lookup.h"
+#include "kjs_binding.h"
+#include "khtml_part.h"
+#include <sys/utsname.h>
+#include "kjs_navigator.lut.h"
+
+using namespace KJS;
+
+namespace KJS {
+
+ // All objects that need plugin info must inherit from PluginBase
+ // Its ctor and dtor take care of the refcounting on the static lists.
+ class PluginBase : public ObjectImp {
+ public:
+ PluginBase(ExecState *exec, bool loadPluginInfo);
+ virtual ~PluginBase();
+
+ struct MimeClassInfo;
+ struct PluginInfo;
+
+ struct MimeClassInfo {
+ QString type;
+ QString desc;
+ QString suffixes;
+ PluginInfo *plugin;
+ };
+
+ struct PluginInfo {
+ QString name;
+ QString file;
+ QString desc;
+ QPtrList<MimeClassInfo> mimes;
+ };
+
+ static QPtrList<PluginInfo> *plugins;
+ static QPtrList<MimeClassInfo> *mimes;
+
+ private:
+ static int m_refCount;
+ };
+
+
+ class Plugins : public PluginBase {
+ public:
+ Plugins(ExecState *exec, bool pluginsEnabled)
+ : PluginBase(exec, pluginsEnabled),
+ m_pluginsEnabled(pluginsEnabled) {};
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ Value pluginByName( ExecState* exec, const QString& name ) const;
+ bool pluginsEnabled() const { return m_pluginsEnabled; };
+ private:
+ bool m_pluginsEnabled;
+ };
+
+
+ class MimeTypes : public PluginBase {
+ public:
+ MimeTypes(ExecState *exec, bool pluginsEnabled)
+ : PluginBase(exec, pluginsEnabled),
+ m_pluginsEnabled(pluginsEnabled) {};
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ Value getValueProperty(ExecState *exec, int token) const;
+ Value mimeTypeByName( ExecState* exec, const QString& name ) const;
+ bool pluginsEnabled() const { return m_pluginsEnabled; };
+ private:
+ bool m_pluginsEnabled;
+ };
+
+
+ class Plugin : public PluginBase {
+ public:
+ Plugin( ExecState *exec, PluginBase::PluginInfo *info )
+ : PluginBase( exec, true )
+ { m_info = info; };
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ Value mimeByName(ExecState* exec, const QString& name ) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ PluginBase::PluginInfo *pluginInfo() const { return m_info; }
+ private:
+ PluginBase::PluginInfo *m_info;
+ };
+
+
+ class MimeType : public PluginBase {
+ public:
+ MimeType( ExecState *exec, PluginBase::MimeClassInfo *info )
+ : PluginBase( exec, true )
+ { m_info = info; };
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ Value getValueProperty(ExecState *exec, int token) const;
+ private:
+ PluginBase::MimeClassInfo *m_info;
+ };
+
+}
+
+
+QPtrList<PluginBase::PluginInfo> *KJS::PluginBase::plugins = 0;
+QPtrList<PluginBase::MimeClassInfo> *KJS::PluginBase::mimes = 0;
+int KJS::PluginBase::m_refCount = 0;
+
+const ClassInfo Navigator::info = { "Navigator", 0, &NavigatorTable, 0 };
+/*
+@begin NavigatorTable 12
+ appCodeName Navigator::AppCodeName DontDelete|ReadOnly
+ appName Navigator::AppName DontDelete|ReadOnly
+ appVersion Navigator::AppVersion DontDelete|ReadOnly
+ language Navigator::Language DontDelete|ReadOnly
+ userAgent Navigator::UserAgent DontDelete|ReadOnly
+ userLanguage Navigator::UserLanguage DontDelete|ReadOnly
+ browserLanguage Navigator::BrowserLanguage DontDelete|ReadOnly
+ platform Navigator::Platform DontDelete|ReadOnly
+ cpuClass Navigator::CpuClass DontDelete|ReadOnly
+ plugins Navigator::_Plugins DontDelete|ReadOnly
+ mimeTypes Navigator::_MimeTypes DontDelete|ReadOnly
+ product Navigator::Product DontDelete|ReadOnly
+ vendor Navigator::Vendor DontDelete|ReadOnly
+ productSub Navigator::ProductSub DontDelete|ReadOnly
+ cookieEnabled Navigator::CookieEnabled DontDelete|ReadOnly
+ javaEnabled Navigator::JavaEnabled DontDelete|Function 0
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(NavigatorFunc)
+
+Navigator::Navigator(ExecState *exec, KHTMLPart *p)
+ : ObjectImp(exec->interpreter()->builtinObjectPrototype()), m_part(p) { }
+
+Value Navigator::get(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Navigator::get " << propertyName.ascii() << endl;
+#endif
+ return lookupGet<NavigatorFunc,Navigator,ObjectImp>(exec,propertyName,&NavigatorTable,this);
+}
+
+Value Navigator::getValueProperty(ExecState *exec, int token) const
+{
+ KURL url = m_part->url();
+ QString userAgent = url.host();
+ if (userAgent.isEmpty())
+ userAgent = "localhost";
+ userAgent = KProtocolManager::userAgentForHost(userAgent);
+ switch (token) {
+ case AppCodeName:
+ return String("Mozilla");
+ case AppName:
+ // If we find "Mozilla" but not "(compatible, ...)" we are a real Netscape
+ if (userAgent.find(QString::fromLatin1("Mozilla")) >= 0 &&
+ userAgent.find(QString::fromLatin1("compatible")) == -1)
+ {
+ //kdDebug() << "appName -> Mozilla" << endl;
+ return String("Netscape");
+ }
+ if (userAgent.find(QString::fromLatin1("Microsoft")) >= 0 ||
+ userAgent.find(QString::fromLatin1("MSIE")) >= 0)
+ {
+ //kdDebug() << "appName -> IE" << endl;
+ return String("Microsoft Internet Explorer");
+ }
+ //kdDebug() << "appName -> Konqueror" << endl;
+ return String("Konqueror");
+ case AppVersion:
+ // We assume the string is something like Mozilla/version (properties)
+ return String(userAgent.mid(userAgent.find('/') + 1));
+ case Product:
+ // We are pretending to be Mozilla or Safari
+ if (userAgent.find(QString::fromLatin1("Mozilla")) >= 0 &&
+ userAgent.find(QString::fromLatin1("compatible")) == -1)
+ {
+ return String("Gecko");
+ }
+ // When spoofing as IE, we use Undefined().
+ if (userAgent.find(QString::fromLatin1("Microsoft")) >= 0 ||
+ userAgent.find(QString::fromLatin1("MSIE")) >= 0)
+ {
+ return Undefined();
+ }
+ // We are acting straight
+ return String("Konqueror/khtml");
+ case ProductSub:
+ {
+ int ix = userAgent.find("Gecko");
+ if (ix >= 0 && userAgent.length() >= (uint)ix+14 && userAgent.unicode()[ix+5] == QChar('/') &&
+ userAgent.find(QRegExp("\\d{8}"), ix+6) == ix+6)
+ {
+ // We have Gecko/<productSub> in the UA string
+ return String(userAgent.mid(ix+6, 8));
+ }
+ else if (ix >= 0)
+ {
+ return String("20040107");
+ }
+ }
+ return Undefined();
+ case Vendor:
+ return String("KDE");
+ case BrowserLanguage:
+ case Language:
+ case UserLanguage:
+ return String(KGlobal::locale()->language());
+ case UserAgent:
+ return String(userAgent);
+ case Platform:
+ // yet another evil hack, but necessary to spoof some sites...
+ if ( (userAgent.find(QString::fromLatin1("Win"),0,false)>=0) )
+ return String(QString::fromLatin1("Win32"));
+ else if ( (userAgent.find(QString::fromLatin1("Macintosh"),0,false)>=0) ||
+ (userAgent.find(QString::fromLatin1("Mac_PowerPC"),0,false)>=0) )
+ return String(QString::fromLatin1("MacPPC"));
+ else
+ {
+ struct utsname name;
+ int ret = uname(&name);
+ if ( ret >= 0 )
+ return String(QString::fromLatin1("%1 %1 X11").arg(name.sysname).arg(name.machine));
+ else // can't happen
+ return String(QString::fromLatin1("Unix X11"));
+ }
+ case CpuClass:
+ {
+ struct utsname name;
+ int ret = uname(&name);
+ if ( ret >= 0 )
+ return String(name.machine);
+ else // can't happen
+ return String("x86");
+ }
+ case _Plugins:
+ return Value(new Plugins(exec, m_part->pluginsEnabled()));
+ case _MimeTypes:
+ return Value(new MimeTypes(exec, m_part->pluginsEnabled()));
+ case CookieEnabled:
+ return Boolean(true); /// ##### FIXME
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMEvent::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+/*******************************************************************/
+
+PluginBase::PluginBase(ExecState *exec, bool loadPluginInfo)
+ : ObjectImp(exec->interpreter()->builtinObjectPrototype() )
+{
+ if ( loadPluginInfo && !plugins ) {
+ plugins = new QPtrList<PluginInfo>;
+ mimes = new QPtrList<MimeClassInfo>;
+ plugins->setAutoDelete( true );
+ mimes->setAutoDelete( true );
+
+ // read in using KTrader
+ KTrader::OfferList offers = KTrader::self()->query("Browser/View");
+ KTrader::OfferList::iterator it;
+ for ( it = offers.begin(); it != offers.end(); ++it ) {
+
+ QVariant pluginsinfo = (**it).property( "X-KDE-BrowserView-PluginsInfo" );
+ if ( !pluginsinfo.isValid() ) {
+ // <backwards compatible>
+ if ((**it).library() == QString("libnsplugin"))
+ pluginsinfo = QVariant("nsplugins/pluginsinfo");
+ else
+ // </backwards compatible>
+ continue;
+ }
+ // read configuration
+ KConfig kc( locate ("data", pluginsinfo.toString()) );
+ unsigned num = (unsigned int) kc.readNumEntry("number");
+ for ( unsigned n = 0; n < num; n++ ) {
+ kc.setGroup( QString::number(n) );
+ PluginInfo *plugin = new PluginInfo;
+
+ plugin->name = kc.readEntry("name");
+ plugin->file = kc.readPathEntry("file");
+ plugin->desc = kc.readEntry("description");
+
+ plugins->append( plugin );
+
+ // get mime types from string
+ QStringList types = QStringList::split( ';', kc.readEntry("mime") );
+ QStringList::Iterator type;
+ for ( type=types.begin(); type!=types.end(); ++type ) {
+
+ // get mime information
+ QStringList tokens = QStringList::split(':', *type, true);
+ if ( tokens.count() < 3 ) // we need 3 items
+ continue;
+
+ MimeClassInfo *mime = new MimeClassInfo;
+ QStringList::Iterator token = tokens.begin();
+ mime->type = (*token).lower();
+ //kdDebug(6070) << "mime->type=" << mime->type << endl;
+ ++token;
+
+ mime->suffixes = *token;
+ ++token;
+
+ mime->desc = *token;
+ ++token;
+
+ mime->plugin = plugin;
+
+ mimes->append( mime );
+ plugin->mimes.append( mime );
+
+ }
+ }
+ }
+ }
+
+ m_refCount++;
+}
+
+PluginBase::~PluginBase()
+{
+ m_refCount--;
+ if ( m_refCount==0 ) {
+ delete plugins;
+ delete mimes;
+ plugins = 0;
+ mimes = 0;
+ }
+}
+
+
+/*******************************************************************/
+
+const ClassInfo Plugins::info = { "PluginArray", 0, &PluginsTable, 0 };
+/*
+@begin PluginsTable 4
+ length Plugins_Length DontDelete|ReadOnly
+ refresh Plugins_Refresh DontDelete|Function 0
+ item Plugins_Item DontDelete|Function 1
+ namedItem Plugins_NamedItem DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(PluginsFunc)
+
+Value Plugins::get(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Plugins::get " << propertyName.qstring() << endl;
+#endif
+ if (!pluginsEnabled()) {
+ if (propertyName == lengthPropertyName )
+ return Number(0);
+ } else {
+ if ( propertyName == lengthPropertyName )
+ return Number(plugins->count());
+
+ // plugins[#]
+ bool ok;
+ unsigned int i = propertyName.toULong(&ok);
+ if( ok && i<plugins->count() )
+ return Value( new Plugin( exec, plugins->at(i) ) );
+
+ // plugin[name]
+ Value val = pluginByName( exec, propertyName.qstring() );
+ if (!val.isA(UndefinedType))
+ return val;
+ }
+
+ return lookupGet<PluginsFunc,Plugins,ObjectImp>(exec,propertyName,&PluginsTable,this);
+}
+
+Value Plugins::pluginByName( ExecState* exec, const QString& name ) const
+{
+ Q_ASSERT(plugins);
+ for ( PluginInfo *pl = plugins->first(); pl!=0; pl = plugins->next() ) {
+ if ( pl->name == name )
+ return Value( new Plugin( exec, pl ) );
+ }
+ return Undefined();
+}
+
+Value Plugins::getValueProperty(ExecState* /*exec*/, int token) const
+{
+ kdDebug(6070) << "WARNING: Unhandled token in Plugins::getValueProperty : " << token << endl;
+ return Undefined();
+}
+
+Value PluginsFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::Plugins, thisObj );
+ KJS::Plugins* base = static_cast<KJS::Plugins *>(thisObj.imp());
+ if (!base->pluginsEnabled()) {
+ if (id == Plugins_Refresh || //## TODO
+ id == Plugins_Item ||
+ id == Plugins_NamedItem)
+ return Undefined();
+ } else {
+ switch( id ) {
+ case Plugins_Refresh:
+ return Undefined(); //## TODO
+ case Plugins_Item:
+ {
+ bool ok;
+ unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
+ if( ok && i<base->plugins->count() )
+ return Value( new Plugin( exec, base->plugins->at(i) ) );
+ return Undefined();
+ }
+ case Plugins_NamedItem:
+ UString s = args[0].toString(exec);
+ return base->pluginByName( exec, s.qstring() );
+ }
+ }
+ kdDebug(6070) << "WARNING: Unhandled token in PluginsFunc::tryCall : " << id << endl;
+ return Undefined();
+}
+
+/*******************************************************************/
+
+const ClassInfo MimeTypes::info = { "MimeTypeArray", 0, &MimeTypesTable, 0 };
+/*
+@begin MimeTypesTable 3
+ length MimeTypes_Length DontDelete|ReadOnly
+ item MimeTypes_Item DontDelete|Function 1
+ namedItem MimeTypes_NamedItem DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(MimeTypesFunc)
+
+Value MimeTypes::get(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "MimeTypes::get " << propertyName.qstring() << endl;
+#endif
+ if (!pluginsEnabled()) {
+ if (propertyName == lengthPropertyName )
+ return Number(0);
+ } else {
+ if( propertyName==lengthPropertyName )
+ return Number( mimes->count() );
+
+ // mimeTypes[#]
+ bool ok;
+ unsigned int i = propertyName.toULong(&ok);
+ if( ok && i<mimes->count() )
+ return Value( new MimeType( exec, mimes->at(i) ) );
+
+ // mimeTypes[name]
+ Value val = mimeTypeByName( exec, propertyName.qstring() );
+ if (!val.isA(UndefinedType))
+ return val;
+ }
+
+ return lookupGet<MimeTypesFunc,MimeTypes,ObjectImp>(exec,propertyName,&MimeTypesTable,this);
+}
+
+Value MimeTypes::mimeTypeByName( ExecState* exec, const QString& name ) const
+{
+ //kdDebug(6070) << "MimeTypes[" << name << "]" << endl;
+ Q_ASSERT(mimes);
+ for ( MimeClassInfo *m = mimes->first(); m!=0; m = mimes->next() ) {
+ if ( m->type == name )
+ return Value( new MimeType( exec, m ) );
+ }
+ return Undefined();
+}
+
+Value MimeTypes::getValueProperty(ExecState* /*exec*/, int token) const
+{
+ kdDebug(6070) << "WARNING: Unhandled token in MimeTypes::getValueProperty : " << token << endl;
+ return Undefined();
+}
+
+Value MimeTypesFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::MimeTypes, thisObj );
+ KJS::MimeTypes* base = static_cast<KJS::MimeTypes *>(thisObj.imp());
+ if (!base->pluginsEnabled()) {
+ if (id == MimeTypes_Item ||
+ id == MimeTypes_NamedItem)
+ return Undefined();
+ } else {
+ switch( id ) {
+ case MimeTypes_Item:
+ {
+ bool ok;
+ unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
+ if( ok && i<base->mimes->count() )
+ return Value( new MimeType( exec, base->mimes->at(i) ) );
+ return Undefined();
+ }
+ case MimeTypes_NamedItem:
+ UString s = args[0].toString(exec);
+ return base->mimeTypeByName( exec, s.qstring() );
+ }
+ }
+ kdDebug(6070) << "WARNING: Unhandled token in MimeTypesFunc::tryCall : " << id << endl;
+ return Undefined();
+}
+
+/************************************************************************/
+const ClassInfo Plugin::info = { "Plugin", 0, &PluginTable, 0 };
+/*
+@begin PluginTable 7
+ name Plugin_Name DontDelete|ReadOnly
+ filename Plugin_FileName DontDelete|ReadOnly
+ description Plugin_Description DontDelete|ReadOnly
+ length Plugin_Length DontDelete|ReadOnly
+ item Plugin_Item DontDelete|Function 1
+ namedItem Plugin_NamedItem DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(PluginFunc)
+
+Value Plugin::get(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Plugin::get " << propertyName.qstring() << endl;
+#endif
+ if ( propertyName == lengthPropertyName )
+ return Number( m_info->mimes.count() );
+
+ // plugin[#]
+ bool ok;
+ unsigned int i = propertyName.toULong(&ok);
+ //kdDebug(6070) << "Plugin::get plugin[" << i << "]" << endl;
+ if( ok && i<m_info->mimes.count() )
+ {
+ //kdDebug(6070) << "returning mimetype " << m_info->mimes.at(i)->type << endl;
+ return Value(new MimeType(exec, m_info->mimes.at(i)));
+ }
+
+ // plugin["name"]
+ Value val = mimeByName( exec, propertyName.qstring() );
+ if (!val.isA(UndefinedType))
+ return val;
+
+ return lookupGet<PluginFunc,Plugin,ObjectImp>(exec, propertyName, &PluginTable, this );
+}
+
+Value Plugin::mimeByName(ExecState* exec, const QString& name) const
+{
+ for ( PluginBase::MimeClassInfo *m = m_info->mimes.first();
+ m != 0; m = m_info->mimes.next() ) {
+ if ( m->type == name )
+ return Value(new MimeType(exec, m));
+ }
+ return Undefined();
+}
+
+Value Plugin::getValueProperty(ExecState* /*exec*/, int token) const
+{
+ switch( token ) {
+ case Plugin_Name:
+ return String( m_info->name );
+ case Plugin_FileName:
+ return String( m_info->file );
+ case Plugin_Description:
+ return String( m_info->desc );
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in Plugin::getValueProperty : " << token << endl;
+ return Undefined();
+ }
+}
+
+Value PluginFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::Plugin, thisObj );
+ KJS::Plugin* plugin = static_cast<KJS::Plugin *>(thisObj.imp());
+ switch( id ) {
+ case Plugin_Item:
+ {
+ bool ok;
+ unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
+ if( ok && i< plugin->pluginInfo()->mimes.count() )
+ return Value( new MimeType( exec, plugin->pluginInfo()->mimes.at(i) ) );
+ return Undefined();
+ }
+ case Plugin_NamedItem:
+ {
+ UString s = args[0].toString(exec);
+ return plugin->mimeByName( exec, s.qstring() );
+ }
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in PluginFunc::tryCall : " << id << endl;
+ return Undefined();
+ }
+}
+
+/*****************************************************************************/
+
+const ClassInfo MimeType::info = { "MimeType", 0, &MimeTypeTable, 0 };
+/*
+@begin MimeTypeTable 4
+ description MimeType_Description DontDelete|ReadOnly
+ enabledPlugin MimeType_EnabledPlugin DontDelete|ReadOnly
+ suffixes MimeType_Suffixes DontDelete|ReadOnly
+ type MimeType_Type DontDelete|ReadOnly
+@end
+*/
+
+Value MimeType::get(ExecState *exec, const Identifier &propertyName) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "MimeType::get " << propertyName.qstring() << endl;
+#endif
+ return lookupGetValue<MimeType,ObjectImp>(exec, propertyName, &MimeTypeTable, this );
+}
+
+Value MimeType::getValueProperty(ExecState* exec, int token) const
+{
+ switch( token ) {
+ case MimeType_Type:
+ return String( m_info->type );
+ case MimeType_Suffixes:
+ return String( m_info->suffixes );
+ case MimeType_Description:
+ return String( m_info->desc );
+ case MimeType_EnabledPlugin:
+ return Value(new Plugin(exec, m_info->plugin));
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in MimeType::getValueProperty : " << token << endl;
+ return Undefined();
+ }
+}
+
+
+Value NavigatorFunc::tryCall(ExecState *exec, Object &thisObj, const List &)
+{
+ KJS_CHECK_THIS( KJS::Navigator, thisObj );
+ Navigator *nav = static_cast<Navigator *>(thisObj.imp());
+ // javaEnabled()
+ return Boolean(nav->part()->javaEnabled());
+}
diff --git a/khtml/ecma/kjs_navigator.h b/khtml/ecma/kjs_navigator.h
new file mode 100644
index 000000000..ccd1ba63b
--- /dev/null
+++ b/khtml/ecma/kjs_navigator.h
@@ -0,0 +1,53 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_NAVIGATOR_H_
+#define _KJS_NAVIGATOR_H_
+
+#include <kjs/object.h>
+
+class KHTMLPart;
+
+namespace KJS {
+
+ class Navigator : public ObjectImp {
+ public:
+ Navigator(ExecState *exec, KHTMLPart *p);
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { AppCodeName, AppName, AppVersion, Language, UserAgent, UserLanguage, Platform,
+ _Plugins, _MimeTypes, Product, ProductSub, Vendor, CookieEnabled, JavaEnabled,
+ BrowserLanguage, CpuClass };
+ KHTMLPart *part() const { return m_part; }
+ private:
+ KHTMLPart *m_part;
+ };
+
+ // Hashtable enums
+ enum { Plugins_Refresh, Plugins_Length, Plugins_Item, Plugins_NamedItem };
+ enum { MimeTypes_Length, MimeTypes_Item, MimeTypes_NamedItem };
+ enum { Plugin_Name, Plugin_FileName, Plugin_Description, Plugin_Length, Plugin_Item, Plugin_NamedItem };
+ enum { MimeType_Type, MimeType_Description, MimeType_EnabledPlugin, MimeType_Suffixes };
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_proxy.cpp b/khtml/ecma/kjs_proxy.cpp
new file mode 100644
index 000000000..789f99f38
--- /dev/null
+++ b/khtml/ecma/kjs_proxy.cpp
@@ -0,0 +1,411 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001,2003 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2001-2003 David Faure (faure@kde.org)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#if defined(HAVE_VALGRIND_MEMCHECK_H) && !defined(NDEBUG)
+
+#include <valgrind/memcheck.h>
+#define VALGRIND_SUPPORT
+
+#endif
+
+
+#include "kjs_proxy.h"
+
+#include "kjs_window.h"
+#include "kjs_events.h"
+#include "kjs_debugwin.h"
+#include "xml/dom_nodeimpl.h"
+#include "khtmlpart_p.h"
+#include <khtml_part.h>
+#include <kprotocolmanager.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <assert.h>
+#include <kjs/function.h>
+
+using namespace KJS;
+
+extern "C" {
+ KJSProxy *kjs_html_init(khtml::ChildFrame *childframe);
+}
+
+namespace KJS {
+
+class KJSProxyImpl : public KJSProxy {
+public:
+ KJSProxyImpl(khtml::ChildFrame *frame);
+ virtual ~KJSProxyImpl();
+ virtual QVariant evaluate(QString filename, int baseLine, const QString &, const DOM::Node &n,
+ Completion *completion = 0);
+ virtual void clear();
+ virtual DOM::EventListener *createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl *node);
+ virtual void finishedWithEvent(const DOM::Event &event);
+ virtual KJS::Interpreter *interpreter();
+
+ virtual void setDebugEnabled(bool enabled);
+ virtual void showDebugWindow(bool show=true);
+ virtual bool paused() const;
+ virtual void dataReceived();
+
+ void initScript();
+ void applyUserAgent();
+
+private:
+ KJS::ScriptInterpreter* m_script;
+ bool m_debugEnabled;
+#ifndef NDEBUG
+ static int s_count;
+#endif
+};
+
+} // namespace KJS
+
+#ifndef NDEBUG
+int KJSProxyImpl::s_count = 0;
+#endif
+
+KJSProxyImpl::KJSProxyImpl(khtml::ChildFrame *frame)
+{
+ m_script = 0;
+ m_frame = frame;
+ m_debugEnabled = false;
+#ifndef NDEBUG
+ s_count++;
+#endif
+}
+
+KJSProxyImpl::~KJSProxyImpl()
+{
+ if ( m_script ) {
+ //kdDebug() << "KJSProxyImpl::~KJSProxyImpl clearing global object " << m_script->globalObject().imp() << endl;
+ // This allows to delete the global-object properties, like all the protos
+ static_cast<ObjectImp*>(m_script->globalObject().imp())->deleteAllProperties( m_script->globalExec() );
+ //kdDebug() << "KJSProxyImpl::~KJSProxyImpl garbage collecting" << endl;
+ while (KJS::Interpreter::collect())
+ ;
+ //kdDebug() << "KJSProxyImpl::~KJSProxyImpl deleting interpreter " << m_script << endl;
+ delete m_script;
+ //kdDebug() << "KJSProxyImpl::~KJSProxyImpl garbage collecting again" << endl;
+ // Garbage collect - as many times as necessary
+ // (we could delete an object which was holding another object, so
+ // the deref() will happen too late for deleting the impl of the 2nd object).
+ while (KJS::Interpreter::collect())
+ ;
+ }
+
+#ifndef NDEBUG
+ s_count--;
+ // If it was the last interpreter, we should have nothing left
+#ifdef KJS_DEBUG_MEM
+ if ( s_count == 0 )
+ Interpreter::finalCheck();
+#endif
+#endif
+}
+
+QVariant KJSProxyImpl::evaluate(QString filename, int baseLine,
+ const QString&str, const DOM::Node &n, Completion *completion) {
+ // evaluate code. Returns the JS return value or an invalid QVariant
+ // if there was none, an error occurred or the type couldn't be converted.
+
+ initScript();
+ // inlineCode is true for <a href="javascript:doSomething()">
+ // and false for <script>doSomething()</script>. Check if it has the
+ // expected value in all cases.
+ // See smart window.open policy for where this is used.
+ bool inlineCode = filename.isNull();
+ //kdDebug(6070) << "KJSProxyImpl::evaluate inlineCode=" << inlineCode << endl;
+
+#ifdef KJS_DEBUGGER
+ if (inlineCode)
+ filename = "(unknown file)";
+ if (KJSDebugWin::debugWindow()) {
+ KJSDebugWin::debugWindow()->attach(m_script);
+ KJSDebugWin::debugWindow()->setNextSourceInfo(filename,baseLine);
+ // KJSDebugWin::debugWindow()->setMode(KJSDebugWin::Step);
+ }
+#else
+ Q_UNUSED(baseLine);
+#endif
+
+ m_script->setInlineCode(inlineCode);
+ Window* window = Window::retrieveWindow( m_frame->m_part );
+ KJS::Value thisNode = n.isNull() ? Window::retrieve( m_frame->m_part ) : getDOMNode(m_script->globalExec(),n);
+
+ UString code( str );
+
+ KJSCPUGuard guard;
+ guard.start();
+ Completion comp = m_script->evaluate(code, thisNode);
+ guard.stop();
+
+ bool success = ( comp.complType() == Normal ) || ( comp.complType() == ReturnValue );
+
+ if (completion)
+ *completion = comp;
+
+#ifdef KJS_DEBUGGER
+ // KJSDebugWin::debugWindow()->setCode(QString::null);
+#endif
+
+ window->afterScriptExecution();
+
+ // let's try to convert the return value
+ if (success && comp.value().isValid())
+ return ValueToVariant( m_script->globalExec(), comp.value());
+ else
+ {
+ if ( comp.complType() == Throw )
+ {
+ UString msg = comp.value().toString(m_script->globalExec());
+ kdDebug(6070) << "WARNING: Script threw exception: " << msg.qstring() << endl;
+ }
+ return QVariant();
+ }
+}
+
+// Implementation of the debug() function
+class TestFunctionImp : public ObjectImp {
+public:
+ TestFunctionImp() : ObjectImp() {}
+ virtual bool implementsCall() const { return true; }
+ virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+};
+
+Value TestFunctionImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
+{
+ fprintf(stderr,"--> %s\n",args[0].toString(exec).ascii());
+ return Undefined();
+}
+
+void KJSProxyImpl::clear() {
+ // clear resources allocated by the interpreter, and make it ready to be used by another page
+ // We have to keep it, so that the Window object for the part remains the same.
+ // (we used to delete and re-create it, previously)
+ if (m_script) {
+#ifdef KJS_DEBUGGER
+ // ###
+ KJSDebugWin *debugWin = KJSDebugWin::debugWindow();
+ if (debugWin) {
+ if (debugWin->getExecState() &&
+ debugWin->getExecState()->interpreter() == m_script)
+ debugWin->slotStop();
+ debugWin->clearInterpreter(m_script);
+ }
+#endif
+ m_script->clear();
+
+ Window *win = static_cast<Window *>(m_script->globalObject().imp());
+ if (win) {
+ win->clear( m_script->globalExec() );
+ // re-add "debug", clear() removed it
+ m_script->globalObject().put(m_script->globalExec(),
+ "debug", Value(new TestFunctionImp()), Internal);
+ if ( win->part() )
+ applyUserAgent();
+ }
+
+ // Really delete everything that can be, so that the DOM nodes get deref'ed
+ //kdDebug() << k_funcinfo << "all done -> collecting" << endl;
+ while (KJS::Interpreter::collect())
+ ;
+ }
+}
+
+DOM::EventListener *KJSProxyImpl::createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl *node)
+{
+ initScript();
+
+#ifdef KJS_DEBUGGER
+ if (KJSDebugWin::debugWindow()) {
+ KJSDebugWin::debugWindow()->attach(m_script);
+ KJSDebugWin::debugWindow()->setNextSourceInfo(sourceUrl,m_handlerLineno);
+ }
+#else
+ Q_UNUSED(sourceUrl);
+#endif
+
+ return KJS::Window::retrieveWindow(m_frame->m_part)->getJSLazyEventListener(code,name,node);
+}
+
+void KJSProxyImpl::finishedWithEvent(const DOM::Event &event)
+{
+ // This is called when the DOM implementation has finished with a particular event. This
+ // is the case in sitations where an event has been created just for temporary usage,
+ // e.g. an image load or mouse move. Once the event has been dispatched, it is forgotten
+ // by the DOM implementation and so does not need to be cached still by the interpreter
+ ScriptInterpreter::forgetDOMObject(event.handle());
+}
+
+KJS::Interpreter *KJSProxyImpl::interpreter()
+{
+ if (!m_script)
+ initScript();
+ return m_script;
+}
+
+void KJSProxyImpl::setDebugEnabled(bool enabled)
+{
+#ifdef KJS_DEBUGGER
+ m_debugEnabled = enabled;
+ //if (m_script)
+ // m_script->setDebuggingEnabled(enabled);
+ // NOTE: this is consistent across all KJSProxyImpl instances, as we only
+ // ever have 1 debug window
+ if (!enabled && KJSDebugWin::debugWindow()) {
+ KJSDebugWin::destroyInstance();
+ }
+ else if (enabled && !KJSDebugWin::debugWindow()) {
+ KJSDebugWin::createInstance();
+ initScript();
+ KJSDebugWin::debugWindow()->attach(m_script);
+ }
+#else
+ Q_UNUSED(enabled);
+#endif
+}
+
+void KJSProxyImpl::showDebugWindow(bool /*show*/)
+{
+#ifdef KJS_DEBUGGER
+ if (KJSDebugWin::debugWindow())
+ KJSDebugWin::debugWindow()->show();
+#else
+ //Q_UNUSED(show);
+#endif
+}
+
+bool KJSProxyImpl::paused() const
+{
+#ifdef KJS_DEBUGGER
+ if (KJSDebugWin::debugWindow())
+ return KJSDebugWin::debugWindow()->inSession();
+#endif
+ return false;
+}
+
+void KJSProxyImpl::dataReceived()
+{
+#ifdef KJS_DEBUGGER
+ if (KJSDebugWin::debugWindow() && m_frame->m_part)
+ KJSDebugWin::debugWindow()->sourceChanged(m_script,m_frame->m_part->url().url());
+#endif
+}
+
+void KJSProxyImpl::initScript()
+{
+ if (m_script)
+ return;
+
+ // Build the global object - which is a Window instance
+ Object globalObject( new Window(m_frame) );
+
+ // Create a KJS interpreter for this part
+ m_script = new KJS::ScriptInterpreter(globalObject, m_frame);
+ static_cast<ObjectImp*>(globalObject.imp())->setPrototype(m_script->builtinObjectPrototype());
+
+#ifdef KJS_DEBUGGER
+ //m_script->setDebuggingEnabled(m_debugEnabled);
+#endif
+ //m_script->enableDebug();
+ globalObject.put(m_script->globalExec(),
+ "debug", Value(new TestFunctionImp()), Internal);
+ applyUserAgent();
+}
+
+void KJSProxyImpl::applyUserAgent()
+{
+ assert( m_script );
+ QString host = m_frame->m_part->url().isLocalFile() ? "localhost" : m_frame->m_part->url().host();
+ QString userAgent = KProtocolManager::userAgentForHost(host);
+ if (userAgent.find(QString::fromLatin1("Microsoft")) >= 0 ||
+ userAgent.find(QString::fromLatin1("MSIE")) >= 0)
+ {
+ m_script->setCompatMode(Interpreter::IECompat);
+#ifdef KJS_VERBOSE
+ kdDebug() << "Setting IE compat mode" << endl;
+#endif
+ }
+ else
+ // If we find "Mozilla" but not "(compatible, ...)" we are a real Netscape
+ if (userAgent.find(QString::fromLatin1("Mozilla")) >= 0 &&
+ userAgent.find(QString::fromLatin1("compatible")) == -1 &&
+ userAgent.find(QString::fromLatin1("KHTML")) == -1)
+ {
+ m_script->setCompatMode(Interpreter::NetscapeCompat);
+#ifdef KJS_VERBOSE
+ kdDebug() << "Setting NS compat mode" << endl;
+#endif
+ }
+}
+
+// Helper method, so that all classes which need jScript() don't need to be added
+// as friend to KHTMLPart
+KJSProxy * KJSProxy::proxy( KHTMLPart *part )
+{
+ return part->jScript();
+}
+
+// initialize HTML module
+KJSProxy *kjs_html_init(khtml::ChildFrame *childframe)
+{
+ return new KJSProxyImpl(childframe);
+}
+
+void KJSCPUGuard::start(unsigned int ms, unsigned int i_ms)
+{
+#ifdef VALGRIND_SUPPORT
+ if (RUNNING_ON_VALGRIND) {
+ ms *= 50;
+ i_ms *= 50;
+ }
+#endif
+
+ oldAlarmHandler = signal(SIGVTALRM, alarmHandler);
+ itimerval tv = {
+ { i_ms / 1000, (i_ms % 1000) * 1000 },
+ { ms / 1000, (ms % 1000) * 1000 }
+ };
+ setitimer(ITIMER_VIRTUAL, &tv, &oldtv);
+}
+
+void KJSCPUGuard::stop()
+{
+ setitimer(ITIMER_VIRTUAL, &oldtv, 0L);
+ signal(SIGVTALRM, oldAlarmHandler);
+}
+
+bool KJSCPUGuard::confirmTerminate() {
+ kdDebug(6070) << "alarmhandler" << endl;
+ return KMessageBox::warningYesNo(0L, i18n("A script on this page is causing KHTML to freeze. If it continues to run, other applications may become less responsive.\nDo you want to abort the script?"), i18n("JavaScript"), i18n("&Abort"), KStdGuiItem::cont(), "kjscupguard_alarmhandler") == KMessageBox::Yes;
+}
+
+void KJSCPUGuard::alarmHandler(int) {
+ ExecState::requestTerminate();
+ ExecState::confirmTerminate = KJSCPUGuard::confirmTerminate;
+}
diff --git a/khtml/ecma/kjs_proxy.h b/khtml/ecma/kjs_proxy.h
new file mode 100644
index 000000000..f76543451
--- /dev/null
+++ b/khtml/ecma/kjs_proxy.h
@@ -0,0 +1,91 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_PROXY_H_
+#define _KJS_PROXY_H_
+
+#include <qvariant.h>
+#include <qstring.h>
+#include <sys/time.h>
+
+class KHTMLPart;
+
+namespace DOM {
+ class Node;
+ class NodeImpl;
+ class EventListener;
+ class Event;
+}
+
+namespace KJS {
+ class List;
+ class Interpreter;
+ class Completion;
+ class KJSDebugWin;
+}
+
+namespace khtml {
+ class ChildFrame;
+}
+
+/**
+ * @internal
+ *
+ * @short Proxy class serving as interface when being dlopen'ed.
+ */
+class KJSProxy {
+public:
+ KJSProxy() { m_handlerLineno = 0; }
+ virtual ~KJSProxy() { }
+ virtual QVariant evaluate(QString filename, int baseLine, const QString &, const DOM::Node &n,
+ KJS::Completion *completion = 0) = 0;
+ virtual void clear() = 0;
+ virtual DOM::EventListener *createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl* node) = 0;
+ virtual void finishedWithEvent(const DOM::Event &event) = 0;
+ virtual KJS::Interpreter *interpreter() = 0;
+
+ virtual void setDebugEnabled(bool enabled) = 0;
+ virtual void showDebugWindow(bool show=true) = 0;
+ virtual bool paused() const = 0;
+ virtual void dataReceived() = 0;
+
+ void setEventHandlerLineno(int lineno) { m_handlerLineno = lineno; }
+
+ khtml::ChildFrame *m_frame;
+ int m_handlerLineno;
+
+ // Helper method, to access the private KHTMLPart::jScript()
+ static KJSProxy *proxy( KHTMLPart *part );
+};
+
+class KJSCPUGuard {
+public:
+ KJSCPUGuard() {}
+ void start(unsigned int msec=5000, unsigned int i_msec=10000);
+ void stop();
+private:
+ void (*oldAlarmHandler)(int);
+ static void alarmHandler(int);
+ static bool confirmTerminate();
+ itimerval oldtv;
+};
+
+#endif
diff --git a/khtml/ecma/kjs_range.cpp b/khtml/ecma/kjs_range.cpp
new file mode 100644
index 000000000..bf148ffe8
--- /dev/null
+++ b/khtml/ecma/kjs_range.cpp
@@ -0,0 +1,233 @@
+
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "kjs_range.h"
+#include "kjs_range.lut.h"
+#include <kdebug.h>
+
+namespace KJS {
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMRange::info = { "Range", 0, &DOMRangeTable, 0 };
+/*
+@begin DOMRangeTable 7
+ startContainer DOMRange::StartContainer DontDelete|ReadOnly
+ startOffset DOMRange::StartOffset DontDelete|ReadOnly
+ endContainer DOMRange::EndContainer DontDelete|ReadOnly
+ endOffset DOMRange::EndOffset DontDelete|ReadOnly
+ collapsed DOMRange::Collapsed DontDelete|ReadOnly
+ commonAncestorContainer DOMRange::CommonAncestorContainer DontDelete|ReadOnly
+@end
+@begin DOMRangeProtoTable 17
+setStart DOMRange::SetStart DontDelete|Function 2
+ setEnd DOMRange::SetEnd DontDelete|Function 2
+ setStartBefore DOMRange::SetStartBefore DontDelete|Function 1
+ setStartAfter DOMRange::SetStartAfter DontDelete|Function 1
+ setEndBefore DOMRange::SetEndBefore DontDelete|Function 1
+ setEndAfter DOMRange::SetEndAfter DontDelete|Function 1
+ collapse DOMRange::Collapse DontDelete|Function 1
+ selectNode DOMRange::SelectNode DontDelete|Function 1
+ selectNodeContents DOMRange::SelectNodeContents DontDelete|Function 1
+ compareBoundaryPoints DOMRange::CompareBoundaryPoints DontDelete|Function 2
+ deleteContents DOMRange::DeleteContents DontDelete|Function 0
+ extractContents DOMRange::ExtractContents DontDelete|Function 0
+ cloneContents DOMRange::CloneContents DontDelete|Function 0
+ insertNode DOMRange::InsertNode DontDelete|Function 1
+ surroundContents DOMRange::SurroundContents DontDelete|Function 1
+ cloneRange DOMRange::CloneRange DontDelete|Function 0
+ toString DOMRange::ToString DontDelete|Function 0
+ detach DOMRange::Detach DontDelete|Function 0
+ createContextualFragment DOMRange::CreateContextualFragment DontDelete|Function 1
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMRangeProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMRangeProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMRange",DOMRangeProto,DOMRangeProtoFunc)
+
+DOMRange::DOMRange(ExecState *exec, DOM::Range r)
+ : DOMObject(DOMRangeProto::self(exec)), range(r) {}
+
+DOMRange::~DOMRange()
+{
+ ScriptInterpreter::forgetDOMObject(range.handle());
+}
+
+Value DOMRange::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMRange,DOMObject>(exec,p,&DOMRangeTable,this);
+}
+
+Value DOMRange::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case StartContainer:
+ return getDOMNode(exec,range.startContainer());
+ case StartOffset:
+ return Number(range.startOffset());
+ case EndContainer:
+ return getDOMNode(exec,range.endContainer());
+ case EndOffset:
+ return Number(range.endOffset());
+ case Collapsed:
+ return Boolean(range.collapsed());
+ case CommonAncestorContainer: {
+ DOM::Range range2 = range; // avoid const error
+ return getDOMNode(exec,range2.commonAncestorContainer());
+ }
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMRange::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+Value DOMRangeProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMRange, thisObj );
+ DOM::Range range = static_cast<DOMRange *>(thisObj.imp())->toRange();
+ Value result;
+
+ switch (id) {
+ case DOMRange::SetStart:
+ range.setStart(toNode(args[0]),args[1].toInteger(exec));
+ result = Undefined();
+ break;
+ case DOMRange::SetEnd:
+ range.setEnd(toNode(args[0]),args[1].toInteger(exec));
+ result = Undefined();
+ break;
+ case DOMRange::SetStartBefore:
+ range.setStartBefore(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::SetStartAfter:
+ range.setStartAfter(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::SetEndBefore:
+ range.setEndBefore(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::SetEndAfter:
+ range.setEndAfter(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::Collapse:
+ range.collapse(args[0].toBoolean(exec));
+ result = Undefined();
+ break;
+ case DOMRange::SelectNode:
+ range.selectNode(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::SelectNodeContents:
+ range.selectNodeContents(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::CompareBoundaryPoints:
+ result = Number(range.compareBoundaryPoints(static_cast<DOM::Range::CompareHow>(args[0].toInteger(exec)),toRange(args[1])));
+ break;
+ case DOMRange::DeleteContents:
+ range.deleteContents();
+ result = Undefined();
+ break;
+ case DOMRange::ExtractContents:
+ result = getDOMNode(exec,range.extractContents());
+ break;
+ case DOMRange::CloneContents:
+ result = getDOMNode(exec,range.cloneContents());
+ break;
+ case DOMRange::InsertNode:
+ range.insertNode(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::SurroundContents:
+ range.surroundContents(toNode(args[0]));
+ result = Undefined();
+ break;
+ case DOMRange::CloneRange:
+ result = getDOMRange(exec,range.cloneRange());
+ break;
+ case DOMRange::ToString:
+ result = String(range.toString());
+ break;
+ case DOMRange::Detach:
+ range.detach();
+ result = Undefined();
+ break;
+ case DOMRange::CreateContextualFragment:
+ Value value = args[0];
+ DOM::DOMString str = value.isA(NullType) ? DOM::DOMString() : value.toString(exec).string();
+ result = getDOMNode(exec, range.createContextualFragment(str));
+ break;
+ };
+
+ return result;
+}
+
+Value getDOMRange(ExecState *exec, DOM::Range r)
+{
+ return cacheDOMObject<DOM::Range, KJS::DOMRange>(exec, r);
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo RangeConstructor::info = { "RangeConstructor", 0, &RangeConstructorTable, 0 };
+/*
+@begin RangeConstructorTable 5
+ START_TO_START DOM::Range::START_TO_START DontDelete|ReadOnly
+ START_TO_END DOM::Range::START_TO_END DontDelete|ReadOnly
+ END_TO_END DOM::Range::END_TO_END DontDelete|ReadOnly
+ END_TO_START DOM::Range::END_TO_START DontDelete|ReadOnly
+@end
+*/
+
+RangeConstructor::RangeConstructor(ExecState *exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()) { }
+
+Value RangeConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<RangeConstructor,DOMObject>(exec,p,&RangeConstructorTable,this);
+}
+
+Value RangeConstructor::getValueProperty(ExecState *, int token) const
+{
+ return Number(token);
+}
+
+Value getRangeConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<RangeConstructor>(exec, "[[range.constructor]]");
+}
+
+
+DOM::Range toRange(const Value& val)
+{
+ Object obj = Object::dynamicCast(val);
+ if (!obj.isValid() || !obj.inherits(&DOMRange::info))
+ return DOM::Range();
+
+ const DOMRange *dobj = static_cast<const DOMRange*>(obj.imp());
+ return dobj->toRange();
+}
+
+} //namespace KJS
diff --git a/khtml/ecma/kjs_range.h b/khtml/ecma/kjs_range.h
new file mode 100644
index 000000000..fbf47020f
--- /dev/null
+++ b/khtml/ecma/kjs_range.h
@@ -0,0 +1,71 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_RANGE_H_
+#define _KJS_RANGE_H_
+
+#include "ecma/kjs_dom.h"
+#include "dom/dom2_range.h"
+
+namespace KJS {
+
+ class DOMRange : public DOMObject {
+ public:
+ DOMRange(ExecState *exec, DOM::Range r);
+ ~DOMRange();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { StartContainer, StartOffset, EndContainer, EndOffset, Collapsed,
+ CommonAncestorContainer,
+ SetStart, SetEnd, SetStartBefore, SetStartAfter, SetEndBefore,
+ SetEndAfter, Collapse, SelectNode, SelectNodeContents,
+ CompareBoundaryPoints, DeleteContents, ExtractContents,
+ CloneContents, InsertNode, SurroundContents, CloneRange, ToString,
+ Detach, CreateContextualFragment };
+ DOM::Range toRange() const { return range; }
+ protected:
+ DOM::Range range;
+ };
+
+ // Constructor object Range
+ class RangeConstructor : public DOMObject {
+ public:
+ RangeConstructor(ExecState *);
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ Value getDOMRange(ExecState *exec, DOM::Range r);
+ Value getRangeConstructor(ExecState *exec);
+
+ /**
+ * Convert an object to a Range. Returns a null Node if not possible.
+ */
+ DOM::Range toRange(const Value&);
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_traversal.cpp b/khtml/ecma/kjs_traversal.cpp
new file mode 100644
index 000000000..5b521b6d5
--- /dev/null
+++ b/khtml/ecma/kjs_traversal.cpp
@@ -0,0 +1,327 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "kjs_traversal.h"
+#include "kjs_traversal.lut.h"
+#include "kjs_proxy.h"
+#include <dom/dom_node.h>
+#include <xml/dom_nodeimpl.h>
+#include <xml/dom_docimpl.h>
+#include <khtmlview.h>
+#include <khtml_part.h>
+#include <kdebug.h>
+
+namespace KJS {
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMNodeIterator::info = { "NodeIterator", 0, &DOMNodeIteratorTable, 0 };
+/*
+@begin DOMNodeIteratorTable 5
+ root DOMNodeIterator::Root DontDelete|ReadOnly
+ whatToShow DOMNodeIterator::WhatToShow DontDelete|ReadOnly
+ filter DOMNodeIterator::Filter DontDelete|ReadOnly
+ expandEntityReferences DOMNodeIterator::ExpandEntityReferences DontDelete|ReadOnly
+@end
+@begin DOMNodeIteratorProtoTable 3
+ nextNode DOMNodeIterator::NextNode DontDelete|Function 0
+ previousNode DOMNodeIterator::PreviousNode DontDelete|Function 0
+ detach DOMNodeIterator::Detach DontDelete|Function 0
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMNodeIteratorProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMNodeIteratorProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMNodeIterator", DOMNodeIteratorProto,DOMNodeIteratorProtoFunc)
+
+DOMNodeIterator::DOMNodeIterator(ExecState *exec, DOM::NodeIterator ni)
+ : DOMObject(DOMNodeIteratorProto::self(exec)), nodeIterator(ni) {}
+
+DOMNodeIterator::~DOMNodeIterator()
+{
+ ScriptInterpreter::forgetDOMObject(nodeIterator.handle());
+}
+
+Value DOMNodeIterator::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMNodeIterator,DOMObject>(exec,p,&DOMNodeIteratorTable,this);
+}
+
+Value DOMNodeIterator::getValueProperty(ExecState *exec, int token) const
+{
+ DOM::NodeIterator ni(nodeIterator);
+ switch (token) {
+ case Root:
+ return getDOMNode(exec,ni.root());
+ case WhatToShow:
+ return Number(ni.whatToShow());
+ case Filter:
+ return getDOMNodeFilter(exec,ni.filter());
+ case ExpandEntityReferences:
+ return Boolean(ni.expandEntityReferences());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMNodeIterator::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+Value DOMNodeIteratorProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &)
+{
+ KJS_CHECK_THIS( KJS::DOMNodeIterator, thisObj );
+ DOM::NodeIterator nodeIterator = static_cast<DOMNodeIterator *>(thisObj.imp())->toNodeIterator();
+ switch (id) {
+ case DOMNodeIterator::PreviousNode:
+ return getDOMNode(exec,nodeIterator.previousNode());
+ case DOMNodeIterator::NextNode:
+ return getDOMNode(exec,nodeIterator.nextNode());
+ case DOMNodeIterator::Detach:
+ nodeIterator.detach();
+ return Undefined();
+ }
+ return Undefined();
+}
+
+Value getDOMNodeIterator(ExecState *exec, DOM::NodeIterator ni)
+{
+ return cacheDOMObject<DOM::NodeIterator, DOMNodeIterator>(exec, ni);
+}
+
+
+// -------------------------------------------------------------------------
+
+const ClassInfo NodeFilterConstructor::info = { "NodeFilterConstructor", 0, &NodeFilterConstructorTable, 0 };
+/*
+@begin NodeFilterConstructorTable 17
+ FILTER_ACCEPT DOM::NodeFilter::FILTER_ACCEPT DontDelete|ReadOnly
+ FILTER_REJECT DOM::NodeFilter::FILTER_REJECT DontDelete|ReadOnly
+ FILTER_SKIP DOM::NodeFilter::FILTER_SKIP DontDelete|ReadOnly
+ SHOW_ALL DOM::NodeFilter::SHOW_ALL DontDelete|ReadOnly
+ SHOW_ELEMENT DOM::NodeFilter::SHOW_ELEMENT DontDelete|ReadOnly
+ SHOW_ATTRIBUTE DOM::NodeFilter::SHOW_ATTRIBUTE DontDelete|ReadOnly
+ SHOW_TEXT DOM::NodeFilter::SHOW_TEXT DontDelete|ReadOnly
+ SHOW_CDATA_SECTION DOM::NodeFilter::SHOW_CDATA_SECTION DontDelete|ReadOnly
+ SHOW_ENTITY_REFERENCE DOM::NodeFilter::SHOW_ENTITY_REFERENCE DontDelete|ReadOnly
+ SHOW_ENTITY DOM::NodeFilter::SHOW_ENTITY DontDelete|ReadOnly
+ SHOW_PROCESSING_INSTRUCTION DOM::NodeFilter::SHOW_PROCESSING_INSTRUCTION DontDelete|ReadOnly
+ SHOW_COMMENT DOM::NodeFilter::SHOW_COMMENT DontDelete|ReadOnly
+ SHOW_DOCUMENT DOM::NodeFilter::SHOW_DOCUMENT DontDelete|ReadOnly
+ SHOW_DOCUMENT_TYPE DOM::NodeFilter::SHOW_DOCUMENT_TYPE DontDelete|ReadOnly
+ SHOW_DOCUMENT_FRAGMENT DOM::NodeFilter::SHOW_DOCUMENT_FRAGMENT DontDelete|ReadOnly
+ SHOW_NOTATION DOM::NodeFilter::SHOW_NOTATION DontDelete|ReadOnly
+@end
+*/
+
+NodeFilterConstructor::NodeFilterConstructor(ExecState* exec)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype())
+{
+}
+
+Value NodeFilterConstructor::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<NodeFilterConstructor,DOMObject>(exec,p,&NodeFilterConstructorTable,this);
+}
+
+Value NodeFilterConstructor::getValueProperty(ExecState *, int token) const
+{
+ // We use the token as the value to return directly
+ return Number(token);
+}
+
+Value getNodeFilterConstructor(ExecState *exec)
+{
+ return cacheGlobalObject<NodeFilterConstructor>(exec, "[[nodeFilter.constructor]]");
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMNodeFilter::info = { "NodeFilter", 0, 0, 0 };
+/*
+@begin DOMNodeFilterProtoTable 1
+ acceptNode DOMNodeFilter::AcceptNode DontDelete|Function 0
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMNodeFilterProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMNodeFilterProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMNodeFilter",DOMNodeFilterProto,DOMNodeFilterProtoFunc)
+
+DOMNodeFilter::DOMNodeFilter(ExecState *exec, DOM::NodeFilter nf)
+ : DOMObject(DOMNodeFilterProto::self(exec)), nodeFilter(nf) {}
+
+DOMNodeFilter::~DOMNodeFilter()
+{
+ ScriptInterpreter::forgetDOMObject(nodeFilter.handle());
+}
+
+Value DOMNodeFilterProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMNodeFilter, thisObj );
+ DOM::NodeFilter nodeFilter = static_cast<DOMNodeFilter *>(thisObj.imp())->toNodeFilter();
+ switch (id) {
+ case DOMNodeFilter::AcceptNode:
+ return Number(nodeFilter.acceptNode(toNode(args[0])));
+ }
+ return Undefined();
+}
+
+Value getDOMNodeFilter(ExecState *exec, DOM::NodeFilter nf)
+{
+ return cacheDOMObject<DOM::NodeFilter, DOMNodeFilter>(exec, nf);
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMTreeWalker::info = { "TreeWalker", 0, &DOMTreeWalkerTable, 0 };
+/*
+@begin DOMTreeWalkerTable 5
+ root DOMTreeWalker::Root DontDelete|ReadOnly
+ whatToShow DOMTreeWalker::WhatToShow DontDelete|ReadOnly
+ filter DOMTreeWalker::Filter DontDelete|ReadOnly
+ expandEntityReferences DOMTreeWalker::ExpandEntityReferences DontDelete|ReadOnly
+ currentNode DOMTreeWalker::CurrentNode DontDelete
+@end
+@begin DOMTreeWalkerProtoTable 7
+ parentNode DOMTreeWalker::ParentNode DontDelete|Function 0
+ firstChild DOMTreeWalker::FirstChild DontDelete|Function 0
+ lastChild DOMTreeWalker::LastChild DontDelete|Function 0
+ previousSibling DOMTreeWalker::PreviousSibling DontDelete|Function 0
+ nextSibling DOMTreeWalker::NextSibling DontDelete|Function 0
+ previousNode DOMTreeWalker::PreviousNode DontDelete|Function 0
+ nextNode DOMTreeWalker::NextNode DontDelete|Function 0
+@end
+*/
+KJS_DEFINE_PROTOTYPE(DOMTreeWalkerProto)
+IMPLEMENT_PROTOFUNC_DOM(DOMTreeWalkerProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("DOMTreeWalker", DOMTreeWalkerProto,DOMTreeWalkerProtoFunc)
+
+DOMTreeWalker::DOMTreeWalker(ExecState *exec, DOM::TreeWalker tw)
+ : DOMObject(DOMTreeWalkerProto::self(exec)), treeWalker(tw) {}
+
+DOMTreeWalker::~DOMTreeWalker()
+{
+ ScriptInterpreter::forgetDOMObject(treeWalker.handle());
+}
+
+Value DOMTreeWalker::tryGet(ExecState *exec, const Identifier &p) const
+{
+ return DOMObjectLookupGetValue<DOMTreeWalker,DOMObject>(exec,p,&DOMTreeWalkerTable,this);
+}
+
+Value DOMTreeWalker::getValueProperty(ExecState *exec, int token) const
+{
+ DOM::TreeWalker tw(treeWalker);
+ switch (token) {
+ case Root:
+ return getDOMNode(exec,tw.root());
+ case WhatToShow:
+ return Number(tw.whatToShow());
+ case Filter:
+ return getDOMNodeFilter(exec,tw.filter());
+ case ExpandEntityReferences:
+ return Boolean(tw.expandEntityReferences());
+ case CurrentNode:
+ return getDOMNode(exec,tw.currentNode());
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in DOMTreeWalker::getValueProperty : " << token << endl;
+ return Value();
+ }
+}
+
+void DOMTreeWalker::tryPut(ExecState *exec, const Identifier &propertyName,
+ const Value& value, int attr)
+{
+ if (propertyName == "currentNode") {
+ treeWalker.setCurrentNode(toNode(value));
+ }
+ else
+ ObjectImp::put(exec, propertyName, value, attr);
+}
+
+Value DOMTreeWalkerProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &)
+{
+ KJS_CHECK_THIS( KJS::DOMTreeWalker, thisObj );
+ DOM::TreeWalker treeWalker = static_cast<DOMTreeWalker *>(thisObj.imp())->toTreeWalker();
+ switch (id) {
+ case DOMTreeWalker::ParentNode:
+ return getDOMNode(exec,treeWalker.parentNode());
+ case DOMTreeWalker::FirstChild:
+ return getDOMNode(exec,treeWalker.firstChild());
+ case DOMTreeWalker::LastChild:
+ return getDOMNode(exec,treeWalker.lastChild());
+ case DOMTreeWalker::PreviousSibling:
+ return getDOMNode(exec,treeWalker.previousSibling());
+ case DOMTreeWalker::NextSibling:
+ return getDOMNode(exec,treeWalker.nextSibling());
+ case DOMTreeWalker::PreviousNode:
+ return getDOMNode(exec,treeWalker.previousSibling());
+ case DOMTreeWalker::NextNode:
+ return getDOMNode(exec,treeWalker.nextNode());
+ }
+ return Undefined();
+}
+
+Value getDOMTreeWalker(ExecState *exec, DOM::TreeWalker tw)
+{
+ return cacheDOMObject<DOM::TreeWalker, DOMTreeWalker>(exec, tw);
+}
+
+DOM::NodeFilter toNodeFilter(const Value& val)
+{
+ Object obj = Object::dynamicCast(val);
+ if (!obj.isValid() || !obj.inherits(&DOMNodeFilter::info))
+ return DOM::NodeFilter();
+
+ const DOMNodeFilter *dobj = static_cast<const DOMNodeFilter*>(obj.imp());
+ return dobj->toNodeFilter();
+}
+
+// -------------------------------------------------------------------------
+
+JSNodeFilter::JSNodeFilter(Object & _filter) : DOM::CustomNodeFilter(), filter( _filter )
+{
+}
+
+JSNodeFilter::~JSNodeFilter()
+{
+}
+
+short JSNodeFilter::acceptNode(const DOM::Node &n)
+{
+ KHTMLView *view = static_cast<DOM::DocumentImpl *>( n.handle()->docPtr() )->view();
+ if (!view)
+ return DOM::NodeFilter::FILTER_REJECT;
+
+ KHTMLPart *part = view->part();
+ KJSProxy *proxy = part->jScript();
+ if (proxy) {
+ ExecState *exec = proxy->interpreter()->globalExec();
+ Object acceptNodeFunc = Object::dynamicCast( filter.get(exec, "acceptNode") );
+ if (!acceptNodeFunc.isNull() && acceptNodeFunc.implementsCall()) {
+ List args;
+ args.append(getDOMNode(exec,n));
+ Value result = acceptNodeFunc.call(exec,filter,args);
+ if (exec->hadException())
+ exec->clearException();
+ return result.toInteger(exec);
+ }
+ }
+
+ return DOM::NodeFilter::FILTER_REJECT;
+}
+
+} //namespace KJS
diff --git a/khtml/ecma/kjs_traversal.h b/khtml/ecma/kjs_traversal.h
new file mode 100644
index 000000000..fd7e064b1
--- /dev/null
+++ b/khtml/ecma/kjs_traversal.h
@@ -0,0 +1,108 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_TRAVERSAL_H_
+#define _KJS_TRAVERSAL_H_
+
+#include "ecma/kjs_dom.h"
+#include "dom/dom2_traversal.h"
+
+namespace KJS {
+
+ class DOMNodeIterator : public DOMObject {
+ public:
+ DOMNodeIterator(ExecState *exec, DOM::NodeIterator ni);
+ ~DOMNodeIterator();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Filter, Root, WhatToShow, ExpandEntityReferences,
+ NextNode, PreviousNode, Detach };
+ DOM::NodeIterator toNodeIterator() const { return nodeIterator; }
+ protected:
+ DOM::NodeIterator nodeIterator;
+ };
+
+ // Constructor object NodeFilter
+ class NodeFilterConstructor : public DOMObject {
+ public:
+ NodeFilterConstructor(ExecState *);
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ class DOMNodeFilter : public DOMObject {
+ public:
+ DOMNodeFilter(ExecState *exec, DOM::NodeFilter nf);
+ ~DOMNodeFilter();
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ virtual DOM::NodeFilter toNodeFilter() const { return nodeFilter; }
+ enum { AcceptNode };
+ protected:
+ DOM::NodeFilter nodeFilter;
+ };
+
+ class DOMTreeWalker : public DOMObject {
+ public:
+ DOMTreeWalker(ExecState *exec, DOM::TreeWalker tw);
+ ~DOMTreeWalker();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName,
+ const Value& value, int attr = None);
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Root, WhatToShow, Filter, ExpandEntityReferences, CurrentNode,
+ ParentNode, FirstChild, LastChild, PreviousSibling, NextSibling,
+ PreviousNode, NextNode };
+ DOM::TreeWalker toTreeWalker() const { return treeWalker; }
+ protected:
+ DOM::TreeWalker treeWalker;
+ };
+
+ Value getDOMNodeIterator(ExecState *exec, DOM::NodeIterator ni);
+ Value getNodeFilterConstructor(ExecState *exec);
+ Value getDOMNodeFilter(ExecState *exec, DOM::NodeFilter nf);
+ Value getDOMTreeWalker(ExecState *exec, DOM::TreeWalker tw);
+
+ /**
+ * Convert an object to a NodeFilter. Returns a null Node if not possible.
+ */
+ DOM::NodeFilter toNodeFilter(const Value&);
+
+ class JSNodeFilter : public DOM::CustomNodeFilter {
+ public:
+ JSNodeFilter(Object & _filter);
+ virtual ~JSNodeFilter();
+ virtual short acceptNode (const DOM::Node &n);
+ protected:
+ Object filter;
+ };
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_views.cpp b/khtml/ecma/kjs_views.cpp
new file mode 100644
index 000000000..dbf354ce8
--- /dev/null
+++ b/khtml/ecma/kjs_views.cpp
@@ -0,0 +1,91 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "ecma/kjs_views.h"
+#include "ecma/kjs_css.h"
+#include "ecma/kjs_window.h"
+#include "kjs_views.lut.h"
+
+using namespace KJS;
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMAbstractView::info = { "AbstractView", 0, &DOMAbstractViewTable, 0 };
+/*
+@begin DOMAbstractViewTable 2
+ document DOMAbstractView::Document DontDelete|ReadOnly
+ getComputedStyle DOMAbstractView::GetComputedStyle DontDelete|Function 2
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(DOMAbstractViewFunc)
+
+DOMAbstractView::DOMAbstractView(ExecState *exec, DOM::AbstractView av)
+ : DOMObject(exec->interpreter()->builtinObjectPrototype()), abstractView(av) {}
+
+DOMAbstractView::~DOMAbstractView()
+{
+ ScriptInterpreter::forgetDOMObject(abstractView.handle());
+}
+
+Value DOMAbstractView::tryGet(ExecState *exec, const Identifier &p) const
+{
+ if ( p == "document" )
+ return getDOMNode(exec,abstractView.document());
+ else if ( p == "getComputedStyle" )
+ return lookupOrCreateFunction<DOMAbstractViewFunc>(exec,p,this,DOMAbstractView::GetComputedStyle,2,DontDelete|Function);
+ else
+ return DOMObject::tryGet(exec,p);
+}
+
+Value DOMAbstractViewFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( KJS::DOMAbstractView, thisObj );
+ DOM::AbstractView abstractView = static_cast<DOMAbstractView *>(thisObj.imp())->toAbstractView();
+ switch (id) {
+ case DOMAbstractView::GetComputedStyle: {
+ DOM::Node arg0 = toNode(args[0]);
+ if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
+ return Undefined(); // throw exception?
+ else
+ return getDOMCSSStyleDeclaration(exec,abstractView.getComputedStyle(static_cast<DOM::Element>(arg0),
+ args[1].toString(exec).string()));
+ }
+ }
+ return Undefined();
+}
+
+Value KJS::getDOMAbstractView(ExecState *exec, DOM::AbstractView av)
+{
+ return cacheDOMObject<DOM::AbstractView, DOMAbstractView>(exec, av);
+}
+
+DOM::AbstractView KJS::toAbstractView (const Value& val)
+{
+ Object obj = Object::dynamicCast(val);
+ if (!obj.isValid() || !obj.inherits(&DOMAbstractView::info))
+ return DOM::AbstractView ();
+
+ // the Window object is considered for all practical purposes as a descendant of AbstractView
+ if (obj.inherits(&Window::info))
+ return static_cast<const Window *>(obj.imp())->toAbstractView();
+
+ const DOMAbstractView *dobj = static_cast<const DOMAbstractView *>(obj.imp());
+ return dobj->toAbstractView ();
+}
diff --git a/khtml/ecma/kjs_views.h b/khtml/ecma/kjs_views.h
new file mode 100644
index 000000000..11e103fde
--- /dev/null
+++ b/khtml/ecma/kjs_views.h
@@ -0,0 +1,53 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_VIEWS_H_
+#define _KJS_VIEWS_H_
+
+#include "ecma/kjs_dom.h"
+#include "dom/dom2_views.h"
+
+namespace KJS {
+
+
+ class DOMAbstractView : public DOMObject {
+ public:
+ DOMAbstractView(ExecState *, DOM::AbstractView av);
+ ~DOMAbstractView();
+ virtual Value tryGet(ExecState *exec,const Identifier &p) const;
+ // no put - all read-only
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ virtual DOM::AbstractView toAbstractView() const { return abstractView; }
+ enum { Document, GetComputedStyle };
+ protected:
+ DOM::AbstractView abstractView;
+ };
+
+ Value getDOMAbstractView(ExecState *exec, DOM::AbstractView av);
+
+ /**
+ * Convert an object to an AbstractView. Returns a null Node if not possible.
+ */
+ DOM::AbstractView toAbstractView(const Value&);
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/kjs_window.cpp b/khtml/ecma/kjs_window.cpp
new file mode 100644
index 000000000..bc5a85e19
--- /dev/null
+++ b/khtml/ecma/kjs_window.cpp
@@ -0,0 +1,2935 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000-2003 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001-2003 David Faure (faure@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "config.h"
+
+#include "khtmlview.h"
+#include "khtml_part.h"
+#include "khtmlpart_p.h"
+#include "khtml_settings.h"
+#include "xml/dom2_eventsimpl.h"
+#include "xml/dom_docimpl.h"
+#include "misc/htmltags.h"
+#include "html/html_documentimpl.h"
+#include "rendering/render_frames.h"
+
+#include <qstylesheet.h>
+#include <qtimer.h>
+#include <qpaintdevicemetrics.h>
+#include <qapplication.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmdcodec.h>
+#include <kparts/browserinterface.h>
+#include <kwin.h>
+
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+#include <kwinmodule.h> // schroder
+#endif
+
+#ifndef KONQ_EMBEDDED
+#include <kbookmarkmanager.h>
+#endif
+#include <kglobalsettings.h>
+#include <assert.h>
+#include <qstyle.h>
+#include <qobjectlist.h>
+#include <kstringhandler.h>
+
+#include "kjs_proxy.h"
+#include "kjs_window.h"
+#include "kjs_navigator.h"
+#include "kjs_mozilla.h"
+#include "kjs_html.h"
+#include "kjs_range.h"
+#include "kjs_traversal.h"
+#include "kjs_css.h"
+#include "kjs_events.h"
+#include "kjs_views.h"
+#include "xmlhttprequest.h"
+#include "xmlserializer.h"
+#include "domparser.h"
+
+using namespace KJS;
+
+namespace KJS {
+
+ class History : public ObjectImp {
+ friend class HistoryFunc;
+ public:
+ History(ExecState *exec, KHTMLPart *p)
+ : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Back, Forward, Go, Length };
+ private:
+ QGuardedPtr<KHTMLPart> part;
+ };
+
+ class External : public ObjectImp {
+ friend class ExternalFunc;
+ public:
+ External(ExecState *exec, KHTMLPart *p)
+ : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { AddFavorite };
+ private:
+ QGuardedPtr<KHTMLPart> part;
+ };
+
+ class FrameArray : public ObjectImp {
+ public:
+ FrameArray(ExecState *exec, KHTMLPart *p)
+ : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+ virtual bool implementsCall() const { return true; }
+ private:
+ QGuardedPtr<KHTMLPart> part;
+ };
+
+#ifdef Q_WS_QWS
+ class KonquerorFunc : public DOMFunction {
+ public:
+ KonquerorFunc(ExecState *exec, const Konqueror* k, const char* name)
+ : DOMFunction(exec), konqueror(k), m_name(name) { }
+ virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args);
+
+ private:
+ const Konqueror* konqueror;
+ QCString m_name;
+ };
+#endif
+} // namespace KJS
+
+#include "kjs_window.lut.h"
+#include "rendering/render_replaced.h"
+
+////////////////////// Screen Object ////////////////////////
+namespace KJS {
+// table for screen object
+/*
+@begin ScreenTable 7
+ height Screen::Height DontEnum|ReadOnly
+ width Screen::Width DontEnum|ReadOnly
+ colorDepth Screen::ColorDepth DontEnum|ReadOnly
+ pixelDepth Screen::PixelDepth DontEnum|ReadOnly
+ availLeft Screen::AvailLeft DontEnum|ReadOnly
+ availTop Screen::AvailTop DontEnum|ReadOnly
+ availHeight Screen::AvailHeight DontEnum|ReadOnly
+ availWidth Screen::AvailWidth DontEnum|ReadOnly
+@end
+*/
+
+const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
+
+// We set the object prototype so that toString is implemented
+Screen::Screen(ExecState *exec)
+ : ObjectImp(exec->interpreter()->builtinObjectPrototype()) {}
+
+Value Screen::get(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Screen::get " << p.qstring() << endl;
+#endif
+ return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
+}
+
+Value Screen::getValueProperty(ExecState *exec, int token) const
+{
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ KWinModule info(0, KWinModule::INFO_DESKTOP);
+#endif
+ QWidget *thisWidget = Window::retrieveActive(exec)->part()->widget();
+ QRect sg = KGlobalSettings::desktopGeometry(thisWidget);
+
+ switch( token ) {
+ case Height:
+ return Number(sg.height());
+ case Width:
+ return Number(sg.width());
+ case ColorDepth:
+ case PixelDepth: {
+ QPaintDeviceMetrics m(QApplication::desktop());
+ return Number(m.depth());
+ }
+ case AvailLeft: {
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ QRect clipped = info.workArea().intersect(sg);
+ return Number(clipped.x()-sg.x());
+#else
+ return Number(10);
+#endif
+ }
+ case AvailTop: {
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ QRect clipped = info.workArea().intersect(sg);
+ return Number(clipped.y()-sg.y());
+#else
+ return Number(10);
+#endif
+ }
+ case AvailHeight: {
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ QRect clipped = info.workArea().intersect(sg);
+ return Number(clipped.height());
+#else
+ return Number(100);
+#endif
+ }
+ case AvailWidth: {
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ QRect clipped = info.workArea().intersect(sg);
+ return Number(clipped.width());
+#else
+ return Number(100);
+#endif
+ }
+ default:
+ kdDebug(6070) << "WARNING: Screen::getValueProperty unhandled token " << token << endl;
+ return Undefined();
+ }
+}
+
+////////////////////// Window Object ////////////////////////
+
+const ClassInfo Window::info = { "Window", &DOMAbstractView::info, &WindowTable, 0 };
+
+/*
+@begin WindowTable 162
+ atob Window::AToB DontDelete|Function 1
+ btoa Window::BToA DontDelete|Function 1
+ closed Window::Closed DontDelete|ReadOnly
+ crypto Window::Crypto DontDelete|ReadOnly
+ defaultStatus Window::DefaultStatus DontDelete
+ defaultstatus Window::DefaultStatus DontDelete
+ status Window::Status DontDelete
+ document Window::Document DontDelete|ReadOnly
+ frameElement Window::FrameElement DontDelete|ReadOnly
+ frames Window::Frames DontDelete|ReadOnly
+ history Window::_History DontDelete|ReadOnly
+ external Window::_External DontDelete|ReadOnly
+ event Window::Event DontDelete|ReadOnly
+ innerHeight Window::InnerHeight DontDelete|ReadOnly
+ innerWidth Window::InnerWidth DontDelete|ReadOnly
+ length Window::Length DontDelete|ReadOnly
+ location Window::_Location DontDelete
+ name Window::Name DontDelete
+ navigator Window::_Navigator DontDelete|ReadOnly
+ clientInformation Window::ClientInformation DontDelete|ReadOnly
+ konqueror Window::_Konqueror DontDelete|ReadOnly
+ offscreenBuffering Window::OffscreenBuffering DontDelete|ReadOnly
+ opener Window::Opener DontDelete|ReadOnly
+ outerHeight Window::OuterHeight DontDelete|ReadOnly
+ outerWidth Window::OuterWidth DontDelete|ReadOnly
+ pageXOffset Window::PageXOffset DontDelete|ReadOnly
+ pageYOffset Window::PageYOffset DontDelete|ReadOnly
+ parent Window::Parent DontDelete|ReadOnly
+ personalbar Window::Personalbar DontDelete|ReadOnly
+ screenX Window::ScreenX DontDelete|ReadOnly
+ screenY Window::ScreenY DontDelete|ReadOnly
+ scrollbars Window::Scrollbars DontDelete|ReadOnly
+ scroll Window::Scroll DontDelete|Function 2
+ scrollBy Window::ScrollBy DontDelete|Function 2
+ scrollTo Window::ScrollTo DontDelete|Function 2
+ scrollX Window::ScrollX DontDelete|ReadOnly
+ scrollY Window::ScrollY DontDelete|ReadOnly
+ moveBy Window::MoveBy DontDelete|Function 2
+ moveTo Window::MoveTo DontDelete|Function 2
+ resizeBy Window::ResizeBy DontDelete|Function 2
+ resizeTo Window::ResizeTo DontDelete|Function 2
+ self Window::Self DontDelete|ReadOnly
+ window Window::_Window DontDelete|ReadOnly
+ top Window::Top DontDelete|ReadOnly
+ screen Window::_Screen DontDelete|ReadOnly
+ alert Window::Alert DontDelete|Function 1
+ confirm Window::Confirm DontDelete|Function 1
+ prompt Window::Prompt DontDelete|Function 2
+ open Window::Open DontDelete|Function 3
+ setTimeout Window::SetTimeout DontDelete|Function 2
+ clearTimeout Window::ClearTimeout DontDelete|Function 1
+ focus Window::Focus DontDelete|Function 0
+ blur Window::Blur DontDelete|Function 0
+ close Window::Close DontDelete|Function 0
+ setInterval Window::SetInterval DontDelete|Function 2
+ clearInterval Window::ClearInterval DontDelete|Function 1
+ captureEvents Window::CaptureEvents DontDelete|Function 0
+ releaseEvents Window::ReleaseEvents DontDelete|Function 0
+ print Window::Print DontDelete|Function 0
+ addEventListener Window::AddEventListener DontDelete|Function 3
+ removeEventListener Window::RemoveEventListener DontDelete|Function 3
+# Normally found in prototype. Add to window object itself to make them
+# accessible in closed and cross-site windows
+ valueOf Window::ValueOf DontDelete|Function 0
+ toString Window::ToString DontDelete|Function 0
+# IE extension
+ navigate Window::Navigate DontDelete|Function 1
+# Mozilla extension
+ sidebar Window::SideBar DontDelete|ReadOnly
+ getComputedStyle Window::GetComputedStyle DontDelete|Function 2
+
+# Warning, when adding a function to this object you need to add a case in Window::get
+
+# Event handlers
+# IE also has: onactivate, onbefore/afterprint, onbeforedeactivate/unload, oncontrolselect,
+# ondeactivate, onhelp, onmovestart/end, onresizestart/end, onscroll.
+# It doesn't have onabort, onchange, ondragdrop (but NS has that last one).
+ onabort Window::Onabort DontDelete
+ onblur Window::Onblur DontDelete
+ onchange Window::Onchange DontDelete
+ onclick Window::Onclick DontDelete
+ ondblclick Window::Ondblclick DontDelete
+ ondragdrop Window::Ondragdrop DontDelete
+ onerror Window::Onerror DontDelete
+ onfocus Window::Onfocus DontDelete
+ onkeydown Window::Onkeydown DontDelete
+ onkeypress Window::Onkeypress DontDelete
+ onkeyup Window::Onkeyup DontDelete
+ onload Window::Onload DontDelete
+ onmousedown Window::Onmousedown DontDelete
+ onmousemove Window::Onmousemove DontDelete
+ onmouseout Window::Onmouseout DontDelete
+ onmouseover Window::Onmouseover DontDelete
+ onmouseup Window::Onmouseup DontDelete
+ onmove Window::Onmove DontDelete
+ onreset Window::Onreset DontDelete
+ onresize Window::Onresize DontDelete
+ onselect Window::Onselect DontDelete
+ onsubmit Window::Onsubmit DontDelete
+ onunload Window::Onunload DontDelete
+
+# Constructors/constant tables
+ Node Window::Node DontDelete
+ Event Window::EventCtor DontDelete
+ Range Window::Range DontDelete
+ NodeFilter Window::NodeFilter DontDelete
+ DOMException Window::DOMException DontDelete
+ CSSRule Window::CSSRule DontDelete
+ MutationEvent Window::MutationEventCtor DontDelete
+ KeyboardEvent Window::KeyboardEventCtor DontDelete
+ EventException Window::EventExceptionCtor DontDelete
+ Image Window::Image DontDelete|ReadOnly
+ Option Window::Option DontDelete|ReadOnly
+ XMLHttpRequest Window::XMLHttpRequest DontDelete|ReadOnly
+ XMLSerializer Window::XMLSerializer DontDelete|ReadOnly
+ DOMParser Window::DOMParser DontDelete|ReadOnly
+
+# Mozilla dom emulation ones.
+ Element Window::ElementCtor DontDelete
+ Document Window::DocumentCtor DontDelete
+ #this one is an alias since we don't have a separate XMLDocument
+ XMLDocument Window::DocumentCtor DontDelete
+ HTMLElement Window::HTMLElementCtor DontDelete
+ HTMLDocument Window::HTMLDocumentCtor DontDelete
+ HTMLHtmlElement Window::HTMLHtmlElementCtor DontDelete
+ HTMLHeadElement Window::HTMLHeadElementCtor DontDelete
+ HTMLLinkElement Window::HTMLLinkElementCtor DontDelete
+ HTMLTitleElement Window::HTMLTitleElementCtor DontDelete
+ HTMLMetaElement Window::HTMLMetaElementCtor DontDelete
+ HTMLBaseElement Window::HTMLBaseElementCtor DontDelete
+ HTMLIsIndexElement Window::HTMLIsIndexElementCtor DontDelete
+ HTMLStyleElement Window::HTMLStyleElementCtor DontDelete
+ HTMLBodyElement Window::HTMLBodyElementCtor DontDelete
+ HTMLFormElement Window::HTMLFormElementCtor DontDelete
+ HTMLSelectElement Window::HTMLSelectElementCtor DontDelete
+ HTMLOptGroupElement Window::HTMLOptGroupElementCtor DontDelete
+ HTMLOptionElement Window::HTMLOptionElementCtor DontDelete
+ HTMLInputElement Window::HTMLInputElementCtor DontDelete
+ HTMLTextAreaElement Window::HTMLTextAreaElementCtor DontDelete
+ HTMLButtonElement Window::HTMLButtonElementCtor DontDelete
+ HTMLLabelElement Window::HTMLLabelElementCtor DontDelete
+ HTMLFieldSetElement Window::HTMLFieldSetElementCtor DontDelete
+ HTMLLegendElement Window::HTMLLegendElementCtor DontDelete
+ HTMLUListElement Window::HTMLUListElementCtor DontDelete
+ HTMLOListElement Window::HTMLOListElementCtor DontDelete
+ HTMLDListElement Window::HTMLDListElementCtor DontDelete
+ HTMLDirectoryElement Window::HTMLDirectoryElementCtor DontDelete
+ HTMLMenuElement Window::HTMLMenuElementCtor DontDelete
+ HTMLLIElement Window::HTMLLIElementCtor DontDelete
+ HTMLDivElement Window::HTMLDivElementCtor DontDelete
+ HTMLParagraphElement Window::HTMLParagraphElementCtor DontDelete
+ HTMLHeadingElement Window::HTMLHeadingElementCtor DontDelete
+ HTMLBlockQuoteElement Window::HTMLBlockQuoteElementCtor DontDelete
+ HTMLQuoteElement Window::HTMLQuoteElementCtor DontDelete
+ HTMLPreElement Window::HTMLPreElementCtor DontDelete
+ HTMLBRElement Window::HTMLBRElementCtor DontDelete
+ HTMLBaseFontElement Window::HTMLBaseFontElementCtor DontDelete
+ HTMLFontElement Window::HTMLFontElementCtor DontDelete
+ HTMLHRElement Window::HTMLHRElementCtor DontDelete
+ HTMLModElement Window::HTMLModElementCtor DontDelete
+ HTMLAnchorElement Window::HTMLAnchorElementCtor DontDelete
+ HTMLImageElement Window::HTMLImageElementCtor DontDelete
+ HTMLObjectElement Window::HTMLObjectElementCtor DontDelete
+ HTMLParamElement Window::HTMLParamElementCtor DontDelete
+ HTMLAppletElement Window::HTMLAppletElementCtor DontDelete
+ HTMLMapElement Window::HTMLMapElementCtor DontDelete
+ HTMLAreaElement Window::HTMLAreaElementCtor DontDelete
+ HTMLScriptElement Window::HTMLScriptElementCtor DontDelete
+ HTMLTableElement Window::HTMLTableElementCtor DontDelete
+ HTMLTableCaptionElement Window::HTMLTableCaptionElementCtor DontDelete
+ HTMLTableColElement Window::HTMLTableColElementCtor DontDelete
+ HTMLTableSectionElement Window::HTMLTableSectionElementCtor DontDelete
+ HTMLTableRowElement Window::HTMLTableRowElementCtor DontDelete
+ HTMLTableCellElement Window::HTMLTableCellElementCtor DontDelete
+ HTMLFrameSetElement Window::HTMLFrameSetElementCtor DontDelete
+ HTMLLayerElement Window::HTMLLayerElementCtor DontDelete
+ HTMLFrameElement Window::HTMLFrameElementCtor DontDelete
+ HTMLIFrameElement Window::HTMLIFrameElementCtor DontDelete
+ CSSStyleDeclaration Window::CSSStyleDeclarationCtor DontDelete
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(WindowFunc)
+
+Window::Window(khtml::ChildFrame *p)
+ : ObjectImp(/*no proto*/), m_frame(p), screen(0), history(0), external(0), m_frames(0), loc(0), m_evt(0)
+{
+ winq = new WindowQObject(this);
+ //kdDebug(6070) << "Window::Window this=" << this << " part=" << m_part << " " << m_part->name() << endl;
+}
+
+Window::~Window()
+{
+ delete winq;
+}
+
+Window *Window::retrieveWindow(KParts::ReadOnlyPart *p)
+{
+ Object obj = Object::dynamicCast( retrieve( p ) );
+#ifndef NDEBUG
+ // obj should never be null, except when javascript has been disabled in that part.
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(p);
+ if ( part && part->jScriptEnabled() )
+ {
+ assert( obj.isValid() );
+#ifndef QWS
+ assert( dynamic_cast<KJS::Window*>(obj.imp()) ); // type checking
+#endif
+ }
+#endif
+ if ( !obj.isValid() ) // JS disabled
+ return 0;
+ return static_cast<KJS::Window*>(obj.imp());
+}
+
+Window *Window::retrieveActive(ExecState *exec)
+{
+ ValueImp *imp = exec->interpreter()->globalObject().imp();
+ assert( imp );
+#ifndef QWS
+ assert( dynamic_cast<KJS::Window*>(imp) );
+#endif
+ return static_cast<KJS::Window*>(imp);
+}
+
+Value Window::retrieve(KParts::ReadOnlyPart *p)
+{
+ assert(p);
+ KHTMLPart * part = ::qt_cast<KHTMLPart *>(p);
+ KJSProxy *proxy = 0L;
+ if (!part) {
+ part = ::qt_cast<KHTMLPart *>(p->parent());
+ if (part)
+ proxy = part->framejScript(p);
+ } else
+ proxy = part->jScript();
+ if (proxy) {
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Window::retrieve part=" << part << " '" << part->name() << "' interpreter=" << proxy->interpreter() << " window=" << proxy->interpreter()->globalObject().imp() << endl;
+#endif
+ return proxy->interpreter()->globalObject(); // the Global object is the "window"
+ } else {
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Window::retrieve part=" << p << " '" << p->name() << "' no jsproxy." << endl;
+#endif
+ return Undefined(); // This can happen with JS disabled on the domain of that window
+ }
+}
+
+Location *Window::location() const
+{
+ if (!loc)
+ const_cast<Window*>(this)->loc = new Location(m_frame);
+ return loc;
+}
+
+ObjectImp* Window::frames( ExecState* exec ) const
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (part)
+ return m_frames ? m_frames :
+ (const_cast<Window*>(this)->m_frames = new FrameArray(exec, part));
+ return 0L;
+}
+
+// reference our special objects during garbage collection
+void Window::mark()
+{
+ ObjectImp::mark();
+ if (screen && !screen->marked())
+ screen->mark();
+ if (history && !history->marked())
+ history->mark();
+ if (external && !external->marked())
+ external->mark();
+ if (m_frames && !m_frames->marked())
+ m_frames->mark();
+ //kdDebug(6070) << "Window::mark " << this << " marking loc=" << loc << endl;
+ if (loc && !loc->marked())
+ loc->mark();
+ if (winq)
+ winq->mark();
+}
+
+bool Window::hasProperty(ExecState *exec, const Identifier &p) const
+{
+ // we don't want any operations on a closed window
+ if (m_frame.isNull() || m_frame->m_part.isNull())
+ return ( p == "closed" );
+
+ if (ObjectImp::hasProperty(exec, p))
+ return true;
+
+ if (Lookup::findEntry(&WindowTable, p))
+ return true;
+
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part)
+ return false;
+
+ QString q = p.qstring();
+ if (part->findFramePart(p.qstring()))
+ return true;
+ // allow window[1] or parent[1] etc. (#56983)
+ bool ok;
+ unsigned int i = p.toArrayIndex(&ok);
+ if (ok) {
+ QPtrList<KParts::ReadOnlyPart> frames = part->frames();
+ unsigned int len = frames.count();
+ if (i < len)
+ return true;
+ }
+
+ // allow shortcuts like 'Image1' instead of document.images.Image1
+ if (part->document().isHTMLDocument()) { // might be XML
+ DOM::HTMLDocument doc = part->htmlDocument();
+ // Keep in sync with tryGet
+
+ if (static_cast<DOM::DocumentImpl*>(doc.handle())->underDocNamedCache().get(p.qstring()))
+ return true;
+
+ return !doc.getElementById(p.string()).isNull();
+ }
+
+ return false;
+}
+
+UString Window::toString(ExecState *) const
+{
+ return "[object Window]";
+}
+
+Value Window::get(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
+#endif
+ // we want only limited operations on a closed window
+ if (m_frame.isNull() || m_frame->m_part.isNull()) {
+ const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
+ if (entry) {
+ switch (entry->value) {
+ case Closed:
+ return Boolean(true);
+ case _Location:
+ return Null();
+ case ValueOf:
+ case ToString:
+ return lookupOrCreateFunction<WindowFunc>(exec,p, this, entry->value,
+ entry->params, entry->attr);
+ default:
+ break;
+ }
+ }
+ return Undefined();
+ }
+
+ // Look for overrides first
+ ValueImp *val = getDirect(p);
+ if (val) {
+ //kdDebug(6070) << "Window::get found dynamic property '" << p.ascii() << "'" << endl;
+ return isSafeScript(exec) ? Value(val) : Undefined();
+ }
+
+ const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+
+ // properties that work on all windows
+ if (entry) {
+ // ReadOnlyPart first
+ switch(entry->value) {
+ case Closed:
+ return Boolean( false );
+ case _Location:
+ // No isSafeScript test here, we must be able to _set_ location.href (#49819)
+ return Value(location());
+ case _Window:
+ case Self:
+ return retrieve(m_frame->m_part);
+ default:
+ break;
+ }
+ if (!part)
+ return Undefined();
+ // KHTMLPart next
+ switch(entry->value) {
+ case Frames:
+ return Value(frames(exec));
+ case Opener:
+ if (!part->opener())
+ return Null(); // ### a null Window might be better, but == null
+ else // doesn't work yet
+ return retrieve(part->opener());
+ case Parent:
+ return retrieve(part->parentPart() ? part->parentPart() : (KHTMLPart*)part);
+ case Top: {
+ KHTMLPart *p = part;
+ while (p->parentPart())
+ p = p->parentPart();
+ return retrieve(p);
+ }
+ case Alert:
+ case Confirm:
+ case Prompt:
+ case Open:
+ case Close:
+ case Focus:
+ case Blur:
+ case AToB:
+ case BToA:
+ case GetComputedStyle:
+ case ValueOf:
+ case ToString:
+ return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+ default:
+ break;
+ }
+ } else if (!part) {
+ // not a KHTMLPart
+ QString rvalue;
+ KParts::LiveConnectExtension::Type rtype;
+ unsigned long robjid;
+ if (m_frame->m_liveconnect &&
+ isSafeScript(exec) &&
+ m_frame->m_liveconnect->get(0, p.qstring(), rtype, robjid, rvalue))
+ return getLiveConnectValue(m_frame->m_liveconnect, p.qstring(), rtype, rvalue, robjid);
+ return Undefined();
+ }
+ // properties that only work on safe windows
+ if (isSafeScript(exec) && entry)
+ {
+ //kdDebug(6070) << "token: " << entry->value << endl;
+ switch( entry->value ) {
+ case Crypto:
+ return Undefined(); // ###
+ case DefaultStatus:
+ return String(UString(part->jsDefaultStatusBarText()));
+ case Status:
+ return String(UString(part->jsStatusBarText()));
+ case Document:
+ if (part->document().isNull()) {
+ kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
+ part->begin();
+ part->write("<HTML><BODY>");
+ part->end();
+ }
+ return getDOMNode(exec,part->document());
+ case FrameElement:
+ if (m_frame->m_frame)
+ return getDOMNode(exec,m_frame->m_frame->element());
+ else
+ return Undefined();
+ case Node:
+ return NodeConstructor::self(exec);
+ case Range:
+ return getRangeConstructor(exec);
+ case NodeFilter:
+ return getNodeFilterConstructor(exec);
+ case DOMException:
+ return getDOMExceptionConstructor(exec);
+ case CSSRule:
+ return getCSSRuleConstructor(exec);
+ case ElementCtor:
+ return ElementPseudoCtor::self(exec);
+ case HTMLElementCtor:
+ return HTMLElementPseudoCtor::self(exec);
+ case HTMLHtmlElementCtor:
+ return HTMLHtmlElementPseudoCtor::self(exec);
+ case HTMLHeadElementCtor:
+ return HTMLHeadElementPseudoCtor::self(exec);
+ case HTMLLinkElementCtor:
+ return HTMLLinkElementPseudoCtor::self(exec);
+ case HTMLTitleElementCtor:
+ return HTMLTitleElementPseudoCtor::self(exec);
+ case HTMLMetaElementCtor:
+ return HTMLMetaElementPseudoCtor::self(exec);
+ case HTMLBaseElementCtor:
+ return HTMLBaseElementPseudoCtor::self(exec);
+ case HTMLIsIndexElementCtor:
+ return HTMLIsIndexElementPseudoCtor::self(exec);
+ case HTMLStyleElementCtor:
+ return HTMLStyleElementPseudoCtor::self(exec);
+ case HTMLBodyElementCtor:
+ return HTMLBodyElementPseudoCtor::self(exec);
+ case HTMLFormElementCtor:
+ return HTMLFormElementPseudoCtor::self(exec);
+ case HTMLSelectElementCtor:
+ return HTMLSelectElementPseudoCtor::self(exec);
+ case HTMLOptGroupElementCtor:
+ return HTMLOptGroupElementPseudoCtor::self(exec);
+ case HTMLOptionElementCtor:
+ return HTMLOptionElementPseudoCtor::self(exec);
+ case HTMLInputElementCtor:
+ return HTMLInputElementPseudoCtor::self(exec);
+ case HTMLTextAreaElementCtor:
+ return HTMLTextAreaElementPseudoCtor::self(exec);
+ case HTMLButtonElementCtor:
+ return HTMLButtonElementPseudoCtor::self(exec);
+ case HTMLLabelElementCtor:
+ return HTMLLabelElementPseudoCtor::self(exec);
+ case HTMLFieldSetElementCtor:
+ return HTMLFieldSetElementPseudoCtor::self(exec);
+ case HTMLLegendElementCtor:
+ return HTMLLegendElementPseudoCtor::self(exec);
+ case HTMLUListElementCtor:
+ return HTMLUListElementPseudoCtor::self(exec);
+ case HTMLOListElementCtor:
+ return HTMLOListElementPseudoCtor::self(exec);
+ case HTMLDListElementCtor:
+ return HTMLDListElementPseudoCtor::self(exec);
+ case HTMLDirectoryElementCtor:
+ return HTMLDirectoryElementPseudoCtor::self(exec);
+ case HTMLMenuElementCtor:
+ return HTMLMenuElementPseudoCtor::self(exec);
+ case HTMLLIElementCtor:
+ return HTMLLIElementPseudoCtor::self(exec);
+ case HTMLDivElementCtor:
+ return HTMLDivElementPseudoCtor::self(exec);
+ case HTMLParagraphElementCtor:
+ return HTMLParagraphElementPseudoCtor::self(exec);
+ case HTMLHeadingElementCtor:
+ return HTMLHeadingElementPseudoCtor::self(exec);
+ case HTMLBlockQuoteElementCtor:
+ return HTMLBlockQuoteElementPseudoCtor::self(exec);
+ case HTMLQuoteElementCtor:
+ return HTMLQuoteElementPseudoCtor::self(exec);
+ case HTMLPreElementCtor:
+ return HTMLPreElementPseudoCtor::self(exec);
+ case HTMLBRElementCtor:
+ return HTMLBRElementPseudoCtor::self(exec);
+ case HTMLBaseFontElementCtor:
+ return HTMLBaseFontElementPseudoCtor::self(exec);
+ case HTMLFontElementCtor:
+ return HTMLFontElementPseudoCtor::self(exec);
+ case HTMLHRElementCtor:
+ return HTMLHRElementPseudoCtor::self(exec);
+ case HTMLModElementCtor:
+ return HTMLModElementPseudoCtor::self(exec);
+ case HTMLAnchorElementCtor:
+ return HTMLAnchorElementPseudoCtor::self(exec);
+ case HTMLImageElementCtor:
+ return HTMLImageElementPseudoCtor::self(exec);
+ case HTMLObjectElementCtor:
+ return HTMLObjectElementPseudoCtor::self(exec);
+ case HTMLParamElementCtor:
+ return HTMLParamElementPseudoCtor::self(exec);
+ case HTMLAppletElementCtor:
+ return HTMLAppletElementPseudoCtor::self(exec);
+ case HTMLMapElementCtor:
+ return HTMLMapElementPseudoCtor::self(exec);
+ case HTMLAreaElementCtor:
+ return HTMLAreaElementPseudoCtor::self(exec);
+ case HTMLScriptElementCtor:
+ return HTMLScriptElementPseudoCtor::self(exec);
+ case HTMLTableElementCtor:
+ return HTMLTableElementPseudoCtor::self(exec);
+ case HTMLTableCaptionElementCtor:
+ return HTMLTableCaptionElementPseudoCtor::self(exec);
+ case HTMLTableColElementCtor:
+ return HTMLTableColElementPseudoCtor::self(exec);
+ case HTMLTableSectionElementCtor:
+ return HTMLTableSectionElementPseudoCtor::self(exec);
+ case HTMLTableRowElementCtor:
+ return HTMLTableRowElementPseudoCtor::self(exec);
+ case HTMLTableCellElementCtor:
+ return HTMLTableCellElementPseudoCtor::self(exec);
+ case HTMLFrameSetElementCtor:
+ return HTMLFrameSetElementPseudoCtor::self(exec);
+ case HTMLLayerElementCtor:
+ return HTMLLayerElementPseudoCtor::self(exec);
+ case HTMLFrameElementCtor:
+ return HTMLFrameElementPseudoCtor::self(exec);
+ case HTMLIFrameElementCtor:
+ return HTMLIFrameElementPseudoCtor::self(exec);
+ case DocumentCtor:
+ return DocumentPseudoCtor::self(exec);
+ case HTMLDocumentCtor:
+ return HTMLDocumentPseudoCtor::self(exec);
+ case CSSStyleDeclarationCtor:
+ return CSSStyleDeclarationPseudoCtor::self(exec);
+ case EventCtor:
+ return EventConstructor::self(exec);
+ case MutationEventCtor:
+ return getMutationEventConstructor(exec);
+ case KeyboardEventCtor:
+ return getKeyboardEventConstructor(exec);
+ case EventExceptionCtor:
+ return getEventExceptionConstructor(exec);
+ case _History:
+ return Value(history ? history :
+ (const_cast<Window*>(this)->history = new History(exec,part)));
+
+ case _External:
+ return Value(external ? external :
+ (const_cast<Window*>(this)->external = new External(exec,part)));
+
+ case Event:
+ if (m_evt)
+ return getDOMEvent(exec,*m_evt);
+ else {
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "WARNING: window(" << this << "," << part->name() << ").event, no event!" << endl;
+#endif
+ return Undefined();
+ }
+ case InnerHeight:
+ if (!part->view())
+ return Undefined();
+ khtml::RenderWidget::flushWidgetResizes(); // make sure frames have their final size
+ return Number(part->view()->visibleHeight());
+ case InnerWidth:
+ if (!part->view())
+ return Undefined();
+ khtml::RenderWidget::flushWidgetResizes(); // make sure frames have their final size
+ return Number(part->view()->visibleWidth());
+ case Length:
+ return Number(part->frames().count());
+ case Name:
+ return String(part->name());
+ case SideBar:
+ return Value(new MozillaSidebarExtension(exec, part));
+ case _Navigator:
+ case ClientInformation: {
+ // Store the navigator in the object so we get the same one each time.
+ Value nav( new Navigator(exec, part) );
+ const_cast<Window *>(this)->put(exec, "navigator", nav, DontDelete|ReadOnly|Internal);
+ const_cast<Window *>(this)->put(exec, "clientInformation", nav, DontDelete|ReadOnly|Internal);
+ return nav;
+ }
+#ifdef Q_WS_QWS
+ case _Konqueror: {
+ Value k( new Konqueror(part) );
+ const_cast<Window *>(this)->put(exec, "konqueror", k, DontDelete|ReadOnly|Internal);
+ return k;
+ }
+#endif
+ case OffscreenBuffering:
+ return Boolean(true);
+ case OuterHeight:
+ case OuterWidth:
+ {
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ if (!part->widget())
+ return Number(0);
+ KWin::WindowInfo inf = KWin::windowInfo(part->widget()->topLevelWidget()->winId());
+ return Number(entry->value == OuterHeight ?
+ inf.geometry().height() : inf.geometry().width());
+#else
+ return Number(entry->value == OuterHeight ?
+ part->view()->height() : part->view()->width());
+#endif
+ }
+ case PageXOffset:
+ return Number(part->view()->contentsX());
+ case PageYOffset:
+ return Number(part->view()->contentsY());
+ case Personalbar:
+ return Undefined(); // ###
+ case ScreenLeft:
+ case ScreenX: {
+ if (!part->view())
+ return Undefined();
+ QRect sg = KGlobalSettings::desktopGeometry(part->view());
+ return Number(part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
+ }
+ case ScreenTop:
+ case ScreenY: {
+ if (!part->view())
+ return Undefined();
+ QRect sg = KGlobalSettings::desktopGeometry(part->view());
+ return Number(part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
+ }
+ case ScrollX: {
+ if (!part->view())
+ return Undefined();
+ return Number(part->view()->contentsX());
+ }
+ case ScrollY: {
+ if (!part->view())
+ return Undefined();
+ return Number(part->view()->contentsY());
+ }
+ case Scrollbars:
+ return Undefined(); // ###
+ case _Screen:
+ return Value(screen ? screen :
+ (const_cast<Window*>(this)->screen = new Screen(exec)));
+ case Image:
+ return Value(new ImageConstructorImp(exec, part->document()));
+ case Option:
+ return Value(new OptionConstructorImp(exec, part->document()));
+ case XMLHttpRequest:
+ return Value(new XMLHttpRequestConstructorImp(exec, part->document()));
+ case XMLSerializer:
+ return Value(new XMLSerializerConstructorImp(exec));
+ case DOMParser:
+ return Value(new DOMParserConstructorImp(exec, part->xmlDocImpl()));
+ case Scroll: // compatibility
+ case ScrollBy:
+ case ScrollTo:
+ case MoveBy:
+ case MoveTo:
+ case ResizeBy:
+ case ResizeTo:
+ case CaptureEvents:
+ case ReleaseEvents:
+ case AddEventListener:
+ case RemoveEventListener:
+ case SetTimeout:
+ case ClearTimeout:
+ case SetInterval:
+ case ClearInterval:
+ case Print:
+ return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+ // IE extension
+ case Navigate:
+ // Disabled in NS-compat mode. Supported by default - can't hurt, unless someone uses
+ // if (navigate) to test for IE (unlikely).
+ if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat )
+ return Undefined();
+ return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+ case Onabort:
+ return getListener(exec,DOM::EventImpl::ABORT_EVENT);
+ case Onblur:
+ return getListener(exec,DOM::EventImpl::BLUR_EVENT);
+ case Onchange:
+ return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
+ case Onclick:
+ return getListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
+ case Ondblclick:
+ return getListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
+ case Ondragdrop:
+ return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
+ case Onerror:
+ return getListener(exec,DOM::EventImpl::ERROR_EVENT);
+ case Onfocus:
+ return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
+ case Onkeydown:
+ return getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
+ case Onkeypress:
+ return getListener(exec,DOM::EventImpl::KEYPRESS_EVENT);
+ case Onkeyup:
+ return getListener(exec,DOM::EventImpl::KEYUP_EVENT);
+ case Onload:
+ return getListener(exec,DOM::EventImpl::LOAD_EVENT);
+ case Onmousedown:
+ return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
+ case Onmousemove:
+ return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
+ case Onmouseout:
+ return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
+ case Onmouseover:
+ return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
+ case Onmouseup:
+ return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
+ case Onmove:
+ return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
+ case Onreset:
+ return getListener(exec,DOM::EventImpl::RESET_EVENT);
+ case Onresize:
+ return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
+ case Onselect:
+ return getListener(exec,DOM::EventImpl::SELECT_EVENT);
+ case Onsubmit:
+ return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
+ case Onunload:
+ return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
+ }
+ }
+
+ // doing the remainder of ObjectImp::get() that is not covered by
+ // the getDirect() call above.
+ // #### guessed position. move further up or down?
+ Object proto = Object::dynamicCast(prototype());
+ assert(proto.isValid());
+ if (p == specialPrototypePropertyName)
+ return isSafeScript(exec) ? Value(proto) : Undefined();
+ Value val2 = proto.get(exec, p);
+ if (!val2.isA(UndefinedType)) {
+ return isSafeScript(exec) ? val2 : Undefined();
+ }
+
+ KParts::ReadOnlyPart *rop = part->findFramePart( p.qstring() );
+ if (rop)
+ return retrieve(rop);
+
+ // allow window[1] or parent[1] etc. (#56983)
+ bool ok;
+ unsigned int i = p.toArrayIndex(&ok);
+ if (ok) {
+ QPtrList<KParts::ReadOnlyPart> frames = part->frames();
+ unsigned int len = frames.count();
+ if (i < len) {
+ KParts::ReadOnlyPart* frame = frames.at(i);
+ if (frame)
+ return Window::retrieve(frame);
+ }
+ }
+
+ //Check for images, forms, objects, etc.
+ if (isSafeScript(exec) && part->document().isHTMLDocument()) { // might be XML
+ DOM::DocumentImpl* docImpl = part->xmlDocImpl();
+ DOM::ElementMappingCache::ItemInfo* info = docImpl->underDocNamedCache().get(p.qstring());
+ if (info) {
+ //May be a false positive, but we can try to avoid doing it the hard way in
+ //simpler cases. The trickiness here is that the cache is kept under both
+ //name and id, but we sometimes ignore id for IE compat
+ DOM::DOMString propertyDOMString = p.string();
+ if (info->nd && DOM::HTMLMappedNameCollectionImpl::matchesName(info->nd,
+ DOM::HTMLCollectionImpl::WINDOW_NAMED_ITEMS, propertyDOMString)) {
+ return getDOMNode(exec, info->nd);
+ } else {
+ //Can't tell it just like that, so better go through collection and count stuff. This is the slow path...
+ DOM::HTMLMappedNameCollection coll(docImpl, DOM::HTMLCollectionImpl::WINDOW_NAMED_ITEMS, propertyDOMString);
+
+ if (coll.length() == 1)
+ return getDOMNode(exec, coll.firstItem());
+ else if (coll.length() > 1)
+ return getHTMLCollection(exec, coll);
+ }
+ }
+ DOM::Element element = part->document().getElementById(p.string());
+ if ( !element.isNull() )
+ return getDOMNode(exec, element );
+ }
+
+ // 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, hence the WARNING to help grepping.
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
+#endif
+ return Undefined();
+}
+
+void Window::put(ExecState* exec, const Identifier &propertyName, const Value &value, int attr)
+{
+ // we don't want any operations on a closed window
+ if (m_frame.isNull() || m_frame->m_part.isNull()) {
+ // ### throw exception? allow setting of some props like location?
+ return;
+ }
+
+ // 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")
+ ( isSafeScript( exec ) && ObjectImp::getDirect(propertyName) ) )
+ {
+ ObjectImp::put( exec, propertyName, value, attr );
+ return;
+ }
+
+ const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
+ if (entry && !m_frame.isNull() && !m_frame->m_part.isNull())
+ {
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
+#endif
+ switch( entry->value) {
+ case _Location:
+ goURL(exec, value.toString(exec).qstring(), false /*don't lock history*/);
+ return;
+ default:
+ break;
+ }
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (part) {
+ switch( entry->value ) {
+ case Status: {
+ if (isSafeScript(exec) && part->settings()->windowStatusPolicy(part->url().host())
+ == KHTMLSettings::KJSWindowStatusAllow) {
+ String s = value.toString(exec);
+ part->setJSStatusBarText(s.value().qstring());
+ }
+ return;
+ }
+ case DefaultStatus: {
+ if (isSafeScript(exec) && part->settings()->windowStatusPolicy(part->url().host())
+ == KHTMLSettings::KJSWindowStatusAllow) {
+ String s = value.toString(exec);
+ part->setJSDefaultStatusBarText(s.value().qstring());
+ }
+ return;
+ }
+ case Onabort:
+ if (isSafeScript(exec))
+ setListener(exec, DOM::EventImpl::ABORT_EVENT,value);
+ return;
+ case Onblur:
+ if (isSafeScript(exec))
+ setListener(exec, DOM::EventImpl::BLUR_EVENT,value);
+ return;
+ case Onchange:
+ if (isSafeScript(exec))
+ setListener(exec, DOM::EventImpl::CHANGE_EVENT,value);
+ return;
+ case Onclick:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
+ return;
+ case Ondblclick:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
+ return;
+ case Ondragdrop:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
+ return;
+ case Onerror:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::ERROR_EVENT,value);
+ return;
+ case Onfocus:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
+ return;
+ case Onkeydown:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
+ return;
+ case Onkeypress:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::KEYPRESS_EVENT,value);
+ return;
+ case Onkeyup:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
+ return;
+ case Onload:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
+ return;
+ case Onmousedown:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
+ return;
+ case Onmousemove:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
+ return;
+ case Onmouseout:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
+ return;
+ case Onmouseover:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
+ return;
+ case Onmouseup:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
+ return;
+ case Onmove:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
+ return;
+ case Onreset:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::RESET_EVENT,value);
+ return;
+ case Onresize:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
+ return;
+ case Onselect:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
+ return;
+ case Onsubmit:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
+ return;
+ case Onunload:
+ if (isSafeScript(exec))
+ setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
+ return;
+ case Name:
+ if (isSafeScript(exec))
+ part->setName( value.toString(exec).qstring().local8Bit().data() );
+ return;
+ default:
+ break;
+ }
+ }
+ }
+ if (m_frame->m_liveconnect &&
+ isSafeScript(exec) &&
+ m_frame->m_liveconnect->put(0, propertyName.qstring(), value.toString(exec).qstring()))
+ return;
+ if (isSafeScript(exec)) {
+ //kdDebug(6070) << "Window("<<this<<")::put storing " << propertyName.qstring() << endl;
+ ObjectImp::put(exec, propertyName, value, attr);
+ }
+}
+
+bool Window::toBoolean(ExecState *) const
+{
+ return !m_frame.isNull() && !m_frame->m_part.isNull();
+}
+
+DOM::AbstractView Window::toAbstractView() const
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part)
+ return DOM::AbstractView();
+ return part->document().defaultView();
+}
+
+void Window::scheduleClose()
+{
+ kdDebug(6070) << "Window::scheduleClose window.close() " << m_frame << endl;
+ Q_ASSERT(winq);
+ QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
+}
+
+void Window::closeNow()
+{
+ if (m_frame.isNull() || m_frame->m_part.isNull()) {
+ kdDebug(6070) << k_funcinfo << "part is deleted already" << endl;
+ } else {
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part) {
+ kdDebug(6070) << "closeNow on non KHTML part" << endl;
+ } else {
+ //kdDebug(6070) << k_funcinfo << " -> closing window" << endl;
+ // We want to make sure that window.open won't find this part by name.
+ part->setName( 0 );
+ part->deleteLater();
+ part = 0;
+ }
+ }
+}
+
+void Window::afterScriptExecution()
+{
+ DOM::DocumentImpl::updateDocumentsRendering();
+ QValueList<DelayedAction> delayedActions = m_delayed;
+ m_delayed.clear();
+ QValueList<DelayedAction>::Iterator it = delayedActions.begin();
+ for ( ; it != delayedActions.end() ; ++it )
+ {
+ switch ((*it).actionId) {
+ case DelayedClose:
+ scheduleClose();
+ return; // stop here, in case of multiple actions
+ case DelayedGoHistory:
+ goHistory( (*it).param.toInt() );
+ break;
+ case NullAction:
+ // FIXME: anything needs to be done here? This is warning anyways.
+ break;
+ };
+ }
+}
+
+bool Window::checkIsSafeScript(KParts::ReadOnlyPart *activePart) const
+{
+ if (m_frame.isNull() || m_frame->m_part.isNull()) { // part deleted ? can't grant access
+ kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
+ return false;
+ }
+ if (!activePart) {
+ kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
+ return false;
+ }
+ if ( activePart == m_frame->m_part ) // Not calling from another frame, no problem.
+ return true;
+
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part)
+ return true; // not a KHTMLPart
+
+ if ( part->document().isNull() )
+ return true; // allow to access a window that was just created (e.g. with window.open("about:blank"))
+
+ DOM::HTMLDocument thisDocument = part->htmlDocument();
+ if ( thisDocument.isNull() ) {
+ kdDebug(6070) << "Window::isSafeScript: trying to access an XML document !?" << endl;
+ return false;
+ }
+
+ KHTMLPart *activeKHTMLPart = ::qt_cast<KHTMLPart *>(activePart);
+ if (!activeKHTMLPart)
+ return true; // not a KHTMLPart
+
+ DOM::HTMLDocument actDocument = activeKHTMLPart->htmlDocument();
+ if ( actDocument.isNull() ) {
+ kdDebug(6070) << "Window::isSafeScript: active part has no document!" << endl;
+ return false;
+ }
+ DOM::DOMString actDomain = actDocument.domain();
+ DOM::DOMString thisDomain = thisDocument.domain();
+
+ if ( actDomain == thisDomain ) {
+#ifdef KJS_VERBOSE
+ //kdDebug(6070) << "JavaScript: access granted, domain is '" << actDomain.string() << "'" << endl;
+#endif
+ return true;
+ }
+
+ kdDebug(6070) << "WARNING: JavaScript: access denied for current frame '" << actDomain.string() << "' to frame '" << thisDomain.string() << "'" << endl;
+ // TODO after 3.1: throw security exception (exec->setException())
+ return false;
+}
+
+void Window::setListener(ExecState *exec, int eventId, Value func)
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part || !isSafeScript(exec))
+ return;
+ DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(part->htmlDocument().handle());
+ if (!doc)
+ return;
+
+ doc->setHTMLWindowEventListener(eventId,getJSEventListener(func,true));
+}
+
+Value Window::getListener(ExecState *exec, int eventId) const
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part || !isSafeScript(exec))
+ return Undefined();
+ DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(part->htmlDocument().handle());
+ if (!doc)
+ return Undefined();
+
+ DOM::EventListener *listener = doc->getHTMLWindowEventListener(eventId);
+ if (listener && static_cast<JSEventListener*>(listener)->listenerObjImp())
+ return static_cast<JSEventListener*>(listener)->listenerObj();
+ else
+ return Null();
+}
+
+
+JSEventListener *Window::getJSEventListener(const Value& val, bool html)
+{
+ // This function is so hot that it's worth coding it directly with imps.
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part || val.type() != ObjectType)
+ return 0;
+
+ // It's ObjectType, so it must be valid.
+ Object listenerObject = Object::dynamicCast(val);
+ ObjectImp *listenerObjectImp = listenerObject.imp();
+
+ // 'listener' is not a simple ecma function. (Always use sanity checks: Better safe than sorry!)
+ if (!listenerObject.implementsCall() && part && part->jScript() && part->jScript()->interpreter())
+ {
+ Interpreter *interpreter = part->jScript()->interpreter();
+
+ // 'listener' probably is an EventListener object containing a 'handleEvent' function.
+ Value handleEventValue = listenerObject.get(interpreter->globalExec(), Identifier("handleEvent"));
+ Object handleEventObject = Object::dynamicCast(handleEventValue);
+
+ if(handleEventObject.isValid() && handleEventObject.implementsCall())
+ {
+ listenerObject = handleEventObject;
+ listenerObjectImp = handleEventObject.imp();
+ }
+ }
+
+ JSEventListener *existingListener = jsEventListeners[listenerObjectImp];
+ if (existingListener) {
+ if ( existingListener->isHTMLEventListener() != html )
+ // The existingListener will have the wrong type, so onclick= will behave like addEventListener or vice versa.
+ kdWarning() << "getJSEventListener: event listener already found but with html=" << !html << " - please report this, we thought it would never happen" << endl;
+ return existingListener;
+ }
+
+ // Note that the JSEventListener constructor adds it to our jsEventListeners list
+ return new JSEventListener(listenerObject, listenerObjectImp, Object(this), html);
+}
+
+JSLazyEventListener *Window::getJSLazyEventListener(const QString& code, const QString& name, DOM::NodeImpl *node)
+{
+ return new JSLazyEventListener(code, name, Object(this), node);
+}
+
+void Window::clear( ExecState *exec )
+{
+ delete winq;
+ winq = 0L;
+ // Get rid of everything, those user vars could hold references to DOM nodes
+ deleteAllProperties( exec );
+
+ // Break the dependency between the listeners and their object
+ QPtrDictIterator<JSEventListener> it(jsEventListeners);
+ for (; it.current(); ++it)
+ it.current()->clear();
+ // Forget about the listeners (the DOM::NodeImpls will delete them)
+ jsEventListeners.clear();
+
+ if (m_frame) {
+ KJSProxy* proxy = m_frame->m_jscript;
+ if (proxy) // i.e. JS not disabled
+ {
+ winq = new WindowQObject(this);
+ // Now recreate a working global object for the next URL that will use us
+ KJS::Interpreter *interpreter = proxy->interpreter();
+ interpreter->initGlobalObject();
+ }
+ }
+}
+
+void Window::setCurrentEvent( DOM::Event *evt )
+{
+ m_evt = evt;
+ //kdDebug(6070) << "Window " << this << " (part=" << m_part << ")::setCurrentEvent m_evt=" << evt << endl;
+}
+
+void Window::goURL(ExecState* exec, const QString& url, bool lockHistory)
+{
+ Window* active = Window::retrieveActive(exec);
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ KHTMLPart *active_part = ::qt_cast<KHTMLPart *>(active->part());
+ // Complete the URL using the "active part" (running interpreter)
+ if (active_part && part) {
+ if (url[0] == QChar('#')) {
+ part->gotoAnchor(url.mid(1));
+ } else {
+ QString dstUrl = active_part->htmlDocument().completeURL(url).string();
+ kdDebug(6070) << "Window::goURL dstUrl=" << dstUrl << endl;
+
+ // check if we're allowed to inject javascript
+ // SYNC check with khtml_part.cpp::slotRedirect!
+ if ( isSafeScript(exec) ||
+ dstUrl.find(QString::fromLatin1("javascript:"), 0, false) != 0 )
+ part->scheduleRedirection(-1,
+ dstUrl,
+ lockHistory);
+ }
+ } else if (!part && !m_frame->m_part.isNull()) {
+ KParts::BrowserExtension *b = KParts::BrowserExtension::childObject(m_frame->m_part);
+ if (b)
+ b->emit openURLRequest(m_frame->m_frame->element()->getDocument()->completeURL(url));
+ kdDebug() << "goURL for ROPart" << endl;
+ }
+}
+
+KParts::ReadOnlyPart *Window::part() const {
+ return m_frame.isNull() ? 0L : static_cast<KParts::ReadOnlyPart *>(m_frame->m_part);
+}
+
+void Window::delayedGoHistory( int steps )
+{
+ m_delayed.append( DelayedAction( DelayedGoHistory, steps ) );
+}
+
+void Window::goHistory( int steps )
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if(!part)
+ // TODO history readonlypart
+ return;
+ KParts::BrowserExtension *ext = part->browserExtension();
+ if(!ext)
+ return;
+ KParts::BrowserInterface *iface = ext->browserInterface();
+
+ if ( !iface )
+ return;
+
+ iface->callMethod( "goHistory(int)", steps );
+ //emit ext->goHistory(steps);
+}
+
+void KJS::Window::resizeTo(QWidget* tl, int width, int height)
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if(!part)
+ // TODO resizeTo readonlypart
+ return;
+ KParts::BrowserExtension *ext = part->browserExtension();
+ if (!ext) {
+ kdDebug(6070) << "Window::resizeTo found no browserExtension" << endl;
+ return;
+ }
+
+ // Security check: within desktop limits and bigger than 100x100 (per spec)
+ if ( width < 100 || height < 100 ) {
+ kdDebug(6070) << "Window::resizeTo refused, window would be too small ("<<width<<","<<height<<")" << endl;
+ return;
+ }
+
+ QRect sg = KGlobalSettings::desktopGeometry(tl);
+
+ if ( width > sg.width() || height > sg.height() ) {
+ kdDebug(6070) << "Window::resizeTo refused, window would be too big ("<<width<<","<<height<<")" << endl;
+ return;
+ }
+
+ kdDebug(6070) << "resizing to " << width << "x" << height << endl;
+
+ emit ext->resizeTopLevelWidget( width, height );
+
+ // If the window is out of the desktop, move it up/left
+ // (maybe we should use workarea instead of sg, otherwise the window ends up below kicker)
+ int right = tl->x() + tl->frameGeometry().width();
+ int bottom = tl->y() + tl->frameGeometry().height();
+ int moveByX = 0;
+ int moveByY = 0;
+ if ( right > sg.right() )
+ moveByX = - right + sg.right(); // always <0
+ if ( bottom > sg.bottom() )
+ moveByY = - bottom + sg.bottom(); // always <0
+ if ( moveByX || moveByY )
+ emit ext->moveTopLevelWidget( tl->x() + moveByX , tl->y() + moveByY );
+}
+
+Value Window::openWindow(ExecState *exec, const List& args)
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ if (!part)
+ return Undefined();
+ KHTMLView *widget = part->view();
+ Value v = args[0];
+ QString str;
+ if (v.isValid() && !v.isA(UndefinedType))
+ str = v.toString(exec).qstring();
+
+ // prepare arguments
+ KURL url;
+ if (!str.isEmpty())
+ {
+ KHTMLPart* p = ::qt_cast<KHTMLPart *>(Window::retrieveActive(exec)->m_frame->m_part);
+ if ( p )
+ url = p->htmlDocument().completeURL(str).string();
+ if ( !p ||
+ !static_cast<DOM::DocumentImpl*>(p->htmlDocument().handle())->isURLAllowed(url.url()) )
+ return Undefined();
+ }
+
+ KHTMLSettings::KJSWindowOpenPolicy policy =
+ part->settings()->windowOpenPolicy(part->url().host());
+ if ( policy == KHTMLSettings::KJSWindowOpenAsk ) {
+ emit part->browserExtension()->requestFocus(part);
+ QString caption;
+ if (!part->url().host().isEmpty())
+ caption = part->url().host() + " - ";
+ caption += i18n( "Confirmation: JavaScript Popup" );
+ if ( KMessageBox::questionYesNo(widget,
+ str.isEmpty() ?
+ i18n( "This site is requesting to open up a new browser "
+ "window via JavaScript.\n"
+ "Do you want to allow this?" ) :
+ i18n( "<qt>This site is requesting to open<p>%1</p>in a new browser window via JavaScript.<br />"
+ "Do you want to allow this?</qt>").arg(KStringHandler::csqueeze(url.htmlURL(), 100)),
+ caption, i18n("Allow"), i18n("Do Not Allow") ) == KMessageBox::Yes )
+ policy = KHTMLSettings::KJSWindowOpenAllow;
+ } else if ( policy == KHTMLSettings::KJSWindowOpenSmart )
+ {
+ // window.open disabled unless from a key/mouse event
+ if (static_cast<ScriptInterpreter *>(exec->interpreter())->isWindowOpenAllowed())
+ policy = KHTMLSettings::KJSWindowOpenAllow;
+ }
+
+ QString frameName = args.size() > 1 ? args[1].toString(exec).qstring() : QString("_blank");
+
+ v = args[2];
+ QString features;
+ if (!v.isNull() && v.type() != UndefinedType && v.toString(exec).size() > 0) {
+ features = v.toString(exec).qstring();
+ // Buggy scripts have ' at beginning and end, cut those
+ if (features.startsWith("\'") && features.endsWith("\'"))
+ features = features.mid(1, features.length()-2);
+ }
+
+ if ( policy != KHTMLSettings::KJSWindowOpenAllow ) {
+ if ( url.isEmpty() )
+ part->setSuppressedPopupIndicator(true, 0);
+ else {
+ part->setSuppressedPopupIndicator(true, part);
+ m_suppressedWindowInfo.append( SuppressedWindowInfo( url, frameName, features ) );
+ }
+ return Undefined();
+ } else {
+ return executeOpenWindow(exec, url, frameName, features);
+ }
+}
+
+Value Window::executeOpenWindow(ExecState *exec, const KURL& url, const QString& frameName, const QString& features)
+{
+ KHTMLPart *p = ::qt_cast<KHTMLPart *>(m_frame->m_part);
+ KHTMLView *widget = p->view();
+ KParts::WindowArgs winargs;
+
+ // scan feature argument
+ if (!features.isEmpty()) {
+ // specifying window params means false defaults
+ winargs.menuBarVisible = false;
+ winargs.toolBarsVisible = false;
+ winargs.statusBarVisible = false;
+ winargs.scrollBarsVisible = false;
+ QStringList flist = QStringList::split(',', features);
+ QStringList::ConstIterator it = flist.begin();
+ while (it != flist.end()) {
+ QString s = *it++;
+ QString key, val;
+ int pos = s.find('=');
+ if (pos >= 0) {
+ key = s.left(pos).stripWhiteSpace().lower();
+ val = s.mid(pos + 1).stripWhiteSpace().lower();
+ QRect screen = KGlobalSettings::desktopGeometry(widget->topLevelWidget());
+
+ if (key == "left" || key == "screenx") {
+ winargs.x = (int)val.toFloat() + screen.x();
+ if (winargs.x < screen.x() || winargs.x > screen.right())
+ winargs.x = screen.x(); // only safe choice until size is determined
+ } else if (key == "top" || key == "screeny") {
+ winargs.y = (int)val.toFloat() + screen.y();
+ if (winargs.y < screen.y() || winargs.y > screen.bottom())
+ winargs.y = screen.y(); // only safe choice until size is determined
+ } else if (key == "height") {
+ winargs.height = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
+ if (winargs.height > screen.height()) // should actually check workspace
+ winargs.height = screen.height();
+ if (winargs.height < 100)
+ winargs.height = 100;
+ } else if (key == "width") {
+ winargs.width = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
+ if (winargs.width > screen.width()) // should actually check workspace
+ winargs.width = screen.width();
+ if (winargs.width < 100)
+ winargs.width = 100;
+ } else {
+ goto boolargs;
+ }
+ continue;
+ } else {
+ // leaving away the value gives true
+ key = s.stripWhiteSpace().lower();
+ val = "1";
+ }
+ boolargs:
+ if (key == "menubar")
+ winargs.menuBarVisible = (val == "1" || val == "yes");
+ else if (key == "toolbar")
+ winargs.toolBarsVisible = (val == "1" || val == "yes");
+ else if (key == "location") // ### missing in WindowArgs
+ winargs.toolBarsVisible = (val == "1" || val == "yes");
+ else if (key == "status" || key == "statusbar")
+ winargs.statusBarVisible = (val == "1" || val == "yes");
+ else if (key == "scrollbars")
+ winargs.scrollBarsVisible = (val == "1" || val == "yes");
+ else if (key == "resizable")
+ winargs.resizable = (val == "1" || val == "yes");
+ else if (key == "fullscreen")
+ winargs.fullscreen = (val == "1" || val == "yes");
+ }
+ }
+
+ KParts::URLArgs uargs;
+ uargs.frameName = frameName;
+
+ if ( uargs.frameName.lower() == "_top" )
+ {
+ while ( p->parentPart() )
+ p = p->parentPart();
+ Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
+ return Window::retrieve(p);
+ }
+ if ( uargs.frameName.lower() == "_parent" )
+ {
+ if ( p->parentPart() )
+ p = p->parentPart();
+ Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
+ return Window::retrieve(p);
+ }
+ if ( uargs.frameName.lower() == "_self")
+ {
+ Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
+ return Window::retrieve(p);
+ }
+ if ( uargs.frameName.lower() == "replace" )
+ {
+ Window::retrieveWindow(p)->goURL(exec, url.url(), true /*lock history*/);
+ return Window::retrieve(p);
+ }
+ uargs.serviceType = "text/html";
+
+ // request window (new or existing if framename is set)
+ KParts::ReadOnlyPart *newPart = 0L;
+ emit p->browserExtension()->createNewWindow(KURL(), uargs,winargs,newPart);
+ if (newPart && ::qt_cast<KHTMLPart*>(newPart)) {
+ KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
+ //qDebug("opener set to %p (this Window's part) in new Window %p (this Window=%p)",part,win,window);
+ khtmlpart->setOpener(p);
+ khtmlpart->setOpenedByJS(true);
+ if (khtmlpart->document().isNull()) {
+ khtmlpart->begin();
+ khtmlpart->write("<HTML><BODY>");
+ khtmlpart->end();
+ if ( p->docImpl() ) {
+ //kdDebug(6070) << "Setting domain to " << p->docImpl()->domain().string() << endl;
+ khtmlpart->docImpl()->setDomain( p->docImpl()->domain());
+ khtmlpart->docImpl()->setBaseURL( p->docImpl()->baseURL() );
+ }
+ }
+ uargs.serviceType = QString::null;
+ if (uargs.frameName.lower() == "_blank")
+ uargs.frameName = QString::null;
+ if (!url.isEmpty())
+ emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
+ return Window::retrieve(khtmlpart); // global object
+ } else
+ return Undefined();
+}
+
+void Window::forgetSuppressedWindows()
+{
+ m_suppressedWindowInfo.clear();
+}
+
+void Window::showSuppressedWindows()
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>( m_frame->m_part );
+ KJS::Interpreter *interpreter = part->jScript()->interpreter();
+ ExecState *exec = interpreter->globalExec();
+
+ QValueList<SuppressedWindowInfo> suppressedWindowInfo = m_suppressedWindowInfo;
+ m_suppressedWindowInfo.clear();
+ QValueList<SuppressedWindowInfo>::Iterator it = suppressedWindowInfo.begin();
+ for ( ; it != suppressedWindowInfo.end() ; ++it ) {
+ executeOpenWindow(exec, (*it).url, (*it).frameName, (*it).features);
+ }
+}
+
+Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( Window, thisObj );
+
+ // these should work no matter whether the window is already
+ // closed or not
+ if (id == Window::ValueOf || id == Window::ToString) {
+ return String("[object Window]");
+ }
+
+ Window *window = static_cast<Window *>(thisObj.imp());
+ QString str, str2;
+
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
+ if (!part)
+ return Undefined();
+
+ KHTMLView *widget = part->view();
+ Value v = args[0];
+ UString s;
+ if (v.isValid() && !v.isA(UndefinedType)) {
+ s = v.toString(exec);
+ str = s.qstring();
+ }
+
+ QString caption;
+ if (part && !part->url().host().isEmpty())
+ caption = part->url().host() + " - ";
+ caption += "JavaScript"; // TODO: i18n
+ // functions that work everywhere
+ switch(id) {
+ case Window::Alert:
+ if (!widget->dialogsAllowed())
+ return Undefined();
+ if ( part && part->xmlDocImpl() )
+ part->xmlDocImpl()->updateRendering();
+ if ( part )
+ emit part->browserExtension()->requestFocus(part);
+ KMessageBox::error(widget, QStyleSheet::convertFromPlainText(str, QStyleSheetItem::WhiteSpaceNormal), caption);
+ return Undefined();
+ case Window::Confirm:
+ if (!widget->dialogsAllowed())
+ return Undefined();
+ if ( part && part->xmlDocImpl() )
+ part->xmlDocImpl()->updateRendering();
+ if ( part )
+ emit part->browserExtension()->requestFocus(part);
+ return Boolean((KMessageBox::warningYesNo(widget, QStyleSheet::convertFromPlainText(str), caption,
+ KStdGuiItem::ok(), KStdGuiItem::cancel()) == KMessageBox::Yes));
+ case Window::Prompt:
+#ifndef KONQ_EMBEDDED
+ if (!widget->dialogsAllowed())
+ return Undefined();
+ if ( part && part->xmlDocImpl() )
+ part->xmlDocImpl()->updateRendering();
+ if ( part )
+ emit part->browserExtension()->requestFocus(part);
+ bool ok;
+ if (args.size() >= 2)
+ str2 = KInputDialog::getText(caption,
+ QStyleSheet::convertFromPlainText(str),
+ args[1].toString(exec).qstring(), &ok, widget);
+ else
+ str2 = KInputDialog::getText(caption,
+ QStyleSheet::convertFromPlainText(str),
+ QString::null, &ok, widget);
+ if ( ok )
+ return String(str2);
+ else
+ return Null();
+#else
+ return Undefined();
+#endif
+ case Window::GetComputedStyle: {
+ if ( !part || !part->xmlDocImpl() )
+ return Undefined();
+ DOM::Node arg0 = toNode(args[0]);
+ if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
+ return Undefined(); // throw exception?
+ else
+ return getDOMCSSStyleDeclaration(exec, part->document().defaultView().getComputedStyle(static_cast<DOM::Element>(arg0),
+ args[1].toString(exec).string()));
+ }
+ case Window::Open:
+ return window->openWindow(exec, args);
+ case Window::Close: {
+ /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
+ The close method closes only windows opened by JavaScript using the open method.
+ If you attempt to close any other window, a confirm is generated, which
+ lets the user choose whether the window closes.
+ This is a security feature to prevent "mail bombs" containing self.close().
+ However, if the window has only one document (the current one) in its
+ session history, the close is allowed without any confirm. This is a
+ special case for one-off windows that need to open other windows and
+ then dispose of themselves.
+ */
+ bool doClose = false;
+ if (!part->openedByJS())
+ {
+ // To conform to the SPEC, we only ask if the window
+ // has more than one entry in the history (NS does that too).
+ History history(exec,part);
+
+ if ( history.get( exec, "length" ).toInt32(exec) <= 1 )
+ {
+ doClose = true;
+ }
+ else
+ {
+ // Can we get this dialog with tabs??? Does it close the window or the tab in that case?
+ emit part->browserExtension()->requestFocus(part);
+ if ( KMessageBox::questionYesNo( window->part()->widget(),
+ i18n("Close window?"), i18n("Confirmation Required"),
+ KStdGuiItem::close(), KStdGuiItem::cancel() )
+ == KMessageBox::Yes )
+ doClose = true;
+ }
+ }
+ else
+ doClose = true;
+
+ if (doClose)
+ {
+ // If this is the current window (the one the interpreter runs in),
+ // then schedule a delayed close (so that the script terminates first).
+ // But otherwise, close immediately. This fixes w=window.open("","name");w.close();window.open("name");
+ if ( Window::retrieveActive(exec) == window ) {
+ if (widget) {
+ // quit all dialogs of this view
+ // this fixes 'setTimeout('self.close()',1000); alert("Hi");' crash
+ widget->closeChildDialogs();
+ }
+ //kdDebug() << "scheduling delayed close" << endl;
+ // We'll close the window at the end of the script execution
+ Window* w = const_cast<Window*>(window);
+ w->m_delayed.append( Window::DelayedAction( Window::DelayedClose ) );
+ } else {
+ //kdDebug() << "closing NOW" << endl;
+ (const_cast<Window*>(window))->closeNow();
+ }
+ }
+ return Undefined();
+ }
+ case Window::Navigate:
+ window->goURL(exec, args[0].toString(exec).qstring(), false /*don't lock history*/);
+ return Undefined();
+ case Window::Focus: {
+ KHTMLSettings::KJSWindowFocusPolicy policy =
+ part->settings()->windowFocusPolicy(part->url().host());
+ if(policy == KHTMLSettings::KJSWindowFocusAllow && widget) {
+ widget->topLevelWidget()->raise();
+ KWin::deIconifyWindow( widget->topLevelWidget()->winId() );
+ widget->setActiveWindow();
+ emit part->browserExtension()->requestFocus(part);
+ }
+ return Undefined();
+ }
+ case Window::Blur:
+ // TODO
+ return Undefined();
+ case Window::BToA:
+ case Window::AToB: {
+ if (!s.is8Bit())
+ return Undefined();
+ QByteArray in, out;
+ char *binData = s.ascii();
+ in.setRawData( binData, s.size() );
+ if (id == Window::AToB)
+ KCodecs::base64Decode( in, out );
+ else
+ KCodecs::base64Encode( in, out );
+ in.resetRawData( binData, s.size() );
+ UChar *d = new UChar[out.size()];
+ for (uint i = 0; i < out.size(); i++)
+ d[i].uc = (uchar) out[i];
+ UString ret(d, out.size(), false /*no copy*/);
+ return String(ret);
+ }
+
+ };
+
+
+ // now unsafe functions..
+ if (!window->isSafeScript(exec))
+ return Undefined();
+
+ switch (id) {
+ case Window::ScrollBy:
+ if(args.size() == 2 && widget)
+ widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
+ return Undefined();
+ case Window::Scroll:
+ case Window::ScrollTo:
+ if(args.size() == 2 && widget)
+ widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
+ return Undefined();
+ case Window::MoveBy: {
+ KHTMLSettings::KJSWindowMovePolicy policy =
+ part->settings()->windowMovePolicy(part->url().host());
+ if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
+ {
+ KParts::BrowserExtension *ext = part->browserExtension();
+ if (ext) {
+ QWidget * tl = widget->topLevelWidget();
+ QRect sg = KGlobalSettings::desktopGeometry(tl);
+
+ QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
+ // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
+ if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
+ dest.x()+tl->width() <= sg.width()+sg.x() &&
+ dest.y()+tl->height() <= sg.height()+sg.y() )
+ emit ext->moveTopLevelWidget( dest.x(), dest.y() );
+ }
+ }
+ return Undefined();
+ }
+ case Window::MoveTo: {
+ KHTMLSettings::KJSWindowMovePolicy policy =
+ part->settings()->windowMovePolicy(part->url().host());
+ if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
+ {
+ KParts::BrowserExtension *ext = part->browserExtension();
+ if (ext) {
+ QWidget * tl = widget->topLevelWidget();
+ QRect sg = KGlobalSettings::desktopGeometry(tl);
+
+ QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
+ // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
+ if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
+ dest.x()+tl->width() <= sg.width()+sg.x() &&
+ dest.y()+tl->height() <= sg.height()+sg.y() )
+ emit ext->moveTopLevelWidget( dest.x(), dest.y() );
+ }
+ }
+ return Undefined();
+ }
+ case Window::ResizeBy: {
+ KHTMLSettings::KJSWindowResizePolicy policy =
+ part->settings()->windowResizePolicy(part->url().host());
+ if(policy == KHTMLSettings::KJSWindowResizeAllow
+ && args.size() == 2 && widget)
+ {
+ QWidget * tl = widget->topLevelWidget();
+ QRect geom = tl->frameGeometry();
+ window->resizeTo( tl,
+ geom.width() + args[0].toInt32(exec),
+ geom.height() + args[1].toInt32(exec) );
+ }
+ return Undefined();
+ }
+ case Window::ResizeTo: {
+ KHTMLSettings::KJSWindowResizePolicy policy =
+ part->settings()->windowResizePolicy(part->url().host());
+ if(policy == KHTMLSettings::KJSWindowResizeAllow
+ && args.size() == 2 && widget)
+ {
+ QWidget * tl = widget->topLevelWidget();
+ window->resizeTo( tl, args[0].toInt32(exec), args[1].toInt32(exec) );
+ }
+ return Undefined();
+ }
+ case Window::SetTimeout:
+ case Window::SetInterval: {
+ bool singleShot;
+ int i; // timeout interval
+ if (args.size() == 0)
+ return Undefined();
+ if (args.size() > 1) {
+ singleShot = (id == Window::SetTimeout);
+ i = args[1].toInt32(exec);
+ } else {
+ // second parameter is missing. Emulate Mozilla behavior.
+ singleShot = true;
+ i = 4;
+ }
+ if (v.isA(StringType)) {
+ int r = (const_cast<Window*>(window))->winq->installTimeout(Identifier(s), i, singleShot );
+ return Number(r);
+ }
+ else if (v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
+ Object func = Object::dynamicCast(v);
+ List funcArgs;
+ ListIterator it = args.begin();
+ int argno = 0;
+ while (it != args.end()) {
+ Value arg = it++;
+ if (argno++ >= 2)
+ funcArgs.append(arg);
+ }
+ if (args.size() < 2)
+ funcArgs.append(Number(i));
+ int r = (const_cast<Window*>(window))->winq->installTimeout(func, funcArgs, i, singleShot );
+ return Number(r);
+ }
+ else
+ return Undefined();
+ }
+ case Window::ClearTimeout:
+ case Window::ClearInterval:
+ (const_cast<Window*>(window))->winq->clearTimeout(v.toInt32(exec));
+ return Undefined();
+ case Window::Print:
+ if ( widget ) {
+ // ### TODO emit onbeforeprint event
+ widget->print();
+ // ### TODO emit onafterprint event
+ }
+ case Window::CaptureEvents:
+ case Window::ReleaseEvents:
+ // Do nothing for now. These are NS-specific legacy calls.
+ break;
+ case Window::AddEventListener: {
+ JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
+ if (listener) {
+ DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
+ docimpl->addWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
+ }
+ return Undefined();
+ }
+ case Window::RemoveEventListener: {
+ JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
+ if (listener) {
+ DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
+ docimpl->removeWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
+ }
+ return Undefined();
+ }
+
+ }
+ return Undefined();
+}
+
+////////////////////// ScheduledAction ////////////////////////
+
+// KDE 4: Make those parameters const ... &
+ScheduledAction::ScheduledAction(Object _func, List _args, DateTimeMS _nextTime, int _interval, bool _singleShot,
+ int _timerId)
+{
+ //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
+ func = static_cast<ObjectImp*>(_func.imp());
+ args = _args;
+ isFunction = true;
+ singleShot = _singleShot;
+ nextTime = _nextTime;
+ interval = _interval;
+ executing = false;
+ timerId = _timerId;
+}
+
+// KDE 4: Make it const QString &
+ScheduledAction::ScheduledAction(QString _code, DateTimeMS _nextTime, int _interval, bool _singleShot, int _timerId)
+{
+ //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
+ //func = 0;
+ //args = 0;
+ func = 0;
+ code = _code;
+ isFunction = false;
+ singleShot = _singleShot;
+ nextTime = _nextTime;
+ interval = _interval;
+ executing = false;
+ timerId = _timerId;
+}
+
+bool ScheduledAction::execute(Window *window)
+{
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
+ if (!part || !part->jScriptEnabled())
+ return false;
+ ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(part->jScript()->interpreter());
+
+ interpreter->setProcessingTimerCallback(true);
+
+ //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
+ if (isFunction) {
+ if (func->implementsCall()) {
+ // #### check this
+ Q_ASSERT( part );
+ if ( part )
+ {
+ KJS::Interpreter *interpreter = part->jScript()->interpreter();
+ 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
+ if (exec->hadException())
+ exec->clearException();
+
+ // Update our document's rendering following the execution of the timeout callback.
+ part->document().updateRendering();
+ }
+ }
+ }
+ else {
+ part->executeScript(DOM::Node(), code);
+ }
+
+ interpreter->setProcessingTimerCallback(false);
+ return true;
+}
+
+void ScheduledAction::mark()
+{
+ if (func && !func->marked())
+ func->mark();
+ args.mark();
+}
+
+ScheduledAction::~ScheduledAction()
+{
+ //kdDebug(6070) << "ScheduledAction::~ScheduledAction " << this << endl;
+}
+
+////////////////////// WindowQObject ////////////////////////
+
+WindowQObject::WindowQObject(Window *w)
+ : parent(w)
+{
+ //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
+ if ( !parent->m_frame )
+ kdDebug(6070) << "WARNING: null part in " << k_funcinfo << endl;
+ else
+ connect( parent->m_frame, SIGNAL( destroyed() ),
+ this, SLOT( parentDestroyed() ) );
+ pausedTime = 0;
+ lastTimerId = 0;
+ currentlyDispatching = false;
+}
+
+WindowQObject::~WindowQObject()
+{
+ //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
+ parentDestroyed(); // reuse same code
+}
+
+void WindowQObject::parentDestroyed()
+{
+ killTimers();
+
+ QPtrListIterator<ScheduledAction> it(scheduledActions);
+ for (; it.current(); ++it)
+ delete it.current();
+ scheduledActions.clear();
+}
+
+int WindowQObject::installTimeout(const Identifier &handler, int t, bool singleShot)
+{
+ int id = ++lastTimerId;
+ if (t < 10) t = 10;
+ DateTimeMS nextTime = DateTimeMS::now().addMSecs(-pausedTime + t);
+
+ ScheduledAction *action = new ScheduledAction(handler.qstring(),nextTime,t,singleShot,id);
+ scheduledActions.append(action);
+ setNextTimer();
+ return id;
+}
+
+int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
+{
+ Object objFunc = Object::dynamicCast( func );
+ if (!objFunc.isValid())
+ return 0;
+ int id = ++lastTimerId;
+ if (t < 10) t = 10;
+
+ DateTimeMS nextTime = DateTimeMS::now().addMSecs(-pausedTime + t);
+ ScheduledAction *action = new ScheduledAction(objFunc,args,nextTime,t,singleShot,id);
+ scheduledActions.append(action);
+ setNextTimer();
+ return id;
+}
+
+void WindowQObject::clearTimeout(int timerId)
+{
+ QPtrListIterator<ScheduledAction> it(scheduledActions);
+ for (; it.current(); ++it) {
+ ScheduledAction *action = it.current();
+ if (action->timerId == timerId) {
+ scheduledActions.removeRef(action);
+ if (!action->executing)
+ delete action;
+ return;
+ }
+ }
+}
+
+bool WindowQObject::hasTimers() const
+{
+ return scheduledActions.count();
+}
+
+void WindowQObject::mark()
+{
+ QPtrListIterator<ScheduledAction> it(scheduledActions);
+ for (; it.current(); ++it)
+ it.current()->mark();
+}
+
+void WindowQObject::timerEvent(QTimerEvent *)
+{
+ killTimers();
+
+ if (scheduledActions.isEmpty())
+ return;
+
+ currentlyDispatching = true;
+
+
+ DateTimeMS currentActual = DateTimeMS::now();
+ DateTimeMS currentAdjusted = currentActual.addMSecs(-pausedTime);
+
+ // Work out which actions are to be executed. We take a separate copy of
+ // this list since the main one may be modified during action execution
+ QPtrList<ScheduledAction> toExecute;
+ QPtrListIterator<ScheduledAction> it(scheduledActions);
+ for (; it.current(); ++it)
+ if (currentAdjusted >= it.current()->nextTime)
+ toExecute.append(it.current());
+
+ // ### verify that the window can't be closed (and action deleted) during execution
+ it = QPtrListIterator<ScheduledAction>(toExecute);
+ for (; it.current(); ++it) {
+ ScheduledAction *action = it.current();
+ if (!scheduledActions.containsRef(action)) // removed by clearTimeout()
+ continue;
+
+ action->executing = true; // prevent deletion in clearTimeout()
+
+ if (parent->part()) {
+ bool ok = action->execute(parent);
+ if ( !ok ) // e.g. JS disabled
+ scheduledActions.removeRef( action );
+ }
+
+ if (action->singleShot) {
+ scheduledActions.removeRef(action);
+ }
+
+ action->executing = false;
+
+ if (!scheduledActions.containsRef(action))
+ delete action;
+ else
+ action->nextTime = action->nextTime.addMSecs(action->interval);
+ }
+
+ pausedTime += currentActual.msecsTo(DateTimeMS::now());
+
+ currentlyDispatching = false;
+
+ // Work out when next event is to occur
+ setNextTimer();
+}
+
+DateTimeMS DateTimeMS::addMSecs(int s) const
+{
+ DateTimeMS c = *this;
+ c.mTime = mTime.addMSecs(s);
+ if (s > 0)
+ {
+ if (c.mTime < mTime)
+ c.mDate = mDate.addDays(1);
+ }
+ else
+ {
+ if (c.mTime > mTime)
+ c.mDate = mDate.addDays(-1);
+ }
+ return c;
+}
+
+bool DateTimeMS::operator >(const DateTimeMS &other) const
+{
+ if (mDate > other.mDate)
+ return true;
+
+ if (mDate < other.mDate)
+ return false;
+
+ return mTime > other.mTime;
+}
+
+bool DateTimeMS::operator >=(const DateTimeMS &other) const
+{
+ if (mDate > other.mDate)
+ return true;
+
+ if (mDate < other.mDate)
+ return false;
+
+ return mTime >= other.mTime;
+}
+
+int DateTimeMS::msecsTo(const DateTimeMS &other) const
+{
+ int d = mDate.daysTo(other.mDate);
+ int ms = mTime.msecsTo(other.mTime);
+ return d*24*60*60*1000 + ms;
+}
+
+
+DateTimeMS DateTimeMS::now()
+{
+ DateTimeMS t;
+ QTime before = QTime::currentTime();
+ t.mDate = QDate::currentDate();
+ t.mTime = QTime::currentTime();
+ if (t.mTime < before)
+ t.mDate = QDate::currentDate(); // prevent race condition in hacky way :)
+ return t;
+}
+
+void WindowQObject::setNextTimer()
+{
+ if (currentlyDispatching)
+ return; // Will schedule at the end
+
+ if (scheduledActions.isEmpty())
+ return;
+
+ QPtrListIterator<ScheduledAction> it(scheduledActions);
+ DateTimeMS nextTime = it.current()->nextTime;
+ for (++it; it.current(); ++it)
+ if (nextTime > it.current()->nextTime)
+ nextTime = it.current()->nextTime;
+
+ DateTimeMS nextTimeActual = nextTime.addMSecs(pausedTime);
+ int nextInterval = DateTimeMS::now().msecsTo(nextTimeActual);
+ if (nextInterval < 0)
+ nextInterval = 0;
+ startTimer(nextInterval);
+}
+
+void WindowQObject::timeoutClose()
+{
+ parent->closeNow();
+}
+
+Value FrameArray::get(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
+#endif
+ if (part.isNull())
+ return Undefined();
+
+ QPtrList<KParts::ReadOnlyPart> frames = part->frames();
+ unsigned int len = frames.count();
+ if (p == lengthPropertyName)
+ return Number(len);
+ else if (p== "location") // non-standard property, but works in NS and IE
+ {
+ Object obj = Object::dynamicCast( Window::retrieve( part ) );
+ if ( obj.isValid() )
+ return obj.get( exec, "location" );
+ return Undefined();
+ }
+
+ // check for the name or number
+ KParts::ReadOnlyPart *frame = part->findFramePart(p.qstring());
+ if (!frame) {
+ bool ok;
+ unsigned int i = p.toArrayIndex(&ok);
+ if (ok && i < len)
+ frame = frames.at(i);
+ }
+
+ // we are potentially fetching a reference to a another Window object here.
+ // i.e. we may be accessing objects from another interpreter instance.
+ // Therefore we have to be a bit careful with memory management.
+ if (frame) {
+ return Window::retrieve(frame);
+ }
+
+ // Fun IE quirk: name lookup in there is actually done by document.all
+ // hence, it can find non-frame things (and even let them hide frame ones!)
+ // We don't quite do that, but do this as a fallback.
+ DOM::DocumentImpl* doc = static_cast<DOM::DocumentImpl*>(part->document().handle());
+ if (doc) {
+ DOM::HTMLCollectionImpl docuAll(doc, DOM::HTMLCollectionImpl::DOC_ALL);
+ DOM::NodeImpl* node = docuAll.namedItem(p.string());
+ if (node) {
+ if (node->id() == ID_FRAME || node->id() == ID_IFRAME) {
+ //Return the Window object.
+ KHTMLPart* part = static_cast<DOM::HTMLFrameElementImpl*>(node)->contentPart();
+ if (part)
+ return Value(Window::retrieveWindow(part));
+ else
+ return Undefined();
+ } else {
+ //Just a regular node..
+ return getDOMNode(exec, node);
+ }
+ }
+ } else {
+ kdWarning(6070) << "Missing own document in FrameArray::get()" << endl;
+ }
+
+ return ObjectImp::get(exec, p);
+}
+
+Value FrameArray::call(ExecState *exec, Object &/*thisObj*/, const List &args)
+{
+ //IE supports a subset of the get functionality as call...
+ //... basically, when the return is a window, it supports that, otherwise it
+ //errors out. We do a cheap-and-easy emulation of that, and just do the same
+ //thing as get does.
+ if (args.size() == 1)
+ return get(exec, Identifier(args[0].toString(exec)));
+
+ return Undefined();
+}
+
+
+////////////////////// Location Object ////////////////////////
+
+const ClassInfo Location::info = { "Location", 0, &LocationTable, 0 };
+/*
+@begin LocationTable 11
+ hash Location::Hash DontDelete
+ host Location::Host DontDelete
+ hostname Location::Hostname DontDelete
+ href Location::Href DontDelete
+ pathname Location::Pathname DontDelete
+ port Location::Port DontDelete
+ protocol Location::Protocol DontDelete
+ search Location::Search DontDelete
+ [[==]] Location::EqualEqual DontDelete|ReadOnly
+ assign Location::Assign DontDelete|Function 1
+ toString Location::ToString DontDelete|Function 0
+ replace Location::Replace DontDelete|Function 1
+ reload Location::Reload DontDelete|Function 0
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(LocationFunc)
+Location::Location(khtml::ChildFrame *f) : m_frame(f)
+{
+ //kdDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part << endl;
+}
+
+Location::~Location()
+{
+ //kdDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part << endl;
+}
+
+KParts::ReadOnlyPart *Location::part() const {
+ return m_frame ? static_cast<KParts::ReadOnlyPart *>(m_frame->m_part) : 0L;
+}
+
+Value Location::get(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
+#endif
+
+ if (m_frame.isNull() || m_frame->m_part.isNull())
+ return Undefined();
+
+ const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
+
+ // properties that work on all Location objects
+ if ( entry && entry->value == Replace )
+ return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+
+ // XSS check
+ const Window* window = Window::retrieveWindow( m_frame->m_part );
+ if ( !window || !window->isSafeScript(exec) )
+ return Undefined();
+
+ KURL url = m_frame->m_part->url();
+ if (entry)
+ switch (entry->value) {
+ case Hash:
+ return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
+ case Host: {
+ UString str = url.host();
+ if (url.port())
+ str += ":" + QString::number((int)url.port());
+ return String(str);
+ // Note: this is the IE spec. The NS spec swaps the two, it says
+ // "The hostname property is the concatenation of the host and port properties, separated by a colon."
+ // Bleh.
+ }
+ case Hostname:
+ return String( url.host() );
+ case Href:
+ if (url.isEmpty())
+ return String("about:blank");
+ else if (!url.hasPath())
+ return String( url.prettyURL()+"/" );
+ else
+ return String( url.prettyURL() );
+ case Pathname:
+ if (url.isEmpty())
+ return String("");
+ return String( url.path().isEmpty() ? QString("/") : url.path() );
+ case Port:
+ return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
+ case Protocol:
+ return String( url.protocol()+":" );
+ case Search:
+ return String( url.query() );
+ case EqualEqual: // [[==]]
+ return String(toString(exec));
+ case ToString:
+ return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+ }
+ // Look for overrides
+ ValueImp * val = ObjectImp::getDirect(p);
+ if (val)
+ return Value(val);
+ if (entry && (entry->attr & Function))
+ return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+
+ return Undefined();
+}
+
+void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
+{
+#ifdef KJS_VERBOSE
+ kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
+#endif
+ if (m_frame.isNull() || m_frame->m_part.isNull())
+ return;
+
+ const Window* window = Window::retrieveWindow( m_frame->m_part );
+ if ( !window )
+ return;
+
+ KURL url = m_frame->m_part->url();
+
+ const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
+
+ if (entry) {
+
+ // XSS check. Only new hrefs can be set from other sites
+ if (entry->value != Href && !window->isSafeScript(exec))
+ return;
+
+ QString str = v.toString(exec).qstring();
+ switch (entry->value) {
+ case Href: {
+ KHTMLPart* p =::qt_cast<KHTMLPart*>(Window::retrieveActive(exec)->part());
+ if ( p )
+ url = p->htmlDocument().completeURL( str ).string();
+ else
+ url = str;
+ break;
+ }
+ case Hash:
+ // when the hash is already the same ignore it
+ if (str == url.ref()) return;
+ url.setRef(str);
+ break;
+ case Host: {
+ QString host = str.left(str.find(":"));
+ QString port = str.mid(str.find(":")+1);
+ url.setHost(host);
+ url.setPort(port.toUInt());
+ break;
+ }
+ case Hostname:
+ url.setHost(str);
+ break;
+ case Pathname:
+ url.setPath(str);
+ break;
+ case Port:
+ url.setPort(str.toUInt());
+ break;
+ case Protocol:
+ url.setProtocol(str);
+ break;
+ case Search:
+ url.setQuery(str);
+ break;
+ }
+ } else {
+ ObjectImp::put(exec, p, v, attr);
+ return;
+ }
+
+ Window::retrieveWindow(m_frame->m_part)->goURL(exec, url.url(), false /* don't lock history*/ );
+}
+
+Value Location::toPrimitive(ExecState *exec, Type) const
+{
+ if (m_frame) {
+ Window* window = Window::retrieveWindow( m_frame->m_part );
+ if ( window && window->isSafeScript(exec) )
+ return String(toString(exec));
+ }
+ return Undefined();
+}
+
+UString Location::toString(ExecState *exec) const
+{
+ if (m_frame) {
+ Window* window = Window::retrieveWindow( m_frame->m_part );
+ if ( window && window->isSafeScript(exec) )
+ {
+ KURL url = m_frame->m_part->url();
+ if (url.isEmpty())
+ return "about:blank";
+ else if (!url.hasPath())
+ return url.prettyURL()+"/";
+ else
+ return url.prettyURL();
+ }
+ }
+ return "";
+}
+
+Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( Location, thisObj );
+ Location *location = static_cast<Location *>(thisObj.imp());
+ KParts::ReadOnlyPart *part = location->part();
+
+ if (!part) return Undefined();
+
+ Window* window = Window::retrieveWindow(part);
+
+ if ( !window->isSafeScript(exec) && id != Location::Replace)
+ return Undefined();
+
+ switch (id) {
+ case Location::Assign:
+ case Location::Replace:
+ Window::retrieveWindow(part)->goURL(exec, args[0].toString(exec).qstring(),
+ id == Location::Replace);
+ break;
+ case Location::Reload: {
+ KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(part);
+ if (khtmlpart)
+ khtmlpart->scheduleRedirection(-1, part->url().url(), true/*lock history*/);
+ else
+ part->openURL(part->url());
+ break;
+ }
+ case Location::ToString:
+ return String(location->toString(exec));
+ }
+ return Undefined();
+}
+
+////////////////////// External Object ////////////////////////
+
+const ClassInfo External::info = { "External", 0, 0, 0 };
+/*
+@begin ExternalTable 4
+ addFavorite External::AddFavorite DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(ExternalFunc)
+
+Value External::get(ExecState *exec, const Identifier &p) const
+{
+ return lookupGetFunction<ExternalFunc,ObjectImp>(exec,p,&ExternalTable,this);
+}
+
+Value ExternalFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( External, thisObj );
+ External *external = static_cast<External *>(thisObj.imp());
+
+ KHTMLPart *part = external->part;
+ if (!part)
+ return Undefined();
+
+ KHTMLView *widget = part->view();
+
+ switch (id) {
+ case External::AddFavorite:
+ {
+#ifndef KONQ_EMBEDDED
+ if (!widget->dialogsAllowed())
+ return Undefined();
+ part->xmlDocImpl()->updateRendering();
+ if (args.size() != 1 && args.size() != 2)
+ return Undefined();
+
+ QString url = args[0].toString(exec).qstring();
+ QString title;
+ if (args.size() == 2)
+ title = args[1].toString(exec).qstring();
+
+ // AK - don't do anything yet, for the moment i
+ // just wanted the base js handling code in cvs
+ return Undefined();
+
+ QString question;
+ if ( title.isEmpty() )
+ question = i18n("Do you want a bookmark pointing to the location \"%1\" to be added to your collection?")
+ .arg(url);
+ else
+ question = i18n("Do you want a bookmark pointing to the location \"%1\" titled \"%2\" to be added to your collection?")
+ .arg(url).arg(title);
+
+ emit part->browserExtension()->requestFocus(part);
+
+ QString caption;
+ if (!part->url().host().isEmpty())
+ caption = part->url().host() + " - ";
+ caption += i18n("JavaScript Attempted Bookmark Insert");
+
+ if (KMessageBox::warningYesNo(
+ widget, question, caption,
+ i18n("Insert"), i18n("Disallow")) == KMessageBox::Yes)
+ {
+ KBookmarkManager *mgr = KBookmarkManager::userBookmarksManager();
+ mgr->addBookmarkDialog(url,title);
+ }
+#else
+ return Undefined();
+#endif
+ break;
+ }
+ default:
+ return Undefined();
+ }
+
+ return Undefined();
+}
+
+////////////////////// History Object ////////////////////////
+
+const ClassInfo History::info = { "History", 0, 0, 0 };
+/*
+@begin HistoryTable 4
+ length History::Length DontDelete|ReadOnly
+ back History::Back DontDelete|Function 0
+ forward History::Forward DontDelete|Function 0
+ go History::Go DontDelete|Function 1
+@end
+*/
+IMPLEMENT_PROTOFUNC_DOM(HistoryFunc)
+
+Value History::get(ExecState *exec, const Identifier &p) const
+{
+ return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
+}
+
+Value History::getValueProperty(ExecState *, int token) const
+{
+ // if previous or next is implemented, make sure its not a major
+ // privacy leak (see i.e. http://security.greymagic.com/adv/gm005-op/)
+ switch (token) {
+ case Length:
+ {
+ if ( !part )
+ return Number( 0 );
+
+ KParts::BrowserExtension *ext = part->browserExtension();
+ if ( !ext )
+ return Number( 0 );
+
+ KParts::BrowserInterface *iface = ext->browserInterface();
+ if ( !iface )
+ return Number( 0 );
+
+ QVariant length = iface->property( "historyLength" );
+
+ if ( length.type() != QVariant::UInt )
+ return Number( 0 );
+
+ return Number( length.toUInt() );
+ }
+ default:
+ kdDebug(6070) << "WARNING: Unhandled token in History::getValueProperty : " << token << endl;
+ return Undefined();
+ }
+}
+
+Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ KJS_CHECK_THIS( History, thisObj );
+ History *history = static_cast<History *>(thisObj.imp());
+
+ Value v = args[0];
+ Number n;
+ if(v.isValid())
+ n = v.toInteger(exec);
+
+ int steps;
+ switch (id) {
+ case History::Back:
+ steps = -1;
+ break;
+ case History::Forward:
+ steps = 1;
+ break;
+ case History::Go:
+ steps = n.intValue();
+ break;
+ default:
+ return Undefined();
+ }
+
+ // Special case for go(0) from a frame -> reload only the frame
+ // go(i!=0) from a frame navigates into the history of the frame only,
+ // in both IE and NS (but not in Mozilla).... we can't easily do that
+ // in Konqueror...
+ if (!steps) // add && history->part->parentPart() to get only frames, but doesn't matter
+ {
+ history->part->openURL( history->part->url() ); /// ## need args.reload=true?
+ } else
+ {
+ // Delay it.
+ // Testcase: history.back(); alert("hello");
+ Window* window = Window::retrieveWindow( history->part );
+ window->delayedGoHistory( steps );
+ }
+ return Undefined();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef Q_WS_QWS
+
+const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
+
+bool Konqueror::hasProperty(ExecState *exec, const Identifier &p) const
+{
+ if ( p.qstring().startsWith( "goHistory" ) ) return false;
+
+ return true;
+}
+
+Value Konqueror::get(ExecState *exec, const Identifier &p) const
+{
+ if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
+ return Undefined();
+
+ KParts::BrowserExtension *ext = part->browserExtension();
+ if ( ext ) {
+ KParts::BrowserInterface *iface = ext->browserInterface();
+ if ( iface ) {
+ QVariant prop = iface->property( p.qstring().latin1() );
+
+ if ( prop.isValid() ) {
+ switch( prop.type() ) {
+ case QVariant::Int:
+ return Number( prop.toInt() );
+ case QVariant::String:
+ return String( prop.toString() );
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return Value( new KonquerorFunc(exec, this, p.qstring().latin1() ) );
+}
+
+Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
+{
+ KParts::BrowserExtension *ext = konqueror->part->browserExtension();
+
+ if (!ext)
+ return Undefined();
+
+ KParts::BrowserInterface *iface = ext->browserInterface();
+
+ if ( !iface )
+ return Undefined();
+
+ QCString n = m_name.data();
+ n += "()";
+ iface->callMethod( n.data(), QVariant() );
+
+ return Undefined();
+}
+
+UString Konqueror::toString(ExecState *) const
+{
+ return UString("[object Konqueror]");
+}
+
+#endif
+/////////////////////////////////////////////////////////////////////////////
+} //namespace KJS
+
+#include "kjs_window.moc"
diff --git a/khtml/ecma/kjs_window.h b/khtml/ecma/kjs_window.h
new file mode 100644
index 000000000..1444110f4
--- /dev/null
+++ b/khtml/ecma/kjs_window.h
@@ -0,0 +1,309 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _KJS_WINDOW_H_
+#define _KJS_WINDOW_H_
+
+#include <qobject.h>
+#include <qguardedptr.h>
+#include <qmap.h>
+#include <qptrlist.h>
+#include <qdatetime.h>
+
+#include "kjs_binding.h"
+#include "kjs_views.h"
+
+class QTimer;
+class KHTMLView;
+class KHTMLPart;
+
+namespace KParts {
+ class ReadOnlyPart;
+}
+
+namespace khtml {
+ class ChildFrame;
+}
+
+namespace KJS {
+
+ class WindowFunc;
+ class WindowQObject;
+ class Location;
+ class History;
+ class External;
+ class FrameArray;
+ class JSEventListener;
+ class JSLazyEventListener;
+
+ class Screen : public ObjectImp {
+ public:
+ Screen(ExecState *exec);
+ enum {
+ Height, Width, ColorDepth, PixelDepth, AvailLeft, AvailTop, AvailHeight,
+ AvailWidth
+ };
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ private:
+ KHTMLView *view;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+ class KDE_EXPORT Window : public ObjectImp {
+ friend QGuardedPtr<KHTMLPart> getInstance();
+ friend class Location;
+ friend class WindowFunc;
+ friend class WindowQObject;
+ friend class ScheduledAction;
+ public:
+ Window(khtml::ChildFrame *p);
+ public:
+ ~Window();
+ /**
+ * 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 Value retrieve(KParts::ReadOnlyPart *p);
+ /**
+ * Returns the Window object for a given part
+ */
+ static Window *retrieveWindow(KParts::ReadOnlyPart *p);
+ /**
+ * returns a pointer to the Window object this javascript interpreting instance
+ * was called from.
+ */
+ static Window *retrieveActive(ExecState *exec);
+ KParts::ReadOnlyPart *part() const;
+ virtual void mark();
+ virtual bool hasProperty(ExecState *exec, const Identifier &p) const;
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual DOM::AbstractView toAbstractView() const;
+ void scheduleClose();
+ void closeNow();
+ void delayedGoHistory(int steps);
+ void goHistory(int steps);
+ void goURL(ExecState* exec, const QString& url, bool lockHistory);
+ Value openWindow(ExecState *exec, const List &args);
+ Value executeOpenWindow(ExecState *exec, const KURL& url, const QString& frameName, const QString& features);
+ void resizeTo(QWidget* tl, int width, int height);
+ void afterScriptExecution();
+ bool isSafeScript(ExecState *exec) const {
+ KParts::ReadOnlyPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->interpreter() )->part();
+ if ( activePart == part() ) return true;
+ return checkIsSafeScript( activePart );
+ }
+ Location *location() const;
+ ObjectImp* frames( ExecState* exec ) const;
+ JSEventListener *getJSEventListener(const Value &val, bool html = false);
+ JSLazyEventListener *getJSLazyEventListener(const QString &code, const QString &name, DOM::NodeImpl* node);
+ void clear( ExecState *exec );
+ virtual UString toString(ExecState *exec) const;
+
+ // Set the current "event" object
+ void setCurrentEvent( DOM::Event *evt );
+
+ QPtrDict<JSEventListener> jsEventListeners;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Closed, Crypto, DefaultStatus, Status, Document, Node, EventCtor, Range,
+ NodeFilter, DOMException, CSSRule, Frames, _History, _External, Event, InnerHeight,
+ InnerWidth, Length, _Location, Navigate, Name, _Navigator, _Konqueror, ClientInformation,
+ OffscreenBuffering, Opener, OuterHeight, OuterWidth, PageXOffset, PageYOffset,
+ Parent, Personalbar, ScreenX, ScreenY, Scrollbars, Scroll, ScrollBy,
+ ScreenTop, ScreenLeft, AToB, BToA, FrameElement, GetComputedStyle,
+ ScrollTo, ScrollX, ScrollY, MoveBy, MoveTo, ResizeBy, ResizeTo, Self, _Window, Top, _Screen,
+ Image, Option, Alert, Confirm, Prompt, Open, SetTimeout, ClearTimeout,
+ XMLHttpRequest, XMLSerializer, DOMParser,
+ Focus, Blur, Close, SetInterval, ClearInterval, CaptureEvents, ReleaseEvents,
+ Print, AddEventListener, RemoveEventListener, SideBar,
+ ValueOf, ToString,
+ Onabort, Onblur,
+ Onchange, Onclick, Ondblclick, Ondragdrop, Onerror, Onfocus,
+ Onkeydown, Onkeypress, Onkeyup, Onload, Onmousedown, Onmousemove,
+ Onmouseout, Onmouseover, Onmouseup, Onmove, Onreset, Onresize,
+ Onselect, Onsubmit, Onunload,
+ MutationEventCtor, KeyboardEventCtor, EventExceptionCtor,
+ ElementCtor, DocumentCtor, HTMLDocumentCtor,
+ HTMLElementCtor, HTMLHtmlElementCtor, HTMLHeadElementCtor, HTMLLinkElementCtor,
+ HTMLTitleElementCtor, HTMLMetaElementCtor, HTMLBaseElementCtor, HTMLIsIndexElementCtor,
+ HTMLStyleElementCtor, HTMLBodyElementCtor, HTMLFormElementCtor, HTMLSelectElementCtor,
+ HTMLOptGroupElementCtor, HTMLOptionElementCtor, HTMLInputElementCtor, HTMLTextAreaElementCtor,
+ HTMLButtonElementCtor, HTMLLabelElementCtor, HTMLFieldSetElementCtor, HTMLLegendElementCtor,
+ HTMLUListElementCtor, HTMLOListElementCtor, HTMLDListElementCtor, HTMLDirectoryElementCtor,
+ HTMLMenuElementCtor, HTMLLIElementCtor, HTMLDivElementCtor, HTMLParagraphElementCtor,
+ HTMLHeadingElementCtor, HTMLBlockQuoteElementCtor, HTMLQuoteElementCtor, HTMLPreElementCtor,
+ HTMLBRElementCtor, HTMLBaseFontElementCtor, HTMLFontElementCtor, HTMLHRElementCtor, HTMLModElementCtor,
+ HTMLAnchorElementCtor, HTMLImageElementCtor, HTMLObjectElementCtor, HTMLParamElementCtor,
+ HTMLAppletElementCtor, HTMLMapElementCtor, HTMLAreaElementCtor, HTMLScriptElementCtor,
+ HTMLTableElementCtor, HTMLTableCaptionElementCtor, HTMLTableColElementCtor,
+ HTMLTableSectionElementCtor, HTMLTableRowElementCtor, HTMLTableCellElementCtor,
+ HTMLFrameSetElementCtor, HTMLLayerElementCtor, HTMLFrameElementCtor, HTMLIFrameElementCtor,
+ CSSStyleDeclarationCtor};
+ WindowQObject *winq;
+
+ void forgetSuppressedWindows();
+ void showSuppressedWindows();
+
+ protected:
+ enum DelayedActionId { NullAction, DelayedClose, DelayedGoHistory };
+
+ Value getListener(ExecState *exec, int eventId) const;
+ void setListener(ExecState *exec, int eventId, Value func);
+ private:
+ struct DelayedAction;
+ friend struct DelayedAction;
+
+ bool checkIsSafeScript( KParts::ReadOnlyPart* activePart ) const;
+
+ QGuardedPtr<khtml::ChildFrame> m_frame;
+ Screen *screen;
+ History *history;
+ External *external;
+ FrameArray *m_frames;
+ Location *loc;
+ DOM::Event *m_evt;
+
+ struct DelayedAction {
+ DelayedAction() : actionId(NullAction) {} // for QValueList
+ DelayedAction( DelayedActionId id, QVariant p = QVariant() ) : actionId(id), param(p) {}
+ DelayedActionId actionId;
+ QVariant param; // just in case
+ };
+ QValueList<DelayedAction> m_delayed;
+
+ struct SuppressedWindowInfo {
+ SuppressedWindowInfo() {} // for QValueList
+ SuppressedWindowInfo( KURL u, QString fr, QString fe ) : url(u), frameName(fr), features(fe) {}
+ KURL url;
+ QString frameName;
+ QString features;
+ };
+ QValueList<SuppressedWindowInfo> m_suppressedWindowInfo;
+ };
+
+ /**
+ * like QDateTime, but properly handles milliseconds
+ */
+ class DateTimeMS
+ {
+ QDate mDate;
+ QTime mTime;
+ public:
+ DateTimeMS addMSecs(int s) const;
+ bool operator >(const DateTimeMS &other) const;
+ bool operator >=(const DateTimeMS &other) const;
+
+ int msecsTo(const DateTimeMS &other) const;
+
+ static DateTimeMS now();
+ };
+
+ /**
+ * An action (either function or string) to be executed after a specified
+ * time interval, either once or repeatedly. Used for window.setTimeout()
+ * and window.setInterval()
+ */
+ class ScheduledAction {
+ public:
+ ScheduledAction(Object _func, List _args, DateTimeMS _nextTime, int _interval, bool _singleShot, int _timerId);
+ ScheduledAction(QString _code, DateTimeMS _nextTime, int _interval, bool _singleShot, int _timerId);
+ ~ScheduledAction();
+ bool execute(Window *window);
+ void mark();
+
+ ObjectImp *func;
+ List args;
+ QString code;
+ bool isFunction;
+ bool singleShot;
+
+ DateTimeMS nextTime;
+ int interval;
+ bool executing;
+ int timerId;
+ };
+
+ class KDE_EXPORT WindowQObject : public QObject {
+ Q_OBJECT
+ public:
+ WindowQObject(Window *w);
+ ~WindowQObject();
+ int installTimeout(const Identifier &handler, int t, bool singleShot);
+ int installTimeout(const Value &func, List args, int t, bool singleShot);
+ void clearTimeout(int timerId);
+ void mark();
+ bool hasTimers() const;
+ public slots:
+ void timeoutClose();
+ protected slots:
+ void parentDestroyed();
+ protected:
+ void timerEvent(QTimerEvent *e);
+ void setNextTimer();
+ private:
+ Window *parent;
+ QPtrList<ScheduledAction> scheduledActions;
+ int pausedTime;
+ int lastTimerId;
+ bool currentlyDispatching;
+ };
+
+ class Location : public ObjectImp {
+ public:
+ ~Location();
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
+ virtual Value toPrimitive(ExecState *exec, Type preferred) const;
+ virtual UString toString(ExecState *exec) const;
+ enum { Hash, Href, Hostname, Host, Pathname, Port, Protocol, Search, EqualEqual,
+ Assign, Replace, Reload, ToString };
+ KParts::ReadOnlyPart *part() const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ private:
+ friend class Window;
+ Location(khtml::ChildFrame *f);
+ QGuardedPtr<khtml::ChildFrame> m_frame;
+ };
+
+#ifdef Q_WS_QWS
+ class Konqueror : public ObjectImp {
+ friend class KonquerorFunc;
+ public:
+ Konqueror(KHTMLPart *p) : part(p) { }
+ virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+ virtual bool hasProperty(ExecState *exec, const Identifier &p) const;
+ virtual UString toString(ExecState *exec) const;
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ private:
+ KHTMLPart *part;
+ };
+#endif
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/testecma.cpp b/khtml/ecma/testecma.cpp
new file mode 100644
index 000000000..44cd7ecb0
--- /dev/null
+++ b/khtml/ecma/testecma.cpp
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * An interactive interpreter to test the ECMA Script language bindings
+ * for the DOM of KHTML.
+ * The 'document' property is preset to an instance of Document and serves
+ * as an entrypoint.
+ *
+ * Example session:
+ *
+ * KJS> text = document.createTextNode('foo');
+ * KJS> document.appendChild(text);
+ * KJS> debug(document.firstChild.nodeValue);
+ * ---> foo
+ */
+
+#include <stdio.h>
+#include <kjs/object.h>
+#include <kjs/interpreter.h>
+#include "dom/dom_doc.h"
+#include "dom/dom_string.h"
+#include "ecma/kjs_dom.h"
+
+
+using namespace KJS;
+
+int main(int, char **)
+{
+ KJScript kjs;
+ kjs.enableDebug();
+ DOM::Document doc;
+
+ DOMDocument *dd = new DOMDocument(&doc);
+ Global::current().put("document", KJSO(dd));
+
+ printf("Entering interactive mode.\n"
+ "You may access the DOM via the 'document' property.\n"
+ "Use debug() to print to the console. Press C-d or C-c to exit.\n\n");
+
+ char buffer[1000];
+ FILE *in = fdopen(0, "r");
+
+ while (1) {
+ printf("KJS> ");
+ if (!fgets(buffer, 999, in))
+ break;
+ kjs.evaluate(buffer);
+ }
+ printf("\n");
+}
diff --git a/khtml/ecma/xmlhttprequest.cpp b/khtml/ecma/xmlhttprequest.cpp
new file mode 100644
index 000000000..de77f3d7e
--- /dev/null
+++ b/khtml/ecma/xmlhttprequest.cpp
@@ -0,0 +1,810 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xmlhttprequest.h"
+#include "xmlhttprequest.lut.h"
+#include "kjs_window.h"
+#include "kjs_events.h"
+
+#include "dom/dom_doc.h"
+#include "dom/dom_exception.h"
+#include "dom/dom_string.h"
+#include "misc/loader.h"
+#include "html/html_documentimpl.h"
+#include "xml/dom2_eventsimpl.h"
+
+#include "khtml_part.h"
+#include "khtmlview.h"
+
+#include <kio/scheduler.h>
+#include <kio/job.h>
+#include <qobject.h>
+#include <kdebug.h>
+
+#ifdef APPLE_CHANGES
+#include "KWQLoader.h"
+#else
+#include <kio/netaccess.h>
+using KIO::NetAccess;
+#endif
+
+#define BANNED_HTTP_HEADERS "authorization,proxy-authorization,"\
+ "content-length,host,connect,copy,move,"\
+ "delete,head,trace,put,propfind,proppatch,"\
+ "mkcol,lock,unlock,options,via,"\
+ "accept-charset,accept-encoding,expect,date,"\
+ "keep-alive,te,trailer,"\
+ "transfer-encoding,upgrade"
+
+using khtml::Decoder;
+
+namespace KJS {
+
+////////////////////// XMLHttpRequest Object ////////////////////////
+
+/* Source for XMLHttpRequestProtoTable.
+@begin XMLHttpRequestProtoTable 7
+ abort XMLHttpRequest::Abort DontDelete|Function 0
+ getAllResponseHeaders XMLHttpRequest::GetAllResponseHeaders DontDelete|Function 0
+ getResponseHeader XMLHttpRequest::GetResponseHeader DontDelete|Function 1
+ open XMLHttpRequest::Open DontDelete|Function 5
+ overrideMimeType XMLHttpRequest::OverrideMIMEType DontDelete|Function 1
+ send XMLHttpRequest::Send DontDelete|Function 1
+ setRequestHeader XMLHttpRequest::SetRequestHeader DontDelete|Function 2
+@end
+*/
+KJS_DEFINE_PROTOTYPE(XMLHttpRequestProto)
+IMPLEMENT_PROTOFUNC_DOM(XMLHttpRequestProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("XMLHttpRequest", XMLHttpRequestProto,XMLHttpRequestProtoFunc)
+
+
+XMLHttpRequestQObject::XMLHttpRequestQObject(XMLHttpRequest *_jsObject)
+{
+ jsObject = _jsObject;
+}
+
+#ifdef APPLE_CHANGES
+void XMLHttpRequestQObject::slotData( KIO::Job* job, const char *data, int size )
+{
+ jsObject->slotData(job, data, size);
+}
+#else
+void XMLHttpRequestQObject::slotData( KIO::Job* job, const QByteArray &data )
+{
+ jsObject->slotData(job, data);
+}
+#endif
+
+void XMLHttpRequestQObject::slotFinished( KIO::Job* job )
+{
+ jsObject->slotFinished(job);
+}
+
+void XMLHttpRequestQObject::slotRedirection( KIO::Job* job, const KURL& url)
+{
+ jsObject->slotRedirection( job, url );
+}
+
+XMLHttpRequestConstructorImp::XMLHttpRequestConstructorImp(ExecState *, const DOM::Document &d)
+ : ObjectImp(), doc(d)
+{
+}
+
+bool XMLHttpRequestConstructorImp::implementsConstruct() const
+{
+ return true;
+}
+
+Object XMLHttpRequestConstructorImp::construct(ExecState *exec, const List &)
+{
+ return Object(new XMLHttpRequest(exec, doc));
+}
+
+const ClassInfo XMLHttpRequest::info = { "XMLHttpRequest", 0, &XMLHttpRequestTable, 0 };
+
+
+/* Source for XMLHttpRequestTable.
+@begin XMLHttpRequestTable 7
+ readyState XMLHttpRequest::ReadyState DontDelete|ReadOnly
+ responseText XMLHttpRequest::ResponseText DontDelete|ReadOnly
+ responseXML XMLHttpRequest::ResponseXML DontDelete|ReadOnly
+ status XMLHttpRequest::Status DontDelete|ReadOnly
+ statusText XMLHttpRequest::StatusText DontDelete|ReadOnly
+ onreadystatechange XMLHttpRequest::Onreadystatechange DontDelete
+ onload XMLHttpRequest::Onload DontDelete
+@end
+*/
+
+Value XMLHttpRequest::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+ return DOMObjectLookupGetValue<XMLHttpRequest,DOMObject>(exec, propertyName, &XMLHttpRequestTable, this);
+}
+
+Value XMLHttpRequest::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case ReadyState:
+ return Number(state);
+ case ResponseText:
+ return getString(DOM::DOMString(response));
+ case ResponseXML:
+ if (state != Completed) {
+ return Null();
+ }
+ if (!createdDocument) {
+ QString mimeType = "text/xml";
+
+ if (!m_mimeTypeOverride.isEmpty()) {
+ mimeType = m_mimeTypeOverride;
+ } else {
+ Value header = getResponseHeader("Content-Type");
+ if (header.type() != UndefinedType) {
+ mimeType = QStringList::split(";", header.toString(exec).qstring())[0].stripWhiteSpace();
+ }
+ }
+
+ if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "application/xhtml+xml") {
+ responseXML = DOM::Document(doc->implementation()->createDocument());
+
+ DOM::DocumentImpl *docImpl = static_cast<DOM::DocumentImpl *>(responseXML.handle());
+
+ docImpl->open();
+ docImpl->write(response);
+ docImpl->finishParsing();
+ docImpl->close();
+
+ typeIsXML = true;
+ } else {
+ typeIsXML = false;
+ }
+ createdDocument = true;
+ }
+
+ if (!typeIsXML) {
+ return Undefined();
+ }
+
+ return getDOMNode(exec,responseXML);
+ case Status:
+ return getStatus();
+ case StatusText:
+ return getStatusText();
+ case Onreadystatechange:
+ if (onReadyStateChangeListener && onReadyStateChangeListener->listenerObjImp()) {
+ return onReadyStateChangeListener->listenerObj();
+ } else {
+ return Null();
+ }
+ case Onload:
+ if (onLoadListener && onLoadListener->listenerObjImp()) {
+ return onLoadListener->listenerObj();
+ } else {
+ return Null();
+ }
+ default:
+ kdWarning() << "XMLHttpRequest::getValueProperty unhandled token " << token << endl;
+ return Value();
+ }
+}
+
+void XMLHttpRequest::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+ DOMObjectLookupPut<XMLHttpRequest,DOMObject>(exec, propertyName, value, attr, &XMLHttpRequestTable, this );
+}
+
+void XMLHttpRequest::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
+{
+ JSEventListener* newListener;
+ switch(token) {
+ case Onreadystatechange:
+ newListener = Window::retrieveActive(exec)->getJSEventListener(value, true);
+ if (newListener != onReadyStateChangeListener) {
+ if (onReadyStateChangeListener) onReadyStateChangeListener->deref();
+ onReadyStateChangeListener = newListener;
+ if (onReadyStateChangeListener) onReadyStateChangeListener->ref();
+ }
+ break;
+ case Onload:
+ newListener = Window::retrieveActive(exec)->getJSEventListener(value, true);
+ if (newListener != onLoadListener) {
+ if (onLoadListener) onLoadListener->deref();
+ onLoadListener = newListener;
+ if (onLoadListener) onLoadListener->ref();
+ }
+ break;
+ default:
+ kdWarning() << "XMLHttpRequest::putValue unhandled token " << token << endl;
+ }
+}
+
+XMLHttpRequest::XMLHttpRequest(ExecState *exec, const DOM::Document &d)
+ : DOMObject(XMLHttpRequestProto::self(exec)),
+ qObject(new XMLHttpRequestQObject(this)),
+ doc(static_cast<DOM::DocumentImpl*>(d.handle())),
+ async(true),
+ contentType(QString::null),
+ job(0),
+ state(Uninitialized),
+ onReadyStateChangeListener(0),
+ onLoadListener(0),
+ decoder(0),
+ createdDocument(false),
+ aborted(false)
+{
+}
+
+XMLHttpRequest::~XMLHttpRequest()
+{
+ if (onReadyStateChangeListener)
+ onReadyStateChangeListener->deref();
+ if (onLoadListener)
+ onLoadListener->deref();
+ delete qObject;
+ qObject = 0;
+ delete decoder;
+ decoder = 0;
+}
+
+void XMLHttpRequest::changeState(XMLHttpRequestState newState)
+{
+ if (state != newState) {
+ state = newState;
+
+ ref();
+
+ if (onReadyStateChangeListener != 0 && doc->view() && doc->view()->part()) {
+ DOM::Event ev = doc->view()->part()->document().createEvent("HTMLEvents");
+ ev.initEvent("readystatechange", true, true);
+ onReadyStateChangeListener->handleEvent(ev);
+ }
+
+ if (state == Completed && onLoadListener != 0 && doc->view() && doc->view()->part()) {
+ DOM::Event ev = doc->view()->part()->document().createEvent("HTMLEvents");
+ ev.initEvent("load", true, true);
+ onLoadListener->handleEvent(ev);
+ }
+
+ deref();
+ }
+}
+
+bool XMLHttpRequest::urlMatchesDocumentDomain(const KURL& _url) const
+{
+ // No need to do work if _url is not valid...
+ if (!_url.isValid())
+ return false;
+
+ KURL documentURL(doc->URL());
+
+ // a local file can load anything
+ if (documentURL.protocol().lower() == "file") {
+ return true;
+ }
+
+ // but a remote document can only load from the same port on the server
+ if (documentURL.protocol().lower() == _url.protocol().lower() &&
+ documentURL.host().lower() == _url.host().lower() &&
+ documentURL.port() == _url.port()) {
+ return true;
+ }
+
+ return false;
+}
+
+void XMLHttpRequest::open(const QString& _method, const KURL& _url, bool _async)
+{
+ abort();
+ aborted = false;
+
+ // clear stuff from possible previous load
+ requestHeaders.clear();
+ responseHeaders = QString();
+ response = QString();
+ createdDocument = false;
+ responseXML = DOM::Document();
+
+ changeState(Uninitialized);
+
+ if (aborted) {
+ return;
+ }
+
+ if (!urlMatchesDocumentDomain(_url)) {
+ return;
+ }
+
+
+ method = _method.lower();
+ url = _url;
+ async = _async;
+
+ changeState(Loading);
+}
+
+void XMLHttpRequest::send(const QString& _body)
+{
+ aborted = false;
+
+ if (method == "post") {
+ QString protocol = url.protocol().lower();
+
+ // Abondon the request when the protocol is other than "http",
+ // instead of blindly changing it to a "get" request.
+ if (!protocol.startsWith("http") && !protocol.startsWith("webdav"))
+ {
+ abort();
+ return;
+ }
+
+ // FIXME: determine post encoding correctly by looking in headers
+ // for charset.
+ QByteArray buf;
+ QCString str = _body.utf8();
+ buf.duplicate(str.data(), str.size() - 1);
+
+ job = KIO::http_post( url, buf, false );
+ if(contentType.isNull())
+ job->addMetaData( "content-type", "Content-type: text/plain" );
+ else
+ job->addMetaData( "content-type", contentType );
+ }
+ else {
+ job = KIO::get( url, false, false );
+ }
+
+ if (!requestHeaders.isEmpty()) {
+ QString rh;
+ QMap<QString, QString>::ConstIterator begin = requestHeaders.begin();
+ QMap<QString, QString>::ConstIterator end = requestHeaders.end();
+ for (QMap<QString, QString>::ConstIterator i = begin; i != end; ++i) {
+ QString key = i.key();
+ QString value = i.data();
+ if (key == "accept") {
+ // The HTTP KIO slave supports an override this way
+ job->addMetaData("accept", value);
+ } else {
+ if (i != begin)
+ rh += "\r\n";
+ rh += key + ": " + value;
+ }
+ }
+
+ job->addMetaData("customHTTPHeader", rh);
+ }
+
+ job->addMetaData("PropagateHttpHeader", "true");
+
+ // Set the default referrer if one is not already supplied
+ // through setRequestHeader. NOTE: the user can still disable
+ // this feature at the protocol level (kio_http).
+ // ### does find() ever succeed? the headers are stored in lower case!
+ if (requestHeaders.find("Referer") == requestHeaders.end()) {
+ KURL documentURL(doc->URL());
+ documentURL.setPass(QString::null);
+ documentURL.setUser(QString::null);
+ job->addMetaData("referrer", documentURL.url());
+ // kdDebug() << "Adding referrer: " << documentURL << endl;
+ }
+
+ if (!async) {
+ QByteArray data;
+ KURL finalURL;
+ QString headers;
+
+#ifdef APPLE_CHANGES
+ data = KWQServeSynchronousRequest(khtml::Cache::loader(), doc->docLoader(), job, finalURL, headers);
+#else
+ QMap<QString, QString> metaData;
+ if ( NetAccess::synchronousRun( job, 0, &data, &finalURL, &metaData ) ) {
+ headers = metaData[ "HTTP-Headers" ];
+ }
+#endif
+ job = 0;
+ processSyncLoadResults(data, finalURL, headers);
+ return;
+ }
+
+ qObject->connect( job, SIGNAL( result( KIO::Job* ) ),
+ SLOT( slotFinished( KIO::Job* ) ) );
+#ifdef APPLE_CHANGES
+ qObject->connect( job, SIGNAL( data( KIO::Job*, const char*, int ) ),
+ SLOT( slotData( KIO::Job*, const char*, int ) ) );
+#else
+ qObject->connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
+ SLOT( slotData( KIO::Job*, const QByteArray& ) ) );
+#endif
+ qObject->connect( job, SIGNAL(redirection(KIO::Job*, const KURL& ) ),
+ SLOT( slotRedirection(KIO::Job*, const KURL&) ) );
+
+#ifdef APPLE_CHANGES
+ KWQServeRequest(khtml::Cache::loader(), doc->docLoader(), job);
+#else
+ KIO::Scheduler::scheduleJob( job );
+#endif
+}
+
+void XMLHttpRequest::abort()
+{
+ if (job) {
+ job->kill();
+ job = 0;
+ }
+ delete decoder;
+ decoder = 0;
+ aborted = true;
+}
+
+void XMLHttpRequest::overrideMIMEType(const QString& override)
+{
+ m_mimeTypeOverride = override;
+}
+
+void XMLHttpRequest::setRequestHeader(const QString& _name, const QString &value)
+{
+ QString name = _name.lower().stripWhiteSpace();
+
+ // Content-type needs to be set seperately from the other headers
+ if(name == "content-type") {
+ contentType = "Content-type: " + value;
+ return;
+ }
+
+ // Sanitize the referrer header to protect against spoofing...
+ if(name == "referer") {
+ KURL referrerURL(value);
+ if (urlMatchesDocumentDomain(referrerURL))
+ requestHeaders[name] = referrerURL.url();
+ return;
+ }
+
+ // Sanitize the request headers below and handle them as if they are
+ // calls to open. Otherwise, we will end up ignoring them all together!
+ // TODO: Do something about "put" which kio_http sort of supports and
+ // the webDAV headers such as PROPFIND etc...
+ if (name == "get" || name == "post") {
+ KURL reqURL (doc->URL(), value.stripWhiteSpace());
+ open(name, reqURL, async);
+ return;
+ }
+
+ // Reject all banned headers. See BANNED_HTTP_HEADERS above.
+ // kdDebug() << "Banned HTTP Headers: " << BANNED_HTTP_HEADERS << endl;
+ QStringList bannedHeaders = QStringList::split(',',
+ QString::fromLatin1(BANNED_HTTP_HEADERS));
+
+ if (bannedHeaders.contains(name))
+ return; // Denied
+
+ requestHeaders[name] = value.stripWhiteSpace();
+}
+
+Value XMLHttpRequest::getAllResponseHeaders() const
+{
+ if (responseHeaders.isEmpty()) {
+ return Undefined();
+ }
+
+ int endOfLine = responseHeaders.find("\n");
+
+ if (endOfLine == -1) {
+ return Undefined();
+ }
+
+ return String(responseHeaders.mid(endOfLine + 1) + "\n");
+}
+
+Value XMLHttpRequest::getResponseHeader(const QString& name) const
+{
+ if (responseHeaders.isEmpty()) {
+ return Undefined();
+ }
+
+ QRegExp headerLinePattern(name + ":", false);
+
+ int matchLength;
+ int headerLinePos = headerLinePattern.search(responseHeaders, 0);
+ matchLength = headerLinePattern.matchedLength();
+ while (headerLinePos != -1) {
+ if (headerLinePos == 0 || responseHeaders[headerLinePos-1] == '\n') {
+ break;
+ }
+
+ headerLinePos = headerLinePattern.search(responseHeaders, headerLinePos + 1);
+ matchLength = headerLinePattern.matchedLength();
+ }
+
+
+ if (headerLinePos == -1) {
+ return Undefined();
+ }
+
+ int endOfLine = responseHeaders.find("\n", headerLinePos + matchLength);
+
+ return String(responseHeaders.mid(headerLinePos + matchLength, endOfLine - (headerLinePos + matchLength)).stripWhiteSpace());
+}
+
+static Value httpStatus(const QString& response, bool textStatus = false)
+{
+ if (response.isEmpty()) {
+ return Undefined();
+ }
+
+ int endOfLine = response.find("\n");
+ QString firstLine = (endOfLine == -1) ? response : response.left(endOfLine);
+ int codeStart = firstLine.find(" ");
+ int codeEnd = firstLine.find(" ", codeStart + 1);
+
+ if (codeStart == -1 || codeEnd == -1) {
+ return Undefined();
+ }
+
+ if (textStatus) {
+ QString statusText = firstLine.mid(codeEnd + 1, endOfLine - (codeEnd + 1)).stripWhiteSpace();
+ return String(statusText);
+ }
+
+ QString number = firstLine.mid(codeStart + 1, codeEnd - (codeStart + 1));
+
+ bool ok = false;
+ int code = number.toInt(&ok);
+ if (!ok) {
+ return Undefined();
+ }
+
+ return Number(code);
+}
+
+Value XMLHttpRequest::getStatus() const
+{
+ return httpStatus(responseHeaders);
+}
+
+Value XMLHttpRequest::getStatusText() const
+{
+ return httpStatus(responseHeaders, true);
+}
+
+void XMLHttpRequest::processSyncLoadResults(const QByteArray &data, const KURL &finalURL, const QString &headers)
+{
+ if (!urlMatchesDocumentDomain(finalURL)) {
+ abort();
+ return;
+ }
+
+ responseHeaders = headers;
+ changeState(Loaded);
+ if (aborted) {
+ return;
+ }
+
+#ifdef APPLE_CHANGES
+ const char *bytes = (const char *)data.data();
+ int len = (int)data.size();
+
+ slotData(0, bytes, len);
+#else
+ slotData(0, data);
+#endif
+
+ if (aborted) {
+ return;
+ }
+
+ slotFinished(0);
+}
+
+void XMLHttpRequest::slotFinished(KIO::Job *)
+{
+ if (decoder) {
+ response += decoder->flush();
+ }
+
+ // make sure to forget about the job before emitting completed,
+ // since changeState triggers JS code, which might e.g. call abort.
+ job = 0;
+ changeState(Completed);
+
+ delete decoder;
+ decoder = 0;
+}
+
+void XMLHttpRequest::slotRedirection(KIO::Job*, const KURL& url)
+{
+ if (!urlMatchesDocumentDomain(url)) {
+ abort();
+ }
+}
+
+#ifdef APPLE_CHANGES
+void XMLHttpRequest::slotData( KIO::Job*, const char *data, int len )
+#else
+void XMLHttpRequest::slotData(KIO::Job*, const QByteArray &_data)
+#endif
+{
+ if (state < Loaded ) {
+ responseHeaders = job->queryMetaData("HTTP-Headers");
+
+ // NOTE: Replace a 304 response with a 200! Both IE and Mozilla do this.
+ // Problem first reported through bug# 110272.
+ int codeStart = responseHeaders.find("304");
+ if ( codeStart != -1) {
+ int codeEnd = responseHeaders.find("\n", codeStart+3);
+ if (codeEnd != -1)
+ responseHeaders.replace(codeStart, (codeEnd-codeStart), "200 OK");
+ }
+
+ changeState(Loaded);
+ }
+
+#ifndef APPLE_CHANGES
+ const char *data = (const char *)_data.data();
+ int len = (int)_data.size();
+#endif
+
+ if ( decoder == NULL ) {
+ int pos = responseHeaders.find("content-type:", 0, false);
+
+ if ( pos > -1 ) {
+ pos += 13;
+ int index = responseHeaders.find('\n', pos);
+ QString type = responseHeaders.mid(pos, (index-pos));
+ index = type.find (';');
+ if (index > -1)
+ encoding = type.mid( index+1 ).remove(QRegExp("charset[ ]*=[ ]*", false)).stripWhiteSpace();
+ }
+
+ decoder = new Decoder;
+ if (!encoding.isNull())
+ decoder->setEncoding(encoding.latin1(), Decoder::EncodingFromHTTPHeader);
+ else {
+ // Per section 2 of W3C working draft spec, fall back to "UTF-8".
+ decoder->setEncoding("UTF-8", Decoder::DefaultEncoding);
+ }
+ }
+ if (len == 0)
+ return;
+
+ if (len == -1)
+ len = strlen(data);
+
+ QString decoded = decoder->decode(data, len);
+
+ response += decoded;
+
+ if (!aborted) {
+ changeState(Interactive);
+ }
+}
+
+Value XMLHttpRequestProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ if (!thisObj.inherits(&XMLHttpRequest::info)) {
+ Object err = Error::create(exec,TypeError);
+ exec->setException(err);
+ return err;
+ }
+
+ XMLHttpRequest *request = static_cast<XMLHttpRequest *>(thisObj.imp());
+ switch (id) {
+ case XMLHttpRequest::Abort:
+ request->abort();
+ return Undefined();
+ case XMLHttpRequest::GetAllResponseHeaders:
+ if (args.size() != 0) {
+ return Undefined();
+ }
+
+ return request->getAllResponseHeaders();
+ case XMLHttpRequest::GetResponseHeader:
+ if (args.size() != 1) {
+ return Undefined();
+ }
+
+ return request->getResponseHeader(args[0].toString(exec).qstring());
+ case XMLHttpRequest::Open:
+ {
+ if (args.size() < 2 || args.size() > 5) {
+ return Undefined();
+ }
+
+ QString method = args[0].toString(exec).qstring();
+ KHTMLPart *part = ::qt_cast<KHTMLPart *>(Window::retrieveActive(exec)->part());
+ if (!part)
+ return Undefined();
+ KURL url = KURL(part->document().completeURL(args[1].toString(exec).qstring()).string());
+
+ bool async = true;
+ if (args.size() >= 3) {
+ async = args[2].toBoolean(exec);
+ }
+
+ if (args.size() >= 4) {
+ url.setUser(args[3].toString(exec).qstring());
+ }
+
+ if (args.size() >= 5) {
+ url.setPass(args[4].toString(exec).qstring());
+ }
+
+ request->open(method, url, async);
+
+ return Undefined();
+ }
+ case XMLHttpRequest::Send:
+ {
+ if (args.size() > 1) {
+ return Undefined();
+ }
+
+ if (request->state != Loading) {
+ return Undefined();
+ }
+
+ QString body;
+ if (args.size() >= 1) {
+ Object obj = Object::dynamicCast(args[0]);
+ if (obj.isValid() && obj.inherits(&DOMDocument::info)) {
+ DOM::Node docNode = static_cast<KJS::DOMDocument *>(obj.imp())->toNode();
+ DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl *>(docNode.handle());
+
+ try {
+ body = doc->toString().string();
+ // FIXME: also need to set content type, including encoding!
+
+ } catch(DOM::DOMException& e) {
+ Object err = Error::create(exec, GeneralError, "Exception serializing document");
+ exec->setException(err);
+ }
+ } else {
+ body = args[0].toString(exec).qstring();
+ }
+ }
+
+ request->send(body);
+
+ return Undefined();
+ }
+ case XMLHttpRequest::SetRequestHeader:
+ if (args.size() != 2) {
+ return Undefined();
+ }
+
+ request->setRequestHeader(args[0].toString(exec).qstring(), args[1].toString(exec).qstring());
+
+ return Undefined();
+
+ case XMLHttpRequest::OverrideMIMEType:
+ if (args.size() < 1) {
+ Object err = Error::create(exec, SyntaxError, "Not enough arguments");
+ exec->setException(err);
+ return err;
+ }
+
+ request->overrideMIMEType(args[0].toString(exec).qstring());
+ return Undefined();
+ }
+
+ return Undefined();
+}
+
+} // end namespace
+
+
+#include "xmlhttprequest.moc"
diff --git a/khtml/ecma/xmlhttprequest.h b/khtml/ecma/xmlhttprequest.h
new file mode 100644
index 000000000..49582a905
--- /dev/null
+++ b/khtml/ecma/xmlhttprequest.h
@@ -0,0 +1,142 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _XMLHTTPREQUEST_H_
+#define _XMLHTTPREQUEST_H_
+
+#include "ecma/kjs_binding.h"
+#include "ecma/kjs_dom.h"
+#include "misc/decoder.h"
+#include "kio/jobclasses.h"
+
+namespace KJS {
+
+ class JSEventListener;
+ class XMLHttpRequestQObject;
+
+ // these exact numeric values are important because JS expects them
+ enum XMLHttpRequestState {
+ Uninitialized = 0,
+ Loading = 1,
+ Loaded = 2,
+ Interactive = 3,
+ Completed = 4
+ };
+
+ class XMLHttpRequestConstructorImp : public ObjectImp {
+ public:
+ XMLHttpRequestConstructorImp(ExecState *exec, const DOM::Document &d);
+ virtual bool implementsConstruct() const;
+ virtual Object construct(ExecState *exec, const List &args);
+ private:
+ DOM::Document doc;
+ };
+
+ class XMLHttpRequest : public DOMObject {
+ public:
+ XMLHttpRequest(ExecState *, const DOM::Document &d);
+ ~XMLHttpRequest();
+ virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+ Value getValueProperty(ExecState *exec, int token) const;
+ virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+ void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
+ virtual bool toBoolean(ExecState *) const { return true; }
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { Onload, Onreadystatechange, ReadyState, ResponseText, ResponseXML, Status, StatusText, Abort,
+ GetAllResponseHeaders, GetResponseHeader, Open, Send, SetRequestHeader,
+ OverrideMIMEType };
+
+ private:
+ friend class XMLHttpRequestProtoFunc;
+ friend class XMLHttpRequestQObject;
+
+ Value getStatusText() const;
+ Value getStatus() const;
+ bool urlMatchesDocumentDomain(const KURL&) const;
+
+ XMLHttpRequestQObject *qObject;
+
+#ifdef APPLE_CHANGES
+ void slotData( KIO::Job* job, const char *data, int size );
+#else
+ void slotData( KIO::Job* job, const QByteArray &data );
+#endif
+ void slotFinished( KIO::Job* );
+ void slotRedirection( KIO::Job*, const KURL& );
+
+ void processSyncLoadResults(const QByteArray &data, const KURL &finalURL, const QString &headers);
+
+ void open(const QString& _method, const KURL& _url, bool _async);
+ void send(const QString& _body);
+ void abort();
+ void setRequestHeader(const QString& name, const QString &value);
+ void overrideMIMEType(const QString& override);
+ Value getAllResponseHeaders() const;
+ Value getResponseHeader(const QString& name) const;
+
+ void changeState(XMLHttpRequestState newState);
+
+ QGuardedPtr<DOM::DocumentImpl> doc;
+
+ KURL url;
+ QString method;
+ bool async;
+ QMap<QString,QString> requestHeaders;
+ QString m_mimeTypeOverride;
+ QString contentType;
+
+ KIO::TransferJob * job;
+
+ XMLHttpRequestState state;
+ JSEventListener *onReadyStateChangeListener;
+ JSEventListener *onLoadListener;
+
+ khtml::Decoder *decoder;
+ QString encoding;
+ QString responseHeaders;
+
+ QString response;
+ mutable bool createdDocument;
+ mutable bool typeIsXML;
+ mutable DOM::Document responseXML;
+
+ bool aborted;
+ };
+
+
+ class XMLHttpRequestQObject : public QObject {
+ Q_OBJECT
+
+ public:
+ XMLHttpRequestQObject(XMLHttpRequest *_jsObject);
+
+ public slots:
+ void slotData( KIO::Job* job, const QByteArray &data );
+ void slotFinished( KIO::Job* job );
+ void slotRedirection( KIO::Job* job, const KURL& url);
+
+ private:
+ XMLHttpRequest *jsObject;
+ };
+
+} // namespace
+
+#endif
diff --git a/khtml/ecma/xmlserializer.cpp b/khtml/ecma/xmlserializer.cpp
new file mode 100644
index 000000000..6abcfe77f
--- /dev/null
+++ b/khtml/ecma/xmlserializer.cpp
@@ -0,0 +1,109 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xmlserializer.h"
+#include "xmlserializer.lut.h"
+
+#include "dom/dom_exception.h"
+#include "dom/dom_doc.h"
+#include "xml/dom_docimpl.h"
+
+#include <kdebug.h>
+
+
+////////////////////// XMLSerializer Object ////////////////////////
+
+/* Source for XMLSerializerProtoTable.
+@begin XMLSerializerProtoTable 1
+ serializeToString XMLSerializer::SerializeToString DontDelete|Function 1
+@end
+*/
+
+namespace KJS {
+
+KJS_DEFINE_PROTOTYPE(XMLSerializerProto)
+IMPLEMENT_PROTOFUNC_DOM(XMLSerializerProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("XMLSerializer", XMLSerializerProto, XMLSerializerProtoFunc)
+
+XMLSerializerConstructorImp::XMLSerializerConstructorImp(ExecState *)
+ : ObjectImp()
+{
+}
+
+bool XMLSerializerConstructorImp::implementsConstruct() const
+{
+ return true;
+}
+
+Object XMLSerializerConstructorImp::construct(ExecState *exec, const List &)
+{
+ return Object(new XMLSerializer(exec));
+}
+
+const ClassInfo XMLSerializer::info = { "XMLSerializer", 0, 0, 0 };
+
+XMLSerializer::XMLSerializer(ExecState *exec)
+ : DOMObject(XMLSerializerProto::self(exec))
+{
+}
+
+Value XMLSerializerProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+ if (!thisObj.inherits(&XMLSerializer::info)) {
+ Object err = Error::create(exec,TypeError);
+ exec->setException(err);
+ return err;
+ }
+
+ switch (id) {
+ case XMLSerializer::SerializeToString:
+ {
+ if (args.size() != 1) {
+ return Undefined();
+ }
+
+ if (!args[0].toObject(exec).inherits(&DOMNode::info)) {
+ return Undefined();
+ }
+
+ DOM::NodeImpl *node = static_cast<DOM::NodeImpl *>(static_cast<KJS::DOMNode *>(args[0].toObject(exec).imp())->toNode().handle());
+
+ if (!node) {
+ return Undefined();
+ }
+
+ QString body;
+
+ try {
+ body = node->toString().string();
+ } catch(DOM::DOMException& e) {
+ Object err = Error::create(exec, GeneralError, "Exception serializing document");
+ exec->setException(err);
+ return err;
+ }
+
+ return getString(body);
+ }
+ }
+
+ return Undefined();
+}
+
+} // end namespace
diff --git a/khtml/ecma/xmlserializer.h b/khtml/ecma/xmlserializer.h
new file mode 100644
index 000000000..629d09afe
--- /dev/null
+++ b/khtml/ecma/xmlserializer.h
@@ -0,0 +1,54 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _XMLSERIALIZER_H_
+#define _XMLSERIALIZER_H_
+
+#include "ecma/kjs_binding.h"
+#include "ecma/kjs_dom.h"
+#include "misc/decoder.h"
+#include "kio/jobclasses.h"
+
+namespace KJS {
+
+ class JSEventListener;
+
+ class XMLSerializerConstructorImp : public ObjectImp {
+ public:
+ XMLSerializerConstructorImp(ExecState *);
+ virtual bool implementsConstruct() const;
+ virtual Object construct(ExecState *exec, const List &args);
+ };
+
+ class XMLSerializer : public DOMObject {
+ public:
+ XMLSerializer(ExecState *);
+ virtual bool toBoolean(ExecState *) const { return true; }
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ enum { SerializeToString };
+
+ private:
+ friend class XMLSerializerProtoFunc;
+ };
+
+} // namespace
+
+#endif