@esportsplus/template 0.17.0 → 0.18.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/build/attributes.js +2 -1
- package/build/constants.js +1 -1
- package/build/event.js +47 -45
- package/build/html/hydrate.js +1 -1
- package/build/html/index.js +2 -2
- package/build/html/{cache.d.ts → parser.d.ts} +1 -1
- package/build/html/{cache.js → parser.js} +5 -3
- package/build/render.js +3 -2
- package/build/slot/cleanup.js +2 -1
- package/build/slot/effect.js +12 -7
- package/build/slot/index.js +1 -8
- package/build/slot/reactive.d.ts +2 -2
- package/build/slot/reactive.js +12 -4
- package/build/slot/render.d.ts +2 -2
- package/build/slot/render.js +36 -13
- package/build/types.d.ts +2 -2
- package/build/utilities/element.d.ts +11 -0
- package/build/utilities/element.js +9 -0
- package/build/utilities/fragment.d.ts +3 -0
- package/build/utilities/fragment.js +11 -0
- package/build/utilities/node.d.ts +8 -0
- package/build/utilities/node.js +9 -0
- package/build/utilities/queue.d.ts +3 -0
- package/build/utilities/queue.js +4 -0
- package/build/utilities/text.d.ts +3 -0
- package/build/utilities/text.js +9 -0
- package/package.json +1 -1
- package/src/attributes.ts +2 -1
- package/src/constants.ts +1 -1
- package/src/event.ts +55 -52
- package/src/html/hydrate.ts +1 -1
- package/src/html/index.ts +2 -2
- package/src/html/{cache.ts → parser.ts} +5 -3
- package/src/render.ts +3 -3
- package/src/slot/cleanup.ts +2 -2
- package/src/slot/effect.ts +13 -12
- package/src/slot/index.ts +3 -14
- package/src/slot/reactive.ts +17 -7
- package/src/slot/render.ts +51 -15
- package/src/types.ts +2 -2
- package/src/utilities/element.ts +28 -0
- package/src/utilities/fragment.ts +22 -0
- package/src/utilities/node.ts +26 -0
- package/src/utilities/queue.ts +9 -0
- package/src/utilities/text.ts +16 -0
- package/build/utilities.d.ts +0 -28
- package/build/utilities.js +0 -37
- package/src/utilities.ts +0 -89
package/src/event.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { root } from '@esportsplus/reactivity';
|
|
2
2
|
import { defineProperty } from '@esportsplus/utilities';
|
|
3
3
|
import { Element } from './types';
|
|
4
|
-
import { addEventListener
|
|
4
|
+
import { addEventListener } from './utilities/element';
|
|
5
|
+
import { parentElement } from './utilities/node';
|
|
6
|
+
import { raf } from './utilities/queue';
|
|
5
7
|
import { ondisconnect } from './slot/cleanup';
|
|
6
8
|
|
|
7
9
|
|
|
@@ -24,35 +26,7 @@ let capture = new Set<`on${string}`>(['onblur', 'onfocus', 'onscroll']),
|
|
|
24
26
|
});
|
|
25
27
|
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
if (event === 'onconnect') {
|
|
29
|
-
let retry = 60,
|
|
30
|
-
task = () => {
|
|
31
|
-
retry--;
|
|
32
|
-
|
|
33
|
-
if (element.isConnected) {
|
|
34
|
-
retry = 0;
|
|
35
|
-
root(() => listener(element));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (retry) {
|
|
39
|
-
raf.add(task);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
raf.add(task);
|
|
44
|
-
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
else if (event === 'ondisconnect') {
|
|
48
|
-
ondisconnect(element, () => listener(element));
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
else if (event === 'onrender') {
|
|
52
|
-
root(() => listener(element));
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
29
|
+
function register(element: Element, event: `on${string}`) {
|
|
56
30
|
let controller = controllers.get(event),
|
|
57
31
|
signal: AbortController['signal'] | undefined;
|
|
58
32
|
|
|
@@ -83,34 +57,63 @@ export default (element: Element, event: `on${string}`, listener: Function): voi
|
|
|
83
57
|
signal = controller.signal;
|
|
84
58
|
}
|
|
85
59
|
|
|
86
|
-
let key = keys[event];
|
|
60
|
+
let key = keys[event] = Symbol();
|
|
61
|
+
|
|
62
|
+
addEventListener.call(window.document, event.slice(2), (e) => {
|
|
63
|
+
let node = e.target as Element | null;
|
|
87
64
|
|
|
88
|
-
|
|
89
|
-
|
|
65
|
+
while (node) {
|
|
66
|
+
if (key in node) {
|
|
67
|
+
defineProperty(e, 'currentTarget', {
|
|
68
|
+
configurable: true,
|
|
69
|
+
get() {
|
|
70
|
+
return node || window.document;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
90
73
|
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
return (node[key] as Function).call(node, e);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
node = parentElement.call(node);
|
|
78
|
+
}
|
|
79
|
+
}, {
|
|
80
|
+
capture: capture.has(event),
|
|
81
|
+
passive: passive.has(event),
|
|
82
|
+
signal
|
|
83
|
+
});
|
|
93
84
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
defineProperty(e, 'currentTarget', {
|
|
97
|
-
configurable: true,
|
|
98
|
-
get() {
|
|
99
|
-
return node || window.document;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
85
|
+
return key;
|
|
86
|
+
}
|
|
102
87
|
|
|
103
|
-
|
|
88
|
+
|
|
89
|
+
export default (element: Element, event: `on${string}`, listener: Function): void => {
|
|
90
|
+
if (event === 'onconnect') {
|
|
91
|
+
let retry = 60,
|
|
92
|
+
task = () => {
|
|
93
|
+
retry--;
|
|
94
|
+
|
|
95
|
+
if (element.isConnected) {
|
|
96
|
+
retry = 0;
|
|
97
|
+
root(() => listener(element));
|
|
104
98
|
}
|
|
105
99
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
if (retry) {
|
|
101
|
+
raf.add(task);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
raf.add(task);
|
|
106
|
+
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
else if (event === 'ondisconnect') {
|
|
110
|
+
ondisconnect(element, () => listener(element));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
else if (event === 'onrender') {
|
|
114
|
+
root(() => listener(element));
|
|
115
|
+
return;
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
element[
|
|
118
|
+
element[ keys[event] || register(element, event) ] = listener;
|
|
116
119
|
};
|
package/src/html/hydrate.ts
CHANGED
package/src/html/index.ts
CHANGED
|
@@ -2,13 +2,13 @@ import { ReactiveArray } from '@esportsplus/reactivity';
|
|
|
2
2
|
import { RENDERABLE, RENDERABLE_HTML_FRAGMENT, RENDERABLE_HTML_REACTIVE_ARRAY } from '~/constants';
|
|
3
3
|
import { RenderableReactive, RenderableTemplate, RenderableValues } from '~/types';
|
|
4
4
|
import hydrate from './hydrate';
|
|
5
|
-
import
|
|
5
|
+
import parser from './parser';
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
const html = (literals: TemplateStringsArray, ...values: RenderableValues[]): RenderableTemplate => {
|
|
9
9
|
return {
|
|
10
10
|
[RENDERABLE]: RENDERABLE_HTML_FRAGMENT,
|
|
11
|
-
fragment: hydrate(
|
|
11
|
+
fragment: hydrate(parser.parse(literals), values),
|
|
12
12
|
literals
|
|
13
13
|
};
|
|
14
14
|
};
|
|
@@ -3,7 +3,9 @@ import {
|
|
|
3
3
|
REGEX_SLOT_NODES, SLOT_HTML, SLOT_MARKER, SLOT_MARKER_LENGTH
|
|
4
4
|
} from '~/constants';
|
|
5
5
|
import { Template } from '~/types';
|
|
6
|
-
import {
|
|
6
|
+
import { firstElementChild, nextElementSibling } from '~/utilities/element';
|
|
7
|
+
import { fragment } from '~/utilities/fragment';
|
|
8
|
+
import { firstChild, nextSibling } from '~/utilities/node';
|
|
7
9
|
import { spread } from '~/attributes';
|
|
8
10
|
import s from '~/slot';
|
|
9
11
|
|
|
@@ -137,9 +139,9 @@ function set(literals: TemplateStringsArray, html: string, slots: Template['slot
|
|
|
137
139
|
}
|
|
138
140
|
|
|
139
141
|
|
|
140
|
-
const
|
|
142
|
+
const parse = (literals: TemplateStringsArray) => {
|
|
141
143
|
return cache.get(literals) || build(literals);
|
|
142
144
|
};
|
|
143
145
|
|
|
144
146
|
|
|
145
|
-
export default {
|
|
147
|
+
export default { parse };
|
package/src/render.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SLOT_HTML } from './constants';
|
|
2
2
|
import { Renderable } from './types';
|
|
3
|
-
import {
|
|
3
|
+
import { fragment } from './utilities/fragment';
|
|
4
|
+
import { firstChild, nodeValue } from './utilities/node';
|
|
4
5
|
import slot from './slot';
|
|
5
6
|
|
|
6
7
|
|
|
@@ -9,9 +10,8 @@ let anchor,
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
export default (parent: HTMLElement, renderable: Renderable) => {
|
|
12
|
-
// parent.nodeValue = '';
|
|
13
13
|
nodeValue.call(parent, '');
|
|
14
14
|
parent.append(anchor = marker.cloneNode());
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
slot(anchor, renderable);
|
|
17
17
|
};
|
package/src/slot/cleanup.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import queue from '@esportsplus/queue';
|
|
2
2
|
import { CLEANUP } from '~/constants';
|
|
3
|
-
import { microtask
|
|
3
|
+
import { microtask } from '~/utilities/queue';
|
|
4
|
+
import { previousSibling } from '~/utilities/node';
|
|
4
5
|
import { SlotGroup } from '~/types';
|
|
5
6
|
|
|
6
7
|
|
|
@@ -51,7 +52,6 @@ const remove = (groups: SlotGroup[]) => {
|
|
|
51
52
|
head = group.head;
|
|
52
53
|
tail = group.tail || head;
|
|
53
54
|
|
|
54
|
-
// for (let node: Element | null = tail; node; node = node.previousSibling as Element | null) {
|
|
55
55
|
for (let node = tail; node; node = previousSibling.call(node)) {
|
|
56
56
|
if (CLEANUP in node) {
|
|
57
57
|
cleanup.add( node[CLEANUP] as VoidFunction[] );
|
package/src/slot/effect.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { effect } from '@esportsplus/reactivity';
|
|
2
|
-
import {
|
|
3
|
-
import { Element,
|
|
4
|
-
import {
|
|
2
|
+
import { STATE_HYDRATING, STATE_NONE } from '~/constants';
|
|
3
|
+
import { Element, SlotGroup } from '~/types';
|
|
4
|
+
import { firstChild, lastChild, nodeValue } from '~/utilities/node'
|
|
5
|
+
import { raf } from '~/utilities/queue'
|
|
5
6
|
import { ondisconnect } from '~/slot/cleanup';
|
|
6
7
|
import { remove } from './cleanup';
|
|
8
|
+
import text from '~/utilities/text';
|
|
7
9
|
import render from './render';
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
function update(this: { group?: SlotGroup, textnode?: Element }, anchor: Element,
|
|
12
|
+
function update(this: { group?: SlotGroup, textnode?: Element }, anchor: Element, value: unknown) {
|
|
11
13
|
let type = typeof value;
|
|
12
14
|
|
|
13
15
|
if (this.group) {
|
|
@@ -19,7 +21,6 @@ function update(this: { group?: SlotGroup, textnode?: Element }, anchor: Element
|
|
|
19
21
|
let textnode = this.textnode;
|
|
20
22
|
|
|
21
23
|
if (textnode) {
|
|
22
|
-
// textnode.nodeValue = String(value);
|
|
23
24
|
nodeValue.call(textnode, String(value));
|
|
24
25
|
}
|
|
25
26
|
else {
|
|
@@ -31,11 +32,13 @@ function update(this: { group?: SlotGroup, textnode?: Element }, anchor: Element
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
else {
|
|
34
|
-
render(anchor,
|
|
35
|
+
let fragment = render(anchor, value);
|
|
36
|
+
|
|
37
|
+
if (!fragment) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
35
40
|
|
|
36
41
|
this.group = {
|
|
37
|
-
// head: fragment.firstChild as Element,
|
|
38
|
-
// tail: fragment.lastChild as Element
|
|
39
42
|
head: firstChild.call(fragment),
|
|
40
43
|
tail: lastChild.call(fragment)
|
|
41
44
|
};
|
|
@@ -50,8 +53,6 @@ export default (anchor: Element, fn: Function) => {
|
|
|
50
53
|
group: undefined as SlotGroup | undefined,
|
|
51
54
|
textnode: undefined as Element | undefined
|
|
52
55
|
},
|
|
53
|
-
// fragment = EMPTY_FRAGMENT.cloneNode() as Fragment,
|
|
54
|
-
fragment = cloneNode.call(EMPTY_FRAGMENT) as Fragment,
|
|
55
56
|
state = STATE_HYDRATING;
|
|
56
57
|
|
|
57
58
|
ondisconnect(
|
|
@@ -60,12 +61,12 @@ export default (anchor: Element, fn: Function) => {
|
|
|
60
61
|
let value = fn();
|
|
61
62
|
|
|
62
63
|
if (state === STATE_HYDRATING) {
|
|
63
|
-
update.call(context, anchor,
|
|
64
|
+
update.call(context, anchor, value);
|
|
64
65
|
state = STATE_NONE;
|
|
65
66
|
}
|
|
66
67
|
else if (state === STATE_NONE) {
|
|
67
68
|
raf.add(() => {
|
|
68
|
-
update.call(context, anchor,
|
|
69
|
+
update.call(context, anchor, value);
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
72
|
})
|
package/src/slot/index.ts
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Element, Fragment } from '~/types';
|
|
3
|
-
import { cloneNode } from '~/utilities';
|
|
1
|
+
import { Element } from '~/types';
|
|
4
2
|
import effect from './effect';
|
|
5
3
|
import render from './render';
|
|
6
4
|
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
let fragment = cloneNode.call(EMPTY_FRAGMENT) as Fragment;
|
|
10
|
-
|
|
11
|
-
render(anchor, fragment, input);
|
|
12
|
-
|
|
13
|
-
anchor.after(fragment);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export default (anchor: Element, value: unknown) => {
|
|
6
|
+
export default (anchor: Element, value: unknown): void => {
|
|
18
7
|
if (typeof value === 'function') {
|
|
19
8
|
return effect(anchor, value as Function);
|
|
20
9
|
}
|
|
21
10
|
|
|
22
|
-
|
|
11
|
+
anchor.after(render(anchor, value));
|
|
23
12
|
};
|
package/src/slot/reactive.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { root, ReactiveArray } from '@esportsplus/reactivity';
|
|
2
2
|
import { EMPTY_FRAGMENT } from '~/constants';
|
|
3
3
|
import { Fragment, RenderableReactive, SlotGroup } from '~/types';
|
|
4
|
-
import { append
|
|
4
|
+
import { append } from '~/utilities/fragment';
|
|
5
|
+
import { cloneNode, firstChild, lastChild } from '~/utilities/node';
|
|
5
6
|
import { remove } from './cleanup';
|
|
6
7
|
|
|
7
8
|
|
|
@@ -100,14 +101,14 @@ class ReactiveArraySlot<T> {
|
|
|
100
101
|
|
|
101
102
|
push(items: T[]) {
|
|
102
103
|
let anchor = this.anchor(),
|
|
103
|
-
array = this.array
|
|
104
|
+
array = this.array,
|
|
105
|
+
length = this.nodes.length;
|
|
106
|
+
|
|
107
|
+
this.nodes.length = length + items.length;
|
|
104
108
|
|
|
105
109
|
for (let i = 0, n = items.length; i < n; i++) {
|
|
106
|
-
this.nodes.
|
|
107
|
-
this.template.call(array, items[i], i)
|
|
108
|
-
);
|
|
110
|
+
this.nodes[i + length] = this.template.call(array, items[i], i);
|
|
109
111
|
}
|
|
110
|
-
|
|
111
112
|
anchor.after(this.fragment);
|
|
112
113
|
}
|
|
113
114
|
|
|
@@ -163,5 +164,14 @@ class ReactiveArraySlot<T> {
|
|
|
163
164
|
|
|
164
165
|
|
|
165
166
|
export default (anchor: Element, renderable: RenderableReactive) => {
|
|
166
|
-
|
|
167
|
+
let { array, template } = renderable,
|
|
168
|
+
slot = new ReactiveArraySlot(anchor, array, template);
|
|
169
|
+
|
|
170
|
+
if (array.length) {
|
|
171
|
+
root(() => {
|
|
172
|
+
slot.nodes = array.map(slot.template);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return slot.fragment;
|
|
167
177
|
};
|
package/src/slot/render.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { isArray } from '@esportsplus/utilities';
|
|
2
2
|
import {
|
|
3
|
+
EMPTY_FRAGMENT,
|
|
3
4
|
RENDERABLE,
|
|
4
5
|
RENDERABLE_ARRAY, RENDERABLE_FRAGMENT, RENDERABLE_HTML_FRAGMENT, RENDERABLE_HTML_REACTIVE_ARRAY,
|
|
5
6
|
RENDERABLE_NODE, RENDERABLE_NODE_LIST, RENDERABLE_TEXT, RENDERABLE_VOID
|
|
6
7
|
} from '~/constants';
|
|
7
8
|
import { Element, Fragment, RenderableReactive, RenderableTemplate } from '~/types';
|
|
8
|
-
import {
|
|
9
|
+
import { cloneNode } from '~/utilities/node';
|
|
10
|
+
import { append } from '~/utilities/fragment';
|
|
11
|
+
import text from '~/utilities/text';
|
|
9
12
|
import reactive from './reactive';
|
|
10
13
|
|
|
11
14
|
|
|
@@ -28,6 +31,7 @@ function type(input: unknown) {
|
|
|
28
31
|
|
|
29
32
|
let nodeType = (input as any).nodeType;
|
|
30
33
|
|
|
34
|
+
// Document Fragment
|
|
31
35
|
if (nodeType === 11) {
|
|
32
36
|
return RENDERABLE_FRAGMENT;
|
|
33
37
|
}
|
|
@@ -39,43 +43,75 @@ function type(input: unknown) {
|
|
|
39
43
|
if (input instanceof NodeList) {
|
|
40
44
|
return RENDERABLE_NODE_LIST;
|
|
41
45
|
}
|
|
42
|
-
}
|
|
43
46
|
|
|
47
|
+
return RENDERABLE_TEXT;
|
|
48
|
+
}
|
|
44
49
|
|
|
45
|
-
|
|
50
|
+
function loop(fragment: Node, input: unknown) {
|
|
46
51
|
let t = type(input);
|
|
47
52
|
|
|
48
53
|
switch (t) {
|
|
54
|
+
case RENDERABLE_HTML_REACTIVE_ARRAY:
|
|
55
|
+
throw new Error('@esportsplus/template: reactive arrays cannot be defined within an slot array value');
|
|
56
|
+
|
|
49
57
|
case RENDERABLE_VOID:
|
|
50
58
|
return;
|
|
51
59
|
|
|
52
|
-
case
|
|
53
|
-
|
|
60
|
+
case RENDERABLE_ARRAY:
|
|
61
|
+
for (let i = 0, n = (input as unknown[]).length; i < n; i++) {
|
|
62
|
+
loop(fragment, (input as unknown[])[i])
|
|
63
|
+
}
|
|
54
64
|
return;
|
|
55
65
|
|
|
56
|
-
case
|
|
57
|
-
append.call(fragment,
|
|
66
|
+
case RENDERABLE_NODE_LIST:
|
|
67
|
+
append.call(fragment, ...input as Element[]);
|
|
68
|
+
return;
|
|
69
|
+
|
|
70
|
+
default:
|
|
71
|
+
append.call(fragment, input as Element)
|
|
58
72
|
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let scratchpad = cloneNode.call(EMPTY_FRAGMENT);
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
export default function render(anchor: Element, input: unknown): Node {
|
|
80
|
+
let fragment = scratchpad,
|
|
81
|
+
t = type(input);
|
|
82
|
+
|
|
83
|
+
switch (t) {
|
|
84
|
+
case RENDERABLE_VOID:
|
|
85
|
+
break;
|
|
86
|
+
|
|
87
|
+
case RENDERABLE_TEXT:
|
|
88
|
+
append.call(fragment, text(input as string));
|
|
89
|
+
break;
|
|
90
|
+
|
|
91
|
+
case RENDERABLE_HTML_FRAGMENT:
|
|
92
|
+
return (input as RenderableTemplate).fragment;
|
|
59
93
|
|
|
60
94
|
case RENDERABLE_HTML_REACTIVE_ARRAY:
|
|
61
95
|
return reactive(anchor, input as RenderableReactive);
|
|
62
96
|
|
|
63
97
|
case RENDERABLE_ARRAY:
|
|
64
98
|
for (let i = 0, n = (input as unknown[]).length; i < n; i++) {
|
|
65
|
-
|
|
99
|
+
loop(fragment, (input as unknown[])[i]);
|
|
66
100
|
}
|
|
67
|
-
|
|
101
|
+
|
|
102
|
+
break;
|
|
68
103
|
|
|
69
104
|
case RENDERABLE_FRAGMENT:
|
|
70
|
-
|
|
71
|
-
return;
|
|
105
|
+
return input as Fragment;
|
|
72
106
|
|
|
73
107
|
case RENDERABLE_NODE:
|
|
74
|
-
append.call(fragment, input as
|
|
75
|
-
|
|
108
|
+
append.call(fragment, input as Element);
|
|
109
|
+
break;
|
|
76
110
|
|
|
77
111
|
case RENDERABLE_NODE_LIST:
|
|
78
|
-
append.call(fragment, ...
|
|
79
|
-
|
|
112
|
+
append.call(fragment, ...input as Element[]);
|
|
113
|
+
break;
|
|
80
114
|
}
|
|
115
|
+
|
|
116
|
+
return fragment;
|
|
81
117
|
};
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactiveArray } from '@esportsplus/reactivity';
|
|
2
2
|
import { RENDERABLE, RENDERABLE_HTML_FRAGMENT, RENDERABLE_HTML_REACTIVE_ARRAY } from './constants';
|
|
3
|
-
import { firstChild } from './utilities';
|
|
3
|
+
import { firstChild } from './utilities/node';
|
|
4
4
|
import attributes from './attributes';
|
|
5
5
|
import slot from './slot';
|
|
6
6
|
import html from './html';
|
|
@@ -37,7 +37,7 @@ type Fragment = (DocumentFragment | Node) & Record<PropertyKey, unknown>;
|
|
|
37
37
|
// - Importing from ^ causes 'cannot be named without a reference to...' error
|
|
38
38
|
type Primitive = bigint | boolean | null | number | string | undefined;
|
|
39
39
|
|
|
40
|
-
type Renderable = Fragment | RenderableReactive;
|
|
40
|
+
type Renderable = Fragment | Primitive | RenderableReactive | RenderableTemplate;
|
|
41
41
|
|
|
42
42
|
type RenderableReactive = Readonly<{
|
|
43
43
|
[RENDERABLE]: typeof RENDERABLE_HTML_REACTIVE_ARRAY;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
|
|
2
|
+
prototype = Element.prototype;
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const addEventListener = prototype.addEventListener;
|
|
6
|
+
|
|
7
|
+
const className = getOwnPropertyDescriptor(prototype, 'className')!.set!;
|
|
8
|
+
|
|
9
|
+
const innerHTML = getOwnPropertyDescriptor(prototype, 'innerHTML')!.set!;
|
|
10
|
+
|
|
11
|
+
const firstElementChild = getOwnPropertyDescriptor(prototype, 'firstElementChild')!.get!;
|
|
12
|
+
|
|
13
|
+
const nextElementSibling = getOwnPropertyDescriptor(prototype, 'nextElementSibling')!.get!;
|
|
14
|
+
|
|
15
|
+
const removeAttribute = prototype.removeAttribute;
|
|
16
|
+
|
|
17
|
+
const setAttribute = prototype.setAttribute;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
addEventListener,
|
|
22
|
+
className,
|
|
23
|
+
innerHTML,
|
|
24
|
+
firstElementChild,
|
|
25
|
+
nextElementSibling,
|
|
26
|
+
removeAttribute,
|
|
27
|
+
setAttribute
|
|
28
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { innerHTML } from './element';
|
|
2
|
+
import { cloneNode } from './node';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
let prototype = DocumentFragment.prototype,
|
|
6
|
+
template = document.createElement('template');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
const append = prototype.append;
|
|
10
|
+
|
|
11
|
+
const fragment = (html: string) => {
|
|
12
|
+
innerHTML.call(template, html);
|
|
13
|
+
|
|
14
|
+
let content = template.content;
|
|
15
|
+
|
|
16
|
+
template = cloneNode.call(template) as HTMLTemplateElement;
|
|
17
|
+
|
|
18
|
+
return content;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export { append, fragment };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
|
|
2
|
+
prototype = Node.prototype;
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const cloneNode = prototype.cloneNode;
|
|
6
|
+
|
|
7
|
+
const firstChild = getOwnPropertyDescriptor(prototype, 'firstChild')!.get!;
|
|
8
|
+
|
|
9
|
+
const lastChild = getOwnPropertyDescriptor(prototype, 'lastChild')!.get!;
|
|
10
|
+
|
|
11
|
+
const nextSibling = getOwnPropertyDescriptor(prototype, 'nextSibling')!.get!;
|
|
12
|
+
|
|
13
|
+
const nodeValue = getOwnPropertyDescriptor(prototype, 'nodeValue')!.set!;
|
|
14
|
+
|
|
15
|
+
const parentElement = getOwnPropertyDescriptor(prototype, 'parentElement')!.get!;
|
|
16
|
+
|
|
17
|
+
const previousSibling = getOwnPropertyDescriptor(prototype, 'previousSibling')!.get!;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
cloneNode,
|
|
22
|
+
firstChild,
|
|
23
|
+
lastChild,
|
|
24
|
+
nextSibling, nodeValue,
|
|
25
|
+
parentElement, previousSibling
|
|
26
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { cloneNode, nodeValue } from './node';
|
|
2
|
+
import { Element } from '~/types';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
let text = document.createTextNode('');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export default (value: string) => {
|
|
9
|
+
let element = cloneNode.call(text);
|
|
10
|
+
|
|
11
|
+
if (value !== '') {
|
|
12
|
+
nodeValue.call(element, value);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return element as Element;
|
|
16
|
+
};
|
package/build/utilities.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Element as E } from './types.js';
|
|
2
|
-
declare const append: (...nodes: (Node | string)[]) => void;
|
|
3
|
-
declare const addEventListener: {
|
|
4
|
-
<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
5
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
6
|
-
};
|
|
7
|
-
declare const removeEventListener: {
|
|
8
|
-
<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
9
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
10
|
-
};
|
|
11
|
-
declare const className: (v: any) => void;
|
|
12
|
-
declare const innerHTML: (v: any) => void;
|
|
13
|
-
declare const firstElementChild: () => any;
|
|
14
|
-
declare const nextElementSibling: () => any;
|
|
15
|
-
declare const removeAttribute: (qualifiedName: string) => void;
|
|
16
|
-
declare const setAttribute: (qualifiedName: string, value: string) => void;
|
|
17
|
-
declare const cloneNode: (subtree?: boolean) => Node;
|
|
18
|
-
declare const firstChild: () => any;
|
|
19
|
-
declare const lastChild: () => any;
|
|
20
|
-
declare const nextSibling: () => any;
|
|
21
|
-
declare const nodeValue: (v: any) => void;
|
|
22
|
-
declare const parentElement: () => any;
|
|
23
|
-
declare const previousSibling: () => any;
|
|
24
|
-
declare const fragment: (html: string) => DocumentFragment;
|
|
25
|
-
declare const microtask: import("@esportsplus/tasks/build/factory").Scheduler;
|
|
26
|
-
declare const raf: import("@esportsplus/tasks/build/factory").Scheduler;
|
|
27
|
-
declare const text: (value: string) => E;
|
|
28
|
-
export { addEventListener, append, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, lastChild, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, previousSibling, raf, removeAttribute, removeEventListener, setAttribute, text };
|
package/build/utilities.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { micro as m, raf as r } from '@esportsplus/tasks';
|
|
2
|
-
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, prototype, template = document.createElement('template'), t = document.createTextNode('');
|
|
3
|
-
prototype = DocumentFragment.prototype;
|
|
4
|
-
const append = prototype.append;
|
|
5
|
-
prototype = Element.prototype;
|
|
6
|
-
const addEventListener = prototype.addEventListener;
|
|
7
|
-
const removeEventListener = prototype.removeEventListener;
|
|
8
|
-
const className = getOwnPropertyDescriptor(prototype, 'className').set;
|
|
9
|
-
const innerHTML = getOwnPropertyDescriptor(prototype, 'innerHTML').set;
|
|
10
|
-
const firstElementChild = getOwnPropertyDescriptor(prototype, 'firstElementChild').get;
|
|
11
|
-
const nextElementSibling = getOwnPropertyDescriptor(prototype, 'nextElementSibling').get;
|
|
12
|
-
const removeAttribute = prototype.removeAttribute;
|
|
13
|
-
const setAttribute = prototype.setAttribute;
|
|
14
|
-
prototype = Node.prototype;
|
|
15
|
-
const cloneNode = prototype.cloneNode;
|
|
16
|
-
const firstChild = getOwnPropertyDescriptor(prototype, 'firstChild').get;
|
|
17
|
-
const lastChild = getOwnPropertyDescriptor(prototype, 'lastChild').get;
|
|
18
|
-
const nextSibling = getOwnPropertyDescriptor(prototype, 'nextSibling').get;
|
|
19
|
-
const nodeValue = getOwnPropertyDescriptor(prototype, 'nodeValue').set;
|
|
20
|
-
const parentElement = getOwnPropertyDescriptor(prototype, 'parentElement').get;
|
|
21
|
-
const previousSibling = getOwnPropertyDescriptor(prototype, 'previousSibling').get;
|
|
22
|
-
const fragment = (html) => {
|
|
23
|
-
innerHTML.call(template, html);
|
|
24
|
-
let { content } = template;
|
|
25
|
-
template = cloneNode.call(template);
|
|
26
|
-
return content;
|
|
27
|
-
};
|
|
28
|
-
const microtask = m();
|
|
29
|
-
const raf = r();
|
|
30
|
-
const text = (value) => {
|
|
31
|
-
let element = cloneNode.call(t);
|
|
32
|
-
if (value !== '') {
|
|
33
|
-
nodeValue.call(element, value);
|
|
34
|
-
}
|
|
35
|
-
return element;
|
|
36
|
-
};
|
|
37
|
-
export { addEventListener, append, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, lastChild, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, previousSibling, raf, removeAttribute, removeEventListener, setAttribute, text };
|