Run js by webextension.
authorDaniel Carl <danielcarl@gmx.de>
Thu, 20 Apr 2017 23:07:48 +0000 (01:07 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Thu, 20 Apr 2017 23:10:38 +0000 (01:10 +0200)
Make sure all the scripts we run internally are also evaluated in case
js is disabled.

src/ex.c
src/ext-proxy.c
src/ext-proxy.h
src/input.c
src/normal.c
src/webextension/ext-main.c
src/webextension/ext-util.c
src/webextension/ext-util.h

index 6818ba1..79191b2 100644 (file)
--- 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)
index ea958fe..6957f97 100644 (file)
@@ -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);
+       }
 }
 
 /**
index 5d4a073..7c70c72 100644 (file)
@@ -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);
 
index 6236c9d..3e7943c 100644 (file)
@@ -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, "");
 }
 
index b7d9234..31cdaa4 100644 (file)
@@ -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;
index 661ba28..46a8233 100644 (file)
@@ -59,6 +59,11 @@ static const GDBusInterfaceVTable interface_vtable = {
 static const char introspection_xml[] =
     "<node>"
     " <interface name='" VB_WEBEXTENSION_INTERFACE "'>"
+    "  <method name='EvalJs'>"
+    "   <arg type='s' name='js' direction='in'/>"
+    "   <arg type='b' name='success' direction='out'/>"
+    "   <arg type='s' name='result' direction='out'/>"
+    "  </method>"
     "  <method name='EvalJsNoResult'>"
     "   <arg type='s' name='js' direction='in'/>"
     "  </method>"
@@ -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);
index facb4a7..bdf55d4 100644 (file)
@@ -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;
+}
index 877933a..2629dbc 100644 (file)
@@ -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 */