Opera Browser Mouse Gestures

This script works on any browser and simulates the Opera Browser Mouse Gestures, but allows you to modify or disable them as you want.

目前为 2021-01-07 提交的版本。查看 最新版本

// ==UserScript==
// @name               Opera Browser Mouse Gestures
// @namespace          OperaBrowserGestures
// @description        This script works on any browser and simulates the Opera Browser Mouse Gestures, but allows you to modify or disable them as you want.
// @version            0.0.2
// @author             hacker09
// @include            *
// @icon               https://www.google.com/s2/favicons?domain=www.opera.com
// @run-at             document-start
// @grant              GM_openInTab
// @grant              window.close
// ==/UserScript==

// --- Script Settings Below ---
const SENSITIVITY = 3; // Adjust the script mouse senvity here between 1 ~ 5
const TOLERANCE = 3; // Adjust the script mouse tolerance here between  1 ~ 5

const funcs = { //Variable to store the functions
  'L': function() { //Function that will run when the mouse movement Left is performed
    window.history.back(); //Go Back
  }, //Finishes the mouse movement Left
  'R': function() { //Function that will run when the mouse movement Right is performed
    window.history.forward(); //Go Foward
  }, //Finishes the mouse movement Right
  'D': function() { //Function that will run when the mouse movement Down is performed
    if (IsShiftNotPressed) { //If the shift key isn't being pressed
      GM_openInTab(link, { //Open the link on a new tab
        active: true, //Focus on the new tab
        insert: true, //Insert the new tab after the actual tab
        setParent: true //Return to the tab the user was in
      }); //Open the link that was hovered
      setTimeout(function() { //Starts the settimeout function
        link = 'about:newtab'; //Make the script open a new browser tab if no links were hovered
      }, 100); //Finishes the settimeout function
    } //Finishes the if condition
    IsShiftNotPressed = true; //Variable to hold the shift key status
  }, //Finishes the mouse movement Down
  'UD': function() { //Function that will run when the mouse movement Up+Down is performed
    window.location.reload(); //Reload the Tab
  }, //Finishes the mouse movement Up+Down
  'DR': function() { //Function that will run when the mouse movement Down+Right is performed
    window.top.close(); //Close the tab
  }, //Finishes the mouse movement Down+Right
  'DU': function() { //Function that will run when the mouse movement Down+Up is performed
    GM_openInTab(link, { //Open the link that was hovered
      active: false, //Don't focus on the new tab
      insert: true, //Insert the new tab after the actual tab
      setParent: true //Return to the tab the user was in
    }); //Open the link that was hovered on a new background tab
    setTimeout(function() { //Starts the setimeout function
      link = 'about:newtab'; //Make the script open a browser tab if no links were hovered
    }, 100); //Finishes the setimeout function
  } //Finishes the mouse movement Down+Up
}; //Finishes the variable to store the functions

// ---------------- Below this line is the math codes that track the mouse movements

const s = 1 << ((7 - SENSITIVITY) << 1);
const t1 = Math.tan(0.15708 * TOLERANCE),
  t2 = 1 / t1;

let x, y, path;

const tracer = function(e) {
  let cx = e.clientX,
    cy = e.clientY,
    deltaX = cx - x,
    deltaY = cy - y,
    distance = deltaX * deltaX + deltaY * deltaY;
  if (distance > s) {
    let slope = Math.abs(deltaY / deltaX),
      direction = '';
    if (slope > t1) {
      direction = deltaY > 0 ? 'D' : 'U';
    } else if (slope <= t2) {
      direction = deltaX > 0 ? 'R' : 'L';
    }
    if (path.charAt(path.length - 1) !== direction) {
      path += direction;
    }
    x = cx;
    y = cy;
  }
};

window.addEventListener('mousedown', function(e) {
  if (e.which === 3) {
    x = e.clientX;
    y = e.clientY;
    path = "";
    window.addEventListener('mousemove', tracer, false);
  }
}, false);

window.addEventListener('contextmenu', function(e) {
  window.removeEventListener('mousemove', tracer, false);
  if (path !== "") {
    e.preventDefault();
    if (funcs.hasOwnProperty(path)) {
      funcs[path]();
    }
  }
}, false);


var link; //Make the variable global
document.addEventListener('mouseover', function(event) { //Add an advent listener to the page
  var hoveredEl = event.target; // The actual element which was hovered.
  if (hoveredEl.tagName !== 'A') { //If the element isn't a
    return; //Ignore non links
  } //Finishes the if condition
  link = hoveredEl.href; //Store the actual hovered link to a variable
}); //Finishes the advent listener

var IsShiftNotPressed = true; //Variable to hold the shift key status
window.addEventListener("contextmenu", function(e) { //Adds an advent listener to the page to know when the shift key is pressed or not
  if (e.shiftKey) { //If the shift key was pressed
    window.open(link, '_blank', 'height=' + window.screen.height + ',width=' + window.screen.width); //Open the link on a new window
    IsShiftNotPressed = false; //Variable to hold the shift key status
  } //Finishes the if condition
}, false); //Finishes the advent listener