From 7facd06ea8e922beb0c4eaabe4ea56a4d88bf5db Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 11:33:28 +0200 Subject: [PATCH 01/16] Update appearance.js use dedicated safe ImprovedTube.enterPip() --- js&css/web-accessible/www.youtube.com/appearance.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/js&css/web-accessible/www.youtube.com/appearance.js b/js&css/web-accessible/www.youtube.com/appearance.js index a952faf48..5dbc8b97b 100644 --- a/js&css/web-accessible/www.youtube.com/appearance.js +++ b/js&css/web-accessible/www.youtube.com/appearance.js @@ -415,10 +415,7 @@ ImprovedTube.improvedtubeYoutubeButtonsUnderPlayer = function () { 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'); button.onclick = function () { - var video = document.querySelector('#movie_player video'); - if (video) { - video.requestPictureInPicture(); - } + ImprovedTube.enterPip(); }; svg.appendChild(path); button.appendChild(svg); From 56e343b564c3edb2a80db510f7afaa7fe656eaa1 Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 11:40:00 +0200 Subject: [PATCH 02/16] Update player.js dedicated safe enterPip() + close Auto PIP when returning to source Tab (player_autoPip_outside) --- .../web-accessible/www.youtube.com/player.js | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/js&css/web-accessible/www.youtube.com/player.js b/js&css/web-accessible/www.youtube.com/player.js index db4417071..764aca435 100644 --- a/js&css/web-accessible/www.youtube.com/player.js +++ b/js&css/web-accessible/www.youtube.com/player.js @@ -7,12 +7,12 @@ ImprovedTube.autoplayDisable = function (videoElement) { || 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 (this.video_url !== location.href) this.user_interacted = false; - // if (no user clicks) and (no ads playing) and - // ( there is a player and ( (it is not in a playlist and auto play is off ) or ( playlist auto play is off and in a playlist ) ) ) or (if we are in a channel and the channel trailer autoplay is off) ) + // if (there is a player) and (no user clicks) and (no ads playing) + // and ( ( it is not in a playlist and auto play is off ) + // or ( playlist auto play is off and in a playlist ) + // or ( we are in a channel and the channel trailer autoplay is off ) ) // user didnt click if (player && !this.user_interacted @@ -75,19 +75,38 @@ ImprovedTube.playerAutopauseWhenSwitchingTabs = function () { } }; /*------------------------------------------------------------------------------ +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; + } +}; +/*------------------------------------------------------------------------------ AUTO PIP WHEN SWITCHING TABS ------------------------------------------------------------------------------*/ ImprovedTube.playerAutoPip = function () { - const video = ImprovedTube.elements.video; - - if (this.storage.player_autoPip === true && video) { - (async () => { - try { - await video.requestPictureInPicture(); - } catch (error) { - console.error('Failed to enter Picture-in-Picture mode', error); - } - })(); + 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(); } }; /*------------------------------------------------------------------------------ From 8b815aa398357c01c567af683a0612a1f0d021ff Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 11:41:31 +0200 Subject: [PATCH 03/16] Update shortcuts.js use new safe enterPip() --- js&css/web-accessible/www.youtube.com/shortcuts.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/js&css/web-accessible/www.youtube.com/shortcuts.js b/js&css/web-accessible/www.youtube.com/shortcuts.js index 645e4d4a0..87cea62b2 100644 --- a/js&css/web-accessible/www.youtube.com/shortcuts.js +++ b/js&css/web-accessible/www.youtube.com/shortcuts.js @@ -151,14 +151,9 @@ ImprovedTube.shortcutQuality = function (key) { ImprovedTube.playerQuality(label[resolution.indexOf(key.replace('shortcutQuality', ''))]); }; /*------------------------------------------------------------------------------ -4.7.2 PICTURE IN PICTURE +4.7.2 PICTURE IN PICTURE (PIP) ------------------------------------------------------------------------------*/ -ImprovedTube.shortcutPictureInPicture = function () { - const video = ImprovedTube.elements.video; - if (video && document.pictureInPictureEnabled && typeof video.requestPictureInPicture == 'function') { - video.requestPictureInPicture().then().catch((err) => console.error(err)); - } -}; +ImprovedTube.shortcutPictureInPicture = this.enterPip; /*------------------------------------------------------------------------------ 4.7.3 TOGGLE CONTROLS ------------------------------------------------------------------------------*/ From 32260bf3542b7738cd50f30b56034a65771477a5 Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 11:42:55 +0200 Subject: [PATCH 04/16] Update player.js player_autoPip_outside and warning --- menu/skeleton-parts/player.js | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/menu/skeleton-parts/player.js b/menu/skeleton-parts/player.js index b78fabba2..c1a1b7bff 100644 --- a/menu/skeleton-parts/player.js +++ b/menu/skeleton-parts/player.js @@ -98,15 +98,39 @@ extension.skeleton.main.layers.section.player.on.click = { component: 'switch', text: 'Auto_PiP_picture_in_picture', id: 'player_autoPip', + custom: true, on: { click: function () { - if (this.dataset.value === 'true' && satus.storage.get('player_autopause_when_switching_tabs')) { - document.getElementById('only_one_player_instance_playing').flip(true); - document.getElementById('autopause_when_switching_tabs').flip(false); + if (this.dataset.value === 'false') { + let where = this; + satus.render({ + component: 'modal', + variant: 'confirm', + content: 'PipRequiresUserInteraction', + ok: function () { + // manually turn switch ON + where.flip(true); + if (satus.storage.get('player_autopause_when_switching_tabs')) { + document.getElementById('only_one_player_instance_playing').flip(true); + document.getElementById('autopause_when_switching_tabs').flip(false); + } + }, + cancel: function () { + // nothing happens when we cancel + } + }, extension.skeleton.rendered); + } else { + // manually turn switch OFF + this.flip(false); } } } }, + player_autoPip_outside: { + component: 'switch', + text: 'playerAutoPipOutside', + value: true + }, player_forced_volume: { component: 'switch', text: 'forcedVolume', From dde08e6f6a94e360372cbdd53c4a9b608941a01d Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 11:44:15 +0200 Subject: [PATCH 05/16] Update sub-options.css player_autoPip sub-option, formatting --- menu/styles/sub-options.css | 90 ++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/menu/styles/sub-options.css b/menu/styles/sub-options.css index bfc357b1e..ce509df6a 100644 --- a/menu/styles/sub-options.css +++ b/menu/styles/sub-options.css @@ -1,33 +1,34 @@ /*----------------- NESTED (CONDITIONAL) SWITCHES -----------------*/ -#remove-home-page-shorts:not([data-value='true']) + .satus-switch, -#remove-home-page-shorts:not([data-value='true']) + .satus-switch + .satus-switch, -#remove-home-page-shorts:not([data-value='true']) + .satus-switch + .satus-switch + .satus-switch, +#remove-home-page-shorts:not([data-value=true]) + .satus-switch, +#remove-home-page-shorts:not([data-value=true]) + .satus-switch + .satus-switch, +#remove-home-page-shorts:not([data-value=true]) + .satus-switch + .satus-switch + .satus-switch, /*----------------- >>> Appearance -----------------*/ /*-transcript compact spacing-*/ -#transcript:not([data-value='true']) + .satus-switch, +#transcript:not([data-value=true]) + .satus-switch, /*-DURATION WITH SPEED-*/ -#show-remaining-duration:not([data-value='true']) + .satus-switch, +#show-remaining-duration:not([data-value=true]) + .satus-switch, /*-comment sidebar scrollbars-*/ -#comments-sidebar:not([data-value='true']) + .satus-switch + #comments-sidebar-simple:not([data-value='true']) + .satus-switch, -/* #comments-sidebar:not([data-value='true']) + .satus-switch, */ +#comments-sidebar:not([data-value=true]) + .satus-switch + #comments-sidebar-simple:not([data-value=true]) + .satus-switch, +/* #comments-sidebar:not([data-value=true]) + .satus-switch, */ /*-------------------------------------------------------------- >>> PLAYER --------------------------------------------------------------*/ -#forced-volume:not([data-value='true']) + .satus-slider, -#forced-playback-speed:not([data-value='true']) + .satus-switch, -#forced-playback-speed:not([data-value='true']) + .satus-switch + .satus-switch, -#forced-playback-speed:not([data-value='true']) + .satus-switch + .satus-switch + .satus-slider, -/* #player_repeat_button:not([data-value='true']) + .satus-switch, */ -#player_screenshot_button:not([data-value='true']) + .satus-switch, -#player_screenshot_button:not([data-value='true']) + .satus-switch + .satus-select, +#player_autoPip:not([data-value=true]) + .satus-switch, +#forced-volume:not([data-value=true]) + .satus-slider, +#forced-playback-speed:not([data-value=true]) + .satus-switch, +#forced-playback-speed:not([data-value=true]) + .satus-switch + .satus-switch, +#forced-playback-speed:not([data-value=true]) + .satus-switch + .satus-switch + .satus-slider, +/* #player_repeat_button:not([data-value=true]) + .satus-switch, */ +#player_screenshot_button:not([data-value=true]) + .satus-switch, +#player_screenshot_button:not([data-value=true]) + .satus-switch + .satus-select, /*-------------------------------------------------------------- SUBTITLES --------------------------------------------------------------*/ -#subtitles-language[data-value='default'] + .satus-switch, +#subtitles-language[data-value=default] + .satus-switch, /*-------------------------------------------------------------- NIGHT MODE --------------------------------------------------------------*/ @@ -36,73 +37,72 @@ NIGHT MODE /*====================================*/ {display: none !important;} -#remove-home-page-shorts[data-value='true'] + .satus-switch, -#remove-home-page-shorts[data-value='true'] + .satus-switch + .satus-switch, -#remove-home-page-shorts[data-value='true'] + .satus-switch + .satus-switch + .satus-switch, +#remove-home-page-shorts[data-value=true] + .satus-switch, +#remove-home-page-shorts[data-value=true] + .satus-switch + .satus-switch, +#remove-home-page-shorts[data-value=true] + .satus-switch + .satus-switch + .satus-switch, /*----------------- >>> Appearance -----------------*/ /*-transcript compact spacing-*/ -#transcript[data-value='true'] + .satus-switch, +#transcript[data-value=true] + .satus-switch, /*-DURATION WITH SPEED-*/ -#show-remaining-duration[data-value='true'] + .satus-switch, +#show-remaining-duration[data-value=true] + .satus-switch, /*-comment sidebar scrollbars-*/ -#comments-sidebar[data-value='true'] + .satus-switch, +#comments-sidebar[data-value=true] + .satus-switch, /*-------------------------------------------------------------- >>> PLAYER --------------------------------------------------------------*/ -#forced-volume[data-value='true'] + .satus-slider, -#forced-playback-speed[data-value='true'] + .satus-switch, -#forced-playback-speed[data-value='true'] + .satus-switch + .satus-switch, -#forced-playback-speed[data-value='true'] + .satus-switch + .satus-switch + .satus-slider, +#player_autoPip[data-value=true] + .satus-switch, +#forced-volume[data-value=true] + .satus-slider, +#forced-playback-speed[data-value=true] + .satus-switch, +#forced-playback-speed[data-value=true] + .satus-switch + .satus-switch, +#forced-playback-speed[data-value=true] + .satus-switch + .satus-switch + .satus-slider, #player_repeat_button + .satus-switch, #player_cinema_mode_button +.satus-switch, #player_auto_cinema_mode +.satus-switch, -#player_screenshot_button[data-value='true'] + .satus-switch, -#player_screenshot_button[data-value='true'] + .satus-switch + .satus-select, +#player_screenshot_button[data-value=true] + .satus-switch, +#player_screenshot_button[data-value=true] + .satus-switch + .satus-select, /*-------------------------------------------------------------- SUBTITLES --------------------------------------------------------------*/ -#subtitles-language:not([data-value='default']) + .satus-switch, +#subtitles-language:not([data-value=default]) + .satus-switch, /*-------------------------------------------------------------- NIGHT MODE --------------------------------------------------------------*/ #activate[data-value='sunset_to_sunrise'] + .satus-time--from, #activate[data-value='sunset_to_sunrise'] + * + .satus-time--to /*====================================*/ - {margin-left:20px; margin-top:-4px; margin-bottom:2px; max-width: calc( 100% - 22px ) !important; border-radius: 2px; border-left: 1px inset; } + {margin-left:20px; margin-top:-4px; margin-bottom:2px; max-width: calc( 100% - 22px ) !important; border-radius: 2px; border-left: 1px inset;} -#remove-home-page-shorts[data-value='true'] + .satus-switch:not(:hover), -#remove-home-page-shorts[data-value='true'] + .satus-switch + .satus-switch:not(:hover), -#remove-home-page-shorts[data-value='true'] + .satus-switch + .satus-switch + .satus-switch:not(:hover), +#remove-home-page-shorts[data-value=true] + .satus-switch:not(:hover), +#remove-home-page-shorts[data-value=true] + .satus-switch + .satus-switch:not(:hover), +#remove-home-page-shorts[data-value=true] + .satus-switch + .satus-switch + .satus-switch:not(:hover), /*----------------- >>> Appearance -----------------*/ /*-transcript compact spacing-*/ -#transcript[data-value='true'] + .satus-switch:not(:hover), +#transcript[data-value=true] + .satus-switch:not(:hover), /*-DURATION WITH SPEED-*/ -#show-remaining-duration[data-value='true'] + .satus-switch:not(:hover), +#show-remaining-duration[data-value=true] + .satus-switch:not(:hover), /*-comment sidebar scrollbars-*/ -#comments-sidebar[data-value='true'] + .satus-switch:not(:hover), +#comments-sidebar[data-value=true] + .satus-switch:not(:hover), /*-------------------------------------------------------------- >>> PLAYER --------------------------------------------------------------*/ -#forced-volume[data-value='true'] + .satus-slider:not(:hover), -#forced-playback-speed[data-value='true'] + .satus-switch:not(:hover), -#forced-playback-speed[data-value='true'] + .satus-switch + .satus-switch:not(:hover), -#forced-playback-speed[data-value='true'] + .satus-switch + .satus-switch + .satus-slider:not(:hover), -#player_screenshot_button[data-value='true'] + .satus-switch:not(:hover), -#player_screenshot_button[data-value='true'] + .satus-switch + .satus-select:not(:hover), +#forced-volume[data-value=true] + .satus-slider:not(:hover), +#forced-playback-speed[data-value=true] + .satus-switch:not(:hover), +#forced-playback-speed[data-value=true] + .satus-switch + .satus-switch:not(:hover), +#forced-playback-speed[data-value=true] + .satus-switch + .satus-switch + .satus-slider:not(:hover), +#player_screenshot_button[data-value=true] + .satus-switch:not(:hover), +#player_screenshot_button[data-value=true] + .satus-switch + .satus-select:not(:hover), /*-------------------------------------------------------------- SUBTITLES --------------------------------------------------------------*/ -#subtitles-language:not([data-value='default']) + .satus-switch:not(:hover), +#subtitles-language:not([data-value=default]) + .satus-switch:not(:hover), /*-------------------------------------------------------------- NIGHT MODE --------------------------------------------------------------*/ #activate[data-value='sunset_to_sunrise'] + .satus-time--from:not(:hover), #activate[data-value='sunset_to_sunrise'] + * + .satus-time--to:not(:hover) /*====================================*/ - { background-color:rgb(69,180,210,0.09); } - - + {background-color:rgb(69,180,210,0.09);} From 23b8e3522428e9b78fb4b28f2ada2baf6829531d Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 11:47:43 +0200 Subject: [PATCH 06/16] Update player.js no-prototype-builtins --- js&css/web-accessible/www.youtube.com/player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js&css/web-accessible/www.youtube.com/player.js b/js&css/web-accessible/www.youtube.com/player.js index 764aca435..3d3c58845 100644 --- a/js&css/web-accessible/www.youtube.com/player.js +++ b/js&css/web-accessible/www.youtube.com/player.js @@ -440,7 +440,7 @@ ImprovedTube.subtitlesUserSettings = function () { break; } - if (ytSettings?.hasOwnProperty(value)) { + if (Object.keys(ytSettings).includes(value)) { ytSettings[value] = setting; } else { console.error('subtitlesUserSettings failed at: ', value, setting); From cc8ff84d1a5ea7d8190b9dc69b70e69d0f74247f Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 11:57:00 +0200 Subject: [PATCH 07/16] Update functions.js linter --- js&css/web-accessible/functions.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/js&css/web-accessible/functions.js b/js&css/web-accessible/functions.js index 0b642913a..6e4441e8f 100644 --- a/js&css/web-accessible/functions.js +++ b/js&css/web-accessible/functions.js @@ -128,12 +128,11 @@ ImprovedTube.ytElementsHandler = function (node) { this.howLongAgoTheVideoWasUploaded(); this.channelVideosCount(); } - } - // else if (name === 'YTD-MENU-RENDERER' && node.classList.contains('ytd-video-primary-info-renderer')) { + //} 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'))) { + } else if (name === 'YTD-PLAYLIST-HEADER-RENDERER' || (name === 'YTD-MENU-RENDERER' && node.classList.contains('ytd-playlist-panel-renderer'))) { this.playlistPopupUpdate(); } else if (name === 'YTD-SUBSCRIBE-BUTTON-RENDERER' || name === 'YT-SUBSCRIBE-BUTTON-VIEW-MODEL' @@ -395,7 +394,6 @@ var timeUpdateInterval = null; var noTimeUpdate = null; ImprovedTube.playerOnTimeUpdate = function () { - var currentTime = Date.now(); if (!timeUpdateInterval) { timeUpdateInterval = setInterval(function () { if (ImprovedTube.video_src !== this.src) { From 847ddd7277bf4f6af1c1866a02b20d8ab4550901 Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 12:07:45 +0200 Subject: [PATCH 08/16] Update appearance.js linter --- .../www.youtube.com/appearance.js | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/js&css/web-accessible/www.youtube.com/appearance.js b/js&css/web-accessible/www.youtube.com/appearance.js index 5dbc8b97b..681505e4e 100644 --- a/js&css/web-accessible/www.youtube.com/appearance.js +++ b/js&css/web-accessible/www.youtube.com/appearance.js @@ -77,26 +77,25 @@ ImprovedTube.playerHdThumbnail = function () { ALWAYS SHOW PROGRESS BAR ------------------------------------------------------------------------------*/ ImprovedTube.showProgressBar = function () { - - var player = ImprovedTube.elements.player; + const player = ImprovedTube.elements.player; if (player && player.className.indexOf("ytp-autohide") !== -1) { - var played = (player.getCurrentTime() * 100) / player.getDuration(), + const played = (player.getCurrentTime() * 100) / player.getDuration(), loaded = player.getVideoBytesLoaded() * 100, play_bars = player.querySelectorAll(".ytp-play-progress"), - load_bars = player.querySelectorAll(".ytp-load-progress"), - width = 0, + load_bars = player.querySelectorAll(".ytp-load-progress"); + let width = 0, progress_play = 0, progress_load = 0; - for (var i = 0, l = play_bars.length; i < l; i++) { + for (let i = 0, l = play_bars.length; i < l; i++) { width += play_bars[i].offsetWidth; } - var width_percent = width / 100; + const width_percent = width / 100; - for (var i = 0, l = play_bars.length; i < l; i++) { - var a = play_bars[i].offsetWidth / width_percent, + for (let i = 0, l = play_bars.length; i < l; i++) { + let a = play_bars[i].offsetWidth / width_percent, b = 0, c = 0; @@ -493,10 +492,11 @@ ImprovedTube.dayOfWeek = function () { if (this.storage.day_of_week === true) { var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; setTimeout(function () { - var videoDate; try { + var videoDate; + try { videoDate = JSON.parse(document.querySelector('#microformat script')?.textContent)?.uploadDate - } //YouTube related video or internal link? - catch { + } catch { + //YouTube related video or internal link? try { videoDate = document.querySelector("[itemprop=datePublished]").content; } catch { } From efcb35c45dbdc56b708cd6144944fc6334c269de Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 14:21:53 +0200 Subject: [PATCH 09/16] Update satus.js fixing modal, multiple other fixes satus.components.select dispatches 'render' Event on component.render, fixes updating player_quality by triggering its on.render sections can be functions was breaking modals, make exception modal 'content' can be a function satus.indexOf was always broken satus.getProperty was always broken --- menu/satus.js | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/menu/satus.js b/menu/satus.js index 4bb833982..06800afa4 100644 --- a/menu/satus.js +++ b/menu/satus.js @@ -516,14 +516,14 @@ satus.fetch = function (url, success, error, type) { # GET PROPERTY --------------------------------------------------------------*/ satus.getProperty = function (object, string) { - var properties = string.split('.'); + const properties = string.split('.'); - for (var i = 0, l = properties.length; i < l; i++) { - var property = properties[i]; + for (let i = 0, l = properties.length; i < l; i++) { + const property = properties[i]; console.log(object); - if (object = object[property]) { + if (object === object[property]) { if (i === l - 1) { return object; } @@ -538,12 +538,12 @@ satus.getProperty = function (object, string) { --------------------------------------------------------------*/ satus.indexOf = function (child, parent) { - var index = 0; + let index = 0; if (satus.isArray(parent)) { index = parent.indexOf(child); } else { - while ((child = child.previousElementSibling)) { + while ((child === child.previousElementSibling)) { index++; } } @@ -824,7 +824,7 @@ satus.render = function (skeleton, container, property, childrenOnly, prepend, s this.append(element, container); } - if (skeleton.hasOwnProperty('parentSkeleton') === false && container) { + if (!Object.keys(skeleton).includes('parentSkeleton') && container) { skeleton.parentSkeleton = container.skeleton; } @@ -839,8 +839,8 @@ satus.render = function (skeleton, container, property, childrenOnly, prepend, s for (var key in skeleton) { var item = skeleton[key]; - // sections can be functions - if (satus.isFunction(item)) { + // sections can be functions, but ignore modals because that would call all the button functions + if (satus.isFunction(item) && skeleton.component != "modal") { item = item(); } @@ -1124,6 +1124,8 @@ satus.text = function (element, value) { >>> MODAL --------------------------------------------------------------*/ satus.components.modal = function (component, skeleton) { + let content = skeleton.content; + component.scrim = component.createChildElement('div', 'scrim'); component.surface = component.createChildElement('div', 'surface'); @@ -1172,13 +1174,15 @@ satus.components.modal = function (component, skeleton) { } }); - if (satus.isset(skeleton.content)) { + if (satus.isset(content)) { component.surface.content = component.surface.createChildElement('p', 'content'); - if (satus.isObject(skeleton.content)) { - satus.render(skeleton.content, component.surface.content); + //modal 'content' can be a function + if (satus.isFunction(content)) content = content(); + if (satus.isObject(content)) { + satus.render(content, component.surface.content); } else { - component.surface.content.textContent = satus.locale.get(skeleton.content); + component.surface.content.textContent = satus.locale.get(content); } } else { component.childrenContainer = component.surface; @@ -1634,6 +1638,8 @@ satus.components.select = function (component, skeleton) { } this.dataset.value = this.value; + + this.dispatchEvent(new CustomEvent('render')); }; component.selectElement.addEventListener('change', function () { From 02cb38afa22fa0491c51129a07ec731e965b9c6d Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 14:31:18 +0200 Subject: [PATCH 10/16] messages.json "Auto-PiP only outside source Tab" --- _locales/en/messages.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 1071c3419..172a83685 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -153,7 +153,10 @@ "message": "Auto" }, "Auto_PiP_picture_in_picture": { - "message": "Auto-PiP (picture in picture)" + "message": "Auto-PiP (Picture in Picture)" + }, + "playerAutoPipOutside": { + "message": "Auto-PiP only outside source Tab" }, "autoFullscreen": { "message": "Auto-fullscreen" From bb369974ece46bf10e77a1adefa66871f3db82a4 Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 14:40:54 +0200 Subject: [PATCH 11/16] Update messages.json --- _locales/en/messages.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 172a83685..18a08750c 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -158,6 +158,9 @@ "playerAutoPipOutside": { "message": "Auto-PiP only outside source Tab" }, + "PipRequiresUserInteraction": { + "message": "PiP requires recent User interaction with source page. This is Chrome Picture-in-Picture API limitations and we cant do anything to bypass it. Works best with Autoplay disabled and manual Play control or deliberately clicking somewhere on the page before switching Tabs." + }, "autoFullscreen": { "message": "Auto-fullscreen" }, From a345424c3d8d4175bbd6a9169b3dd746048f476e Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 14:59:03 +0200 Subject: [PATCH 12/16] Update satus.js more cleanup, removing obsolete flash detection --- menu/satus.js | 145 ++++++++++++++++---------------------------------- 1 file changed, 45 insertions(+), 100 deletions(-) diff --git a/menu/satus.js b/menu/satus.js index 06800afa4..19263d9bb 100644 --- a/menu/satus.js +++ b/menu/satus.js @@ -70,12 +70,15 @@ components.grid components.textField chart chart.bar select -components.divider() base(component) section - alert time sidebar +components.divider() + base(component) + section + time layers list colorPicker - radio slider + radio + slider tabs shortcut checkbox @@ -90,11 +93,14 @@ RGB2HSL HUE2RGB HSL2RGB # HARDWARE and SOFTWARE values # OS: Name Bitness # Browser: Name Version Platform - Manifest Languages + Manifest + Languages Cookies - Flash Java Audio - Video WebGL - # Device: Screen + Java + Audio + Video + WebGL + # Device: Screen RAM GPU Cores Touch Connection ---------------------------------------------------------------- @@ -239,34 +245,16 @@ satus.isset = function (target, is_object) { /*------------------------------------------------------------- # is___(target) --------------------------------------------------------------*/ -satus.isFunction =function (target) { - return typeof target ==='function'; -}; - +satus.isFunction = function (target) { return typeof target ==='function'; }; satus.isArray = Array.isArray; -satus.isString = function (t) { - return typeof t ==='string'; -}; -satus.isNumber = function (t) { - return (typeof t ==='number' && !isNaN(t)); -}; -satus.isObject = function (t) { - return (t instanceof Object && t !== null); -}; -satus.isElement = function (t) { - return (t instanceof Element || t instanceof HTMLDocument); -}; -satus.isNodeList = function (t) { - return t instanceof NodeList; -}; -satus.isBoolean = function (t) { - return (t === false || t === true); -}; +satus.isString = function (t) { return typeof t ==='string'; }; +satus.isNumber = function (t) { return (typeof t ==='number' && !isNaN(t)); }; +satus.isObject = function (t) { return (t instanceof Object && t !== null); }; +satus.isElement = function (t) { return (t instanceof Element || t instanceof HTMLDocument); }; +satus.isNodeList = function (t) { return t instanceof NodeList; }; +satus.isBoolean = function (t) { return (t === false || t === true); }; /*---LOG------------------------------------------------------*/ -satus.log =function () { - console.log.apply(null, arguments); -}; - +satus.log = function () { console.log.apply(null, arguments);}; /*-------------------------------------------------------------- # DOM @@ -521,8 +509,6 @@ satus.getProperty = function (object, string) { for (let i = 0, l = properties.length; i < l; i++) { const property = properties[i]; - console.log(object); - if (object === object[property]) { if (i === l - 1) { return object; @@ -567,7 +553,7 @@ satus.toIndex = function (index, child, parent) { satus.on = function (element, listeners) { if (listeners) { for (var type in listeners) { - if (type == 'parentObject') { + if (type === 'parentObject') { continue; } @@ -762,19 +748,18 @@ satus.render = function (skeleton, container, property, childrenOnly, prepend, s if (skeleton.storage != false) { element.storage = (function () { var parent = element, + // default storage is same as element name (property) key = skeleton.storage || property || false, value; - if (satus.isFunction(key)) { - key = key(); - } + if (satus.isFunction(key)) key = key(); if (skeleton.storage !== false) { if (key) { value = satus.storage.get(key); } - if (skeleton.hasOwnProperty('value') && value === undefined) { + if (Object.keys(skeleton).includes('value') && value === undefined) { value = skeleton.value; } } @@ -876,9 +861,7 @@ satus.storage.clear = function (callback) { chrome.storage.local.clear(function () { satus.events.trigger('storage-clear'); - if (callback) { - callback(); - } + if (callback) callback(); }); }; @@ -927,9 +910,7 @@ satus.storage.import = function (keys, callback) { } // satus.log('STORAGE: data was successfully imported'); satus.events.trigger('storage-import'); - if (callback) { - callback(items); - } + if (callback) callback(items); loading.style.display = 'none'; }); }; @@ -965,9 +946,7 @@ satus.storage.remove = function (key, callback) { chrome.storage.local.set(this.data, function () { satus.events.trigger('storage-remove'); - if (callback) { - callback(); - } + if (callback) callback(); }); } }; @@ -976,8 +955,7 @@ satus.storage.remove = function (key, callback) { # SET --------------------------------------------------------------*/ satus.storage.set = function (key, value, callback) { - var items = {}, - target = this.data; + var target = this.data; if (typeof key !== 'string') { return; @@ -1007,9 +985,7 @@ satus.storage.set = function (key, value, callback) { chrome.storage.local.set({[key]: value}, function () { satus.events.trigger('storage-set'); - if (callback) { - callback(); - } + if (callback) callback(); }); }; @@ -1125,7 +1101,7 @@ satus.text = function (element, value) { --------------------------------------------------------------*/ satus.components.modal = function (component, skeleton) { let content = skeleton.content; - + component.scrim = component.createChildElement('div', 'scrim'); component.surface = component.createChildElement('div', 'surface'); @@ -1284,8 +1260,8 @@ satus.components.textField = function (component, skeleton) { handlers: { regex: function (value, target) { var regex_token = /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g, - char_class_token = /[^\\-]+|-|\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)/g, - char_class_parts = /^(\[\^?)(]?(?:[^\\\]]+|\\[\S\s]?)*)(]?)$/, + //char_class_token = /[^\\-]+|-|\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)/g, + //char_class_parts = /^(\[\^?)(]?(?:[^\\\]]+|\\[\S\s]?)*)(]?)$/, quantifier = /^(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??$/, matches = value.match(regex_token); @@ -1416,14 +1392,13 @@ satus.components.textField = function (component, skeleton) { }; cursor.update = function () { - var component = this.parentNode.parentNode.parentNode, + const component = this.parentNode.parentNode.parentNode, input = component.input, value = input.value, - rows_count = value.split('\n').length, start = input.selectionStart, end = input.selectionEnd, - rows = value.slice(0, start).split('\n'), - top = 0; + rows = value.slice(0, start).split('\n'); + let top = 0; this.style.animation = 'none'; @@ -1466,7 +1441,7 @@ satus.components.textField = function (component, skeleton) { }; // global listener, make sure we remove when element no longer exists - function selectionchange (event) { + function selectionchange () { if (!document.body.contains(component)) { document.removeEventListener('selectionchange', selectionchange); return; @@ -1479,7 +1454,7 @@ satus.components.textField = function (component, skeleton) { document.addEventListener('selectionchange', selectionchange); input.addEventListener('input', function () { - var component = this.parentNode.parentNode; + const component = this.parentNode.parentNode; if (component.skeleton.storage) { component.storage.value = this.value; @@ -1490,8 +1465,8 @@ satus.components.textField = function (component, skeleton) { component.cursor.update(); }); - input.addEventListener('scroll', function (event) { - var component = this.parentNode.parentNode; + input.addEventListener('scroll', function () { + const component = this.parentNode.parentNode; component.display.style.top = -this.scrollTop + 'px'; component.display.style.left = -this.scrollLeft + 'px'; @@ -1677,11 +1652,6 @@ satus.components.base = function (component) { component.layers = []; }; /*-------------------------------------------------------------- ->>> ALERT ---------------------------------------------------------------*/ - -satus.components.alert = function (component, skeleton) {}; -/*-------------------------------------------------------------- >>> TIME --------------------------------------------------------------*/ satus.components.time = function (component, skeleton) { @@ -1727,11 +1697,6 @@ satus.components.time = function (component, skeleton) { component.classList.add('satus-select'); }; - -/*-------------------------------------------------------------- ->>> SIDEBAR ---------------------------------------------------------------*/ -satus.components.sidebar = function (component, skeleton) {}; /*-------------------------------------------------------------- >>> LAYERS --------------------------------------------------------------*/ @@ -1828,7 +1793,7 @@ satus.components.colorPicker = function (component, skeleton) { } }); - element.value = component.storage.value || component.skeleton.value || [0, 0, 0]; + element.value = component.storage.value || skeleton.value || [0, 0, 0]; return element; })(component.createChildElement('span', 'value')); @@ -1869,8 +1834,7 @@ satus.components.colorPicker = function (component, skeleton) { function mousemove (event) { var hsl = palette.skeleton.parentSkeleton.value, x = event.clientX - rect.left, - y = event.clientY - rect.top, - s; + y = event.clientY - rect.top; x = Math.min(Math.max(x, 0), rect.width) / (rect.width / 100); y = Math.min(Math.max(y, 0), rect.height) / (rect.height / 100); @@ -2843,7 +2807,6 @@ satus.color.hslToRgb = function (array) { # Manifest # Languages # Cookies - # Flash # Java # Audio # Video @@ -3003,24 +2966,6 @@ satus.user.browser.cookies = function () { return false; }; -/*-------------------------------------------------------------- -# FLASH ---------------------------------------------------------------*/ - -satus.user.browser.flash = function () { - try { - if (new ActiveXObject('ShockwaveFlash.ShockwaveFlash')) { - return true; - } - } catch (error) { - if (navigator.mimeTypes['application/x-shockwave-flash']) { - return true; - } - } - - return false; -}; - /*-------------------------------------------------------------- # JAVA --------------------------------------------------------------*/ @@ -3164,7 +3109,7 @@ satus.user.device.touch = function () { var result = {}; if ( - window.hasOwnProperty('ontouchstart') || + Object.keys(window).includes('ontouchstart') || window.DocumentTouch && document instanceof window.DocumentTouch || navigator.maxTouchPoints > 0 || window.navigator.msMaxTouchPoints > 0 @@ -3214,7 +3159,7 @@ satus.search = function (query, object, callback) { query = query.toLowerCase(); - function parse (items, parent) { + function parse (items) { threads++; for (const [key, item] of Object.entries(items)) { @@ -3234,7 +3179,7 @@ satus.search = function (query, object, callback) { && !satus.isArray(item) && !satus.isElement(item) && !satus.isFunction(item)) { - parse(item, items); + parse(item); } } } From 56332f07f6f16f1fa9d90ff1a12521aa45259279 Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 15:00:00 +0200 Subject: [PATCH 13/16] Update settings.js obsolete flash detection --- menu/skeleton-parts/settings.js | 1 - 1 file changed, 1 deletion(-) diff --git a/menu/skeleton-parts/settings.js b/menu/skeleton-parts/settings.js index aa4af84e9..1bf37d16c 100644 --- a/menu/skeleton-parts/settings.js +++ b/menu/skeleton-parts/settings.js @@ -700,7 +700,6 @@ extension.skeleton.header.sectionEnd.menu.on.click.settings.on.click.secondSecti ['platform', satus.user.browser.platform()], ['audioFormats', satus.user.browser.audio().join(', ')], ['videoFormats', satus.user.browser.video().join(', ')], - ['Flash', satus.user.browser.flash()], ['Java', satus.user.browser.java()], ['Cookies', satus.user.browser.cookies()] ] From 2ecdf483cb412c229c657887997b9a406c530d0a Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 15:24:01 +0200 Subject: [PATCH 14/16] player.js hide Auto PiP in browsers not supporting Chrome PiP API --- menu/skeleton-parts/player.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/menu/skeleton-parts/player.js b/menu/skeleton-parts/player.js index c1a1b7bff..c93d11e06 100644 --- a/menu/skeleton-parts/player.js +++ b/menu/skeleton-parts/player.js @@ -101,6 +101,7 @@ extension.skeleton.main.layers.section.player.on.click = { custom: true, on: { click: function () { + if (!document.pictureInPictureEnabled) return; if (this.dataset.value === 'false') { let where = this; satus.render({ @@ -129,7 +130,16 @@ extension.skeleton.main.layers.section.player.on.click = { player_autoPip_outside: { component: 'switch', text: 'playerAutoPipOutside', - value: true + id: 'player_autoPip_outside', + value: true, + on: { + render: function () { + if (!document.pictureInPictureEnabled) { + document.getElementById('player_autoPip').remove(); + document.getElementById('player_autoPip_outside').remove(); + } + } + } }, player_forced_volume: { component: 'switch', From 6394cb6740e79e11348dfe3a4c6cc974456bbbb8 Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 16:11:59 +0200 Subject: [PATCH 15/16] Update player.js player_quality fix --- menu/skeleton-parts/player.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/menu/skeleton-parts/player.js b/menu/skeleton-parts/player.js index c93d11e06..8712fb82e 100644 --- a/menu/skeleton-parts/player.js +++ b/menu/skeleton-parts/player.js @@ -747,7 +747,7 @@ extension.skeleton.main.layers.section.player.on.click = { text: '1440p', value: 'hd1440' }, { - text: '2160p', + text: '2160p (4K UHD)', value: 'hd2160' }, { text: '2880p', @@ -758,25 +758,31 @@ extension.skeleton.main.layers.section.player.on.click = { }], on: { render: function () { + // relies on options.text above auto always starting with a number for parseInt to work + const options = this.childNodes[2].options, + index = this.childNodes[2].selectedIndex; + cutoff = 1080; if (satus.storage.get('player_h264')) { - if (this.childNodes[2].selectedIndex >6) { + if (parseInt(options[index].text) > cutoff) { this.childNodes[1].style = 'color: red!important; font-weight: bold;'; this.childNodes[1].textContent = '1080p'; } else { - this.childNodes[1].style = ''; - this.childNodes[1].textContent = this.childNodes[2].options[this.childNodes[2].selectedIndex].text; + this.childNodes[1].removeAttribute('style'); + this.childNodes[1].textContent = options[index].text; } - for (let index =7; index <= 10; index++) { - this.childNodes[2].childNodes[index].style = 'color: red!important; font-weight: bold;'; + for (const [i, node] of Array.from(options).entries()) { + if (parseInt(node.text) > cutoff) { + this.childNodes[2].childNodes[i].style = 'color: red!important; font-weight: bold;'; + } } } else if (satus.storage.get('block_vp9') && satus.storage.get('block_h264')) { this.childNodes[1].style = 'color: red!important; font-weight: bold;'; this.childNodes[1].textContent = 'Video disabled'; } else { - this.childNodes[1].style = ''; - this.childNodes[1].textContent = this.childNodes[2].options[this.childNodes[2].selectedIndex].text; - for (let index =7; index <= 10; index++) { - this.childNodes[2].childNodes[index].style = ''; + this.childNodes[1].removeAttribute('style'); + this.childNodes[1].textContent = options[index].text; + for (const node of options) { + node.removeAttribute('style'); } } } From 5b54b12e13b84694fe10a2b45439f5a51c23ecd9 Mon Sep 17 00:00:00 2001 From: Rasz_pl Date: Sun, 7 Jul 2024 16:12:58 +0200 Subject: [PATCH 16/16] Update messages.json redundant entry --- _locales/en/messages.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 18a08750c..37c4cce95 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -41,9 +41,6 @@ "hideLogo": { "message": "Logo: Hide!" }, - "2160p": { - "message": "2160p - 4K" - }, "about": { "message": "About" },