Răsfoiți Sursa

feat: begin new onSelectorExists()

Sv443 1 an în urmă
părinte
comite
7a7fdf8c85
4 a modificat fișierele cu 64 adăugiri și 4 ștergeri
  1. 26 2
      dist/BetterYTM.user.js
  2. 1 1
      src/features/layout.ts
  3. 9 0
      src/types.ts
  4. 28 1
      src/utils.ts

+ 26 - 2
dist/BetterYTM.user.js

@@ -489,7 +489,7 @@ const scriptInfo = {
     name: GM.info.script.name,
     version: GM.info.script.version,
     namespace: GM.info.script.namespace,
-    lastCommit: "ad72937", // assert as generic string instead of union
+    lastCommit: "816715e", // assert as generic string instead of literal
 };
 
 
@@ -1210,7 +1210,7 @@ function addAnchorImprovements() {
         });
         // related tab in /watch
         // TODO: items are lazy-loaded so this needs to be done differently
-        // maybe the onSelectorExists feature can be expanded to support conditional continuous checking & querySelectorAll
+        // maybe the onSelectorExists feature can be expanded to conditionally support continuous checking & querySelectorAll
         const relatedTabAnchorImprovements = (tabElem) => {
             const relatedCarouselShelves = tabElem === null || tabElem === void 0 ? void 0 : tabElem.querySelectorAll("ytmusic-carousel-shelf-renderer");
             if (relatedCarouselShelves)
@@ -1992,10 +1992,12 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export */   initSelectorExistsCheck: function() { return /* binding */ initSelectorExistsCheck; },
 /* harmony export */   insertAfter: function() { return /* binding */ insertAfter; },
 /* harmony export */   log: function() { return /* binding */ log; },
+/* harmony export */   onSelector: function() { return /* binding */ onSelector; },
 /* harmony export */   onSelectorExists: function() { return /* binding */ onSelectorExists; },
 /* harmony export */   openInNewTab: function() { return /* binding */ openInNewTab; },
 /* harmony export */   pauseFor: function() { return /* binding */ pauseFor; },
 /* harmony export */   precacheImages: function() { return /* binding */ precacheImages; },
+/* harmony export */   removeOnSelector: function() { return /* binding */ removeOnSelector; },
 /* harmony export */   setLogLevel: function() { return /* binding */ setLogLevel; },
 /* harmony export */   warn: function() { return /* binding */ warn; }
 /* harmony export */ });
@@ -2186,6 +2188,27 @@ function onSelectorExists(selector, listener) {
             selectorExistsMap.set(selector, [listener]);
     }
 }
+/**
+ * Calls the `listener` as soon as the `selector` exists in the DOM.
+ * Listeners are deleted when they are called once, unless `options.continuous` is set.
+ * Multiple listeners with the same selector may be registered.
+ * @template TElem The type of element that this selector will return - FIXME: listener inferring doesn't work when this generic is given
+ */
+function onSelector(options, listener) {
+    // TODO:
+    void [options, listener];
+}
+// onSelector({
+//   selector: "a",
+//   all: true,
+// }, (elem) => {
+//   void elem;
+// });
+/** Removes all listeners registered in `onSelector()` with a matching selector property */
+function removeOnSelector(selector) {
+    // TODO:
+    void [selector];
+}
 /** Initializes the MutationObserver responsible for checking selectors registered in `onSelectorExists()` */
 function initSelectorExistsCheck() {
     const observer = new MutationObserver(() => {
@@ -2622,6 +2645,7 @@ yt-multi-page-menu-section-renderer.ytd-multi-page-menu-renderer {
   position: absolute;
   right: 0;
   padding-left: 25px;
+  height: 100%;
 }
 
 .side-panel.modular ytmusic-player-queue-item:hover .bytm-queue-btn-container {

+ 1 - 1
src/features/layout.ts

@@ -316,7 +316,7 @@ export function addAnchorImprovements() {
     // related tab in /watch
 
     // TODO: items are lazy-loaded so this needs to be done differently
-    // maybe the onSelectorExists feature can be expanded to support conditional continuous checking & querySelectorAll
+    // maybe the onSelectorExists feature can be expanded to conditionally support continuous checking & querySelectorAll
     const relatedTabAnchorImprovements = (tabElem: HTMLElement) => {
       const relatedCarouselShelves = tabElem?.querySelectorAll<HTMLElement>("ytmusic-carousel-shelf-renderer");
       if(relatedCarouselShelves)

+ 9 - 0
src/types.ts

@@ -10,6 +10,15 @@ export type Domain = "yt" | "ytm";
 /** Feature category to be used in the menu for grouping features */
 export type FeatureCategory = "input" | "layout" | "lyrics";
 
+export type SelectorExistsOpts = {
+  /** The selector to check for */
+  selector: string;
+  /** Whether to use `querySelectorAll()` instead */
+  all?: boolean;
+  /** Whether to call the listener continuously instead of once */
+  continuous?: boolean;
+};
+
 /** Feature configuration */
 export interface FeatureConfig {
   //#SECTION input

+ 28 - 1
src/utils.ts

@@ -1,5 +1,5 @@
 import { branch, scriptInfo } from "./constants";
-import type { Domain, LogLevel } from "./types";
+import type { Domain, LogLevel, SelectorExistsOpts } from "./types";
 
 //#SECTION logging
 
@@ -225,6 +225,33 @@ export function onSelectorExists(selector: string, listener: (element: HTMLEleme
   }
 }
 
+/**
+ * Calls the `listener` as soon as the `selector` exists in the DOM.  
+ * Listeners are deleted when they are called once, unless `options.continuous` is set.  
+ * Multiple listeners with the same selector may be registered.
+ * @template TElem The type of element that this selector will return - FIXME: listener inferring doesn't work when this generic is given
+ */
+export function onSelector<TElem = HTMLElement, TOpts extends SelectorExistsOpts = SelectorExistsOpts>(
+  options: TOpts,
+  listener: (element: TOpts["all"] extends true ? (TElem extends HTMLElement ? NodeListOf<TElem> : TElem) : TElem) => void,
+) {
+  // TODO:
+  void [options, listener];
+}
+
+// onSelector({
+//   selector: "a",
+//   all: true,
+// }, (elem) => {
+//   void elem;
+// });
+
+/** Removes all listeners registered in `onSelector()` with a matching selector property */
+export function removeOnSelector(selector: string) {
+  // TODO:
+  void [selector];
+}
+
 /** Initializes the MutationObserver responsible for checking selectors registered in `onSelectorExists()` */
 export function initSelectorExistsCheck() {
   const observer = new MutationObserver(() => {