-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAutoScroll.user.js
executable file
·127 lines (120 loc) · 4.27 KB
/
AutoScroll.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// ==UserScript==
// @name AutoScroll
// @namespace github.com/steventheworker
// @version 0.2
// @description a feature that is solely built into Firefox (within the Apple ecosystem). Use autoscrolling on chrome/Safari with this userscript. (ie: hold middle mouse button to AutoScroll)
// @author Steven G.
// @match *://*/*
// @grant none
// @icon https://upload.wikimedia.org/wikipedia/en/7/71/Safari_14_icon.png
// ==/UserScript==
let millisecs = 33;
let tentativeElement; // the element you want to be scrolling on, other than the window object
let el; //this is equal to tentativeElement, when window won't scroll, resets on mouseup
let scrolling = false;
let refinterval;
let startClick = {};
let cur = {};
let scrollCounter = 0; //every time interval runs +1, resets on mouseup
let initScrollX; //start scrollX, initialized on mousedown
let initScrollY; //start scrollY, initialized on mousedown
let redditMode = 0; // 0 = not reddit.com, 1 = reddit.com (but not a thread), 2 = reddit thread, 3 = reddit thread (overlayed (affects scrolling))
function isScrollable(node) {
const style = getComputedStyle(node);
const x = style.getPropertyValue("overflow-x");
const y = style.getPropertyValue("overflow-y");
return (x !== "visible" && x !== "hidden") ||
(y !== "visible" && y !== "hidden")
? true
: false;
}
function getScrollParent(node) {
if (redditMode && redditMode !== 1 && redditMode !== 2) return redditMode;
if (!node || node === document) return null;
if (isScrollable(node)) return node;
else return getScrollParent(node.parentNode);
}
(function () {
("use strict");
// Check if the URL matches a Reddit thread pattern (overlay scroll fix)
if (window.location.host.includes("reddit.com")) {
const handleRedditURLChange = () => {
if (window.location.href.includes("/comments/")) {
const overlayScrollEl = document.getElementById(
"overlayScrollContainer"
);
redditMode = document.getElementById("overlayScrollContainer") || 2; // prettier-ignore
} else redditMode = 1;
};
window.addEventListener("mouseup", () => {
setTimeout(handleRedditURLChange, 500);
});
handleRedditURLChange();
}
window.addEventListener("mousedown", function (e) {
const isMiddle = e.button === 1;
if (isMiddle) {
tentativeElement = getScrollParent(e.target);
initScrollX = window.scrollX;
initScrollY = window.scrollY;
startClick = {
x: e.pageX - window.scrollX,
y: e.pageY - window.scrollY,
};
scrolling = true;
//interval
refinterval = setInterval(function () {
if (!scrolling) return;
const SameScrollXY =
initScrollX === window.scrollX &&
initScrollY === window.scrollY;
if (scrollCounter === 3 && SameScrollXY) el = tentativeElement; //if no scroll changes within x intervals, scroll tentativeElement instead
if (el || tentativeElement === redditMode)
startClick = {
x: e.pageX,
y: e.pageY,
};
const dx = cur.x - startClick.x;
const dy = cur.y - startClick.y;
scrollCounter++;
if (el || tentativeElement === redditMode)
return el.scrollBy(dx, dy);
window.scroll(dx, dy);
}, millisecs);
addVisual(startClick.x, startClick.y);
}
});
window.addEventListener("mouseup", function (e) {
const isMiddle = e.button === 1;
if (!isMiddle) return;
scrolling = false;
clearInterval(refinterval);
scrollCounter = 0;
el = undefined;
if (visual) visual = visual.remove();
});
window.addEventListener("mousemove", function (e) {
cur = { x: e.pageX, y: e.pageY };
});
})();
// visually indicate where autoScroll was started @ x,y coordinate (Grey "point" (cross/x shaped visual))
let visual;
function addVisual(x, y) {
const old = document.getElementById("autoscroll-visual");
if (old) old.remove(); //remove any old "point's"
visual = document.createElement("div");
visual.id = "autoscroll-visual";
visual.style.position = "fixed";
visual.style.top = y + "px";
visual.style.left = x + "px";
visual.style.width = "4px";
visual.style.height = "4px";
visual.style.marginLeft = "-2px";
visual.style.marginTop = "-2px";
visual.style.background = "grey";
visual.style.display = "inline-block";
visual.style.pointerEvents = "none";
visual.style.zIndex = 9999;
visual.style.outline = "1px dashed black";
document.body.appendChild(visual);
}