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. */