@esportsplus/template 0.15.16 → 0.15.18
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 +2 -2
- package/build/attributes.js +90 -45
- package/build/constants.d.ts +1 -2
- package/build/constants.js +1 -2
- package/build/event.js +6 -5
- package/build/html/hydrate.d.ts +3 -3
- package/build/html/hydrate.js +26 -25
- package/build/slot.d.ts +4 -4
- package/build/slot.js +70 -65
- package/build/types.d.ts +8 -7
- package/build/types.js +1 -1
- package/build/utilities.d.ts +2 -1
- package/build/utilities.js +2 -1
- package/package.json +3 -3
- package/src/attributes.ts +138 -50
- package/src/constants.ts +4 -16
- package/src/event.ts +8 -6
- package/src/html/hydrate.ts +31 -37
- package/src/slot.ts +95 -81
- package/src/types.ts +6 -4
- package/src/utilities.ts +3 -1
package/build/utilities.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ declare const addEventListener: {
|
|
|
3
3
|
<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
4
4
|
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
5
5
|
};
|
|
6
|
+
declare const append: (...nodes: (Node | string)[]) => void;
|
|
6
7
|
declare const removeEventListener: {
|
|
7
8
|
<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
8
9
|
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
@@ -24,4 +25,4 @@ declare const fragment: (html: string) => DocumentFragment;
|
|
|
24
25
|
declare const microtask: import("@esportsplus/tasks/build/factory").Scheduler;
|
|
25
26
|
declare const raf: import("@esportsplus/tasks/build/factory").Scheduler;
|
|
26
27
|
declare const text: (value: string) => E;
|
|
27
|
-
export { addEventListener, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, parentNode, prepend, raf, removeAttribute, removeEventListener, setAttribute, text };
|
|
28
|
+
export { addEventListener, append, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, parentNode, prepend, raf, removeAttribute, removeEventListener, setAttribute, text };
|
package/build/utilities.js
CHANGED
|
@@ -2,6 +2,7 @@ import { micro as m, raf as r } from '@esportsplus/tasks';
|
|
|
2
2
|
let prototype, template = document.createElement('template'), t = document.createTextNode('');
|
|
3
3
|
prototype = Element.prototype;
|
|
4
4
|
const addEventListener = prototype.addEventListener;
|
|
5
|
+
const append = prototype.append;
|
|
5
6
|
const removeEventListener = prototype.removeEventListener;
|
|
6
7
|
const className = Object.getOwnPropertyDescriptor(prototype, 'className').set;
|
|
7
8
|
const innerHTML = Object.getOwnPropertyDescriptor(prototype, 'innerHTML').set;
|
|
@@ -32,4 +33,4 @@ const text = (value) => {
|
|
|
32
33
|
}
|
|
33
34
|
return element;
|
|
34
35
|
};
|
|
35
|
-
export { addEventListener, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, parentNode, prepend, raf, removeAttribute, removeEventListener, setAttribute, text };
|
|
36
|
+
export { addEventListener, append, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, parentNode, prepend, raf, removeAttribute, removeEventListener, setAttribute, text };
|
package/package.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"author": "ICJR",
|
|
3
3
|
"dependencies": {
|
|
4
4
|
"@esportsplus/queue": "^0.1.0",
|
|
5
|
-
"@esportsplus/reactivity": "^0.12.
|
|
5
|
+
"@esportsplus/reactivity": "^0.12.4",
|
|
6
6
|
"@esportsplus/tasks": "^0.2.1",
|
|
7
|
-
"@esportsplus/utilities": "^0.
|
|
7
|
+
"@esportsplus/utilities": "^0.22.1"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@esportsplus/typescript": "^0.9.2"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"private": false,
|
|
15
15
|
"type": "module",
|
|
16
16
|
"types": "./build/index.d.ts",
|
|
17
|
-
"version": "0.15.
|
|
17
|
+
"version": "0.15.18",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc && tsc-alias",
|
|
20
20
|
"-": "-"
|
package/src/attributes.ts
CHANGED
|
@@ -3,15 +3,42 @@ import { isArray, isFunction, isObject, isString } from '@esportsplus/utilities'
|
|
|
3
3
|
import { ondisconnect } from './slot';
|
|
4
4
|
import { Attributes, Element } from './types';
|
|
5
5
|
import { className, raf, removeAttribute, setAttribute } from './utilities';
|
|
6
|
+
import q from '@esportsplus/queue';
|
|
6
7
|
import event from './event';
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const EFFECT_KEY = Symbol();
|
|
11
|
+
|
|
12
|
+
const HYDRATE_KEY = Symbol();
|
|
13
|
+
|
|
14
|
+
const STORE_KEY = Symbol();
|
|
15
|
+
|
|
16
|
+
const UPDATES_KEY = Symbol();
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const STATE_HYDRATING = 0;
|
|
20
|
+
|
|
21
|
+
const STATE_NONE = 1;
|
|
22
|
+
|
|
23
|
+
const STATE_WAITING = 2;
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
type Context = {
|
|
27
|
+
element: Element;
|
|
28
|
+
store: Record<PropertyKey, unknown>
|
|
29
|
+
updates: Record<PropertyKey, unknown>;
|
|
30
|
+
updating: boolean;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type State = typeof STATE_HYDRATING | typeof STATE_NONE | typeof STATE_WAITING;
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
let delimiters: Record<string, string> = {
|
|
11
37
|
class: ' ',
|
|
12
38
|
style: ';'
|
|
13
39
|
},
|
|
14
|
-
|
|
40
|
+
queue = q<Context>(64),
|
|
41
|
+
scheduled = false;
|
|
15
42
|
|
|
16
43
|
|
|
17
44
|
function attribute(element: Element, name: string, value: unknown) {
|
|
@@ -29,73 +56,115 @@ function attribute(element: Element, name: string, value: unknown) {
|
|
|
29
56
|
}
|
|
30
57
|
}
|
|
31
58
|
|
|
32
|
-
function
|
|
59
|
+
function schedule() {
|
|
60
|
+
if (scheduled) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
scheduled = true;
|
|
65
|
+
raf.add(task);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function set(context: Context, name: string, value: unknown, state: State) {
|
|
33
69
|
if (isArray(value)) {
|
|
34
70
|
for (let i = 0, n = value.length; i < n; i++) {
|
|
35
|
-
set(
|
|
71
|
+
set(context, name, value[i], state);
|
|
36
72
|
}
|
|
37
73
|
}
|
|
38
74
|
else if (isFunction(value)) {
|
|
39
75
|
if (name.startsWith('on')) {
|
|
40
|
-
event(element, name as `on${string}`, value);
|
|
76
|
+
event(context.element, name as `on${string}`, value);
|
|
41
77
|
}
|
|
42
78
|
else {
|
|
43
|
-
|
|
79
|
+
context.store[EFFECT_KEY] ??= 0;
|
|
80
|
+
|
|
81
|
+
let id = (context.store[EFFECT_KEY] as number)++;
|
|
44
82
|
|
|
45
83
|
ondisconnect(
|
|
46
|
-
element,
|
|
84
|
+
context.element,
|
|
47
85
|
effect(() => {
|
|
48
|
-
let v = (value as Function)(element);
|
|
86
|
+
let v = (value as Function)(context.element);
|
|
49
87
|
|
|
50
88
|
if (isArray(v)) {
|
|
51
89
|
let last = v.length - 1;
|
|
52
90
|
|
|
53
91
|
for (let i = 0, n = v.length; i < n; i++) {
|
|
54
|
-
update(
|
|
92
|
+
update(
|
|
93
|
+
context,
|
|
94
|
+
id,
|
|
95
|
+
name,
|
|
96
|
+
v[i],
|
|
97
|
+
state === STATE_HYDRATING
|
|
98
|
+
? state
|
|
99
|
+
: i !== last ? STATE_WAITING : state
|
|
100
|
+
);
|
|
55
101
|
}
|
|
56
102
|
}
|
|
57
103
|
else {
|
|
58
|
-
update(
|
|
104
|
+
update(context, id, name, v, state);
|
|
59
105
|
}
|
|
60
106
|
})
|
|
61
107
|
);
|
|
62
108
|
|
|
63
|
-
|
|
109
|
+
state = STATE_NONE;
|
|
64
110
|
}
|
|
65
111
|
}
|
|
66
112
|
else {
|
|
67
|
-
update(
|
|
113
|
+
update(context, null, name, value, state);
|
|
68
114
|
}
|
|
69
115
|
}
|
|
70
116
|
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
117
|
+
function task() {
|
|
118
|
+
let context,
|
|
119
|
+
n = queue.length;
|
|
120
|
+
|
|
121
|
+
while ((context = queue.next()) && n--) {
|
|
122
|
+
let { element, updates } = context;
|
|
123
|
+
|
|
124
|
+
for (let name in updates) {
|
|
125
|
+
attribute(element, name, updates[name]);
|
|
126
|
+
delete updates[name];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
context.updating = false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (queue.length) {
|
|
133
|
+
raf.add(task);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
scheduled = false;
|
|
137
|
+
}
|
|
75
138
|
}
|
|
76
139
|
|
|
77
|
-
function update(
|
|
140
|
+
function update(
|
|
141
|
+
context: Context,
|
|
142
|
+
id: null | number,
|
|
143
|
+
name: string,
|
|
144
|
+
value: unknown,
|
|
145
|
+
state: State
|
|
146
|
+
) {
|
|
78
147
|
if (value === false || value == null) {
|
|
79
148
|
value = '';
|
|
80
149
|
}
|
|
81
150
|
|
|
82
|
-
let
|
|
151
|
+
let store = context.store;
|
|
83
152
|
|
|
84
153
|
if (name in delimiters) {
|
|
85
154
|
let cache = name + '.static',
|
|
86
155
|
delimiter = delimiters[name],
|
|
87
|
-
dynamic =
|
|
156
|
+
dynamic = store[name] as Attributes | undefined;
|
|
88
157
|
|
|
89
158
|
if (dynamic === undefined) {
|
|
90
|
-
let value = (element.getAttribute(name) || '').trim();
|
|
159
|
+
let value = (context.element.getAttribute(name) || '').trim();
|
|
91
160
|
|
|
92
|
-
|
|
93
|
-
|
|
161
|
+
store[cache] = value;
|
|
162
|
+
store[name] = dynamic = {};
|
|
94
163
|
}
|
|
95
164
|
|
|
96
165
|
if (id === null) {
|
|
97
166
|
if (value && isString(value)) {
|
|
98
|
-
|
|
167
|
+
store[cache] += (store[cache] ? delimiter : '') + value;
|
|
99
168
|
}
|
|
100
169
|
}
|
|
101
170
|
else {
|
|
@@ -117,7 +186,7 @@ function update(element: Element, id: null | string, name: string, value: unknow
|
|
|
117
186
|
}
|
|
118
187
|
}
|
|
119
188
|
|
|
120
|
-
let cold =
|
|
189
|
+
let cold = store[id] as Attributes | undefined;
|
|
121
190
|
|
|
122
191
|
if (cold !== undefined) {
|
|
123
192
|
for (let part in cold) {
|
|
@@ -129,61 +198,80 @@ function update(element: Element, id: null | string, name: string, value: unknow
|
|
|
129
198
|
}
|
|
130
199
|
}
|
|
131
200
|
|
|
132
|
-
|
|
201
|
+
store[id] = hot;
|
|
133
202
|
}
|
|
134
203
|
|
|
135
|
-
value =
|
|
204
|
+
value = store[cache];
|
|
136
205
|
|
|
137
206
|
for (let key in dynamic) {
|
|
138
207
|
value += (value ? delimiter : '') + key;
|
|
139
208
|
}
|
|
140
209
|
}
|
|
141
|
-
else if (
|
|
142
|
-
if (
|
|
210
|
+
else if (id !== null) {
|
|
211
|
+
if (store[name] === value) {
|
|
143
212
|
return;
|
|
144
213
|
}
|
|
145
214
|
|
|
146
|
-
|
|
215
|
+
store[name] = value as string;
|
|
147
216
|
}
|
|
148
217
|
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
attributes[name] = value;
|
|
152
|
-
}
|
|
218
|
+
if (state === STATE_HYDRATING) {
|
|
219
|
+
((context.element[HYDRATE_KEY] ??= {}) as Record<PropertyKey, unknown>)[name] = value;
|
|
153
220
|
}
|
|
154
221
|
else {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
222
|
+
context.updates[name] = value;
|
|
223
|
+
|
|
224
|
+
if (state === STATE_NONE && !context.updating) {
|
|
225
|
+
context.updating = true;
|
|
226
|
+
queue.add(context);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!scheduled) {
|
|
230
|
+
schedule();
|
|
231
|
+
}
|
|
158
232
|
}
|
|
159
233
|
}
|
|
160
234
|
|
|
161
235
|
|
|
162
236
|
const apply = (element: Element) => {
|
|
237
|
+
let attributes = element[HYDRATE_KEY] as Record<PropertyKey, unknown> | undefined;
|
|
238
|
+
|
|
239
|
+
if (!attributes) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
163
243
|
for (let key in attributes) {
|
|
164
244
|
attribute(element, key, attributes[key]);
|
|
165
245
|
}
|
|
166
246
|
|
|
167
|
-
|
|
247
|
+
delete element[HYDRATE_KEY];
|
|
168
248
|
};
|
|
169
249
|
|
|
170
|
-
const spread = function (element: Element,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
let attrs = attributes[i];
|
|
250
|
+
const spread = function (element: Element, value: Attributes | Attributes[]) {
|
|
251
|
+
let cache = (element[STORE_KEY] ??= { [UPDATES_KEY]: {} }) as Record<PropertyKey, unknown>,
|
|
252
|
+
context = {
|
|
253
|
+
element,
|
|
254
|
+
store: cache,
|
|
255
|
+
updates: cache[UPDATES_KEY] as Record<PropertyKey, unknown>,
|
|
256
|
+
updating: false
|
|
257
|
+
};
|
|
179
258
|
|
|
180
|
-
|
|
181
|
-
|
|
259
|
+
if (isArray(value)) {
|
|
260
|
+
for (let i = 0, n = value.length; i < n; i++) {
|
|
261
|
+
let v = value[i];
|
|
262
|
+
|
|
263
|
+
for (let name in v) {
|
|
264
|
+
set(context, name, v[name], STATE_HYDRATING);
|
|
182
265
|
}
|
|
183
266
|
}
|
|
184
267
|
}
|
|
268
|
+
else if (isObject(value)) {
|
|
269
|
+
for (let name in value) {
|
|
270
|
+
set(context, name, value[name], STATE_HYDRATING);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
185
273
|
};
|
|
186
274
|
|
|
187
275
|
|
|
188
276
|
export default { apply, spread };
|
|
189
|
-
export { apply, spread }
|
|
277
|
+
export { apply, spread };
|
package/src/constants.ts
CHANGED
|
@@ -43,8 +43,6 @@ const RENDERABLE_REACTIVE = Symbol();
|
|
|
43
43
|
const RENDERABLE_TEMPLATE = Symbol();
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
const SLOT_CLEANUP = Symbol();
|
|
47
|
-
|
|
48
46
|
const SLOT_HTML = '<!--$-->';
|
|
49
47
|
|
|
50
48
|
const SLOT_MARKER = '{{$}}';
|
|
@@ -53,18 +51,8 @@ const SLOT_MARKER_LENGTH = SLOT_MARKER.length;
|
|
|
53
51
|
|
|
54
52
|
|
|
55
53
|
export {
|
|
56
|
-
NODE_CLOSING,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
NODE_WHITELIST,
|
|
61
|
-
REGEX_EMPTY_TEXT_NODES,
|
|
62
|
-
REGEX_SLOT_NODES,
|
|
63
|
-
RENDERABLE,
|
|
64
|
-
RENDERABLE_REACTIVE,
|
|
65
|
-
RENDERABLE_TEMPLATE,
|
|
66
|
-
SLOT_CLEANUP,
|
|
67
|
-
SLOT_HTML,
|
|
68
|
-
SLOT_MARKER,
|
|
69
|
-
SLOT_MARKER_LENGTH
|
|
54
|
+
NODE_CLOSING, NODE_ELEMENT, NODE_SLOT, NODE_VOID, NODE_WHITELIST,
|
|
55
|
+
REGEX_EMPTY_TEXT_NODES, REGEX_SLOT_NODES,
|
|
56
|
+
RENDERABLE, RENDERABLE_REACTIVE, RENDERABLE_TEMPLATE,
|
|
57
|
+
SLOT_HTML, SLOT_MARKER, SLOT_MARKER_LENGTH
|
|
70
58
|
};
|
package/src/event.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { root } from '@esportsplus/reactivity';
|
|
|
2
2
|
import { defineProperty } from '@esportsplus/utilities';
|
|
3
3
|
import { ondisconnect } from './slot';
|
|
4
4
|
import { Element } from './types';
|
|
5
|
-
import { addEventListener, parentElement } from './utilities';
|
|
5
|
+
import { addEventListener, parentElement, raf } from './utilities';
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
let capture = new Set<`on${string}`>(['onblur', 'onfocus', 'onscroll']),
|
|
@@ -26,7 +26,8 @@ let capture = new Set<`on${string}`>(['onblur', 'onfocus', 'onscroll']),
|
|
|
26
26
|
|
|
27
27
|
export default (element: Element, event: `on${string}`, listener: Function): void => {
|
|
28
28
|
if (event === 'onconnect') {
|
|
29
|
-
let
|
|
29
|
+
let retry = 60,
|
|
30
|
+
task = () => {
|
|
30
31
|
retry--;
|
|
31
32
|
|
|
32
33
|
if (element.isConnected) {
|
|
@@ -34,11 +35,12 @@ export default (element: Element, event: `on${string}`, listener: Function): voi
|
|
|
34
35
|
root(() => listener(element));
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
if (
|
|
38
|
-
|
|
38
|
+
if (retry) {
|
|
39
|
+
raf.add(task);
|
|
39
40
|
}
|
|
40
|
-
}
|
|
41
|
-
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
raf.add(task);
|
|
42
44
|
|
|
43
45
|
return;
|
|
44
46
|
}
|
package/src/html/hydrate.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { root
|
|
2
|
-
import { Element, Elements, Renderable, RenderableReactive, RenderableTemplate, Template } from '~/types';
|
|
1
|
+
import { root } from '@esportsplus/reactivity';
|
|
2
|
+
import { Element, Elements, HydrateResult, Renderable, RenderableReactive, RenderableTemplate, Template } from '~/types';
|
|
3
3
|
import { Slot } from '~/slot';
|
|
4
4
|
import { cloneNode, firstChild, nextSibling } from '~/utilities';
|
|
5
5
|
import { apply } from '~/attributes';
|
|
@@ -10,26 +10,36 @@ function reactive<T>(renderable: RenderableReactive<T>, slot: Slot) {
|
|
|
10
10
|
let array = renderable.values,
|
|
11
11
|
factory = renderable.template,
|
|
12
12
|
refresh = () => {
|
|
13
|
-
slot.
|
|
14
|
-
reactive(renderable, slot);
|
|
13
|
+
slot.render( root(() => array.map(template)) );
|
|
15
14
|
},
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
array.on('
|
|
15
|
+
template = function(data, i) {
|
|
16
|
+
let renderable = factory.call(this, data, i);
|
|
17
|
+
|
|
18
|
+
return hydrate<T>(renderable, cache.get(renderable));
|
|
19
|
+
} as (this: typeof array, ...args: Parameters<Parameters<typeof array['map']>[0]>) => HydrateResult;
|
|
20
|
+
|
|
21
|
+
array.on('pop', () => {
|
|
22
|
+
slot.pop();
|
|
23
|
+
});
|
|
24
|
+
array.on('push', ({ items }) => {
|
|
25
|
+
slot.push( ...root(() => array.map(template, array.length - items.length)) );
|
|
26
|
+
});
|
|
23
27
|
array.on('reverse', refresh);
|
|
24
|
-
array.on('shift', () =>
|
|
28
|
+
array.on('shift', () => {
|
|
29
|
+
slot.shift();
|
|
30
|
+
});
|
|
25
31
|
array.on('sort', refresh);
|
|
26
|
-
array.on('splice', ({ deleteCount: d, items: i, start: s }) =>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
array.on('splice', ({ deleteCount: d, items: i, start: s }) => {
|
|
33
|
+
slot.splice(s, d, ...root(() => array.map(template, s, i.length)));
|
|
34
|
+
});
|
|
35
|
+
array.on('unshift', ({ items }) => {
|
|
36
|
+
slot.unshift( ...root(() => array.map(template, 0, items.length)) );
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return array.map(template);
|
|
30
40
|
}
|
|
31
41
|
|
|
32
|
-
function
|
|
42
|
+
function hydrate<T>(renderable: Renderable<T>, template: Template): HydrateResult {
|
|
33
43
|
let elements: Elements = [],
|
|
34
44
|
fragment = cloneNode.call(template.fragment, true),
|
|
35
45
|
slots = template.slots;
|
|
@@ -42,8 +52,7 @@ function render<T>(renderable: Renderable<T>, template: Template) {
|
|
|
42
52
|
for (let i = slots.length - 1; i >= 0; i--) {
|
|
43
53
|
let { fn, path, slot } = slots[i];
|
|
44
54
|
|
|
45
|
-
if (path
|
|
46
|
-
else {
|
|
55
|
+
if (path !== previous) {
|
|
47
56
|
apply(node);
|
|
48
57
|
|
|
49
58
|
node = fragment;
|
|
@@ -55,7 +64,7 @@ function render<T>(renderable: Renderable<T>, template: Template) {
|
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
// @ts-ignore
|
|
58
|
-
fn(node, values[slot]
|
|
67
|
+
fn(node, values[slot]);
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
apply(node);
|
|
@@ -65,22 +74,7 @@ function render<T>(renderable: Renderable<T>, template: Template) {
|
|
|
65
74
|
elements.push(element);
|
|
66
75
|
}
|
|
67
76
|
|
|
68
|
-
return elements;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function template<T>(array: ReactiveArray<T>, template: RenderableReactive<T>['template'], i: number, n?: number) {
|
|
72
|
-
let groups: Elements[] = [],
|
|
73
|
-
renderables = array.map< RenderableTemplate<T> >(template, i, n);
|
|
74
|
-
|
|
75
|
-
for (let i = 0, n = renderables.length; i < n; i++) {
|
|
76
|
-
let renderable = renderables[i];
|
|
77
|
-
|
|
78
|
-
groups.push(
|
|
79
|
-
render(renderable, cache.get(renderable))
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return groups;
|
|
77
|
+
return { elements, fragment };
|
|
84
78
|
}
|
|
85
79
|
|
|
86
80
|
|
|
@@ -89,6 +83,6 @@ export default {
|
|
|
89
83
|
return reactive(renderable, slot);
|
|
90
84
|
},
|
|
91
85
|
static: <T>(renderable: RenderableTemplate<T>) => {
|
|
92
|
-
return
|
|
86
|
+
return hydrate(renderable, renderable.template || (renderable.template = cache.get(renderable)));
|
|
93
87
|
}
|
|
94
88
|
};
|