@esportsplus/template 0.16.1 → 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.
Potentially problematic release.
This version of @esportsplus/template might be problematic. Click here for more details.
- package/build/attributes.js +29 -24
- package/build/constants.d.ts +13 -3
- package/build/constants.js +14 -4
- package/build/event.js +48 -46
- package/build/html/hydrate.d.ts +2 -8
- package/build/html/hydrate.js +28 -79
- package/build/html/index.d.ts +2106 -5
- package/build/html/index.js +12 -4
- package/build/html/{cache.d.ts → parser.d.ts} +1 -1
- package/build/html/{cache.js → parser.js} +6 -4
- package/build/render.d.ts +1 -2
- package/build/render.js +7 -10
- package/build/slot/cleanup.d.ts +4 -0
- package/build/slot/cleanup.js +52 -0
- package/build/slot/effect.d.ts +3 -0
- package/build/slot/effect.js +56 -0
- package/build/slot/index.d.ts +3 -0
- package/build/slot/index.js +8 -0
- package/build/slot/reactive.d.ts +3 -0
- package/build/slot/reactive.js +125 -0
- package/build/slot/render.d.ts +2 -0
- package/build/slot/render.js +81 -0
- package/build/svg.d.ts +1 -2
- package/build/types.d.ts +21 -17
- 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 +2 -2
- package/src/attributes.ts +32 -29
- package/src/constants.ts +32 -5
- package/src/event.ts +55 -52
- package/src/html/hydrate.ts +36 -108
- package/src/html/index.ts +16 -8
- package/src/html/{cache.ts → parser.ts} +5 -3
- package/src/render.ts +8 -12
- package/src/slot/cleanup.ts +74 -0
- package/src/slot/effect.ts +74 -0
- package/src/slot/index.ts +12 -0
- package/src/slot/reactive.ts +177 -0
- package/src/slot/render.ts +117 -0
- package/src/svg.ts +1 -2
- package/src/types.ts +25 -18
- 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/slot.d.ts +0 -21
- package/build/slot.js +0 -204
- package/build/utilities.d.ts +0 -28
- package/build/utilities.js +0 -37
- package/src/slot.ts +0 -277
- package/src/utilities.ts +0 -87
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { effect } from '@esportsplus/reactivity';
|
|
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'
|
|
6
|
+
import { ondisconnect } from '~/slot/cleanup';
|
|
7
|
+
import { remove } from './cleanup';
|
|
8
|
+
import text from '~/utilities/text';
|
|
9
|
+
import render from './render';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
function update(this: { group?: SlotGroup, textnode?: Element }, anchor: Element, value: unknown) {
|
|
13
|
+
let type = typeof value;
|
|
14
|
+
|
|
15
|
+
if (this.group) {
|
|
16
|
+
remove([this.group]);
|
|
17
|
+
this.group = undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (value == null || type !== 'object') {
|
|
21
|
+
let textnode = this.textnode;
|
|
22
|
+
|
|
23
|
+
if (textnode) {
|
|
24
|
+
nodeValue.call(textnode, String(value));
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
textnode = this.textnode = text( String(value) );
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!textnode.isConnected) {
|
|
31
|
+
anchor.after(textnode);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
let fragment = render(anchor, value);
|
|
36
|
+
|
|
37
|
+
if (!fragment) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.group = {
|
|
42
|
+
head: firstChild.call(fragment),
|
|
43
|
+
tail: lastChild.call(fragment)
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
anchor.after(fragment);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
export default (anchor: Element, fn: Function) => {
|
|
52
|
+
let context = {
|
|
53
|
+
group: undefined as SlotGroup | undefined,
|
|
54
|
+
textnode: undefined as Element | undefined
|
|
55
|
+
},
|
|
56
|
+
state = STATE_HYDRATING;
|
|
57
|
+
|
|
58
|
+
ondisconnect(
|
|
59
|
+
anchor,
|
|
60
|
+
effect(() => {
|
|
61
|
+
let value = fn();
|
|
62
|
+
|
|
63
|
+
if (state === STATE_HYDRATING) {
|
|
64
|
+
update.call(context, anchor, value);
|
|
65
|
+
state = STATE_NONE;
|
|
66
|
+
}
|
|
67
|
+
else if (state === STATE_NONE) {
|
|
68
|
+
raf.add(() => {
|
|
69
|
+
update.call(context, anchor, value);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
);
|
|
74
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Element } from '~/types';
|
|
2
|
+
import effect from './effect';
|
|
3
|
+
import render from './render';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export default (anchor: Element, value: unknown): void => {
|
|
7
|
+
if (typeof value === 'function') {
|
|
8
|
+
return effect(anchor, value as Function);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
anchor.after(render(anchor, value));
|
|
12
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { root, ReactiveArray } from '@esportsplus/reactivity';
|
|
2
|
+
import { EMPTY_FRAGMENT } from '~/constants';
|
|
3
|
+
import { Fragment, RenderableReactive, SlotGroup } from '~/types';
|
|
4
|
+
import { append } from '~/utilities/fragment';
|
|
5
|
+
import { cloneNode, firstChild, lastChild } from '~/utilities/node';
|
|
6
|
+
import { remove } from './cleanup';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ReactiveArraySlot<T> {
|
|
10
|
+
array: ReactiveArray<T[]>;
|
|
11
|
+
fragment = cloneNode.call(EMPTY_FRAGMENT) as Fragment;
|
|
12
|
+
marker: Element;
|
|
13
|
+
nodes: SlotGroup[] = [];
|
|
14
|
+
template: (
|
|
15
|
+
this: ReactiveArray<T[]>,
|
|
16
|
+
...args: Parameters< Parameters<ReactiveArray<T[]>['map']>[0] >
|
|
17
|
+
) => SlotGroup;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
constructor(anchor: Element, array: ReactiveArray<T[]>, template: RenderableReactive['template']) {
|
|
21
|
+
let fragment = this.fragment;
|
|
22
|
+
|
|
23
|
+
this.array = array;
|
|
24
|
+
this.marker = anchor;
|
|
25
|
+
this.template = function (data, i) {
|
|
26
|
+
let frag = template.call(this, data, i).fragment,
|
|
27
|
+
group = {
|
|
28
|
+
head: firstChild.call(frag),
|
|
29
|
+
tail: lastChild.call(frag)
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
append.call(fragment, frag);
|
|
33
|
+
|
|
34
|
+
return group;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
let render = () => {
|
|
39
|
+
root(() => this.render());
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
array.on('clear', () => this.clear());
|
|
43
|
+
array.on('reverse', render);
|
|
44
|
+
array.on('pop', () => this.pop());
|
|
45
|
+
array.on('push', ({ items }) => {
|
|
46
|
+
root(() => this.push(items));
|
|
47
|
+
});
|
|
48
|
+
array.on('shift', () => this.shift());
|
|
49
|
+
array.on('sort', render);
|
|
50
|
+
array.on('splice', ({ deleteCount, items, start }) => {
|
|
51
|
+
root(() => this.splice(start, deleteCount, ...items));
|
|
52
|
+
});
|
|
53
|
+
array.on('unshift', ({ items }) => {
|
|
54
|
+
root(() => this.unshift(items));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (array.length) {
|
|
58
|
+
render();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
get length() {
|
|
64
|
+
return this.nodes.length;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
set length(n: number) {
|
|
68
|
+
if (n >= this.nodes.length) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
else if (n === 0) {
|
|
72
|
+
this.clear();
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.splice(n);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
anchor(index: number = this.nodes.length - 1) {
|
|
81
|
+
let node = this.nodes[index];
|
|
82
|
+
|
|
83
|
+
if (node) {
|
|
84
|
+
return node.tail || node.head;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return this.marker;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
clear() {
|
|
91
|
+
remove(this.nodes);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
pop() {
|
|
95
|
+
let group = this.nodes.pop();
|
|
96
|
+
|
|
97
|
+
if (group) {
|
|
98
|
+
remove([group]);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
push(items: T[]) {
|
|
103
|
+
let anchor = this.anchor(),
|
|
104
|
+
array = this.array,
|
|
105
|
+
length = this.nodes.length;
|
|
106
|
+
|
|
107
|
+
this.nodes.length = length + items.length;
|
|
108
|
+
|
|
109
|
+
for (let i = 0, n = items.length; i < n; i++) {
|
|
110
|
+
this.nodes[i + length] = this.template.call(array, items[i], i);
|
|
111
|
+
}
|
|
112
|
+
anchor.after(this.fragment);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
render() {
|
|
116
|
+
let nodes = this.nodes;
|
|
117
|
+
|
|
118
|
+
if (nodes.length) {
|
|
119
|
+
remove(nodes);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
nodes = this.array.map(this.template);
|
|
123
|
+
this.marker.after(this.fragment);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
shift() {
|
|
127
|
+
let group = this.nodes.shift();
|
|
128
|
+
|
|
129
|
+
if (group) {
|
|
130
|
+
remove([group]);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
splice(start: number, stop: number = this.nodes.length, ...items: T[]) {
|
|
135
|
+
if (!items.length) {
|
|
136
|
+
return remove(this.nodes.splice(start, stop));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let array = this.array,
|
|
140
|
+
n = items.length,
|
|
141
|
+
nodes = new Array(n);
|
|
142
|
+
|
|
143
|
+
for (let i = 0; i < n; i++) {
|
|
144
|
+
nodes[i] = this.template.call(array, items[i], i);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
remove(this.nodes.splice(start, stop, ...nodes));
|
|
148
|
+
this.anchor(start - 1).after(this.fragment);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
unshift(items: T[]) {
|
|
152
|
+
let array = this.array,
|
|
153
|
+
n = items.length,
|
|
154
|
+
nodes = new Array(n);
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < n; i++) {
|
|
157
|
+
nodes[i] = this.template.call(array, items[i], i);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.nodes.unshift(...nodes);
|
|
161
|
+
this.marker.after(this.fragment);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
export default (anchor: Element, renderable: RenderableReactive) => {
|
|
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;
|
|
177
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { isArray } from '@esportsplus/utilities';
|
|
2
|
+
import {
|
|
3
|
+
EMPTY_FRAGMENT,
|
|
4
|
+
RENDERABLE,
|
|
5
|
+
RENDERABLE_ARRAY, RENDERABLE_FRAGMENT, RENDERABLE_HTML_FRAGMENT, RENDERABLE_HTML_REACTIVE_ARRAY,
|
|
6
|
+
RENDERABLE_NODE, RENDERABLE_NODE_LIST, RENDERABLE_TEXT, RENDERABLE_VOID
|
|
7
|
+
} from '~/constants';
|
|
8
|
+
import { Element, Fragment, RenderableReactive, RenderableTemplate } from '~/types';
|
|
9
|
+
import { cloneNode } from '~/utilities/node';
|
|
10
|
+
import { append } from '~/utilities/fragment';
|
|
11
|
+
import text from '~/utilities/text';
|
|
12
|
+
import reactive from './reactive';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
function type(input: unknown) {
|
|
16
|
+
if (input === false || input == null || input === '') {
|
|
17
|
+
return RENDERABLE_VOID;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (typeof input !== 'object') {
|
|
21
|
+
return RENDERABLE_TEXT;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (RENDERABLE in input) {
|
|
25
|
+
return input[RENDERABLE];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (isArray(input)) {
|
|
29
|
+
return RENDERABLE_ARRAY;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let nodeType = (input as any).nodeType;
|
|
33
|
+
|
|
34
|
+
// Document Fragment
|
|
35
|
+
if (nodeType === 11) {
|
|
36
|
+
return RENDERABLE_FRAGMENT;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (nodeType !== undefined) {
|
|
40
|
+
return RENDERABLE_NODE;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (input instanceof NodeList) {
|
|
44
|
+
return RENDERABLE_NODE_LIST;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return RENDERABLE_TEXT;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function loop(fragment: Node, input: unknown) {
|
|
51
|
+
let t = type(input);
|
|
52
|
+
|
|
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
|
+
|
|
57
|
+
case RENDERABLE_VOID:
|
|
58
|
+
return;
|
|
59
|
+
|
|
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
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
|
|
66
|
+
case RENDERABLE_NODE_LIST:
|
|
67
|
+
append.call(fragment, ...input as Element[]);
|
|
68
|
+
return;
|
|
69
|
+
|
|
70
|
+
default:
|
|
71
|
+
append.call(fragment, input as Element)
|
|
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;
|
|
93
|
+
|
|
94
|
+
case RENDERABLE_HTML_REACTIVE_ARRAY:
|
|
95
|
+
return reactive(anchor, input as RenderableReactive);
|
|
96
|
+
|
|
97
|
+
case RENDERABLE_ARRAY:
|
|
98
|
+
for (let i = 0, n = (input as unknown[]).length; i < n; i++) {
|
|
99
|
+
loop(fragment, (input as unknown[])[i]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
break;
|
|
103
|
+
|
|
104
|
+
case RENDERABLE_FRAGMENT:
|
|
105
|
+
return input as Fragment;
|
|
106
|
+
|
|
107
|
+
case RENDERABLE_NODE:
|
|
108
|
+
append.call(fragment, input as Element);
|
|
109
|
+
break;
|
|
110
|
+
|
|
111
|
+
case RENDERABLE_NODE_LIST:
|
|
112
|
+
append.call(fragment, ...input as Element[]);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return fragment;
|
|
117
|
+
};
|
package/src/svg.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import html from './html';
|
|
2
|
-
import { RenderableTemplate } from './types';
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
const svg = html.bind(null) as typeof html & {
|
|
6
|
-
sprite:
|
|
5
|
+
sprite: (symbol: string) => ReturnType<typeof html>
|
|
7
6
|
};
|
|
8
7
|
|
|
9
8
|
svg.sprite = (symbol: string) => {
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ReactiveArray } from '@esportsplus/reactivity';
|
|
2
|
-
import { RENDERABLE,
|
|
3
|
-
import { firstChild } from './utilities';
|
|
2
|
+
import { RENDERABLE, RENDERABLE_HTML_FRAGMENT, RENDERABLE_HTML_REACTIVE_ARRAY } from './constants';
|
|
3
|
+
import { firstChild } from './utilities/node';
|
|
4
4
|
import attributes from './attributes';
|
|
5
5
|
import slot from './slot';
|
|
6
|
+
import html from './html';
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
type Attribute = Primitive | Effect<Primitive | Primitive[]>;
|
|
@@ -24,38 +25,43 @@ type Attributes = {
|
|
|
24
25
|
|
|
25
26
|
type Effect<T> = () => EffectResponse<T>;
|
|
26
27
|
|
|
27
|
-
type EffectResponse<T> = T extends [] ?
|
|
28
|
+
type EffectResponse<T> = T extends [] ? (Primitive | Renderable)[] : Primitive | Renderable;
|
|
28
29
|
|
|
29
30
|
type Element = HTMLElement & Attributes & Record<PropertyKey, unknown>;
|
|
30
31
|
|
|
31
32
|
type Elements = Element[];
|
|
32
33
|
|
|
33
|
-
type Fragment = DocumentFragment | Node
|
|
34
|
+
type Fragment = (DocumentFragment | Node) & Record<PropertyKey, unknown>;
|
|
34
35
|
|
|
35
36
|
// Copied from '@esportsplus/utilities'
|
|
36
37
|
// - Importing from ^ causes 'cannot be named without a reference to...' error
|
|
37
38
|
type Primitive = bigint | boolean | null | number | string | undefined;
|
|
38
39
|
|
|
39
|
-
type Renderable
|
|
40
|
+
type Renderable = Fragment | Primitive | RenderableReactive | RenderableTemplate;
|
|
40
41
|
|
|
41
|
-
type RenderableReactive
|
|
42
|
-
[RENDERABLE]: typeof
|
|
43
|
-
|
|
42
|
+
type RenderableReactive = Readonly<{
|
|
43
|
+
[RENDERABLE]: typeof RENDERABLE_HTML_REACTIVE_ARRAY;
|
|
44
|
+
array: ReactiveArray<unknown[]>;
|
|
44
45
|
template: (
|
|
45
|
-
this:
|
|
46
|
-
...args: Parameters< Parameters<ReactiveArray<
|
|
47
|
-
) =>
|
|
48
|
-
values: ReactiveArray<T>;
|
|
46
|
+
this: ReactiveArray<unknown[]>,
|
|
47
|
+
...args: Parameters< Parameters<ReactiveArray<unknown[]>['map']>[0] >
|
|
48
|
+
) => ReturnType<typeof html>;
|
|
49
49
|
}>;
|
|
50
50
|
|
|
51
|
-
type RenderableTemplate
|
|
52
|
-
[RENDERABLE]: typeof
|
|
51
|
+
type RenderableTemplate = {
|
|
52
|
+
[RENDERABLE]: typeof RENDERABLE_HTML_FRAGMENT;
|
|
53
|
+
fragment: Fragment;
|
|
53
54
|
literals: TemplateStringsArray;
|
|
54
|
-
template: Template | null;
|
|
55
|
-
values: (RenderableValue<T> | RenderableValue<T>[])[];
|
|
56
55
|
};
|
|
57
56
|
|
|
58
|
-
type RenderableValue<T = unknown> = Attributes | Readonly<Attributes> | Readonly<Attributes[]> | Effect<T> | Primitive |
|
|
57
|
+
type RenderableValue<T = unknown> = Attributes | Readonly<Attributes> | Readonly<Attributes[]> | Effect<T> | Fragment | Primitive | RenderableReactive;
|
|
58
|
+
|
|
59
|
+
type RenderableValues = RenderableValue | RenderableValue[];
|
|
60
|
+
|
|
61
|
+
type SlotGroup = {
|
|
62
|
+
head: Element;
|
|
63
|
+
tail: Element;
|
|
64
|
+
};
|
|
59
65
|
|
|
60
66
|
type Template = {
|
|
61
67
|
fragment: DocumentFragment;
|
|
@@ -77,6 +83,7 @@ export type {
|
|
|
77
83
|
Attributes,
|
|
78
84
|
Effect, Element, Elements,
|
|
79
85
|
Fragment,
|
|
80
|
-
Renderable, RenderableReactive, RenderableTemplate, RenderableValue,
|
|
86
|
+
Renderable, RenderableReactive, RenderableTemplate, RenderableValue, RenderableValues,
|
|
87
|
+
SlotGroup,
|
|
81
88
|
Template
|
|
82
89
|
};
|
|
@@ -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/slot.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Element, Elements, Fragment } from './types.js';
|
|
2
|
-
declare class Slot {
|
|
3
|
-
marker: Element;
|
|
4
|
-
nodes: Elements[];
|
|
5
|
-
text: Element | null;
|
|
6
|
-
constructor(marker: Element);
|
|
7
|
-
get length(): number;
|
|
8
|
-
set length(n: number);
|
|
9
|
-
anchor(index?: number): Element;
|
|
10
|
-
clear(): this;
|
|
11
|
-
pop(): this;
|
|
12
|
-
push(fragment: Fragment, ...nodes: Elements[]): this;
|
|
13
|
-
render(input: unknown, state?: number): this;
|
|
14
|
-
shift(): this;
|
|
15
|
-
splice(start: number, stop?: number, fragment?: Fragment, ...nodes: Elements[]): this;
|
|
16
|
-
unshift(fragment: Fragment, ...nodes: Elements[]): this;
|
|
17
|
-
}
|
|
18
|
-
declare const ondisconnect: (element: Element, fn: VoidFunction) => void;
|
|
19
|
-
declare const _default: (marker: Element, value: unknown) => void;
|
|
20
|
-
export default _default;
|
|
21
|
-
export { ondisconnect, Slot };
|