@splendidlabz/utils 1.10.0 → 1.10.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/CHANGELOG.md +12 -0
- package/dist/cjs/dom/actions/index.cjs +75 -73
- package/dist/cjs/dom/actions/masonry.cjs +4 -2
- package/dist/cjs/dom/actions/prefer-horizontal-scroll.cjs +24 -24
- package/dist/cjs/dom/actions/sticky.cjs +4 -2
- package/dist/cjs/dom/index.cjs +62 -49
- package/dist/cjs/dom/observers/index.cjs +14 -3
- package/dist/cjs/dom/observers/resize-observer.cjs +4 -2
- package/dist/cjs/dom/observers/scroll-observer.cjs +14 -3
- package/dist/esm/dom/actions/index.js +75 -73
- package/dist/esm/dom/actions/masonry.js +4 -2
- package/dist/esm/dom/actions/prefer-horizontal-scroll.js +24 -24
- package/dist/esm/dom/actions/sticky.js +4 -2
- package/dist/esm/dom/index.js +62 -49
- package/dist/esm/dom/observers/index.js +14 -3
- package/dist/esm/dom/observers/resize-observer.js +4 -2
- package/dist/esm/dom/observers/scroll-observer.js +14 -3
- package/dist/types/dom/events.d.cts +2 -2
- package/dist/types/dom/observers/resize-observer.d.cts +3 -3
- package/dist/types/dom/observers/scroll-observer.d.cts +2 -12
- package/dist/types/dom/spam-prevention.d.cts +7 -7
- package/dist/types/lib/checks.d.cts +1 -1
- package/package.json +1 -1
- package/src/dom/actions/prefer-horizontal-scroll.js +3 -8
- package/src/dom/events.js +1 -1
- package/src/dom/font-size.js +1 -1
- package/src/dom/observers/resize-observer.js +6 -4
- package/src/dom/observers/scroll-observer.js +17 -2
- package/src/dom/spam-prevention.js +5 -4
- package/src/dom/events.test.js +0 -99
package/src/dom/events.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @typedef {Object} EventListener
|
|
3
3
|
* @property {Element} node - The DOM element to attach the event listener to
|
|
4
4
|
* @property {string} event - The event type (e.g., 'click', 'keydown')
|
|
5
|
-
* @property {
|
|
5
|
+
* @property {EventListenerOrEventListenerObject} handler - The event handler function
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
package/src/dom/font-size.js
CHANGED
|
@@ -5,8 +5,8 @@ import { useObserverMethodOnTarget } from './observer.js'
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates and manages a ResizeObserver instance to monitor size changes of a target element.
|
|
7
7
|
*
|
|
8
|
-
* @param {Element|Window|NodeList|Element[]} target - The element(s) to observe.
|
|
9
|
-
* - If window is provided, document.
|
|
8
|
+
* @param {Element|Window|Document|NodeList|Element[]} target - The element(s) to observe.
|
|
9
|
+
* - If window or document is provided, document.documentElement will be observed instead.
|
|
10
10
|
* - If NodeList or Array of elements is provided, all elements will be observed.
|
|
11
11
|
* @param {Object} options - Configuration options for the resize observer
|
|
12
12
|
* @param {boolean} [options.observe=true] - Whether to start observing immediately. If false, the observer won't be created.
|
|
@@ -39,13 +39,15 @@ export function resizeObserver(target, options) {
|
|
|
39
39
|
const { callback, ...opts } = options
|
|
40
40
|
const observer = new ResizeObserver(observerFn)
|
|
41
41
|
|
|
42
|
-
if (target === window
|
|
42
|
+
if (target === window || target === document)
|
|
43
|
+
target = document.documentElement
|
|
43
44
|
useObserverMethodOnTarget(target, observer, 'observe', opts)
|
|
44
45
|
|
|
45
46
|
function observerFn(entries) {
|
|
46
47
|
for (const entry of entries) {
|
|
47
48
|
if (callback) callback({ entry, entries, observer })
|
|
48
|
-
else
|
|
49
|
+
else
|
|
50
|
+
dispatchEvent(entry.target, 'resize-obs', { entry, entries, observer })
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -18,9 +18,24 @@ const defaultOptions = {
|
|
|
18
18
|
* @property {Function} [onEnterThreshold] - Called when entering threshold zone
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @param {Element | Document | Window} node
|
|
23
|
+
* @returns {Element}
|
|
24
|
+
*/
|
|
25
|
+
function getScrollElement(node) {
|
|
26
|
+
if (
|
|
27
|
+
node === document ||
|
|
28
|
+
node === window ||
|
|
29
|
+
node === document.documentElement
|
|
30
|
+
) {
|
|
31
|
+
return document.documentElement
|
|
32
|
+
}
|
|
33
|
+
return /** @type {Element} */ (node)
|
|
34
|
+
}
|
|
35
|
+
|
|
21
36
|
/**
|
|
22
37
|
* Scroll Observer - Optimized for performance
|
|
23
|
-
* @param {Element} node - The element to observe scroll events on
|
|
38
|
+
* @param {Element | Document | Window} node - The element to observe scroll events on
|
|
24
39
|
* @param {ScrollObserverOptions} [options] - Configuration options
|
|
25
40
|
*/
|
|
26
41
|
export function scrollObserver(node, options = {}) {
|
|
@@ -38,7 +53,7 @@ export function scrollObserver(node, options = {}) {
|
|
|
38
53
|
// Determine scroll context once at initialization
|
|
39
54
|
const isDocumentScroll =
|
|
40
55
|
node === document || node === window || node === document.documentElement
|
|
41
|
-
const scrollElement =
|
|
56
|
+
const scrollElement = getScrollElement(node)
|
|
42
57
|
const eventTarget = isDocumentScroll ? window : node
|
|
43
58
|
|
|
44
59
|
// Cache DOM references and expensive calculations
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Enhances a form element with spam detection capabilities
|
|
3
3
|
* @param {HTMLFormElement} form - The form element to enhance
|
|
4
|
-
* @param {Object} options - Configuration options
|
|
5
|
-
* @param {string} options.honeypotField - Name of the honeypot field (default: 'hp')
|
|
6
|
-
* @param {number} options.honeypotDuration - Minimum time in ms for legitimate form fill (default: 2000)
|
|
7
|
-
* @returns {
|
|
4
|
+
* @param {Object} [options] - Configuration options
|
|
5
|
+
* @param {string} [options.honeypotField] - Name of the honeypot field (default: 'hp')
|
|
6
|
+
* @param {number} [options.honeypotDuration] - Minimum time in ms for legitimate form fill (default: 2000)
|
|
7
|
+
* @returns {void}
|
|
8
8
|
*/
|
|
9
9
|
export function preventSpam(
|
|
10
10
|
form,
|
|
@@ -25,6 +25,7 @@ export function preventSpam(
|
|
|
25
25
|
form.containsSpam = function () {
|
|
26
26
|
const fillTime = Date.now() - startTime
|
|
27
27
|
const isTooFast = fillTime < honeypotDuration
|
|
28
|
+
/** @type {HTMLInputElement | null} */
|
|
28
29
|
const honeypotInput = form.querySelector(`[name="${honeypotField}"]`)
|
|
29
30
|
const hasHoneypotValue = honeypotInput?.value?.trim()
|
|
30
31
|
const noInteraction = !hasInteraction
|
package/src/dom/events.test.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { describe, expect, it } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import { createListeners } from './events.js'
|
|
5
|
-
|
|
6
|
-
describe('Listeners Factory', _ => {
|
|
7
|
-
it('Empty', _ => {
|
|
8
|
-
const listeners = createListeners()
|
|
9
|
-
expect(listeners.list).toEqual([])
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it('Begins with some listeners', _ => {
|
|
13
|
-
const node1 = document.createElement('div')
|
|
14
|
-
const node2 = document.createElement('p')
|
|
15
|
-
const event1 = 'click'
|
|
16
|
-
const event2 = 'keydown'
|
|
17
|
-
const cb1 = _ => {}
|
|
18
|
-
const cb2 = _ => {}
|
|
19
|
-
|
|
20
|
-
const listeners = createListeners([
|
|
21
|
-
{ node: node1, event: event1, handler: cb1 },
|
|
22
|
-
{ node: node2, event: event2, handler: cb2 },
|
|
23
|
-
])
|
|
24
|
-
|
|
25
|
-
expect(listeners.list).toEqual([
|
|
26
|
-
{ node: node1, event: event1, handler: cb1 },
|
|
27
|
-
{ node: node2, event: event2, handler: cb2 },
|
|
28
|
-
])
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('Add', _ => {
|
|
32
|
-
const node = document.createElement('div')
|
|
33
|
-
const event = 'click'
|
|
34
|
-
const handler = _ => {
|
|
35
|
-
node.setAttribute('clicked', true)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const listeners = createListeners()
|
|
39
|
-
listeners.add({ node, event, handler })
|
|
40
|
-
|
|
41
|
-
// Ensures the listener was added to the list
|
|
42
|
-
expect(listeners.list.length).toBe(1)
|
|
43
|
-
|
|
44
|
-
// Ensures the listener works
|
|
45
|
-
node.click()
|
|
46
|
-
expect(node.getAttribute('clicked')).toBe('true')
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('Remove', _ => {
|
|
50
|
-
const node = document.createElement('div')
|
|
51
|
-
const event = 'click'
|
|
52
|
-
const handler = _ => {
|
|
53
|
-
const count = node.getAttribute('count') || 0
|
|
54
|
-
node.setAttribute('count', count + 1)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const listener = { node, event, handler }
|
|
58
|
-
const listeners = createListeners([listener])
|
|
59
|
-
|
|
60
|
-
node.click()
|
|
61
|
-
expect(node.getAttribute('count')).toBe('1')
|
|
62
|
-
|
|
63
|
-
listeners.remove(listener)
|
|
64
|
-
|
|
65
|
-
// Ensures listener has been removed
|
|
66
|
-
node.click()
|
|
67
|
-
|
|
68
|
-
expect(listeners.list.length).toBe(0)
|
|
69
|
-
expect(node.getAttribute('count')).toBe('1')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('Clears all listeners from', _ => {
|
|
73
|
-
const node1 = document.createElement('div')
|
|
74
|
-
const node2 = document.createElement('p')
|
|
75
|
-
const event1 = 'click'
|
|
76
|
-
const event2 = 'click'
|
|
77
|
-
const cb1 = _ => {
|
|
78
|
-
node1.setAttribute('clicked', true)
|
|
79
|
-
}
|
|
80
|
-
const cb2 = _ => {
|
|
81
|
-
node2.setAttribute('clicked', true)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const listeners = createListeners([
|
|
85
|
-
{ node: node1, event: event1, handler: cb1 },
|
|
86
|
-
{ node: node2, event: event2, handler: cb2 },
|
|
87
|
-
])
|
|
88
|
-
|
|
89
|
-
listeners.clear()
|
|
90
|
-
expect(listeners.list).toEqual([])
|
|
91
|
-
|
|
92
|
-
// Ensures none of the listeners work anymore
|
|
93
|
-
node1.click()
|
|
94
|
-
node2.click()
|
|
95
|
-
|
|
96
|
-
expect(node1.getAttribute('clicked')).toBe(null)
|
|
97
|
-
expect(node2.getAttribute('clicked')).toBe(null)
|
|
98
|
-
})
|
|
99
|
-
})
|