From: Virgil Dupras Date: Tue, 2 May 2017 00:34:53 +0000 (-0400) Subject: Make hints wotk in "new window" mode X-Git-Url: https://git.owens.tech/assets/static/git-logo.png/assets/static/git-logo.png/git?a=commitdiff_plain;h=81f543df5763f8efbfe7a20ad02fc1db8a9d61e4;p=vimb.git Make hints wotk in "new window" mode The old "set target to _blank" trick doesn't work anymore since the whole "noopener" vulnerability thing (https://mathiasbynens.github.io/rel-noopener/) I couldn't find a workaround. We're unfortunately now limited in the kind of elements we can interact with in "new window" mode. --- diff --git a/src/hints.c b/src/hints.c index 3cd9e5f..8a5f921 100644 --- a/src/hints.c +++ b/src/hints.c @@ -19,6 +19,7 @@ #include "config.h" #include +#include #include #include #include @@ -32,11 +33,9 @@ #include "ext-proxy.h" static struct { - JSObjectRef obj; /* the js object */ char mode; /* mode identifying char - that last char of the hint prompt */ int promptlen; /* length of the hint prompt chars 2 or 3 */ gboolean gmode; /* indicate if the hints 'g' mode is used */ - JSContextRef ctx; /* holds the setting if JavaScript can open windows automatically that we * have to change to open windows via hinting */ gboolean allow_open_win; @@ -45,7 +44,7 @@ static struct { extern struct Vimb vb; -static void call_hints_function(Client *c, const char *func, char* args); +static void call_hints_function(Client *c, const char *func, const char* args); static void fire_timeout(Client *c, gboolean on); static gboolean fire_cb(gpointer data); @@ -89,17 +88,15 @@ void hints_clear(Client *c) call_hints_function(c, "clear", ""); - /* g_signal_emit_by_name(c->webview, "hovering-over-link", NULL, NULL); */ - /* if open window was not allowed for JavaScript, restore this */ - /* if (!hints.allow_open_win) { */ - /* WebKitWebSettings *setting = webkit_web_view_get_settings(c->webview); */ - /* g_object_set(G_OBJECT(setting), "javascript-can-open-windows-automatically", hints.allow_open_win, NULL); */ - /* } */ + if (!hints.allow_open_win) { + WebKitSettings *setting = webkit_web_view_get_settings(c->webview); + g_object_set(G_OBJECT(setting), "javascript-can-open-windows-automatically", hints.allow_open_win, NULL); + } } } -void hints_create(Client *c, char *input) +void hints_create(Client *c, const char *input) { char *jsargs; @@ -115,16 +112,16 @@ void hints_create(Client *c, char *input) if (!(c->mode->flags & FLAG_HINTING)) { c->mode->flags |= FLAG_HINTING; - /* WebKitWebSettings *setting = webkit_web_view_get_settings(c->webview); */ + WebKitSettings *setting = webkit_web_view_get_settings(c->webview); /* before we enable JavaScript to open new windows, we save the actual * value to be able restore it after hints where fired */ - /* g_object_get(G_OBJECT(setting), "javascript-can-open-windows-automatically", &(hints.allow_open_win), NULL); */ + g_object_get(G_OBJECT(setting), "javascript-can-open-windows-automatically", &(hints.allow_open_win), NULL); /* if window open is already allowed there's no need to allow it again */ - /* if (!hints.allow_open_win) { */ - /* g_object_set(G_OBJECT(setting), "javascript-can-open-windows-automatically", true, NULL); */ - /* } */ + if (!hints.allow_open_win) { + g_object_set(G_OBJECT(setting), "javascript-can-open-windows-automatically", true, NULL); + } hints.promptlen = hints.gmode ? 3 : 2; @@ -133,7 +130,7 @@ void hints_create(Client *c, char *input) hints.gmode ? "true" : "false", MAXIMUM_HINTS, GET_CHAR(c, "hintkeys"), - GET_BOOL(c, "hint-follow-last") ? "true" : "false", + GET_BOOL(c, "hint-follow-last") ? "true" : "false", GET_BOOL(c, "hint-number-same-length") ? "true" : "false" ); @@ -145,8 +142,10 @@ void hints_create(Client *c, char *input) return; } - jsargs = *(input + hints.promptlen) ? input + hints.promptlen : ""; - call_hints_function(c, "filter", jsargs); + call_hints_function( + c, "filter", + *(input + hints.promptlen) ? input + hints.promptlen : "" + ); } void hints_focus_next(Client *c, const gboolean back) @@ -161,6 +160,11 @@ void hints_fire(Client *c) void hints_follow_link(Client *c, const gboolean back, int count) { + /* TODO implement outside of hints.c */ + /* We would previously "piggyback" on hints.js for the "js" part of this feature + * but this would actually be more elegant in its own JS file. This has nothing + * to do with hints. + */ /* char *json = g_strdup_printf( */ /* "[%s]", */ /* back ? vb.config.prevpattern : vb.config.nextpattern */ @@ -249,8 +253,7 @@ static void hints_function_callback(GDBusProxy *proxy, GAsyncResult *result, Cli gboolean success = FALSE; char *value = NULL; - g_print("callback!\n"); - GVariant *return_value = g_dbus_proxy_call_finish(proxy, result, NULL); + GVariant *return_value = g_dbus_proxy_call_finish(proxy, result, NULL); if (!return_value) { return; } @@ -259,19 +262,11 @@ static void hints_function_callback(GDBusProxy *proxy, GAsyncResult *result, Cli if (!success) { return; } - g_print("foo! %s\n", value); if (!strncmp(value, "ERROR:", 6)) { return; } - if (!strncmp(value, "OVER:", 5)) { - /* g_signal_emit_by_name( */ - /* c->webview, "hovering-over-link", NULL, *(value + 5) == '\0' ? NULL : (value + 5) */ - /* ); */ - return; - } - /* following return values mark fired hints */ if (!strncmp(value, "DONE:", 5)) { fire_timeout(c, false); @@ -346,7 +341,7 @@ static void hints_function_callback(GDBusProxy *proxy, GAsyncResult *result, Cli } } -static void call_hints_function(Client *c, const char *func, char* args) +static void call_hints_function(Client *c, const char *func, const char* args) { char *jscode; @@ -367,7 +362,6 @@ static void fire_timeout(Client *c, gboolean on) if (on) { millis = GET_INT(c, "hint-timeout"); - g_print("millis %d", millis); if (millis) { hints.timeout_id = g_timeout_add(millis, (GSourceFunc)fire_cb, c); } diff --git a/src/hints.h b/src/hints.h index 1b23e86..6821554 100644 --- a/src/hints.h +++ b/src/hints.h @@ -23,7 +23,7 @@ #include "main.h" VbResult hints_keypress(Client *c, int key); -void hints_create(Client *c, char *input); +void hints_create(Client *c, const char *input); void hints_fire(Client *c); void hints_follow_link(Client *c, gboolean back, int count); void hints_increment_uri(Client *c, int count); diff --git a/src/normal.c b/src/normal.c index 156ef52..73c9a3a 100644 --- a/src/normal.c +++ b/src/normal.c @@ -621,7 +621,7 @@ static VbResult normal_pass(Client *c, const NormalCmdInfo *info) static VbResult normal_prevnext(Client *c, const NormalCmdInfo *info) { -#if 0 /* TODO need hinting to be available */ +#if 0 /* TODO implement outside of hints.js */ int count = info->count ? info->count : 1; if (info->key2 == ']') { hints_follow_link(FALSE, count); diff --git a/src/scripts/hints.js b/src/scripts/hints.js index 6f3530f..c381e45 100644 --- a/src/scripts/hints.js +++ b/src/scripts/hints.js @@ -397,18 +397,15 @@ var hints = Object.freeze((function(){ /* internal used methods */ function open(e, newWin) { - var oldTarget = e.target; - if (newWin) { - /* set target to open in new window */ - e.target = "_blank"; - } else if (e.target === "_blank") { - e.removeAttribute("target"); + if (newWin && e.hasAttribute('href')) { + /* Since the "noopener" vulnerability thing, it's not possible to set an anchor's + * target to _blank. Therefore, we can't simulate ctrl-click through _blank like we + * used to. Therefore, we limit ourselves to "window.open()" in cases we're firing a + * simple link. In other cases, we fire the even normally. + */ + window.open(e.getAttribute('href'), '_blank'); } - /* to open links in new window the mouse events are fired with ctrl */ - /* key - otherwise some ugly pages will ignore this attribute in their */ - /* mouse event observers like duckduckgo */ - click(e, newWin); - e.target = oldTarget; + click(e); } /* set focus on hint with given index valid hints array */ @@ -424,24 +421,22 @@ var hints = Object.freeze((function(){ activeHint.e.classList.add(fClass); activeHint.label.classList.add(fClass); mouseEvent(activeHint.e, "mouseover"); - - return "OVER:" + getSrc(activeHint.e);; } } - function click(e, ctrl) { - mouseEvent(e, "mouseover", ctrl); - mouseEvent(e, "mousedown", ctrl); - mouseEvent(e, "mouseup", ctrl); - mouseEvent(e, "click", ctrl); + function click(e) { + mouseEvent(e, "mouseover"); + mouseEvent(e, "mousedown"); + mouseEvent(e, "mouseup"); + mouseEvent(e, "click"); } - function mouseEvent(e, name, ctrl) { + function mouseEvent(e, name) { var evObj = e.ownerDocument.createEvent("MouseEvents"); evObj.initMouseEvent( name, true, true, e.ownerDocument.defaultView, 0, 0, 0, 0, 0, - (typeof ctrl != "undefined") ? ctrl : false, false, false, false, 0, null + false, false, false, false, 0, null ); e.dispatchEvent(evObj); }