@oscarpalmer/toretto 0.45.0 → 0.47.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.
- package/dist/aria.d.mts +68 -0
- package/dist/aria.mjs +49 -0
- package/dist/attribute/get.attribute.d.mts +3 -0
- package/dist/attribute/get.attribute.mjs +3 -3
- package/dist/attribute/index.d.mts +7 -1
- package/dist/attribute/set.attribute.d.mts +5 -0
- package/dist/attribute/set.attribute.mjs +1 -1
- package/dist/create.d.mts +4 -2
- package/dist/create.mjs +1 -1
- package/dist/data.d.mts +4 -0
- package/dist/data.mjs +1 -2
- package/dist/event/delegation.mjs +3 -4
- package/dist/event/index.d.mts +9 -1
- package/dist/event/index.mjs +3 -2
- package/dist/find/index.d.mts +14 -1
- package/dist/find/index.mjs +36 -1
- package/dist/find/relative.d.mts +5 -0
- package/dist/find/relative.mjs +1 -0
- package/dist/focusable.d.mts +4 -0
- package/dist/focusable.mjs +4 -0
- package/dist/html/index.d.mts +8 -4
- package/dist/html/index.mjs +4 -3
- package/dist/index.d.mts +185 -22
- package/dist/index.mjs +295 -144
- package/dist/internal/attribute.mjs +2 -2
- package/dist/internal/element-value.mjs +2 -4
- package/dist/internal/is.d.mts +15 -3
- package/dist/internal/is.mjs +15 -3
- package/dist/is.d.mts +5 -2
- package/dist/is.mjs +4 -3
- package/dist/models.d.mts +21 -8
- package/dist/property/get.property.d.mts +2 -0
- package/dist/property/get.property.mjs +4 -3
- package/dist/property/set.property.d.mts +3 -0
- package/dist/property/set.property.mjs +3 -4
- package/dist/style.d.mts +7 -0
- package/dist/style.mjs +8 -4
- package/dist/touch.d.mts +4 -0
- package/package.json +10 -6
- package/src/aria.ts +166 -0
- package/src/attribute/get.attribute.ts +5 -3
- package/src/attribute/index.ts +6 -0
- package/src/attribute/set.attribute.ts +5 -0
- package/src/create.ts +5 -3
- package/src/data.ts +11 -6
- package/src/event/delegation.ts +5 -6
- package/src/event/index.ts +11 -8
- package/src/find/index.ts +64 -1
- package/src/find/relative.ts +5 -0
- package/src/focusable.ts +4 -0
- package/src/html/index.ts +11 -9
- package/src/index.ts +1 -0
- package/src/internal/attribute.ts +4 -2
- package/src/internal/element-value.ts +2 -3
- package/src/internal/is.ts +22 -2
- package/src/is.ts +4 -1
- package/src/models.ts +122 -8
- package/src/property/get.property.ts +6 -5
- package/src/property/set.property.ts +5 -3
- package/src/style.ts +12 -6
- package/src/touch.ts +4 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {kebabCase} from '@oscarpalmer/atoms/string/case';
|
|
2
2
|
import {getAttributeValue} from '../internal/get-value';
|
|
3
|
-
import {isHTMLOrSVGElement} from '../internal/is';
|
|
4
3
|
|
|
5
4
|
// #region Types
|
|
6
5
|
|
|
@@ -12,6 +11,7 @@ type DataPrefixedName = `data-${string}`;
|
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Get the value of a specific attribute from an element
|
|
14
|
+
*
|
|
15
15
|
* @param element Element to get attribute from
|
|
16
16
|
* @param name Attribute name
|
|
17
17
|
* @param parse Parse value? _(defaults to `true`)_
|
|
@@ -21,6 +21,7 @@ export function getAttribute(element: Element, name: DataPrefixedName, parse?: b
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Get the value of a specific attribute from an element
|
|
24
|
+
*
|
|
24
25
|
* @param element Element to get attribute from
|
|
25
26
|
* @param name Attribute name
|
|
26
27
|
* @returns Attribute value _(or `undefined`)_
|
|
@@ -28,13 +29,14 @@ export function getAttribute(element: Element, name: DataPrefixedName, parse?: b
|
|
|
28
29
|
export function getAttribute(element: Element, name: string): unknown;
|
|
29
30
|
|
|
30
31
|
export function getAttribute(element: Element, name: string, parseValues?: boolean): unknown {
|
|
31
|
-
if (
|
|
32
|
+
if (element instanceof Element && typeof name === 'string') {
|
|
32
33
|
return getAttributeValue(element, kebabCase(name), parseValues !== false);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* Get specific attributes from an element
|
|
39
|
+
*
|
|
38
40
|
* @param element Element to get attributes from
|
|
39
41
|
* @param names Attribute names
|
|
40
42
|
* @param parseData Parse data values? _(defaults to `true`)_
|
|
@@ -47,7 +49,7 @@ export function getAttributes<Key extends string>(
|
|
|
47
49
|
): Record<Key, unknown> {
|
|
48
50
|
const attributes: Record<string, unknown> = {};
|
|
49
51
|
|
|
50
|
-
if (!(
|
|
52
|
+
if (!(element instanceof Element && Array.isArray(names))) {
|
|
51
53
|
return attributes;
|
|
52
54
|
}
|
|
53
55
|
|
package/src/attribute/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {Attribute} from '../models';
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Is the attribute considered bad and potentially harmful?
|
|
12
|
+
*
|
|
12
13
|
* @param attribute Attribute to check
|
|
13
14
|
* @returns `true` if attribute is considered bad
|
|
14
15
|
*/
|
|
@@ -16,6 +17,7 @@ export function isBadAttribute(attribute: Attr | Attribute): boolean;
|
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Is the attribute considered bad and potentially harmful?
|
|
20
|
+
*
|
|
19
21
|
* @param name Attribute name
|
|
20
22
|
* @param value Attribute value
|
|
21
23
|
* @returns `true` if attribute is considered bad
|
|
@@ -28,6 +30,7 @@ export function isBadAttribute(first: unknown, second?: unknown): boolean {
|
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* Is the attribute a boolean attribute?
|
|
33
|
+
*
|
|
31
34
|
* @param name Attribute to check
|
|
32
35
|
* @returns `true` if attribute is a boolean attribute
|
|
33
36
|
*/
|
|
@@ -35,6 +38,7 @@ export function isBooleanAttribute(attribute: Attr | Attribute): boolean;
|
|
|
35
38
|
|
|
36
39
|
/**
|
|
37
40
|
* Is the attribute a boolean attribute?
|
|
41
|
+
*
|
|
38
42
|
* @param name Attribute name
|
|
39
43
|
* @returns `true` if attribute is a boolean attribute
|
|
40
44
|
*/
|
|
@@ -48,6 +52,7 @@ export function isBooleanAttribute(first: unknown): boolean {
|
|
|
48
52
|
* Is the attribute an invalid boolean attribute?
|
|
49
53
|
*
|
|
50
54
|
* _(I.e., its value is not empty or the same as its name)_
|
|
55
|
+
*
|
|
51
56
|
* @param attribute Attribute to check
|
|
52
57
|
* @returns `true` if attribute is an invalid boolean attribute
|
|
53
58
|
*/
|
|
@@ -57,6 +62,7 @@ export function isInvalidBooleanAttribute(attribute: Attr | Attribute): boolean;
|
|
|
57
62
|
* Is the attribute an invalid boolean attribute?
|
|
58
63
|
*
|
|
59
64
|
* _(I.e., its value is not empty or the same as its name)_
|
|
65
|
+
*
|
|
60
66
|
* @param name Attribute name
|
|
61
67
|
* @param value Attribute value
|
|
62
68
|
* @returns `true` if attribute is an invalid boolean attribute
|
|
@@ -14,6 +14,7 @@ export type DispatchedAttributeName = 'checked' | 'open' | 'value';
|
|
|
14
14
|
* Set an attribute on an element
|
|
15
15
|
*
|
|
16
16
|
* _(Or remove it, if value is `null` or `undefined`)_
|
|
17
|
+
*
|
|
17
18
|
* @param element Element for attribute
|
|
18
19
|
* @param name Attribute name
|
|
19
20
|
* @param value Attribute value
|
|
@@ -30,6 +31,7 @@ export function setAttribute(
|
|
|
30
31
|
* Set an attribute on an element
|
|
31
32
|
*
|
|
32
33
|
* _(Or remove it, if value is `null` or `undefined`)_
|
|
34
|
+
*
|
|
33
35
|
* @param element Element for attribute
|
|
34
36
|
* @param name Attribute name
|
|
35
37
|
* @param value Attribute value
|
|
@@ -40,6 +42,7 @@ export function setAttribute(element: Element, name: string, value?: unknown): v
|
|
|
40
42
|
* Set an attribute on an element
|
|
41
43
|
*
|
|
42
44
|
* _(Or remove it, if value is `null` or `undefined`)_
|
|
45
|
+
*
|
|
43
46
|
* @param element Element for attribute
|
|
44
47
|
* @param attribute Attribute to set
|
|
45
48
|
* @param dispatch Dispatch event for attribute? _(defaults to `true`)_
|
|
@@ -63,6 +66,7 @@ export function setAttribute(
|
|
|
63
66
|
* Set one or more attributes on an element
|
|
64
67
|
*
|
|
65
68
|
* _(Or remove them, if their value is `null` or `undefined`)_
|
|
69
|
+
*
|
|
66
70
|
* @param element Element for attributes
|
|
67
71
|
* @param attributes Attributes to set
|
|
68
72
|
* @param dispatch Dispatch events for relevant attributes? _(defaults to `true`)_
|
|
@@ -77,6 +81,7 @@ export function setAttributes(
|
|
|
77
81
|
* Set one or more attributes on an element
|
|
78
82
|
*
|
|
79
83
|
* _(Or remove them, if their value is `null` or `undefined`)_
|
|
84
|
+
*
|
|
80
85
|
* @param element Element for attributes
|
|
81
86
|
* @param attributes Attributes to set
|
|
82
87
|
* @param dispatch Dispatch events for relevant attributes? _(defaults to `true`)_
|
package/src/create.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {Primitive} from '@oscarpalmer/atoms/models';
|
|
2
2
|
import {setAttributes} from './attribute';
|
|
3
|
-
import {setStyles} from './style';
|
|
4
3
|
import {setProperties} from './property';
|
|
4
|
+
import {setStyles} from './style';
|
|
5
5
|
|
|
6
6
|
// #region Types
|
|
7
7
|
|
|
@@ -16,7 +16,8 @@ type Styles = Partial<Record<keyof CSSStyleDeclaration, unknown>>;
|
|
|
16
16
|
// #region Functions
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Creates an
|
|
19
|
+
* Creates an _HTML_ element with the specified tag name together with optional properties, attributes, and styles
|
|
20
|
+
*
|
|
20
21
|
* @param tag Tag name
|
|
21
22
|
* @param properties Element properties
|
|
22
23
|
* @param attributes Element attributes
|
|
@@ -31,7 +32,8 @@ export function createElement<TagName extends keyof HTMLElementTagNameMap>(
|
|
|
31
32
|
): HTMLElementTagNameMap[TagName];
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
|
-
* Creates an
|
|
35
|
+
* Creates an _HTML_ element with the specified tag name together with optional properties, attributes, and styles
|
|
36
|
+
*
|
|
35
37
|
* @param tag Tag name
|
|
36
38
|
* @param properties Element properties
|
|
37
39
|
* @param attributes Element attributes
|
package/src/data.ts
CHANGED
|
@@ -3,12 +3,12 @@ import {parse} from '@oscarpalmer/atoms/string';
|
|
|
3
3
|
import {camelCase, kebabCase} from '@oscarpalmer/atoms/string/case';
|
|
4
4
|
import {setElementValues, updateElementValue} from './internal/element-value';
|
|
5
5
|
import {EXPRESSION_DATA_PREFIX} from './internal/get-value';
|
|
6
|
-
import {isHTMLOrSVGElement} from './internal/is';
|
|
7
6
|
|
|
8
7
|
// #region Functions
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Get a keyed data value from an element
|
|
11
|
+
*
|
|
12
12
|
* @param element Element to get data from
|
|
13
13
|
* @param key Data key
|
|
14
14
|
* @param parse Parse values? _(defaults to `true`)_
|
|
@@ -18,6 +18,7 @@ export function getData(element: Element, key: string, parse?: boolean): unknown
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Get keyed data values from an element
|
|
21
|
+
*
|
|
21
22
|
* @param element Element to get data from
|
|
22
23
|
* @param keys Keys of the data values to get
|
|
23
24
|
* @param parse Parse values? _(defaults to `true`)_
|
|
@@ -30,14 +31,14 @@ export function getData<Key extends string>(
|
|
|
30
31
|
): Record<Key, unknown>;
|
|
31
32
|
|
|
32
33
|
export function getData(element: Element, keys: string | string[], parseValues?: boolean): unknown {
|
|
33
|
-
if (!
|
|
34
|
+
if (!(element instanceof Element)) {
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
const noParse = parseValues === false;
|
|
38
39
|
|
|
39
40
|
if (typeof keys === 'string') {
|
|
40
|
-
const value = element.dataset[camelCase(keys)];
|
|
41
|
+
const value = (element as HTMLElement).dataset[camelCase(keys)];
|
|
41
42
|
|
|
42
43
|
if (value === undefined) {
|
|
43
44
|
return;
|
|
@@ -52,7 +53,7 @@ export function getData(element: Element, keys: string | string[], parseValues?:
|
|
|
52
53
|
|
|
53
54
|
for (let index = 0; index < length; index += 1) {
|
|
54
55
|
const key = keys[index];
|
|
55
|
-
const value = element.dataset[camelCase(key)];
|
|
56
|
+
const value = (element as HTMLElement).dataset[camelCase(key)];
|
|
56
57
|
|
|
57
58
|
if (value == null) {
|
|
58
59
|
data[key] = undefined;
|
|
@@ -70,6 +71,7 @@ function getName(original: string): string {
|
|
|
70
71
|
|
|
71
72
|
/**
|
|
72
73
|
* Set data values on an element
|
|
74
|
+
*
|
|
73
75
|
* @param element Element to set data on
|
|
74
76
|
* @param data Data to set
|
|
75
77
|
*/
|
|
@@ -77,6 +79,7 @@ export function setData(element: Element, data: PlainObject): void;
|
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
81
|
* Set a data value on an element
|
|
82
|
+
*
|
|
80
83
|
* @param element Element to set data on
|
|
81
84
|
* @param key Data key
|
|
82
85
|
* @param value Data value
|
|
@@ -92,9 +95,11 @@ function updateDataAttribute(element: Element, key: string, value: unknown): voi
|
|
|
92
95
|
element,
|
|
93
96
|
getName(key),
|
|
94
97
|
value,
|
|
95
|
-
//
|
|
98
|
+
// Using `.call` in `updateElementValue`
|
|
99
|
+
// oxlint-disable-next-line typescript/unbound-method
|
|
96
100
|
element.setAttribute,
|
|
97
|
-
//
|
|
101
|
+
// Using `.call` in `updateElementValue`
|
|
102
|
+
// oxlint-disable-next-line typescript/unbound-method
|
|
98
103
|
element.removeAttribute,
|
|
99
104
|
false,
|
|
100
105
|
true,
|
package/src/event/delegation.ts
CHANGED
|
@@ -43,7 +43,7 @@ export function addDelegatedListener(
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
function delegatedEventHandler(this: boolean, event: Event): void {
|
|
46
|
-
const key =
|
|
46
|
+
const key = `@${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
47
47
|
|
|
48
48
|
const items = event.composedPath();
|
|
49
49
|
const {length} = items;
|
|
@@ -51,7 +51,8 @@ function delegatedEventHandler(this: boolean, event: Event): void {
|
|
|
51
51
|
let cancelled = false;
|
|
52
52
|
let target = items[0];
|
|
53
53
|
|
|
54
|
-
//
|
|
54
|
+
// Using `.call` to ensure correct `this` context
|
|
55
|
+
// oxlint-disable-next-line typescript/unbound-method
|
|
55
56
|
const originalStopPropagation = event.stopPropagation;
|
|
56
57
|
|
|
57
58
|
event.stopPropagation = function () {
|
|
@@ -108,7 +109,7 @@ export function getDelegatedName(
|
|
|
108
109
|
!options.once &&
|
|
109
110
|
options.signal == null
|
|
110
111
|
) {
|
|
111
|
-
return
|
|
112
|
+
return `@${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
|
|
@@ -138,13 +139,11 @@ export function removeDelegatedListener(
|
|
|
138
139
|
|
|
139
140
|
const DELEGATED = new Set<string>();
|
|
140
141
|
|
|
141
|
-
const EVENT_PREFIX = '@';
|
|
142
|
-
|
|
143
142
|
const EVENT_SUFFIX_ACTIVE = ':active';
|
|
144
143
|
|
|
145
144
|
const EVENT_SUFFIX_PASSIVE = ':passive';
|
|
146
145
|
|
|
147
|
-
const EVENT_TYPES
|
|
146
|
+
const EVENT_TYPES = new Set([
|
|
148
147
|
'beforeinput',
|
|
149
148
|
'click',
|
|
150
149
|
'dblclick',
|
package/src/event/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {noop} from '@oscarpalmer/atoms/function';
|
|
2
2
|
import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
3
|
+
import type {EventPosition} from '@oscarpalmer/atoms/models';
|
|
3
4
|
import {getBoolean} from '../internal/get-value';
|
|
4
5
|
import {isEventTarget} from '../internal/is';
|
|
5
|
-
import type {CustomEventListener,
|
|
6
|
+
import type {CustomEventListener, RemovableEventListener} from '../models';
|
|
6
7
|
import {
|
|
7
8
|
addDelegatedListener,
|
|
8
9
|
type EventTargetWithListeners,
|
|
@@ -34,7 +35,7 @@ function createDispatchOptions(options: EventInit): EventInit {
|
|
|
34
35
|
function createEvent(type: string, options?: CustomEventInit): Event {
|
|
35
36
|
const hasOptions = isPlainObject(options);
|
|
36
37
|
|
|
37
|
-
if (hasOptions &&
|
|
38
|
+
if (hasOptions && 'detail' in (options as CustomEventInit)) {
|
|
38
39
|
return new CustomEvent(type, {
|
|
39
40
|
...createDispatchOptions(options as CustomEventInit),
|
|
40
41
|
detail: options?.detail,
|
|
@@ -55,6 +56,7 @@ function createEventOptions(options?: AddEventListenerOptions): EventOptions {
|
|
|
55
56
|
|
|
56
57
|
/**
|
|
57
58
|
* Dispatch an event for a target
|
|
59
|
+
*
|
|
58
60
|
* @param target Event target
|
|
59
61
|
* @param type Type of event
|
|
60
62
|
* @param options Options for event _(bubbles and is cancelable by default)_
|
|
@@ -67,6 +69,7 @@ export function dispatch<Type extends keyof HTMLElementEventMap>(
|
|
|
67
69
|
|
|
68
70
|
/**
|
|
69
71
|
* Dispatch an event for a target
|
|
72
|
+
*
|
|
70
73
|
* @param target Event target
|
|
71
74
|
* @param type Type of event
|
|
72
75
|
* @param options Options for event _(bubbles and is cancelable by default)_
|
|
@@ -85,6 +88,7 @@ export function dispatch<Type extends keyof HTMLElementEventMap>(
|
|
|
85
88
|
|
|
86
89
|
/**
|
|
87
90
|
* Get the X- and Y-coordinates from a pointer event
|
|
91
|
+
*
|
|
88
92
|
* @param event Pointer event
|
|
89
93
|
* @returns X- and Y-coordinates
|
|
90
94
|
*/
|
|
@@ -105,6 +109,7 @@ export function getPosition(event: MouseEvent | TouchEvent): EventPosition | und
|
|
|
105
109
|
|
|
106
110
|
/**
|
|
107
111
|
* Remove an event listener
|
|
112
|
+
*
|
|
108
113
|
* @param target Event target
|
|
109
114
|
* @param type Type of event
|
|
110
115
|
* @param listener Event listener
|
|
@@ -119,6 +124,7 @@ export function off(
|
|
|
119
124
|
|
|
120
125
|
/**
|
|
121
126
|
* Remove an event listener
|
|
127
|
+
*
|
|
122
128
|
* @param target Event target
|
|
123
129
|
* @param type Type of event
|
|
124
130
|
* @param listener Event listener
|
|
@@ -133,6 +139,7 @@ export function off(
|
|
|
133
139
|
|
|
134
140
|
/**
|
|
135
141
|
* Remove an event listener
|
|
142
|
+
*
|
|
136
143
|
* @param target Event target
|
|
137
144
|
* @param type Type of event
|
|
138
145
|
* @param listener Event listener
|
|
@@ -161,6 +168,7 @@ export function off(
|
|
|
161
168
|
|
|
162
169
|
/**
|
|
163
170
|
* Add an event listener
|
|
171
|
+
*
|
|
164
172
|
* @param target Event target
|
|
165
173
|
* @param type Type of event
|
|
166
174
|
* @param listener Event listener
|
|
@@ -175,6 +183,7 @@ export function on<Type extends keyof HTMLElementEventMap>(
|
|
|
175
183
|
|
|
176
184
|
/**
|
|
177
185
|
* Add an event listener
|
|
186
|
+
*
|
|
178
187
|
* @param target Event target
|
|
179
188
|
* @param type Type of event
|
|
180
189
|
* @param listener Event listener
|
|
@@ -222,9 +231,3 @@ export function on(
|
|
|
222
231
|
}
|
|
223
232
|
|
|
224
233
|
// #endregion
|
|
225
|
-
|
|
226
|
-
// #region Variables
|
|
227
|
-
|
|
228
|
-
const PROPERTY_DETAIL = 'detail';
|
|
229
|
-
|
|
230
|
-
// #endregion
|
package/src/find/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
1
|
+
import type {EventPosition, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import {isEventPosition} from '../internal/is';
|
|
2
3
|
import type {Selector} from '../models';
|
|
3
4
|
|
|
4
5
|
// #region Functions
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Find the first element that matches the tag name
|
|
9
|
+
*
|
|
8
10
|
* @param tagName Tag name of element to find
|
|
9
11
|
* @param context Context to search within _(defaults to `document`)_
|
|
10
12
|
* @returns Found element or `null`
|
|
@@ -16,6 +18,7 @@ export function findElement<TagName extends keyof HTMLElementTagNameMap>(
|
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Find the first element that matches the selector
|
|
21
|
+
*
|
|
19
22
|
* @param selector Selector to find element for
|
|
20
23
|
* @param context Context to search within _(defaults to `document`)_
|
|
21
24
|
* @returns Found element or `null`
|
|
@@ -120,6 +123,7 @@ function findElementOrElementsFromNodes(
|
|
|
120
123
|
|
|
121
124
|
/**
|
|
122
125
|
* Find elements that match the selector
|
|
126
|
+
*
|
|
123
127
|
* @param tagName tagName to find elements for
|
|
124
128
|
* @param context Context to search within _(defaults to `document`)_
|
|
125
129
|
* @returns Found elements
|
|
@@ -131,6 +135,7 @@ export function findElements(
|
|
|
131
135
|
|
|
132
136
|
/**
|
|
133
137
|
* Find elements that match the selector
|
|
138
|
+
*
|
|
134
139
|
* @param selector Selector to find elements for
|
|
135
140
|
* @param context Context to search within _(defaults to `document`)_
|
|
136
141
|
* @returns Found elements
|
|
@@ -141,11 +146,65 @@ export function findElements(selector: Selector, context?: Selector | null): Ele
|
|
|
141
146
|
return findElementOrElements(selector, context, false) as never;
|
|
142
147
|
}
|
|
143
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Get elements from an event position
|
|
151
|
+
*
|
|
152
|
+
* @param position Event position
|
|
153
|
+
* @returns Elements at the event position
|
|
154
|
+
*/
|
|
155
|
+
export function getElementFromPosition(position: EventPosition): Element[] {
|
|
156
|
+
if (!isEventPosition(position) || typeof document.elementFromPoint !== 'function') {
|
|
157
|
+
return [];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const {x, y} = position;
|
|
161
|
+
|
|
162
|
+
const elements: Element[] = [];
|
|
163
|
+
const events: {value: string; priority: string}[] = [];
|
|
164
|
+
|
|
165
|
+
let current: Element | null;
|
|
166
|
+
|
|
167
|
+
while (true) {
|
|
168
|
+
current = document.elementFromPoint(x, y);
|
|
169
|
+
|
|
170
|
+
if (current == null || elements.indexOf(current) !== -1) {
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!(current instanceof HTMLElement)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
elements.push(current);
|
|
179
|
+
|
|
180
|
+
events.push({
|
|
181
|
+
value: current.style.getPropertyValue(STYLE_POINTER_EVENTS),
|
|
182
|
+
priority: current.style.getPropertyPriority(STYLE_POINTER_EVENTS),
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
current.style.setProperty(STYLE_POINTER_EVENTS, STYLE_NONE, STYLE_IMPORTANT);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const {length} = elements;
|
|
189
|
+
|
|
190
|
+
for (let index = 0; index < length; index += 1) {
|
|
191
|
+
const element = elements[index];
|
|
192
|
+
const event = events[index];
|
|
193
|
+
|
|
194
|
+
if (element instanceof HTMLElement) {
|
|
195
|
+
element.style.setProperty(STYLE_POINTER_EVENTS, event.value ?? '', event.priority);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return elements;
|
|
200
|
+
}
|
|
201
|
+
|
|
144
202
|
/**
|
|
145
203
|
* Get the most specific element under the pointer
|
|
146
204
|
*
|
|
147
205
|
* - Ignores elements with `pointer-events: none` and `visibility: hidden`
|
|
148
206
|
* - _(If `skipIgnore` is `true`, no elements are ignored)_
|
|
207
|
+
*
|
|
149
208
|
* @param skipIgnore Skip ignored elements?
|
|
150
209
|
* @returns Found element or `null`
|
|
151
210
|
*/
|
|
@@ -192,8 +251,12 @@ const QUERY_SELECTOR_SINGLE = 'querySelector';
|
|
|
192
251
|
|
|
193
252
|
const STYLE_HIDDEN = 'hidden';
|
|
194
253
|
|
|
254
|
+
const STYLE_IMPORTANT = 'important';
|
|
255
|
+
|
|
195
256
|
const STYLE_NONE = 'none';
|
|
196
257
|
|
|
258
|
+
const STYLE_POINTER_EVENTS = 'pointer-events';
|
|
259
|
+
|
|
197
260
|
const SUFFIX_HOVER = ':hover';
|
|
198
261
|
|
|
199
262
|
const TAG_HEAD = 'HEAD';
|
package/src/find/relative.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* - If no match is found, `null` is returned
|
|
7
7
|
* - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
|
|
8
|
+
*
|
|
8
9
|
* @param origin Origin to start from
|
|
9
10
|
* @param tagName Tag name to match
|
|
10
11
|
* @returns Found ancestor or `null`
|
|
@@ -19,6 +20,7 @@ export function findAncestor<TagName extends keyof HTMLElementTagNameMap>(
|
|
|
19
20
|
*
|
|
20
21
|
* - If no match is found, `null` is returned
|
|
21
22
|
* - _(If you want to search upwards, downwards, and sideways, use {@link findRelatives})_
|
|
23
|
+
*
|
|
22
24
|
* @param origin Origin to start from
|
|
23
25
|
* @param selector Selector to match
|
|
24
26
|
* @returns Found ancestor or `null`
|
|
@@ -71,6 +73,7 @@ export function findAncestor(
|
|
|
71
73
|
* Finds the closest elements to the origin element that matches the tag name
|
|
72
74
|
*
|
|
73
75
|
* Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
|
|
76
|
+
*
|
|
74
77
|
* @param origin Element to start from
|
|
75
78
|
* @param tagName Tag name to match
|
|
76
79
|
* @param context Context to search within
|
|
@@ -86,6 +89,7 @@ export function findRelatives<TagName extends keyof HTMLElementTagNameMap>(
|
|
|
86
89
|
* Finds the closest elements to the origin element that matches the selector
|
|
87
90
|
*
|
|
88
91
|
* Traverses up, down, and sideways in the _DOM_-tree. _(If you only want to traverse up, use {@link findAncestor})_
|
|
92
|
+
*
|
|
89
93
|
* @param origin Element to start from
|
|
90
94
|
* @param selector Selector to match
|
|
91
95
|
* @param context Context to search within
|
|
@@ -144,6 +148,7 @@ export function findRelatives(
|
|
|
144
148
|
|
|
145
149
|
/**
|
|
146
150
|
* Get the distance between two elements _(i.e., the amount of nodes of between them)_
|
|
151
|
+
*
|
|
147
152
|
* @param origin Origin element
|
|
148
153
|
* @param target Target element
|
|
149
154
|
* @returns Distance between elements, or `-1` if distance cannot be calculated
|
package/src/focusable.ts
CHANGED
|
@@ -17,6 +17,7 @@ type InertElement = Element & {inert: boolean};
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Get a list of focusable elements within a parent element
|
|
20
|
+
*
|
|
20
21
|
* @param parent Parent element
|
|
21
22
|
* @returns Focusable elements
|
|
22
23
|
*/
|
|
@@ -33,6 +34,7 @@ function getItem(element: Element, tabbable: boolean): ElementWithTabIndex {
|
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Get a list of tabbable elements within a parent element
|
|
37
|
+
*
|
|
36
38
|
* @param parent Parent element
|
|
37
39
|
* @returns Tabbable elements
|
|
38
40
|
*/
|
|
@@ -137,6 +139,7 @@ function isEditable(element: Element): boolean {
|
|
|
137
139
|
|
|
138
140
|
/**
|
|
139
141
|
* Is the element focusable?
|
|
142
|
+
*
|
|
140
143
|
* @param element Element to check
|
|
141
144
|
* @returns `true` if focusable, otherwise `false`
|
|
142
145
|
*/
|
|
@@ -221,6 +224,7 @@ function isSummarised(item: ElementWithTabIndex): boolean {
|
|
|
221
224
|
|
|
222
225
|
/**
|
|
223
226
|
* Is the element tabbable?
|
|
227
|
+
*
|
|
224
228
|
* @param element Element to check
|
|
225
229
|
* @returns `true` if tabbable, otherwise `false`
|
|
226
230
|
*/
|
package/src/html/index.ts
CHANGED
|
@@ -5,9 +5,9 @@ import {sanitizeNodes} from './sanitize';
|
|
|
5
5
|
|
|
6
6
|
// #region Types
|
|
7
7
|
|
|
8
|
-
type HtmlOptions = {
|
|
8
|
+
export type HtmlOptions = {
|
|
9
9
|
/**
|
|
10
|
-
* Cache template element for the
|
|
10
|
+
* Cache template element for the _HTML_ string? _(defaults to `true`)_
|
|
11
11
|
*/
|
|
12
12
|
cache?: boolean;
|
|
13
13
|
};
|
|
@@ -175,13 +175,15 @@ function hasNodes(value: unknown): value is HTMLCollection | NodeList | Node[] {
|
|
|
175
175
|
|
|
176
176
|
/**
|
|
177
177
|
* Create nodes from a template string
|
|
178
|
+
*
|
|
178
179
|
* @returns Created nodes
|
|
179
180
|
*/
|
|
180
181
|
export function html(strings: TemplateStringsArray, ...values: unknown[]): Node[];
|
|
181
182
|
|
|
182
183
|
/**
|
|
183
|
-
* Create nodes from an
|
|
184
|
-
*
|
|
184
|
+
* Create nodes from an _HTML_ string or a template element
|
|
185
|
+
*
|
|
186
|
+
* @param value _HTML_ string or ID for a template element
|
|
185
187
|
* @param options Options for creating nodes
|
|
186
188
|
* @returns Created nodes
|
|
187
189
|
*/
|
|
@@ -189,6 +191,7 @@ export function html(value: string, options?: HtmlOptions): Node[];
|
|
|
189
191
|
|
|
190
192
|
/**
|
|
191
193
|
* Create nodes from a template element
|
|
194
|
+
*
|
|
192
195
|
* @param template Template element
|
|
193
196
|
* @param options Options for creating nodes
|
|
194
197
|
* @returns Created nodes
|
|
@@ -213,8 +216,9 @@ html.clear = (): void => {
|
|
|
213
216
|
};
|
|
214
217
|
|
|
215
218
|
/**
|
|
216
|
-
* Remove cached template element for an
|
|
217
|
-
*
|
|
219
|
+
* Remove cached template element for an _HTML_ string or _ID_
|
|
220
|
+
*
|
|
221
|
+
* @param template _HTML_ string or ID for a template element
|
|
218
222
|
*/
|
|
219
223
|
html.remove = (template: string): void => {
|
|
220
224
|
templates.delete(template);
|
|
@@ -249,6 +253,7 @@ function replaceComments(origin: NodeList | Node[], replacements: Node[]): void
|
|
|
249
253
|
|
|
250
254
|
/**
|
|
251
255
|
* Sanitize one or more nodes, recursively
|
|
256
|
+
*
|
|
252
257
|
* @param value Node or nodes to sanitize
|
|
253
258
|
* @param options Sanitization options
|
|
254
259
|
* @returns Sanitized nodes
|
|
@@ -279,7 +284,4 @@ const templates = new SizedMap<string, HTMLTemplateElement>(128);
|
|
|
279
284
|
|
|
280
285
|
let parser: DOMParser;
|
|
281
286
|
|
|
282
|
-
// @ts-expect-error debug
|
|
283
|
-
window.templates = templates;
|
|
284
|
-
|
|
285
287
|
// #endregion
|
package/src/index.ts
CHANGED
|
@@ -142,9 +142,11 @@ export function updateAttribute(
|
|
|
142
142
|
element,
|
|
143
143
|
name,
|
|
144
144
|
isBoolean ? (next ? '' : null) : value,
|
|
145
|
-
//
|
|
145
|
+
// Using `.call` in `updateElementValue`
|
|
146
|
+
// oxlint-disable-next-line typescript/unbound-method
|
|
146
147
|
element.setAttribute,
|
|
147
|
-
//
|
|
148
|
+
// Using `.call` in `updateElementValue`
|
|
149
|
+
// oxlint-disable-next-line typescript/unbound-method
|
|
148
150
|
element.removeAttribute,
|
|
149
151
|
isBoolean,
|
|
150
152
|
false,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import {getString} from '@oscarpalmer/atoms/string';
|
|
3
3
|
import {kebabCase} from '@oscarpalmer/atoms/string/case';
|
|
4
|
-
import {isHTMLOrSVGElement} from '../is';
|
|
5
4
|
import {isAttribute} from './attribute';
|
|
6
5
|
|
|
7
6
|
// #region Functions
|
|
@@ -26,7 +25,7 @@ export function setElementValue(
|
|
|
26
25
|
callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void,
|
|
27
26
|
style?: boolean,
|
|
28
27
|
): void {
|
|
29
|
-
if (!
|
|
28
|
+
if (!(element instanceof Element)) {
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
32
31
|
|
|
@@ -45,7 +44,7 @@ export function setElementValues(
|
|
|
45
44
|
callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void,
|
|
46
45
|
style?: boolean,
|
|
47
46
|
): void {
|
|
48
|
-
if (!
|
|
47
|
+
if (!(element instanceof Element)) {
|
|
49
48
|
return;
|
|
50
49
|
}
|
|
51
50
|
|