generated from adobe/aem-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 181
/
Copy pathwaitfor.js
130 lines (116 loc) · 3.04 KB
/
waitfor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
export const waitForElement = (
selector,
{
options = {
childList: true,
subtree: true,
},
rootEl = document.body,
textContent = '',
} = {},
) => new Promise((resolve) => {
const el = document.querySelector(selector);
if (el) {
resolve(el);
return;
}
const observer = new MutationObserver((mutations, obsv) => {
mutations.forEach((mutation) => {
const nodes = [...mutation.addedNodes];
nodes.some((node) => {
if (node.matches && node.matches(selector)) {
if (textContent && node.textContent !== textContent) return false;
obsv.disconnect();
resolve(node);
return true;
}
// check for child in added node
const treeWalker = document.createTreeWalker(node);
let { currentNode } = treeWalker;
while (currentNode) {
if (currentNode.matches && currentNode.matches(selector)) {
obsv.disconnect();
resolve(currentNode);
return true;
}
currentNode = treeWalker.nextNode();
}
return false;
});
});
});
observer.observe(rootEl, options);
});
export const waitForUpdate = (
el,
options = {
childList: true,
subtree: true,
},
) => new Promise((resolve) => {
const observer = new MutationObserver((mutations, obsv) => {
obsv.disconnect();
resolve();
});
observer.observe(el, options);
});
export const waitForRemoval = (
selector,
options = {
childList: true,
subtree: false,
},
) => new Promise((resolve) => {
const el = document.querySelector(selector);
if (!el) {
resolve();
return;
}
const observer = new MutationObserver((mutations, obsv) => {
mutations.forEach((mutation) => {
const nodes = [...mutation.removedNodes];
nodes.some((node) => {
if (node.matches(selector)) {
obsv.disconnect();
resolve();
return true;
}
return false;
});
});
});
observer.observe(el.parentElement, options);
});
/**
* Promise based setTimeout that can be await'd
* @param {int} timeOut time out in milliseconds
* @param {*} cb Callback function to call when time elapses
* @returns
*/
export const delay = (timeOut, cb) => new Promise((resolve) => {
setTimeout(() => {
resolve((cb && cb()) || null);
}, timeOut);
});
/**
* Waits for predicate function to be true or times out.
* @param {function} predicate Callback that returns boolean
* @param {number} timeout Timeout in milliseconds
* @param {number} interval Interval delay in milliseconds
* @returns {Promise}
*/
export function waitFor(predicate, timeout = 1000, interval = 100) {
return new Promise((resolve, reject) => {
if (predicate()) resolve();
const intervalId = setInterval(() => {
if (predicate()) {
clearInterval(intervalId);
resolve();
}
}, interval);
setTimeout(() => {
clearInterval(intervalId);
reject(new Error('Timed out waiting for predicate to be true'));
}, timeout);
});
}