Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 59 additions & 42 deletions youtube-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2160,12 +2160,19 @@ ImprovedTube.channelDefaultTab = function() {
7.0 SHORTCUTS
--------------------------------------------------------------------------------
TODO: CONNECT & TEST
TODO: Use keyboard library
------------------------------------------------------------------------------*/

ImprovedTube.shortcuts = function() {
const printError = (section, message) => {
console.error(`%c[Improve YouTube!] ${section}%c – ${message}`, "font-weight: bold; color: red;", "font-weight: unset; color: unset;");
}

var self = this,
keys = {},
/** @type {Partial<Pick<KeyboardEvent, "keyCode" | "altKey" | "shiftKey" | "ctrlKey" | "metaKey">>} */
pressedKey = {},
wheel = 0,
/** Is cursor under the video element */
hover = false,
status_timer;

Expand All @@ -2192,11 +2199,36 @@ ImprovedTube.shortcuts = function() {
}, 500);
}

function start(type = 'keys') {
/**
* @param {KeyboardEvent | WheelEvent} event
*/
function trigger(event) {
if (document.activeElement && ['EMBED', 'INPUT', 'OBJECT', 'TEXTAREA', 'IFRAME'].indexOf(document.activeElement.tagName) !== -1 || event.target.isContentEditable) {
return false;
return;
}

const buttonsSelectors = {
like: "#menu #top-level-buttons-computed ytd-toggle-button-renderer:nth-child(1) a",
dislike: "#menu #top-level-buttons-computed ytd-toggle-button-renderer:nth-child(2) a",
subscribe: "#subscribe-button a"
};
const pressButton = (
/** @type {keyof typeof buttonsSelectors} */
button
) => {
const elems = document.querySelectorAll(buttonsSelectors[button]);
const visibleButton = [].find.call(elems, elem => elem.offsetParent !== null);
// TODO throw natural error with `cause`
if (!visibleButton) {
const player = document.querySelector('#movie_player');
// if there is no player the most likely we are not in watch page?
if (!player) return;
printError("Shortcuts", `Can't find ${button} button in visible DOM`);
return;
}
visibleButton.click();
};

var features = {
shortcut_auto: function() {
var player = document.querySelector('#movie_player');
Expand Down Expand Up @@ -2476,25 +2508,14 @@ ImprovedTube.shortcuts = function() {
}
},
shortcut_like_shortcut: function() {
var like = (document.querySelectorAll('#menu #top-level-buttons-computed ytd-toggle-button-renderer')[0]);

if (like) {
like.click();
}
pressButton("like")
},
shortcut_dislike_shortcut: function() {
var like = (document.querySelectorAll('#menu #top-level-buttons-computed ytd-toggle-button-renderer')[1]);

if (like) {
like.click();
}
pressButton("dislike")
},
shortcut_subscribe: function() {
var button = document.querySelector('#subscribe-button .ytd-subscribe-button-renderer');
pressButton("subscribe")

if (button) {
button.click();
}
},
shortcut_dark_theme: function() {
if (document.documentElement.hasAttribute('dark')) {
Expand Down Expand Up @@ -2556,27 +2577,27 @@ ImprovedTube.shortcuts = function() {
}
};

for (var i in features) {
if (self.isset(self.storage[i])) {
var data = JSON.parse(self.storage[i]) || {};
for (var featureName in features) {
if (self.isset(self.storage[featureName])) {
var data = JSON.parse(self.storage[featureName]) || {};

if (
(data.keyCode === keys.keyCode || !self.isset(data.keyCode)) &&
(data.shiftKey === keys.shiftKey || !self.isset(data.shiftKey)) &&
(data.ctrlKey === keys.ctrlKey || !self.isset(data.ctrlKey)) &&
(data.altKey === keys.altKey || !self.isset(data.altKey)) &&
(data.keyCode === pressedKey.keyCode || !self.isset(data.keyCode)) &&
(data.shiftKey === pressedKey.shiftKey || !self.isset(data.shiftKey)) &&
(data.ctrlKey === pressedKey.ctrlKey || !self.isset(data.ctrlKey)) &&
(data.altKey === pressedKey.altKey || !self.isset(data.altKey)) &&
((data.wheel > 0) === (wheel > 0) || !self.isset(data.wheel)) &&
((hover === true && (data.wheel > 0) === (wheel > 0) && Object.keys(keys).length === 0 && keys.constructor === Object) || (self.isset(data.key) || self.isset(data.altKey) || self.isset(data.ctrlKey)))
((hover === true && (data.wheel > 0) === (wheel > 0) && Object.keys(pressedKey).length === 0) || (self.isset(data.key) || self.isset(data.altKey) || self.isset(data.ctrlKey)))
) {
if (type === 'wheel' && self.isset(data.wheel) || type === 'keys') {
if (event.type === 'wheel' && self.isset(data.wheel) || event.type === 'keydown') {
event.preventDefault();
event.stopPropagation();
}

features[i]();

if (type === 'wheel' && self.isset(data.wheel) || type === 'keys') {
return false;
features[featureName]();
if (event.type === 'wheel' && self.isset(data.wheel) || event.type === 'keydown') {
return;
}
}
}
Expand All @@ -2589,19 +2610,14 @@ ImprovedTube.shortcuts = function() {
-------------------------------------------------------------------------*/

window.addEventListener('keydown', function(event) {
keys = {
key: event.key,
keyCode: event.keyCode,
shiftKey: event.shiftKey,
ctrlKey: event.ctrlKey,
altKey: event.altKey
};
// shortcut will be fired again and again until the key is released. To get rid of that: if (event.repeat) return;
pressedKey = event;

start();
trigger(event);
}, true);

window.addEventListener('keyup', function(event) {
keys = {};
pressedKey = {};
}, true);


Expand All @@ -2614,8 +2630,9 @@ ImprovedTube.shortcuts = function() {

hover = false;

for (var i = 0, l = path.length; i < l; i++) {
if (path[i].classList && path[i].classList.contains('html5-video-player')) {
// TODO: refactor with elem.target.closest(".html5-video-player")
for (let elem of path) {
if (elem.classList && elem.classList.contains('html5-video-player')) {
hover = true;
}
}
Expand All @@ -2627,7 +2644,7 @@ ImprovedTube.shortcuts = function() {
window.addEventListener('wheel', function(event) {
wheel = event.deltaY;

start('wheel');
trigger(event);
}, {
passive: false,
capture: true
Expand Down