forked from mr-pennyworth/alfred-gif
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgif-browser.js
111 lines (95 loc) · 3.02 KB
/
gif-browser.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
// Negative indices for arrays
Array.prototype.get = function(i) {
return this[(i + this.length) % this.length];
};
function isElementInViewport(el) {
let rect = el.getBoundingClientRect();
let right = (window.innerWidth || document.documentElement.clientWidth);
// bottom of the viewport is covered by the footer
// gotta account for that too.
let bottom = (
(window.innerHeight || document.documentElement.clientHeight)
- document.querySelector("footer").getBoundingClientRect().height
);
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= bottom &&
rect.right <= right
);
}
function activate(elem, scroll) {
let active = document.querySelector('.active');
var next = elem;
if (active == next) return;
if (!next || !next.classList.contains('cell')) return;
if (active) active.classList.remove('active');
next.classList.add('active');
// Safari doesn't support smooth scrolling
// http://iamdustan.com/smoothscroll/
if (scroll && !isElementInViewport(next)) {
next.scrollIntoView({behavior: "smooth"});
}
document.querySelector("#caption").textContent =
next.getAttribute("title");
return next.getAttribute("src");
}
function findAncestorCell(elem) {
while (elem) {
if (elem.classList.contains('cell')) {
return elem;
} else {
elem = elem.parentElement;
}
}
}
function activateAtCoords(x, y) {
let elemAtCoords = document.elementFromPoint(x, y);
return activate(findAncestorCell(elemAtCoords), false);
}
function changeActive(nextActiveFunc) {
let active = document.querySelector('.active');
var next = null;
if (active) {
next = nextActiveFunc(active);
} else {
// no active element, so make the first image active.
next = document.querySelector('.cell');
}
return activate(next, true);
}
const prevSibling = (e) => e.previousSibling;
const nextSibling = (e) => e.nextSibling;
const iterateTillMatch = (iterFunc, matchPattern) => {
const inner = (e) => {
var next = iterFunc(e);
// text nodes don't have "matches" method
while (next && (!next.matches || !next.matches(matchPattern))) {
next = iterFunc(next);
}
return next;
};
return inner;
};
const up = () => changeActive(iterateTillMatch(prevSibling, '.cell'));
const down = () => changeActive(iterateTillMatch(nextSibling, '.cell'));
function getAdj(node, right) {
let nodeRect = node.getBoundingClientRect();
let midY = nodeRect.y + nodeRect.height / 2;
let nodeX = nodeRect.x;
let column = node.parentElement;
var adjCol;
if (right) {
adjCol = iterateTillMatch(nextSibling, '.column')(column);
} else {
adjCol = iterateTillMatch(prevSibling, '.column')(column);
}
if (!adjCol) return null;
let allCells = [...adjCol.querySelectorAll('.cell')];
return allCells.filter((cell) => {
let bb = cell.getBoundingClientRect();
return ((bb.y < midY) && (midY <= bb.y + bb.height));
})[0];
}
const right = () => changeActive((e) => getAdj(e, true));
const left = () => changeActive((e) => getAdj(e, false));