tiny-essentials 1.17.0 → 1.18.0

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.
Files changed (39) hide show
  1. package/dist/v1/TinyBasicsEs.js +336 -45
  2. package/dist/v1/TinyBasicsEs.min.js +1 -1
  3. package/dist/v1/TinyClipboard.js +459 -0
  4. package/dist/v1/TinyClipboard.min.js +1 -0
  5. package/dist/v1/TinyDragger.js +336 -45
  6. package/dist/v1/TinyDragger.min.js +1 -1
  7. package/dist/v1/TinyEssentials.js +1218 -45
  8. package/dist/v1/TinyEssentials.min.js +1 -1
  9. package/dist/v1/TinyHtml.js +336 -45
  10. package/dist/v1/TinyHtml.min.js +1 -1
  11. package/dist/v1/TinySmartScroller.js +336 -45
  12. package/dist/v1/TinySmartScroller.min.js +1 -1
  13. package/dist/v1/TinyTextRangeEditor.js +497 -0
  14. package/dist/v1/TinyTextRangeEditor.min.js +1 -0
  15. package/dist/v1/TinyUploadClicker.js +338 -45
  16. package/dist/v1/TinyUploadClicker.min.js +1 -1
  17. package/dist/v1/build/TinyClipboard.cjs +7 -0
  18. package/dist/v1/build/TinyClipboard.d.mts +3 -0
  19. package/dist/v1/build/TinyClipboard.mjs +2 -0
  20. package/dist/v1/build/TinyTextRangeEditor.cjs +7 -0
  21. package/dist/v1/build/TinyTextRangeEditor.d.mts +3 -0
  22. package/dist/v1/build/TinyTextRangeEditor.mjs +2 -0
  23. package/dist/v1/index.cjs +4 -0
  24. package/dist/v1/index.d.mts +3 -1
  25. package/dist/v1/index.mjs +3 -1
  26. package/dist/v1/libs/TinyClipboard.cjs +420 -0
  27. package/dist/v1/libs/TinyClipboard.d.mts +155 -0
  28. package/dist/v1/libs/TinyClipboard.mjs +398 -0
  29. package/dist/v1/libs/TinyHtml.cjs +336 -45
  30. package/dist/v1/libs/TinyHtml.d.mts +238 -27
  31. package/dist/v1/libs/TinyHtml.mjs +320 -47
  32. package/dist/v1/libs/TinyTextRangeEditor.cjs +458 -0
  33. package/dist/v1/libs/TinyTextRangeEditor.d.mts +200 -0
  34. package/dist/v1/libs/TinyTextRangeEditor.mjs +424 -0
  35. package/docs/v1/README.md +2 -0
  36. package/docs/v1/libs/TinyClipboard.md +213 -0
  37. package/docs/v1/libs/TinyHtml.md +211 -15
  38. package/docs/v1/libs/TinyTextRangeEditor.md +208 -0
  39. package/package.json +1 -1
@@ -2573,6 +2573,19 @@ const {
2573
2573
  areElsCollRight: TinyHtml_areElsCollRight,
2574
2574
  } = collision_namespaceObject;
2575
2575
 
2576
+ /**
2577
+ * Callback invoked on each animation frame with the current scroll position,
2578
+ * normalized animation time (`0` to `1`), and a completion flag.
2579
+ *
2580
+ * @typedef {(progress: { x: number, y: number, isComplete: boolean, time: number }) => void} OnScrollAnimation
2581
+ */
2582
+
2583
+ /**
2584
+ * A list of supported easing function names for smooth animations.
2585
+ *
2586
+ * @typedef {'linear' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic'} Easings
2587
+ */
2588
+
2576
2589
  /**
2577
2590
  * Represents a raw Node element or an instance of TinyHtml.
2578
2591
  * This type is used to abstract interactions with both plain elements
@@ -2643,6 +2656,21 @@ const {
2643
2656
  * @typedef {Element|Window|Document} ElementAndWinAndDoc
2644
2657
  */
2645
2658
 
2659
+ /**
2660
+ * Represents a raw DOM element with document or an instance of TinyHtml.
2661
+ * This type is used to abstract interactions with both plain elements
2662
+ * and wrapped elements via the TinyHtml class.
2663
+ *
2664
+ * @typedef {ElementWithDoc|TinyHtml} TinyElementWithDoc
2665
+ */
2666
+
2667
+ /**
2668
+ * Represents a value that can be either a DOM Element, or the document object.
2669
+ * Useful for functions that operate generically on measurable targets.
2670
+ *
2671
+ * @typedef {Element|Document} ElementWithDoc
2672
+ */
2673
+
2646
2674
  /**
2647
2675
  * A parameter type used for filtering or matching elements.
2648
2676
  * It can be:
@@ -2662,12 +2690,6 @@ const {
2662
2690
  * @typedef {Window|Element|Document|Text} ConstructorElValues
2663
2691
  */
2664
2692
 
2665
- /**
2666
- * The handler function used in event listeners.
2667
- *
2668
- * @typedef {(e: Event) => any} EventRegistryHandle
2669
- */
2670
-
2671
2693
  /**
2672
2694
  * Options passed to `addEventListener` or `removeEventListener`.
2673
2695
  * Can be a boolean or an object of type `AddEventListenerOptions`.
@@ -2679,7 +2701,7 @@ const {
2679
2701
  * Structure describing a registered event callback and its options.
2680
2702
  *
2681
2703
  * @typedef {Object} EventRegistryItem
2682
- * @property {EventRegistryHandle} handler - The function to be executed when the event is triggered.
2704
+ * @property {EventListenerOrEventListenerObject|null} handler - The function to be executed when the event is triggered.
2683
2705
  * @property {EventRegistryOptions} [options] - Optional configuration passed to the listener.
2684
2706
  */
2685
2707
 
@@ -3238,9 +3260,9 @@ class TinyHtml {
3238
3260
  * Ensures the input is returned as an array.
3239
3261
  * Useful to normalize operations across multiple or single element/window/document elements.
3240
3262
  *
3241
- * @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/window element or array of html elements.
3263
+ * @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/document/window element or array of html elements.
3242
3264
  * @param {string} where - The method or context name where validation is being called.
3243
- * @returns {ElementAndWindow[]} - Always returns an array of element/window elements.
3265
+ * @returns {ElementAndWindow[]} - Always returns an array of element/document/window elements.
3244
3266
  * @readonly
3245
3267
  */
3246
3268
  static _preElemsAndWinAndDoc(elems, where) {
@@ -3257,9 +3279,9 @@ class TinyHtml {
3257
3279
  * Ensures the input is returned as an single element/window/document element.
3258
3280
  * Useful to normalize operations across multiple or single element/window/document elements.
3259
3281
  *
3260
- * @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/window element or array of html elements.
3282
+ * @param {TinyElementAndWinAndDoc|TinyElementAndWinAndDoc[]} elems - A single element/document/window element or array of html elements.
3261
3283
  * @param {string} where - The method or context name where validation is being called.
3262
- * @returns {ElementAndWindow} - Always returns an single element/window element.
3284
+ * @returns {ElementAndWindow} - Always returns an single element/document/window element.
3263
3285
  * @readonly
3264
3286
  */
3265
3287
  static _preElemAndWinAndDoc(elems, where) {
@@ -3273,6 +3295,32 @@ class TinyHtml {
3273
3295
  return result;
3274
3296
  }
3275
3297
 
3298
+ /**
3299
+ * Ensures the input is returned as an array.
3300
+ * Useful to normalize operations across multiple or single element with document elements.
3301
+ *
3302
+ * @param {TinyElementWithDoc|TinyElementWithDoc[]} elems - A single element with document element or array of html elements.
3303
+ * @param {string} where - The method or context name where validation is being called.
3304
+ * @returns {ElementWithDoc[]} - Always returns an array of element with document elements.
3305
+ * @readonly
3306
+ */
3307
+ static _preElemsWithDoc(elems, where) {
3308
+ return TinyHtml._preElemsTemplate(elems, where, [Element, Document], ['Element', 'Document']);
3309
+ }
3310
+
3311
+ /**
3312
+ * Ensures the input is returned as an single element with document element.
3313
+ * Useful to normalize operations across multiple or single element with document elements.
3314
+ *
3315
+ * @param {TinyElementWithDoc|TinyElementWithDoc[]} elems - A single element/window element or array of html elements.
3316
+ * @param {string} where - The method or context name where validation is being called.
3317
+ * @returns {ElementWithDoc} - Always returns an single element/window element.
3318
+ * @readonly
3319
+ */
3320
+ static _preElemWithDoc(elems, where) {
3321
+ return TinyHtml._preElemTemplate(elems, where, [Element, Document], ['Element', 'Document']);
3322
+ }
3323
+
3276
3324
  /**
3277
3325
  * Normalizes and converts one or more DOM elements (or TinyHtml instances)
3278
3326
  * into an array of `TinyHtml` instances.
@@ -4981,7 +5029,7 @@ class TinyHtml {
4981
5029
  */
4982
5030
  static setWinScrollTop(value) {
4983
5031
  if (typeof value !== 'number') throw new TypeError('The value must be a number.');
4984
- window.scrollTo({ top: value });
5032
+ TinyHtml.setScrollTop(window, value);
4985
5033
  }
4986
5034
 
4987
5035
  /**
@@ -4990,7 +5038,7 @@ class TinyHtml {
4990
5038
  */
4991
5039
  static setWinScrollLeft(value) {
4992
5040
  if (typeof value !== 'number') throw new TypeError('The value must be a number.');
4993
- window.scrollTo({ left: value });
5041
+ TinyHtml.setScrollLeft(window, value);
4994
5042
  }
4995
5043
 
4996
5044
  /**
@@ -5307,6 +5355,30 @@ class TinyHtml {
5307
5355
 
5308
5356
  //////////////////////////////////////////////////
5309
5357
 
5358
+ /**
5359
+ * Applies an animation to one or multiple TinyElement instances.
5360
+ *
5361
+ * @param {TinyElement|TinyElement[]} el - A single TinyElement or an array of TinyElements to animate.
5362
+ * @param {Keyframe[] | PropertyIndexedKeyframes | null} keyframes - The keyframes used to define the animation.
5363
+ * @param {number | KeyframeAnimationOptions} [ops] - Timing or configuration options for the animation.
5364
+ * @returns {TinyElement|TinyElement[]}
5365
+ */
5366
+ static animate(el, keyframes, ops) {
5367
+ TinyHtml._preElems(el, 'animate').forEach((elem) => elem.animate(keyframes, ops));
5368
+ return el;
5369
+ }
5370
+
5371
+ /**
5372
+ * Applies an animation to one or multiple TinyElement instances.
5373
+ *
5374
+ * @param {Keyframe[] | PropertyIndexedKeyframes | null} keyframes - The keyframes used to define the animation.
5375
+ * @param {number | KeyframeAnimationOptions} [ops] - Timing or configuration options for the animation.
5376
+ * @returns {TinyElement|TinyElement[]}
5377
+ */
5378
+ animate(keyframes, ops) {
5379
+ return TinyHtml.animate(this, keyframes, ops);
5380
+ }
5381
+
5310
5382
  /**
5311
5383
  * Gets the offset of the element relative to the document.
5312
5384
  * @param {TinyElement} el - Target element.
@@ -5462,26 +5534,147 @@ class TinyHtml {
5462
5534
  }
5463
5535
 
5464
5536
  /**
5465
- * Sets the vertical scroll position.
5466
- * @param {TinyElementAndWindow|TinyElementAndWindow[]} el - Element or window.
5467
- * @param {number} value - Scroll top value.
5468
- * @returns {TinyElementAndWindow|TinyElementAndWindow[]}
5537
+ * Collection of easing functions used for scroll and animation calculations.
5538
+ * Each function receives a normalized time value (`t` from 0 to 1) and returns the eased progress.
5539
+ *
5540
+ * @type {Record<string, (t: number) => number>}
5469
5541
  */
5470
- static setScrollTop(el, value) {
5471
- if (typeof value !== 'number') throw new TypeError('ScrollTop value must be a number.');
5472
- TinyHtml._preElemsAndWindow(el, 'setScrollTop').forEach((elem) => {
5473
- if (TinyHtml.isWindow(elem)) {
5474
- elem.scrollTo(elem.pageXOffset, value);
5542
+ static easings = {
5543
+ linear: (t) => t,
5544
+ easeInQuad: (t) => t * t,
5545
+ easeOutQuad: (t) => t * (2 - t),
5546
+ easeInOutQuad: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
5547
+ easeInCubic: (t) => t * t * t,
5548
+ easeOutCubic: (t) => --t * t * t + 1,
5549
+ easeInOutCubic: (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1),
5550
+ };
5551
+
5552
+ /**
5553
+ * Smoothly scrolls one or more elements (or the window) to the specified X and Y coordinates
5554
+ * using a custom duration and easing function.
5555
+ *
5556
+ * If `duration` or a valid `easing` is not provided, the scroll will be performed immediately.
5557
+ *
5558
+ * @param {TinyElementAndWindow | TinyElementAndWindow[]} el - A single element, array of elements, or the window to scroll.
5559
+ * @param {Object} [settings={}] - Configuration object for the scroll animation.
5560
+ * @param {number} [settings.targetX] - The horizontal scroll target in pixels.
5561
+ * @param {number} [settings.targetY] - The vertical scroll target in pixels.
5562
+ * @param {number} [settings.duration] - The duration of the animation in milliseconds.
5563
+ * @param {Easings} [settings.easing] - The easing function name to use for the scroll animation.
5564
+ * @param {OnScrollAnimation} [settings.onAnimation] - Optional callback invoked on each animation
5565
+ * frame with the current scroll position, normalized animation time (`0` to `1`), and a completion flag.
5566
+ * @returns {TinyElementAndWindow|TinyElementAndWindow[]}
5567
+ * @throws {TypeError} If `el` is not a valid element, array, or window.
5568
+ * @throws {TypeError} If `targetX` or `targetY` is defined but not a number.
5569
+ * @throws {TypeError} If `duration` is defined but not a number.
5570
+ * @throws {TypeError} If `easing` is defined but not a valid easing function name.
5571
+ * @throws {TypeError} If `onAnimation` is defined but not a function.
5572
+ */
5573
+ static scrollToXY(el, { targetX, targetY, duration, easing, onAnimation } = {}) {
5574
+ if (targetX !== undefined && typeof targetX !== 'number')
5575
+ throw new TypeError('`targetX` must be a number if provided.');
5576
+ if (targetY !== undefined && typeof targetY !== 'number')
5577
+ throw new TypeError('`targetY` must be a number if provided.');
5578
+ if (duration !== undefined && typeof duration !== 'number')
5579
+ throw new TypeError('`duration` must be a number if provided.');
5580
+ if (easing !== undefined && typeof easing !== 'string')
5581
+ throw new TypeError('`easing` must be a string if provided.');
5582
+ if (easing !== undefined && typeof TinyHtml.easings[easing] !== 'function')
5583
+ throw new TypeError(`Unknown easing function: "${easing}".`);
5584
+ if (onAnimation !== undefined && typeof onAnimation !== 'function')
5585
+ throw new TypeError('`onAnimation` must be a function if provided.');
5586
+
5587
+ /**
5588
+ * Performs an instant scroll to the given coordinates.
5589
+ *
5590
+ * @param {ElementAndWindow} elem - The element or window to scroll.
5591
+ * @param {number} newX - The final horizontal scroll position.
5592
+ * @param {number} newY - The final vertical scroll position.
5593
+ * @param {number} time - Normalized progress value.
5594
+ */
5595
+ const executeScroll = (elem, newX, newY, time) => {
5596
+ if (elem instanceof Window) {
5597
+ window.scrollTo(newX, newY);
5475
5598
  } else if (elem.nodeType === 9) {
5476
5599
  // @ts-ignore
5477
- elem.defaultView.scrollTo(elem.defaultView.pageXOffset, value);
5600
+ elem.defaultView.scrollTo(newX, newY);
5478
5601
  } else {
5479
- elem.scrollTop = value;
5602
+ const startX = elem instanceof Window ? window.scrollX : elem.scrollLeft;
5603
+ const startY = elem instanceof Window ? window.scrollY : elem.scrollTop;
5604
+ if (startX !== newX) elem.scrollLeft = newX;
5605
+ if (startY !== newY) elem.scrollTop = newY;
5480
5606
  }
5607
+ if (typeof onAnimation === 'function')
5608
+ onAnimation({ x: newX, y: newY, isComplete: time >= 1, time });
5609
+ };
5610
+
5611
+ TinyHtml._preElemsAndWindow(el, 'scrollToXY').forEach((elem) => {
5612
+ const startX = elem instanceof Window ? window.scrollX : elem.scrollLeft;
5613
+ const startY = elem instanceof Window ? window.scrollY : elem.scrollTop;
5614
+ const targX = targetX ?? startX;
5615
+ const targY = targetY ?? startY;
5616
+
5617
+ const changeX = targX - startX;
5618
+ const changeY = targY - startY;
5619
+
5620
+ const ease = (typeof easing === 'string' && TinyHtml.easings[easing]) || null;
5621
+ if (typeof duration !== 'number' || typeof ease !== 'function')
5622
+ return executeScroll(elem, targX, targY, 1);
5623
+ const startTime = performance.now();
5624
+ const dur = duration ?? 0;
5625
+
5626
+ /**
5627
+ * Animates the scroll position based on easing and time.
5628
+ *
5629
+ * @param {number} currentTime - Timestamp provided by requestAnimationFrame.
5630
+ */
5631
+ function animateScroll(currentTime) {
5632
+ if (typeof ease !== 'function') return;
5633
+ const time = Math.min(1, (currentTime - startTime) / dur);
5634
+ const easedTime = ease(time);
5635
+
5636
+ const newX = startX + changeX * easedTime;
5637
+ const newY = startY + changeY * easedTime;
5638
+ executeScroll(elem, newX, newY, time);
5639
+
5640
+ if (time < 1) requestAnimationFrame(animateScroll);
5641
+ }
5642
+
5643
+ requestAnimationFrame(animateScroll);
5481
5644
  });
5482
5645
  return el;
5483
5646
  }
5484
5647
 
5648
+ /**
5649
+ * Smoothly scrolls one or more elements (or the window) to the specified X and Y coordinates
5650
+ * using a custom duration and easing function.
5651
+ *
5652
+ * If `duration` or a valid `easing` is not provided, the scroll will be performed immediately.
5653
+ *
5654
+ * @param {Object} [settings={}] - Configuration object for the scroll animation.
5655
+ * @param {number} [settings.targetX] - The horizontal scroll target in pixels.
5656
+ * @param {number} [settings.targetY] - The vertical scroll target in pixels.
5657
+ * @param {number} [settings.duration] - The duration of the animation in milliseconds.
5658
+ * @param {Easings} [settings.easing] - The easing function name to use for the scroll animation.
5659
+ * @param {OnScrollAnimation} [settings.onAnimation] - Optional callback invoked on each animation
5660
+ * frame with the current scroll position, normalized animation time (`0` to `1`), and a completion flag.
5661
+ * @returns {TinyElementAndWindow|TinyElementAndWindow[]}
5662
+ */
5663
+ scrollToXY({ targetX, targetY, duration, easing, onAnimation } = {}) {
5664
+ return TinyHtml.scrollToXY(this, { targetX, targetY, duration, easing, onAnimation });
5665
+ }
5666
+
5667
+ /**
5668
+ * Sets the vertical scroll position.
5669
+ * @param {TinyElementAndWindow|TinyElementAndWindow[]} el - Element or window.
5670
+ * @param {number} value - Scroll top value.
5671
+ * @returns {TinyElementAndWindow|TinyElementAndWindow[]}
5672
+ */
5673
+ static setScrollTop(el, value) {
5674
+ if (typeof value !== 'number') throw new TypeError('ScrollTop value must be a number.');
5675
+ return TinyHtml.scrollToXY(el, { targetY: value });
5676
+ }
5677
+
5485
5678
  /**
5486
5679
  * Sets the vertical scroll position.
5487
5680
  * @param {number} value - Scroll top value.
@@ -5499,17 +5692,7 @@ class TinyHtml {
5499
5692
  */
5500
5693
  static setScrollLeft(el, value) {
5501
5694
  if (typeof value !== 'number') throw new TypeError('ScrollLeft value must be a number.');
5502
- TinyHtml._preElemsAndWindow(el, 'setScrollLeft').forEach((elem) => {
5503
- if (TinyHtml.isWindow(elem)) {
5504
- elem.scrollTo(value, elem.pageYOffset);
5505
- } else if (elem.nodeType === 9) {
5506
- // @ts-ignore
5507
- elem.defaultView.scrollTo(value, elem.defaultView.pageYOffset);
5508
- } else {
5509
- elem.scrollLeft = value;
5510
- }
5511
- });
5512
- return el;
5695
+ return TinyHtml.scrollToXY(el, { targetX: value });
5513
5696
  }
5514
5697
 
5515
5698
  /**
@@ -6397,12 +6580,120 @@ class TinyHtml {
6397
6580
 
6398
6581
  ////////////////////////////////////////////
6399
6582
 
6583
+ /**
6584
+ * Registers a listener for the "paste" event to extract files and text from the clipboard (e.g., when the user presses Ctrl+V).
6585
+ *
6586
+ * This method allows reacting to pasted content by providing separate callbacks for files and plain text.
6587
+ * Useful for building file upload areas, rich-text editors, or input enhancements.
6588
+ *
6589
+ * @param {TinyElementWithDoc|TinyElementWithDoc[]} el - The target element(s) where the "paste" event will be listened.
6590
+ * @param {Object} [settings={}] - Optional callbacks to handle clipboard content.
6591
+ * @param {(data: DataTransferItem, file: File) => void} [settings.onFilePaste] - Called for each file pasted from the clipboard (e.g., images).
6592
+ * @param {(data: DataTransferItem, text: string) => void} [settings.onTextPaste] - Called when plain text is pasted from the clipboard.
6593
+ * @returns {EventListenerOrEventListenerObject} The internal "paste" event handler used.
6594
+ */
6595
+ static listenForPaste(el, { onFilePaste, onTextPaste } = {}) {
6596
+ if (typeof onFilePaste !== 'undefined' && typeof onFilePaste !== 'function')
6597
+ throw new TypeError('onFilePaste must be a function.');
6598
+ if (typeof onTextPaste !== 'undefined' && typeof onTextPaste !== 'function')
6599
+ throw new TypeError('onTextPaste must be a function.');
6600
+
6601
+ /** @type {EventListenerOrEventListenerObject} */
6602
+ const pasteEvent = (event) => {
6603
+ if (!(event instanceof ClipboardEvent)) return;
6604
+ const items = event.clipboardData?.items || [];
6605
+ for (const item of items) {
6606
+ if (item.kind === 'file') {
6607
+ if (typeof onFilePaste === 'function') {
6608
+ const file = item.getAsFile();
6609
+ if (file) onFilePaste(item, file);
6610
+ }
6611
+ } else if (item.kind === 'string') {
6612
+ if (typeof onTextPaste === 'function')
6613
+ item.getAsString((text) => onTextPaste(item, text));
6614
+ }
6615
+ }
6616
+ };
6617
+
6618
+ TinyHtml._preElemsWithDoc(el, 'listenForPaste').forEach((elem) =>
6619
+ TinyHtml.on(elem, 'paste', pasteEvent),
6620
+ );
6621
+ return pasteEvent;
6622
+ }
6623
+
6624
+ /**
6625
+ * Registers a listener for the "paste" event to extract files and text from the clipboard (e.g., when the user presses Ctrl+V).
6626
+ *
6627
+ * This method allows reacting to pasted content by providing separate callbacks for files and plain text.
6628
+ * Useful for building file upload areas, rich-text editors, or input enhancements.
6629
+ *
6630
+ * @param {Object} [settings={}] - Optional callbacks to handle clipboard content.
6631
+ * @param {(data: DataTransferItem, file: File) => void} [settings.onFilePaste] - Called for each file pasted from the clipboard (e.g., images).
6632
+ * @param {(data: DataTransferItem, text: string) => void} [settings.onTextPaste] - Called when plain text is pasted from the clipboard.
6633
+ * @returns {EventListenerOrEventListenerObject} The internal "paste" event handler used.
6634
+ */
6635
+ listenForPaste({ onFilePaste, onTextPaste } = {}) {
6636
+ return TinyHtml.listenForPaste(this, { onFilePaste, onTextPaste });
6637
+ }
6638
+
6639
+ /**
6640
+ * Checks if the element has a listener for a specific event.
6641
+ *
6642
+ * @param {TinyEventTarget} el - The element to check.
6643
+ * @param {string} event - The event name to check.
6644
+ * @returns {boolean}
6645
+ */
6646
+ static hasEventListener(el, event) {
6647
+ const elem = TinyHtml._preEventTargetElem(el, 'hasEventListener');
6648
+ if (!__eventRegistry.has(elem)) return false;
6649
+ const events = __eventRegistry.get(elem);
6650
+ return !!(events && Array.isArray(events[event]) && events[event].length > 0);
6651
+ }
6652
+
6653
+ /**
6654
+ * Checks if the element has a listener for a specific event.
6655
+ *
6656
+ * @param {string} event - The event name to check.
6657
+ * @returns {boolean}
6658
+ */
6659
+ hasEventListener(event) {
6660
+ return TinyHtml.hasEventListener(this, event);
6661
+ }
6662
+
6663
+ /**
6664
+ * Checks if the element has the exact handler registered for a specific event.
6665
+ *
6666
+ * @param {TinyEventTarget} el - The element to check.
6667
+ * @param {string} event - The event name to check.
6668
+ * @param {EventListenerOrEventListenerObject} handler - The handler function to check.
6669
+ * @returns {boolean}
6670
+ */
6671
+ static hasExactEventListener(el, event, handler) {
6672
+ const elem = TinyHtml._preEventTargetElem(el, 'hasExactEventListener');
6673
+ if (typeof handler !== 'function') throw new TypeError('The "handler" must be a function.');
6674
+ if (!__eventRegistry.has(elem)) return false;
6675
+ const events = __eventRegistry.get(elem);
6676
+ if (!events || !Array.isArray(events[event])) return false;
6677
+ return events[event].some((item) => item.handler === handler);
6678
+ }
6679
+
6680
+ /**
6681
+ * Checks if the element has the exact handler registered for a specific event.
6682
+ *
6683
+ * @param {string} event - The event name to check.
6684
+ * @param {EventListenerOrEventListenerObject} handler - The handler function to check.
6685
+ * @returns {boolean}
6686
+ */
6687
+ hasExactEventListener(event, handler) {
6688
+ return TinyHtml.hasExactEventListener(this, event, handler);
6689
+ }
6690
+
6400
6691
  /**
6401
6692
  * Registers an event listener on the specified element.
6402
6693
  *
6403
6694
  * @param {TinyEventTarget|TinyEventTarget[]} el - The target to listen on.
6404
6695
  * @param {string} event - The event type (e.g. 'click', 'keydown').
6405
- * @param {EventRegistryHandle} handler - The callback function to run on event.
6696
+ * @param {EventListenerOrEventListenerObject|null} handler - The callback function to run on event.
6406
6697
  * @param {EventRegistryOptions} [options] - Optional event listener options.
6407
6698
  * @returns {TinyEventTarget|TinyEventTarget[]}
6408
6699
  */
@@ -6424,7 +6715,7 @@ class TinyHtml {
6424
6715
  * Registers an event listener on the specified element.
6425
6716
  *
6426
6717
  * @param {string} event - The event type (e.g. 'click', 'keydown').
6427
- * @param {EventRegistryHandle} handler - The callback function to run on event.
6718
+ * @param {EventListenerOrEventListenerObject|null} handler - The callback function to run on event.
6428
6719
  * @param {EventRegistryOptions} [options] - Optional event listener options.
6429
6720
  * @returns {TinyEventTarget|TinyEventTarget[]}
6430
6721
  */
@@ -6437,17 +6728,17 @@ class TinyHtml {
6437
6728
  *
6438
6729
  * @param {TinyEventTarget|TinyEventTarget[]} el - The target to listen on.
6439
6730
  * @param {string} event - The event type (e.g. 'click', 'keydown').
6440
- * @param {EventRegistryHandle} handler - The callback function to run on event.
6731
+ * @param {EventListenerOrEventListenerObject} handler - The callback function to run on event.
6441
6732
  * @param {EventRegistryOptions} [options={}] - Optional event listener options.
6442
6733
  * @returns {TinyEventTarget|TinyEventTarget[]}
6443
6734
  */
6444
6735
  static once(el, event, handler, options = {}) {
6445
6736
  if (typeof event !== 'string') throw new TypeError('The event name must be a string.');
6446
6737
  TinyHtml._preEventTargetElems(el, 'once').forEach((elem) => {
6447
- /** @type {EventRegistryHandle} e */
6738
+ /** @type {EventListenerOrEventListenerObject} */
6448
6739
  const wrapped = (e) => {
6449
6740
  TinyHtml.off(elem, event, wrapped);
6450
- handler(e);
6741
+ if (typeof handler === 'function') handler(e);
6451
6742
  };
6452
6743
 
6453
6744
  TinyHtml.on(
@@ -6464,7 +6755,7 @@ class TinyHtml {
6464
6755
  * Registers an event listener that runs only once, then is removed.
6465
6756
  *
6466
6757
  * @param {string} event - The event type (e.g. 'click', 'keydown').
6467
- * @param {EventRegistryHandle} handler - The callback function to run on event.
6758
+ * @param {EventListenerOrEventListenerObject} handler - The callback function to run on event.
6468
6759
  * @param {EventRegistryOptions} [options={}] - Optional event listener options.
6469
6760
  * @returns {TinyEventTarget|TinyEventTarget[]}
6470
6761
  */
@@ -6477,7 +6768,7 @@ class TinyHtml {
6477
6768
  *
6478
6769
  * @param {TinyEventTarget|TinyEventTarget[]} el - The target element.
6479
6770
  * @param {string} event - The event type.
6480
- * @param {EventRegistryHandle} handler - The function originally bound to the event.
6771
+ * @param {EventListenerOrEventListenerObject|null} handler - The function originally bound to the event.
6481
6772
  * @param {boolean|EventListenerOptions} [options] - Optional listener options.
6482
6773
  * @returns {TinyEventTarget|TinyEventTarget[]}
6483
6774
  */
@@ -6499,7 +6790,7 @@ class TinyHtml {
6499
6790
  * Removes a specific event listener from an element.
6500
6791
  *
6501
6792
  * @param {string} event - The event type.
6502
- * @param {EventRegistryHandle} handler - The function originally bound to the event.
6793
+ * @param {EventListenerOrEventListenerObject|null} handler - The function originally bound to the event.
6503
6794
  * @param {boolean|EventListenerOptions} [options] - Optional listener options.
6504
6795
  * @returns {TinyEventTarget|TinyEventTarget[]}
6505
6796
  */
@@ -6542,7 +6833,7 @@ class TinyHtml {
6542
6833
  * Removes all event listeners of all types from the element.
6543
6834
  *
6544
6835
  * @param {TinyEventTarget|TinyEventTarget[]} el - The target element.
6545
- * @param {((handler: EventListenerOrEventListenerObject, event: string) => boolean)|null} [filterFn=null] -
6836
+ * @param {((handler: EventListenerOrEventListenerObject|null, event: string) => boolean)|null} [filterFn=null] -
6546
6837
  * Optional filter function to selectively remove specific handlers.
6547
6838
  * @returns {TinyEventTarget|TinyEventTarget[]}
6548
6839
  */
@@ -6569,7 +6860,7 @@ class TinyHtml {
6569
6860
  /**
6570
6861
  * Removes all event listeners of all types from the element.
6571
6862
  *
6572
- * @param {((handler: EventListenerOrEventListenerObject, event: string) => boolean)|null} [filterFn=null] -
6863
+ * @param {((handler: EventListenerOrEventListenerObject|null, event: string) => boolean)|null} [filterFn=null] -
6573
6864
  * Optional filter function to selectively remove specific handlers.
6574
6865
  * @returns {TinyEventTarget|TinyEventTarget[]}
6575
6866
  */