1010// @include *
1111// @grant none
1212// @run -at document-body
13- // @version 0.3i
13+ // @version 0.3j
1414// ==/UserScript==
1515
1616/* jshint multistr: true, strict: false, browser: true, devel: true */
@@ -27,10 +27,13 @@ var middleIsStart, startX, startY, startScrollTop, startScrollLeft, lastScrollHe
2727
2828var relativeScrolling , lastX , lastY , scaleX , scaleY , power , offsetMiddle ;
2929
30+ var startAfterLongPress , longPressTimer , eventBeforeLongPress ;
31+
3032// NOTE: Do not run on iframes
3133if ( window . top === window . self ) {
3234 // USER SETTINGS
3335 mouseBtn = 3 ; // 1:left, 2:middle, 3:right mouse button
36+ startAfterLongPress = false ; // Only start scrolling after a long click
3437 reverse = false ; // reversed scroll direction
3538 stopOnSecondClick = false ; // keep scrolling until the left mouse button clicked
3639 verticalScroll = false ; // vertical scrolling
@@ -58,27 +61,67 @@ if (window.top === window.self) {
5861 cursorMask . setAttribute ( "style" , "position: fixed; width: 100%; height: 100%; zindex: 5000; top: 0px; left: 0px; cursor: " + cursorStyle + "; background: none; display: none;" ) ;
5962 document . body . appendChild ( cursorMask ) ;
6063
61- window . addEventListener ( "mousedown" , rightMbDown , false ) ;
64+ window . addEventListener ( "mousedown" , handleMouseDown , false ) ;
65+ window . addEventListener ( "mouseup" , handleMouseUp , false ) ;
6266}
6367
64- function rightMbDown ( e ) {
68+ function handleMouseDown ( e ) {
6569 if ( e . which == mouseBtn ) {
66- if ( ! down ) {
67- down = true ;
68- setStartData ( e ) ;
69- lastX = e . clientX ;
70- lastY = e . clientY ;
71- if ( ! slowScrollStart )
72- scroll ( e ) ;
73- window . addEventListener ( "mousemove" , waitScroll , false ) ;
74- if ( ! stopOnSecondClick )
75- window . addEventListener ( "mouseup" , stop , false ) ;
70+ if ( startAfterLongPress ) {
71+ startLongPress ( e ) ;
7672 } else {
77- stop ( ) ;
73+ if ( ! down ) {
74+ start ( e ) ;
75+ } else {
76+ stop ( ) ;
77+ }
7878 }
7979 }
8080}
8181
82+ function handleMouseUp ( e ) {
83+ if ( startAfterLongPress ) {
84+ cancelLongPress ( ) ;
85+ }
86+ }
87+
88+ function startLongPress ( e ) {
89+ cancelLongPress ( ) ;
90+ eventBeforeLongPress = e ;
91+ longPressTimer = setTimeout ( longPressDetected , 500 ) ;
92+ window . addEventListener ( "mousemove" , cancelLongPress , false ) ;
93+ }
94+
95+ function longPressDetected ( ) {
96+ // Cleanup
97+ cancelLongPress ( ) ;
98+ if ( mouseBtn == 1 ) {
99+ // After a long press with the left mouse button, the browser will start selecting text, which will get messy when we scroll
100+ // So we try to cancel that selection
101+ selectNoText ( ) ;
102+ }
103+ start ( eventBeforeLongPress ) ;
104+ // Give the user a visual indication that scrolling mode has started
105+ cursorMask . style . display = "" ;
106+ }
107+
108+ function cancelLongPress ( ) {
109+ clearTimeout ( longPressTimer ) ;
110+ window . removeEventListener ( "mousemove" , cancelLongPress ) ;
111+ }
112+
113+ function start ( e ) {
114+ down = true ;
115+ setStartData ( e ) ;
116+ lastX = e . clientX ;
117+ lastY = e . clientY ;
118+ if ( ! slowScrollStart )
119+ scroll ( e ) ;
120+ window . addEventListener ( "mousemove" , waitScroll , false ) ;
121+ if ( ! stopOnSecondClick )
122+ window . addEventListener ( "mouseup" , stop , false ) ;
123+ }
124+
82125function setStartData ( e ) {
83126 lastScrollHeight = getScrollHeight ( ) ;
84127 startX = e . clientX ;
@@ -206,3 +249,15 @@ function fFalse() {
206249function slowF ( x ) {
207250 return 1 / ( 1 + Math . pow ( Math . E , ( - 0.1 * x ) ) ) ;
208251}
252+ function selectNoText ( ) {
253+ if ( document . body . createTextRange ) {
254+ const range = document . body . createTextRange ( ) ;
255+ range . select ( ) ;
256+ } else if ( window . getSelection ) {
257+ const selection = window . getSelection ( ) ;
258+ const range = document . createRange ( ) ;
259+ selection . removeAllRanges ( ) ;
260+ } else {
261+ console . warn ( "Could not unselect text: Unsupported browser." ) ;
262+ }
263+ }
0 commit comments