@oscarpalmer/toretto 0.32.0 → 0.34.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/attribute/index.js +2 -2
- package/dist/attribute/set.js +7 -12
- package/dist/data.js +2 -2
- package/dist/index.js +1 -1
- package/dist/internal/attribute.js +29 -36
- package/dist/internal/element-value.js +26 -13
- package/dist/style.js +3 -3
- package/dist/toretto.full.js +258 -131
- package/package.json +7 -7
- package/src/attribute/set.ts +52 -56
- package/src/data.ts +2 -1
- package/src/index.ts +1 -1
- package/src/internal/attribute.ts +51 -55
- package/src/internal/element-value.ts +43 -13
- package/src/models.ts +2 -7
- package/src/style.ts +3 -2
- package/types/attribute/set.d.ts +19 -37
- package/types/index.d.ts +1 -1
- package/types/internal/attribute.d.ts +3 -4
- package/types/internal/element-value.d.ts +3 -3
- package/types/models.d.ts +2 -6
package/src/index.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type {PlainObject} from '@oscarpalmer/atoms';
|
|
2
2
|
import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {isHTMLOrSVGElement} from './is';
|
|
3
|
+
import type {Attribute} from '../models';
|
|
4
|
+
import {updateElementValue} from './element-value';
|
|
6
5
|
|
|
7
6
|
function badAttributeHandler(name?: string, value?: string): boolean {
|
|
8
|
-
if (name
|
|
7
|
+
if (typeof name !== 'string' || name.trim().length === 0 || typeof value !== 'string') {
|
|
9
8
|
return true;
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -28,17 +27,19 @@ function badAttributeHandler(name?: string, value?: string): boolean {
|
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
function booleanAttributeHandler(name?: string, value?: string): boolean {
|
|
31
|
-
if (name
|
|
30
|
+
if (typeof name !== 'string' || name.trim().length === 0 || typeof value !== 'string') {
|
|
32
31
|
return true;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
const normalizedName = name.toLowerCase();
|
|
35
|
+
|
|
36
|
+
if (!booleanAttributesSet.has(normalizedName)) {
|
|
36
37
|
return false;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
const normalized = value.toLowerCase()
|
|
40
|
+
const normalized = value.toLowerCase();
|
|
40
41
|
|
|
41
|
-
return !(normalized.length === 0 || normalized ===
|
|
42
|
+
return !(normalized.length === 0 || normalized === normalizedName);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
function decodeAttribute(value: string): string {
|
|
@@ -73,12 +74,12 @@ function handleAttribute(
|
|
|
73
74
|
return callback(name, value?.replace(EXPRESSION_WHITESPACE, ''));
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
function isAttribute(value: unknown): value is Attr | Attribute {
|
|
77
|
+
export function isAttribute(value: unknown): value is Attr | Attribute {
|
|
77
78
|
return (
|
|
78
79
|
value instanceof Attr ||
|
|
79
80
|
(isPlainObject(value) &&
|
|
80
81
|
typeof (value as PlainObject).name === 'string' &&
|
|
81
|
-
|
|
82
|
+
'value' in (value as PlainObject))
|
|
82
83
|
);
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -117,67 +118,53 @@ export function _isInvalidBooleanAttribute(
|
|
|
117
118
|
return handleAttribute(booleanAttributeHandler, decode, first, second);
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
export function isProperty(value: unknown): value is Property {
|
|
121
|
-
return isPlainObject(value) && typeof (value as PlainObject).name === 'string';
|
|
122
|
-
}
|
|
123
|
-
|
|
124
121
|
function isValidSourceAttribute(name: string, value: string): boolean {
|
|
125
122
|
return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
|
|
126
123
|
}
|
|
127
124
|
|
|
128
|
-
function updateAttribute(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
125
|
+
export function updateAttribute(
|
|
126
|
+
element: Element,
|
|
127
|
+
name: string,
|
|
128
|
+
value: unknown,
|
|
129
|
+
dispatch?: unknown,
|
|
130
|
+
): void {
|
|
131
|
+
const normalizedName = name.toLowerCase();
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
element.removeAttribute(name);
|
|
137
|
-
} else {
|
|
138
|
-
element.setAttribute(name, isBoolean ? '' : getString(value));
|
|
139
|
-
}
|
|
140
|
-
}
|
|
133
|
+
const isBoolean = booleanAttributesSet.has(normalizedName);
|
|
141
134
|
|
|
142
|
-
|
|
143
|
-
|
|
135
|
+
const next = isBoolean
|
|
136
|
+
? value === true ||
|
|
137
|
+
(typeof value === 'string' && (value === '' || value.toLowerCase() === normalizedName))
|
|
138
|
+
: value == null
|
|
139
|
+
? ''
|
|
140
|
+
: value;
|
|
144
141
|
|
|
145
|
-
(
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function updateValue(element: Element, first: unknown, second: unknown): void {
|
|
150
|
-
if (!isHTMLOrSVGElement(element)) {
|
|
151
|
-
return;
|
|
142
|
+
if (name in element) {
|
|
143
|
+
updateProperty(element, normalizedName, next, dispatch);
|
|
152
144
|
}
|
|
153
145
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
146
|
+
updateElementValue(
|
|
147
|
+
element,
|
|
148
|
+
name,
|
|
149
|
+
isBoolean ? (next ? '' : null) : value,
|
|
150
|
+
element.setAttribute,
|
|
151
|
+
element.removeAttribute,
|
|
152
|
+
isBoolean,
|
|
153
|
+
false,
|
|
154
|
+
);
|
|
159
155
|
}
|
|
160
156
|
|
|
161
|
-
|
|
162
|
-
element
|
|
163
|
-
values: Attribute<unknown>[] | Record<string, unknown>,
|
|
164
|
-
): void {
|
|
165
|
-
if (!isHTMLOrSVGElement(element)) {
|
|
157
|
+
function updateProperty(element: Element, name: string, value: unknown, dispatch?: unknown): void {
|
|
158
|
+
if (Object.is((element as unknown as PlainObject)[name], value)) {
|
|
166
159
|
return;
|
|
167
160
|
}
|
|
168
161
|
|
|
169
|
-
|
|
170
|
-
const entries = Object.entries(values);
|
|
171
|
-
const {length} = entries;
|
|
162
|
+
(element as unknown as PlainObject)[name] = value;
|
|
172
163
|
|
|
173
|
-
|
|
174
|
-
const entry = entries[index];
|
|
164
|
+
const event = dispatch !== false && elementEvents[element.tagName]?.[name];
|
|
175
165
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
} else {
|
|
179
|
-
updateAttribute(element, entry[0], entry[1]);
|
|
180
|
-
}
|
|
166
|
+
if (typeof event === 'string') {
|
|
167
|
+
element.dispatchEvent(new Event(event, {bubbles: true}));
|
|
181
168
|
}
|
|
182
169
|
}
|
|
183
170
|
|
|
@@ -201,6 +188,8 @@ const EXPRESSION_URI_VALUE =
|
|
|
201
188
|
// oxlint-disable-next-line no-control-regex
|
|
202
189
|
const EXPRESSION_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
|
|
203
190
|
|
|
191
|
+
//
|
|
192
|
+
|
|
204
193
|
/**
|
|
205
194
|
* List of boolean attributes
|
|
206
195
|
*/
|
|
@@ -233,6 +222,13 @@ export const booleanAttributes: readonly string[] = Object.freeze([
|
|
|
233
222
|
|
|
234
223
|
const booleanAttributesSet = new Set(booleanAttributes);
|
|
235
224
|
|
|
225
|
+
const elementEvents: Record<string, Record<string, string>> = {
|
|
226
|
+
DETAILS: {open: 'toggle'},
|
|
227
|
+
INPUT: {checked: 'change', value: 'input'},
|
|
228
|
+
SELECT: {value: 'change'},
|
|
229
|
+
TEXTAREA: {value: 'input'},
|
|
230
|
+
};
|
|
231
|
+
|
|
236
232
|
const formElement = document.createElement('form');
|
|
237
233
|
|
|
238
234
|
let textArea: HTMLTextAreaElement;
|
|
@@ -1,28 +1,57 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {isNullableOrWhitespace, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
1
|
+
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
3
2
|
import {isHTMLOrSVGElement} from '../is';
|
|
3
|
+
import {isAttribute} from './attribute';
|
|
4
4
|
|
|
5
|
-
export function
|
|
5
|
+
export function setElementValue(
|
|
6
6
|
element: Element,
|
|
7
|
-
first:
|
|
7
|
+
first: unknown,
|
|
8
8
|
second: unknown,
|
|
9
|
+
third: unknown,
|
|
9
10
|
callback: (element: Element, key: string, value: unknown) => void,
|
|
10
11
|
): void {
|
|
11
12
|
if (!isHTMLOrSVGElement(element)) {
|
|
12
13
|
return;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
if (typeof first === 'string') {
|
|
17
|
+
setElementValues(element, first, second, third, callback);
|
|
18
|
+
} else if (isAttribute(first)) {
|
|
19
|
+
setElementValues(element, first.name, first.value, third, callback);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function setElementValues(
|
|
24
|
+
element: Element,
|
|
25
|
+
first: unknown,
|
|
26
|
+
second: unknown,
|
|
27
|
+
third: unknown,
|
|
28
|
+
callback: (element: Element, key: string, value: unknown, dispatch?: unknown) => void,
|
|
29
|
+
): void {
|
|
30
|
+
if (!isHTMLOrSVGElement(element)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (typeof first === 'string') {
|
|
35
|
+
callback(element, first, second, third);
|
|
36
|
+
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const isArray = Array.isArray(first);
|
|
41
|
+
|
|
42
|
+
if (!isArray && !(typeof first === 'object' && first !== null)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({name, value}));
|
|
47
|
+
const {length} = entries;
|
|
18
48
|
|
|
19
|
-
|
|
20
|
-
|
|
49
|
+
for (let index = 0; index < length; index += 1) {
|
|
50
|
+
const entry = entries[index];
|
|
21
51
|
|
|
22
|
-
|
|
52
|
+
if (typeof entry === 'object' && typeof entry?.name === 'string') {
|
|
53
|
+
callback(element, entry.name, entry.value, third);
|
|
23
54
|
}
|
|
24
|
-
} else if (typeof first === 'string') {
|
|
25
|
-
callback(element, first, second);
|
|
26
55
|
}
|
|
27
56
|
}
|
|
28
57
|
|
|
@@ -32,9 +61,10 @@ export function updateElementValue(
|
|
|
32
61
|
value: unknown,
|
|
33
62
|
set: (key: string, value: string) => void,
|
|
34
63
|
remove: (key: string) => void,
|
|
64
|
+
isBoolean: boolean,
|
|
35
65
|
json: boolean,
|
|
36
66
|
): void {
|
|
37
|
-
if (isNullableOrWhitespace(value)) {
|
|
67
|
+
if (isBoolean ? value == null : isNullableOrWhitespace(value)) {
|
|
38
68
|
remove.call(element, key);
|
|
39
69
|
} else {
|
|
40
70
|
set.call(element, key, json ? JSON.stringify(value) : String(value));
|
package/src/models.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Attribute for an element
|
|
3
3
|
*/
|
|
4
|
-
export type Attribute
|
|
4
|
+
export type Attribute = {
|
|
5
5
|
name: string;
|
|
6
|
-
value:
|
|
6
|
+
value: unknown;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -19,11 +19,6 @@ export type EventPosition = {
|
|
|
19
19
|
y: number;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
/**
|
|
23
|
-
* Property for an element
|
|
24
|
-
*/
|
|
25
|
-
export type Property = Attribute<unknown>;
|
|
26
|
-
|
|
27
22
|
/**
|
|
28
23
|
* Event listener that can be removed
|
|
29
24
|
*/
|
package/src/style.ts
CHANGED
|
@@ -97,7 +97,7 @@ export function setStyle(
|
|
|
97
97
|
property: keyof CSSStyleDeclaration,
|
|
98
98
|
value?: string,
|
|
99
99
|
): void {
|
|
100
|
-
setElementValues(element, property as string, value, updateStyleProperty);
|
|
100
|
+
setElementValues(element, property as string, value, null, updateStyleProperty);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
/**
|
|
@@ -106,7 +106,7 @@ export function setStyle(
|
|
|
106
106
|
* @param styles Styles to set
|
|
107
107
|
*/
|
|
108
108
|
export function setStyles(element: Element, styles: Partial<CSSStyleDeclaration>): void {
|
|
109
|
-
setElementValues(element, styles as never, null, updateStyleProperty);
|
|
109
|
+
setElementValues(element, styles as never, null, null, updateStyleProperty);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
/**
|
|
@@ -169,6 +169,7 @@ function updateStyleProperty(element: Element, key: string, value: unknown): voi
|
|
|
169
169
|
(this as HTMLElement).style[property as never] = '';
|
|
170
170
|
},
|
|
171
171
|
false,
|
|
172
|
+
false,
|
|
172
173
|
);
|
|
173
174
|
}
|
|
174
175
|
|
package/types/attribute/set.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import type { Attribute
|
|
1
|
+
import type { Attribute } from '../models';
|
|
2
|
+
type DispatchedAttribute = 'checked' | 'open' | 'value';
|
|
3
|
+
/**
|
|
4
|
+
* Set an attribute on an element
|
|
5
|
+
*
|
|
6
|
+
* _(Or remove it, if value is `null` or `undefined`)_
|
|
7
|
+
* @param element Element for attribute
|
|
8
|
+
* @param name Attribute name
|
|
9
|
+
* @param value Attribute value
|
|
10
|
+
* @param dispatch Dispatch event for attribute? _(defaults to `true`)_
|
|
11
|
+
*/
|
|
12
|
+
export declare function setAttribute<Name extends DispatchedAttribute>(element: Element, name: Name, value?: unknown, dispatch?: boolean): void;
|
|
2
13
|
/**
|
|
3
14
|
* Set an attribute on an element
|
|
4
15
|
*
|
|
@@ -14,54 +25,25 @@ export declare function setAttribute(element: Element, name: string, value?: unk
|
|
|
14
25
|
* _(Or remove it, if value is `null` or `undefined`)_
|
|
15
26
|
* @param element Element for attribute
|
|
16
27
|
* @param attribute Attribute to set
|
|
28
|
+
* @param dispatch Dispatch event for attribute? _(defaults to `true`)_
|
|
17
29
|
*/
|
|
18
|
-
export declare function setAttribute(element: Element, attribute: Attr | Attribute): void;
|
|
30
|
+
export declare function setAttribute(element: Element, attribute: Attr | Attribute, dispatch?: boolean): void;
|
|
19
31
|
/**
|
|
20
32
|
* Set one or more attributes on an element
|
|
21
33
|
*
|
|
22
34
|
* _(Or remove them, if their value is `null` or `undefined`)_
|
|
23
35
|
* @param element Element for attributes
|
|
24
36
|
* @param attributes Attributes to set
|
|
37
|
+
* @param dispatch Dispatch events for relevant attributes? _(defaults to `true`)_
|
|
25
38
|
*/
|
|
26
|
-
export declare function setAttributes(element: Element, attributes: Array<Attr | Attribute
|
|
39
|
+
export declare function setAttributes(element: Element, attributes: Array<Attr | Attribute>, dispatch?: boolean): void;
|
|
27
40
|
/**
|
|
28
41
|
* Set one or more attributes on an element
|
|
29
42
|
*
|
|
30
43
|
* _(Or remove them, if their value is `null` or `undefined`)_
|
|
31
44
|
* @param element Element for attributes
|
|
32
45
|
* @param attributes Attributes to set
|
|
46
|
+
* @param dispatch Dispatch events for relevant attributes? _(defaults to `true`)_
|
|
33
47
|
*/
|
|
34
|
-
export declare function setAttributes(element: Element, attributes: Record<string, unknown
|
|
35
|
-
|
|
36
|
-
* Set a property on an element
|
|
37
|
-
*
|
|
38
|
-
* _(Or remove it, if value is not an empty string or does not match the name)_
|
|
39
|
-
* @param element Element for property
|
|
40
|
-
* @param name Property name
|
|
41
|
-
* @param value Property value
|
|
42
|
-
*/
|
|
43
|
-
export declare function setProperty(element: Element, name: string, value: boolean | string): void;
|
|
44
|
-
/**
|
|
45
|
-
* Set a property on an element
|
|
46
|
-
*
|
|
47
|
-
* _(Or remove it, if value is not an empty string or does not match the name)_
|
|
48
|
-
* @param element Element for property
|
|
49
|
-
* @param property Property to set
|
|
50
|
-
*/
|
|
51
|
-
export declare function setProperty(element: Element, property: Property): void;
|
|
52
|
-
/**
|
|
53
|
-
* Set one or more properties on an element
|
|
54
|
-
*
|
|
55
|
-
* _(Or remove them, if their value is not an empty string or does not match the name)_
|
|
56
|
-
* @param element Element for properties
|
|
57
|
-
* @param properties Properties to set
|
|
58
|
-
*/
|
|
59
|
-
export declare function setProperties(element: Element, properties: Property[]): void;
|
|
60
|
-
/**
|
|
61
|
-
* Set one or more properties on an element
|
|
62
|
-
*
|
|
63
|
-
* _(Or remove them, if their value is not an empty string or does not match the name)_
|
|
64
|
-
* @param element Element for properties
|
|
65
|
-
* @param properties Properties to set
|
|
66
|
-
*/
|
|
67
|
-
export declare function setProperties(element: Element, properties: Record<string, unknown>): void;
|
|
48
|
+
export declare function setAttributes(element: Element, attributes: Record<string, unknown>, dispatch?: boolean): void;
|
|
49
|
+
export {};
|
package/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import supportsTouch from './touch';
|
|
2
|
-
export { isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, } from './attribute';
|
|
2
|
+
export { isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, } from './attribute/index';
|
|
3
3
|
export * from './data';
|
|
4
4
|
export * from './event/index';
|
|
5
5
|
export * from './find/index';
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { Attribute
|
|
1
|
+
import type { Attribute } from '../models';
|
|
2
|
+
export declare function isAttribute(value: unknown): value is Attr | Attribute;
|
|
2
3
|
export declare function _isBadAttribute(first: unknown, second: unknown, decode: boolean): boolean;
|
|
3
4
|
export declare function _isBooleanAttribute(first: unknown, decode: boolean): boolean;
|
|
4
5
|
export declare function _isEmptyNonBooleanAttribute(first: unknown, second: unknown, decode: boolean): boolean;
|
|
5
6
|
export declare function _isInvalidBooleanAttribute(first: unknown, second: unknown, decode: boolean): boolean;
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function updateValue(element: Element, first: unknown, second: unknown): void;
|
|
8
|
-
export declare function updateValues(element: Element, values: Attribute<unknown>[] | Record<string, unknown>): void;
|
|
7
|
+
export declare function updateAttribute(element: Element, name: string, value: unknown, dispatch?: unknown): void;
|
|
9
8
|
/**
|
|
10
9
|
* List of boolean attributes
|
|
11
10
|
*/
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function setElementValues(element: Element, first:
|
|
3
|
-
export declare function updateElementValue(element: Element, key: string, value: unknown, set: (key: string, value: string) => void, remove: (key: string) => void, json: boolean): void;
|
|
1
|
+
export declare function setElementValue(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown) => void): void;
|
|
2
|
+
export declare function setElementValues(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch?: unknown) => void): void;
|
|
3
|
+
export declare function updateElementValue(element: Element, key: string, value: unknown, set: (key: string, value: string) => void, remove: (key: string) => void, isBoolean: boolean, json: boolean): void;
|
package/types/models.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Attribute for an element
|
|
3
3
|
*/
|
|
4
|
-
export type Attribute
|
|
4
|
+
export type Attribute = {
|
|
5
5
|
name: string;
|
|
6
|
-
value:
|
|
6
|
+
value: unknown;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Event listener for custom events
|
|
@@ -16,10 +16,6 @@ export type EventPosition = {
|
|
|
16
16
|
x: number;
|
|
17
17
|
y: number;
|
|
18
18
|
};
|
|
19
|
-
/**
|
|
20
|
-
* Property for an element
|
|
21
|
-
*/
|
|
22
|
-
export type Property = Attribute<unknown>;
|
|
23
19
|
/**
|
|
24
20
|
* Event listener that can be removed
|
|
25
21
|
*/
|