Greasy Fork

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.1
// @author             hacker09
// @include            *
// @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