@oscarpalmer/toretto 0.40.0 → 0.42.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/{get.d.mts → get.attribute.d.mts} +3 -2
- package/dist/attribute/{get.mjs → get.attribute.mjs} +4 -3
- package/dist/attribute/index.d.mts +3 -16
- package/dist/attribute/index.mjs +4 -7
- package/dist/attribute/{set.d.mts → set.attribute.d.mts} +4 -4
- package/dist/attribute/{set.mjs → set.attribute.mjs} +2 -2
- package/dist/create.d.mts +25 -0
- package/dist/create.mjs +17 -0
- package/dist/data.d.mts +1 -1
- package/dist/data.mjs +7 -7
- package/dist/event/delegation.mjs +8 -1
- package/dist/html/index.d.mts +23 -26
- package/dist/html/index.mjs +85 -18
- package/dist/html/sanitize.mjs +6 -5
- package/dist/index.d.mts +114 -53
- package/dist/index.mjs +553 -561
- package/dist/internal/attribute.d.mts +4 -3
- package/dist/internal/attribute.mjs +13 -23
- package/dist/internal/element-value.d.mts +2 -2
- package/dist/internal/element-value.mjs +4 -2
- package/dist/internal/get-value.mjs +1 -1
- package/dist/internal/property.d.mts +4 -0
- package/dist/internal/property.mjs +21 -0
- package/dist/property/get.property.d.mts +20 -0
- package/dist/property/get.property.mjs +35 -0
- package/dist/property/index.d.mts +3 -0
- package/dist/property/index.mjs +3 -0
- package/dist/property/set.property.d.mts +32 -0
- package/dist/property/set.property.mjs +34 -0
- package/dist/style.d.mts +12 -7
- package/dist/style.mjs +14 -18
- package/package.json +12 -5
- package/src/attribute/{get.ts → get.attribute.ts} +14 -3
- package/src/attribute/index.ts +10 -22
- package/src/attribute/{set.ts → set.attribute.ts} +9 -5
- package/src/create.ts +81 -0
- package/src/data.ts +17 -9
- package/src/event/delegation.ts +24 -3
- package/src/event/index.ts +9 -3
- package/src/find/index.ts +12 -4
- package/src/find/relative.ts +4 -0
- package/src/focusable.ts +10 -2
- package/src/html/index.ts +166 -58
- package/src/html/sanitize.ts +14 -11
- package/src/index.ts +2 -1
- package/src/internal/attribute.ts +23 -42
- package/src/internal/element-value.ts +11 -4
- package/src/internal/get-value.ts +8 -0
- package/src/internal/is.ts +4 -0
- package/src/internal/property.ts +42 -0
- package/src/is.ts +10 -2
- package/src/property/get.property.ts +73 -0
- package/src/property/index.ts +2 -0
- package/src/property/set.property.ts +102 -0
- package/src/style.ts +52 -27
- package/src/touch.ts +14 -2
|
@@ -4,12 +4,13 @@ import { Attribute } from "../models.mjs";
|
|
|
4
4
|
declare function isAttribute(value: unknown): value is Attr | Attribute;
|
|
5
5
|
declare function _isBadAttribute(first: unknown, second: unknown, decode: boolean): boolean;
|
|
6
6
|
declare function _isBooleanAttribute(first: unknown, decode: boolean): boolean;
|
|
7
|
-
declare function _isEmptyNonBooleanAttribute(first: unknown, second: unknown, decode: boolean): boolean;
|
|
8
7
|
declare function _isInvalidBooleanAttribute(first: unknown, second: unknown, decode: boolean): boolean;
|
|
9
|
-
declare function updateAttribute(element: Element, name: string, value: unknown, dispatch
|
|
8
|
+
declare function updateAttribute(element: Element, name: string, value: unknown, dispatch: boolean): void;
|
|
10
9
|
/**
|
|
11
10
|
* List of boolean attributes
|
|
12
11
|
*/
|
|
13
12
|
declare const booleanAttributes: readonly string[];
|
|
13
|
+
declare const booleanAttributesSet: Set<string>;
|
|
14
|
+
declare const dispatchedAttributes: Set<string>;
|
|
14
15
|
//#endregion
|
|
15
|
-
export { _isBadAttribute, _isBooleanAttribute,
|
|
16
|
+
export { _isBadAttribute, _isBooleanAttribute, _isInvalidBooleanAttribute, booleanAttributes, booleanAttributesSet, dispatchedAttributes, isAttribute, updateAttribute };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { updateElementValue } from "./element-value.mjs";
|
|
2
|
+
import { updateProperty } from "./property.mjs";
|
|
2
3
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
4
|
+
import { kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
3
5
|
//#region src/internal/attribute.ts
|
|
4
6
|
function badAttributeHandler(name, value) {
|
|
5
7
|
if (typeof name !== "string" || name.trim().length === 0 || typeof value !== "string") return true;
|
|
@@ -29,6 +31,7 @@ function handleAttribute(callback, decode, first, second) {
|
|
|
29
31
|
name = first;
|
|
30
32
|
value = second;
|
|
31
33
|
}
|
|
34
|
+
if (name != null) name = kebabCase(name);
|
|
32
35
|
if (decode && value != null) value = decodeAttribute(value);
|
|
33
36
|
return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
|
|
34
37
|
}
|
|
@@ -41,9 +44,6 @@ function _isBadAttribute(first, second, decode) {
|
|
|
41
44
|
function _isBooleanAttribute(first, decode) {
|
|
42
45
|
return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
|
|
43
46
|
}
|
|
44
|
-
function _isEmptyNonBooleanAttribute(first, second, decode) {
|
|
45
|
-
return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
|
|
46
|
-
}
|
|
47
47
|
function _isInvalidBooleanAttribute(first, second, decode) {
|
|
48
48
|
return handleAttribute(booleanAttributeHandler, decode, first, second);
|
|
49
49
|
}
|
|
@@ -51,18 +51,12 @@ function isValidSourceAttribute(name, value) {
|
|
|
51
51
|
return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
|
|
52
52
|
}
|
|
53
53
|
function updateAttribute(element, name, value, dispatch) {
|
|
54
|
-
const
|
|
55
|
-
const isBoolean = booleanAttributesSet.has(
|
|
56
|
-
const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() ===
|
|
57
|
-
if (
|
|
54
|
+
const lowerCaseName = name.toLowerCase();
|
|
55
|
+
const isBoolean = booleanAttributesSet.has(lowerCaseName);
|
|
56
|
+
const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === lowerCaseName) : value == null ? "" : value;
|
|
57
|
+
if (isBoolean || dispatchedAttributes.has(name)) updateProperty(element, name, next, dispatch);
|
|
58
58
|
updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
|
|
59
59
|
}
|
|
60
|
-
function updateProperty(element, name, value, dispatch) {
|
|
61
|
-
if (Object.is(element[name], value)) return;
|
|
62
|
-
element[name] = value;
|
|
63
|
-
const event = dispatch !== false && elementEvents[element.tagName]?.[name];
|
|
64
|
-
if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
|
|
65
|
-
}
|
|
66
60
|
const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
|
|
67
61
|
const EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
|
|
68
62
|
const EXPRESSION_EVENT_NAME = /^on/i;
|
|
@@ -101,16 +95,12 @@ const booleanAttributes = Object.freeze([
|
|
|
101
95
|
"selected"
|
|
102
96
|
]);
|
|
103
97
|
const booleanAttributesSet = new Set(booleanAttributes);
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
},
|
|
110
|
-
SELECT: { value: "change" },
|
|
111
|
-
TEXTAREA: { value: "input" }
|
|
112
|
-
};
|
|
98
|
+
const dispatchedAttributes = new Set([
|
|
99
|
+
"checked",
|
|
100
|
+
"open",
|
|
101
|
+
"value"
|
|
102
|
+
]);
|
|
113
103
|
const formElement = document.createElement("form");
|
|
114
104
|
let textArea;
|
|
115
105
|
//#endregion
|
|
116
|
-
export { _isBadAttribute, _isBooleanAttribute,
|
|
106
|
+
export { _isBadAttribute, _isBooleanAttribute, _isInvalidBooleanAttribute, booleanAttributes, booleanAttributesSet, dispatchedAttributes, isAttribute, updateAttribute };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/internal/element-value.d.ts
|
|
2
|
-
declare function setElementValue(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown) => void): void;
|
|
3
|
-
declare function setElementValues(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch
|
|
2
|
+
declare function setElementValue(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void): void;
|
|
3
|
+
declare function setElementValues(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void): void;
|
|
4
4
|
declare function updateElementValue(element: Element, key: string, value: unknown, set: (key: string, value: string) => void, remove: (key: string) => void, isBoolean: boolean, json: boolean): void;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { setElementValue, setElementValues, updateElementValue };
|
|
@@ -2,6 +2,7 @@ import { isHTMLOrSVGElement } from "./is.mjs";
|
|
|
2
2
|
import "../is.mjs";
|
|
3
3
|
import { isAttribute } from "./attribute.mjs";
|
|
4
4
|
import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
|
|
5
|
+
import { kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
5
6
|
//#region src/internal/element-value.ts
|
|
6
7
|
function setElementValue(element, first, second, third, callback) {
|
|
7
8
|
if (!isHTMLOrSVGElement(element)) return;
|
|
@@ -10,8 +11,9 @@ function setElementValue(element, first, second, third, callback) {
|
|
|
10
11
|
}
|
|
11
12
|
function setElementValues(element, first, second, third, callback) {
|
|
12
13
|
if (!isHTMLOrSVGElement(element)) return;
|
|
14
|
+
const dispatch = third !== false;
|
|
13
15
|
if (typeof first === "string") {
|
|
14
|
-
callback(element, first, second,
|
|
16
|
+
callback(element, kebabCase(first), second, dispatch);
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
19
|
const isArray = Array.isArray(first);
|
|
@@ -23,7 +25,7 @@ function setElementValues(element, first, second, third, callback) {
|
|
|
23
25
|
const { length } = entries;
|
|
24
26
|
for (let index = 0; index < length; index += 1) {
|
|
25
27
|
const entry = entries[index];
|
|
26
|
-
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value,
|
|
28
|
+
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, kebabCase(entry.name), entry.value, dispatch);
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parse } from "@oscarpalmer/atoms/string";
|
|
2
1
|
import { camelCase, kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
2
|
+
import { parse } from "@oscarpalmer/atoms/string";
|
|
3
3
|
//#region src/internal/get-value.ts
|
|
4
4
|
function getBoolean(value, defaultValue) {
|
|
5
5
|
return typeof value === "boolean" ? value : defaultValue ?? false;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { camelCase } from "@oscarpalmer/atoms/string/case";
|
|
2
|
+
//#region src/internal/property.ts
|
|
3
|
+
function updateProperty(element, name, value, dispatch) {
|
|
4
|
+
let property = name;
|
|
5
|
+
if (!(property in element)) property = camelCase(name);
|
|
6
|
+
if (!(property in element) || Object.is(element[property], value)) return;
|
|
7
|
+
element[property] = value;
|
|
8
|
+
const event = dispatch && elementEvents[element.tagName]?.[property];
|
|
9
|
+
if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
|
|
10
|
+
}
|
|
11
|
+
const elementEvents = {
|
|
12
|
+
DETAILS: { open: "toggle" },
|
|
13
|
+
INPUT: {
|
|
14
|
+
checked: "change",
|
|
15
|
+
value: "input"
|
|
16
|
+
},
|
|
17
|
+
SELECT: { value: "change" },
|
|
18
|
+
TEXTAREA: { value: "input" }
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { updateProperty };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Primitive } from "@oscarpalmer/atoms/models";
|
|
2
|
+
|
|
3
|
+
//#region src/property/get.property.d.ts
|
|
4
|
+
type GetProperties<Target extends Element> = { [Property in keyof Target as Target[Property] extends Primitive ? Property : never]?: Target[Property] };
|
|
5
|
+
/**
|
|
6
|
+
* Get the values of one or more properties on an element
|
|
7
|
+
* @param target Target element
|
|
8
|
+
* @param properties Properties to get
|
|
9
|
+
* @returns Property values
|
|
10
|
+
*/
|
|
11
|
+
declare function getProperties<Target extends Element, Property extends keyof GetProperties<Target>>(target: Target, properties: Property[]): Pick<GetProperties<Target>, Property>;
|
|
12
|
+
/**
|
|
13
|
+
* Get the value of a property on an element
|
|
14
|
+
* @param target Target element
|
|
15
|
+
* @param property Property to get
|
|
16
|
+
* @returns Property value
|
|
17
|
+
*/
|
|
18
|
+
declare function getProperty<Target extends Element, Property extends keyof GetProperties<Target>>(target: Target, property: Property): GetProperties<Target>[Property];
|
|
19
|
+
//#endregion
|
|
20
|
+
export { getProperties, getProperty };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { isHTMLOrSVGElement } from "../internal/is.mjs";
|
|
2
|
+
import { camelCase } from "@oscarpalmer/atoms/string/case";
|
|
3
|
+
//#region src/property/get.property.ts
|
|
4
|
+
/**
|
|
5
|
+
* Get the values of one or more properties on an element
|
|
6
|
+
* @param target Target element
|
|
7
|
+
* @param properties Properties to get
|
|
8
|
+
* @returns Property values
|
|
9
|
+
*/
|
|
10
|
+
function getProperties(target, properties) {
|
|
11
|
+
const values = {};
|
|
12
|
+
if (!isHTMLOrSVGElement(target) || !Array.isArray(properties)) return values;
|
|
13
|
+
const { length } = properties;
|
|
14
|
+
for (let index = 0; index < length; index += 1) {
|
|
15
|
+
const property = properties[index];
|
|
16
|
+
if (typeof property === "string") values[property] = getPropertyValue(target, property);
|
|
17
|
+
}
|
|
18
|
+
return values;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the value of a property on an element
|
|
22
|
+
* @param target Target element
|
|
23
|
+
* @param property Property to get
|
|
24
|
+
* @returns Property value
|
|
25
|
+
*/
|
|
26
|
+
function getProperty(target, property) {
|
|
27
|
+
if (isHTMLOrSVGElement(target) && typeof property === "string") return getPropertyValue(target, property);
|
|
28
|
+
}
|
|
29
|
+
function getPropertyValue(element, property) {
|
|
30
|
+
let actual = property;
|
|
31
|
+
if (!(actual in element)) actual = camelCase(actual);
|
|
32
|
+
if (actual in element) return element[actual];
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { getProperties, getProperty };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DispatchedAttributeName } from "../attribute/set.attribute.mjs";
|
|
2
|
+
import { Primitive } from "@oscarpalmer/atoms/models";
|
|
3
|
+
|
|
4
|
+
//#region src/property/set.property.d.ts
|
|
5
|
+
type DispatchedPropertyValue<Target extends Element, Property extends DispatchedAttributeName> = Property extends keyof SetProperties<Target> ? SetProperties<Target>[Property] : never;
|
|
6
|
+
type SetProperties<Target extends Element> = { [Property in keyof Target as Target[Property] extends Primitive ? Property : never]?: Target[Property] };
|
|
7
|
+
/**
|
|
8
|
+
* Set the values of one or more properties on an element
|
|
9
|
+
*
|
|
10
|
+
* Also updates attributes for boolean/dispatchable properties, and if `dispatch` is `true`, will dispatch events for dispatchable properties
|
|
11
|
+
* @param target Target element
|
|
12
|
+
* @param properties Properties to set
|
|
13
|
+
* @param dispatch Dispatch events for properties? _(defaults to `true`)_
|
|
14
|
+
*/
|
|
15
|
+
declare function setProperties<Target extends Element>(target: Target, properties: SetProperties<Target>, dispatch?: boolean): void;
|
|
16
|
+
/**
|
|
17
|
+
* Set the value for a dispatchable property on an element
|
|
18
|
+
* @param target Target element
|
|
19
|
+
* @param property Property to set
|
|
20
|
+
* @param value Value to set
|
|
21
|
+
* @param dispatch Dispatch event for property? _(defaults to `true`)_
|
|
22
|
+
*/
|
|
23
|
+
declare function setProperty<Target extends Element, Property extends DispatchedAttributeName>(target: Target, property: Property, value: DispatchedPropertyValue<Target, Property>, dispatch?: boolean): void;
|
|
24
|
+
/**
|
|
25
|
+
* Set the value for a property on an element
|
|
26
|
+
* @param target Target element
|
|
27
|
+
* @param property Property to set
|
|
28
|
+
* @param value Value to set
|
|
29
|
+
*/
|
|
30
|
+
declare function setProperty<Target extends Element, Property extends keyof SetProperties<Target>>(target: Target, property: Property, value: SetProperties<Target>[Property]): void;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { setProperties, setProperty };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isHTMLOrSVGElement } from "../internal/is.mjs";
|
|
2
|
+
import "../is.mjs";
|
|
3
|
+
import { updateProperty } from "../internal/property.mjs";
|
|
4
|
+
import { booleanAttributesSet, dispatchedAttributes } from "../internal/attribute.mjs";
|
|
5
|
+
import { setAttribute } from "../attribute/set.attribute.mjs";
|
|
6
|
+
import "../attribute/index.mjs";
|
|
7
|
+
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
8
|
+
//#region src/property/set.property.ts
|
|
9
|
+
/**
|
|
10
|
+
* Set the values of one or more properties on an element
|
|
11
|
+
*
|
|
12
|
+
* Also updates attributes for boolean/dispatchable properties, and if `dispatch` is `true`, will dispatch events for dispatchable properties
|
|
13
|
+
* @param target Target element
|
|
14
|
+
* @param properties Properties to set
|
|
15
|
+
* @param dispatch Dispatch events for properties? _(defaults to `true`)_
|
|
16
|
+
*/
|
|
17
|
+
function setProperties(target, properties, dispatch) {
|
|
18
|
+
if (!isHTMLOrSVGElement(target) || !isPlainObject(properties)) return;
|
|
19
|
+
const shouldDispatch = dispatch !== false;
|
|
20
|
+
const keys = Object.keys(properties);
|
|
21
|
+
const { length } = keys;
|
|
22
|
+
for (let index = 0; index < length; index += 1) {
|
|
23
|
+
const key = keys[index];
|
|
24
|
+
if (booleanAttributesSet.has(key.toLowerCase()) || dispatchedAttributes.has(key)) setAttribute(target, key, properties[key], shouldDispatch);
|
|
25
|
+
else updateProperty(target, key, properties[key], shouldDispatch);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function setProperty(target, property, value, dispatch) {
|
|
29
|
+
if (!isHTMLOrSVGElement(target) || typeof property !== "string") return;
|
|
30
|
+
if (booleanAttributesSet.has(property.toLowerCase()) || dispatchedAttributes.has(property)) setAttribute(target, property, value, dispatch !== false);
|
|
31
|
+
else updateProperty(target, property, value, dispatch !== false);
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { setProperties, setProperty };
|
package/dist/style.d.mts
CHANGED
|
@@ -11,6 +11,7 @@ type StyleToggler = {
|
|
|
11
11
|
*/
|
|
12
12
|
remove(): void;
|
|
13
13
|
};
|
|
14
|
+
type Styles = Partial<Record<keyof CSSStyleDeclaration, unknown>>;
|
|
14
15
|
/**
|
|
15
16
|
* Get a style from an element
|
|
16
17
|
* @param element Element to get the style from
|
|
@@ -28,31 +29,35 @@ declare function getStyle(element: Element, property: keyof CSSStyleDeclaration,
|
|
|
28
29
|
*/
|
|
29
30
|
declare function getStyles<Property extends keyof CSSStyleDeclaration>(element: Element, properties: Property[], computed?: boolean): Record<Property, string | undefined>;
|
|
30
31
|
/**
|
|
31
|
-
* Get the text direction of
|
|
32
|
-
* @param element
|
|
33
|
-
* @param computed Get the computed text direction? _(defaults to `false`)_
|
|
32
|
+
* Get the text direction of a node or element _(or document, if element is invalid)_
|
|
33
|
+
* @param node Node or element to get the text direction from
|
|
34
34
|
* @returns Text direction
|
|
35
35
|
*/
|
|
36
|
-
declare function getTextDirection(
|
|
36
|
+
declare function getTextDirection(node: Element | Node): TextDirection;
|
|
37
|
+
/**
|
|
38
|
+
* Get the text direction of the document
|
|
39
|
+
* @returns Text direction
|
|
40
|
+
*/
|
|
41
|
+
declare function getTextDirection(): TextDirection;
|
|
37
42
|
/**
|
|
38
43
|
* Set a style on an element
|
|
39
44
|
* @param element Element to set the style on
|
|
40
45
|
* @param property Style name
|
|
41
46
|
* @param value Style value
|
|
42
47
|
*/
|
|
43
|
-
declare function setStyle(element: Element, property: keyof CSSStyleDeclaration, value?:
|
|
48
|
+
declare function setStyle(element: Element, property: keyof CSSStyleDeclaration, value?: unknown): void;
|
|
44
49
|
/**
|
|
45
50
|
* Set styles on an element
|
|
46
51
|
* @param element Element to set the styles on
|
|
47
52
|
* @param styles Styles to set
|
|
48
53
|
*/
|
|
49
|
-
declare function setStyles(element: Element, styles:
|
|
54
|
+
declare function setStyles(element: Element, styles: Styles): void;
|
|
50
55
|
/**
|
|
51
56
|
* Toggle styles for an element
|
|
52
57
|
* @param element Element to style
|
|
53
58
|
* @param styles Styles to be set or removed
|
|
54
59
|
* @returns Style toggler
|
|
55
60
|
*/
|
|
56
|
-
declare function toggleStyles(element: Element, styles:
|
|
61
|
+
declare function toggleStyles(element: Element, styles: Styles): StyleToggler;
|
|
57
62
|
//#endregion
|
|
58
63
|
export { StyleToggler, getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles };
|
package/dist/style.mjs
CHANGED
|
@@ -10,8 +10,7 @@ import { getStyleValue } from "./internal/get-value.mjs";
|
|
|
10
10
|
* @returns Style value
|
|
11
11
|
*/
|
|
12
12
|
function getStyle(element, property, computed) {
|
|
13
|
-
if (
|
|
14
|
-
return getStyleValue(element, property, computed === true);
|
|
13
|
+
if (isHTMLOrSVGElement(element) && typeof property === "string") return getStyleValue(element, property, computed === true);
|
|
15
14
|
}
|
|
16
15
|
/**
|
|
17
16
|
* Get styles from an element
|
|
@@ -30,18 +29,13 @@ function getStyles(element, properties, computed) {
|
|
|
30
29
|
}
|
|
31
30
|
return styles;
|
|
32
31
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (!(element instanceof Element)) return;
|
|
41
|
-
const direction = element.getAttribute(ATTRIBUTE_DIRECTION);
|
|
42
|
-
if (direction != null && EXPRESSION_DIRECTION.test(direction)) return direction.toLowerCase();
|
|
43
|
-
const value = getStyleValue(element, "direction", computed === true);
|
|
44
|
-
return value === "rtl" ? value : "ltr";
|
|
32
|
+
function getTextDirection(node) {
|
|
33
|
+
let target;
|
|
34
|
+
if (isHTMLOrSVGElement(node)) target = node;
|
|
35
|
+
else target = node instanceof Node ? node.ownerDocument?.documentElement ?? document.documentElement : document.documentElement;
|
|
36
|
+
let { direction } = target.style;
|
|
37
|
+
if (direction === "") direction = getStyleValue(target, PROPETY_DIRECTION, true);
|
|
38
|
+
return direction === DIRECTION_RTL ? DIRECTION_RTL : DIRECTION_LTR;
|
|
45
39
|
}
|
|
46
40
|
/**
|
|
47
41
|
* Set a style on an element
|
|
@@ -76,11 +70,12 @@ function toggleStyles(element, styles) {
|
|
|
76
70
|
} else {
|
|
77
71
|
next = { ...values };
|
|
78
72
|
values = {};
|
|
79
|
-
for (
|
|
73
|
+
for (let index = 0; index < length; index += 1) values[keys[index]] = void 0;
|
|
80
74
|
}
|
|
81
75
|
setStyles(element, next);
|
|
82
76
|
}
|
|
83
77
|
const keys = Object.keys(styles);
|
|
78
|
+
const { length } = keys;
|
|
84
79
|
let hasSet = false;
|
|
85
80
|
let values = {};
|
|
86
81
|
return {
|
|
@@ -94,12 +89,13 @@ function toggleStyles(element, styles) {
|
|
|
94
89
|
}
|
|
95
90
|
function updateStyleProperty(element, key, value) {
|
|
96
91
|
updateElementValue(element, key, value, function(property, style) {
|
|
97
|
-
this.style[property] = style;
|
|
92
|
+
this.style[property] = String(style);
|
|
98
93
|
}, function(property) {
|
|
99
94
|
this.style[property] = "";
|
|
100
95
|
}, false, false);
|
|
101
96
|
}
|
|
102
|
-
const
|
|
103
|
-
const
|
|
97
|
+
const DIRECTION_LTR = "ltr";
|
|
98
|
+
const DIRECTION_RTL = "rtl";
|
|
99
|
+
const PROPETY_DIRECTION = "direction";
|
|
104
100
|
//#endregion
|
|
105
101
|
export { getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscarpalmer/toretto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"description": "A collection of badass DOM utilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dom",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"types": "./dist/attribute/index.d.mts",
|
|
35
35
|
"default": "./dist/attribute/index.mjs"
|
|
36
36
|
},
|
|
37
|
+
"./create": {
|
|
38
|
+
"types": "./dist/create.d.mts",
|
|
39
|
+
"default": "./dist/create.mjs"
|
|
40
|
+
},
|
|
37
41
|
"./data": {
|
|
38
42
|
"types": "./dist/data.d.mts",
|
|
39
43
|
"default": "./dist/data.mjs"
|
|
@@ -61,6 +65,10 @@
|
|
|
61
65
|
"./models": {
|
|
62
66
|
"types": "./dist/models.d.mts"
|
|
63
67
|
},
|
|
68
|
+
"./property": {
|
|
69
|
+
"types": "./dist/property/index.d.mts",
|
|
70
|
+
"default": "./dist/property/index.mjs"
|
|
71
|
+
},
|
|
64
72
|
"./style": {
|
|
65
73
|
"types": "./dist/style.d.mts",
|
|
66
74
|
"default": "./dist/style.mjs"
|
|
@@ -75,16 +83,15 @@
|
|
|
75
83
|
"tsdown:build": "npx tsdown -c ./tsdown.config.ts",
|
|
76
84
|
"tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
|
|
77
85
|
"test": "npx vp test run --coverage",
|
|
78
|
-
"test:leak": "npx vp test run --detect-async-leaks --coverage"
|
|
79
|
-
"watch": "npx vite build --watch"
|
|
86
|
+
"test:leak": "npx vp test run --detect-async-leaks --coverage"
|
|
80
87
|
},
|
|
81
88
|
"dependencies": {
|
|
82
|
-
"@oscarpalmer/atoms": "^0.
|
|
89
|
+
"@oscarpalmer/atoms": "^0.172"
|
|
83
90
|
},
|
|
84
91
|
"devDependencies": {
|
|
85
92
|
"@types/node": "^25.5",
|
|
86
93
|
"@vitest/coverage-istanbul": "^4.1",
|
|
87
|
-
"jsdom": "^
|
|
94
|
+
"jsdom": "^29",
|
|
88
95
|
"tsdown": "^0.21",
|
|
89
96
|
"typescript": "^5.9",
|
|
90
97
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import {kebabCase} from '@oscarpalmer/atoms/string/case';
|
|
1
2
|
import {getAttributeValue} from '../internal/get-value';
|
|
2
3
|
import {isHTMLOrSVGElement} from '../internal/is';
|
|
3
4
|
|
|
5
|
+
// #region Types
|
|
6
|
+
|
|
7
|
+
type DataPrefixedName = `data-${string}`;
|
|
8
|
+
|
|
9
|
+
// #endregion
|
|
10
|
+
|
|
11
|
+
// #region Functions
|
|
12
|
+
|
|
4
13
|
/**
|
|
5
14
|
* Get the value of a specific attribute from an element
|
|
6
15
|
* @param element Element to get attribute from
|
|
@@ -8,7 +17,7 @@ import {isHTMLOrSVGElement} from '../internal/is';
|
|
|
8
17
|
* @param parse Parse value? _(defaults to `true`)_
|
|
9
18
|
* @returns Attribute value _(or `undefined`)_
|
|
10
19
|
*/
|
|
11
|
-
export function getAttribute(element: Element, name:
|
|
20
|
+
export function getAttribute(element: Element, name: DataPrefixedName, parse?: boolean): unknown;
|
|
12
21
|
|
|
13
22
|
/**
|
|
14
23
|
* Get the value of a specific attribute from an element
|
|
@@ -20,7 +29,7 @@ export function getAttribute(element: Element, name: string): unknown;
|
|
|
20
29
|
|
|
21
30
|
export function getAttribute(element: Element, name: string, parseValues?: boolean): unknown {
|
|
22
31
|
if (isHTMLOrSVGElement(element) && typeof name === 'string') {
|
|
23
|
-
return getAttributeValue(element, name, parseValues !== false);
|
|
32
|
+
return getAttributeValue(element, kebabCase(name), parseValues !== false);
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
35
|
|
|
@@ -50,9 +59,11 @@ export function getAttributes<Key extends string>(
|
|
|
50
59
|
const name = names[index];
|
|
51
60
|
|
|
52
61
|
if (typeof name === 'string') {
|
|
53
|
-
attributes[name] = getAttributeValue(element, name, shouldParse);
|
|
62
|
+
attributes[name] = getAttributeValue(element, kebabCase(name), shouldParse);
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
return attributes;
|
|
58
67
|
}
|
|
68
|
+
|
|
69
|
+
// #endregion
|
package/src/attribute/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
_isBadAttribute,
|
|
3
3
|
_isBooleanAttribute,
|
|
4
|
-
_isEmptyNonBooleanAttribute,
|
|
5
4
|
_isInvalidBooleanAttribute,
|
|
6
5
|
} from '../internal/attribute';
|
|
7
6
|
import type {Attribute} from '../models';
|
|
8
7
|
|
|
8
|
+
// #region Functions
|
|
9
|
+
|
|
9
10
|
/**
|
|
10
11
|
* Is the attribute considered bad and potentially harmful?
|
|
11
12
|
* @param attribute Attribute to check
|
|
@@ -43,25 +44,6 @@ export function isBooleanAttribute(first: unknown): boolean {
|
|
|
43
44
|
return _isBooleanAttribute(first, true);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
/**
|
|
47
|
-
* Is the attribute empty and not a boolean attribute?
|
|
48
|
-
* @param attribute Attribute to check
|
|
49
|
-
* @returns `true` if attribute is empty and not a boolean attribute
|
|
50
|
-
*/
|
|
51
|
-
export function isEmptyNonBooleanAttribute(attribute: Attr | Attribute): boolean;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Is the attribute empty and not a boolean attribute?
|
|
55
|
-
* @param name Attribute name
|
|
56
|
-
* @param value Attribute value
|
|
57
|
-
* @returns `true` if attribute is empty and not a boolean attribute
|
|
58
|
-
*/
|
|
59
|
-
export function isEmptyNonBooleanAttribute(name: string, value: string): boolean;
|
|
60
|
-
|
|
61
|
-
export function isEmptyNonBooleanAttribute(first: unknown, second?: unknown): boolean {
|
|
62
|
-
return _isEmptyNonBooleanAttribute(first, second, true);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
47
|
/**
|
|
66
48
|
* Is the attribute an invalid boolean attribute?
|
|
67
49
|
*
|
|
@@ -85,6 +67,12 @@ export function isInvalidBooleanAttribute(first: unknown, second?: unknown): boo
|
|
|
85
67
|
return _isInvalidBooleanAttribute(first, second, true);
|
|
86
68
|
}
|
|
87
69
|
|
|
70
|
+
// #endregion
|
|
71
|
+
|
|
72
|
+
// #region Exports
|
|
73
|
+
|
|
88
74
|
export {booleanAttributes} from '../internal/attribute';
|
|
89
|
-
export * from './get';
|
|
90
|
-
export
|
|
75
|
+
export * from './get.attribute';
|
|
76
|
+
export {setAttribute, setAttributes} from './set.attribute';
|
|
77
|
+
|
|
78
|
+
// #endregion
|
|
@@ -2,11 +2,13 @@ import {updateAttribute} from '../internal/attribute';
|
|
|
2
2
|
import {setElementValue, setElementValues} from '../internal/element-value';
|
|
3
3
|
import type {Attribute} from '../models';
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// #region Types
|
|
6
6
|
|
|
7
|
-
type
|
|
7
|
+
export type DispatchedAttributeName = 'checked' | 'open' | 'value';
|
|
8
8
|
|
|
9
|
-
//
|
|
9
|
+
// #endregion
|
|
10
|
+
|
|
11
|
+
// #region Functions
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Set an attribute on an element
|
|
@@ -17,9 +19,9 @@ type DispatchedAttribute = 'checked' | 'open' | 'value';
|
|
|
17
19
|
* @param value Attribute value
|
|
18
20
|
* @param dispatch Dispatch event for attribute? _(defaults to `true`)_
|
|
19
21
|
*/
|
|
20
|
-
export function setAttribute
|
|
22
|
+
export function setAttribute(
|
|
21
23
|
element: Element,
|
|
22
|
-
name:
|
|
24
|
+
name: DispatchedAttributeName,
|
|
23
25
|
value?: unknown,
|
|
24
26
|
dispatch?: boolean,
|
|
25
27
|
): void;
|
|
@@ -92,3 +94,5 @@ export function setAttributes(
|
|
|
92
94
|
): void {
|
|
93
95
|
setElementValues(element, attributes, null, dispatch, updateAttribute);
|
|
94
96
|
}
|
|
97
|
+
|
|
98
|
+
// #endregion
|