From 68f359d1ec2212939f19a25dfb182d08cfa37afd Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 28 Nov 2012 18:07:36 +0000 Subject: initial event fireing implementation --- Makefile.sources.javascript | 1 + javascript/js.h | 3 +++ javascript/jsapi.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ javascript/jsapi/binding.h | 7 ++++++ javascript/jsapi/event.bnd | 36 +++++++++++++++++++++++++++++ javascript/jsapi/window.bnd | 47 +++++++++++++++++++++++++++++++++++++ javascript/none.c | 5 ++++ render/html.c | 6 +++++ 8 files changed, 161 insertions(+) create mode 100644 javascript/jsapi/event.bnd diff --git a/Makefile.sources.javascript b/Makefile.sources.javascript index 2a33565a6..1ece3b683 100644 --- a/Makefile.sources.javascript +++ b/Makefile.sources.javascript @@ -21,6 +21,7 @@ JSAPI_BINDING_htmlcollection := javascript/jsapi/htmlcollection.bnd JSAPI_BINDING_nodelist := javascript/jsapi/nodelist.bnd JSAPI_BINDING_text := javascript/jsapi/text.bnd JSAPI_BINDING_node := javascript/jsapi/node.bnd +JSAPI_BINDING_event := javascript/jsapi/event.bnd # 1: input file # 2: output file diff --git a/javascript/js.h b/javascript/js.h index a6566f975..4dd8f15d3 100644 --- a/javascript/js.h +++ b/javascript/js.h @@ -51,4 +51,7 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv); /* execute some javascript in a context */ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen); +/* fire an event at a dom node */ +bool js_fire_event(jscontext *ctx, const char *type, void *target); + #endif /* _NETSURF_JAVASCRIPT_JS_H_ */ diff --git a/javascript/jsapi.c b/javascript/jsapi.c index 35e3da35d..2aa0f8918 100644 --- a/javascript/jsapi.c +++ b/javascript/jsapi.c @@ -149,3 +149,59 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen) return false; } + +bool js_fire_event(jscontext *ctx, const char *type, void *target) +{ + JSContext *cx = (JSContext *)ctx; + dom_node *node = target; + JSObject *jsevent; + jsval rval; + jsval argv[1]; + JSBool ret = JS_TRUE; + dom_exception exc; + dom_event *event; + dom_string *type_dom; + + if (node == NULL) { + /* deliver to window */ + if (cx == NULL) { + return false; + } + + exc = dom_string_create((unsigned char*)type, strlen(type), &type_dom); + if (exc != DOM_NO_ERR) { + return false; + } + +/* exc = dom_event_create(document, &event);*/ + exc = -1; + if (exc != DOM_NO_ERR) { + return false; + } + + exc = dom_event_init(event, type_dom, false, false); + dom_string_unref(type_dom); + if (exc != DOM_NO_ERR) { + return false; + } + + jsevent = jsapi_new_Event(cx, NULL, NULL, event); + if (jsevent == NULL) { + return false; + } + + argv[0] = OBJECT_TO_JSVAL(jsevent); + + ret = JS_CallFunctionName(cx, + JS_GetGlobalObject(cx), + "dispatchEvent", + 1, + argv, + &rval); + } + + if (ret == JS_TRUE) { + return true; + } + return false; +} diff --git a/javascript/jsapi/binding.h b/javascript/jsapi/binding.h index 6d069b973..f27493532 100644 --- a/javascript/jsapi/binding.h +++ b/javascript/jsapi/binding.h @@ -149,4 +149,11 @@ JSObject *jsapi_new_Node(JSContext *cx, JSObject *prototype, JSObject *parent); +extern JSClass JSClass_Event; +JSObject *jsapi_InitClass_Event(JSContext *cx, JSObject *parent); +JSObject *jsapi_new_Event(JSContext *cx, + JSObject *prototype, + JSObject *parent, + dom_event *event); + #endif diff --git a/javascript/jsapi/event.bnd b/javascript/jsapi/event.bnd new file mode 100644 index 000000000..cc03c920a --- /dev/null +++ b/javascript/jsapi/event.bnd @@ -0,0 +1,36 @@ +/* Binding to generate event interface + * + * Copyright 2012 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * Released under the terms of the MIT License, + * http://www.opensource.org/licenses/mit-license + */ + +webidlfile "dom.idl"; + +hdrcomment "Copyright 2012 Vincent Sanders "; +hdrcomment "This file is part of NetSurf, http://www.netsurf-browser.org/"; +hdrcomment "Released under the terms of the MIT License,"; +hdrcomment " http://www.opensource.org/licenses/mit-license"; + +preamble %{ + +#include + +#include "utils/config.h" +#include "utils/log.h" + +#include "javascript/jsapi.h" +#include "javascript/jsapi/binding.h" + +%} + +binding node { + type js_libdom; /* the binding type */ + + interface Event; /* Web IDL interface to generate */ + + private "dom_event *" event; +} diff --git a/javascript/jsapi/window.bnd b/javascript/jsapi/window.bnd index 7875ab40f..3f8930441 100644 --- a/javascript/jsapi/window.bnd +++ b/javascript/jsapi/window.bnd @@ -23,6 +23,7 @@ preamble %{ #include "utils/config.h" #include "utils/log.h" +#include "utils/corestrings.h" #include "javascript/jsapi.h" #include "javascript/jsapi/binding.h" @@ -147,6 +148,11 @@ api init %{ return NULL; } + user_proto = jsapi_InitClass_Event(cx, prototype); + if (user_proto == NULL) { + return NULL; + } + %} api new %{ @@ -211,10 +217,51 @@ getter self %{ jsret = obj; %} +/* boolean dispatchEvent(Event event); */ +operation dispatchEvent %{ + /* this implementation is unique to the window object as it is + * not a "real" dom node. + */ + + /* caution, this must match the struct generated from event.bnd */ + if (event == JSVAL_VOID) { + jsret = JS_FALSE; + } else { + dom_event *domevent; + dom_string *type_dom; + dom_exception exc; + jsval eventval = JSVAL_VOID; + jsval event_argv[1]; + jsval event_rval; + + domevent = JS_GetInstancePrivate(cx, event, &JSClass_Event, NULL); + if (domevent == NULL) { + /** @todo type error? */ + jsret = JS_FALSE; + } else { + exc = dom_event_get_type(domevent, &type_dom); + if (dom_string_isequal(type_dom, corestring_dom_load)) { + JS_GetProperty(cx, JSAPI_THIS_OBJECT(cx, vp), "onload", &eventval); + } + + if (eventval != JSVAL_VOID) { + event_argv[0] = event; + jsret = JS_CallFunctionValue(cx, NULL, eventval, 1, event_argv, &event_rval); + } + } + } +%} + getter EventHandler %{ + /* this implementation is unique to the window object as it is + * not a dom node. + */ JSLOG("propname[%d] %s %s", tinyid , jsclass_properties[tinyid].name, JS_GetTypeName(cx, JS_TypeOfValue(cx, tinyid_jsval))); %} setter EventHandler %{ + /* this implementation is unique to the window object as it is + * not a dom node. + */ JSLOG("propname[%d] %s %s", tinyid, jsclass_properties[tinyid].name, JS_GetTypeName(cx, JS_TypeOfValue(cx, tinyid_jsval))); %} diff --git a/javascript/none.c b/javascript/none.c index b5cfc7875..6354a12ff 100644 --- a/javascript/none.c +++ b/javascript/none.c @@ -53,3 +53,8 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen) { return true; } + +bool js_fire_event(jscontext *ctx, const char *type, void *target) +{ + return true; +} diff --git a/render/html.c b/render/html.c index 548295c64..fc6084332 100644 --- a/render/html.c +++ b/render/html.c @@ -331,6 +331,12 @@ void html_finish_conversion(html_content *c) } } + /* fire a simple event named load at the Document's Window + * object, but with its target set to the Document object (and + * the currentTarget set to the Window object) + */ + js_fire_event(c->jscontext, "load", NULL); + /* convert dom tree to box tree */ LOG(("DOM to box (%p)", c)); content_set_status(&c->base, messages_get("Processing")); -- cgit v1.2.3