@aegisjsproject/callback-registry 1.0.1 → 1.0.3
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/CHANGELOG.md +16 -0
- package/callbackRegistry.cjs +782 -256
- package/callbackRegistry.mjs +1 -1
- package/callbackRegistry.mjs.map +1 -1
- package/callbacks.cjs +583 -0
- package/callbacks.js +81 -0
- package/events.js +442 -107
- package/package.json +5 -2
package/callbackRegistry.cjs
CHANGED
|
@@ -1,11 +1,617 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const PREFIX = 'data-aegis-event-';
|
|
4
|
+
const EVENT_PREFIX = PREFIX + 'on-';
|
|
5
|
+
const EVENT_PREFIX_LENGTH = EVENT_PREFIX.length;
|
|
6
|
+
const DATA_PREFIX = 'aegisEventOn';
|
|
7
|
+
const DATA_PREFIX_LENGTH = DATA_PREFIX.length;
|
|
8
|
+
const signalSymbol = Symbol('aegis:signal');
|
|
9
|
+
const controllerSymbol = Symbol('aegis:controller');
|
|
10
|
+
const signalRegistry = new Map();
|
|
11
|
+
const controllerRegistry = new Map();
|
|
12
|
+
|
|
13
|
+
const once = PREFIX + 'once';
|
|
14
|
+
const passive = PREFIX + 'passive';
|
|
15
|
+
const capture = PREFIX + 'capture';
|
|
16
|
+
const signal = PREFIX + 'signal';
|
|
17
|
+
const controller = PREFIX + 'controller';
|
|
18
|
+
const onAbort = EVENT_PREFIX + 'abort';
|
|
19
|
+
const onBlur = EVENT_PREFIX + 'blur';
|
|
20
|
+
const onFocus = EVENT_PREFIX + 'focus';
|
|
21
|
+
const onCancel = EVENT_PREFIX + 'cancel';
|
|
22
|
+
const onAuxclick = EVENT_PREFIX + 'auxclick';
|
|
23
|
+
const onBeforeinput = EVENT_PREFIX + 'beforeinput';
|
|
24
|
+
const onBeforetoggle = EVENT_PREFIX + 'beforetoggle';
|
|
25
|
+
const onCanplay = EVENT_PREFIX + 'canplay';
|
|
26
|
+
const onCanplaythrough = EVENT_PREFIX + 'canplaythrough';
|
|
27
|
+
const onChange = EVENT_PREFIX + 'change';
|
|
28
|
+
const onClick = EVENT_PREFIX + 'click';
|
|
29
|
+
const onClose = EVENT_PREFIX + 'close';
|
|
30
|
+
const onCommand = EVENT_PREFIX + 'command';
|
|
31
|
+
const onContextmenu = EVENT_PREFIX + 'contextmenu';
|
|
32
|
+
const onCopy = EVENT_PREFIX + 'copy';
|
|
33
|
+
const onCuechange = EVENT_PREFIX + 'cuechange';
|
|
34
|
+
const onCut = EVENT_PREFIX + 'cut';
|
|
35
|
+
const onDblclick = EVENT_PREFIX + 'dblclick';
|
|
36
|
+
const onDrag = EVENT_PREFIX + 'drag';
|
|
37
|
+
const onDragend = EVENT_PREFIX + 'dragend';
|
|
38
|
+
const onDragenter = EVENT_PREFIX + 'dragenter';
|
|
39
|
+
const onDragexit = EVENT_PREFIX + 'dragexit';
|
|
40
|
+
const onDragleave = EVENT_PREFIX + 'dragleave';
|
|
41
|
+
const onDragover = EVENT_PREFIX + 'dragover';
|
|
42
|
+
const onDragstart = EVENT_PREFIX + 'dragstart';
|
|
43
|
+
const onDrop = EVENT_PREFIX + 'drop';
|
|
44
|
+
const onDurationchange = EVENT_PREFIX + 'durationchange';
|
|
45
|
+
const onEmptied = EVENT_PREFIX + 'emptied';
|
|
46
|
+
const onEnded = EVENT_PREFIX + 'ended';
|
|
47
|
+
const onFormdata = EVENT_PREFIX + 'formdata';
|
|
48
|
+
const onInput = EVENT_PREFIX + 'input';
|
|
49
|
+
const onInvalid = EVENT_PREFIX + 'invalid';
|
|
50
|
+
const onKeydown = EVENT_PREFIX + 'keydown';
|
|
51
|
+
const onKeypress = EVENT_PREFIX + 'keypress';
|
|
52
|
+
const onKeyup = EVENT_PREFIX + 'keyup';
|
|
53
|
+
const onLoad = EVENT_PREFIX + 'load';
|
|
54
|
+
const onLoadeddata = EVENT_PREFIX + 'loadeddata';
|
|
55
|
+
const onLoadedmetadata = EVENT_PREFIX + 'loadedmetadata';
|
|
56
|
+
const onLoadstart = EVENT_PREFIX + 'loadstart';
|
|
57
|
+
const onMousedown = EVENT_PREFIX + 'mousedown';
|
|
58
|
+
const onMouseenter = EVENT_PREFIX + 'mouseenter';
|
|
59
|
+
const onMouseleave = EVENT_PREFIX + 'mouseleave';
|
|
60
|
+
const onMousemove = EVENT_PREFIX + 'mousemove';
|
|
61
|
+
const onMouseout = EVENT_PREFIX + 'mouseout';
|
|
62
|
+
const onMouseover = EVENT_PREFIX + 'mouseover';
|
|
63
|
+
const onMouseup = EVENT_PREFIX + 'mouseup';
|
|
64
|
+
const onWheel = EVENT_PREFIX + 'wheel';
|
|
65
|
+
const onPaste = EVENT_PREFIX + 'paste';
|
|
66
|
+
const onPause = EVENT_PREFIX + 'pause';
|
|
67
|
+
const onPlay = EVENT_PREFIX + 'play';
|
|
68
|
+
const onPlaying = EVENT_PREFIX + 'playing';
|
|
69
|
+
const onProgress = EVENT_PREFIX + 'progress';
|
|
70
|
+
const onRatechange = EVENT_PREFIX + 'ratechange';
|
|
71
|
+
const onReset = EVENT_PREFIX + 'reset';
|
|
72
|
+
const onResize = EVENT_PREFIX + 'resize';
|
|
73
|
+
const onScroll = EVENT_PREFIX + 'scroll';
|
|
74
|
+
const onScrollend = EVENT_PREFIX + 'scrollend';
|
|
75
|
+
const onSecuritypolicyviolation = EVENT_PREFIX + 'securitypolicyviolation';
|
|
76
|
+
const onSeeked = EVENT_PREFIX + 'seeked';
|
|
77
|
+
const onSeeking = EVENT_PREFIX + 'seeking';
|
|
78
|
+
const onSelect = EVENT_PREFIX + 'select';
|
|
79
|
+
const onSlotchange = EVENT_PREFIX + 'slotchange';
|
|
80
|
+
const onStalled = EVENT_PREFIX + 'stalled';
|
|
81
|
+
const onSubmit = EVENT_PREFIX + 'submit';
|
|
82
|
+
const onSuspend = EVENT_PREFIX + 'suspend';
|
|
83
|
+
const onTimeupdate = EVENT_PREFIX + 'timeupdate';
|
|
84
|
+
const onVolumechange = EVENT_PREFIX + 'volumechange';
|
|
85
|
+
const onWaiting = EVENT_PREFIX + 'waiting';
|
|
86
|
+
const onSelectstart = EVENT_PREFIX + 'selectstart';
|
|
87
|
+
const onSelectionchange = EVENT_PREFIX + 'selectionchange';
|
|
88
|
+
const onToggle = EVENT_PREFIX + 'toggle';
|
|
89
|
+
const onPointercancel = EVENT_PREFIX + 'pointercancel';
|
|
90
|
+
const onPointerdown = EVENT_PREFIX + 'pointerdown';
|
|
91
|
+
const onPointerup = EVENT_PREFIX + 'pointerup';
|
|
92
|
+
const onPointermove = EVENT_PREFIX + 'pointermove';
|
|
93
|
+
const onPointerout = EVENT_PREFIX + 'pointerout';
|
|
94
|
+
const onPointerover = EVENT_PREFIX + 'pointerover';
|
|
95
|
+
const onPointerenter = EVENT_PREFIX + 'pointerenter';
|
|
96
|
+
const onPointerleave = EVENT_PREFIX + 'pointerleave';
|
|
97
|
+
const onGotpointercapture = EVENT_PREFIX + 'gotpointercapture';
|
|
98
|
+
const onLostpointercapture = EVENT_PREFIX + 'lostpointercapture';
|
|
99
|
+
const onMozfullscreenchange = EVENT_PREFIX + 'mozfullscreenchange';
|
|
100
|
+
const onMozfullscreenerror = EVENT_PREFIX + 'mozfullscreenerror';
|
|
101
|
+
const onAnimationcancel = EVENT_PREFIX + 'animationcancel';
|
|
102
|
+
const onAnimationend = EVENT_PREFIX + 'animationend';
|
|
103
|
+
const onAnimationiteration = EVENT_PREFIX + 'animationiteration';
|
|
104
|
+
const onAnimationstart = EVENT_PREFIX + 'animationstart';
|
|
105
|
+
const onTransitioncancel = EVENT_PREFIX + 'transitioncancel';
|
|
106
|
+
const onTransitionend = EVENT_PREFIX + 'transitionend';
|
|
107
|
+
const onTransitionrun = EVENT_PREFIX + 'transitionrun';
|
|
108
|
+
const onTransitionstart = EVENT_PREFIX + 'transitionstart';
|
|
109
|
+
const onWebkitanimationend = EVENT_PREFIX + 'webkitanimationend';
|
|
110
|
+
const onWebkitanimationiteration = EVENT_PREFIX + 'webkitanimationiteration';
|
|
111
|
+
const onWebkitanimationstart = EVENT_PREFIX + 'webkitanimationstart';
|
|
112
|
+
const onWebkittransitionend = EVENT_PREFIX + 'webkittransitionend';
|
|
113
|
+
const onError = EVENT_PREFIX + 'error';
|
|
114
|
+
|
|
115
|
+
const eventAttrs = [
|
|
116
|
+
onAbort,
|
|
117
|
+
onBlur,
|
|
118
|
+
onFocus,
|
|
119
|
+
onCancel,
|
|
120
|
+
onAuxclick,
|
|
121
|
+
onBeforeinput,
|
|
122
|
+
onBeforetoggle,
|
|
123
|
+
onCanplay,
|
|
124
|
+
onCanplaythrough,
|
|
125
|
+
onChange,
|
|
126
|
+
onClick,
|
|
127
|
+
onClose,
|
|
128
|
+
onCommand,
|
|
129
|
+
onContextmenu,
|
|
130
|
+
onCopy,
|
|
131
|
+
onCuechange,
|
|
132
|
+
onCut,
|
|
133
|
+
onDblclick,
|
|
134
|
+
onDrag,
|
|
135
|
+
onDragend,
|
|
136
|
+
onDragenter,
|
|
137
|
+
onDragexit,
|
|
138
|
+
onDragleave,
|
|
139
|
+
onDragover,
|
|
140
|
+
onDragstart,
|
|
141
|
+
onDrop,
|
|
142
|
+
onDurationchange,
|
|
143
|
+
onEmptied,
|
|
144
|
+
onEnded,
|
|
145
|
+
onFormdata,
|
|
146
|
+
onInput,
|
|
147
|
+
onInvalid,
|
|
148
|
+
onKeydown,
|
|
149
|
+
onKeypress,
|
|
150
|
+
onKeyup,
|
|
151
|
+
onLoad,
|
|
152
|
+
onLoadeddata,
|
|
153
|
+
onLoadedmetadata,
|
|
154
|
+
onLoadstart,
|
|
155
|
+
onMousedown,
|
|
156
|
+
onMouseenter,
|
|
157
|
+
onMouseleave,
|
|
158
|
+
onMousemove,
|
|
159
|
+
onMouseout,
|
|
160
|
+
onMouseover,
|
|
161
|
+
onMouseup,
|
|
162
|
+
onWheel,
|
|
163
|
+
onPaste,
|
|
164
|
+
onPause,
|
|
165
|
+
onPlay,
|
|
166
|
+
onPlaying,
|
|
167
|
+
onProgress,
|
|
168
|
+
onRatechange,
|
|
169
|
+
onReset,
|
|
170
|
+
onResize,
|
|
171
|
+
onScroll,
|
|
172
|
+
onScrollend,
|
|
173
|
+
onSecuritypolicyviolation,
|
|
174
|
+
onSeeked,
|
|
175
|
+
onSeeking,
|
|
176
|
+
onSelect,
|
|
177
|
+
onSlotchange,
|
|
178
|
+
onStalled,
|
|
179
|
+
onSubmit,
|
|
180
|
+
onSuspend,
|
|
181
|
+
onTimeupdate,
|
|
182
|
+
onVolumechange,
|
|
183
|
+
onWaiting,
|
|
184
|
+
onSelectstart,
|
|
185
|
+
onSelectionchange,
|
|
186
|
+
onToggle,
|
|
187
|
+
onPointercancel,
|
|
188
|
+
onPointerdown,
|
|
189
|
+
onPointerup,
|
|
190
|
+
onPointermove,
|
|
191
|
+
onPointerout,
|
|
192
|
+
onPointerover,
|
|
193
|
+
onPointerenter,
|
|
194
|
+
onPointerleave,
|
|
195
|
+
onGotpointercapture,
|
|
196
|
+
onLostpointercapture,
|
|
197
|
+
onMozfullscreenchange,
|
|
198
|
+
onMozfullscreenerror,
|
|
199
|
+
onAnimationcancel,
|
|
200
|
+
onAnimationend,
|
|
201
|
+
onAnimationiteration,
|
|
202
|
+
onAnimationstart,
|
|
203
|
+
onTransitioncancel,
|
|
204
|
+
onTransitionend,
|
|
205
|
+
onTransitionrun,
|
|
206
|
+
onTransitionstart,
|
|
207
|
+
onWebkitanimationend,
|
|
208
|
+
onWebkitanimationiteration,
|
|
209
|
+
onWebkitanimationstart,
|
|
210
|
+
onWebkittransitionend,
|
|
211
|
+
onError,
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
let selector = eventAttrs.map(attr => `[${CSS.escape(attr)}]`).join(', ');
|
|
215
|
+
|
|
216
|
+
const attrToProp = attr => `on${attr[EVENT_PREFIX_LENGTH].toUpperCase()}${attr.substring(EVENT_PREFIX_LENGTH + 1)}`;
|
|
217
|
+
|
|
218
|
+
const eventToProp = event => EVENT_PREFIX + event;
|
|
219
|
+
|
|
220
|
+
const hasEventAttribute = event => eventAttrs.includes(EVENT_PREFIX + event);
|
|
221
|
+
|
|
222
|
+
const isEventDataAttr = ([name]) => name.startsWith(DATA_PREFIX);
|
|
223
|
+
|
|
224
|
+
function _addListeners(el, { signal, attrFilter = EVENTS } = {}) {
|
|
225
|
+
const dataset = el.dataset;
|
|
226
|
+
|
|
227
|
+
for (const [attr, val] of Object.entries(dataset).filter(isEventDataAttr)) {
|
|
228
|
+
try {
|
|
229
|
+
const event = 'on' + attr.substring(DATA_PREFIX_LENGTH);
|
|
230
|
+
|
|
231
|
+
if (attrFilter.hasOwnProperty(event) && hasCallback(val)) {
|
|
232
|
+
el.addEventListener(event.substring(2).toLowerCase(), getCallback(val), {
|
|
233
|
+
passive: dataset.hasOwnProperty('aegisEventPassive'),
|
|
234
|
+
capture: dataset.hasOwnProperty('aegisEventCapture'),
|
|
235
|
+
once: dataset.hasOwnProperty('aegisEventOnce'),
|
|
236
|
+
signal: dataset.hasOwnProperty('aegisEventSignal') ? getSignal(dataset.aegisEventSignal) : signal,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
} catch(err) {
|
|
240
|
+
reportError(err);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const observer = new MutationObserver(records => {
|
|
246
|
+
records.forEach(record => {
|
|
247
|
+
switch(record.type) {
|
|
248
|
+
case 'childList':
|
|
249
|
+
[...record.addedNodes]
|
|
250
|
+
.filter(node => node.nodeType === Node.ELEMENT_NODE)
|
|
251
|
+
.forEach(node => attachListeners(node));
|
|
252
|
+
break;
|
|
253
|
+
|
|
254
|
+
case 'attributes':
|
|
255
|
+
if (typeof record.oldValue === 'string' && hasCallback(record.oldValue)) {
|
|
256
|
+
record.target.removeEventListener(
|
|
257
|
+
record.attributeName.substring(EVENT_PREFIX_LENGTH),
|
|
258
|
+
getCallback(record.oldValue), {
|
|
259
|
+
once: record.target.hasAttribute(once),
|
|
260
|
+
capture: record.target.hasAttribute(capture),
|
|
261
|
+
passive: record.target.hasAttribute(passive),
|
|
262
|
+
}
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (
|
|
267
|
+
record.target.hasAttribute(record.attributeName)
|
|
268
|
+
&& hasCallback(record.target.getAttribute(record.attributeName))
|
|
269
|
+
) {
|
|
270
|
+
record.target.addEventListener(
|
|
271
|
+
record.attributeName.substring(EVENT_PREFIX_LENGTH),
|
|
272
|
+
getCallback(record.target.getAttribute(record.attributeName)), {
|
|
273
|
+
once: record.target.hasAttribute(once),
|
|
274
|
+
capture: record.target.hasAttribute(capture),
|
|
275
|
+
passive: record.target.hasAttribute(passive),
|
|
276
|
+
signal: record.target.hasAttribute(signal) ? getSignal(record.target.getAttribute(signal)) : undefined,
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const EVENTS = {
|
|
286
|
+
onAbort,
|
|
287
|
+
onBlur,
|
|
288
|
+
onFocus,
|
|
289
|
+
onCancel,
|
|
290
|
+
onAuxclick,
|
|
291
|
+
onBeforeinput,
|
|
292
|
+
onBeforetoggle,
|
|
293
|
+
onCanplay,
|
|
294
|
+
onCanplaythrough,
|
|
295
|
+
onChange,
|
|
296
|
+
onClick,
|
|
297
|
+
onClose,
|
|
298
|
+
onCommand,
|
|
299
|
+
onContextmenu,
|
|
300
|
+
onCopy,
|
|
301
|
+
onCuechange,
|
|
302
|
+
onCut,
|
|
303
|
+
onDblclick,
|
|
304
|
+
onDrag,
|
|
305
|
+
onDragend,
|
|
306
|
+
onDragenter,
|
|
307
|
+
onDragexit,
|
|
308
|
+
onDragleave,
|
|
309
|
+
onDragover,
|
|
310
|
+
onDragstart,
|
|
311
|
+
onDrop,
|
|
312
|
+
onDurationchange,
|
|
313
|
+
onEmptied,
|
|
314
|
+
onEnded,
|
|
315
|
+
onFormdata,
|
|
316
|
+
onInput,
|
|
317
|
+
onInvalid,
|
|
318
|
+
onKeydown,
|
|
319
|
+
onKeypress,
|
|
320
|
+
onKeyup,
|
|
321
|
+
onLoad,
|
|
322
|
+
onLoadeddata,
|
|
323
|
+
onLoadedmetadata,
|
|
324
|
+
onLoadstart,
|
|
325
|
+
onMousedown,
|
|
326
|
+
onMouseenter,
|
|
327
|
+
onMouseleave,
|
|
328
|
+
onMousemove,
|
|
329
|
+
onMouseout,
|
|
330
|
+
onMouseover,
|
|
331
|
+
onMouseup,
|
|
332
|
+
onWheel,
|
|
333
|
+
onPaste,
|
|
334
|
+
onPause,
|
|
335
|
+
onPlay,
|
|
336
|
+
onPlaying,
|
|
337
|
+
onProgress,
|
|
338
|
+
onRatechange,
|
|
339
|
+
onReset,
|
|
340
|
+
onResize,
|
|
341
|
+
onScroll,
|
|
342
|
+
onScrollend,
|
|
343
|
+
onSecuritypolicyviolation,
|
|
344
|
+
onSeeked,
|
|
345
|
+
onSeeking,
|
|
346
|
+
onSelect,
|
|
347
|
+
onSlotchange,
|
|
348
|
+
onStalled,
|
|
349
|
+
onSubmit,
|
|
350
|
+
onSuspend,
|
|
351
|
+
onTimeupdate,
|
|
352
|
+
onVolumechange,
|
|
353
|
+
onWaiting,
|
|
354
|
+
onSelectstart,
|
|
355
|
+
onSelectionchange,
|
|
356
|
+
onToggle,
|
|
357
|
+
onPointercancel,
|
|
358
|
+
onPointerdown,
|
|
359
|
+
onPointerup,
|
|
360
|
+
onPointermove,
|
|
361
|
+
onPointerout,
|
|
362
|
+
onPointerover,
|
|
363
|
+
onPointerenter,
|
|
364
|
+
onPointerleave,
|
|
365
|
+
onGotpointercapture,
|
|
366
|
+
onLostpointercapture,
|
|
367
|
+
onMozfullscreenchange,
|
|
368
|
+
onMozfullscreenerror,
|
|
369
|
+
onAnimationcancel,
|
|
370
|
+
onAnimationend,
|
|
371
|
+
onAnimationiteration,
|
|
372
|
+
onAnimationstart,
|
|
373
|
+
onTransitioncancel,
|
|
374
|
+
onTransitionend,
|
|
375
|
+
onTransitionrun,
|
|
376
|
+
onTransitionstart,
|
|
377
|
+
onWebkitanimationend,
|
|
378
|
+
onWebkitanimationiteration,
|
|
379
|
+
onWebkitanimationstart,
|
|
380
|
+
onWebkittransitionend,
|
|
381
|
+
onError,
|
|
382
|
+
once,
|
|
383
|
+
passive,
|
|
384
|
+
capture,
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Register an attribute to observe for adding/removing event listeners
|
|
389
|
+
*
|
|
390
|
+
* @param {string} attr Name of the attribute to observe
|
|
391
|
+
* @param {object} options
|
|
392
|
+
* @param {boolean} [options.addListeners=false] Whether or not to automatically add listeners
|
|
393
|
+
* @param {Document|Element} [options.base=document.body] Root node to observe
|
|
394
|
+
* @param {AbortSignal} [options.signal] An abort signal to remove any listeners when aborted
|
|
395
|
+
* @returns {string} The resulting `data-*` attribute name
|
|
396
|
+
*/
|
|
397
|
+
function registerEventAttribute(attr, {
|
|
398
|
+
addListeners = false,
|
|
399
|
+
base = document.body,
|
|
400
|
+
signal,
|
|
401
|
+
} = {}) {
|
|
402
|
+
const fullAttr = EVENT_PREFIX + attr.toLowerCase();
|
|
403
|
+
|
|
404
|
+
if (! eventAttrs.includes(fullAttr)) {
|
|
405
|
+
const sel = `[${CSS.escape(fullAttr)}]`;
|
|
406
|
+
const prop = attrToProp(fullAttr);
|
|
407
|
+
eventAttrs.push(fullAttr);
|
|
408
|
+
EVENTS[prop] = fullAttr;
|
|
409
|
+
selector += `, ${sel}`;
|
|
410
|
+
|
|
411
|
+
if (addListeners) {
|
|
412
|
+
requestAnimationFrame(() => {
|
|
413
|
+
const config = { attrFilter: { [prop]: sel }, signal };
|
|
414
|
+
[base, ...base.querySelectorAll(sel)].forEach(el => _addListeners(el, config));
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return fullAttr;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Registers an `AbortController` in the controller registry and returns the key for it
|
|
424
|
+
*
|
|
425
|
+
* @param {AbortController} controller
|
|
426
|
+
* @returns {string} The randomly generated key with which the controller is registered
|
|
427
|
+
* @throws {TypeError} If controller is not an `AbortController`
|
|
428
|
+
* @throws {Error} Any `reason` if controller is already aborted
|
|
429
|
+
*/
|
|
430
|
+
function registerController(controller) {
|
|
431
|
+
if (! (controller instanceof AbortController)) {
|
|
432
|
+
throw new TypeError('Controller is not an `AbortSignal.');
|
|
433
|
+
} else if (controller.signal.aborted) {
|
|
434
|
+
throw controller.signal.reason;
|
|
435
|
+
} else if (typeof controller.signal[controllerSymbol] === 'string') {
|
|
436
|
+
return controller.signal[controllerSymbol];
|
|
437
|
+
} else {
|
|
438
|
+
const key = 'aegis:event:controller:' + crypto.randomUUID();
|
|
439
|
+
Object.defineProperty(controller.signal, controllerSymbol, { value: key, writable: false, enumerable: false });
|
|
440
|
+
controllerRegistry.set(key, controller);
|
|
441
|
+
|
|
442
|
+
controller.signal.addEventListener('abort', unregisterController, { once: true });
|
|
443
|
+
|
|
444
|
+
return key;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Removes a controller from the registry
|
|
450
|
+
*
|
|
451
|
+
* @param {AbortController|AbortSignal|string} key The registed key or the controller or signal it corresponds to
|
|
452
|
+
* @returns {boolean} Whether or not the controller was successfully unregistered
|
|
453
|
+
*/
|
|
454
|
+
function unregisterController(key) {
|
|
455
|
+
if (key instanceof AbortController) {
|
|
456
|
+
return controllerRegistry.delete(key.signal[controllerSymbol]);
|
|
457
|
+
} else if (key instanceof AbortSignal) {
|
|
458
|
+
return controllerRegistry.delete(key[controllerSymbol]);
|
|
459
|
+
} else {
|
|
460
|
+
return controllerRegistry.delete(key);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Creates and registers an `AbortController` in the controller registry and returns the key for it
|
|
466
|
+
*
|
|
467
|
+
* @param {object} options
|
|
468
|
+
* @param {AbortSignal} [options.signal] An optional `AbortSignal` to externally abort the controller with
|
|
469
|
+
* @returns {string} The randomly generated key with which the controller is registered
|
|
470
|
+
*/
|
|
471
|
+
function createController({ signal } = {}) {
|
|
472
|
+
const controller = new AbortController();
|
|
473
|
+
|
|
474
|
+
if (signal instanceof AbortSignal) {
|
|
475
|
+
signal.addEventListener('abort', ({ target }) => controller.abort(target.reason), { signal: controller.signal});
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return registerController(controller);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Get a registetd controller from the registry
|
|
483
|
+
*
|
|
484
|
+
* @param {string} key Generated key with which the controller was registered
|
|
485
|
+
* @returns {AbortController|void} Any registered controller, if any
|
|
486
|
+
*/
|
|
487
|
+
const getController = key => controllerRegistry.get(key);
|
|
488
|
+
|
|
489
|
+
function abortController(key, reason) {
|
|
490
|
+
const controller = getController(key);
|
|
491
|
+
|
|
492
|
+
if (! (controller instanceof AbortController)) {
|
|
493
|
+
return false;
|
|
494
|
+
} else if (typeof reason === 'string') {
|
|
495
|
+
controller.abort(new Error(reason));
|
|
496
|
+
return true;
|
|
497
|
+
} else {
|
|
498
|
+
controller.abort(reason);
|
|
499
|
+
return true;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Register an `AbortSignal` to be used in declarative HTML as a value for `data-aegis-event-signal`
|
|
505
|
+
*
|
|
506
|
+
* @param {AbortSignal} signal The signal to register
|
|
507
|
+
* @returns {string} The registered key
|
|
508
|
+
* @throws {TypeError} Thrown if not an `AbortSignal`
|
|
509
|
+
*/
|
|
510
|
+
function registerSignal(signal) {
|
|
511
|
+
if (! (signal instanceof AbortSignal)) {
|
|
512
|
+
throw new TypeError('Signal must be an `AbortSignal`.');
|
|
513
|
+
} else if (typeof signal[signalSymbol] === 'string') {
|
|
514
|
+
return signal[signalSymbol];
|
|
515
|
+
} else {
|
|
516
|
+
const key = 'aegis:event:signal:' + crypto.randomUUID();
|
|
517
|
+
Object.defineProperty(signal, signalSymbol, { value: key, writable: false, enumerable: false });
|
|
518
|
+
signalRegistry.set(key, signal);
|
|
519
|
+
signal.addEventListener('abort', ({ target }) => unregisterSignal(target[signalSymbol]), { once: true });
|
|
520
|
+
|
|
521
|
+
return key;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Gets and `AbortSignal` from the registry
|
|
527
|
+
*
|
|
528
|
+
* @param {string} key The registered key for the signal
|
|
529
|
+
* @returns {AbortSignal|void} The corresponding `AbortSignal`, if any
|
|
530
|
+
*/
|
|
531
|
+
const getSignal = key => signalRegistry.get(key);
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Removes an `AbortSignal` from the registry
|
|
535
|
+
*
|
|
536
|
+
* @param {AbortSignal|string} signal An `AbortSignal` or the registered key for one
|
|
537
|
+
* @returns {boolean} Whether or not the signal was sucessfully unregistered
|
|
538
|
+
* @throws {TypeError} Throws if `signal` is not an `AbortSignal` or the key for a registered signal
|
|
539
|
+
*/
|
|
540
|
+
function unregisterSignal(signal) {
|
|
541
|
+
if (signal instanceof AbortSignal) {
|
|
542
|
+
return signalRegistry.delete(signal[signalSymbol]);
|
|
543
|
+
} else if (typeof signal === 'string') {
|
|
544
|
+
return signalRegistry.delete(signal);
|
|
545
|
+
} else {
|
|
546
|
+
throw new TypeError('Signal must be an `AbortSignal` or registered key/attribute.');
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Add listeners to an element and its children, matching a generated query based on registered attributes
|
|
552
|
+
*
|
|
553
|
+
* @param {Element|Document} target Root node to add listeners from
|
|
554
|
+
* @param {object} options
|
|
555
|
+
* @param {AbortSignal} [options.signal] Optional signal to remove event listeners
|
|
556
|
+
* @returns {Element|Document} Returns the passed target node
|
|
557
|
+
*/
|
|
558
|
+
function attachListeners(target, { signal } = {}) {
|
|
559
|
+
const nodes = target instanceof Element && target.matches(selector)
|
|
560
|
+
? [target, ...target.querySelectorAll(selector)]
|
|
561
|
+
: target.querySelectorAll(selector);
|
|
562
|
+
|
|
563
|
+
nodes.forEach(el => _addListeners(el, { signal }));
|
|
564
|
+
|
|
565
|
+
return target;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Add a node to the `MutationObserver` to observe attributes and add/remove event listeners
|
|
570
|
+
*
|
|
571
|
+
* @param {Document|Element} root Element to observe attributes on
|
|
572
|
+
*/
|
|
573
|
+
function observeEvents(root = document) {
|
|
574
|
+
attachListeners(root);
|
|
575
|
+
|
|
576
|
+
observer.observe(root, {
|
|
577
|
+
subtree: true,
|
|
578
|
+
childList:true,
|
|
579
|
+
attributes: true,
|
|
580
|
+
attributeOldValue: true,
|
|
581
|
+
attributeFilter: eventAttrs,
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Disconnects the `MutationObserver`, disabling observing of all attribute changes
|
|
587
|
+
*
|
|
588
|
+
* @returns {void}
|
|
589
|
+
*/
|
|
590
|
+
const disconnectEventsObserver = () => observer.disconnect();
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Register a global error handler callback
|
|
594
|
+
*
|
|
595
|
+
* @param {Function} callback Callback to register as a global error handler
|
|
596
|
+
* @param {EventInit} config Typical event listener config object
|
|
597
|
+
*/
|
|
598
|
+
function setGlobalErrorHandler(callback, { capture, once, passive, signal } = {}) {
|
|
599
|
+
if (callback instanceof Function) {
|
|
600
|
+
globalThis.addEventListener('error', callback, { capture, once, passive, signal });
|
|
601
|
+
} else {
|
|
602
|
+
throw new TypeError('Callback is not a function.');
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
3
606
|
let _isRegistrationOpen = true;
|
|
4
607
|
|
|
5
608
|
const $$ = (selector, base = document) => base.querySelectorAll(selector);
|
|
6
609
|
|
|
7
610
|
const $ = (selector, base = document) => base.querySelector(selector);
|
|
8
611
|
|
|
612
|
+
const requestFullscreen = { attr: 'data-request-fullscreen-selector', data: 'requestFullscreenSelector' };
|
|
613
|
+
const toggleFullsceen = { attr: 'data-toggle-fullscreen-selector', data: 'toggleFullscreenSelector' };
|
|
614
|
+
|
|
9
615
|
const FUNCS = {
|
|
10
616
|
debug: {
|
|
11
617
|
log: 'aegis:debug:log',
|
|
@@ -17,10 +623,12 @@ const FUNCS = {
|
|
|
17
623
|
back: 'aegis:navigate:back',
|
|
18
624
|
forward: 'aegis:navigate:forward',
|
|
19
625
|
reload: 'aegis:navigate:reload',
|
|
626
|
+
close: 'aegis:navigate:close',
|
|
20
627
|
link: 'aegis:navigate:go',
|
|
21
628
|
popup: 'aegis:navigate:popup',
|
|
22
629
|
},
|
|
23
630
|
ui: {
|
|
631
|
+
command: 'aegis:ui:command',
|
|
24
632
|
print: 'aegis:ui:print',
|
|
25
633
|
remove: 'aegis:ui:remove',
|
|
26
634
|
hide: 'aegis:ui:hide',
|
|
@@ -34,6 +642,14 @@ const FUNCS = {
|
|
|
34
642
|
disable: 'aegis:ui:disable',
|
|
35
643
|
scrollTo: 'aegis:ui:scrollTo',
|
|
36
644
|
prevent: 'aegis:ui:prevent',
|
|
645
|
+
revokeObjectURL: 'aegis:ui:revokeObjectURL',
|
|
646
|
+
cancelAnimationFrame: 'aegis:ui:cancelAnimationFrame',
|
|
647
|
+
requestFullscreen: 'aegis:ui:requestFullscreen',
|
|
648
|
+
toggleFullscreen: 'aegis:ui:toggleFullsceen',
|
|
649
|
+
exitFullsceen: 'aegis:ui:exitFullscreen',
|
|
650
|
+
open: 'aegis:ui:open',
|
|
651
|
+
close: 'aegis:ui:close',
|
|
652
|
+
abortController: 'aegis:ui:controller:abort',
|
|
37
653
|
},
|
|
38
654
|
};
|
|
39
655
|
|
|
@@ -45,6 +661,7 @@ const registry = new Map([
|
|
|
45
661
|
[FUNCS.navigate.back, () => history.back()],
|
|
46
662
|
[FUNCS.navigate.forward, () => history.forward()],
|
|
47
663
|
[FUNCS.navigate.reload, () => history.go(0)],
|
|
664
|
+
[FUNCS.navigate.close, () => globalThis.close()],
|
|
48
665
|
[FUNCS.navigate.link, event => {
|
|
49
666
|
if (event.isTrusted) {
|
|
50
667
|
event.preventDefault();
|
|
@@ -83,6 +700,13 @@ const registry = new Map([
|
|
|
83
700
|
});
|
|
84
701
|
}
|
|
85
702
|
}],
|
|
703
|
+
[FUNCS.ui.revokeObjectURL, ({ currentTarget }) => URL.revokeObjectURL(currentTarget.src)],
|
|
704
|
+
[FUNCS.ui.cancelAnimationFrame, ({ currentTarget }) => cancelAnimationFrame(parseInt(currentTarget.dataset.animationFrame))],
|
|
705
|
+
[FUNCS.ui.clearInterval, ({ currentTarget }) => clearInterval(parseInt(currentTarget.dataset.clearInterval))],
|
|
706
|
+
[FUNCS.ui.clearTimeout, ({ currentTarget }) => clearTimeout(parseInt(currentTarget.dataset.timeout))],
|
|
707
|
+
[FUNCS.ui.abortController, ({ currentTarget }) => abortController(currentTarget.dataset.aegisEventController, currentTarget.dataset.aegisControllerReason)],
|
|
708
|
+
[FUNCS.ui.open, ({ currentTarget }) => document.querySelector(currentTarget.dataset.openSelector).open = true],
|
|
709
|
+
[FUNCS.ui.close, ({ currentTarget }) => document.querySelector(currentTarget.dataset.closeSelector).open = false],
|
|
86
710
|
[FUNCS.ui.showModal, ({ currentTarget }) => {
|
|
87
711
|
const target = $(currentTarget.dataset.showModalSelector);
|
|
88
712
|
|
|
@@ -120,6 +744,25 @@ const registry = new Map([
|
|
|
120
744
|
}],
|
|
121
745
|
[FUNCS.ui.print, () => globalThis.print()],
|
|
122
746
|
[FUNCS.ui.prevent, event => event.preventDefault()],
|
|
747
|
+
[FUNCS.ui.requestFullscreen, ({ currentTarget}) => {
|
|
748
|
+
if (currentTarget.dataset.hasOwnProperty(requestFullscreen.data)) {
|
|
749
|
+
document.getElementById(currentTarget.dataset[requestFullscreen.data]).requestFullscreen();
|
|
750
|
+
} else {
|
|
751
|
+
currentTarget.requestFullscreen();
|
|
752
|
+
}
|
|
753
|
+
}],
|
|
754
|
+
[FUNCS.ui.toggleFullscreen, ({ currentTarget }) => {
|
|
755
|
+
const target = currentTarget.dataset.hasOwnProperty(toggleFullsceen.data)
|
|
756
|
+
? document.getElementById(currentTarget.dataset[toggleFullsceen.data])
|
|
757
|
+
: currentTarget;
|
|
758
|
+
|
|
759
|
+
if (target.isSameNode(document.fullscreenElement)) {
|
|
760
|
+
document.exitFullscreen();
|
|
761
|
+
} else {
|
|
762
|
+
target.requestFullscreen();
|
|
763
|
+
}
|
|
764
|
+
}],
|
|
765
|
+
[FUNCS.ui.exitFullsceen, () => document.exitFullscreen()],
|
|
123
766
|
]);
|
|
124
767
|
|
|
125
768
|
/**
|
|
@@ -240,289 +883,172 @@ function getHost(target) {
|
|
|
240
883
|
}
|
|
241
884
|
}
|
|
242
885
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
EVENT_PREFIX + 'abort',
|
|
254
|
-
EVENT_PREFIX + 'blur',
|
|
255
|
-
EVENT_PREFIX + 'focus',
|
|
256
|
-
EVENT_PREFIX + 'cancel',
|
|
257
|
-
EVENT_PREFIX + 'auxclick',
|
|
258
|
-
EVENT_PREFIX + 'beforeinput',
|
|
259
|
-
EVENT_PREFIX + 'beforetoggle',
|
|
260
|
-
EVENT_PREFIX + 'canplay',
|
|
261
|
-
EVENT_PREFIX + 'canplaythrough',
|
|
262
|
-
EVENT_PREFIX + 'change',
|
|
263
|
-
EVENT_PREFIX + 'click',
|
|
264
|
-
EVENT_PREFIX + 'close',
|
|
265
|
-
EVENT_PREFIX + 'contextmenu',
|
|
266
|
-
EVENT_PREFIX + 'copy',
|
|
267
|
-
EVENT_PREFIX + 'cuechange',
|
|
268
|
-
EVENT_PREFIX + 'cut',
|
|
269
|
-
EVENT_PREFIX + 'dblclick',
|
|
270
|
-
EVENT_PREFIX + 'drag',
|
|
271
|
-
EVENT_PREFIX + 'dragend',
|
|
272
|
-
EVENT_PREFIX + 'dragenter',
|
|
273
|
-
EVENT_PREFIX + 'dragexit',
|
|
274
|
-
EVENT_PREFIX + 'dragleave',
|
|
275
|
-
EVENT_PREFIX + 'dragover',
|
|
276
|
-
EVENT_PREFIX + 'dragstart',
|
|
277
|
-
EVENT_PREFIX + 'drop',
|
|
278
|
-
EVENT_PREFIX + 'durationchange',
|
|
279
|
-
EVENT_PREFIX + 'emptied',
|
|
280
|
-
EVENT_PREFIX + 'ended',
|
|
281
|
-
EVENT_PREFIX + 'formdata',
|
|
282
|
-
EVENT_PREFIX + 'input',
|
|
283
|
-
EVENT_PREFIX + 'invalid',
|
|
284
|
-
EVENT_PREFIX + 'keydown',
|
|
285
|
-
EVENT_PREFIX + 'keypress',
|
|
286
|
-
EVENT_PREFIX + 'keyup',
|
|
287
|
-
EVENT_PREFIX + 'load',
|
|
288
|
-
EVENT_PREFIX + 'loadeddata',
|
|
289
|
-
EVENT_PREFIX + 'loadedmetadata',
|
|
290
|
-
EVENT_PREFIX + 'loadstart',
|
|
291
|
-
EVENT_PREFIX + 'mousedown',
|
|
292
|
-
EVENT_PREFIX + 'mouseenter',
|
|
293
|
-
EVENT_PREFIX + 'mouseleave',
|
|
294
|
-
EVENT_PREFIX + 'mousemove',
|
|
295
|
-
EVENT_PREFIX + 'mouseout',
|
|
296
|
-
EVENT_PREFIX + 'mouseover',
|
|
297
|
-
EVENT_PREFIX + 'mouseup',
|
|
298
|
-
EVENT_PREFIX + 'wheel',
|
|
299
|
-
EVENT_PREFIX + 'paste',
|
|
300
|
-
EVENT_PREFIX + 'pause',
|
|
301
|
-
EVENT_PREFIX + 'play',
|
|
302
|
-
EVENT_PREFIX + 'playing',
|
|
303
|
-
EVENT_PREFIX + 'progress',
|
|
304
|
-
EVENT_PREFIX + 'ratechange',
|
|
305
|
-
EVENT_PREFIX + 'reset',
|
|
306
|
-
EVENT_PREFIX + 'resize',
|
|
307
|
-
EVENT_PREFIX + 'scroll',
|
|
308
|
-
EVENT_PREFIX + 'scrollend',
|
|
309
|
-
EVENT_PREFIX + 'securitypolicyviolation',
|
|
310
|
-
EVENT_PREFIX + 'seeked',
|
|
311
|
-
EVENT_PREFIX + 'seeking',
|
|
312
|
-
EVENT_PREFIX + 'select',
|
|
313
|
-
EVENT_PREFIX + 'slotchange',
|
|
314
|
-
EVENT_PREFIX + 'stalled',
|
|
315
|
-
EVENT_PREFIX + 'submit',
|
|
316
|
-
EVENT_PREFIX + 'suspend',
|
|
317
|
-
EVENT_PREFIX + 'timeupdate',
|
|
318
|
-
EVENT_PREFIX + 'volumechange',
|
|
319
|
-
EVENT_PREFIX + 'waiting',
|
|
320
|
-
EVENT_PREFIX + 'selectstart',
|
|
321
|
-
EVENT_PREFIX + 'selectionchange',
|
|
322
|
-
EVENT_PREFIX + 'toggle',
|
|
323
|
-
EVENT_PREFIX + 'pointercancel',
|
|
324
|
-
EVENT_PREFIX + 'pointerdown',
|
|
325
|
-
EVENT_PREFIX + 'pointerup',
|
|
326
|
-
EVENT_PREFIX + 'pointermove',
|
|
327
|
-
EVENT_PREFIX + 'pointerout',
|
|
328
|
-
EVENT_PREFIX + 'pointerover',
|
|
329
|
-
EVENT_PREFIX + 'pointerenter',
|
|
330
|
-
EVENT_PREFIX + 'pointerleave',
|
|
331
|
-
EVENT_PREFIX + 'gotpointercapture',
|
|
332
|
-
EVENT_PREFIX + 'lostpointercapture',
|
|
333
|
-
EVENT_PREFIX + 'mozfullscreenchange',
|
|
334
|
-
EVENT_PREFIX + 'mozfullscreenerror',
|
|
335
|
-
EVENT_PREFIX + 'animationcancel',
|
|
336
|
-
EVENT_PREFIX + 'animationend',
|
|
337
|
-
EVENT_PREFIX + 'animationiteration',
|
|
338
|
-
EVENT_PREFIX + 'animationstart',
|
|
339
|
-
EVENT_PREFIX + 'transitioncancel',
|
|
340
|
-
EVENT_PREFIX + 'transitionend',
|
|
341
|
-
EVENT_PREFIX + 'transitionrun',
|
|
342
|
-
EVENT_PREFIX + 'transitionstart',
|
|
343
|
-
EVENT_PREFIX + 'webkitanimationend',
|
|
344
|
-
EVENT_PREFIX + 'webkitanimationiteration',
|
|
345
|
-
EVENT_PREFIX + 'webkitanimationstart',
|
|
346
|
-
EVENT_PREFIX + 'webkittransitionend',
|
|
347
|
-
EVENT_PREFIX + 'error',
|
|
348
|
-
];
|
|
349
|
-
|
|
350
|
-
let selector = eventAttrs.map(attr => `[${CSS.escape(attr)}]`).join(', ');
|
|
351
|
-
|
|
352
|
-
const attrToProp = attr => `on${attr[EVENT_PREFIX_LENGTH].toUpperCase()}${attr.substring(EVENT_PREFIX_LENGTH + 1)}`;
|
|
353
|
-
|
|
354
|
-
const attrEntriesMap = attr => [attrToProp(attr), attr];
|
|
355
|
-
|
|
356
|
-
const isEventDataAttr = ([name]) => name.startsWith(DATA_PREFIX);
|
|
357
|
-
|
|
358
|
-
const DATA_EVENTS = Object.fromEntries([...eventAttrs].map(attrEntriesMap));
|
|
359
|
-
|
|
360
|
-
function _addListeners(el, { signal, attrFilter = EVENTS } = {}) {
|
|
361
|
-
const dataset = el.dataset;
|
|
362
|
-
|
|
363
|
-
for (const [attr, val] of Object.entries(dataset).filter(isEventDataAttr)) {
|
|
364
|
-
try {
|
|
365
|
-
const event = 'on' + attr.substring(DATA_PREFIX_LENGTH);
|
|
366
|
-
|
|
367
|
-
if (attrFilter.hasOwnProperty(event) && hasCallback(val)) {
|
|
368
|
-
el.addEventListener(event.substring(2).toLowerCase(), getCallback(val), {
|
|
369
|
-
passive: dataset.hasOwnProperty('aegisEventPassive'),
|
|
370
|
-
capture: dataset.hasOwnProperty('aegisEventCapture'),
|
|
371
|
-
once: dataset.hasOwnProperty('aegisEventOnce'),
|
|
372
|
-
signal,
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
} catch(err) {
|
|
376
|
-
console.error(err);
|
|
886
|
+
function on(event, callback, { capture: capture$1 = false, passive: passive$1 = false, once: once$1 = false, signal: signal$1 } = {}) {
|
|
887
|
+
if (callback instanceof Function) {
|
|
888
|
+
return on(event, createCallback(callback), { capture: capture$1, passive: passive$1, once: once$1, signal: signal$1 });
|
|
889
|
+
} else if (typeof callback !== 'string' || callback.length === 0) {
|
|
890
|
+
throw new TypeError('Callback must be a function or a registered callback string.');
|
|
891
|
+
} else if (typeof event !== 'string' || event.length === 0) {
|
|
892
|
+
throw new TypeError('Event must be a non-empty string.');
|
|
893
|
+
} else {
|
|
894
|
+
if (! hasEventAttribute(event)) {
|
|
895
|
+
registerEventAttribute(event);
|
|
377
896
|
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
const observer = new MutationObserver(records => {
|
|
382
|
-
records.forEach(record => {
|
|
383
|
-
switch(record.type) {
|
|
384
|
-
case 'childList':
|
|
385
|
-
[...record.addedNodes]
|
|
386
|
-
.filter(node => node.nodeType === Node.ELEMENT_NODE)
|
|
387
|
-
.forEach(node => attachListeners(node));
|
|
388
|
-
break;
|
|
389
897
|
|
|
390
|
-
|
|
391
|
-
if (typeof record.oldValue === 'string' && hasCallback(record.oldValue)) {
|
|
392
|
-
record.target.removeEventListener(
|
|
393
|
-
record.attributeName.substring(EVENT_PREFIX_LENGTH),
|
|
394
|
-
getCallback(record.oldValue), {
|
|
395
|
-
once: record.target.hasAttribute(once),
|
|
396
|
-
capture: record.target.hasAttribute(capture),
|
|
397
|
-
passive: record.target.hasAttribute(passive),
|
|
398
|
-
}
|
|
399
|
-
);
|
|
400
|
-
}
|
|
898
|
+
const parts = [[eventToProp(event), callback]];
|
|
401
899
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
&& hasCallback(record.target.getAttribute(record.attributeName))
|
|
405
|
-
) {
|
|
406
|
-
record.target.addEventListener(
|
|
407
|
-
record.attributeName.substring(EVENT_PREFIX_LENGTH),
|
|
408
|
-
getCallback(record.target.getAttribute(record.attributeName)), {
|
|
409
|
-
once: record.target.hasAttribute(once),
|
|
410
|
-
capture: record.target.hasAttribute(capture),
|
|
411
|
-
passive: record.target.hasAttribute(passive),
|
|
412
|
-
}
|
|
413
|
-
);
|
|
414
|
-
}
|
|
415
|
-
break;
|
|
900
|
+
if (capture$1) {
|
|
901
|
+
parts.push([capture, '']);
|
|
416
902
|
}
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
const EVENTS = { ...DATA_EVENTS, once, passive, capture };
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Register an attribute to observe for adding/removing event listeners
|
|
424
|
-
*
|
|
425
|
-
* @param {string} attr Name of the attribute to observe
|
|
426
|
-
* @param {object} options
|
|
427
|
-
* @param {boolean} [options.addListeners=false] Whether or not to automatically add listeners
|
|
428
|
-
* @param {Document|Element} [options.base=document.body] Root node to observe
|
|
429
|
-
* @param {AbortSignal} [options.signal] An abort signal to remove any listeners when aborted
|
|
430
|
-
* @returns {string} The resulting `data-*` attribute name
|
|
431
|
-
*/
|
|
432
|
-
function registerEventAttribute(attr, {
|
|
433
|
-
addListeners = false,
|
|
434
|
-
base = document.body,
|
|
435
|
-
signal,
|
|
436
|
-
} = {}) {
|
|
437
|
-
const fullAttr = EVENT_PREFIX + attr.toLowerCase();
|
|
438
|
-
|
|
439
|
-
if (! eventAttrs.includes(fullAttr)) {
|
|
440
|
-
const sel = `[${CSS.escape(fullAttr)}]`;
|
|
441
|
-
const prop = attrToProp(fullAttr);
|
|
442
|
-
eventAttrs.push(fullAttr);
|
|
443
|
-
EVENTS[prop] = fullAttr;
|
|
444
|
-
selector += `, ${sel}`;
|
|
445
903
|
|
|
446
|
-
if (
|
|
447
|
-
|
|
448
|
-
const config = { attrFilter: { [prop]: sel }, signal };
|
|
449
|
-
[base, ...base.querySelectorAll(sel)].forEach(el => _addListeners(el, config));
|
|
450
|
-
});
|
|
904
|
+
if (passive$1) {
|
|
905
|
+
parts.push([passive, '']);
|
|
451
906
|
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
return fullAttr;
|
|
455
|
-
}
|
|
456
907
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
* @param {Element|Document} target Root node to add listeners from
|
|
461
|
-
* @param {object} options
|
|
462
|
-
* @param {AbortSignal} [options.signal] Optional signal to remove event listeners
|
|
463
|
-
* @returns {Element|Document} Returns the passed target node
|
|
464
|
-
*/
|
|
465
|
-
function attachListeners(target, { signal } = {}) {
|
|
466
|
-
const nodes = target instanceof Element && target.matches(selector)
|
|
467
|
-
? [target, ...target.querySelectorAll(selector)]
|
|
468
|
-
: target.querySelectorAll(selector);
|
|
469
|
-
|
|
470
|
-
nodes.forEach(el => _addListeners(el, { signal }));
|
|
471
|
-
|
|
472
|
-
return target;
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Add a node to the `MutationObserver` to observe attributes and add/remove event listeners
|
|
476
|
-
*
|
|
477
|
-
* @param {Document|Element} root Element to observe attributes on
|
|
478
|
-
*/
|
|
479
|
-
function observeEvents(root = document) {
|
|
480
|
-
attachListeners(root);
|
|
481
|
-
observer.observe(root, {
|
|
482
|
-
subtree: true,
|
|
483
|
-
childList:true,
|
|
484
|
-
attributes: true,
|
|
485
|
-
attributeOldValue: true,
|
|
486
|
-
attributeFilter: eventAttrs,
|
|
487
|
-
});
|
|
488
|
-
}
|
|
908
|
+
if (once$1) {
|
|
909
|
+
parts.push([once, '']);
|
|
910
|
+
}
|
|
489
911
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const disconnectEventsObserver = () => observer.disconnect();
|
|
912
|
+
if (signal$1 instanceof AbortSignal) {
|
|
913
|
+
parts.push([signal, registerSignal(signal$1)]);
|
|
914
|
+
} else if (typeof signal$1 === 'string') {
|
|
915
|
+
parts.push([signal, signal$1]);
|
|
916
|
+
}
|
|
496
917
|
|
|
497
|
-
|
|
498
|
-
* Register a global error handler callback
|
|
499
|
-
*
|
|
500
|
-
* @param {Function} callback Callback to register as a global error handler
|
|
501
|
-
* @param {EventInit} config Typical event listener config object
|
|
502
|
-
*/
|
|
503
|
-
function setGlobalErrorHandler(callback, { capture, once, passive, signal } = {}) {
|
|
504
|
-
if (callback instanceof Function) {
|
|
505
|
-
globalThis.addEventListener('error', callback, { capture, once, passive, signal });
|
|
506
|
-
} else {
|
|
507
|
-
throw new TypeError('Callback is not a function.');
|
|
918
|
+
return parts.map(([prop, val]) => `${prop}="${val}"`).join(' ');
|
|
508
919
|
}
|
|
509
920
|
}
|
|
510
921
|
|
|
511
922
|
exports.EVENTS = EVENTS;
|
|
512
923
|
exports.FUNCS = FUNCS;
|
|
924
|
+
exports.abortController = abortController;
|
|
513
925
|
exports.attachListeners = attachListeners;
|
|
514
926
|
exports.callCallback = callCallback;
|
|
927
|
+
exports.capture = capture;
|
|
515
928
|
exports.clearRegistry = clearRegistry;
|
|
516
929
|
exports.closeRegistration = closeRegistration;
|
|
930
|
+
exports.controller = controller;
|
|
517
931
|
exports.createCallback = createCallback;
|
|
932
|
+
exports.createController = createController;
|
|
518
933
|
exports.disconnectEventsObserver = disconnectEventsObserver;
|
|
934
|
+
exports.eventAttrs = eventAttrs;
|
|
935
|
+
exports.eventToProp = eventToProp;
|
|
519
936
|
exports.getCallback = getCallback;
|
|
937
|
+
exports.getController = getController;
|
|
520
938
|
exports.getHost = getHost;
|
|
939
|
+
exports.getSignal = getSignal;
|
|
521
940
|
exports.hasCallback = hasCallback;
|
|
941
|
+
exports.hasEventAttribute = hasEventAttribute;
|
|
522
942
|
exports.isRegistrationOpen = isRegistrationOpen;
|
|
523
943
|
exports.listCallbacks = listCallbacks;
|
|
524
944
|
exports.observeEvents = observeEvents;
|
|
945
|
+
exports.on = on;
|
|
946
|
+
exports.onAbort = onAbort;
|
|
947
|
+
exports.onAnimationcancel = onAnimationcancel;
|
|
948
|
+
exports.onAnimationend = onAnimationend;
|
|
949
|
+
exports.onAnimationiteration = onAnimationiteration;
|
|
950
|
+
exports.onAnimationstart = onAnimationstart;
|
|
951
|
+
exports.onAuxclick = onAuxclick;
|
|
952
|
+
exports.onBeforeinput = onBeforeinput;
|
|
953
|
+
exports.onBeforetoggle = onBeforetoggle;
|
|
954
|
+
exports.onBlur = onBlur;
|
|
955
|
+
exports.onCancel = onCancel;
|
|
956
|
+
exports.onCanplay = onCanplay;
|
|
957
|
+
exports.onCanplaythrough = onCanplaythrough;
|
|
958
|
+
exports.onChange = onChange;
|
|
959
|
+
exports.onClick = onClick;
|
|
960
|
+
exports.onClose = onClose;
|
|
961
|
+
exports.onCommand = onCommand;
|
|
962
|
+
exports.onContextmenu = onContextmenu;
|
|
963
|
+
exports.onCopy = onCopy;
|
|
964
|
+
exports.onCuechange = onCuechange;
|
|
965
|
+
exports.onCut = onCut;
|
|
966
|
+
exports.onDblclick = onDblclick;
|
|
967
|
+
exports.onDrag = onDrag;
|
|
968
|
+
exports.onDragend = onDragend;
|
|
969
|
+
exports.onDragenter = onDragenter;
|
|
970
|
+
exports.onDragexit = onDragexit;
|
|
971
|
+
exports.onDragleave = onDragleave;
|
|
972
|
+
exports.onDragover = onDragover;
|
|
973
|
+
exports.onDragstart = onDragstart;
|
|
974
|
+
exports.onDrop = onDrop;
|
|
975
|
+
exports.onDurationchange = onDurationchange;
|
|
976
|
+
exports.onEmptied = onEmptied;
|
|
977
|
+
exports.onEnded = onEnded;
|
|
978
|
+
exports.onError = onError;
|
|
979
|
+
exports.onFocus = onFocus;
|
|
980
|
+
exports.onFormdata = onFormdata;
|
|
981
|
+
exports.onGotpointercapture = onGotpointercapture;
|
|
982
|
+
exports.onInput = onInput;
|
|
983
|
+
exports.onInvalid = onInvalid;
|
|
984
|
+
exports.onKeydown = onKeydown;
|
|
985
|
+
exports.onKeypress = onKeypress;
|
|
986
|
+
exports.onKeyup = onKeyup;
|
|
987
|
+
exports.onLoad = onLoad;
|
|
988
|
+
exports.onLoadeddata = onLoadeddata;
|
|
989
|
+
exports.onLoadedmetadata = onLoadedmetadata;
|
|
990
|
+
exports.onLoadstart = onLoadstart;
|
|
991
|
+
exports.onLostpointercapture = onLostpointercapture;
|
|
992
|
+
exports.onMousedown = onMousedown;
|
|
993
|
+
exports.onMouseenter = onMouseenter;
|
|
994
|
+
exports.onMouseleave = onMouseleave;
|
|
995
|
+
exports.onMousemove = onMousemove;
|
|
996
|
+
exports.onMouseout = onMouseout;
|
|
997
|
+
exports.onMouseover = onMouseover;
|
|
998
|
+
exports.onMouseup = onMouseup;
|
|
999
|
+
exports.onMozfullscreenchange = onMozfullscreenchange;
|
|
1000
|
+
exports.onMozfullscreenerror = onMozfullscreenerror;
|
|
1001
|
+
exports.onPaste = onPaste;
|
|
1002
|
+
exports.onPause = onPause;
|
|
1003
|
+
exports.onPlay = onPlay;
|
|
1004
|
+
exports.onPlaying = onPlaying;
|
|
1005
|
+
exports.onPointercancel = onPointercancel;
|
|
1006
|
+
exports.onPointerdown = onPointerdown;
|
|
1007
|
+
exports.onPointerenter = onPointerenter;
|
|
1008
|
+
exports.onPointerleave = onPointerleave;
|
|
1009
|
+
exports.onPointermove = onPointermove;
|
|
1010
|
+
exports.onPointerout = onPointerout;
|
|
1011
|
+
exports.onPointerover = onPointerover;
|
|
1012
|
+
exports.onPointerup = onPointerup;
|
|
1013
|
+
exports.onProgress = onProgress;
|
|
1014
|
+
exports.onRatechange = onRatechange;
|
|
1015
|
+
exports.onReset = onReset;
|
|
1016
|
+
exports.onResize = onResize;
|
|
1017
|
+
exports.onScroll = onScroll;
|
|
1018
|
+
exports.onScrollend = onScrollend;
|
|
1019
|
+
exports.onSecuritypolicyviolation = onSecuritypolicyviolation;
|
|
1020
|
+
exports.onSeeked = onSeeked;
|
|
1021
|
+
exports.onSeeking = onSeeking;
|
|
1022
|
+
exports.onSelect = onSelect;
|
|
1023
|
+
exports.onSelectionchange = onSelectionchange;
|
|
1024
|
+
exports.onSelectstart = onSelectstart;
|
|
1025
|
+
exports.onSlotchange = onSlotchange;
|
|
1026
|
+
exports.onStalled = onStalled;
|
|
1027
|
+
exports.onSubmit = onSubmit;
|
|
1028
|
+
exports.onSuspend = onSuspend;
|
|
1029
|
+
exports.onTimeupdate = onTimeupdate;
|
|
1030
|
+
exports.onToggle = onToggle;
|
|
1031
|
+
exports.onTransitioncancel = onTransitioncancel;
|
|
1032
|
+
exports.onTransitionend = onTransitionend;
|
|
1033
|
+
exports.onTransitionrun = onTransitionrun;
|
|
1034
|
+
exports.onTransitionstart = onTransitionstart;
|
|
1035
|
+
exports.onVolumechange = onVolumechange;
|
|
1036
|
+
exports.onWaiting = onWaiting;
|
|
1037
|
+
exports.onWebkitanimationend = onWebkitanimationend;
|
|
1038
|
+
exports.onWebkitanimationiteration = onWebkitanimationiteration;
|
|
1039
|
+
exports.onWebkitanimationstart = onWebkitanimationstart;
|
|
1040
|
+
exports.onWebkittransitionend = onWebkittransitionend;
|
|
1041
|
+
exports.onWheel = onWheel;
|
|
1042
|
+
exports.once = once;
|
|
1043
|
+
exports.passive = passive;
|
|
525
1044
|
exports.registerCallback = registerCallback;
|
|
1045
|
+
exports.registerController = registerController;
|
|
526
1046
|
exports.registerEventAttribute = registerEventAttribute;
|
|
1047
|
+
exports.registerSignal = registerSignal;
|
|
1048
|
+
exports.requestFullscreen = requestFullscreen;
|
|
527
1049
|
exports.setGlobalErrorHandler = setGlobalErrorHandler;
|
|
1050
|
+
exports.signal = signal;
|
|
1051
|
+
exports.toggleFullsceen = toggleFullsceen;
|
|
528
1052
|
exports.unregisterCallback = unregisterCallback;
|
|
1053
|
+
exports.unregisterController = unregisterController;
|
|
1054
|
+
exports.unregisterSignal = unregisterSignal;
|