diff options
Diffstat (limited to 'javascript/jsapi.c')
-rw-r--r-- | javascript/jsapi.c | 120 |
1 files changed, 105 insertions, 15 deletions
diff --git a/javascript/jsapi.c b/javascript/jsapi.c index e5b4ddf6e..eebb33fee 100644 --- a/javascript/jsapi.c +++ b/javascript/jsapi.c @@ -32,7 +32,7 @@ void js_initialise(void) /* Create a JS runtime. */ #if JS_VERSION >= 180 - JS_SetCStringsAreUTF8(); /* we prefer our runtime to be utf-8 */ + JS_SetCStringsAreUTF8(); /* we prefer our runtime to be utf-8 */ #endif rt = JS_NewRuntime(8L * 1024L * 1024L); @@ -97,7 +97,7 @@ void js_destroycontext(jscontext *ctx) * * This performs the following actions * 1. constructs a new global object by initialising a window class - * 2. Instantiate the global a window object + * 2. Instantiate the global a window object */ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv) { @@ -116,7 +116,7 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv) } window = jsapi_new_Window(cx, window_proto, NULL, win_priv, doc_priv); - + return (jsobject *)window; } @@ -139,9 +139,9 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen) return false; } - if (JS_EvaluateScript(cx, - JS_GetGlobalObject(cx), - txt, txtlen, + if (JS_EvaluateScript(cx, + JS_GetGlobalObject(cx), + txt, txtlen, "<head>", 0, &rval) == JS_TRUE) { return true; @@ -174,8 +174,8 @@ bool js_fire_event(jscontext *ctx, const char *type, dom_document *doc, dom_node JSLOG("Dispatching event %s at window", type); /* create and initialise and event object */ - exc = dom_string_create((unsigned char*)type, - strlen(type), + exc = dom_string_create((unsigned char*)type, + strlen(type), &type_dom); if (exc != DOM_NO_ERR) { return false; @@ -200,18 +200,18 @@ bool js_fire_event(jscontext *ctx, const char *type, dom_document *doc, dom_node /* dispatch event at the window object */ argv[0] = OBJECT_TO_JSVAL(jsevent); - ret = JS_CallFunctionName(cx, - JS_GetGlobalObject(cx), - "dispatchEvent", - 1, - argv, + ret = JS_CallFunctionName(cx, + JS_GetGlobalObject(cx), + "dispatchEvent", + 1, + argv, &rval); } else { JSLOG("Dispatching event %s at %p", type, node); /* create and initialise and event object */ - exc = dom_string_create((unsigned char*)type, - strlen(type), + exc = dom_string_create((unsigned char*)type, + strlen(type), &type_dom); if (exc != DOM_NO_ERR) { return false; @@ -237,3 +237,93 @@ bool js_fire_event(jscontext *ctx, const char *type, dom_document *doc, dom_node } return false; } + +struct js_dom_event_private { + JSContext *cx; /* javascript context */ + jsval funcval; /* javascript function to call */ + struct dom_node *node; /* dom node event listening on */ + dom_string *type; /* event type */ + dom_event_listener *listener; /* the listener containing this */ +}; + +static void +js_dom_event_listener(struct dom_event *event, void *pw) +{ + struct js_dom_event_private *private = pw; + jsval event_argv[1]; + jsval event_rval; + JSObject *jsevent; + + JSLOG("WOOT dom event with %p", private); + + if (!JSVAL_IS_VOID(private->funcval)) { + jsevent = jsapi_new_Event(private->cx, NULL, NULL, event); + if (jsevent != NULL) { + + /* dispatch event at the window object */ + event_argv[0] = OBJECT_TO_JSVAL(jsevent); + + JS_CallFunctionValue(private->cx, + NULL, + private->funcval, + 1, + event_argv, + &event_rval); + } + } +} + +/* add a listener to a dom node + * + * 1. Create a dom_event_listener From a handle_event function pointer + * and a private word In a document context + * + * 2. Register for your events on a target (dom nodes are targets) + * dom_event_target_add_event_listener(node, evt_name, listener, + * capture_or_not) + * + */ + +bool +js_dom_event_add_listener(jscontext *ctx, + struct dom_document *document, + struct dom_node *node, + struct dom_string *event_type_dom, + void *js_funcval) +{ + JSContext *cx = (JSContext *)ctx; + dom_exception exc; + struct js_dom_event_private *private; + + private = malloc(sizeof(struct js_dom_event_private)); + if (private == NULL) { + return false; + } + + exc = dom_event_listener_create(document, + js_dom_event_listener, + private, + &private->listener); + if (exc != DOM_NO_ERR) { + return false; + } + + private->cx = cx; + private->funcval = *(jsval *)js_funcval; + private->node = node; + private->type = event_type_dom; + + JSLOG("adding %p to listener", private); + + JS_AddValueRoot(cx, &private->funcval); + exc = dom_event_target_add_event_listener(private->node, + private->type, + private->listener, + true); + if (exc != DOM_NO_ERR) { + JSLOG("failed to add listener"); + JS_RemoveValueRoot(cx, &private->funcval); + } + + return true; +} |