powerpagestoolkit 2.6.3 → 2.6.3201
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -9
- package/dist/DOMNodeReference.d.ts +9 -3
- package/dist/bundle.js +102 -46
- package/dist/createDOMNodeReferences.d.ts +6 -8
- package/dist/waitFor.d.ts +2 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,31 +27,88 @@ A powerful class for managing DOM elements with automatic value synchronization
|
|
|
27
27
|
|
|
28
28
|
#### Basic Usage
|
|
29
29
|
|
|
30
|
-
DOMNodeReferences are instantiated with the help of the following factory function
|
|
30
|
+
DOMNodeReferences are instantiated with the help of the following factory function: `createRef`
|
|
31
31
|
|
|
32
32
|
```typescript
|
|
33
33
|
createRef(
|
|
34
|
-
target: HTMLElement | string,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
target: HTMLElement | string,
|
|
35
|
+
options: {
|
|
36
|
+
multiple: (() => boolean) | boolean = false,
|
|
37
|
+
root: HTMLElement,
|
|
38
|
+
timeout: number
|
|
39
|
+
}
|
|
38
40
|
): Promise<DOMNodeReference | DOMNodeReferenceArray>;
|
|
39
41
|
```
|
|
40
42
|
|
|
43
|
+
createRef takes two main arguments:
|
|
44
|
+
|
|
45
|
+
<table style="width: 100%; border-collapse: collapse;">
|
|
46
|
+
<thead>
|
|
47
|
+
<tr>
|
|
48
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Property</th>
|
|
49
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Type</th>
|
|
50
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Details</th>
|
|
51
|
+
</tr>
|
|
52
|
+
</thead>
|
|
53
|
+
<tbody>
|
|
54
|
+
<tr>
|
|
55
|
+
<td style="border: 1px solid #ddd; padding: 8px;">target</td>
|
|
56
|
+
<td style="border: 1px solid #ddd; padding: 8px;">
|
|
57
|
+
<pre><code class="language-javascript">string | HTMLElement</code></pre>
|
|
58
|
+
</td>
|
|
59
|
+
<td style="border: 1px solid #ddd; padding: 8px;">
|
|
60
|
+
Use standard <code>querySelector</code> syntax to target an element, or elements in the DOM, or pass in an instance of the element itself to create a reference.
|
|
61
|
+
</td>
|
|
62
|
+
</tr>
|
|
63
|
+
<tr>
|
|
64
|
+
<td style="border: 1px solid #ddd; padding: 8px;">options</td>
|
|
65
|
+
<td style="border: 1px solid #ddd; padding: 8px;">
|
|
66
|
+
<pre><code class="language-javascript">{
|
|
67
|
+
multiple: () => boolean | boolean,
|
|
68
|
+
root: HTMLElement,
|
|
69
|
+
timeout: number
|
|
70
|
+
}</code></pre>
|
|
71
|
+
</td>
|
|
72
|
+
<td style="border: 1px solid #ddd; padding: 8px;">
|
|
73
|
+
Provides advanced configurations for niche scenarios, such as async DOM element loading, returning arrays of elements, or specifying the parent to search within for the target node.
|
|
74
|
+
</td>
|
|
75
|
+
</tr>
|
|
76
|
+
</tbody>
|
|
77
|
+
</table>
|
|
78
|
+
|
|
41
79
|
Import the utility function for creating DOMNodeReference(s)
|
|
42
80
|
|
|
43
81
|
```typescript
|
|
44
82
|
import { createRef } from "powerpagestoolkit";
|
|
45
83
|
```
|
|
46
84
|
|
|
47
|
-
Instantiate one, or multiple instances of a DOMNodeReference
|
|
85
|
+
Instantiate one, or multiple instances of a DOMNodeReference, and optionally configure advanced options
|
|
48
86
|
|
|
49
|
-
```
|
|
87
|
+
```javascript
|
|
50
88
|
// Create a single reference
|
|
51
|
-
const node = await createRef("#myElement"
|
|
89
|
+
const node = await createRef("#myElement");
|
|
52
90
|
|
|
53
91
|
// Create multiple references
|
|
54
|
-
const nodes = await createRef(".my-class", true);
|
|
92
|
+
const nodes = await createRef(".my-class", { multiple: true });
|
|
93
|
+
|
|
94
|
+
/******************/
|
|
95
|
+
// ADVANCED OPTIONS
|
|
96
|
+
// in the event that you need to be more granular with how you are targeting
|
|
97
|
+
// and retrieving elements, there are additional options
|
|
98
|
+
// If the node you are targeted is not available at the initial execution
|
|
99
|
+
// of the script, set a timeout for 2 seconds
|
|
100
|
+
const node2 = await createRef("#target", { timeout: 2000 });
|
|
101
|
+
|
|
102
|
+
// need to target a node within a specific node? use that node as the root
|
|
103
|
+
const otherElement = document.getElementById("id");
|
|
104
|
+
const node3 = await createRef("#target", { root: otherElement });
|
|
105
|
+
|
|
106
|
+
// implement all options:
|
|
107
|
+
const nodes2 = await createRef("#target", {
|
|
108
|
+
multiple: true,
|
|
109
|
+
timeout: 4000,
|
|
110
|
+
root: otherElement,
|
|
111
|
+
});
|
|
55
112
|
```
|
|
56
113
|
|
|
57
114
|
#### Properties
|
|
@@ -7,12 +7,16 @@ declare const _updateRadioGroup: unique symbol;
|
|
|
7
7
|
declare const _attachVisibilityController: unique symbol;
|
|
8
8
|
declare const _attachRadioButtons: unique symbol;
|
|
9
9
|
declare const _bindMethods: unique symbol;
|
|
10
|
+
declare const observers: unique symbol;
|
|
11
|
+
declare const boundEventListeners: unique symbol;
|
|
10
12
|
export default class DOMNodeReference {
|
|
11
13
|
target: HTMLElement | string;
|
|
14
|
+
root: HTMLElement;
|
|
15
|
+
private debounceTime;
|
|
12
16
|
private isLoaded;
|
|
13
17
|
private defaultDisplay;
|
|
14
|
-
private observers;
|
|
15
|
-
private boundEventListeners;
|
|
18
|
+
private [observers];
|
|
19
|
+
private [boundEventListeners];
|
|
16
20
|
/**
|
|
17
21
|
* The value of the element that this node represents
|
|
18
22
|
* stays in syncs with the live DOM elements?.,m via event handler
|
|
@@ -41,8 +45,10 @@ export default class DOMNodeReference {
|
|
|
41
45
|
/**
|
|
42
46
|
* Creates an instance of DOMNodeReference.
|
|
43
47
|
* @param target - The CSS selector to find the desired DOM element.
|
|
48
|
+
* @param root - Optionally specify the element within to search for the element targeted by 'target'
|
|
49
|
+
* Defaults to 'document.body'
|
|
44
50
|
*/
|
|
45
|
-
/******/ /******/ constructor(target: HTMLElement | string);
|
|
51
|
+
/******/ /******/ constructor(target: HTMLElement | string, root?: HTMLElement, debounceTime?: number);
|
|
46
52
|
[_init](): Promise<void>;
|
|
47
53
|
/**
|
|
48
54
|
* Initializes value synchronization with appropriate event listeners
|
package/dist/bundle.js
CHANGED
|
@@ -103,35 +103,77 @@ var API = {
|
|
|
103
103
|
var API_default = API;
|
|
104
104
|
|
|
105
105
|
// src/waitFor.ts
|
|
106
|
-
function waitFor(target, root = document) {
|
|
106
|
+
function waitFor(target, root = document, multiple = false, debounceTime) {
|
|
107
107
|
return new Promise((resolve, reject) => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
if (multiple) {
|
|
109
|
+
let timeout;
|
|
110
|
+
const observedElements = [];
|
|
111
|
+
const observedSet = /* @__PURE__ */ new Set();
|
|
112
|
+
if (debounceTime < 1) {
|
|
113
|
+
return resolve(
|
|
114
|
+
Array.from(root.querySelectorAll(target))
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
const observer = new MutationObserver(() => {
|
|
118
|
+
const found = Array.from(root.querySelectorAll(target));
|
|
119
|
+
found.forEach((element) => {
|
|
120
|
+
if (!observedSet.has(element)) {
|
|
121
|
+
observedSet.add(element);
|
|
122
|
+
observedElements.push(element);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
111
125
|
clearTimeout(timeout);
|
|
126
|
+
timeout = setTimeout(() => {
|
|
127
|
+
if (observedElements.length > 0) {
|
|
128
|
+
observer.disconnect();
|
|
129
|
+
resolve(observedElements);
|
|
130
|
+
} else {
|
|
131
|
+
reject(
|
|
132
|
+
new Error(
|
|
133
|
+
`No elements found with target: "${target}" within ${debounceTime / 1e3} seconds. If the element you are expected has not loading, consider raising your timeout.`
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}, debounceTime);
|
|
138
|
+
});
|
|
139
|
+
observer.observe(root, {
|
|
140
|
+
childList: true,
|
|
141
|
+
subtree: true,
|
|
142
|
+
attributes: false
|
|
143
|
+
});
|
|
144
|
+
} else {
|
|
145
|
+
const observer = new MutationObserver(() => {
|
|
146
|
+
const observedElement = root.querySelector(target);
|
|
147
|
+
if (observedElement) {
|
|
148
|
+
clearTimeout(timeout);
|
|
149
|
+
observer.disconnect();
|
|
150
|
+
resolve(observedElement);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const timeout = setTimeout(() => {
|
|
112
154
|
observer.disconnect();
|
|
113
|
-
|
|
155
|
+
reject(
|
|
156
|
+
new Error(
|
|
157
|
+
`Element not found by target: "${target}" within ${debounceTime / 1e3} second. If the element you are expected has not loading, consider raising your timeout.`
|
|
158
|
+
)
|
|
159
|
+
);
|
|
160
|
+
}, debounceTime);
|
|
161
|
+
if (target instanceof HTMLElement) {
|
|
162
|
+
clearTimeout(timeout);
|
|
163
|
+
return resolve(target);
|
|
114
164
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
clearTimeout(timeout);
|
|
127
|
-
return resolve(element);
|
|
165
|
+
const element = root.querySelector(target);
|
|
166
|
+
if (element) {
|
|
167
|
+
clearTimeout(timeout);
|
|
168
|
+
return resolve(element);
|
|
169
|
+
}
|
|
170
|
+
observer.observe(root, {
|
|
171
|
+
subtree: true,
|
|
172
|
+
attributes: true,
|
|
173
|
+
childList: true
|
|
174
|
+
// Detects added/removed child elements
|
|
175
|
+
});
|
|
128
176
|
}
|
|
129
|
-
observer.observe(document.body, {
|
|
130
|
-
subtree: true,
|
|
131
|
-
attributes: true,
|
|
132
|
-
childList: true
|
|
133
|
-
// Detects added/removed child elements
|
|
134
|
-
});
|
|
135
177
|
});
|
|
136
178
|
}
|
|
137
179
|
|
|
@@ -237,13 +279,17 @@ var _updateRadioGroup = Symbol("_URG");
|
|
|
237
279
|
var _attachVisibilityController = Symbol("_AVC");
|
|
238
280
|
var _attachRadioButtons = Symbol("_ARB");
|
|
239
281
|
var _bindMethods = Symbol("_B");
|
|
282
|
+
var observers = Symbol("O");
|
|
283
|
+
var boundEventListeners = Symbol("BEV");
|
|
240
284
|
var DOMNodeReference = class _DOMNodeReference {
|
|
241
285
|
// properties initialized in the constructor
|
|
242
286
|
target;
|
|
287
|
+
root;
|
|
288
|
+
debounceTime;
|
|
243
289
|
isLoaded;
|
|
244
290
|
defaultDisplay;
|
|
245
|
-
observers = [];
|
|
246
|
-
boundEventListeners = [];
|
|
291
|
+
[observers] = [];
|
|
292
|
+
[boundEventListeners] = [];
|
|
247
293
|
/**
|
|
248
294
|
* The value of the element that this node represents
|
|
249
295
|
* stays in syncs with the live DOM elements?.,m via event handler
|
|
@@ -252,11 +298,15 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
252
298
|
/**
|
|
253
299
|
* Creates an instance of DOMNodeReference.
|
|
254
300
|
* @param target - The CSS selector to find the desired DOM element.
|
|
301
|
+
* @param root - Optionally specify the element within to search for the element targeted by 'target'
|
|
302
|
+
* Defaults to 'document.body'
|
|
255
303
|
*/
|
|
256
304
|
/******/
|
|
257
305
|
/******/
|
|
258
|
-
constructor(target) {
|
|
306
|
+
constructor(target, root = document.body, debounceTime = 5e3) {
|
|
259
307
|
this.target = target;
|
|
308
|
+
this.root = root;
|
|
309
|
+
this.debounceTime = debounceTime;
|
|
260
310
|
this.isLoaded = false;
|
|
261
311
|
this.defaultDisplay = "";
|
|
262
312
|
this.value = null;
|
|
@@ -264,8 +314,11 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
264
314
|
}
|
|
265
315
|
async [_init]() {
|
|
266
316
|
try {
|
|
267
|
-
|
|
268
|
-
|
|
317
|
+
if (this.target instanceof HTMLElement) {
|
|
318
|
+
this.element = this.target;
|
|
319
|
+
} else {
|
|
320
|
+
this.element = await waitFor(this.target, this.root, false, this.debounceTime);
|
|
321
|
+
}
|
|
269
322
|
if (!this.element) {
|
|
270
323
|
throw new DOMNodeNotFoundError(this);
|
|
271
324
|
}
|
|
@@ -323,7 +376,7 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
323
376
|
this.element.addEventListener(eventType, this.updateValue);
|
|
324
377
|
const _element = this.element;
|
|
325
378
|
const _updateValue = this.updateValue;
|
|
326
|
-
this
|
|
379
|
+
this[boundEventListeners].push({
|
|
327
380
|
element: _element,
|
|
328
381
|
handler: _updateValue,
|
|
329
382
|
event: eventType
|
|
@@ -343,10 +396,10 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
343
396
|
if (!parentElement) {
|
|
344
397
|
throw new Error("Date input must have a parent element");
|
|
345
398
|
}
|
|
346
|
-
const dateNode = await waitFor("[data-date-format]", parentElement);
|
|
399
|
+
const dateNode = await waitFor("[data-date-format]", parentElement, false, 1500);
|
|
347
400
|
dateNode.addEventListener("select", this.updateValue);
|
|
348
401
|
const _handler = this.updateValue;
|
|
349
|
-
this
|
|
402
|
+
this[boundEventListeners].push({
|
|
350
403
|
element: dateNode,
|
|
351
404
|
handler: _handler,
|
|
352
405
|
event: "select"
|
|
@@ -435,10 +488,10 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
435
488
|
}
|
|
436
489
|
}
|
|
437
490
|
[_destroy]() {
|
|
438
|
-
this
|
|
491
|
+
this[boundEventListeners]?.forEach((binding) => {
|
|
439
492
|
binding.element?.removeEventListener(binding.event, binding.handler);
|
|
440
493
|
});
|
|
441
|
-
this
|
|
494
|
+
this[observers]?.forEach((observer) => {
|
|
442
495
|
observer.disconnect();
|
|
443
496
|
});
|
|
444
497
|
this.yesRadio?.[_destroy]();
|
|
@@ -477,7 +530,7 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
477
530
|
this.element.addEventListener(eventType, eventHandler.bind(this));
|
|
478
531
|
const _element = this.element;
|
|
479
532
|
const _handler = eventHandler;
|
|
480
|
-
this
|
|
533
|
+
this[boundEventListeners].push({
|
|
481
534
|
element: _element,
|
|
482
535
|
handler: _handler,
|
|
483
536
|
event: eventType
|
|
@@ -596,7 +649,7 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
596
649
|
);
|
|
597
650
|
if (childInputs.length > 0) {
|
|
598
651
|
const promises = childInputs.map(async (input) => {
|
|
599
|
-
const inputRef = await createDOMNodeReference(input, false);
|
|
652
|
+
const inputRef = await createDOMNodeReference(input, { multiple: false });
|
|
600
653
|
return inputRef.clearValue();
|
|
601
654
|
});
|
|
602
655
|
await Promise.all(promises);
|
|
@@ -880,14 +933,14 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
880
933
|
}
|
|
881
934
|
};
|
|
882
935
|
dep.on("change", handleChange);
|
|
883
|
-
this
|
|
936
|
+
this[boundEventListeners].push({
|
|
884
937
|
element: dep.element,
|
|
885
938
|
event: "change",
|
|
886
939
|
handler: handleChange
|
|
887
940
|
});
|
|
888
941
|
if (trackInputEvents) {
|
|
889
942
|
dep.on("input", handleChange);
|
|
890
|
-
this
|
|
943
|
+
this[boundEventListeners].push({
|
|
891
944
|
element: dep.element,
|
|
892
945
|
event: "input",
|
|
893
946
|
handler: handleChange
|
|
@@ -907,12 +960,12 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
907
960
|
attributeFilter: ["style"],
|
|
908
961
|
subtree: false
|
|
909
962
|
});
|
|
910
|
-
this
|
|
963
|
+
this[observers].push(observer);
|
|
911
964
|
}
|
|
912
965
|
if (trackRadioButtons && dep.yesRadio && dep.noRadio) {
|
|
913
966
|
[dep.yesRadio, dep.noRadio].forEach((radio) => {
|
|
914
967
|
radio.on("change", handleChange);
|
|
915
|
-
this
|
|
968
|
+
this[boundEventListeners].push({
|
|
916
969
|
element: radio.element,
|
|
917
970
|
event: "change",
|
|
918
971
|
handler: handleChange
|
|
@@ -964,12 +1017,17 @@ var DOMNodeReference = class _DOMNodeReference {
|
|
|
964
1017
|
subtree: true,
|
|
965
1018
|
childList: true
|
|
966
1019
|
});
|
|
967
|
-
this
|
|
1020
|
+
this[observers].push(observer);
|
|
968
1021
|
}
|
|
969
1022
|
};
|
|
970
1023
|
|
|
971
1024
|
// src/createDOMNodeReferences.ts
|
|
972
|
-
async function createDOMNodeReference(target,
|
|
1025
|
+
async function createDOMNodeReference(target, options = {
|
|
1026
|
+
multiple: false,
|
|
1027
|
+
root: document.body,
|
|
1028
|
+
timeout: 0
|
|
1029
|
+
}) {
|
|
1030
|
+
const { multiple = false, root = document.body, timeout = 0 } = options;
|
|
973
1031
|
try {
|
|
974
1032
|
const isMultiple = typeof multiple === "function" ? multiple() : multiple;
|
|
975
1033
|
if (isMultiple) {
|
|
@@ -978,9 +1036,7 @@ async function createDOMNodeReference(target, multiple = false) {
|
|
|
978
1036
|
`'target' must be of type 'string' if 'multiple' is set to 'true'. Received type: '${typeof target}'`
|
|
979
1037
|
);
|
|
980
1038
|
}
|
|
981
|
-
const elements =
|
|
982
|
-
document.querySelectorAll(target)
|
|
983
|
-
);
|
|
1039
|
+
const elements = await waitFor(target, root, true, timeout);
|
|
984
1040
|
const initializedElements = await Promise.all(
|
|
985
1041
|
elements.map(async (element) => {
|
|
986
1042
|
const instance2 = new DOMNodeReference(element);
|
|
@@ -990,7 +1046,7 @@ async function createDOMNodeReference(target, multiple = false) {
|
|
|
990
1046
|
);
|
|
991
1047
|
return enhanceArray(initializedElements);
|
|
992
1048
|
}
|
|
993
|
-
const instance = new DOMNodeReference(target);
|
|
1049
|
+
const instance = new DOMNodeReference(target, root, timeout);
|
|
994
1050
|
await instance[_init]();
|
|
995
1051
|
return new Proxy(instance, createProxyHandler());
|
|
996
1052
|
} catch (e) {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import DOMNodeReference from "./DOMNodeReference.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
9
|
-
export default function createDOMNodeReference(target: HTMLElement | string, multiple?: (() => boolean) | boolean): Promise<DOMNodeReference | DOMNodeReference[]>;
|
|
2
|
+
export default function createDOMNodeReference(target: HTMLElement | string, options?: {
|
|
3
|
+
multiple?: false | undefined;
|
|
4
|
+
}): Promise<DOMNodeReference>;
|
|
5
|
+
export default function createDOMNodeReference(target: HTMLElement | string, options?: {
|
|
6
|
+
multiple?: true;
|
|
7
|
+
}): Promise<DOMNodeReference[]>;
|
package/dist/waitFor.d.ts
CHANGED
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @param target basic querySelector syntax to select an element
|
|
4
|
-
* @param root optional parameter to replace document as the root from which to perform the node search
|
|
5
|
-
* @returns
|
|
6
|
-
*/
|
|
7
|
-
export default function waitFor(target: HTMLElement | string, root?: HTMLElement | Document): Promise<HTMLElement>;
|
|
1
|
+
export default function waitFor(target: HTMLElement | string, root: HTMLElement | Document, multiple: false, debounceTime: number): Promise<HTMLElement>;
|
|
2
|
+
export default function waitFor(target: HTMLElement | string, root: HTMLElement | Document, multiple: true, debounceTime: number): Promise<HTMLElement[]>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "powerpagestoolkit",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.3201",
|
|
4
4
|
"description": "Reference, manipulate, and engage with Power Pages sites through the nodes in the DOM; use a variety of custom methods that allow customizing your power pages site quicker and easier. ",
|
|
5
5
|
"main": "./dist/bundle.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|