From 6ebaecccafbca464ee366d45fd15a0df13509849 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 1 Jan 2012 21:42:38 +0000 Subject: Totaly prefunctry binding to spidermonkey svn path=/trunk/netsurf/; revision=13360 --- Docs/BUILDING-GTK | 5 +++ Makefile.defaults | 4 ++ Makefile.sources | 9 ++++- desktop/browser.c | 13 ++++++- desktop/browser.h | 5 +++ desktop/js.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ desktop/js.h | 11 ++++++ desktop/netsurf.c | 5 +++ desktop/nojs.c | 24 ++++++++++++ gtk/Makefile.target | 2 + 10 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 desktop/js.c create mode 100644 desktop/js.h create mode 100644 desktop/nojs.c diff --git a/Docs/BUILDING-GTK b/Docs/BUILDING-GTK index 8d2f21541..8f3204c1b 100644 --- a/Docs/BUILDING-GTK +++ b/Docs/BUILDING-GTK @@ -75,6 +75,11 @@ they are invalid. But as this is currently unimplemented in the GTK flavour of NetSurf, this won't make a difference at all. + For experimental javascript support the mozilla spiermonkey library + is required: + + $ apt-get install libmozjs-dev + Fedora: $ yum install libglade2-devel curl-devel libxml2-devel libmng-devel diff --git a/Makefile.defaults b/Makefile.defaults index 0301bdf86..0ebe04a4c 100644 --- a/Makefile.defaults +++ b/Makefile.defaults @@ -61,6 +61,10 @@ NETSURF_USE_WEBP := NO # Valid options: YES, NO NETSURF_USE_VIDEO := NO +# Enable NetSurf's use of spidermonkey for javascript +# Valid options: YES, NO +NETSURF_USE_JS := NO + # Enable NetSurf's use of libharu for PDF export and GTK printing support. # There is no auto-detection available for this, as it does not have a # pkg-config file. diff --git a/Makefile.sources b/Makefile.sources index 5b2764eda..e0f8c3335 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -58,8 +58,15 @@ S_PDF := $(addprefix desktop/save_pdf/,$(S_PDF)) # S_BROWSER are sources related to full browsers but are common # between RISC OS, GTK, BeOS and AmigaOS builds -S_BROWSER := browser.c download.c frames.c history_core.c netsurf.c \ +S_BROWSER := browser.c download.c frames.c history_core.c netsurf.c \ save_complete.c save_text.c selection.c textinput.c + +ifeq ($(NETSURF_USE_JS),YES) +S_BROWSER += js.c +else +S_BROWSER += nojs.c +endif + S_BROWSER := $(addprefix desktop/,$(S_BROWSER)) # The following files depend on the testament diff --git a/desktop/browser.c b/desktop/browser.c index 8ae68d377..9645d5ed6 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -54,6 +54,7 @@ #include "desktop/selection.h" #include "desktop/textinput.h" #include "desktop/plotters.h" +#include "desktop/js.h" #include "render/form.h" #include "render/html.h" @@ -646,6 +647,8 @@ struct browser_window *browser_window_create(const char *url, return NULL; } + bw->jsctx = js_newcontext(); + /* Initialise common parts */ browser_window_initialise_common(bw, clone); @@ -669,8 +672,9 @@ struct browser_window *browser_window_create(const char *url, return NULL; } - if (url) + if (url) { browser_window_go(bw, url, referer, history_add); + } return bw; @@ -936,6 +940,9 @@ void browser_window_go_post(struct browser_window *bw, const char *url, browser_window_set_status(bw, messages_get("Loading")); bw->history_add = add_to_history; + /* fresh javascript compartment */ + bw->jsglobal = js_newcompartment(bw->jsctx); + /* Verifiable fetches may trigger a download */ if (verifiable) fetch_flags |= HLCACHE_RETRIEVE_MAY_DOWNLOAD; @@ -1943,6 +1950,10 @@ void browser_window_destroy_internal(struct browser_window *bw) bw->box = NULL; } + if (bw->jsctx != NULL) { + js_destroycontext(bw->jsctx); + } + /* These simply free memory, so are safe here */ if (bw->frag_id != NULL) diff --git a/desktop/browser.h b/desktop/browser.h index 563d31431..5136cb205 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -197,6 +197,11 @@ struct browser_window { /** Current context for free text search, or NULL if none */ struct search_context *cur_search; + /** current javascript context */ + struct jscontext *jsctx; + /** current global javascript object */ + struct jsobject *jsglobal; + /** cache of the currently displayed status text. */ char *status_text; /**< Current status bar text. */ int status_text_len; /**< Length of the ::status_text buffer. */ diff --git a/desktop/js.c b/desktop/js.c new file mode 100644 index 000000000..540ff82a5 --- /dev/null +++ b/desktop/js.c @@ -0,0 +1,104 @@ +#include "mozjs/jsapi.h" + +#include "desktop/js.h" +#include "utils/log.h" + +static JSRuntime *rt; /* global runtime */ + +void js_initialise(void) +{ + /* Create a JS runtime. */ + rt = JS_NewRuntime(8L * 1024L * 1024L); + LOG(("New runtime handle %p", rt)); +} + +void js_finalise(void) +{ + if (rt != NULL) { + LOG(("destroying runtime handle %p", rt)); + JS_DestroyRuntime(rt); + } + JS_ShutDown(); +} + +/* The error reporter callback. */ +static void js_reportError(JSContext *cx, const char *message, JSErrorReport *report) +{ + LOG(("%s:%u:%s\n", + report->filename ? report->filename : "", + (unsigned int) report->lineno, + message)); +} + +jscontext *js_newcontext(void) +{ + JSContext *cx; + + if (rt == NULL) { + return NULL; + } + + cx = JS_NewContext(rt, 8192); + if (cx == NULL) { + return NULL; + } + JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT ); + JS_SetVersion(cx, JSVERSION_LATEST); + JS_SetErrorReporter(cx, js_reportError); + + LOG(("New Context %p", cx)); + + return (jscontext *)cx; +} + +void js_destroycontext(jscontext *ctx) +{ + JSContext *cx = (JSContext *)ctx; + if (cx != NULL) { + LOG(("Destroying Context %p", cx)); + JS_DestroyContext(cx); + } +} + + + +/* The class of the global object. */ +static JSClass global_class = { + "global", JSCLASS_GLOBAL_FLAGS, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + + +jsobject *js_newcompartment(jscontext *ctx) +{ + JSContext *cx = (JSContext *)ctx; + JSObject *global; + + if (cx == NULL) { + return NULL; + } +#ifdef HAVE_JS_NEWCOMPARTMENTANDGLOBALOBJECT + global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); + if (global == NULL) { + return NULL; + } +#else + global = JS_NewObject(cx, &global_class, NULL, NULL); + if (global == NULL) { + return NULL; + } + JS_SetGlobalObject(cx, global); +#endif + + /* Populate the global object with the standard globals, + like Object and Array. */ + if (!JS_InitStandardClasses(cx, global)) { + return NULL; + } + + LOG(("Creating new global object %p", global)); + + return (jsobject *)global; +} diff --git a/desktop/js.h b/desktop/js.h new file mode 100644 index 000000000..b70845f16 --- /dev/null +++ b/desktop/js.h @@ -0,0 +1,11 @@ + +typedef struct jscontext jscontext; +typedef struct jsobject jsobject; + +void js_initialise(void); +void js_finalise(void); + +jscontext *js_newcontext(void); +void js_destroycontext(jscontext *ctx); + +jsobject *js_newcompartment(jscontext *ctx); diff --git a/desktop/netsurf.c b/desktop/netsurf.c index 8fa02255f..698606da1 100644 --- a/desktop/netsurf.c +++ b/desktop/netsurf.c @@ -46,6 +46,7 @@ #include "desktop/gui.h" #include "desktop/options.h" #include "desktop/searchweb.h" +#include "desktop/js.h" #include "render/html.h" #include "render/textplain.h" #include "utils/log.h" @@ -229,6 +230,8 @@ nserror netsurf_init(int *pargc, options_commandline(pargc, *pargv); + js_initialise(); + return ret; } @@ -252,6 +255,8 @@ int netsurf_main_loop(void) void netsurf_exit(void) { + js_finalise(); + hlcache_stop(); LOG(("Closing GUI")); diff --git a/desktop/nojs.c b/desktop/nojs.c new file mode 100644 index 000000000..9a5c3c65e --- /dev/null +++ b/desktop/nojs.c @@ -0,0 +1,24 @@ +#include "desktop/js.h" +#include "utils/log.h" + +void js_initialise(void) +{ +} + +void js_finalise(void) +{ +} + +jscontext *js_newcontext(void) +{ + return NULL; +} + +void js_destroycontext(jscontext *ctx) +{ +} + +jsobject *js_newcompartment(jscontext *ctx) +{ + return NULL; +} diff --git a/gtk/Makefile.target b/gtk/Makefile.target index 1086d426f..e80461092 100644 --- a/gtk/Makefile.target +++ b/gtk/Makefile.target @@ -14,6 +14,7 @@ NETSURF_FEATURE_GIF_CFLAGS := -DWITH_GIF NETSURF_FEATURE_PNG_CFLAGS := -DWITH_PNG NETSURF_FEATURE_WEBP_CFLAGS := -DWITH_WEBP NETSURF_FEATURE_VIDEO_CFLAGS := -DWITH_VIDEO +NETSURF_FEATURE_JS_CFLAGS := -DWITH_JS -DJS_HAS_FILE_OBJECT=0 # add a line similar to below for each optional pkg-configed lib here $(eval $(call pkg_config_find_and_add,RSVG,librsvg-2.0,SVG)) @@ -23,6 +24,7 @@ $(eval $(call pkg_config_find_and_add,BMP,libnsbmp,BMP)) $(eval $(call pkg_config_find_and_add,GIF,libnsgif,GIF)) $(eval $(call pkg_config_find_and_add,PNG,libpng,PNG )) $(eval $(call pkg_config_find_and_add,VIDEO,gstreamer-0.10,Video)) +$(eval $(call pkg_config_find_and_add,JS,mozilla-js,Javascript)) # no pkg-config for this library $(eval $(call feature_enabled,WEBP,-DWITH_WEBP,-lwebp,WebP (libwebp))) -- cgit v1.2.3