malinajs 0.6.52 → 0.7.0-alpha
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/compile.js +1304 -1050
- package/malina-esbuild.js +10 -4
- package/malina.js +1305 -1051
- package/package.json +1 -1
- package/runtime.js +433 -301
package/malina.js
CHANGED
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
function Q(s) {
|
|
28
|
-
return s.replace(
|
|
28
|
+
return s.replace(/`/g, '\\`').replace(/\\/g, '\\\\');
|
|
29
29
|
}
|
|
30
30
|
function Q2(s) {
|
|
31
|
-
return s.replace(
|
|
31
|
+
return s.replace(/`/g, '\\`').replace(/\\/g, '\\\\').replace(/\n/g, '\\n');
|
|
32
32
|
}
|
|
33
33
|
function unwrapExp(e) {
|
|
34
34
|
assert(e, 'Empty expression');
|
|
@@ -79,11 +79,20 @@
|
|
|
79
79
|
return true;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
function checkFunctionCall(body) {
|
|
83
|
+
if(body.length != 1) return;
|
|
84
|
+
if(body[0].type != 'ExpressionStatement') return;
|
|
85
|
+
let obj = body[0].expression;
|
|
86
|
+
if(obj.type != 'CallExpression') return;
|
|
87
|
+
if(obj.callee?.type == 'Identifier') return obj.callee.name;
|
|
88
|
+
}
|
|
89
|
+
|
|
82
90
|
if(checkIdentificator(ast.body)) return 'identifier';
|
|
83
91
|
if(checkMemberIdentificator(ast.body)) return 'identifier';
|
|
84
92
|
if(checkFunction(ast.body)) return 'function';
|
|
85
93
|
|
|
86
|
-
|
|
94
|
+
let fn = checkFunctionCall(ast.body);
|
|
95
|
+
if(fn) return {type: 'function-call', name: fn};
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
function checkRootName(name) {
|
|
@@ -111,147 +120,6 @@
|
|
|
111
120
|
}
|
|
112
121
|
|
|
113
122
|
|
|
114
|
-
function compactDOM() {
|
|
115
|
-
let data = this.DOM;
|
|
116
|
-
const details = {
|
|
117
|
-
node: [n => n.body],
|
|
118
|
-
each: [n => n.body],
|
|
119
|
-
slot: [n => n.body],
|
|
120
|
-
fragment: [n => n.body],
|
|
121
|
-
if: [n => n.body, n => n.bodyMain],
|
|
122
|
-
await: [n => n.parts.main, n => n.parts.then, n => n.parts.catch]
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
function go(body, parentNode) {
|
|
126
|
-
let i;
|
|
127
|
-
|
|
128
|
-
const getPrev = () => {
|
|
129
|
-
return i > 0 && body.length ? body[i - 1] : null;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const getNext = () => {
|
|
133
|
-
return i < body.length ? body[i + 1] : null;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
for(i=0; i<body.length; i++) {
|
|
137
|
-
let node = body[i];
|
|
138
|
-
if(node.type == 'text') {
|
|
139
|
-
let next = getNext();
|
|
140
|
-
if(next && next.type == 'text') {
|
|
141
|
-
node.value += next.value;
|
|
142
|
-
body.splice(i + 1, 1);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if(node.value) {
|
|
146
|
-
if(!node.value.trim()) {
|
|
147
|
-
node.value = ' ';
|
|
148
|
-
} else {
|
|
149
|
-
let rx = node.value.match(/^(\s*)(.*?)(\s*)$/);
|
|
150
|
-
if(rx) {
|
|
151
|
-
let r = '';
|
|
152
|
-
if(rx[1]) r += ' ';
|
|
153
|
-
r += rx[2];
|
|
154
|
-
if(rx[3]) r += ' ';
|
|
155
|
-
node.value = r;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
} else {
|
|
160
|
-
if(node.type == 'node' && (node.name == 'pre' || node.name == 'textarea')) continue;
|
|
161
|
-
let keys = details[node.type];
|
|
162
|
-
keys && keys.forEach(k => {
|
|
163
|
-
let body = k(node);
|
|
164
|
-
if(body && body.length) go(body, node);
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const isTable = n => ['thead', 'tbody', 'tfoot', 'tr', 'td', 'th', 'colgroup', 'col'].includes(n.name);
|
|
170
|
-
|
|
171
|
-
i = 0;
|
|
172
|
-
while(i < body.length) {
|
|
173
|
-
let node = body[i];
|
|
174
|
-
if(node.type == 'text' && !node.value.trim()) {
|
|
175
|
-
if(parentNode && (parentNode.name == 'table' || isTable(parentNode)) && (i == 0 || i == body.length -1)) {
|
|
176
|
-
body.splice(i, 1);
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
let prev = getPrev();
|
|
181
|
-
let next = getNext();
|
|
182
|
-
if(prev && next) {
|
|
183
|
-
if(prev.type == 'node' && next.type == 'node') {
|
|
184
|
-
if(isTable(prev) && isTable(next) ||
|
|
185
|
-
prev.name == 'li' && next.name == 'li' ||
|
|
186
|
-
prev.name == 'div' && next.name == 'div') {
|
|
187
|
-
body.splice(i, 1);
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
} else if(parentNode) {
|
|
192
|
-
let p = prev && prev.type == 'node' && prev.name;
|
|
193
|
-
let n = next && next.type == 'node' && next.name;
|
|
194
|
-
|
|
195
|
-
if((p == 'td' || n == 'td') && ((parentNode.type == 'node' && parentNode.name == 'tr') || (parentNode.type == 'each'))) {
|
|
196
|
-
body.splice(i, 1);
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
if((p == 'tbody' || n == 'tbody') && (parentNode.type == 'node' && parentNode.name == 'table')) {
|
|
200
|
-
body.splice(i, 1);
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
if((p == 'li' || n == 'li') && (parentNode.type == 'node' && parentNode.name == 'ul')) {
|
|
204
|
-
body.splice(i, 1);
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
if(parentNode.type == 'node' && parentNode.name == 'div') {
|
|
208
|
-
body.splice(i, 1);
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
if(parentNode.type == 'node' && (prev && prev.type == 'each' || next && next.type == 'each')) {
|
|
212
|
-
body.splice(i, 1);
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
i++;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function trimNodes(srcNodes) {
|
|
223
|
-
let nodes = srcNodes.slice();
|
|
224
|
-
let ex = [];
|
|
225
|
-
while(nodes.length) {
|
|
226
|
-
let n = nodes[0];
|
|
227
|
-
if(n.type == 'fragment' || n.type == 'comment') {
|
|
228
|
-
ex.push(n);
|
|
229
|
-
nodes.shift();
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
232
|
-
if(n.type == 'text' && !n.value.trim()) nodes.shift();
|
|
233
|
-
else break;
|
|
234
|
-
}
|
|
235
|
-
nodes = [...ex, ...nodes];
|
|
236
|
-
ex = [];
|
|
237
|
-
while(nodes.length) {
|
|
238
|
-
let n = last(nodes);
|
|
239
|
-
if(n.type == 'fragment' || n.type == 'comment') {
|
|
240
|
-
ex.push(n);
|
|
241
|
-
nodes.pop();
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
if(n.type == 'text' && !n.value.trim()) nodes.pop();
|
|
245
|
-
else break;
|
|
246
|
-
}
|
|
247
|
-
return [...nodes, ...ex];
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
data.body = trimNodes(data.body);
|
|
251
|
-
|
|
252
|
-
go(data.body);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
123
|
const genId = () => {
|
|
256
124
|
let id = Math.floor(Date.now() * Math.random()).toString(36);
|
|
257
125
|
if(id.length > 6) id = id.substring(id.length - 6);
|
|
@@ -347,95 +215,136 @@
|
|
|
347
215
|
return result;
|
|
348
216
|
};
|
|
349
217
|
|
|
350
|
-
|
|
351
218
|
function I(value = 0) {
|
|
352
219
|
this.$indent = value;
|
|
353
220
|
}
|
|
354
221
|
|
|
355
|
-
|
|
222
|
+
|
|
223
|
+
function xWriter(ctx, node) {
|
|
356
224
|
this._ctx = ctx;
|
|
357
225
|
this.inuse = ctx.inuse;
|
|
358
|
-
this.result = [];
|
|
359
|
-
this.indent = 0;
|
|
360
226
|
|
|
361
|
-
this.
|
|
362
|
-
return new I(this.indent);
|
|
363
|
-
};
|
|
364
|
-
this.writeIndent = function() {this.write(this.getIndent());};
|
|
365
|
-
this.goIndent = function(fn) {
|
|
366
|
-
this.indent++;
|
|
367
|
-
fn();
|
|
368
|
-
this.indent--;
|
|
369
|
-
};
|
|
227
|
+
this.indent = 0;
|
|
370
228
|
this.write = function(...args) {
|
|
371
229
|
for(let i of args) {
|
|
372
|
-
if(i === true)
|
|
373
|
-
else
|
|
230
|
+
if(i === true) node.$result.push(new I(this.indent));
|
|
231
|
+
else node.$result.push(i);
|
|
374
232
|
}
|
|
375
233
|
};
|
|
376
|
-
this.writeLine = function(s) {
|
|
377
|
-
|
|
234
|
+
this.writeLine = function(s) {this.write(true, s);};
|
|
235
|
+
this.writeIndent = function() {this.write(true);};
|
|
236
|
+
this.goIndent = fn => {
|
|
237
|
+
this.indent++;
|
|
238
|
+
fn();
|
|
239
|
+
this.indent--;
|
|
378
240
|
};
|
|
379
|
-
this._compile = function() {
|
|
380
|
-
let result = this.result.slice();
|
|
381
|
-
let dyn, prevDyn = 0, index = 99;
|
|
382
|
-
|
|
383
|
-
for(;index>0;index--) {
|
|
384
|
-
dyn = 0;
|
|
385
|
-
let parts = result.slice();
|
|
386
|
-
result = [];
|
|
387
|
-
parts.forEach(n => {
|
|
388
|
-
if(n.node) {
|
|
389
|
-
dyn++;
|
|
390
|
-
let r = this.subBuild(n.node, n.indent);
|
|
391
|
-
if(r?.length) result.push(...r);
|
|
392
|
-
} else result.push(n);
|
|
393
|
-
});
|
|
394
|
-
if(dyn == 0) break;
|
|
395
|
-
if(dyn == prevDyn) throw 'Compile error: circular dependencies';
|
|
396
|
-
prevDyn = dyn;
|
|
397
|
-
}
|
|
398
|
-
if(index <= 0) throw 'Compile error: circular dependencies';
|
|
399
241
|
|
|
400
|
-
|
|
242
|
+
this.add = this.build = function(n) {
|
|
243
|
+
if(n === null) return;
|
|
244
|
+
assert(n instanceof xNode);
|
|
245
|
+
assert(!n.$inserted, 'already inserted');
|
|
246
|
+
node.$result.push({node: n, indent: this.indent});
|
|
247
|
+
n.$inserted = true;
|
|
401
248
|
};
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
249
|
+
|
|
250
|
+
this.isEmpty = function(n) {
|
|
251
|
+
if(n == null) return true;
|
|
252
|
+
assert(n.$done, 'Node is not built');
|
|
253
|
+
return !n.$result.some(r => {
|
|
254
|
+
if(typeof(r) == 'string') return true;
|
|
255
|
+
else if(r.node instanceof xNode) return !this.isEmpty(r.node);
|
|
256
|
+
else if(r instanceof I) return true;
|
|
257
|
+
else {
|
|
258
|
+
console.error('Type', r);
|
|
259
|
+
throw 'error type';
|
|
409
260
|
}
|
|
410
|
-
|
|
411
|
-
}).join('');
|
|
261
|
+
});
|
|
412
262
|
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function xBuild(ctx, node) {
|
|
266
|
+
let pending = 0;
|
|
267
|
+
const resolve = n => {
|
|
268
|
+
n.$compile?.forEach(c => {
|
|
269
|
+
c != null && resolve(c);
|
|
270
|
+
});
|
|
271
|
+
if(!n.$done) {
|
|
272
|
+
let ready = true;
|
|
273
|
+
if(n.$deps?.length) {
|
|
274
|
+
if(n.$deps.some(i => i != null && !i.$done)) {
|
|
275
|
+
pending++;
|
|
276
|
+
ready = false;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if(ready) {
|
|
280
|
+
let w = new xWriter(ctx, n);
|
|
281
|
+
n.$handler(w, n);
|
|
282
|
+
n.$done = true;
|
|
419
283
|
}
|
|
420
284
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
w.build(node);
|
|
428
|
-
let r = w._compile();
|
|
429
|
-
return r.length ? r : null;
|
|
285
|
+
|
|
286
|
+
if(n.$done) {
|
|
287
|
+
n.$result.forEach(r => {
|
|
288
|
+
if(r?.node instanceof xNode) resolve(r.node);
|
|
289
|
+
});
|
|
290
|
+
} else pending++;
|
|
430
291
|
};
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
292
|
+
let depth;
|
|
293
|
+
for(depth=10;depth > 0;depth--) {
|
|
294
|
+
pending = 0;
|
|
295
|
+
resolve(node);
|
|
296
|
+
if(!pending) break;
|
|
297
|
+
}
|
|
298
|
+
if(!depth) throw new Error('xNode: Circular dependency');
|
|
299
|
+
|
|
300
|
+
let result = [];
|
|
301
|
+
|
|
302
|
+
const asm = (n, baseIndent) => {
|
|
303
|
+
if(!n.$done) {
|
|
304
|
+
console.log('not resolved', n);
|
|
305
|
+
throw 'node is not resolved';
|
|
306
|
+
}
|
|
307
|
+
n.$result.forEach(r => {
|
|
308
|
+
if(typeof(r) == 'string') result.push(r);
|
|
309
|
+
else if(r.node instanceof xNode) {
|
|
310
|
+
asm(r.node, r.indent + baseIndent);
|
|
311
|
+
}
|
|
312
|
+
else if(r instanceof I) {
|
|
313
|
+
r.$indent += baseIndent;
|
|
314
|
+
result.push(r);
|
|
315
|
+
} else {
|
|
316
|
+
console.error('Type', r);
|
|
317
|
+
throw 'error type';
|
|
318
|
+
}
|
|
435
319
|
});
|
|
436
320
|
};
|
|
321
|
+
asm(node, 0);
|
|
322
|
+
|
|
323
|
+
for(let i = 0; i < result.length; i++) {
|
|
324
|
+
let r = result[i];
|
|
325
|
+
let next = result[i+1];
|
|
326
|
+
|
|
327
|
+
if(r instanceof I) {
|
|
328
|
+
if(next instanceof I) {
|
|
329
|
+
result[i] = '';
|
|
330
|
+
} else {
|
|
331
|
+
let s = '\n';
|
|
332
|
+
let j = r.$indent;
|
|
333
|
+
while(j--) {
|
|
334
|
+
s += ' ';
|
|
335
|
+
}
|
|
336
|
+
result[i] = s;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return result.join('');
|
|
437
342
|
}
|
|
438
343
|
|
|
344
|
+
|
|
345
|
+
const noop = () => {};
|
|
346
|
+
|
|
347
|
+
|
|
439
348
|
function xNode(_type, _data, _handler) {
|
|
440
349
|
/*
|
|
441
350
|
xNode(type, data, handler)
|
|
@@ -448,7 +357,10 @@
|
|
|
448
357
|
let type, data, handler;
|
|
449
358
|
if(typeof _type == 'string') {
|
|
450
359
|
type = _type;
|
|
451
|
-
if(
|
|
360
|
+
if(_data === false && !_handler) {
|
|
361
|
+
handler = noop;
|
|
362
|
+
data = null;
|
|
363
|
+
} else if(typeof _data == 'function') {
|
|
452
364
|
assert(!_handler);
|
|
453
365
|
handler = _data;
|
|
454
366
|
} else {
|
|
@@ -474,8 +386,20 @@
|
|
|
474
386
|
assert(handler);
|
|
475
387
|
}
|
|
476
388
|
|
|
477
|
-
this
|
|
478
|
-
this
|
|
389
|
+
this.$type = type;
|
|
390
|
+
this.$handler = handler;
|
|
391
|
+
this.$done = false;
|
|
392
|
+
this.$inserted = false;
|
|
393
|
+
this.$result = [];
|
|
394
|
+
this.$depends = function(n) {
|
|
395
|
+
assert(!this.$done, 'Attempt to add dependecy, but node is already resolved');
|
|
396
|
+
if(!this.$deps) this.$deps = [];
|
|
397
|
+
this.$deps.push(n);
|
|
398
|
+
};
|
|
399
|
+
this.$value = function(value) {
|
|
400
|
+
assert(!this.$done, 'Attempt to set active, depends node is already resolved');
|
|
401
|
+
this.value = value === undefined ? true : value;
|
|
402
|
+
};
|
|
479
403
|
return this;
|
|
480
404
|
}
|
|
481
405
|
|
|
@@ -515,7 +439,7 @@
|
|
|
515
439
|
xNode.init.block.init(node);
|
|
516
440
|
},
|
|
517
441
|
handler: (ctx, node) => {
|
|
518
|
-
if(!node.inline) ctx.
|
|
442
|
+
if(!node.inline) ctx.write(true);
|
|
519
443
|
|
|
520
444
|
if(node.arrow) {
|
|
521
445
|
if(node.name) ctx.write(`let ${node.name} = `);
|
|
@@ -525,7 +449,7 @@
|
|
|
525
449
|
}
|
|
526
450
|
ctx.write(`(${node.args.join(', ')}) `);
|
|
527
451
|
if(node.arrow) ctx.write('=> ');
|
|
528
|
-
ctx.write(`{
|
|
452
|
+
ctx.write(`{`, true);
|
|
529
453
|
ctx.indent++;
|
|
530
454
|
xNode.init.block.handler(ctx, node);
|
|
531
455
|
ctx.indent--;
|
|
@@ -541,10 +465,11 @@
|
|
|
541
465
|
node.voidTag = false;
|
|
542
466
|
|
|
543
467
|
node.bindName = xNode.init.node.bindName;
|
|
468
|
+
node.getLast = () => last(node.children);
|
|
544
469
|
node.push = function(n) {
|
|
545
470
|
if(typeof n == 'string') {
|
|
546
471
|
let p = last(this.children);
|
|
547
|
-
if(p && p
|
|
472
|
+
if(p && p.$type == 'node:text') {
|
|
548
473
|
p.value += n;
|
|
549
474
|
return p;
|
|
550
475
|
}
|
|
@@ -575,7 +500,12 @@
|
|
|
575
500
|
});
|
|
576
501
|
}
|
|
577
502
|
|
|
578
|
-
let className =
|
|
503
|
+
let className = {};
|
|
504
|
+
node.class.forEach(sel => {
|
|
505
|
+
if(sel.$selector) sel = ctx._ctx.css.resolve(sel);
|
|
506
|
+
className[sel] = true;
|
|
507
|
+
});
|
|
508
|
+
className = Object.keys(className).join(' ');
|
|
579
509
|
if(className) ctx.write(` class="${className}"`);
|
|
580
510
|
|
|
581
511
|
if(node.children.length) {
|
|
@@ -612,11 +542,13 @@
|
|
|
612
542
|
},
|
|
613
543
|
template: (ctx, node) => {
|
|
614
544
|
let template = ctx._ctx.xBuild(node.body);
|
|
615
|
-
let convert;
|
|
616
|
-
if(node.svg)
|
|
617
|
-
|
|
545
|
+
let convert, cloneNode = node.cloneNode;
|
|
546
|
+
if(node.svg) {
|
|
547
|
+
convert = '$runtime.svgToFragment';
|
|
548
|
+
cloneNode = false;
|
|
549
|
+
} else if(!template.match(/[<>]/) && !node.requireFragment) {
|
|
618
550
|
convert = '$runtime.createTextNode';
|
|
619
|
-
|
|
551
|
+
cloneNode = false;
|
|
620
552
|
} else {
|
|
621
553
|
convert = '$$htmlToFragment';
|
|
622
554
|
template = template.replace(/<!---->/g, '<>');
|
|
@@ -624,33 +556,177 @@
|
|
|
624
556
|
if(node.raw) {
|
|
625
557
|
ctx.write(ctx._ctx.Q(template));
|
|
626
558
|
} else if(node.inline) {
|
|
627
|
-
ctx.write(`${convert}(\`${ctx._ctx.Q(template)}
|
|
559
|
+
ctx.write(`${convert}(\`${ctx._ctx.Q(template)}\``);
|
|
560
|
+
if(cloneNode || node.requireFragment) {
|
|
561
|
+
let opt = (cloneNode ? 1 : 0) + (node.requireFragment ? 2 : 0);
|
|
562
|
+
ctx.write(`, ${opt})`);
|
|
563
|
+
} else ctx.write(')');
|
|
628
564
|
} else {
|
|
629
565
|
assert(node.name);
|
|
630
|
-
ctx.
|
|
566
|
+
ctx.write(true, `const ${node.name} = ${convert}(\`${ctx._ctx.Q(template)}\``);
|
|
567
|
+
if(cloneNode || node.requireFragment) {
|
|
568
|
+
let opt = (cloneNode ? 1 : 0) + (node.requireFragment ? 2 : 0);
|
|
569
|
+
ctx.write(`, ${opt});`);
|
|
570
|
+
} else ctx.write(');');
|
|
631
571
|
}
|
|
632
572
|
}
|
|
633
573
|
};
|
|
634
574
|
|
|
575
|
+
function compactDOM() {
|
|
576
|
+
let data = this.DOM;
|
|
577
|
+
const details = {
|
|
578
|
+
node: [n => n.body],
|
|
579
|
+
each: [n => n.body],
|
|
580
|
+
slot: [n => n.body],
|
|
581
|
+
fragment: [n => n.body],
|
|
582
|
+
if: [n => n.body, n => n.bodyMain],
|
|
583
|
+
await: [n => n.parts.main, n => n.parts.then, n => n.parts.catch]
|
|
584
|
+
};
|
|
635
585
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
586
|
+
function go(body, parentNode) {
|
|
587
|
+
let i;
|
|
588
|
+
|
|
589
|
+
const getPrev = () => {
|
|
590
|
+
return i > 0 && body.length ? body[i - 1] : null;
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
const getNext = () => {
|
|
594
|
+
return i < body.length ? body[i + 1] : null;
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
for(i=0; i<body.length; i++) {
|
|
598
|
+
let node = body[i];
|
|
599
|
+
if(node.type == 'text') {
|
|
600
|
+
let next = getNext();
|
|
601
|
+
if(next && next.type == 'text') {
|
|
602
|
+
node.value += next.value;
|
|
603
|
+
body.splice(i + 1, 1);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if(node.value) {
|
|
607
|
+
if(!node.value.trim()) {
|
|
608
|
+
node.value = ' ';
|
|
609
|
+
} else {
|
|
610
|
+
let rx = node.value.match(/^(\s*)(.*?)(\s*)$/);
|
|
611
|
+
if(rx) {
|
|
612
|
+
let r = '';
|
|
613
|
+
if(rx[1]) r += ' ';
|
|
614
|
+
r += rx[2];
|
|
615
|
+
if(rx[3]) r += ' ';
|
|
616
|
+
node.value = r;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
} else {
|
|
621
|
+
if(node.type == 'node' && (node.name == 'pre' || node.name == 'textarea')) continue;
|
|
622
|
+
let keys = details[node.type];
|
|
623
|
+
keys && keys.forEach(k => {
|
|
624
|
+
let body = k(node);
|
|
625
|
+
if(body && body.length) go(body, node);
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const isTable = n => ['thead', 'tbody', 'tfoot', 'tr', 'td', 'th'].includes(n.name);
|
|
631
|
+
|
|
632
|
+
i = 0;
|
|
633
|
+
while(i < body.length) {
|
|
634
|
+
let node = body[i];
|
|
635
|
+
if(node.type == 'text' && !node.value.trim()) {
|
|
636
|
+
if(parentNode && (parentNode.name == 'table' || isTable(parentNode)) && (i == 0 || i == body.length -1)) {
|
|
637
|
+
body.splice(i, 1);
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
let prev = getPrev();
|
|
642
|
+
let next = getNext();
|
|
643
|
+
|
|
644
|
+
if(next?.type == 'node' && ['br', 'div'].includes(next.name)) {
|
|
645
|
+
body.splice(i, 1);
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if(prev?.type == 'node' && ['br', 'div'].includes(prev.name)) {
|
|
650
|
+
body.splice(i, 1);
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
if(prev && next) {
|
|
655
|
+
if(prev.type == 'node' && next.type == 'node') {
|
|
656
|
+
if(isTable(prev) && isTable(next) ||
|
|
657
|
+
prev.name == 'li' && next.name == 'li' ||
|
|
658
|
+
prev.name == 'div' && next.name == 'div') {
|
|
659
|
+
body.splice(i, 1);
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
} else if(parentNode) {
|
|
664
|
+
let p = prev && prev.type == 'node' && prev.name;
|
|
665
|
+
let n = next && next.type == 'node' && next.name;
|
|
666
|
+
|
|
667
|
+
if((p == 'td' || n == 'td') && ((parentNode.type == 'node' && parentNode.name == 'tr') || (parentNode.type == 'each'))) {
|
|
668
|
+
body.splice(i, 1);
|
|
669
|
+
continue;
|
|
670
|
+
}
|
|
671
|
+
if((p == 'tbody' || n == 'tbody') && (parentNode.type == 'node' && parentNode.name == 'table')) {
|
|
672
|
+
body.splice(i, 1);
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if((p == 'li' || n == 'li') && (parentNode.type == 'node' && parentNode.name == 'ul')) {
|
|
676
|
+
body.splice(i, 1);
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
if(parentNode.type == 'node' && parentNode.name == 'div') {
|
|
680
|
+
body.splice(i, 1);
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
if(parentNode.type == 'node' && (prev && prev.type == 'each' || next && next.type == 'each')) {
|
|
684
|
+
body.splice(i, 1);
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
if(parentNode.type == 'node' && parentNode.name == 'button' && (!p || !n)) {
|
|
688
|
+
body.splice(i, 1);
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
i++;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
function trimNodes(srcNodes) {
|
|
699
|
+
let nodes = srcNodes.slice();
|
|
700
|
+
let ex = [];
|
|
701
|
+
while(nodes.length) {
|
|
702
|
+
let n = nodes[0];
|
|
703
|
+
if(n.type == 'fragment' || n.type == 'comment') {
|
|
704
|
+
ex.push(n);
|
|
705
|
+
nodes.shift();
|
|
706
|
+
continue;
|
|
707
|
+
}
|
|
708
|
+
if(n.type == 'text' && !n.value.trim()) nodes.shift();
|
|
709
|
+
else break;
|
|
710
|
+
}
|
|
711
|
+
nodes = [...ex, ...nodes];
|
|
712
|
+
ex = [];
|
|
713
|
+
while(nodes.length) {
|
|
714
|
+
let n = last(nodes);
|
|
715
|
+
if(n.type == 'fragment' || n.type == 'comment') {
|
|
716
|
+
ex.push(n);
|
|
717
|
+
nodes.pop();
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
if(n.type == 'text' && !n.value.trim()) nodes.pop();
|
|
721
|
+
else break;
|
|
722
|
+
}
|
|
723
|
+
return [...nodes, ...ex];
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
data.body = trimNodes(data.body);
|
|
727
|
+
|
|
728
|
+
go(data.body);
|
|
729
|
+
}
|
|
654
730
|
|
|
655
731
|
function parse() {
|
|
656
732
|
let source = this.source;
|
|
@@ -739,7 +815,7 @@
|
|
|
739
815
|
}
|
|
740
816
|
}
|
|
741
817
|
if(begin) {
|
|
742
|
-
if(a.match(/[\da-zA-Z
|
|
818
|
+
if(a.match(/[\da-zA-Z^]/)) {
|
|
743
819
|
name += a;
|
|
744
820
|
continue;
|
|
745
821
|
} else {
|
|
@@ -1101,13 +1177,11 @@
|
|
|
1101
1177
|
watchers: [],
|
|
1102
1178
|
imports: [],
|
|
1103
1179
|
importedNames: [],
|
|
1104
|
-
autosubscribeNames: [],
|
|
1105
1180
|
props: [],
|
|
1106
1181
|
rootVariables: {},
|
|
1107
1182
|
rootFunctions: {},
|
|
1108
1183
|
readOnly: false,
|
|
1109
|
-
autoimport: {}
|
|
1110
|
-
comments: []
|
|
1184
|
+
autoimport: {}
|
|
1111
1185
|
};
|
|
1112
1186
|
if(source) {
|
|
1113
1187
|
this.script.readOnly = this.scriptNodes.some(n => n.attributes.some(a => a.name == 'read-only'));
|
|
@@ -1121,11 +1195,7 @@
|
|
|
1121
1195
|
return rx[1] + '$$_noCheck;';
|
|
1122
1196
|
}).join('\n');
|
|
1123
1197
|
}
|
|
1124
|
-
|
|
1125
|
-
if(isBlockComment) return;
|
|
1126
|
-
this.script.comments.push({start, end, value});
|
|
1127
|
-
};
|
|
1128
|
-
this.script.ast = acorn.parse(source, {sourceType: 'module', ecmaVersion: 12, onComment});
|
|
1198
|
+
this.script.ast = acorn.parse(source, {sourceType: 'module', ecmaVersion: 12});
|
|
1129
1199
|
|
|
1130
1200
|
if(source.includes('$props')) this.require('$props');
|
|
1131
1201
|
if(source.includes('$attributes')) this.require('$attributes');
|
|
@@ -1286,7 +1356,7 @@
|
|
|
1286
1356
|
|
|
1287
1357
|
const makeWatch = (n) => {
|
|
1288
1358
|
function assertExpression(n) {
|
|
1289
|
-
if(
|
|
1359
|
+
if(n.type == 'Identifier') return;
|
|
1290
1360
|
if(n.type.endsWith('Expression')) return;
|
|
1291
1361
|
throw 'Wrong expression';
|
|
1292
1362
|
}
|
|
@@ -1332,31 +1402,14 @@
|
|
|
1332
1402
|
let lastPropIndex = null;
|
|
1333
1403
|
let constantProps = true;
|
|
1334
1404
|
|
|
1335
|
-
if(result.comments.length) {
|
|
1336
|
-
result.comments.forEach(c => {
|
|
1337
|
-
for(let i = 1; i < ast.body.length; i++) {
|
|
1338
|
-
let p = ast.body[i-1];
|
|
1339
|
-
let n = ast.body[i];
|
|
1340
|
-
if(p.end < c.start && c.start < n.start) {
|
|
1341
|
-
p._comment = c.value;
|
|
1342
|
-
return;
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
});
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
1405
|
ast.body.forEach(n => {
|
|
1349
1406
|
if(n.type == 'ImportDeclaration') {
|
|
1350
1407
|
imports.push(n);
|
|
1351
1408
|
n.specifiers.forEach(s => {
|
|
1352
1409
|
if(s.local.type != 'Identifier') return;
|
|
1353
|
-
|
|
1354
|
-
result.importedNames.push(name);
|
|
1355
|
-
if(name[0].toLowerCase() == name[0]) {
|
|
1356
|
-
if(!n._comment || !n._comment.includes('!no-autosubscribe')) result.autosubscribeNames.push(s.local.name);
|
|
1357
|
-
}
|
|
1410
|
+
result.importedNames.push(s.local.name);
|
|
1358
1411
|
if(s.type != 'ImportDefaultSpecifier') return;
|
|
1359
|
-
result.imports.push(name);
|
|
1412
|
+
result.imports.push(s.local.name);
|
|
1360
1413
|
});
|
|
1361
1414
|
return;
|
|
1362
1415
|
} else if(n.type == 'ExportNamedDeclaration') {
|
|
@@ -1390,11 +1443,12 @@
|
|
|
1390
1443
|
resultBody.push(n);
|
|
1391
1444
|
});
|
|
1392
1445
|
|
|
1446
|
+
this.glob.component.$handler = (ctx, n) => {
|
|
1447
|
+
if(this.inuse.$component || n.value) ctx.writeLine('const $component = $runtime.current_component;');
|
|
1448
|
+
};
|
|
1449
|
+
this.module.head.push(this.glob.component);
|
|
1450
|
+
|
|
1393
1451
|
let header = [];
|
|
1394
|
-
header.push(rawNode(() => {
|
|
1395
|
-
if(this.inuse.$component) return 'const $component = $runtime.current_component;';
|
|
1396
|
-
}));
|
|
1397
|
-
|
|
1398
1452
|
header.push(rawNode(() => {
|
|
1399
1453
|
if(this.inuse.$events) return 'const $events = $option.events || {};';
|
|
1400
1454
|
}));
|
|
@@ -1404,7 +1458,7 @@
|
|
|
1404
1458
|
if(this.inuse.$props) return 'let $props = $option.props || {};';
|
|
1405
1459
|
}));
|
|
1406
1460
|
|
|
1407
|
-
if(!constantProps && !this.script.readOnly) this.require('apply'
|
|
1461
|
+
if(!constantProps && !this.script.readOnly) this.require('apply');
|
|
1408
1462
|
|
|
1409
1463
|
resultBody.splice(lastPropIndex, 0, rawNode(() => {
|
|
1410
1464
|
let code = [];
|
|
@@ -1463,11 +1517,14 @@
|
|
|
1463
1517
|
if(this.inuse.$onDestroy) return `const $onDestroy = fn => $component._d.push(fn);`;
|
|
1464
1518
|
}));
|
|
1465
1519
|
|
|
1466
|
-
if(this.config.autoSubscribe
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
if(this.
|
|
1470
|
-
|
|
1520
|
+
if(this.config.autoSubscribe) {
|
|
1521
|
+
let names = result.importedNames.filter(name => name[0].toLowerCase() == name[0]);
|
|
1522
|
+
if(names.length) {
|
|
1523
|
+
if(!this.script.readOnly) this.require('$cd', 'apply');
|
|
1524
|
+
header.push(rawNode(() => {
|
|
1525
|
+
if(this.inuse.apply) return `$runtime.autoSubscribe(${names.join(', ')});`;
|
|
1526
|
+
}));
|
|
1527
|
+
}
|
|
1471
1528
|
}
|
|
1472
1529
|
|
|
1473
1530
|
if(!rootFunctions.$emit) {
|
|
@@ -1555,21 +1612,38 @@
|
|
|
1555
1612
|
let code = astring.generate({
|
|
1556
1613
|
type: 'CustomBlock',
|
|
1557
1614
|
body: node.body
|
|
1558
|
-
}, {generator, startingIndentLevel:
|
|
1559
|
-
|
|
1615
|
+
}, {generator, startingIndentLevel: 0});
|
|
1616
|
+
code.split(/\n/).forEach(s => {
|
|
1617
|
+
if(s) ctx.write(true, s);
|
|
1618
|
+
});
|
|
1560
1619
|
};
|
|
1561
1620
|
|
|
1562
1621
|
function buildRuntime() {
|
|
1563
|
-
let runtime = xNode('block', {scope: true});
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1622
|
+
let runtime = xNode('block', {scope: true, $compile: []});
|
|
1623
|
+
|
|
1624
|
+
let rootCD = this.glob.rootCD;
|
|
1625
|
+
rootCD.$handler = (ctx, n) => {
|
|
1626
|
+
n.$value(!!n.$deps[0].value);
|
|
1627
|
+
if(n.value) {
|
|
1628
|
+
ctx.writeLine('let $cd = $component.$cd;');
|
|
1629
|
+
this.glob.component.$value(true);
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
runtime.push(rootCD);
|
|
1633
|
+
this.glob.component.$depends(rootCD);
|
|
1567
1634
|
|
|
1568
|
-
let bb = this.buildBlock(this.DOM, {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1635
|
+
let bb = this.buildBlock(this.DOM, {
|
|
1636
|
+
inline: true,
|
|
1637
|
+
template: {
|
|
1638
|
+
name: '$parentElement',
|
|
1639
|
+
cloneNode: true
|
|
1640
|
+
}
|
|
1641
|
+
});
|
|
1642
|
+
bb.requireCD && rootCD.$depends(bb.requireCD);
|
|
1643
|
+
runtime.push(bb.template);
|
|
1644
|
+
runtime.push(xNode('root-event', (ctx) => {
|
|
1645
|
+
if(!this.inuse.rootEvent) return;
|
|
1646
|
+
ctx.write(true, `const $$addRootEvent = $runtime.makeRootEvent($parentElement);`);
|
|
1573
1647
|
}));
|
|
1574
1648
|
runtime.push(bb.source);
|
|
1575
1649
|
|
|
@@ -1592,8 +1666,10 @@
|
|
|
1592
1666
|
}
|
|
1593
1667
|
}));
|
|
1594
1668
|
|
|
1595
|
-
runtime.push(xNode('bind-component-element',
|
|
1596
|
-
|
|
1669
|
+
runtime.push(xNode('bind-component-element', {
|
|
1670
|
+
$deps: [this.glob.componentFn]
|
|
1671
|
+
}, (ctx) => {
|
|
1672
|
+
if(this.glob.componentFn.value == 'thin') ctx.writeLine(`return {$dom: $parentElement};`);
|
|
1597
1673
|
else ctx.writeLine('return $parentElement;');
|
|
1598
1674
|
}));
|
|
1599
1675
|
|
|
@@ -1627,17 +1703,34 @@
|
|
|
1627
1703
|
|
|
1628
1704
|
function buildBlock(data, option={}) {
|
|
1629
1705
|
let rootTemplate = xNode('node', {inline: true, _ctx: this});
|
|
1706
|
+
let rootSVG = false, requireFragment = option.template?.requireFragment;
|
|
1630
1707
|
let binds = xNode('block');
|
|
1631
1708
|
let result = {};
|
|
1709
|
+
let requireCD = result.requireCD = xNode('require-cd', false);
|
|
1632
1710
|
let inuse = Object.assign({}, this.inuse);
|
|
1633
1711
|
|
|
1712
|
+
if(!option.parentElement) option.parentElement = '$parentElement';
|
|
1713
|
+
|
|
1714
|
+
if(option.each?.blockPrefix) binds.push(option.each.blockPrefix);
|
|
1715
|
+
|
|
1716
|
+
if(option.allowSingleBlock && data.body.length == 1) {
|
|
1717
|
+
let n = data.body[0];
|
|
1718
|
+
if(n.type == 'node' && n.name.match(/^[A-Z]/)) {
|
|
1719
|
+
let component = this.makeComponent(n, requireCD);
|
|
1720
|
+
return {
|
|
1721
|
+
requireCD,
|
|
1722
|
+
singleBlock: component.bind
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1634
1727
|
const go = (data, isRoot, tpl) => {
|
|
1635
1728
|
let body = data.body.filter(n => {
|
|
1636
1729
|
if(n.type == 'script' || n.type == 'style' || n.type == 'slot') return false;
|
|
1637
1730
|
if(n.type == 'comment' && !this.config.preserveComments) return false;
|
|
1638
1731
|
if(n.type == 'fragment') {
|
|
1639
1732
|
try {
|
|
1640
|
-
let f = this.makeFragment(n);
|
|
1733
|
+
let f = this.makeFragment(n, requireCD);
|
|
1641
1734
|
f && binds.push(f);
|
|
1642
1735
|
} catch (e) {
|
|
1643
1736
|
wrapException(e, n);
|
|
@@ -1650,7 +1743,7 @@
|
|
|
1650
1743
|
if(tpl.name == 'table') {
|
|
1651
1744
|
let result = [], tbody = null;
|
|
1652
1745
|
body.forEach(n => {
|
|
1653
|
-
if(n.type == 'node' && ['thead', 'tbody', 'tfoot'
|
|
1746
|
+
if(n.type == 'node' && ['thead', 'tbody', 'tfoot'].includes(n.name)) {
|
|
1654
1747
|
result.push(n);
|
|
1655
1748
|
tbody = null;
|
|
1656
1749
|
return;
|
|
@@ -1682,11 +1775,29 @@
|
|
|
1682
1775
|
if(svgElements[node.name]) svg = true;
|
|
1683
1776
|
else return other = true;
|
|
1684
1777
|
});
|
|
1685
|
-
if(svg && !other)
|
|
1778
|
+
if(svg && !other) rootSVG = true;
|
|
1686
1779
|
}
|
|
1687
1780
|
|
|
1781
|
+
let lastStatic;
|
|
1782
|
+
|
|
1783
|
+
const placeLabel = name => {
|
|
1784
|
+
let el;
|
|
1785
|
+
if(lastStatic) {
|
|
1786
|
+
el = lastStatic;
|
|
1787
|
+
el.label = true;
|
|
1788
|
+
lastStatic = null;
|
|
1789
|
+
} else {
|
|
1790
|
+
el = xNode('node:comment', {label: true, value: name});
|
|
1791
|
+
tpl.push(el);
|
|
1792
|
+
}
|
|
1793
|
+
return el;
|
|
1794
|
+
};
|
|
1795
|
+
|
|
1688
1796
|
const bindNode = (n) => {
|
|
1689
1797
|
if(n.type === 'text') {
|
|
1798
|
+
let prev = tpl.getLast();
|
|
1799
|
+
if(prev?.$type == 'node:text' && prev._boundName) tpl.push(xNode('node:comment', {label: true}));
|
|
1800
|
+
|
|
1690
1801
|
if(n.value.indexOf('{') >= 0) {
|
|
1691
1802
|
const pe = this.parseText(n.value);
|
|
1692
1803
|
this.detectDependency(pe);
|
|
@@ -1696,13 +1807,18 @@
|
|
|
1696
1807
|
textNode = tpl.push(pe.staticText);
|
|
1697
1808
|
} else {
|
|
1698
1809
|
textNode = tpl.push(' ');
|
|
1699
|
-
|
|
1810
|
+
let bindText = xNode('bindText', {
|
|
1811
|
+
$deps: [this.glob.apply],
|
|
1700
1812
|
el: textNode.bindName(),
|
|
1701
1813
|
exp: pe.result
|
|
1702
1814
|
}, (ctx, n) => {
|
|
1703
|
-
if(this.
|
|
1704
|
-
|
|
1705
|
-
|
|
1815
|
+
if(this.glob.apply.value) {
|
|
1816
|
+
requireCD.$value(true);
|
|
1817
|
+
ctx.writeLine(`$runtime.bindText($cd, ${n.el}, () => ${n.exp});`);
|
|
1818
|
+
} else ctx.writeLine(`${n.el}.textContent = ${n.exp};`);
|
|
1819
|
+
});
|
|
1820
|
+
binds.push(bindText);
|
|
1821
|
+
requireCD.$depends(bindText);
|
|
1706
1822
|
}
|
|
1707
1823
|
|
|
1708
1824
|
pe.parts.forEach(p => {
|
|
@@ -1714,32 +1830,46 @@
|
|
|
1714
1830
|
]}));
|
|
1715
1831
|
});
|
|
1716
1832
|
|
|
1833
|
+
lastStatic = textNode;
|
|
1717
1834
|
} else {
|
|
1718
|
-
tpl.push(n.value);
|
|
1835
|
+
lastStatic = tpl.push(n.value);
|
|
1719
1836
|
}
|
|
1720
1837
|
} else if(n.type === 'template') {
|
|
1838
|
+
lastStatic = null;
|
|
1721
1839
|
tpl.push(n.openTag);
|
|
1722
1840
|
tpl.push(n.content);
|
|
1723
1841
|
tpl.push('</template>');
|
|
1724
1842
|
} else if(n.type === 'node') {
|
|
1725
1843
|
if(n.name == 'malina' && !option.malinaElement) {
|
|
1726
1844
|
let b;
|
|
1727
|
-
if(n.elArg == 'portal') b = this.attachPortal(n);
|
|
1728
|
-
else b = this.attachHead(n);
|
|
1845
|
+
if(n.elArg == 'portal') b = this.attachPortal(n, requireCD);
|
|
1846
|
+
else b = this.attachHead(n, requireCD);
|
|
1729
1847
|
b && binds.push(b);
|
|
1730
1848
|
return;
|
|
1731
1849
|
}
|
|
1732
1850
|
if(n.name == 'component' || n.name.match(/^[A-Z]/)) {
|
|
1733
1851
|
if(n.name == 'component' || !n.elArg) {
|
|
1734
1852
|
// component
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1853
|
+
if(isRoot) requireFragment = true;
|
|
1854
|
+
let el = placeLabel(n.name);
|
|
1855
|
+
|
|
1856
|
+
if(n.name == 'component') {
|
|
1857
|
+
// dyn-component
|
|
1858
|
+
binds.push(this.makeComponentDyn(n, requireCD, el));
|
|
1859
|
+
} else {
|
|
1860
|
+
let component = this.makeComponent(n, requireCD);
|
|
1861
|
+
binds.push(xNode('attach-component', {
|
|
1862
|
+
component: component.bind,
|
|
1863
|
+
el: el.bindName()
|
|
1864
|
+
}, (ctx, n) => {
|
|
1865
|
+
ctx.write(true, `$runtime.attachBlock($cd, ${n.el}, `);
|
|
1866
|
+
ctx.add(n.component);
|
|
1867
|
+
ctx.write(')');
|
|
1868
|
+
}));
|
|
1869
|
+
}
|
|
1739
1870
|
} else {
|
|
1740
|
-
let el =
|
|
1741
|
-
|
|
1742
|
-
let b = this.attchExportedFragment(n, el, n.name);
|
|
1871
|
+
let el = placeLabel(`exported ${n.elArg}`);
|
|
1872
|
+
let b = this.attchExportedFragment(n, el, n.name, requireCD);
|
|
1743
1873
|
b && binds.push(b);
|
|
1744
1874
|
}
|
|
1745
1875
|
return;
|
|
@@ -1748,33 +1878,52 @@
|
|
|
1748
1878
|
let slotName = n.elArg;
|
|
1749
1879
|
if(!slotName) {
|
|
1750
1880
|
if(option.context == 'fragment') {
|
|
1751
|
-
let el =
|
|
1752
|
-
|
|
1753
|
-
binds.push(this.attachFragmentSlot(el));
|
|
1881
|
+
let el = placeLabel('fragment-slot');
|
|
1882
|
+
binds.push(this.attachFragmentSlot(el, requireCD));
|
|
1754
1883
|
return;
|
|
1755
1884
|
} else slotName = 'default';
|
|
1756
1885
|
}
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1886
|
+
|
|
1887
|
+
let el = placeLabel(slotName);
|
|
1888
|
+
let slot = this.attachSlot(slotName, n, requireCD);
|
|
1889
|
+
|
|
1890
|
+
binds.push(xNode('attach-slot', {
|
|
1891
|
+
$deps: [requireCD],
|
|
1892
|
+
$compile: [slot],
|
|
1893
|
+
el: el.bindName(),
|
|
1894
|
+
slot,
|
|
1895
|
+
requireCD
|
|
1896
|
+
}, (ctx, n) => {
|
|
1897
|
+
if(n.requireCD.value) ctx.write(true, `$runtime.attachBlock($cd, ${n.el}, `);
|
|
1898
|
+
else ctx.write(true, `$runtime.attachBlock($component, ${n.el}, `);
|
|
1899
|
+
ctx.add(n.slot);
|
|
1900
|
+
ctx.write(');', true);
|
|
1901
|
+
}));
|
|
1760
1902
|
return;
|
|
1761
1903
|
}
|
|
1762
1904
|
if(n.name == 'fragment') {
|
|
1905
|
+
requireCD.$value(true);
|
|
1763
1906
|
assert(n.elArg, 'Fragment name is required');
|
|
1764
|
-
let el =
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1907
|
+
let el = placeLabel(`fragment ${n.elArg}`);
|
|
1908
|
+
binds.push(xNode('attach-fragment', {
|
|
1909
|
+
el: el.bindName(),
|
|
1910
|
+
fragment: this.attachFragment(n)
|
|
1911
|
+
}, (ctx, n) => {
|
|
1912
|
+
ctx.write(true, `$runtime.attachBlock($cd, ${n.el}, `);
|
|
1913
|
+
ctx.add(n.fragment);
|
|
1914
|
+
ctx.write(`)`);
|
|
1915
|
+
}));
|
|
1768
1916
|
return;
|
|
1769
1917
|
}
|
|
1770
1918
|
|
|
1771
1919
|
let el = xNode('node', {name: n.name});
|
|
1772
1920
|
if(option.oneElement) el._boundName = option.oneElement;
|
|
1773
1921
|
tpl.push(el);
|
|
1922
|
+
lastStatic = el;
|
|
1774
1923
|
|
|
1775
1924
|
if(n.attributes.some(a => a.name.startsWith('{...'))) {
|
|
1776
1925
|
n.spreading = [];
|
|
1777
|
-
|
|
1926
|
+
requireCD.$value(true);
|
|
1778
1927
|
binds.push(xNode('spread-to-element', {
|
|
1779
1928
|
el: el.bindName(),
|
|
1780
1929
|
props: n.spreading
|
|
@@ -1784,7 +1933,7 @@
|
|
|
1784
1933
|
}
|
|
1785
1934
|
let bindTail = [];
|
|
1786
1935
|
n.attributes.forEach(p => {
|
|
1787
|
-
let b = this.bindProp(p, n, el);
|
|
1936
|
+
let b = this.bindProp(p, n, el, requireCD);
|
|
1788
1937
|
if(b) {
|
|
1789
1938
|
if(b.bind) binds.push(b.bind);
|
|
1790
1939
|
if(b.bindTail) bindTail.push(b.bindTail);
|
|
@@ -1816,7 +1965,9 @@
|
|
|
1816
1965
|
go(n, false, el);
|
|
1817
1966
|
}
|
|
1818
1967
|
} else if(n.type === 'each') {
|
|
1968
|
+
requireCD.$value(true);
|
|
1819
1969
|
if(data.type == 'node' && data.body.length == 1) {
|
|
1970
|
+
lastStatic = null;
|
|
1820
1971
|
let eachBlock = this.makeEachBlock(n, {
|
|
1821
1972
|
elName: tpl.bindName(),
|
|
1822
1973
|
onlyChild: true
|
|
@@ -1824,17 +1975,15 @@
|
|
|
1824
1975
|
binds.push(eachBlock.source);
|
|
1825
1976
|
return;
|
|
1826
1977
|
} else {
|
|
1827
|
-
|
|
1828
|
-
|
|
1978
|
+
if(isRoot) requireFragment = true;
|
|
1979
|
+
let element = placeLabel(n.value);
|
|
1829
1980
|
let eachBlock = this.makeEachBlock(n, {elName: element.bindName()});
|
|
1830
1981
|
binds.push(eachBlock.source);
|
|
1831
1982
|
return;
|
|
1832
1983
|
}
|
|
1833
1984
|
} else if(n.type === 'if') {
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
let ifBlock = this.makeifBlock(n, element);
|
|
1837
|
-
binds.push(ifBlock.source);
|
|
1985
|
+
if(isRoot) requireFragment = true;
|
|
1986
|
+
binds.push(this.makeifBlock(n, placeLabel(n.value), requireCD));
|
|
1838
1987
|
return;
|
|
1839
1988
|
} else if(n.type === 'systag') {
|
|
1840
1989
|
let r = n.value.match(/^@(\w+)\s+(.*)$/s);
|
|
@@ -1842,18 +1991,20 @@
|
|
|
1842
1991
|
let exp = r[2];
|
|
1843
1992
|
|
|
1844
1993
|
if(name == 'html') {
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
binds.push(this.makeHtmlBlock(exp, el));
|
|
1994
|
+
if(isRoot) requireFragment = true;
|
|
1995
|
+
let el = placeLabel('html');
|
|
1996
|
+
binds.push(this.makeHtmlBlock(exp, el, requireCD));
|
|
1848
1997
|
return;
|
|
1849
1998
|
} else throw 'Wrong tag';
|
|
1850
1999
|
} else if(n.type === 'await') {
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
2000
|
+
if(isRoot) requireFragment = true;
|
|
2001
|
+
requireCD.$value(true);
|
|
2002
|
+
let el = placeLabel(n.value);
|
|
2003
|
+
let r = this.makeAwaitBlock(n, el);
|
|
2004
|
+
r && binds.push(r);
|
|
1854
2005
|
return;
|
|
1855
2006
|
} else if(n.type === 'comment') {
|
|
1856
|
-
tpl.push(n.content);
|
|
2007
|
+
lastStatic = tpl.push(n.content);
|
|
1857
2008
|
}
|
|
1858
2009
|
};
|
|
1859
2010
|
body.forEach(node => {
|
|
@@ -1866,57 +2017,111 @@
|
|
|
1866
2017
|
};
|
|
1867
2018
|
go(data, true, rootTemplate);
|
|
1868
2019
|
if(option.protectLastTag) {
|
|
1869
|
-
let l =
|
|
1870
|
-
if(l
|
|
2020
|
+
let l = rootTemplate.getLast();
|
|
2021
|
+
if(l?.label) {
|
|
1871
2022
|
rootTemplate.push(xNode('node:comment', {value: ''}));
|
|
1872
2023
|
}
|
|
1873
2024
|
}
|
|
1874
2025
|
|
|
1875
|
-
|
|
1876
|
-
|
|
2026
|
+
let innerBlock = null;
|
|
1877
2027
|
if(binds.body.length) {
|
|
1878
|
-
|
|
2028
|
+
binds.push(requireCD);
|
|
2029
|
+
innerBlock = xNode('block');
|
|
1879
2030
|
if(!option.oneElement) {
|
|
1880
|
-
innerBlock.push(xNode('bindNodes',
|
|
2031
|
+
innerBlock.push(xNode('bindNodes', {
|
|
2032
|
+
tpl: rootTemplate,
|
|
2033
|
+
root: option.parentElement,
|
|
2034
|
+
single: rootTemplate.children.length == 1 && !requireFragment
|
|
2035
|
+
}, (ctx, n) => {
|
|
1881
2036
|
|
|
1882
2037
|
const gen = (parent, parentName) => {
|
|
1883
2038
|
for(let i=0; i < parent.children.length; i++) {
|
|
1884
2039
|
let node = parent.children[i];
|
|
1885
2040
|
let diff = i == 0 ? '[$runtime.firstChild]' : `[$runtime.childNodes][${i}]`;
|
|
1886
2041
|
|
|
1887
|
-
if(node._boundName) ctx.
|
|
2042
|
+
if(node._boundName) ctx.write(true, `let ${node._boundName} = ${parentName() + diff};`);
|
|
1888
2043
|
if(node.children) gen(node, () => {
|
|
1889
2044
|
if(node._boundName) return node._boundName;
|
|
1890
2045
|
return parentName() + diff;
|
|
1891
2046
|
});
|
|
1892
2047
|
}
|
|
1893
2048
|
};
|
|
1894
|
-
|
|
2049
|
+
if(n.single) {
|
|
2050
|
+
let node = n.tpl.children[0];
|
|
2051
|
+
if(node._boundName) ctx.write(true, `let ${node._boundName} = ${n.root};`);
|
|
2052
|
+
if(node.children) gen(node, () => n.root);
|
|
2053
|
+
} else {
|
|
2054
|
+
gen(n.tpl, () => n.root);
|
|
2055
|
+
}
|
|
1895
2056
|
}));
|
|
1896
2057
|
}
|
|
1897
2058
|
innerBlock.push(binds);
|
|
1898
2059
|
|
|
1899
2060
|
if(option.inline) {
|
|
1900
2061
|
result.source = innerBlock;
|
|
1901
|
-
} else if(option.inlineFunction) {
|
|
1902
|
-
result.source = xNode('function', {
|
|
1903
|
-
inline: true,
|
|
1904
|
-
arrow: true,
|
|
1905
|
-
args: ['$cd', '$parentElement'].concat(option.args || []),
|
|
1906
|
-
body: [innerBlock]
|
|
1907
|
-
});
|
|
1908
|
-
} else {
|
|
1909
|
-
result.name = '$$build' + (this.uniqIndex++);
|
|
1910
|
-
result.source = xNode('function', {
|
|
1911
|
-
name: result.name,
|
|
1912
|
-
args: ['$cd', '$parentElement'].concat(option.args || []),
|
|
1913
|
-
body: [innerBlock]
|
|
1914
|
-
});
|
|
1915
2062
|
}
|
|
1916
2063
|
} else {
|
|
2064
|
+
result.requireCD.$done = true;
|
|
1917
2065
|
result.name = '$runtime.noop';
|
|
1918
2066
|
result.source = null;
|
|
1919
2067
|
}
|
|
2068
|
+
|
|
2069
|
+
if(!option.inline) {
|
|
2070
|
+
let template = xNode('template', {
|
|
2071
|
+
body: rootTemplate,
|
|
2072
|
+
svg: rootSVG,
|
|
2073
|
+
requireFragment
|
|
2074
|
+
});
|
|
2075
|
+
if(option.template) Object.assign(template, option.template);
|
|
2076
|
+
else template.inline = true;
|
|
2077
|
+
|
|
2078
|
+
result.block = xNode('block', {
|
|
2079
|
+
$compile: [innerBlock, requireCD],
|
|
2080
|
+
$deps: [requireCD],
|
|
2081
|
+
requireCD,
|
|
2082
|
+
innerBlock,
|
|
2083
|
+
tpl: template,
|
|
2084
|
+
each: option.each,
|
|
2085
|
+
parentElement: option.parentElement
|
|
2086
|
+
}, (ctx, n) => {
|
|
2087
|
+
if(n.each && !ctx.isEmpty(n.innerBlock)) {
|
|
2088
|
+
if(n.requireCD.value) ctx.write(`$runtime.makeEachBlock(`);
|
|
2089
|
+
else ctx.write(`$runtime.makeStaticEachBlock(`);
|
|
2090
|
+
} else {
|
|
2091
|
+
if(n.requireCD.value) ctx.write(`$runtime.makeBlock(`);
|
|
2092
|
+
else ctx.write(`$runtime.makeStaticBlock(`);
|
|
2093
|
+
}
|
|
2094
|
+
ctx.add(n.tpl);
|
|
2095
|
+
if(!ctx.isEmpty(n.innerBlock)) {
|
|
2096
|
+
if(n.each) {
|
|
2097
|
+
if(n.requireCD.value) ctx.write(`, ($cd, ${n.parentElement}, ${n.each.itemName}, ${n.each.indexName}) => {`, true);
|
|
2098
|
+
else ctx.write(`, (${n.parentElement}, ${n.each.itemName}, ${n.each.indexName}) => {`, true);
|
|
2099
|
+
} else {
|
|
2100
|
+
let extra = option.extraArguments ? ', ' + option.extraArguments.join(', ') : '';
|
|
2101
|
+
if(n.requireCD.value) ctx.write(`, ($cd, ${n.parentElement}${extra}) => {`, true);
|
|
2102
|
+
else ctx.write(`, (${n.parentElement}${extra}) => {`, true);
|
|
2103
|
+
}
|
|
2104
|
+
ctx.indent++;
|
|
2105
|
+
ctx.add(n.innerBlock);
|
|
2106
|
+
if(n.each?.rebind) {
|
|
2107
|
+
ctx.write(true, `return `);
|
|
2108
|
+
ctx.add(n.each.rebind);
|
|
2109
|
+
ctx.write(`;`, true);
|
|
2110
|
+
} ctx.indent--;
|
|
2111
|
+
ctx.write(true, `}`);
|
|
2112
|
+
}
|
|
2113
|
+
ctx.write(`)`);
|
|
2114
|
+
});
|
|
2115
|
+
} else {
|
|
2116
|
+
result.template = xNode('template', {
|
|
2117
|
+
body: rootTemplate,
|
|
2118
|
+
svg: rootSVG,
|
|
2119
|
+
requireFragment
|
|
2120
|
+
});
|
|
2121
|
+
if(option.template) Object.assign(result.template, option.template);
|
|
2122
|
+
else result.template.inline = true;
|
|
2123
|
+
}
|
|
2124
|
+
|
|
1920
2125
|
result.inuse = {};
|
|
1921
2126
|
for(let k in this.inuse) {
|
|
1922
2127
|
result.inuse[k] = this.inuse[k] - (inuse[k] || 0);
|
|
@@ -3869,7 +4074,7 @@
|
|
|
3869
4074
|
}
|
|
3870
4075
|
} else cleanSelectorItems.push(s);
|
|
3871
4076
|
}
|
|
3872
|
-
while(cleanSelectorItems.length &&
|
|
4077
|
+
while(cleanSelectorItems.length && last(cleanSelectorItems).type == 'WhiteSpace') cleanSelectorItems.pop();
|
|
3873
4078
|
if(!cleanSelectorItems.length || globalBlock) { // fully global?
|
|
3874
4079
|
assert(origin.length);
|
|
3875
4080
|
fullSelector.children = origin;
|
|
@@ -3894,7 +4099,8 @@
|
|
|
3894
4099
|
cleanSelector,
|
|
3895
4100
|
isSimple,
|
|
3896
4101
|
source: [],
|
|
3897
|
-
fullyGlobal: origin.every(i => i.global)
|
|
4102
|
+
fullyGlobal: origin.every(i => i.global),
|
|
4103
|
+
hashedSelectors: []
|
|
3898
4104
|
};
|
|
3899
4105
|
}
|
|
3900
4106
|
|
|
@@ -3902,17 +4108,18 @@
|
|
|
3902
4108
|
assert(sobj.isSimple);
|
|
3903
4109
|
if(!sobj.external) sobj.external = emptyBlock ? true : genId$1();
|
|
3904
4110
|
} else if(!sobj.local) {
|
|
3905
|
-
|
|
3906
|
-
else sobj.local = self.id;
|
|
4111
|
+
sobj.local = true;
|
|
3907
4112
|
}
|
|
3908
4113
|
|
|
3909
|
-
let hash = external ? sobj.external : sobj.local;
|
|
3910
4114
|
if(emptyBlock) fullSelector.emptyBlock = true;
|
|
3911
4115
|
sobj.source.push(fullSelector);
|
|
3912
4116
|
|
|
3913
4117
|
let hashed = origin.slice();
|
|
4118
|
+
hashed._external = external;
|
|
4119
|
+
sobj.hashedSelectors.push(hashed);
|
|
4120
|
+
|
|
3914
4121
|
const insert = (i) => {
|
|
3915
|
-
hashed.splice(i, 0, {type: "ClassSelector", loc: null, name:
|
|
4122
|
+
hashed.splice(i, 0, {type: "ClassSelector", loc: null, name: null, __hash: true});
|
|
3916
4123
|
};
|
|
3917
4124
|
|
|
3918
4125
|
for(let i=hashed.length-1;i>=0;i--) {
|
|
@@ -3940,6 +4147,7 @@
|
|
|
3940
4147
|
self.markAsExternal = (name) => {
|
|
3941
4148
|
let sobj = selectors['.' + name];
|
|
3942
4149
|
if(!sobj) selectors['.' + name] = sobj = {isSimple: true, cleanSelector: '.' + name};
|
|
4150
|
+
assert(!sobj.resolved);
|
|
3943
4151
|
if(!sobj.external) sobj.external = true;
|
|
3944
4152
|
active = true;
|
|
3945
4153
|
};
|
|
@@ -3953,7 +4161,36 @@
|
|
|
3953
4161
|
});
|
|
3954
4162
|
};
|
|
3955
4163
|
|
|
4164
|
+
let _hashesResolved = false;
|
|
4165
|
+
const resolveHashes = () => {
|
|
4166
|
+
if(_hashesResolved) return;
|
|
4167
|
+
_hashesResolved = true;
|
|
4168
|
+
Object.values(selectors).forEach(sel => {
|
|
4169
|
+
if(!sel.hashedSelectors) return;
|
|
4170
|
+
if(sel.resolved) return;
|
|
4171
|
+
sel.resolved = true;
|
|
4172
|
+
if(sel.external) {
|
|
4173
|
+
if(sel.local === true) {
|
|
4174
|
+
if(self.passingClass) sel.local = genId$1();
|
|
4175
|
+
else sel.local = self.id;
|
|
4176
|
+
} } else {
|
|
4177
|
+
assert(sel.local === true);
|
|
4178
|
+
if(self.passingClass) sel.local = genId$1();
|
|
4179
|
+
else sel.local = self.id;
|
|
4180
|
+
}
|
|
4181
|
+
sel.hashedSelectors.forEach(hashed => {
|
|
4182
|
+
let hash = hashed._external ? sel.external : sel.local;
|
|
4183
|
+
assert(hash);
|
|
4184
|
+
hashed.forEach(n => {
|
|
4185
|
+
if(!n.__hash) return;
|
|
4186
|
+
n.name = hash;
|
|
4187
|
+
});
|
|
4188
|
+
});
|
|
4189
|
+
});
|
|
4190
|
+
};
|
|
4191
|
+
|
|
3956
4192
|
self.getClassMap = () => {
|
|
4193
|
+
resolveHashes();
|
|
3957
4194
|
let classMap = {};
|
|
3958
4195
|
let metaClass = {};
|
|
3959
4196
|
Object.values(selectors).forEach(sel => {
|
|
@@ -3978,6 +4215,7 @@
|
|
|
3978
4215
|
});
|
|
3979
4216
|
|
|
3980
4217
|
Object.values(selectors).forEach(sel => {
|
|
4218
|
+
sel.$selector = true;
|
|
3981
4219
|
if(sel.fullyGlobal || !sel.local) return;
|
|
3982
4220
|
let selected;
|
|
3983
4221
|
try {
|
|
@@ -3988,17 +4226,30 @@
|
|
|
3988
4226
|
throw e;
|
|
3989
4227
|
}
|
|
3990
4228
|
selected.forEach(s => {
|
|
3991
|
-
s.node.__node.classes.add(sel
|
|
3992
|
-
s.lvl.forEach(l => l.__node.classes.add(sel
|
|
4229
|
+
s.node.__node.classes.add(sel);
|
|
4230
|
+
s.lvl.forEach(l => l.__node.classes.add(sel));
|
|
3993
4231
|
});
|
|
3994
4232
|
});
|
|
3995
4233
|
};
|
|
3996
4234
|
|
|
4235
|
+
self.resolve = sel => {
|
|
4236
|
+
resolveHashes();
|
|
4237
|
+
assert(sel.resolved);
|
|
4238
|
+
if(sel.external) {
|
|
4239
|
+
assert(sel.external !== true);
|
|
4240
|
+
return sel.external;
|
|
4241
|
+
}
|
|
4242
|
+
assert(sel.local && sel.local !== true);
|
|
4243
|
+
return sel.local;
|
|
4244
|
+
};
|
|
4245
|
+
|
|
3997
4246
|
self.getContent = function() {
|
|
3998
4247
|
removeBlocks.forEach(node => {
|
|
3999
4248
|
let i = node.parent.children.indexOf(node);
|
|
4000
4249
|
if(i>=0) node.parent.children.splice(i, 1);
|
|
4001
4250
|
});
|
|
4251
|
+
resolveHashes();
|
|
4252
|
+
|
|
4002
4253
|
return astList.map(ast => csstree.generate(ast)).join('');
|
|
4003
4254
|
};
|
|
4004
4255
|
}
|
|
@@ -4024,10 +4275,8 @@
|
|
|
4024
4275
|
//if(e.name[0].match(/[A-Z]/)) return;
|
|
4025
4276
|
let n = new Node(e.name, {__node: e});
|
|
4026
4277
|
e.attributes.forEach(a => {
|
|
4027
|
-
if(a.name == 'class')
|
|
4028
|
-
|
|
4029
|
-
n.attributes[a.name] = a.value;
|
|
4030
|
-
} else if(a.name == 'id') n.attributes.id = n.id = a.value;
|
|
4278
|
+
if(a.name == 'class') n.className += ' ' + a.value;
|
|
4279
|
+
else if(a.name == 'id') n.id = a.value;
|
|
4031
4280
|
else if(a.name.startsWith('class:')) {
|
|
4032
4281
|
n.className += ' ' + a.name.substring(6);
|
|
4033
4282
|
} else n.attributes[a.name] = a.value;
|
|
@@ -4069,10 +4318,6 @@
|
|
|
4069
4318
|
return this.attributes[n];
|
|
4070
4319
|
};
|
|
4071
4320
|
|
|
4072
|
-
Node.prototype.hasAttribute = function(n) {
|
|
4073
|
-
return n in this.attributes;
|
|
4074
|
-
};
|
|
4075
|
-
|
|
4076
4321
|
Node.prototype.appendChild = function(n) {
|
|
4077
4322
|
n.parentElement = this;
|
|
4078
4323
|
this.childNodes.push(n);
|
|
@@ -4111,22 +4356,21 @@
|
|
|
4111
4356
|
return result;
|
|
4112
4357
|
};
|
|
4113
4358
|
|
|
4114
|
-
function makeComponent(node,
|
|
4359
|
+
function makeComponent(node, requireCD) {
|
|
4360
|
+
this.require('apply');
|
|
4361
|
+
|
|
4115
4362
|
let propList = node.attributes;
|
|
4116
|
-
let forwardAllEvents = false;
|
|
4117
4363
|
|
|
4118
|
-
this.require('$context'
|
|
4364
|
+
this.require('$context');
|
|
4365
|
+
requireCD.$value(true); // FIX
|
|
4119
4366
|
|
|
4120
|
-
let options = [];
|
|
4121
|
-
let dynamicComponent;
|
|
4122
4367
|
let reference = null;
|
|
4123
4368
|
let propsFn = [], propsSetter = [], $class=[], staticProps = true;
|
|
4369
|
+
let slotBlocks = [];
|
|
4370
|
+
let anchorBlocks = [];
|
|
4124
4371
|
|
|
4125
4372
|
let componentName = node.name;
|
|
4126
|
-
if(componentName
|
|
4127
|
-
assert(node.elArg);
|
|
4128
|
-
dynamicComponent = node.elArg[0] == '{' ? unwrapExp(node.elArg) : node.elArg;
|
|
4129
|
-
} else if(this.config.autoimport) {
|
|
4373
|
+
if(componentName != 'component' && this.config.autoimport) {
|
|
4130
4374
|
let imported = this.script.autoimport[componentName] || this.script.importedNames.includes(componentName)
|
|
4131
4375
|
|| this.script.rootVariables[componentName] || this.script.rootFunctions[componentName];
|
|
4132
4376
|
|
|
@@ -4136,30 +4380,12 @@
|
|
|
4136
4380
|
}
|
|
4137
4381
|
}
|
|
4138
4382
|
|
|
4139
|
-
|
|
4140
|
-
let
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
if(
|
|
4144
|
-
|
|
4145
|
-
ctx.writeLine('let events = {...$events};');
|
|
4146
|
-
} else if(passOption.events) {
|
|
4147
|
-
ctx.writeLine('let events = {};');
|
|
4148
|
-
}
|
|
4149
|
-
}));
|
|
4150
|
-
|
|
4151
|
-
head.push(xNode('slots', ctx => {
|
|
4152
|
-
if(passOption.slots) ctx.writeLine('let slots = {};');
|
|
4153
|
-
}));
|
|
4154
|
-
|
|
4155
|
-
head.push(xNode('anchor', ctx => {
|
|
4156
|
-
if(passOption.anchor) ctx.writeLine('let anchor = {};');
|
|
4157
|
-
}));
|
|
4158
|
-
|
|
4159
|
-
let _boundEvents = {};
|
|
4160
|
-
const boundEvent = (name) => {
|
|
4161
|
-
if(!_boundEvents[name]) _boundEvents[name] = forwardAllEvents ? 1 : 0;
|
|
4162
|
-
_boundEvents[name]++;
|
|
4383
|
+
// events
|
|
4384
|
+
let forwardAllEvents = false;
|
|
4385
|
+
let events = {};
|
|
4386
|
+
const passEvent = (name, bind) => {
|
|
4387
|
+
if(!events[name]) events[name] = [];
|
|
4388
|
+
events[name].push(bind);
|
|
4163
4389
|
};
|
|
4164
4390
|
|
|
4165
4391
|
if(node.body && node.body.length) {
|
|
@@ -4187,12 +4413,11 @@
|
|
|
4187
4413
|
Object.values(slots).forEach(slot => {
|
|
4188
4414
|
if(!slot.body.length) return;
|
|
4189
4415
|
assert(isSimpleName(slot.name));
|
|
4190
|
-
passOption.slots = true;
|
|
4191
4416
|
|
|
4192
4417
|
let props;
|
|
4193
|
-
let rx = slot.value && slot.value.match(/^#slot\S*\s+(.*)$/
|
|
4418
|
+
let rx = slot.value && slot.value.match(/^#slot\S*\s+(.*)$/);
|
|
4194
4419
|
if(rx) {
|
|
4195
|
-
props = rx[1].trim().split(
|
|
4420
|
+
props = rx[1].trim().split(/[\s,]+/);
|
|
4196
4421
|
assert(props.length);
|
|
4197
4422
|
props.forEach(n => {
|
|
4198
4423
|
assert(isSimpleName(n), 'Wrong prop for slot');
|
|
@@ -4203,7 +4428,7 @@
|
|
|
4203
4428
|
if(contentNodes.length == 1 && contentNodes[0].type == 'node' && contentNodes[0].name == 'slot') {
|
|
4204
4429
|
let parentSlot = contentNodes[0];
|
|
4205
4430
|
if(!parentSlot.body || !parentSlot.body.length) {
|
|
4206
|
-
|
|
4431
|
+
slotBlocks.push(xNode('empty-slot', {
|
|
4207
4432
|
childName: slot.name,
|
|
4208
4433
|
parentName: parentSlot.elArg || 'default'
|
|
4209
4434
|
}, (ctx, n) => {
|
|
@@ -4214,94 +4439,68 @@
|
|
|
4214
4439
|
}
|
|
4215
4440
|
|
|
4216
4441
|
if(props) this.require('apply');
|
|
4217
|
-
|
|
4442
|
+
requireCD.$value(true); // FIXME
|
|
4218
4443
|
|
|
4219
4444
|
let block = this.buildBlock(slot, {inline: true});
|
|
4220
4445
|
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
svg: block.svg,
|
|
4224
|
-
inline: true
|
|
4225
|
-
});
|
|
4226
|
-
|
|
4227
|
-
head.push(xNode('slot', {
|
|
4446
|
+
slotBlocks.push(xNode('slot', {
|
|
4447
|
+
$deps: [this.glob.apply],
|
|
4228
4448
|
name: slot.name,
|
|
4229
|
-
template,
|
|
4449
|
+
template: block.template,
|
|
4230
4450
|
bind: block.source,
|
|
4231
4451
|
componentName,
|
|
4232
4452
|
props
|
|
4233
4453
|
}, (ctx, n) => {
|
|
4234
4454
|
if(n.bind) {
|
|
4235
|
-
ctx.write(true,
|
|
4236
|
-
|
|
4237
|
-
ctx.write(
|
|
4238
|
-
ctx.
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
}
|
|
4248
|
-
ctx.build(n.bind);
|
|
4249
|
-
if(push) ctx.writeLine(`return {push, el: $parentElement};`);
|
|
4250
|
-
else ctx.writeLine(`return $parentElement;`);
|
|
4251
|
-
} else {
|
|
4252
|
-
ctx.write(true, `return `);
|
|
4253
|
-
ctx.build(n.template);
|
|
4254
|
-
ctx.write(`;\n`);
|
|
4255
|
-
}
|
|
4256
|
-
});
|
|
4257
|
-
ctx.writeLine(`});`);
|
|
4455
|
+
ctx.write(true, `${n.name}: $runtime.makeSlot($cd, `);
|
|
4456
|
+
ctx.add(n.template);
|
|
4457
|
+
ctx.write(`, ($cd, $parentElement, $context, $instance_${n.componentName}`);
|
|
4458
|
+
if(n.props) ctx.write(`, $localProps`);
|
|
4459
|
+
ctx.write(`) => {`, true);
|
|
4460
|
+
ctx.indent++;
|
|
4461
|
+
if(n.props) ctx.write(true, `let {${n.props.join(', ')}} = $localProps;`);
|
|
4462
|
+
ctx.add(n.bind);
|
|
4463
|
+
|
|
4464
|
+
if(n.props && this.glob.apply.value) ctx.write(true, `return ($localProps) => ({${n.props.join(', ')}} = $localProps, $$apply());`);
|
|
4465
|
+
ctx.indent--;
|
|
4466
|
+
ctx.writeLine(`})`);
|
|
4258
4467
|
} else {
|
|
4259
|
-
ctx.write(true,
|
|
4260
|
-
ctx.
|
|
4261
|
-
ctx.write(
|
|
4468
|
+
ctx.write(true, `${n.name}: $runtime.makeStaticBlock(`);
|
|
4469
|
+
ctx.add(n.template);
|
|
4470
|
+
ctx.write(')');
|
|
4262
4471
|
}
|
|
4263
4472
|
}));
|
|
4264
4473
|
});
|
|
4265
4474
|
|
|
4266
4475
|
anchors.forEach(n => {
|
|
4267
|
-
|
|
4268
|
-
let block =
|
|
4476
|
+
let bb = this.buildBlock({body: [n]}, {inline: true, oneElement: 'el', bindAttributes: true});
|
|
4477
|
+
let block = bb.source;
|
|
4269
4478
|
let name = n.name.slice(1) || 'default';
|
|
4270
4479
|
assert(isSimpleName(name));
|
|
4271
|
-
|
|
4480
|
+
|
|
4481
|
+
anchorBlocks.push(xNode('anchor', {
|
|
4482
|
+
$compile: [block],
|
|
4483
|
+
$deps: [bb.requireCD],
|
|
4272
4484
|
name,
|
|
4273
|
-
|
|
4274
|
-
$cd: block.inuse.$cd
|
|
4485
|
+
block
|
|
4275
4486
|
}, (ctx, n) => {
|
|
4276
|
-
|
|
4277
|
-
ctx.
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
});
|
|
4285
|
-
ctx.writeLine(`}`);
|
|
4286
|
-
ctx.writeLine(`return () => {$childCD.destroy();}`);
|
|
4287
|
-
} else {
|
|
4288
|
-
ctx.build(n.source);
|
|
4289
|
-
}
|
|
4290
|
-
});
|
|
4291
|
-
ctx.writeLine(`}`);
|
|
4487
|
+
let useCD = n.$deps[0].value;
|
|
4488
|
+
if(useCD) ctx.write(`${n.name}: {$: ($cd, el) => {`);
|
|
4489
|
+
else ctx.write(`${n.name}: (el) => {`);
|
|
4490
|
+
ctx.indent++;
|
|
4491
|
+
ctx.build(n.block);
|
|
4492
|
+
ctx.indent--;
|
|
4493
|
+
if(useCD) ctx.write(true, `}}`);
|
|
4494
|
+
else ctx.write(true, `}`);
|
|
4292
4495
|
}));
|
|
4293
4496
|
});
|
|
4294
4497
|
}
|
|
4295
4498
|
|
|
4296
|
-
propList = propList.filter(
|
|
4297
|
-
let name = prop.name;
|
|
4298
|
-
let value = prop.value;
|
|
4499
|
+
propList = propList.filter(({name}) => {
|
|
4299
4500
|
if(name == '@@') {
|
|
4300
4501
|
forwardAllEvents = true;
|
|
4301
|
-
this.require('$events');
|
|
4302
4502
|
return false;
|
|
4303
4503
|
} else if(name == 'this') {
|
|
4304
|
-
dynamicComponent = unwrapExp(value);
|
|
4305
4504
|
return false;
|
|
4306
4505
|
}
|
|
4307
4506
|
return true;
|
|
@@ -4351,35 +4550,21 @@
|
|
|
4351
4550
|
if(name.startsWith('@@')) {
|
|
4352
4551
|
let event = name.substring(2);
|
|
4353
4552
|
assert(!value);
|
|
4354
|
-
passOption.events = true;
|
|
4355
|
-
boundEvent(event);
|
|
4356
4553
|
this.require('$events');
|
|
4357
|
-
|
|
4554
|
+
passEvent(event, xNode('forwardEvent', {
|
|
4358
4555
|
event
|
|
4359
|
-
}, (ctx,
|
|
4360
|
-
|
|
4361
|
-
else ctx.writeLine(`events.${data.event} = $events.${data.event};`);
|
|
4556
|
+
}, (ctx, n) => {
|
|
4557
|
+
ctx.write(`$events.${n.event}`);
|
|
4362
4558
|
}));
|
|
4363
4559
|
return;
|
|
4364
4560
|
}
|
|
4365
4561
|
|
|
4366
4562
|
let {event, fn} = this.makeEventProp(prop);
|
|
4367
4563
|
|
|
4368
|
-
|
|
4369
|
-
boundEvent(event);
|
|
4370
|
-
head.push(xNode('passEvent', {
|
|
4371
|
-
event,
|
|
4564
|
+
passEvent(event, xNode('passEvent', {
|
|
4372
4565
|
fn
|
|
4373
4566
|
}, (ctx, n) => {
|
|
4374
|
-
|
|
4375
|
-
ctx.write(true, `$runtime.$$addEventForComponent(events, '${n.event}', `);
|
|
4376
|
-
ctx.build(n.fn);
|
|
4377
|
-
ctx.write(`);\n`);
|
|
4378
|
-
} else {
|
|
4379
|
-
ctx.write(true, `events.${n.event} = `);
|
|
4380
|
-
ctx.build(n.fn);
|
|
4381
|
-
ctx.write(`;\n`);
|
|
4382
|
-
}
|
|
4567
|
+
ctx.add(n.fn);
|
|
4383
4568
|
}));
|
|
4384
4569
|
return;
|
|
4385
4570
|
} else if(this.config.passClass && (name == 'class' || name.startsWith('class:'))) {
|
|
@@ -4392,6 +4577,7 @@
|
|
|
4392
4577
|
assert(metaClass);
|
|
4393
4578
|
}
|
|
4394
4579
|
assert(value);
|
|
4580
|
+
this.css.passingClass = true;
|
|
4395
4581
|
|
|
4396
4582
|
const parsed = this.parseText(prop.value);
|
|
4397
4583
|
this.detectDependency(parsed);
|
|
@@ -4409,41 +4595,87 @@
|
|
|
4409
4595
|
});
|
|
4410
4596
|
|
|
4411
4597
|
|
|
4412
|
-
if(
|
|
4413
|
-
if(passOption.slots) options.push('slots');
|
|
4414
|
-
if(passOption.anchor) options.push('anchor');
|
|
4598
|
+
if(Object.keys(events).length == 0) events = null;
|
|
4415
4599
|
|
|
4416
4600
|
let result = xNode('component', {
|
|
4417
|
-
el: element.bindName(),
|
|
4418
4601
|
componentName,
|
|
4419
|
-
head,
|
|
4420
|
-
options,
|
|
4421
|
-
$cd: '$cd',
|
|
4422
4602
|
staticProps,
|
|
4423
4603
|
props: propsFn,
|
|
4424
4604
|
propsSetter,
|
|
4425
4605
|
reference,
|
|
4426
|
-
$class
|
|
4606
|
+
$class,
|
|
4607
|
+
forwardAllEvents,
|
|
4608
|
+
events,
|
|
4609
|
+
slots: slotBlocks.length ? slotBlocks : null,
|
|
4610
|
+
anchors: anchorBlocks.length ? anchorBlocks : null
|
|
4427
4611
|
}, (ctx, n) => {
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
if(head) {
|
|
4432
|
-
ctx.addBlock(head);
|
|
4433
|
-
n.requireScope = true;
|
|
4434
|
-
}
|
|
4612
|
+
if(n.reference) throw 'not implemented'; // FIXME
|
|
4613
|
+
let comma = false;
|
|
4614
|
+
ctx.write(`$runtime.callComponent($context, ${n.componentName}, {`);
|
|
4435
4615
|
|
|
4436
4616
|
if(n.props.length && n.staticProps) {
|
|
4437
|
-
|
|
4617
|
+
ctx.write(`props: {${n.props.join(', ')}}`);
|
|
4618
|
+
comma = true;
|
|
4438
4619
|
n.props = [];
|
|
4439
4620
|
}
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4621
|
+
ctx.indent++;
|
|
4622
|
+
if(n.forwardAllEvents && !n.events) {
|
|
4623
|
+
if(comma) ctx.write(', ');
|
|
4624
|
+
comma = true;
|
|
4625
|
+
ctx.write('events: $events');
|
|
4626
|
+
} else if(n.events && !n.forwardAllEvents) {
|
|
4627
|
+
if(comma) ctx.write(',', true);
|
|
4628
|
+
comma = true;
|
|
4629
|
+
ctx.write('events: {');
|
|
4630
|
+
ctx.indent++;
|
|
4631
|
+
ctx.write(true);
|
|
4632
|
+
Object.entries(n.events).forEach(([event, list], index) => {
|
|
4633
|
+
if(index) ctx.write(',', true);
|
|
4634
|
+
ctx.write(event + ': ');
|
|
4635
|
+
if(list.length == 1) ctx.add(list[0]);
|
|
4636
|
+
else {
|
|
4637
|
+
ctx.write('$runtime.mergeEvents(');
|
|
4638
|
+
list.forEach((b, i) => {
|
|
4639
|
+
if(i) ctx.write(', ');
|
|
4640
|
+
ctx.add(b);
|
|
4641
|
+
});
|
|
4642
|
+
ctx.write(')');
|
|
4643
|
+
}
|
|
4644
|
+
});
|
|
4645
|
+
ctx.indent--;
|
|
4646
|
+
ctx.write(true, '}');
|
|
4647
|
+
} else if(n.events && n.forwardAllEvents) {
|
|
4648
|
+
throw 'not implemented'; // FIXME
|
|
4649
|
+
}
|
|
4650
|
+
if(n.slots) {
|
|
4651
|
+
if(comma) ctx.write(', ');
|
|
4652
|
+
comma = true;
|
|
4653
|
+
ctx.write('slots: {');
|
|
4654
|
+
ctx.indent++;
|
|
4655
|
+
n.slots.forEach((slot, i) => {
|
|
4656
|
+
if(i) ctx.write(',');
|
|
4657
|
+
ctx.write(true);
|
|
4658
|
+
ctx.add(slot);
|
|
4659
|
+
});
|
|
4660
|
+
ctx.indent--;
|
|
4661
|
+
ctx.write(true, '}');
|
|
4662
|
+
}
|
|
4663
|
+
if(n.anchors) {
|
|
4664
|
+
if(comma) ctx.write(', ');
|
|
4665
|
+
comma = true;
|
|
4666
|
+
ctx.write('anchor: {');
|
|
4667
|
+
ctx.indent++;
|
|
4668
|
+
n.anchors.forEach((anchor, i) => {
|
|
4669
|
+
if(i) ctx.write(',');
|
|
4670
|
+
ctx.write(true);
|
|
4671
|
+
ctx.add(anchor);
|
|
4672
|
+
});
|
|
4673
|
+
ctx.indent--;
|
|
4674
|
+
ctx.write(true, '}');
|
|
4675
|
+
}
|
|
4676
|
+
ctx.write('}');
|
|
4444
4677
|
|
|
4445
4678
|
let other = '';
|
|
4446
|
-
ctx.indent++;
|
|
4447
4679
|
if(n.props.length) ctx.write(`,\n`, true, `() => ({${n.props.join(', ')}})`);
|
|
4448
4680
|
else other = ', null';
|
|
4449
4681
|
|
|
@@ -4469,77 +4701,61 @@
|
|
|
4469
4701
|
} else other += ', null';
|
|
4470
4702
|
|
|
4471
4703
|
ctx.indent--;
|
|
4472
|
-
ctx.write(`)
|
|
4704
|
+
ctx.write(true, `)`);
|
|
4473
4705
|
});
|
|
4474
4706
|
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
let r = ctx.subBuild(n.component);
|
|
4480
|
-
|
|
4481
|
-
if(n.component.requireScope) {
|
|
4482
|
-
ctx.writeLine('{');
|
|
4483
|
-
ctx.goIndent(() => {
|
|
4484
|
-
ctx.addBlock(r);
|
|
4485
|
-
});
|
|
4486
|
-
ctx.writeLine('}');
|
|
4487
|
-
} else ctx.addBlock(r);
|
|
4488
|
-
})};
|
|
4489
|
-
} else {
|
|
4490
|
-
this.detectDependency(dynamicComponent);
|
|
4707
|
+
return {bind: result};
|
|
4708
|
+
}
|
|
4709
|
+
function makeComponentDyn(node, requireCD, element) {
|
|
4710
|
+
let dynamicComponent;
|
|
4491
4711
|
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
if(ctx.inuse.apply) {
|
|
4502
|
-
ctx.writeLine(`let childCD, finalLabel = $runtime.getFinalLabel(${n.el});`);
|
|
4503
|
-
ctx.writeLine(`$watch($cd, () => (${n.exp}), ($ComponentConstructor) => {`);
|
|
4504
|
-
ctx.goIndent(() => {
|
|
4505
|
-
ctx.writeLine(`if(childCD) {`);
|
|
4506
|
-
ctx.goIndent(() => {
|
|
4507
|
-
ctx.writeLine(`childCD.destroy();`);
|
|
4508
|
-
ctx.writeLine(`$runtime.removeElementsBetween(${n.el}, finalLabel);`);
|
|
4509
|
-
});
|
|
4510
|
-
ctx.writeLine(`}`);
|
|
4511
|
-
ctx.writeLine(`childCD = null;`);
|
|
4512
|
-
ctx.writeLine(`if($ComponentConstructor) {`);
|
|
4513
|
-
ctx.goIndent(() => {
|
|
4514
|
-
ctx.writeLine(`childCD = $cd.new();`);
|
|
4515
|
-
ctx.build(n.component);
|
|
4516
|
-
});
|
|
4517
|
-
ctx.writeLine(`}`);
|
|
4518
|
-
});
|
|
4519
|
-
ctx.writeLine(`});`);
|
|
4520
|
-
} else {
|
|
4521
|
-
ctx.writeLine(`let $ComponentConstructor = ${n.exp};`);
|
|
4522
|
-
ctx.writeLine(`if($ComponentConstructor) {`);
|
|
4523
|
-
ctx.goIndent(() => {
|
|
4524
|
-
ctx.writeLine(`let childCD = $cd;`);
|
|
4525
|
-
ctx.build(n.component);
|
|
4526
|
-
});
|
|
4527
|
-
ctx.writeLine(`}`);
|
|
4528
|
-
}
|
|
4529
|
-
});
|
|
4530
|
-
ctx.writeLine('}');
|
|
4531
|
-
})};
|
|
4712
|
+
if(node.elArg) {
|
|
4713
|
+
dynamicComponent = node.elArg[0] == '{' ? unwrapExp(node.elArg) : node.elArg;
|
|
4714
|
+
} else {
|
|
4715
|
+
node.props.some(({name, value}) => {
|
|
4716
|
+
if(name == 'this') {
|
|
4717
|
+
dynamicComponent = unwrapExp(value);
|
|
4718
|
+
return true;
|
|
4719
|
+
}
|
|
4720
|
+
});
|
|
4532
4721
|
}
|
|
4722
|
+
|
|
4723
|
+
assert(dynamicComponent);
|
|
4724
|
+
this.detectDependency(dynamicComponent);
|
|
4725
|
+
requireCD.$value(true);
|
|
4726
|
+
|
|
4727
|
+
let component = this.makeComponent(node, requireCD).bind;
|
|
4728
|
+
|
|
4729
|
+
component.componentName = '$ComponentConstructor';
|
|
4730
|
+
return xNode('dyn-component', {
|
|
4731
|
+
el: element.bindName(),
|
|
4732
|
+
exp: dynamicComponent,
|
|
4733
|
+
component
|
|
4734
|
+
}, (ctx, n) => {
|
|
4735
|
+
ctx.write(true, `$runtime.attachDynComponent($cd, ${n.el}, () => ${n.exp}, ($ComponentConstructor) => `);
|
|
4736
|
+
ctx.add(n.component);
|
|
4737
|
+
ctx.write(')');
|
|
4738
|
+
});
|
|
4533
4739
|
}
|
|
4534
4740
|
|
|
4535
|
-
function bindProp(prop, node, element) {
|
|
4741
|
+
function bindProp(prop, node, element, requireCD) {
|
|
4536
4742
|
let name, arg;
|
|
4743
|
+
|
|
4744
|
+
if(prop.content.startsWith('{*')) {
|
|
4745
|
+
const pe = this.parseText(prop.content);
|
|
4746
|
+
assert(pe.parts[0].type == 'js');
|
|
4747
|
+
let exp = pe.parts[0].value;
|
|
4748
|
+
if(!exp.endsWith(';')) exp += ';';
|
|
4749
|
+
return {bind: xNode('block', {body: [
|
|
4750
|
+
replaceElementKeyword(exp, () => element.bindName())
|
|
4751
|
+
]})};
|
|
4752
|
+
}
|
|
4753
|
+
|
|
4537
4754
|
if(prop.name[0] == '@' || prop.name.startsWith('on:')) name = 'event';
|
|
4538
|
-
if(
|
|
4755
|
+
else if(prop.name[0] == ':') {
|
|
4539
4756
|
name = 'bind';
|
|
4540
4757
|
arg = prop.name.substring(1);
|
|
4541
|
-
}
|
|
4542
|
-
if(!name && prop.name[0] == '*') {
|
|
4758
|
+
} else if(prop.name[0] == '*') {
|
|
4543
4759
|
let rx = prop.name.match(/^\*\{.*\}$/);
|
|
4544
4760
|
if(rx) {
|
|
4545
4761
|
assert(prop.value == null, 'wrong binding: ' + prop.content);
|
|
@@ -4549,17 +4765,7 @@
|
|
|
4549
4765
|
name = 'use';
|
|
4550
4766
|
arg = prop.name.substring(1);
|
|
4551
4767
|
}
|
|
4552
|
-
}
|
|
4553
|
-
if(prop.content.startsWith('{*')) {
|
|
4554
|
-
const pe = this.parseText(prop.content);
|
|
4555
|
-
assert(pe.parts[0].type == 'js');
|
|
4556
|
-
let exp = pe.parts[0].value;
|
|
4557
|
-
if(!exp.endsWith(';')) exp += ';';
|
|
4558
|
-
return {bind: xNode('block', {body: [
|
|
4559
|
-
replaceElementKeyword(exp, () => element.bindName())
|
|
4560
|
-
]})};
|
|
4561
|
-
}
|
|
4562
|
-
if(!name && prop.value == null) {
|
|
4768
|
+
} else if(prop.value == null) {
|
|
4563
4769
|
let rx = prop.name.match(/^\{(.*)\}$/);
|
|
4564
4770
|
if(rx) {
|
|
4565
4771
|
name = rx[1];
|
|
@@ -4567,7 +4773,6 @@
|
|
|
4567
4773
|
// spread operator
|
|
4568
4774
|
name = name.substring(3);
|
|
4569
4775
|
assert(detectExpressionType(name) == 'identifier');
|
|
4570
|
-
this.detectDependency(name);
|
|
4571
4776
|
return node.spreading.push(`...${name}`);
|
|
4572
4777
|
} else {
|
|
4573
4778
|
prop.value = prop.name;
|
|
@@ -4598,7 +4803,8 @@
|
|
|
4598
4803
|
} else if(name == 'event') {
|
|
4599
4804
|
if(prop.name.startsWith('@@')) {
|
|
4600
4805
|
assert(!prop.value);
|
|
4601
|
-
|
|
4806
|
+
requireCD.$value(true);
|
|
4807
|
+
this.require('$events');
|
|
4602
4808
|
if(prop.name == '@@') {
|
|
4603
4809
|
return {bind: xNode('forwardAllEvents', {
|
|
4604
4810
|
el: element.bindName()
|
|
@@ -4618,18 +4824,20 @@
|
|
|
4618
4824
|
})};
|
|
4619
4825
|
}
|
|
4620
4826
|
|
|
4621
|
-
let {event, fn} = this.makeEventProp(prop, () => element.bindName());
|
|
4622
|
-
|
|
4623
|
-
|
|
4827
|
+
let {event, fn, rootModifier} = this.makeEventProp(prop, () => element.bindName());
|
|
4828
|
+
if(rootModifier) this.require('rootEvent');
|
|
4829
|
+
else requireCD.$value(true);
|
|
4624
4830
|
|
|
4625
4831
|
return {bind: xNode('bindEvent', {
|
|
4626
4832
|
event,
|
|
4627
4833
|
fn,
|
|
4628
|
-
el: element.bindName()
|
|
4834
|
+
el: element.bindName(),
|
|
4835
|
+
rootModifier
|
|
4629
4836
|
}, (ctx, n) => {
|
|
4630
|
-
ctx.write(true,
|
|
4837
|
+
if(n.rootModifier) ctx.write(true, `$$addRootEvent(${n.el}, '${n.event}', `);
|
|
4838
|
+
else ctx.write(true, `$runtime.addEvent($cd, ${n.el}, '${n.event}', `);
|
|
4631
4839
|
ctx.build(n.fn);
|
|
4632
|
-
ctx.write(`)
|
|
4840
|
+
ctx.write(`);`);
|
|
4633
4841
|
})};
|
|
4634
4842
|
} else if(name == 'bind') {
|
|
4635
4843
|
if(this.script.readOnly) {
|
|
@@ -4637,7 +4845,8 @@
|
|
|
4637
4845
|
return;
|
|
4638
4846
|
}
|
|
4639
4847
|
|
|
4640
|
-
|
|
4848
|
+
requireCD.$value(true);
|
|
4849
|
+
this.require('apply');
|
|
4641
4850
|
let exp;
|
|
4642
4851
|
arg = arg.split(/[\:\|]/);
|
|
4643
4852
|
let attr = arg.shift();
|
|
@@ -4716,7 +4925,7 @@
|
|
|
4716
4925
|
})};
|
|
4717
4926
|
} else if(name == 'use') {
|
|
4718
4927
|
if(arg) {
|
|
4719
|
-
|
|
4928
|
+
requireCD.$value(true);
|
|
4720
4929
|
assert(isSimpleName(arg), 'Wrong name: ' + arg);
|
|
4721
4930
|
this.checkRootName(arg);
|
|
4722
4931
|
let args = prop.value ? `, () => [${getExpression()}]` : '';
|
|
@@ -4780,8 +4989,7 @@
|
|
|
4780
4989
|
});
|
|
4781
4990
|
|
|
4782
4991
|
if(compound) {
|
|
4783
|
-
let
|
|
4784
|
-
if(node.classes.has(this.css.id)) defaultHash = this.css.id;
|
|
4992
|
+
let classes = Array.from(node.classes);
|
|
4785
4993
|
node.classes.clear();
|
|
4786
4994
|
if(this.config.passClass) this.require('resolveClass');
|
|
4787
4995
|
let exp = props.map(prop => {
|
|
@@ -4798,24 +5006,40 @@
|
|
|
4798
5006
|
const bind = xNode('compound-class', {
|
|
4799
5007
|
el: element.bindName(),
|
|
4800
5008
|
exp,
|
|
4801
|
-
|
|
5009
|
+
classes,
|
|
5010
|
+
requireCD
|
|
4802
5011
|
}, (ctx, n) => {
|
|
5012
|
+
let base = '';
|
|
5013
|
+
if(n.classes.length) {
|
|
5014
|
+
if(this.css.passingClass) {
|
|
5015
|
+
base = [];
|
|
5016
|
+
n.classes.forEach(c => {
|
|
5017
|
+
if(c.local) base.push(this.css.resolve(c));
|
|
5018
|
+
});
|
|
5019
|
+
base = base.join(' ');
|
|
5020
|
+
if(base) base = `, '${base}'`;
|
|
5021
|
+
} else {
|
|
5022
|
+
if(n.classes.some(c => c.local)) base = `,'${this.css.id}'`;
|
|
5023
|
+
}
|
|
5024
|
+
}
|
|
5025
|
+
|
|
4803
5026
|
if(ctx.inuse.resolveClass) {
|
|
4804
|
-
let base = n.defaultHash ? `,'${n.defaultHash}'` : '';
|
|
4805
5027
|
if(ctx.inuse.apply) {
|
|
4806
|
-
|
|
5028
|
+
n.requireCD.$value(true);
|
|
5029
|
+
ctx.write(true, `$runtime.bindClassExp($cd, ${n.el}, () => $$resolveClass((${n.exp})${base}))`);
|
|
4807
5030
|
} else {
|
|
4808
|
-
ctx.
|
|
5031
|
+
ctx.write(true, `$runtime.setClassToElement(${n.el}, $$resolveClass((${n.exp})${base}));`);
|
|
4809
5032
|
}
|
|
4810
5033
|
} else {
|
|
4811
|
-
let base = n.defaultHash ? ` + ' ${n.defaultHash}'` : '';
|
|
4812
5034
|
if(ctx.inuse.apply) {
|
|
4813
|
-
|
|
5035
|
+
n.requireCD.$value(true);
|
|
5036
|
+
ctx.write(true, `$runtime.bindClassExp($cd, ${n.el}, () => (${n.exp})${base})`);
|
|
4814
5037
|
} else {
|
|
4815
|
-
ctx.
|
|
5038
|
+
ctx.write(true, `$runtime.setClassToElement(${n.el}, ${n.exp}${base});`);
|
|
4816
5039
|
}
|
|
4817
5040
|
}
|
|
4818
5041
|
});
|
|
5042
|
+
requireCD.$depends(bind);
|
|
4819
5043
|
return {bind};
|
|
4820
5044
|
} else {
|
|
4821
5045
|
let bind = xNode('block');
|
|
@@ -4829,18 +5053,22 @@
|
|
|
4829
5053
|
assert(className);
|
|
4830
5054
|
let exp = prop.value ? unwrapExp(prop.value) : className;
|
|
4831
5055
|
this.detectDependency(exp);
|
|
4832
|
-
|
|
5056
|
+
|
|
5057
|
+
let n = xNode('bindClass', {
|
|
5058
|
+
$deps: [this.glob.apply],
|
|
4833
5059
|
el: element.bindName(),
|
|
4834
5060
|
className,
|
|
4835
5061
|
exp,
|
|
4836
|
-
$element: exp.includes('$element')
|
|
5062
|
+
$element: exp.includes('$element'),
|
|
5063
|
+
requireCD
|
|
4837
5064
|
}, (ctx, n) => {
|
|
4838
5065
|
if(n.$element) {
|
|
4839
5066
|
ctx.writeLine(`{`);
|
|
4840
5067
|
ctx.indent++;
|
|
4841
5068
|
ctx.writeLine(`let $element = ${n.el};`);
|
|
4842
5069
|
}
|
|
4843
|
-
if(
|
|
5070
|
+
if(this.glob.apply.value) {
|
|
5071
|
+
n.requireCD.$value(true);
|
|
4844
5072
|
ctx.writeLine(`$runtime.bindClass($cd, ${n.el}, () => !!(${n.exp}), '${n.className}');`);
|
|
4845
5073
|
} else {
|
|
4846
5074
|
ctx.writeLine(`(${n.exp}) && $runtime.addClass(${n.el}, '${n.className}');`);
|
|
@@ -4849,18 +5077,22 @@
|
|
|
4849
5077
|
ctx.indent--;
|
|
4850
5078
|
ctx.writeLine(`}`);
|
|
4851
5079
|
}
|
|
4852
|
-
})
|
|
5080
|
+
});
|
|
5081
|
+
requireCD.$depends(n);
|
|
5082
|
+
bind.push(n);
|
|
4853
5083
|
}
|
|
4854
5084
|
});
|
|
4855
5085
|
return {bind: bind.body.length ? bind : null};
|
|
4856
5086
|
}
|
|
4857
5087
|
} else if(name[0] == '^') {
|
|
4858
|
-
|
|
5088
|
+
requireCD.$value(true);
|
|
4859
5089
|
return {bindTail: xNode('bindAnchor', {
|
|
4860
5090
|
name: name.slice(1) || 'default',
|
|
4861
5091
|
el: element.bindName()
|
|
4862
5092
|
}, (ctx, n) => {
|
|
4863
|
-
ctx.
|
|
5093
|
+
ctx.write(true, `$runtime.attachAnchor($option, $cd, ${n.el}`);
|
|
5094
|
+
if(n.name == 'default') ctx.write(`);`);
|
|
5095
|
+
else ctx.write(`, '${n.name}');`);
|
|
4864
5096
|
})};
|
|
4865
5097
|
} else {
|
|
4866
5098
|
if(prop.value && prop.value.indexOf('{') >= 0) {
|
|
@@ -4879,36 +5111,41 @@
|
|
|
4879
5111
|
selected: true,
|
|
4880
5112
|
innerHTML: true,
|
|
4881
5113
|
innerText: true,
|
|
5114
|
+
placeholder: true,
|
|
4882
5115
|
src: true,
|
|
4883
5116
|
readonly: 'readOnly'
|
|
4884
5117
|
};
|
|
4885
5118
|
|
|
5119
|
+
let n = xNode('bindAttribute', {
|
|
5120
|
+
name,
|
|
5121
|
+
exp,
|
|
5122
|
+
hasElement,
|
|
5123
|
+
el: element.bindName(),
|
|
5124
|
+
requireCD
|
|
5125
|
+
}, (ctx, data) => {
|
|
5126
|
+
if(data.hasElement) ctx.writeLine(`let $element=${data.el};`);
|
|
5127
|
+
if(propList[name]) {
|
|
5128
|
+
let propName = propList[name] === true ? name : propList[name];
|
|
5129
|
+
if(ctx.inuse.apply) {
|
|
5130
|
+
requireCD.$value(true);
|
|
5131
|
+
ctx.writeLine(`$watchReadOnly($cd, () => (${data.exp}), (value) => {${data.el}.${propName} = value;});`);
|
|
5132
|
+
} else {
|
|
5133
|
+
ctx.writeLine(`${data.el}.${propName} = ${data.exp};`);
|
|
5134
|
+
}
|
|
5135
|
+
} else {
|
|
5136
|
+
if(ctx.inuse.apply) {
|
|
5137
|
+
requireCD.$value(true);
|
|
5138
|
+
ctx.writeLine(`$runtime.bindAttribute($cd, ${data.el}, '${data.name}', () => (${data.exp}));`);
|
|
5139
|
+
} else {
|
|
5140
|
+
ctx.writeLine(`$runtime.bindAttributeBase(${data.el}, '${data.name}', ${data.exp});`);
|
|
5141
|
+
}
|
|
5142
|
+
}
|
|
5143
|
+
});
|
|
5144
|
+
requireCD.$depends(n);
|
|
5145
|
+
|
|
4886
5146
|
return {bind: xNode('block', {
|
|
4887
5147
|
scope: hasElement,
|
|
4888
|
-
body: [
|
|
4889
|
-
xNode('bindAttribute', {
|
|
4890
|
-
name,
|
|
4891
|
-
exp,
|
|
4892
|
-
hasElement,
|
|
4893
|
-
el: element.bindName()
|
|
4894
|
-
}, (ctx, data) => {
|
|
4895
|
-
if(data.hasElement) ctx.writeLine(`let $element=${data.el};`);
|
|
4896
|
-
if(propList[name]) {
|
|
4897
|
-
let propName = propList[name] === true ? name : propList[name];
|
|
4898
|
-
if(ctx.inuse.apply) {
|
|
4899
|
-
ctx.writeLine(`$watchReadOnly($cd, () => (${data.exp}), (value) => {${data.el}.${propName} = value;});`);
|
|
4900
|
-
} else {
|
|
4901
|
-
ctx.writeLine(`${data.el}.${propName} = ${data.exp};`);
|
|
4902
|
-
}
|
|
4903
|
-
} else {
|
|
4904
|
-
if(ctx.inuse.apply) {
|
|
4905
|
-
ctx.writeLine(`$runtime.bindAttribute($cd, ${data.el}, '${data.name}', () => (${data.exp}));`);
|
|
4906
|
-
} else {
|
|
4907
|
-
ctx.writeLine(`$runtime.bindAttributeBase(${data.el}, '${data.name}', ${data.exp});`);
|
|
4908
|
-
}
|
|
4909
|
-
}
|
|
4910
|
-
})
|
|
4911
|
-
]
|
|
5148
|
+
body: [n]
|
|
4912
5149
|
})};
|
|
4913
5150
|
}
|
|
4914
5151
|
|
|
@@ -4921,104 +5158,86 @@
|
|
|
4921
5158
|
}
|
|
4922
5159
|
}
|
|
4923
5160
|
|
|
4924
|
-
function makeifBlock(data, element) {
|
|
4925
|
-
let r = data.value.match(/^#if (.*)$/
|
|
5161
|
+
function makeifBlock(data, element, requireCD) {
|
|
5162
|
+
let r = data.value.match(/^#if (.*)$/);
|
|
4926
5163
|
let exp = r[1];
|
|
4927
5164
|
assert(exp, 'Wrong binding: ' + data.value);
|
|
4928
5165
|
this.detectDependency(exp);
|
|
4929
5166
|
this.require('$cd');
|
|
4930
5167
|
|
|
4931
|
-
let mainBlock, elseBlock
|
|
5168
|
+
let mainBlock, elseBlock;
|
|
4932
5169
|
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
5170
|
+
const getBlock = b => {
|
|
5171
|
+
if(b.singleBlock) {
|
|
5172
|
+
return xNode('make-block', {
|
|
5173
|
+
block: b.singleBlock
|
|
5174
|
+
}, (ctx, n) => {
|
|
5175
|
+
ctx.write('() => ');
|
|
5176
|
+
ctx.add(n.block);
|
|
5177
|
+
})
|
|
5178
|
+
}
|
|
5179
|
+
return b.block;
|
|
5180
|
+
};
|
|
4936
5181
|
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
svg: elseBlock.svg
|
|
4941
|
-
});
|
|
5182
|
+
if(data.bodyMain) {
|
|
5183
|
+
mainBlock = getBlock(this.buildBlock({body: data.bodyMain}, {protectLastTag: true, allowSingleBlock: true}));
|
|
5184
|
+
elseBlock = getBlock(this.buildBlock(data, {protectLastTag: true, allowSingleBlock: true}));
|
|
4942
5185
|
} else {
|
|
4943
|
-
mainBlock = this.buildBlock(data, {protectLastTag: true,
|
|
5186
|
+
mainBlock = getBlock(this.buildBlock(data, {protectLastTag: true, allowSingleBlock: true}));
|
|
4944
5187
|
}
|
|
5188
|
+
|
|
5189
|
+
const result = xNode('if:bind', {
|
|
5190
|
+
$deps: [this.glob.apply],
|
|
5191
|
+
requireCD,
|
|
5192
|
+
el: element.bindName(),
|
|
5193
|
+
exp,
|
|
5194
|
+
mainBlock: mainBlock,
|
|
5195
|
+
elseBlock: elseBlock
|
|
5196
|
+
}, (ctx, n) => {
|
|
5197
|
+
if(this.glob.apply.value) {
|
|
5198
|
+
n.requireCD.$value(true);
|
|
5199
|
+
ctx.write(true, `$runtime.ifBlock($cd, ${n.el}, () => !!(${n.exp}),`);
|
|
5200
|
+
} else {
|
|
5201
|
+
this.glob.component.$value(true);
|
|
5202
|
+
ctx.write(true, `$runtime.ifBlockReadOnly($component, ${n.el}, () => !!(${n.exp}),`);
|
|
5203
|
+
}
|
|
4945
5204
|
|
|
4946
|
-
mainTpl = xNode('template', {
|
|
4947
|
-
inline: true,
|
|
4948
|
-
body: mainBlock.tpl,
|
|
4949
|
-
svg: mainBlock.svg
|
|
4950
|
-
});
|
|
4951
|
-
|
|
4952
|
-
const source = xNode('if:bind', {
|
|
4953
|
-
el: element.bindName(),
|
|
4954
|
-
exp,
|
|
4955
|
-
mainTpl,
|
|
4956
|
-
mainBlock: mainBlock.source,
|
|
4957
|
-
elseTpl,
|
|
4958
|
-
elseBlock: elseBlock && elseBlock.source
|
|
4959
|
-
},
|
|
4960
|
-
(ctx, data) => {
|
|
4961
|
-
ctx.writeLine(`$runtime.$$ifBlock($cd, ${data.el}, () => !!(${data.exp}),`);
|
|
4962
5205
|
ctx.indent++;
|
|
4963
|
-
ctx.
|
|
4964
|
-
ctx.
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
ctx.build(xNode('function', {
|
|
4969
|
-
inline: true,
|
|
4970
|
-
arrow: true,
|
|
4971
|
-
args: ['$cd', '$parentElement'],
|
|
4972
|
-
body: [data.mainBlock]
|
|
4973
|
-
}));
|
|
4974
|
-
} else ctx.write('$runtime.noop');
|
|
4975
|
-
if(data.elseTpl) {
|
|
4976
|
-
ctx.write(',\n');
|
|
4977
|
-
ctx.writeIndent();
|
|
4978
|
-
ctx.build(data.elseTpl);
|
|
4979
|
-
ctx.write(',\n');
|
|
4980
|
-
ctx.writeIndent();
|
|
4981
|
-
if(data.elseBlock) {
|
|
4982
|
-
ctx.build(xNode('function', {
|
|
4983
|
-
inline: true,
|
|
4984
|
-
arrow: true,
|
|
4985
|
-
args: ['$cd', '$parentElement'],
|
|
4986
|
-
body: [data.elseBlock]
|
|
4987
|
-
}));
|
|
4988
|
-
} else ctx.write('$runtime.noop');
|
|
5206
|
+
ctx.write(true);
|
|
5207
|
+
ctx.add(n.mainBlock);
|
|
5208
|
+
if(n.elseBlock) {
|
|
5209
|
+
ctx.write(',');
|
|
5210
|
+
ctx.add(n.elseBlock);
|
|
4989
5211
|
}
|
|
4990
5212
|
ctx.indent--;
|
|
4991
|
-
ctx.write(')
|
|
5213
|
+
ctx.write(true, ');', true);
|
|
4992
5214
|
});
|
|
4993
|
-
|
|
4994
|
-
|
|
5215
|
+
requireCD.$depends(result);
|
|
5216
|
+
this.glob.component.$depends(result);
|
|
5217
|
+
return result;
|
|
4995
5218
|
}
|
|
4996
5219
|
|
|
4997
5220
|
function makeEachBlock(data, option) {
|
|
4998
|
-
|
|
4999
|
-
let nodeItems = trimEmptyNodes(data.body);
|
|
5000
|
-
if(!nodeItems.length) nodeItems = [data.body[0]];
|
|
5001
|
-
|
|
5002
|
-
let itemData = this.buildBlock({body: nodeItems}, {protectLastTag: true, inline: true});
|
|
5221
|
+
this.require('apply');
|
|
5003
5222
|
|
|
5004
5223
|
// #each items as item, index (key)
|
|
5005
|
-
let rx = data.value.match(/^#each\s+(.+)\s+as\s+(.+)$/
|
|
5224
|
+
let rx = data.value.match(/^#each\s+(.+)\s+as\s+(.+)$/);
|
|
5006
5225
|
assert(rx, `Wrong #each expression '${data.value}'`);
|
|
5007
5226
|
let arrayName = rx[1];
|
|
5008
5227
|
let right = rx[2];
|
|
5009
5228
|
let keyName;
|
|
5010
5229
|
|
|
5011
5230
|
// get keyName
|
|
5012
|
-
rx = right.match(/^(.*)\s*\(\s*([^\(\)]+)\s*\)\s*$/
|
|
5231
|
+
rx = right.match(/^(.*)\s*\(\s*([^\(\)]+)\s*\)\s*$/);
|
|
5013
5232
|
if(rx) {
|
|
5014
5233
|
right = rx[1];
|
|
5015
5234
|
keyName = rx[2];
|
|
5016
5235
|
}
|
|
5017
5236
|
right = right.trim();
|
|
5018
5237
|
|
|
5019
|
-
let itemName, indexName,
|
|
5238
|
+
let itemName, indexName, blockPrefix = null;
|
|
5020
5239
|
if(right[0] == '{') {
|
|
5021
|
-
rx = right.match(/^(\{[^}]+\})(.*)$/
|
|
5240
|
+
rx = right.match(/^(\{[^}]+\})(.*)$/);
|
|
5022
5241
|
assert(rx, `Wrong #each expression '${data.value}'`);
|
|
5023
5242
|
let exp = rx[1], keywords;
|
|
5024
5243
|
|
|
@@ -5033,12 +5252,15 @@
|
|
|
5033
5252
|
if(indexName[0] == ',') indexName = indexName.substring(1).trim();
|
|
5034
5253
|
indexName = indexName || '$index';
|
|
5035
5254
|
|
|
5036
|
-
|
|
5255
|
+
blockPrefix = xNode('each:unwrap', {
|
|
5037
5256
|
exp,
|
|
5038
5257
|
keywords
|
|
5039
5258
|
}, (ctx, n) => {
|
|
5040
|
-
ctx.writeLine(`let ${n.
|
|
5041
|
-
|
|
5259
|
+
if(this.script.readOnly) ctx.writeLine(`let ${n.exp} = $$item;`);
|
|
5260
|
+
else {
|
|
5261
|
+
ctx.writeLine(`let ${n.keywords.join(', ')};`);
|
|
5262
|
+
ctx.writeLine(`$runtime.prefixPush($cd, () => (${n.exp} = $$item));`);
|
|
5263
|
+
}
|
|
5042
5264
|
});
|
|
5043
5265
|
} else {
|
|
5044
5266
|
rx = right.trim().split(/\s*\,\s*/);
|
|
@@ -5071,82 +5293,93 @@
|
|
|
5071
5293
|
})]
|
|
5072
5294
|
});
|
|
5073
5295
|
}
|
|
5074
|
-
let
|
|
5075
|
-
if(
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
`let $cd = $ctx.cd;`,
|
|
5082
|
-
bind0,
|
|
5083
|
-
itemData.source,
|
|
5084
|
-
xNode(ctx => {
|
|
5085
|
-
ctx.writeLine(`$ctx.rebind = function(_${indexName}, _${itemName}) {`);
|
|
5086
|
-
ctx.indent++;
|
|
5087
|
-
ctx.writeLine(`${indexName} = _${indexName};`);
|
|
5088
|
-
ctx.writeLine(`${itemName} = _${itemName};`);
|
|
5089
|
-
ctx.indent--;
|
|
5090
|
-
ctx.writeLine(`};`);
|
|
5091
|
-
})
|
|
5092
|
-
]
|
|
5093
|
-
});
|
|
5094
|
-
} else {
|
|
5095
|
-
bind = xNode('function', {
|
|
5096
|
-
inline: true,
|
|
5097
|
-
arrow: true,
|
|
5098
|
-
args: ['$ctx'],
|
|
5099
|
-
body: [`$ctx.rebind = $runtime.noop;`]
|
|
5296
|
+
let rebind;
|
|
5297
|
+
if(!this.script.readOnly) {
|
|
5298
|
+
rebind = xNode('block', {
|
|
5299
|
+
itemName,
|
|
5300
|
+
indexName
|
|
5301
|
+
}, (ctx, n) => {
|
|
5302
|
+
ctx.write(`(_${n.indexName}, _${n.itemName}) => {${n.indexName}=_${n.indexName}; ${n.itemName}=_${n.itemName};}`);
|
|
5100
5303
|
});
|
|
5101
5304
|
}
|
|
5102
5305
|
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5306
|
+
let nodeItems = trimEmptyNodes(data.body);
|
|
5307
|
+
if(!nodeItems.length) nodeItems = [data.body[0]];
|
|
5308
|
+
|
|
5309
|
+
let itemBlock, block = this.buildBlock({body: nodeItems}, {
|
|
5310
|
+
protectLastTag: true,
|
|
5311
|
+
allowSingleBlock: !blockPrefix,
|
|
5312
|
+
each: {
|
|
5313
|
+
blockPrefix,
|
|
5314
|
+
rebind,
|
|
5315
|
+
itemName,
|
|
5316
|
+
indexName
|
|
5317
|
+
}
|
|
5107
5318
|
});
|
|
5108
5319
|
|
|
5109
|
-
|
|
5320
|
+
if(block.singleBlock) {
|
|
5321
|
+
itemBlock = xNode('each-component', {
|
|
5322
|
+
block: block.singleBlock,
|
|
5323
|
+
rebind,
|
|
5324
|
+
itemName,
|
|
5325
|
+
indexName
|
|
5326
|
+
}, (ctx, n) => {
|
|
5327
|
+
ctx.write(`$runtime.makeEachSingleBlock((${n.itemName}, ${n.indexName}) => [`);
|
|
5328
|
+
ctx.indent++;
|
|
5329
|
+
ctx.write(true);
|
|
5330
|
+
ctx.add(n.rebind);
|
|
5331
|
+
ctx.write(',', true);
|
|
5332
|
+
ctx.add(n.block);
|
|
5333
|
+
ctx.indent--;
|
|
5334
|
+
ctx.write(true, `])`);
|
|
5335
|
+
});
|
|
5336
|
+
} else itemBlock = block.block;
|
|
5337
|
+
|
|
5110
5338
|
const source = xNode('each', {
|
|
5111
5339
|
keyFunction,
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
}, (ctx, data) => {
|
|
5340
|
+
block: itemBlock,
|
|
5341
|
+
}, (ctx, n) => {
|
|
5115
5342
|
ctx.writeLine(`$runtime.$$eachBlock($cd, ${option.elName}, ${option.onlyChild?1:0}, () => (${arrayName}),`);
|
|
5116
5343
|
ctx.indent++;
|
|
5117
|
-
ctx.
|
|
5118
|
-
if(
|
|
5119
|
-
else if(
|
|
5344
|
+
ctx.write(true);
|
|
5345
|
+
if(n.keyFunction === 'noop') ctx.write('$runtime.noop');
|
|
5346
|
+
else if(n.keyFunction) ctx.add(n.keyFunction);
|
|
5120
5347
|
else ctx.write('$runtime.eachDefaultKey');
|
|
5121
|
-
ctx.write(
|
|
5122
|
-
ctx.
|
|
5123
|
-
ctx.build(data.template);
|
|
5124
|
-
ctx.write(`,\n`);
|
|
5125
|
-
ctx.writeIndent();
|
|
5126
|
-
ctx.build(data.bind);
|
|
5127
|
-
ctx.write(`);\n`);
|
|
5348
|
+
ctx.write(`,`);
|
|
5349
|
+
ctx.add(n.block);
|
|
5128
5350
|
ctx.indent--;
|
|
5351
|
+
ctx.write(true, `);`, true);
|
|
5129
5352
|
});
|
|
5130
5353
|
this.detectDependency(arrayName);
|
|
5131
5354
|
|
|
5132
5355
|
return {source};
|
|
5133
5356
|
}
|
|
5134
5357
|
|
|
5135
|
-
function makeHtmlBlock(exp, label) {
|
|
5358
|
+
function makeHtmlBlock(exp, label, requireCD) {
|
|
5136
5359
|
this.detectDependency(exp);
|
|
5137
5360
|
this.require('$cd');
|
|
5138
|
-
|
|
5361
|
+
const result = xNode('block', {
|
|
5362
|
+
$deps: [this.glob.apply],
|
|
5139
5363
|
el: label.bindName(),
|
|
5140
|
-
exp
|
|
5364
|
+
exp,
|
|
5365
|
+
requireCD
|
|
5141
5366
|
}, (ctx, n) => {
|
|
5142
|
-
|
|
5367
|
+
let cd;
|
|
5368
|
+
if(this.glob.apply.value) {
|
|
5369
|
+
n.requireCD.$value(true);
|
|
5370
|
+
cd = '$cd';
|
|
5371
|
+
} else cd = 'null';
|
|
5372
|
+
ctx.write(true, `$runtime.$$htmlBlock(${cd}, ${n.el}, () => (${n.exp}));`);
|
|
5143
5373
|
});
|
|
5374
|
+
|
|
5375
|
+
requireCD.$depends(result);
|
|
5376
|
+
return result;
|
|
5144
5377
|
}
|
|
5145
5378
|
|
|
5146
5379
|
function makeAwaitBlock(node, element) {
|
|
5147
5380
|
let valueForThen, exp;
|
|
5148
5381
|
|
|
5149
|
-
let rx = node.value.match(/^#await\s+(.+)\s+then\s+(\S+)\s*$/
|
|
5382
|
+
let rx = node.value.match(/^#await\s+(.+)\s+then\s+(\S+)\s*$/);
|
|
5150
5383
|
if(rx) {
|
|
5151
5384
|
assert(!node.parts.then);
|
|
5152
5385
|
node.parts.then = node.parts.main;
|
|
@@ -5154,7 +5387,7 @@
|
|
|
5154
5387
|
exp = rx[1];
|
|
5155
5388
|
valueForThen = rx[2];
|
|
5156
5389
|
} else {
|
|
5157
|
-
rx = node.value.match(/^#await\s+(.+)\s*$/
|
|
5390
|
+
rx = node.value.match(/^#await\s+(.+)\s*$/);
|
|
5158
5391
|
assert(rx);
|
|
5159
5392
|
exp = rx[1].trim();
|
|
5160
5393
|
}
|
|
@@ -5163,7 +5396,7 @@
|
|
|
5163
5396
|
|
|
5164
5397
|
let parts = [null, null, null];
|
|
5165
5398
|
if(node.parts.main && node.parts.main.length) {
|
|
5166
|
-
parts[0] = this.buildBlock({body: node.parts.main}, {protectLastTag: true
|
|
5399
|
+
parts[0] = this.buildBlock({body: node.parts.main}, {protectLastTag: true});
|
|
5167
5400
|
}
|
|
5168
5401
|
if(node.parts.then && node.parts.then.length) {
|
|
5169
5402
|
let args = [];
|
|
@@ -5171,27 +5404,30 @@
|
|
|
5171
5404
|
assert(isSimpleName(valueForThen));
|
|
5172
5405
|
args.push(valueForThen);
|
|
5173
5406
|
} else {
|
|
5174
|
-
let rx = node.parts.thenValue.match(/^[^ ]+\s+(.*)$/
|
|
5407
|
+
let rx = node.parts.thenValue.match(/^[^ ]+\s+(.*)$/);
|
|
5175
5408
|
if(rx) {
|
|
5176
5409
|
assert(isSimpleName(rx[1]));
|
|
5177
5410
|
args.push(rx[1]);
|
|
5178
5411
|
}
|
|
5179
5412
|
}
|
|
5180
|
-
parts[1] = this.buildBlock({body: node.parts.then}, {protectLastTag: true,
|
|
5413
|
+
parts[1] = this.buildBlock({body: node.parts.then}, {protectLastTag: true, extraArguments: args});
|
|
5181
5414
|
}
|
|
5182
5415
|
if(node.parts.catch && node.parts.catch.length) {
|
|
5183
5416
|
let args = [];
|
|
5184
|
-
let rx = node.parts.catchValue.match(/^[^ ]+\s+(.*)$/
|
|
5417
|
+
let rx = node.parts.catchValue.match(/^[^ ]+\s+(.*)$/);
|
|
5185
5418
|
if(rx) {
|
|
5186
5419
|
assert(isSimpleName(rx[1]));
|
|
5187
5420
|
args.push(rx[1]);
|
|
5188
5421
|
}
|
|
5189
|
-
parts[2] = this.buildBlock({body: node.parts.catch}, {protectLastTag: true,
|
|
5422
|
+
parts[2] = this.buildBlock({body: node.parts.catch}, {protectLastTag: true, extraArguments: args});
|
|
5190
5423
|
}
|
|
5191
5424
|
|
|
5425
|
+
if(this.script.readOnly) {
|
|
5426
|
+
this.warning('script read-only conflicts with await');
|
|
5427
|
+
return;
|
|
5428
|
+
}
|
|
5192
5429
|
this.detectDependency(exp);
|
|
5193
|
-
|
|
5194
|
-
this.require('apply', '$cd');
|
|
5430
|
+
this.require('apply');
|
|
5195
5431
|
|
|
5196
5432
|
return xNode('await', {
|
|
5197
5433
|
el: element.bindName(),
|
|
@@ -5199,127 +5435,88 @@
|
|
|
5199
5435
|
parts,
|
|
5200
5436
|
keywords
|
|
5201
5437
|
}, (ctx, n) => {
|
|
5202
|
-
ctx.
|
|
5203
|
-
ctx.
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
ctx.build(source);
|
|
5211
|
-
ctx.write(',\n');
|
|
5212
|
-
ctx.writeIndent();
|
|
5213
|
-
} else ctx.write(`$runtime.noop, `);
|
|
5214
|
-
ctx.build(xNode('template', {body: tpl, svg, inline: true}));
|
|
5215
|
-
ctx.write(index == 2 ? '\n' : ',\n');
|
|
5216
|
-
} else {
|
|
5217
|
-
ctx.writeLine(`null, null` + (index == 2 ? '' : ','));
|
|
5218
|
-
} });
|
|
5438
|
+
ctx.write(true, `$runtime.$$awaitBlock($cd, ${n.el}, () => [${n.keywords.join(', ')}], () => ${n.exp},`);
|
|
5439
|
+
ctx.indent++;
|
|
5440
|
+
n.parts.forEach((part, index) => {
|
|
5441
|
+
if(index) ctx.write(', ');
|
|
5442
|
+
if(part) {
|
|
5443
|
+
ctx.write(true);
|
|
5444
|
+
ctx.add(part.block);
|
|
5445
|
+
} else ctx.write('null');
|
|
5219
5446
|
});
|
|
5220
|
-
ctx.
|
|
5447
|
+
ctx.indent--;
|
|
5448
|
+
ctx.write(');', true);
|
|
5221
5449
|
});
|
|
5222
5450
|
}
|
|
5223
5451
|
|
|
5224
|
-
function attachSlot(slotName,
|
|
5225
|
-
let props = [];
|
|
5452
|
+
function attachSlot(slotName, node, requireCD) {
|
|
5453
|
+
let props = [], staticProps = true;
|
|
5454
|
+
|
|
5226
5455
|
if(node.attributes && node.attributes.length) {
|
|
5227
5456
|
node.attributes.forEach(prop => {
|
|
5228
|
-
let name = prop
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
value
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
if(value[0] == '{') {
|
|
5237
|
-
value = unwrapExp(value);
|
|
5238
|
-
this.detectDependency(value);
|
|
5457
|
+
let {name, value, ...ip} = this.inspectProp(prop);
|
|
5458
|
+
if(!ip.static) staticProps = false;
|
|
5459
|
+
props.push(xNode('slot-prop', {
|
|
5460
|
+
name,
|
|
5461
|
+
value
|
|
5462
|
+
}, (ctx, n) => {
|
|
5463
|
+
ctx.write(`${n.name}: ${n.value}`);
|
|
5464
|
+
}));
|
|
5239
5465
|
|
|
5240
|
-
props.push(xNode('prop', {
|
|
5241
|
-
name,
|
|
5242
|
-
value,
|
|
5243
|
-
dyn: true
|
|
5244
|
-
}, (ctx, n) => {
|
|
5245
|
-
if(this.inuse.apply) ctx.write(`${n.name}: () => (${n.value})`);
|
|
5246
|
-
else ctx.write(`${n.name}: (${n.value})`);
|
|
5247
|
-
}));
|
|
5248
|
-
} else {
|
|
5249
|
-
props.push(xNode('static-prop', {
|
|
5250
|
-
name,
|
|
5251
|
-
value
|
|
5252
|
-
}, (ctx, n) => {
|
|
5253
|
-
ctx.write(`${n.name}: \`${this.Q(n.value)}\``);
|
|
5254
|
-
}));
|
|
5255
|
-
}
|
|
5256
5466
|
});
|
|
5257
5467
|
}
|
|
5258
5468
|
let placeholder;
|
|
5259
|
-
if(node.body
|
|
5260
|
-
let block = this.buildBlock(node, {inline: true});
|
|
5261
|
-
|
|
5262
|
-
const tpl = xNode('template', {
|
|
5263
|
-
name: '$parentElement',
|
|
5264
|
-
body: block.tpl,
|
|
5265
|
-
svg: block.svg
|
|
5266
|
-
});
|
|
5469
|
+
if(node.body?.length) placeholder = this.buildBlock(node).block;
|
|
5267
5470
|
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
body: block.source,
|
|
5271
|
-
tpl
|
|
5272
|
-
}, (ctx, n) => {
|
|
5273
|
-
ctx.build(n.tpl);
|
|
5274
|
-
ctx.build(n.body);
|
|
5275
|
-
ctx.writeLine(`$runtime.insertAfter(${n.el}, $parentElement);`);
|
|
5276
|
-
});
|
|
5277
|
-
}
|
|
5278
|
-
|
|
5279
|
-
this.require('$component', '$cd', '$context');
|
|
5471
|
+
this.require('$context');
|
|
5472
|
+
this.glob.component.$value(true);
|
|
5280
5473
|
|
|
5281
|
-
|
|
5474
|
+
let result = xNode('slot', {
|
|
5475
|
+
$deps: [this.glob.apply],
|
|
5282
5476
|
name: slotName,
|
|
5283
|
-
el: label.bindName(),
|
|
5284
5477
|
props,
|
|
5285
|
-
|
|
5478
|
+
staticProps,
|
|
5479
|
+
placeholder,
|
|
5480
|
+
requireCD
|
|
5286
5481
|
}, (ctx, n) => {
|
|
5287
|
-
let
|
|
5288
|
-
|
|
5289
|
-
if(
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
}
|
|
5293
|
-
ctx.write(
|
|
5482
|
+
let dynamicProps = this.glob.apply.value && !n.staticProps;
|
|
5483
|
+
|
|
5484
|
+
if(dynamicProps) n.requireCD.$value(true);
|
|
5485
|
+
|
|
5486
|
+
let missed = '', slotName = n.name == 'default' ? 'null' : n.name;
|
|
5487
|
+
if(dynamicProps) ctx.write(`$runtime.invokeSlot($component, ${slotName}, $context`);
|
|
5488
|
+
else ctx.write(`$runtime.invokeSlotBase($component, ${slotName}, $context`);
|
|
5489
|
+
|
|
5294
5490
|
if(n.props.length) {
|
|
5295
|
-
ctx.write(
|
|
5296
|
-
ctx.
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
ctx.build(prop);
|
|
5301
|
-
if(i + 1 < n.props.length) ctx.write(',');
|
|
5302
|
-
ctx.write('\n');
|
|
5303
|
-
}
|
|
5491
|
+
if(dynamicProps) ctx.write(', () => ({');
|
|
5492
|
+
else ctx.write(', {');
|
|
5493
|
+
n.props.forEach((prop, i) => {
|
|
5494
|
+
if(i) ctx.write(', ');
|
|
5495
|
+
ctx.add(prop);
|
|
5304
5496
|
});
|
|
5305
|
-
ctx.write(
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5497
|
+
ctx.write('}');
|
|
5498
|
+
if(dynamicProps) ctx.write(')');
|
|
5499
|
+
} else missed += ', null';
|
|
5500
|
+
|
|
5309
5501
|
if(n.placeholder) {
|
|
5310
|
-
ctx.write(',
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5502
|
+
ctx.write(missed, ', ');
|
|
5503
|
+
missed = '';
|
|
5504
|
+
ctx.add(n.placeholder);
|
|
5505
|
+
} else missed += ', null';
|
|
5506
|
+
|
|
5507
|
+
if(dynamicProps) {
|
|
5508
|
+
ctx.write(missed, ', ');
|
|
5509
|
+
if(this.config.immutable) ctx.write(`$runtime.keyComparator`);
|
|
5510
|
+
else ctx.write(`$runtime.$$compareDeep`);
|
|
5511
|
+
}
|
|
5512
|
+
ctx.write(')');
|
|
5318
5513
|
});
|
|
5514
|
+
requireCD.$depends(result);
|
|
5515
|
+
return result;
|
|
5319
5516
|
}
|
|
5320
5517
|
|
|
5321
|
-
function makeFragment(node) {
|
|
5322
|
-
let rx = node.value.match(/#fragment\:(\S+)(.*)$/
|
|
5518
|
+
function makeFragment(node, requireCD) {
|
|
5519
|
+
let rx = node.value.match(/#fragment\:(\S+)(.*)$/);
|
|
5323
5520
|
assert(rx);
|
|
5324
5521
|
let name = rx[1], external = false;
|
|
5325
5522
|
assert(isSimpleName(name));
|
|
@@ -5334,9 +5531,12 @@
|
|
|
5334
5531
|
});
|
|
5335
5532
|
}
|
|
5336
5533
|
|
|
5534
|
+
if(external) requireCD.$value(true);
|
|
5535
|
+
|
|
5337
5536
|
let block;
|
|
5338
|
-
if(node.body && node.body.length)
|
|
5339
|
-
|
|
5537
|
+
if(node.body && node.body.length) {
|
|
5538
|
+
block = this.buildBlock({body: trimEmptyNodes(node.body)}, {inline: true, context: 'fragment', parentElement: '$dom'});
|
|
5539
|
+
} else {
|
|
5340
5540
|
this.warning(`Empty fragment: '${node.value}'`);
|
|
5341
5541
|
return xNode('empty-fragment', {name}, (ctx, n) => {
|
|
5342
5542
|
ctx.writeLine(`function $fragment_${n.name}() {};`);
|
|
@@ -5344,36 +5544,45 @@
|
|
|
5344
5544
|
}
|
|
5345
5545
|
|
|
5346
5546
|
return xNode('fragment', {
|
|
5547
|
+
$compile: [block.source, this.glob.apply],
|
|
5548
|
+
$deps: [block.requireCD],
|
|
5347
5549
|
name,
|
|
5348
5550
|
props,
|
|
5349
5551
|
external,
|
|
5350
|
-
|
|
5351
|
-
template: xNode('template', {
|
|
5352
|
-
name: '$parentElement',
|
|
5353
|
-
body: block.tpl,
|
|
5354
|
-
svg: block.svg
|
|
5355
|
-
})
|
|
5552
|
+
block
|
|
5356
5553
|
}, (ctx, n) => {
|
|
5357
|
-
ctx.
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5554
|
+
if(ctx.isEmpty(n.block.source)) {
|
|
5555
|
+
ctx.write(true, `let $fragment_${n.name} = $runtime.makeStaticBlock(`);
|
|
5556
|
+
ctx.add(n.block.template);
|
|
5557
|
+
ctx.write(');');
|
|
5558
|
+
} else {
|
|
5559
|
+
ctx.write(true, `function $fragment_${n.name}($props, $events={}, $$fragmentSlot) {`);
|
|
5560
|
+
ctx.indent++;
|
|
5561
|
+
|
|
5562
|
+
if(n.block.requireCD.value) ctx.write(true, 'let $cd = $runtime.cd_new();');
|
|
5563
|
+
|
|
5564
|
+
if(n.props?.length) {
|
|
5565
|
+
if(this.glob.apply.value) {
|
|
5566
|
+
ctx.writeLine('let ' + n.props.join(', ') + ';');
|
|
5567
|
+
ctx.writeLine(`$runtime.unwrapProps($cd, $props, ($$) => ({${n.props.join(', ')}} = $$));`);
|
|
5568
|
+
} else {
|
|
5569
|
+
ctx.writeLine('let ' + n.props.join(', ') + ';');
|
|
5570
|
+
ctx.writeLine(`$props && ({${n.props.join(', ')}} = ($runtime.isFunction($props) ? $props() : $props));`);
|
|
5571
|
+
}
|
|
5367
5572
|
}
|
|
5573
|
+
|
|
5574
|
+
ctx.write(true, 'let $dom = ');
|
|
5575
|
+
ctx.add(n.block.template);
|
|
5576
|
+
ctx.write(';');
|
|
5577
|
+
|
|
5578
|
+
ctx.add(n.block.source);
|
|
5579
|
+
if(n.block.requireCD.value) ctx.write(true, `return {$cd, $dom};`);
|
|
5580
|
+
else ctx.write(true, `return {$dom};`);
|
|
5581
|
+
|
|
5582
|
+
ctx.indent--;
|
|
5583
|
+
ctx.writeLine('}');
|
|
5368
5584
|
}
|
|
5369
|
-
|
|
5370
|
-
ctx.build(n.template);
|
|
5371
|
-
ctx.build(n.source);
|
|
5372
|
-
ctx.writeLine(`$runtime.insertAfter($$label, $parentElement);`);
|
|
5373
|
-
|
|
5374
|
-
ctx.indent--;
|
|
5375
|
-
ctx.writeLine('}');
|
|
5376
|
-
if(n.external) ctx.writeLine(`$runtime.exportFragment($component, '${n.name}', $fragment_${n.name});`);
|
|
5585
|
+
if(n.external) ctx.writeLine(`$runtime.exportFragment($cd, '${n.name}', $fragment_${n.name});`);
|
|
5377
5586
|
});
|
|
5378
5587
|
}
|
|
5379
5588
|
|
|
@@ -5395,7 +5604,7 @@
|
|
|
5395
5604
|
name = name.substring(2);
|
|
5396
5605
|
events.push({
|
|
5397
5606
|
name,
|
|
5398
|
-
callback: `$events
|
|
5607
|
+
callback: `$events.${name}`
|
|
5399
5608
|
});
|
|
5400
5609
|
}
|
|
5401
5610
|
return;
|
|
@@ -5414,64 +5623,48 @@
|
|
|
5414
5623
|
}
|
|
5415
5624
|
|
|
5416
5625
|
|
|
5417
|
-
function attachFragment(node
|
|
5626
|
+
function attachFragment(node) {
|
|
5418
5627
|
let name = node.elArg;
|
|
5419
5628
|
assert(isSimpleName(name));
|
|
5420
5629
|
|
|
5421
|
-
let slotBlock = null;
|
|
5422
|
-
|
|
5423
|
-
if(node.body?.length) slotBlock = this.buildBlock({body: trimEmptyNodes(node.body)}, {inline: true});
|
|
5424
|
-
|
|
5425
|
-
let {props, events, forwardAllEvents, staticProps} = parseAttibutes.call(this, node.attributes);
|
|
5426
|
-
this.require('$cd');
|
|
5427
|
-
|
|
5428
5630
|
let slot = null;
|
|
5429
|
-
if(
|
|
5430
|
-
let template = xNode('template', {
|
|
5431
|
-
name: '$parentElement',
|
|
5432
|
-
body: slotBlock.tpl,
|
|
5433
|
-
svg: slotBlock.svg,
|
|
5434
|
-
inline: !slotBlock.source
|
|
5435
|
-
});
|
|
5631
|
+
if(node.body?.length) slot = this.buildBlock({body: trimEmptyNodes(node.body)}, {inline: true});
|
|
5436
5632
|
|
|
5437
|
-
|
|
5438
|
-
source: slotBlock.source,
|
|
5439
|
-
template
|
|
5440
|
-
};
|
|
5441
|
-
}
|
|
5633
|
+
let {props, events, forwardAllEvents, staticProps} = parseAttibutes.call(this, node.attributes);
|
|
5442
5634
|
|
|
5443
5635
|
return xNode('call-fragment', {
|
|
5636
|
+
$compile: [slot?.source],
|
|
5637
|
+
$deps: [this.glob.apply],
|
|
5444
5638
|
forwardAllEvents,
|
|
5445
|
-
el: element.bindName(),
|
|
5446
5639
|
name,
|
|
5447
5640
|
events,
|
|
5448
5641
|
props,
|
|
5449
5642
|
slot,
|
|
5450
5643
|
staticProps
|
|
5451
5644
|
}, (ctx, n) => {
|
|
5452
|
-
ctx.write(
|
|
5645
|
+
ctx.write(`$fragment_${n.name}(`);
|
|
5453
5646
|
let missed = '';
|
|
5454
5647
|
ctx.indent++;
|
|
5455
5648
|
|
|
5456
5649
|
if(n.props.length) {
|
|
5457
|
-
ctx.write(
|
|
5650
|
+
ctx.write(true);
|
|
5458
5651
|
|
|
5459
5652
|
const writeProps = () => ctx.write('{' + n.props.map(p => p.name == p.value ? p.name : `${p.name}: ${p.value}`).join(', ') + '}');
|
|
5460
5653
|
|
|
5461
|
-
if(n.staticProps) writeProps();
|
|
5654
|
+
if(n.staticProps || !this.glob.apply.value) writeProps();
|
|
5462
5655
|
else {
|
|
5463
5656
|
ctx.write(`() => (`);
|
|
5464
5657
|
writeProps();
|
|
5465
5658
|
ctx.write(`)`);
|
|
5466
5659
|
}
|
|
5467
|
-
} else missed = '
|
|
5660
|
+
} else missed = 'null';
|
|
5468
5661
|
|
|
5469
5662
|
if(n.forwardAllEvents) {
|
|
5470
5663
|
if(n.events.length) this.warning(`Fragment: mixing binding and forwarding is not supported: '${node.openTag}'`);
|
|
5471
5664
|
ctx.write(missed, ', $events');
|
|
5472
5665
|
missed = '';
|
|
5473
5666
|
} else if(n.events.length) {
|
|
5474
|
-
ctx.write(missed, '
|
|
5667
|
+
ctx.write(missed, ',', true, '{');
|
|
5475
5668
|
missed = '';
|
|
5476
5669
|
|
|
5477
5670
|
n.events.forEach((e, i) => {
|
|
@@ -5489,42 +5682,42 @@
|
|
|
5489
5682
|
} else missed += ', 0';
|
|
5490
5683
|
|
|
5491
5684
|
if(n.slot) {
|
|
5492
|
-
ctx.write(missed, '
|
|
5685
|
+
ctx.write(missed, ',', true);
|
|
5493
5686
|
missed = '';
|
|
5494
|
-
if(n.slot.source) {
|
|
5495
|
-
ctx.
|
|
5496
|
-
ctx.
|
|
5497
|
-
|
|
5498
|
-
ctx.build(n.slot.source);
|
|
5499
|
-
ctx.writeLine(`$runtime.insertAfter($$label, $parentElement);`);
|
|
5500
|
-
});
|
|
5501
|
-
ctx.write(true, `}`);
|
|
5687
|
+
if(ctx.isEmpty(n.slot.source)) {
|
|
5688
|
+
ctx.write(`$runtime.makeStaticBlock(`);
|
|
5689
|
+
ctx.add(n.slot.template);
|
|
5690
|
+
ctx.write(`)`);
|
|
5502
5691
|
} else {
|
|
5503
|
-
ctx.write(
|
|
5504
|
-
ctx.
|
|
5505
|
-
ctx.write(
|
|
5692
|
+
ctx.write(`$runtime.makeBlock(`);
|
|
5693
|
+
ctx.add(n.slot.template);
|
|
5694
|
+
ctx.write(`, ($cd, $parentElement) => {`, true);
|
|
5695
|
+
ctx.indent++;
|
|
5696
|
+
ctx.add(n.slot.source);
|
|
5697
|
+
ctx.indent--;
|
|
5698
|
+
ctx.write(true, `})`);
|
|
5506
5699
|
}
|
|
5507
5700
|
}
|
|
5508
5701
|
|
|
5509
5702
|
ctx.indent--;
|
|
5510
|
-
if(n.props.length || n.events.length || n.slot) ctx.write(true, ')
|
|
5511
|
-
else ctx.write(')
|
|
5703
|
+
if(n.props.length || n.events.length || n.slot) ctx.write(true, ')');
|
|
5704
|
+
else ctx.write(')');
|
|
5512
5705
|
|
|
5513
5706
|
});
|
|
5514
5707
|
}
|
|
5515
5708
|
|
|
5516
|
-
function attachFragmentSlot(label) {
|
|
5517
|
-
|
|
5709
|
+
function attachFragmentSlot(label, requireCD) {
|
|
5710
|
+
requireCD.$value(true);
|
|
5518
5711
|
|
|
5519
5712
|
return xNode('fragment-slot', {
|
|
5520
5713
|
el: label.bindName()
|
|
5521
5714
|
}, (ctx, n) => {
|
|
5522
|
-
ctx.
|
|
5715
|
+
ctx.write(true, `$runtime.attachBlock($cd, ${n.el}, $$fragmentSlot?.())`);
|
|
5523
5716
|
});
|
|
5524
5717
|
}
|
|
5525
5718
|
|
|
5526
|
-
function attchExportedFragment(node, label, componentName) {
|
|
5527
|
-
|
|
5719
|
+
function attchExportedFragment(node, label, componentName, requireCD) {
|
|
5720
|
+
requireCD.$value(true);
|
|
5528
5721
|
|
|
5529
5722
|
let data = {
|
|
5530
5723
|
name: node.elArg,
|
|
@@ -5534,48 +5727,44 @@
|
|
|
5534
5727
|
|
|
5535
5728
|
let body = trimEmptyNodes(node.body || []);
|
|
5536
5729
|
if(body.length) {
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
data
|
|
5540
|
-
data.template
|
|
5541
|
-
raw: true,
|
|
5542
|
-
body: block.tpl
|
|
5543
|
-
});
|
|
5730
|
+
data.slot = this.buildBlock({body}, {inline: true});
|
|
5731
|
+
data.$compile = [data.slot.source];
|
|
5732
|
+
data.$deps = [data.slot.requireCD];
|
|
5733
|
+
// assert(!data.slot.template.svg, 'SVG is not supported for exported fragment');
|
|
5544
5734
|
}
|
|
5545
5735
|
|
|
5546
5736
|
let pa = parseAttibutes.call(this, node.attributes);
|
|
5547
|
-
data
|
|
5548
|
-
data.events = pa.events;
|
|
5549
|
-
data.forwardAllEvents = pa.forwardAllEvents;
|
|
5550
|
-
data.staticProps = pa.staticProps;
|
|
5737
|
+
data = {...pa, ...data};
|
|
5551
5738
|
|
|
5552
5739
|
return xNode('attach-exported-fragment', data, (ctx, n) => {
|
|
5553
|
-
ctx.write(true, `$runtime.
|
|
5554
|
-
let missed = '';
|
|
5740
|
+
ctx.write(true, `$runtime.attachBlock($cd, ${n.label}, $runtime.callExportedFragment($instance_${n.componentName}, '${n.name}'`);
|
|
5555
5741
|
ctx.indent++;
|
|
5742
|
+
let missed = '';
|
|
5556
5743
|
|
|
5557
|
-
if(n.
|
|
5558
|
-
ctx.write('
|
|
5559
|
-
|
|
5560
|
-
const writeProps = () => ctx.write('{' + n.props.map(p => p.name == p.value ? p.name : `${p.name}: ${p.value}`).join(', ') + '}');
|
|
5744
|
+
if(n.slot) {
|
|
5745
|
+
ctx.write(',', true);
|
|
5561
5746
|
|
|
5562
|
-
if(n.
|
|
5563
|
-
|
|
5564
|
-
ctx.
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
ctx.write(
|
|
5568
|
-
|
|
5569
|
-
ctx.write(
|
|
5747
|
+
if(ctx.isEmpty(n.slot.source)) {
|
|
5748
|
+
ctx.write(`$runtime.makeStaticBlock(`);
|
|
5749
|
+
ctx.add(n.slot.template);
|
|
5750
|
+
ctx.write(`)`);
|
|
5751
|
+
} else {
|
|
5752
|
+
ctx.write(`$runtime.makeBlockBound($cd, `);
|
|
5753
|
+
ctx.add(n.slot.template);
|
|
5754
|
+
ctx.write(`, ($cd, $parentElement) => {`, true);
|
|
5755
|
+
ctx.indent++;
|
|
5756
|
+
ctx.add(n.slot.source);
|
|
5757
|
+
ctx.indent--;
|
|
5758
|
+
ctx.write(true, `})`);
|
|
5570
5759
|
}
|
|
5571
|
-
} else missed = ',
|
|
5760
|
+
} else missed = ', null';
|
|
5572
5761
|
|
|
5573
5762
|
if(n.forwardAllEvents) {
|
|
5574
5763
|
if(n.events.length) this.warning(`Fragment: mixing binding and forwarding is not supported: '${node.openTag}'`);
|
|
5575
5764
|
ctx.write(missed, ', $events');
|
|
5576
5765
|
missed = '';
|
|
5577
5766
|
} else if(n.events.length) {
|
|
5578
|
-
ctx.write(missed, '
|
|
5767
|
+
ctx.write(missed, ',', true, '{');
|
|
5579
5768
|
missed = '';
|
|
5580
5769
|
|
|
5581
5770
|
n.events.forEach((e, i) => {
|
|
@@ -5590,27 +5779,32 @@
|
|
|
5590
5779
|
}
|
|
5591
5780
|
});
|
|
5592
5781
|
ctx.write('}');
|
|
5593
|
-
} else missed += ',
|
|
5782
|
+
} else missed += ', null';
|
|
5594
5783
|
|
|
5595
|
-
if(n.
|
|
5596
|
-
if(missed) ctx.write(missed
|
|
5597
|
-
|
|
5598
|
-
ctx.
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
ctx.
|
|
5605
|
-
|
|
5606
|
-
ctx.write(
|
|
5784
|
+
if(n.props.length) {
|
|
5785
|
+
if(missed) ctx.write(missed);
|
|
5786
|
+
missed = '';
|
|
5787
|
+
ctx.write(',', true);
|
|
5788
|
+
|
|
5789
|
+
const writeProps = () => ctx.write('{' + n.props.map(p => p.name == p.value ? p.name : `${p.name}: ${p.value}`).join(', ') + '}');
|
|
5790
|
+
|
|
5791
|
+
if(n.staticProps) writeProps();
|
|
5792
|
+
else {
|
|
5793
|
+
ctx.write(`() => (`);
|
|
5794
|
+
writeProps();
|
|
5795
|
+
ctx.write(`), `);
|
|
5796
|
+
if(this.config.immutable) ctx.write(`$runtime.keyComparator`);
|
|
5797
|
+
else ctx.write(`$runtime.$$compareDeep`);
|
|
5607
5798
|
}
|
|
5608
|
-
|
|
5799
|
+
|
|
5800
|
+
}
|
|
5801
|
+
|
|
5609
5802
|
ctx.indent--;
|
|
5803
|
+
ctx.write('));');
|
|
5610
5804
|
});
|
|
5611
5805
|
}
|
|
5612
5806
|
|
|
5613
|
-
function attachHead(n) {
|
|
5807
|
+
function attachHead(n, requireCD) {
|
|
5614
5808
|
if(n.elArg == 'window' || n.elArg == 'body') {
|
|
5615
5809
|
let name = 'el' + (this.uniqIndex++);
|
|
5616
5810
|
let block = this.buildBlock({body: [n]}, {malinaElement: true, inline: true, oneElement: name, bindAttributes: true});
|
|
@@ -5636,7 +5830,10 @@
|
|
|
5636
5830
|
return true;
|
|
5637
5831
|
});
|
|
5638
5832
|
|
|
5639
|
-
let d = {
|
|
5833
|
+
let d = {
|
|
5834
|
+
$deps: [this.glob.apply],
|
|
5835
|
+
requireCD
|
|
5836
|
+
};
|
|
5640
5837
|
if(title?.body?.[0]) {
|
|
5641
5838
|
assert(title.body[0].type == 'text');
|
|
5642
5839
|
let r = this.parseText(title.body[0].value);
|
|
@@ -5647,27 +5844,39 @@
|
|
|
5647
5844
|
}
|
|
5648
5845
|
}
|
|
5649
5846
|
if(body.length) {
|
|
5650
|
-
let
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5847
|
+
let bb = this.buildBlock({body}, {
|
|
5848
|
+
inline: true,
|
|
5849
|
+
template: {
|
|
5850
|
+
name: '$parentElement',
|
|
5851
|
+
cloneNode: true,
|
|
5852
|
+
requireFragment: true
|
|
5853
|
+
}
|
|
5655
5854
|
});
|
|
5855
|
+
d.source = bb.source;
|
|
5856
|
+
d.template = bb.template;
|
|
5857
|
+
d.blockCD = bb.requireCD;
|
|
5858
|
+
|
|
5859
|
+
d.$compile = [d.source];
|
|
5860
|
+
d.$deps.push(d.blockCD);
|
|
5861
|
+
|
|
5656
5862
|
this.require('$onDestroy');
|
|
5657
5863
|
}
|
|
5658
5864
|
|
|
5659
|
-
|
|
5865
|
+
const result = xNode('malina:head', d, (ctx, n) => {
|
|
5866
|
+
if(n.blockCD.value) n.requireCD.$value(true);
|
|
5660
5867
|
if(n.title != null) ctx.writeLine(`document.title = ${n.title};`);
|
|
5661
5868
|
if(n.dynTitle) {
|
|
5662
|
-
if(
|
|
5663
|
-
|
|
5869
|
+
if(this.glob.apply.value) {
|
|
5870
|
+
n.requireCD.$value(true);
|
|
5871
|
+
ctx.writeLine(`$watchReadOnly($cd, () => (${n.dynTitle}), (value) => {document.title = value;});`);
|
|
5872
|
+
} else ctx.writeLine(`document.title = ${n.dynTitle};`);
|
|
5664
5873
|
}
|
|
5665
5874
|
|
|
5666
5875
|
if(n.template) {
|
|
5667
5876
|
ctx.writeLine(`{`);
|
|
5668
5877
|
ctx.indent++;
|
|
5669
|
-
ctx.
|
|
5670
|
-
ctx.
|
|
5878
|
+
ctx.add(n.template);
|
|
5879
|
+
ctx.add(n.source);
|
|
5671
5880
|
ctx.writeLine(`let a=$parentElement.firstChild, b=$parentElement.lastChild;`);
|
|
5672
5881
|
ctx.writeLine(`$onDestroy(() => {$runtime.$$removeElements(a, b)});`);
|
|
5673
5882
|
ctx.writeLine(`document.head.appendChild($parentElement);`);
|
|
@@ -5675,6 +5884,8 @@
|
|
|
5675
5884
|
ctx.writeLine(`}`);
|
|
5676
5885
|
}
|
|
5677
5886
|
});
|
|
5887
|
+
requireCD.$depends(result);
|
|
5888
|
+
return result;
|
|
5678
5889
|
} else throw 'Wrong tag';
|
|
5679
5890
|
}
|
|
5680
5891
|
|
|
@@ -5728,37 +5939,47 @@
|
|
|
5728
5939
|
return {name, value, rawValue, static: statical};
|
|
5729
5940
|
}
|
|
5730
5941
|
|
|
5731
|
-
function attachPortal(node) {
|
|
5942
|
+
function attachPortal(node, requireCD) {
|
|
5732
5943
|
let body = trimEmptyNodes(node.body || []);
|
|
5733
5944
|
if(!body.length) return;
|
|
5734
|
-
|
|
5945
|
+
|
|
5946
|
+
let bb = this.buildBlock({body}, {
|
|
5947
|
+
inline: true,
|
|
5948
|
+
template: {
|
|
5949
|
+
name: '$parentElement',
|
|
5950
|
+
cloneNode: true,
|
|
5951
|
+
requireFragment: true
|
|
5952
|
+
}
|
|
5953
|
+
});
|
|
5954
|
+
|
|
5955
|
+
this.require('$component');
|
|
5735
5956
|
|
|
5736
5957
|
let mount = node.attributes.find(a => a.name == 'mount')?.value;
|
|
5737
5958
|
if(mount) mount = unwrapExp(mount);
|
|
5738
5959
|
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5960
|
+
const result = xNode('portal', {
|
|
5961
|
+
$compile: [bb.source],
|
|
5962
|
+
$deps: [bb.requireCD],
|
|
5742
5963
|
mount,
|
|
5743
|
-
source:
|
|
5744
|
-
template:
|
|
5745
|
-
|
|
5746
|
-
body: block.tpl,
|
|
5747
|
-
svg: block.svg
|
|
5748
|
-
})
|
|
5964
|
+
source: bb.source,
|
|
5965
|
+
template: bb.template,
|
|
5966
|
+
requireCD
|
|
5749
5967
|
}, (ctx, n) => {
|
|
5968
|
+
if(n.$deps[0].value) n.requireCD.$value(true);
|
|
5750
5969
|
let label = n.mount || 'document.body';
|
|
5751
5970
|
ctx.writeLine('{');
|
|
5752
5971
|
ctx.indent++;
|
|
5753
|
-
ctx.
|
|
5754
|
-
ctx.
|
|
5972
|
+
ctx.add(n.template);
|
|
5973
|
+
ctx.add(n.source);
|
|
5755
5974
|
ctx.writeLine(`let $$first = $parentElement[$runtime.firstChild];`);
|
|
5756
5975
|
ctx.writeLine(`let $$last = $parentElement.lastChild;`);
|
|
5757
|
-
ctx.writeLine(`$runtime.cd_onDestroy($cd, () => $runtime.$$removeElements($$first, $$last));`);
|
|
5976
|
+
ctx.writeLine(`$runtime.cd_onDestroy(${n.$deps[0].value ? '$cd' : '$component'}, () => $runtime.$$removeElements($$first, $$last));`);
|
|
5758
5977
|
ctx.writeLine(`$tick(() => ${label}.appendChild($parentElement));`);
|
|
5759
5978
|
ctx.indent--;
|
|
5760
5979
|
ctx.writeLine('}');
|
|
5761
5980
|
});
|
|
5981
|
+
requireCD.$depends(result);
|
|
5982
|
+
return result;
|
|
5762
5983
|
}
|
|
5763
5984
|
|
|
5764
5985
|
function makeEventProp(prop, requireElement) {
|
|
@@ -5781,6 +6002,7 @@
|
|
|
5781
6002
|
let modList = [], _mod = '';
|
|
5782
6003
|
let handler = '', exp, func;
|
|
5783
6004
|
let step = 0;
|
|
6005
|
+
let rootModifier = false;
|
|
5784
6006
|
for(let a of name) {
|
|
5785
6007
|
if(a == '|') {
|
|
5786
6008
|
assert$1(step <= 1);
|
|
@@ -5808,14 +6030,18 @@
|
|
|
5808
6030
|
|
|
5809
6031
|
this.detectDependency(exp || handler);
|
|
5810
6032
|
|
|
6033
|
+
let globalFunction = false;
|
|
5811
6034
|
if(exp) {
|
|
5812
6035
|
let type = detectExpressionType(exp);
|
|
5813
6036
|
if(type == 'identifier') {
|
|
6037
|
+
globalFunction = !!this.script.rootFunctions[exp];
|
|
5814
6038
|
handler = exp;
|
|
5815
6039
|
exp = null;
|
|
5816
6040
|
} else if(type == 'function') {
|
|
5817
6041
|
func = exp;
|
|
5818
6042
|
exp = null;
|
|
6043
|
+
} else if(type?.type == 'function-call') {
|
|
6044
|
+
globalFunction = !!this.script.rootFunctions[type.name];
|
|
5819
6045
|
} }
|
|
5820
6046
|
|
|
5821
6047
|
// modifiers
|
|
@@ -5836,6 +6062,10 @@
|
|
|
5836
6062
|
let mods = [];
|
|
5837
6063
|
let preventInserted;
|
|
5838
6064
|
modList.forEach(opt => {
|
|
6065
|
+
if(opt == 'root') {
|
|
6066
|
+
rootModifier = true;
|
|
6067
|
+
return;
|
|
6068
|
+
}
|
|
5839
6069
|
if(opt == 'preventDefault' || opt == 'prevent') {
|
|
5840
6070
|
if(preventInserted) return;
|
|
5841
6071
|
mods.push('$event.preventDefault();');
|
|
@@ -5874,7 +6104,8 @@
|
|
|
5874
6104
|
exp,
|
|
5875
6105
|
handlerName: handler,
|
|
5876
6106
|
func,
|
|
5877
|
-
mods
|
|
6107
|
+
mods,
|
|
6108
|
+
globalFunction
|
|
5878
6109
|
}, (ctx, n) => {
|
|
5879
6110
|
if(n.handlerName && !ctx.inuse.apply && !n.mods) return ctx.write(n.handlerName);
|
|
5880
6111
|
ctx.write(`($event) => { `);
|
|
@@ -5884,14 +6115,14 @@
|
|
|
5884
6115
|
if(last(n.exp) != ';') n.exp += ';';
|
|
5885
6116
|
ctx.write(`${n.exp}`);
|
|
5886
6117
|
} else if(n.func) ctx.write(`(${n.func})($event);`);
|
|
5887
|
-
if(ctx.inuse.apply) ctx.write(` $$apply();`);
|
|
6118
|
+
if(ctx.inuse.apply && !n.globalFunction) ctx.write(` $$apply();`);
|
|
5888
6119
|
ctx.write(`}`);
|
|
5889
6120
|
});
|
|
5890
6121
|
|
|
5891
|
-
return {event, fn};
|
|
6122
|
+
return {event, fn, rootModifier};
|
|
5892
6123
|
}
|
|
5893
6124
|
|
|
5894
|
-
const version = '0.
|
|
6125
|
+
const version = '0.7.0-alpha';
|
|
5895
6126
|
|
|
5896
6127
|
|
|
5897
6128
|
async function compile(source, config = {}) {
|
|
@@ -5924,6 +6155,7 @@
|
|
|
5924
6155
|
makeEachBlock,
|
|
5925
6156
|
makeifBlock,
|
|
5926
6157
|
makeComponent,
|
|
6158
|
+
makeComponentDyn,
|
|
5927
6159
|
makeHtmlBlock,
|
|
5928
6160
|
parseText,
|
|
5929
6161
|
makeAwaitBlock,
|
|
@@ -5939,17 +6171,27 @@
|
|
|
5939
6171
|
checkRootName: checkRootName,
|
|
5940
6172
|
|
|
5941
6173
|
inuse: {},
|
|
5942
|
-
|
|
5943
|
-
|
|
6174
|
+
glob: {
|
|
6175
|
+
apply: xNode('apply', false),
|
|
6176
|
+
component: xNode('$component', false),
|
|
6177
|
+
componentFn: xNode('componentFn', false),
|
|
6178
|
+
rootCD: xNode('root-cd', false)
|
|
6179
|
+
},
|
|
6180
|
+
require: function(...args) {
|
|
6181
|
+
for(let name of args) {
|
|
5944
6182
|
let deps = true;
|
|
5945
6183
|
if(name == '$props:no-deps') {name = '$props'; deps = false;} if(name == 'apply' && ctx.script.readOnly) name = 'blankApply';
|
|
5946
6184
|
if(ctx.inuse[name] == null) ctx.inuse[name] = 0;
|
|
5947
6185
|
ctx.inuse[name]++;
|
|
5948
6186
|
if(!deps) continue;
|
|
6187
|
+
if(name == 'apply') ctx.glob.apply.$value(true);
|
|
6188
|
+
if(name == '$component') ctx.glob.component.$value(true);
|
|
5949
6189
|
if(name == '$attributes') ctx.require('$props');
|
|
5950
6190
|
if(name == '$props' && !ctx.script.readOnly) ctx.require('apply', '$cd');
|
|
5951
|
-
if(name == '
|
|
5952
|
-
|
|
6191
|
+
if(name == '$cd') {
|
|
6192
|
+
ctx.glob.rootCD.$value(true);
|
|
6193
|
+
ctx.require('$component');
|
|
6194
|
+
}
|
|
5953
6195
|
if(name == '$onDestroy') ctx.require('$component');
|
|
5954
6196
|
if(name == '$onMount') ctx.require('$component');
|
|
5955
6197
|
}
|
|
@@ -5982,9 +6224,7 @@
|
|
|
5982
6224
|
},
|
|
5983
6225
|
|
|
5984
6226
|
xBuild: node => {
|
|
5985
|
-
|
|
5986
|
-
w.build(node);
|
|
5987
|
-
return w.toString();
|
|
6227
|
+
return xBuild(ctx, node);
|
|
5988
6228
|
}
|
|
5989
6229
|
};
|
|
5990
6230
|
|
|
@@ -6036,48 +6276,9 @@
|
|
|
6036
6276
|
result.push(`import { $$htmlToFragment } from 'malinajs/runtime.js';`);
|
|
6037
6277
|
}
|
|
6038
6278
|
result.push(ctx.module.top);
|
|
6279
|
+
result.push(makeComponentFn.call(ctx));
|
|
6039
6280
|
|
|
6040
|
-
result
|
|
6041
|
-
name: config.name,
|
|
6042
|
-
body: [ctx.module.head, ctx.module.code, ctx.module.body]
|
|
6043
|
-
}, (ctx, n) => {
|
|
6044
|
-
ctx.writeIndent();
|
|
6045
|
-
if(config.exportDefault) ctx.write('export default ');
|
|
6046
|
-
else ctx.write(`const ${n.name} = `);
|
|
6047
|
-
|
|
6048
|
-
let component = xNode('function', {
|
|
6049
|
-
args: ['$option'],
|
|
6050
|
-
inline: true,
|
|
6051
|
-
arrow: true,
|
|
6052
|
-
body: n.body
|
|
6053
|
-
});
|
|
6054
|
-
|
|
6055
|
-
if(ctx.inuse.apply) {
|
|
6056
|
-
ctx.write('$runtime.makeComponent(');
|
|
6057
|
-
component.args.push('$$apply');
|
|
6058
|
-
ctx.build(component);
|
|
6059
|
-
ctx.write(', $runtime.$base);\n');
|
|
6060
|
-
} else if(ctx.inuse.$cd || ctx.inuse.$component || ctx.inuse.$context || ctx.inuse.blankApply) {
|
|
6061
|
-
if(ctx.inuse.blankApply) {
|
|
6062
|
-
component.body[0].body.unshift(xNode('block', (ctx) => {
|
|
6063
|
-
ctx.writeLine('let $$apply = $runtime.noop;');
|
|
6064
|
-
}));
|
|
6065
|
-
}
|
|
6066
|
-
|
|
6067
|
-
ctx.write('$runtime.makeComponent(');
|
|
6068
|
-
ctx.build(component);
|
|
6069
|
-
ctx.write(', $runtime.$readOnlyBase);\n');
|
|
6070
|
-
} else {
|
|
6071
|
-
ctx.write('($element, $option={}) => {\n');
|
|
6072
|
-
ctx.goIndent(() => {
|
|
6073
|
-
ctx.inuse.$insertElementByOption = true;
|
|
6074
|
-
ctx.build(xNode('block', {body: n.body}));
|
|
6075
|
-
});
|
|
6076
|
-
ctx.write('}');
|
|
6077
|
-
}
|
|
6078
|
-
}));
|
|
6079
|
-
|
|
6080
|
-
ctx.result = ctx.xBuild(result);
|
|
6281
|
+
ctx.result = xBuild(ctx, result);
|
|
6081
6282
|
|
|
6082
6283
|
await hook(ctx, 'build');
|
|
6083
6284
|
return ctx;
|
|
@@ -6126,8 +6327,7 @@
|
|
|
6126
6327
|
|
|
6127
6328
|
if(localConfig) {
|
|
6128
6329
|
const confFn = require(localConfig);
|
|
6129
|
-
|
|
6130
|
-
else result = confFn;
|
|
6330
|
+
result = confFn(result, filename);
|
|
6131
6331
|
}
|
|
6132
6332
|
if(!result.path) result.path = filename;
|
|
6133
6333
|
if(!result.name) result.name = filename.match(/([^/\\]+)\.\w+$/)[1];
|
|
@@ -6135,6 +6335,60 @@
|
|
|
6135
6335
|
return result;
|
|
6136
6336
|
}
|
|
6137
6337
|
|
|
6338
|
+
|
|
6339
|
+
function makeComponentFn() {
|
|
6340
|
+
let componentFn = xNode('componentFn', {
|
|
6341
|
+
$deps: [this.glob.apply, this.glob.rootCD],
|
|
6342
|
+
body: [this.module.head, this.module.code, this.module.body],
|
|
6343
|
+
}, (ctx, n) => {
|
|
6344
|
+
let component = xNode('function', {
|
|
6345
|
+
args: ['$option'],
|
|
6346
|
+
inline: true,
|
|
6347
|
+
arrow: true,
|
|
6348
|
+
body: n.body
|
|
6349
|
+
});
|
|
6350
|
+
|
|
6351
|
+
if(this.glob.apply.value) {
|
|
6352
|
+
ctx.add(this.glob.componentFn);
|
|
6353
|
+
ctx.write('$runtime.makeComponent(');
|
|
6354
|
+
component.args.push('$$apply');
|
|
6355
|
+
ctx.add(component);
|
|
6356
|
+
ctx.write(', $runtime.$base);', true);
|
|
6357
|
+
} else if(this.glob.rootCD.value || ctx.inuse.$cd || ctx.inuse.$component || ctx.inuse.$context || ctx.inuse.blankApply) {
|
|
6358
|
+
ctx.add(this.glob.componentFn);
|
|
6359
|
+
if(ctx.inuse.blankApply) {
|
|
6360
|
+
component.body[0].body.unshift(xNode('block', (ctx) => {
|
|
6361
|
+
ctx.writeLine('let $$apply = $runtime.noop;');
|
|
6362
|
+
}));
|
|
6363
|
+
}
|
|
6364
|
+
|
|
6365
|
+
ctx.write('$runtime.makeComponent(');
|
|
6366
|
+
ctx.add(component);
|
|
6367
|
+
ctx.write(');', true);
|
|
6368
|
+
} else {
|
|
6369
|
+
this.glob.componentFn.$value('thin');
|
|
6370
|
+
ctx.add(this.glob.componentFn);
|
|
6371
|
+
ctx.write('($option={}) => {', true);
|
|
6372
|
+
ctx.goIndent(() => {
|
|
6373
|
+
ctx.add(xNode('block', {body: n.body}));
|
|
6374
|
+
});
|
|
6375
|
+
ctx.write(true, '}');
|
|
6376
|
+
}
|
|
6377
|
+
});
|
|
6378
|
+
|
|
6379
|
+
return xNode('block', {
|
|
6380
|
+
$compile: [this.module.head, this.module.code, this.module.body],
|
|
6381
|
+
name: this.config.name,
|
|
6382
|
+
componentFn
|
|
6383
|
+
}, (ctx, n) => {
|
|
6384
|
+
ctx.writeIndent();
|
|
6385
|
+
if(this.config.exportDefault) ctx.write('export default ');
|
|
6386
|
+
else ctx.write(`const ${n.name} = `);
|
|
6387
|
+
ctx.add(this.glob.apply);
|
|
6388
|
+
ctx.add(n.componentFn);
|
|
6389
|
+
});
|
|
6390
|
+
}
|
|
6391
|
+
|
|
6138
6392
|
exports.compile = compile;
|
|
6139
6393
|
exports.version = version;
|
|
6140
6394
|
|