On Mon, 2012-01-23 at 10:45 +0100, m0n0 wrote:
> Hello Steven,
> 
> >as a weekend project I integrated spidermonkey's javascript
> >functionality into netsurf;
> 
>  nice to see someone is picking up on that. :)

Indeed, thanks. I've attached a diff of the changes against a vanilla
2.8 source tree.

However, I'm concerned that the rest of the core code is not yet at the
point where adding JavaScript support is sensible. Certainly, there is
still a great deal of work required before any of the Document object
becomes possible.

>  I think there needs to be some auto-generator code / structures for the
>  Javascript to Browser/DOM glue. At least the getters for DOM attributes
>  and styles can probably generated by an script? And the generator must 
>  not
>  disturb of development of custom JavaScript glue. Maybe the libcss 
>  autogenerator
>  script is an good example on how to implement such thing?

Even Vincent will agree that it's not really a good example of how to do
things. :) It does, however, work for that specific scenario --
JavaScript bindings are more expressive and thus would require more
work.


J.
diff -urN netsurf-2.8/netsurf-2.8/css/select.c netsurf-2.8-js/netsurf-2.8/css/select.c
--- netsurf-2.8/netsurf-2.8/css/select.c	2011-08-31 22:12:57.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/css/select.c	2012-01-22 00:52:00.000000000 +0000
@@ -31,6 +31,7 @@
 #include "utils/log.h"
 #include "utils/url.h"
 #include "utils/utils.h"
+#include "js/js.h"
 
 static css_error node_name(void *pw, void *node, css_qname *qname);
 static css_error node_classes(void *pw, void *node,
diff -urN netsurf-2.8/netsurf-2.8/js/document.c netsurf-2.8-js/netsurf-2.8/js/document.c
--- netsurf-2.8/netsurf-2.8/js/document.c	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/document.c	2012-01-21 23:09:48.000000000 +0000
@@ -0,0 +1,46 @@
+#include <js/jsapi.h>
+#include "js/js.h"
+#include "render/html_internal.h"
+
+
+#ifdef USE_JS
+
+static JSBool document_getPropertyURL(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+	struct html_content *c;
+
+	c = JS_GetContextPrivate(cx);
+
+	*vp = STRING_TO_JSVAL(JS_NewStringCopyN(cx, c->base_url, strlen(c->base_url)));
+
+	return JS_TRUE;
+}
+
+
+static JSClass document_class =
+{
+        "document", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+
+static JSPropertySpec document_props[] = {
+    {"URL",       1,       JSPROP_READONLY, document_getPropertyURL, NULL},
+    {0}
+};
+
+static JSFunctionSpec document_functions[] = {
+//        JS_FS("open",   js_document_open,   1, 0),
+        JS_FS_END
+};
+
+extern void define_document(JSContext *cx)
+{
+	JSObject *obj;
+
+        obj = JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, &document_class, NULL, 0, NULL, document_functions, NULL, NULL);
+	JS_DefineProperties(cx, obj, document_props);
+}
+
+#endif
+
diff -urN netsurf-2.8/netsurf-2.8/js/document.h netsurf-2.8-js/netsurf-2.8/js/document.h
--- netsurf-2.8/netsurf-2.8/js/document.h	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/document.h	2012-01-21 18:38:38.000000000 +0000
@@ -0,0 +1,6 @@
+
+#ifdef USE_JS
+
+void define_document(JSContext *cx);
+
+#endif
diff -urN netsurf-2.8/netsurf-2.8/js/js.c netsurf-2.8-js/netsurf-2.8/js/js.c
--- netsurf-2.8/netsurf-2.8/js/js.c	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/js.c	2012-01-22 07:17:46.000000000 +0000
@@ -0,0 +1,163 @@
+#include "js/js.h"
+#include "render/form.h"
+#include "utils/utils.h"
+#include "js/window.h"
+#include "js/document.h"
+#include "js/rocketlauncher.h"
+#include <js/jsapi.h>
+#include <pthread.h>
+
+#ifdef USE_JS
+
+static JSRuntime *rt;
+
+/* The class of the global object. */
+static JSClass global_class =
+{
+	"global", JSCLASS_GLOBAL_FLAGS,
+	JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
+	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
+	JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+JSBool js_alert(JSContext *cx, uintN argc, jsval *vp);
+
+static JSFunctionSpec global_functions[] =
+{
+	JS_FS("alert", js_alert, 1, 0),
+	JS_FS_END
+};
+
+__attribute__ ((constructor)) static void js_constructor() 
+{
+	if (rt != NULL)
+		return;
+
+	rt = JS_NewRuntime(8L * 1024L * 1024L);
+
+	if (rt == NULL)
+	{
+		fprintf(stderr, "error initializing js-runtime :(\n");
+		exit(-1);
+	}
+
+}
+
+__attribute__ ((destructor)) static void js_destructor() 
+{
+	if (rt != NULL)
+	{
+		JS_DestroyRuntime(rt);
+		JS_ShutDown();
+		rt = NULL;
+	}
+}
+
+static void reportError(JSContext *cx, const char *message, JSErrorReport *report)
+{
+	fprintf(stderr, "%s:%u:%s\n",
+			report->filename ? report->filename : "<no filename>",
+			(unsigned int) report->lineno,
+			message);
+}
+
+
+
+
+JSBool js_alert(JSContext *cx, uintN argc, jsval *vp)
+{
+	JSString* u16_txt;
+	unsigned int length;
+	char *txt;
+
+	if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &u16_txt))
+		return JS_FALSE;
+
+	length = JS_GetStringEncodingLength(cx, u16_txt);
+	txt = alloca(sizeof(char)*(length+1));
+	JS_EncodeStringToBuffer(u16_txt, txt, length);
+	txt[length] = '\0';
+	printf("alert: %s\n", txt);
+
+#ifndef TEST
+	warn_user(txt, NULL);
+#endif
+
+	JS_SET_RVAL(cx, vp, JSVAL_VOID);
+	
+	return JS_TRUE;
+}
+
+
+JSContext *js_init(html_content *c)
+{
+	/* JS variables. */
+	//JSRuntime *rt;
+	JSContext *cx;
+	JSObject  *global;
+
+
+	/* Create a context. */
+	cx = JS_NewContext(rt, 8192);
+	if (cx == NULL)
+		return NULL;
+	JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
+	JS_SetVersion(cx, JSVERSION_LATEST);
+	JS_SetErrorReporter(cx, reportError);
+
+	/* Create the global object in a new compartment. */
+	global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
+	if (global == NULL)
+		return NULL;
+
+	if (!JS_DefineFunctions(cx, global, global_functions))
+		return JS_FALSE;
+
+	JS_SetContextPrivate(cx, c);
+
+	define_window(cx);
+	define_document(cx);
+	define_rocketlauncher(cx);
+	/* Populate the global object with the standard globals,
+	   like Object and Array. */
+	if (!JS_InitStandardClasses(cx, global))
+		return NULL;
+
+	return cx;
+}
+
+
+void js_stop(JSContext *cx)
+{
+	printf("js_stop\n");
+	JS_DestroyContext(cx);
+}
+
+void js_exec(html_content *c, char *txt)
+{
+	jsval rval;
+
+	if (txt == NULL)
+		return;
+
+	if (c->jcx == NULL)
+		c->jcx = js_init(c);
+	
+	JS_EvaluateScript(c->jcx, JS_GetGlobalObject(c->jcx), txt, strlen(txt), "<head>", 0, &rval);
+}
+
+#endif
+
+#ifdef TEST
+#define TESTSCRIPT "alert(\"hello world\");"
+void main()
+{
+	JSContext *cx;
+	jsval rval;
+
+	cx = js_init(NULL);
+	JS_EvaluateScript(cx, JS_GetGlobalObject(cx), TESTSCRIPT, strlen(TESTSCRIPT), "TEST", 0, &rval);
+}
+
+#endif
+
diff -urN netsurf-2.8/netsurf-2.8/js/js.h netsurf-2.8-js/netsurf-2.8/js/js.h
--- netsurf-2.8/netsurf-2.8/js/js.h	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/js.h	2012-01-22 07:11:42.000000000 +0000
@@ -0,0 +1,18 @@
+#ifndef NETSURF_JS_H_
+#define NETSURF_JS_H_
+
+#define USE_JS
+
+
+
+#ifdef USE_JS
+#include <js/jsapi.h>
+#include "render/html_internal.h"
+
+void js_exec(html_content *c, char *txt);
+void js_stop(JSContext *cx);
+
+#endif // USE_JS
+
+#endif // NETSURF_JS_H_
+
diff -urN netsurf-2.8/netsurf-2.8/js/Makefile.test netsurf-2.8-js/netsurf-2.8/js/Makefile.test
--- netsurf-2.8/netsurf-2.8/js/Makefile.test	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/Makefile.test	2012-01-21 01:27:13.000000000 +0000
@@ -0,0 +1,3 @@
+
+all: js.h js.c
+	colorgcc -lmozjs185 js.c -L /usr/lib/firefox/ -Wall -I ../ -I /usr/include/libxml2/ -DTEST
diff -urN netsurf-2.8/netsurf-2.8/js/rocketlauncher.c netsurf-2.8-js/netsurf-2.8/js/rocketlauncher.c
--- netsurf-2.8/netsurf-2.8/js/rocketlauncher.c	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/rocketlauncher.c	2012-01-22 08:20:43.000000000 +0000
@@ -0,0 +1,67 @@
+#include <js/jsapi.h>
+#include "js/js.h"
+#include "render/html_internal.h"
+
+
+#ifdef USE_JS
+
+#define RL_VER "Rocketlauncher v2"
+
+static JSBool rocketlauncher_getPropertyURL(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+	struct html_content *c;
+
+	c = JS_GetContextPrivate(cx);
+
+	*vp = STRING_TO_JSVAL(JS_NewStringCopyN(cx, RL_VER, strlen(RL_VER)));
+
+	return JS_TRUE;
+}
+
+
+static JSClass rocketlauncher_class =
+{
+        "rocketlauncher", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+
+static JSPropertySpec rocketlauncher_props[] = {
+    {"VERSION",       1,       JSPROP_READONLY, rocketlauncher_getPropertyURL, NULL},
+    {0}
+};
+
+
+JSBool rocketlauncher_target(JSContext *cx, uintN argc, jsval *vp)
+{
+        unsigned int length;
+	int x, y, z, h;
+
+        if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "iiii", &x, &y, &z, &h))
+                return JS_FALSE;
+
+
+	printf("rocketlauncher-target  x: %d y: %d z: %d height: %d\n", x, y, z, h);
+
+        JS_SET_RVAL(cx, vp, JSVAL_VOID);
+        
+        return JS_TRUE;
+}
+
+
+
+static JSFunctionSpec rocketlauncher_functions[] = {
+        JS_FS("target",   rocketlauncher_target,   4, 0),
+        JS_FS_END
+};
+
+extern void define_rocketlauncher(JSContext *cx)
+{
+	JSObject *obj;
+
+        obj = JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, &rocketlauncher_class, NULL, 0, NULL, rocketlauncher_functions, NULL, NULL);
+	JS_DefineProperties(cx, obj, rocketlauncher_props);
+}
+
+#endif
+
diff -urN netsurf-2.8/netsurf-2.8/js/rocketlauncher.h netsurf-2.8-js/netsurf-2.8/js/rocketlauncher.h
--- netsurf-2.8/netsurf-2.8/js/rocketlauncher.h	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/rocketlauncher.h	2012-01-22 07:17:29.000000000 +0000
@@ -0,0 +1,6 @@
+
+#ifdef USE_JS
+
+void define_rocketlauncher(JSContext *cx);
+
+#endif
diff -urN netsurf-2.8/netsurf-2.8/js/window.c netsurf-2.8-js/netsurf-2.8/js/window.c
--- netsurf-2.8/netsurf-2.8/js/window.c	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/window.c	2012-01-21 23:32:02.000000000 +0000
@@ -0,0 +1,92 @@
+#include <js/jsapi.h>
+#include "js/js.h"
+#include "js/window.h"
+#include "desktop/browser.h"
+
+#ifdef USE_JS
+
+
+static JSClass window_class =
+{
+        "window", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+JSBool js_window_open(JSContext *cx, uintN argc, jsval *vp)
+{
+        JSString* u16_url, *u16_name;
+        unsigned int length;
+        char *url;
+	char *name;
+
+        if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "SS", &u16_url, &u16_name))
+                return JS_FALSE;
+
+        length = JS_GetStringEncodingLength(cx, u16_url);
+        url = alloca(sizeof(char)*(length+1));
+        JS_EncodeStringToBuffer(u16_url, url, length);
+	url[length] = '\0';
+
+        length = JS_GetStringEncodingLength(cx, u16_name);
+        name = alloca(sizeof(char)*(length+1));
+        JS_EncodeStringToBuffer(u16_name, name, length);
+	name[length] = '\0';
+
+
+        printf("window.open: url: %s name: %s\n", url, name);
+
+        struct browser_window *bw = calloc(1, sizeof(struct browser_window));
+        struct gui_window *gw;
+
+        browser_window_initialise_common(bw, NULL);
+        bw->browser_window_type = BROWSER_WINDOW_NORMAL;
+
+        gw = browser_window_create(url, bw, NULL, false, false);
+     
+	JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyN(cx, name, strlen(name)))); 
+
+        return JS_TRUE;
+}
+
+JSBool js_window_close(JSContext *cx, uintN argc, jsval *vp)
+{
+	struct html_content *c;
+	struct browser_window *bw;
+
+	c = JS_GetContextPrivate(cx);
+
+	bw = c->bw;
+
+	if (c->bw == NULL)
+		return JS_FALSE;
+
+	while(bw != NULL && bw->parent != NULL)
+		bw = bw->parent;
+
+	browser_window_destroy(c->bw);
+
+	JS_SET_RVAL(cx, vp, JSVAL_VOID);
+
+	return JS_TRUE;
+}
+
+
+
+static JSFunctionSpec window_functions[] = {
+	JS_FS("open",   js_window_open,   2, 0),
+	JS_FS("close",   js_window_close,   0, 0),
+	JS_FS_END
+};
+
+
+extern void define_window(JSContext *cx)
+{
+        JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, &window_class, NULL, 0, NULL, window_functions, NULL, NULL);
+}
+
+
+
+
+#endif
+
diff -urN netsurf-2.8/netsurf-2.8/js/window.h netsurf-2.8-js/netsurf-2.8/js/window.h
--- netsurf-2.8/netsurf-2.8/js/window.h	1970-01-01 01:00:00.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/js/window.h	2012-01-21 04:32:51.000000000 +0000
@@ -0,0 +1,6 @@
+
+#ifdef USE_JS
+
+void define_window(JSContext *cx);
+
+#endif
diff -urN netsurf-2.8/netsurf-2.8/Makefile netsurf-2.8-js/netsurf-2.8/Makefile
--- netsurf-2.8/netsurf-2.8/Makefile	2011-08-28 15:29:15.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/Makefile	2012-01-21 18:08:13.000000000 +0000
@@ -141,7 +141,7 @@
 STRIP=strip
 
 # Override this only if the host compiler is called something different
-HOST_CC := gcc
+HOST_CC := colorgcc
 
 ifeq ($(TARGET),riscos)
   ifeq ($(HOST),riscos)
@@ -345,7 +345,7 @@
 $(eval $(call feature_enabled,LIBICONV_PLUG,-DLIBICONV_PLUG,,glibc internal iconv))
 
 # common libraries without pkg-config support
-LDFLAGS += -lz
+LDFLAGS += -lz -lmozjs185 -L /usr/lib/firefox/
 
 CFLAGS += -DNETSURF_UA_FORMAT_STRING=\"$(NETSURF_UA_FORMAT_STRING)\"
 CFLAGS += -DNETSURF_HOMEPAGE=\"$(NETSURF_HOMEPAGE)\"
diff -urN netsurf-2.8/netsurf-2.8/Makefile.defaults netsurf-2.8-js/netsurf-2.8/Makefile.defaults
--- netsurf-2.8/netsurf-2.8/Makefile.defaults	2011-05-09 19:13:36.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/Makefile.defaults	2012-01-21 01:31:16.000000000 +0000
@@ -407,7 +407,7 @@
   SDK_VERSION := $(MACOSX_VERSION)
 
   # Optimisation levels
-  CFLAGS += -O2 -Wuninitialized 
+  CFLAGS += -O2 -Wuninitialized -g -v -Wall -lmozjs185 -L /usr/lib/firefox/
 
 endif
 
diff -urN netsurf-2.8/netsurf-2.8/Makefile.sources netsurf-2.8-js/netsurf-2.8/Makefile.sources
--- netsurf-2.8/netsurf-2.8/Makefile.sources	2011-09-05 00:50:14.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/Makefile.sources	2012-01-22 07:18:45.000000000 +0000
@@ -22,6 +22,8 @@
 S_HTTP := challenge.c generics.c primitives.c parameter.c		\
 	content-disposition.c content-type.c www-authenticate.c
 
+S_JS := js.c window.c document.c rocketlauncher.c
+
 S_DESKTOP := cookies.c history_global_core.c hotlist.c knockout.c	\
 	mouse.c options.c plot_style.c print.c search.c searchweb.c	\
 	scrollbar.c sslcert.c textarea.c thumbnail.c tree.c		\
@@ -34,7 +36,8 @@
 	$(addprefix render/,$(S_RENDER))				\
 	$(addprefix utils/,$(S_UTILS))					\
 	$(addprefix utils/http/,$(S_HTTP))				\
-	$(addprefix desktop/,$(S_DESKTOP))
+	$(addprefix desktop/,$(S_DESKTOP))				\
+	$(addprefix js/,$(S_JS))
 
 # S_IMAGE are sources related to image management
 S_IMAGE_YES := image.c image_cache.c
diff -urN netsurf-2.8/netsurf-2.8/render/box.c netsurf-2.8-js/netsurf-2.8/render/box.c
--- netsurf-2.8/netsurf-2.8/render/box.c	2011-08-31 18:53:40.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/render/box.c	2012-01-22 06:38:01.000000000 +0000
@@ -166,6 +166,8 @@
 	box->object = NULL;
 	box->object_params = NULL;
 	box->iframe = NULL;
+	box->js_onload = NULL;
+	box->js_onclick = NULL;
 
 	return box;
 }
diff -urN netsurf-2.8/netsurf-2.8/render/box_construct.c netsurf-2.8-js/netsurf-2.8/render/box_construct.c
--- netsurf-2.8/netsurf-2.8/render/box_construct.c	2011-07-08 09:38:17.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/render/box_construct.c	2012-01-22 04:51:43.000000000 +0000
@@ -50,6 +50,7 @@
 #include "utils/talloc.h"
 #include "utils/url.h"
 #include "utils/utils.h"
+#include "js/js.h"
 
 
 static const content_type image_types = CONTENT_IMAGE;
@@ -332,6 +333,16 @@
 	element = bsearch((const char *) n->name, element_table,
 			ELEMENT_TABLE_COUNT, sizeof(element_table[0]),
 			(int (*)(const void *, const void *)) strcmp);
+
+#ifdef USE_JS
+	/* for js */
+	if (strcmp(n->name, "body") == 0) {
+		box->js_onload = xmlGetProp(n, "onload");
+	} else if (strcmp(n->name, "img") == 0) {
+		box->js_onclick = xmlGetProp(n, "onclick");
+	}
+#endif
+
 	if (element) {
 		/* a special convert function exists for this element */
 		if (!element->convert(n, content, box, &convert_children))
diff -urN netsurf-2.8/netsurf-2.8/render/box.h netsurf-2.8-js/netsurf-2.8/render/box.h
--- netsurf-2.8/netsurf-2.8/render/box.h	2011-08-31 18:53:40.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/render/box.h	2012-01-22 04:50:53.000000000 +0000
@@ -95,6 +95,7 @@
 #include "css/css.h"
 #include "utils/types.h"
 
+#define USE_JS 
 struct box;
 struct column;
 struct object_params;
@@ -215,6 +216,11 @@
 	const char *target;  /**< Link target, or 0. */
 	char *title;  /**< Title, or 0. */
 
+#ifdef USE_JS
+	char *js_onload;
+	char *js_onclick;
+#endif
+
 	unsigned int columns;  /**< Number of columns for TABLE / TABLE_CELL. */
 	unsigned int rows;     /**< Number of rows for TABLE only. */
 	unsigned int start_column;  /**< Start column for TABLE_CELL only. */
diff -urN netsurf-2.8/netsurf-2.8/render/html.c netsurf-2.8-js/netsurf-2.8/render/html.c
--- netsurf-2.8/netsurf-2.8/render/html.c	2011-09-15 23:47:50.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/render/html.c	2012-01-22 07:10:58.000000000 +0000
@@ -50,6 +50,7 @@
 #include "utils/talloc.h"
 #include "utils/url.h"
 #include "utils/utils.h"
+#include "js/js.h"
 
 #define CHUNK 4096
 
@@ -518,8 +519,8 @@
 	}
 	for (head = html->children;
 			head != NULL && head->type != XML_ELEMENT_NODE;
-			head = head->next)
-		;
+			head = head->next);
+
 	if (head && strcmp((const char *) head->name, "head") != 0) {
 		head = NULL;
 		LOG(("head element not found"));
@@ -580,6 +581,28 @@
 	return true;
 }
 
+static void js_onload_exec(void *userdata, struct box *b)
+{
+	if (b->js_onload == NULL)
+		return;
+
+	html_content *c = (html_content*) userdata;
+	js_exec(c, b->js_onload);
+}
+
+static void walk_boxes(void (*userfunction)(void*, struct box*), void *userdata, struct box *b)
+{
+	if (b == NULL)
+		return;
+
+	userfunction(userdata, b);
+
+	walk_boxes(userfunction, userdata, b->next);
+	walk_boxes(userfunction, userdata, b->children);
+
+
+}
+
 /**
  * Complete conversion of an HTML document
  * 
@@ -603,6 +626,7 @@
 	html = xmlDocGetRootElement(c->document);
 	assert(html != NULL);
 
+
 	/* check that the base stylesheet loaded; layout fails without it */
 	if (c->stylesheets[STYLESHEET_BASE].data.external == NULL) {
 		msg_data.error = "Base stylesheet failed to load";
@@ -671,6 +695,8 @@
                 html_dump_frameset(c->frameset, 0);
 #endif
 
+	walk_boxes(js_onload_exec, c, c->layout);
+
 	/* extract image maps - can't do this sensibly in xml_to_box */
 	if (imagemap_extract(html, c) == false) {
 		LOG(("imagemap extraction failed"));
@@ -731,6 +757,10 @@
 
 			free(title2);
 
+		} else if (strcmp((const char *) node->name, "script") == 0) {
+			xmlChar *script_content = xmlNodeGetContent(node);
+			js_exec(c, script_content);
+			xmlFree(script_content);
 		} else if (strcmp((const char *) node->name, "base") == 0) {
 			char *href = (char *) xmlGetProp(node,
 					(const xmlChar *) "href");
@@ -792,6 +822,7 @@
 		if (n->type != XML_ELEMENT_NODE)
 			continue;
 
+
 		/* Recurse into noscript elements */
 		if (strcmp((const char *) n->name, "noscript") == 0) {
 			if (!html_meta_refresh(c, n)) {
@@ -1879,12 +1910,15 @@
 
 void html_destroy(struct content *c)
 {
-	html_content *html = (html_content *) c;
+	struct html_content *html = (struct html_content *) c;
 	unsigned int i;
 	struct form *f, *g;
 
 	LOG(("content %p", c));
 
+	/* Destroy javascript context */
+	//js_stop(html->jcx); // TODO: find better position to do this
+
 	/* Destroy forms */
 	for (f = html->forms; f != NULL; f = g) {
 		g = f->prev;
diff -urN netsurf-2.8/netsurf-2.8/render/html_interaction.c netsurf-2.8-js/netsurf-2.8/render/html_interaction.c
--- netsurf-2.8/netsurf-2.8/render/html_interaction.c	2011-09-06 17:26:02.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/render/html_interaction.c	2012-01-22 07:11:15.000000000 +0000
@@ -42,6 +42,7 @@
 #include "render/textinput.h"
 #include "utils/messages.h"
 #include "utils/utils.h"
+#include "js/js.h"
 
 
 static gui_pointer_shape get_pointer_shape(struct browser_window *bw,
@@ -286,6 +287,11 @@
 			url_box = box;
 		}
 
+#ifdef USE_JS
+		if (box->js_onclick && mouse & BROWSER_MOUSE_CLICK_1)
+			js_exec(html, box->js_onclick);
+#endif
+
 		if (box->usemap) {
 			url = imagemap_get(html, box->usemap,
 					box_x, box_y, x, y, &target);
diff -urN netsurf-2.8/netsurf-2.8/render/html_internal.h netsurf-2.8-js/netsurf-2.8/render/html_internal.h
--- netsurf-2.8/netsurf-2.8/render/html_internal.h	2011-08-24 13:29:30.000000000 +0100
+++ netsurf-2.8-js/netsurf-2.8/render/html_internal.h	2012-01-22 03:33:35.000000000 +0000
@@ -23,10 +23,17 @@
 #ifndef NETSURF_RENDER_HTML_INTERNAL_H_
 #define NETSURF_RENDER_HTML_INTERNAL_H_
 
+#define USE_JS
+
+#ifdef USE_JS
+#include <js/jsapi.h>
+#endif
+
 #include "content/content_protected.h"
 #include "desktop/selection.h"
 #include "render/html.h"
 
+
 /** Data specific to CONTENT_HTML. */
 typedef struct html_content {
 	struct content base;
@@ -65,6 +72,11 @@
 	/**< Style selection context */
 	css_select_ctx *select_ctx;
 
+	/** Context for javascript engine */
+#ifdef USE_JS
+	JSContext *jcx;
+#endif
+
 	/** Number of entries in object_list. */
 	unsigned int num_objects;
 	/** List of objects. */

Reply via email to