#ifndef EL__ECMASCRIPT_ECMASCRIPT_H #define EL__ECMASCRIPT_ECMASCRIPT_H /* This is a trivial ECMAScript driver. All your base are belong to pasky. */ /* In the future you will get DOM, a complete ECMAScript interface and free * plasm displays for everyone. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef CONFIG_ECMASCRIPT_SMJS #include #endif #ifdef CONFIG_QUICKJS #include #endif #ifdef CONFIG_MUJS #include #endif #ifdef CONFIG_ECMASCRIPT #include "main/module.h" #include "main/timer.h" #include "util/time.h" //#define ECMASCRIPT_DEBUG 1 #ifdef ECMASCRIPT_DEBUG #include #endif #ifdef __cplusplus extern "C" { #endif struct document_view; struct form_state; struct form_view; struct string; struct terminal; struct uri; struct view_state; struct ecmascript_interpreter { struct view_state *vs; void *backend_data; /* Nesting level of calls to backend functions. When this is * nonzero, there are references to backend_data in the C * stack, so it is not safe to free the data yet. */ int backend_nesting; /* Used by document.write() */ struct string *ret; /* The code evaluated by setTimeout() */ struct string code; struct heartbeat *heartbeat; /* This is a cross-rerenderings accumulator of * @document.onload_snippets (see its description for juicy details). * They enter this list as they continue to appear there, and they * never leave it (so that we can always find from where to look for * any new snippets in document.onload_snippets). Instead, as we * go through the list we maintain a pointer to the last processed * entry. */ LIST_OF(struct string_list_item) onload_snippets; struct string_list_item *current_onload_snippet; /* ID of the {struct document} where those onload_snippets belong to. * It is kept at 0 until it is definitively hard-attached to a given * final document. Then if we suddenly appear with this structure upon * a document with a different ID, we reset the state and start with a * fresh one (normally, that does not happen since reloading sets * ecmascript_fragile, but it can happen i.e. when the urrent document * is reloaded in another tab and then you just cause the current tab * to redraw. */ unsigned int onload_snippets_cache_id; void *ac; void *ac2; #ifdef CONFIG_QUICKJS JSValue document_obj; JSValue location_obj; #else void *document_obj; void *location_obj; #endif #ifdef CONFIG_QUICKJS JSValueConst fun; #endif #ifdef CONFIG_ECMASCRIPT_SMJS JS::RootedValue fun; #endif #ifdef CONFIG_MUJS const char *fun; #endif bool changed; }; struct ecmascript_timeout { LIST_HEAD(struct ecmascript_timeout); struct string code; #ifdef CONFIG_QUICKJS JSValueConst fun; #endif #ifdef CONFIG_ECMASCRIPT_SMJS JS::RootedValue fun; #endif #ifdef CONFIG_MUJS js_State *ctx; const char *fun; #endif struct ecmascript_interpreter *interpreter; timer_id_T tid; }; struct delayed_goto { /* It might look more convenient to pass doc_view around but it could * disappear during wild dances inside of frames or so. */ struct view_state *vs; struct uri *uri; }; /* Why is the interpreter bound to {struct view_state} instead of {struct * document}? That's easy, because the script won't raid just inside of the * document, but it will also want to generate pop-up boxes, adjust form * contents (which is doc_view-specific) etc. Of course the cons are that we * need to wait with any javascript code execution until we get bound to the * view_state through document_view - that means we are going to re-render the * document if it contains a