-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathduration-filter.user.js
76 lines (68 loc) · 2.43 KB
/
duration-filter.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
// ==UserScript==
// @name Youtube Duration Filter
// @namespace http://tampermonkey.net/
// @version 0.1
// @description
// @author Josh Parker
// @match https://www.youtube.com/c/*/videos*
// @match https://www.youtube.com/channel/*/videos*
// @match https://www.youtube.com/user/*/videos*
// @match https://www.youtube.com/@*/videos
// @icon https://www.google.com/s2/favicons?domain=youtube.com
// @grant none
// ==/UserScript==
(function userScript() {
const parseDuration = function parseDuration(duration) {
const durationMatch = duration.match(/(((?<hours>\d+):)?(?<minutes>\d+):)?(?<seconds>\d+)/);
if (durationMatch) {
const { hours, minutes, seconds } = durationMatch.groups;
return +seconds + (minutes || 0) * 60 + (hours || 0) * 3600;
}
return null;
};
const ygvrDuration = function ygvrDurationMapper(ygvr) {
const durationElement = ygvr.querySelector('span.ytd-thumbnail-overlay-time-status-renderer');
if (durationElement) {
const text = durationElement.innerText;
return parseDuration(text);
}
return null;
};
const durationFilterForm = document.createElement('form');
durationFilterForm.innerHTML = `
<h2>duration filter</h2>
<h3>format hh:mm:ss</h3>
<label for="duration-filter-min">min</label>
<input id="duration-filter-min" type="text" pattern="(([0-9]?\\d:)?[0-5]?\\d:)?[0-5]?\\d" />
<br><label for="duration-filter-max">max</label>
<input id="duration-filter-max" type="text" pattern="(([0-9]?\\d:)?[0-5]?\\d:)?[0-5]?\\d" />
<button>filter</button>
`;
durationFilterForm.id = 'duration-filter';
durationFilterForm.onsubmit = function filterDurations(event) {
event.preventDefault();
const min = parseDuration(document.querySelector('input#duration-filter-min').value);
const max = parseDuration(document.querySelector('input#duration-filter-max').value);
const ygvrNodeList = document.querySelectorAll(
'ytd-rich-grid-row #contents ytd-rich-item-renderer',
);
ygvrNodeList.forEach((node) => {
const duration = ygvrDuration(node);
if (!duration || duration > max || duration < min) {
node.parentNode.removeChild(node);
}
});
};
const styleCss = `
form#duration-filter {
position: fixed;
bottom: 0;
right: 0;
z-index: 0;
}
`;
const style = document.createElement('style');
style.appendChild(new Text(styleCss));
document.body.appendChild(durationFilterForm);
document.body.appendChild(style);
}());