Firefox Hide Scrollbars

Hide Scrollbars in Firefox

目前為 2018-06-07 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Firefox Hide Scrollbars
  3. // @namespace http://qashto.com/
  4. // @version 2.0.4
  5. // @description Hide Scrollbars in Firefox
  6. // @author qashto
  7. // @match *://*/*
  8. // @exclude *://www.youtube.com/*
  9. // @run-at document-start
  10. // @grant GM_addStyle
  11. // ==/UserScript==
  12.  
  13. console.log('hiding scrollbars...');
  14.  
  15. // if used as userscript add style with GM_addStyle
  16. try {
  17. GM_addStyle(`
  18. :root {
  19. --scrollbar-height: 0;
  20. --scrollbar-width: 0;
  21. height: 100vh !important;
  22. overflow: hidden !important;
  23. position: relative !important;
  24. width: 100vw !important;
  25. }
  26.  
  27. :root,
  28. body {
  29. max-height: initial !important;
  30. max-width: initial !important;
  31. min-height: initial !important;
  32. min-width: initial !important;
  33. }
  34.  
  35. body {
  36. height: calc(100vh + var(--scrollbar-height)) !important;
  37. overflow: auto !important;
  38. width: calc(100vw + var(--scrollbar-width)) !important;
  39. }
  40. `);
  41. } catch (ror) {}
  42.  
  43. /**
  44. * Compatibility with userscripts. Userscripts run in a different context to
  45. * content scripts and don't need to make structured clones to pass objects
  46. * to page scripts.
  47. */
  48. if (!exportFunction && !cloneInto) {
  49. function exportFunction(func, targetScope, options = {}) {
  50. if (options.defineAs) {
  51. targetScope[options.defineAs] = func;
  52. }
  53.  
  54. return func;
  55. }
  56.  
  57. function cloneInto(obj) {
  58. return obj;
  59. }
  60.  
  61. window.wrappedJSObject = window;
  62.  
  63.  
  64. // Userscript-specific definition of document getters/setters
  65. let documentScrollHandler;
  66. Object.defineProperties(Document.prototype, {
  67. scrollingElement: {
  68. get() {
  69. return document.body;
  70. }
  71. },
  72. onscroll: {
  73. get() {
  74. return documentScrollHandler;
  75. },
  76. set(listener) {
  77. if (documentScrollHandler) {
  78. document.body.removeEventListener("scroll", documentScrollHandler);
  79. }
  80. if (listener) {
  81. documentScrollHandler = listener;
  82. document.body.addEventListener('scroll', documentScrollHandler);
  83. }
  84. }
  85. }
  86. });
  87. } else if (browser && browser.runtime && browser.runtime.id) {
  88. /**
  89. * getters/setters cannot be passed via structured clone, so we have to inject
  90. * a script into the page context.
  91. */
  92.  
  93. const scriptElement = document.createElement("script");
  94. scriptElement.src = browser.runtime.getURL("js/pageContext.js");
  95. scriptElement.addEventListener("load", () => {
  96. scriptElement.remove();
  97. });
  98.  
  99. document.documentElement.appendChild(scriptElement);
  100. }
  101.  
  102. function getScrollbarSize() {
  103. const div = document.createElement('div');
  104. div.style.visibility = 'hidden';
  105. div.style.overflow = 'scroll';
  106. document.documentElement.appendChild(div);
  107.  
  108. const scrollbarHeight = div.offsetHeight - div.clientHeight;
  109. const scrollbarWidth = div.offsetWidth - div.clientWidth;
  110.  
  111. div.remove();
  112.  
  113. return [
  114. scrollbarWidth,
  115. scrollbarHeight
  116. ];
  117. }
  118.  
  119. document.addEventListener('DOMContentLoaded', () => {
  120. const [scrollbarWidth, scrollbarHeight] = getScrollbarSize();
  121.  
  122. document.body.style.setProperty(
  123. '--scrollbar-height', `${scrollbarHeight}px`);
  124. document.body.style.setProperty(
  125. '--scrollbar-width', `${scrollbarWidth}px`);
  126.  
  127.  
  128. document.body.addEventListener('scroll', ev => {
  129. const scrollLeft = cloneInto(document.body.scrollLeft, window);
  130. const scrollTop = cloneInto(document.body.scrollTop, window);
  131.  
  132. window.wrappedJSObject.scrollX = scrollLeft;
  133. window.wrappedJSObject.pageXOffset = scrollLeft;
  134. window.wrappedJSObject.scrollY = scrollTop;
  135. window.wrappedJSObject.pageYOffset = scrollTop;
  136. });
  137.  
  138. exportFunction(document.body.scroll.bind(document.body), window, {
  139. defineAs: 'scroll'
  140. });
  141. exportFunction(document.body.scrollTo.bind(document.body), window, {
  142. defineAs: 'scrollTo'
  143. });
  144. exportFunction(document.body.scrollBy.bind(document.body), window, {
  145. defineAs: 'scrollBy'
  146. });
  147. });
  148.  
  149. function handleAddScrollEvent() {
  150. if (arguments[0] === 'scroll') {
  151. document.body.addEventListener(...arguments);
  152. return;
  153. }
  154. }
  155.  
  156. function handleRemoveScrollEvent() {
  157. if (arguments[0] === 'scroll') {
  158. document.body.removeEventListener(...arguments);
  159. return;
  160. }
  161. }
  162.  
  163.  
  164. const initial_windowAddEventListener = Window.prototype.addEventListener;
  165. const initial_windowRemoveEventListener = Window.prototype.addEventListener;
  166. const initial_documentAddEventListener = Document.prototype.addEventListener;
  167. const initial_documentRemoveEventListener = Document.prototype.addEventListener;
  168.  
  169. function windowAddEventListener() {
  170. handleAddScrollEvent(...arguments);
  171. initial_windowAddEventListener.apply(this, arguments);
  172. }
  173.  
  174. function windowRemoveEventListener() {
  175. handleRemoveScrollEvent(...arguments);
  176. initial_windowAddEventListener.apply(this, arguments);
  177. }
  178.  
  179. function documentAddEventListener() {
  180. handleAddScrollEvent(...arguments);
  181. initial_documentAddEventListener.apply(this, arguments);
  182. }
  183.  
  184. function documentRemoveEventListener() {
  185. handleRemoveScrollEvent(...arguments);
  186. initial_documentAddEventListener.apply(this, arguments);
  187. }
  188.  
  189. exportFunction(windowAddEventListener, Window.prototype, {
  190. defineAs: 'addEventListener'
  191. });
  192. exportFunction(windowRemoveEventListener, Window.prototype, {
  193. defineAs: 'removeEventListener'
  194. });
  195. exportFunction(documentAddEventListener, Document.prototype, {
  196. defineAs: 'addEventListener'
  197. });
  198. exportFunction(documentRemoveEventListener, Document.prototype, {
  199. defineAs: 'removeEventListener'
  200. });
  201.  
  202. console.log('scrollbars hidden!');