From 0035771d5a174e6d96bf1b1c66fde4813fcd6135 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Fri, 21 Apr 2017 01:07:48 +0200 Subject: Run js by webextension. Make sure all the scripts we run internally are also evaluated in case js is disabled. --- src/ex.c | 53 +++++++++++++++------------------------------ src/ext-proxy.c | 8 +++++-- src/ext-proxy.h | 2 +- src/input.c | 4 ++-- src/normal.c | 23 ++++++++++---------- src/webextension/ext-main.c | 26 ++++++++++++++++++---- src/webextension/ext-util.c | 22 +++++++++++++++++++ src/webextension/ext-util.h | 1 + 8 files changed, 83 insertions(+), 56 deletions(-) diff --git a/src/ex.c b/src/ex.c index 6818ba1..79191b2 100644 --- a/src/ex.c +++ b/src/ex.c @@ -39,6 +39,7 @@ #include "setting.h" #include "shortcut.h" #include "util.h" +#include "ext-proxy.h" typedef enum { /* TODO add feature autocmd */ @@ -126,8 +127,7 @@ static VbCmdResult execute(Client *c, const ExArg *arg); static VbCmdResult ex_bookmark(Client *c, const ExArg *arg); static VbCmdResult ex_eval(Client *c, const ExArg *arg); -static void ex_eval_javascript_finished(GObject *object, - GAsyncResult *result, Client *c); +static void on_eval_script_finished(GDBusProxy *proxy, GAsyncResult *result, Client *c); static VbCmdResult ex_hardcopy(Client *c, const ExArg *arg); static VbCmdResult ex_map(Client *c, const ExArg *arg); static VbCmdResult ex_unmap(Client *c, const ExArg *arg); @@ -784,47 +784,30 @@ static VbCmdResult ex_eval(Client *c, const ExArg *arg) { /* Called as :eval! - don't print to inputbox. */ if (arg->bang) { - webkit_web_view_run_javascript(c->webview, arg->rhs->str, NULL, NULL, NULL); + ext_proxy_eval_script(c, arg->rhs->str, NULL); } else { - webkit_web_view_run_javascript(c->webview, arg->rhs->str, NULL, - (GAsyncReadyCallback)ex_eval_javascript_finished, c); + ext_proxy_eval_script(c, arg->rhs->str, (GAsyncReadyCallback)on_eval_script_finished); } return CMD_SUCCESS; } -static void ex_eval_javascript_finished(GObject *object, - GAsyncResult *result, Client *c) +static void on_eval_script_finished(GDBusProxy *proxy, GAsyncResult *result, Client *c) { - WebKitJavascriptResult *js_result; - JSValueRef value; - JSGlobalContextRef context; - GError *error = NULL; - - js_result = webkit_web_view_run_javascript_finish(WEBKIT_WEB_VIEW(object), result, &error); - if (!js_result) { - vb_echo(c, MSG_ERROR, TRUE, "%s", error->message); - g_error_free(error); - - return; - } - - context = webkit_javascript_result_get_global_context(js_result); - value = webkit_javascript_result_get_value(js_result); - if (JSValueIsString(context, value)) { - JSStringRef str_ref; - char *string; - size_t len; - - str_ref = JSValueToStringCopy(context, value, NULL); - len = JSStringGetMaximumUTF8CStringSize(str_ref); - string = g_new(char, len); - JSStringGetUTF8CString(str_ref, string, len); - JSStringRelease(str_ref); - vb_echo(c, MSG_NORMAL, FALSE, "%s", string); - g_free(string); + gboolean success = FALSE; + char *string = NULL; + + GVariant *return_value = g_dbus_proxy_call_finish(proxy, result, NULL); + if (return_value) { + g_variant_get(return_value, "(bs)", &success, &string); + if (success) { + vb_echo(c, MSG_NORMAL, FALSE, "%s", string); + } else { + vb_echo(c, MSG_ERROR, TRUE, "%s", string); + } + } else { + vb_echo(c, MSG_ERROR, TRUE, ""); } - webkit_javascript_result_unref(js_result); } static VbCmdResult ex_hardcopy(Client *c, const ExArg *arg) diff --git a/src/ext-proxy.c b/src/ext-proxy.c index ea958fe..6957f97 100644 --- a/src/ext-proxy.c +++ b/src/ext-proxy.c @@ -153,9 +153,13 @@ static void on_proxy_created(GDBusProxy *new_proxy, GAsyncResult *result, NULL); } -void ext_proxy_eval_script(Client *c, char *js) +void ext_proxy_eval_script(Client *c, char *js, GAsyncReadyCallback callback) { - dbus_call(c, "EvalJsNoResult", g_variant_new("(s)", js), NULL); + if (callback) { + dbus_call(c, "EvalJs", g_variant_new("(s)", js), callback); + } else { + dbus_call(c, "EvalJsNoResult", g_variant_new("(s)", js), NULL); + } } /** diff --git a/src/ext-proxy.h b/src/ext-proxy.h index 5d4a073..7c70c72 100644 --- a/src/ext-proxy.h +++ b/src/ext-proxy.h @@ -23,7 +23,7 @@ #include "main.h" const char *ext_proxy_init(void); -void ext_proxy_eval_script(Client *c, char *js); +void ext_proxy_eval_script(Client *c, char *js, GAsyncReadyCallback callback); void ext_proxy_focus_input(Client *c); void ext_proxy_set_header(Client *c, const char *headers); diff --git a/src/input.c b/src/input.c index 6236c9d..3e7943c 100644 --- a/src/input.c +++ b/src/input.c @@ -38,7 +38,7 @@ void input_enter(Client *c) * disturbing the user */ gtk_widget_grab_focus(GTK_WIDGET(c->webview)); vb_modelabel_update(c, "-- INPUT --"); - webkit_web_view_run_javascript(c->webview, "var vimb_input_mode_element = document.activeElement;", NULL, NULL, NULL); + ext_proxy_eval_script(c, "var vimb_input_mode_element = document.activeElement;", NULL); } /** @@ -46,7 +46,7 @@ void input_enter(Client *c) */ void input_leave(Client *c) { - webkit_web_view_run_javascript(c->webview, "vimb_input_mode_element.blur();", NULL, NULL, NULL); + ext_proxy_eval_script(c, "vimb_input_mode_element.blur();", NULL); vb_modelabel_update(c, ""); } diff --git a/src/normal.c b/src/normal.c index b7d9234..31cdaa4 100644 --- a/src/normal.c +++ b/src/normal.c @@ -28,6 +28,7 @@ #include "normal.h" #include "scripts/scripts.h" #include "util.h" +#include "ext-proxy.h" typedef enum { PHASE_START, @@ -321,7 +322,7 @@ void pass_enter(Client *c) */ void pass_leave(Client *c) { - webkit_web_view_run_javascript(c->webview, "document.activeElement.blur();", NULL, NULL, NULL); + ext_proxy_eval_script(c, "document.activeElement.blur();", NULL); vb_modelabel_update(c, ""); } @@ -422,9 +423,7 @@ static VbResult normal_fire(Client *c, const NormalCmdInfo *info) * highlight. We use the search_matches as indicator that the searching is * active. */ if (c->state.search.active) { - webkit_web_view_run_javascript(c->webview, - "getSelection().anchorNode.parentNode.click();", NULL, NULL, - NULL); + ext_proxy_eval_script(c, "getSelection().anchorNode.parentNode.click();", NULL); return RESULT_COMPLETE; } @@ -497,7 +496,7 @@ static VbResult normal_increment_decrement(Client *c, const NormalCmdInfo *info) int count = info->count ? info->count : 1; js = g_strdup_printf(INCREMENT_URI_NUMBER, info->key == CTRL('A') ? count : -count); - webkit_web_view_run_javascript(c->webview, js, NULL, NULL, NULL); + ext_proxy_eval_script(c, js, NULL); g_free(js); return RESULT_COMPLETE; @@ -688,19 +687,19 @@ static VbResult normal_scroll(Client *c, const NormalCmdInfo *info) js = g_strdup_printf( "window.scroll(window.scrollX, %d * (1 + (document.height - window.innerHeight) / 100));", info->count); - ext_proxy_eval_script(c, js); + ext_proxy_eval_script(c, js, NULL); g_free(js); return RESULT_COMPLETE; } /* Without count scroll to the end of the page. */ - ext_proxy_eval_script(c, "window.scroll(window.scrollX, document.body.scrollHeight);"); + ext_proxy_eval_script(c, "window.scroll(window.scrollX, document.body.scrollHeight);", NULL); return RESULT_COMPLETE; case '0': - ext_proxy_eval_script(c, "window.scroll(0, window.scrollY);"); + ext_proxy_eval_script(c, "window.scroll(0, window.scrollY);", NULL); return RESULT_COMPLETE; case '$': - ext_proxy_eval_script(c, "window.scroll(document.body.scrollWidth, window.scrollY);"); + ext_proxy_eval_script(c, "window.scroll(document.body.scrollWidth, window.scrollY);", NULL); return RESULT_COMPLETE; default: if (info->key2 == 'g') { @@ -708,18 +707,18 @@ static VbResult normal_scroll(Client *c, const NormalCmdInfo *info) js = g_strdup_printf( "window.scroll(window.scrollX, %d * (1 + (document.height - window.innerHeight) / 100));", info->count); - ext_proxy_eval_script(c, js); + ext_proxy_eval_script(c, js, NULL); g_free(js); return RESULT_COMPLETE; } /* Without count gg scrolls to the top of the page. */ - ext_proxy_eval_script(c, "window.scroll(window.scrollX, 0);"); + ext_proxy_eval_script(c, "window.scroll(window.scrollX, 0);", NULL); return RESULT_COMPLETE; } return RESULT_ERROR; } js = g_strdup_printf("window.scrollBy(%d,%d);", x, y); - ext_proxy_eval_script(c, js); + ext_proxy_eval_script(c, js, NULL); g_free(js); return RESULT_COMPLETE; diff --git a/src/webextension/ext-main.c b/src/webextension/ext-main.c index 661ba28..46a8233 100644 --- a/src/webextension/ext-main.c +++ b/src/webextension/ext-main.c @@ -59,6 +59,11 @@ static const GDBusInterfaceVTable interface_vtable = { static const char introspection_xml[] = "" " " + " " + " " + " " + " " + " " " " " " " " @@ -293,16 +298,29 @@ static void dbus_handle_method_call(GDBusConnection *conn, const char *sender, { char *value; - if (!g_strcmp0(method, "EvalJsNoResult")) { - g_variant_get(parameters, "(s)", &value); + if (g_str_has_prefix(method, "EvalJs")) { + char *result = NULL; + gboolean success; + gboolean no_result = !g_strcmp0(method, "EvalJsNoResult"); + JSValueRef ref = NULL; JSGlobalContextRef jsContext; + g_variant_get(parameters, "(s)", &value); + jsContext = webkit_frame_get_javascript_context_for_script_world( webkit_web_page_get_main_frame(ext.webpage), webkit_script_world_get_default() ); - JSValueRef ref = NULL; - ext_util_js_eval(jsContext, value, &ref); + + success = ext_util_js_eval(jsContext, value, &ref); + + if (no_result) { + g_dbus_method_invocation_return_value(invocation, NULL); + } else { + result = ext_util_js_ref_to_string(jsContext, ref); + g_dbus_method_invocation_return_value(invocation, g_variant_new("(bs)", success, result)); + g_free(result); + } } else if (!g_strcmp0(method, "FocusInput")) { ext_dom_focus_input(webkit_web_page_get_dom_document(ext.webpage)); g_dbus_method_invocation_return_value(invocation, NULL); diff --git a/src/webextension/ext-util.c b/src/webextension/ext-util.c index facb4a7..bdf55d4 100644 --- a/src/webextension/ext-util.c +++ b/src/webextension/ext-util.c @@ -79,3 +79,25 @@ gboolean ext_util_create_tmp_file(const char *content, char **file) return TRUE; } + +/** + * Returns a new allocates string for given value reference. + * String must be freed if not used anymore. + */ +char* ext_util_js_ref_to_string(JSContextRef ctx, JSValueRef ref) +{ + char *string; + size_t len; + JSStringRef str_ref; + + g_return_val_if_fail(ref != NULL, NULL); + + str_ref = JSValueToStringCopy(ctx, ref, NULL); + len = JSStringGetMaximumUTF8CStringSize(str_ref); + + string = g_new0(char, len); + JSStringGetUTF8CString(str_ref, string, len); + JSStringRelease(str_ref); + + return string; +} diff --git a/src/webextension/ext-util.h b/src/webextension/ext-util.h index 877933a..2629dbc 100644 --- a/src/webextension/ext-util.h +++ b/src/webextension/ext-util.h @@ -25,5 +25,6 @@ gboolean ext_util_create_tmp_file(const char *content, char **file); gboolean ext_util_js_eval(JSContextRef ctx, const char *script, JSValueRef *result); +char* ext_util_js_ref_to_string(JSContextRef ctx, JSValueRef ref); #endif /* end of include guard: _EXT_UTIL_H */ -- cgit v1.2.3