@oscarpalmer/toretto 0.25.0 → 0.26.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.js +17 -0
- package/dist/attribute/index.js +4 -0
- package/dist/attribute/is.js +5 -0
- package/dist/attribute/misc.js +0 -0
- package/dist/attribute/set.js +14 -0
- package/dist/attribute/update.js +31 -0
- package/dist/data.js +1 -1
- package/dist/event/delegation.js +94 -0
- package/dist/{event.js → event/index.js} +13 -6
- package/dist/{find.js → find/index.js} +1 -64
- package/dist/find/relative.js +66 -0
- package/dist/html.js +5 -2
- package/dist/index.js +10 -6
- package/dist/internal/attribute.js +60 -0
- package/dist/internal/element-value.js +2 -1
- package/dist/internal/is.js +7 -0
- package/dist/internal/sanitize.js +1 -1
- package/dist/is.js +1 -6
- package/dist/style.js +1 -1
- package/dist/toretto.full.js +335 -207
- package/package.json +8 -12
- package/src/attribute/get.ts +66 -0
- package/src/attribute/index.ts +9 -0
- package/src/attribute/is.ts +9 -0
- package/src/attribute/misc.ts +0 -0
- package/src/attribute/set.ts +137 -0
- package/src/attribute/update.ts +86 -0
- package/src/data.ts +1 -1
- package/src/event/delegation.ts +193 -0
- package/src/{event.ts → event/index.ts} +62 -20
- package/src/find/index.ts +190 -0
- package/src/find/relative.ts +183 -0
- package/src/html.ts +21 -1
- package/src/index.ts +2 -3
- package/src/internal/attribute.ts +196 -0
- package/src/internal/is.ts +25 -0
- package/src/internal/sanitize.ts +1 -1
- package/src/is.ts +4 -26
- package/src/style.ts +1 -1
- package/types/attribute/get.d.ts +23 -0
- package/types/attribute/index.d.ts +3 -0
- package/types/attribute/is.d.ts +2 -0
- package/types/attribute/misc.d.ts +1 -0
- package/types/attribute/set.d.ts +67 -0
- package/types/attribute/update.d.ts +5 -0
- package/types/event/delegation.d.ts +7 -0
- package/types/{event.d.ts → event/index.d.ts} +5 -5
- package/types/find/index.d.ts +26 -0
- package/types/find/relative.d.ts +21 -0
- package/types/html.d.ts +7 -0
- package/types/index.d.ts +2 -3
- package/types/internal/attribute.d.ts +60 -0
- package/types/internal/is.d.ts +13 -0
- package/types/is.d.ts +1 -13
- package/dist/attribute.js +0 -118
- package/dist/sanitize.js +0 -5
- package/src/attribute.ts +0 -479
- package/src/find.ts +0 -371
- package/src/sanitize.ts +0 -21
- package/types/attribute.d.ts +0 -149
- package/types/find.d.ts +0 -48
- package/types/sanitize.d.ts +0 -8
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isHTMLOrSVGElement } from "../internal/is.js";
|
|
2
|
+
import { getAttributeValue } from "../internal/get-value.js";
|
|
3
|
+
function getAttribute(element, name, parseValues) {
|
|
4
|
+
if (isHTMLOrSVGElement(element) && typeof name === "string") return getAttributeValue(element, name, parseValues !== false);
|
|
5
|
+
}
|
|
6
|
+
function getAttributes(element, names, parseData) {
|
|
7
|
+
const attributes = {};
|
|
8
|
+
if (!(isHTMLOrSVGElement(element) && Array.isArray(names))) return attributes;
|
|
9
|
+
const shouldParse = parseData !== false;
|
|
10
|
+
const { length } = names;
|
|
11
|
+
for (let index = 0; index < length; index += 1) {
|
|
12
|
+
const name = names[index];
|
|
13
|
+
if (typeof name === "string") attributes[name] = getAttributeValue(element, name, shouldParse);
|
|
14
|
+
}
|
|
15
|
+
return attributes;
|
|
16
|
+
}
|
|
17
|
+
export { getAttribute, getAttributes };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { booleanAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute } from "../internal/attribute.js";
|
|
2
|
+
import { getAttribute, getAttributes } from "./get.js";
|
|
3
|
+
import { setAttribute, setAttributes, setProperties, setProperty } from "./set.js";
|
|
4
|
+
export { booleanAttributes, getAttribute, getAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute, setAttribute, setAttributes, setProperties, setProperty };
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { updateAttribute, updateProperty, updateValue, updateValues } from "./update.js";
|
|
2
|
+
function setAttribute(element, first, second) {
|
|
3
|
+
updateValue(element, first, second, updateAttribute);
|
|
4
|
+
}
|
|
5
|
+
function setAttributes(element, attributes) {
|
|
6
|
+
updateValues(element, attributes);
|
|
7
|
+
}
|
|
8
|
+
function setProperty(element, first, second) {
|
|
9
|
+
updateValue(element, first, second, updateProperty);
|
|
10
|
+
}
|
|
11
|
+
function setProperties(element, properties) {
|
|
12
|
+
updateValues(element, properties, updateProperty);
|
|
13
|
+
}
|
|
14
|
+
export { setAttribute, setAttributes, setProperties, setProperty };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { isHTMLOrSVGElement } from "../internal/is.js";
|
|
2
|
+
import { booleanAttributes } from "../internal/attribute.js";
|
|
3
|
+
import { isProperty } from "./is.js";
|
|
4
|
+
import { getString } from "@oscarpalmer/atoms/string";
|
|
5
|
+
function updateAttribute(element, name, value) {
|
|
6
|
+
if (booleanAttributes.includes(name.toLowerCase())) updateProperty(element, name, value, false);
|
|
7
|
+
else if (value == null) element.removeAttribute(name);
|
|
8
|
+
else element.setAttribute(name, typeof value === "string" ? value : getString(value));
|
|
9
|
+
}
|
|
10
|
+
function updateProperty(element, name, value, validate) {
|
|
11
|
+
const actual = validate ?? true ? name.toLowerCase() : name;
|
|
12
|
+
if (actual === "hidden") element.hidden = value === "" || value === true;
|
|
13
|
+
else element[actual] = value === "" || typeof value === "string" && value.toLowerCase() === actual || value === true;
|
|
14
|
+
}
|
|
15
|
+
function updateValue(element, first, second, callback) {
|
|
16
|
+
if (!isHTMLOrSVGElement(element)) return;
|
|
17
|
+
if (isProperty(first)) callback(element, first.name, first.value);
|
|
18
|
+
else if (typeof first === "string") callback(element, first, second);
|
|
19
|
+
}
|
|
20
|
+
function updateValues(element, values, callback) {
|
|
21
|
+
if (!isHTMLOrSVGElement(element)) return;
|
|
22
|
+
const isArray = Array.isArray(values);
|
|
23
|
+
const entries = Object.entries(values);
|
|
24
|
+
const { length } = entries;
|
|
25
|
+
for (let index = 0; index < length; index += 1) {
|
|
26
|
+
const entry = entries[index];
|
|
27
|
+
if (isArray) (callback ?? updateAttribute)(element, entry[1].name, entry[1].value);
|
|
28
|
+
else (callback ?? updateAttribute)(element, entry[0], entry[1]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export { updateAttribute, updateProperty, updateValue, updateValues };
|
package/dist/data.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isHTMLOrSVGElement } from "./is.js";
|
|
1
|
+
import { isHTMLOrSVGElement } from "./internal/is.js";
|
|
2
2
|
import { setElementValues, updateElementValue } from "./internal/element-value.js";
|
|
3
3
|
import { EXPRESSION_DATA_PREFIX } from "./internal/get-value.js";
|
|
4
4
|
import { kebabCase, parse } from "@oscarpalmer/atoms/string";
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { isEventTarget } from "../internal/is.js";
|
|
2
|
+
function addDelegatedHandler(document$1, type, name, passive) {
|
|
3
|
+
const listeners = `${name}${LISTENERS_SUFFIX}`;
|
|
4
|
+
if (document$1[listeners] != null) {
|
|
5
|
+
document$1[listeners] += 1;
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
document$1[listeners] = 1;
|
|
9
|
+
document$1.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
|
|
10
|
+
}
|
|
11
|
+
function addDelegatedListener(target, type, name, listener, passive) {
|
|
12
|
+
target[name] ??= /* @__PURE__ */ new Set();
|
|
13
|
+
target[name]?.add(listener);
|
|
14
|
+
addDelegatedHandler(document, type, name, passive);
|
|
15
|
+
return () => {
|
|
16
|
+
removeDelegatedListener(target, type, name, listener, passive);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function delegatedEventHandler(event) {
|
|
20
|
+
const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
21
|
+
let target = event.target;
|
|
22
|
+
const items = event.composedPath();
|
|
23
|
+
const { length } = items;
|
|
24
|
+
for (let index = 0; index < length; index += 1) {
|
|
25
|
+
target = items[index];
|
|
26
|
+
const listeners = target[key];
|
|
27
|
+
if (!target.disabled && listeners != null) {
|
|
28
|
+
Object.defineProperties(event, {
|
|
29
|
+
currentTarget: {
|
|
30
|
+
configurable: true,
|
|
31
|
+
value: target
|
|
32
|
+
},
|
|
33
|
+
target: {
|
|
34
|
+
configurable: true,
|
|
35
|
+
value: target
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
for (const listener of listeners) {
|
|
39
|
+
listener.call(target, event);
|
|
40
|
+
if (event.cancelBubble) return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function getDelegatedName(target, type, options) {
|
|
46
|
+
if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
47
|
+
}
|
|
48
|
+
function removeDelegatedHandler(document$1, type, name, passive) {
|
|
49
|
+
const listeners = `${name}${LISTENERS_SUFFIX}`;
|
|
50
|
+
document$1[listeners] -= 1;
|
|
51
|
+
if (document$1[listeners] < 1) {
|
|
52
|
+
document$1[listeners] = void 0;
|
|
53
|
+
document$1.removeEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function removeDelegatedListener(target, type, name, listener, passive) {
|
|
57
|
+
const handlers = target[name];
|
|
58
|
+
if (handlers == null || !handlers.has(listener)) return false;
|
|
59
|
+
handlers.delete(listener);
|
|
60
|
+
if (handlers?.size === 0) target[name] = void 0;
|
|
61
|
+
removeDelegatedHandler(document, type, name, passive);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
var EVENT_PREFIX = "@";
|
|
65
|
+
var EVENT_SUFFIX_ACTIVE = ":active";
|
|
66
|
+
var EVENT_SUFFIX_PASSIVE = ":passive";
|
|
67
|
+
var EVENT_TYPES = new Set([
|
|
68
|
+
"beforeinput",
|
|
69
|
+
"click",
|
|
70
|
+
"dblclick",
|
|
71
|
+
"contextmenu",
|
|
72
|
+
"focusin",
|
|
73
|
+
"focusout",
|
|
74
|
+
"input",
|
|
75
|
+
"keydown",
|
|
76
|
+
"keyup",
|
|
77
|
+
"mousedown",
|
|
78
|
+
"mousemove",
|
|
79
|
+
"mouseout",
|
|
80
|
+
"mouseover",
|
|
81
|
+
"mouseup",
|
|
82
|
+
"pointerdown",
|
|
83
|
+
"pointermove",
|
|
84
|
+
"pointerout",
|
|
85
|
+
"pointerover",
|
|
86
|
+
"pointerup",
|
|
87
|
+
"touchend",
|
|
88
|
+
"touchmove",
|
|
89
|
+
"touchstart"
|
|
90
|
+
]);
|
|
91
|
+
var HANDLER_ACTIVE = delegatedEventHandler.bind(false);
|
|
92
|
+
var HANDLER_PASSIVE = delegatedEventHandler.bind(true);
|
|
93
|
+
var LISTENERS_SUFFIX = ":listeners";
|
|
94
|
+
export { addDelegatedListener, getDelegatedName, removeDelegatedListener };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { isEventTarget } from "
|
|
2
|
-
import { getBoolean } from "
|
|
1
|
+
import { isEventTarget } from "../internal/is.js";
|
|
2
|
+
import { getBoolean } from "../internal/get-value.js";
|
|
3
|
+
import { addDelegatedListener, getDelegatedName, removeDelegatedListener } from "./delegation.js";
|
|
3
4
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
4
5
|
import { noop } from "@oscarpalmer/atoms/function";
|
|
5
6
|
function createDispatchOptions(options) {
|
|
6
7
|
return {
|
|
7
|
-
bubbles: getBoolean(options?.bubbles),
|
|
8
|
-
cancelable: getBoolean(options?.cancelable),
|
|
8
|
+
bubbles: getBoolean(options?.bubbles, true),
|
|
9
|
+
cancelable: getBoolean(options?.cancelable, true),
|
|
9
10
|
composed: getBoolean(options?.composed)
|
|
10
11
|
};
|
|
11
12
|
}
|
|
@@ -22,7 +23,7 @@ function createEventOptions(options) {
|
|
|
22
23
|
capture: getBoolean(options?.capture),
|
|
23
24
|
once: getBoolean(options?.once),
|
|
24
25
|
passive: getBoolean(options?.passive, true),
|
|
25
|
-
signal: options?.signal
|
|
26
|
+
signal: options?.signal instanceof AbortSignal ? options.signal : void 0
|
|
26
27
|
};
|
|
27
28
|
}
|
|
28
29
|
function dispatch(target, type, options) {
|
|
@@ -44,12 +45,18 @@ function getPosition(event) {
|
|
|
44
45
|
} : void 0;
|
|
45
46
|
}
|
|
46
47
|
function off(target, type, listener, options) {
|
|
47
|
-
if (isEventTarget(target)
|
|
48
|
+
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return;
|
|
49
|
+
const extended = createEventOptions(options);
|
|
50
|
+
const delegated = getDelegatedName(target, type, extended);
|
|
51
|
+
if (delegated == null || !removeDelegatedListener(target, type, delegated, listener, extended.passive)) target.removeEventListener(type, listener, extended);
|
|
48
52
|
}
|
|
49
53
|
function on(target, type, listener, options) {
|
|
50
54
|
if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
|
|
51
55
|
const extended = createEventOptions(options);
|
|
56
|
+
const delegated = getDelegatedName(target, type, extended);
|
|
57
|
+
if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
|
|
52
58
|
target.addEventListener(type, listener, extended);
|
|
59
|
+
if (extended.once) return noop;
|
|
53
60
|
return () => {
|
|
54
61
|
target.removeEventListener(type, listener, extended);
|
|
55
62
|
};
|
|
@@ -1,26 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
if (origin === target || origin.parentElement === target) return 0;
|
|
3
|
-
const comparison = origin.compareDocumentPosition(target);
|
|
4
|
-
const children = [...origin.parentElement?.children ?? []];
|
|
5
|
-
if (children.includes(target)) return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
6
|
-
const beforeOrInside = !!(comparison & 2 || comparison & 8);
|
|
7
|
-
if (beforeOrInside || !!(comparison & 4 || comparison & 16)) return traverse(beforeOrInside ? origin : target, beforeOrInside ? target : origin) ?? -1;
|
|
8
|
-
}
|
|
9
|
-
function findAncestor(origin, selector) {
|
|
10
|
-
if (!(origin instanceof Element) || selector == null) return null;
|
|
11
|
-
if (typeof selector === "string") {
|
|
12
|
-
if (origin.matches?.(selector)) return origin;
|
|
13
|
-
return origin.closest(selector);
|
|
14
|
-
}
|
|
15
|
-
if (typeof selector !== "function") return null;
|
|
16
|
-
if (selector(origin)) return origin;
|
|
17
|
-
let parent = origin.parentElement;
|
|
18
|
-
while (parent != null && !selector(parent)) {
|
|
19
|
-
if (parent === document.body) return null;
|
|
20
|
-
parent = parent.parentElement;
|
|
21
|
-
}
|
|
22
|
-
return parent;
|
|
23
|
-
}
|
|
1
|
+
import { findAncestor, findRelatives } from "./relative.js";
|
|
24
2
|
function findElement(selector, context) {
|
|
25
3
|
return findElementOrElements(selector, context, true);
|
|
26
4
|
}
|
|
@@ -62,27 +40,6 @@ function findElementOrElementsFromNodes(array, context, contexts) {
|
|
|
62
40
|
function findElements(selector, context) {
|
|
63
41
|
return findElementOrElements(selector, context, false);
|
|
64
42
|
}
|
|
65
|
-
function findRelatives(origin, selector, context) {
|
|
66
|
-
if (!(origin instanceof Element) || typeof selector !== "string") return [];
|
|
67
|
-
if (origin.matches(selector)) return [origin];
|
|
68
|
-
const elements = [...(context instanceof Document || context instanceof Element ? context : document).querySelectorAll(selector)];
|
|
69
|
-
const { length } = elements;
|
|
70
|
-
if (length === 0) return [];
|
|
71
|
-
const distances = [];
|
|
72
|
-
let minimum;
|
|
73
|
-
for (let index = 0; index < length; index += 1) {
|
|
74
|
-
const element = elements[index];
|
|
75
|
-
const distance = getDistanceBetweenElements(origin, element) ?? -1;
|
|
76
|
-
if (distance > -1) {
|
|
77
|
-
if (minimum == null || distance < minimum) minimum = distance;
|
|
78
|
-
distances.push({
|
|
79
|
-
distance,
|
|
80
|
-
element
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return minimum == null ? [] : distances.filter((found) => found.distance === minimum).map((found) => found.element);
|
|
85
|
-
}
|
|
86
43
|
function getElementUnderPointer(skipIgnore) {
|
|
87
44
|
const elements = [...document.querySelectorAll(SUFFIX_HOVER)];
|
|
88
45
|
const { length } = elements;
|
|
@@ -98,26 +55,6 @@ function getElementUnderPointer(skipIgnore) {
|
|
|
98
55
|
function isContext(value) {
|
|
99
56
|
return typeof value?.querySelector === "function" && typeof value?.querySelectorAll === "function";
|
|
100
57
|
}
|
|
101
|
-
function traverse(from, to) {
|
|
102
|
-
let index = [...to.children].indexOf(from);
|
|
103
|
-
if (index > -1) return index + 1;
|
|
104
|
-
let current = from;
|
|
105
|
-
let distance = 0;
|
|
106
|
-
let parent = from.parentElement;
|
|
107
|
-
while (parent != null) {
|
|
108
|
-
if (parent === to) return distance + 1;
|
|
109
|
-
const children = [...parent.children ?? []];
|
|
110
|
-
if (children.includes(to)) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
|
|
111
|
-
index = children.findIndex((child) => child.contains(to));
|
|
112
|
-
if (index > -1) {
|
|
113
|
-
const traversed = traverse(current, children[index]) ?? -1;
|
|
114
|
-
return traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
|
|
115
|
-
}
|
|
116
|
-
current = parent;
|
|
117
|
-
distance += 1;
|
|
118
|
-
parent = parent.parentElement;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
58
|
var QUERY_SELECTOR_ALL = "querySelectorAll";
|
|
122
59
|
var QUERY_SELECTOR_SINGLE = "querySelector";
|
|
123
60
|
var STYLE_HIDDEN = "hidden";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
function getDistanceBetweenElements(origin, target) {
|
|
2
|
+
if (origin === target || origin.parentElement === target) return 0;
|
|
3
|
+
const comparison = origin.compareDocumentPosition(target);
|
|
4
|
+
const children = [...origin.parentElement?.children ?? []];
|
|
5
|
+
if (children.includes(target)) return Math.abs(children.indexOf(origin) - children.indexOf(target));
|
|
6
|
+
const beforeOrInside = !!(comparison & 2 || comparison & 8);
|
|
7
|
+
if (beforeOrInside || !!(comparison & 4 || comparison & 16)) return traverse(beforeOrInside ? origin : target, beforeOrInside ? target : origin) ?? -1;
|
|
8
|
+
}
|
|
9
|
+
function findAncestor(origin, selector) {
|
|
10
|
+
if (!(origin instanceof Element) || selector == null) return null;
|
|
11
|
+
if (typeof selector === "string") {
|
|
12
|
+
if (origin.matches?.(selector)) return origin;
|
|
13
|
+
return origin.closest(selector);
|
|
14
|
+
}
|
|
15
|
+
if (typeof selector !== "function") return null;
|
|
16
|
+
if (selector(origin)) return origin;
|
|
17
|
+
let parent = origin.parentElement;
|
|
18
|
+
while (parent != null && !selector(parent)) {
|
|
19
|
+
if (parent === document.body) return null;
|
|
20
|
+
parent = parent.parentElement;
|
|
21
|
+
}
|
|
22
|
+
return parent;
|
|
23
|
+
}
|
|
24
|
+
function findRelatives(origin, selector, context) {
|
|
25
|
+
if (!(origin instanceof Element) || typeof selector !== "string") return [];
|
|
26
|
+
if (origin.matches(selector)) return [origin];
|
|
27
|
+
const elements = [...(context instanceof Document || context instanceof Element ? context : document).querySelectorAll(selector)];
|
|
28
|
+
const { length } = elements;
|
|
29
|
+
if (length === 0) return [];
|
|
30
|
+
if (length === 1) return [elements[0]];
|
|
31
|
+
const distances = [];
|
|
32
|
+
let minimum;
|
|
33
|
+
for (let index = 0; index < length; index += 1) {
|
|
34
|
+
const element = elements[index];
|
|
35
|
+
const distance = getDistanceBetweenElements(origin, element) ?? -1;
|
|
36
|
+
if (distance > -1) {
|
|
37
|
+
if (minimum == null || distance < minimum) minimum = distance;
|
|
38
|
+
distances.push({
|
|
39
|
+
distance,
|
|
40
|
+
element
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return minimum == null ? [] : distances.filter((found) => found.distance === minimum).map((found) => found.element);
|
|
45
|
+
}
|
|
46
|
+
function traverse(from, to) {
|
|
47
|
+
let index = [...to.children].indexOf(from);
|
|
48
|
+
if (index > -1) return index + 1;
|
|
49
|
+
let current = from;
|
|
50
|
+
let distance = 0;
|
|
51
|
+
let parent = from.parentElement;
|
|
52
|
+
while (parent != null) {
|
|
53
|
+
if (parent === to) return distance + 1;
|
|
54
|
+
const children = [...parent.children ?? []];
|
|
55
|
+
if (children.includes(to)) return distance + Math.abs(children.indexOf(current) - children.indexOf(to));
|
|
56
|
+
index = children.findIndex((child) => child.contains(to));
|
|
57
|
+
if (index > -1) {
|
|
58
|
+
const traversed = traverse(current, children[index]) ?? -1;
|
|
59
|
+
return traversed === -1 ? -1 : distance + Math.abs(index - children.indexOf(current)) + traversed;
|
|
60
|
+
}
|
|
61
|
+
current = parent;
|
|
62
|
+
distance += 1;
|
|
63
|
+
parent = parent.parentElement;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export { findAncestor, findRelatives };
|
package/dist/html.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sanitizeNodes } from "./internal/sanitize.js";
|
|
1
|
+
import { getSanitizeOptions, sanitizeNodes } from "./internal/sanitize.js";
|
|
2
2
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
3
3
|
function createTemplate(html$1, ignore) {
|
|
4
4
|
const template = document.createElement("template");
|
|
@@ -47,6 +47,9 @@ html.remove = (template) => {
|
|
|
47
47
|
}
|
|
48
48
|
templates = updated;
|
|
49
49
|
};
|
|
50
|
+
function sanitize(value, options) {
|
|
51
|
+
return sanitizeNodes(Array.isArray(value) ? value : [value], getSanitizeOptions(options));
|
|
52
|
+
}
|
|
50
53
|
var EXPRESSION_ID = /^[a-z][\w-]*$/i;
|
|
51
54
|
var templates = {};
|
|
52
|
-
export { html };
|
|
55
|
+
export { html, sanitize };
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import touch_default from "./touch.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isEventTarget, isHTMLOrSVGElement } from "./internal/is.js";
|
|
3
|
+
import { isChildNode, isInDocument } from "./is.js";
|
|
3
4
|
import { getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles } from "./style.js";
|
|
4
|
-
import { booleanAttributes,
|
|
5
|
-
import {
|
|
5
|
+
import { booleanAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute } from "./internal/attribute.js";
|
|
6
|
+
import { getAttribute, getAttributes } from "./attribute/get.js";
|
|
7
|
+
import { setAttribute, setAttributes, setProperties, setProperty } from "./attribute/set.js";
|
|
8
|
+
import "./attribute/index.js";
|
|
6
9
|
import { getData, setData } from "./data.js";
|
|
7
|
-
import { dispatch, getPosition, off, on } from "./event.js";
|
|
8
|
-
import {
|
|
10
|
+
import { dispatch, getPosition, off, on } from "./event/index.js";
|
|
11
|
+
import { findAncestor, findRelatives } from "./find/relative.js";
|
|
12
|
+
import { $ as findElement, $$ as findElements, getElementUnderPointer } from "./find/index.js";
|
|
9
13
|
import { getFocusable, getTabbable, isFocusable, isTabbable } from "./focusable.js";
|
|
10
|
-
import { html } from "./html.js";
|
|
14
|
+
import { html, sanitize } from "./html.js";
|
|
11
15
|
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 };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
2
|
+
function isAttribute(value) {
|
|
3
|
+
return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
|
|
4
|
+
}
|
|
5
|
+
function isBadAttribute(first, second) {
|
|
6
|
+
return isValidAttribute((attribute) => attribute == null || EXPRESSION_ON_PREFIX.test(attribute.name) || EXPRESSION_SOURCE_PREFIX.test(attribute.name) && EXPRESSION_VALUE_PREFIX.test(String(attribute.value)), first, second);
|
|
7
|
+
}
|
|
8
|
+
function isBooleanAttribute(value) {
|
|
9
|
+
return isValidAttribute((attribute) => attribute != null && booleanAttributes.includes(attribute.name.toLowerCase()), value, "");
|
|
10
|
+
}
|
|
11
|
+
function isEmptyNonBooleanAttribute(first, second) {
|
|
12
|
+
return isValidAttribute((attribute) => attribute != null && !booleanAttributes.includes(attribute.name) && String(attribute.value).trim().length === 0, first, second);
|
|
13
|
+
}
|
|
14
|
+
function isInvalidBooleanAttribute(first, second) {
|
|
15
|
+
return isValidAttribute((attribute) => {
|
|
16
|
+
if (attribute == null) return true;
|
|
17
|
+
if (!booleanAttributes.includes(attribute.name)) return false;
|
|
18
|
+
const normalized = String(attribute.value).toLowerCase().trim();
|
|
19
|
+
return !(normalized.length === 0 || normalized === attribute.name);
|
|
20
|
+
}, first, second);
|
|
21
|
+
}
|
|
22
|
+
function isValidAttribute(callback, first, second) {
|
|
23
|
+
let attribute;
|
|
24
|
+
if (isAttribute(first)) attribute = first;
|
|
25
|
+
else if (typeof first === "string" && typeof second === "string") attribute = {
|
|
26
|
+
name: first,
|
|
27
|
+
value: second
|
|
28
|
+
};
|
|
29
|
+
return callback(attribute);
|
|
30
|
+
}
|
|
31
|
+
var EXPRESSION_ON_PREFIX = /^on/i;
|
|
32
|
+
var EXPRESSION_SOURCE_PREFIX = /^(href|src|xlink:href)$/i;
|
|
33
|
+
var EXPRESSION_VALUE_PREFIX = /(data:text\/html|javascript:)/i;
|
|
34
|
+
const booleanAttributes = Object.freeze([
|
|
35
|
+
"async",
|
|
36
|
+
"autofocus",
|
|
37
|
+
"autoplay",
|
|
38
|
+
"checked",
|
|
39
|
+
"controls",
|
|
40
|
+
"default",
|
|
41
|
+
"defer",
|
|
42
|
+
"disabled",
|
|
43
|
+
"formnovalidate",
|
|
44
|
+
"hidden",
|
|
45
|
+
"inert",
|
|
46
|
+
"ismap",
|
|
47
|
+
"itemscope",
|
|
48
|
+
"loop",
|
|
49
|
+
"multiple",
|
|
50
|
+
"muted",
|
|
51
|
+
"nomodule",
|
|
52
|
+
"novalidate",
|
|
53
|
+
"open",
|
|
54
|
+
"playsinline",
|
|
55
|
+
"readonly",
|
|
56
|
+
"required",
|
|
57
|
+
"reversed",
|
|
58
|
+
"selected"
|
|
59
|
+
]);
|
|
60
|
+
export { booleanAttributes, isBadAttribute, isBooleanAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { isHTMLOrSVGElement } from "
|
|
1
|
+
import { isHTMLOrSVGElement } from "./is.js";
|
|
2
|
+
import "../is.js";
|
|
2
3
|
import { isNullableOrWhitespace, isPlainObject } from "@oscarpalmer/atoms/is";
|
|
3
4
|
function setElementValues(element, first, second, callback) {
|
|
4
5
|
if (!isHTMLOrSVGElement(element)) return;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
function isEventTarget(value) {
|
|
2
|
+
return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
|
|
3
|
+
}
|
|
4
|
+
function isHTMLOrSVGElement(value) {
|
|
5
|
+
return value instanceof HTMLElement || value instanceof SVGElement;
|
|
6
|
+
}
|
|
7
|
+
export { isEventTarget, isHTMLOrSVGElement };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isBadAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute } from "
|
|
1
|
+
import { isBadAttribute, isEmptyNonBooleanAttribute, isInvalidBooleanAttribute } from "./attribute.js";
|
|
2
2
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
3
3
|
function getSanitizeOptions(input) {
|
|
4
4
|
const options = isPlainObject(input) ? input : {};
|
package/dist/is.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
+
import { isEventTarget, isHTMLOrSVGElement } from "./internal/is.js";
|
|
1
2
|
function isChildNode(value) {
|
|
2
3
|
return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
|
|
3
4
|
}
|
|
4
|
-
function isEventTarget(value) {
|
|
5
|
-
return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
|
|
6
|
-
}
|
|
7
|
-
function isHTMLOrSVGElement(value) {
|
|
8
|
-
return value instanceof HTMLElement || value instanceof SVGElement;
|
|
9
|
-
}
|
|
10
5
|
function isInDocument(node, document) {
|
|
11
6
|
if (!(node instanceof Node)) return false;
|
|
12
7
|
if (!(document instanceof Document)) return node.ownerDocument?.contains(node) ?? true;
|
package/dist/style.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isHTMLOrSVGElement } from "./is.js";
|
|
1
|
+
import { isHTMLOrSVGElement } from "./internal/is.js";
|
|
2
2
|
import { setElementValues, updateElementValue } from "./internal/element-value.js";
|
|
3
3
|
import { getStyleValue } from "./internal/get-value.js";
|
|
4
4
|
function getStyle(element, property, computed) {
|