Skip to content
Open
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1513,5 +1513,8 @@
},
"excludeShortsInPlayAll": {
"message": "Exclude Shorts when using \"Play all\""
},
"disableHoldToPlay2x":{
"message": "Disable hold to play 2x"
}
}
144 changes: 143 additions & 1 deletion js&css/extension/functions.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
window.ImprovedTube = window.ImprovedTube || {};
/*--------------------------------------------------------------
>>> FUNCTIONS:
/*--------------------------------------------------------------
Expand All @@ -6,4 +7,145 @@
extension.functions.getUrlParameter = function (url, parameter) {
var match = url.match(new RegExp('(\\?|\\&)' + parameter + '=[^&]+'));
if (match) {return match[0].substr(3);}
};
};

/*------------------------------------------------------------------------------
DISABLE/ENABLE HOLD TO PLAY ON 2X SPEED (GLOBAL)
------------------------------------------------------------------------------*/
ImprovedTube._holdToPlayListener = null;

// DISABLE
ImprovedTube.disableHoldToPlay = function () {
console.log('[ImprovedTube] disableHoldToPlay called');


// REMOVE PREVIOUS LISTENERS
if (this._holdToPlayListener) {
document.removeEventListener('keydown', this._holdToPlayListener, true);
document.removeEventListener('keyup', this._holdToPlayListener, true);
document.removeEventListener('mousedown', this._holdToPlayListener, true);
document.removeEventListener('mouseup', this._holdToPlayListener, true);
this._holdToPlayListener = null;
console.log('[ImprovedTube] Removed previous holdToPlay listeners');
}


this._holdToPlayListener = (e) => {
// BLOCK SPACEBAR HOLD (block ALL keydown/keyup for Space)
if ((e.type === 'keydown' && e.code === 'Space') ||
(e.type === 'keyup' && e.code === 'Space')) {
console.log('[ImprovedTube] Blocked spacebar event:', e.type, e);
e.stopImmediatePropagation();
e.preventDefault();
}
// BLOCK MOUSE HOLD
if ((e.type === 'mousedown' || e.type === 'mouseup') && e.target.tagName === 'VIDEO') {
console.log('[ImprovedTube] Blocked mouse event:', e.type, e);
e.stopImmediatePropagation();
e.preventDefault();
}
};


document.addEventListener('keydown', this._holdToPlayListener, true);
document.addEventListener('keyup', this._holdToPlayListener, true);
document.addEventListener('mousedown', this._holdToPlayListener, true);
document.addEventListener('mouseup', this._holdToPlayListener, true);
console.log('[ImprovedTube] Attached holdToPlay listeners');

// REATTACH LISTENERS IF VIDEO ELEMENT CHANGES (YOUTUBE SPA NAVIGATION)
if (!this._holdToPlayVideoObserver) {
this._holdToPlayVideoObserver = new MutationObserver(() => {
// CHECK CHROME STORAGE FOR THE NEWEST VALUE
chrome.storage.local.get('disable_hold_to_play_2x', (result) => {
console.log('[ImprovedTube] MutationObserver: disable_hold_to_play_2x =', result.disable_hold_to_play_2x);
if (result.disable_hold_to_play_2x) {
ImprovedTube.disableHoldToPlay();
} else {
ImprovedTube.enableHoldToPlay();
}
});
});
const player = document.getElementById('movie_player') || document.querySelector('.html5-video-player');
if (player) {
this._holdToPlayVideoObserver.observe(player, { childList: true, subtree: true });
console.log('[ImprovedTube] MutationObserver attached to player');
}
}
};
// ENABLE
ImprovedTube.enableHoldToPlay = function () {
console.log('[ImprovedTube] enableHoldToPlay called');
if (this._holdToPlayListener) {
document.removeEventListener('keydown', this._holdToPlayListener, true);
document.removeEventListener('keyup', this._holdToPlayListener, true);
document.removeEventListener('mousedown', this._holdToPlayListener, true);
document.removeEventListener('mouseup', this._holdToPlayListener, true);
this._holdToPlayListener = null;
console.log('[ImprovedTube] Removed holdToPlay listeners (enable)');
}
if (this._holdToPlayVideoObserver) {
this._holdToPlayVideoObserver.disconnect();
this._holdToPlayVideoObserver = null;
console.log('[ImprovedTube] MutationObserver disconnected (enable)');
}
};

// LISTEN FOR STORAGE CHANGES TO UPDATE THE BEHAVIOR INSTANTLY
if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.onChanged) {
chrome.storage.onChanged.addListener(function(changes, area) {
if (area === 'local' && changes.disable_hold_to_play_2x) {
console.log('[ImprovedTube] chrome.storage.onChanged: disable_hold_to_play_2x =', changes.disable_hold_to_play_2x.newValue);
if (changes.disable_hold_to_play_2x.newValue) {
ImprovedTube.disableHoldToPlay();
} else {
ImprovedTube.enableHoldToPlay();
}
}
});
}

// CHECKS CHROME STORAGE ON CONTENT SCRIPT LOAD AND INITIALIZES
if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.local) {
chrome.storage.local.get('disable_hold_to_play_2x', (result) => {
console.log('[ImprovedTube] Content script loaded. disable_hold_to_play_2x =', result.disable_hold_to_play_2x);
if (result.disable_hold_to_play_2x) {
// SCRIPT TAG INJECTION (TO CATCH EVENTS BEFORE YT DOES)
const code = `
(function() {
function blockHoldToPlay(e) {
if ((e.type === 'keydown' && e.code === 'Space') ||
(e.type === 'keyup' && e.code === 'Space')) {
console.log('[ImprovedTube injected] Blocked spacebar event:', e.type, e);
e.stopImmediatePropagation();
e.preventDefault();
}
if ((e.type === 'mousedown' || e.type === 'mouseup') && e.target.tagName === 'VIDEO') {
console.log('[ImprovedTube injected] Blocked mouse event:', e.type, e);
e.stopImmediatePropagation();
e.preventDefault();
}
}
window.addEventListener('keydown', blockHoldToPlay, true);
window.addEventListener('keyup', blockHoldToPlay, true);
window.addEventListener('mousedown', blockHoldToPlay, true);
window.addEventListener('mouseup', blockHoldToPlay, true);
console.log('[ImprovedTube injected] Hold-to-play block active');
})();
`;
const script = document.createElement('script');
script.textContent = code;
(document.head || document.documentElement).appendChild(script);
script.remove();
}
// RUN THE NORMAL CONTENT SCRIPT LOGIC
if (result.disable_hold_to_play_2x) {
ImprovedTube.disableHoldToPlay();
} else {
ImprovedTube.enableHoldToPlay();
}
});
}
/*------------------------------------------------------------------------------
END OF DISABLE/ENABLE HOLD TO PLAY ON 2X SPEED (GLOBAL)
------------------------------------------------------------------------------*/
2 changes: 1 addition & 1 deletion js&css/web-accessible/www.youtube.com/appearance.js
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ ImprovedTube.playerRevertTheaterButtonSize();
document.addEventListener('yt-page-data-updated', run);
document.addEventListener('yt-navigate-finish', run);
window.addEventListener('load', run);
etTimeout(run, 2000); // fallback for late loads
setTimeout(run, 2000); // fallback for late loads
})();

/*------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion js&css/web-accessible/www.youtube.com/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ window.addEventListener('load', () => { setTimeout(() => { clearInterval(waitFo
} // else { }
}
}
}
}
/*------------------------------------------------------------------------------
SUBTITLES
------------------------------------------------------------------------------*/
Expand Down
181 changes: 96 additions & 85 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,86 +1,97 @@
{
"manifest_version": 3,
"short_name": "ImprovedTube",
"name": "'Improve YouTube!' 🎧 (for YouTube & Videos)",
"description": "__MSG_description_ext__",
"version": "4",
"default_locale": "en",
"icons": {
"128": "menu/icons/128.png",
"16": "menu/icons/16.png",
"32": "menu/icons/32.png",
"48": "menu/icons/48.png"
},
"browser_specific_settings": {
"gecko": {
"id": "{3c6bf0cc-3ae2-42fb-9993-0d33104fdcaf}"
}
},
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "menu/index.html",
"default_area": "navbar"
},
"options_page": "menu/index.html",
"options_ui": {
"page": "menu/index.html"
},
"content_scripts": [
{
"all_frames": true,
"css": [
"js&css/extension/www.youtube.com/styles.css",
"js&css/extension/www.youtube.com/night-mode/night-mode.css",
"js&css/extension/www.youtube.com/general/general.css",
"js&css/extension/www.youtube.com/appearance/header/header.css",
"js&css/extension/www.youtube.com/appearance/player/player.css",
"js&css/extension/www.youtube.com/appearance/details/details.css",
"js&css/extension/www.youtube.com/appearance/sidebar/sidebar.css",
"js&css/extension/www.youtube.com/appearance/comments/comments.css"
],
"exclude_matches": [
"https://www.youtube.com/audiolibrary/*",
"https://www.youtube.com/tv*"
],
"js": [
"js&css/extension/core.js",
"js&css/extension/functions.js",
"js&css/extension/www.youtube.com/night-mode/night-mode.js",
"js&css/extension/www.youtube.com/general/general.js",
"js&css/extension/www.youtube.com/appearance/sidebar/sidebar.js",
"js&css/extension/www.youtube.com/appearance/comments/comments.js",
"js&css/extension/init.js"
],
"matches": ["https://www.youtube.com/*"],
"run_at": "document_start"
}
],
"host_permissions": ["https://www.youtube.com/*"],
"optional_permissions": ["downloads"],
"permissions": ["contextMenus", "storage"],
"web_accessible_resources": [
{
"resources": [
"menu/index.html",
"js&css/web-accessible/core.js",
"js&css/web-accessible/functions.js",
"js&css/web-accessible/www.youtube.com/appearance.js",
"js&css/web-accessible/www.youtube.com/player.js",
"js&css/web-accessible/www.youtube.com/themes.js",
"js&css/web-accessible/www.youtube.com/playlist.js",
"js&css/web-accessible/www.youtube.com/playlist-complete-playlist.js",
"js&css/web-accessible/www.youtube.com/playlist-cleaner.js",
"js&css/web-accessible/www.youtube.com/channel.js",
"js&css/web-accessible/www.youtube.com/shortcuts.js",
"js&css/web-accessible/www.youtube.com/blocklist.js",
"js&css/web-accessible/www.youtube.com/settings.js",
"js&css/web-accessible/www.youtube.com/last-watched-overlay.js",
"js&css/web-accessible/init.js",
"menu/icons/48.png"
],
"matches": ["https://www.youtube.com/*"]
}
]
}
"action": {
"default_area": "navbar",
"default_popup": "menu/index.html"
},
"background": {
"service_worker": "background.js"
},
"browser_specific_settings": {
"gecko": {
"id": "{3c6bf0cc-3ae2-42fb-9993-0d33104fdcaf}"
}
},
"content_scripts": [
{
"all_frames": true,
"css": [
"js&css/extension/www.youtube.com/styles.css",
"js&css/extension/www.youtube.com/night-mode/night-mode.css",
"js&css/extension/www.youtube.com/general/general.css",
"js&css/extension/www.youtube.com/appearance/header/header.css",
"js&css/extension/www.youtube.com/appearance/player/player.css",
"js&css/extension/www.youtube.com/appearance/details/details.css",
"js&css/extension/www.youtube.com/appearance/sidebar/sidebar.css",
"js&css/extension/www.youtube.com/appearance/comments/comments.css"
],
"exclude_matches": [
"https://www.youtube.com/audiolibrary/*",
"https://www.youtube.com/tv*"
],
"js": [
"js&css/extension/core.js",
"js&css/extension/functions.js",
"js&css/extension/www.youtube.com/night-mode/night-mode.js",
"js&css/extension/www.youtube.com/general/general.js",
"js&css/extension/www.youtube.com/appearance/sidebar/sidebar.js",
"js&css/extension/www.youtube.com/appearance/comments/comments.js",
"js&css/extension/init.js"
],
"matches": [
"https://www.youtube.com/*"
],
"run_at": "document_start"
}
],
"default_locale": "en",
"description": "__MSG_description_ext__",
"host_permissions": [
"https://www.youtube.com/*"
],
"icons": {
"128": "menu/icons/128.png",
"16": "menu/icons/16.png",
"32": "menu/icons/32.png",
"48": "menu/icons/48.png"
},
"manifest_version": 3,
"name": "'Improve YouTube!' \u00f0\u0178\u017d\u00a7 (for YouTube & Videos)",
"optional_permissions": [
"downloads"
],
"options_page": "menu/index.html",
"options_ui": {
"page": "menu/index.html"
},
"permissions": [
"contextMenus",
"storage"
],
"short_name": "ImprovedTube",
"version": "4",
"web_accessible_resources": [
{
"matches": [
"https://www.youtube.com/*"
],
"resources": [
"menu/index.html",
"js&css/web-accessible/core.js",
"js&css/web-accessible/functions.js",
"js&css/web-accessible/www.youtube.com/appearance.js",
"js&css/web-accessible/www.youtube.com/player.js",
"js&css/web-accessible/www.youtube.com/themes.js",
"js&css/web-accessible/www.youtube.com/playlist.js",
"js&css/web-accessible/www.youtube.com/playlist-complete-playlist.js",
"js&css/web-accessible/www.youtube.com/playlist-cleaner.js",
"js&css/web-accessible/www.youtube.com/channel.js",
"js&css/web-accessible/www.youtube.com/shortcuts.js",
"js&css/web-accessible/www.youtube.com/blocklist.js",
"js&css/web-accessible/www.youtube.com/settings.js",
"js&css/web-accessible/www.youtube.com/last-watched-overlay.js",
"js&css/web-accessible/init.js",
"menu/icons/48.png"
]
}
]
}
4 changes: 1 addition & 3 deletions menu/skeleton-parts/appearance.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,11 +428,9 @@ extension.skeleton.main.layers.section.appearance.on.click.player = {
component: "switch",
text: "hideTopLoadingBar",
tags: "remove,hide"
},
}
}
}


};

/*--------------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions menu/skeleton-parts/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,11 @@ extension.skeleton.main.layers.section.player.on.click = {
component: 'switch',
text: 'customMiniPlayer'
},
disable_hold_to_play_2x: {
component: 'switch',
text: 'disableHoldToPlay2x',
value: false,
},
forced_play_video_from_the_beginning: {
component: 'switch',
text: 'forcedPlayVideoFromTheBeginning'
Expand Down