summaryrefslogtreecommitdiff
path: root/javascript/jsapi.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@netsurf-browser.org>2012-12-04 18:01:11 +0000
committerVincent Sanders <vince@netsurf-browser.org>2012-12-04 18:01:11 +0000
commit897acff532415ed81f9066b8b811ae744918da84 (patch)
tree093efaf239abc7d9e2411005cdaea8d14fc245d4 /javascript/jsapi.c
parent878fe3e68cbda4f3d51cce7bc3b0ffcc27135367 (diff)
downloadnetsurf-897acff532415ed81f9066b8b811ae744918da84.tar.gz
netsurf-897acff532415ed81f9066b8b811ae744918da84.tar.bz2
make events work on elements
Diffstat (limited to 'javascript/jsapi.c')
-rw-r--r--javascript/jsapi.c120
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;
+}