tiny-essentials 1.20.0 → 1.20.2
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 +5 -0
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/basics/html.cjs +33 -2
- package/dist/v1/basics/html.d.mts +14 -4
- package/dist/v1/basics/html.mjs +27 -2
- package/dist/v1/basics/index.cjs +2 -0
- package/dist/v1/basics/index.d.mts +3 -1
- package/dist/v1/basics/index.mjs +3 -3
- package/dist/v1/basics/simpleMath.cjs +23 -4
- package/dist/v1/basics/simpleMath.d.mts +18 -4
- package/dist/v1/basics/simpleMath.mjs +22 -4
- package/dist/v1/index.cjs +2 -0
- package/dist/v1/index.d.mts +3 -1
- package/dist/v1/index.mjs +3 -3
- package/dist/v1/libs/TinyDragger.cjs +1 -1
- package/dist/v1/libs/TinyDragger.mjs +1 -1
- package/dist/v1/libs/TinyHtml.cjs +500 -105
- package/dist/v1/libs/TinyHtml.d.mts +251 -42
- package/dist/v1/libs/TinyHtml.mjs +448 -96
- package/dist/v1/libs/TinyIframeEvents.cjs +2 -1
- package/dist/v1/libs/TinyNewWinEvents.cjs +4 -2
- package/docs/v1/basics/html.md +78 -22
- package/docs/v1/basics/simpleMath.md +22 -4
- package/docs/v1/libs/TinyHtml.md +268 -6
- package/package.json +1 -1
- package/dist/v1/ColorSafeStringify.js +0 -235
- package/dist/v1/TinyAfterScrollWatcher.js +0 -219
- package/dist/v1/TinyBasicsEs.js +0 -9334
- package/dist/v1/TinyClipboard.js +0 -459
- package/dist/v1/TinyColorConverter.js +0 -617
- package/dist/v1/TinyDomReadyManager.js +0 -213
- package/dist/v1/TinyDragDropDetector.js +0 -307
- package/dist/v1/TinyDragger.js +0 -6569
- package/dist/v1/TinyEssentials.js +0 -20792
- package/dist/v1/TinyEvents.js +0 -402
- package/dist/v1/TinyHtml.js +0 -5545
- package/dist/v1/TinyIframeEvents.js +0 -854
- package/dist/v1/TinyLevelUp.js +0 -291
- package/dist/v1/TinyLocalStorage.js +0 -1440
- package/dist/v1/TinyNewWinEvents.js +0 -888
- package/dist/v1/TinyNotifications.js +0 -408
- package/dist/v1/TinyNotifyCenter.js +0 -493
- package/dist/v1/TinyPromiseQueue.js +0 -299
- package/dist/v1/TinyRateLimiter.js +0 -611
- package/dist/v1/TinySmartScroller.js +0 -7039
- package/dist/v1/TinyTextRangeEditor.js +0 -497
- package/dist/v1/TinyTimeout.js +0 -233
- package/dist/v1/TinyToastNotify.js +0 -441
- package/dist/v1/TinyUploadClicker.js +0 -14353
- package/dist/v1/UltraRandomMsgGen.js +0 -995
|
@@ -1,854 +0,0 @@
|
|
|
1
|
-
/******/ (() => { // webpackBootstrap
|
|
2
|
-
/******/ "use strict";
|
|
3
|
-
/******/ // The require scope
|
|
4
|
-
/******/ var __webpack_require__ = {};
|
|
5
|
-
/******/
|
|
6
|
-
/************************************************************************/
|
|
7
|
-
/******/ /* webpack/runtime/define property getters */
|
|
8
|
-
/******/ (() => {
|
|
9
|
-
/******/ // define getter functions for harmony exports
|
|
10
|
-
/******/ __webpack_require__.d = (exports, definition) => {
|
|
11
|
-
/******/ for(var key in definition) {
|
|
12
|
-
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
13
|
-
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
14
|
-
/******/ }
|
|
15
|
-
/******/ }
|
|
16
|
-
/******/ };
|
|
17
|
-
/******/ })();
|
|
18
|
-
/******/
|
|
19
|
-
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
20
|
-
/******/ (() => {
|
|
21
|
-
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
22
|
-
/******/ })();
|
|
23
|
-
/******/
|
|
24
|
-
/************************************************************************/
|
|
25
|
-
var __webpack_exports__ = {};
|
|
26
|
-
|
|
27
|
-
// EXPORTS
|
|
28
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
29
|
-
TinyIframeEvents: () => (/* reexport */ libs_TinyIframeEvents)
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
;// ./src/v1/basics/objChecker.mjs
|
|
33
|
-
/**
|
|
34
|
-
* Counts the number of elements in an array or the number of properties in an object.
|
|
35
|
-
*
|
|
36
|
-
* @param {Array<*>|Record<string | number | symbol, any>} obj - The array or object to count.
|
|
37
|
-
* @returns {number} - The count of items (array elements or object keys), or `0` if the input is neither an array nor an object.
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* countObj([1, 2, 3]); // 3
|
|
41
|
-
* countObj({ a: 1, b: 2 }); // 2
|
|
42
|
-
* countObj('not an object'); // 0
|
|
43
|
-
*/
|
|
44
|
-
function countObj(obj) {
|
|
45
|
-
// Is Array
|
|
46
|
-
if (Array.isArray(obj)) return obj.length;
|
|
47
|
-
// Object
|
|
48
|
-
if (isJsonObject(obj)) return Object.keys(obj).length;
|
|
49
|
-
// Nothing
|
|
50
|
-
return 0;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Determines whether a given value is a pure JSON object (plain object).
|
|
55
|
-
*
|
|
56
|
-
* A pure object satisfies the following:
|
|
57
|
-
* - It is not null.
|
|
58
|
-
* - Its type is "object".
|
|
59
|
-
* - Its internal [[Class]] is "[object Object]".
|
|
60
|
-
* - It is not an instance of built-in types like Array, Date, Map, Set, etc.
|
|
61
|
-
*
|
|
62
|
-
* This function is useful for strict data validation when you want to ensure
|
|
63
|
-
* a value is a clean JSON-compatible object, free of class instances or special types.
|
|
64
|
-
*
|
|
65
|
-
* @param {unknown} value - The value to test.
|
|
66
|
-
* @returns {value is Record<string | number | symbol, unknown>} Returns true if the value is a pure object.
|
|
67
|
-
*/
|
|
68
|
-
function isJsonObject(value) {
|
|
69
|
-
if (value === null || typeof value !== 'object') return false;
|
|
70
|
-
if (Array.isArray(value)) return false;
|
|
71
|
-
if (Object.prototype.toString.call(value) !== '[object Object]') return false;
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
;// ./src/v1/libs/TinyEvents.mjs
|
|
76
|
-
/**
|
|
77
|
-
* A generic event listener callback function.
|
|
78
|
-
*
|
|
79
|
-
* @callback handler
|
|
80
|
-
* @param {...any} payload - The data payload passed when the event is triggered.
|
|
81
|
-
* @returns {void}
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* TinyEvents provides a minimalistic event emitter system similar to Node.js's EventEmitter,
|
|
86
|
-
* enabling components to subscribe to, emit, and manage events and their listeners.
|
|
87
|
-
*
|
|
88
|
-
* Features include:
|
|
89
|
-
* - Adding/removing event listeners (`on`, `off`, `offAll`, `offAllTypes`)
|
|
90
|
-
* - One-time listeners (`once`)
|
|
91
|
-
* - Emitting events (`emit`)
|
|
92
|
-
* - Listener inspection and limits (`listenerCount`, `listeners`, `eventNames`)
|
|
93
|
-
* - Maximum listener control (`setMaxListeners`, `getMaxListeners`)
|
|
94
|
-
*
|
|
95
|
-
* This class is useful for lightweight, dependency-free publish/subscribe event handling
|
|
96
|
-
* within modular JavaScript applications.
|
|
97
|
-
*
|
|
98
|
-
* @class
|
|
99
|
-
*/
|
|
100
|
-
class TinyEvents {
|
|
101
|
-
/** @type {Map<string, { handler: handler; config: { once: boolean } }[]>} */
|
|
102
|
-
#listeners = new Map();
|
|
103
|
-
|
|
104
|
-
/** @type {number} */
|
|
105
|
-
#maxListeners = 10;
|
|
106
|
-
|
|
107
|
-
/** @type {boolean} */
|
|
108
|
-
#throwMaxListeners = false;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Enables or disables throwing an error when the maximum number of listeners is exceeded.
|
|
112
|
-
*
|
|
113
|
-
* @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
|
|
114
|
-
*/
|
|
115
|
-
setThrowOnMaxListeners(shouldThrow) {
|
|
116
|
-
if (typeof shouldThrow !== 'boolean')
|
|
117
|
-
throw new TypeError('setThrowOnMaxListeners(value): value must be a boolean');
|
|
118
|
-
this.#throwMaxListeners = shouldThrow;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Checks whether an error will be thrown when the max listener limit is exceeded.
|
|
123
|
-
*
|
|
124
|
-
* @returns {boolean} True if an error will be thrown, false if only a warning is shown.
|
|
125
|
-
*/
|
|
126
|
-
getThrowOnMaxListeners() {
|
|
127
|
-
return this.#throwMaxListeners;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
///////////////////////////////////////////////////
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Internal method to prepend a listener with options.
|
|
134
|
-
*
|
|
135
|
-
* @param {string} event - Event name.
|
|
136
|
-
* @param {handler} handler - The callback function.
|
|
137
|
-
* @param {Object} [settings={}] - Optional settings.
|
|
138
|
-
* @param {boolean} [settings.once=false] - If the listener should be executed once.
|
|
139
|
-
*/
|
|
140
|
-
#prepend(event, handler, { once = false } = {}) {
|
|
141
|
-
let eventData = this.#listeners.get(event);
|
|
142
|
-
if (!Array.isArray(eventData)) {
|
|
143
|
-
eventData = [];
|
|
144
|
-
this.#listeners.set(event, eventData);
|
|
145
|
-
}
|
|
146
|
-
eventData.unshift({ handler, config: { once } });
|
|
147
|
-
|
|
148
|
-
const max = this.#maxListeners;
|
|
149
|
-
if (max > 0 && eventData.length > max) {
|
|
150
|
-
const warnMessage =
|
|
151
|
-
`Possible memory leak detected. ${eventData.length} "${event}" listeners added. ` +
|
|
152
|
-
`Use setMaxListeners() to increase limit.`;
|
|
153
|
-
if (!this.#throwMaxListeners) console.warn(warnMessage);
|
|
154
|
-
else throw new Error(warnMessage);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Adds a listener to the beginning of the listeners array for the specified event.
|
|
160
|
-
*
|
|
161
|
-
* @param {string} event - Event name.
|
|
162
|
-
* @param {handler} handler - The callback function.
|
|
163
|
-
*/
|
|
164
|
-
prependListener(event, handler) {
|
|
165
|
-
if (typeof event !== 'string')
|
|
166
|
-
throw new TypeError('prepend(event, handler): event name must be a string');
|
|
167
|
-
if (typeof handler !== 'function')
|
|
168
|
-
throw new TypeError('prepend(event, handler): handler must be a function');
|
|
169
|
-
this.#prepend(event, handler);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Adds a one-time listener to the beginning of the listeners array for the specified event.
|
|
174
|
-
*
|
|
175
|
-
* @param {string} event - Event name.
|
|
176
|
-
* @param {handler} handler - The callback function.
|
|
177
|
-
* @returns {handler} - The wrapped handler used internally.
|
|
178
|
-
*/
|
|
179
|
-
prependListenerOnce(event, handler) {
|
|
180
|
-
if (typeof event !== 'string')
|
|
181
|
-
throw new TypeError('prependOnceListener(event, handler): event name must be a string');
|
|
182
|
-
if (typeof handler !== 'function')
|
|
183
|
-
throw new TypeError('prependOnceListener(event, handler): handler must be a function');
|
|
184
|
-
|
|
185
|
-
/** @type {handler} */
|
|
186
|
-
const wrapped = (...args) => {
|
|
187
|
-
this.off(event, wrapped);
|
|
188
|
-
handler(...args);
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
this.#prepend(event, wrapped, { once: true });
|
|
192
|
-
return wrapped;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
////////////////////////////////////////////////////////////
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Adds a event listener.
|
|
199
|
-
*
|
|
200
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
201
|
-
* @param {handler} handler - Callback function to be called when event fires.
|
|
202
|
-
* @param {Object} [settings={}] - Optional settings.
|
|
203
|
-
* @param {boolean} [settings.once=false] - This is a once event.
|
|
204
|
-
*/
|
|
205
|
-
#on(event, handler, { once = false } = {}) {
|
|
206
|
-
let eventData = this.#listeners.get(event);
|
|
207
|
-
if (!Array.isArray(eventData)) {
|
|
208
|
-
eventData = [];
|
|
209
|
-
this.#listeners.set(event, eventData);
|
|
210
|
-
}
|
|
211
|
-
eventData.push({ handler, config: { once } });
|
|
212
|
-
// Warn if listener count exceeds the max allowed
|
|
213
|
-
const max = this.#maxListeners;
|
|
214
|
-
if (max > 0 && eventData.length > max) {
|
|
215
|
-
const warnMessage =
|
|
216
|
-
`Possible memory leak detected. ${eventData.length} "${event}" listeners added. ` +
|
|
217
|
-
`Use setMaxListeners() to increase limit.`;
|
|
218
|
-
if (!this.#throwMaxListeners) console.warn(warnMessage);
|
|
219
|
-
else throw new Error(warnMessage);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Adds a event listener.
|
|
225
|
-
*
|
|
226
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
227
|
-
* @param {handler} handler - Callback function to be called when event fires.
|
|
228
|
-
*/
|
|
229
|
-
on(event, handler) {
|
|
230
|
-
if (typeof event !== 'string')
|
|
231
|
-
throw new TypeError('on(event, handler): event name must be a string');
|
|
232
|
-
if (typeof handler !== 'function')
|
|
233
|
-
throw new TypeError('on(event, handler): handler must be a function');
|
|
234
|
-
return this.#on(event, handler);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Registers an event listener that runs only once, then is removed.
|
|
239
|
-
*
|
|
240
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
241
|
-
* @param {handler} handler - The callback function to run on event.
|
|
242
|
-
* @returns {handler} - The wrapped version of the handler.
|
|
243
|
-
*/
|
|
244
|
-
once(event, handler) {
|
|
245
|
-
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
246
|
-
if (typeof handler !== 'function')
|
|
247
|
-
throw new TypeError('once(event, handler): handler must be a function');
|
|
248
|
-
|
|
249
|
-
/** @type {handler} */
|
|
250
|
-
const wrapped = (e) => {
|
|
251
|
-
this.off(event, wrapped);
|
|
252
|
-
if (typeof handler === 'function') handler(e);
|
|
253
|
-
};
|
|
254
|
-
this.#on(event, wrapped, { once: true });
|
|
255
|
-
return wrapped;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Adds a event listener.
|
|
260
|
-
*
|
|
261
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
262
|
-
* @param {handler} handler - Callback function to be called when event fires.
|
|
263
|
-
*/
|
|
264
|
-
appendListener(event, handler) {
|
|
265
|
-
return this.on(event, handler);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Registers an event listener that runs only once, then is removed.
|
|
270
|
-
*
|
|
271
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
272
|
-
* @param {handler} handler - The callback function to run on event.
|
|
273
|
-
* @returns {handler} - The wrapped version of the handler.
|
|
274
|
-
*/
|
|
275
|
-
appendListenerOnce(event, handler) {
|
|
276
|
-
return this.once(event, handler);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
///////////////////////////////////////////////
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Removes a previously registered event listener.
|
|
283
|
-
*
|
|
284
|
-
* @param {string} event - The name of the event to remove the handler from.
|
|
285
|
-
* @param {handler} handler - The specific callback function to remove.
|
|
286
|
-
*/
|
|
287
|
-
off(event, handler) {
|
|
288
|
-
if (typeof event !== 'string')
|
|
289
|
-
throw new TypeError('off(event, handler): event name must be a string');
|
|
290
|
-
if (typeof handler !== 'function')
|
|
291
|
-
throw new TypeError('off(event, handler): handler must be a function');
|
|
292
|
-
|
|
293
|
-
const listeners = this.#listeners.get(event);
|
|
294
|
-
if (!Array.isArray(listeners)) return;
|
|
295
|
-
|
|
296
|
-
const index = listeners.findIndex((listener) => listener.handler === handler);
|
|
297
|
-
if (index !== -1) listeners.splice(index, 1);
|
|
298
|
-
|
|
299
|
-
// Optionally clean up empty arrays (optional)
|
|
300
|
-
if (listeners.length === 0) this.#listeners.delete(event);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Removes all event listeners of a specific type from the element.
|
|
305
|
-
*
|
|
306
|
-
* @param {string} event - The event type to remove (e.g. 'onScrollBoundary').
|
|
307
|
-
*/
|
|
308
|
-
offAll(event) {
|
|
309
|
-
if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
|
|
310
|
-
this.#listeners.delete(event);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Removes all event listeners of all types from the element.
|
|
315
|
-
*/
|
|
316
|
-
offAllTypes() {
|
|
317
|
-
this.#listeners.clear();
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/////////////////////////////////////////////
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Returns the number of listeners for a given event.
|
|
324
|
-
*
|
|
325
|
-
* @param {string} event - The name of the event.
|
|
326
|
-
* @returns {number} Number of listeners for the event.
|
|
327
|
-
*/
|
|
328
|
-
listenerCount(event) {
|
|
329
|
-
if (typeof event !== 'string')
|
|
330
|
-
throw new TypeError('listenerCount(event): event name must be a string');
|
|
331
|
-
|
|
332
|
-
const listeners = this.#listeners.get(event);
|
|
333
|
-
return Array.isArray(listeners) ? listeners.length : 0;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Returns a copy of the array of listeners for the specified event.
|
|
338
|
-
*
|
|
339
|
-
* @param {string} event - The name of the event.
|
|
340
|
-
* @returns {handler[]} Array of listener functions.
|
|
341
|
-
*/
|
|
342
|
-
listeners(event) {
|
|
343
|
-
if (typeof event !== 'string')
|
|
344
|
-
throw new TypeError('listeners(event): event name must be a string');
|
|
345
|
-
|
|
346
|
-
const listeners = this.#listeners.get(event);
|
|
347
|
-
return Array.isArray(listeners)
|
|
348
|
-
? [...listeners]
|
|
349
|
-
.filter((listener) => !listener.config.once)
|
|
350
|
-
.map((listener) => listener.handler)
|
|
351
|
-
: [];
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Returns a copy of the array of listeners for the specified event.
|
|
356
|
-
*
|
|
357
|
-
* @param {string} event - The name of the event.
|
|
358
|
-
* @returns {handler[]} Array of listener functions.
|
|
359
|
-
*/
|
|
360
|
-
onceListeners(event) {
|
|
361
|
-
if (typeof event !== 'string')
|
|
362
|
-
throw new TypeError('onceListeners(event): event name must be a string');
|
|
363
|
-
|
|
364
|
-
const listeners = this.#listeners.get(event);
|
|
365
|
-
return Array.isArray(listeners)
|
|
366
|
-
? [...listeners]
|
|
367
|
-
.filter((listener) => listener.config.once)
|
|
368
|
-
.map((listener) => listener.handler)
|
|
369
|
-
: [];
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Returns a copy of the internal listeners array for the specified event,
|
|
374
|
-
* including wrapper functions like those used by `.once()`.
|
|
375
|
-
* @param {string | symbol} event - The event name.
|
|
376
|
-
* @returns {handler[]} An array of raw listener functions.
|
|
377
|
-
*/
|
|
378
|
-
allListeners(event) {
|
|
379
|
-
if (typeof event !== 'string')
|
|
380
|
-
throw new TypeError('allListeners(event): event name must be a string');
|
|
381
|
-
const listeners = this.#listeners.get(event);
|
|
382
|
-
return Array.isArray(listeners) ? [...listeners].map((listener) => listener.handler) : [];
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Returns an array of event names for which there are registered listeners.
|
|
387
|
-
*
|
|
388
|
-
* @returns {string[]} Array of registered event names.
|
|
389
|
-
*/
|
|
390
|
-
eventNames() {
|
|
391
|
-
return [...this.#listeners.keys()];
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Emits an event, triggering all registered handlers for that event.
|
|
396
|
-
*
|
|
397
|
-
* @param {string} event - The event name to emit.
|
|
398
|
-
* @param {...any} payload - Optional data to pass to each handler.
|
|
399
|
-
* @returns {boolean} True if any listeners were called, false otherwise.
|
|
400
|
-
*/
|
|
401
|
-
emit(event, ...payload) {
|
|
402
|
-
if (typeof event !== 'string')
|
|
403
|
-
throw new TypeError('emit(event, data): event name must be a string');
|
|
404
|
-
|
|
405
|
-
const listeners = this.#listeners.get(event);
|
|
406
|
-
if (!Array.isArray(listeners) || listeners.length === 0) return false;
|
|
407
|
-
|
|
408
|
-
// Call all listeners with the provided data
|
|
409
|
-
listeners.forEach((listener) => listener.handler(...payload));
|
|
410
|
-
return true;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
///////////////////////////////////
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* Sets the maximum number of listeners per event before a warning is shown.
|
|
417
|
-
*
|
|
418
|
-
* @param {number} n - The maximum number of listeners.
|
|
419
|
-
*/
|
|
420
|
-
setMaxListeners(n) {
|
|
421
|
-
if (!Number.isInteger(n) || n < 0)
|
|
422
|
-
throw new TypeError('setMaxListeners(n): n must be a non-negative integer');
|
|
423
|
-
this.#maxListeners = n;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* Gets the maximum number of listeners allowed per event.
|
|
428
|
-
*
|
|
429
|
-
* @returns {number} The maximum number of listeners.
|
|
430
|
-
*/
|
|
431
|
-
getMaxListeners() {
|
|
432
|
-
return this.#maxListeners;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/* harmony default export */ const libs_TinyEvents = (TinyEvents);
|
|
437
|
-
|
|
438
|
-
;// ./src/v1/libs/TinyIframeEvents.mjs
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
/** @type {WeakMap<Window, TinyIframeEvents>} */
|
|
443
|
-
const instances = new WeakMap();
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* @callback handler
|
|
447
|
-
* A function to handle incoming event payloads.
|
|
448
|
-
* @param {any} payload - The data sent by the emitter.
|
|
449
|
-
* @param {MessageEvent<any>} event - Metadata about the message.
|
|
450
|
-
*/
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* A flexible event routing system for structured communication
|
|
454
|
-
* between a parent window and its iframe using `postMessage`.
|
|
455
|
-
*
|
|
456
|
-
* This class abstracts the complexity of cross-origin and window-type handling,
|
|
457
|
-
* allowing both the iframe and parent to:
|
|
458
|
-
* - Send events with arbitrary payloads
|
|
459
|
-
* - Listen to specific event names
|
|
460
|
-
* - Filter events by origin and source
|
|
461
|
-
* - Work symmetrically from both sides with automatic direction handling
|
|
462
|
-
*
|
|
463
|
-
* Use this class when building applications that require modular, event-driven
|
|
464
|
-
* communication across embedded frames.
|
|
465
|
-
*/
|
|
466
|
-
class TinyIframeEvents {
|
|
467
|
-
#events = new libs_TinyEvents();
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Enables or disables throwing an error when the maximum number of listeners is exceeded.
|
|
471
|
-
*
|
|
472
|
-
* @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
|
|
473
|
-
*/
|
|
474
|
-
setThrowOnMaxListeners(shouldThrow) {
|
|
475
|
-
return this.#events.setThrowOnMaxListeners(shouldThrow);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Checks whether an error will be thrown when the max listener limit is exceeded.
|
|
480
|
-
*
|
|
481
|
-
* @returns {boolean} True if an error will be thrown, false if only a warning is shown.
|
|
482
|
-
*/
|
|
483
|
-
getThrowOnMaxListeners() {
|
|
484
|
-
return this.#events.getThrowOnMaxListeners();
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/////////////////////////////////////////////////////////////
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Adds a listener to the beginning of the listeners array for the specified event.
|
|
491
|
-
*
|
|
492
|
-
* @param {string} event - Event name.
|
|
493
|
-
* @param {handler} handler - The callback function.
|
|
494
|
-
*/
|
|
495
|
-
prependListener(event, handler) {
|
|
496
|
-
return this.#events.prependListener(event, handler);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
/**
|
|
500
|
-
* Adds a one-time listener to the beginning of the listeners array for the specified event.
|
|
501
|
-
*
|
|
502
|
-
* @param {string} event - Event name.
|
|
503
|
-
* @param {handler} handler - The callback function.
|
|
504
|
-
* @returns {handler} - The wrapped handler used internally.
|
|
505
|
-
*/
|
|
506
|
-
prependListenerOnce(event, handler) {
|
|
507
|
-
return this.#events.prependListenerOnce(event, handler);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
//////////////////////////////////////////////////////////////////////
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* Adds a event listener.
|
|
514
|
-
*
|
|
515
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
516
|
-
* @param {handler} handler - Callback function to be called when event fires.
|
|
517
|
-
*/
|
|
518
|
-
appendListener(event, handler) {
|
|
519
|
-
return this.#events.appendListener(event, handler);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* Registers an event listener that runs only once, then is removed.
|
|
524
|
-
*
|
|
525
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
526
|
-
* @param {handler} handler - The callback function to run on event.
|
|
527
|
-
* @returns {handler} - The wrapped version of the handler.
|
|
528
|
-
*/
|
|
529
|
-
appendListenerOnce(event, handler) {
|
|
530
|
-
return this.#events.appendListenerOnce(event, handler);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
/**
|
|
534
|
-
* Adds a event listener.
|
|
535
|
-
*
|
|
536
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
537
|
-
* @param {handler} handler - Callback function to be called when event fires.
|
|
538
|
-
*/
|
|
539
|
-
on(event, handler) {
|
|
540
|
-
return this.#events.on(event, handler);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Registers an event listener that runs only once, then is removed.
|
|
545
|
-
*
|
|
546
|
-
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
547
|
-
* @param {handler} handler - The callback function to run on event.
|
|
548
|
-
* @returns {handler} - The wrapped version of the handler.
|
|
549
|
-
*/
|
|
550
|
-
once(event, handler) {
|
|
551
|
-
return this.#events.once(event, handler);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
////////////////////////////////////////////////////////////////////
|
|
555
|
-
|
|
556
|
-
/**
|
|
557
|
-
* Removes a previously registered event listener.
|
|
558
|
-
*
|
|
559
|
-
* @param {string} event - The name of the event to remove the handler from.
|
|
560
|
-
* @param {handler} handler - The specific callback function to remove.
|
|
561
|
-
*/
|
|
562
|
-
off(event, handler) {
|
|
563
|
-
return this.#events.off(event, handler);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
/**
|
|
567
|
-
* Removes all event listeners of a specific type from the element.
|
|
568
|
-
*
|
|
569
|
-
* @param {string} event - The event type to remove (e.g. 'onScrollBoundary').
|
|
570
|
-
*/
|
|
571
|
-
offAll(event) {
|
|
572
|
-
return this.#events.offAll(event);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
/**
|
|
576
|
-
* Removes all event listeners of all types from the element.
|
|
577
|
-
*/
|
|
578
|
-
offAllTypes() {
|
|
579
|
-
return this.#events.offAllTypes();
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
////////////////////////////////////////////////////////////
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Returns the number of listeners for a given event.
|
|
586
|
-
*
|
|
587
|
-
* @param {string} event - The name of the event.
|
|
588
|
-
* @returns {number} Number of listeners for the event.
|
|
589
|
-
*/
|
|
590
|
-
listenerCount(event) {
|
|
591
|
-
return this.#events.listenerCount(event);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* Returns a copy of the array of listeners for the specified event.
|
|
596
|
-
*
|
|
597
|
-
* @param {string} event - The name of the event.
|
|
598
|
-
* @returns {handler[]} Array of listener functions.
|
|
599
|
-
*/
|
|
600
|
-
listeners(event) {
|
|
601
|
-
return this.#events.listeners(event);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Returns a copy of the array of listeners for the specified event.
|
|
606
|
-
*
|
|
607
|
-
* @param {string} event - The name of the event.
|
|
608
|
-
* @returns {handler[]} Array of listener functions.
|
|
609
|
-
*/
|
|
610
|
-
onceListeners(event) {
|
|
611
|
-
return this.#events.onceListeners(event);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* Returns a copy of the internal listeners array for the specified event,
|
|
616
|
-
* including wrapper functions like those used by `.once()`.
|
|
617
|
-
* @param {string | symbol} event - The event name.
|
|
618
|
-
* @returns {handler[]} An array of raw listener functions.
|
|
619
|
-
*/
|
|
620
|
-
allListeners(event) {
|
|
621
|
-
return this.#events.allListeners(event);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
/**
|
|
625
|
-
* Returns an array of event names for which there are registered listeners.
|
|
626
|
-
*
|
|
627
|
-
* @returns {string[]} Array of registered event names.
|
|
628
|
-
*/
|
|
629
|
-
eventNames() {
|
|
630
|
-
return this.#events.eventNames();
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
//////////////////////////////////////////////////////
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
* Sets the maximum number of listeners per event before a warning is shown.
|
|
637
|
-
*
|
|
638
|
-
* @param {number} n - The maximum number of listeners.
|
|
639
|
-
*/
|
|
640
|
-
setMaxListeners(n) {
|
|
641
|
-
return this.#events.setMaxListeners(n);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
/**
|
|
645
|
-
* Gets the maximum number of listeners allowed per event.
|
|
646
|
-
*
|
|
647
|
-
* @returns {number} The maximum number of listeners.
|
|
648
|
-
*/
|
|
649
|
-
getMaxListeners() {
|
|
650
|
-
return this.#events.getMaxListeners();
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
///////////////////////////////////////////////////
|
|
654
|
-
|
|
655
|
-
/** @type {Window} */
|
|
656
|
-
#targetWindow;
|
|
657
|
-
|
|
658
|
-
/** @type {string} */
|
|
659
|
-
#targetOrigin;
|
|
660
|
-
|
|
661
|
-
/** @type {string} */
|
|
662
|
-
#selfType;
|
|
663
|
-
|
|
664
|
-
/** @type {boolean} */
|
|
665
|
-
#isDestroyed = false;
|
|
666
|
-
|
|
667
|
-
/** @type {boolean} */
|
|
668
|
-
#ready = false;
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* @typedef {object} IframeEventBase
|
|
672
|
-
* @property {string} eventName - The name of the custom event route.
|
|
673
|
-
* @property {any} payload - The data being sent (can be any type).
|
|
674
|
-
* @property {'iframe' | 'parent'} direction - Indicates the sender: 'iframe' or 'parent'.
|
|
675
|
-
*/
|
|
676
|
-
|
|
677
|
-
/**
|
|
678
|
-
* Queue of messages emitted before connection is ready
|
|
679
|
-
* @type {IframeEventBase[]}
|
|
680
|
-
*/
|
|
681
|
-
#pendingQueue = [];
|
|
682
|
-
|
|
683
|
-
/** @type {string} Internal message type for routed communication */
|
|
684
|
-
#secretEventName = '__tinyIframeEvent__';
|
|
685
|
-
|
|
686
|
-
/**
|
|
687
|
-
* Gets the internal secret iframe event name.
|
|
688
|
-
* @returns {string}
|
|
689
|
-
*/
|
|
690
|
-
get secretEventName() {
|
|
691
|
-
return this.#secretEventName;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* Sets the internal secret iframe event name.
|
|
696
|
-
* @param {string} name
|
|
697
|
-
* @throws {TypeError} If the value is not a string.
|
|
698
|
-
*/
|
|
699
|
-
set secretEventName(name) {
|
|
700
|
-
if (typeof name !== 'string') throw new TypeError('TinyIframeEvents: secretEventName must be a string.');
|
|
701
|
-
this.#secretEventName = name;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
/**
|
|
705
|
-
* Creates a new TinyIframeEvents instance to manage communication between iframe and parent.
|
|
706
|
-
* Automatically determines the current context (`iframe` or `parent`) based on the `targetWindow`.
|
|
707
|
-
*
|
|
708
|
-
* @param {Object} config - Configuration object.
|
|
709
|
-
* @param {HTMLIFrameElement} [config.targetIframe] - The target window to post messages to. Defaults to `window.parent` (assumes this is inside an iframe).
|
|
710
|
-
* @param {string} [config.targetOrigin] - The target origin to restrict messages to. Defaults to `window.location.origin`.
|
|
711
|
-
*/
|
|
712
|
-
constructor({ targetIframe, targetOrigin } = {}) {
|
|
713
|
-
if (
|
|
714
|
-
typeof targetIframe !== 'undefined' &&
|
|
715
|
-
(!(targetIframe instanceof HTMLIFrameElement) || !targetIframe.contentWindow)
|
|
716
|
-
)
|
|
717
|
-
throw new TypeError(
|
|
718
|
-
`[TinyIframeEvents] Invalid "targetIframe" provided: expected a HTML Iframe Element, received ${typeof targetIframe}`,
|
|
719
|
-
);
|
|
720
|
-
if (typeof targetOrigin !== 'undefined' && typeof targetOrigin !== 'string')
|
|
721
|
-
throw new TypeError(
|
|
722
|
-
`[TinyIframeEvents] Invalid "targetOrigin" provided: expected a string, received ${typeof targetOrigin}`,
|
|
723
|
-
);
|
|
724
|
-
|
|
725
|
-
this.#targetWindow = targetIframe?.contentWindow ?? window.parent;
|
|
726
|
-
this.#targetOrigin = targetOrigin ?? window.location.origin;
|
|
727
|
-
this.#selfType = !targetIframe ? 'iframe' : 'parent';
|
|
728
|
-
if (instances.has(this.#targetWindow)) throw new Error('Duplicate window reference.');
|
|
729
|
-
|
|
730
|
-
this._boundOnMessage = this.#onMessage.bind(this);
|
|
731
|
-
this._boundOnceMessage = this.#onceMessage.bind(this);
|
|
732
|
-
|
|
733
|
-
if (
|
|
734
|
-
this.#targetWindow.document.readyState === 'complete' ||
|
|
735
|
-
this.#targetWindow.document.readyState === 'interactive'
|
|
736
|
-
)
|
|
737
|
-
this.#onceMessage();
|
|
738
|
-
else {
|
|
739
|
-
this.#targetWindow.addEventListener('load', this._boundOnceMessage, false);
|
|
740
|
-
this.#targetWindow.addEventListener('DOMContentLoaded', this._boundOnceMessage, false);
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
window.addEventListener('message', this._boundOnMessage, false);
|
|
744
|
-
instances.set(this.#targetWindow, this);
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
/**
|
|
748
|
-
* Marks the communication as ready and flushes any queued messages.
|
|
749
|
-
*/
|
|
750
|
-
#onceMessage() {
|
|
751
|
-
if (this.#ready) return;
|
|
752
|
-
this.#ready = true;
|
|
753
|
-
this.#flushQueue();
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* Internal handler for the message event. Filters and dispatches incoming messages.
|
|
758
|
-
*
|
|
759
|
-
* @param {MessageEvent<any>} event - The message event received via `postMessage`.
|
|
760
|
-
*/
|
|
761
|
-
#onMessage(event) {
|
|
762
|
-
const { data, source } = event;
|
|
763
|
-
|
|
764
|
-
// Reject non-object or unrelated messages
|
|
765
|
-
if (!isJsonObject(data) || !data[this.#secretEventName]) return;
|
|
766
|
-
|
|
767
|
-
const { eventName, payload, direction } = data;
|
|
768
|
-
|
|
769
|
-
// Reject if not from the expected window (for security)
|
|
770
|
-
if (source !== this.#targetWindow) return;
|
|
771
|
-
|
|
772
|
-
// Reject if direction is not meant for this side
|
|
773
|
-
if (
|
|
774
|
-
(this.#selfType === 'iframe' && direction !== 'iframe') ||
|
|
775
|
-
(this.#selfType === 'parent' && direction !== 'parent')
|
|
776
|
-
)
|
|
777
|
-
return;
|
|
778
|
-
|
|
779
|
-
this.#events.emit(/** @type {string} */ (eventName), payload, event);
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
/**
|
|
783
|
-
* Sends an event to the target window.
|
|
784
|
-
*
|
|
785
|
-
* @param {string} eventName - A unique name identifying the event.
|
|
786
|
-
* @param {*} payload - The data to send with the event. Can be any serializable value.
|
|
787
|
-
* @throws {Error} If `eventName` is not a string.
|
|
788
|
-
*/
|
|
789
|
-
emit(eventName, payload) {
|
|
790
|
-
if (typeof eventName !== 'string') throw new TypeError('Event name must be a string.');
|
|
791
|
-
if (this.#isDestroyed) throw new Error('Cannot emit: instance has been destroyed.');
|
|
792
|
-
|
|
793
|
-
/** @type {IframeEventBase} */
|
|
794
|
-
const message = {
|
|
795
|
-
[this.#secretEventName]: true,
|
|
796
|
-
eventName,
|
|
797
|
-
payload,
|
|
798
|
-
direction: this.#selfType === 'parent' ? 'iframe' : 'parent',
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
if (!this.#ready) {
|
|
802
|
-
this.#pendingQueue.push(message);
|
|
803
|
-
return;
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
this.#targetWindow.postMessage(message, this.#targetOrigin);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
/**
|
|
810
|
-
* Sends all pending messages queued before handshake completion.
|
|
811
|
-
*
|
|
812
|
-
* @returns {void}
|
|
813
|
-
*/
|
|
814
|
-
#flushQueue() {
|
|
815
|
-
while (this.#pendingQueue.length) {
|
|
816
|
-
const data = this.#pendingQueue.shift();
|
|
817
|
-
if (data) this.#targetWindow.postMessage(data, this.#targetOrigin);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
/**
|
|
822
|
-
* Checks if the communication instance has been destroyed.
|
|
823
|
-
*
|
|
824
|
-
* @returns {boolean}
|
|
825
|
-
*/
|
|
826
|
-
isDestroyed() {
|
|
827
|
-
return this.#isDestroyed;
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
/**
|
|
831
|
-
* Unsubscribes all registered event listeners and removes the message handler.
|
|
832
|
-
* Call this when the instance is no longer needed to prevent memory leaks.
|
|
833
|
-
*/
|
|
834
|
-
destroy() {
|
|
835
|
-
this.#isDestroyed = true;
|
|
836
|
-
window.removeEventListener('message', this._boundOnMessage);
|
|
837
|
-
this.#targetWindow.removeEventListener('load', this._boundOnceMessage, false);
|
|
838
|
-
this.#targetWindow.removeEventListener('DOMContentLoaded', this._boundOnceMessage, false);
|
|
839
|
-
this.#events.offAllTypes();
|
|
840
|
-
this.#pendingQueue = [];
|
|
841
|
-
instances.delete(this.#targetWindow);
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
/* harmony default export */ const libs_TinyIframeEvents = (TinyIframeEvents);
|
|
846
|
-
|
|
847
|
-
;// ./src/v1/build/TinyIframeEvents.mjs
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
window.TinyIframeEvents = __webpack_exports__.TinyIframeEvents;
|
|
853
|
-
/******/ })()
|
|
854
|
-
;
|