More Keybinds

Adds some extra keystrokes to Firefox.

目前為 2020-01-30 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name More Keybinds
  3. // @namespace MK
  4. // @description Adds some extra keystrokes to Firefox.
  5. // @version 1.2.3
  6. // @include *
  7. // @run-at document-start
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. // jQuery might be present
  12. /* eslint-env jquery */
  13.  
  14. // Not all keys fire a keypress event (Chrome 2010), so we use keydown.
  15. document.addEventListener('keydown', keypressListener, false);
  16.  
  17. function keypressListener(evt) {
  18. var code = evt.keyCode || evt.which;
  19.  
  20. /*
  21. var modifierReport = "";
  22. modifierReport += ( evt.ctrlKey ? "Ctrl " : "" );
  23. modifierReport += ( evt.shiftKey ? "Shift " : "" );
  24. modifierReport += ( evt.altKey ? "Alt " : "" );
  25. GM_log("Caught keypress "+code+" with modifiers: "+modifierReport);
  26. */
  27.  
  28. // Actions
  29.  
  30. // Ctrl+Delete goes Back
  31. if (code == 8 && evt.ctrlKey) {
  32. window.history.back();
  33. }
  34.  
  35. // Ctrl+Enter goes Forward
  36. if (code == 13 && evt.ctrlKey) {
  37. window.history.forward();
  38. }
  39.  
  40. /* These conflict with selecting words in text!
  41.  
  42. // Ctrl+Shift+Left goes Back
  43. if (code == 37 && evt.ctrlKey && evt.shiftKey) {
  44. window.history.back();
  45. }
  46.  
  47. // Ctrl+Shift+Right goes Forward
  48. if (code == 39 && evt.ctrlKey && evt.shiftKey) {
  49. window.history.forward();
  50. }
  51.  
  52. */
  53.  
  54. // Ctrl+Shift+Up goes up in the URL path (removes the tail leaf)
  55. // Cmd+Alt+Up on macOS also works
  56. if ((code == 38 && evt.ctrlKey && evt.shiftKey) || (evt.code == 'ArrowUp' && evt.altKey && evt.metaKey)) {
  57. var newURL = document.location.href;
  58. if (newURL.slice(-1)=='/') {
  59. newURL = newURL.slice(0,-1);
  60. }
  61. document.location.href = document.location.href.replace(/[#/?][^#/?]*[/]*$/,'');
  62. }
  63.  
  64. // Do not intercept any of the keys below when the user is focused on an input or textarea.
  65. /*
  66. //var focusedElement = document.activeElement; // document.body if no input is focused
  67. var focusedElement = evt.target || event.srcElement;
  68. if (focusedElement) {
  69. var isInput = focusedElement.nodeName === 'INPUT' || focusedElement.nodeName === 'TEXTAREA';
  70. if (isInput) {
  71. return;
  72. }
  73. }
  74. */
  75. // From next_imageprevious_image.user.js:
  76. if (evt.target.tagName && evt.target.tagName.match(/input|select|textarea/i) || evt.target.getAttribute('contenteditable')==="true") {
  77. return;
  78. }
  79.  
  80. if (!evt.ctrlKey && !evt.shiftKey && !evt.metaKey) {
  81. if (document.location.host !== "9gag.com" /* && document.location.host !== "github.com" */) {
  82. if (code === 'K'.charCodeAt(0)) {
  83. bestScrollBy(-getScrollAmount());
  84. }
  85.  
  86. if (code === 'J'.charCodeAt(0)) {
  87. bestScrollBy(+getScrollAmount());
  88. }
  89. }
  90. }
  91.  
  92. }
  93.  
  94. // Try to perform a smooth vertical scroll, but fall back to a jump scroll if neccessary
  95. function bestScrollBy(amount) {
  96. if (typeof window.scrollBy === 'function') {
  97. // If browser has native scrollBy, use that
  98. window.scrollBy({
  99. left: 0,
  100. top: amount,
  101. behavior: 'smooth'
  102. });
  103. } else if (typeof $ !== "undefined" && $.fn && $.fn.animate) {
  104. // Otherwise, if jQuery is present, use that
  105. queue(function(next){
  106. $("html,body").animate({scrollTop: $(document).scrollTop() + amount}, 200, "swing", ifBody(next));
  107. });
  108. } else {
  109. // Otherwise perform a jerky scroll
  110. // Does not do anything in Chrome:
  111. document.body.scrollTop += amount;
  112. // Works in Chrome/Firefox:
  113. document.documentElement.scrollTop += amount;
  114. }
  115. }
  116.  
  117. function getScrollAmount() {
  118. return window.innerHeight / 6;
  119. }
  120.  
  121. function ifBody(fn) {
  122. return function(){
  123. // jQuery calls complete once for each element, and we have two elements. Annoying!
  124. if (this === document.body) {
  125. fn();
  126. }
  127. };
  128. }
  129.  
  130. var actions = [];
  131. var running = false;
  132. function queue(action) {
  133. actions.push(action);
  134. if (!running) {
  135. dequeue();
  136. }
  137. }
  138. function dequeue() {
  139. if (actions.length > 0) {
  140. var nextAction = actions.shift();
  141. running = true;
  142. nextAction(dequeue);
  143. } else {
  144. running = false;
  145. }
  146. }