Jelajahi Sumber

chore: build

Sv443 1 tahun lalu
induk
melakukan
91ed52392d
1 mengubah file dengan 184 tambahan dan 103 penghapusan
  1. 184 103
      dist/BetterYTM.user.js

+ 184 - 103
dist/BetterYTM.user.js

@@ -17,7 +17,7 @@
 // @license           AGPL-3.0-only
 // @author            Sv443
 // @copyright         Sv443 (https://github.com/Sv443)
-// @icon              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/logo/logo_48.png?b=1486137
+// @icon              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/logo/logo_48.png?b=19c129f
 // @match             https://music.youtube.com/*
 // @match             https://www.youtube.com/*
 // @run-at            document-start
@@ -35,38 +35,38 @@
 // @grant             GM.openInTab
 // @grant             unsafeWindow
 // @noframes
-// @resource          css-anchor_improvements https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/style/anchorImprovements.css?b=1486137
-// @resource          css-fix_spacing         https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/style/fixSpacing.css?b=1486137
-// @resource          doc-changelog           https://raw.githubusercontent.com/Sv443/BetterYTM/develop/changelog.md?b=1486137
-// @resource          icon-advanced_mode      https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/plus_circle_small.svg?b=1486137
-// @resource          icon-arrow_down         https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/arrow_down.svg?b=1486137
-// @resource          icon-delete             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/delete.svg?b=1486137
-// @resource          icon-error              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/error.svg?b=1486137
-// @resource          icon-experimental       https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/beaker_small.svg?b=1486137
-// @resource          icon-globe              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/globe.svg?b=1486137
-// @resource          icon-help               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/help.svg?b=1486137
-// @resource          icon-image              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/image.svg?b=1486137
-// @resource          icon-image_filled       https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/image_filled.svg?b=1486137
-// @resource          icon-link               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/link.svg?b=1486137
-// @resource          icon-lyrics             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/lyrics.svg?b=1486137
-// @resource          icon-skip_to            https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/skip_to.svg?b=1486137
-// @resource          icon-spinner            https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/spinner.svg?b=1486137
-// @resource          img-logo                https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/logo/logo_48.png?b=1486137
-// @resource          img-close               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/close.png?b=1486137
-// @resource          img-discord             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/discord.png?b=1486137
-// @resource          img-github              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/github.png?b=1486137
-// @resource          img-greasyfork          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/greasyfork.png?b=1486137
-// @resource          img-openuserjs          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/openuserjs.png?b=1486137
-// @resource          trans-de_DE             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/de_DE.json?b=1486137
-// @resource          trans-en_US             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/en_US.json?b=1486137
-// @resource          trans-en_UK             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/en_UK.json?b=1486137
-// @resource          trans-es_ES             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/es_ES.json?b=1486137
-// @resource          trans-fr_FR             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/fr_FR.json?b=1486137
-// @resource          trans-hi_IN             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/hi_IN.json?b=1486137
-// @resource          trans-ja_JA             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/ja_JA.json?b=1486137
-// @resource          trans-pt_BR             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/pt_BR.json?b=1486137
-// @resource          trans-zh_CN             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/zh_CN.json?b=1486137
-// @require           https://cdn.jsdelivr.net/npm/@sv443-network/userutils@6.1.0/dist/index.global.js
+// @resource          css-anchor_improvements https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/style/anchorImprovements.css?b=19c129f
+// @resource          css-fix_spacing         https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/style/fixSpacing.css?b=19c129f
+// @resource          doc-changelog           https://raw.githubusercontent.com/Sv443/BetterYTM/develop/changelog.md?b=19c129f
+// @resource          icon-advanced_mode      https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/plus_circle_small.svg?b=19c129f
+// @resource          icon-arrow_down         https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/arrow_down.svg?b=19c129f
+// @resource          icon-delete             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/delete.svg?b=19c129f
+// @resource          icon-error              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/error.svg?b=19c129f
+// @resource          icon-experimental       https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/beaker_small.svg?b=19c129f
+// @resource          icon-globe              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/globe.svg?b=19c129f
+// @resource          icon-help               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/help.svg?b=19c129f
+// @resource          icon-image              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/image.svg?b=19c129f
+// @resource          icon-image_filled       https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/image_filled.svg?b=19c129f
+// @resource          icon-link               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/link.svg?b=19c129f
+// @resource          icon-lyrics             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/lyrics.svg?b=19c129f
+// @resource          icon-skip_to            https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/skip_to.svg?b=19c129f
+// @resource          icon-spinner            https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/icons/spinner.svg?b=19c129f
+// @resource          img-logo                https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/logo/logo_48.png?b=19c129f
+// @resource          img-close               https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/close.png?b=19c129f
+// @resource          img-discord             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/discord.png?b=19c129f
+// @resource          img-github              https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/github.png?b=19c129f
+// @resource          img-greasyfork          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/greasyfork.png?b=19c129f
+// @resource          img-openuserjs          https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/images/external/openuserjs.png?b=19c129f
+// @resource          trans-de_DE             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/de_DE.json?b=19c129f
+// @resource          trans-en_US             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/en_US.json?b=19c129f
+// @resource          trans-en_UK             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/en_UK.json?b=19c129f
+// @resource          trans-es_ES             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/es_ES.json?b=19c129f
+// @resource          trans-fr_FR             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/fr_FR.json?b=19c129f
+// @resource          trans-hi_IN             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/hi_IN.json?b=19c129f
+// @resource          trans-ja_JA             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/ja_JA.json?b=19c129f
+// @resource          trans-pt_BR             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/pt_BR.json?b=19c129f
+// @resource          trans-zh_CN             https://raw.githubusercontent.com/Sv443/BetterYTM/develop/assets/translations/zh_CN.json?b=19c129f
+// @require           https://cdn.jsdelivr.net/npm/@sv443-network/userutils@6.2.0/dist/index.global.js
 // @require           https://cdn.jsdelivr.net/npm/[email protected]/dist/fuse.basic.js
 // @require           https://cdn.jsdelivr.net/npm/[email protected]/lib/marked.umd.js
 // @grant             GM.registerMenuCommand
@@ -193,7 +193,7 @@ var PluginIntent;
 })(PluginIntent || (PluginIntent = {}));const modeRaw = "development";
 const branchRaw = "develop";
 const hostRaw = "github";
-const buildNumberRaw = "1486137";
+const buildNumberRaw = "19c129f";
 /** The mode in which the script was built (production or development) */
 const mode = (modeRaw.match(/^#{{.+}}$/) ? "production" : modeRaw);
 /** The branch to use in various URLs that point to the GitHub repo */
@@ -807,6 +807,33 @@ class BytmDialog extends NanoEmitter {
             return dialogWrapperEl;
         });
     }
+}/**
+ * Creates a generic button element.
+ * If `href` is provided, the button will be an anchor element.
+ * If `onClick` is provided, the button will be a div element.
+ */
+function createGenericBtn({ resourceName, title, href, onClick, }) {
+    return __awaiter(this, void 0, void 0, function* () {
+        let btnElem;
+        if (href) {
+            btnElem = document.createElement("a");
+            btnElem.href = href;
+            btnElem.role = "button";
+            btnElem.target = "_blank";
+            btnElem.rel = "noopener noreferrer";
+        }
+        else {
+            btnElem = document.createElement("div");
+            onClick && onInteraction(btnElem, onClick);
+        }
+        btnElem.classList.add("bytm-generic-btn");
+        btnElem.ariaLabel = btnElem.title = title;
+        const imgElem = document.createElement("img");
+        imgElem.classList.add("bytm-generic-btn-img");
+        imgElem.src = yield getResourceUrl(resourceName);
+        btnElem.appendChild(imgElem);
+        return btnElem;
+    });
 }/** Array of all site events */
 const allSiteEvents = [
     "configChanged",
@@ -1148,7 +1175,7 @@ var updates = {
 	openuserjs: "https://openuserjs.org/scripts/Sv443/BetterYTM"
 };
 var dependencies = {
-	"@sv443-network/userutils": "^6.1.0",
+	"@sv443-network/userutils": "^6.2.0",
 	"fuse.js": "^7.0.0",
 	marked: "^12.0.0",
 	nanoevents: "^9.0.0"
@@ -2869,8 +2896,8 @@ function exchangeLogo() {
         }),
     });
 }
-/** Called whenever the avatar popover menu exists to add a BYTM-Configuration button to the user menu popover */
-function addConfigMenuOption(container) {
+/** Called whenever the avatar popover menu exists on YTM to add a BYTM config menu button to the user menu popover */
+function addConfigMenuOptionYTM(container) {
     return __awaiter(this, void 0, void 0, function* () {
         const cfgOptElem = document.createElement("div");
         cfgOptElem.className = "bytm-cfg-menu-option";
@@ -2902,6 +2929,28 @@ function addConfigMenuOption(container) {
         log("Added BYTM-Configuration button to menu popover");
     });
 }
+/** Called whenever the titlebar (masthead) exists on YT to add a BYTM config menu button */
+function addConfigMenuOptionYT(container) {
+    return __awaiter(this, void 0, void 0, function* () {
+        const btnElem = yield createGenericBtn({
+            resourceName: "img-logo",
+            title: t("open_menu_tooltip", scriptInfo.name),
+            onClick(e) {
+                if ((!e.shiftKey && !e.ctrlKey) || logoExchanged)
+                    openCfgMenu();
+                if (!logoExchanged && (e.shiftKey || e.ctrlKey))
+                    exchangeLogo();
+            },
+        });
+        const firstChild = container.firstElementChild;
+        if (firstChild)
+            container.insertBefore(btnElem, firstChild);
+        else {
+            const notifEl = container.querySelector("ytd-notification-topbar-button-renderer");
+            notifEl && UserUtils.insertAfter(notifEl, btnElem);
+        }
+    });
+}
 //#MARKER remove upgrade tab
 /** Removes the "Upgrade" / YT Music Premium tab from the sidebar */
 function removeUpgradeTab() {
@@ -4898,79 +4947,103 @@ function getFeaturesInterface() {
 }/** Options that are applied to every SelectorObserver instance */
 const defaultObserverOptions = {
     defaultDebounce: 100,
+    defaultDebounceEdge: "rising",
 };
 /** Global SelectorObserver instances usable throughout the script for improved performance */
 const globservers = {};
 /** Call after DOM load to initialize all SelectorObserver instances */
 function initObservers() {
     try {
+        //#MARKER both sites
         // #SECTION body = the entire <body> element - use sparingly due to performance impacts!
-        globservers.body = new UserUtils.SelectorObserver(document.body, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: false }));
+        globservers.body = new UserUtils.SelectorObserver(document.body, Object.assign(Object.assign({}, defaultObserverOptions), { defaultDebounce: 150, subtree: false }));
         globservers.body.enable();
-        if (getDomain() !== "ytm")
-            return;
-        //#SECTION navBar = the navigation / title bar at the top of the page
-        const navBarSelector = "ytmusic-nav-bar";
-        globservers.navBar = new UserUtils.SelectorObserver(navBarSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: false }));
-        globservers.body.addListener(navBarSelector, {
-            listener: () => globservers.navBar.enable(),
-        });
-        // #SECTION mainPanel = the main content panel - includes things like the video element
-        const mainPanelSelector = "ytmusic-player-page #main-panel";
-        globservers.mainPanel = new UserUtils.SelectorObserver(mainPanelSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
-        globservers.body.addListener(mainPanelSelector, {
-            listener: () => globservers.mainPanel.enable(),
-        });
-        // #SECTION sideBar = the sidebar on the left side of the page
-        const sidebarSelector = "ytmusic-app-layout tp-yt-app-drawer";
-        globservers.sideBar = new UserUtils.SelectorObserver(sidebarSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
-        globservers.body.addListener(sidebarSelector, {
-            listener: () => globservers.sideBar.enable(),
-        });
-        // #SECTION sideBarMini = the minimized sidebar on the left side of the page
-        const sideBarMiniSelector = "ytmusic-app-layout #mini-guide";
-        globservers.sideBarMini = new UserUtils.SelectorObserver(sideBarMiniSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
-        globservers.body.addListener(sideBarMiniSelector, {
-            listener: () => globservers.sideBarMini.enable(),
-        });
-        // #SECTION sidePanel = the side panel on the right side of the /watch page
-        const sidePanelSelector = "#side-panel";
-        globservers.sidePanel = new UserUtils.SelectorObserver(sidePanelSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
-        globservers.body.addListener(sidePanelSelector, {
-            listener: () => globservers.sidePanel.enable(),
-        });
-        // #SECTION playerBar = media controls bar at the bottom of the page
-        const playerBarSelector = "ytmusic-app-layout ytmusic-player-bar.ytmusic-app";
-        globservers.playerBar = new UserUtils.SelectorObserver(playerBarSelector, Object.assign(Object.assign({}, defaultObserverOptions), { defaultDebounce: 200 }));
-        globservers.body.addListener(playerBarSelector, {
-            listener: () => {
-                globservers.playerBar.enable();
-            },
-        });
-        // #SECTION playerBarInfo = song title, artist, album, etc. inside the player bar
-        const playerBarInfoSelector = `${playerBarSelector} .middle-controls .content-info-wrapper`;
-        globservers.playerBarInfo = new UserUtils.SelectorObserver(playerBarInfoSelector, Object.assign(Object.assign({}, defaultObserverOptions), { attributes: true, attributeFilter: ["title"] }));
-        globservers.playerBarInfo.addListener(playerBarInfoSelector, {
-            listener: () => globservers.playerBarInfo.enable(),
-        });
-        // #SECTION playerBarMiddleButtons = the buttons inside the player bar (like, dislike, lyrics, etc.)
-        const playerBarMiddleButtonsSelector = ".middle-controls .middle-controls-buttons";
-        globservers.playerBarMiddleButtons = new UserUtils.SelectorObserver(playerBarMiddleButtonsSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
-        globservers.playerBar.addListener(playerBarMiddleButtonsSelector, {
-            listener: () => globservers.playerBarMiddleButtons.enable(),
-        });
-        // #SECTION playerBarRightControls = the controls on the right side of the player bar (volume, repeat, shuffle, etc.)
-        const playerBarRightControls = ".right-controls .middle-controls-buttons";
-        globservers.playerBarRightControls = new UserUtils.SelectorObserver(playerBarRightControls, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
-        globservers.playerBar.addListener(playerBarRightControls, {
-            listener: () => globservers.playerBarRightControls.enable(),
-        });
-        // #SECTION popupContainer = the container for popups (e.g. the queue popup)
-        const popupContainerSelector = "ytmusic-app ytmusic-popup-container";
-        globservers.popupContainer = new UserUtils.SelectorObserver(popupContainerSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
-        globservers.body.addListener(popupContainerSelector, {
-            listener: () => globservers.popupContainer.enable(),
-        });
+        switch (getDomain()) {
+            case "ytm": {
+                //#MARKER YTM
+                //#SECTION navBar = the navigation / title bar at the top of the page
+                const navBarSelector = "ytmusic-nav-bar";
+                globservers.navBar = new UserUtils.SelectorObserver(navBarSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: false }));
+                globservers.body.addListener(navBarSelector, {
+                    listener: () => globservers.navBar.enable(),
+                });
+                // #SECTION mainPanel = the main content panel - includes things like the video element
+                const mainPanelSelector = "ytmusic-player-page #main-panel";
+                globservers.mainPanel = new UserUtils.SelectorObserver(mainPanelSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.body.addListener(mainPanelSelector, {
+                    listener: () => globservers.mainPanel.enable(),
+                });
+                // #SECTION sideBar = the sidebar on the left side of the page
+                const sidebarSelector = "ytmusic-app-layout tp-yt-app-drawer";
+                globservers.sideBar = new UserUtils.SelectorObserver(sidebarSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.body.addListener(sidebarSelector, {
+                    listener: () => globservers.sideBar.enable(),
+                });
+                // #SECTION sideBarMini = the minimized sidebar on the left side of the page
+                const sideBarMiniSelector = "ytmusic-app-layout #mini-guide";
+                globservers.sideBarMini = new UserUtils.SelectorObserver(sideBarMiniSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.body.addListener(sideBarMiniSelector, {
+                    listener: () => globservers.sideBarMini.enable(),
+                });
+                // #SECTION sidePanel = the side panel on the right side of the /watch page
+                const sidePanelSelector = "#side-panel";
+                globservers.sidePanel = new UserUtils.SelectorObserver(sidePanelSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.body.addListener(sidePanelSelector, {
+                    listener: () => globservers.sidePanel.enable(),
+                });
+                // #SECTION playerBar = media controls bar at the bottom of the page
+                const playerBarSelector = "ytmusic-app-layout ytmusic-player-bar.ytmusic-app";
+                globservers.playerBar = new UserUtils.SelectorObserver(playerBarSelector, Object.assign(Object.assign({}, defaultObserverOptions), { defaultDebounce: 200 }));
+                globservers.body.addListener(playerBarSelector, {
+                    listener: () => {
+                        globservers.playerBar.enable();
+                    },
+                });
+                // #SECTION playerBarInfo = song title, artist, album, etc. inside the player bar
+                const playerBarInfoSelector = `${playerBarSelector} .middle-controls .content-info-wrapper`;
+                globservers.playerBarInfo = new UserUtils.SelectorObserver(playerBarInfoSelector, Object.assign(Object.assign({}, defaultObserverOptions), { attributes: true, attributeFilter: ["title"] }));
+                globservers.playerBarInfo.addListener(playerBarInfoSelector, {
+                    listener: () => globservers.playerBarInfo.enable(),
+                });
+                // #SECTION playerBarMiddleButtons = the buttons inside the player bar (like, dislike, lyrics, etc.)
+                const playerBarMiddleButtonsSelector = ".middle-controls .middle-controls-buttons";
+                globservers.playerBarMiddleButtons = new UserUtils.SelectorObserver(playerBarMiddleButtonsSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.playerBar.addListener(playerBarMiddleButtonsSelector, {
+                    listener: () => globservers.playerBarMiddleButtons.enable(),
+                });
+                // #SECTION playerBarRightControls = the controls on the right side of the player bar (volume, repeat, shuffle, etc.)
+                const playerBarRightControls = ".right-controls .middle-controls-buttons";
+                globservers.playerBarRightControls = new UserUtils.SelectorObserver(playerBarRightControls, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.playerBar.addListener(playerBarRightControls, {
+                    listener: () => globservers.playerBarRightControls.enable(),
+                });
+                // #SECTION popupContainer = the container for popups (e.g. the queue popup)
+                const popupContainerSelector = "ytmusic-app ytmusic-popup-container";
+                globservers.popupContainer = new UserUtils.SelectorObserver(popupContainerSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.body.addListener(popupContainerSelector, {
+                    listener: () => globservers.popupContainer.enable(),
+                });
+                break;
+            }
+            case "yt": {
+                //#MARKER YT
+                // #SECTION ytGuide = the left sidebar menu
+                const ytGuideSelector = "#content tp-yt-app-drawer#guide #guide-inner-content";
+                globservers.ytGuide = new UserUtils.SelectorObserver(ytGuideSelector, Object.assign(Object.assign({}, defaultObserverOptions), { subtree: true }));
+                globservers.body.addListener(ytGuideSelector, {
+                    listener: () => globservers.ytGuide.enable(),
+                });
+                // // #SECTION ytMasthead = the masthead at the top of the page
+                // const mastheadSelector = "#content ytd-masthead#masthead";
+                // globservers.ytMasthead = new SelectorObserver(mastheadSelector, {
+                //   ...defaultObserverOptions,
+                //   subtree: true,
+                // });
+                // globservers.body.addListener(mastheadSelector, {
+                //   listener: () => globservers.ytMasthead.enable(),
+                // });
+            }
+        }
         //#SECTION finalize
         emitInterface("bytm:observersReady");
     }
@@ -4981,6 +5054,9 @@ function initObservers() {
 /**
  * Interface function for adding listeners to the {@linkcode globservers}
  * @param selector Relative to the observer's root element, so the selector can only start at of the root element's children at the earliest!
+ * @param options Options for the listener
+ * @template TElem The type of the element that the listener will be attached to. If set to `0`, the type HTMLElement will be used.
+ * @template TDomain This restricts which observers are available with the current domain
  */
 function addSelectorListener(observerName, selector, options) {
     globservers[observerName].addListener(selector, options);
@@ -5658,7 +5734,7 @@ function onDomLoad() {
                     yield GM.setValue("bytm-installed", JSON.stringify({ timestamp: Date.now(), version: scriptInfo.version }));
                 }
                 addSelectorListener("body", "tp-yt-iron-dropdown #contentWrapper ytd-multi-page-menu-renderer #container.menu-container", {
-                    listener: addConfigMenuOption,
+                    listener: addConfigMenuOptionYTM,
                 });
                 if (features.arrowKeySupport)
                     ftInit.push(initArrowKeySkip());
@@ -5685,6 +5761,11 @@ function onDomLoad() {
                     ftInit.push(initHideCursorOnIdle());
                 ftInit.push(initVolumeFeatures());
             }
+            if (domain === "yt") {
+                addSelectorListener("ytGuide", "#sections ytd-guide-section-renderer:nth-child(5) #items ytd-guide-entry-renderer:nth-child(1)", {
+                    listener: (el) => el.parentElement && addConfigMenuOptionYT(el.parentElement),
+                });
+            }
             if (["ytm", "yt"].includes(domain)) {
                 if (features.switchBetweenSites)
                     ftInit.push(initSiteSwitch(domain));