-
Notifications
You must be signed in to change notification settings - Fork 4
/
swipe2nav.js
143 lines (124 loc) · 4.11 KB
/
swipe2nav.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Released under MIT License
var sensitivity = 50;
var timeout = false;
var movement = 0;
var clearMovementTimer = null;
var forceDisable = false;
var pinchZoomScale = 1;
let getSensitivity = browser.storage.local.get("sensitivity").then(s => sensitivity = s.sensitivity, e => console.error(e));
// Modify movement variable and handle its reset
const handleMovement = function(direction)
{
// Clear existing reset timer
clearTimeout(clearMovementTimer);
// Set up new reset timer
clearMovementTimer = setTimeout(function() { movement = 0; }, 800);
// Modify movement
movement += direction;
}
// Return direction for `history.go()` function
const figureoutDirection = function(event)
{
const deltaX = event.deltaX;
const deltaY = event.deltaY;
let direction = NaN;
const isAtEdge = $el => $el.scrollLeft() <= 0 || $el.scrollLeft() + $el.outerWidth() >= $el[0].scrollWidth;
// We start from the element under the mouse pointer (event.target),
// and move up the DOM tree, looking for an element that is not at
// the scroll edge (ie. can be scrolled leftward or rightward). If
// such an element exists, then we want to fail the if condition below
// and return NaN so that we scroll instead of going back. In this case,
// at the end of the loop `el` will be the element that can be scrolled.
let el = event.target;
let atEdge = true;
while(el !== null)
{
atEdge = isAtEdge($(el));
if(!atEdge) break;
el = el.parentElement;
}
// Check we are at either horizontal edge of the page
if (atEdge)
{
// Check we are horizontal scrolling and not vertically
if (Math.abs(deltaX) > 0 && Math.abs(deltaY) == 0)
{
// Go forwards
if (deltaX > 0)
direction = 1;
// Go forwards
else if (deltaX < 0)
direction = -1;
}
}
// If we just hit the edge of something being scrolled right
// after this, we want a little timeout so the user has time
// to stop scrolling at the leftmost/rightmost part.
if(el && !isAtEdge($(el)))
{
timeout = true;
// This timeout is a bit longer since it takes the user
// a short while to realize that they're at the edge and
// stop scrolling.
setTimeout(() => {
timeout = false;
}, 2000);
direction = NaN;
}
return direction;
}
// Main navigation function
const navigate = function(event)
{
// Do nothing when forceDisable is true
if (forceDisable) return;
// Event is scroll event from jquery.mousewheel
goDir = figureoutDirection(event);
// If direction is set disable scroll navigation and go
if (!isNaN(goDir))
{
handleMovement(goDir);
if (Math.abs(movement) > sensitivity)
{
// Hands off mouse events
$(document).off("wheel");
// Check we are not waiting on timeout
if (!timeout)
{
// Lock out timer
timeout = true;
// Navigate
history.go(goDir);
// Re-enable navigation after 500ms to prevent accidental gestures
setTimeout(function() { enableNav() }, 500);
}
}
}
}
// Temporary solution to https://github.com/totu/Swipe2Nav/issues/11
// Disable functionality in pinch-zoom state
function handleResize()
{
pinchZoomScale = window.visualViewport.scale;
forceDisable = (pinchZoomScale > 1);
}
// Enable addon functionality
const enableNav = function()
{
// Detect initial pinch zoom state
handleResize();
// Hook handle resize function to detect pinch zoom
window.visualViewport.addEventListener('resize', handleResize);
// Hook navigate function to mouse movement
$(document).on('mousewheel', navigate);
// Reset timeout boolean
clearTimeout(clearMovementTimer);
movement = 0;
timeout = false;
}
// First run so we can get it working
enableNav();
// Just incase some pages are doing weird things
$(document).ready(function() {
enableNav();
});