summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Gläßer <tobimensch@users.noreply.github.com>2018-10-29 10:05:09 -0400
committerThomas Buckley-Houston <tom@tombh.co.uk>2019-06-24 09:09:58 +0300
commit15c7b45b6feb37a6cfcb5b9f4cf8caa78e9e3b27 (patch)
tree940afca61fe1d6b368180b1f83c5ae777907eca7
parent7b7e6bc308321220d52e5c7d39890321755bade8 (diff)
Added features needed for vim like navigation to the webextension.
-rw-r--r--webext/src/background/tab_commands_mixin.js3
-rw-r--r--webext/src/dom/commands_mixin.js189
2 files changed, 183 insertions, 9 deletions
diff --git a/webext/src/background/tab_commands_mixin.js b/webext/src/background/tab_commands_mixin.js
index d26baeb..99f66c8 100644
--- a/webext/src/background/tab_commands_mixin.js
+++ b/webext/src/background/tab_commands_mixin.js
@@ -17,6 +17,9 @@ export default MixinBase =>
case "/frame_pixels":
this.sendToTerminal(`/frame_pixels,${message.slice(14)}`);
break;
+ case "/link_hints":
+ this.sendToTerminal(`/link_hints,${message.slice(12)}`);
+ break;
case "/tab_info":
incoming = JSON.parse(utils.rebuildArgsToSingleArg(parts));
this._updateTabInfo(incoming);
diff --git a/webext/src/dom/commands_mixin.js b/webext/src/dom/commands_mixin.js
index 10b357d..3541cac 100644
--- a/webext/src/dom/commands_mixin.js
+++ b/webext/src/dom/commands_mixin.js
@@ -1,4 +1,10 @@
import utils from "utils";
+import { Rect } from "vimium";
+import { DomUtils } from "vimium";
+import { LocalHints } from "vimium";
+import { VimiumNormal } from "vimium";
+import { MiscVimium } from "vimium";
+MiscVimium();
export default MixinBase =>
class extends MixinBase {
@@ -35,19 +41,148 @@ export default MixinBase =>
break;
case "/url":
url = utils.rebuildArgsToSingleArg(parts);
- document.location.href = url;
+ window.location.href = url;
+ break;
+ case "/url_up":
+ this.urlUp();
+ break;
+ case "/url_root":
+ window.location.href = window.location.origin;
break;
case "/history_back":
history.go(-1);
break;
+ case "/history_forward":
+ history.go(1);
+ break;
+ case "/reload":
+ window.location.reload();
+ break;
case "/window_stop":
window.stop();
break;
+ case "/find_next":
+ this.findNext(parts[1]);
+ break;
+ case "/find_previous":
+ window.find(parts[1], false, true, false, false, true, true);
+ break;
+ case "/get_link_hints":
+ this.getLinkHints(false);
+ break;
+ case "/get_clickable_hints":
+ this.getLinkHints(true);
+ break;
+ case "/focus_first_text_input":
+ this.focusFirstTextInput();
+ break;
+ case "/follow_link_labeled_next":
+ this._followLinkLabeledNext();
+ break;
+ case "/follow_link_labeled_previous":
+ this._followLinkLabeledPrevious();
+ break;
default:
this.log("Unknown command sent to tab", message);
}
}
+ focusFirstTextInput() {
+ VimiumNormal.focusInput(1);
+ }
+
+ //adapted vimium code
+ followLinkLabeledNext() {
+ var nextPatterns = "next,more,newer,>,›,→,»,≫,>>,weiter" || "";
+ var nextStrings = nextPatterns.split(",").filter(function(s) {
+ return s.trim().length;
+ });
+ return (
+ VimiumNormal.findAndFollowRel("next") ||
+ VimiumNormal.findAndFollowLink(nextStrings)
+ );
+ }
+
+ _followLinkLabeledNext() {
+ this.followLinkLabeledNext();
+ }
+
+ //adapted vimium code
+ followLinkLabeledPrevious() {
+ var previousPatterns =
+ "prev,previous,back,older,<,‹,←,«,≪,<<,zurück" || "";
+ var previousStrings = previousPatterns.split(",").filter(function(s) {
+ return s.trim().length;
+ });
+ return (
+ VimiumNormal.findAndFollowRel("prev") ||
+ VimiumNormal.findAndFollowLink(previousStrings)
+ );
+ }
+
+ _followLinkLabeledPrevious() {
+ this.followLinkLabeledPrevious();
+ }
+
+ urlUp() {
+ // this is taken from vimium's code
+ var url = window.location.href;
+ if (url[url.length - 1] === "/") {
+ url = url.substring(0, url.length - 1);
+ }
+ var urlsplit = url.split("/");
+ // make sure we haven't hit the base domain yet
+ if (urlsplit.length > 3) {
+ urlsplit = urlsplit.slice(0, Math.max(3, urlsplit.length - 1));
+ window.location.href = urlsplit.join("/");
+ }
+ }
+
+ getLinkHints(clickable) {
+ var hints = LocalHints.getLocalHints(!clickable);
+ var rect, bottom, top, left, right, width, height, results, result, href;
+ results = [];
+ for (let idx in hints) {
+ if (!hints[idx].hasOwnProperty("rect")) {
+ continue;
+ }
+ href = hints[idx]["href"];
+ rect = hints[idx]["rect"];
+ bottom = Math.round(
+ ((rect["bottom"] - window.scrollY) *
+ this.dimensions.scale_factor.height) /
+ 2
+ );
+ top = Math.round(
+ ((rect["top"] - window.scrollY) *
+ this.dimensions.scale_factor.height) /
+ 2
+ );
+ left = Math.round(rect["left"] * this.dimensions.scale_factor.width);
+ right = Math.round(rect["right"] * this.dimensions.scale_factor.width);
+ result = Rect.create(left, top, right, bottom);
+ result.href = href;
+ results.push(result);
+ }
+ this.sendMessage(`/link_hints,${JSON.stringify(results)}`);
+ }
+
+ findNext(text) {
+ window.find(text, false, false, false, false, true, true);
+ //var s = window.getSelection();
+ //var oRange = s.getRangeAt(0); //get the text range
+ //var oRect = oRange.getBoundingClientRect();
+ //window.scrollTo(400, 20000);
+ this.dimensions.y_scroll = Math.round(
+ window.scrollY * this.dimensions.scale_factor.height
+ );
+ this.dimensions.x_scroll = Math.round(
+ window.scrollX * this.dimensions.scale_factor.width
+ );
+ this.dimensions.update();
+ this._mightSendBigFrames();
+ }
+
_launch() {
const mode = this.config.http_server_mode_type;
if (mode.includes("raw_text_")) {
@@ -119,9 +254,25 @@ export default MixinBase =>
_handleMouse(input) {
switch (input.button) {
case 1:
- this._mouseAction("mousemove", input.mouse_x, input.mouse_y);
+ var y_hack = false;
+ if (input.hasOwnProperty("y_hack")) {
+ y_hack = true;
+ }
+ this._mouseAction(
+ "mousemove",
+ input.mouse_x,
+ input.mouse_y,
+ 0,
+ y_hack
+ );
if (!this._mousedown) {
- this._mouseAction("mousedown", input.mouse_x, input.mouse_y);
+ this._mouseAction(
+ "mousedown",
+ input.mouse_x,
+ input.mouse_y,
+ 0,
+ y_hack
+ );
setTimeout(() => {
this.sendSmallTextFrame();
}, 500);
@@ -129,10 +280,26 @@ export default MixinBase =>
this._mousedown = true;
break;
case 0:
- this._mouseAction("mousemove", input.mouse_x, input.mouse_y);
+ var y_hack = false;
+ if (input.hasOwnProperty("y_hack")) {
+ y_hack = true;
+ }
+ this._mouseAction(
+ "mousemove",
+ input.mouse_x,
+ input.mouse_y,
+ 0,
+ y_hack
+ );
if (this._mousedown) {
- this._mouseAction("click", input.mouse_x, input.mouse_y);
- this._mouseAction("mouseup", input.mouse_x, input.mouse_y);
+ this._mouseAction("click", input.mouse_x, input.mouse_y, 0, y_hack);
+ this._mouseAction(
+ "mouseup",
+ input.mouse_x,
+ input.mouse_y,
+ 0,
+ y_hack
+ );
}
this._mousedown = false;
break;
@@ -186,8 +353,12 @@ export default MixinBase =>
}
}
- _mouseAction(type, x, y) {
- const [dom_x, dom_y] = this._getDOMCoordsFromMouseCoords(x, y);
+ _mouseAction(type, x, y, button, y_hack = false) {
+ let [dom_x, dom_y] = this._getDOMCoordsFromMouseCoords(x, y);
+ if (y_hack) {
+ const [dom_x2, dom_y2] = this._getDOMCoordsFromMouseCoords(x, y + 1);
+ dom_y = (dom_y + dom_y2) / 2;
+ }
const element = document.elementFromPoint(
dom_x - window.scrollX,
dom_y - window.scrollY
@@ -208,7 +379,7 @@ export default MixinBase =>
false,
false,
false,
- 0,
+ button,
null
);
element.dispatchEvent(clickEvent);