tiny-essentials 1.20.0 → 1.20.1
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/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/libs/TinyDragger.cjs +1 -1
- package/dist/v1/libs/TinyDragger.mjs +1 -1
- package/dist/v1/libs/TinyHtml.cjs +292 -103
- package/dist/v1/libs/TinyHtml.d.mts +142 -39
- package/dist/v1/libs/TinyHtml.mjs +266 -94
- package/dist/v1/libs/TinyIframeEvents.cjs +2 -1
- package/dist/v1/libs/TinyNewWinEvents.cjs +4 -2
- package/docs/v1/libs/TinyHtml.md +128 -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
|
@@ -199,11 +199,39 @@ const __elemCollision = {
|
|
|
199
199
|
class TinyHtml {
|
|
200
200
|
/** @typedef {import('../basics/collision.mjs').ObjRect} ObjRect */
|
|
201
201
|
static Utils = { ...TinyCollision };
|
|
202
|
+
/**
|
|
203
|
+
* Creates a new TinyHtml element from a tag name and optional attributes.
|
|
204
|
+
*
|
|
205
|
+
* You can alias this method for convenience:
|
|
206
|
+
* ```js
|
|
207
|
+
* const createElement = TinyHtml.createFrom;
|
|
208
|
+
* const myDiv = createElement('div', { class: 'box' });
|
|
209
|
+
* ```
|
|
210
|
+
*
|
|
211
|
+
* @param {string} tagName - The HTML tag name (e.g., 'div', 'span', 'button').
|
|
212
|
+
* @param {Record<string, string|null>} [attrs] - Optional key-value pairs representing HTML attributes.
|
|
213
|
+
* If the value is `null`, the attribute will still be set with an empty value.
|
|
214
|
+
* @returns {TinyHtml} - A new instance of TinyHtml representing the created element.
|
|
215
|
+
* @throws {TypeError} - If `tagName` is not a string, or `attrs` is not a plain object when defined.
|
|
216
|
+
*/
|
|
217
|
+
static createFrom(tagName, attrs) {
|
|
218
|
+
if (typeof tagName !== 'string')
|
|
219
|
+
throw new TypeError('The "tagName" must be a string.');
|
|
220
|
+
if (typeof attrs !== 'undefined' && typeof attrs !== 'object')
|
|
221
|
+
throw new TypeError('The "attrs" must be a object.');
|
|
222
|
+
const elem = TinyHtml.createElement(tagName);
|
|
223
|
+
if (typeof attrs === 'object') {
|
|
224
|
+
for (const attrName in attrs) {
|
|
225
|
+
elem.setAttr(attrName, attrs[attrName]);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return elem;
|
|
229
|
+
}
|
|
202
230
|
/**
|
|
203
231
|
* Creates a new DOM element with the specified tag name and options, then wraps it in a TinyHtml instance.
|
|
204
232
|
*
|
|
205
233
|
* @param {string} tagName - The tag name of the element to create (e.g., 'div', 'span').
|
|
206
|
-
* @param {ElementCreationOptions} ops - Optional settings for creating the element.
|
|
234
|
+
* @param {ElementCreationOptions} [ops] - Optional settings for creating the element.
|
|
207
235
|
* @returns {TinyHtml} A TinyHtml instance wrapping the newly created DOM element.
|
|
208
236
|
* @throws {TypeError} If tagName is not a string or ops is not an object.
|
|
209
237
|
*/
|
|
@@ -246,7 +274,7 @@ class TinyHtml {
|
|
|
246
274
|
}
|
|
247
275
|
template.innerHTML = htmlString;
|
|
248
276
|
if (!(template.content.firstChild instanceof Element))
|
|
249
|
-
throw new Error('');
|
|
277
|
+
throw new Error('The HTML string must contain a valid HTML element.');
|
|
250
278
|
return new TinyHtml(template.content.firstChild);
|
|
251
279
|
}
|
|
252
280
|
/**
|
|
@@ -276,17 +304,16 @@ class TinyHtml {
|
|
|
276
304
|
*
|
|
277
305
|
* @param {string} selector - A valid CSS selector string.
|
|
278
306
|
* @param {Document|Element} elem - Target element.
|
|
279
|
-
* @returns {TinyHtml
|
|
307
|
+
* @returns {TinyHtml} An array of TinyHtml instances wrapping the matched elements.
|
|
280
308
|
*/
|
|
281
309
|
static queryAll(selector, elem = document) {
|
|
282
|
-
|
|
283
|
-
return TinyHtml.toTinyElm([...newEls]);
|
|
310
|
+
return new TinyHtml(elem.querySelectorAll(selector));
|
|
284
311
|
}
|
|
285
312
|
/**
|
|
286
313
|
* Queries the element for all elements matching the CSS selector and wraps them in TinyHtml instances.
|
|
287
314
|
*
|
|
288
315
|
* @param {string} selector - A valid CSS selector string.
|
|
289
|
-
* @returns {TinyHtml
|
|
316
|
+
* @returns {TinyHtml} An array of TinyHtml instances wrapping the matched elements.
|
|
290
317
|
*/
|
|
291
318
|
querySelectorAll(selector) {
|
|
292
319
|
return TinyHtml.queryAll(selector, TinyHtml._preElem(this, 'queryAll'));
|
|
@@ -308,17 +335,16 @@ class TinyHtml {
|
|
|
308
335
|
*
|
|
309
336
|
* @param {string} selector - The class name to search for.
|
|
310
337
|
* @param {Document|Element} elem - Target element.
|
|
311
|
-
* @returns {TinyHtml
|
|
338
|
+
* @returns {TinyHtml} An array of TinyHtml instances wrapping the found elements.
|
|
312
339
|
*/
|
|
313
340
|
static getByClassName(selector, elem = document) {
|
|
314
|
-
|
|
315
|
-
return TinyHtml.toTinyElm([...newEls]);
|
|
341
|
+
return new TinyHtml(elem.getElementsByClassName(selector));
|
|
316
342
|
}
|
|
317
343
|
/**
|
|
318
344
|
* Retrieves all elements with the specified class name and wraps them in TinyHtml instances.
|
|
319
345
|
*
|
|
320
346
|
* @param {string} selector - The class name to search for.
|
|
321
|
-
* @returns {TinyHtml
|
|
347
|
+
* @returns {TinyHtml} An array of TinyHtml instances wrapping the found elements.
|
|
322
348
|
*/
|
|
323
349
|
getElementsByClassName(selector) {
|
|
324
350
|
return TinyHtml.getByClassName(selector, TinyHtml._preElem(this, 'getByClassName'));
|
|
@@ -327,11 +353,10 @@ class TinyHtml {
|
|
|
327
353
|
* Retrieves all elements with the specified name attribute and wraps them in TinyHtml instances.
|
|
328
354
|
*
|
|
329
355
|
* @param {string} selector - The name attribute to search for.
|
|
330
|
-
* @returns {TinyHtml
|
|
356
|
+
* @returns {TinyHtml} An array of TinyHtml instances wrapping the found elements.
|
|
331
357
|
*/
|
|
332
358
|
static getByName(selector) {
|
|
333
|
-
|
|
334
|
-
return TinyHtml.toTinyElm([...newEls]);
|
|
359
|
+
return new TinyHtml(document.getElementsByName(selector));
|
|
335
360
|
}
|
|
336
361
|
/**
|
|
337
362
|
* Retrieves all elements with the specified local tag name within the given namespace URI,
|
|
@@ -340,11 +365,10 @@ class TinyHtml {
|
|
|
340
365
|
* @param {string} localName - The local name (tag) of the elements to search for.
|
|
341
366
|
* @param {string|null} [namespaceURI='http://www.w3.org/1999/xhtml'] - The namespace URI to search within.
|
|
342
367
|
* @param {Document|Element} elem - Target element.
|
|
343
|
-
* @returns {TinyHtml
|
|
368
|
+
* @returns {TinyHtml} An array of TinyHtml instances wrapping the found elements.
|
|
344
369
|
*/
|
|
345
370
|
static getByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml', elem = document) {
|
|
346
|
-
|
|
347
|
-
return TinyHtml.toTinyElm([...newEls]);
|
|
371
|
+
return new TinyHtml(elem.getElementsByTagNameNS(namespaceURI, localName));
|
|
348
372
|
}
|
|
349
373
|
/**
|
|
350
374
|
* Retrieves all elements with the specified local tag name within the given namespace URI,
|
|
@@ -352,7 +376,7 @@ class TinyHtml {
|
|
|
352
376
|
*
|
|
353
377
|
* @param {string} localName - The local name (tag) of the elements to search for.
|
|
354
378
|
* @param {string|null} [namespaceURI='http://www.w3.org/1999/xhtml'] - The namespace URI to search within.
|
|
355
|
-
* @returns {TinyHtml
|
|
379
|
+
* @returns {TinyHtml} An array of TinyHtml instances wrapping the found elements.
|
|
356
380
|
*/
|
|
357
381
|
getElementsByTagNameNS(localName, namespaceURI = 'http://www.w3.org/1999/xhtml') {
|
|
358
382
|
return TinyHtml.getByTagNameNS(localName, namespaceURI, TinyHtml._preElem(this, 'getByTagNameNS'));
|
|
@@ -361,81 +385,146 @@ class TinyHtml {
|
|
|
361
385
|
/**
|
|
362
386
|
* Returns the current target held by this instance.
|
|
363
387
|
*
|
|
388
|
+
* @param {number} index - The index of the element to retrieve.
|
|
364
389
|
* @returns {ConstructorElValues} - The instance's target element.
|
|
365
390
|
*/
|
|
366
|
-
get() {
|
|
367
|
-
|
|
391
|
+
get(index) {
|
|
392
|
+
if (typeof index !== 'number')
|
|
393
|
+
throw new TypeError('The index must be a number.');
|
|
394
|
+
if (!this.#el[index])
|
|
395
|
+
throw new Error(`No element found at index ${index}.`);
|
|
396
|
+
return this.#el[index];
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Extracts a single DOM element from the internal list at the specified index.
|
|
400
|
+
*
|
|
401
|
+
* @param {number} index - The index of the element to extract.
|
|
402
|
+
* @returns {TinyHtml} A new TinyHtml instance wrapping the extracted element.
|
|
403
|
+
*/
|
|
404
|
+
extract(index) {
|
|
405
|
+
if (typeof index !== 'number')
|
|
406
|
+
throw new TypeError('The index must be a number.');
|
|
407
|
+
if (!this.#el[index])
|
|
408
|
+
throw new Error(`Cannot extract: no element exists at index ${index}.`);
|
|
409
|
+
return new TinyHtml(this.#el[index]);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Checks whether the element exists at the given index.
|
|
413
|
+
*
|
|
414
|
+
* @param {number} index - The index to check.
|
|
415
|
+
* @returns {boolean} - True if the element exists; otherwise, false.
|
|
416
|
+
*/
|
|
417
|
+
exists(index) {
|
|
418
|
+
if (typeof index !== 'number')
|
|
419
|
+
throw new TypeError('The index must be a number.');
|
|
420
|
+
if (!this.#el[index])
|
|
421
|
+
return false;
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Returns the current targets held by this instance.
|
|
426
|
+
*
|
|
427
|
+
* @returns {ConstructorElValues[]} - The instance's targets element.
|
|
428
|
+
*/
|
|
429
|
+
getAll() {
|
|
430
|
+
return [...this.#el];
|
|
368
431
|
}
|
|
369
432
|
/**
|
|
370
433
|
* Returns the current Element held by this instance.
|
|
371
434
|
*
|
|
372
435
|
* @param {string} where - The method name or context calling this.
|
|
436
|
+
* @param {number} index - The index of the element to retrieve.
|
|
373
437
|
* @returns {ConstructorElValues} - The instance's element.
|
|
374
438
|
* @readonly
|
|
375
439
|
*/
|
|
376
|
-
_getElement(where) {
|
|
377
|
-
if (!(this.#el instanceof Element) &&
|
|
378
|
-
!(this.#el instanceof Window) &&
|
|
379
|
-
!(this.#el instanceof Document))
|
|
440
|
+
_getElement(where, index) {
|
|
441
|
+
if (!(this.#el[index] instanceof Element) &&
|
|
442
|
+
!(this.#el[index] instanceof Window) &&
|
|
443
|
+
!(this.#el[index] instanceof Document))
|
|
444
|
+
throw new Error(`[TinyHtml] Invalid Element in ${where}().`);
|
|
445
|
+
return this.#el[index];
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Returns the current Elements held by this instance.
|
|
449
|
+
*
|
|
450
|
+
* @param {string} where - The method name or context calling this.
|
|
451
|
+
* @returns {ConstructorElValues[]} - The instance's elements.
|
|
452
|
+
* @readonly
|
|
453
|
+
*/
|
|
454
|
+
_getElements(where) {
|
|
455
|
+
if (!this.#el.every((el) => el instanceof Element || el instanceof Window || el instanceof Document))
|
|
380
456
|
throw new Error(`[TinyHtml] Invalid Element in ${where}().`);
|
|
381
|
-
return this.#el;
|
|
457
|
+
return [...this.#el];
|
|
382
458
|
}
|
|
383
459
|
//////////////////////////////////////////////////////
|
|
384
460
|
/**
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
* @param {
|
|
388
|
-
* @param {string
|
|
389
|
-
* @
|
|
461
|
+
* Prepares and validates multiple elements against allowed types.
|
|
462
|
+
*
|
|
463
|
+
* @param {TinyElement | EventTarget | null | (TinyElement | EventTarget | null)[]} elems - The input elements to validate.
|
|
464
|
+
* @param {string} where - The method name or context calling this.
|
|
465
|
+
* @param {any[]} TheTinyElements - The list of allowed constructors (e.g., Element, Document).
|
|
466
|
+
* @param {string[]} elemName - The list of expected element names for error reporting.
|
|
467
|
+
* @returns {any[]} - A flat array of validated elements.
|
|
468
|
+
* @throws {Error} - If any element is not an instance of one of the allowed types.
|
|
390
469
|
* @readonly
|
|
391
470
|
*/
|
|
392
471
|
static _preElemsTemplate(elems, where, TheTinyElements, elemName) {
|
|
393
472
|
/** @param {(TinyElement|EventTarget|null)[]} item */
|
|
394
|
-
const checkElement = (item) =>
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
473
|
+
const checkElement = (item) => {
|
|
474
|
+
/** @type {any[]} */
|
|
475
|
+
const results = [];
|
|
476
|
+
item.map((elem) => (elem instanceof TinyHtml ? elem._getElements(where) : [elem]).map((result) => {
|
|
477
|
+
let allowed = false;
|
|
478
|
+
for (const TheTinyElement of TheTinyElements) {
|
|
479
|
+
if (result instanceof TheTinyElement) {
|
|
480
|
+
allowed = true;
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
401
483
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
484
|
+
if (!allowed)
|
|
485
|
+
throw new Error(`[TinyHtml] Invalid element of the list "${elemName.join(',')}" in ${where}().`);
|
|
486
|
+
results.push(result);
|
|
487
|
+
return result;
|
|
488
|
+
}));
|
|
489
|
+
return results;
|
|
490
|
+
};
|
|
407
491
|
if (!Array.isArray(elems))
|
|
408
492
|
return checkElement([elems]);
|
|
409
493
|
return checkElement(elems);
|
|
410
494
|
}
|
|
411
495
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
* @param {
|
|
415
|
-
* @param {string
|
|
416
|
-
* @param {
|
|
417
|
-
* @
|
|
496
|
+
* Prepares and validates a single element against allowed types.
|
|
497
|
+
*
|
|
498
|
+
* @param {TinyElement | EventTarget | null | (TinyElement | EventTarget | null)[]} elems - The input element or list to validate.
|
|
499
|
+
* @param {string} where - The method name or context calling this.
|
|
500
|
+
* @param {any[]} TheTinyElements - The list of allowed constructors (e.g., Element, Document).
|
|
501
|
+
* @param {string[]} elemName - The list of expected element names for error reporting.
|
|
502
|
+
* @param {boolean} [canNull=false] - Whether `null` is allowed as a valid value.
|
|
503
|
+
* @returns {any} - The validated element or `null` if allowed.
|
|
504
|
+
* @throws {Error} - If the element is not valid or if multiple elements are provided.
|
|
418
505
|
* @readonly
|
|
419
506
|
*/
|
|
420
507
|
static _preElemTemplate(elems, where, TheTinyElements, elemName, canNull = false) {
|
|
421
508
|
/** @param {(TinyElement|EventTarget|null)[]} item */
|
|
422
509
|
const checkElement = (item) => {
|
|
423
510
|
const elem = item[0];
|
|
424
|
-
|
|
511
|
+
const result = elem instanceof TinyHtml ? elem._getElements(where) : [elem];
|
|
512
|
+
if (result.length > 1)
|
|
513
|
+
throw new Error(`[TinyHtml] Invalid element amount in ${where}() (Received ${result.length}/1).`);
|
|
425
514
|
let allowed = false;
|
|
426
515
|
for (const TheTinyElement of TheTinyElements) {
|
|
427
|
-
if (result instanceof TheTinyElement) {
|
|
516
|
+
if (result[0] instanceof TheTinyElement) {
|
|
428
517
|
allowed = true;
|
|
429
518
|
break;
|
|
430
519
|
}
|
|
431
520
|
}
|
|
432
|
-
if (canNull && (result === null || typeof result === 'undefined')) {
|
|
433
|
-
result = null;
|
|
521
|
+
if (canNull && (result[0] === null || typeof result[0] === 'undefined')) {
|
|
522
|
+
result[0] = null;
|
|
434
523
|
allowed = true;
|
|
435
524
|
}
|
|
436
525
|
if (!allowed)
|
|
437
526
|
throw new Error(`[TinyHtml] Invalid element of the list "${elemName.join(',')}" in ${where}().`);
|
|
438
|
-
return result;
|
|
527
|
+
return result[0];
|
|
439
528
|
};
|
|
440
529
|
if (!Array.isArray(elems))
|
|
441
530
|
return checkElement([elems]);
|
|
@@ -689,8 +778,13 @@ class TinyHtml {
|
|
|
689
778
|
*/
|
|
690
779
|
static fromTinyElm(elems) {
|
|
691
780
|
/** @param {TinyElement[]} item */
|
|
692
|
-
const checkElement = (item) =>
|
|
693
|
-
|
|
781
|
+
const checkElement = (item) => {
|
|
782
|
+
/** @type {Element[]} */
|
|
783
|
+
const result = [];
|
|
784
|
+
item.map((elem) =>
|
|
785
|
+
/** @type {Element[]} */ (elem instanceof TinyHtml ? elem._getElements('fromTinyElm') : [elem]).map((elem) => result.push(elem)));
|
|
786
|
+
return result;
|
|
787
|
+
};
|
|
694
788
|
if (!Array.isArray(elems))
|
|
695
789
|
return checkElement([elems]);
|
|
696
790
|
return checkElement(elems);
|
|
@@ -1452,7 +1546,7 @@ class TinyHtml {
|
|
|
1452
1546
|
const targ = TinyHtml._preNodeElem(target, 'insertBefore');
|
|
1453
1547
|
const childNode = TinyHtml._preNodeElemWithNull(child, 'insertBefore');
|
|
1454
1548
|
if (!targ.parentNode)
|
|
1455
|
-
throw new Error('');
|
|
1549
|
+
throw new Error('The target element has no parent node to insert before.');
|
|
1456
1550
|
targ.parentNode.insertBefore(elem, childNode || targ);
|
|
1457
1551
|
return el;
|
|
1458
1552
|
}
|
|
@@ -1479,7 +1573,7 @@ class TinyHtml {
|
|
|
1479
1573
|
const targ = TinyHtml._preNodeElem(target, 'insertBefore');
|
|
1480
1574
|
const childNode = TinyHtml._preNodeElemWithNull(child, 'insertBefore');
|
|
1481
1575
|
if (!targ.parentNode)
|
|
1482
|
-
throw new Error('');
|
|
1576
|
+
throw new Error('The target element has no parent node to insert after.');
|
|
1483
1577
|
targ.parentNode.insertBefore(elem, childNode || targ.nextSibling);
|
|
1484
1578
|
return el;
|
|
1485
1579
|
}
|
|
@@ -1526,23 +1620,40 @@ class TinyHtml {
|
|
|
1526
1620
|
//////////////////////////////////////////////////////
|
|
1527
1621
|
/**
|
|
1528
1622
|
* The target HTML element for instance-level operations.
|
|
1529
|
-
* @type {ConstructorElValues}
|
|
1623
|
+
* @type {ConstructorElValues[]}
|
|
1530
1624
|
*/
|
|
1531
1625
|
#el;
|
|
1532
1626
|
/**
|
|
1533
1627
|
* Creates an instance of TinyHtml for a specific Element.
|
|
1534
1628
|
* Useful when you want to operate repeatedly on the same element using instance methods.
|
|
1535
|
-
* @param {ConstructorElValues} el - The element to wrap and manipulate.
|
|
1629
|
+
* @param {ConstructorElValues|ConstructorElValues[]|NodeListOf<Element>|HTMLCollectionOf<Element>|NodeListOf<HTMLElement>} el - The element to wrap and manipulate.
|
|
1536
1630
|
*/
|
|
1537
1631
|
constructor(el) {
|
|
1538
1632
|
if (el instanceof TinyHtml)
|
|
1539
1633
|
throw new Error(`[TinyHtml] You are trying to put a TinyHtml inside another TinyHtml in constructor.`);
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
!(el instanceof
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1634
|
+
/** @param {any[]} els */
|
|
1635
|
+
const elCheck = (els) => {
|
|
1636
|
+
if (!els.every((el) => el instanceof Element ||
|
|
1637
|
+
el instanceof Window ||
|
|
1638
|
+
el instanceof Document ||
|
|
1639
|
+
el instanceof Text))
|
|
1640
|
+
throw new Error(`[TinyHtml] Invalid Target in constructor.`);
|
|
1641
|
+
};
|
|
1642
|
+
if (Array.isArray(el)) {
|
|
1643
|
+
elCheck(el);
|
|
1644
|
+
this.#el = el;
|
|
1645
|
+
}
|
|
1646
|
+
else if (el instanceof NodeList || el instanceof HTMLCollection) {
|
|
1647
|
+
const els = [...el];
|
|
1648
|
+
elCheck(els);
|
|
1649
|
+
this.#el = els;
|
|
1650
|
+
}
|
|
1651
|
+
else {
|
|
1652
|
+
const els = [el];
|
|
1653
|
+
elCheck(els);
|
|
1654
|
+
// @ts-ignore
|
|
1655
|
+
this.#el = els;
|
|
1656
|
+
}
|
|
1546
1657
|
}
|
|
1547
1658
|
/**
|
|
1548
1659
|
* Checks whether the given object is a window.
|
|
@@ -1932,7 +2043,13 @@ class TinyHtml {
|
|
|
1932
2043
|
msTransform: '-ms-transform',
|
|
1933
2044
|
msTransition: '-ms-transition',
|
|
1934
2045
|
};
|
|
1935
|
-
/**
|
|
2046
|
+
/**
|
|
2047
|
+
* Public proxy to manage camelCase ➝ kebab-case CSS property aliasing.
|
|
2048
|
+
*
|
|
2049
|
+
* Modifying this object ensures that the reverse mapping in `cssPropRevAliases` is updated accordingly.
|
|
2050
|
+
*
|
|
2051
|
+
* @type {Record<string | symbol, string>}
|
|
2052
|
+
*/
|
|
1936
2053
|
static cssPropAliases = new Proxy(TinyHtml.#cssPropAliases, {
|
|
1937
2054
|
set(target, camelCaseKey, kebabValue) {
|
|
1938
2055
|
target[camelCaseKey] = kebabValue;
|
|
@@ -1941,7 +2058,13 @@ class TinyHtml {
|
|
|
1941
2058
|
return true;
|
|
1942
2059
|
},
|
|
1943
2060
|
});
|
|
1944
|
-
/**
|
|
2061
|
+
/**
|
|
2062
|
+
* Reverse map of `cssPropAliases`, mapping kebab-case back to camelCase CSS property names.
|
|
2063
|
+
*
|
|
2064
|
+
* This enables consistent bidirectional lookups of style properties.
|
|
2065
|
+
*
|
|
2066
|
+
* @type {Record<string | symbol, string>}
|
|
2067
|
+
*/
|
|
1945
2068
|
static cssPropRevAliases = Object.fromEntries(Object.entries(TinyHtml.#cssPropAliases).map(([camel, kebab]) => [kebab, camel]));
|
|
1946
2069
|
/**
|
|
1947
2070
|
* Converts a camelCase string to kebab-case
|
|
@@ -3410,7 +3533,7 @@ class TinyHtml {
|
|
|
3410
3533
|
throw new TypeError('The "type" must be a string.');
|
|
3411
3534
|
if (typeof where !== 'string')
|
|
3412
3535
|
throw new TypeError('The "where" must be a string.');
|
|
3413
|
-
if (!(elem instanceof HTMLInputElement))
|
|
3536
|
+
if (!(elem instanceof HTMLInputElement) && !(elem instanceof HTMLTextAreaElement))
|
|
3414
3537
|
throw new Error(`Provided element is not an HTMLInputElement in ${where}().`);
|
|
3415
3538
|
if (typeof TinyHtml._valTypes[type] !== 'function')
|
|
3416
3539
|
throw new Error(`No handler found for type "${type}" in ${where}().`);
|
|
@@ -3923,13 +4046,70 @@ class TinyHtml {
|
|
|
3923
4046
|
}
|
|
3924
4047
|
///////////////////////////////////////////////////////////////
|
|
3925
4048
|
/**
|
|
3926
|
-
*
|
|
3927
|
-
*
|
|
4049
|
+
* Internal property name normalization map (similar to jQuery's `propFix`).
|
|
4050
|
+
* Maps attribute-like names to their JavaScript DOM property equivalents.
|
|
4051
|
+
*
|
|
4052
|
+
* Example: `'for'` ➝ `'htmlFor'`, `'class'` ➝ `'className'`.
|
|
4053
|
+
*
|
|
4054
|
+
* ⚠️ Do not modify this object directly. Use `TinyHtml.propFix` to ensure reverse mapping (`attrFix`) remains in sync.
|
|
4055
|
+
*
|
|
4056
|
+
* @type {Record<string | symbol, string>}
|
|
3928
4057
|
*/
|
|
3929
|
-
static
|
|
4058
|
+
static #propFix = {
|
|
3930
4059
|
for: 'htmlFor',
|
|
3931
4060
|
class: 'className',
|
|
3932
4061
|
};
|
|
4062
|
+
/**
|
|
4063
|
+
* Public proxy for normalized DOM property names.
|
|
4064
|
+
*
|
|
4065
|
+
* Setting a new entry here will also automatically update the reverse map in `TinyHtml.attrFix`.
|
|
4066
|
+
*
|
|
4067
|
+
* @type {Record<string | symbol, string>}
|
|
4068
|
+
*/
|
|
4069
|
+
static propFix = new Proxy(TinyHtml.#propFix, {
|
|
4070
|
+
set(target, val1, val2) {
|
|
4071
|
+
target[val1] = val2;
|
|
4072
|
+
// @ts-ignore
|
|
4073
|
+
TinyHtml.attrFix[val2] = val1;
|
|
4074
|
+
return true;
|
|
4075
|
+
},
|
|
4076
|
+
});
|
|
4077
|
+
/**
|
|
4078
|
+
* Reverse map of `propFix`, mapping property names back to their attribute equivalents.
|
|
4079
|
+
*
|
|
4080
|
+
* Used when converting DOM property names into HTML attribute names.
|
|
4081
|
+
*
|
|
4082
|
+
* @type {Record<string | symbol, string>}
|
|
4083
|
+
*/
|
|
4084
|
+
static attrFix = Object.fromEntries(Object.entries(TinyHtml.#propFix).map(([val1, val2]) => [val2, val1]));
|
|
4085
|
+
/**
|
|
4086
|
+
* Normalizes an attribute name to its corresponding DOM property name.
|
|
4087
|
+
*
|
|
4088
|
+
* Example: `'class'` ➝ `'className'`, `'for'` ➝ `'htmlFor'`.
|
|
4089
|
+
* If the name is not mapped, it returns the original name.
|
|
4090
|
+
*
|
|
4091
|
+
* @param {string} name - The attribute name to normalize.
|
|
4092
|
+
* @returns {string} - The corresponding property name.
|
|
4093
|
+
*/
|
|
4094
|
+
static getPropName(name) {
|
|
4095
|
+
// @ts-ignore
|
|
4096
|
+
const propName = typeof TinyHtml.propFix[name] === 'string' ? TinyHtml.propFix[name] : name;
|
|
4097
|
+
return propName;
|
|
4098
|
+
}
|
|
4099
|
+
/**
|
|
4100
|
+
* Converts a DOM property name back to its corresponding attribute name.
|
|
4101
|
+
*
|
|
4102
|
+
* Example: `'className'` ➝ `'class'`, `'htmlFor'` ➝ `'for'`.
|
|
4103
|
+
* If the name is not mapped, it returns the original name.
|
|
4104
|
+
*
|
|
4105
|
+
* @param {string} name - The property name to convert.
|
|
4106
|
+
* @returns {string} - The corresponding attribute name.
|
|
4107
|
+
*/
|
|
4108
|
+
static getAttrName(name) {
|
|
4109
|
+
// @ts-ignore
|
|
4110
|
+
const propName = typeof TinyHtml.attrFix[name] === 'string' ? TinyHtml.attrFix[name] : name;
|
|
4111
|
+
return propName;
|
|
4112
|
+
}
|
|
3933
4113
|
/**
|
|
3934
4114
|
* Get an attribute on an element.
|
|
3935
4115
|
* @param {TinyElement} el
|
|
@@ -3940,7 +4120,7 @@ class TinyHtml {
|
|
|
3940
4120
|
if (typeof name !== 'string')
|
|
3941
4121
|
throw new TypeError('The "name" must be a string.');
|
|
3942
4122
|
const elem = TinyHtml._preElem(el, 'attr');
|
|
3943
|
-
return elem.getAttribute(name);
|
|
4123
|
+
return elem.getAttribute(TinyHtml.getAttrName(name));
|
|
3944
4124
|
}
|
|
3945
4125
|
/**
|
|
3946
4126
|
* Get an attribute on an element.
|
|
@@ -3964,9 +4144,9 @@ class TinyHtml {
|
|
|
3964
4144
|
throw new TypeError('The "value" must be a string.');
|
|
3965
4145
|
TinyHtml._preElems(el, 'setAttr').forEach((elem) => {
|
|
3966
4146
|
if (value === null)
|
|
3967
|
-
elem.removeAttribute(name);
|
|
4147
|
+
elem.removeAttribute(TinyHtml.getAttrName(name));
|
|
3968
4148
|
else
|
|
3969
|
-
elem.setAttribute(name, value);
|
|
4149
|
+
elem.setAttribute(TinyHtml.getAttrName(name), value);
|
|
3970
4150
|
});
|
|
3971
4151
|
return el;
|
|
3972
4152
|
}
|
|
@@ -3988,7 +4168,7 @@ class TinyHtml {
|
|
|
3988
4168
|
static removeAttr(el, name) {
|
|
3989
4169
|
if (typeof name !== 'string')
|
|
3990
4170
|
throw new TypeError('The "name" must be a string.');
|
|
3991
|
-
TinyHtml._preElems(el, 'removeAttr').forEach((elem) => elem.removeAttribute(name));
|
|
4171
|
+
TinyHtml._preElems(el, 'removeAttr').forEach((elem) => elem.removeAttribute(TinyHtml.getAttrName(name)));
|
|
3992
4172
|
return el;
|
|
3993
4173
|
}
|
|
3994
4174
|
/**
|
|
@@ -4009,7 +4189,7 @@ class TinyHtml {
|
|
|
4009
4189
|
if (typeof name !== 'string')
|
|
4010
4190
|
throw new TypeError('The "name" must be a string.');
|
|
4011
4191
|
const elem = TinyHtml._preElem(el, 'hasAttr');
|
|
4012
|
-
return elem.hasAttribute(name);
|
|
4192
|
+
return elem.hasAttribute(TinyHtml.getAttrName(name));
|
|
4013
4193
|
}
|
|
4014
4194
|
/**
|
|
4015
4195
|
* Check if an attribute exists on an element.
|
|
@@ -4030,9 +4210,7 @@ class TinyHtml {
|
|
|
4030
4210
|
throw new TypeError('The "name" must be a string.');
|
|
4031
4211
|
const elem = TinyHtml._preElem(el, 'hasProp');
|
|
4032
4212
|
// @ts-ignore
|
|
4033
|
-
|
|
4034
|
-
// @ts-ignore
|
|
4035
|
-
return !!elem[propName];
|
|
4213
|
+
return !!elem[TinyHtml.getPropName(name)];
|
|
4036
4214
|
}
|
|
4037
4215
|
/**
|
|
4038
4216
|
* Check if a property exists.
|
|
@@ -4053,9 +4231,7 @@ class TinyHtml {
|
|
|
4053
4231
|
throw new TypeError('The "name" must be a string.');
|
|
4054
4232
|
TinyHtml._preElems(el, 'addProp').forEach((elem) => {
|
|
4055
4233
|
// @ts-ignore
|
|
4056
|
-
|
|
4057
|
-
// @ts-ignore
|
|
4058
|
-
elem[name] = true;
|
|
4234
|
+
elem[TinyHtml.getPropName(name)] = true;
|
|
4059
4235
|
});
|
|
4060
4236
|
return el;
|
|
4061
4237
|
}
|
|
@@ -4078,9 +4254,7 @@ class TinyHtml {
|
|
|
4078
4254
|
throw new TypeError('The "name" must be a string.');
|
|
4079
4255
|
TinyHtml._preElems(el, 'removeProp').forEach((elem) => {
|
|
4080
4256
|
// @ts-ignore
|
|
4081
|
-
|
|
4082
|
-
// @ts-ignore
|
|
4083
|
-
elem[name] = false;
|
|
4257
|
+
elem[TinyHtml.getPropName(name)] = false;
|
|
4084
4258
|
});
|
|
4085
4259
|
return el;
|
|
4086
4260
|
}
|
|
@@ -4105,9 +4279,7 @@ class TinyHtml {
|
|
|
4105
4279
|
throw new TypeError('The "force" must be a boolean.');
|
|
4106
4280
|
TinyHtml._preElems(el, 'toggleProp').forEach((elem) => {
|
|
4107
4281
|
// @ts-ignore
|
|
4108
|
-
const
|
|
4109
|
-
// @ts-ignore
|
|
4110
|
-
const shouldEnable = force === undefined ? !elem[propName] : force;
|
|
4282
|
+
const shouldEnable = force === undefined ? !elem[TinyHtml.getPropName(name)] : force;
|
|
4111
4283
|
// @ts-ignore
|
|
4112
4284
|
if (shouldEnable)
|
|
4113
4285
|
TinyHtml.addProp(elem, name);
|
|
@@ -4200,20 +4372,20 @@ class TinyHtml {
|
|
|
4200
4372
|
result[name] = rect[name];
|
|
4201
4373
|
}
|
|
4202
4374
|
if (typeof extraRect !== 'object' || extraRect === null || Array.isArray(extraRect))
|
|
4203
|
-
throw new Error('');
|
|
4375
|
+
throw new Error('extraRect must be a non-null object.');
|
|
4204
4376
|
const { height = 0, width = 0, top = 0, bottom = 0, left = 0, right = 0 } = extraRect;
|
|
4205
4377
|
if (typeof height !== 'number')
|
|
4206
|
-
throw new Error('');
|
|
4378
|
+
throw new Error('extraRect.height must be a number.');
|
|
4207
4379
|
if (typeof width !== 'number')
|
|
4208
|
-
throw new Error('');
|
|
4380
|
+
throw new Error('extraRect.width must be a number.');
|
|
4209
4381
|
if (typeof top !== 'number')
|
|
4210
|
-
throw new Error('');
|
|
4382
|
+
throw new Error('extraRect.top must be a number.');
|
|
4211
4383
|
if (typeof bottom !== 'number')
|
|
4212
|
-
throw new Error('');
|
|
4384
|
+
throw new Error('extraRect.bottom must be a number.');
|
|
4213
4385
|
if (typeof left !== 'number')
|
|
4214
|
-
throw new Error('');
|
|
4386
|
+
throw new Error('extraRect.left must be a number.');
|
|
4215
4387
|
if (typeof right !== 'number')
|
|
4216
|
-
throw new Error('');
|
|
4388
|
+
throw new Error('extraRect.right must be a number.');
|
|
4217
4389
|
// @ts-ignore
|
|
4218
4390
|
result.height += height;
|
|
4219
4391
|
// @ts-ignore
|
|
@@ -261,7 +261,8 @@ class TinyIframeEvents {
|
|
|
261
261
|
* @throws {TypeError} If the value is not a string.
|
|
262
262
|
*/
|
|
263
263
|
set secretEventName(name) {
|
|
264
|
-
if (typeof name !== 'string')
|
|
264
|
+
if (typeof name !== 'string')
|
|
265
|
+
throw new TypeError('TinyIframeEvents: secretEventName must be a string.');
|
|
265
266
|
this.#secretEventName = name;
|
|
266
267
|
}
|
|
267
268
|
|
|
@@ -253,7 +253,8 @@ class TinyNewWinEvents {
|
|
|
253
253
|
* @throws {TypeError} If the value is not a string.
|
|
254
254
|
*/
|
|
255
255
|
set readyEventName(name) {
|
|
256
|
-
if (typeof name !== 'string')
|
|
256
|
+
if (typeof name !== 'string')
|
|
257
|
+
throw new TypeError('TinyNewWinEvents: readyEventName must be a string.');
|
|
257
258
|
this.#readyEventName = name;
|
|
258
259
|
}
|
|
259
260
|
|
|
@@ -271,7 +272,8 @@ class TinyNewWinEvents {
|
|
|
271
272
|
* @throws {TypeError} If the value is not a string.
|
|
272
273
|
*/
|
|
273
274
|
set routeEventName(name) {
|
|
274
|
-
if (typeof name !== 'string')
|
|
275
|
+
if (typeof name !== 'string')
|
|
276
|
+
throw new TypeError('TinyNewWinEvents: routeEventName must be a string.');
|
|
275
277
|
this.#routeEventName = name;
|
|
276
278
|
}
|
|
277
279
|
|