@oscarpalmer/abydon 0.8.0 → 0.9.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/fragment.mjs +21 -11
- package/dist/helpers/dom.mjs +4 -23
- package/dist/helpers/index.mjs +5 -5
- package/dist/index.js +317 -250
- package/dist/node/attribute/index.mjs +1 -9
- package/dist/node/attribute/value.mjs +27 -44
- package/dist/node/index.mjs +16 -7
- package/dist/node/value.mjs +41 -24
- package/package.json +5 -4
- package/src/fragment.ts +35 -13
- package/src/helpers/dom.ts +8 -36
- package/src/helpers/index.ts +4 -8
- package/src/models.ts +10 -3
- package/src/node/attribute/index.ts +13 -34
- package/src/node/attribute/value.ts +23 -50
- package/src/node/event.ts +2 -2
- package/src/node/index.ts +26 -10
- package/src/node/value.ts +68 -29
- package/types/helpers/dom.d.ts +3 -5
- package/types/helpers/index.d.ts +3 -3
- package/types/models.d.ts +8 -3
- package/types/node/attribute/index.d.ts +2 -3
- package/types/node/attribute/value.d.ts +2 -2
- package/types/node/event.d.ts +2 -2
- package/types/node/index.d.ts +2 -2
- package/types/node/value.d.ts +2 -1
|
@@ -6,18 +6,11 @@ function getValue(data, original) {
|
|
|
6
6
|
const matches = commentExpression.exec(original ?? "");
|
|
7
7
|
return matches == null ? original : data.values[+matches[1]];
|
|
8
8
|
}
|
|
9
|
-
function isBadAttribute(name, value2) {
|
|
10
|
-
return /^on/i.test(name) || /^(href|src|xlink:href)$/i.test(name) && /(data:text\/html|javascript:)/i.test(value2);
|
|
11
|
-
}
|
|
12
9
|
function mapAttributes(data, element) {
|
|
13
10
|
const attributes = [...element.attributes];
|
|
14
11
|
const { length } = attributes;
|
|
15
12
|
for (let index = 0;index < length; index += 1) {
|
|
16
13
|
const { name, value: value2 } = attributes[index];
|
|
17
|
-
if (isBadAttribute(name, value2)) {
|
|
18
|
-
element.removeAttribute(name);
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
14
|
const actual = getValue(data, value2);
|
|
22
15
|
if (name.startsWith("@")) {
|
|
23
16
|
mapEvent(element, name, actual);
|
|
@@ -38,6 +31,5 @@ function mapValue(element, name, value2) {
|
|
|
38
31
|
}
|
|
39
32
|
var commentExpression = /^<!--abydon\.(\d+)-->$/;
|
|
40
33
|
export {
|
|
41
|
-
mapAttributes
|
|
42
|
-
isBadAttribute
|
|
34
|
+
mapAttributes
|
|
43
35
|
};
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
// src/node/attribute/value.ts
|
|
2
|
-
import {closest} from "@oscarpalmer/atoms/element";
|
|
3
2
|
import {getString} from "@oscarpalmer/atoms/string";
|
|
4
3
|
import {effect, isReactive} from "@oscarpalmer/sentinel";
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import {
|
|
5
|
+
isBooleanAttribute,
|
|
6
|
+
setAttribute as setAttr
|
|
7
|
+
} from "@oscarpalmer/toretto/attribute";
|
|
8
|
+
function setAttribute(element, name, value) {
|
|
9
|
+
element.removeAttribute(name);
|
|
7
10
|
switch (true) {
|
|
8
11
|
case classPattern.test(name):
|
|
9
|
-
setClasses(
|
|
12
|
+
setClasses(element, name, value);
|
|
10
13
|
return;
|
|
11
14
|
case stylePattern.test(name):
|
|
12
|
-
setStyle(
|
|
15
|
+
setStyle(element, name, value);
|
|
13
16
|
return;
|
|
14
17
|
default:
|
|
15
|
-
setValue(
|
|
18
|
+
setValue(element, name, value);
|
|
16
19
|
break;
|
|
17
20
|
}
|
|
18
21
|
}
|
|
19
|
-
function setClasses(
|
|
22
|
+
function setClasses(element, name, value) {
|
|
20
23
|
function update(value2) {
|
|
21
24
|
if (/^(|true)$/.test(getString(value2))) {
|
|
22
|
-
|
|
25
|
+
element.classList.add(...classes);
|
|
23
26
|
} else {
|
|
24
|
-
|
|
27
|
+
element.classList.remove(...classes);
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
const classes = name.slice(6).split(".");
|
|
@@ -33,12 +36,12 @@ function setClasses(element2, name, value) {
|
|
|
33
36
|
update(value);
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
|
-
function setStyle(
|
|
39
|
+
function setStyle(element, name, value) {
|
|
37
40
|
function update(value2) {
|
|
38
41
|
if (value2 == null || value2 === false || value2 === true && unit == null) {
|
|
39
|
-
|
|
42
|
+
element.style.removeProperty(property);
|
|
40
43
|
} else {
|
|
41
|
-
|
|
44
|
+
element.style.setProperty(property, value2 === true ? unit : getString(value2));
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
const [, property, unit] = /^\w+\.([a-z-]+)(?:\.(\w+))?$/i.exec(name) ?? [];
|
|
@@ -53,14 +56,14 @@ function setStyle(element2, name, value) {
|
|
|
53
56
|
update(value);
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
function setValue(
|
|
57
|
-
const callback =
|
|
59
|
+
function setValue(element, name, value) {
|
|
60
|
+
const callback = isBooleanAttribute(name) && name in element ? name === "selected" ? updateSelected : updateProperty : setAttr;
|
|
58
61
|
if (isReactive(value)) {
|
|
59
62
|
effect(() => {
|
|
60
|
-
callback(
|
|
63
|
+
callback(element, name, value.get());
|
|
61
64
|
});
|
|
62
65
|
} else {
|
|
63
|
-
callback(
|
|
66
|
+
callback(element, name, value);
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
69
|
function triggerSelectChange(select) {
|
|
@@ -68,37 +71,17 @@ function triggerSelectChange(select) {
|
|
|
68
71
|
select.dispatchEvent(new Event("change", { bubbles: true }));
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
element2.removeAttribute(name);
|
|
74
|
-
} else {
|
|
75
|
-
element2.setAttribute(name, getString(value));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
function updateProperty(element2, name, value) {
|
|
79
|
-
element2[name] = /^(|true)$/.test(getString(value));
|
|
74
|
+
function updateProperty(element, name, value) {
|
|
75
|
+
element[name] = /^(|true)$/.test(getString(value));
|
|
80
76
|
}
|
|
81
|
-
function updateSelected(
|
|
82
|
-
const select = closest(
|
|
77
|
+
function updateSelected(element, name, value) {
|
|
78
|
+
const select = element.closest("select");
|
|
83
79
|
const options = [...select?.options ?? []];
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
updateProperty(element3, name, value);
|
|
89
|
-
};
|
|
80
|
+
if (select != null && options.includes(element)) {
|
|
81
|
+
triggerSelectChange(select);
|
|
82
|
+
}
|
|
83
|
+
updateProperty(element, name, value);
|
|
90
84
|
}
|
|
91
|
-
var booleanAttributes = new Set([
|
|
92
|
-
"checked",
|
|
93
|
-
"disabled",
|
|
94
|
-
"hidden",
|
|
95
|
-
"inert",
|
|
96
|
-
"multiple",
|
|
97
|
-
"open",
|
|
98
|
-
"readOnly",
|
|
99
|
-
"required",
|
|
100
|
-
"selected"
|
|
101
|
-
]);
|
|
102
85
|
var classPattern = /^class\./;
|
|
103
86
|
var stylePattern = /^style\./;
|
|
104
87
|
export {
|
package/dist/node/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/node/index.ts
|
|
2
2
|
import {isReactive} from "@oscarpalmer/sentinel";
|
|
3
|
-
import {
|
|
3
|
+
import {isFragment, isProperElement} from "../helpers";
|
|
4
4
|
import {createNodes} from "../helpers/dom";
|
|
5
5
|
import {mapAttributes} from "./attribute";
|
|
6
6
|
import {setReactiveNode} from "./value";
|
|
@@ -8,7 +8,7 @@ function mapNode(data, comment) {
|
|
|
8
8
|
const matches = commentExpression.exec(comment.textContent ?? "");
|
|
9
9
|
const value2 = matches == null ? null : data.values[+matches[1]];
|
|
10
10
|
if (value2 != null) {
|
|
11
|
-
mapValue(comment, value2);
|
|
11
|
+
mapValue(data, comment, value2);
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
function mapNodes(data, nodes) {
|
|
@@ -19,7 +19,7 @@ function mapNodes(data, nodes) {
|
|
|
19
19
|
mapNode(data, node);
|
|
20
20
|
continue;
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
22
|
+
if (isProperElement(node)) {
|
|
23
23
|
mapAttributes(data, node);
|
|
24
24
|
}
|
|
25
25
|
if (node.hasChildNodes()) {
|
|
@@ -27,19 +27,28 @@ function mapNodes(data, nodes) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
function mapValue(comment, value2) {
|
|
30
|
+
function mapValue(data, comment, value2) {
|
|
31
31
|
switch (true) {
|
|
32
32
|
case typeof value2 === "function":
|
|
33
|
-
mapValue(comment, value2());
|
|
33
|
+
mapValue(data, comment, value2());
|
|
34
34
|
return;
|
|
35
35
|
case isReactive(value2):
|
|
36
|
-
setReactiveNode(comment, value2);
|
|
36
|
+
setReactiveNode(data, comment, value2);
|
|
37
37
|
break;
|
|
38
38
|
default:
|
|
39
|
-
comment
|
|
39
|
+
replaceComment(data, comment, value2);
|
|
40
40
|
break;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
+
function replaceComment(data, comment, value2) {
|
|
44
|
+
const item = data.items.find((item2) => item2.nodes.includes(comment));
|
|
45
|
+
const nodes = createNodes(value2);
|
|
46
|
+
if (item != null) {
|
|
47
|
+
item.fragment = isFragment(value2) ? value2 : undefined;
|
|
48
|
+
item.nodes = nodes;
|
|
49
|
+
}
|
|
50
|
+
comment.replaceWith(...nodes);
|
|
51
|
+
}
|
|
43
52
|
var commentExpression = /^abydon\.(\d+)$/;
|
|
44
53
|
export {
|
|
45
54
|
mapNodes
|
package/dist/node/value.mjs
CHANGED
|
@@ -2,39 +2,56 @@
|
|
|
2
2
|
import {isNullableOrWhitespace} from "@oscarpalmer/atoms/is";
|
|
3
3
|
import {getString} from "@oscarpalmer/atoms/string";
|
|
4
4
|
import {effect} from "@oscarpalmer/sentinel";
|
|
5
|
-
import {isFragment,
|
|
5
|
+
import {isFragment, isProperNode} from "../helpers";
|
|
6
6
|
import {createNodes, replaceNodes} from "../helpers/dom";
|
|
7
|
-
function
|
|
7
|
+
function setNodes(nodes, comment, text, value) {
|
|
8
|
+
const next = createNodes(value);
|
|
9
|
+
if (nodes == null) {
|
|
10
|
+
if (comment.parentNode != null) {
|
|
11
|
+
replaceNodes([comment], next);
|
|
12
|
+
} else if (text.parentNode != null) {
|
|
13
|
+
replaceNodes([text], next);
|
|
14
|
+
}
|
|
15
|
+
} else {
|
|
16
|
+
replaceNodes(nodes, next);
|
|
17
|
+
}
|
|
18
|
+
return next;
|
|
19
|
+
}
|
|
20
|
+
function setReactiveNode(data, comment, reactive) {
|
|
21
|
+
const item = data.items.find((item2) => item2.nodes.includes(comment));
|
|
8
22
|
const text = new Text;
|
|
9
23
|
let nodes;
|
|
10
24
|
effect(() => {
|
|
11
25
|
const value = reactive.get();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} else if (text.parentNode != null) {
|
|
18
|
-
replaceNodes([text], next);
|
|
19
|
-
}
|
|
20
|
-
} else {
|
|
21
|
-
replaceNodes(nodes, next);
|
|
22
|
-
}
|
|
23
|
-
nodes = next;
|
|
24
|
-
return;
|
|
26
|
+
const valueIsFragment = isFragment(value);
|
|
27
|
+
if (valueIsFragment || isProperNode(value)) {
|
|
28
|
+
nodes = setNodes(nodes, comment, text, value);
|
|
29
|
+
} else {
|
|
30
|
+
nodes = setText(nodes, comment, text, value) ? [text] : undefined;
|
|
25
31
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
replaceNodes(nodes, [isNullable ? comment : text]);
|
|
30
|
-
} else if (isNullable && comment.parentNode == null) {
|
|
31
|
-
text.replaceWith(comment);
|
|
32
|
-
} else if (!isNullable && text.parentNode == null) {
|
|
33
|
-
comment.replaceWith(text);
|
|
32
|
+
if (item != null) {
|
|
33
|
+
item.fragment = valueIsFragment ? value : undefined;
|
|
34
|
+
item.nodes = [...nodes ?? [comment]];
|
|
34
35
|
}
|
|
35
|
-
nodes = undefined;
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
|
+
function setText(nodes, comment, text, value) {
|
|
39
|
+
const isNullable = isNullableOrWhitespace(value);
|
|
40
|
+
text.textContent = isNullable ? "" : getString(value);
|
|
41
|
+
if (nodes != null) {
|
|
42
|
+
replaceNodes(nodes, [isNullable ? comment : text]);
|
|
43
|
+
return !isNullable;
|
|
44
|
+
}
|
|
45
|
+
if (isNullable && comment.parentNode == null) {
|
|
46
|
+
text.replaceWith(comment);
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (!isNullable && text.parentNode == null) {
|
|
50
|
+
comment.replaceWith(text);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
38
55
|
export {
|
|
39
56
|
setReactiveNode
|
|
40
57
|
};
|
package/package.json
CHANGED
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
"url": "https://oscarpalmer.se"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@oscarpalmer/atoms": "^0.
|
|
8
|
-
"@oscarpalmer/sentinel": "^0.23.0"
|
|
7
|
+
"@oscarpalmer/atoms": "^0.71.0",
|
|
8
|
+
"@oscarpalmer/sentinel": "^0.23.0",
|
|
9
|
+
"@oscarpalmer/toretto": "0.12.1"
|
|
9
10
|
},
|
|
10
11
|
"devDependencies": {
|
|
11
12
|
"@biomejs/biome": "^1.8.3",
|
|
12
13
|
"@types/bun": "^1.1.6",
|
|
13
|
-
"bun": "^1.1.
|
|
14
|
+
"bun": "^1.1.24",
|
|
14
15
|
"dts-bundle-generator": "^9.5.1",
|
|
15
16
|
"typescript": "^5.5.4"
|
|
16
17
|
},
|
|
@@ -46,5 +47,5 @@
|
|
|
46
47
|
},
|
|
47
48
|
"type": "module",
|
|
48
49
|
"types": "types/index.d.ts",
|
|
49
|
-
"version": "0.
|
|
50
|
+
"version": "0.9.0"
|
|
50
51
|
}
|
package/src/fragment.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {html} from '@oscarpalmer/toretto/html';
|
|
2
2
|
import {parse} from './html';
|
|
3
|
-
import type {FragmentData} from './models';
|
|
3
|
+
import type {FragmentData, ProperNode} from './models';
|
|
4
4
|
import {mapNodes} from './node';
|
|
5
5
|
|
|
6
6
|
export class Fragment {
|
|
7
|
-
private
|
|
7
|
+
private readonly $fragment = true;
|
|
8
8
|
private readonly data: FragmentData;
|
|
9
9
|
|
|
10
10
|
constructor(strings: TemplateStringsArray, expressions: unknown[]) {
|
|
11
11
|
this.data = {
|
|
12
12
|
expressions,
|
|
13
13
|
strings,
|
|
14
|
-
|
|
14
|
+
items: [],
|
|
15
15
|
values: [],
|
|
16
16
|
};
|
|
17
17
|
}
|
|
@@ -27,30 +27,52 @@ export class Fragment {
|
|
|
27
27
|
* Gets a list of the fragment's nodes
|
|
28
28
|
*/
|
|
29
29
|
get(): Node[] {
|
|
30
|
-
if (this.data.
|
|
30
|
+
if (this.data.items.length === 0) {
|
|
31
31
|
const parsed = parse(this.data);
|
|
32
|
-
const templated = createTemplate(parsed);
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
const templated = html(parsed, {
|
|
34
|
+
sanitiseBooleanAttributes: false,
|
|
35
|
+
});
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
this.data.items.splice(
|
|
38
|
+
0,
|
|
39
|
+
this.data.items.length,
|
|
40
|
+
...templated.map(node => ({
|
|
41
|
+
nodes: [node as ProperNode],
|
|
42
|
+
})),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
mapNodes(
|
|
46
|
+
this.data,
|
|
47
|
+
this.data.items.flatMap(
|
|
48
|
+
item => item.fragment?.get() ?? item.nodes,
|
|
49
|
+
) as ProperNode[],
|
|
50
|
+
);
|
|
37
51
|
}
|
|
38
52
|
|
|
39
|
-
return [
|
|
53
|
+
return [
|
|
54
|
+
...(this.data.items.flatMap(
|
|
55
|
+
item => item.fragment?.get() ?? item.nodes,
|
|
56
|
+
) as ProperNode[]),
|
|
57
|
+
];
|
|
40
58
|
}
|
|
41
59
|
|
|
42
60
|
/**
|
|
43
61
|
* Removes the fragment from the DOM
|
|
44
62
|
*/
|
|
45
63
|
remove(): void {
|
|
46
|
-
const {length} = this.data.
|
|
64
|
+
const {length} = this.data.items;
|
|
47
65
|
|
|
48
66
|
for (let index = 0; index < length; index += 1) {
|
|
49
|
-
const
|
|
67
|
+
const item = this.data.items[index];
|
|
68
|
+
|
|
69
|
+
item.fragment?.remove();
|
|
50
70
|
|
|
51
|
-
node.
|
|
71
|
+
for (const node of item.nodes) {
|
|
72
|
+
node.remove();
|
|
73
|
+
}
|
|
52
74
|
}
|
|
53
75
|
|
|
54
|
-
this.data.
|
|
76
|
+
this.data.items.splice(0, length);
|
|
55
77
|
}
|
|
56
78
|
}
|
package/src/helpers/dom.ts
CHANGED
|
@@ -1,48 +1,20 @@
|
|
|
1
1
|
import {getString} from '@oscarpalmer/atoms/string';
|
|
2
|
-
import type {
|
|
3
|
-
import {isFragment,
|
|
4
|
-
|
|
5
|
-
export function createNodes(value: unknown): FragmentNode[] {
|
|
6
|
-
if (isFragmentNode(value)) {
|
|
7
|
-
return [value];
|
|
8
|
-
}
|
|
2
|
+
import type {ProperNode} from '../models';
|
|
3
|
+
import {isFragment, isProperNode} from './index';
|
|
9
4
|
|
|
5
|
+
export function createNodes(value: unknown): ProperNode[] {
|
|
10
6
|
if (isFragment(value)) {
|
|
11
|
-
return value.get() as
|
|
7
|
+
return value.get() as ProperNode[];
|
|
12
8
|
}
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export function createTemplate(html: string): Node {
|
|
18
|
-
const template = document.createElement('template');
|
|
19
|
-
|
|
20
|
-
template.innerHTML = html;
|
|
21
|
-
|
|
22
|
-
const cloned = template.content.cloneNode(true);
|
|
23
|
-
|
|
24
|
-
const scripts = [
|
|
25
|
-
...(cloned instanceof Element ? cloned.querySelectorAll('script') : []),
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
const {length} = scripts;
|
|
29
|
-
|
|
30
|
-
for (let index = 0; index < length; index += 1) {
|
|
31
|
-
scripts[index].remove();
|
|
10
|
+
if (isProperNode(value)) {
|
|
11
|
+
return [value];
|
|
32
12
|
}
|
|
33
13
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return cloned;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function getNodes(node: Node): Node[] {
|
|
40
|
-
return /^documentfragment$/i.test(node.constructor.name)
|
|
41
|
-
? [...node.childNodes]
|
|
42
|
-
: [node];
|
|
14
|
+
return [new Text(getString(value))];
|
|
43
15
|
}
|
|
44
16
|
|
|
45
|
-
export function replaceNodes(from:
|
|
17
|
+
export function replaceNodes(from: ProperNode[], to: ProperNode[]): void {
|
|
46
18
|
const {length} = from;
|
|
47
19
|
|
|
48
20
|
for (let index = 0; index < length; index += 1) {
|
package/src/helpers/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {Fragment} from '../fragment';
|
|
2
|
-
import type {
|
|
2
|
+
import type {ProperElement, ProperNode} from '../models';
|
|
3
3
|
|
|
4
4
|
export function isFragment(value: unknown): value is Fragment {
|
|
5
5
|
return (
|
|
@@ -10,14 +10,10 @@ export function isFragment(value: unknown): value is Fragment {
|
|
|
10
10
|
);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function
|
|
13
|
+
export function isProperElement(value: unknown): value is ProperElement {
|
|
14
14
|
return value instanceof HTMLElement || value instanceof SVGElement;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export function
|
|
18
|
-
return
|
|
19
|
-
value instanceof Comment ||
|
|
20
|
-
value instanceof Element ||
|
|
21
|
-
value instanceof Text
|
|
22
|
-
);
|
|
17
|
+
export function isProperNode(value: unknown): value is ProperNode {
|
|
18
|
+
return value instanceof CharacterData || value instanceof Element;
|
|
23
19
|
}
|
package/src/models.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
import type {Fragment} from './fragment';
|
|
2
|
+
|
|
1
3
|
export type FragmentData = {
|
|
2
4
|
expressions: unknown[];
|
|
3
|
-
|
|
5
|
+
items: FragmentItem[];
|
|
4
6
|
strings: TemplateStringsArray;
|
|
5
7
|
values: unknown[];
|
|
6
8
|
};
|
|
7
9
|
|
|
8
|
-
export type
|
|
10
|
+
export type FragmentItem = {
|
|
11
|
+
fragment?: Fragment;
|
|
12
|
+
nodes: ProperNode[];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type ProperElement = HTMLElement | SVGElement;
|
|
9
16
|
|
|
10
|
-
export type
|
|
17
|
+
export type ProperNode = CharacterData | Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {isReactive} from '@oscarpalmer/sentinel';
|
|
2
|
-
import type {FragmentData,
|
|
2
|
+
import type {FragmentData, ProperElement} from '../../models';
|
|
3
3
|
import {mapEvent} from '../event';
|
|
4
4
|
import {setAttribute} from './value';
|
|
5
5
|
|
|
@@ -11,45 +11,24 @@ function getValue(data: FragmentData, original: string): unknown {
|
|
|
11
11
|
return matches == null ? original : data.values[+matches[1]];
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
(/^(href|src|xlink:href)$/i.test(name) &&
|
|
18
|
-
/(data:text\/html|javascript:)/i.test(value))
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function mapAttributes(
|
|
23
|
-
data: FragmentData,
|
|
24
|
-
element: FragmentElement,
|
|
25
|
-
): void {
|
|
26
|
-
const attributes = [...element.attributes];
|
|
27
|
-
const {length} = attributes;
|
|
28
|
-
|
|
29
|
-
for (let index = 0; index < length; index += 1) {
|
|
30
|
-
const {name, value} = attributes[index];
|
|
14
|
+
export function mapAttributes(data: FragmentData, element: ProperElement): void {
|
|
15
|
+
const attributes = [...element.attributes];
|
|
16
|
+
const {length} = attributes;
|
|
31
17
|
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
for (let index = 0; index < length; index += 1) {
|
|
19
|
+
const {name, value} = attributes[index];
|
|
34
20
|
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const actual = getValue(data, value);
|
|
21
|
+
const actual = getValue(data, value);
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
23
|
+
if (name.startsWith('@')) {
|
|
24
|
+
mapEvent(element, name, actual);
|
|
25
|
+
} else if (name.includes('.') || isReactive(actual)) {
|
|
26
|
+
mapValue(element, name, actual);
|
|
27
|
+
}
|
|
44
28
|
}
|
|
45
29
|
}
|
|
46
|
-
}
|
|
47
30
|
|
|
48
|
-
function mapValue(
|
|
49
|
-
element: FragmentElement,
|
|
50
|
-
name: string,
|
|
51
|
-
value: unknown,
|
|
52
|
-
): void {
|
|
31
|
+
function mapValue(element: ProperElement, name: string, value: unknown): void {
|
|
53
32
|
switch (true) {
|
|
54
33
|
case typeof value === 'function':
|
|
55
34
|
mapValue(element, name, value());
|