Sv443 1 gadu atpakaļ
vecāks
revīzija
3bbf438bd4
1 mainītis faili ar 84 papildinājumiem un 12 dzēšanām
  1. 84 12
      dist/BetterYTM.user.js

+ 84 - 12
dist/BetterYTM.user.js

@@ -487,7 +487,7 @@ const scriptInfo = Object.freeze({
     name: GM.info.script.name,
     version: GM.info.script.version,
     namespace: GM.info.script.namespace,
-    lastCommit: "d2eee28", // assert as generic string instead of union
+    lastCommit: "1d36fe9", // assert as generic string instead of union
 });
 
 
@@ -663,7 +663,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
- // TODO
+
 
 /** Contains all possible features with their default values and other config */
 const featInfo = {
@@ -699,11 +699,10 @@ const featInfo = {
         default: false,
     },
     anchorImprovements: {
-        desc: "TODO: Make it so middle clicking a song to open it in a new tab is easier",
+        desc: "Make it so middle clicking a song to open it in a new tab is easier",
         type: "toggle",
         category: "input",
         default: true,
-        visible: false,
     },
     //#SECTION layout
     removeUpgradeTab: {
@@ -1170,8 +1169,59 @@ function addQueueButtons(queueItem) {
 }
 //#MARKER better clickable stuff
 // TODO: account for the fact initially the elements might not exist, if the site was opened directly with the /watch path
+/** Adds anchors around elements and tweaks existing ones so songs are easier to open in a new tab */
 function addAnchorImprovements() {
-    void 0;
+    /** Only adds anchor improvements for carousel shelves that contain the regular list-item-renderer, not the two-row-item-renderer */
+    const conditionalAnchorImprovements = (el) => {
+        const listItemRenderer = el.querySelector("ytmusic-responsive-list-item-renderer");
+        if (listItemRenderer) {
+            const itemsElem = el.querySelector("ul#items");
+            if (itemsElem) {
+                (0,_utils__WEBPACK_IMPORTED_MODULE_2__.log)("Adding anchor improvements to carousel shelf");
+                improveCarouselAnchors(itemsElem);
+            }
+        }
+    };
+    // initial three shelves aren't included in the event fire
+    (0,_utils__WEBPACK_IMPORTED_MODULE_2__.onSelectorExists)("ytmusic-carousel-shelf-renderer", () => {
+        const carouselShelves = document.body.querySelectorAll("ytmusic-carousel-shelf-renderer");
+        carouselShelves.forEach(conditionalAnchorImprovements);
+    });
+    // every shelf that's loaded by scrolling:
+    _events__WEBPACK_IMPORTED_MODULE_3__.siteEvents.on("carouselShelvesChanged", (evt) => {
+        const { addedNodes, removedNodes } = (0,_events__WEBPACK_IMPORTED_MODULE_3__.getEvtData)(evt);
+        void removedNodes;
+        if (addedNodes.length > 0)
+            addedNodes.forEach(conditionalAnchorImprovements);
+    });
+}
+/**
+ * Actually adds the anchor improvements to carousel shelf items
+ * @param itemsElement The container with the selector `ul#items` inside of each `ytmusic-carousel`
+ */
+function improveCarouselAnchors(itemsElement) {
+    if (itemsElement.classList.contains("bytm-anchors-improved"))
+        return;
+    itemsElement.classList.add("bytm-anchors-improved");
+    for (const listItem of itemsElement.querySelectorAll("ytmusic-responsive-list-item-renderer")) {
+        try {
+            const thumbnailElem = listItem.querySelector(".left-items");
+            const titleElem = listItem.querySelector(".title-column yt-formatted-string.title a");
+            if (!thumbnailElem || !titleElem) {
+                (0,_utils__WEBPACK_IMPORTED_MODULE_2__.error)("Couldn't add carousel shelf anchor improvements because either the thumbnail or title element couldn't be found");
+                continue;
+            }
+            const thumbnailAnchor = document.createElement("a");
+            thumbnailAnchor.className = "bytm-carousel-shelf-anchor";
+            thumbnailAnchor.href = titleElem.href;
+            thumbnailAnchor.target = "_self";
+            thumbnailAnchor.role = "button";
+            (0,_utils__WEBPACK_IMPORTED_MODULE_2__.addParent)(thumbnailElem, thumbnailAnchor);
+        }
+        catch (err) {
+            (0,_utils__WEBPACK_IMPORTED_MODULE_2__.error)("Couldn't add anchor improvements due to error:", err);
+        }
+    }
 }
 
 
@@ -1819,6 +1869,7 @@ function openMenu() {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
 /* harmony export */   addGlobalStyle: function() { return /* binding */ addGlobalStyle; },
+/* harmony export */   addParent: function() { return /* binding */ addParent; },
 /* harmony export */   autoPlural: function() { return /* binding */ autoPlural; },
 /* harmony export */   clamp: function() { return /* binding */ clamp; },
 /* harmony export */   dbg: function() { return /* binding */ dbg; },
@@ -1834,7 +1885,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export */   onSelectorExists: function() { return /* binding */ onSelectorExists; },
 /* harmony export */   openInNewTab: function() { return /* binding */ openInNewTab; },
 /* harmony export */   pauseFor: function() { return /* binding */ pauseFor; },
-/* harmony export */   precacheImage: function() { return /* binding */ precacheImage; },
+/* harmony export */   precacheImages: function() { return /* binding */ precacheImages; },
 /* harmony export */   setLogLevel: function() { return /* binding */ setLogLevel; },
 /* harmony export */   warn: function() { return /* binding */ warn; }
 /* harmony export */ });
@@ -1958,6 +2009,15 @@ function insertAfter(beforeNode, afterNode) {
     (_a = beforeNode.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(afterNode, beforeNode.nextSibling);
     return afterNode;
 }
+/** Adds a parent container around the provided element - returns the new parent node */
+function addParent(element, newParent) {
+    const oldParent = element.parentNode;
+    if (!oldParent)
+        throw new Error("Element doesn't have a parent node");
+    oldParent.replaceChild(newParent, element);
+    newParent.appendChild(element);
+    return newParent;
+}
 /**
  * Adds global CSS style through a `<style>` element in the document's `<head>`
  * @param style CSS string
@@ -2006,14 +2066,15 @@ function initSelectorExistsCheck() {
     });
     log("Initialized \"selector exists\" MutationObserver");
 }
-/** Preloads an image by URL so it can be loaded from cache later on */
-function precacheImage(src, rejects = false) {
-    return new Promise((res, rej) => {
+/** Preloads an array of image URLs so they can be loaded instantly from cache later on */
+function precacheImages(srcUrls, rejects = false) {
+    const promises = srcUrls.map(src => new Promise((res, rej) => {
         const image = new Image();
         image.src = src;
         image.addEventListener("load", () => res(image));
         image.addEventListener("error", () => rejects && rej(`Failed to preload image with URL '${src}'`));
-    });
+    }));
+    return Promise.allSettled(promises);
 }
 //#SECTION misc
 /**
@@ -2203,8 +2264,9 @@ function init() {
         yield (0,_features_index__WEBPACK_IMPORTED_MODULE_4__.preInitLayout)();
         try {
             document.addEventListener("DOMContentLoaded", onDomLoad);
-            Promise.all(precacheImgs.map(imgSrc => (0,_utils__WEBPACK_IMPORTED_MODULE_2__.precacheImage)(imgSrc)))
-                .then(() => (0,_utils__WEBPACK_IMPORTED_MODULE_2__.log)(`Pre-cached ${precacheImgs.length} images`));
+            (0,_utils__WEBPACK_IMPORTED_MODULE_2__.precacheImages)(precacheImgs)
+                .then(() => (0,_utils__WEBPACK_IMPORTED_MODULE_2__.log)(`Pre-cached ${precacheImgs.length} images`))
+                .catch((e) => (0,_utils__WEBPACK_IMPORTED_MODULE_2__.error)(`Pre-caching error: ${e}`));
         }
         catch (err) {
             console.error(`${_constants__WEBPACK_IMPORTED_MODULE_1__.scriptInfo.name} - General Error:`, err);
@@ -2413,6 +2475,16 @@ ytmusic-app ytmusic-popup-container tp-yt-iron-dropdown[data-bytm-hidden=true] {
   display: none !important;
 }
 
+/* #MARKER anchor improvements */
+
+ytmusic-responsive-list-item-renderer .left-items {
+  margin-right: 0 !important;
+}
+
+.bytm-carousel-shelf-anchor {
+  margin: 0 var(--ytmusic-responsive-list-item-thumbnail-margin-right, 16px) 0 0;
+}
+
 /*!******************************************************************************!*\
   !*** css ./node_modules/css-loader/dist/cjs.js!./src/features/menu/menu.css ***!
   \******************************************************************************/