Skip to content

Commit

Permalink
utils.js: add observeAttributes to waitForChildAdd
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
throwaway96 committed Mar 29, 2024
1 parent e853522 commit 6f38433
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/userScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down
30 changes: 22 additions & 8 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>}
* 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<T>} 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) {
Expand Down Expand Up @@ -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
});
});
}

0 comments on commit 6f38433

Please sign in to comment.