@esportsplus/template 0.18.0 → 0.19.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.
Potentially problematic release.
This version of @esportsplus/template might be problematic. Click here for more details.
- package/build/attributes.js +2 -3
- package/build/constants.d.ts +2 -9
- package/build/constants.js +2 -9
- package/build/html/index.d.ts +3 -2106
- package/build/html/index.js +33 -7
- package/build/html/parser.js +9 -5
- package/build/index.d.ts +1 -1
- package/build/slot/effect.js +13 -13
- package/build/slot/index.js +4 -2
- package/build/slot/reactive.d.ts +2 -2
- package/build/slot/reactive.js +14 -12
- package/build/slot/render.js +22 -66
- package/build/types.d.ts +4 -12
- package/build/utilities/fragment.js +5 -5
- package/build/utilities/node.d.ts +2 -1
- package/build/utilities/node.js +2 -1
- package/build/utilities/text.d.ts +1 -2
- package/package.json +2 -2
- package/src/attributes.ts +21 -25
- package/src/constants.ts +2 -19
- package/src/html/index.ts +49 -10
- package/src/html/parser.ts +11 -5
- package/src/index.ts +1 -1
- package/src/slot/cleanup.ts +1 -2
- package/src/slot/effect.ts +27 -30
- package/src/slot/index.ts +4 -3
- package/src/slot/reactive.ts +16 -16
- package/src/slot/render.ts +25 -92
- package/src/types.ts +5 -18
- package/src/utilities/fragment.ts +6 -7
- package/src/utilities/node.ts +3 -0
- package/src/utilities/text.ts +1 -2
- package/build/html/hydrate.d.ts +0 -3
- package/build/html/hydrate.js +0 -34
- package/src/html/hydrate.ts +0 -53
package/build/html/index.js
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
|
-
import { RENDERABLE,
|
|
2
|
-
import
|
|
1
|
+
import { RENDERABLE, RENDERABLE_HTML_REACTIVE_ARRAY } from '../constants.js';
|
|
2
|
+
import { cloneNode } from '../utilities/node.js';
|
|
3
3
|
import parser from './parser.js';
|
|
4
4
|
const html = (literals, ...values) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
let { fragment, slots } = parser.parse(literals);
|
|
6
|
+
fragment = cloneNode.call(fragment, true);
|
|
7
|
+
if (slots !== null) {
|
|
8
|
+
let node, nodePath, parent, parentPath;
|
|
9
|
+
for (let i = 0, n = slots.length; i < n; i++) {
|
|
10
|
+
let { fn, path, slot } = slots[i], pp = path.parent, pr = path.relative;
|
|
11
|
+
if (pp !== parentPath) {
|
|
12
|
+
if (pp === nodePath) {
|
|
13
|
+
parent = node;
|
|
14
|
+
parentPath = nodePath;
|
|
15
|
+
nodePath = undefined;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
parent = fragment;
|
|
19
|
+
parentPath = pp;
|
|
20
|
+
for (let i = 0, n = pp.length; i < n; i++) {
|
|
21
|
+
parent = pp[i].call(parent);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (pr !== nodePath) {
|
|
26
|
+
node = parent;
|
|
27
|
+
nodePath = path.absolute;
|
|
28
|
+
for (let i = 0, n = pr.length; i < n; i++) {
|
|
29
|
+
node = pr[i].call(node);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
fn(node, values[slot]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return fragment;
|
|
10
36
|
};
|
|
11
37
|
html.reactive = (array, template) => {
|
|
12
38
|
return {
|
package/build/html/parser.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { NODE_CLOSING, NODE_ELEMENT, NODE_SLOT, NODE_VOID, NODE_WHITELIST, REGEX_EMPTY_TEXT_NODES, REGEX_SLOT_NODES, SLOT_HTML, SLOT_MARKER, SLOT_MARKER_LENGTH } from '../constants.js';
|
|
2
2
|
import { firstElementChild, nextElementSibling } from '../utilities/element.js';
|
|
3
|
-
import { fragment } from '../utilities/fragment.js';
|
|
4
3
|
import { firstChild, nextSibling } from '../utilities/node.js';
|
|
5
4
|
import { spread } from '../attributes.js';
|
|
5
|
+
import { fragment } from '../utilities/fragment.js';
|
|
6
6
|
import s from '../slot/index.js';
|
|
7
7
|
let cache = new WeakMap();
|
|
8
8
|
function build(literals) {
|
|
@@ -87,16 +87,20 @@ function methods(children, copy, first, next) {
|
|
|
87
87
|
return methods;
|
|
88
88
|
}
|
|
89
89
|
function set(literals, html, slots = null) {
|
|
90
|
-
let
|
|
90
|
+
let value = {
|
|
91
91
|
fragment: fragment(html),
|
|
92
92
|
html,
|
|
93
93
|
literals,
|
|
94
94
|
slots
|
|
95
95
|
};
|
|
96
|
-
cache.set(literals,
|
|
97
|
-
return
|
|
96
|
+
cache.set(literals, value);
|
|
97
|
+
return value;
|
|
98
98
|
}
|
|
99
99
|
const parse = (literals) => {
|
|
100
|
-
|
|
100
|
+
let result = cache.get(literals);
|
|
101
|
+
if (result === undefined) {
|
|
102
|
+
result = build(literals);
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
101
105
|
};
|
|
102
106
|
export default { parse };
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as html } from './html/index.js';
|
|
2
2
|
export { default as render } from './render.js';
|
|
3
3
|
export { default as svg } from './svg.js';
|
|
4
|
-
export type { Attributes, Element,
|
|
4
|
+
export type { Attributes, Element, Renderable, RenderableValue } from './types.js';
|
package/build/slot/effect.js
CHANGED
|
@@ -2,17 +2,18 @@ import { effect } from '@esportsplus/reactivity';
|
|
|
2
2
|
import { STATE_HYDRATING, STATE_NONE } from '../constants.js';
|
|
3
3
|
import { firstChild, lastChild, nodeValue } from '../utilities/node.js';
|
|
4
4
|
import { raf } from '../utilities/queue.js';
|
|
5
|
-
import { ondisconnect } from '../slot/cleanup.js';
|
|
6
5
|
import { remove } from './cleanup.js';
|
|
7
6
|
import text from '../utilities/text.js';
|
|
8
7
|
import render from './render.js';
|
|
9
8
|
function update(anchor, value) {
|
|
10
|
-
let type = typeof value;
|
|
11
9
|
if (this.group) {
|
|
12
10
|
remove([this.group]);
|
|
13
11
|
this.group = undefined;
|
|
14
12
|
}
|
|
15
|
-
if (value == null ||
|
|
13
|
+
if (value == null || value === false) {
|
|
14
|
+
value = '';
|
|
15
|
+
}
|
|
16
|
+
if (typeof value !== 'object') {
|
|
16
17
|
let textnode = this.textnode;
|
|
17
18
|
if (textnode) {
|
|
18
19
|
nodeValue.call(textnode, String(value));
|
|
@@ -25,15 +26,14 @@ function update(anchor, value) {
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
else {
|
|
28
|
-
let fragment = render(anchor, value);
|
|
29
|
-
if (
|
|
30
|
-
|
|
29
|
+
let fragment = render(anchor, value), head = firstChild.call(fragment);
|
|
30
|
+
if (head) {
|
|
31
|
+
this.group = {
|
|
32
|
+
head,
|
|
33
|
+
tail: lastChild.call(fragment)
|
|
34
|
+
};
|
|
35
|
+
anchor.after(fragment);
|
|
31
36
|
}
|
|
32
|
-
this.group = {
|
|
33
|
-
head: firstChild.call(fragment),
|
|
34
|
-
tail: lastChild.call(fragment)
|
|
35
|
-
};
|
|
36
|
-
anchor.after(fragment);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
export default (anchor, fn) => {
|
|
@@ -41,7 +41,7 @@ export default (anchor, fn) => {
|
|
|
41
41
|
group: undefined,
|
|
42
42
|
textnode: undefined
|
|
43
43
|
}, state = STATE_HYDRATING;
|
|
44
|
-
|
|
44
|
+
effect(() => {
|
|
45
45
|
let value = fn();
|
|
46
46
|
if (state === STATE_HYDRATING) {
|
|
47
47
|
update.call(context, anchor, value);
|
|
@@ -52,5 +52,5 @@ export default (anchor, fn) => {
|
|
|
52
52
|
update.call(context, anchor, value);
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
-
})
|
|
55
|
+
});
|
|
56
56
|
};
|
package/build/slot/index.js
CHANGED
|
@@ -2,7 +2,9 @@ import effect from './effect.js';
|
|
|
2
2
|
import render from './render.js';
|
|
3
3
|
export default (anchor, value) => {
|
|
4
4
|
if (typeof value === 'function') {
|
|
5
|
-
|
|
5
|
+
effect(anchor, value);
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
anchor.after(render(anchor, value));
|
|
6
9
|
}
|
|
7
|
-
anchor.after(render(anchor, value));
|
|
8
10
|
};
|
package/build/slot/reactive.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default: (anchor: Element, renderable: RenderableReactive) =>
|
|
1
|
+
import { RenderableReactive } from '../types.js';
|
|
2
|
+
declare const _default: (anchor: Element, renderable: RenderableReactive) => Node;
|
|
3
3
|
export default _default;
|
package/build/slot/reactive.js
CHANGED
|
@@ -2,45 +2,47 @@ import { root } from '@esportsplus/reactivity';
|
|
|
2
2
|
import { EMPTY_FRAGMENT } from '../constants.js';
|
|
3
3
|
import { append } from '../utilities/fragment.js';
|
|
4
4
|
import { cloneNode, firstChild, lastChild } from '../utilities/node.js';
|
|
5
|
-
import { remove } from './cleanup.js';
|
|
5
|
+
import { ondisconnect, remove } from './cleanup.js';
|
|
6
6
|
class ReactiveArraySlot {
|
|
7
7
|
array;
|
|
8
|
-
fragment
|
|
8
|
+
fragment;
|
|
9
9
|
marker;
|
|
10
10
|
nodes = [];
|
|
11
11
|
template;
|
|
12
12
|
constructor(anchor, array, template) {
|
|
13
|
-
let fragment = this.fragment;
|
|
13
|
+
let fragment = this.fragment = cloneNode.call(EMPTY_FRAGMENT);
|
|
14
14
|
this.array = array;
|
|
15
15
|
this.marker = anchor;
|
|
16
16
|
this.template = function (data, i) {
|
|
17
|
-
let frag =
|
|
17
|
+
let dispose, frag = root((d) => {
|
|
18
|
+
dispose = d;
|
|
19
|
+
return template.call(this, data, i);
|
|
20
|
+
}), group = {
|
|
18
21
|
head: firstChild.call(frag),
|
|
19
22
|
tail: lastChild.call(frag)
|
|
20
23
|
};
|
|
21
24
|
append.call(fragment, frag);
|
|
25
|
+
ondisconnect(group.head, dispose);
|
|
22
26
|
return group;
|
|
23
27
|
};
|
|
24
|
-
let render = () => {
|
|
25
|
-
root(() => this.render());
|
|
26
|
-
};
|
|
27
28
|
array.on('clear', () => this.clear());
|
|
28
|
-
array.on('reverse',
|
|
29
|
+
array.on('reverse', () => {
|
|
30
|
+
root(() => this.render());
|
|
31
|
+
});
|
|
29
32
|
array.on('pop', () => this.pop());
|
|
30
33
|
array.on('push', ({ items }) => {
|
|
31
34
|
root(() => this.push(items));
|
|
32
35
|
});
|
|
33
36
|
array.on('shift', () => this.shift());
|
|
34
|
-
array.on('sort',
|
|
37
|
+
array.on('sort', () => {
|
|
38
|
+
root(() => this.render());
|
|
39
|
+
});
|
|
35
40
|
array.on('splice', ({ deleteCount, items, start }) => {
|
|
36
41
|
root(() => this.splice(start, deleteCount, ...items));
|
|
37
42
|
});
|
|
38
43
|
array.on('unshift', ({ items }) => {
|
|
39
44
|
root(() => this.unshift(items));
|
|
40
45
|
});
|
|
41
|
-
if (array.length) {
|
|
42
|
-
render();
|
|
43
|
-
}
|
|
44
46
|
}
|
|
45
47
|
get length() {
|
|
46
48
|
return this.nodes.length;
|
package/build/slot/render.js
CHANGED
|
@@ -1,81 +1,37 @@
|
|
|
1
1
|
import { isArray } from '@esportsplus/utilities';
|
|
2
|
-
import { EMPTY_FRAGMENT, RENDERABLE
|
|
3
|
-
import { cloneNode } from '../utilities/node.js';
|
|
2
|
+
import { EMPTY_FRAGMENT, RENDERABLE } from '../constants.js';
|
|
3
|
+
import { cloneNode, lastChild } from '../utilities/node.js';
|
|
4
4
|
import { append } from '../utilities/fragment.js';
|
|
5
5
|
import text from '../utilities/text.js';
|
|
6
6
|
import reactive from './reactive.js';
|
|
7
|
-
function
|
|
8
|
-
if (input
|
|
9
|
-
return
|
|
7
|
+
export default function render(anchor, input) {
|
|
8
|
+
if (input == null || input === false || input === '') {
|
|
9
|
+
return EMPTY_FRAGMENT;
|
|
10
10
|
}
|
|
11
11
|
if (typeof input !== 'object') {
|
|
12
|
-
return
|
|
12
|
+
return text(input);
|
|
13
|
+
}
|
|
14
|
+
if ('nodeType' in input) {
|
|
15
|
+
return input;
|
|
13
16
|
}
|
|
14
17
|
if (RENDERABLE in input) {
|
|
15
|
-
return input
|
|
18
|
+
return reactive(anchor, input);
|
|
16
19
|
}
|
|
17
20
|
if (isArray(input)) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (nodeType !== undefined) {
|
|
25
|
-
return RENDERABLE_NODE;
|
|
21
|
+
let fragment = cloneNode.call(EMPTY_FRAGMENT);
|
|
22
|
+
for (let i = 0, n = input.length; i < n; i++) {
|
|
23
|
+
append.call(fragment, render(anchor, input[i]));
|
|
24
|
+
anchor = lastChild.call(fragment);
|
|
25
|
+
}
|
|
26
|
+
return fragment;
|
|
26
27
|
}
|
|
27
28
|
if (input instanceof NodeList) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let t = type(input);
|
|
34
|
-
switch (t) {
|
|
35
|
-
case RENDERABLE_HTML_REACTIVE_ARRAY:
|
|
36
|
-
throw new Error('@esportsplus/template: reactive arrays cannot be defined within an slot array value');
|
|
37
|
-
case RENDERABLE_VOID:
|
|
38
|
-
return;
|
|
39
|
-
case RENDERABLE_ARRAY:
|
|
40
|
-
for (let i = 0, n = input.length; i < n; i++) {
|
|
41
|
-
loop(fragment, input[i]);
|
|
42
|
-
}
|
|
43
|
-
return;
|
|
44
|
-
case RENDERABLE_NODE_LIST:
|
|
45
|
-
append.call(fragment, ...input);
|
|
46
|
-
return;
|
|
47
|
-
default:
|
|
48
|
-
append.call(fragment, input);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
let scratchpad = cloneNode.call(EMPTY_FRAGMENT);
|
|
53
|
-
export default function render(anchor, input) {
|
|
54
|
-
let fragment = scratchpad, t = type(input);
|
|
55
|
-
switch (t) {
|
|
56
|
-
case RENDERABLE_VOID:
|
|
57
|
-
break;
|
|
58
|
-
case RENDERABLE_TEXT:
|
|
59
|
-
append.call(fragment, text(input));
|
|
60
|
-
break;
|
|
61
|
-
case RENDERABLE_HTML_FRAGMENT:
|
|
62
|
-
return input.fragment;
|
|
63
|
-
case RENDERABLE_HTML_REACTIVE_ARRAY:
|
|
64
|
-
return reactive(anchor, input);
|
|
65
|
-
case RENDERABLE_ARRAY:
|
|
66
|
-
for (let i = 0, n = input.length; i < n; i++) {
|
|
67
|
-
loop(fragment, input[i]);
|
|
68
|
-
}
|
|
69
|
-
break;
|
|
70
|
-
case RENDERABLE_FRAGMENT:
|
|
71
|
-
return input;
|
|
72
|
-
case RENDERABLE_NODE:
|
|
73
|
-
append.call(fragment, input);
|
|
74
|
-
break;
|
|
75
|
-
case RENDERABLE_NODE_LIST:
|
|
76
|
-
append.call(fragment, ...input);
|
|
77
|
-
break;
|
|
29
|
+
let fragment = cloneNode.call(EMPTY_FRAGMENT), nodes = Array.from(input);
|
|
30
|
+
for (let i = 0, n = nodes.length; i < n; i++) {
|
|
31
|
+
append.call(fragment, nodes[i]);
|
|
32
|
+
}
|
|
33
|
+
return fragment;
|
|
78
34
|
}
|
|
79
|
-
return
|
|
35
|
+
return text(input);
|
|
80
36
|
}
|
|
81
37
|
;
|
package/build/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactiveArray } from '@esportsplus/reactivity';
|
|
2
|
-
import { RENDERABLE,
|
|
2
|
+
import { RENDERABLE, RENDERABLE_HTML_REACTIVE_ARRAY } from './constants.js';
|
|
3
3
|
import { firstChild } from './utilities/node.js';
|
|
4
4
|
import attributes from './attributes.js';
|
|
5
5
|
import slot from './slot/index.js';
|
|
@@ -20,22 +20,14 @@ type Attributes = {
|
|
|
20
20
|
type Effect<T> = () => EffectResponse<T>;
|
|
21
21
|
type EffectResponse<T> = T extends [] ? (Primitive | Renderable)[] : Primitive | Renderable;
|
|
22
22
|
type Element = HTMLElement & Attributes & Record<PropertyKey, unknown>;
|
|
23
|
-
type Elements = Element[];
|
|
24
|
-
type Fragment = (DocumentFragment | Node) & Record<PropertyKey, unknown>;
|
|
25
23
|
type Primitive = bigint | boolean | null | number | string | undefined;
|
|
26
|
-
type Renderable =
|
|
24
|
+
type Renderable = DocumentFragment | Node | NodeList | Primitive | RenderableReactive | Renderable[];
|
|
27
25
|
type RenderableReactive = Readonly<{
|
|
28
26
|
[RENDERABLE]: typeof RENDERABLE_HTML_REACTIVE_ARRAY;
|
|
29
27
|
array: ReactiveArray<unknown[]>;
|
|
30
28
|
template: (this: ReactiveArray<unknown[]>, ...args: Parameters<Parameters<ReactiveArray<unknown[]>['map']>[0]>) => ReturnType<typeof html>;
|
|
31
29
|
}>;
|
|
32
|
-
type
|
|
33
|
-
[RENDERABLE]: typeof RENDERABLE_HTML_FRAGMENT;
|
|
34
|
-
fragment: Fragment;
|
|
35
|
-
literals: TemplateStringsArray;
|
|
36
|
-
};
|
|
37
|
-
type RenderableValue<T = unknown> = Attributes | Readonly<Attributes> | Readonly<Attributes[]> | Effect<T> | Fragment | Primitive | RenderableReactive;
|
|
38
|
-
type RenderableValues = RenderableValue | RenderableValue[];
|
|
30
|
+
type RenderableValue<T = unknown> = Attributes | Readonly<Attributes> | Readonly<Attributes[]> | Effect<T> | Primitive | RenderableReactive;
|
|
39
31
|
type SlotGroup = {
|
|
40
32
|
head: Element;
|
|
41
33
|
tail: Element;
|
|
@@ -54,4 +46,4 @@ type Template = {
|
|
|
54
46
|
slot: number;
|
|
55
47
|
}[] | null;
|
|
56
48
|
};
|
|
57
|
-
export type { Attributes, Effect, Element,
|
|
49
|
+
export type { Attributes, Effect, Element, Renderable, RenderableReactive, RenderableValue, SlotGroup, Template };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { innerHTML } from './element.js';
|
|
2
2
|
import { cloneNode } from './node.js';
|
|
3
|
-
let
|
|
4
|
-
const append = prototype.append;
|
|
3
|
+
let scratchpad = document.createElement('template');
|
|
4
|
+
const append = DocumentFragment.prototype.append;
|
|
5
5
|
const fragment = (html) => {
|
|
6
|
-
innerHTML.call(
|
|
7
|
-
let content =
|
|
8
|
-
|
|
6
|
+
innerHTML.call(scratchpad, html);
|
|
7
|
+
let content = scratchpad.content;
|
|
8
|
+
scratchpad = cloneNode.call(scratchpad);
|
|
9
9
|
return content;
|
|
10
10
|
};
|
|
11
11
|
export { append, fragment };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
declare const appendChild: <T extends Node>(node: T) => T;
|
|
1
2
|
declare const cloneNode: (subtree?: boolean) => Node;
|
|
2
3
|
declare const firstChild: () => any;
|
|
3
4
|
declare const lastChild: () => any;
|
|
@@ -5,4 +6,4 @@ declare const nextSibling: () => any;
|
|
|
5
6
|
declare const nodeValue: (v: any) => void;
|
|
6
7
|
declare const parentElement: () => any;
|
|
7
8
|
declare const previousSibling: () => any;
|
|
8
|
-
export { cloneNode, firstChild, lastChild, nextSibling, nodeValue, parentElement, previousSibling };
|
|
9
|
+
export { appendChild, cloneNode, firstChild, lastChild, nextSibling, nodeValue, parentElement, previousSibling };
|
package/build/utilities/node.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, prototype = Node.prototype;
|
|
2
|
+
const appendChild = prototype.appendChild;
|
|
2
3
|
const cloneNode = prototype.cloneNode;
|
|
3
4
|
const firstChild = getOwnPropertyDescriptor(prototype, 'firstChild').get;
|
|
4
5
|
const lastChild = getOwnPropertyDescriptor(prototype, 'lastChild').get;
|
|
@@ -6,4 +7,4 @@ const nextSibling = getOwnPropertyDescriptor(prototype, 'nextSibling').get;
|
|
|
6
7
|
const nodeValue = getOwnPropertyDescriptor(prototype, 'nodeValue').set;
|
|
7
8
|
const parentElement = getOwnPropertyDescriptor(prototype, 'parentElement').get;
|
|
8
9
|
const previousSibling = getOwnPropertyDescriptor(prototype, 'previousSibling').get;
|
|
9
|
-
export { cloneNode, firstChild, lastChild, nextSibling, nodeValue, parentElement, previousSibling };
|
|
10
|
+
export { appendChild, cloneNode, firstChild, lastChild, nextSibling, nodeValue, parentElement, previousSibling };
|
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.16.1",
|
|
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.19.0",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc && tsc-alias",
|
|
20
20
|
"-": "-"
|
package/src/attributes.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { effect } from '@esportsplus/reactivity';
|
|
2
2
|
import { isArray, isObject, isString } from '@esportsplus/utilities';
|
|
3
|
-
import { ondisconnect } from './slot/cleanup';
|
|
4
3
|
import { STATE_HYDRATING, STATE_NONE, STATE_WAITING } from './constants';
|
|
5
4
|
import { Attributes, Element } from './types';
|
|
6
5
|
import { className, removeAttribute, setAttribute } from './utilities/element';
|
|
@@ -74,31 +73,28 @@ function set(context: Context, name: string, value: unknown, state: State) {
|
|
|
74
73
|
|
|
75
74
|
let id = (context.store[EFFECT] as number)++;
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
context.element
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
: i !== last ? STATE_WAITING : state
|
|
94
|
-
);
|
|
95
|
-
}
|
|
76
|
+
effect(() => {
|
|
77
|
+
let v = (value as Function)(context.element);
|
|
78
|
+
|
|
79
|
+
if (isArray(v)) {
|
|
80
|
+
let last = v.length - 1;
|
|
81
|
+
|
|
82
|
+
for (let i = 0, n = v.length; i < n; i++) {
|
|
83
|
+
update(
|
|
84
|
+
context,
|
|
85
|
+
id,
|
|
86
|
+
name,
|
|
87
|
+
v[i],
|
|
88
|
+
state === STATE_HYDRATING
|
|
89
|
+
? state
|
|
90
|
+
: i !== last ? STATE_WAITING : state
|
|
91
|
+
);
|
|
96
92
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
update(context, id, name, v, state);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
102
98
|
|
|
103
99
|
state = STATE_NONE;
|
|
104
100
|
}
|
package/src/constants.ts
CHANGED
|
@@ -47,21 +47,7 @@ const REGEX_SLOT_NODES = /<([\w-]+|[\/!])(?:([^><]*{{\$}}[^><]*)|(?:[^><]*))?>|{
|
|
|
47
47
|
|
|
48
48
|
const RENDERABLE = Symbol();
|
|
49
49
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
const RENDERABLE_FRAGMENT = 1;
|
|
53
|
-
|
|
54
|
-
const RENDERABLE_HTML_FRAGMENT = 2;
|
|
55
|
-
|
|
56
|
-
const RENDERABLE_HTML_REACTIVE_ARRAY = 3;
|
|
57
|
-
|
|
58
|
-
const RENDERABLE_NODE = 4;
|
|
59
|
-
|
|
60
|
-
const RENDERABLE_NODE_LIST = 5;
|
|
61
|
-
|
|
62
|
-
const RENDERABLE_TEXT = 6;
|
|
63
|
-
|
|
64
|
-
const RENDERABLE_VOID = 7;
|
|
50
|
+
const RENDERABLE_HTML_REACTIVE_ARRAY = 1;
|
|
65
51
|
|
|
66
52
|
|
|
67
53
|
const SLOT_HTML = '<!--$-->';
|
|
@@ -83,10 +69,7 @@ export {
|
|
|
83
69
|
EMPTY_FRAGMENT,
|
|
84
70
|
NODE_CLOSING, NODE_ELEMENT, NODE_SLOT, NODE_VOID, NODE_WHITELIST,
|
|
85
71
|
REGEX_EMPTY_TEXT_NODES, REGEX_SLOT_NODES,
|
|
86
|
-
RENDERABLE,
|
|
87
|
-
RENDERABLE_HTML_FRAGMENT, RENDERABLE_HTML_REACTIVE_ARRAY,
|
|
88
|
-
RENDERABLE_NODE, RENDERABLE_NODE_LIST, RENDERABLE_TEXT,
|
|
89
|
-
RENDERABLE_VOID,
|
|
72
|
+
RENDERABLE, RENDERABLE_HTML_REACTIVE_ARRAY,
|
|
90
73
|
SLOT_HTML, SLOT_MARKER, SLOT_MARKER_LENGTH,
|
|
91
74
|
STATE_HYDRATING, STATE_NONE, STATE_WAITING
|
|
92
75
|
};
|
package/src/html/index.ts
CHANGED
|
@@ -1,19 +1,58 @@
|
|
|
1
1
|
import { ReactiveArray } from '@esportsplus/reactivity';
|
|
2
|
-
import { RENDERABLE,
|
|
3
|
-
import { RenderableReactive,
|
|
4
|
-
import
|
|
2
|
+
import { RENDERABLE, RENDERABLE_HTML_REACTIVE_ARRAY } from '~/constants';
|
|
3
|
+
import { RenderableReactive, RenderableValue } from '~/types';
|
|
4
|
+
import { cloneNode } from '~/utilities/node';
|
|
5
5
|
import parser from './parser';
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
const html = (literals: TemplateStringsArray, ...values:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
const html = (literals: TemplateStringsArray, ...values: (RenderableValue | RenderableValue[])[]): DocumentFragment => {
|
|
9
|
+
let { fragment, slots } = parser.parse(literals);
|
|
10
|
+
|
|
11
|
+
fragment = cloneNode.call(fragment, true) as DocumentFragment;
|
|
12
|
+
|
|
13
|
+
if (slots !== null) {
|
|
14
|
+
let node, nodePath, parent, parentPath;
|
|
15
|
+
|
|
16
|
+
for (let i = 0, n = slots.length; i < n; i++) {
|
|
17
|
+
let { fn, path, slot } = slots[i],
|
|
18
|
+
pp = path.parent,
|
|
19
|
+
pr = path.relative;
|
|
20
|
+
|
|
21
|
+
if (pp !== parentPath) {
|
|
22
|
+
if (pp === nodePath) {
|
|
23
|
+
parent = node;
|
|
24
|
+
parentPath = nodePath;
|
|
25
|
+
|
|
26
|
+
nodePath = undefined;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
parent = fragment;
|
|
30
|
+
parentPath = pp;
|
|
31
|
+
|
|
32
|
+
for (let i = 0, n = pp.length; i < n; i++) {
|
|
33
|
+
parent = pp[i].call(parent);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (pr !== nodePath) {
|
|
39
|
+
node = parent;
|
|
40
|
+
nodePath = path.absolute;
|
|
41
|
+
|
|
42
|
+
for (let i = 0, n = pr.length; i < n; i++) {
|
|
43
|
+
node = pr[i].call(node);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
fn(node, values[slot]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return fragment;
|
|
14
53
|
};
|
|
15
54
|
|
|
16
|
-
html.reactive = <T>(array: ReactiveArray<T[]>, template: RenderableReactive['template']) => {
|
|
55
|
+
html.reactive = <T>(array: ReactiveArray<T[]>, template: RenderableReactive['template']): RenderableReactive => {
|
|
17
56
|
return {
|
|
18
57
|
[RENDERABLE]: RENDERABLE_HTML_REACTIVE_ARRAY,
|
|
19
58
|
array,
|
package/src/html/parser.ts
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
} from '~/constants';
|
|
5
5
|
import { Template } from '~/types';
|
|
6
6
|
import { firstElementChild, nextElementSibling } from '~/utilities/element';
|
|
7
|
-
import { fragment } from '~/utilities/fragment';
|
|
8
7
|
import { firstChild, nextSibling } from '~/utilities/node';
|
|
9
8
|
import { spread } from '~/attributes';
|
|
9
|
+
import { fragment } from '~/utilities/fragment';
|
|
10
10
|
import s from '~/slot';
|
|
11
11
|
|
|
12
12
|
|
|
@@ -126,21 +126,27 @@ function methods(children: number, copy: (typeof firstChild)[], first: (typeof f
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
function set(literals: TemplateStringsArray, html: string, slots: Template['slots'] = null) {
|
|
129
|
-
let
|
|
129
|
+
let value = {
|
|
130
130
|
fragment: fragment(html),
|
|
131
131
|
html,
|
|
132
132
|
literals,
|
|
133
133
|
slots
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
-
cache.set(literals,
|
|
136
|
+
cache.set(literals, value);
|
|
137
137
|
|
|
138
|
-
return
|
|
138
|
+
return value;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
const parse = (literals: TemplateStringsArray) => {
|
|
143
|
-
|
|
143
|
+
let result = cache.get(literals);
|
|
144
|
+
|
|
145
|
+
if (result === undefined) {
|
|
146
|
+
result = build(literals);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return result;
|
|
144
150
|
};
|
|
145
151
|
|
|
146
152
|
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as html } from './html';
|
|
2
2
|
export { default as render } from './render';
|
|
3
3
|
export { default as svg } from './svg';
|
|
4
|
-
export type { Attributes, Element,
|
|
4
|
+
export type { Attributes, Element, Renderable, RenderableValue } from './types';
|