Ver código fonte

ref: better way to open urls in a new tab

Sv443 1 ano atrás
pai
commit
99ce92eb66

+ 4 - 4
package-lock.json

@@ -9,7 +9,7 @@
       "version": "1.1.1",
       "license": "AGPL-3.0-only",
       "dependencies": {
-        "@sv443-network/userutils": "^6.2.0",
+        "@sv443-network/userutils": "^6.3.0",
         "fuse.js": "^7.0.0",
         "marked": "^12.0.0",
         "nanoevents": "^9.0.0"
@@ -600,9 +600,9 @@
       ]
     },
     "node_modules/@sv443-network/userutils": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/@sv443-network/userutils/-/userutils-6.2.0.tgz",
-      "integrity": "sha512-28D+8uBd0Z5UWg4YASgM5RB6u2QMgX180UKLrg+Hz42Hlh8mXTpe9HgthxEo8zLtMfPP/M5ykrOw1PcGhW+2aQ=="
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@sv443-network/userutils/-/userutils-6.3.0.tgz",
+      "integrity": "sha512-YNszpjAJPqQiwpRaA+gHROlJkiL/wFDOeQ8LtSIkJvyoMbuaP47bXni9B/eh1BWqN+60xazLSQtmy1xO5OF9wQ=="
     },
     "node_modules/@tsconfig/node10": {
       "version": "1.0.9",

+ 1 - 1
package.json

@@ -58,7 +58,7 @@
     "openuserjs": "https://openuserjs.org/scripts/Sv443/BetterYTM"
   },
   "dependencies": {
-    "@sv443-network/userutils": "^6.2.0",
+    "@sv443-network/userutils": "^6.3.0",
     "fuse.js": "^7.0.0",
     "marked": "^12.0.0",
     "nanoevents": "^9.0.0"

+ 4 - 4
src/features/layout.ts

@@ -1,8 +1,8 @@
-import { addParent, autoPlural, debounce, fetchAdvanced, insertAfter, openInNewTab, pauseFor } from "@sv443-network/userutils";
+import { addParent, autoPlural, debounce, fetchAdvanced, insertAfter, pauseFor } from "@sv443-network/userutils";
 import { getFeatures } from "../config";
 import { siteEvents } from "../siteEvents";
 import { addSelectorListener } from "../observers";
-import { error, getResourceUrl, log, warn, t, onInteraction, getBestThumbnailUrl, getDomain, addStyle, currentMediaType, domLoaded, waitVideoElementReady } from "../utils";
+import { error, getResourceUrl, log, warn, t, onInteraction, openInTab, getBestThumbnailUrl, getDomain, addStyle, currentMediaType, domLoaded, waitVideoElementReady } from "../utils";
 import { scriptInfo } from "../constants";
 import { openCfgMenu } from "../menu/menu_old";
 import { createGenericBtn } from "../components";
@@ -549,8 +549,8 @@ export async function initThumbnailOverlay() {
       toggleBtnElem.classList.add("ytmusic-player-bar", "bytm-generic-btn", "bytm-no-select");
   
       onInteraction(toggleBtnElem, (e) => {
-        if(e instanceof MouseEvent && e.shiftKey)
-          return openInNewTab(toggleBtnElem.href);
+        if(e.shiftKey)
+          return openInTab(toggleBtnElem.href);
         invertOverlay = !invertOverlay;
         updateOverlayVisibility();
       });

+ 16 - 5
src/features/songLists.css

@@ -25,7 +25,12 @@
 
 #side-panel ytmusic-player-queue-item:hover .bytm-queue-btn-container,
 ytmusic-playlist-shelf-renderer ytmusic-responsive-list-item-renderer:hover .bytm-queue-btn-container,
-ytmusic-shelf-renderer ytmusic-responsive-list-item-renderer:hover .bytm-queue-btn-container {
+ytmusic-shelf-renderer ytmusic-responsive-list-item-renderer:hover .bytm-queue-btn-container,
+/* same thing but with :focus-within */
+#side-panel ytmusic-player-queue-item:focus-within .bytm-queue-btn-container,
+ytmusic-playlist-shelf-renderer ytmusic-responsive-list-item-renderer:focus-within .bytm-queue-btn-container,
+ytmusic-shelf-renderer ytmusic-responsive-list-item-renderer:focus-within .bytm-queue-btn-container
+{
   display: inline-flex;
   align-items: center;
 }
@@ -36,14 +41,16 @@ ytmusic-responsive-list-item-renderer .title-column {
 
 #side-panel ytmusic-player-queue-item[play-button-state="loading"] .bytm-queue-btn-container,
 #side-panel ytmusic-player-queue-item[play-button-state="playing"] .bytm-queue-btn-container,
-#side-panel ytmusic-player-queue-item[play-button-state="paused"] .bytm-queue-btn-container {
+#side-panel ytmusic-player-queue-item[play-button-state="paused"] .bytm-queue-btn-container
+{
   /* using a var() with predefined value from YTM is not viable since the nesting changes the actual value of the variable */
   background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, #030303 15%);
 }
 
 #side-panel ytmusic-player-queue-item[selected][play-button-state="loading"] .bytm-queue-btn-container,
 #side-panel ytmusic-player-queue-item[selected][play-button-state="playing"] .bytm-queue-btn-container,
-#side-panel ytmusic-player-queue-item[selected][play-button-state="paused"] .bytm-queue-btn-container {
+#side-panel ytmusic-player-queue-item[selected][play-button-state="paused"] .bytm-queue-btn-container
+{
   /* using a var() with predefined value from YTM is not viable since the nesting changes the actual value of the variable */
   background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, #1D1D1D 15%);
 }
@@ -60,10 +67,14 @@ ytmusic-responsive-list-item-renderer.bytm-has-queue-btns .bytm-generic-list-que
   visibility: hidden !important;
 }
 
-ytmusic-responsive-list-item-renderer.bytm-has-queue-btns:hover .bytm-generic-list-queue-btn-container {
+ytmusic-responsive-list-item-renderer.bytm-has-queue-btns:hover .bytm-generic-list-queue-btn-container,
+ytmusic-responsive-list-item-renderer.bytm-has-queue-btns:focus-within .bytm-generic-list-queue-btn-container
+{
   visibility: visible;
 }
 
-ytmusic-responsive-list-item-renderer.bytm-has-queue-btns:hover .bytm-generic-list-queue-btn-container a.bytm-generic-btn {
+ytmusic-responsive-list-item-renderer.bytm-has-queue-btns:hover .bytm-generic-list-queue-btn-container a.bytm-generic-btn,
+ytmusic-responsive-list-item-renderer.bytm-has-queue-btns:focus-within .bytm-generic-list-queue-btn-container a.bytm-generic-btn
+{
   visibility: visible !important;
 }

+ 5 - 5
src/features/songLists.ts

@@ -1,13 +1,13 @@
-import { autoPlural, openInNewTab, pauseFor } from "@sv443-network/userutils";
-import { clearInner, error, getResourceUrl, log, onInteraction, t, warn } from "../utils";
+import { autoPlural, pauseFor } from "@sv443-network/userutils";
+import { clearInner, error, getResourceUrl, log, onInteraction, openInTab, t, warn } from "../utils";
 import { SiteEventsMap, siteEvents } from "../siteEvents";
 import { emitInterface } from "../interface";
 import { fetchLyricsUrlTop, createLyricsBtn, sanitizeArtists, sanitizeSong, splitVideoTitle } from "./lyrics";
 import { getLyricsCacheEntry } from "./lyricsCache";
 import type { LyricsCacheEntry } from "../types";
+import { addSelectorListener } from "../observers";
 import { getFeatures } from "../config";
 import "./songLists.css";
-import { addSelectorListener } from "src/observers";
 
 /** Initializes the queue buttons */
 export async function initQueueButtons() {
@@ -186,12 +186,12 @@ async function addQueueButtons(
         if(!lyricsUrl) {
           resetImgElem();
           if(confirm(t("lyrics_not_found_confirm_open_search")))
-            openInNewTab(`https://genius.com/search?q=${encodeURIComponent(`${artistsSan} - ${songSan}`)}`);
+            openInTab(`https://genius.com/search?q=${encodeURIComponent(`${artistsSan} - ${songSan}`)}`);
           return;
         }
       }
 
-      lyricsUrl && openInNewTab(lyricsUrl);
+      lyricsUrl && openInTab(lyricsUrl);
     });
   }
 

+ 11 - 1
src/utils/misc.ts

@@ -1,4 +1,4 @@
-import { compress, fetchAdvanced, randomId } from "@sv443-network/userutils";
+import { compress, fetchAdvanced, openInNewTab, randomId } from "@sv443-network/userutils";
 import { marked } from "marked";
 import { branch, compressionFormat, repo } from "../constants";
 import { type Domain, type ResourceKey } from "../types";
@@ -105,6 +105,16 @@ export function reserialize<T>(data: T): T {
   return JSON.parse(JSON.stringify(data));
 }
 
+/** Opens the given URL in a new tab, using GM.openInTab if available */
+export function openInTab(href: string, background = true) {
+  try {
+    openInNewTab(href, background);
+  }
+  catch(err) {
+    window.open(href, "_blank", "noopener noreferrer");
+  }
+}
+
 //#region resources
 
 /**