diff options
author | Marco Peereboom <marco@conformal.com> | 2011-10-28 16:37:46 -0500 |
---|---|---|
committer | Marco Peereboom <marco@conformal.com> | 2011-10-28 16:37:46 -0500 |
commit | 24df09088aa37d73eae53ead1031b799b8f2a054 (patch) | |
tree | 7d3eb9f270e8e35ff03e39ade516ea6946aa8fc1 | |
parent | e8559a35289301116c195e75d080d9132800066a (diff) | |
download | xombrero-24df09088aa37d73eae53ead1031b799b8f2a054.tar.gz |
add mechanism to run external JavaScript
Add the :script <filename> command to load and execute a piece of JavaScript in the current tab context. This should enable all kinds of awesome extension for xxxterm. This is also dangerous and not yet properly cordoned off so use with care. This feature is experimental. New things will be added to it as it becomes apparent what else needs to be done to add things such as password managers etc.
-rw-r--r-- | xxxterm.1 | 2 | ||||
-rw-r--r-- | xxxterm.c | 78 |
2 files changed, 80 insertions, 0 deletions
diff --git a/xxxterm.1 b/xxxterm.1 index 4225559..c431afb 100644 --- a/xxxterm.1 +++ b/xxxterm.1 @@ -535,6 +535,8 @@ and reload all current tabs. Runs the script path_to_script with the current uri as the argument. If path_to_script is not provided, the value of default_script is used instead. +.It Cm script [filename] +Run an external JavaScript script file in the current tab context. .It Cm session , Cm session show Display the current session name. By default the session name is main_session. diff --git a/xxxterm.c b/xxxterm.c index 5eb8825..1e2945a 100644 --- a/xxxterm.c +++ b/xxxterm.c @@ -541,6 +541,8 @@ struct karg { #define XT_BUFCMD_SZ (8) +#define XT_EJS_SHOW (1<<0) + /* mime types */ struct mime_type { char *mt_type; @@ -5649,6 +5651,79 @@ done: return (XT_CB_PASSTHROUGH); } +int +script_cmd(struct tab *t, struct karg *args) +{ + JSGlobalContextRef ctx; + WebKitWebFrame *frame; + JSStringRef str; + JSValueRef val, exception; + char *es; + struct stat sb; + FILE *f = NULL; + char *buf = NULL; + + if (t == NULL) + goto done; + + if ((f = fopen(args->s, "r")) == NULL) { + show_oops(t, "Can't open script file: %s", args->s); + goto done; + } + + if (fstat(fileno(f), &sb) == -1) { + show_oops(t, "Can't stat script file: %s", args->s); + goto done; + } + + buf = g_malloc0(sb.st_size + 1); + if (fread(buf, 1, sb.st_size, f) != sb.st_size) { + show_oops(t, "Can't read script file: %s", args->s); + goto done; + } + + /* this code needs to be redone */ + frame = webkit_web_view_get_main_frame(t->wv); + ctx = webkit_web_frame_get_global_context(frame); + + str = JSStringCreateWithUTF8CString(buf); + val = JSEvaluateScript(ctx, str, JSContextGetGlobalObject(ctx), + NULL, 0, &exception); + JSStringRelease(str); + + DNPRINTF(XT_D_JS, "run_script: val %p\n", val); + if (val == NULL) { + es = js_ref_to_string(ctx, exception); + if (es) { + show_oops(t, "script exception: %s", es); + g_free(es); + } + goto done; + } else { + es = js_ref_to_string(ctx, val); +#if 0 + /* return values */ + if (!strncmp(es, XT_JS_DONE, XT_JS_DONE_LEN)) + ; /* do nothing */ + if (!strncmp(es, XT_JS_INSERT, XT_JS_INSERT_LEN)) + ; /* do nothing */ +#endif + if (es) { + show_oops(t, "script complete return value: '%s'", es); + g_free(es); + } else + show_oops(t, "script complete: without a return value"); + } + +done: + if (f) + fclose(f); + if (buf) + g_free(buf); + + return (XT_CB_PASSTHROUGH); +} + /* * Make a hardcopy of the page */ @@ -6208,6 +6283,9 @@ struct cmd { { "open", 1, session_cmd, XT_OPEN, XT_SESSARG }, { "save", 1, session_cmd, XT_SAVE, XT_USERARG }, { "show", 1, session_cmd, XT_SHOW, 0 }, + + /* external javascript */ + { "script", 0, script_cmd, XT_EJS_SHOW, XT_USERARG }, }; struct { |