From a1e4274c1cfb342e26034c912d0669339bf1e3e1 Mon Sep 17 00:00:00 2001 From: throwaway96 <68320646+throwaway96@users.noreply.github.com> Date: Wed, 27 Mar 2024 00:40:59 -0400 Subject: [PATCH] utils.js: add observeAttributes to waitForChildAdd You must now specify whether waitForChildAdd() should check the predicate on attribute changes. None of its callers depended on this behavior, so the callback and predicate were running hundreds of times unnecessarily. A new parameter, observeAttributes, has been added before abortSignal. When it is true, you will get the old behavior. When it is false, the predicate will not be called on attribute changes. --- src/userScript.js | 3 ++- src/utils.js | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/userScript.js b/src/userScript.js index 0ee2da5f..cd550219 100644 --- a/src/userScript.js +++ b/src/userScript.js @@ -21,7 +21,8 @@ import './ui.js'; /** @type {HTMLVideoElement} */ const video = await waitForChildAdd( document.body, - (node) => node instanceof HTMLVideoElement + (node) => node instanceof HTMLVideoElement, + false ); const playerCtrlObs = new MutationObserver(() => { diff --git a/src/utils.js b/src/utils.js index a5707c76..55519f00 100644 --- a/src/utils.js +++ b/src/utils.js @@ -87,14 +87,24 @@ export function handleLaunch(params) { } /** - * Wait for a child element to be added that holds true for a predicate - * @template T - * @param {Element} parent - * @param {(node: Node) => node is T} predicate - * @param {AbortSignal=} abortSignal - * @return {Promise} + * Wait for a child element to be added for which a predicate is true. + * + * When `observeAttributes` is false, the predicate is checked only when a node + * is first added. If you want the predicate to run every time an attribute is + * modified, set `observeAttributes` to true. + * @template {Node} T + * @param {Element} parent Root of tree to watch + * @param {(node: Node) => node is T} predicate Function that checks whether its argument is the desired element + * @param {boolean} observeAttributes Also run predicate on attribute changes + * @param {AbortSignal=} abortSignal Signal that can be used to stop waiting + * @return {Promise} Matched element */ -export async function waitForChildAdd(parent, predicate, abortSignal) { +export async function waitForChildAdd( + parent, + predicate, + observeAttributes, + abortSignal +) { return new Promise((resolve, reject) => { const obs = new MutationObserver((mutations) => { for (const mut of mutations) { @@ -128,6 +138,10 @@ export async function waitForChildAdd(parent, predicate, abortSignal) { }); } - obs.observe(parent, { subtree: true, attributes: true, childList: true }); + obs.observe(parent, { + subtree: true, + attributes: observeAttributes, + childList: true + }); }); }