@esportsplus/template 0.15.19 → 0.16.1
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.
Potentially problematic release.
This version of @esportsplus/template might be problematic. Click here for more details.
- package/build/attributes.d.ts +1 -3
- package/build/attributes.js +3 -14
- package/build/constants.d.ts +2 -1
- package/build/constants.js +3 -1
- package/build/html/cache.d.ts +2 -2
- package/build/html/cache.js +23 -13
- package/build/html/hydrate.d.ts +5 -3
- package/build/html/hydrate.js +62 -40
- package/build/render.d.ts +1 -1
- package/build/slot.d.ts +9 -9
- package/build/slot.js +105 -100
- package/build/types.d.ts +8 -7
- package/package.json +2 -2
- package/src/attributes.ts +3 -19
- package/src/constants.ts +7 -0
- package/src/html/cache.ts +28 -16
- package/src/html/hydrate.ts +80 -45
- package/src/slot.ts +119 -128
- package/src/types.ts +8 -4
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "ICJR",
|
|
3
3
|
"dependencies": {
|
|
4
4
|
"@esportsplus/queue": "^0.1.0",
|
|
5
|
-
"@esportsplus/reactivity": "^0.
|
|
5
|
+
"@esportsplus/reactivity": "^0.13.2",
|
|
6
6
|
"@esportsplus/tasks": "^0.2.1",
|
|
7
7
|
"@esportsplus/utilities": "^0.22.1"
|
|
8
8
|
},
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"private": false,
|
|
15
15
|
"type": "module",
|
|
16
16
|
"types": "./build/index.d.ts",
|
|
17
|
-
"version": "0.
|
|
17
|
+
"version": "0.16.1",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc && tsc-alias",
|
|
20
20
|
"-": "-"
|
package/src/attributes.ts
CHANGED
|
@@ -9,8 +9,6 @@ import event from './event';
|
|
|
9
9
|
|
|
10
10
|
const EFFECT_KEY = Symbol();
|
|
11
11
|
|
|
12
|
-
const HYDRATE_KEY = Symbol();
|
|
13
|
-
|
|
14
12
|
const STORE_KEY = Symbol();
|
|
15
13
|
|
|
16
14
|
const UPDATES_KEY = Symbol();
|
|
@@ -216,7 +214,7 @@ function update(
|
|
|
216
214
|
}
|
|
217
215
|
|
|
218
216
|
if (state === STATE_HYDRATING) {
|
|
219
|
-
(
|
|
217
|
+
attribute(context.element, name, value);
|
|
220
218
|
}
|
|
221
219
|
else {
|
|
222
220
|
context.updates[name] = value;
|
|
@@ -233,20 +231,6 @@ function update(
|
|
|
233
231
|
}
|
|
234
232
|
|
|
235
233
|
|
|
236
|
-
const apply = (element: Element) => {
|
|
237
|
-
let attributes = element[HYDRATE_KEY] as Record<PropertyKey, unknown> | undefined;
|
|
238
|
-
|
|
239
|
-
if (!attributes) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
for (let key in attributes) {
|
|
244
|
-
attribute(element, key, attributes[key]);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
delete element[HYDRATE_KEY];
|
|
248
|
-
};
|
|
249
|
-
|
|
250
234
|
const spread = function (element: Element, value: Attributes | Attributes[]) {
|
|
251
235
|
let cache = (element[STORE_KEY] ??= { [UPDATES_KEY]: {} }) as Record<PropertyKey, unknown>,
|
|
252
236
|
context = {
|
|
@@ -273,5 +257,5 @@ const spread = function (element: Element, value: Attributes | Attributes[]) {
|
|
|
273
257
|
};
|
|
274
258
|
|
|
275
259
|
|
|
276
|
-
export default {
|
|
277
|
-
export {
|
|
260
|
+
export default { spread };
|
|
261
|
+
export { spread };
|
package/src/constants.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { fragment } from './utilities';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const EMPTY_FRAGMENT = fragment('');
|
|
5
|
+
|
|
6
|
+
|
|
1
7
|
const NODE_CLOSING = 1;
|
|
2
8
|
|
|
3
9
|
const NODE_COMMENT = 2;
|
|
@@ -51,6 +57,7 @@ const SLOT_MARKER_LENGTH = SLOT_MARKER.length;
|
|
|
51
57
|
|
|
52
58
|
|
|
53
59
|
export {
|
|
60
|
+
EMPTY_FRAGMENT,
|
|
54
61
|
NODE_CLOSING, NODE_ELEMENT, NODE_SLOT, NODE_VOID, NODE_WHITELIST,
|
|
55
62
|
REGEX_EMPTY_TEXT_NODES, REGEX_SLOT_NODES,
|
|
56
63
|
RENDERABLE, RENDERABLE_REACTIVE, RENDERABLE_TEMPLATE,
|
package/src/html/cache.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
NODE_CLOSING, NODE_ELEMENT, NODE_SLOT, NODE_VOID, NODE_WHITELIST, REGEX_EMPTY_TEXT_NODES,
|
|
3
3
|
REGEX_SLOT_NODES, SLOT_HTML, SLOT_MARKER, SLOT_MARKER_LENGTH
|
|
4
4
|
} from '~/constants';
|
|
5
|
-
import {
|
|
5
|
+
import { Template } from '~/types';
|
|
6
6
|
import { firstChild, firstElementChild, fragment, nextElementSibling, nextSibling } from '~/utilities';
|
|
7
7
|
import { spread } from '~/attributes';
|
|
8
8
|
import s from '~/slot';
|
|
@@ -11,8 +11,10 @@ import s from '~/slot';
|
|
|
11
11
|
let cache = new WeakMap<TemplateStringsArray, Template>();
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
function build(literals: TemplateStringsArray
|
|
15
|
-
|
|
14
|
+
function build(literals: TemplateStringsArray) {
|
|
15
|
+
let n = literals.length - 1;
|
|
16
|
+
|
|
17
|
+
if (n === 0) {
|
|
16
18
|
return set(literals, literals[0]);
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -25,12 +27,11 @@ function build(literals: TemplateStringsArray, values: unknown[]) {
|
|
|
25
27
|
levels = [{
|
|
26
28
|
children: 0,
|
|
27
29
|
elements: 0,
|
|
28
|
-
path: [] as NonNullable<Template['slots']>[
|
|
30
|
+
path: [] as NonNullable<Template['slots']>[number]['path']['parent']
|
|
29
31
|
}],
|
|
30
32
|
parsed = html.split(SLOT_MARKER),
|
|
31
33
|
slot = 0,
|
|
32
|
-
slots: Template['slots'] = []
|
|
33
|
-
total = values.length;
|
|
34
|
+
slots: Template['slots'] = [];
|
|
34
35
|
|
|
35
36
|
for (let match of html.matchAll(REGEX_SLOT_NODES)) {
|
|
36
37
|
let parent = levels[level],
|
|
@@ -42,16 +43,23 @@ function build(literals: TemplateStringsArray, values: unknown[]) {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
if (type === NODE_ELEMENT || type === NODE_VOID) {
|
|
45
|
-
let attr = match[2]
|
|
46
|
+
let attr = match[2],
|
|
47
|
+
path = parent.path.length
|
|
48
|
+
? methods(parent.elements, parent.path, firstElementChild, nextElementSibling)
|
|
49
|
+
: methods(parent.children, [], firstChild, nextSibling);
|
|
46
50
|
|
|
47
51
|
if (attr) {
|
|
48
52
|
let i = attr.indexOf(SLOT_MARKER),
|
|
49
|
-
|
|
53
|
+
p = {
|
|
54
|
+
absolute: path,
|
|
55
|
+
parent: parent.path,
|
|
56
|
+
relative: path.slice(parent.path.length)
|
|
57
|
+
};
|
|
50
58
|
|
|
51
59
|
while (i !== -1) {
|
|
52
60
|
slots.push({
|
|
53
61
|
fn: spread,
|
|
54
|
-
path,
|
|
62
|
+
path: p,
|
|
55
63
|
slot
|
|
56
64
|
});
|
|
57
65
|
|
|
@@ -64,24 +72,28 @@ function build(literals: TemplateStringsArray, values: unknown[]) {
|
|
|
64
72
|
levels[++level] = {
|
|
65
73
|
children: 0,
|
|
66
74
|
elements: 0,
|
|
67
|
-
path
|
|
68
|
-
? methods(parent.elements, parent.path, firstElementChild, nextElementSibling)
|
|
69
|
-
: methods(parent.children, [], firstChild, nextSibling)
|
|
75
|
+
path
|
|
70
76
|
};
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
parent.elements++;
|
|
74
80
|
}
|
|
75
81
|
else if (type === NODE_SLOT) {
|
|
82
|
+
let relative = methods(parent.children, [], firstChild, nextSibling);
|
|
83
|
+
|
|
76
84
|
buffer += parsed[slot] + SLOT_HTML;
|
|
77
85
|
slots.push({
|
|
78
86
|
fn: s,
|
|
79
|
-
path:
|
|
87
|
+
path: {
|
|
88
|
+
absolute: [...parent.path, ...relative],
|
|
89
|
+
parent: parent.path,
|
|
90
|
+
relative
|
|
91
|
+
},
|
|
80
92
|
slot: slot++
|
|
81
93
|
});
|
|
82
94
|
}
|
|
83
95
|
|
|
84
|
-
if (slot ===
|
|
96
|
+
if (slot === n) {
|
|
85
97
|
buffer += parsed[slot];
|
|
86
98
|
break;
|
|
87
99
|
}
|
|
@@ -125,8 +137,8 @@ function set(literals: TemplateStringsArray, html: string, slots: Template['slot
|
|
|
125
137
|
}
|
|
126
138
|
|
|
127
139
|
|
|
128
|
-
const get =
|
|
129
|
-
return cache.get(literals) || build(literals
|
|
140
|
+
const get = (literals: TemplateStringsArray) => {
|
|
141
|
+
return cache.get(literals) || build(literals);
|
|
130
142
|
};
|
|
131
143
|
|
|
132
144
|
|
package/src/html/hydrate.ts
CHANGED
|
@@ -1,90 +1,125 @@
|
|
|
1
1
|
import { root } from '@esportsplus/reactivity';
|
|
2
|
-
import {
|
|
2
|
+
import { EMPTY_FRAGMENT } from '~/constants';
|
|
3
|
+
import { Elements, Fragment, RenderableReactive, RenderableTemplate } from '~/types';
|
|
3
4
|
import { Slot } from '~/slot';
|
|
4
|
-
import { cloneNode
|
|
5
|
-
import { apply } from '~/attributes';
|
|
5
|
+
import { cloneNode } from '~/utilities';
|
|
6
6
|
import cache from './cache';
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
function reactive<T>(renderable: RenderableReactive<T>, slot: Slot) {
|
|
9
|
+
function reactive<T>(elements: Elements[], fragment: Fragment, renderable: RenderableReactive<T>, slot: Slot) {
|
|
10
10
|
let array = renderable.values,
|
|
11
11
|
factory = renderable.template,
|
|
12
12
|
refresh = () => {
|
|
13
|
-
|
|
13
|
+
root(() => array.map(template));
|
|
14
|
+
|
|
15
|
+
slot.clear();
|
|
16
|
+
slot.anchor().after(fragment);
|
|
17
|
+
slot.nodes = elements;
|
|
18
|
+
|
|
19
|
+
reset();
|
|
20
|
+
},
|
|
21
|
+
reset = () => {
|
|
22
|
+
elements = [];
|
|
23
|
+
fragment = cloneNode.call(EMPTY_FRAGMENT);
|
|
14
24
|
},
|
|
15
25
|
template = function(data, i) {
|
|
16
|
-
|
|
26
|
+
hydrate(elements, fragment, factory.call(this, data, i));
|
|
27
|
+
} as (this: typeof array, ...args: Parameters<Parameters<typeof array['map']>[0]>) => void;
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
array.on('clear', () => slot.clear());
|
|
30
|
+
array.on('pop', () => slot.pop());
|
|
31
|
+
array.on('reverse', refresh);
|
|
32
|
+
array.on('shift', () => slot.shift());
|
|
33
|
+
array.on('sort', refresh);
|
|
20
34
|
|
|
21
|
-
array.on('pop', () => {
|
|
22
|
-
slot.pop();
|
|
23
|
-
});
|
|
24
35
|
array.on('push', ({ items }) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
let anchor = slot.anchor();
|
|
37
|
+
|
|
38
|
+
elements = slot.nodes;
|
|
39
|
+
|
|
40
|
+
root(() => array.map(template, array.length - items.length));
|
|
41
|
+
|
|
42
|
+
anchor.after(fragment);
|
|
43
|
+
reset();
|
|
30
44
|
});
|
|
31
|
-
array.on('sort', refresh);
|
|
32
45
|
array.on('splice', ({ deleteCount: d, items: i, start: s }) => {
|
|
33
|
-
|
|
46
|
+
if (array.length === 0) {
|
|
47
|
+
slot.clear();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
root(() => array.map(template, s, i.length))
|
|
52
|
+
|
|
53
|
+
slot.splice(s, d, fragment, ...elements);
|
|
54
|
+
reset();
|
|
34
55
|
});
|
|
35
56
|
array.on('unshift', ({ items }) => {
|
|
36
|
-
|
|
57
|
+
root(() => array.map(template, 0, items.length))
|
|
58
|
+
|
|
59
|
+
slot.unshift(fragment, ...elements);
|
|
60
|
+
reset();
|
|
37
61
|
});
|
|
38
62
|
|
|
39
|
-
|
|
63
|
+
root(() => array.map(template));
|
|
64
|
+
reset();
|
|
40
65
|
}
|
|
41
66
|
|
|
42
|
-
function hydrate<T>(
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
slots = template.slots;
|
|
67
|
+
function hydrate<T>(elements: Elements[] | null, fragment: Fragment, renderable: RenderableTemplate<T>) {
|
|
68
|
+
let { fragment: frag, slots } = cache.get(renderable.literals),
|
|
69
|
+
clone = cloneNode.call(frag, true);
|
|
46
70
|
|
|
47
71
|
if (slots !== null) {
|
|
48
72
|
let node,
|
|
49
|
-
|
|
73
|
+
nodePath,
|
|
74
|
+
parent,
|
|
75
|
+
parentPath,
|
|
50
76
|
values = renderable.values;
|
|
51
77
|
|
|
52
|
-
for (let i = slots.length
|
|
53
|
-
let { fn, path, slot } = slots[i]
|
|
78
|
+
for (let i = 0, n = slots.length; i < n; i++) {
|
|
79
|
+
let { fn, path, slot } = slots[i],
|
|
80
|
+
pp = path.parent,
|
|
81
|
+
pr = path.relative;
|
|
82
|
+
|
|
83
|
+
if (pp !== parentPath) {
|
|
84
|
+
if (pp === nodePath) {
|
|
85
|
+
parent = node;
|
|
86
|
+
parentPath = nodePath;
|
|
54
87
|
|
|
55
|
-
|
|
56
|
-
if (node) {
|
|
57
|
-
apply(node);
|
|
88
|
+
nodePath = undefined;
|
|
58
89
|
}
|
|
90
|
+
else {
|
|
91
|
+
parent = clone;
|
|
92
|
+
parentPath = pp;
|
|
59
93
|
|
|
60
|
-
|
|
61
|
-
|
|
94
|
+
for (let o = 0, j = pp.length; o < j; o++) {
|
|
95
|
+
parent = pp[o].call(parent);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (pr !== nodePath) {
|
|
101
|
+
node = parent;
|
|
102
|
+
nodePath = path.absolute;
|
|
62
103
|
|
|
63
|
-
for (let o = 0, j =
|
|
64
|
-
node =
|
|
104
|
+
for (let o = 0, j = pr.length; o < j; o++) {
|
|
105
|
+
node = pr[o].call(node);
|
|
65
106
|
}
|
|
66
107
|
}
|
|
67
108
|
|
|
68
109
|
// @ts-ignore
|
|
69
110
|
fn(node, values[slot]);
|
|
70
111
|
}
|
|
71
|
-
|
|
72
|
-
apply(node);
|
|
73
112
|
}
|
|
74
113
|
|
|
75
|
-
|
|
76
|
-
elements.push(
|
|
114
|
+
if (elements) {
|
|
115
|
+
elements.push([...clone.childNodes] as Elements);
|
|
77
116
|
}
|
|
78
117
|
|
|
79
|
-
|
|
118
|
+
fragment.appendChild(clone)
|
|
80
119
|
}
|
|
81
120
|
|
|
82
121
|
|
|
83
122
|
export default {
|
|
84
|
-
reactive
|
|
85
|
-
|
|
86
|
-
},
|
|
87
|
-
static: <T>(renderable: RenderableTemplate<T>) => {
|
|
88
|
-
return hydrate(renderable, renderable.template || (renderable.template = cache.get(renderable)));
|
|
89
|
-
}
|
|
123
|
+
reactive,
|
|
124
|
+
static: hydrate
|
|
90
125
|
};
|