diff --git a/js&css/extension/init.js b/js&css/extension/init.js index a7801f0c9..121d96596 100644 --- a/js&css/extension/init.js +++ b/js&css/extension/init.js @@ -1,251 +1,287 @@ /*-------------------------------------------------------------- >>> INITIALIZATION --------------------------------------------------------------*/ -extension.features.youtubeHomePage('init'); +extension.features.youtubeHomePage("init"); -document.documentElement.setAttribute('it-pathname', location.pathname); +document.documentElement.setAttribute("it-pathname", location.pathname); -window.addEventListener('yt-navigate-finish', function () { - document.documentElement.setAttribute('it-pathname', location.pathname); +window.addEventListener("yt-navigate-finish", function () { + document.documentElement.setAttribute("it-pathname", location.pathname); - extension.features.trackWatchedVideos(); - extension.features.thumbnailsQuality(); + extension.features.trackWatchedVideos(); + extension.features.thumbnailsQuality(); }); extension.messages.create(); extension.messages.listener(); -extension.events.on('init', function (resolve) { - extension.storage.listener(); - extension.storage.load(function () { - resolve(); - }); -}, { - async: true -}); - -function bodyReady () { - if (extension.ready && extension.domReady) { - extension.features.addScrollToTop(); - extension.features.font(); - extension.features.changeThumbnailsPerRow?.(); - extension.features.clickableLinksInVideoDescriptions(); - } +extension.events.on( + "init", + function (resolve) { + extension.storage.listener(); + extension.storage.load(function () { + resolve(); + }); + }, + { + async: true, + } +); + +function bodyReady() { + if (extension.ready && extension.domReady) { + extension.features.addScrollToTop(); + extension.features.font(); + extension.features.changeThumbnailsPerRow?.(); + extension.features.clickableLinksInVideoDescriptions(); + } } -extension.events.on('init', function () { - extension.features.bluelight(); - extension.features.dim(); - extension.features.youtubeHomePage(); - extension.features.collapseOfSubscriptionSections(); - extension.features.confirmationBeforeClosing(); - extension.features.defaultContentCountry(); - extension.features.popupWindowButtons(); - extension.features.disableThumbnailPlayback(); - extension.features.markWatchedVideos(); - extension.features.relatedVideos(); - extension.features.comments(); - extension.features.openNewTab(); - extension.features.removeListParamOnNewTab(); - bodyReady(); -}); - -chrome.runtime.sendMessage({ - action: 'tab-connected' -}, function (response) { - if (response) { - extension.tabId = response.tabId; - } +extension.events.on("init", function () { + extension.features.bluelight(); + extension.features.dim(); + extension.features.youtubeHomePage(); + extension.features.collapseOfSubscriptionSections(); + extension.features.confirmationBeforeClosing(); + extension.features.defaultContentCountry(); + extension.features.popupWindowButtons(); + extension.features.disableThumbnailPlayback(); + extension.features.markWatchedVideos(); + extension.features.relatedVideos(); + extension.features.comments(); + extension.features.openNewTab(); + extension.features.removeListParamOnNewTab(); + bodyReady(); }); -extension.inject([ - '/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/themes.js', - '/js&css/web-accessible/www.youtube.com/player.js', - '/js&css/web-accessible/www.youtube.com/playlist.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/init.js' -], function () { - extension.ready = true; - - extension.events.trigger('init'); -}); - -document.addEventListener('DOMContentLoaded', function () { - extension.domReady = true; - - bodyReady(); +chrome.runtime.sendMessage( + { + action: "tab-connected", + }, + function (response) { + if (response) { + extension.tabId = response.tabId; + } + } +); + +extension.inject( + [ + "/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/themes.js", + "/js&css/web-accessible/www.youtube.com/player.js", + "/js&css/web-accessible/www.youtube.com/playlist.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/init.js", + ], + function () { + extension.ready = true; + + extension.events.trigger("init"); + } +); + +document.addEventListener("DOMContentLoaded", function () { + extension.domReady = true; + + bodyReady(); }); chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { - if (request.action === 'focus') { - extension.messages.send({ - focus: true - }); - } else if (request.action === 'blur') { - extension.messages.send({ - blur: true - }); - } else if (request.action === 'pause') { - extension.messages.send({ - pause: true - }); - } else if (request.action === 'set-volume') { - extension.messages.send({ - setVolume: request.value - }); - } else if (request.action === 'set-playback-speed') { - extension.messages.send({ - setPlaybackSpeed: request.value - }); - } else if (request.action === 'mixer') { - extension.messages.send({ - mixer: true - }, sendResponse, 'mixer'); - - return true; - } else if (request.action === 'delete-youtube-cookies') { - extension.messages.send({ - deleteCookies: true - }); - } else if (request.action === "another-video-started-playing") { - extension.features.onlyOnePlayerInstancePlaying(); - } + if (request.action === "focus") { + extension.messages.send({ + focus: true, + }); + } else if (request.action === "blur") { + extension.messages.send({ + blur: true, + }); + } else if (request.action === "pause") { + extension.messages.send({ + pause: true, + }); + } else if (request.action === "set-volume") { + extension.messages.send({ + setVolume: request.value, + }); + } else if (request.action === "set-playback-speed") { + extension.messages.send({ + setPlaybackSpeed: request.value, + }); + } else if (request.action === "mixer") { + extension.messages.send( + { + mixer: true, + }, + sendResponse, + "mixer" + ); + + return true; + } else if (request.action === "delete-youtube-cookies") { + extension.messages.send({ + deleteCookies: true, + }); + } else if (request.action === "another-video-started-playing") { + extension.features.onlyOnePlayerInstancePlaying(); + } }); -document.addEventListener('it-message-from-youtube', function () { - var provider = document.querySelector('#it-messages-from-youtube'); - - if (provider) { - var message = provider.textContent; - - document.dispatchEvent(new CustomEvent('it-message-from-youtube--readed')); - - try { - message = JSON.parse(message); - } catch (error) { - console.log(error); - } - - //console.log(message); - - if (message.requestOptionsUrl === true) { - extension.messages.send({ - responseOptionsUrl: chrome.runtime.getURL('menu/index.html') - }); - } else if (message.onlyOnePlayer === true) { - chrome.runtime.sendMessage({ - name: 'only-one-player' - }); - } else if (message.action === 'fixPopup') { - chrome.runtime.sendMessage({ - action: 'fixPopup', - width: message.width, - height: message.height, - title: message.title, - }); - } else if (message.action === 'analyzer') { - if (extension.storage.data.analyzer_activation === true) { - var data = message.name, - date = new Date().toDateString(), - hours = new Date().getHours() + ':00'; - - if (!extension.storage.data.analyzer) { - extension.storage.data.analyzer = {}; - } - - if (!extension.storage.data.analyzer[date]) { - extension.storage.data.analyzer[date] = {}; - } - - if (!extension.storage.data.analyzer[date][hours]) { - extension.storage.data.analyzer[date][hours] = {}; - } - - if (!extension.storage.data.analyzer[date][hours][data]) { - extension.storage.data.analyzer[date][hours][data] = 0; - } - - extension.storage.data.analyzer[date][hours][data]++; - - chrome.storage.local.set({ - analyzer: extension.storage.data.analyzer - }); - } - } else if (message.action === 'blocklist') { - if (!extension.storage.data.blocklist || typeof extension.storage.data.blocklist !== 'object') { - extension.storage.data.blocklist = {videos: {}, channels: {}}; - } - - switch (message.type) { - case 'channel': - if (!extension.storage.data.blocklist.channels || typeof extension.storage.data.blocklist.channels !== 'object') { - extension.storage.data.blocklist.channels = {}; - } - if (message.added) { - extension.storage.data.blocklist.channels[message.id] = { - title: message.title, - preview: message.preview, - when: message.when - } - } else { - delete extension.storage.data.blocklist.channels[message.id]; - } - break - - case 'video': - if (!extension.storage.data.blocklist.videos || typeof extension.storage.data.blocklist.videos !== 'object') { - extension.storage.data.blocklist.videos = {}; - } - if (message.added) { - extension.storage.data.blocklist.videos[message.id] = { - title: message.title, - when: message.when - } - } else { - delete extension.storage.data.blocklist.videos[message.id]; - } - break - } - - chrome.storage.local.set({ - blocklist: extension.storage.data.blocklist - }); - } else if (message.action === 'watched') { - if (!extension.storage.data.watched || typeof extension.storage.data.watched !== 'object') { - extension.storage.data.watched = {}; - } - - if (message.type === 'add') { - extension.storage.data.watched[message.id] = { - title: message.title - }; - } - - if (message.type === 'remove') { - delete extension.storage.data.watched[message.id]; - } - - chrome.storage.local.set({ - watched: extension.storage.data.watched - }); - } else if (message.action === 'set') { - if (message.value) { - chrome.storage.local.set({[message.key]: message.value}); - } else { - chrome.storage.local.remove([message.key]); - } - } - } +document.addEventListener("it-message-from-youtube", function () { + var provider = document.querySelector("#it-messages-from-youtube"); + + if (provider) { + var message = provider.textContent; + + document.dispatchEvent(new CustomEvent("it-message-from-youtube--readed")); + + try { + message = JSON.parse(message); + } catch (error) { + console.log(error); + } + + //console.log(message); + + if (message.requestOptionsUrl === true) { + extension.messages.send({ + responseOptionsUrl: chrome.runtime.getURL("menu/index.html"), + }); + } else if (message.onlyOnePlayer === true) { + chrome.runtime.sendMessage({ + name: "only-one-player", + }); + } else if (message.action === "fixPopup") { + chrome.runtime.sendMessage({ + action: "fixPopup", + width: message.width, + height: message.height, + title: message.title, + }); + } else if (message.action === "analyzer") { + if (extension.storage.data.analyzer_activation === true) { + var data = message.name, + date = new Date().toDateString(), + hours = new Date().getHours() + ":00"; + + if (!extension.storage.data.analyzer) { + extension.storage.data.analyzer = {}; + } + + if (!extension.storage.data.analyzer[date]) { + extension.storage.data.analyzer[date] = {}; + } + + if (!extension.storage.data.analyzer[date][hours]) { + extension.storage.data.analyzer[date][hours] = {}; + } + + if (!extension.storage.data.analyzer[date][hours][data]) { + extension.storage.data.analyzer[date][hours][data] = 0; + } + + extension.storage.data.analyzer[date][hours][data]++; + + chrome.storage.local.set({ + analyzer: extension.storage.data.analyzer, + }); + } + } else if (message.action === "blocklist") { + if ( + !extension.storage.data.blocklist || + typeof extension.storage.data.blocklist !== "object" + ) { + extension.storage.data.blocklist = { videos: {}, channels: {} }; + } + + switch (message.type) { + case "channel": + if ( + !extension.storage.data.blocklist.channels || + typeof extension.storage.data.blocklist.channels !== "object" + ) { + extension.storage.data.blocklist.channels = {}; + } + if (message.added) { + extension.storage.data.blocklist.channels[message.id] = { + title: message.title, + preview: message.preview, + when: message.when, + }; + } else { + delete extension.storage.data.blocklist.channels[message.id]; + } + break; + + case "video": + if ( + !extension.storage.data.blocklist.videos || + typeof extension.storage.data.blocklist.videos !== "object" + ) { + extension.storage.data.blocklist.videos = {}; + } + if (message.added) { + extension.storage.data.blocklist.videos[message.id] = { + title: message.title, + when: message.when, + }; + } else { + delete extension.storage.data.blocklist.videos[message.id]; + } + break; + } + + chrome.storage.local.set({ + blocklist: extension.storage.data.blocklist, + }); + } else if (message.action === "watched") { + if ( + !extension.storage.data.watched || + typeof extension.storage.data.watched !== "object" + ) { + extension.storage.data.watched = {}; + } + + if (message.type === "add") { + extension.storage.data.watched[message.id] = { + title: message.title, + }; + } + + if (message.type === "remove") { + delete extension.storage.data.watched[message.id]; + } + + chrome.storage.local.set({ + watched: extension.storage.data.watched, + }); + } else if (message.action === "set") { + if (message.value) { + chrome.storage.local.set({ [message.key]: message.value }); + } else { + chrome.storage.local.remove([message.key]); + } + } + } }); -document.addEventListener('it-play', function () { - // var videos = document.querySelectorAll('video'); - try {chrome.runtime.sendMessage({action: 'play'}) - } catch (error) {console.log(error); setTimeout(function () { try { chrome.runtime.sendMessage({action: 'play'}, function (response) { console.log(response) } ); } catch { } }, 321) } -}); \ No newline at end of file +document.addEventListener("it-play", function () { + // var videos = document.querySelectorAll('video'); + try { + chrome.runtime.sendMessage({ action: "play" }); + } catch (error) { + console.log(error); + setTimeout(function () { + try { + chrome.runtime.sendMessage({ action: "play" }, function (response) { + console.log(response); + }); + } catch {} + }, 321); + } +}); diff --git a/js&css/web-accessible/functions.js b/js&css/web-accessible/functions.js index b2808b708..ba8165767 100644 --- a/js&css/web-accessible/functions.js +++ b/js&css/web-accessible/functions.js @@ -2,19 +2,29 @@ >>> FUNCTIONS --------------------------------------------------------------*/ ImprovedTube.childHandler = function (node) { - //console.log(node.nodeName); - if (node.nodeName === 'SCRIPT' || node.nodeName === 'iron-iconset-svg' || node.nodeName === 'svg' || node.nodeName === 'SPAN' || node.nodeName === '#text' || node.nodeName === '#comment' || node.nodeName === 'yt-icon-shape' || node.nodeName === 'DOM-IF' || node.nodeName === 'DOM-REPEAT') { - return - } - var children = node.children; - this.ytElementsHandler(node); - - if (children) { - for (var i = 0, l = children.length; i < l; i++) { - ImprovedTube.childHandler(children[i]); - } - } -} + //console.log(node.nodeName); + if ( + node.nodeName === "SCRIPT" || + node.nodeName === "iron-iconset-svg" || + node.nodeName === "svg" || + node.nodeName === "SPAN" || + node.nodeName === "#text" || + node.nodeName === "#comment" || + node.nodeName === "yt-icon-shape" || + node.nodeName === "DOM-IF" || + node.nodeName === "DOM-REPEAT" + ) { + return; + } + var children = node.children; + this.ytElementsHandler(node); + + if (children) { + for (var i = 0, l = children.length; i < l; i++) { + ImprovedTube.childHandler(children[i]); + } + } +}; /* const DOM_filter = /^(SCRIPT|DOM-IF|DOM-REPEAT|svg|SPAN|#text|#comment|yt-icon-shape|iron-iconset-svg)$/; @@ -33,457 +43,593 @@ ImprovedTube.childHandler = function (node) { //console.log(node.nodeName); }; */ ImprovedTube.ytElementsHandler = function (node) { - const name = node.nodeName, - id = node.id; - - if (name === 'A') { - if (node.href) { - this.channelDefaultTab(node); - } - if (this.storage.blocklist_activate) { - // we are interested in thumbnails and video-previews, skip ones with 'button.it-add-to-blocklist' already - if (((node.href && node.classList.contains('ytd-thumbnail')) || node.classList.contains('ytd-video-preview')) - && !node.querySelector("button.it-add-to-blocklist")) { - this.blocklistNode(node); - } - } - } else if (name === 'YTD-TOGGLE-BUTTON-RENDERER' || name === 'YTD-PLAYLIST-LOOP-BUTTON-RENDERER') { - //can be precise previously node.parentComponent & node.parentComponent.parentComponent - if (node.closest("YTD-MENU-RENDERER") - && node.closest("YTD-PLAYLIST-PANEL-RENDERER")) { - - var index = Array.prototype.indexOf.call(node.parentNode.children, node); - if (index === 0) { - if (this.storage.playlist_reverse === true) { - //can be precise: - try {this.elements.playlist.actions = node.parentNode.parentNode.parentNode.parentNode;} - catch {try {this.elements.playlist.actions = node.parentNode.parentNode.parentNode;} - catch {try {this.elements.playlist.actions = node.parentNode.parentNode;} - catch {try {this.elements.playlist.actions = node.parentNode;} - catch {try {this.elements.playlist.actions = node;} catch {}} - } - } - } - } - this.playlistReverse(); - } else if (index === 1) { - this.elements.playlist.shuffle_button = node; - - this.playlistShuffle(); - - if (this.storage.playlist_reverse === true) { - //can be precise: - try {this.elements.playlist.actions = node.parentNode.parentNode.parentNode.parentNode;} - catch {try {this.elements.playlist.actions = node.parentNode.parentNode.parentNode;} - catch {try {this.elements.playlist.actions = node.parentNode.parentNode;} - catch {try {this.elements.playlist.actions = node.parentNode;} - catch {try {this.elements.playlist.actions = node;} catch {}} - } - } - } - } - this.playlistReverse(); - } - } - } else if (name === 'YTD-GUIDE-SECTION-RENDERER') { - if (!this.elements.sidebar_section) { - this.elements.sidebar_section = node; - - this.improvedtubeYoutubeIcon(); - } - } else if (name === 'YTD-VIDEO-PRIMARY-INFO-RENDERER') { - this.elements.video_title = node.querySelector('.title.ytd-video-primary-info-renderer'); - - this.improvedtubeYoutubeIcon(); - this.improvedtubeYoutubeButtonsUnderPlayer(); + const name = node.nodeName, + id = node.id; - } else if (name === 'YTD-VIDEO-SECONDARY-INFO-RENDERER') { - this.elements.yt_channel_name = node.querySelector('ytd-channel-name'); - this.elements.yt_channel_link = node.querySelector('ytd-channel-name a'); + if (name === "A") { + if (node.href) { + this.channelDefaultTab(node); + } + if (this.storage.blocklist_activate) { + // we are interested in thumbnails and video-previews, skip ones with 'button.it-add-to-blocklist' already + if ( + ((node.href && node.classList.contains("ytd-thumbnail")) || + node.classList.contains("ytd-video-preview")) && + !node.querySelector("button.it-add-to-blocklist") + ) { + this.blocklistNode(node); + } + } + } else if ( + name === "YTD-TOGGLE-BUTTON-RENDERER" || + name === "YTD-PLAYLIST-LOOP-BUTTON-RENDERER" + ) { + //can be precise previously node.parentComponent & node.parentComponent.parentComponent + if ( + node.closest("YTD-MENU-RENDERER") && + node.closest("YTD-PLAYLIST-PANEL-RENDERER") + ) { + var index = Array.prototype.indexOf.call(node.parentNode.children, node); + if (index === 0) { + if (this.storage.playlist_reverse === true) { + //can be precise: + try { + this.elements.playlist.actions = + node.parentNode.parentNode.parentNode.parentNode; + } catch { + try { + this.elements.playlist.actions = + node.parentNode.parentNode.parentNode; + } catch { + try { + this.elements.playlist.actions = node.parentNode.parentNode; + } catch { + try { + this.elements.playlist.actions = node.parentNode; + } catch { + try { + this.elements.playlist.actions = node; + } catch {} + } + } + } + } + } + this.playlistReverse(); + } else if (index === 1) { + this.elements.playlist.shuffle_button = node; + + this.playlistShuffle(); + + if (this.storage.playlist_reverse === true) { + //can be precise: + try { + this.elements.playlist.actions = + node.parentNode.parentNode.parentNode.parentNode; + } catch { + try { + this.elements.playlist.actions = + node.parentNode.parentNode.parentNode; + } catch { + try { + this.elements.playlist.actions = node.parentNode.parentNode; + } catch { + try { + this.elements.playlist.actions = node.parentNode; + } catch { + try { + this.elements.playlist.actions = node; + } catch {} + } + } + } + } + } + this.playlistReverse(); + } + } + } else if (name === "YTD-GUIDE-SECTION-RENDERER") { + if (!this.elements.sidebar_section) { + this.elements.sidebar_section = node; - if (document.documentElement.dataset.pageType === 'video') { - this.howLongAgoTheVideoWasUploaded(); - this.channelVideosCount(); - this.exactUploadDate(); - } - //} else if (name === 'YTD-MENU-RENDERER' && node.classList.contains('ytd-video-primary-info-renderer')) { - // if (document.documentElement.dataset.pageType === 'video') { - // this.hideDetailButton(node.querySelector('#flexible-item-buttons').children); - // } - } else if (name === 'YTD-PLAYLIST-HEADER-RENDERER' || (name === 'YTD-MENU-RENDERER' && node.classList.contains('ytd-playlist-panel-renderer'))) { - this.playlistPopup(); - } else if (name === 'YTD-SUBSCRIBE-BUTTON-RENDERER' - || name === 'YT-SUBSCRIBE-BUTTON-VIEW-MODEL' - || (name === 'YTD-BUTTON-RENDERER' && node.classList.contains('ytd-c4-tabbed-header-renderer'))) { - ImprovedTube.blocklistChannel(node); - ImprovedTube.elements.subscribe_button = node; - } else if (id === 'chat-messages') { - this.elements.livechat.button = document.querySelector('[aria-label="Close"]'); - // console.log(document.querySelector('[aria-label="Close"]')) - this.livechat(); - } else if (name === 'YTD-MASTHEAD') { - if (!this.elements.masthead) { - this.elements.masthead = {start: node.querySelector('#start'), - end: node.querySelector('#end'), - logo: node.querySelector('a#logo') - }; - - this.improvedtubeYoutubeIcon(); - } - } else if (name === 'TP-YT-APP-DRAWER') { - if (!this.elements.app_drawer) { - this.elements.app_drawer = {start: node.querySelector('div#header'), - logo: node.querySelector('a#logo') - }; + this.improvedtubeYoutubeIcon(); + } + } else if (name === "YTD-VIDEO-PRIMARY-INFO-RENDERER") { + this.elements.video_title = node.querySelector( + ".title.ytd-video-primary-info-renderer" + ); + + this.improvedtubeYoutubeIcon(); + this.improvedtubeYoutubeButtonsUnderPlayer(); + } else if (name === "YTD-VIDEO-SECONDARY-INFO-RENDERER") { + this.elements.yt_channel_name = node.querySelector("ytd-channel-name"); + this.elements.yt_channel_link = node.querySelector("ytd-channel-name a"); + + if (document.documentElement.dataset.pageType === "video") { + this.howLongAgoTheVideoWasUploaded(); + this.channelVideosCount(); + this.exactUploadDate(); + } + //} else if (name === 'YTD-MENU-RENDERER' && node.classList.contains('ytd-video-primary-info-renderer')) { + // if (document.documentElement.dataset.pageType === 'video') { + // this.hideDetailButton(node.querySelector('#flexible-item-buttons').children); + // } + } else if ( + name === "YTD-PLAYLIST-HEADER-RENDERER" || + (name === "YTD-MENU-RENDERER" && + node.classList.contains("ytd-playlist-panel-renderer")) + ) { + this.playlistPopup(); + } else if ( + name === "YTD-SUBSCRIBE-BUTTON-RENDERER" || + name === "YT-SUBSCRIBE-BUTTON-VIEW-MODEL" || + (name === "YTD-BUTTON-RENDERER" && + node.classList.contains("ytd-c4-tabbed-header-renderer")) + ) { + ImprovedTube.blocklistChannel(node); + ImprovedTube.elements.subscribe_button = node; + } else if (id === "chat-messages") { + this.elements.livechat.button = document.querySelector( + '[aria-label="Close"]' + ); + // console.log(document.querySelector('[aria-label="Close"]')) + this.livechat(); + } else if (name === "YTD-MASTHEAD") { + if (!this.elements.masthead) { + this.elements.masthead = { + start: node.querySelector("#start"), + end: node.querySelector("#end"), + logo: node.querySelector("a#logo"), + }; + + this.improvedtubeYoutubeIcon(); + } + } else if (name === "TP-YT-APP-DRAWER") { + if (!this.elements.app_drawer) { + this.elements.app_drawer = { + start: node.querySelector("div#header"), + logo: node.querySelector("a#logo"), + }; + + this.improvedtubeYoutubeIcon(); + } + } else if (name === "YTD-PLAYER") { + if (!this.elements.ytd_player) { + ImprovedTube.elements.ytd_player = node; + } + } else if (id === "shorts-player") { + if (!this.elements.shorts_player) { + ImprovedTube.elements.shorts_player = node; + } + } else if (id === "movie_player") { + if (!this.elements.player) { + ImprovedTube.elements.player = node; + ImprovedTube._mutedAdsObserverInitialized = false; + + if (ImprovedTube.storage.ads === "mute_ads") { + ImprovedTube.muteAds(); + } + + // if (this.storage.player_autoplay === false) { ImprovedTube.elements.player.stopVideo(); } + ImprovedTube.elements.video = node.querySelector("video"); + ImprovedTube.elements.player_left_controls = + node.querySelector(".ytp-left-controls"); + ImprovedTube.elements.player_right_controls = node.querySelector( + ".ytp-right-controls" + ); + ImprovedTube.elements.player_thumbnail = node.querySelector( + ".ytp-cued-thumbnail-overlay-image" + ); + ImprovedTube.elements.player_subtitles_button = node.querySelector( + ".ytp-subtitles-button" + ); + ImprovedTube.playerSize(); + if ( + typeof this.storage.ads !== "undefined" && + this.storage.ads !== "all_videos" + ) { + new MutationObserver(function (mutationList) { + for (var i = 0, l = mutationList.length; i < l; i++) { + var mutation = mutationList[i]; + + if (mutation.type === "childList") { + for (var j = 0, k = mutation.addedNodes.length; j < k; j++) { + var node = mutation.addedNodes[j]; + + if ( + node instanceof Element && + node.querySelector( + 'ytp-ad-player-overlay, .ytp-ad-text, .ytp-ad-overlay-close-container, ytd-button-renderer#dismiss-button, *[id^="ad-text"], *[id^="skip-button"], .ytp-ad-skip-button.ytp-button, .ytp-ad-skip-button-modern.ytp-button' + ) !== null + ) { + ImprovedTube.playerAds(node); + } + } + } + if ( + mutation.type === "attributes" && + mutation.attributeName === "id" && + mutation.target.querySelector( + '*[id^="ad-text"], *[id^="skip-button"], .ytp-ad-skip-button-modern.ytp-button' + ) + ) { + ImprovedTube.playerAds(node); + } + } + }).observe(node, { + childList: true, // attributes: true, + subtree: true, + }); + } - this.improvedtubeYoutubeIcon(); - } - } else if (name === 'YTD-PLAYER') { - if (!this.elements.ytd_player) { - ImprovedTube.elements.ytd_player = node; - } - } else if (id === 'shorts-player') { - if (!this.elements.shorts_player) { - ImprovedTube.elements.shorts_player = node; - } - }else if (id === 'movie_player') { - if (!this.elements.player) { - ImprovedTube.elements.player = node; - // if (this.storage.player_autoplay === false) { ImprovedTube.elements.player.stopVideo(); } - ImprovedTube.elements.video = node.querySelector('video'); - ImprovedTube.elements.player_left_controls = node.querySelector('.ytp-left-controls'); - ImprovedTube.elements.player_right_controls = node.querySelector('.ytp-right-controls'); - ImprovedTube.elements.player_thumbnail = node.querySelector('.ytp-cued-thumbnail-overlay-image'); - ImprovedTube.elements.player_subtitles_button = node.querySelector('.ytp-subtitles-button'); - ImprovedTube.playerSize(); - if (typeof this.storage.ads !== 'undefined' && this.storage.ads !== "all_videos") { - new MutationObserver(function (mutationList) { - for (var i = 0, l = mutationList.length; i < l; i++) { - var mutation = mutationList[i]; - - if (mutation.type === 'childList') { - for (var j = 0, k = mutation.addedNodes.length; j < k; j++) { - var node = mutation.addedNodes[j]; - - if (node instanceof Element - && node.querySelector('ytp-ad-player-overlay, .ytp-ad-text, .ytp-ad-overlay-close-container, ytd-button-renderer#dismiss-button, *[id^="ad-text"], *[id^="skip-button"], .ytp-ad-skip-button.ytp-button, .ytp-ad-skip-button-modern.ytp-button') !== null) { - ImprovedTube.playerAds(node); - } - } - } - if (mutation.type === 'attributes' && mutation.attributeName === 'id' && mutation.target.querySelector('*[id^="ad-text"], *[id^="skip-button"], .ytp-ad-skip-button-modern.ytp-button',)) { - ImprovedTube.playerAds(node); - } - } - }).observe(node, {childList: true, // attributes: true, - subtree: true - }); - } + new MutationObserver(function (mutationList) { + for (var i = 0, l = mutationList.length; i < l; i++) { + var mutation = mutationList[i]; - new MutationObserver(function (mutationList) { - for (var i = 0, l = mutationList.length; i < l; i++) { - var mutation = mutationList[i]; + if (mutation.type === "attributes") { + if (mutation.attributeName === "style") { + ImprovedTube.playerHdThumbnail(); + } + } + } + }).observe(ImprovedTube.elements.player_thumbnail, { + attributes: true, + attributeFilter: ["style"], + childList: false, + subtree: false, + }); + } + } else if (name === "YTD-WATCH-FLEXY") { + this.elements.ytd_watch = node; + + if ( + this.isset(this.storage.player_size) && + this.storage.player_size !== "do_not_change" + ) { + node.calculateCurrentPlayerSize_ = function () { + if (!this.theater && ImprovedTube.elements.player) { + if (this.updateStyles) { + this.updateStyles({ + "--ytd-watch-flexy-width-ratio": 1, + "--ytd-watch-flexy-height-ratio": 0.5625, + }); - if (mutation.type === 'attributes') { - if (mutation.attributeName === 'style') { - ImprovedTube.playerHdThumbnail(); - } - } - } - }).observe(ImprovedTube.elements.player_thumbnail, {attributes: true, - attributeFilter: ['style'], - childList: false, - subtree: false - }); - } - } else if (name === 'YTD-WATCH-FLEXY') { - this.elements.ytd_watch = node; - - if ( - this.isset(this.storage.player_size) && - this.storage.player_size !== 'do_not_change' - ) { - node.calculateCurrentPlayerSize_ = function () { - if (!this.theater && ImprovedTube.elements.player) { - if (this.updateStyles) { - this.updateStyles({'--ytd-watch-flexy-width-ratio': 1, - '--ytd-watch-flexy-height-ratio': 0.5625 - }); - - this.updateStyles({'--ytd-watch-width-ratio': 1, - '--ytd-watch-height-ratio': 0.5625 - }); - } - - return {width: ImprovedTube.elements.player.offsetWidth, - height: Math.round(ImprovedTube.elements.player.offsetWidth / (16 / 9)) - }; - } + this.updateStyles({ + "--ytd-watch-width-ratio": 1, + "--ytd-watch-height-ratio": 0.5625, + }); + } + + return { + width: ImprovedTube.elements.player.offsetWidth, + height: Math.round( + ImprovedTube.elements.player.offsetWidth / (16 / 9) + ), + }; + } - return {width: NaN, // ?? - height: NaN - }; - }; + return { + width: NaN, // ?? + height: NaN, + }; + }; - node.calculateNormalPlayerSize_ = node.calculateCurrentPlayerSize_; // ?? - } - } else if (document.documentElement.dataset.pageType === 'video') { - if (id === 'description-inline-expander' || id === 'description-inner') { - setTimeout(function () {ImprovedTube.expandDescription(node);}, 300); - } else if (id === 'meta') {setTimeout(function () {ImprovedTube.expandDescription(node.querySelector('#more'));}, 200); - // } else if (id === 'below') { setTimeout(function () {}, 0); - } else if (id === 'panels') { setTimeout(function () { ImprovedTube.transcript(node); ImprovedTube.chapters(node);ImprovedTube.elements.panels = node;}, 200); - } /* else if (name === 'TP-YT-PAPER-BUTTON') { + node.calculateNormalPlayerSize_ = node.calculateCurrentPlayerSize_; // ?? + } + } else if (document.documentElement.dataset.pageType === "video") { + if (id === "description-inline-expander" || id === "description-inner") { + setTimeout(function () { + ImprovedTube.expandDescription(node); + }, 300); + } else if (id === "meta") { + setTimeout(function () { + ImprovedTube.expandDescription(node.querySelector("#more")); + }, 200); + // } else if (id === 'below') { setTimeout(function () {}, 0); + } else if (id === "panels") { + setTimeout(function () { + ImprovedTube.transcript(node); + ImprovedTube.chapters(node); + ImprovedTube.elements.panels = node; + }, 200); + } /* else if (name === 'TP-YT-PAPER-BUTTON') { if ( (id === 'expand-sizer' || id === 'expand') && node.parentNode.id === 'description-inline-expander') { setTimeout(function () { ImprovedTube.expandDescription(node); console.log("EXPAND DESCRIPTION, OLD WAY") }, 750); }} */ - } else if (id === 'panels') { - ImprovedTube.elements.panels = node; - } + } else if (id === "panels") { + ImprovedTube.elements.panels = node; + } }; ImprovedTube.pageType = function () { - if (/\/watch\?|\/live\//.test(location.href)) { - document.documentElement.dataset.pageType = 'video'; - } else if (location.pathname === '/') { - document.documentElement.dataset.pageType = 'home'; - } else if (/\/subscriptions\?/.test(location.href)) { - document.documentElement.dataset.pageType = 'subscriptions'; - } else if (/\/@|(\/(channel|user|c)\/)[^/]+(?!\/videos)/.test(location.href)) { - document.documentElement.dataset.pageType = 'channel'; - } else if (/\/shorts\//.test(location.href)) { - document.documentElement.dataset.pageType = 'shorts'; - } else { - document.documentElement.dataset.pageType = 'other'; - } + if (/\/watch\?|\/live\//.test(location.href)) { + document.documentElement.dataset.pageType = "video"; + } else if (location.pathname === "/") { + document.documentElement.dataset.pageType = "home"; + } else if (/\/subscriptions\?/.test(location.href)) { + document.documentElement.dataset.pageType = "subscriptions"; + } else if ( + /\/@|(\/(channel|user|c)\/)[^/]+(?!\/videos)/.test(location.href) + ) { + document.documentElement.dataset.pageType = "channel"; + } else if (/\/shorts\//.test(location.href)) { + document.documentElement.dataset.pageType = "shorts"; + } else { + document.documentElement.dataset.pageType = "other"; + } }; ImprovedTube.pageOnFocus = function () { - ImprovedTube.playerAutopauseWhenSwitchingTabs(); - ImprovedTube.playerAutoPip(); - ImprovedTube.playerQualityWithoutFocus(); + ImprovedTube.playerAutopauseWhenSwitchingTabs(); + ImprovedTube.playerAutoPip(); + ImprovedTube.playerQualityWithoutFocus(); +}; +ImprovedTube.stop_shorts_autoloop = function () { + if (document.documentElement.dataset.pageType === "shorts") { + const video = ImprovedTube.elements.shorts_player.querySelector("video"); + video.removeAttribute("loop"); + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if ( + mutation.type === "attributes" && + mutation.attributeName === "loop" + ) { + video.removeAttribute("loop"); + } + }); + }); + observer.observe(video, { attributes: true }); + } }; -ImprovedTube.stop_shorts_autoloop =function(){ - if(document.documentElement.dataset.pageType === 'shorts'){ - const video = ImprovedTube.elements.shorts_player.querySelector('video') - video.removeAttribute('loop'); - const observer = new MutationObserver((mutations) => { - mutations.forEach((mutation) => { - if (mutation.type === 'attributes' && mutation.attributeName === 'loop') { - video.removeAttribute('loop'); - } - }); - }); - observer.observe(video, { attributes: true }); - } -} ImprovedTube.videoPageUpdate = function () { - if (document.documentElement.dataset.pageType === 'video') { - var video_id = this.getParam(new URL(location.href).search.substr(1), 'v'); - - if (this.storage.track_watched_videos === true && video_id) { - ImprovedTube.messages.send({action: 'watched', - type: 'add', - id: video_id, - title: document.title - }); - } + if (document.documentElement.dataset.pageType === "video") { + var video_id = this.getParam(new URL(location.href).search.substr(1), "v"); + + if (this.storage.track_watched_videos === true && video_id) { + ImprovedTube.messages.send({ + action: "watched", + type: "add", + id: video_id, + title: document.title, + }); + } - this.initialVideoUpdateDone = true; - - ImprovedTube.howLongAgoTheVideoWasUploaded(); - ImprovedTube.dayOfWeek(); - ImprovedTube.exactUploadDate(); - ImprovedTube.channelVideosCount(); - ImprovedTube.upNextAutoplay(); - ImprovedTube.playerAutofullscreen(); - ImprovedTube.playerSize(); - if (this.storage.player_always_repeat === true) { ImprovedTube.playerRepeat(); }; - ImprovedTube.playerScreenshotButton(); - ImprovedTube.playerRepeatButton(); - ImprovedTube.playerRotateButton(); - ImprovedTube.playerPopupButton(); - ImprovedTube.playerFitToWinButton(); - ImprovedTube.playerRewindAndForwardButtons() - ImprovedTube.playerCinemaModeButton(); - ImprovedTube.playerHamburgerButton(); - ImprovedTube.playerControls(); - } + this.initialVideoUpdateDone = true; + + ImprovedTube.howLongAgoTheVideoWasUploaded(); + ImprovedTube.dayOfWeek(); + ImprovedTube.exactUploadDate(); + ImprovedTube.channelVideosCount(); + ImprovedTube.upNextAutoplay(); + ImprovedTube.playerAutofullscreen(); + ImprovedTube.playerSize(); + if (this.storage.player_always_repeat === true) { + ImprovedTube.playerRepeat(); + } + ImprovedTube.playerScreenshotButton(); + ImprovedTube.playerRepeatButton(); + ImprovedTube.playerRotateButton(); + ImprovedTube.playerPopupButton(); + ImprovedTube.playerFitToWinButton(); + ImprovedTube.playerRewindAndForwardButtons(); + ImprovedTube.playerCinemaModeButton(); + ImprovedTube.playerHamburgerButton(); + ImprovedTube.playerControls(); + } }; ImprovedTube.playerOnPlay = function () { - HTMLMediaElement.prototype.play = (function (original) { - return function () { - if (!this.closest('#inline-preview-player')) { - this.removeEventListener('loadedmetadata', ImprovedTube.playerOnLoadedMetadata); - this.addEventListener('loadedmetadata', ImprovedTube.playerOnLoadedMetadata); - - this.removeEventListener('timeupdate', ImprovedTube.playerOnTimeUpdate); - this.addEventListener('timeupdate', ImprovedTube.playerOnTimeUpdate); - - this.removeEventListener('pause', ImprovedTube.playerOnPause, true); - this.addEventListener('pause', ImprovedTube.playerOnPause, true); - this.onpause = () => { - console.log('this.onpause'); - }; - - this.removeEventListener('ended', ImprovedTube.playerOnEnded, true); - this.addEventListener('ended', ImprovedTube.playerOnEnded, true); - ImprovedTube.autoplayDisable(this); - ImprovedTube.playerLoudnessNormalization(); - ImprovedTube.playerCinemaModeEnable(); - } - return original.apply(this, arguments); - } - })(HTMLMediaElement.prototype.play); + HTMLMediaElement.prototype.play = (function (original) { + return function () { + if (!this.closest("#inline-preview-player")) { + this.removeEventListener( + "loadedmetadata", + ImprovedTube.playerOnLoadedMetadata + ); + this.addEventListener( + "loadedmetadata", + ImprovedTube.playerOnLoadedMetadata + ); + + this.removeEventListener("timeupdate", ImprovedTube.playerOnTimeUpdate); + this.addEventListener("timeupdate", ImprovedTube.playerOnTimeUpdate); + + this.removeEventListener("pause", ImprovedTube.playerOnPause, true); + this.addEventListener("pause", ImprovedTube.playerOnPause, true); + this.onpause = () => { + console.log("this.onpause"); + }; + + this.removeEventListener("ended", ImprovedTube.playerOnEnded, true); + this.addEventListener("ended", ImprovedTube.playerOnEnded, true); + ImprovedTube.autoplayDisable(this); + ImprovedTube.playerLoudnessNormalization(); + ImprovedTube.playerCinemaModeEnable(); + } + return original.apply(this, arguments); + }; + })(HTMLMediaElement.prototype.play); }; ImprovedTube.initPlayer = function () { - if (ImprovedTube.elements.player && ImprovedTube.video_url !== location.href) { - ImprovedTube.video_url = location.href; - ImprovedTube.user_interacted = false; - ImprovedTube.played_before_blur = false; - - delete ImprovedTube.elements.player.dataset.defaultQuality; - - ImprovedTube.forcedPlayVideoFromTheBeginning(); - ImprovedTube.playerPlaybackSpeed(); - ImprovedTube.playerSubtitles(); - ImprovedTube.subtitlesLanguage(); - ImprovedTube.subtitlesUserSettings(); - ImprovedTube.subtitlesDisableLyrics(); - ImprovedTube.playerQuality(); - ImprovedTube.batteryFeatures(); - ImprovedTube.playerVolume(); - if (this.storage.player_always_repeat === true) { ImprovedTube.playerRepeat(); } - - ImprovedTube.playerScreenshotButton(); - ImprovedTube.playerRepeatButton(); - ImprovedTube.playerRotateButton(); - ImprovedTube.playerPopupButton(); - ImprovedTube.playerFitToWinButton(); - ImprovedTube.playerRewindAndForwardButtons() - ImprovedTube.playerHamburgerButton(); - ImprovedTube.playerControls(); - ImprovedTube.playerHideProgressPreview(); - ImprovedTube.expandDescription(); - setTimeout(function () {ImprovedTube.forcedTheaterMode(); }, 150); - if (location.href.indexOf('/embed/') === -1) { ImprovedTube.miniPlayer(); } - if (ImprovedTube.storage.disable_auto_dubbing === true) { ImprovedTube.disableAutoDubbing(); } - } + if ( + ImprovedTube.elements.player && + ImprovedTube.video_url !== location.href + ) { + ImprovedTube.video_url = location.href; + ImprovedTube.user_interacted = false; + ImprovedTube.played_before_blur = false; + + delete ImprovedTube.elements.player.dataset.defaultQuality; + + ImprovedTube.forcedPlayVideoFromTheBeginning(); + ImprovedTube.playerPlaybackSpeed(); + ImprovedTube.playerSubtitles(); + ImprovedTube.subtitlesLanguage(); + ImprovedTube.subtitlesUserSettings(); + ImprovedTube.subtitlesDisableLyrics(); + ImprovedTube.playerQuality(); + ImprovedTube.batteryFeatures(); + ImprovedTube.playerVolume(); + if (this.storage.player_always_repeat === true) { + ImprovedTube.playerRepeat(); + } + + ImprovedTube.playerScreenshotButton(); + ImprovedTube.playerRepeatButton(); + ImprovedTube.playerRotateButton(); + ImprovedTube.playerPopupButton(); + ImprovedTube.playerFitToWinButton(); + ImprovedTube.playerRewindAndForwardButtons(); + ImprovedTube.playerHamburgerButton(); + ImprovedTube.playerControls(); + ImprovedTube.playerHideProgressPreview(); + ImprovedTube.expandDescription(); + setTimeout(function () { + ImprovedTube.forcedTheaterMode(); + }, 150); + if (location.href.indexOf("/embed/") === -1) { + ImprovedTube.miniPlayer(); + } + if (ImprovedTube.storage.disable_auto_dubbing === true) { + ImprovedTube.disableAutoDubbing(); + } + } }; var timeUpdateInterval = null; var noTimeUpdate = null; ImprovedTube.playerOnTimeUpdate = function () { - if (!timeUpdateInterval) { - timeUpdateInterval = setInterval(function () { - if (ImprovedTube.video_src !== this.src) { - ImprovedTube.video_src = this.src; - - if (ImprovedTube.initialVideoUpdateDone !== true) { - ImprovedTube.playerQuality(); - ImprovedTube.playerVolume(); - ImprovedTube.playerPlaybackSpeed(); - } - } else if (ImprovedTube.latestVideoDuration !== this.duration) { - ImprovedTube.latestVideoDuration = this.duration; - - ImprovedTube.playerQuality(); - ImprovedTube.playerVolume(); - ImprovedTube.playerPlaybackSpeed(); - } - - if (ImprovedTube.storage.always_show_progress_bar === true) {ImprovedTube.showProgressBar();} - if (ImprovedTube.storage.player_remaining_duration === true) {ImprovedTube.playerRemainingDuration();} - ImprovedTube.played_time += .5; -//Counting time of the player playing for the analyzer feature. (not equal to video time if playback speed isnt 1.00) -//We can also allow to measure session times too and HID times. - }, 500); - } - clearInterval(noTimeUpdate); - noTimeUpdate = setTimeout(function () { - clearInterval(timeUpdateInterval); - timeUpdateInterval = null; - }, 987); + if (!timeUpdateInterval) { + timeUpdateInterval = setInterval(function () { + if (ImprovedTube.video_src !== this.src) { + ImprovedTube.video_src = this.src; + + if (ImprovedTube.initialVideoUpdateDone !== true) { + ImprovedTube.playerQuality(); + ImprovedTube.playerVolume(); + ImprovedTube.playerPlaybackSpeed(); + } + } else if (ImprovedTube.latestVideoDuration !== this.duration) { + ImprovedTube.latestVideoDuration = this.duration; + + ImprovedTube.playerQuality(); + ImprovedTube.playerVolume(); + ImprovedTube.playerPlaybackSpeed(); + } + + if (ImprovedTube.storage.always_show_progress_bar === true) { + ImprovedTube.showProgressBar(); + } + if (ImprovedTube.storage.player_remaining_duration === true) { + ImprovedTube.playerRemainingDuration(); + } + ImprovedTube.played_time += 0.5; + //Counting time of the player playing for the analyzer feature. (not equal to video time if playback speed isnt 1.00) + //We can also allow to measure session times too and HID times. + }, 500); + } + clearInterval(noTimeUpdate); + noTimeUpdate = setTimeout(function () { + clearInterval(timeUpdateInterval); + timeUpdateInterval = null; + }, 987); }; ImprovedTube.playerOnLoadedMetadata = function () { - setTimeout(function () {ImprovedTube.playerSize();}, 100); - setTimeout(function () { if (ImprovedTube.elements.panels) { ImprovedTube.transcript(ImprovedTube.elements.panels); ImprovedTube.chapters(ImprovedTube.elements.panels);}}, 250); + setTimeout(function () { + ImprovedTube.playerSize(); + }, 100); + setTimeout(function () { + if (ImprovedTube.elements.panels) { + ImprovedTube.transcript(ImprovedTube.elements.panels); + ImprovedTube.chapters(ImprovedTube.elements.panels); + } + }, 250); }; ImprovedTube.playerOnPause = function (event) { - ImprovedTube.playlistUpNextAutoplay(event); - - if (ImprovedTube.elements.yt_channel_name) { - ImprovedTube.messages.send({action: 'analyzer', - name: ImprovedTube.elements.yt_channel_name.__data.tooltipText, - time: ImprovedTube.played_time - }); - } - ImprovedTube.played_time = 0; - ImprovedTube.playerControls(); - ImprovedTube.playerCinemaModeDisable(); - + ImprovedTube.playlistUpNextAutoplay(event); + + if (ImprovedTube.elements.yt_channel_name) { + ImprovedTube.messages.send({ + action: "analyzer", + name: ImprovedTube.elements.yt_channel_name.__data.tooltipText, + time: ImprovedTube.played_time, + }); + } + ImprovedTube.played_time = 0; + ImprovedTube.playerControls(); + ImprovedTube.playerCinemaModeDisable(); }; // if ( document.documentElement.dataset.pageType === 'video' -// && (ImprovedTube.storage.description === "expanded" || ImprovedTube.storage.transcript === true || ImprovedTube.storage.chapters === true )) { +// && (ImprovedTube.storage.description === "expanded" || ImprovedTube.storage.transcript === true || ImprovedTube.storage.chapters === true )) { // ImprovedTube.forbidFocus = function (ms) /*-------------------------------------------------------------- # HIDE PROGRESS BAR PREVIEW --------------------------------------------------------------*/ ImprovedTube.playerHideProgressPreview = function () { - const shouldHide = this.storage.player_hide_progress_preview === true; - - if (shouldHide) { - document.documentElement.setAttribute('it-hide-progress-preview', 'true'); - - // Force refresh the player UI - if (this.elements.player) { - this.elements.player.dispatchEvent(new Event('mousemove')); - // Also try to force hide any existing tooltips - const tooltips = document.querySelectorAll('.ytp-tooltip, .ytp-preview, .ytp-tooltip-text-wrapper'); - tooltips.forEach(tooltip => { - tooltip.style.display = 'none'; - tooltip.style.opacity = '0'; - tooltip.style.visibility = 'hidden'; - }); - } - } else { - document.documentElement.removeAttribute('it-hide-progress-preview'); + const shouldHide = this.storage.player_hide_progress_preview === true; + + if (shouldHide) { + document.documentElement.setAttribute("it-hide-progress-preview", "true"); + + // Force refresh the player UI + if (this.elements.player) { + this.elements.player.dispatchEvent(new Event("mousemove")); + // Also try to force hide any existing tooltips + const tooltips = document.querySelectorAll( + ".ytp-tooltip, .ytp-preview, .ytp-tooltip-text-wrapper" + ); + tooltips.forEach((tooltip) => { + tooltip.style.display = "none"; + tooltip.style.opacity = "0"; + tooltip.style.visibility = "hidden"; + }); } + } else { + document.documentElement.removeAttribute("it-hide-progress-preview"); + } }; ImprovedTube.playerOnEnded = function (event) { - ImprovedTube.playlistUpNextAutoplay(event); + ImprovedTube.playlistUpNextAutoplay(event); - ImprovedTube.messages.send({action: 'analyzer', - //adding "?" (not a fix) - name: ImprovedTube.elements.yt_channel_name?.__data.tooltipText, - time: ImprovedTube.played_time - }); + ImprovedTube.messages.send({ + action: "analyzer", + //adding "?" (not a fix) + name: ImprovedTube.elements.yt_channel_name?.__data.tooltipText, + time: ImprovedTube.played_time, + }); - ImprovedTube.played_time = 0; + ImprovedTube.played_time = 0; }; // https://github.com/code-charity/youtube/pull/2431 ImprovedTube.onkeydown = function () { - ImprovedTube.pauseWhileTypingOnYoutube() - window.addEventListener('keydown', function () { - ImprovedTube.user_interacted = true; // = event.key - }, true); + ImprovedTube.pauseWhileTypingOnYoutube(); + window.addEventListener( + "keydown", + function () { + ImprovedTube.user_interacted = true; // = event.key + }, + true + ); }; ImprovedTube.onmousedown = function (event) { - window.addEventListener('mousedown', function (event) { - ImprovedTube.user_interacted = true; // = mousedown - }, true); + window.addEventListener( + "mousedown", + function (event) { + ImprovedTube.user_interacted = true; // = mousedown + }, + true + ); }; /* @@ -518,216 +664,290 @@ ImprovedTube.onmousedown = function () { */ ImprovedTube.getParam = function (query, name) { - var params = query.split('&'), - param = false; + var params = query.split("&"), + param = false; - for (var i = 0; i < params.length; i++) { - params[i] = params[i].split('='); + for (var i = 0; i < params.length; i++) { + params[i] = params[i].split("="); - if (params[i][0] == name) { - param = params[i][1]; - } - } + if (params[i][0] == name) { + param = params[i][1]; + } + } - if (param) { - return param; - } else { - return false; - } + if (param) { + return param; + } else { + return false; + } }; ImprovedTube.getParams = function (query) { - var params = query.split('&'), - result = {}; + var params = query.split("&"), + result = {}; - for (var i = 0, l = params.length; i < l; i++) { - params[i] = params[i].split('='); + for (var i = 0, l = params.length; i < l; i++) { + params[i] = params[i].split("="); - result[params[i][0]] = params[i][1]; - } + result[params[i][0]] = params[i][1]; + } - return result; + return result; }; ImprovedTube.getCookieValueByName = function (name) { - var match = document.cookie.match(new RegExp('([; ]' + name + '|^' + name + ')([^\\s;]*)', 'g')); + var match = document.cookie.match( + new RegExp("([; ]" + name + "|^" + name + ")([^\\s;]*)", "g") + ); - if (match) { - var cookie = match[0]; + if (match) { + var cookie = match[0]; - return cookie.replace(name + '=', '').replace(' ', ''); - } else return ''; + return cookie.replace(name + "=", "").replace(" ", ""); + } else return ""; }; ImprovedTube.getPrefCookieValueByName = function (name) { - let prefs = this.getParams(this.getCookieValueByName('PREF')); - return prefs[name]; + let prefs = this.getParams(this.getCookieValueByName("PREF")); + return prefs[name]; }; // set PREF cookie name=value or delete name if value == null ImprovedTube.setPrefCookieValueByName = function (name, value) { - let originalPref = this.getCookieValueByName('PREF'); - let prefs = this.getParams(originalPref); - let newPrefs = ''; - let ampersant = ''; - - if (name == 'f6' && prefs[name] & 1) { - // f6 holds other settings, possible values 80000 80001 400 401 1 none - // make sure we remember 1 bit - prefs[name] = value | 1; - } else { - prefs[name] = value; - } - - for (let pref in prefs) { - if (prefs[pref]) { - newPrefs += ampersant + pref + '=' + prefs[pref]; - ampersant = '&'; - } - } - // only write cookie if its different from the old one - if (originalPref != newPrefs) { - this.setCookie('PREF', newPrefs); - } + let originalPref = this.getCookieValueByName("PREF"); + let prefs = this.getParams(originalPref); + let newPrefs = ""; + let ampersant = ""; + + if (name == "f6" && prefs[name] & 1) { + // f6 holds other settings, possible values 80000 80001 400 401 1 none + // make sure we remember 1 bit + prefs[name] = value | 1; + } else { + prefs[name] = value; + } + + for (let pref in prefs) { + if (prefs[pref]) { + newPrefs += ampersant + pref + "=" + prefs[pref]; + ampersant = "&"; + } + } + // only write cookie if its different from the old one + if (originalPref != newPrefs) { + this.setCookie("PREF", newPrefs); + } }; ImprovedTube.setCookie = function (name, value) { - var date = new Date(); + var date = new Date(); - date.setTime(date.getTime() + 3.154e+10); + date.setTime(date.getTime() + 3.154e10); - document.cookie = name + '=' + value + '; path=/; domain=.youtube.com; expires=' + date.toGMTString(); + document.cookie = + name + + "=" + + value + + "; path=/; domain=.youtube.com; expires=" + + date.toGMTString(); }; ImprovedTube.createIconButton = function (options) { - const button = options.href ? document.createElement('a') : document.createElement('button'), - svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), - path = document.createElementNS('http://www.w3.org/2000/svg', 'path'), - type = this.button_icons[options.type]; - - for (const attr of type.svg) svg.setAttribute(attr[0], attr[1]); - for (const attr of type.path) path.setAttribute(attr[0], attr[1]); - - svg.appendChild(path); - button.appendChild(svg); - - if (options.className) button.className = options.className; - if (options.id) button.id = options.id; - if (options.text) button.appendChild(document.createTextNode(options.text)); - if (options.href) button.href = options.href; - if (options.onclick) { - if (!options.propagate) { - //we fully own all click events landing on this button - button.onclick = function (event) { - event.preventDefault(); - event.stopPropagation(); - options.onclick.apply(this, arguments); - } - } else { - button.onclick = options.onclick; - } - } - return button; + const button = options.href + ? document.createElement("a") + : document.createElement("button"), + svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), + path = document.createElementNS("http://www.w3.org/2000/svg", "path"), + type = this.button_icons[options.type]; + + for (const attr of type.svg) svg.setAttribute(attr[0], attr[1]); + for (const attr of type.path) path.setAttribute(attr[0], attr[1]); + + svg.appendChild(path); + button.appendChild(svg); + + if (options.className) button.className = options.className; + if (options.id) button.id = options.id; + if (options.text) button.appendChild(document.createTextNode(options.text)); + if (options.href) button.href = options.href; + if (options.onclick) { + if (!options.propagate) { + //we fully own all click events landing on this button + button.onclick = function (event) { + event.preventDefault(); + event.stopPropagation(); + options.onclick.apply(this, arguments); + }; + } else { + button.onclick = options.onclick; + } + } + return button; }; ImprovedTube.createPlayerButton = function (options) { - var controls = options.position == "right" ? this.elements.player_right_controls : this.elements.player_left_controls; - if (controls) { - var button = document.createElement('button'); + var controls = + options.position == "right" + ? this.elements.player_right_controls + : this.elements.player_left_controls; + if (controls) { + var button = document.createElement("button"); - button.className = 'ytp-button it-player-button'; + button.className = "ytp-button it-player-button"; - button.dataset.title = options.title; + button.dataset.title = options.title; - button.addEventListener('mouseover', function () { - var tooltip = document.createElement('div'), - rect = this.getBoundingClientRect(); + button.addEventListener("mouseover", function () { + var tooltip = document.createElement("div"), + rect = this.getBoundingClientRect(); - tooltip.className = 'it-player-button--tooltip'; + tooltip.className = "it-player-button--tooltip"; - tooltip.style.left = rect.left + rect.width / 2 + 'px'; - tooltip.style.top = rect.top - 8 + 'px'; + tooltip.style.left = rect.left + rect.width / 2 + "px"; + tooltip.style.top = rect.top - 8 + "px"; - tooltip.textContent = this.dataset.title; - if (this.storage && (this.storage.player_cinema_mode_button || this.storage.player_auto_hide_cinema_mode_when_paused || this.storage.player_auto_cinema_mode)) { - tooltip.style.zIndex = 10001;} // needed for cinema mode - function mouseleave () { - tooltip.remove(); + tooltip.textContent = this.dataset.title; + if ( + this.storage && + (this.storage.player_cinema_mode_button || + this.storage.player_auto_hide_cinema_mode_when_paused || + this.storage.player_auto_cinema_mode) + ) { + tooltip.style.zIndex = 10001; + } // needed for cinema mode + function mouseleave() { + tooltip.remove(); - this.removeEventListener('mouseleave', mouseleave); - } + this.removeEventListener("mouseleave", mouseleave); + } - this.addEventListener('mouseleave', mouseleave); + this.addEventListener("mouseleave", mouseleave); - document.body.appendChild(tooltip); - }); + document.body.appendChild(tooltip); + }); - if (options.id) { - if (this.elements.buttons[options.id]) { - this.elements.buttons[options.id].remove(); - } + if (options.id) { + if (this.elements.buttons[options.id]) { + this.elements.buttons[options.id].remove(); + } - button.id = options.id; + button.id = options.id; - this.elements.buttons[options.id] = button; - } + this.elements.buttons[options.id] = button; + } - if (options.child) { - button.appendChild(options.child); - } + if (options.child) { + button.appendChild(options.child); + } - button.style.opacity = options.opacity || .5; + button.style.opacity = options.opacity || 0.5; - if (options.onclick) { - button.onclick = options.onclick; - } + if (options.onclick) { + button.onclick = options.onclick; + } - controls.insertBefore(button, controls.childNodes[3]); - return button; - } + controls.insertBefore(button, controls.childNodes[3]); + return button; + } }; -ImprovedTube.empty = function (element) {for (var i = element.childNodes.length - 1; i > -1; i--) { element.childNodes[i].remove(); }}; -ImprovedTube.isset = function (variable) {return !(typeof variable === 'undefined' || variable === null || variable === 'null');}; +ImprovedTube.empty = function (element) { + for (var i = element.childNodes.length - 1; i > -1; i--) { + element.childNodes[i].remove(); + } +}; +ImprovedTube.isset = function (variable) { + return !( + typeof variable === "undefined" || + variable === null || + variable === "null" + ); +}; ImprovedTube.showStatus = function (value) { - if (!this.elements.status) { - this.elements.status = document.createElement('div'); + if (!this.elements.status) { + this.elements.status = document.createElement("div"); - this.elements.status.id = 'it-status'; - } + this.elements.status.id = "it-status"; + } - if (typeof value === 'number') { - value = value.toFixed(2); - } + if (typeof value === "number") { + value = value.toFixed(2); + } - this.elements.status.textContent = value; + this.elements.status.textContent = value; - if (ImprovedTube.status_timer) { - clearTimeout(ImprovedTube.status_timer); - } + if (ImprovedTube.status_timer) { + clearTimeout(ImprovedTube.status_timer); + } - ImprovedTube.status_timer = setTimeout(function () {ImprovedTube.elements.status.remove();}, 500); + ImprovedTube.status_timer = setTimeout(function () { + ImprovedTube.elements.status.remove(); + }, 500); - this.elements.player.appendChild(this.elements.status); + this.elements.player.appendChild(this.elements.status); }; -ImprovedTube.videoId = (url = document.URL) => url.match(ImprovedTube.regex.video_id)?.[1] || new URL(url).searchParams.get('v') || movie_player?.getVideoData?.().video_id || (console.log('No VIDEO ID URL MATCH match: Regex & url are:', ImprovedTube.regex.video_id, url), undefined); -ImprovedTube.videoTitle = function () {return document.title?.replace(/\s*-\s*YouTube$/, '') || movie_player.getVideoData().title || document.querySelector('#title > h1 > *')?.textContent}; +ImprovedTube.videoId = (url = document.URL) => + url.match(ImprovedTube.regex.video_id)?.[1] || + new URL(url).searchParams.get("v") || + movie_player?.getVideoData?.().video_id || + (console.log( + "No VIDEO ID URL MATCH match: Regex & url are:", + ImprovedTube.regex.video_id, + url + ), + undefined); +ImprovedTube.videoTitle = function () { + return ( + document.title?.replace(/\s*-\s*YouTube$/, "") || + movie_player.getVideoData().title || + document.querySelector("#title > h1 > *")?.textContent + ); +}; // Function to extract and store the number of subscribers ImprovedTube.extractSubscriberCount = function (subscriberCountNode) { - if (!subscriberCountNode) {subscriberCountNode = document.getElementById('owner-sub-count');} - if (subscriberCountNode) { - // Extract the subscriber count and store it for further use - var subscriberCountText = subscriberCountNode.textContent.trim(); - var subscriberCount = parseFloat(subscriberCountText.replace(/[^0-9.]/g, '')); - - if (subscriberCountText.includes('K')) { - subscriberCount *= 1000; - } else if (subscriberCountText.includes('M')) { - subscriberCount *= 1000000; - } + if (!subscriberCountNode) { + subscriberCountNode = document.getElementById("owner-sub-count"); + } + if (subscriberCountNode) { + // Extract the subscriber count and store it for further use + var subscriberCountText = subscriberCountNode.textContent.trim(); + var subscriberCount = parseFloat( + subscriberCountText.replace(/[^0-9.]/g, "") + ); + + if (subscriberCountText.includes("K")) { + subscriberCount *= 1000; + } else if (subscriberCountText.includes("M")) { + subscriberCount *= 1000000; + } - ImprovedTube.subscriberCount = subscriberCount; - } + ImprovedTube.subscriberCount = subscriberCount; + } }; + +(function tryInitMuteAds(attempt = 0) { + if ( + ImprovedTube.storage.ads === "mute_ads" && + !ImprovedTube._mutedAdsObserverInitialized + ) { + const player = document.getElementById("movie_player"); + const video = document.querySelector(".video-stream.html5-main-video"); + + if (player && video) { + ImprovedTube.elements.player = player; + ImprovedTube.elements.video = video; + ImprovedTube.muteAds(); + return; + } + + if (attempt < 20) { + setTimeout(() => tryInitMuteAds(attempt + 1), 300); // retry every 300ms + } else { + console.warn( + "[tryInitMuteAds] Gave up after 6 seconds — player not found" + ); + } + } +})(); diff --git a/js&css/web-accessible/www.youtube.com/player.js b/js&css/web-accessible/www.youtube.com/player.js index 9ddfefb8e..d30a07f7e 100644 --- a/js&css/web-accessible/www.youtube.com/player.js +++ b/js&css/web-accessible/www.youtube.com/player.js @@ -2,248 +2,487 @@ AUTOPLAY DISABLE ------------------------------------------------------------------------------*/ ImprovedTube.autoplayDisable = function (videoElement) { - if (this.storage.player_autoplay_disable - || this.storage.playlist_autoplay === false - || this.storage.channel_trailer_autoplay === false) { - const player = this.elements.player || videoElement.closest('.html5-video-player') || videoElement.closest('#movie_player'); // #movie_player: outdated since 2024? - - if (this.video_url !== location.href) { this.user_interacted = false; } - - //if (there is a player) and (no user clicks) and (no ads playing) - // and( ((auto play is off and it is not in a playlist) - // or (playlist auto play is off and in a playlist)) - // or (we are in a channel and the channel trailer autoplay is off) ) - - if (player && !this.user_interacted // (=user didnt click or type) - && !player.classList.contains('ad-showing') // (=no ads playing, needs an update?) - && ((location.href.includes('/watch?') // #1703 // (=video page) - // player_autoplay_disable & not playlist - && (this.storage.player_autoplay_disable && !location.href.includes('list=')) - // !playlist_autoplay & playlist - || (this.storage.playlist_autoplay === false && location.href.includes('list='))) - // channel homepage & !channel_trailer_autoplay - || (this.storage.channel_trailer_autoplay === false && this.regex.channel.test(location.href)))) { - - setTimeout(function () { - try { player.pauseVideo(); } catch (error) { console.log("autoplayDisable: Pausing"); videoElement.pause(); } - }); - } else { - document.dispatchEvent(new CustomEvent('it-play')); - } - } else { - document.dispatchEvent(new CustomEvent('it-play')); - } + if ( + this.storage.player_autoplay_disable || + this.storage.playlist_autoplay === false || + this.storage.channel_trailer_autoplay === false + ) { + const player = + this.elements.player || + videoElement.closest(".html5-video-player") || + videoElement.closest("#movie_player"); // #movie_player: outdated since 2024? + + if (this.video_url !== location.href) { + this.user_interacted = false; + } + + //if (there is a player) and (no user clicks) and (no ads playing) + // and( ((auto play is off and it is not in a playlist) + // or (playlist auto play is off and in a playlist)) + // or (we are in a channel and the channel trailer autoplay is off) ) + + if ( + player && + !this.user_interacted && // (=user didnt click or type) + !player.classList.contains("ad-showing") && // (=no ads playing, needs an update?) + ((location.href.includes("/watch?") && // #1703 // (=video page) + // player_autoplay_disable & not playlist + this.storage.player_autoplay_disable && + !location.href.includes("list=")) || + // !playlist_autoplay & playlist + (this.storage.playlist_autoplay === false && + location.href.includes("list=")) || + // channel homepage & !channel_trailer_autoplay + (this.storage.channel_trailer_autoplay === false && + this.regex.channel.test(location.href))) + ) { + setTimeout(function () { + try { + player.pauseVideo(); + } catch (error) { + console.log("autoplayDisable: Pausing"); + videoElement.pause(); + } + }); + } else { + document.dispatchEvent(new CustomEvent("it-play")); + } + } else { + document.dispatchEvent(new CustomEvent("it-play")); + } }; /*------------------------------------------------------------------------------ FORCED PLAY VIDEO FROM THE BEGINNING ------------------------------------------------------------------------------*/ ImprovedTube.forcedPlayVideoFromTheBeginning = function () { - const player = this.elements.player, - video = this.elements.video, - paused = video?.paused; - - if (player && video && this.storage.forced_play_video_from_the_beginning && location.pathname == '/watch') { - player.seekTo(0); - // restore previous paused state - if (paused) { player.pauseVideo(); } - } + const player = this.elements.player, + video = this.elements.video, + paused = video?.paused; + + if ( + player && + video && + this.storage.forced_play_video_from_the_beginning && + location.pathname == "/watch" + ) { + player.seekTo(0); + // restore previous paused state + if (paused) { + player.pauseVideo(); + } + } }; /*------------------------------------------------------------------------------ AUTOPAUSE WHEN SWITCHING TABS ------------------------------------------------------------------------------*/ ImprovedTube.playerAutopauseWhenSwitchingTabs = function () { - const player = this.elements.player; - - if (this.storage.player_autopause_when_switching_tabs && player) { - if (this.focus && this.played_before_blur && this.elements.video.paused) { - player.playVideo(); - } else { - this.played_before_blur = !this.elements.video.paused; - if (!this.elements.video.paused) { - player.pauseVideo(); - } - } - } + const player = this.elements.player; + + if (this.storage.player_autopause_when_switching_tabs && player) { + if (this.focus && this.played_before_blur && this.elements.video.paused) { + player.playVideo(); + } else { + this.played_before_blur = !this.elements.video.paused; + if (!this.elements.video.paused) { + player.pauseVideo(); + } + } + } }; /*------------------------------------------------------------------------------ PICTURE IN PICTURE (PIP) ------------------------------------------------------------------------------*/ ImprovedTube.enterPip = function (disable) { - const video = this.elements.video; - - if (!disable - && video - && document.pictureInPictureEnabled - && typeof video.requestPictureInPicture == 'function') { - - video.requestPictureInPicture().then(() => { - if (video.paused) { - // manually send Play message to "Auto-pause while I'm not in the tab", paused PiP wont do it automatically. - document.dispatchEvent(new CustomEvent('it-play')); - } - return true; - }).catch((err) => console.error('playerAutoPip: Failed to enter Picture-in-Picture mode', err)); - } else if (document.pictureInPictureElement && typeof document.exitPictureInPicture == 'function') { - document.exitPictureInPicture(); - return false; - } + const video = this.elements.video; + + if ( + !disable && + video && + document.pictureInPictureEnabled && + typeof video.requestPictureInPicture == "function" + ) { + video + .requestPictureInPicture() + .then(() => { + if (video.paused) { + // manually send Play message to "Auto-pause while I'm not in the tab", paused PiP wont do it automatically. + document.dispatchEvent(new CustomEvent("it-play")); + } + return true; + }) + .catch((err) => + console.error( + "playerAutoPip: Failed to enter Picture-in-Picture mode", + err + ) + ); + } else if ( + document.pictureInPictureElement && + typeof document.exitPictureInPicture == "function" + ) { + document.exitPictureInPicture(); + return false; + } }; /*------------------------------------------------------------------------------ AUTO PIP WHEN SWITCHING TABS ------------------------------------------------------------------------------*/ ImprovedTube.playerAutoPip = function () { - const video = this.elements.video; - - if (this.storage.player_autoPip && this.storage.player_autoPip_outside && this.focus) { - this.enterPip(true); - } else if (this.storage.player_autoPip && !this.focus && !video?.paused) { - this.enterPip(); - } + const video = this.elements.video; + + if ( + this.storage.player_autoPip && + this.storage.player_autoPip_outside && + this.focus + ) { + this.enterPip(true); + } else if (this.storage.player_autoPip && !this.focus && !video?.paused) { + this.enterPip(); + } }; /*------------------------------------------------------------------------------ PLAYBACK SPEED ------------------------------------------------------------------------------*/ ImprovedTube.playbackSpeed = function (newSpeed) { - const video = this.elements.video, - player = this.elements.player, - speed = video?.playbackRate ? Number(video.playbackRate.toFixed(2)) : (player?.getPlaybackRate ? Number(player.getPlaybackRate().toFixed(2)) : null); - - if (!speed) { - console.error('PlaybackSpeed: Cant establish playbackRate/getPlaybackRate'); - return false; - } - - // called with no option or demanded speed already set, only provide readback - if (!newSpeed || speed == newSpeed) return speed; - - if (video?.playbackRate) { - video.playbackRate = newSpeed; - newSpeed = video.playbackRate; - } else if (player?.setPlaybackRate && player.getPlaybackRate) { - player.setPlaybackRate(newSpeed); - newSpeed = player.getPlaybackRate(); - } else newSpeed = false; - - return newSpeed; + const video = this.elements.video, + player = this.elements.player, + speed = video?.playbackRate + ? Number(video.playbackRate.toFixed(2)) + : player?.getPlaybackRate + ? Number(player.getPlaybackRate().toFixed(2)) + : null; + + if (!speed) { + console.error("PlaybackSpeed: Cant establish playbackRate/getPlaybackRate"); + return false; + } + + // called with no option or demanded speed already set, only provide readback + if (!newSpeed || speed == newSpeed) return speed; + + if (video?.playbackRate) { + video.playbackRate = newSpeed; + newSpeed = video.playbackRate; + } else if (player?.setPlaybackRate && player.getPlaybackRate) { + player.setPlaybackRate(newSpeed); + newSpeed = player.getPlaybackRate(); + } else newSpeed = false; + + return newSpeed; }; /*------------------------------------------------------------------------------ PERMANENT PLAYBACK SPEED ------------------------------------------------------------------------------*/ -ImprovedTube.playerPlaybackSpeed = function () { if (this.storage.player_forced_playback_speed === true) { - var player = this.elements.player; if (!player) return; - var video = this.elements.video || player.querySelector('video'); - option = this.storage.player_playback_speed; - if (this.isset(option) === false) { option = 1; } - else if ( option !== 1 ) { - const speed = video?.playbackRate ? Number(video.playbackRate.toFixed(2)) : (player?.getPlaybackRate ? Number(player.getPlaybackRate().toFixed(2)) : null); - if (speed !== option && speed !== 1 && speed !== Number((Math.floor(option / 0.05) * 0.05).toFixed(2))) - { console.log("skipping permanent speed, since speed was manually set differently for this video to:" + video.playbackRate + ", was it?"); return; } - } - if (!(player.getVideoData() && player.getVideoData().isLive)) - { player.setPlaybackRate(Number(option)); if (!video) { video = { playbackRate: 1 }; }; video.playbackRate = Number(option); // #1729 q2 // hi! @raszpl - if ( (this.storage.player_force_speed_on_music !== true || this.storage.player_dont_speed_education === true) - && option !== 1) { - ImprovedTube.speedException = function () { - if (this.storage.player_dont_speed_education === true && DATA.genre === 'Education') - {player.setPlaybackRate(Number(1)); video.playbackRate = Number(1); return;} - if (this.storage.player_force_speed_on_music === true) - { //player.setPlaybackRate(Number(option)); video.playbackRate = Number(option); - return;} - if (DATA.keywords && !keywords) { keywords = DATA.keywords.join(', ') || ''; } - if (keywords === 'video, sharing, camera phone, video phone, free, upload') { keywords = ''; } - var musicIdentifiers = /(official|music|lyrics?)[ -]video|(cover|studio|radio|album|alternate)[- ]version|soundtrack|unplugged|\bmedley\b|\blo-fi\b|\blofi\b|a(lla)? cappella|feat\.|(piano|guitar|jazz|ukulele|violin|reggae)[- ](version|cover)|karaok|backing[- ]track|instrumental|(sing|play)[- ]?along|卡拉OK|卡拉OK|الكاريوكي|караоке|カラオケ|노래방|bootleg|mashup|Radio edit|Guest (vocals|musician)|(title|opening|closing|bonus|hidden)[ -]track|live acoustic|interlude|featuring|recorded (at|live)/i; - var musicIdentifiersTitleOnly = /lyrics|theme song|\bremix|\bAMV ?[^a-z0-9]|[^a-z0-9] ?AMV\b|\bfull song\b|\bsong:|\bsong[\!$]|^song\b|( - .*\bSong\b|\bSong\b.* - )|cover ?[^a-z0-9]|[^a-z0-9] ?cover|\bconcert\b/i; - var musicIdentifiersTitle = new RegExp(musicIdentifiersTitleOnly.source + '|' + musicIdentifiers.source, "i"); - var musicRegexMatch = musicIdentifiersTitle.test(DATA.title); - if (!musicRegexMatch) { - var musicIdentifiersTagsOnly = /, (lyrics|remix|song|music|AMV|theme song|full song),|\(Musical Genre\)|, jazz|, reggae/i; - var musicIdentifiersTags = new RegExp(musicIdentifiersTagsOnly.source + '|' + musicIdentifiers.source, "i"); - keywordsAmount = 1 + ((keywords || '').match(/,/) || []).length; - if ( ((keywords || '').match(musicIdentifiersTags) || []).length / keywordsAmount > 0.08) { - musicRegexMatch = true}} - notMusicRegexMatch = /\bdo[ck]u|interv[iyj]|back[- ]?stage|インタビュー|entrevista|面试|面試|회견|wawancara|مقابلة|интервью|entretien|기록한 것|记录|記錄|ドキュメンタリ|وثائقي|документальный/i.test(DATA.title + " " + keywords); - // (Tags/keywords shouldnt lie & very few songs titles might have these words) - if (DATA.duration) { - function parseDuration (duration) { const [_, h = 0, m = 0, s = 0] = duration.match(/PT(?:(\d+)?H)?(?:(\d+)?M)?(\d+)?S?/).map(part => parseInt(part) || 0); - return h * 3600 + m * 60 + s; } - DATA.lengthSeconds = parseDuration(DATA.duration); } - function testSongDuration (s, ytMusic) { - if (135 <= s && s <= 260) {return 'veryCommon';} - if (105 <= s && s <= 420) {return 'common';} - if (420 <= s && s <= 720) {return 'long';} - if (45 <= s && s <= 105) {return 'short';} - if (ytMusic && ytMusic > 1 && (85 <= s / ytMusic && (s / ytMusic <= 375 || ytMusic == 10))) {return 'multiple';} - //does Youtube ever show more than 10 songs below the description? - } - var songDurationType = testSongDuration(DATA.lengthSeconds); - console.log("genre: " + DATA.genre + "//title: " + DATA.title + "//keywords: " + keywords + "//music word match: " + musicRegexMatch + "// not music word match:" + notMusicRegexMatch + "//duration: " + DATA.lengthSeconds + "//song duration type: " + songDurationType); - // check if the video is PROBABLY MUSIC: - if ( ( DATA.genre === 'Music' && (!notMusicRegexMatch || songDurationType === 'veryCommon')) - || ( musicRegexMatch && !notMusicRegexMatch && (typeof songDurationType !== 'undefined' - || (/album|Álbum|专辑|專輯|एलबम|البوم|アルバム|альбом|앨범|mixtape|concert|playlist|\b(live|cd|vinyl|lp|ep|compilation|collection|symphony|suite|medley)\b/i.test(DATA.title + " " + keywords) - && 1000 <= DATA.lengthSeconds )) ) // && 1150 <= DATA.lengthSeconds <= 5000 - || ( DATA.genre === 'Music' && musicRegexMatch && (typeof songDurationType !== 'undefined' - || (/album|Álbum|专辑|專輯|एलबम|البوم|アルバム|альбом|앨범|mixtape|concert|playlist|\b(live|cd|vinyl|lp|ep|compilation|collection|symphony|suite|medley)\b/i.test(DATA.title + " " + keywords) - && 1000 <= DATA.lengthSeconds )) ) // && DATA.lengthSeconds <= 5000 - || (amountOfSongs && testSongDuration(DATA.lengthSeconds, amountOfSongs ) !== 'undefined') - // || location.href.indexOf('music.') !== -1 // (=currently we are only running on www.youtube.com anyways) - ) { player.setPlaybackRate(1); video.playbackRate = 1; console.log ("...,thus must be music?"); } - else { // Now this video might rarely be music - // - however we can make extra-sure after waiting for the video descripion to load... (#1539) - var tries = 0; var intervalMs = 210; if (location.href.indexOf('/watch?') !== -1) {var maxTries = 10;} else {var maxTries = 0;} - // ...except when it is an embedded player? - var waitForDescription = setInterval(() => { - if (++tries >= maxTries) { - subtitle = document.querySelector('#title + #subtitle:last-of-type') - if ( subtitle && 1 <= Number((subtitle?.innerHTML?.match(/^\d+/) || [])[0]) // indicates buyable/registered music (amount of songs) - && typeof testSongDuration(DATA.lengthSeconds, Number((subtitle?.innerHTML?.match(/^\d+/) || [])[0]) ) !== 'undefined' ) // resonable duration - {player.setPlaybackRate(1); video.playbackRate = 1; console.log("...but YouTube shows music below the description!"); clearInterval(waitForDescription); } - intervalMs *= 1.11; }}, intervalMs); - window.addEventListener('load', () => { setTimeout(() => { clearInterval(waitForDescription); }, 1234); }); - } - } - //DATA (TO-DO: make the Data available to more/all features? #1452 #1763 (Then can replace ImprovedTube.elements.category === 'music', VideoID is also used elsewhere) - DATA = {}; - defaultKeywords = "video,sharing,camera,phone,video phone,free,upload"; - keywords = false; amountOfSongs = false; - - ImprovedTube.fetchDOMData = function () { - try { DATA = JSON.parse(document.querySelector('#microformat script')?.textContent) ?? false; DATA.title = DATA.name;} - catch { DATA.genre = false; DATA.keywords = false; DATA.lengthSeconds = false; - try { - DATA.title = document.getElementsByTagName('meta')?.title?.content || false; - DATA.genre = document.querySelector('meta[itemprop=genre]')?.content || false; - DATA.duration = document.querySelector('meta[itemprop=duration]')?.content || false; - } catch {}} - -let tries = 0; const maxTries = 11; let intervalMs = 200; -const waitForVideoTitle = setInterval(() => { const title = ImprovedTube.videoTitle?.(); tries++; - -if (title && title !== 'YouTube') { - clearInterval(waitForVideoTitle); - DATA.videoID = ImprovedTube.videoId() || false; // console.log("SPEED: TITLE:" + ImprovedTube.videoTitle() + DATA.title); - if ( DATA.title === ImprovedTube.videoTitle() || DATA.title.replace(/\s{2,}/g, ' ') === ImprovedTube.videoTitle() ) - { keywords = document.querySelector('meta[name="keywords"]')?.content || ''; ImprovedTube.speedException(); } - else { keywords = ''; (async function () { try { const response = await fetch(`https://www.youtube.com/watch?v=${DATA.videoID}`); - console.log("loading the html source:" + `https://www.youtube.com/watch?v=${DATA.videoID}`); - const htmlContent = await response.text(); - const metaRegex = /]+(name|itemprop)=["'](keywords|genre|duration)["'][^>]+content=["']([^"']+)["'][^>]*>/gi; - let match; while ((match = metaRegex.exec(htmlContent)) !== null) { // console.log(match); - const [, property, value] = match; - if (property === 'keywords') { keywords = value;} else {DATA[property] = value;} - } - amountOfSongs = (htmlContent.slice(-80000).match(/},"subtitle":{"simpleText":"(\d*)\s/) || [])[1] || false; - if (keywords) { ImprovedTube.speedException(); } - } catch (error) { console.error('Error: fetching from https://Youtube.com/watch?v=${DATA.videoID}', error); keywords = ''; } - })(); - } -} - -if (tries >= maxTries) { clearInterval(waitForVideoTitle); } intervalMs *= 1.11; }, intervalMs); -window.addEventListener('load', () => { setTimeout(() => { clearInterval(waitForVideoTitle) }, 5000);}); - }; - ImprovedTube.fetchDOMData(); -/* +ImprovedTube.playerPlaybackSpeed = function () { + if (this.storage.player_forced_playback_speed === true) { + var player = this.elements.player; + if (!player) return; + var video = this.elements.video || player.querySelector("video"); + option = this.storage.player_playback_speed; + if (this.isset(option) === false) { + option = 1; + } else if (option !== 1) { + const speed = video?.playbackRate + ? Number(video.playbackRate.toFixed(2)) + : player?.getPlaybackRate + ? Number(player.getPlaybackRate().toFixed(2)) + : null; + if ( + speed !== option && + speed !== 1 && + speed !== Number((Math.floor(option / 0.05) * 0.05).toFixed(2)) + ) { + console.log( + "skipping permanent speed, since speed was manually set differently for this video to:" + + video.playbackRate + + ", was it?" + ); + return; + } + } + if (!(player.getVideoData() && player.getVideoData().isLive)) { + player.setPlaybackRate(Number(option)); + if (!video) { + video = { playbackRate: 1 }; + } + video.playbackRate = Number(option); // #1729 q2 // hi! @raszpl + if ( + (this.storage.player_force_speed_on_music !== true || + this.storage.player_dont_speed_education === true) && + option !== 1 + ) { + ImprovedTube.speedException = function () { + if ( + this.storage.player_dont_speed_education === true && + DATA.genre === "Education" + ) { + player.setPlaybackRate(Number(1)); + video.playbackRate = Number(1); + return; + } + if (this.storage.player_force_speed_on_music === true) { + //player.setPlaybackRate(Number(option)); video.playbackRate = Number(option); + return; + } + if (DATA.keywords && !keywords) { + keywords = DATA.keywords.join(", ") || ""; + } + if ( + keywords === + "video, sharing, camera phone, video phone, free, upload" + ) { + keywords = ""; + } + var musicIdentifiers = + /(official|music|lyrics?)[ -]video|(cover|studio|radio|album|alternate)[- ]version|soundtrack|unplugged|\bmedley\b|\blo-fi\b|\blofi\b|a(lla)? cappella|feat\.|(piano|guitar|jazz|ukulele|violin|reggae)[- ](version|cover)|karaok|backing[- ]track|instrumental|(sing|play)[- ]?along|卡拉OK|卡拉OK|الكاريوكي|караоке|カラオケ|노래방|bootleg|mashup|Radio edit|Guest (vocals|musician)|(title|opening|closing|bonus|hidden)[ -]track|live acoustic|interlude|featuring|recorded (at|live)/i; + var musicIdentifiersTitleOnly = + /lyrics|theme song|\bremix|\bAMV ?[^a-z0-9]|[^a-z0-9] ?AMV\b|\bfull song\b|\bsong:|\bsong[\!$]|^song\b|( - .*\bSong\b|\bSong\b.* - )|cover ?[^a-z0-9]|[^a-z0-9] ?cover|\bconcert\b/i; + var musicIdentifiersTitle = new RegExp( + musicIdentifiersTitleOnly.source + "|" + musicIdentifiers.source, + "i" + ); + var musicRegexMatch = musicIdentifiersTitle.test(DATA.title); + if (!musicRegexMatch) { + var musicIdentifiersTagsOnly = + /, (lyrics|remix|song|music|AMV|theme song|full song),|\(Musical Genre\)|, jazz|, reggae/i; + var musicIdentifiersTags = new RegExp( + musicIdentifiersTagsOnly.source + "|" + musicIdentifiers.source, + "i" + ); + keywordsAmount = 1 + ((keywords || "").match(/,/) || []).length; + if ( + ((keywords || "").match(musicIdentifiersTags) || []).length / + keywordsAmount > + 0.08 + ) { + musicRegexMatch = true; + } + } + notMusicRegexMatch = + /\bdo[ck]u|interv[iyj]|back[- ]?stage|インタビュー|entrevista|面试|面試|회견|wawancara|مقابلة|интервью|entretien|기록한 것|记录|記錄|ドキュメンタリ|وثائقي|документальный/i.test( + DATA.title + " " + keywords + ); + // (Tags/keywords shouldnt lie & very few songs titles might have these words) + if (DATA.duration) { + function parseDuration(duration) { + const [_, h = 0, m = 0, s = 0] = duration + .match(/PT(?:(\d+)?H)?(?:(\d+)?M)?(\d+)?S?/) + .map((part) => parseInt(part) || 0); + return h * 3600 + m * 60 + s; + } + DATA.lengthSeconds = parseDuration(DATA.duration); + } + function testSongDuration(s, ytMusic) { + if (135 <= s && s <= 260) { + return "veryCommon"; + } + if (105 <= s && s <= 420) { + return "common"; + } + if (420 <= s && s <= 720) { + return "long"; + } + if (45 <= s && s <= 105) { + return "short"; + } + if ( + ytMusic && + ytMusic > 1 && + 85 <= s / ytMusic && + (s / ytMusic <= 375 || ytMusic == 10) + ) { + return "multiple"; + } + //does Youtube ever show more than 10 songs below the description? + } + var songDurationType = testSongDuration(DATA.lengthSeconds); + console.log( + "genre: " + + DATA.genre + + "//title: " + + DATA.title + + "//keywords: " + + keywords + + "//music word match: " + + musicRegexMatch + + "// not music word match:" + + notMusicRegexMatch + + "//duration: " + + DATA.lengthSeconds + + "//song duration type: " + + songDurationType + ); + // check if the video is PROBABLY MUSIC: + if ( + (DATA.genre === "Music" && + (!notMusicRegexMatch || songDurationType === "veryCommon")) || + (musicRegexMatch && + !notMusicRegexMatch && + (typeof songDurationType !== "undefined" || + (/album|Álbum|专辑|專輯|एलबम|البوم|アルバム|альбом|앨범|mixtape|concert|playlist|\b(live|cd|vinyl|lp|ep|compilation|collection|symphony|suite|medley)\b/i.test( + DATA.title + " " + keywords + ) && + 1000 <= DATA.lengthSeconds))) || // && 1150 <= DATA.lengthSeconds <= 5000 + (DATA.genre === "Music" && + musicRegexMatch && + (typeof songDurationType !== "undefined" || + (/album|Álbum|专辑|專輯|एलबम|البوم|アルバム|альбом|앨범|mixtape|concert|playlist|\b(live|cd|vinyl|lp|ep|compilation|collection|symphony|suite|medley)\b/i.test( + DATA.title + " " + keywords + ) && + 1000 <= DATA.lengthSeconds))) || // && DATA.lengthSeconds <= 5000 + (amountOfSongs && + testSongDuration(DATA.lengthSeconds, amountOfSongs) !== + "undefined") + // || location.href.indexOf('music.') !== -1 // (=currently we are only running on www.youtube.com anyways) + ) { + player.setPlaybackRate(1); + video.playbackRate = 1; + console.log("...,thus must be music?"); + } else { + // Now this video might rarely be music + // - however we can make extra-sure after waiting for the video descripion to load... (#1539) + var tries = 0; + var intervalMs = 210; + if (location.href.indexOf("/watch?") !== -1) { + var maxTries = 10; + } else { + var maxTries = 0; + } + // ...except when it is an embedded player? + var waitForDescription = setInterval(() => { + if (++tries >= maxTries) { + subtitle = document.querySelector( + "#title + #subtitle:last-of-type" + ); + if ( + subtitle && + 1 <= Number((subtitle?.innerHTML?.match(/^\d+/) || [])[0]) && // indicates buyable/registered music (amount of songs) + typeof testSongDuration( + DATA.lengthSeconds, + Number((subtitle?.innerHTML?.match(/^\d+/) || [])[0]) + ) !== "undefined" + ) { + // resonable duration + player.setPlaybackRate(1); + video.playbackRate = 1; + console.log( + "...but YouTube shows music below the description!" + ); + clearInterval(waitForDescription); + } + intervalMs *= 1.11; + } + }, intervalMs); + window.addEventListener("load", () => { + setTimeout(() => { + clearInterval(waitForDescription); + }, 1234); + }); + } + }; + //DATA (TO-DO: make the Data available to more/all features? #1452 #1763 (Then can replace ImprovedTube.elements.category === 'music', VideoID is also used elsewhere) + DATA = {}; + defaultKeywords = "video,sharing,camera,phone,video phone,free,upload"; + keywords = false; + amountOfSongs = false; + + ImprovedTube.fetchDOMData = function () { + try { + DATA = + JSON.parse( + document.querySelector("#microformat script")?.textContent + ) ?? false; + DATA.title = DATA.name; + } catch { + DATA.genre = false; + DATA.keywords = false; + DATA.lengthSeconds = false; + try { + DATA.title = + document.getElementsByTagName("meta")?.title?.content || false; + DATA.genre = + document.querySelector("meta[itemprop=genre]")?.content || + false; + DATA.duration = + document.querySelector("meta[itemprop=duration]")?.content || + false; + } catch {} + } + + let tries = 0; + const maxTries = 11; + let intervalMs = 200; + const waitForVideoTitle = setInterval(() => { + const title = ImprovedTube.videoTitle?.(); + tries++; + + if (title && title !== "YouTube") { + clearInterval(waitForVideoTitle); + DATA.videoID = ImprovedTube.videoId() || false; // console.log("SPEED: TITLE:" + ImprovedTube.videoTitle() + DATA.title); + if ( + DATA.title === ImprovedTube.videoTitle() || + DATA.title.replace(/\s{2,}/g, " ") === ImprovedTube.videoTitle() + ) { + keywords = + document.querySelector('meta[name="keywords"]')?.content || + ""; + ImprovedTube.speedException(); + } else { + keywords = ""; + (async function () { + try { + const response = await fetch( + `https://www.youtube.com/watch?v=${DATA.videoID}` + ); + console.log( + "loading the html source:" + + `https://www.youtube.com/watch?v=${DATA.videoID}` + ); + const htmlContent = await response.text(); + const metaRegex = + /]+(name|itemprop)=["'](keywords|genre|duration)["'][^>]+content=["']([^"']+)["'][^>]*>/gi; + let match; + while ((match = metaRegex.exec(htmlContent)) !== null) { + // console.log(match); + const [, property, value] = match; + if (property === "keywords") { + keywords = value; + } else { + DATA[property] = value; + } + } + amountOfSongs = + (htmlContent + .slice(-80000) + .match(/},"subtitle":{"simpleText":"(\d*)\s/) || + [])[1] || false; + if (keywords) { + ImprovedTube.speedException(); + } + } catch (error) { + console.error( + "Error: fetching from https://Youtube.com/watch?v=${DATA.videoID}", + error + ); + keywords = ""; + } + })(); + } + } + + if (tries >= maxTries) { + clearInterval(waitForVideoTitle); + } + intervalMs *= 1.11; + }, intervalMs); + window.addEventListener("load", () => { + setTimeout(() => { + clearInterval(waitForVideoTitle); + }, 5000); + }); + }; + ImprovedTube.fetchDOMData(); + /* if ( (history && history.length === 1) || !history?.state?.endpoint?.watchEndpoint) { ImprovedTube.fetchDOMData(); } else { //Invidious instances. Should be updated automatically!... @@ -264,48 +503,70 @@ window.addEventListener('load', () => { setTimeout(() => { clearInterval(waitFo else { ImprovedTube.fetchDOMData();} } })(); } -*/ - } // else { } - } -} -} +*/ + } // else { } + } + } +}; /*------------------------------------------------------------------------------ SUBTITLES ------------------------------------------------------------------------------*/ ImprovedTube.playerSubtitles = function () { - const player = this.elements.player; - - if (player && player.isSubtitlesOn && player.toggleSubtitles && player.toggleSubtitlesOn) { - switch (this.storage.player_subtitles) { - case true: - case 'enabled': - player.toggleSubtitlesOn(); - break - - case 'disabled': - if (player.isSubtitlesOn()) { player.toggleSubtitles(); } - break - } - } + const player = this.elements.player; + + if ( + player && + player.isSubtitlesOn && + player.toggleSubtitles && + player.toggleSubtitlesOn + ) { + switch (this.storage.player_subtitles) { + case true: + case "enabled": + player.toggleSubtitlesOn(); + break; + + case "disabled": + if (player.isSubtitlesOn()) { + player.toggleSubtitles(); + } + break; + } + } }; /*------------------------------------------------------------------------------ SUBTITLES LANGUAGE ------------------------------------------------------------------------------*/ ImprovedTube.subtitlesLanguage = function () { - const option = this.storage.subtitles_language, - player = this.elements.player; - let subtitlesState; - - if (option && player && player.getOption && player.setOption && player.isSubtitlesOn && player.toggleSubtitles) { - const matchedTrack = player.getOption('captions', 'tracklist', {includeAsr: true})?.find(track => track.languageCode.includes(option) && (!track.vss_id.includes("a.") || this.storage.auto_generate)); - - if (matchedTrack) { - subtitlesState = player.isSubtitlesOn(); - player.setOption('captions', 'track', matchedTrack); - // setOption forces Subtitles ON, restore state from before calling it. - if (!subtitlesState) { player.toggleSubtitles(); } - } - } + const option = this.storage.subtitles_language, + player = this.elements.player; + let subtitlesState; + + if ( + option && + player && + player.getOption && + player.setOption && + player.isSubtitlesOn && + player.toggleSubtitles + ) { + const matchedTrack = player + .getOption("captions", "tracklist", { includeAsr: true }) + ?.find( + (track) => + track.languageCode.includes(option) && + (!track.vss_id.includes("a.") || this.storage.auto_generate) + ); + + if (matchedTrack) { + subtitlesState = player.isSubtitlesOn(); + player.setOption("captions", "track", matchedTrack); + // setOption forces Subtitles ON, restore state from before calling it. + if (!subtitlesState) { + player.toggleSubtitles(); + } + } + } }; /*------------------------------------------------------------------------------ SUBTITLES FONT FAMILY @@ -330,800 +591,1043 @@ default = { }, ------------------------------------------------------------------------------*/ ImprovedTube.subtitlesUserSettings = function () { - const ourSettings = { - fontFamily: this.storage.subtitles_font_family, - color: this.storage.subtitles_font_color, - fontSizeIncrement: this.storage.subtitles_font_size, - background: this.storage.subtitles_background_color, - backgroundOpacity: this.storage.subtitles_background_opacity, - windowColor: this.storage.subtitles_window_color, - windowOpacity: this.storage.subtitles_window_opacity, - charEdgeStyle: this.storage.subtitles_character_edge_style, - textOpacity: this.storage.subtitles_font_opacity - }, - userSettings = Object.keys(ourSettings).filter(e => ourSettings[e]), - player = this.elements.player; - - if (userSettings.length && player && player.getSubtitlesUserSettings && player.updateSubtitlesUserSettings) { - let ytSettings = player.getSubtitlesUserSettings(), - setting; - - if (!ytSettings) return; //null SubtitlesUserSettings seem to mean subtitles not available - - for (const value of userSettings) { - setting = null; - switch (value) { - case 'fontFamily': - case 'fontSizeIncrement': - case 'charEdgeStyle': - setting = Number(ourSettings[value]); - break; - - case 'color': - case 'background': - case 'windowColor': - setting = ourSettings[value]; - break; - - case 'backgroundOpacity': - case 'windowOpacity': - case 'textOpacity': - setting = Number(ourSettings[value]) / 100; - break; - } - - if (Object.keys(ytSettings).includes(value)) { - ytSettings[value] = setting; - } else { - console.error('subtitlesUserSettings failed at: ', value, setting); - } - } - player.updateSubtitlesUserSettings(ytSettings); - } + const ourSettings = { + fontFamily: this.storage.subtitles_font_family, + color: this.storage.subtitles_font_color, + fontSizeIncrement: this.storage.subtitles_font_size, + background: this.storage.subtitles_background_color, + backgroundOpacity: this.storage.subtitles_background_opacity, + windowColor: this.storage.subtitles_window_color, + windowOpacity: this.storage.subtitles_window_opacity, + charEdgeStyle: this.storage.subtitles_character_edge_style, + textOpacity: this.storage.subtitles_font_opacity, + }, + userSettings = Object.keys(ourSettings).filter((e) => ourSettings[e]), + player = this.elements.player; + + if ( + userSettings.length && + player && + player.getSubtitlesUserSettings && + player.updateSubtitlesUserSettings + ) { + let ytSettings = player.getSubtitlesUserSettings(), + setting; + + if (!ytSettings) return; //null SubtitlesUserSettings seem to mean subtitles not available + + for (const value of userSettings) { + setting = null; + switch (value) { + case "fontFamily": + case "fontSizeIncrement": + case "charEdgeStyle": + setting = Number(ourSettings[value]); + break; + + case "color": + case "background": + case "windowColor": + setting = ourSettings[value]; + break; + + case "backgroundOpacity": + case "windowOpacity": + case "textOpacity": + setting = Number(ourSettings[value]) / 100; + break; + } + + if (Object.keys(ytSettings).includes(value)) { + ytSettings[value] = setting; + } else { + console.error("subtitlesUserSettings failed at: ", value, setting); + } + } + player.updateSubtitlesUserSettings(ytSettings); + } }; /*------------------------------------------------------------------------------ SUBTITLES DISABLE SUBTILES FOR LYRICS ------------------------------------------------------------------------------*/ ImprovedTube.subtitlesDisableLyrics = function () { - if (this.storage.subtitles_disable_lyrics) { - const player = this.elements.player; - - if (player && player.isSubtitlesOn && player.isSubtitlesOn() && player.toggleSubtitles) { - // Music detection only uses 3 identifiers for Lyrics: lyrics, sing-along, karaoke. - // Easier to simply use those here. Can replace with music detection later. - const terms = ["sing along", "sing-along", "karaoke", "lyric", "卡拉OK", "卡拉OK", "الكاريوكي", "караоке", "カラオケ", "노래방"]; - if (terms.some(term => this.videoTitle().toLowerCase().includes(term))) { - player.toggleSubtitles(); - } - } - } + if (this.storage.subtitles_disable_lyrics) { + const player = this.elements.player; + + if ( + player && + player.isSubtitlesOn && + player.isSubtitlesOn() && + player.toggleSubtitles + ) { + // Music detection only uses 3 identifiers for Lyrics: lyrics, sing-along, karaoke. + // Easier to simply use those here. Can replace with music detection later. + const terms = [ + "sing along", + "sing-along", + "karaoke", + "lyric", + "卡拉OK", + "卡拉OK", + "الكاريوكي", + "караоке", + "カラオケ", + "노래방", + ]; + if ( + terms.some((term) => this.videoTitle().toLowerCase().includes(term)) + ) { + player.toggleSubtitles(); + } + } + } }; /*------------------------------------------------------------------------------ UP NEXT AUTOPLAY ------------------------------------------------------------------------------*/ ImprovedTube.upNextAutoplay = function () { - var option = this.storage.up_next_autoplay; + var option = this.storage.up_next_autoplay; - if (this.isset(option)) { - var toggle = document.querySelector('.ytp-autonav-toggle-button'); + if (this.isset(option)) { + var toggle = document.querySelector(".ytp-autonav-toggle-button"); - if (toggle) { - if (option !== (toggle.getAttribute('aria-checked') === 'true')) { - toggle.click(); - } - } - } + if (toggle) { + if (option !== (toggle.getAttribute("aria-checked") === "true")) { + toggle.click(); + } + } + } }; /*------------------------------------------------------------------------------ ADS ------------------------------------------------------------------------------*/ -ImprovedTube.playerAds = function (parent) { - let button = parent.querySelector('.ytp-ad-skip-button-modern.ytp-button,[class*="ytp-ad-skip-button"].ytp-button') || parent; - // TODO: Replace this with centralized video element pointer - let video = document.querySelector('.video-stream.html5-main-video') || false; - function skipAd () { - if (video) video.currentTime = video.duration; - if (button) button.click(); - } - if (this.storage.ads === 'block_all') { - skipAd(); - } else if (this.storage.ads === 'subscribed_channels') { - if (!parent.querySelector('#meta paper-button[subscribed]')) { - skipAd(); - } - } else if (this.storage.ads === 'block_music') { - if (ImprovedTube.elements.category === 'music') { - skipAd(); - } - } else if (this.storage.ads === 'small_creators') { - let userDefiniedLimit = this.storage.smallCreatorsCount * parseInt(this.storage.smallCreatorsUnit); - let subscribersNumber = ImprovedTube.subscriberCount; - if (subscribersNumber > userDefiniedLimit) { - skipAd(); - } - } +ImprovedTube.muteAds = function () { + if ( + !ImprovedTube.storage.ads || + ImprovedTube.storage.ads !== "mute_ads" || + ImprovedTube._mutedAdsObserverInitialized + ) + return; + + let player = document.querySelector(".html5-video-player"); + let video = document.querySelector(".video-stream.html5-main-video"); + + if (!player || !video) return; + + let observer = new MutationObserver(() => { + let isAd = player.classList.contains("ad-showing") && video.duration < 40; + + if (isAd) { + if (ImprovedTube.wasMutedBeforeAd === undefined) { + ImprovedTube.wasMutedBeforeAd = video.muted; + video.muted = true; + } + } else { + if (ImprovedTube.wasMutedBeforeAd !== undefined) { + video.muted = ImprovedTube.wasMutedBeforeAd; + ImprovedTube.wasMutedBeforeAd = undefined; + } + } + }); + + observer.observe(player, { attributes: true, attributeFilter: ["class"] }); + + ImprovedTube._mutedAdsObserverInitialized = true; +}; + +ImprovedTube.playerAds = function (parent) { + let button = + parent.querySelector( + '.ytp-ad-skip-button-modern.ytp-button,[class*="ytp-ad-skip-button"].ytp-button' + ) || parent; + + // TODO: Replace this with centralized video element pointer + let video = document.querySelector(".video-stream.html5-main-video") || false; + function skipAd() { + if (video) video.currentTime = video.duration; + if (button) button.click(); + } + + if (this.storage.ads === "block_all") { + skipAd(); + } else if (this.storage.ads === "subscribed_channels") { + if (!parent.querySelector("#meta paper-button[subscribed]")) { + skipAd(); + } + } else if (this.storage.ads === "block_music") { + if (ImprovedTube.elements.category === "music") { + skipAd(); + } + } else if (this.storage.ads === "small_creators") { + let userDefiniedLimit = + this.storage.smallCreatorsCount * + parseInt(this.storage.smallCreatorsUnit); + let subscribersNumber = ImprovedTube.subscriberCount; + if (subscribersNumber > userDefiniedLimit) { + skipAd(); + } + } else { + if (this.storage.ads === "mute_ads") { + ImprovedTube.muteAds(); + } + } }; + /*------------------------------------------------------------------------------ AUTO FULLSCREEN ------------------------------------------------------------------------------*/ ImprovedTube.playerAutofullscreen = function () { - if ( - this.storage.player_autofullscreen === true && - document.documentElement.dataset.pageType === 'video' && - !document.fullscreenElement - ) { - this.elements.player.toggleFullscreen(); - } + if ( + this.storage.player_autofullscreen === true && + document.documentElement.dataset.pageType === "video" && + !document.fullscreenElement + ) { + this.elements.player.toggleFullscreen(); + } }; /*------------------------------------------------------------------------------ QUALITY ------------------------------------------------------------------------------*/ ImprovedTube.playerQuality = function (quality = this.storage.player_quality) { - let player = this.elements.player; - if (quality && quality !== 'disabled' - && player && player.getAvailableQualityLevels - && (!player.dataset.defaultQuality || player.dataset.defaultQuality != quality)) { - let available_quality_levels = player.getAvailableQualityLevels(); - function closest (num, arr) { - let curr = arr[0]; - let diff = Math.abs(num - curr); - for (let val = 1; val < arr.length; val++) { - let newdiff = Math.abs(num - arr[val]); - if (newdiff < diff) { - diff = newdiff; - curr = arr[val]; - } - } - return curr; - }; - - if (!available_quality_levels.includes(quality)) { - let label = ['tiny', 'small', 'medium', 'large', 'hd720', 'hd1080', 'hd1440', 'hd2160', 'hd2880', 'highres']; - let resolution = ['144', '240', '360', '480', '720', '1080', '1440', '2160', '2880', '4320']; - let availableresolutions = available_quality_levels.map(q => resolution[label.indexOf(q)]); - quality = label[resolution.indexOf(closest(resolution[label.indexOf(quality)], availableresolutions))]; - } - player.setPlaybackQualityRange(quality); - player.setPlaybackQuality(quality); - player.dataset.defaultQuality = quality; - } + let player = this.elements.player; + if ( + quality && + quality !== "disabled" && + player && + player.getAvailableQualityLevels && + (!player.dataset.defaultQuality || player.dataset.defaultQuality != quality) + ) { + let available_quality_levels = player.getAvailableQualityLevels(); + function closest(num, arr) { + let curr = arr[0]; + let diff = Math.abs(num - curr); + for (let val = 1; val < arr.length; val++) { + let newdiff = Math.abs(num - arr[val]); + if (newdiff < diff) { + diff = newdiff; + curr = arr[val]; + } + } + return curr; + } + + if (!available_quality_levels.includes(quality)) { + let label = [ + "tiny", + "small", + "medium", + "large", + "hd720", + "hd1080", + "hd1440", + "hd2160", + "hd2880", + "highres", + ]; + let resolution = [ + "144", + "240", + "360", + "480", + "720", + "1080", + "1440", + "2160", + "2880", + "4320", + ]; + let availableresolutions = available_quality_levels.map( + (q) => resolution[label.indexOf(q)] + ); + quality = + label[ + resolution.indexOf( + closest(resolution[label.indexOf(quality)], availableresolutions) + ) + ]; + } + player.setPlaybackQualityRange(quality); + player.setPlaybackQuality(quality); + player.dataset.defaultQuality = quality; + } }; /*------------------------------------------------------------------------------ QUALITY WITHOUT FOCUS ------------------------------------------------------------------------------*/ ImprovedTube.playerQualityWithoutFocus = function () { - let player = this.elements.player, - qualityWithoutFocus = this.storage.player_quality_without_focus; - if (qualityWithoutFocus && qualityWithoutFocus !== 'auto' && player && player.getPlaybackQuality) { - if (this.focus) { - if (ImprovedTube.qualityBeforeBlur) { - ImprovedTube.playerQuality(ImprovedTube.qualityBeforeBlur); - ImprovedTube.qualityBeforeBlur = undefined; - } - } else { - if (!ImprovedTube.elements.video.paused) { - if (!ImprovedTube.qualityBeforeBlur) { - ImprovedTube.qualityBeforeBlur = player.getPlaybackQuality(); - } - ImprovedTube.playerQuality(qualityWithoutFocus); - } - } - } + let player = this.elements.player, + qualityWithoutFocus = this.storage.player_quality_without_focus; + if ( + qualityWithoutFocus && + qualityWithoutFocus !== "auto" && + player && + player.getPlaybackQuality + ) { + if (this.focus) { + if (ImprovedTube.qualityBeforeBlur) { + ImprovedTube.playerQuality(ImprovedTube.qualityBeforeBlur); + ImprovedTube.qualityBeforeBlur = undefined; + } + } else { + if (!ImprovedTube.elements.video.paused) { + if (!ImprovedTube.qualityBeforeBlur) { + ImprovedTube.qualityBeforeBlur = player.getPlaybackQuality(); + } + ImprovedTube.playerQuality(qualityWithoutFocus); + } + } + } }; /*------------------------------------------------------------------------------ BATTERY FEATURES; PLAYER QUALITY BASED ON POWER STATUS ------------------------------------------------------------------------------*/ ImprovedTube.batteryFeatures = async function () { - if (ImprovedTube.storage.qualityWhenRunningOnBattery - || ImprovedTube.storage.pauseWhileIUnplugTheCharger - || ImprovedTube.storage.whenBatteryIslowDecreaseQuality) { - const updateQuality = async (battery, charging) => { - if (battery) { - if (!battery.charging) { - if (ImprovedTube.storage.pauseWhileIUnplugTheCharger && charging) { - ImprovedTube.elements.player.pauseVideo(); - ImprovedTube.paused = true; - } - if (ImprovedTube.storage.qualityWhenRunningOnBattery) { - ImprovedTube.playerQuality(ImprovedTube.storage.qualityWhenRunningOnBattery); - } - if (ImprovedTube.storage.whenBatteryIslowDecreaseQuality) { - let quality; - if (battery.level > 0.11 || battery.dischargingTime > 900) { - quality = "large"; - } else if (battery.level > 0.08 || battery.dischargingTime > 600) { - quality = "medium"; - } else if (battery.level > 0.04 || battery.dischargingTime > 360) { - quality = "small"; - } else { - quality = "tiny"; - } - ImprovedTube.playerQuality(quality); - } - } else if (charging && ImprovedTube.paused && ImprovedTube.storage.pauseWhileIUnplugTheCharger) { - ImprovedTube.elements.player.playVideo(); - delete ImprovedTube.paused; - } - } - }; - const battery = await navigator.getBattery(); - battery.addEventListener("levelchange", () => updateQuality(battery)); - battery.addEventListener("chargingchange", () => updateQuality(battery, true)); - await updateQuality(battery); - } + if ( + ImprovedTube.storage.qualityWhenRunningOnBattery || + ImprovedTube.storage.pauseWhileIUnplugTheCharger || + ImprovedTube.storage.whenBatteryIslowDecreaseQuality + ) { + const updateQuality = async (battery, charging) => { + if (battery) { + if (!battery.charging) { + if (ImprovedTube.storage.pauseWhileIUnplugTheCharger && charging) { + ImprovedTube.elements.player.pauseVideo(); + ImprovedTube.paused = true; + } + if (ImprovedTube.storage.qualityWhenRunningOnBattery) { + ImprovedTube.playerQuality( + ImprovedTube.storage.qualityWhenRunningOnBattery + ); + } + if (ImprovedTube.storage.whenBatteryIslowDecreaseQuality) { + let quality; + if (battery.level > 0.11 || battery.dischargingTime > 900) { + quality = "large"; + } else if (battery.level > 0.08 || battery.dischargingTime > 600) { + quality = "medium"; + } else if (battery.level > 0.04 || battery.dischargingTime > 360) { + quality = "small"; + } else { + quality = "tiny"; + } + ImprovedTube.playerQuality(quality); + } + } else if ( + charging && + ImprovedTube.paused && + ImprovedTube.storage.pauseWhileIUnplugTheCharger + ) { + ImprovedTube.elements.player.playVideo(); + delete ImprovedTube.paused; + } + } + }; + const battery = await navigator.getBattery(); + battery.addEventListener("levelchange", () => updateQuality(battery)); + battery.addEventListener("chargingchange", () => + updateQuality(battery, true) + ); + await updateQuality(battery); + } }; /*------------------------------------------------------------------------------ FORCED VOLUME ------------------------------------------------------------------------------*/ ImprovedTube.playerVolume = function () { - if (this.storage.player_forced_volume === true) { - var volume = this.storage.player_volume; - - if (!this.isset(volume)) { - volume = 100; - } else { - volume = Number(volume); - } - - if (!this.audioContextGain && volume <= 100) { - if (this.audioContext) { - this.audioContext.close(); - } - - this.elements.player.setVolume(volume); - } else { - if (!this.audioContext) { - this.audioContext = new AudioContext(); - - this.audioContextSource = this.audioContext.createMediaElementSource(document.querySelector('video')); - this.audioContextGain = this.audioContext.createGain(); - - this.audioContextGain.gain.value = 1; - this.audioContextSource.connect(this.audioContextGain); - this.audioContextGain.connect(this.audioContext.destination) - } - if (this.elements.player.getVolume() !== 100) { this.elements.player.setVolume(100);} - this.audioContextGain.gain.value = volume / 100; - } - } + if (this.storage.player_forced_volume === true) { + var volume = this.storage.player_volume; + + if (!this.isset(volume)) { + volume = 100; + } else { + volume = Number(volume); + } + + if (!this.audioContextGain && volume <= 100) { + if (this.audioContext) { + this.audioContext.close(); + } + + this.elements.player.setVolume(volume); + } else { + if (!this.audioContext) { + this.audioContext = new AudioContext(); + + this.audioContextSource = this.audioContext.createMediaElementSource( + document.querySelector("video") + ); + this.audioContextGain = this.audioContext.createGain(); + + this.audioContextGain.gain.value = 1; + this.audioContextSource.connect(this.audioContextGain); + this.audioContextGain.connect(this.audioContext.destination); + } + if (this.elements.player.getVolume() !== 100) { + this.elements.player.setVolume(100); + } + this.audioContextGain.gain.value = volume / 100; + } + } }; /*------------------------------------------------------------------------------ LOUDNESS NORMALIZATION ------------------------------------------------------------------------------*/ ImprovedTube.onvolumechange = function () { - if (document.querySelector('.ytp-volume-panel') && ImprovedTube.storage.player_loudness_normalization === false) { - var volume = Number(document.querySelector('.ytp-volume-panel').getAttribute('aria-valuenow')); - - this.volume = volume / 100; - } + if ( + document.querySelector(".ytp-volume-panel") && + ImprovedTube.storage.player_loudness_normalization === false + ) { + var volume = Number( + document.querySelector(".ytp-volume-panel").getAttribute("aria-valuenow") + ); + + this.volume = volume / 100; + } }; ImprovedTube.playerLoudnessNormalization = function () { - var video = this.elements.video; - - if (video) { - video.removeEventListener('volumechange', this.onvolumechange); - video.addEventListener('volumechange', this.onvolumechange); - } - - if (this.storage.player_loudness_normalization === false) { - try { - var local_storage = localStorage['yt-player-volume']; - - if (this.isset(Number(this.storage.player_volume)) && this.storage.player_forced_volume === true) { - return; - } else if (local_storage) { - local_storage = JSON.parse(JSON.parse(local_storage).data); - - local_storage = Number(local_storage.volume); - - video.volume = local_storage / 100; - } else { - video.volume = 100; - } - } catch (err) {} - } + var video = this.elements.video; + + if (video) { + video.removeEventListener("volumechange", this.onvolumechange); + video.addEventListener("volumechange", this.onvolumechange); + } + + if (this.storage.player_loudness_normalization === false) { + try { + var local_storage = localStorage["yt-player-volume"]; + + if ( + this.isset(Number(this.storage.player_volume)) && + this.storage.player_forced_volume === true + ) { + return; + } else if (local_storage) { + local_storage = JSON.parse(JSON.parse(local_storage).data); + + local_storage = Number(local_storage.volume); + + video.volume = local_storage / 100; + } else { + video.volume = 100; + } + } catch (err) {} + } }; /*------------------------------------------------------------------------------ SCREENSHOT ------------------------------------------------------------------------------*/ ImprovedTube.screenshot = function () { - const video = ImprovedTube.elements.video, - cvs = document.createElement('canvas'), - ctx = cvs.getContext('2d'); - let subText = ''; - - cvs.width = video.videoWidth; - cvs.height = video.videoHeight; - - ctx.drawImage(video, 0, 0, cvs.width, cvs.height); - - if (ImprovedTube.storage.embed_subtitle != false) { - let captionElements = document.querySelectorAll('.captions-text .ytp-caption-segment'); - captionElements.forEach(function (caption) {subText += caption.textContent.trim() + ' ';}); - - ImprovedTube.renderSubtitle(ctx, captionElements); - } - - cvs.toBlob(function (blob) { - if (ImprovedTube.storage.player_screenshot_save_as == 'clipboard') { - window.focus(); - navigator.clipboard.write([ - new ClipboardItem({ - 'image/png': blob - }) - ]) - .then(function () { console.log("ImprovedTube: Screeeeeeenshot tada!"); }) - .catch(function (error) { - console.log('ImprovedTube screenshot: ', error); - alert('ImprovedTube Screenshot to Clipboard error. Details in Debug Console.'); - }); - } else { - let a = document.createElement('a'); - a.href = URL.createObjectURL(blob); - a.download = (ImprovedTube.videoId() || location.href.match) + ' ' + new Date(ImprovedTube.elements.player.getCurrentTime() * 1000).toISOString().substr(11, 8).replace(/:/g, '-') + ' ' + ImprovedTube.videoTitle() + (subText ? ' - ' + subText.trim() : '') + '.png'; - a.click(); - console.log("ImprovedTube: Screeeeeeenshot tada!"); - } - }); + const video = ImprovedTube.elements.video, + cvs = document.createElement("canvas"), + ctx = cvs.getContext("2d"); + let subText = ""; + + cvs.width = video.videoWidth; + cvs.height = video.videoHeight; + + ctx.drawImage(video, 0, 0, cvs.width, cvs.height); + + if (ImprovedTube.storage.embed_subtitle != false) { + let captionElements = document.querySelectorAll( + ".captions-text .ytp-caption-segment" + ); + captionElements.forEach(function (caption) { + subText += caption.textContent.trim() + " "; + }); + + ImprovedTube.renderSubtitle(ctx, captionElements); + } + + cvs.toBlob(function (blob) { + if (ImprovedTube.storage.player_screenshot_save_as == "clipboard") { + window.focus(); + navigator.clipboard + .write([ + new ClipboardItem({ + "image/png": blob, + }), + ]) + .then(function () { + console.log("ImprovedTube: Screeeeeeenshot tada!"); + }) + .catch(function (error) { + console.log("ImprovedTube screenshot: ", error); + alert( + "ImprovedTube Screenshot to Clipboard error. Details in Debug Console." + ); + }); + } else { + let a = document.createElement("a"); + a.href = URL.createObjectURL(blob); + a.download = + (ImprovedTube.videoId() || location.href.match) + + " " + + new Date(ImprovedTube.elements.player.getCurrentTime() * 1000) + .toISOString() + .substr(11, 8) + .replace(/:/g, "-") + + " " + + ImprovedTube.videoTitle() + + (subText ? " - " + subText.trim() : "") + + ".png"; + a.click(); + console.log("ImprovedTube: Screeeeeeenshot tada!"); + } + }); }; ImprovedTube.renderSubtitle = function (ctx, captionElements) { - if (ctx && captionElements) { - captionElements.forEach(function (captionElement, index) { - var captionText = captionElement.textContent.trim(); - var captionStyles = window.getComputedStyle(captionElement); - - ctx.fillStyle = captionStyles.color; - ctx.font = captionStyles.font; - ctx.textAlign = 'center'; - ctx.textBaseline = 'bottom'; - var txtWidth = ctx.measureText(captionText).width; - var txtHeight = parseFloat(captionStyles.fontSize); - - var xOfset = (ctx.canvas.width - txtWidth) / 2; - - var padding = 5; // Adjust the padding as needed - var yofset = ctx.canvas.height - (captionElements.length - index) * (txtHeight + 2 * padding); - - ctx.fillStyle = captionStyles.backgroundColor; - ctx.fillRect(xOfset - padding, yofset - txtHeight - padding, txtWidth + 2 * padding, txtHeight + 2 * padding); - ctx.fillStyle = captionStyles.color; - ctx.fillText(captionText, xOfset + txtWidth / 2, yofset); - }); - } + if (ctx && captionElements) { + captionElements.forEach(function (captionElement, index) { + var captionText = captionElement.textContent.trim(); + var captionStyles = window.getComputedStyle(captionElement); + + ctx.fillStyle = captionStyles.color; + ctx.font = captionStyles.font; + ctx.textAlign = "center"; + ctx.textBaseline = "bottom"; + var txtWidth = ctx.measureText(captionText).width; + var txtHeight = parseFloat(captionStyles.fontSize); + + var xOfset = (ctx.canvas.width - txtWidth) / 2; + + var padding = 5; // Adjust the padding as needed + var yofset = + ctx.canvas.height - + (captionElements.length - index) * (txtHeight + 2 * padding); + + ctx.fillStyle = captionStyles.backgroundColor; + ctx.fillRect( + xOfset - padding, + yofset - txtHeight - padding, + txtWidth + 2 * padding, + txtHeight + 2 * padding + ); + ctx.fillStyle = captionStyles.color; + ctx.fillText(captionText, xOfset + txtWidth / 2, yofset); + }); + } }; ImprovedTube.playerScreenshotButton = function () { - if (this.storage.player_screenshot_button === true) { - var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), - path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - - svg.setAttributeNS(null, 'viewBox', '0 0 24 24'); - path.setAttributeNS(null, 'd', 'M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z'); - - svg.appendChild(path); - - this.createPlayerButton({ - id: 'it-screenshot-button', - child: svg, - opacity: 0.64, - onclick: this.screenshot, - title: 'Screenshot' - }); - } + if (this.storage.player_screenshot_button === true) { + var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), + path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + + svg.setAttributeNS(null, "viewBox", "0 0 24 24"); + path.setAttributeNS( + null, + "d", + "M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" + ); + + svg.appendChild(path); + + this.createPlayerButton({ + id: "it-screenshot-button", + child: svg, + opacity: 0.64, + onclick: this.screenshot, + title: "Screenshot", + }); + } }; /*------------------------------------------------------------------------------ REPEAT -------------------------------------------------------------------------------*/ ImprovedTube.playerRepeat = function () { - setTimeout(function () { - if (!/ad-showing/.test(ImprovedTube.elements.player.className)) { - ImprovedTube.elements.video.setAttribute('loop', ''); - } - //ImprovedTube.elements.buttons['it-repeat-styles'].style.opacity = '1'; //old class from version 3.x? that both repeat buttons could have - }, 200); -} + setTimeout(function () { + if (!/ad-showing/.test(ImprovedTube.elements.player.className)) { + ImprovedTube.elements.video.setAttribute("loop", ""); + } + //ImprovedTube.elements.buttons['it-repeat-styles'].style.opacity = '1'; //old class from version 3.x? that both repeat buttons could have + }, 200); +}; /*------------------------------------------------------------------------------ REPEAT BUTTON ------------------------------------------------------------------------------*/ ImprovedTube.playerRepeatButton = function () { - if (this.storage.player_repeat_button === true) { - var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), - path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - svg.setAttributeNS(null, 'viewBox', '0 0 24 24'); - path.setAttributeNS(null, 'd', 'M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4zm-4-2V9h-1l-2 1v1h1.5v4H13z'); - svg.appendChild(path); - var transparentOrOn = 0.5; if (this.storage.player_always_repeat === true ) { transparentOrOn = 1; } - this.createPlayerButton({ - id: 'it-repeat-button', - child: svg, - opacity: transparentOrOn, - onclick: function () { - var video = ImprovedTube.elements.video; - function matchLoopState (opacity) { - var thisButton = document.querySelector('#it-repeat-button'); - thisButton.style.opacity = opacity; - if (ImprovedTube.storage.below_player_loop !== false) { - var otherButton = document.querySelector('#it-below-player-loop'); - otherButton.children[0].style.opacity = opacity; - } - } if (video.hasAttribute('loop')) { - video.removeAttribute('loop'); - matchLoopState('.5') - } else if (!/ad-showing/.test(ImprovedTube.elements.player.className)) { - video.setAttribute('loop', ''); - matchLoopState('1') - } - }, - title: 'Repeat', - }); - } + if (this.storage.player_repeat_button === true) { + var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), + path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + svg.setAttributeNS(null, "viewBox", "0 0 24 24"); + path.setAttributeNS( + null, + "d", + "M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4zm-4-2V9h-1l-2 1v1h1.5v4H13z" + ); + svg.appendChild(path); + var transparentOrOn = 0.5; + if (this.storage.player_always_repeat === true) { + transparentOrOn = 1; + } + this.createPlayerButton({ + id: "it-repeat-button", + child: svg, + opacity: transparentOrOn, + onclick: function () { + var video = ImprovedTube.elements.video; + function matchLoopState(opacity) { + var thisButton = document.querySelector("#it-repeat-button"); + thisButton.style.opacity = opacity; + if (ImprovedTube.storage.below_player_loop !== false) { + var otherButton = document.querySelector("#it-below-player-loop"); + otherButton.children[0].style.opacity = opacity; + } + } + if (video.hasAttribute("loop")) { + video.removeAttribute("loop"); + matchLoopState(".5"); + } else if (!/ad-showing/.test(ImprovedTube.elements.player.className)) { + video.setAttribute("loop", ""); + matchLoopState("1"); + } + }, + title: "Repeat", + }); + } }; /*------------------------------------------------------------------------------ ROTATE ------------------------------------------------------------------------------*/ ImprovedTube.playerRotateButton = function () { - if (this.storage.player_rotate_button === true) { - var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), - path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - - svg.setAttributeNS(null, 'viewBox', '0 0 24 24'); - path.setAttributeNS(null, 'd', 'M15.55 5.55L11 1v3.07a8 8 0 0 0 0 15.86v-2.02a6 6 0 0 1 0-11.82V10l4.55-4.45zM19.93 11a7.9 7.9 0 0 0-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02a7.92 7.92 0 0 0 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41A7.9 7.9 0 0 0 19.93 13h-2.02a5.9 5.9 0 0 1-1.02 2.48z'); - - svg.appendChild(path); - - this.createPlayerButton({ - id: 'it-rotate-button', - child: svg, - opacity: 0.85, - onclick: function (e) { - var player = ImprovedTube.elements.player, - video = ImprovedTube.elements.video, - rotate = Number(document.body.dataset.itRotate) || 0, - transform = ''; - if(!e.ctrlKey){ - rotate += 90; - } else { - rotate -= 90; - } - - if (rotate === 360) { - rotate = 0; - } else if (rotate < 0){ - rotate = 270; - } - - document.body.dataset.itRotate = rotate; - - transform += 'rotate(' + rotate + 'deg)'; - - if (rotate == 90 || rotate == 270) { - var is_vertical_video = video.videoHeight > video.videoWidth; - - transform += ' scale(' + (is_vertical_video ? player.clientWidth : player.clientHeight) / (is_vertical_video ? player.clientHeight : player.clientWidth) + ')'; - } - - if (!ImprovedTube.elements.buttons['it-rotate-styles']) { - var style = document.createElement('style'); - - ImprovedTube.elements.buttons['it-rotate-styles'] = style; - - document.body.appendChild(style); - } - - ImprovedTube.elements.buttons['it-rotate-styles'].textContent = 'video{transform:' + transform + '}'; - }, - title: 'Rotate' - }); - } + if (this.storage.player_rotate_button === true) { + var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), + path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + + svg.setAttributeNS(null, "viewBox", "0 0 24 24"); + path.setAttributeNS( + null, + "d", + "M15.55 5.55L11 1v3.07a8 8 0 0 0 0 15.86v-2.02a6 6 0 0 1 0-11.82V10l4.55-4.45zM19.93 11a7.9 7.9 0 0 0-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02a7.92 7.92 0 0 0 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41A7.9 7.9 0 0 0 19.93 13h-2.02a5.9 5.9 0 0 1-1.02 2.48z" + ); + + svg.appendChild(path); + + this.createPlayerButton({ + id: "it-rotate-button", + child: svg, + opacity: 0.85, + onclick: function (e) { + var player = ImprovedTube.elements.player, + video = ImprovedTube.elements.video, + rotate = Number(document.body.dataset.itRotate) || 0, + transform = ""; + if (!e.ctrlKey) { + rotate += 90; + } else { + rotate -= 90; + } + + if (rotate === 360) { + rotate = 0; + } else if (rotate < 0) { + rotate = 270; + } + + document.body.dataset.itRotate = rotate; + + transform += "rotate(" + rotate + "deg)"; + + if (rotate == 90 || rotate == 270) { + var is_vertical_video = video.videoHeight > video.videoWidth; + + transform += + " scale(" + + (is_vertical_video ? player.clientWidth : player.clientHeight) / + (is_vertical_video ? player.clientHeight : player.clientWidth) + + ")"; + } + + if (!ImprovedTube.elements.buttons["it-rotate-styles"]) { + var style = document.createElement("style"); + + ImprovedTube.elements.buttons["it-rotate-styles"] = style; + + document.body.appendChild(style); + } + + ImprovedTube.elements.buttons["it-rotate-styles"].textContent = + "video{transform:" + transform + "}"; + }, + title: "Rotate", + }); + } }; /*------------------------------------------------------------------------------ FIT-TO-WIN BUTTON ------------------------------------------------------------------------------*/ ImprovedTube.playerFitToWinButton = function () { - if (this.storage.player_fit_to_win_button === true && (/watch\?/.test(location.href))) { - let tempContainer = document.createElement("div"); - let svg; - if (typeof trustedTypes !== 'undefined' && typeof trustedTypes.createPolicy === 'function') { - // Create a Trusted Type policy - const policy = trustedTypes.createPolicy('default', { - createHTML: (string) => string, - }); - - // Use the policy to set innerHTML - tempContainer.innerHTML = policy.createHTML(` + if ( + this.storage.player_fit_to_win_button === true && + /watch\?/.test(location.href) + ) { + let tempContainer = document.createElement("div"); + let svg; + if ( + typeof trustedTypes !== "undefined" && + typeof trustedTypes.createPolicy === "function" + ) { + // Create a Trusted Type policy + const policy = trustedTypes.createPolicy("default", { + createHTML: (string) => string, + }); + + // Use the policy to set innerHTML + tempContainer.innerHTML = policy.createHTML(` `); - // Ensure the SVG element is correctly parsed - svg = tempContainer.querySelector('svg'); - } else {tempContainer.innerHTML = ` + // Ensure the SVG element is correctly parsed + svg = tempContainer.querySelector("svg"); + } else { + tempContainer.innerHTML = ` `; - svg = tempContainer.firstChild;} - this.createPlayerButton({ - id: 'it-fit-to-win-player-button', - child: svg, - opacity: 0.85, - position: "right", - onclick: ImprovedTube.toggleFitToWindow, - title: 'Fit To Window' - }); - } + svg = tempContainer.firstChild; + } + this.createPlayerButton({ + id: "it-fit-to-win-player-button", + child: svg, + opacity: 0.85, + position: "right", + onclick: ImprovedTube.toggleFitToWindow, + title: "Fit To Window", + }); + } }; -ImprovedTube.toggleFitToWindow = function() { - let previousSize = ImprovedTube.storage.player_size === "fit_to_window" ? "do_not_change" : (ImprovedTube.storage.player_size ?? "do_not_change"); - let isFTW = document.querySelector("html").getAttribute("it-player-size") === "fit_to_window" - if (isFTW) { - document.querySelector("html").setAttribute("it-player-size", previousSize); - } else { - document.querySelector("html").setAttribute("it-player-size", "fit_to_window"); - } - window.dispatchEvent(new Event("resize")); +ImprovedTube.toggleFitToWindow = function () { + let previousSize = + ImprovedTube.storage.player_size === "fit_to_window" + ? "do_not_change" + : ImprovedTube.storage.player_size ?? "do_not_change"; + let isFTW = + document.querySelector("html").getAttribute("it-player-size") === + "fit_to_window"; + if (isFTW) { + document.querySelector("html").setAttribute("it-player-size", previousSize); + } else { + document + .querySelector("html") + .setAttribute("it-player-size", "fit_to_window"); + } + window.dispatchEvent(new Event("resize")); }; /*------------------------------------------------------------------------------ CINEMA MODE BUTTON ------------------------------------------------------------------------------*/ var xpath = function (xpathToExecute) { - var result = []; - var nodesSnapshot = document.evaluate(xpathToExecute, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); - for ( var i=0; i < nodesSnapshot.snapshotLength; i++ ) { - result.push( nodesSnapshot.snapshotItem(i) ); - } - return result; -} + var result = []; + var nodesSnapshot = document.evaluate( + xpathToExecute, + document, + null, + XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, + null + ); + for (var i = 0; i < nodesSnapshot.snapshotLength; i++) { + result.push(nodesSnapshot.snapshotItem(i)); + } + return result; +}; -function createOverlay () { - var overlay = document.createElement('div'); - overlay.id = 'overlay_cinema'; - overlay.style.position = 'fixed'; - overlay.style.top = '0'; - overlay.style.left = '0'; - overlay.style.width = '100%'; - overlay.style.height = '100%'; - overlay.style.backgroundColor = 'rgba(0, 0, 0, 1)'; - overlay.style.zIndex = '9999'; - overlay.style.display = 'block'; - document.body.appendChild(overlay); +function createOverlay() { + var overlay = document.createElement("div"); + overlay.id = "overlay_cinema"; + overlay.style.position = "fixed"; + overlay.style.top = "0"; + overlay.style.left = "0"; + overlay.style.width = "100%"; + overlay.style.height = "100%"; + overlay.style.backgroundColor = "rgba(0, 0, 0, 1)"; + overlay.style.zIndex = "9999"; + overlay.style.display = "block"; + document.body.appendChild(overlay); } ImprovedTube.playerCinemaModeButton = function () { - if (this.storage.player_cinema_mode_button && (/watch\?/.test(location.href))) { - var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), - path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - - svg.setAttributeNS(null, 'viewBox', '0 0 24 24'); - // TODO: change path such that cinema mode has its own unique icon - path.setAttributeNS(null, 'd', 'm 2.1852 2.2 h 3.7188 h 5.2974 h 5.184 h 3.5478 c 0.6012 0 1.1484 0.2737 1.5444 0.7113 c 0.396 0.4396 0.6408 1.047 0.6408 1.7143 v 1.4246 v 11.4386 v 1.4166 c 0 0.6673 -0.2466 1.2747 -0.6408 1.7143 c -0.396 0.4396 -0.9432 0.7113 -1.5444 0.7113 h -3.456 c -0.0288 0.006 -0.0594 0.008 -0.0918 0.008 c -0.0306 0 -0.0612 -0.002 -0.0918 -0.008 h -5.0004 c -0.0288 0.006 -0.0594 0.008 -0.0918 0.008 c -0.0306 0 -0.0612 -0.002 -0.0918 -0.008 h -5.1138 c -0.0288 0.006 -0.0594 0.008 -0.0918 0.008 c -0.0306 0 -0.0612 -0.002 -0.0918 -0.008 h -3.627 c -0.6012 0 -1.1484 -0.2737 -1.5444 -0.7113 s -0.6408 -1.047 -0.6408 -1.7143 v -1.4166 v -11.4386 v -1.4246 c 0 -0.6673 0.2466 -1.2747 0.6408 -1.7143 c 0.396 -0.4376 0.9432 -0.7113 1.5444 -0.7113 l 0 0 z m 7.749 6.2418 l 3.6954 2.8611 c 0.0576 0.04 0.1098 0.0959 0.1512 0.1618 c 0.1656 0.2657 0.1044 0.6274 -0.1332 0.8112 l -3.681 2.8252 c -0.09 0.0819 -0.207 0.1319 -0.333 0.1319 c -0.2916 0 -0.5274 -0.2617 -0.5274 -0.5854 v -5.7283 h 0.0018 c 0 -0.1159 0.0306 -0.2318 0.0936 -0.3337 c 0.1674 -0.2637 0.495 -0.3277 0.7326 -0.1439 l 0 0 z m 6.9768 9.6324 v 2.0879 h 3.0204 c 0.3114 0 0.594 -0.1419 0.7992 -0.3696 c 0.2052 -0.2278 0.333 -0.5415 0.333 -0.8871 v -0.8312 h -4.1526 l 0 0 z m -1.053 2.0879 v -2.0879 h -4.1292 v 2.0879 h 4.1292 l 0 0 z m -5.1822 0 v -2.0879 h -4.2444 v 2.0879 h 4.2444 l 0 0 z m -5.2992 0 v -2.0879 h -4.3236 v 0.8312 c 0 0.3457 0.1278 0.6593 0.333 0.8871 c 0.2052 0.2278 0.4878 0.3696 0.7992 0.3696 h 3.1914 l 0 0 z m -4.3236 -3.2567 h 4.851 h 5.2974 h 5.184 h 4.68 v -10.2697 h -4.68 h -5.184 h -5.2974 h -4.851 v 10.2697 l 0 0 z m 14.805 -11.4386 v -2.0979 h -4.1292 v 2.0959 h 4.1292 l 0 0.002 z m 1.053 -2.0979 v 2.0959 h 4.1526 v -0.8392 c 0 -0.3457 -0.1278 -0.6593 -0.333 -0.8871 c -0.2052 -0.2278 -0.4878 -0.3696 -0.7992 -0.3696 h -3.0204 l 0 0 z m -6.2352 2.0979 v -2.0979 h -4.2444 v 2.0959 h 4.2444 l 0 0.002 z m -5.2992 0 v -2.0979 h -3.1914 c -0.3114 0 -0.594 0.1419 -0.7992 0.3696 c -0.2052 0.2278 -0.333 0.5415 -0.333 0.8871 v 0.8392 h 4.3236 l 0 0.002 z'); - - svg.appendChild(path); - - this.createPlayerButton({ - id: 'it-cinema-mode-button', - child: svg, - // position: "right", // using right only works when we also have fit to window button enabled for some reason - opacity: 0.64, - onclick: function () { - var player = xpath('//*[@id="movie_player"]/div[1]/video')[0].parentNode.parentNode - // console.log(player) - if (player.style.zIndex == 10000) { - player.style.zIndex = 1; - svg.parentNode.style.opacity = 0.64; - svg.parentNode.style.zIndex = 1; - } else { - player.style.zIndex = 10000; - svg.parentNode.style.opacity = 1; - } - - var overlay = document.getElementById('overlay_cinema'); - if (!overlay) { - createOverlay(); - } else { - overlay.style.display = overlay.style.display === 'none' || overlay.style.display === '' ? 'block' : 'none'; - } - //console.log(overlay) - }, - title: 'Cinema Mode' - }); - } -} + if (this.storage.player_cinema_mode_button && /watch\?/.test(location.href)) { + var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), + path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + + svg.setAttributeNS(null, "viewBox", "0 0 24 24"); + // TODO: change path such that cinema mode has its own unique icon + path.setAttributeNS( + null, + "d", + "m 2.1852 2.2 h 3.7188 h 5.2974 h 5.184 h 3.5478 c 0.6012 0 1.1484 0.2737 1.5444 0.7113 c 0.396 0.4396 0.6408 1.047 0.6408 1.7143 v 1.4246 v 11.4386 v 1.4166 c 0 0.6673 -0.2466 1.2747 -0.6408 1.7143 c -0.396 0.4396 -0.9432 0.7113 -1.5444 0.7113 h -3.456 c -0.0288 0.006 -0.0594 0.008 -0.0918 0.008 c -0.0306 0 -0.0612 -0.002 -0.0918 -0.008 h -5.0004 c -0.0288 0.006 -0.0594 0.008 -0.0918 0.008 c -0.0306 0 -0.0612 -0.002 -0.0918 -0.008 h -5.1138 c -0.0288 0.006 -0.0594 0.008 -0.0918 0.008 c -0.0306 0 -0.0612 -0.002 -0.0918 -0.008 h -3.627 c -0.6012 0 -1.1484 -0.2737 -1.5444 -0.7113 s -0.6408 -1.047 -0.6408 -1.7143 v -1.4166 v -11.4386 v -1.4246 c 0 -0.6673 0.2466 -1.2747 0.6408 -1.7143 c 0.396 -0.4376 0.9432 -0.7113 1.5444 -0.7113 l 0 0 z m 7.749 6.2418 l 3.6954 2.8611 c 0.0576 0.04 0.1098 0.0959 0.1512 0.1618 c 0.1656 0.2657 0.1044 0.6274 -0.1332 0.8112 l -3.681 2.8252 c -0.09 0.0819 -0.207 0.1319 -0.333 0.1319 c -0.2916 0 -0.5274 -0.2617 -0.5274 -0.5854 v -5.7283 h 0.0018 c 0 -0.1159 0.0306 -0.2318 0.0936 -0.3337 c 0.1674 -0.2637 0.495 -0.3277 0.7326 -0.1439 l 0 0 z m 6.9768 9.6324 v 2.0879 h 3.0204 c 0.3114 0 0.594 -0.1419 0.7992 -0.3696 c 0.2052 -0.2278 0.333 -0.5415 0.333 -0.8871 v -0.8312 h -4.1526 l 0 0 z m -1.053 2.0879 v -2.0879 h -4.1292 v 2.0879 h 4.1292 l 0 0 z m -5.1822 0 v -2.0879 h -4.2444 v 2.0879 h 4.2444 l 0 0 z m -5.2992 0 v -2.0879 h -4.3236 v 0.8312 c 0 0.3457 0.1278 0.6593 0.333 0.8871 c 0.2052 0.2278 0.4878 0.3696 0.7992 0.3696 h 3.1914 l 0 0 z m -4.3236 -3.2567 h 4.851 h 5.2974 h 5.184 h 4.68 v -10.2697 h -4.68 h -5.184 h -5.2974 h -4.851 v 10.2697 l 0 0 z m 14.805 -11.4386 v -2.0979 h -4.1292 v 2.0959 h 4.1292 l 0 0.002 z m 1.053 -2.0979 v 2.0959 h 4.1526 v -0.8392 c 0 -0.3457 -0.1278 -0.6593 -0.333 -0.8871 c -0.2052 -0.2278 -0.4878 -0.3696 -0.7992 -0.3696 h -3.0204 l 0 0 z m -6.2352 2.0979 v -2.0979 h -4.2444 v 2.0959 h 4.2444 l 0 0.002 z m -5.2992 0 v -2.0979 h -3.1914 c -0.3114 0 -0.594 0.1419 -0.7992 0.3696 c -0.2052 0.2278 -0.333 0.5415 -0.333 0.8871 v 0.8392 h 4.3236 l 0 0.002 z" + ); + + svg.appendChild(path); + + this.createPlayerButton({ + id: "it-cinema-mode-button", + child: svg, + // position: "right", // using right only works when we also have fit to window button enabled for some reason + opacity: 0.64, + onclick: function () { + var player = xpath('//*[@id="movie_player"]/div[1]/video')[0].parentNode + .parentNode; + // console.log(player) + if (player.style.zIndex == 10000) { + player.style.zIndex = 1; + svg.parentNode.style.opacity = 0.64; + svg.parentNode.style.zIndex = 1; + } else { + player.style.zIndex = 10000; + svg.parentNode.style.opacity = 1; + } + + var overlay = document.getElementById("overlay_cinema"); + if (!overlay) { + createOverlay(); + } else { + overlay.style.display = + overlay.style.display === "none" || overlay.style.display === "" + ? "block" + : "none"; + } + //console.log(overlay) + }, + title: "Cinema Mode", + }); + } +}; ImprovedTube.playerCinemaModeDisable = function () { - if (this.storage.player_auto_hide_cinema_mode_when_paused) { - var overlay = document.getElementById('overlay_cinema'); - if (overlay) { - overlay.style.display = 'none' - var player = xpath('//*[@id="movie_player"]/div[1]/video')[0].parentNode.parentNode - player.style.zIndex = 1; - var cinemaModeButton = xpath('//*[@id="it-cinema-mode-button"]')[0] - cinemaModeButton.style.opacity = 0.64 - } - } -} + if (this.storage.player_auto_hide_cinema_mode_when_paused) { + var overlay = document.getElementById("overlay_cinema"); + if (overlay) { + overlay.style.display = "none"; + var player = xpath('//*[@id="movie_player"]/div[1]/video')[0].parentNode + .parentNode; + player.style.zIndex = 1; + var cinemaModeButton = xpath('//*[@id="it-cinema-mode-button"]')[0]; + cinemaModeButton.style.opacity = 0.64; + } + } +}; ImprovedTube.playerCinemaModeEnable = function () { - if (this.storage.player_auto_cinema_mode || this.storage.player_auto_hide_cinema_mode_when_paused) { - - if ((/watch\?/.test(location.href))) { - var overlay = document.getElementById('overlay_cinema'); - - if (this.storage.player_auto_cinema_mode === true && !overlay) { - createOverlay(); - overlay = document.getElementById('overlay_cinema'); - } - - // console.log(overlay && this.storage.player_auto_hide_cinema_mode_when_paused === true || this.storage.player_auto_cinema_mode === true && overlay) - if (overlay) { - overlay.style.display = 'block' - var player = xpath('//*[@id="movie_player"]/div[1]/video')[0].parentNode.parentNode - player.style.zIndex = 10000; - // console.log(player) - var cinemaModeButton = xpath('//*[@id="it-cinema-mode-button"]')[0] - cinemaModeButton.style.opacity = 1 - } - } - } -} + if ( + this.storage.player_auto_cinema_mode || + this.storage.player_auto_hide_cinema_mode_when_paused + ) { + if (/watch\?/.test(location.href)) { + var overlay = document.getElementById("overlay_cinema"); + + if (this.storage.player_auto_cinema_mode === true && !overlay) { + createOverlay(); + overlay = document.getElementById("overlay_cinema"); + } + + // console.log(overlay && this.storage.player_auto_hide_cinema_mode_when_paused === true || this.storage.player_auto_cinema_mode === true && overlay) + if (overlay) { + overlay.style.display = "block"; + var player = xpath('//*[@id="movie_player"]/div[1]/video')[0].parentNode + .parentNode; + player.style.zIndex = 10000; + // console.log(player) + var cinemaModeButton = xpath('//*[@id="it-cinema-mode-button"]')[0]; + cinemaModeButton.style.opacity = 1; + } + } + } +}; /*------------------------------------------------------------------------------ HAMBURGER MENU ------------------------------------------------------------------------------*/ ImprovedTube.playerHamburgerButton = function () { - if (this.storage.player_hamburger_button === true) { - const videoPlayer = document.querySelector('.html5-video-player'); - - if (!videoPlayer) { - return; - } - - const controlsContainer = videoPlayer.querySelector('.ytp-right-controls'); - - if (!controlsContainer) { - return; - } - - let hamburgerMenu = document.querySelector('.custom-hamburger-menu'); - if (!hamburgerMenu) { - hamburgerMenu = document.createElement('div'); - hamburgerMenu.className = 'custom-hamburger-menu'; - hamburgerMenu.style.position = 'absolute'; - hamburgerMenu.style.right = '0'; - hamburgerMenu.style.marginTop = '8px'; - hamburgerMenu.style.cursor = 'pointer'; - - const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - svg.setAttributeNS(null, 'viewBox', '0 0 24 24'); - svg.setAttribute('style', 'width: 32px; height: 32px;'); - - const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttributeNS(null, 'd', 'M3 18h18v-2H3v2zM3 13h18v-2H3v2zM3 6v2h18V6H3z'); - path.setAttributeNS(null, 'fill', 'white'); - - svg.appendChild(path); - hamburgerMenu.appendChild(svg); - - controlsContainer.style.paddingRight = '40px'; - controlsContainer.parentNode.appendChild(hamburgerMenu); - - let controlsVisible = true; - controlsContainer.style.display = controlsVisible ? 'none' : 'flex'; - controlsVisible = false; - - hamburgerMenu.addEventListener('click', function () { - controlsContainer.style.display = controlsVisible ? 'none' : 'flex'; - controlsVisible = !controlsVisible; - - // Change the opacity of hamburgerMenu based on controls visibility - hamburgerMenu.style.opacity = controlsVisible ? '0.85' : '0.65'; - }); - } - } + if (this.storage.player_hamburger_button === true) { + const videoPlayer = document.querySelector(".html5-video-player"); + + if (!videoPlayer) { + return; + } + + const controlsContainer = videoPlayer.querySelector(".ytp-right-controls"); + + if (!controlsContainer) { + return; + } + + let hamburgerMenu = document.querySelector(".custom-hamburger-menu"); + if (!hamburgerMenu) { + hamburgerMenu = document.createElement("div"); + hamburgerMenu.className = "custom-hamburger-menu"; + hamburgerMenu.style.position = "absolute"; + hamburgerMenu.style.right = "0"; + hamburgerMenu.style.marginTop = "8px"; + hamburgerMenu.style.cursor = "pointer"; + + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + svg.setAttributeNS(null, "viewBox", "0 0 24 24"); + svg.setAttribute("style", "width: 32px; height: 32px;"); + + const path = document.createElementNS( + "http://www.w3.org/2000/svg", + "path" + ); + path.setAttributeNS( + null, + "d", + "M3 18h18v-2H3v2zM3 13h18v-2H3v2zM3 6v2h18V6H3z" + ); + path.setAttributeNS(null, "fill", "white"); + + svg.appendChild(path); + hamburgerMenu.appendChild(svg); + + controlsContainer.style.paddingRight = "40px"; + controlsContainer.parentNode.appendChild(hamburgerMenu); + + let controlsVisible = true; + controlsContainer.style.display = controlsVisible ? "none" : "flex"; + controlsVisible = false; + + hamburgerMenu.addEventListener("click", function () { + controlsContainer.style.display = controlsVisible ? "none" : "flex"; + controlsVisible = !controlsVisible; + + // Change the opacity of hamburgerMenu based on controls visibility + hamburgerMenu.style.opacity = controlsVisible ? "0.85" : "0.65"; + }); + } + } }; /*------------------------------------------------------------------------------ POPUP PLAYER ------------------------------------------------------------------------------*/ ImprovedTube.playerPopupButton = function () { - if (this.storage.player_popup_button === true && location.href.indexOf('youtube.com/embed') === -1 ) { - var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), - path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - - svg.setAttributeNS(null, 'viewBox', '0 0 24 24'); - path.setAttributeNS(null, 'd', 'M19 7h-8v6h8V7zm2-4H3C2 3 1 4 1 5v14c0 1 1 2 2 2h18c1 0 2-1 2-2V5c0-1-1-2-2-2zm0 16H3V5h18v14z'); - - svg.appendChild(path); - - this.createPlayerButton({ - id: 'it-popup-player-button', - child: svg, - opacity: 0.8, - onclick: function () { - "use strict"; - const ytPlayer = ImprovedTube.elements.player; - ytPlayer.pauseVideo(); - const videoID = location.search.match(ImprovedTube.regex.video_id)[1], - listMatch = location.search.match(ImprovedTube.regex.playlist_id), - popup = window.open( - `${location.protocol}//www.youtube.com/embed/${videoID}?start=${parseInt(ytPlayer.getCurrentTime())}&autoplay=${ImprovedTube.storage.player_autoplay_disable ? '0' : '1'}${listMatch?`&list=${listMatch[1]}`:''}`, - '_blank', - `directories=no,toolbar=no,location=no,menubar=no,status=no,titlebar=no,scrollbars=no,resizable=no,width=${ytPlayer.offsetWidth / 3},height=${ytPlayer.offsetHeight / 3}` - ); - if (popup && listMatch) { - //! If the video is not in the playlist or not within the first 200 entries, then it automatically selects the first video in the list. - popup.addEventListener('load', function () { - "use strict"; - //~ check if the video ID in the link of the video title matches the original video ID in the URL and if not remove the playlist from the URL (reloads the page). - const videoLink = this.document.querySelector('div#player div.ytp-title-text>a[href]'); - if (videoLink && videoLink.href.match(ImprovedTube.regex.video_id)[1] !== videoID) this.location.search = this.location.search.replace(/(\?)list=[^&]+&|&list=[^&]+/, '$1'); - }, {passive: true, once: true}); - } - //~ change focused tab to URL-less popup - ImprovedTube.messages.send({ - action: 'fixPopup', - width: ytPlayer.offsetWidth * 0.75, - height: ytPlayer.offsetHeight * 0.75, - title: document.title - }); - }, - title: 'Popup' - }); - } + if ( + this.storage.player_popup_button === true && + location.href.indexOf("youtube.com/embed") === -1 + ) { + var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), + path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + + svg.setAttributeNS(null, "viewBox", "0 0 24 24"); + path.setAttributeNS( + null, + "d", + "M19 7h-8v6h8V7zm2-4H3C2 3 1 4 1 5v14c0 1 1 2 2 2h18c1 0 2-1 2-2V5c0-1-1-2-2-2zm0 16H3V5h18v14z" + ); + + svg.appendChild(path); + + this.createPlayerButton({ + id: "it-popup-player-button", + child: svg, + opacity: 0.8, + onclick: function () { + "use strict"; + const ytPlayer = ImprovedTube.elements.player; + ytPlayer.pauseVideo(); + const videoID = location.search.match(ImprovedTube.regex.video_id)[1], + listMatch = location.search.match(ImprovedTube.regex.playlist_id), + popup = window.open( + `${ + location.protocol + }//www.youtube.com/embed/${videoID}?start=${parseInt( + ytPlayer.getCurrentTime() + )}&autoplay=${ + ImprovedTube.storage.player_autoplay_disable ? "0" : "1" + }${listMatch ? `&list=${listMatch[1]}` : ""}`, + "_blank", + `directories=no,toolbar=no,location=no,menubar=no,status=no,titlebar=no,scrollbars=no,resizable=no,width=${ + ytPlayer.offsetWidth / 3 + },height=${ytPlayer.offsetHeight / 3}` + ); + if (popup && listMatch) { + //! If the video is not in the playlist or not within the first 200 entries, then it automatically selects the first video in the list. + popup.addEventListener( + "load", + function () { + "use strict"; + //~ check if the video ID in the link of the video title matches the original video ID in the URL and if not remove the playlist from the URL (reloads the page). + const videoLink = this.document.querySelector( + "div#player div.ytp-title-text>a[href]" + ); + if ( + videoLink && + videoLink.href.match(ImprovedTube.regex.video_id)[1] !== videoID + ) + this.location.search = this.location.search.replace( + /(\?)list=[^&]+&|&list=[^&]+/, + "$1" + ); + }, + { passive: true, once: true } + ); + } + //~ change focused tab to URL-less popup + ImprovedTube.messages.send({ + action: "fixPopup", + width: ytPlayer.offsetWidth * 0.75, + height: ytPlayer.offsetHeight * 0.75, + title: document.title, + }); + }, + title: "Popup", + }); + } }; /*------------------------------------------------------------------------------ Force SDR ------------------------------------------------------------------------------*/ ImprovedTube.playerSDR = function () { - if (this.storage.player_SDR === true) { - Object.defineProperty(window.screen, 'pixelDepth', { - enumerable: true, - configurable: true, - value: 24 - }); - } + if (this.storage.player_SDR === true) { + Object.defineProperty(window.screen, "pixelDepth", { + enumerable: true, + configurable: true, + value: 24, + }); + } }; /*------------------------------------------------------------------------------ Hide controls ------------------------------------------------------------------------------*/ ImprovedTube.playerControls = function () { - const player = this.elements.player, - hide = this.storage.player_hide_controls; - - if (player && player.hideControls && player.showControls) { - - if (hide === 'when_paused' && this.elements.video.paused) { - player.hideControls(); - - player.onmouseenter = player.showControls; - player.onmouseleave = player.hideControls; - player.onmousemove = (function () { - let thread, - onmousestop = function () { - if (document.querySelector(".ytp-progress-bar:hover")) { - thread = setTimeout(onmousestop, 1000); - } else { - player.hideControls(); - } - }; - - return function () { - player.showControls(); - clearTimeout(thread); - thread = setTimeout(onmousestop, 1000); - }; - })(); - return; - } else if (hide === 'always') { - player.hideControls(); - } else { - player.showControls(); - } - player.onmouseenter = null; - player.onmouseleave = null; - player.onmousemove = null; - } + const player = this.elements.player, + hide = this.storage.player_hide_controls; + + if (player && player.hideControls && player.showControls) { + if (hide === "when_paused" && this.elements.video.paused) { + player.hideControls(); + + player.onmouseenter = player.showControls; + player.onmouseleave = player.hideControls; + player.onmousemove = (function () { + let thread, + onmousestop = function () { + if (document.querySelector(".ytp-progress-bar:hover")) { + thread = setTimeout(onmousestop, 1000); + } else { + player.hideControls(); + } + }; + + return function () { + player.showControls(); + clearTimeout(thread); + thread = setTimeout(onmousestop, 1000); + }; + })(); + return; + } else if (hide === "always") { + player.hideControls(); + } else { + player.showControls(); + } + player.onmouseenter = null; + player.onmouseleave = null; + player.onmousemove = null; + } }; /*# HIDE VIDEO TITLE IN FULLSCREEN */ // Easier with CSS only (see player.css) //ImprovedTube.hideVideoTitleFullScreen = function (){ if (ImprovedTube.storage.hide_video_title_fullScreen === true) { @@ -1132,631 +1636,865 @@ ImprovedTube.playerControls = function () { /*------------------------------------------------------------------------------ CUSTOM MINI-PLAYER ------------------------------------------------------------------------------*/ -ImprovedTube.mini_player__setSize = function (width, height, keep_ar, keep_area) { - if (keep_ar) { - const aspect_ratio = ImprovedTube.elements.video.style.width.replace('px', '') / ImprovedTube.elements.video.style.height.replace('px', ''); - if (keep_area) { - height = Math.sqrt((width * height) / aspect_ratio); - width = height * aspect_ratio; - } else { - height = width / aspect_ratio; - } - } - - ImprovedTube.elements.player.style.width = width + 'px'; - ImprovedTube.elements.player.style.height = height + 'px'; +ImprovedTube.mini_player__setSize = function ( + width, + height, + keep_ar, + keep_area +) { + if (keep_ar) { + const aspect_ratio = + ImprovedTube.elements.video.style.width.replace("px", "") / + ImprovedTube.elements.video.style.height.replace("px", ""); + if (keep_area) { + height = Math.sqrt((width * height) / aspect_ratio); + width = height * aspect_ratio; + } else { + height = width / aspect_ratio; + } + } + + ImprovedTube.elements.player.style.width = width + "px"; + ImprovedTube.elements.player.style.height = height + "px"; }; ImprovedTube.miniPlayer_scroll = function () { - if (window.scrollY >= 256 && ImprovedTube.mini_player__mode === false && ImprovedTube.elements.player.classList.contains('ytp-player-minimized') === false) { - ImprovedTube.mini_player__mode = true; - - ImprovedTube.mini_player__original_width = ImprovedTube.elements.player.offsetWidth; - ImprovedTube.mini_player__original_height = ImprovedTube.elements.player.offsetHeight; - - ImprovedTube.elements.player.classList.add('it-mini-player'); - - ImprovedTube.mini_player__x = Math.max(0, Math.min(ImprovedTube.mini_player__x, document.body.offsetWidth - ImprovedTube.mini_player__width)); - ImprovedTube.mini_player__y = Math.max(0, Math.min(ImprovedTube.mini_player__y, window.innerHeight - ImprovedTube.mini_player__height)); - - ImprovedTube.mini_player__cursor = ''; - document.documentElement.removeAttribute('it-mini-player-cursor'); - - ImprovedTube.elements.player.style.transform = 'translate(' + ImprovedTube.mini_player__x + 'px, ' + ImprovedTube.mini_player__y + 'px)'; - - ImprovedTube.mini_player__setSize(ImprovedTube.mini_player__width, ImprovedTube.mini_player__height, true, true); - - window.addEventListener('resize', ImprovedTube.miniPlayer_scroll); - } else if (window.scrollY < 256 && ImprovedTube.mini_player__mode === true || ImprovedTube.elements.player.classList.contains('ytp-player-minimized') === true) { - ImprovedTube.mini_player__mode = false; - ImprovedTube.elements.player.classList.remove('it-mini-player'); - ImprovedTube.mini_player__move = false; - ImprovedTube.elements.player.style.transform = 'translate(' + 0 + 'px, ' + 0 + 'px)'; - ImprovedTube.elements.player.style.width = ''; - ImprovedTube.elements.player.style.height = ''; - - ImprovedTube.mini_player__cursor = ''; - document.documentElement.removeAttribute('it-mini-player-cursor'); - - window.dispatchEvent(new Event('resize')); - - window.removeEventListener('mousedown', ImprovedTube.miniPlayer_mouseDown); - window.removeEventListener('mousemove', ImprovedTube.miniPlayer_mouseMove); - window.removeEventListener('mouseup', ImprovedTube.miniPlayer_mouseUp); - window.removeEventListener('click', ImprovedTube.miniPlayer_click); - window.removeEventListener('scroll', ImprovedTube.miniPlayer_scroll); - window.removeEventListener('mousemove', ImprovedTube.miniPlayer_cursorUpdate); - } + if ( + window.scrollY >= 256 && + ImprovedTube.mini_player__mode === false && + ImprovedTube.elements.player.classList.contains("ytp-player-minimized") === + false + ) { + ImprovedTube.mini_player__mode = true; + + ImprovedTube.mini_player__original_width = + ImprovedTube.elements.player.offsetWidth; + ImprovedTube.mini_player__original_height = + ImprovedTube.elements.player.offsetHeight; + + ImprovedTube.elements.player.classList.add("it-mini-player"); + + ImprovedTube.mini_player__x = Math.max( + 0, + Math.min( + ImprovedTube.mini_player__x, + document.body.offsetWidth - ImprovedTube.mini_player__width + ) + ); + ImprovedTube.mini_player__y = Math.max( + 0, + Math.min( + ImprovedTube.mini_player__y, + window.innerHeight - ImprovedTube.mini_player__height + ) + ); + + ImprovedTube.mini_player__cursor = ""; + document.documentElement.removeAttribute("it-mini-player-cursor"); + + ImprovedTube.elements.player.style.transform = + "translate(" + + ImprovedTube.mini_player__x + + "px, " + + ImprovedTube.mini_player__y + + "px)"; + + ImprovedTube.mini_player__setSize( + ImprovedTube.mini_player__width, + ImprovedTube.mini_player__height, + true, + true + ); + + window.addEventListener("resize", ImprovedTube.miniPlayer_scroll); + } else if ( + (window.scrollY < 256 && ImprovedTube.mini_player__mode === true) || + ImprovedTube.elements.player.classList.contains("ytp-player-minimized") === + true + ) { + ImprovedTube.mini_player__mode = false; + ImprovedTube.elements.player.classList.remove("it-mini-player"); + ImprovedTube.mini_player__move = false; + ImprovedTube.elements.player.style.transform = + "translate(" + 0 + "px, " + 0 + "px)"; + ImprovedTube.elements.player.style.width = ""; + ImprovedTube.elements.player.style.height = ""; + + ImprovedTube.mini_player__cursor = ""; + document.documentElement.removeAttribute("it-mini-player-cursor"); + + window.dispatchEvent(new Event("resize")); + + window.removeEventListener("mousedown", ImprovedTube.miniPlayer_mouseDown); + window.removeEventListener("mousemove", ImprovedTube.miniPlayer_mouseMove); + window.removeEventListener("mouseup", ImprovedTube.miniPlayer_mouseUp); + window.removeEventListener("click", ImprovedTube.miniPlayer_click); + window.removeEventListener("scroll", ImprovedTube.miniPlayer_scroll); + window.removeEventListener( + "mousemove", + ImprovedTube.miniPlayer_cursorUpdate + ); + } }; ImprovedTube.miniPlayer_mouseDown = function (event) { - if (event.button !== 0) { - return false; - } + if (event.button !== 0) { + return false; + } - if (ImprovedTube.miniPlayer_resize() === true) { - return false; - } + if (ImprovedTube.miniPlayer_resize() === true) { + return false; + } - var is_player = false, - path = event.composedPath(); + var is_player = false, + path = event.composedPath(); - for (var i = 0, l = path.length; i < l; i++) { - if ((path[i].classList && path[i].classList.contains('it-mini-player')) === true) { - is_player = true; - } - } + for (var i = 0, l = path.length; i < l; i++) { + if ( + (path[i].classList && path[i].classList.contains("it-mini-player")) === + true + ) { + is_player = true; + } + } - if (is_player === false) { - return false; - } + if (is_player === false) { + return false; + } - event.preventDefault(); + event.preventDefault(); - var bcr = ImprovedTube.elements.player.getBoundingClientRect(); + var bcr = ImprovedTube.elements.player.getBoundingClientRect(); - ImprovedTube.miniPlayer_mouseDown_x = event.clientX; - ImprovedTube.miniPlayer_mouseDown_y = event.clientY; - ImprovedTube.mini_player__width = bcr.width; - ImprovedTube.mini_player__height = bcr.height; + ImprovedTube.miniPlayer_mouseDown_x = event.clientX; + ImprovedTube.miniPlayer_mouseDown_y = event.clientY; + ImprovedTube.mini_player__width = bcr.width; + ImprovedTube.mini_player__height = bcr.height; - ImprovedTube.mini_player__player_offset_x = event.clientX - bcr.x; - ImprovedTube.mini_player__player_offset_y = event.clientY - bcr.y; + ImprovedTube.mini_player__player_offset_x = event.clientX - bcr.x; + ImprovedTube.mini_player__player_offset_y = event.clientY - bcr.y; - ImprovedTube.mini_player__max_x = document.body.offsetWidth - ImprovedTube.mini_player__width; - ImprovedTube.mini_player__max_y = window.innerHeight - ImprovedTube.mini_player__height; + ImprovedTube.mini_player__max_x = + document.body.offsetWidth - ImprovedTube.mini_player__width; + ImprovedTube.mini_player__max_y = + window.innerHeight - ImprovedTube.mini_player__height; - window.addEventListener('mouseup', ImprovedTube.miniPlayer_mouseUp); - window.addEventListener('mousemove', ImprovedTube.miniPlayer_mouseMove); + window.addEventListener("mouseup", ImprovedTube.miniPlayer_mouseUp); + window.addEventListener("mousemove", ImprovedTube.miniPlayer_mouseMove); }; ImprovedTube.miniPlayer_mouseUp = function () { - var strg = JSON.parse(localStorage.getItem('improvedtube-mini-player')) || {}; + var strg = JSON.parse(localStorage.getItem("improvedtube-mini-player")) || {}; - strg.x = ImprovedTube.mini_player__x; - strg.y = ImprovedTube.mini_player__y; + strg.x = ImprovedTube.mini_player__x; + strg.y = ImprovedTube.mini_player__y; - localStorage.setItem('improvedtube-mini-player', JSON.stringify(strg)); + localStorage.setItem("improvedtube-mini-player", JSON.stringify(strg)); - window.removeEventListener('mouseup', ImprovedTube.miniPlayer_mouseUp); - window.removeEventListener('mousemove', ImprovedTube.miniPlayer_mouseMove); + window.removeEventListener("mouseup", ImprovedTube.miniPlayer_mouseUp); + window.removeEventListener("mousemove", ImprovedTube.miniPlayer_mouseMove); - ImprovedTube.mini_player__move = false; + ImprovedTube.mini_player__move = false; - setTimeout(function () { - window.removeEventListener('click', ImprovedTube.miniPlayer_click, true); - }); + setTimeout(function () { + window.removeEventListener("click", ImprovedTube.miniPlayer_click, true); + }); }; ImprovedTube.miniPlayer_click = function (event) { - event.stopPropagation(); - event.preventDefault(); + event.stopPropagation(); + event.preventDefault(); }; ImprovedTube.miniPlayer_mouseMove = function (event) { - if ( - event.clientX < ImprovedTube.miniPlayer_mouseDown_x - 5 || - event.clientY < ImprovedTube.miniPlayer_mouseDown_y - 5 || - event.clientX > ImprovedTube.miniPlayer_mouseDown_x + 5 || - event.clientY > ImprovedTube.miniPlayer_mouseDown_y + 5 - ) { - var x = event.clientX - ImprovedTube.mini_player__player_offset_x, - y = event.clientY - ImprovedTube.mini_player__player_offset_y; - - if (ImprovedTube.mini_player__move === false) { - ImprovedTube.mini_player__move = true; - - window.addEventListener('click', ImprovedTube.miniPlayer_click, true); - } - - if (x < 0) { - x = 0; - } - - if (y < 0) { - y = 0; - } - - if (x > ImprovedTube.mini_player__max_x) { - x = ImprovedTube.mini_player__max_x; - } - - if (y > ImprovedTube.mini_player__max_y) { - y = ImprovedTube.mini_player__max_y; - } - - ImprovedTube.mini_player__x = x; - ImprovedTube.mini_player__y = y; - - ImprovedTube.elements.player.style.transform = 'translate(' + x + 'px, ' + y + 'px)'; - } + if ( + event.clientX < ImprovedTube.miniPlayer_mouseDown_x - 5 || + event.clientY < ImprovedTube.miniPlayer_mouseDown_y - 5 || + event.clientX > ImprovedTube.miniPlayer_mouseDown_x + 5 || + event.clientY > ImprovedTube.miniPlayer_mouseDown_y + 5 + ) { + var x = event.clientX - ImprovedTube.mini_player__player_offset_x, + y = event.clientY - ImprovedTube.mini_player__player_offset_y; + + if (ImprovedTube.mini_player__move === false) { + ImprovedTube.mini_player__move = true; + + window.addEventListener("click", ImprovedTube.miniPlayer_click, true); + } + + if (x < 0) { + x = 0; + } + + if (y < 0) { + y = 0; + } + + if (x > ImprovedTube.mini_player__max_x) { + x = ImprovedTube.mini_player__max_x; + } + + if (y > ImprovedTube.mini_player__max_y) { + y = ImprovedTube.mini_player__max_y; + } + + ImprovedTube.mini_player__x = x; + ImprovedTube.mini_player__y = y; + + ImprovedTube.elements.player.style.transform = + "translate(" + x + "px, " + y + "px)"; + } }; ImprovedTube.miniPlayer_cursorUpdate = function (event) { - var x = event.clientX, - y = event.clientY, - c = ImprovedTube.mini_player__cursor; - - if ( - x >= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width - ImprovedTube.miniPlayer_resize_offset && - x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && - y >= ImprovedTube.mini_player__y && - y <= ImprovedTube.mini_player__y + ImprovedTube.miniPlayer_resize_offset - ) { - c = 'ne-resize'; - } else if ( - x >= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width - ImprovedTube.miniPlayer_resize_offset && - x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && - y >= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ImprovedTube.miniPlayer_resize_offset && - y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ) { - c = 'se-resize'; - } else if ( - x >= ImprovedTube.mini_player__x && - x <= ImprovedTube.mini_player__x + ImprovedTube.miniPlayer_resize_offset && - y >= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ImprovedTube.miniPlayer_resize_offset && - y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ) { - c = 'sw-resize'; - } else if ( - x >= ImprovedTube.mini_player__x && - x <= ImprovedTube.mini_player__x + ImprovedTube.miniPlayer_resize_offset && - y >= ImprovedTube.mini_player__y && - y <= ImprovedTube.mini_player__y + ImprovedTube.miniPlayer_resize_offset - ) { - c = 'nw-resize'; - } else if ( - x >= ImprovedTube.mini_player__x && - x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && - y >= ImprovedTube.mini_player__y && - y <= ImprovedTube.mini_player__y + ImprovedTube.miniPlayer_resize_offset - ) { - c = 'n-resize'; - } else if ( - x >= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width - ImprovedTube.miniPlayer_resize_offset && - x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && - y >= ImprovedTube.mini_player__y && - y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ) { - c = 'e-resize'; - } else if ( - x >= ImprovedTube.mini_player__x && - x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && - y >= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ImprovedTube.miniPlayer_resize_offset && - y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ) { - c = 's-resize'; - } else if ( - x >= ImprovedTube.mini_player__x && - x <= ImprovedTube.mini_player__x + ImprovedTube.miniPlayer_resize_offset && - y >= ImprovedTube.mini_player__y && - y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - ) { - c = 'w-resize'; - } else { - c = ''; - } - - if (ImprovedTube.mini_player__cursor !== c) { - ImprovedTube.mini_player__cursor = c; - - document.documentElement.setAttribute('it-mini-player-cursor', ImprovedTube.mini_player__cursor); - } + var x = event.clientX, + y = event.clientY, + c = ImprovedTube.mini_player__cursor; + + if ( + x >= + ImprovedTube.mini_player__x + + ImprovedTube.mini_player__width - + ImprovedTube.miniPlayer_resize_offset && + x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && + y >= ImprovedTube.mini_player__y && + y <= ImprovedTube.mini_player__y + ImprovedTube.miniPlayer_resize_offset + ) { + c = "ne-resize"; + } else if ( + x >= + ImprovedTube.mini_player__x + + ImprovedTube.mini_player__width - + ImprovedTube.miniPlayer_resize_offset && + x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && + y >= + ImprovedTube.mini_player__y + + ImprovedTube.mini_player__height - + ImprovedTube.miniPlayer_resize_offset && + y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height + ) { + c = "se-resize"; + } else if ( + x >= ImprovedTube.mini_player__x && + x <= ImprovedTube.mini_player__x + ImprovedTube.miniPlayer_resize_offset && + y >= + ImprovedTube.mini_player__y + + ImprovedTube.mini_player__height - + ImprovedTube.miniPlayer_resize_offset && + y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height + ) { + c = "sw-resize"; + } else if ( + x >= ImprovedTube.mini_player__x && + x <= ImprovedTube.mini_player__x + ImprovedTube.miniPlayer_resize_offset && + y >= ImprovedTube.mini_player__y && + y <= ImprovedTube.mini_player__y + ImprovedTube.miniPlayer_resize_offset + ) { + c = "nw-resize"; + } else if ( + x >= ImprovedTube.mini_player__x && + x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && + y >= ImprovedTube.mini_player__y && + y <= ImprovedTube.mini_player__y + ImprovedTube.miniPlayer_resize_offset + ) { + c = "n-resize"; + } else if ( + x >= + ImprovedTube.mini_player__x + + ImprovedTube.mini_player__width - + ImprovedTube.miniPlayer_resize_offset && + x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && + y >= ImprovedTube.mini_player__y && + y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height + ) { + c = "e-resize"; + } else if ( + x >= ImprovedTube.mini_player__x && + x <= ImprovedTube.mini_player__x + ImprovedTube.mini_player__width && + y >= + ImprovedTube.mini_player__y + + ImprovedTube.mini_player__height - + ImprovedTube.miniPlayer_resize_offset && + y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height + ) { + c = "s-resize"; + } else if ( + x >= ImprovedTube.mini_player__x && + x <= ImprovedTube.mini_player__x + ImprovedTube.miniPlayer_resize_offset && + y >= ImprovedTube.mini_player__y && + y <= ImprovedTube.mini_player__y + ImprovedTube.mini_player__height + ) { + c = "w-resize"; + } else { + c = ""; + } + + if (ImprovedTube.mini_player__cursor !== c) { + ImprovedTube.mini_player__cursor = c; + + document.documentElement.setAttribute( + "it-mini-player-cursor", + ImprovedTube.mini_player__cursor + ); + } }; ImprovedTube.miniPlayer_resize = function () { - if (ImprovedTube.mini_player__cursor !== '') { - window.removeEventListener('mousemove', ImprovedTube.miniPlayer_cursorUpdate); - window.addEventListener('mouseup', ImprovedTube.miniPlayer_resizeMouseUp); - window.addEventListener('mousemove', ImprovedTube.miniPlayer_resizeMouseMove); - - return true; - } + if (ImprovedTube.mini_player__cursor !== "") { + window.removeEventListener( + "mousemove", + ImprovedTube.miniPlayer_cursorUpdate + ); + window.addEventListener("mouseup", ImprovedTube.miniPlayer_resizeMouseUp); + window.addEventListener( + "mousemove", + ImprovedTube.miniPlayer_resizeMouseMove + ); + + return true; + } }; ImprovedTube.miniPlayer_resizeMouseMove = function (event) { - if (ImprovedTube.mini_player__cursor === 'n-resize') { - ImprovedTube.elements.player.style.transform = 'translate(' + ImprovedTube.mini_player__x + 'px, ' + event.clientY + 'px)'; - ImprovedTube.mini_player__setSize(ImprovedTube.mini_player__width, ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - event.clientY); - } else if (ImprovedTube.mini_player__cursor === 'e-resize') { - ImprovedTube.mini_player__setSize(event.clientX - ImprovedTube.mini_player__x, ImprovedTube.mini_player__height); - } else if (ImprovedTube.mini_player__cursor === 's-resize') { - ImprovedTube.mini_player__setSize(ImprovedTube.mini_player__width, event.clientY - ImprovedTube.mini_player__y); - } else if (ImprovedTube.mini_player__cursor === 'w-resize') { - ImprovedTube.elements.player.style.transform = 'translate(' + event.clientX + 'px, ' + ImprovedTube.mini_player__y + 'px)'; - ImprovedTube.mini_player__setSize(ImprovedTube.mini_player__x + ImprovedTube.mini_player__width - event.clientX, ImprovedTube.mini_player__height); - } else if (ImprovedTube.mini_player__cursor === 'ne-resize') { - ImprovedTube.elements.player.style.transform = 'translate(' + ImprovedTube.mini_player__x + 'px, ' + event.clientY + 'px)'; - ImprovedTube.mini_player__setSize(event.clientX - ImprovedTube.mini_player__x, ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - event.clientY, true); - } else if (ImprovedTube.mini_player__cursor === 'se-resize') { - ImprovedTube.mini_player__setSize(event.clientX - ImprovedTube.mini_player__x, event.clientY - ImprovedTube.mini_player__y, true); - } else if (ImprovedTube.mini_player__cursor === 'sw-resize') { - ImprovedTube.elements.player.style.transform = 'translate(' + event.clientX + 'px, ' + ImprovedTube.mini_player__y + 'px)'; - ImprovedTube.mini_player__setSize(ImprovedTube.mini_player__x + ImprovedTube.mini_player__width - event.clientX, event.clientY - ImprovedTube.mini_player__y, true); - } else if (ImprovedTube.mini_player__cursor === 'nw-resize') { - ImprovedTube.elements.player.style.transform = 'translate(' + event.clientX + 'px, ' + event.clientY + 'px)'; - ImprovedTube.mini_player__setSize(ImprovedTube.mini_player__x + ImprovedTube.mini_player__width - event.clientX, ImprovedTube.mini_player__y + ImprovedTube.mini_player__height - event.clientY, true); - } + if (ImprovedTube.mini_player__cursor === "n-resize") { + ImprovedTube.elements.player.style.transform = + "translate(" + + ImprovedTube.mini_player__x + + "px, " + + event.clientY + + "px)"; + ImprovedTube.mini_player__setSize( + ImprovedTube.mini_player__width, + ImprovedTube.mini_player__y + + ImprovedTube.mini_player__height - + event.clientY + ); + } else if (ImprovedTube.mini_player__cursor === "e-resize") { + ImprovedTube.mini_player__setSize( + event.clientX - ImprovedTube.mini_player__x, + ImprovedTube.mini_player__height + ); + } else if (ImprovedTube.mini_player__cursor === "s-resize") { + ImprovedTube.mini_player__setSize( + ImprovedTube.mini_player__width, + event.clientY - ImprovedTube.mini_player__y + ); + } else if (ImprovedTube.mini_player__cursor === "w-resize") { + ImprovedTube.elements.player.style.transform = + "translate(" + + event.clientX + + "px, " + + ImprovedTube.mini_player__y + + "px)"; + ImprovedTube.mini_player__setSize( + ImprovedTube.mini_player__x + + ImprovedTube.mini_player__width - + event.clientX, + ImprovedTube.mini_player__height + ); + } else if (ImprovedTube.mini_player__cursor === "ne-resize") { + ImprovedTube.elements.player.style.transform = + "translate(" + + ImprovedTube.mini_player__x + + "px, " + + event.clientY + + "px)"; + ImprovedTube.mini_player__setSize( + event.clientX - ImprovedTube.mini_player__x, + ImprovedTube.mini_player__y + + ImprovedTube.mini_player__height - + event.clientY, + true + ); + } else if (ImprovedTube.mini_player__cursor === "se-resize") { + ImprovedTube.mini_player__setSize( + event.clientX - ImprovedTube.mini_player__x, + event.clientY - ImprovedTube.mini_player__y, + true + ); + } else if (ImprovedTube.mini_player__cursor === "sw-resize") { + ImprovedTube.elements.player.style.transform = + "translate(" + + event.clientX + + "px, " + + ImprovedTube.mini_player__y + + "px)"; + ImprovedTube.mini_player__setSize( + ImprovedTube.mini_player__x + + ImprovedTube.mini_player__width - + event.clientX, + event.clientY - ImprovedTube.mini_player__y, + true + ); + } else if (ImprovedTube.mini_player__cursor === "nw-resize") { + ImprovedTube.elements.player.style.transform = + "translate(" + event.clientX + "px, " + event.clientY + "px)"; + ImprovedTube.mini_player__setSize( + ImprovedTube.mini_player__x + + ImprovedTube.mini_player__width - + event.clientX, + ImprovedTube.mini_player__y + + ImprovedTube.mini_player__height - + event.clientY, + true + ); + } }; ImprovedTube.miniPlayer_resizeMouseUp = function () { - var bcr = ImprovedTube.elements.player.getBoundingClientRect(); + var bcr = ImprovedTube.elements.player.getBoundingClientRect(); - ImprovedTube.mini_player__x = bcr.left; - ImprovedTube.mini_player__y = bcr.top; - ImprovedTube.mini_player__width = bcr.width; - ImprovedTube.mini_player__height = bcr.height; + ImprovedTube.mini_player__x = bcr.left; + ImprovedTube.mini_player__y = bcr.top; + ImprovedTube.mini_player__width = bcr.width; + ImprovedTube.mini_player__height = bcr.height; - window.dispatchEvent(new Event('resize')); + window.dispatchEvent(new Event("resize")); - var strg = JSON.parse(localStorage.getItem('improvedtube-mini-player')) || {}; + var strg = JSON.parse(localStorage.getItem("improvedtube-mini-player")) || {}; - strg.width = ImprovedTube.mini_player__width; - strg.height = ImprovedTube.mini_player__height; + strg.width = ImprovedTube.mini_player__width; + strg.height = ImprovedTube.mini_player__height; - localStorage.setItem('improvedtube-mini-player', JSON.stringify(strg)); + localStorage.setItem("improvedtube-mini-player", JSON.stringify(strg)); - window.addEventListener('mousemove', ImprovedTube.miniPlayer_cursorUpdate); - window.removeEventListener('mouseup', ImprovedTube.miniPlayer_resizeMouseUp); - window.removeEventListener('mousemove', ImprovedTube.miniPlayer_resizeMouseMove); + window.addEventListener("mousemove", ImprovedTube.miniPlayer_cursorUpdate); + window.removeEventListener("mouseup", ImprovedTube.miniPlayer_resizeMouseUp); + window.removeEventListener( + "mousemove", + ImprovedTube.miniPlayer_resizeMouseMove + ); }; ImprovedTube.miniPlayer = function () { - if (this.storage.mini_player === true) { - var data = localStorage.getItem('improvedtube-mini-player'); - - try { - if (this.isset(data)) { - data = JSON.parse(data); - } else { - data = {}; - } - } catch (error) { - data = {}; - } - - data.x = data.x || 300; - data.y = data.y || 35; - data.width = data.width || 300; - data.height = data.height || 225; - - this.mini_player__x = data.x; - this.mini_player__y = data.y; - this.mini_player__width = data.width; - this.mini_player__height = data.height; - - window.removeEventListener('scroll', this.miniPlayer_scroll); - window.addEventListener('scroll', this.miniPlayer_scroll); - } else { - this.mini_player__mode = false; - this.elements.player.classList.remove('it-mini-player'); - this.mini_player__move = false; - - this.elements.player.style.width = ''; - this.elements.player.style.height = ''; - this.elements.player.style.transform = 'translate(' + 0 + 'px, ' + 0 + 'px)'; - - this.elements.player.classList.remove('it-mini-player'); - - this.mini_player__cursor = ''; - document.documentElement.removeAttribute('it-mini-player-cursor'); - - window.dispatchEvent(new Event('resize')); - - window.removeEventListener('mousedown', this.miniPlayer_mouseDown); - window.removeEventListener('mousemove', this.miniPlayer_mouseMove); - window.removeEventListener('mouseup', this.miniPlayer_mouseUp); - window.removeEventListener('click', this.miniPlayer_click); - window.removeEventListener('scroll', this.miniPlayer_scroll); - window.removeEventListener('mousemove', this.miniPlayer_cursorUpdate); - } + if (this.storage.mini_player === true) { + var data = localStorage.getItem("improvedtube-mini-player"); + + try { + if (this.isset(data)) { + data = JSON.parse(data); + } else { + data = {}; + } + } catch (error) { + data = {}; + } + + data.x = data.x || 300; + data.y = data.y || 35; + data.width = data.width || 300; + data.height = data.height || 225; + + this.mini_player__x = data.x; + this.mini_player__y = data.y; + this.mini_player__width = data.width; + this.mini_player__height = data.height; + + window.removeEventListener("scroll", this.miniPlayer_scroll); + window.addEventListener("scroll", this.miniPlayer_scroll); + } else { + this.mini_player__mode = false; + this.elements.player.classList.remove("it-mini-player"); + this.mini_player__move = false; + + this.elements.player.style.width = ""; + this.elements.player.style.height = ""; + this.elements.player.style.transform = + "translate(" + 0 + "px, " + 0 + "px)"; + + this.elements.player.classList.remove("it-mini-player"); + + this.mini_player__cursor = ""; + document.documentElement.removeAttribute("it-mini-player-cursor"); + + window.dispatchEvent(new Event("resize")); + + window.removeEventListener("mousedown", this.miniPlayer_mouseDown); + window.removeEventListener("mousemove", this.miniPlayer_mouseMove); + window.removeEventListener("mouseup", this.miniPlayer_mouseUp); + window.removeEventListener("click", this.miniPlayer_click); + window.removeEventListener("scroll", this.miniPlayer_scroll); + window.removeEventListener("mousemove", this.miniPlayer_cursorUpdate); + } }; /*------------------------------------------------------------------------------ CUSTOM PAUSE FUNCTIONS ------------------------------------------------------------------------------*/ ImprovedTube.pauseWhileTypingOnYoutube = function () { - if (ImprovedTube.storage.pause_while_typing_on_youtube === true) { - var timeoutId; // Declare a variable to hold the timeout ID - - // Add event listener to the whole document - document.addEventListener('keydown', function (e) { - // Check on the storage for pause_while_typing_on_youtube_storage is false - - // If player is NOT in the viewport, return - if (!isPlayerInViewport()) { - return; - } - - var player = ImprovedTube.elements.player; - - if (player) { - if ( - (/^[a-z0-9]$/i.test(e.key) || e.key === "Backspace") && - !(e.ctrlKey && (e.key === "c" || e.key === "x" || e.key === "a")) && - ( document.activeElement.tagName === "INPUT" || document.activeElement.tagName === "TEXTAREA" || document.activeElement.tagName === "DIV" )) { - // Pause the video - // Check if player is paused - if (!player.paused) { - player.pauseVideo(); - } - - // Clear any existing timeout - if (timeoutId) { - clearTimeout(timeoutId); - } - - // Set a new timeout to play the video after 1 second - timeoutId = setTimeout(function () { - player.playVideo(); - }, 2000); // 2000 milliseconds = 2 seconds - } - } - }); - - function isPlayerInViewport () { - var player = ImprovedTube.elements.player; - if (player) { - var rect = player.getBoundingClientRect(); - var windowHeight = (window.innerHeight || document.documentElement.clientHeight); - var windowWidth = (window.innerWidth || document.documentElement.clientWidth); - - // Check if the player is in the viewport - return ( - rect.top != 0 && - rect.left != 0 && - rect.bottom <= windowHeight && - rect.right <= windowWidth - ); - } - return false; - } - - } + if (ImprovedTube.storage.pause_while_typing_on_youtube === true) { + var timeoutId; // Declare a variable to hold the timeout ID + + // Add event listener to the whole document + document.addEventListener("keydown", function (e) { + // Check on the storage for pause_while_typing_on_youtube_storage is false + + // If player is NOT in the viewport, return + if (!isPlayerInViewport()) { + return; + } + + var player = ImprovedTube.elements.player; + + if (player) { + if ( + (/^[a-z0-9]$/i.test(e.key) || e.key === "Backspace") && + !(e.ctrlKey && (e.key === "c" || e.key === "x" || e.key === "a")) && + (document.activeElement.tagName === "INPUT" || + document.activeElement.tagName === "TEXTAREA" || + document.activeElement.tagName === "DIV") + ) { + // Pause the video + // Check if player is paused + if (!player.paused) { + player.pauseVideo(); + } + + // Clear any existing timeout + if (timeoutId) { + clearTimeout(timeoutId); + } + + // Set a new timeout to play the video after 1 second + timeoutId = setTimeout(function () { + player.playVideo(); + }, 2000); // 2000 milliseconds = 2 seconds + } + } + }); + + function isPlayerInViewport() { + var player = ImprovedTube.elements.player; + if (player) { + var rect = player.getBoundingClientRect(); + var windowHeight = + window.innerHeight || document.documentElement.clientHeight; + var windowWidth = + window.innerWidth || document.documentElement.clientWidth; + + // Check if the player is in the viewport + return ( + rect.top != 0 && + rect.left != 0 && + rect.bottom <= windowHeight && + rect.right <= windowWidth + ); + } + return false; + } + } }; /*------------------------------------------------------------------------------ HIDE PROGRESS BAR PREVIEW ------------------------------------------------------------------------------*/ ImprovedTube.playerHideProgressPreview = function () { - if (this.storage.player_hide_progress_preview === true) { - document.documentElement.setAttribute('it-hide-progress-preview', 'true'); - } else { - document.documentElement.removeAttribute('it-hide-progress-preview'); - } + if (this.storage.player_hide_progress_preview === true) { + document.documentElement.setAttribute("it-hide-progress-preview", "true"); + } else { + document.documentElement.removeAttribute("it-hide-progress-preview"); + } +}; +ImprovedTube.playerRewindAndForwardButtons = function () { + if (this.storage.player_rewind_and_forward_buttons === true) { + const svgNamespace = "http://www.w3.org/2000/svg"; + const svgBackward = document.createElementNS(svgNamespace, "svg"); + const path1 = document.createElementNS(svgNamespace, "path"); + const path2 = document.createElementNS(svgNamespace, "path"); + svgBackward.setAttribute("t", "1742599438764"); + svgBackward.setAttribute("class", "icon"); + svgBackward.setAttribute("viewBox", "0 0 1024 1024"); + svgBackward.setAttribute("version", "1.1"); + svgBackward.setAttribute("xmlns", svgNamespace); + svgBackward.setAttribute("p-id", "1636"); + svgBackward.setAttribute("width", "50%"); + svgBackward.setAttribute("height", "50%"); + svgBackward.style.display = "block"; + svgBackward.style.margin = "0 auto"; + path1.setAttribute( + "d", + "M508.50205 146.714035c221.770057 0.399766 401.364825 180.194417 401.364825 402.064415 0 222.069881-179.994534 402.064415-402.064416 402.064416-222.069881 0-402.064415-179.994534-402.064415-402.064416-0.099941-80.852625 24.185829-159.806363 69.759126-226.467304 11.393324-16.690221 7.095842-39.376928-9.594379-50.770252-16.690221-11.393324-39.376928-7.095842-50.770251 9.594378-53.468671 78.254148-82.55163 170.899863-82.55163 267.74312 0 262.446223 212.675386 475.121608 475.121608 475.121608 262.446223 0 475.121608-212.675386 475.121608-475.121608 0-262.146399-212.375561-474.821784-474.521959-475.121609V22.386883c0-8.095257-4.497365-15.490923-11.593207-19.288698-7.095842-3.797775-15.790748-3.398009-22.486825 1.099356L316.514542 109.335936c-6.096428 4.097599-9.794261 10.893617-9.794261 18.289284 0 7.295725 3.697833 14.191685 9.794261 18.289283l157.807535 105.238337c6.696077 4.497365 15.390982 4.897131 22.486824 1.099356 7.095842-3.797775 11.593207-11.293383 11.593207-19.288698v-86.249463h0.099942zM497.008784 700.989264" + ); + path1.setAttribute("fill", "#ffffff"); + path2.setAttribute( + "d", + "M638.026157 359.889127v59.964865H439.442514l-11.693148 114.133125h1.699004c12.792504-12.792504 27.383955-22.087058 44.274058-27.983603 15.091158-5.796604 31.981261-8.694905 50.670311-8.694906 38.977162 0 71.058364 12.792504 95.444075 38.477455 24.485653 25.585009 37.278157 61.164162 37.278158 105.937927 0 43.074761-16.290455 78.054265-48.871365 105.338278-30.282256 24.485653-65.761468 36.678509-107.137224 36.678509-37.877806 0-70.458716-10.493851-97.243022-30.881905-30.282256-22.686707-46.572711-53.568612-49.471013-91.946126h66.960765c2.898302 22.686707 11.693149 39.57681 26.784306 50.670311 12.792504 9.294554 30.881905 14.59145 53.568613 14.59145 24.485653 0 45.373414-7.595549 62.263517-22.686707 16.290455-15.091158 25.085302-35.479211 25.085302-61.164162 0-27.983603-7.595549-50.070662-21.587351-65.761467-13.991802-16.290455-34.979504-23.886004-61.763811-23.886005-18.089401 0-33.780207 2.898302-46.572711 9.294554-14.59145 6.995901-25.585009 17.489752-33.780207 31.981261h-63.462815l22.686707-234.062854h253.451494z" + ); + path2.setAttribute("fill", "#ffffff"); + svgBackward.appendChild(path1); + svgBackward.appendChild(path2); + const svgForward = document.createElementNS(svgNamespace, "svg"); + const path3 = document.createElementNS(svgNamespace, "path"); + const path4 = document.createElementNS(svgNamespace, "path"); + svgForward.setAttribute("t", "1742599438764"); + svgForward.setAttribute("class", "icon"); + svgForward.setAttribute("viewBox", "0 0 1024 1024"); + svgForward.setAttribute("version", "1.1"); + svgForward.setAttribute("xmlns", svgNamespace); + svgForward.setAttribute("p-id", "1636"); + svgForward.setAttribute("width", "50%"); + svgForward.setAttribute("height", "50%"); + svgForward.style.display = "block"; + svgForward.style.margin = "0 auto"; + path3.setAttribute( + "d", + "M507.101913 146.742679V232.90902c0 8.096837 4.498243 15.493948 11.595471 19.292464 7.097228 3.798516 15.793831 3.398672 22.491214-1.099571l157.838345-105.258883c6.097618-4.098399 9.796173-10.895744 9.796173-18.292854 0-7.29715-3.698555-14.194455-9.796173-18.292855L541.288559 4.19836c-6.697384-4.498243-15.393987-4.898087-22.491214-1.09957-7.097228 3.798516-11.595471 11.195627-11.595471 19.292463v51.180008C245.004295 73.971105 32.587271 286.588052 32.587271 548.785631c0 262.497462 212.716907 475.214369 475.214369 475.214369 262.497462 0 475.214369-212.716907 475.214369-475.214369 0-96.862163-29.088637-189.426005-82.567747-267.795393-11.395549-16.693479-34.186646-20.9918-50.780164-9.596251-16.693479 11.395549-20.9918 34.186646-9.596251 50.780164 45.582194 66.673955 69.972667 145.743069 69.772745 226.511519 0 222.113237-180.029676 402.142913-402.142913 402.142913-222.113237 0-402.142913-180.029676-402.142913-402.142913 0.099961-221.713393 179.829754-401.643108 401.543147-401.942991z m11.595471 554.383444" + ); + path3.setAttribute("fill", "#ffffff"); + path4.setAttribute( + "d", + "M638.050761 359.959391v59.976572H439.428348l-11.695431 114.155408h1.699336c12.795002-12.795002 27.389301-22.091371 44.282702-27.989067 15.094104-5.797735 31.987505-8.696603 50.680203-8.696603 38.984772 0 71.072237 12.795002 95.46271 38.484967 24.490433 25.590004 37.285435 61.176103 37.285435 105.95861 0 43.083171-16.293635 78.069504-48.880905 105.358844-30.288169 24.490433-65.774307 36.68567-107.158142 36.685669-37.885201 0-70.472472-10.4959-97.262007-30.887934-30.288169-22.691136-46.581804-53.579071-49.480671-91.964076h66.973838c2.898868 22.691136 11.695431 39.584537 26.789535 50.680203 12.795002 9.296369 30.887934 14.594299 53.579071 14.594299 24.490433 0 45.382273-7.597032 62.275673-22.691137 16.293635-15.094104 25.090199-35.486138 25.0902-61.176103 0-27.989067-7.597032-50.080437-21.591566-65.774307-13.994533-16.293635-34.986333-23.890668-61.775869-23.890667-18.092932 0-33.786802 2.898868-46.581804 9.296368-14.594299 6.997267-25.590004 17.493167-33.786802 31.987505h-63.475205l22.691136-234.108551h253.500976z" + ); + path4.setAttribute("fill", "#ffffff"); + svgForward.appendChild(path3); + svgForward.appendChild(path4); + + this.createPlayerButton({ + id: "it-forward-player-button", + opacity: 0.85, + position: "right", + child: svgForward, + + onclick: function () { + ImprovedTube.elements.player.seekTo( + ImprovedTube.elements.player.getCurrentTime() + 5 + ); + }, + title: "forward 5 seconds", + }).classList.remove("it-player-button"); + this.createPlayerButton({ + id: "it-rewind-player-button", + opacity: 0.85, + position: "right", + child: svgBackward, + + onclick: function () { + ImprovedTube.elements.player.seekTo( + ImprovedTube.elements.player.getCurrentTime() - 5 + ); + }, + title: "rewind 5 seconds", + }).classList.remove("it-player-button"); + } }; -ImprovedTube.playerRewindAndForwardButtons = function(){ - if(this.storage.player_rewind_and_forward_buttons===true){ - const svgNamespace = "http://www.w3.org/2000/svg"; - const svgBackward = document.createElementNS(svgNamespace, "svg"); - const path1 = document.createElementNS(svgNamespace, "path"); - const path2 = document.createElementNS(svgNamespace, "path"); - svgBackward.setAttribute("t", "1742599438764"); - svgBackward.setAttribute("class", "icon"); - svgBackward.setAttribute("viewBox", "0 0 1024 1024"); - svgBackward.setAttribute("version", "1.1"); - svgBackward.setAttribute("xmlns", svgNamespace); - svgBackward.setAttribute("p-id", "1636"); - svgBackward.setAttribute("width", "50%"); - svgBackward.setAttribute("height", "50%"); - svgBackward.style.display = "block"; - svgBackward.style.margin = "0 auto"; - path1.setAttribute("d", "M508.50205 146.714035c221.770057 0.399766 401.364825 180.194417 401.364825 402.064415 0 222.069881-179.994534 402.064415-402.064416 402.064416-222.069881 0-402.064415-179.994534-402.064415-402.064416-0.099941-80.852625 24.185829-159.806363 69.759126-226.467304 11.393324-16.690221 7.095842-39.376928-9.594379-50.770252-16.690221-11.393324-39.376928-7.095842-50.770251 9.594378-53.468671 78.254148-82.55163 170.899863-82.55163 267.74312 0 262.446223 212.675386 475.121608 475.121608 475.121608 262.446223 0 475.121608-212.675386 475.121608-475.121608 0-262.146399-212.375561-474.821784-474.521959-475.121609V22.386883c0-8.095257-4.497365-15.490923-11.593207-19.288698-7.095842-3.797775-15.790748-3.398009-22.486825 1.099356L316.514542 109.335936c-6.096428 4.097599-9.794261 10.893617-9.794261 18.289284 0 7.295725 3.697833 14.191685 9.794261 18.289283l157.807535 105.238337c6.696077 4.497365 15.390982 4.897131 22.486824 1.099356 7.095842-3.797775 11.593207-11.293383 11.593207-19.288698v-86.249463h0.099942zM497.008784 700.989264"); - path1.setAttribute("fill", "#ffffff"); - path2.setAttribute("d", "M638.026157 359.889127v59.964865H439.442514l-11.693148 114.133125h1.699004c12.792504-12.792504 27.383955-22.087058 44.274058-27.983603 15.091158-5.796604 31.981261-8.694905 50.670311-8.694906 38.977162 0 71.058364 12.792504 95.444075 38.477455 24.485653 25.585009 37.278157 61.164162 37.278158 105.937927 0 43.074761-16.290455 78.054265-48.871365 105.338278-30.282256 24.485653-65.761468 36.678509-107.137224 36.678509-37.877806 0-70.458716-10.493851-97.243022-30.881905-30.282256-22.686707-46.572711-53.568612-49.471013-91.946126h66.960765c2.898302 22.686707 11.693149 39.57681 26.784306 50.670311 12.792504 9.294554 30.881905 14.59145 53.568613 14.59145 24.485653 0 45.373414-7.595549 62.263517-22.686707 16.290455-15.091158 25.085302-35.479211 25.085302-61.164162 0-27.983603-7.595549-50.070662-21.587351-65.761467-13.991802-16.290455-34.979504-23.886004-61.763811-23.886005-18.089401 0-33.780207 2.898302-46.572711 9.294554-14.59145 6.995901-25.585009 17.489752-33.780207 31.981261h-63.462815l22.686707-234.062854h253.451494z"); - path2.setAttribute("fill", "#ffffff"); - svgBackward.appendChild(path1); - svgBackward.appendChild(path2); - const svgForward = document.createElementNS(svgNamespace, "svg"); - const path3 = document.createElementNS(svgNamespace, "path"); - const path4 = document.createElementNS(svgNamespace, "path"); - svgForward.setAttribute("t", "1742599438764"); - svgForward.setAttribute("class", "icon"); - svgForward.setAttribute("viewBox", "0 0 1024 1024"); - svgForward.setAttribute("version", "1.1"); - svgForward.setAttribute("xmlns", svgNamespace); - svgForward.setAttribute("p-id", "1636"); - svgForward.setAttribute("width", "50%"); - svgForward.setAttribute("height", "50%"); - svgForward.style.display = "block"; - svgForward.style.margin = "0 auto"; - path3.setAttribute("d", "M507.101913 146.742679V232.90902c0 8.096837 4.498243 15.493948 11.595471 19.292464 7.097228 3.798516 15.793831 3.398672 22.491214-1.099571l157.838345-105.258883c6.097618-4.098399 9.796173-10.895744 9.796173-18.292854 0-7.29715-3.698555-14.194455-9.796173-18.292855L541.288559 4.19836c-6.697384-4.498243-15.393987-4.898087-22.491214-1.09957-7.097228 3.798516-11.595471 11.195627-11.595471 19.292463v51.180008C245.004295 73.971105 32.587271 286.588052 32.587271 548.785631c0 262.497462 212.716907 475.214369 475.214369 475.214369 262.497462 0 475.214369-212.716907 475.214369-475.214369 0-96.862163-29.088637-189.426005-82.567747-267.795393-11.395549-16.693479-34.186646-20.9918-50.780164-9.596251-16.693479 11.395549-20.9918 34.186646-9.596251 50.780164 45.582194 66.673955 69.972667 145.743069 69.772745 226.511519 0 222.113237-180.029676 402.142913-402.142913 402.142913-222.113237 0-402.142913-180.029676-402.142913-402.142913 0.099961-221.713393 179.829754-401.643108 401.543147-401.942991z m11.595471 554.383444"); - path3.setAttribute("fill", "#ffffff"); - path4.setAttribute("d", "M638.050761 359.959391v59.976572H439.428348l-11.695431 114.155408h1.699336c12.795002-12.795002 27.389301-22.091371 44.282702-27.989067 15.094104-5.797735 31.987505-8.696603 50.680203-8.696603 38.984772 0 71.072237 12.795002 95.46271 38.484967 24.490433 25.590004 37.285435 61.176103 37.285435 105.95861 0 43.083171-16.293635 78.069504-48.880905 105.358844-30.288169 24.490433-65.774307 36.68567-107.158142 36.685669-37.885201 0-70.472472-10.4959-97.262007-30.887934-30.288169-22.691136-46.581804-53.579071-49.480671-91.964076h66.973838c2.898868 22.691136 11.695431 39.584537 26.789535 50.680203 12.795002 9.296369 30.887934 14.594299 53.579071 14.594299 24.490433 0 45.382273-7.597032 62.275673-22.691137 16.293635-15.094104 25.090199-35.486138 25.0902-61.176103 0-27.989067-7.597032-50.080437-21.591566-65.774307-13.994533-16.293635-34.986333-23.890668-61.775869-23.890667-18.092932 0-33.786802 2.898868-46.581804 9.296368-14.594299 6.997267-25.590004 17.493167-33.786802 31.987505h-63.475205l22.691136-234.108551h253.500976z"); - path4.setAttribute("fill", "#ffffff"); - svgForward.appendChild(path3); - svgForward.appendChild(path4); - - - this.createPlayerButton({ - id: 'it-forward-player-button', - opacity: 0.85, - position: "right", - child: svgForward, - - onclick: function () { - ImprovedTube.elements.player.seekTo(ImprovedTube.elements.player.getCurrentTime() + 5); - }, - title: 'forward 5 seconds', - }).classList.remove('it-player-button'); - this.createPlayerButton({ - id: 'it-rewind-player-button', - opacity: 0.85, - position: "right", - child: svgBackward, - - onclick: function () { - ImprovedTube.elements.player.seekTo(ImprovedTube.elements.player.getCurrentTime() - 5); - }, - title: 'rewind 5 seconds', - }).classList.remove('it-player-button'); - - - - } - } /*------------------------------------------------------------------------------ # DISABLE AUTO DUBBING ------------------------------------------------------------------------------*/ ImprovedTube.disableAutoDubbing = function () { - const player = this.elements.player; - const tracks = player.getAvailableAudioTracks(); - const originalTrack = findOriginalAudioTrack(tracks); - - if (originalTrack) { - player.setAudioTrack(originalTrack); - } - - function findOriginalAudioTrack(audioTracks) { - // Score tracks based on likely original source - for (const track of audioTracks) { - if (hasOriginalKeyword(track)) { - return track; - } - } - - for (const track of audioTracks) { - if (hasASR(track)) { - return track; - } - } - - function hasASR(track) { - return Array.isArray(track.captionTracks) && - track.captionTracks.some(ct => ct.kind === 'asr'); - } - - function hasOriginalKeyword(track) { - var name = track?.HB?.name?.toLowerCase() || ''; - const localizedOriginalWords = ['original', 'originale', 'originalny', 'originalaudio', 'origineel', 'orijinal']; // Add more if needed - if (name === '') { - // Try to get the localized name from other variable - name = track?.Af.name?.toLowerCase() || ''; - } - - return localizedOriginalWords.some(word => name.includes(word)); - } - - // As a fallback: default or first item - const fallback = audioTracks.find(t => t?.HB?.isDefault) || audioTracks[0]; - console.log(fallback); - return fallback; - } -} + const player = this.elements.player; + const tracks = player.getAvailableAudioTracks(); + const originalTrack = findOriginalAudioTrack(tracks); + + if (originalTrack) { + player.setAudioTrack(originalTrack); + } + + function findOriginalAudioTrack(audioTracks) { + // Score tracks based on likely original source + for (const track of audioTracks) { + if (hasOriginalKeyword(track)) { + return track; + } + } + + for (const track of audioTracks) { + if (hasASR(track)) { + return track; + } + } + + function hasASR(track) { + return ( + Array.isArray(track.captionTracks) && + track.captionTracks.some((ct) => ct.kind === "asr") + ); + } + + function hasOriginalKeyword(track) { + var name = track?.HB?.name?.toLowerCase() || ""; + const localizedOriginalWords = [ + "original", + "originale", + "originalny", + "originalaudio", + "origineel", + "orijinal", + ]; // Add more if needed + if (name === "") { + // Try to get the localized name from other variable + name = track?.Af.name?.toLowerCase() || ""; + } + + return localizedOriginalWords.some((word) => name.includes(word)); + } + + // As a fallback: default or first item + const fallback = + audioTracks.find((t) => t?.HB?.isDefault) || audioTracks[0]; + console.log(fallback); + return fallback; + } +}; /*------------------------------------------------------------------------------ # JUMP TO THE NEXT KEY SCENE ------------------------------------------------------------------------------*/ ImprovedTube.jumpToKeyScene = function () { - ImprovedTube.mostReplayed = function () { - const player = document.querySelector('video'); - - const data = extractYtInitialData(); - if (!data) - return console.warn("Failed to extract ytInitialData."); - - const markers = getMostReplayedMarkers(data); - if (!markers.length) - return console.warn("No 'Most Replayed' markers found."); - - const currentMillis = player.currentTime * 1000; - const sortedMarkers = markers.slice().sort((a, b) => a.decorationTimeMillis - b.decorationTimeMillis); - const nextMarker = sortedMarkers.find(m => m.decorationTimeMillis > currentMillis) || sortedMarkers[0]; // fallback to first if none ahead - const targetSeconds = nextMarker.decorationTimeMillis / 1000; - - player.currentTime = targetSeconds; - player.play(); - console.log(`Jumped to Most Replayed @ ${Math.floor(targetSeconds / 60)}:${Math.floor(targetSeconds % 60).toString().padStart(2, "0")}`); - - function extractYtInitialData() { - const scriptTags = document.querySelectorAll('script'); - - for (let i = 0; i < scriptTags.length; i++) { - if (DATA.ytInitialData) { var ytIData = DATA.ytInitialData; } - else { - const scriptContent = scriptTags[i].textContent; - var ytIData = scriptContent.match(/var ytInitialData = ({.*?});/s); - } - - if (ytIData) { - try { - return JSON.parse(ytIData[1]); - } catch (e) { - console.warn("Failed to parse ytInitialData JSON", e); - return null; - } - } - } - - return null; - } - - function getMostReplayedMarkers(parsedJson) { - const decorations = parsedJson?.['frameworkUpdates']?.['entityBatchUpdate']?.['mutations']?.[0] - ?.['payload']?.['macroMarkersListEntity']?.['markersList']?.['markersDecoration']?.['timedMarkerDecorations']; - return decorations; - } - } - - DATA = {}; - ImprovedTube.fetchDOMData2 = function () { - try { DATA = JSON.parse(document.querySelector('#microformat script')?.textContent) ?? false; DATA.title = DATA.name;} - catch { DATA.genre = false; DATA.keywords = false; DATA.lengthSeconds = false; - try { - DATA.title = document.getElementsByTagName('meta')?.title?.content || false; - DATA.genre = document.querySelector('meta[itemprop=genre]')?.content || false; - DATA.duration = document.querySelector('meta[itemprop=duration]')?.content || false; - } catch {}} - -let tries = 0; const maxTries = 3; let intervalMs = 25; -const waitForVideoTitle = setInterval(() => { const title = ImprovedTube.videoTitle?.(); tries++; -if (title && title !== 'YouTube') { - clearInterval(waitForVideoTitle); - DATA.videoID = ImprovedTube.videoId() || false; - console.log("MOST REPLAYED: TITLE:" + ImprovedTube.videoTitle() + DATA.title); - if ( (DATA.title === ImprovedTube.videoTitle() || DATA.title.replace(/\s{2,}/g, ' ') === ImprovedTube.videoTitle()) - && ((history && history.length === 1) || !history?.state?.endpoint?.watchEndpoint)) - { ImprovedTube.mostReplayed(); } - else { keywords = ''; (async function () { try { const response = await fetch(`https://www.youtube.com/watch?v=${DATA.videoID}`); - console.log("loading the html source:" + `https://www.youtube.com/watch?v=${DATA.videoID}`); - const htmlContent = await response.text(); - DATA.ytInitialData = htmlContent.match(/var ytInitialData = ({.*?});/s); - if (DATA.ytInitialData) { ImprovedTube.mostReplayed(); } - } catch (error) { -const o = Object.assign(document.createElement('div'), { innerText: 'too few views' }); -const keySceneButton = document.querySelector('button[data-tooltip="Key Scene"]'); - if (keySceneButton) { keySceneButton.style.transition = 'opacity 0.4s'; keySceneButton.style.opacity = '0.3'; - setTimeout(() => { keySceneButton.style.opacity = '0.8'; }, 5000);} - console.error(`Error: fetching from https://Youtube.com/watch?v=${DATA.videoID}`, error); } - })(); - } -} - -if (tries >= maxTries) { clearInterval(waitForVideoTitle); } intervalMs *= 1.11; }, intervalMs); -window.addEventListener('load', () => { setTimeout(() => { clearInterval(waitForVideoTitle) }, 5000);}); - }; - ImprovedTube.fetchDOMData2(); - - - - -} + ImprovedTube.mostReplayed = function () { + const player = document.querySelector("video"); + + const data = extractYtInitialData(); + if (!data) return console.warn("Failed to extract ytInitialData."); + + const markers = getMostReplayedMarkers(data); + if (!markers.length) + return console.warn("No 'Most Replayed' markers found."); + + const currentMillis = player.currentTime * 1000; + const sortedMarkers = markers + .slice() + .sort((a, b) => a.decorationTimeMillis - b.decorationTimeMillis); + const nextMarker = + sortedMarkers.find((m) => m.decorationTimeMillis > currentMillis) || + sortedMarkers[0]; // fallback to first if none ahead + const targetSeconds = nextMarker.decorationTimeMillis / 1000; + + player.currentTime = targetSeconds; + player.play(); + console.log( + `Jumped to Most Replayed @ ${Math.floor(targetSeconds / 60)}:${Math.floor( + targetSeconds % 60 + ) + .toString() + .padStart(2, "0")}` + ); + + function extractYtInitialData() { + const scriptTags = document.querySelectorAll("script"); + + for (let i = 0; i < scriptTags.length; i++) { + if (DATA.ytInitialData) { + var ytIData = DATA.ytInitialData; + } else { + const scriptContent = scriptTags[i].textContent; + var ytIData = scriptContent.match(/var ytInitialData = ({.*?});/s); + } + + if (ytIData) { + try { + return JSON.parse(ytIData[1]); + } catch (e) { + console.warn("Failed to parse ytInitialData JSON", e); + return null; + } + } + } + + return null; + } + + function getMostReplayedMarkers(parsedJson) { + const decorations = + parsedJson?.["frameworkUpdates"]?.["entityBatchUpdate"]?.[ + "mutations" + ]?.[0]?.["payload"]?.["macroMarkersListEntity"]?.["markersList"]?.[ + "markersDecoration" + ]?.["timedMarkerDecorations"]; + return decorations; + } + }; + + DATA = {}; + ImprovedTube.fetchDOMData2 = function () { + try { + DATA = + JSON.parse( + document.querySelector("#microformat script")?.textContent + ) ?? false; + DATA.title = DATA.name; + } catch { + DATA.genre = false; + DATA.keywords = false; + DATA.lengthSeconds = false; + try { + DATA.title = + document.getElementsByTagName("meta")?.title?.content || false; + DATA.genre = + document.querySelector("meta[itemprop=genre]")?.content || false; + DATA.duration = + document.querySelector("meta[itemprop=duration]")?.content || false; + } catch {} + } + + let tries = 0; + const maxTries = 3; + let intervalMs = 25; + const waitForVideoTitle = setInterval(() => { + const title = ImprovedTube.videoTitle?.(); + tries++; + if (title && title !== "YouTube") { + clearInterval(waitForVideoTitle); + DATA.videoID = ImprovedTube.videoId() || false; + console.log( + "MOST REPLAYED: TITLE:" + ImprovedTube.videoTitle() + DATA.title + ); + if ( + (DATA.title === ImprovedTube.videoTitle() || + DATA.title.replace(/\s{2,}/g, " ") === ImprovedTube.videoTitle()) && + ((history && history.length === 1) || + !history?.state?.endpoint?.watchEndpoint) + ) { + ImprovedTube.mostReplayed(); + } else { + keywords = ""; + (async function () { + try { + const response = await fetch( + `https://www.youtube.com/watch?v=${DATA.videoID}` + ); + console.log( + "loading the html source:" + + `https://www.youtube.com/watch?v=${DATA.videoID}` + ); + const htmlContent = await response.text(); + DATA.ytInitialData = htmlContent.match( + /var ytInitialData = ({.*?});/s + ); + if (DATA.ytInitialData) { + ImprovedTube.mostReplayed(); + } + } catch (error) { + const o = Object.assign(document.createElement("div"), { + innerText: "too few views", + }); + const keySceneButton = document.querySelector( + 'button[data-tooltip="Key Scene"]' + ); + if (keySceneButton) { + keySceneButton.style.transition = "opacity 0.4s"; + keySceneButton.style.opacity = "0.3"; + setTimeout(() => { + keySceneButton.style.opacity = "0.8"; + }, 5000); + } + console.error( + `Error: fetching from https://Youtube.com/watch?v=${DATA.videoID}`, + error + ); + } + })(); + } + } + + if (tries >= maxTries) { + clearInterval(waitForVideoTitle); + } + intervalMs *= 1.11; + }, intervalMs); + window.addEventListener("load", () => { + setTimeout(() => { + clearInterval(waitForVideoTitle); + }, 5000); + }); + }; + ImprovedTube.fetchDOMData2(); +}; diff --git a/menu/skeleton-parts/general.js b/menu/skeleton-parts/general.js index 0dbb2e444..199faea87 100644 --- a/menu/skeleton-parts/general.js +++ b/menu/skeleton-parts/general.js @@ -3,502 +3,822 @@ --------------------------------------------------------------*/ extension.skeleton.main.layers.section.general = { - component: 'button', - variant: 'general', - category: true, - on: { - click: { - section_1: { - component: 'section', - variant: 'card', - improvedtube_youtube_icon: { - text: 'improvedtubeIconOnYoutube', - component: 'select', - options: [{ - text: 'disabled', - value: 'disabled' - }, { - text: 'draggable', - value: 'draggable' - }, { - text: 'youtubeHeaderLeft', - value: 'header_left' - }, { - text: 'youtubeHeaderRight', - value: 'header_right' - }, { - text: 'sidebar', - value: 'sidebar' - }, { - text: 'belowPlayer', - value: 'below_player' - }] - }, - /* improvedTubeSidePanel: { + component: "button", + variant: "general", + category: true, + on: { + click: { + section_1: { + component: "section", + variant: "card", + improvedtube_youtube_icon: { + text: "improvedtubeIconOnYoutube", + component: "select", + options: [ + { + text: "disabled", + value: "disabled", + }, + { + text: "draggable", + value: "draggable", + }, + { + text: "youtubeHeaderLeft", + value: "header_left", + }, + { + text: "youtubeHeaderRight", + value: "header_right", + }, + { + text: "sidebar", + value: "sidebar", + }, + { + text: "belowPlayer", + value: "below_player", + }, + ], + }, + /* improvedTubeSidePanel: { component: 'switch', text: 'improvedTubeSidePanel' }, - */ default_content_country: { - component: 'select', - text: 'defaultContentCountry', - options:[{text:"default", value:"default"}, {text:"Afghanistan", value:"AF"}, {text:"Albania", value:"AL"}, {text:"Algeria", value:"DZ"}, {text:"AmericanSamoa", value:"AS"}, {text:"Andorra", value:"AD"}, {text:"Angola", value:"AO"}, {text:"Anguilla", value:"AI"}, {text:"Antarctica", value:"AQ"}, {text:"AntiguaandBarbuda", value:"AG"}, {text:"Argentina", value:"AR"}, {text:"Armenia", value:"AM"}, {text:"Aruba", value:"AW"}, {text:"Australia", value:"AU"}, {text:"Austria", value:"AT"}, {text:"Azerbaijan", value:"AZ"}, {text:"Bahrain", value:"BH"}, {text:"BailiwickofGuernsey", value:"GG"}, {text:"Bangladesh", value:"BD"}, {text:"Barbados", value:"BB"}, {text:"Belarus", value:"BY"}, {text:"Belgium", value:"BE"}, {text:"Belize", value:"BZ"}, {text:"Benin", value:"BJ"}, {text:"Bermuda", value:"BM"}, {text:"Bhutan", value:"BT"}, {text:"Bolivia", value:"BO"}, {text:"Bonaire", value:"BQ"}, {text:"BosniaandHerzegovina", value:"BA"}, {text:"Botswana", value:"BW"}, {text:"BouvetIsland", value:"BV"}, {text:"Brazil", value:"BR"}, {text:"BritishIndianOceanTerritory", value:"IO"}, {text:"BritishVirginIslands", value:"VG"}, {text:"Brunei", value:"BN"}, {text:"Bulgaria", value:"BG"}, {text:"BurkinaFaso", value:"BF"}, {text:"Burundi", value:"BI"}, {text:"Cambodia", value:"KH"}, {text:"Cameroon", value:"CM"}, {text:"Canada", value:"CA"}, {text:"CapeVerde", value:"CV"}, {text:"CaymanIslands", value:"KY"}, {text:"CentralAfricanRepublic", value:"CF"}, {text:"Chad", value:"TD"}, {text:"Chile", value:"CL"}, {text:"China", value:"CN"}, {text:"ChristmasIsland", value:"CX"}, {text:"Cocos(Keeling)Islands", value:"CC"}, {text:"CollectivityofSaintMartin", value:"MF"}, {text:"Colombia", value:"CO"}, {text:"Comoros", value:"KM"}, {text:"CookIslands", value:"CK"}, {text:"CostaRica", value:"CR"}, {text:"Croatia", value:"HR"}, {text:"Cuba", value:"CU"}, {text:"Curaçao", value:"CW"}, {text:"Cyprus", value:"CY"}, {text:"CzechRepublic", value:"CZ"}, {text:"DemocraticRepublicoftheCongo", value:"CD"}, {text:"Denmark", value:"DK"}, {text:"Djibouti", value:"DJ"}, {text:"Dominica", value:"DM"}, {text:"DominicanRepublic", value:"DO"}, {text:"EastTimor", value:"TL"}, {text:"Ecuador", value:"EC"}, {text:"Egypt", value:"EG"}, {text:"ElSalvador", value:"SV"}, {text:"EquatorialGuinea", value:"GQ"}, {text:"Eritrea", value:"ER"}, {text:"Estonia", value:"EE"}, {text:"Eswatini", value:"SZ"}, {text:"Ethiopia", value:"ET"}, {text:"FalklandIslands", value:"FK"}, {text:"FaroeIslands", value:"FO"}, {text:"FederatedStatesofMicronesia", value:"FM"}, {text:"Fiji", value:"FJ"}, {text:"Finland", value:"FI"}, {text:"France", value:"FR"}, {text:"FrenchGuiana", value:"GF"}, {text:"FrenchPolynesia", value:"PF"}, {text:"FrenchSouthernandAntarcticLands", value:"TF"}, {text:"Gabon", value:"GA"}, {text:"Georgia(country)", value:"GE"}, {text:"Germany", value:"DE"}, {text:"Ghana", value:"GH"}, {text:"Gibraltar", value:"GI"}, {text:"Greece", value:"GR"}, {text:"Greenland", value:"GL"}, {text:"Grenada", value:"GD"}, {text:"Guadeloupe", value:"GP"}, {text:"Guam", value:"GU"}, {text:"Guatemala", value:"GT"}, {text:"Guinea", value:"GN"}, {text:"Guinea-Bissau", value:"GW"}, {text:"Guyana", value:"GY"}, {text:"Haiti", value:"HT"}, {text:"HeardIslandandMcDonaldIslands", value:"HM"}, {text:"HolySee", value:"VA"}, {text:"Honduras", value:"HN"}, {text:"HongKong", value:"HK"}, {text:"Hungary", value:"HU"}, {text:"Iceland", value:"IS"}, {text:"India", value:"IN"}, {text:"Indonesia", value:"ID"}, {text:"Iran", value:"IR"}, {text:"Iraq", value:"IQ"}, {text:"IsleofMan", value:"IM"}, {text:"Israel", value:"IL"}, {text:"Italy", value:"IT"}, {text:"IvoryCoast", value:"CI"}, {text:"Jamaica", value:"JM"}, {text:"Japan", value:"JP"}, {text:"Jersey", value:"JE"}, {text:"Jordan", value:"JO"}, {text:"Kazakhstan", value:"KZ"}, {text:"Kenya", value:"KE"}, {text:"Kiribati", value:"KI"}, {text:"Kuwait", value:"KW"}, {text:"Kyrgyzstan", value:"KG"}, {text:"Laos", value:"LA"}, {text:"Latvia", value:"LV"}, {text:"Lebanon", value:"LB"}, {text:"Lesotho", value:"LS"}, {text:"Liberia", value:"LR"}, {text:"Libya", value:"LY"}, {text:"Liechtenstein", value:"LI"}, {text:"Lithuania", value:"LT"}, {text:"Luxembourg", value:"LU"}, {text:"Macau", value:"MO"}, {text:"Madagascar", value:"MG"}, {text:"Malawi", value:"MW"}, {text:"Malaysia", value:"MY"}, {text:"Maldives", value:"MV"}, {text:"Mali", value:"ML"}, {text:"Malta", value:"MT"}, {text:"MarshallIslands", value:"MH"}, {text:"Martinique", value:"MQ"}, {text:"Mauritania", value:"MR"}, {text:"Mauritius", value:"MU"}, {text:"Mayotte", value:"YT"}, {text:"Mexico", value:"MX"}, {text:"Moldova", value:"MD"}, {text:"Monaco", value:"MC"}, {text:"Mongolia", value:"MN"}, {text:"Montenegro", value:"ME"}, {text:"Montserrat", value:"MS"}, {text:"Morocco", value:"MA"}, {text:"Mozambique", value:"MZ"}, {text:"Myanmar", value:"MM"}, {text:"Namibia", value:"NA"}, {text:"Nauru", value:"NR"}, {text:"Nepal", value:"NP"}, {text:"Netherlands", value:"NL"}, {text:"NewCaledonia", value:"NC"}, {text:"NewZealand", value:"NZ"}, {text:"Nicaragua", value:"NI"}, {text:"Niger", value:"NE"}, {text:"Nigeria", value:"NG"}, {text:"Niue", value:"NU"}, {text:"NorfolkIsland", value:"NF"}, {text:"NorthKorea", value:"KP"}, {text:"NorthMacedonia", value:"MK"}, {text:"NorthernMarianaIslands", value:"MP"}, {text:"Norway", value:"NO"}, {text:"Oman", value:"OM"}, {text:"Pakistan", value:"PK"}, {text:"Palau", value:"PW"}, {text:"Panama", value:"PA"}, {text:"PapuaNewGuinea", value:"PG"}, {text:"Paraguay", value:"PY"}, {text:"Peru", value:"PE"}, {text:"Philippines", value:"PH"}, {text:"PitcairnIslands", value:"PN"}, {text:"Poland", value:"PL"}, {text:"Portugal", value:"PT"}, {text:"PuertoRico", value:"PR"}, {text:"Qatar", value:"QA"}, {text:"RepublicofIreland", value:"IE"}, {text:"RepublicoftheCongo", value:"CG"}, {text:"Romania", value:"RO"}, {text:"Russia", value:"RU"}, {text:"Rwanda", value:"RW"}, {text:"Réunion", value:"RE"}, {text:"SaintBarthélemy", value:"BL"}, {text:"SaintHelena", value:"SH"}, {text:"SaintKittsandNevis", value:"KN"}, {text:"SaintLucia", value:"LC"}, {text:"SaintPierreandMiquelon", value:"PM"}, {text:"SaintVincentandtheGrenadines", value:"VC"}, {text:"Samoa", value:"WS"}, {text:"SanMarino", value:"SM"}, {text:"SaudiArabia", value:"SA"}, {text:"Senegal", value:"SN"}, {text:"Serbia", value:"RS"}, {text:"Seychelles", value:"SC"}, {text:"SierraLeone", value:"SL"}, {text:"Singapore", value:"SG"}, {text:"SintMaarten", value:"SX"}, {text:"Slovakia", value:"SK"}, {text:"Slovenia", value:"SI"}, {text:"SolomonIslands", value:"SB"}, {text:"Somalia", value:"SO"}, {text:"SouthAfrica", value:"ZA"}, {text:"SouthGeorgiaandtheSouthSandwichIslands", value:"GS"}, {text:"SouthKorea", value:"KR"}, {text:"SouthSudan", value:"SS"}, {text:"Spain", value:"ES"}, {text:"SriLanka", value:"LK"}, {text:"StateofPalestine", value:"PS"}, {text:"Sudan", value:"SD"}, {text:"Suriname", value:"SR"}, {text:"Svalbard", value:"SJ"}, {text:"Sweden", value:"SE"}, {text:"Switzerland", value:"CH"}, {text:"Syria", value:"SY"}, {text:"SãoToméandPríncipe", value:"ST"}, {text:"Taiwan", value:"TW"}, {text:"Tajikistan", value:"TJ"}, {text:"Tanzania", value:"TZ"}, {text:"Thailand", value:"TH"}, {text:"TheBahamas", value:"BS"}, {text:"TheGambia", value:"GM"}, {text:"Togo", value:"TG"}, {text:"Tokelau", value:"TK"}, {text:"Tonga", value:"TO"}, {text:"TrinidadandTobago", value:"TT"}, {text:"Tunisia", value:"TN"}, {text:"Turkey", value:"TR"}, {text:"Turkmenistan", value:"TM"}, {text:"TurksandCaicosIslands", value:"TC"}, {text:"Tuvalu", value:"TV"}, {text:"Uganda", value:"UG"}, {text:"Ukraine", value:"UA"}, {text:"UnitedArabEmirates", value:"AE"}, {text:"UnitedKingdom", value:"GB"}, {text:"UnitedStatesVirginIslands", value:"VI"}, {text:"UnitedStates", value:"UM"}, {text:"UnitedStates", value:"US"}, {text:"Uruguay", value:"UY"}, {text:"Uzbekistan", value:"UZ"}, {text:"Vanuatu", value:"VU"}, {text:"Venezuela", value:"VE"}, {text:"Vietnam", value:"VN"}, {text:"WallisandFutuna", value:"WF"}, {text:"WesternSahara", value:"EH"}, {text:"Yemen", value:"YE"}, {text:"Zambia", value:"ZM"}, {text:"Zimbabwe", value:"ZW"}, {text:"ÅlandIslands", value:"AX"}] - }, - cursorLighting: { - component: 'switch', - text: 'cursorLighting', - }, - search: { - component: 'section', - variant: 'card', - title: 'Youtube_Search', - remove_related_search_results: { - component: 'switch', - text: 'removeRelatedSearchResults' - }, - open_new_tab: { - component: "switch", - text: "openNewTab", - }, - remove_shorts_reel_search_results: { - component: 'switch', - text: 'removeShortsReelSearchResults' - } - }, - remove_home_page_shorts: { - component: 'switch', - text: 'hideHomePageShorts', - id: 'remove-home-page-shorts' - }, - remove_subscriptions_shorts: { - component: 'switch', - text: 'atSubscriptions', - id: 'remove-subscriptions-shorts' - }, - remove_trending_shorts: { - component: 'switch', - text: 'atTrending' - }, - remove_history_shorts: { - component: 'switch', - text: 'atHistory' - }, - hide_ai_summary: { - component: 'switch', - text: 'hideAISummary', - id: 'hide-ai-summary' - }, - youtube_home_page: { - component: 'select', - text: 'youtubeHomePage', - options: [{ - text: 'home', - value: '/' - }, { - text: 'trending', - value: '/feed/trending' - }, { - text: 'subscriptions', - value: '/feed/subscriptions' - }, { - text: 'history', - value: '/feed/history' - }, { - text: 'watchLater', - value: '/playlist?list=WL' - }, { - text: 'search', - value: 'search' - }, { - text: 'liked', - value: '/playlist?list=LL' - }, { - text: 'library', - value: '/feed/library' - }, { - text: 'withoutVideos', - value: 'hidecontent' - }], - tags: 'trending,subscriptions,history,watch,search,undistracted,zen' - }, - collapse_of_subscription_sections: { - component: 'switch', - text: 'collapseOfSubscriptionSections' - }, - ads: { - text: 'ads', - component: 'select', - options: [{ - text: 'onAllVideos', - value: 'all_videos', - default: 'true' - }, { - text: 'blockAll', - value: 'block_all' - }, { - text: 'onSmallCreators', - value: 'small_creators' - }, { - text: 'onSubscribedChannels', - value: 'subscribed_channels' - }, { - text: 'blockMusic', - value: 'block_music' - }], - storage: 'ads', + */ default_content_country: { + component: "select", + text: "defaultContentCountry", + options: [ + { text: "default", value: "default" }, + { text: "Afghanistan", value: "AF" }, + { text: "Albania", value: "AL" }, + { text: "Algeria", value: "DZ" }, + { text: "AmericanSamoa", value: "AS" }, + { text: "Andorra", value: "AD" }, + { text: "Angola", value: "AO" }, + { text: "Anguilla", value: "AI" }, + { text: "Antarctica", value: "AQ" }, + { text: "AntiguaandBarbuda", value: "AG" }, + { text: "Argentina", value: "AR" }, + { text: "Armenia", value: "AM" }, + { text: "Aruba", value: "AW" }, + { text: "Australia", value: "AU" }, + { text: "Austria", value: "AT" }, + { text: "Azerbaijan", value: "AZ" }, + { text: "Bahrain", value: "BH" }, + { text: "BailiwickofGuernsey", value: "GG" }, + { text: "Bangladesh", value: "BD" }, + { text: "Barbados", value: "BB" }, + { text: "Belarus", value: "BY" }, + { text: "Belgium", value: "BE" }, + { text: "Belize", value: "BZ" }, + { text: "Benin", value: "BJ" }, + { text: "Bermuda", value: "BM" }, + { text: "Bhutan", value: "BT" }, + { text: "Bolivia", value: "BO" }, + { text: "Bonaire", value: "BQ" }, + { text: "BosniaandHerzegovina", value: "BA" }, + { text: "Botswana", value: "BW" }, + { text: "BouvetIsland", value: "BV" }, + { text: "Brazil", value: "BR" }, + { text: "BritishIndianOceanTerritory", value: "IO" }, + { text: "BritishVirginIslands", value: "VG" }, + { text: "Brunei", value: "BN" }, + { text: "Bulgaria", value: "BG" }, + { text: "BurkinaFaso", value: "BF" }, + { text: "Burundi", value: "BI" }, + { text: "Cambodia", value: "KH" }, + { text: "Cameroon", value: "CM" }, + { text: "Canada", value: "CA" }, + { text: "CapeVerde", value: "CV" }, + { text: "CaymanIslands", value: "KY" }, + { text: "CentralAfricanRepublic", value: "CF" }, + { text: "Chad", value: "TD" }, + { text: "Chile", value: "CL" }, + { text: "China", value: "CN" }, + { text: "ChristmasIsland", value: "CX" }, + { text: "Cocos(Keeling)Islands", value: "CC" }, + { text: "CollectivityofSaintMartin", value: "MF" }, + { text: "Colombia", value: "CO" }, + { text: "Comoros", value: "KM" }, + { text: "CookIslands", value: "CK" }, + { text: "CostaRica", value: "CR" }, + { text: "Croatia", value: "HR" }, + { text: "Cuba", value: "CU" }, + { text: "Curaçao", value: "CW" }, + { text: "Cyprus", value: "CY" }, + { text: "CzechRepublic", value: "CZ" }, + { text: "DemocraticRepublicoftheCongo", value: "CD" }, + { text: "Denmark", value: "DK" }, + { text: "Djibouti", value: "DJ" }, + { text: "Dominica", value: "DM" }, + { text: "DominicanRepublic", value: "DO" }, + { text: "EastTimor", value: "TL" }, + { text: "Ecuador", value: "EC" }, + { text: "Egypt", value: "EG" }, + { text: "ElSalvador", value: "SV" }, + { text: "EquatorialGuinea", value: "GQ" }, + { text: "Eritrea", value: "ER" }, + { text: "Estonia", value: "EE" }, + { text: "Eswatini", value: "SZ" }, + { text: "Ethiopia", value: "ET" }, + { text: "FalklandIslands", value: "FK" }, + { text: "FaroeIslands", value: "FO" }, + { text: "FederatedStatesofMicronesia", value: "FM" }, + { text: "Fiji", value: "FJ" }, + { text: "Finland", value: "FI" }, + { text: "France", value: "FR" }, + { text: "FrenchGuiana", value: "GF" }, + { text: "FrenchPolynesia", value: "PF" }, + { text: "FrenchSouthernandAntarcticLands", value: "TF" }, + { text: "Gabon", value: "GA" }, + { text: "Georgia(country)", value: "GE" }, + { text: "Germany", value: "DE" }, + { text: "Ghana", value: "GH" }, + { text: "Gibraltar", value: "GI" }, + { text: "Greece", value: "GR" }, + { text: "Greenland", value: "GL" }, + { text: "Grenada", value: "GD" }, + { text: "Guadeloupe", value: "GP" }, + { text: "Guam", value: "GU" }, + { text: "Guatemala", value: "GT" }, + { text: "Guinea", value: "GN" }, + { text: "Guinea-Bissau", value: "GW" }, + { text: "Guyana", value: "GY" }, + { text: "Haiti", value: "HT" }, + { text: "HeardIslandandMcDonaldIslands", value: "HM" }, + { text: "HolySee", value: "VA" }, + { text: "Honduras", value: "HN" }, + { text: "HongKong", value: "HK" }, + { text: "Hungary", value: "HU" }, + { text: "Iceland", value: "IS" }, + { text: "India", value: "IN" }, + { text: "Indonesia", value: "ID" }, + { text: "Iran", value: "IR" }, + { text: "Iraq", value: "IQ" }, + { text: "IsleofMan", value: "IM" }, + { text: "Israel", value: "IL" }, + { text: "Italy", value: "IT" }, + { text: "IvoryCoast", value: "CI" }, + { text: "Jamaica", value: "JM" }, + { text: "Japan", value: "JP" }, + { text: "Jersey", value: "JE" }, + { text: "Jordan", value: "JO" }, + { text: "Kazakhstan", value: "KZ" }, + { text: "Kenya", value: "KE" }, + { text: "Kiribati", value: "KI" }, + { text: "Kuwait", value: "KW" }, + { text: "Kyrgyzstan", value: "KG" }, + { text: "Laos", value: "LA" }, + { text: "Latvia", value: "LV" }, + { text: "Lebanon", value: "LB" }, + { text: "Lesotho", value: "LS" }, + { text: "Liberia", value: "LR" }, + { text: "Libya", value: "LY" }, + { text: "Liechtenstein", value: "LI" }, + { text: "Lithuania", value: "LT" }, + { text: "Luxembourg", value: "LU" }, + { text: "Macau", value: "MO" }, + { text: "Madagascar", value: "MG" }, + { text: "Malawi", value: "MW" }, + { text: "Malaysia", value: "MY" }, + { text: "Maldives", value: "MV" }, + { text: "Mali", value: "ML" }, + { text: "Malta", value: "MT" }, + { text: "MarshallIslands", value: "MH" }, + { text: "Martinique", value: "MQ" }, + { text: "Mauritania", value: "MR" }, + { text: "Mauritius", value: "MU" }, + { text: "Mayotte", value: "YT" }, + { text: "Mexico", value: "MX" }, + { text: "Moldova", value: "MD" }, + { text: "Monaco", value: "MC" }, + { text: "Mongolia", value: "MN" }, + { text: "Montenegro", value: "ME" }, + { text: "Montserrat", value: "MS" }, + { text: "Morocco", value: "MA" }, + { text: "Mozambique", value: "MZ" }, + { text: "Myanmar", value: "MM" }, + { text: "Namibia", value: "NA" }, + { text: "Nauru", value: "NR" }, + { text: "Nepal", value: "NP" }, + { text: "Netherlands", value: "NL" }, + { text: "NewCaledonia", value: "NC" }, + { text: "NewZealand", value: "NZ" }, + { text: "Nicaragua", value: "NI" }, + { text: "Niger", value: "NE" }, + { text: "Nigeria", value: "NG" }, + { text: "Niue", value: "NU" }, + { text: "NorfolkIsland", value: "NF" }, + { text: "NorthKorea", value: "KP" }, + { text: "NorthMacedonia", value: "MK" }, + { text: "NorthernMarianaIslands", value: "MP" }, + { text: "Norway", value: "NO" }, + { text: "Oman", value: "OM" }, + { text: "Pakistan", value: "PK" }, + { text: "Palau", value: "PW" }, + { text: "Panama", value: "PA" }, + { text: "PapuaNewGuinea", value: "PG" }, + { text: "Paraguay", value: "PY" }, + { text: "Peru", value: "PE" }, + { text: "Philippines", value: "PH" }, + { text: "PitcairnIslands", value: "PN" }, + { text: "Poland", value: "PL" }, + { text: "Portugal", value: "PT" }, + { text: "PuertoRico", value: "PR" }, + { text: "Qatar", value: "QA" }, + { text: "RepublicofIreland", value: "IE" }, + { text: "RepublicoftheCongo", value: "CG" }, + { text: "Romania", value: "RO" }, + { text: "Russia", value: "RU" }, + { text: "Rwanda", value: "RW" }, + { text: "Réunion", value: "RE" }, + { text: "SaintBarthélemy", value: "BL" }, + { text: "SaintHelena", value: "SH" }, + { text: "SaintKittsandNevis", value: "KN" }, + { text: "SaintLucia", value: "LC" }, + { text: "SaintPierreandMiquelon", value: "PM" }, + { text: "SaintVincentandtheGrenadines", value: "VC" }, + { text: "Samoa", value: "WS" }, + { text: "SanMarino", value: "SM" }, + { text: "SaudiArabia", value: "SA" }, + { text: "Senegal", value: "SN" }, + { text: "Serbia", value: "RS" }, + { text: "Seychelles", value: "SC" }, + { text: "SierraLeone", value: "SL" }, + { text: "Singapore", value: "SG" }, + { text: "SintMaarten", value: "SX" }, + { text: "Slovakia", value: "SK" }, + { text: "Slovenia", value: "SI" }, + { text: "SolomonIslands", value: "SB" }, + { text: "Somalia", value: "SO" }, + { text: "SouthAfrica", value: "ZA" }, + { text: "SouthGeorgiaandtheSouthSandwichIslands", value: "GS" }, + { text: "SouthKorea", value: "KR" }, + { text: "SouthSudan", value: "SS" }, + { text: "Spain", value: "ES" }, + { text: "SriLanka", value: "LK" }, + { text: "StateofPalestine", value: "PS" }, + { text: "Sudan", value: "SD" }, + { text: "Suriname", value: "SR" }, + { text: "Svalbard", value: "SJ" }, + { text: "Sweden", value: "SE" }, + { text: "Switzerland", value: "CH" }, + { text: "Syria", value: "SY" }, + { text: "SãoToméandPríncipe", value: "ST" }, + { text: "Taiwan", value: "TW" }, + { text: "Tajikistan", value: "TJ" }, + { text: "Tanzania", value: "TZ" }, + { text: "Thailand", value: "TH" }, + { text: "TheBahamas", value: "BS" }, + { text: "TheGambia", value: "GM" }, + { text: "Togo", value: "TG" }, + { text: "Tokelau", value: "TK" }, + { text: "Tonga", value: "TO" }, + { text: "TrinidadandTobago", value: "TT" }, + { text: "Tunisia", value: "TN" }, + { text: "Turkey", value: "TR" }, + { text: "Turkmenistan", value: "TM" }, + { text: "TurksandCaicosIslands", value: "TC" }, + { text: "Tuvalu", value: "TV" }, + { text: "Uganda", value: "UG" }, + { text: "Ukraine", value: "UA" }, + { text: "UnitedArabEmirates", value: "AE" }, + { text: "UnitedKingdom", value: "GB" }, + { text: "UnitedStatesVirginIslands", value: "VI" }, + { text: "UnitedStates", value: "UM" }, + { text: "UnitedStates", value: "US" }, + { text: "Uruguay", value: "UY" }, + { text: "Uzbekistan", value: "UZ" }, + { text: "Vanuatu", value: "VU" }, + { text: "Venezuela", value: "VE" }, + { text: "Vietnam", value: "VN" }, + { text: "WallisandFutuna", value: "WF" }, + { text: "WesternSahara", value: "EH" }, + { text: "Yemen", value: "YE" }, + { text: "Zambia", value: "ZM" }, + { text: "Zimbabwe", value: "ZW" }, + { text: "ÅlandIslands", value: "AX" }, + ], + }, + cursorLighting: { + component: "switch", + text: "cursorLighting", + }, + search: { + component: "section", + variant: "card", + title: "Youtube_Search", + remove_related_search_results: { + component: "switch", + text: "removeRelatedSearchResults", + }, + open_new_tab: { + component: "switch", + text: "openNewTab", + }, + remove_shorts_reel_search_results: { + component: "switch", + text: "removeShortsReelSearchResults", + }, + }, + remove_home_page_shorts: { + component: "switch", + text: "hideHomePageShorts", + id: "remove-home-page-shorts", + }, + remove_subscriptions_shorts: { + component: "switch", + text: "atSubscriptions", + id: "remove-subscriptions-shorts", + }, + remove_trending_shorts: { + component: "switch", + text: "atTrending", + }, + remove_history_shorts: { + component: "switch", + text: "atHistory", + }, + hide_ai_summary: { + component: "switch", + text: "hideAISummary", + id: "hide-ai-summary", + }, + youtube_home_page: { + component: "select", + text: "youtubeHomePage", + options: [ + { + text: "home", + value: "/", + }, + { + text: "trending", + value: "/feed/trending", + }, + { + text: "subscriptions", + value: "/feed/subscriptions", + }, + { + text: "history", + value: "/feed/history", + }, + { + text: "watchLater", + value: "/playlist?list=WL", + }, + { + text: "search", + value: "search", + }, + { + text: "liked", + value: "/playlist?list=LL", + }, + { + text: "library", + value: "/feed/library", + }, + { + text: "withoutVideos", + value: "hidecontent", + }, + ], + tags: "trending,subscriptions,history,watch,search,undistracted,zen", + }, + collapse_of_subscription_sections: { + component: "switch", + text: "collapseOfSubscriptionSections", + }, + ads: { + text: "ads", + component: "select", + options: [ + { + text: "onAllVideos", + value: "all_videos", + default: "true", + }, + { + text: "blockAll", + value: "block_all", + }, + { + text: "onSmallCreators", + value: "small_creators", + }, + { + text: "onSubscribedChannels", + value: "subscribed_channels", + }, + { + text: "blockMusic", + value: "block_music", + }, + { + text: "Mute Ads", + value: "mute_ads", + }, + ], + storage: "ads", - on: { - change: function (event) { - const selectedValue = event.target.value; + on: { + change: function (event) { + const selectedValue = event.target.value; - // Perform actions based on the selected value - const numberOfSubscribersInput = this.parentNode.querySelector('.count-component'); - if (selectedValue === 'small_creators') { - numberOfSubscribersInput.style.display = 'flex'; - } else { - numberOfSubscribersInput.style.display = 'none'; - } - } - } - }, - count: { - component: 'countComponent', - class: "count-component", - }, - hide_banner_ads: { - component: 'switch', - text: 'hideBannerAds' - } - }, - embed: { - component: 'section', - variant: 'card', - title: 'Embedded_YouTube', + // Perform actions based on the selected value + const numberOfSubscribersInput = + this.parentNode.querySelector(".count-component"); + if (selectedValue === "small_creators") { + numberOfSubscribersInput.style.display = "flex"; + } else { + numberOfSubscribersInput.style.display = "none"; + } + }, + }, + }, + count: { + component: "countComponent", + class: "count-component", + }, + hide_banner_ads: { + component: "switch", + text: "hideBannerAds", + }, + }, + embed: { + component: "section", + variant: "card", + title: "Embedded_YouTube", - embeddedHidePauseOverlay: { - component: 'switch', - text: 'Hide_Pause_Overlay', - }, - embeddedHideYoutubeLogo: { - component: 'switch', - text: 'Hide_YouTube_Logo' - }, - embeddedHideShare: { - component: 'switch', - text: 'embedded_Hide_Share' - } - }, - section_3: { - component: 'section', - variant: 'card', - title: 'thumbnails', - hide_animated_thumbnails: { - component: 'switch', - text: 'hideAnimatedThumbnails', - tags: 'preview' - }, - disable_thumbnail_playback: { - component: 'switch', - text: 'disableThumbnailPlayback', - }, - popup_window_buttons: { - component: 'switch', - text: 'popupWindowButtons', - }, - hide_thumbnail_overlay: { - component: 'switch', - text: 'hideThumbnailOverlay', - tags: 'preview' - }, - hide_thumbnail_icon: { - component: "switch", - text: "hideThumbnailIcon", - tags: "preview", - }, - hide_thumbnail_dots: { - component: 'switch', - text: 'hideThumbnailDots', - tags: 'preview' - }, - thumbnails_quality: { - component: 'select', - text: 'thumbnailsQuality', - options: [{ - text: 'default', - value: 'null' - }, { - text: 'low', - value: 'default' - }, { - text: 'medium', - value: 'mqdefault' - }, { - text: 'high', - value: 'hqdefault' - }, { - text: 'sd', - value: 'sddefault' - }, { - text: 'hd', - value: 'maxresdefault' - }], - tags: 'preview quality' - }, - change_thumbnails_per_row: { - component: 'select', - text: 'changeThumbnailsPerRow', - options: [{ - text: '4', - value: '4' - },{ - text: '3', - value: '3' - }, { - text: '5', - value: '5' - }, { - text: '6', - value: '6' - }, { - text: '7', - value: '7' - }, { - text: '8', - value: '8' - },{ - text: '9 (experimental)', - value: '9' - },{ - text: '10 (experimental)', - value: '10' - },{ - text: '11 (experimental)', - value: '11' - },{ - text: '12 (experimental)', - value: '12' - },{ - text: '2 (experimental)', - value: '2' - },{ - text: '1 (experimental)', - value: '1' - }], - tags: 'change thumbnails per row' - }, - thumbnail_size: { - component: "select", - text: "Thumbnail Size", - storage: "thumbnail_size", - options: [ - { text: "Default", value: "default" }, - { text: "Small", value: "small" }, - { text: "x-small", value: "x-small" } - ] - } - }, section_2: { - component: 'section', - variant: 'card', - title: 'watchedVideos', + embeddedHidePauseOverlay: { + component: "switch", + text: "Hide_Pause_Overlay", + }, + embeddedHideYoutubeLogo: { + component: "switch", + text: "Hide_YouTube_Logo", + }, + embeddedHideShare: { + component: "switch", + text: "embedded_Hide_Share", + }, + }, + section_3: { + component: "section", + variant: "card", + title: "thumbnails", + hide_animated_thumbnails: { + component: "switch", + text: "hideAnimatedThumbnails", + tags: "preview", + }, + disable_thumbnail_playback: { + component: "switch", + text: "disableThumbnailPlayback", + }, + popup_window_buttons: { + component: "switch", + text: "popupWindowButtons", + }, + hide_thumbnail_overlay: { + component: "switch", + text: "hideThumbnailOverlay", + tags: "preview", + }, + hide_thumbnail_icon: { + component: "switch", + text: "hideThumbnailIcon", + tags: "preview", + }, + hide_thumbnail_dots: { + component: "switch", + text: "hideThumbnailDots", + tags: "preview", + }, + thumbnails_quality: { + component: "select", + text: "thumbnailsQuality", + options: [ + { + text: "default", + value: "null", + }, + { + text: "low", + value: "default", + }, + { + text: "medium", + value: "mqdefault", + }, + { + text: "high", + value: "hqdefault", + }, + { + text: "sd", + value: "sddefault", + }, + { + text: "hd", + value: "maxresdefault", + }, + ], + tags: "preview quality", + }, + change_thumbnails_per_row: { + component: "select", + text: "changeThumbnailsPerRow", + options: [ + { + text: "4", + value: "4", + }, + { + text: "3", + value: "3", + }, + { + text: "5", + value: "5", + }, + { + text: "6", + value: "6", + }, + { + text: "7", + value: "7", + }, + { + text: "8", + value: "8", + }, + { + text: "9 (experimental)", + value: "9", + }, + { + text: "10 (experimental)", + value: "10", + }, + { + text: "11 (experimental)", + value: "11", + }, + { + text: "12 (experimental)", + value: "12", + }, + { + text: "2 (experimental)", + value: "2", + }, + { + text: "1 (experimental)", + value: "1", + }, + ], + tags: "change thumbnails per row", + }, + thumbnail_size: { + component: "select", + text: "Thumbnail Size", + storage: "thumbnail_size", + options: [ + { text: "Default", value: "default" }, + { text: "Small", value: "small" }, + { text: "x-small", value: "x-small" }, + ], + }, + }, + section_2: { + component: "section", + variant: "card", + title: "watchedVideos", - mark_watched_videos: { - component: 'switch', - text: 'markWatchedVideos', - on: { - click: function () { - setTimeout(() => { - if (satus.storage.get('mark_watched_videos')) { - if (!satus.storage.get('track_watched_videos')) { - this.nextSibling.click(); - } - } - }, 250); - } - } - }, - track_watched_videos: { - component: 'switch', - text: 'trackWatchedVideos' - }, - hide_watched_videos: { - component: 'switch', - text: 'hideWatchedVideos' - }, - delete_watched_videos: { - component: 'button', - text: 'deleteWatchedVideos', - style: { - justifyContent: 'space-between' - }, - on: { - click: { - component: 'modal', - variant: 'confirm', - content: 'thisWillRemoveAllWatchedVideos', - buttons: { - cancel: { - component: 'button', - text: 'cancel', - on: { - click: function () { - this.modalProvider.close(); - } - } - }, - reset: { - component: 'button', - text: 'accept', - on: { - click: function () { - var modal = this.parentNode.parentNode.parentNode; + mark_watched_videos: { + component: "switch", + text: "markWatchedVideos", + on: { + click: function () { + setTimeout(() => { + if (satus.storage.get("mark_watched_videos")) { + if (!satus.storage.get("track_watched_videos")) { + this.nextSibling.click(); + } + } + }, 250); + }, + }, + }, + track_watched_videos: { + component: "switch", + text: "trackWatchedVideos", + }, + hide_watched_videos: { + component: "switch", + text: "hideWatchedVideos", + }, + delete_watched_videos: { + component: "button", + text: "deleteWatchedVideos", + style: { + justifyContent: "space-between", + }, + on: { + click: { + component: "modal", + variant: "confirm", + content: "thisWillRemoveAllWatchedVideos", + buttons: { + cancel: { + component: "button", + text: "cancel", + on: { + click: function () { + this.modalProvider.close(); + }, + }, + }, + reset: { + component: "button", + text: "accept", + on: { + click: function () { + var modal = this.parentNode.parentNode.parentNode; - satus.storage.remove('watched'); + satus.storage.remove("watched"); - modal.skeleton.parentSkeleton.counter.rendered.textContent = '0'; + modal.skeleton.parentSkeleton.counter.rendered.textContent = + "0"; - modal.close(); - } - } - } - } - } - }, + modal.close(); + }, + }, + }, + }, + }, + }, - counter: { - component: 'span', - style: { - opacity: .64 - }, - on: { - render: function () { - var watched = satus.storage.get('watched'); + counter: { + component: "span", + style: { + opacity: 0.64, + }, + on: { + render: function () { + var watched = satus.storage.get("watched"); - if (watched) { - this.textContent = Object.keys(watched).length; - } else { - this.textContent = '0'; - } - } - } - } - } - }, - section_4: { - component: 'section', - variant: 'card', - title: 'more', - confirmation_before_closing: { - component: 'switch', - text: 'confirmationBeforeClosing', - tags: 'random prevent close exit' - }, - font: { - component: 'select', - text: 'font', - options: [{ - text: 'default', - value: 'Default' - }, { - text: 'Comfortaa', - value: 'Comfortaa' - }, { - text: 'Lato', - value: 'Lato' - }, { - text: 'Marriweather', - value: 'Marriweather' - }, { - text: 'Montserrat', - value: 'Montserrat' - }, { - text: 'Noto Sans', - value: 'Noto+Sans' - }, { - text: 'Open Sans', - value: 'Open+Sans' - }, { - text: 'Oswald', - value: 'Oswald' - }, { - text: 'Poppins', - value: 'Poppins' - }, { - text: 'PT Sans', - value: 'PT+Sans' - }, { - text: 'Raleway', - value: 'Raleway' - }, { - text: 'Roboto Condensed', - value: 'Roboto+Condensed' - }, { - text: 'Roboto Mono', - value: 'Roboto+Mono' - }, { - text: 'Roboto Slab', - value: 'Roboto+Slab' - }, { - text: 'Source Sans Pro', - value: 'Source+Sans+Pro' - }] - }, - scroll_bar: { - component: 'select', - text: 'scrollBar', - options: [{ - text: 'default', - value: 'default' - }, { - text: 'hidden', - value: 'hidden' - }] - }, - add_scroll_to_top: { - component: 'switch', - text: 'addScrollToTop', - tags: 'up' - }, - remove_member_only: { - component: 'switch', - text: 'removeMemberOnly', - }, - remove_context_buttons: { - component: 'switch', - text: 'removeContextButtons', - }, - remove_list_param_from_links: { - component: 'switch', - text: 'removePlaylistParam' - }, - clickable_links_in_description: { - component: 'switch', - text: 'clickableLinksInDescription' - } - } - } - }, - icon: { - component: 'span', + if (watched) { + this.textContent = Object.keys(watched).length; + } else { + this.textContent = "0"; + } + }, + }, + }, + }, + }, + section_4: { + component: "section", + variant: "card", + title: "more", + confirmation_before_closing: { + component: "switch", + text: "confirmationBeforeClosing", + tags: "random prevent close exit", + }, + font: { + component: "select", + text: "font", + options: [ + { + text: "default", + value: "Default", + }, + { + text: "Comfortaa", + value: "Comfortaa", + }, + { + text: "Lato", + value: "Lato", + }, + { + text: "Marriweather", + value: "Marriweather", + }, + { + text: "Montserrat", + value: "Montserrat", + }, + { + text: "Noto Sans", + value: "Noto+Sans", + }, + { + text: "Open Sans", + value: "Open+Sans", + }, + { + text: "Oswald", + value: "Oswald", + }, + { + text: "Poppins", + value: "Poppins", + }, + { + text: "PT Sans", + value: "PT+Sans", + }, + { + text: "Raleway", + value: "Raleway", + }, + { + text: "Roboto Condensed", + value: "Roboto+Condensed", + }, + { + text: "Roboto Mono", + value: "Roboto+Mono", + }, + { + text: "Roboto Slab", + value: "Roboto+Slab", + }, + { + text: "Source Sans Pro", + value: "Source+Sans+Pro", + }, + ], + }, + scroll_bar: { + component: "select", + text: "scrollBar", + options: [ + { + text: "default", + value: "default", + }, + { + text: "hidden", + value: "hidden", + }, + ], + }, + add_scroll_to_top: { + component: "switch", + text: "addScrollToTop", + tags: "up", + }, + remove_member_only: { + component: "switch", + text: "removeMemberOnly", + }, + remove_context_buttons: { + component: "switch", + text: "removeContextButtons", + }, + remove_list_param_from_links: { + component: "switch", + text: "removePlaylistParam", + }, + clickable_links_in_description: { + component: "switch", + text: "clickableLinksInDescription", + }, + }, + }, + }, + icon: { + component: "span", - svg: { - component: 'svg', - attr: { - 'viewBox': '0 0 24 24', - 'fill': 'none', - 'stroke': 'currentColor', - 'stroke-linecap': 'round', - 'stroke-width': '1.75' - }, + svg: { + component: "svg", + attr: { + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + "stroke-linecap": "round", + "stroke-width": "1.75", + }, - path: { - component: 'path', - attr: { - 'd': 'M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1zM4 22v-7' - } - } - } - }, - label: { - component: 'span', - text: 'general' - } + path: { + component: "path", + attr: { + d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1zM4 22v-7", + }, + }, + }, + }, + label: { + component: "span", + text: "general", + }, };