diff --git a/src/ecmascript/ecmascript.c b/src/ecmascript/ecmascript.c index 99a63bef..0d31732b 100644 --- a/src/ecmascript/ecmascript.c +++ b/src/ecmascript/ecmascript.c @@ -130,6 +130,7 @@ ecmascript_get_interpreter(struct view_state *vs) #else spidermonkey_get_interpreter(interpreter); #endif + init_string(&interpreter->code); return interpreter; } @@ -143,6 +144,8 @@ ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter) spidermonkey_put_interpreter(interpreter); #endif free_string_list(&interpreter->onload_snippets); + kill_timer(&interpreter->timeout); + done_string(&interpreter->code); interpreter->vs->ecmascript = NULL; mem_free(interpreter); } @@ -297,6 +300,26 @@ ecmascript_set_action(unsigned char **action, unsigned char *string) } } +static void +ecmascript_timeout_handler(void *i) +{ + struct ecmascript_interpreter *interpreter = i; + + ecmascript_eval(interpreter, &interpreter->code, NULL); +} + +void +ecmascript_set_timeout(struct ecmascript_interpreter *interpreter, unsigned char *code, int timeout) +{ + assert(interpreter); + if (!code) return; + done_string(&interpreter->code); + init_string(&interpreter->code); + add_to_string(&interpreter->code, code); + mem_free(code); + install_timer(&interpreter->timeout, timeout, ecmascript_timeout_handler, interpreter); +} + static struct module *ecmascript_modules[] = { #ifdef CONFIG_ECMASCRIPT_SEE &see_module, diff --git a/src/ecmascript/ecmascript.h b/src/ecmascript/ecmascript.h index b09e251c..c54638d8 100644 --- a/src/ecmascript/ecmascript.h +++ b/src/ecmascript/ecmascript.h @@ -6,6 +6,7 @@ * plasm displays for everyone. */ #include "main/module.h" +#include "main/timer.h" #include "util/time.h" struct string; @@ -20,6 +21,11 @@ struct ecmascript_interpreter { void *backend_data; /* Used by document.write() */ struct string *ret; + + /* The code evaluated by setTimeout() */ + struct string code; + timer_id_T timeout; + time_t exec_start; /* This is a cross-rerenderings accumulator of @@ -75,6 +81,8 @@ void ecmascript_timeout_dialog(struct terminal *term, int max_exec_time); void ecmascript_set_action(unsigned char **action, unsigned char *string); +void ecmascript_set_timeout(struct ecmascript_interpreter *interpreter, unsigned char *code, int timeout); + extern struct module ecmascript_module; #endif diff --git a/src/ecmascript/see.c b/src/ecmascript/see.c index 6cef7a75..53170d05 100644 --- a/src/ecmascript/see.c +++ b/src/ecmascript/see.c @@ -68,6 +68,22 @@ see_done(struct module *xxx) { } +static void +js_setTimeout(struct SEE_interpreter *interp, struct SEE_object *self, + struct SEE_object *thisobj, int argc, struct SEE_value **argv, + struct SEE_value *res) +{ + struct ecmascript_interpreter *ei; + unsigned char *code; + int timeout; + + if (argc != 2) return; + ei = ((struct global_object *)interp)->interpreter; + code = SEE_value_to_unsigned_char(interp, argv[0]); + timeout = SEE_ToInt32(interp, argv[1]); + ecmascript_set_timeout(ei, code, timeout); +} + void * see_get_interpreter(struct ecmascript_interpreter *interpreter) { @@ -77,6 +93,8 @@ see_get_interpreter(struct ecmascript_interpreter *interpreter) interpreter->backend_data = g; g->max_exec_time = get_opt_int("ecmascript.max_exec_time"); g->exec_start = time(NULL); + /* used by setTimeout */ + g->interpreter = interpreter; SEE_interpreter_init(interp); init_js_window_object(interpreter); init_js_menubar_object(interpreter); @@ -86,6 +104,7 @@ see_get_interpreter(struct ecmascript_interpreter *interpreter) init_js_location_object(interpreter); init_js_document_object(interpreter); init_js_forms_object(interpreter); + SEE_CFUNCTION_PUTA(interp, interp->Global, "setTimeout", js_setTimeout, 2, 0); return interp; } diff --git a/src/ecmascript/see/window.h b/src/ecmascript/see/window.h index f7a7e4d1..2f353901 100644 --- a/src/ecmascript/see/window.h +++ b/src/ecmascript/see/window.h @@ -3,6 +3,7 @@ struct SEE_object; struct SEE_interpreter; +struct ecmascript_interpreter; struct string; struct view_state; @@ -16,6 +17,8 @@ struct js_window_object { struct global_object { struct SEE_interpreter interp; + /* used by setTimeout */ + struct ecmascript_interpreter *interpreter; struct js_window_object *win; struct string *ret; int exec_start;