@oscarpalmer/toretto 0.23.0 → 0.24.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.js +5 -5
- package/dist/data.js +7 -4
- package/dist/event.js +2 -1
- package/dist/find.js +32 -16
- package/dist/focusable.js +48 -36
- package/dist/html.js +18 -10
- package/dist/index.js +2 -2
- package/dist/internal/get-value.js +3 -3
- package/dist/is.js +10 -8
- package/dist/style.js +34 -5
- package/dist/toretto.full.js +237 -129
- package/package.json +5 -5
- package/src/attribute.ts +40 -40
- package/src/data.ts +20 -9
- package/src/event.ts +5 -1
- package/src/find.ts +78 -36
- package/src/focusable.ts +82 -43
- package/src/html.ts +73 -43
- package/src/internal/element-value.ts +2 -1
- package/src/internal/get-value.ts +4 -2
- package/src/is.ts +18 -14
- package/src/style.ts +74 -6
- package/src/touch.ts +3 -3
- package/types/data.d.ts +1 -1
- package/types/find.d.ts +2 -2
- package/types/html.d.ts +27 -14
- package/types/internal/element-value.d.ts +1 -1
- package/types/internal/get-value.d.ts +1 -0
- package/types/style.d.ts +17 -0
package/dist/attribute.js
CHANGED
|
@@ -7,7 +7,7 @@ function getAttribute(element, name, parseValues) {
|
|
|
7
7
|
}
|
|
8
8
|
function getAttributes(element, names, parseData) {
|
|
9
9
|
const attributes = {};
|
|
10
|
-
if (!isHTMLOrSVGElement(element)
|
|
10
|
+
if (!(isHTMLOrSVGElement(element) && Array.isArray(names))) return attributes;
|
|
11
11
|
const shouldParse = parseData !== false;
|
|
12
12
|
const { length } = names;
|
|
13
13
|
for (let index = 0; index < length; index += 1) {
|
|
@@ -20,7 +20,7 @@ function isAttribute(value) {
|
|
|
20
20
|
return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
|
|
21
21
|
}
|
|
22
22
|
function isBadAttribute(first, second) {
|
|
23
|
-
return validateAttribute((attribute) => attribute == null ||
|
|
23
|
+
return validateAttribute((attribute) => attribute == null || EXPRESSION_ON_PREFIX.test(attribute.name) || EXPRESSION_SOURCE_PREFIX.test(attribute.name) && EXPRESSION_VALUE_PREFIX.test(String(attribute.value)), first, second);
|
|
24
24
|
}
|
|
25
25
|
function isBooleanAttribute(value) {
|
|
26
26
|
return validateAttribute((attribute) => attribute != null && booleanAttributes.includes(attribute.name.toLowerCase()), value, "");
|
|
@@ -86,6 +86,9 @@ function validateAttribute(callback, first, second) {
|
|
|
86
86
|
};
|
|
87
87
|
return callback(attribute);
|
|
88
88
|
}
|
|
89
|
+
var EXPRESSION_ON_PREFIX = /^on/i;
|
|
90
|
+
var EXPRESSION_SOURCE_PREFIX = /^(href|src|xlink:href)$/i;
|
|
91
|
+
var EXPRESSION_VALUE_PREFIX = /(data:text\/html|javascript:)/i;
|
|
89
92
|
const booleanAttributes = Object.freeze([
|
|
90
93
|
"async",
|
|
91
94
|
"autofocus",
|
|
@@ -112,7 +115,4 @@ const booleanAttributes = Object.freeze([
|
|
|
112
115
|
"reversed",
|
|
113
116
|
"selected"
|
|
114
117
|
]);
|
|
115
|
-
var onPrefix = /^on/i;
|
|
116
|
-
var sourcePrefix = /^(href|src|xlink:href)$/i;
|
|
117
|
-
var valuePrefix = /(data:text\/html|javascript:)/i;
|
|
118
118
|
export { booleanAttributes, getAttribute, getAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, setAttribute, setAttributes, setProperties, setProperty };
|
package/dist/data.js
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import { isHTMLOrSVGElement } from "./is.js";
|
|
2
2
|
import { setElementValues, updateElementValue } from "./internal/element-value.js";
|
|
3
|
+
import { EXPRESSION_DATA_PREFIX } from "./internal/get-value.js";
|
|
3
4
|
import { kebabCase, parse } from "@oscarpalmer/atoms/string";
|
|
4
5
|
function getData(element, keys, parseValues) {
|
|
5
6
|
if (!isHTMLOrSVGElement(element)) return;
|
|
6
7
|
const shouldParse = parseValues !== false;
|
|
7
8
|
if (typeof keys === "string") {
|
|
8
9
|
const value = element.dataset[keys];
|
|
9
|
-
|
|
10
|
+
if (value === void 0) return;
|
|
11
|
+
return shouldParse ? parse(value) : value;
|
|
10
12
|
}
|
|
11
13
|
const { length } = keys;
|
|
12
14
|
const data = {};
|
|
13
15
|
for (let index = 0; index < length; index += 1) {
|
|
14
16
|
const key = keys[index];
|
|
15
17
|
const value = element.dataset[key];
|
|
16
|
-
|
|
18
|
+
if (value == null) data[key] = void 0;
|
|
19
|
+
else data[key] = shouldParse ? parse(value) : value;
|
|
17
20
|
}
|
|
18
21
|
return data;
|
|
19
22
|
}
|
|
20
23
|
function getName(original) {
|
|
21
|
-
return
|
|
24
|
+
return `${ATTRIBUTE_DATA_PREFIX}${kebabCase(original).replace(EXPRESSION_DATA_PREFIX, "")}`;
|
|
22
25
|
}
|
|
23
26
|
function setData(element, first, second) {
|
|
24
27
|
setElementValues(element, first, second, updateDataAttribute);
|
|
@@ -26,5 +29,5 @@ function setData(element, first, second) {
|
|
|
26
29
|
function updateDataAttribute(element, key, value) {
|
|
27
30
|
updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, true);
|
|
28
31
|
}
|
|
29
|
-
var
|
|
32
|
+
var ATTRIBUTE_DATA_PREFIX = "data-";
|
|
30
33
|
export { getData, setData };
|
package/dist/event.js
CHANGED
|
@@ -11,7 +11,7 @@ function createDispatchOptions(options) {
|
|
|
11
11
|
}
|
|
12
12
|
function createEvent(type, options) {
|
|
13
13
|
const hasOptions = isPlainObject(options);
|
|
14
|
-
if (hasOptions &&
|
|
14
|
+
if (hasOptions && PROPERTY_DETAIL in options) return new CustomEvent(type, {
|
|
15
15
|
...createDispatchOptions(options),
|
|
16
16
|
detail: options?.detail
|
|
17
17
|
});
|
|
@@ -54,4 +54,5 @@ function on(target, type, listener, options) {
|
|
|
54
54
|
target.removeEventListener(type, listener, extended);
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
+
var PROPERTY_DETAIL = "detail";
|
|
57
58
|
export { dispatch, getPosition, off, on };
|
package/dist/find.js
CHANGED
|
@@ -25,26 +25,36 @@ function findElement(selector, context) {
|
|
|
25
25
|
return findElementOrElements(selector, context, true);
|
|
26
26
|
}
|
|
27
27
|
function findElementOrElements(selector, context, single) {
|
|
28
|
-
const callback = single ?
|
|
28
|
+
const callback = single ? QUERY_SELECTOR_SINGLE : QUERY_SELECTOR_ALL;
|
|
29
29
|
const contexts = context == null ? [document] : findElementOrElements(context, void 0, false).filter(isContext);
|
|
30
|
+
if (typeof selector === "string") return findElementOrElementsForSelector(selector, contexts, callback, single);
|
|
31
|
+
let array;
|
|
32
|
+
if (Array.isArray(selector)) array = selector;
|
|
33
|
+
else array = selector instanceof Node ? [selector] : [...selector];
|
|
34
|
+
return findElementOrElementsFromNodes(array, context, contexts);
|
|
35
|
+
}
|
|
36
|
+
function findElementOrElementsForSelector(selector, contexts, callback, single) {
|
|
37
|
+
const { length } = contexts;
|
|
30
38
|
const result = [];
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (value == null) continue;
|
|
37
|
-
return value;
|
|
38
|
-
}
|
|
39
|
-
result.push(...Array.from(value));
|
|
39
|
+
for (let index = 0; index < length; index += 1) {
|
|
40
|
+
const value = contexts[index][callback](selector);
|
|
41
|
+
if (single) {
|
|
42
|
+
if (value == null) continue;
|
|
43
|
+
return value;
|
|
40
44
|
}
|
|
41
|
-
|
|
45
|
+
result.push(...Array.from(value));
|
|
42
46
|
}
|
|
43
|
-
|
|
47
|
+
return single ? null : result.filter((value, index, array) => array.indexOf(value) === index);
|
|
48
|
+
}
|
|
49
|
+
function findElementOrElementsFromNodes(array, context, contexts) {
|
|
50
|
+
const result = [];
|
|
51
|
+
const nodes = array.filter((node) => node instanceof Node);
|
|
44
52
|
const { length } = nodes;
|
|
45
53
|
for (let index = 0; index < length; index += 1) {
|
|
46
54
|
const node = nodes[index];
|
|
47
|
-
|
|
55
|
+
let element;
|
|
56
|
+
if (node instanceof Document) element = node.body;
|
|
57
|
+
else element = node instanceof Element ? node : void 0;
|
|
48
58
|
if (element != null && (context == null || contexts.length === 0 || contexts.some((context$1) => context$1 === element || context$1.contains(element))) && !result.includes(element)) result.push(element);
|
|
49
59
|
}
|
|
50
60
|
return result;
|
|
@@ -74,14 +84,14 @@ function findRelatives(origin, selector, context) {
|
|
|
74
84
|
return minimum == null ? [] : distances.filter((found) => found.distance === minimum).map((found) => found.element);
|
|
75
85
|
}
|
|
76
86
|
function getElementUnderPointer(skipIgnore) {
|
|
77
|
-
const elements = [...document.querySelectorAll(
|
|
87
|
+
const elements = [...document.querySelectorAll(SUFFIX_HOVER)];
|
|
78
88
|
const { length } = elements;
|
|
79
89
|
const returned = [];
|
|
80
90
|
for (let index = 0; index < length; index += 1) {
|
|
81
91
|
const element = elements[index];
|
|
82
|
-
if (element.tagName ===
|
|
92
|
+
if (element.tagName === TAG_HEAD) continue;
|
|
83
93
|
const style = getComputedStyle(element);
|
|
84
|
-
if (skipIgnore === true || style.pointerEvents !==
|
|
94
|
+
if (skipIgnore === true || style.pointerEvents !== STYLE_NONE && style.visibility !== STYLE_HIDDEN) returned.push(element);
|
|
85
95
|
}
|
|
86
96
|
return returned.at(-1) ?? null;
|
|
87
97
|
}
|
|
@@ -108,4 +118,10 @@ function traverse(from, to) {
|
|
|
108
118
|
parent = parent.parentElement;
|
|
109
119
|
}
|
|
110
120
|
}
|
|
121
|
+
var QUERY_SELECTOR_ALL = "querySelectorAll";
|
|
122
|
+
var QUERY_SELECTOR_SINGLE = "querySelector";
|
|
123
|
+
var STYLE_HIDDEN = "hidden";
|
|
124
|
+
var STYLE_NONE = "none";
|
|
125
|
+
var SUFFIX_HOVER = ":hover";
|
|
126
|
+
var TAG_HEAD = "HEAD";
|
|
111
127
|
export { findElement as $, findElement, findElements as $$, findElements, findAncestor, findRelatives, getElementUnderPointer };
|
package/dist/focusable.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
function getFocusable(parent) {
|
|
2
|
-
return getValidElements(parent,
|
|
2
|
+
return getValidElements(parent, FILTERS_FOCUSABLE, false);
|
|
3
3
|
}
|
|
4
4
|
function getItem(element, tabbable) {
|
|
5
5
|
return {
|
|
6
6
|
element,
|
|
7
|
-
tabIndex: tabbable ? getTabIndex(element) :
|
|
7
|
+
tabIndex: tabbable ? getTabIndex(element) : TABINDEX_DEFAULT
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
10
|
function getTabbable(parent) {
|
|
11
|
-
return getValidElements(parent,
|
|
11
|
+
return getValidElements(parent, FILTERS_TABBABLE, true);
|
|
12
12
|
}
|
|
13
13
|
function getTabIndex(element) {
|
|
14
|
-
const tabIndex = element?.tabIndex ??
|
|
15
|
-
if (tabIndex <
|
|
14
|
+
const tabIndex = element?.tabIndex ?? TABINDEX_DEFAULT;
|
|
15
|
+
if (tabIndex < TABINDEX_BASE && (EXPRESSION_SPECIAL_TABINDEX.test(element.tagName) || isEditable(element)) && !hasTabIndex(element)) return TABINDEX_BASE;
|
|
16
16
|
return tabIndex;
|
|
17
17
|
}
|
|
18
18
|
function getValidElements(parent, filters, tabbable) {
|
|
19
19
|
if (!(parent instanceof Element)) return [];
|
|
20
|
-
const elements = [...parent.querySelectorAll(
|
|
20
|
+
const elements = [...parent.querySelectorAll(SELECTOR_FULL)];
|
|
21
21
|
const items = [];
|
|
22
22
|
let { length } = elements;
|
|
23
23
|
for (let index = 0; index < length; index += 1) {
|
|
@@ -30,16 +30,16 @@ function getValidElements(parent, filters, tabbable) {
|
|
|
30
30
|
length = items.length;
|
|
31
31
|
for (let index = 0; index < length; index += 1) {
|
|
32
32
|
const item = items[index];
|
|
33
|
-
if (item.tabIndex ===
|
|
33
|
+
if (item.tabIndex === TABINDEX_BASE) zeroed.push(item.element);
|
|
34
34
|
else indiced[item.tabIndex] = [...indiced[item.tabIndex] ?? [], item.element];
|
|
35
35
|
}
|
|
36
36
|
return [...indiced.flat(), ...zeroed];
|
|
37
37
|
}
|
|
38
38
|
function hasTabIndex(element) {
|
|
39
|
-
return !Number.isNaN(Number.parseInt(element.getAttribute(
|
|
39
|
+
return !Number.isNaN(Number.parseInt(element.getAttribute(ATTRIBUTE_TABINDEX), 10));
|
|
40
40
|
}
|
|
41
41
|
function isDisabled(item) {
|
|
42
|
-
if (
|
|
42
|
+
if (EXPRESSION_DISABLEABLE.test(item.element.tagName) && isDisabledFromFieldset(item.element)) return true;
|
|
43
43
|
return item.element.disabled ?? false;
|
|
44
44
|
}
|
|
45
45
|
function isDisabledFromFieldset(element) {
|
|
@@ -50,7 +50,7 @@ function isDisabledFromFieldset(element) {
|
|
|
50
50
|
const { length } = children;
|
|
51
51
|
for (let index = 0; index < length; index += 1) {
|
|
52
52
|
const child = children[index];
|
|
53
|
-
if (child instanceof HTMLLegendElement) return parent.matches(
|
|
53
|
+
if (child instanceof HTMLLegendElement) return parent.matches(SELECTOR_FIELDSET_DISABLED) || !child.contains(element);
|
|
54
54
|
}
|
|
55
55
|
return true;
|
|
56
56
|
}
|
|
@@ -59,72 +59,84 @@ function isDisabledFromFieldset(element) {
|
|
|
59
59
|
return false;
|
|
60
60
|
}
|
|
61
61
|
function isEditable(element) {
|
|
62
|
-
return
|
|
62
|
+
return EXPRESSION_TRUEISH.test(element.getAttribute(ATTRIBUTE_CONTENTEDITABLE));
|
|
63
63
|
}
|
|
64
64
|
function isFocusable(element) {
|
|
65
|
-
return element instanceof Element ? isValidElement(element,
|
|
65
|
+
return element instanceof Element ? isValidElement(element, FILTERS_FOCUSABLE, false) : false;
|
|
66
66
|
}
|
|
67
67
|
function isHidden(item) {
|
|
68
|
-
if ((item.element.hidden ?? false) || item.element instanceof HTMLInputElement && item.element.type ===
|
|
69
|
-
if ((item.element.matches(
|
|
68
|
+
if ((item.element.hidden ?? false) || item.element instanceof HTMLInputElement && item.element.type === STYLE_HIDDEN) return true;
|
|
69
|
+
if ((item.element.matches(SELECTOR_SUMMARY_FIRST) ? item.element.parentElement : item.element)?.matches(SELECTOR_DETAILS_CLOSED_CHILDREN) ?? false) return true;
|
|
70
70
|
const style = getComputedStyle(item.element);
|
|
71
|
-
if (style.display ===
|
|
71
|
+
if (style.display === STYLE_NONE || style.visibility === STYLE_HIDDEN) return true;
|
|
72
72
|
const { height, width } = item.element.getBoundingClientRect();
|
|
73
73
|
return height === 0 && width === 0;
|
|
74
74
|
}
|
|
75
75
|
function isInert(item) {
|
|
76
|
-
return (item.element.inert ?? false) ||
|
|
76
|
+
return (item.element.inert ?? false) || EXPRESSION_TRUEISH.test(item.element.getAttribute(ATTRIBUTE_INERT)) || item.element.parentElement != null && isInert({
|
|
77
77
|
element: item.element.parentElement,
|
|
78
|
-
tabIndex:
|
|
78
|
+
tabIndex: TABINDEX_DEFAULT
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
function isNotTabbable(item) {
|
|
82
|
-
return (item.tabIndex ??
|
|
82
|
+
return (item.tabIndex ?? TABINDEX_DEFAULT) < TABINDEX_BASE;
|
|
83
83
|
}
|
|
84
84
|
function isNotTabbableRadio(item) {
|
|
85
|
-
if (!(item.element instanceof HTMLInputElement) || item.element.type !==
|
|
85
|
+
if (!(item.element instanceof HTMLInputElement) || item.element.type !== TYPE_RADIO || !item.element.name || item.element.checked) return false;
|
|
86
86
|
const parent = item.element.form ?? item.element.getRootNode?.() ?? item.element.ownerDocument;
|
|
87
87
|
const realName = CSS?.escape?.(item.element.name) ?? item.element.name;
|
|
88
|
-
const checked = [...parent.querySelectorAll(
|
|
88
|
+
const checked = [...parent.querySelectorAll(`${SELECTOR_RADIO_PREFIX}${realName}${SELECTOR_RADIO_SUFFIX}`)].find((radio) => radio.checked);
|
|
89
89
|
return checked != null && checked !== item.element;
|
|
90
90
|
}
|
|
91
91
|
function isSummarised(item) {
|
|
92
|
-
return item.element instanceof HTMLDetailsElement && [...item.element.children].some((child) =>
|
|
92
|
+
return item.element instanceof HTMLDetailsElement && [...item.element.children].some((child) => EXPRESSION_SUMMARY.test(child.tagName));
|
|
93
93
|
}
|
|
94
94
|
function isTabbable(element) {
|
|
95
|
-
return element instanceof Element ? isValidElement(element,
|
|
95
|
+
return element instanceof Element ? isValidElement(element, FILTERS_TABBABLE, true) : false;
|
|
96
96
|
}
|
|
97
97
|
function isValidElement(element, filters, tabbable) {
|
|
98
98
|
const item = getItem(element, tabbable);
|
|
99
99
|
return !filters.some((filter) => filter(item));
|
|
100
100
|
}
|
|
101
|
-
var
|
|
102
|
-
var
|
|
103
|
-
var
|
|
101
|
+
var ATTRIBUTE_CONTENTEDITABLE = "contenteditable";
|
|
102
|
+
var ATTRIBUTE_INERT = "inert";
|
|
103
|
+
var ATTRIBUTE_TABINDEX = "tabindex";
|
|
104
|
+
var EXPRESSION_DISABLEABLE = /^(button|input|select|textarea)$/i;
|
|
105
|
+
var EXPRESSION_SPECIAL_TABINDEX = /^(audio|details|video)$/i;
|
|
106
|
+
var EXPRESSION_SUMMARY = /^summary$/i;
|
|
107
|
+
var EXPRESSION_TRUEISH = /^(|true)$/i;
|
|
108
|
+
var FILTERS_FOCUSABLE = [
|
|
104
109
|
isDisabled,
|
|
105
110
|
isInert,
|
|
106
111
|
isHidden,
|
|
107
112
|
isSummarised
|
|
108
113
|
];
|
|
109
|
-
var
|
|
114
|
+
var FILTERS_TABBABLE = [
|
|
115
|
+
isNotTabbable,
|
|
116
|
+
isNotTabbableRadio,
|
|
117
|
+
...FILTERS_FOCUSABLE
|
|
118
|
+
];
|
|
119
|
+
var SELECTOR_DETAILS_CLOSED_CHILDREN = "details:not([open]) *";
|
|
120
|
+
var SELECTOR_FIELDSET_DISABLED = "fieldset[disabled] *";
|
|
121
|
+
var SELECTOR_SUMMARY_FIRST = "details > summary:first-of-type";
|
|
122
|
+
var SELECTOR_RADIO_PREFIX = "input[type=\"radio\"][name=\"";
|
|
123
|
+
var SELECTOR_RADIO_SUFFIX = "\"]";
|
|
124
|
+
var SELECTOR_FULL = [
|
|
110
125
|
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
111
126
|
"[tabindex]:not(slot)",
|
|
112
127
|
"a[href]",
|
|
113
128
|
"audio[controls]",
|
|
114
129
|
"button",
|
|
115
130
|
"details",
|
|
116
|
-
|
|
131
|
+
SELECTOR_SUMMARY_FIRST,
|
|
117
132
|
"input",
|
|
118
133
|
"select",
|
|
119
134
|
"textarea",
|
|
120
135
|
"video[controls]"
|
|
121
|
-
].map((selector
|
|
122
|
-
var
|
|
123
|
-
var
|
|
124
|
-
var
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
...focusableFilters
|
|
128
|
-
];
|
|
129
|
-
var trueishPattern = /^(|true)$/i;
|
|
136
|
+
].map((selector) => `${selector}:not([inert])`).join(",");
|
|
137
|
+
var STYLE_HIDDEN = "hidden";
|
|
138
|
+
var STYLE_NONE = "none";
|
|
139
|
+
var TABINDEX_BASE = 0;
|
|
140
|
+
var TABINDEX_DEFAULT = -1;
|
|
141
|
+
var TYPE_RADIO = "radio";
|
|
130
142
|
export { getFocusable, getTabbable, isFocusable, isTabbable };
|
package/dist/html.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { sanitize } from "./sanitize.js";
|
|
2
|
-
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
3
2
|
function createTemplate(html$1) {
|
|
4
3
|
const template = document.createElement("template");
|
|
5
4
|
template.innerHTML = html$1;
|
|
@@ -8,15 +7,18 @@ function createTemplate(html$1) {
|
|
|
8
7
|
}
|
|
9
8
|
function getTemplate(value) {
|
|
10
9
|
if (typeof value !== "string" || value.trim().length === 0) return;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
let template = templates[value];
|
|
11
|
+
if (template != null) return template;
|
|
12
|
+
const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
|
|
13
|
+
template = element instanceof HTMLTemplateElement ? element : createTemplate(value);
|
|
14
|
+
templates[value] = template;
|
|
15
|
+
return template;
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
var html = ((value, sanitization) => {
|
|
18
18
|
if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
|
|
19
|
-
|
|
19
|
+
let options;
|
|
20
|
+
if (sanitization == null || sanitization === true) options = {};
|
|
21
|
+
else options = sanitization === false ? void 0 : sanitization;
|
|
20
22
|
const template = value instanceof HTMLTemplateElement ? value : getTemplate(value);
|
|
21
23
|
if (template == null) return [];
|
|
22
24
|
const cloned = template.content.cloneNode(true);
|
|
@@ -25,7 +27,13 @@ function html(value, sanitization) {
|
|
|
25
27
|
for (let index = 0; index < length; index += 1) scripts[index].remove();
|
|
26
28
|
cloned.normalize();
|
|
27
29
|
return options != null ? sanitize([...cloned.childNodes], options) : [...cloned.childNodes];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
+
});
|
|
31
|
+
html.clear = () => {
|
|
32
|
+
templates = {};
|
|
33
|
+
};
|
|
34
|
+
html.remove = (template) => {
|
|
35
|
+
if (typeof template === "string") templates[template] = void 0;
|
|
36
|
+
};
|
|
37
|
+
var EXPRESSION_ID = /^[a-z][\w-]*$/i;
|
|
30
38
|
var templates = {};
|
|
31
39
|
export { html };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import touch_default from "./touch.js";
|
|
2
2
|
import { isChildNode, isEventTarget, isHTMLOrSVGElement, isInDocument } from "./is.js";
|
|
3
|
-
import { getStyle, getStyles, getTextDirection, setStyle, setStyles } from "./style.js";
|
|
3
|
+
import { getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles } from "./style.js";
|
|
4
4
|
import { booleanAttributes, getAttribute, getAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, setAttribute, setAttributes, setProperties, setProperty } from "./attribute.js";
|
|
5
5
|
import { sanitize } from "./sanitize.js";
|
|
6
6
|
import { getData, setData } from "./data.js";
|
|
@@ -8,4 +8,4 @@ import { dispatch, getPosition, off, on } from "./event.js";
|
|
|
8
8
|
import { $ as findElement, $$ as findElements, findAncestor, findRelatives, getElementUnderPointer } from "./find.js";
|
|
9
9
|
import { getFocusable, getTabbable, isFocusable, isTabbable } from "./focusable.js";
|
|
10
10
|
import { html } from "./html.js";
|
|
11
|
-
export { findElement as $, findElement, findElements as $$, findElements, booleanAttributes, dispatch, findAncestor, findRelatives, getAttribute, getAttributes, getData, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setAttribute, setAttributes, setData, setProperties, setProperty, setStyle, setStyles, touch_default as supportsTouch };
|
|
11
|
+
export { findElement as $, findElement, findElements as $$, findElements, booleanAttributes, dispatch, findAncestor, findRelatives, getAttribute, getAttributes, getData, getElementUnderPointer, getFocusable, getPosition, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEmptyNonBooleanAttribute, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setAttribute, setAttributes, setData, setProperties, setProperty, setStyle, setStyles, touch_default as supportsTouch, toggleStyles };
|
|
@@ -6,11 +6,11 @@ function getAttributeValue(element, name, parseValue) {
|
|
|
6
6
|
const normalized = kebabCase(name);
|
|
7
7
|
const attribute = element.attributes[normalized];
|
|
8
8
|
const value = attribute instanceof Attr ? attribute.value : void 0;
|
|
9
|
-
return
|
|
9
|
+
return EXPRESSION_DATA_PREFIX.test(normalized) && typeof value === "string" && parseValue ? parse(value) ?? value : value;
|
|
10
10
|
}
|
|
11
11
|
function getStyleValue(element, property, computed) {
|
|
12
12
|
const name = camelCase(property);
|
|
13
13
|
return computed ? getComputedStyle(element)[name] : element.style[name];
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
export { getAttributeValue, getBoolean, getStyleValue };
|
|
15
|
+
const EXPRESSION_DATA_PREFIX = /^data-/i;
|
|
16
|
+
export { EXPRESSION_DATA_PREFIX, getAttributeValue, getBoolean, getStyleValue };
|
package/dist/is.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function isChildNode(value) {
|
|
2
|
-
return value instanceof Node &&
|
|
2
|
+
return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
|
|
3
3
|
}
|
|
4
4
|
function isEventTarget(value) {
|
|
5
5
|
return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
|
|
@@ -8,13 +8,15 @@ function isHTMLOrSVGElement(value) {
|
|
|
8
8
|
return value instanceof HTMLElement || value instanceof SVGElement;
|
|
9
9
|
}
|
|
10
10
|
function isInDocument(node, document) {
|
|
11
|
-
|
|
11
|
+
if (!(node instanceof Node)) return false;
|
|
12
|
+
if (!(document instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
|
|
13
|
+
return node.ownerDocument == null ? node === document : node.ownerDocument === document && document.contains(node);
|
|
12
14
|
}
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
var CHILD_NODE_TYPES = new Set([
|
|
16
|
+
Node.ELEMENT_NODE,
|
|
17
|
+
Node.TEXT_NODE,
|
|
18
|
+
Node.PROCESSING_INSTRUCTION_NODE,
|
|
19
|
+
Node.COMMENT_NODE,
|
|
20
|
+
Node.DOCUMENT_TYPE_NODE
|
|
19
21
|
]);
|
|
20
22
|
export { isChildNode, isEventTarget, isHTMLOrSVGElement, isInDocument };
|
package/dist/style.js
CHANGED
|
@@ -7,7 +7,7 @@ function getStyle(element, property, computed) {
|
|
|
7
7
|
}
|
|
8
8
|
function getStyles(element, properties, computed) {
|
|
9
9
|
const styles = {};
|
|
10
|
-
if (!isHTMLOrSVGElement(element)
|
|
10
|
+
if (!(isHTMLOrSVGElement(element) && Array.isArray(properties))) return styles;
|
|
11
11
|
const { length } = properties;
|
|
12
12
|
for (let index = 0; index < length; index += 1) {
|
|
13
13
|
const property = properties[index];
|
|
@@ -17,9 +17,10 @@ function getStyles(element, properties, computed) {
|
|
|
17
17
|
}
|
|
18
18
|
function getTextDirection(element, computed) {
|
|
19
19
|
if (!(element instanceof Element)) return;
|
|
20
|
-
const direction = element.getAttribute(
|
|
21
|
-
if (direction != null &&
|
|
22
|
-
|
|
20
|
+
const direction = element.getAttribute(ATTRIBUTE_DIRECTION);
|
|
21
|
+
if (direction != null && EXPRESSION_DIRECTION.test(direction)) return direction.toLowerCase();
|
|
22
|
+
const value = getStyleValue(element, "direction", computed === true);
|
|
23
|
+
return value === "rtl" ? value : "ltr";
|
|
23
24
|
}
|
|
24
25
|
function setStyle(element, property, value) {
|
|
25
26
|
setElementValues(element, property, value, updateStyleProperty);
|
|
@@ -27,6 +28,32 @@ function setStyle(element, property, value) {
|
|
|
27
28
|
function setStyles(element, styles) {
|
|
28
29
|
setElementValues(element, styles, null, updateStyleProperty);
|
|
29
30
|
}
|
|
31
|
+
function toggleStyles(element, styles) {
|
|
32
|
+
function toggle(set) {
|
|
33
|
+
hasSet = set;
|
|
34
|
+
let next;
|
|
35
|
+
if (set) {
|
|
36
|
+
values = getStyles(element, keys);
|
|
37
|
+
next = styles;
|
|
38
|
+
} else {
|
|
39
|
+
next = { ...values };
|
|
40
|
+
values = {};
|
|
41
|
+
for (const key of keys) values[key] = void 0;
|
|
42
|
+
}
|
|
43
|
+
setStyles(element, next);
|
|
44
|
+
}
|
|
45
|
+
const keys = Object.keys(styles);
|
|
46
|
+
let hasSet = false;
|
|
47
|
+
let values = {};
|
|
48
|
+
return {
|
|
49
|
+
set() {
|
|
50
|
+
if (!hasSet) toggle(true);
|
|
51
|
+
},
|
|
52
|
+
remove() {
|
|
53
|
+
if (hasSet) toggle(false);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
30
57
|
function updateStyleProperty(element, key, value) {
|
|
31
58
|
updateElementValue(element, key, value, function(property, value$1) {
|
|
32
59
|
this.style[property] = value$1;
|
|
@@ -34,4 +61,6 @@ function updateStyleProperty(element, key, value) {
|
|
|
34
61
|
this.style[property] = "";
|
|
35
62
|
}, false);
|
|
36
63
|
}
|
|
37
|
-
|
|
64
|
+
var ATTRIBUTE_DIRECTION = "dir";
|
|
65
|
+
var EXPRESSION_DIRECTION = /^(ltr|rtl)$/i;
|
|
66
|
+
export { getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles };
|