malinajs 0.6.50 → 0.7.1-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/malina-esbuild.js +10 -4
- package/malina.js +1305 -1050
- package/package.json +1 -2
- package/readme.md +1 -1
- package/runtime.js +489 -316
- package/compile.js +0 -6164
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,93 +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
4502
|
return false;
|
|
4302
4503
|
} else if(name == 'this') {
|
|
4303
|
-
dynamicComponent = unwrapExp(value);
|
|
4304
4504
|
return false;
|
|
4305
4505
|
}
|
|
4306
4506
|
return true;
|
|
@@ -4350,35 +4550,21 @@
|
|
|
4350
4550
|
if(name.startsWith('@@')) {
|
|
4351
4551
|
let event = name.substring(2);
|
|
4352
4552
|
assert(!value);
|
|
4353
|
-
passOption.events = true;
|
|
4354
|
-
boundEvent(event);
|
|
4355
4553
|
this.require('$events');
|
|
4356
|
-
|
|
4554
|
+
passEvent(event, xNode('forwardEvent', {
|
|
4357
4555
|
event
|
|
4358
|
-
}, (ctx,
|
|
4359
|
-
|
|
4360
|
-
else ctx.writeLine(`events.${data.event} = $events.${data.event};`);
|
|
4556
|
+
}, (ctx, n) => {
|
|
4557
|
+
ctx.write(`$events.${n.event}`);
|
|
4361
4558
|
}));
|
|
4362
4559
|
return;
|
|
4363
4560
|
}
|
|
4364
4561
|
|
|
4365
4562
|
let {event, fn} = this.makeEventProp(prop);
|
|
4366
4563
|
|
|
4367
|
-
|
|
4368
|
-
boundEvent(event);
|
|
4369
|
-
head.push(xNode('passEvent', {
|
|
4370
|
-
event,
|
|
4564
|
+
passEvent(event, xNode('passEvent', {
|
|
4371
4565
|
fn
|
|
4372
4566
|
}, (ctx, n) => {
|
|
4373
|
-
|
|
4374
|
-
ctx.write(true, `$runtime.$$addEventForComponent(events, '${n.event}', `);
|
|
4375
|
-
ctx.build(n.fn);
|
|
4376
|
-
ctx.write(`);\n`);
|
|
4377
|
-
} else {
|
|
4378
|
-
ctx.write(true, `events.${n.event} = `);
|
|
4379
|
-
ctx.build(n.fn);
|
|
4380
|
-
ctx.write(`;\n`);
|
|
4381
|
-
}
|
|
4567
|
+
ctx.add(n.fn);
|
|
4382
4568
|
}));
|
|
4383
4569
|
return;
|
|
4384
4570
|
} else if(this.config.passClass && (name == 'class' || name.startsWith('class:'))) {
|
|
@@ -4391,6 +4577,7 @@
|
|
|
4391
4577
|
assert(metaClass);
|
|
4392
4578
|
}
|
|
4393
4579
|
assert(value);
|
|
4580
|
+
this.css.passingClass = true;
|
|
4394
4581
|
|
|
4395
4582
|
const parsed = this.parseText(prop.value);
|
|
4396
4583
|
this.detectDependency(parsed);
|
|
@@ -4408,41 +4595,87 @@
|
|
|
4408
4595
|
});
|
|
4409
4596
|
|
|
4410
4597
|
|
|
4411
|
-
if(
|
|
4412
|
-
if(passOption.slots) options.push('slots');
|
|
4413
|
-
if(passOption.anchor) options.push('anchor');
|
|
4598
|
+
if(Object.keys(events).length == 0) events = null;
|
|
4414
4599
|
|
|
4415
4600
|
let result = xNode('component', {
|
|
4416
|
-
el: element.bindName(),
|
|
4417
4601
|
componentName,
|
|
4418
|
-
head,
|
|
4419
|
-
options,
|
|
4420
|
-
$cd: '$cd',
|
|
4421
4602
|
staticProps,
|
|
4422
4603
|
props: propsFn,
|
|
4423
4604
|
propsSetter,
|
|
4424
4605
|
reference,
|
|
4425
|
-
$class
|
|
4606
|
+
$class,
|
|
4607
|
+
forwardAllEvents,
|
|
4608
|
+
events,
|
|
4609
|
+
slots: slotBlocks.length ? slotBlocks : null,
|
|
4610
|
+
anchors: anchorBlocks.length ? anchorBlocks : null
|
|
4426
4611
|
}, (ctx, n) => {
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
if(head) {
|
|
4431
|
-
ctx.addBlock(head);
|
|
4432
|
-
n.requireScope = true;
|
|
4433
|
-
}
|
|
4612
|
+
if(n.reference) throw 'not implemented'; // FIXME
|
|
4613
|
+
let comma = false;
|
|
4614
|
+
ctx.write(`$runtime.callComponent($context, ${n.componentName}, {`);
|
|
4434
4615
|
|
|
4435
4616
|
if(n.props.length && n.staticProps) {
|
|
4436
|
-
|
|
4617
|
+
ctx.write(`props: {${n.props.join(', ')}}`);
|
|
4618
|
+
comma = true;
|
|
4437
4619
|
n.props = [];
|
|
4438
4620
|
}
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
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('}');
|
|
4443
4677
|
|
|
4444
4678
|
let other = '';
|
|
4445
|
-
ctx.indent++;
|
|
4446
4679
|
if(n.props.length) ctx.write(`,\n`, true, `() => ({${n.props.join(', ')}})`);
|
|
4447
4680
|
else other = ', null';
|
|
4448
4681
|
|
|
@@ -4468,77 +4701,61 @@
|
|
|
4468
4701
|
} else other += ', null';
|
|
4469
4702
|
|
|
4470
4703
|
ctx.indent--;
|
|
4471
|
-
ctx.write(`)
|
|
4704
|
+
ctx.write(true, `)`);
|
|
4472
4705
|
});
|
|
4473
4706
|
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
let r = ctx.subBuild(n.component);
|
|
4479
|
-
|
|
4480
|
-
if(n.component.requireScope) {
|
|
4481
|
-
ctx.writeLine('{');
|
|
4482
|
-
ctx.goIndent(() => {
|
|
4483
|
-
ctx.addBlock(r);
|
|
4484
|
-
});
|
|
4485
|
-
ctx.writeLine('}');
|
|
4486
|
-
} else ctx.addBlock(r);
|
|
4487
|
-
})};
|
|
4488
|
-
} else {
|
|
4489
|
-
this.detectDependency(dynamicComponent);
|
|
4707
|
+
return {bind: result};
|
|
4708
|
+
}
|
|
4709
|
+
function makeComponentDyn(node, requireCD, element) {
|
|
4710
|
+
let dynamicComponent;
|
|
4490
4711
|
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
if(ctx.inuse.apply) {
|
|
4501
|
-
ctx.writeLine(`let childCD, finalLabel = $runtime.getFinalLabel(${n.el});`);
|
|
4502
|
-
ctx.writeLine(`$watch($cd, () => (${n.exp}), ($ComponentConstructor) => {`);
|
|
4503
|
-
ctx.goIndent(() => {
|
|
4504
|
-
ctx.writeLine(`if(childCD) {`);
|
|
4505
|
-
ctx.goIndent(() => {
|
|
4506
|
-
ctx.writeLine(`childCD.destroy();`);
|
|
4507
|
-
ctx.writeLine(`$runtime.removeElementsBetween(${n.el}, finalLabel);`);
|
|
4508
|
-
});
|
|
4509
|
-
ctx.writeLine(`}`);
|
|
4510
|
-
ctx.writeLine(`childCD = null;`);
|
|
4511
|
-
ctx.writeLine(`if($ComponentConstructor) {`);
|
|
4512
|
-
ctx.goIndent(() => {
|
|
4513
|
-
ctx.writeLine(`childCD = $cd.new();`);
|
|
4514
|
-
ctx.build(n.component);
|
|
4515
|
-
});
|
|
4516
|
-
ctx.writeLine(`}`);
|
|
4517
|
-
});
|
|
4518
|
-
ctx.writeLine(`});`);
|
|
4519
|
-
} else {
|
|
4520
|
-
ctx.writeLine(`let $ComponentConstructor = ${n.exp};`);
|
|
4521
|
-
ctx.writeLine(`if($ComponentConstructor) {`);
|
|
4522
|
-
ctx.goIndent(() => {
|
|
4523
|
-
ctx.writeLine(`let childCD = $cd;`);
|
|
4524
|
-
ctx.build(n.component);
|
|
4525
|
-
});
|
|
4526
|
-
ctx.writeLine(`}`);
|
|
4527
|
-
}
|
|
4528
|
-
});
|
|
4529
|
-
ctx.writeLine('}');
|
|
4530
|
-
})};
|
|
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
|
+
});
|
|
4531
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
|
+
});
|
|
4532
4739
|
}
|
|
4533
4740
|
|
|
4534
|
-
function bindProp(prop, node, element) {
|
|
4741
|
+
function bindProp(prop, node, element, requireCD) {
|
|
4535
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
|
+
|
|
4536
4754
|
if(prop.name[0] == '@' || prop.name.startsWith('on:')) name = 'event';
|
|
4537
|
-
if(
|
|
4755
|
+
else if(prop.name[0] == ':') {
|
|
4538
4756
|
name = 'bind';
|
|
4539
4757
|
arg = prop.name.substring(1);
|
|
4540
|
-
}
|
|
4541
|
-
if(!name && prop.name[0] == '*') {
|
|
4758
|
+
} else if(prop.name[0] == '*') {
|
|
4542
4759
|
let rx = prop.name.match(/^\*\{.*\}$/);
|
|
4543
4760
|
if(rx) {
|
|
4544
4761
|
assert(prop.value == null, 'wrong binding: ' + prop.content);
|
|
@@ -4548,17 +4765,7 @@
|
|
|
4548
4765
|
name = 'use';
|
|
4549
4766
|
arg = prop.name.substring(1);
|
|
4550
4767
|
}
|
|
4551
|
-
}
|
|
4552
|
-
if(prop.content.startsWith('{*')) {
|
|
4553
|
-
const pe = this.parseText(prop.content);
|
|
4554
|
-
assert(pe.parts[0].type == 'js');
|
|
4555
|
-
let exp = pe.parts[0].value;
|
|
4556
|
-
if(!exp.endsWith(';')) exp += ';';
|
|
4557
|
-
return {bind: xNode('block', {body: [
|
|
4558
|
-
replaceElementKeyword(exp, () => element.bindName())
|
|
4559
|
-
]})};
|
|
4560
|
-
}
|
|
4561
|
-
if(!name && prop.value == null) {
|
|
4768
|
+
} else if(prop.value == null) {
|
|
4562
4769
|
let rx = prop.name.match(/^\{(.*)\}$/);
|
|
4563
4770
|
if(rx) {
|
|
4564
4771
|
name = rx[1];
|
|
@@ -4566,7 +4773,6 @@
|
|
|
4566
4773
|
// spread operator
|
|
4567
4774
|
name = name.substring(3);
|
|
4568
4775
|
assert(detectExpressionType(name) == 'identifier');
|
|
4569
|
-
this.detectDependency(name);
|
|
4570
4776
|
return node.spreading.push(`...${name}`);
|
|
4571
4777
|
} else {
|
|
4572
4778
|
prop.value = prop.name;
|
|
@@ -4597,7 +4803,8 @@
|
|
|
4597
4803
|
} else if(name == 'event') {
|
|
4598
4804
|
if(prop.name.startsWith('@@')) {
|
|
4599
4805
|
assert(!prop.value);
|
|
4600
|
-
|
|
4806
|
+
requireCD.$value(true);
|
|
4807
|
+
this.require('$events');
|
|
4601
4808
|
if(prop.name == '@@') {
|
|
4602
4809
|
return {bind: xNode('forwardAllEvents', {
|
|
4603
4810
|
el: element.bindName()
|
|
@@ -4617,18 +4824,20 @@
|
|
|
4617
4824
|
})};
|
|
4618
4825
|
}
|
|
4619
4826
|
|
|
4620
|
-
let {event, fn} = this.makeEventProp(prop, () => element.bindName());
|
|
4621
|
-
|
|
4622
|
-
|
|
4827
|
+
let {event, fn, rootModifier} = this.makeEventProp(prop, () => element.bindName());
|
|
4828
|
+
if(rootModifier) this.require('rootEvent');
|
|
4829
|
+
else requireCD.$value(true);
|
|
4623
4830
|
|
|
4624
4831
|
return {bind: xNode('bindEvent', {
|
|
4625
4832
|
event,
|
|
4626
4833
|
fn,
|
|
4627
|
-
el: element.bindName()
|
|
4834
|
+
el: element.bindName(),
|
|
4835
|
+
rootModifier
|
|
4628
4836
|
}, (ctx, n) => {
|
|
4629
|
-
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}', `);
|
|
4630
4839
|
ctx.build(n.fn);
|
|
4631
|
-
ctx.write(`)
|
|
4840
|
+
ctx.write(`);`);
|
|
4632
4841
|
})};
|
|
4633
4842
|
} else if(name == 'bind') {
|
|
4634
4843
|
if(this.script.readOnly) {
|
|
@@ -4636,7 +4845,8 @@
|
|
|
4636
4845
|
return;
|
|
4637
4846
|
}
|
|
4638
4847
|
|
|
4639
|
-
|
|
4848
|
+
requireCD.$value(true);
|
|
4849
|
+
this.require('apply');
|
|
4640
4850
|
let exp;
|
|
4641
4851
|
arg = arg.split(/[\:\|]/);
|
|
4642
4852
|
let attr = arg.shift();
|
|
@@ -4715,7 +4925,7 @@
|
|
|
4715
4925
|
})};
|
|
4716
4926
|
} else if(name == 'use') {
|
|
4717
4927
|
if(arg) {
|
|
4718
|
-
|
|
4928
|
+
requireCD.$value(true);
|
|
4719
4929
|
assert(isSimpleName(arg), 'Wrong name: ' + arg);
|
|
4720
4930
|
this.checkRootName(arg);
|
|
4721
4931
|
let args = prop.value ? `, () => [${getExpression()}]` : '';
|
|
@@ -4779,8 +4989,7 @@
|
|
|
4779
4989
|
});
|
|
4780
4990
|
|
|
4781
4991
|
if(compound) {
|
|
4782
|
-
let
|
|
4783
|
-
if(node.classes.has(this.css.id)) defaultHash = this.css.id;
|
|
4992
|
+
let classes = Array.from(node.classes);
|
|
4784
4993
|
node.classes.clear();
|
|
4785
4994
|
if(this.config.passClass) this.require('resolveClass');
|
|
4786
4995
|
let exp = props.map(prop => {
|
|
@@ -4797,24 +5006,40 @@
|
|
|
4797
5006
|
const bind = xNode('compound-class', {
|
|
4798
5007
|
el: element.bindName(),
|
|
4799
5008
|
exp,
|
|
4800
|
-
|
|
5009
|
+
classes,
|
|
5010
|
+
requireCD
|
|
4801
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
|
+
|
|
4802
5026
|
if(ctx.inuse.resolveClass) {
|
|
4803
|
-
let base = n.defaultHash ? `,'${n.defaultHash}'` : '';
|
|
4804
5027
|
if(ctx.inuse.apply) {
|
|
4805
|
-
|
|
5028
|
+
n.requireCD.$value(true);
|
|
5029
|
+
ctx.write(true, `$runtime.bindClassExp($cd, ${n.el}, () => $$resolveClass((${n.exp})${base}))`);
|
|
4806
5030
|
} else {
|
|
4807
|
-
ctx.
|
|
5031
|
+
ctx.write(true, `$runtime.setClassToElement(${n.el}, $$resolveClass((${n.exp})${base}));`);
|
|
4808
5032
|
}
|
|
4809
5033
|
} else {
|
|
4810
|
-
let base = n.defaultHash ? ` + ' ${n.defaultHash}'` : '';
|
|
4811
5034
|
if(ctx.inuse.apply) {
|
|
4812
|
-
|
|
5035
|
+
n.requireCD.$value(true);
|
|
5036
|
+
ctx.write(true, `$runtime.bindClassExp($cd, ${n.el}, () => (${n.exp})${base})`);
|
|
4813
5037
|
} else {
|
|
4814
|
-
ctx.
|
|
5038
|
+
ctx.write(true, `$runtime.setClassToElement(${n.el}, ${n.exp}${base});`);
|
|
4815
5039
|
}
|
|
4816
5040
|
}
|
|
4817
5041
|
});
|
|
5042
|
+
requireCD.$depends(bind);
|
|
4818
5043
|
return {bind};
|
|
4819
5044
|
} else {
|
|
4820
5045
|
let bind = xNode('block');
|
|
@@ -4828,18 +5053,22 @@
|
|
|
4828
5053
|
assert(className);
|
|
4829
5054
|
let exp = prop.value ? unwrapExp(prop.value) : className;
|
|
4830
5055
|
this.detectDependency(exp);
|
|
4831
|
-
|
|
5056
|
+
|
|
5057
|
+
let n = xNode('bindClass', {
|
|
5058
|
+
$deps: [this.glob.apply],
|
|
4832
5059
|
el: element.bindName(),
|
|
4833
5060
|
className,
|
|
4834
5061
|
exp,
|
|
4835
|
-
$element: exp.includes('$element')
|
|
5062
|
+
$element: exp.includes('$element'),
|
|
5063
|
+
requireCD
|
|
4836
5064
|
}, (ctx, n) => {
|
|
4837
5065
|
if(n.$element) {
|
|
4838
5066
|
ctx.writeLine(`{`);
|
|
4839
5067
|
ctx.indent++;
|
|
4840
5068
|
ctx.writeLine(`let $element = ${n.el};`);
|
|
4841
5069
|
}
|
|
4842
|
-
if(
|
|
5070
|
+
if(this.glob.apply.value) {
|
|
5071
|
+
n.requireCD.$value(true);
|
|
4843
5072
|
ctx.writeLine(`$runtime.bindClass($cd, ${n.el}, () => !!(${n.exp}), '${n.className}');`);
|
|
4844
5073
|
} else {
|
|
4845
5074
|
ctx.writeLine(`(${n.exp}) && $runtime.addClass(${n.el}, '${n.className}');`);
|
|
@@ -4848,18 +5077,22 @@
|
|
|
4848
5077
|
ctx.indent--;
|
|
4849
5078
|
ctx.writeLine(`}`);
|
|
4850
5079
|
}
|
|
4851
|
-
})
|
|
5080
|
+
});
|
|
5081
|
+
requireCD.$depends(n);
|
|
5082
|
+
bind.push(n);
|
|
4852
5083
|
}
|
|
4853
5084
|
});
|
|
4854
5085
|
return {bind: bind.body.length ? bind : null};
|
|
4855
5086
|
}
|
|
4856
5087
|
} else if(name[0] == '^') {
|
|
4857
|
-
|
|
5088
|
+
requireCD.$value(true);
|
|
4858
5089
|
return {bindTail: xNode('bindAnchor', {
|
|
4859
5090
|
name: name.slice(1) || 'default',
|
|
4860
5091
|
el: element.bindName()
|
|
4861
5092
|
}, (ctx, n) => {
|
|
4862
|
-
ctx.
|
|
5093
|
+
ctx.write(true, `$runtime.attachAnchor($option, $cd, ${n.el}`);
|
|
5094
|
+
if(n.name == 'default') ctx.write(`);`);
|
|
5095
|
+
else ctx.write(`, '${n.name}');`);
|
|
4863
5096
|
})};
|
|
4864
5097
|
} else {
|
|
4865
5098
|
if(prop.value && prop.value.indexOf('{') >= 0) {
|
|
@@ -4878,36 +5111,41 @@
|
|
|
4878
5111
|
selected: true,
|
|
4879
5112
|
innerHTML: true,
|
|
4880
5113
|
innerText: true,
|
|
5114
|
+
placeholder: true,
|
|
4881
5115
|
src: true,
|
|
4882
5116
|
readonly: 'readOnly'
|
|
4883
5117
|
};
|
|
4884
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
|
+
|
|
4885
5146
|
return {bind: xNode('block', {
|
|
4886
5147
|
scope: hasElement,
|
|
4887
|
-
body: [
|
|
4888
|
-
xNode('bindAttribute', {
|
|
4889
|
-
name,
|
|
4890
|
-
exp,
|
|
4891
|
-
hasElement,
|
|
4892
|
-
el: element.bindName()
|
|
4893
|
-
}, (ctx, data) => {
|
|
4894
|
-
if(data.hasElement) ctx.writeLine(`let $element=${data.el};`);
|
|
4895
|
-
if(propList[name]) {
|
|
4896
|
-
let propName = propList[name] === true ? name : propList[name];
|
|
4897
|
-
if(ctx.inuse.apply) {
|
|
4898
|
-
ctx.writeLine(`$watchReadOnly($cd, () => (${data.exp}), (value) => {${data.el}.${propName} = value;});`);
|
|
4899
|
-
} else {
|
|
4900
|
-
ctx.writeLine(`${data.el}.${propName} = ${data.exp};`);
|
|
4901
|
-
}
|
|
4902
|
-
} else {
|
|
4903
|
-
if(ctx.inuse.apply) {
|
|
4904
|
-
ctx.writeLine(`$runtime.bindAttribute($cd, ${data.el}, '${data.name}', () => (${data.exp}));`);
|
|
4905
|
-
} else {
|
|
4906
|
-
ctx.writeLine(`$runtime.bindAttributeBase(${data.el}, '${data.name}', ${data.exp});`);
|
|
4907
|
-
}
|
|
4908
|
-
}
|
|
4909
|
-
})
|
|
4910
|
-
]
|
|
5148
|
+
body: [n]
|
|
4911
5149
|
})};
|
|
4912
5150
|
}
|
|
4913
5151
|
|
|
@@ -4920,104 +5158,86 @@
|
|
|
4920
5158
|
}
|
|
4921
5159
|
}
|
|
4922
5160
|
|
|
4923
|
-
function makeifBlock(data, element) {
|
|
4924
|
-
let r = data.value.match(/^#if (.*)$/
|
|
5161
|
+
function makeifBlock(data, element, requireCD) {
|
|
5162
|
+
let r = data.value.match(/^#if (.*)$/);
|
|
4925
5163
|
let exp = r[1];
|
|
4926
5164
|
assert(exp, 'Wrong binding: ' + data.value);
|
|
4927
5165
|
this.detectDependency(exp);
|
|
4928
5166
|
this.require('$cd');
|
|
4929
5167
|
|
|
4930
|
-
let mainBlock, elseBlock
|
|
5168
|
+
let mainBlock, elseBlock;
|
|
4931
5169
|
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
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
|
+
};
|
|
4935
5181
|
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
svg: elseBlock.svg
|
|
4940
|
-
});
|
|
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}));
|
|
4941
5185
|
} else {
|
|
4942
|
-
mainBlock = this.buildBlock(data, {protectLastTag: true,
|
|
5186
|
+
mainBlock = getBlock(this.buildBlock(data, {protectLastTag: true, allowSingleBlock: true}));
|
|
4943
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
|
+
}
|
|
4944
5204
|
|
|
4945
|
-
mainTpl = xNode('template', {
|
|
4946
|
-
inline: true,
|
|
4947
|
-
body: mainBlock.tpl,
|
|
4948
|
-
svg: mainBlock.svg
|
|
4949
|
-
});
|
|
4950
|
-
|
|
4951
|
-
const source = xNode('if:bind', {
|
|
4952
|
-
el: element.bindName(),
|
|
4953
|
-
exp,
|
|
4954
|
-
mainTpl,
|
|
4955
|
-
mainBlock: mainBlock.source,
|
|
4956
|
-
elseTpl,
|
|
4957
|
-
elseBlock: elseBlock && elseBlock.source
|
|
4958
|
-
},
|
|
4959
|
-
(ctx, data) => {
|
|
4960
|
-
ctx.writeLine(`$runtime.$$ifBlock($cd, ${data.el}, () => !!(${data.exp}),`);
|
|
4961
5205
|
ctx.indent++;
|
|
4962
|
-
ctx.
|
|
4963
|
-
ctx.
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
ctx.build(xNode('function', {
|
|
4968
|
-
inline: true,
|
|
4969
|
-
arrow: true,
|
|
4970
|
-
args: ['$cd', '$parentElement'],
|
|
4971
|
-
body: [data.mainBlock]
|
|
4972
|
-
}));
|
|
4973
|
-
} else ctx.write('$runtime.noop');
|
|
4974
|
-
if(data.elseTpl) {
|
|
4975
|
-
ctx.write(',\n');
|
|
4976
|
-
ctx.writeIndent();
|
|
4977
|
-
ctx.build(data.elseTpl);
|
|
4978
|
-
ctx.write(',\n');
|
|
4979
|
-
ctx.writeIndent();
|
|
4980
|
-
if(data.elseBlock) {
|
|
4981
|
-
ctx.build(xNode('function', {
|
|
4982
|
-
inline: true,
|
|
4983
|
-
arrow: true,
|
|
4984
|
-
args: ['$cd', '$parentElement'],
|
|
4985
|
-
body: [data.elseBlock]
|
|
4986
|
-
}));
|
|
4987
|
-
} 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);
|
|
4988
5211
|
}
|
|
4989
5212
|
ctx.indent--;
|
|
4990
|
-
ctx.write(')
|
|
5213
|
+
ctx.write(true, ');', true);
|
|
4991
5214
|
});
|
|
4992
|
-
|
|
4993
|
-
|
|
5215
|
+
requireCD.$depends(result);
|
|
5216
|
+
this.glob.component.$depends(result);
|
|
5217
|
+
return result;
|
|
4994
5218
|
}
|
|
4995
5219
|
|
|
4996
5220
|
function makeEachBlock(data, option) {
|
|
4997
|
-
|
|
4998
|
-
let nodeItems = trimEmptyNodes(data.body);
|
|
4999
|
-
if(!nodeItems.length) nodeItems = [data.body[0]];
|
|
5000
|
-
|
|
5001
|
-
let itemData = this.buildBlock({body: nodeItems}, {protectLastTag: true, inline: true});
|
|
5221
|
+
this.require('apply');
|
|
5002
5222
|
|
|
5003
5223
|
// #each items as item, index (key)
|
|
5004
|
-
let rx = data.value.match(/^#each\s+(.+)\s+as\s+(.+)$/
|
|
5224
|
+
let rx = data.value.match(/^#each\s+(.+)\s+as\s+(.+)$/);
|
|
5005
5225
|
assert(rx, `Wrong #each expression '${data.value}'`);
|
|
5006
5226
|
let arrayName = rx[1];
|
|
5007
5227
|
let right = rx[2];
|
|
5008
5228
|
let keyName;
|
|
5009
5229
|
|
|
5010
5230
|
// get keyName
|
|
5011
|
-
rx = right.match(/^(.*)\s*\(\s*([^\(\)]+)\s*\)\s*$/
|
|
5231
|
+
rx = right.match(/^(.*)\s*\(\s*([^\(\)]+)\s*\)\s*$/);
|
|
5012
5232
|
if(rx) {
|
|
5013
5233
|
right = rx[1];
|
|
5014
5234
|
keyName = rx[2];
|
|
5015
5235
|
}
|
|
5016
5236
|
right = right.trim();
|
|
5017
5237
|
|
|
5018
|
-
let itemName, indexName,
|
|
5238
|
+
let itemName, indexName, blockPrefix = null;
|
|
5019
5239
|
if(right[0] == '{') {
|
|
5020
|
-
rx = right.match(/^(\{[^}]+\})(.*)$/
|
|
5240
|
+
rx = right.match(/^(\{[^}]+\})(.*)$/);
|
|
5021
5241
|
assert(rx, `Wrong #each expression '${data.value}'`);
|
|
5022
5242
|
let exp = rx[1], keywords;
|
|
5023
5243
|
|
|
@@ -5032,12 +5252,15 @@
|
|
|
5032
5252
|
if(indexName[0] == ',') indexName = indexName.substring(1).trim();
|
|
5033
5253
|
indexName = indexName || '$index';
|
|
5034
5254
|
|
|
5035
|
-
|
|
5255
|
+
blockPrefix = xNode('each:unwrap', {
|
|
5036
5256
|
exp,
|
|
5037
5257
|
keywords
|
|
5038
5258
|
}, (ctx, n) => {
|
|
5039
|
-
ctx.writeLine(`let ${n.
|
|
5040
|
-
|
|
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
|
+
}
|
|
5041
5264
|
});
|
|
5042
5265
|
} else {
|
|
5043
5266
|
rx = right.trim().split(/\s*\,\s*/);
|
|
@@ -5070,82 +5293,93 @@
|
|
|
5070
5293
|
})]
|
|
5071
5294
|
});
|
|
5072
5295
|
}
|
|
5073
|
-
let
|
|
5074
|
-
if(
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
`let $cd = $ctx.cd;`,
|
|
5081
|
-
bind0,
|
|
5082
|
-
itemData.source,
|
|
5083
|
-
xNode(ctx => {
|
|
5084
|
-
ctx.writeLine(`$ctx.rebind = function(_${indexName}, _${itemName}) {`);
|
|
5085
|
-
ctx.indent++;
|
|
5086
|
-
ctx.writeLine(`${indexName} = _${indexName};`);
|
|
5087
|
-
ctx.writeLine(`${itemName} = _${itemName};`);
|
|
5088
|
-
ctx.indent--;
|
|
5089
|
-
ctx.writeLine(`};`);
|
|
5090
|
-
})
|
|
5091
|
-
]
|
|
5092
|
-
});
|
|
5093
|
-
} else {
|
|
5094
|
-
bind = xNode('function', {
|
|
5095
|
-
inline: true,
|
|
5096
|
-
arrow: true,
|
|
5097
|
-
args: ['$ctx'],
|
|
5098
|
-
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};}`);
|
|
5099
5303
|
});
|
|
5100
5304
|
}
|
|
5101
5305
|
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
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
|
+
}
|
|
5106
5318
|
});
|
|
5107
5319
|
|
|
5108
|
-
|
|
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
|
+
|
|
5109
5338
|
const source = xNode('each', {
|
|
5110
5339
|
keyFunction,
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
}, (ctx, data) => {
|
|
5340
|
+
block: itemBlock,
|
|
5341
|
+
}, (ctx, n) => {
|
|
5114
5342
|
ctx.writeLine(`$runtime.$$eachBlock($cd, ${option.elName}, ${option.onlyChild?1:0}, () => (${arrayName}),`);
|
|
5115
5343
|
ctx.indent++;
|
|
5116
|
-
ctx.
|
|
5117
|
-
if(
|
|
5118
|
-
else if(
|
|
5344
|
+
ctx.write(true);
|
|
5345
|
+
if(n.keyFunction === 'noop') ctx.write('$runtime.noop');
|
|
5346
|
+
else if(n.keyFunction) ctx.add(n.keyFunction);
|
|
5119
5347
|
else ctx.write('$runtime.eachDefaultKey');
|
|
5120
|
-
ctx.write(
|
|
5121
|
-
ctx.
|
|
5122
|
-
ctx.build(data.template);
|
|
5123
|
-
ctx.write(`,\n`);
|
|
5124
|
-
ctx.writeIndent();
|
|
5125
|
-
ctx.build(data.bind);
|
|
5126
|
-
ctx.write(`);\n`);
|
|
5348
|
+
ctx.write(`,`);
|
|
5349
|
+
ctx.add(n.block);
|
|
5127
5350
|
ctx.indent--;
|
|
5351
|
+
ctx.write(true, `);`, true);
|
|
5128
5352
|
});
|
|
5129
5353
|
this.detectDependency(arrayName);
|
|
5130
5354
|
|
|
5131
5355
|
return {source};
|
|
5132
5356
|
}
|
|
5133
5357
|
|
|
5134
|
-
function makeHtmlBlock(exp, label) {
|
|
5358
|
+
function makeHtmlBlock(exp, label, requireCD) {
|
|
5135
5359
|
this.detectDependency(exp);
|
|
5136
5360
|
this.require('$cd');
|
|
5137
|
-
|
|
5361
|
+
const result = xNode('block', {
|
|
5362
|
+
$deps: [this.glob.apply],
|
|
5138
5363
|
el: label.bindName(),
|
|
5139
|
-
exp
|
|
5364
|
+
exp,
|
|
5365
|
+
requireCD
|
|
5140
5366
|
}, (ctx, n) => {
|
|
5141
|
-
|
|
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}));`);
|
|
5142
5373
|
});
|
|
5374
|
+
|
|
5375
|
+
requireCD.$depends(result);
|
|
5376
|
+
return result;
|
|
5143
5377
|
}
|
|
5144
5378
|
|
|
5145
5379
|
function makeAwaitBlock(node, element) {
|
|
5146
5380
|
let valueForThen, exp;
|
|
5147
5381
|
|
|
5148
|
-
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*$/);
|
|
5149
5383
|
if(rx) {
|
|
5150
5384
|
assert(!node.parts.then);
|
|
5151
5385
|
node.parts.then = node.parts.main;
|
|
@@ -5153,7 +5387,7 @@
|
|
|
5153
5387
|
exp = rx[1];
|
|
5154
5388
|
valueForThen = rx[2];
|
|
5155
5389
|
} else {
|
|
5156
|
-
rx = node.value.match(/^#await\s+(.+)\s*$/
|
|
5390
|
+
rx = node.value.match(/^#await\s+(.+)\s*$/);
|
|
5157
5391
|
assert(rx);
|
|
5158
5392
|
exp = rx[1].trim();
|
|
5159
5393
|
}
|
|
@@ -5162,7 +5396,7 @@
|
|
|
5162
5396
|
|
|
5163
5397
|
let parts = [null, null, null];
|
|
5164
5398
|
if(node.parts.main && node.parts.main.length) {
|
|
5165
|
-
parts[0] = this.buildBlock({body: node.parts.main}, {protectLastTag: true
|
|
5399
|
+
parts[0] = this.buildBlock({body: node.parts.main}, {protectLastTag: true});
|
|
5166
5400
|
}
|
|
5167
5401
|
if(node.parts.then && node.parts.then.length) {
|
|
5168
5402
|
let args = [];
|
|
@@ -5170,27 +5404,30 @@
|
|
|
5170
5404
|
assert(isSimpleName(valueForThen));
|
|
5171
5405
|
args.push(valueForThen);
|
|
5172
5406
|
} else {
|
|
5173
|
-
let rx = node.parts.thenValue.match(/^[^ ]+\s+(.*)$/
|
|
5407
|
+
let rx = node.parts.thenValue.match(/^[^ ]+\s+(.*)$/);
|
|
5174
5408
|
if(rx) {
|
|
5175
5409
|
assert(isSimpleName(rx[1]));
|
|
5176
5410
|
args.push(rx[1]);
|
|
5177
5411
|
}
|
|
5178
5412
|
}
|
|
5179
|
-
parts[1] = this.buildBlock({body: node.parts.then}, {protectLastTag: true,
|
|
5413
|
+
parts[1] = this.buildBlock({body: node.parts.then}, {protectLastTag: true, extraArguments: args});
|
|
5180
5414
|
}
|
|
5181
5415
|
if(node.parts.catch && node.parts.catch.length) {
|
|
5182
5416
|
let args = [];
|
|
5183
|
-
let rx = node.parts.catchValue.match(/^[^ ]+\s+(.*)$/
|
|
5417
|
+
let rx = node.parts.catchValue.match(/^[^ ]+\s+(.*)$/);
|
|
5184
5418
|
if(rx) {
|
|
5185
5419
|
assert(isSimpleName(rx[1]));
|
|
5186
5420
|
args.push(rx[1]);
|
|
5187
5421
|
}
|
|
5188
|
-
parts[2] = this.buildBlock({body: node.parts.catch}, {protectLastTag: true,
|
|
5422
|
+
parts[2] = this.buildBlock({body: node.parts.catch}, {protectLastTag: true, extraArguments: args});
|
|
5189
5423
|
}
|
|
5190
5424
|
|
|
5425
|
+
if(this.script.readOnly) {
|
|
5426
|
+
this.warning('script read-only conflicts with await');
|
|
5427
|
+
return;
|
|
5428
|
+
}
|
|
5191
5429
|
this.detectDependency(exp);
|
|
5192
|
-
|
|
5193
|
-
this.require('apply', '$cd');
|
|
5430
|
+
this.require('apply');
|
|
5194
5431
|
|
|
5195
5432
|
return xNode('await', {
|
|
5196
5433
|
el: element.bindName(),
|
|
@@ -5198,127 +5435,88 @@
|
|
|
5198
5435
|
parts,
|
|
5199
5436
|
keywords
|
|
5200
5437
|
}, (ctx, n) => {
|
|
5201
|
-
ctx.
|
|
5202
|
-
ctx.
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
ctx.build(source);
|
|
5210
|
-
ctx.write(',\n');
|
|
5211
|
-
ctx.writeIndent();
|
|
5212
|
-
} else ctx.write(`$runtime.noop, `);
|
|
5213
|
-
ctx.build(xNode('template', {body: tpl, svg, inline: true}));
|
|
5214
|
-
ctx.write(index == 2 ? '\n' : ',\n');
|
|
5215
|
-
} else {
|
|
5216
|
-
ctx.writeLine(`null, null` + (index == 2 ? '' : ','));
|
|
5217
|
-
} });
|
|
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');
|
|
5218
5446
|
});
|
|
5219
|
-
ctx.
|
|
5447
|
+
ctx.indent--;
|
|
5448
|
+
ctx.write(');', true);
|
|
5220
5449
|
});
|
|
5221
5450
|
}
|
|
5222
5451
|
|
|
5223
|
-
function attachSlot(slotName,
|
|
5224
|
-
let props = [];
|
|
5452
|
+
function attachSlot(slotName, node, requireCD) {
|
|
5453
|
+
let props = [], staticProps = true;
|
|
5454
|
+
|
|
5225
5455
|
if(node.attributes && node.attributes.length) {
|
|
5226
5456
|
node.attributes.forEach(prop => {
|
|
5227
|
-
let name = prop
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
value
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
if(value[0] == '{') {
|
|
5236
|
-
value = unwrapExp(value);
|
|
5237
|
-
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
|
+
}));
|
|
5238
5465
|
|
|
5239
|
-
props.push(xNode('prop', {
|
|
5240
|
-
name,
|
|
5241
|
-
value,
|
|
5242
|
-
dyn: true
|
|
5243
|
-
}, (ctx, n) => {
|
|
5244
|
-
if(this.inuse.apply) ctx.write(`${n.name}: () => (${n.value})`);
|
|
5245
|
-
else ctx.write(`${n.name}: (${n.value})`);
|
|
5246
|
-
}));
|
|
5247
|
-
} else {
|
|
5248
|
-
props.push(xNode('static-prop', {
|
|
5249
|
-
name,
|
|
5250
|
-
value
|
|
5251
|
-
}, (ctx, n) => {
|
|
5252
|
-
ctx.write(`${n.name}: \`${this.Q(n.value)}\``);
|
|
5253
|
-
}));
|
|
5254
|
-
}
|
|
5255
5466
|
});
|
|
5256
5467
|
}
|
|
5257
5468
|
let placeholder;
|
|
5258
|
-
if(node.body
|
|
5259
|
-
let block = this.buildBlock(node, {inline: true});
|
|
5260
|
-
|
|
5261
|
-
const tpl = xNode('template', {
|
|
5262
|
-
name: '$parentElement',
|
|
5263
|
-
body: block.tpl,
|
|
5264
|
-
svg: block.svg
|
|
5265
|
-
});
|
|
5469
|
+
if(node.body?.length) placeholder = this.buildBlock(node).block;
|
|
5266
5470
|
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
body: block.source,
|
|
5270
|
-
tpl
|
|
5271
|
-
}, (ctx, n) => {
|
|
5272
|
-
ctx.build(n.tpl);
|
|
5273
|
-
ctx.build(n.body);
|
|
5274
|
-
ctx.writeLine(`$runtime.insertAfter(${n.el}, $parentElement);`);
|
|
5275
|
-
});
|
|
5276
|
-
}
|
|
5277
|
-
|
|
5278
|
-
this.require('$component', '$cd', '$context');
|
|
5471
|
+
this.require('$context');
|
|
5472
|
+
this.glob.component.$value(true);
|
|
5279
5473
|
|
|
5280
|
-
|
|
5474
|
+
let result = xNode('slot', {
|
|
5475
|
+
$deps: [this.glob.apply],
|
|
5281
5476
|
name: slotName,
|
|
5282
|
-
el: label.bindName(),
|
|
5283
5477
|
props,
|
|
5284
|
-
|
|
5478
|
+
staticProps,
|
|
5479
|
+
placeholder,
|
|
5480
|
+
requireCD
|
|
5285
5481
|
}, (ctx, n) => {
|
|
5286
|
-
let
|
|
5287
|
-
|
|
5288
|
-
if(
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
}
|
|
5292
|
-
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
|
+
|
|
5293
5490
|
if(n.props.length) {
|
|
5294
|
-
ctx.write(
|
|
5295
|
-
ctx.
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
ctx.build(prop);
|
|
5300
|
-
if(i + 1 < n.props.length) ctx.write(',');
|
|
5301
|
-
ctx.write('\n');
|
|
5302
|
-
}
|
|
5491
|
+
if(dynamicProps) ctx.write(', () => ({');
|
|
5492
|
+
else ctx.write(', {');
|
|
5493
|
+
n.props.forEach((prop, i) => {
|
|
5494
|
+
if(i) ctx.write(', ');
|
|
5495
|
+
ctx.add(prop);
|
|
5303
5496
|
});
|
|
5304
|
-
ctx.write(
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5497
|
+
ctx.write('}');
|
|
5498
|
+
if(dynamicProps) ctx.write(')');
|
|
5499
|
+
} else missed += ', null';
|
|
5500
|
+
|
|
5308
5501
|
if(n.placeholder) {
|
|
5309
|
-
ctx.write(',
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
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(')');
|
|
5317
5513
|
});
|
|
5514
|
+
requireCD.$depends(result);
|
|
5515
|
+
return result;
|
|
5318
5516
|
}
|
|
5319
5517
|
|
|
5320
|
-
function makeFragment(node) {
|
|
5321
|
-
let rx = node.value.match(/#fragment\:(\S+)(.*)$/
|
|
5518
|
+
function makeFragment(node, requireCD) {
|
|
5519
|
+
let rx = node.value.match(/#fragment\:(\S+)(.*)$/);
|
|
5322
5520
|
assert(rx);
|
|
5323
5521
|
let name = rx[1], external = false;
|
|
5324
5522
|
assert(isSimpleName(name));
|
|
@@ -5333,9 +5531,12 @@
|
|
|
5333
5531
|
});
|
|
5334
5532
|
}
|
|
5335
5533
|
|
|
5534
|
+
if(external) requireCD.$value(true);
|
|
5535
|
+
|
|
5336
5536
|
let block;
|
|
5337
|
-
if(node.body && node.body.length)
|
|
5338
|
-
|
|
5537
|
+
if(node.body && node.body.length) {
|
|
5538
|
+
block = this.buildBlock({body: trimEmptyNodes(node.body)}, {inline: true, context: 'fragment', parentElement: '$dom'});
|
|
5539
|
+
} else {
|
|
5339
5540
|
this.warning(`Empty fragment: '${node.value}'`);
|
|
5340
5541
|
return xNode('empty-fragment', {name}, (ctx, n) => {
|
|
5341
5542
|
ctx.writeLine(`function $fragment_${n.name}() {};`);
|
|
@@ -5343,36 +5544,45 @@
|
|
|
5343
5544
|
}
|
|
5344
5545
|
|
|
5345
5546
|
return xNode('fragment', {
|
|
5547
|
+
$compile: [block.source, this.glob.apply],
|
|
5548
|
+
$deps: [block.requireCD],
|
|
5346
5549
|
name,
|
|
5347
5550
|
props,
|
|
5348
5551
|
external,
|
|
5349
|
-
|
|
5350
|
-
template: xNode('template', {
|
|
5351
|
-
name: '$parentElement',
|
|
5352
|
-
body: block.tpl,
|
|
5353
|
-
svg: block.svg
|
|
5354
|
-
})
|
|
5552
|
+
block
|
|
5355
5553
|
}, (ctx, n) => {
|
|
5356
|
-
ctx.
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
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
|
+
}
|
|
5366
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('}');
|
|
5367
5584
|
}
|
|
5368
|
-
|
|
5369
|
-
ctx.build(n.template);
|
|
5370
|
-
ctx.build(n.source);
|
|
5371
|
-
ctx.writeLine(`$runtime.insertAfter(label, $parentElement);`);
|
|
5372
|
-
|
|
5373
|
-
ctx.indent--;
|
|
5374
|
-
ctx.writeLine('}');
|
|
5375
|
-
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});`);
|
|
5376
5586
|
});
|
|
5377
5587
|
}
|
|
5378
5588
|
|
|
@@ -5394,7 +5604,7 @@
|
|
|
5394
5604
|
name = name.substring(2);
|
|
5395
5605
|
events.push({
|
|
5396
5606
|
name,
|
|
5397
|
-
callback: `$events
|
|
5607
|
+
callback: `$events.${name}`
|
|
5398
5608
|
});
|
|
5399
5609
|
}
|
|
5400
5610
|
return;
|
|
@@ -5413,64 +5623,48 @@
|
|
|
5413
5623
|
}
|
|
5414
5624
|
|
|
5415
5625
|
|
|
5416
|
-
function attachFragment(node
|
|
5626
|
+
function attachFragment(node) {
|
|
5417
5627
|
let name = node.elArg;
|
|
5418
5628
|
assert(isSimpleName(name));
|
|
5419
5629
|
|
|
5420
|
-
let slotBlock = null;
|
|
5421
|
-
|
|
5422
|
-
if(node.body?.length) slotBlock = this.buildBlock({body: trimEmptyNodes(node.body)}, {inline: true});
|
|
5423
|
-
|
|
5424
|
-
let {props, events, forwardAllEvents, staticProps} = parseAttibutes.call(this, node.attributes);
|
|
5425
|
-
this.require('$cd');
|
|
5426
|
-
|
|
5427
5630
|
let slot = null;
|
|
5428
|
-
if(
|
|
5429
|
-
let template = xNode('template', {
|
|
5430
|
-
name: '$parentElement',
|
|
5431
|
-
body: slotBlock.tpl,
|
|
5432
|
-
svg: slotBlock.svg,
|
|
5433
|
-
inline: !slotBlock.source
|
|
5434
|
-
});
|
|
5631
|
+
if(node.body?.length) slot = this.buildBlock({body: trimEmptyNodes(node.body)}, {inline: true});
|
|
5435
5632
|
|
|
5436
|
-
|
|
5437
|
-
source: slotBlock.source,
|
|
5438
|
-
template
|
|
5439
|
-
};
|
|
5440
|
-
}
|
|
5633
|
+
let {props, events, forwardAllEvents, staticProps} = parseAttibutes.call(this, node.attributes);
|
|
5441
5634
|
|
|
5442
5635
|
return xNode('call-fragment', {
|
|
5636
|
+
$compile: [slot?.source],
|
|
5637
|
+
$deps: [this.glob.apply],
|
|
5443
5638
|
forwardAllEvents,
|
|
5444
|
-
el: element.bindName(),
|
|
5445
5639
|
name,
|
|
5446
5640
|
events,
|
|
5447
5641
|
props,
|
|
5448
5642
|
slot,
|
|
5449
5643
|
staticProps
|
|
5450
5644
|
}, (ctx, n) => {
|
|
5451
|
-
ctx.write(
|
|
5645
|
+
ctx.write(`$fragment_${n.name}(`);
|
|
5452
5646
|
let missed = '';
|
|
5453
5647
|
ctx.indent++;
|
|
5454
5648
|
|
|
5455
5649
|
if(n.props.length) {
|
|
5456
|
-
ctx.write(
|
|
5650
|
+
ctx.write(true);
|
|
5457
5651
|
|
|
5458
5652
|
const writeProps = () => ctx.write('{' + n.props.map(p => p.name == p.value ? p.name : `${p.name}: ${p.value}`).join(', ') + '}');
|
|
5459
5653
|
|
|
5460
|
-
if(n.staticProps) writeProps();
|
|
5654
|
+
if(n.staticProps || !this.glob.apply.value) writeProps();
|
|
5461
5655
|
else {
|
|
5462
5656
|
ctx.write(`() => (`);
|
|
5463
5657
|
writeProps();
|
|
5464
5658
|
ctx.write(`)`);
|
|
5465
5659
|
}
|
|
5466
|
-
} else missed = '
|
|
5660
|
+
} else missed = 'null';
|
|
5467
5661
|
|
|
5468
5662
|
if(n.forwardAllEvents) {
|
|
5469
5663
|
if(n.events.length) this.warning(`Fragment: mixing binding and forwarding is not supported: '${node.openTag}'`);
|
|
5470
5664
|
ctx.write(missed, ', $events');
|
|
5471
5665
|
missed = '';
|
|
5472
5666
|
} else if(n.events.length) {
|
|
5473
|
-
ctx.write(missed, '
|
|
5667
|
+
ctx.write(missed, ',', true, '{');
|
|
5474
5668
|
missed = '';
|
|
5475
5669
|
|
|
5476
5670
|
n.events.forEach((e, i) => {
|
|
@@ -5488,42 +5682,42 @@
|
|
|
5488
5682
|
} else missed += ', 0';
|
|
5489
5683
|
|
|
5490
5684
|
if(n.slot) {
|
|
5491
|
-
ctx.write(missed, '
|
|
5685
|
+
ctx.write(missed, ',', true);
|
|
5492
5686
|
missed = '';
|
|
5493
|
-
if(n.slot.source) {
|
|
5494
|
-
ctx.
|
|
5495
|
-
ctx.
|
|
5496
|
-
|
|
5497
|
-
ctx.build(n.slot.source);
|
|
5498
|
-
ctx.writeLine(`$runtime.insertAfter(label, $parentElement);`);
|
|
5499
|
-
});
|
|
5500
|
-
ctx.write(true, `}`);
|
|
5687
|
+
if(ctx.isEmpty(n.slot.source)) {
|
|
5688
|
+
ctx.write(`$runtime.makeStaticBlock(`);
|
|
5689
|
+
ctx.add(n.slot.template);
|
|
5690
|
+
ctx.write(`)`);
|
|
5501
5691
|
} else {
|
|
5502
|
-
ctx.write(
|
|
5503
|
-
ctx.
|
|
5504
|
-
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, `})`);
|
|
5505
5699
|
}
|
|
5506
5700
|
}
|
|
5507
5701
|
|
|
5508
5702
|
ctx.indent--;
|
|
5509
|
-
if(n.props.length || n.events.length || n.slot) ctx.write(true, ')
|
|
5510
|
-
else ctx.write(')
|
|
5703
|
+
if(n.props.length || n.events.length || n.slot) ctx.write(true, ')');
|
|
5704
|
+
else ctx.write(')');
|
|
5511
5705
|
|
|
5512
5706
|
});
|
|
5513
5707
|
}
|
|
5514
5708
|
|
|
5515
|
-
function attachFragmentSlot(label) {
|
|
5516
|
-
|
|
5709
|
+
function attachFragmentSlot(label, requireCD) {
|
|
5710
|
+
requireCD.$value(true);
|
|
5517
5711
|
|
|
5518
5712
|
return xNode('fragment-slot', {
|
|
5519
5713
|
el: label.bindName()
|
|
5520
5714
|
}, (ctx, n) => {
|
|
5521
|
-
ctx.
|
|
5715
|
+
ctx.write(true, `$runtime.attachBlock($cd, ${n.el}, $$fragmentSlot?.())`);
|
|
5522
5716
|
});
|
|
5523
5717
|
}
|
|
5524
5718
|
|
|
5525
|
-
function attchExportedFragment(node, label, componentName) {
|
|
5526
|
-
|
|
5719
|
+
function attchExportedFragment(node, label, componentName, requireCD) {
|
|
5720
|
+
requireCD.$value(true);
|
|
5527
5721
|
|
|
5528
5722
|
let data = {
|
|
5529
5723
|
name: node.elArg,
|
|
@@ -5533,48 +5727,44 @@
|
|
|
5533
5727
|
|
|
5534
5728
|
let body = trimEmptyNodes(node.body || []);
|
|
5535
5729
|
if(body.length) {
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
data
|
|
5539
|
-
data.template
|
|
5540
|
-
raw: true,
|
|
5541
|
-
body: block.tpl
|
|
5542
|
-
});
|
|
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');
|
|
5543
5734
|
}
|
|
5544
5735
|
|
|
5545
5736
|
let pa = parseAttibutes.call(this, node.attributes);
|
|
5546
|
-
data
|
|
5547
|
-
data.events = pa.events;
|
|
5548
|
-
data.forwardAllEvents = pa.forwardAllEvents;
|
|
5549
|
-
data.staticProps = pa.staticProps;
|
|
5737
|
+
data = {...pa, ...data};
|
|
5550
5738
|
|
|
5551
5739
|
return xNode('attach-exported-fragment', data, (ctx, n) => {
|
|
5552
|
-
ctx.write(true, `$runtime.
|
|
5553
|
-
let missed = '';
|
|
5740
|
+
ctx.write(true, `$runtime.attachBlock($cd, ${n.label}, $runtime.callExportedFragment($instance_${n.componentName}, '${n.name}'`);
|
|
5554
5741
|
ctx.indent++;
|
|
5742
|
+
let missed = '';
|
|
5555
5743
|
|
|
5556
|
-
if(n.
|
|
5557
|
-
ctx.write('
|
|
5558
|
-
|
|
5559
|
-
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);
|
|
5560
5746
|
|
|
5561
|
-
if(n.
|
|
5562
|
-
|
|
5563
|
-
ctx.
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
ctx.write(
|
|
5567
|
-
|
|
5568
|
-
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, `})`);
|
|
5569
5759
|
}
|
|
5570
|
-
} else missed = ',
|
|
5760
|
+
} else missed = ', null';
|
|
5571
5761
|
|
|
5572
5762
|
if(n.forwardAllEvents) {
|
|
5573
5763
|
if(n.events.length) this.warning(`Fragment: mixing binding and forwarding is not supported: '${node.openTag}'`);
|
|
5574
5764
|
ctx.write(missed, ', $events');
|
|
5575
5765
|
missed = '';
|
|
5576
5766
|
} else if(n.events.length) {
|
|
5577
|
-
ctx.write(missed, '
|
|
5767
|
+
ctx.write(missed, ',', true, '{');
|
|
5578
5768
|
missed = '';
|
|
5579
5769
|
|
|
5580
5770
|
n.events.forEach((e, i) => {
|
|
@@ -5589,27 +5779,32 @@
|
|
|
5589
5779
|
}
|
|
5590
5780
|
});
|
|
5591
5781
|
ctx.write('}');
|
|
5592
|
-
} else missed += ',
|
|
5782
|
+
} else missed += ', null';
|
|
5593
5783
|
|
|
5594
|
-
if(n.
|
|
5595
|
-
if(missed) ctx.write(missed
|
|
5596
|
-
|
|
5597
|
-
ctx.
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
ctx.
|
|
5604
|
-
|
|
5605
|
-
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`);
|
|
5606
5798
|
}
|
|
5607
|
-
|
|
5799
|
+
|
|
5800
|
+
}
|
|
5801
|
+
|
|
5608
5802
|
ctx.indent--;
|
|
5803
|
+
ctx.write('));');
|
|
5609
5804
|
});
|
|
5610
5805
|
}
|
|
5611
5806
|
|
|
5612
|
-
function attachHead(n) {
|
|
5807
|
+
function attachHead(n, requireCD) {
|
|
5613
5808
|
if(n.elArg == 'window' || n.elArg == 'body') {
|
|
5614
5809
|
let name = 'el' + (this.uniqIndex++);
|
|
5615
5810
|
let block = this.buildBlock({body: [n]}, {malinaElement: true, inline: true, oneElement: name, bindAttributes: true});
|
|
@@ -5635,7 +5830,10 @@
|
|
|
5635
5830
|
return true;
|
|
5636
5831
|
});
|
|
5637
5832
|
|
|
5638
|
-
let d = {
|
|
5833
|
+
let d = {
|
|
5834
|
+
$deps: [this.glob.apply],
|
|
5835
|
+
requireCD
|
|
5836
|
+
};
|
|
5639
5837
|
if(title?.body?.[0]) {
|
|
5640
5838
|
assert(title.body[0].type == 'text');
|
|
5641
5839
|
let r = this.parseText(title.body[0].value);
|
|
@@ -5646,27 +5844,39 @@
|
|
|
5646
5844
|
}
|
|
5647
5845
|
}
|
|
5648
5846
|
if(body.length) {
|
|
5649
|
-
let
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5847
|
+
let bb = this.buildBlock({body}, {
|
|
5848
|
+
inline: true,
|
|
5849
|
+
template: {
|
|
5850
|
+
name: '$parentElement',
|
|
5851
|
+
cloneNode: true,
|
|
5852
|
+
requireFragment: true
|
|
5853
|
+
}
|
|
5654
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
|
+
|
|
5655
5862
|
this.require('$onDestroy');
|
|
5656
5863
|
}
|
|
5657
5864
|
|
|
5658
|
-
|
|
5865
|
+
const result = xNode('malina:head', d, (ctx, n) => {
|
|
5866
|
+
if(n.blockCD.value) n.requireCD.$value(true);
|
|
5659
5867
|
if(n.title != null) ctx.writeLine(`document.title = ${n.title};`);
|
|
5660
5868
|
if(n.dynTitle) {
|
|
5661
|
-
if(
|
|
5662
|
-
|
|
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};`);
|
|
5663
5873
|
}
|
|
5664
5874
|
|
|
5665
5875
|
if(n.template) {
|
|
5666
5876
|
ctx.writeLine(`{`);
|
|
5667
5877
|
ctx.indent++;
|
|
5668
|
-
ctx.
|
|
5669
|
-
ctx.
|
|
5878
|
+
ctx.add(n.template);
|
|
5879
|
+
ctx.add(n.source);
|
|
5670
5880
|
ctx.writeLine(`let a=$parentElement.firstChild, b=$parentElement.lastChild;`);
|
|
5671
5881
|
ctx.writeLine(`$onDestroy(() => {$runtime.$$removeElements(a, b)});`);
|
|
5672
5882
|
ctx.writeLine(`document.head.appendChild($parentElement);`);
|
|
@@ -5674,6 +5884,8 @@
|
|
|
5674
5884
|
ctx.writeLine(`}`);
|
|
5675
5885
|
}
|
|
5676
5886
|
});
|
|
5887
|
+
requireCD.$depends(result);
|
|
5888
|
+
return result;
|
|
5677
5889
|
} else throw 'Wrong tag';
|
|
5678
5890
|
}
|
|
5679
5891
|
|
|
@@ -5727,37 +5939,47 @@
|
|
|
5727
5939
|
return {name, value, rawValue, static: statical};
|
|
5728
5940
|
}
|
|
5729
5941
|
|
|
5730
|
-
function attachPortal(node) {
|
|
5942
|
+
function attachPortal(node, requireCD) {
|
|
5731
5943
|
let body = trimEmptyNodes(node.body || []);
|
|
5732
5944
|
if(!body.length) return;
|
|
5733
|
-
|
|
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');
|
|
5734
5956
|
|
|
5735
5957
|
let mount = node.attributes.find(a => a.name == 'mount')?.value;
|
|
5736
5958
|
if(mount) mount = unwrapExp(mount);
|
|
5737
5959
|
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5960
|
+
const result = xNode('portal', {
|
|
5961
|
+
$compile: [bb.source],
|
|
5962
|
+
$deps: [bb.requireCD],
|
|
5741
5963
|
mount,
|
|
5742
|
-
source:
|
|
5743
|
-
template:
|
|
5744
|
-
|
|
5745
|
-
body: block.tpl,
|
|
5746
|
-
svg: block.svg
|
|
5747
|
-
})
|
|
5964
|
+
source: bb.source,
|
|
5965
|
+
template: bb.template,
|
|
5966
|
+
requireCD
|
|
5748
5967
|
}, (ctx, n) => {
|
|
5968
|
+
if(n.$deps[0].value) n.requireCD.$value(true);
|
|
5749
5969
|
let label = n.mount || 'document.body';
|
|
5750
5970
|
ctx.writeLine('{');
|
|
5751
5971
|
ctx.indent++;
|
|
5752
|
-
ctx.
|
|
5753
|
-
ctx.
|
|
5972
|
+
ctx.add(n.template);
|
|
5973
|
+
ctx.add(n.source);
|
|
5754
5974
|
ctx.writeLine(`let $$first = $parentElement[$runtime.firstChild];`);
|
|
5755
5975
|
ctx.writeLine(`let $$last = $parentElement.lastChild;`);
|
|
5756
|
-
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));`);
|
|
5757
5977
|
ctx.writeLine(`$tick(() => ${label}.appendChild($parentElement));`);
|
|
5758
5978
|
ctx.indent--;
|
|
5759
5979
|
ctx.writeLine('}');
|
|
5760
5980
|
});
|
|
5981
|
+
requireCD.$depends(result);
|
|
5982
|
+
return result;
|
|
5761
5983
|
}
|
|
5762
5984
|
|
|
5763
5985
|
function makeEventProp(prop, requireElement) {
|
|
@@ -5780,6 +6002,7 @@
|
|
|
5780
6002
|
let modList = [], _mod = '';
|
|
5781
6003
|
let handler = '', exp, func;
|
|
5782
6004
|
let step = 0;
|
|
6005
|
+
let rootModifier = false;
|
|
5783
6006
|
for(let a of name) {
|
|
5784
6007
|
if(a == '|') {
|
|
5785
6008
|
assert$1(step <= 1);
|
|
@@ -5807,14 +6030,18 @@
|
|
|
5807
6030
|
|
|
5808
6031
|
this.detectDependency(exp || handler);
|
|
5809
6032
|
|
|
6033
|
+
let globalFunction = false;
|
|
5810
6034
|
if(exp) {
|
|
5811
6035
|
let type = detectExpressionType(exp);
|
|
5812
6036
|
if(type == 'identifier') {
|
|
6037
|
+
globalFunction = !!this.script.rootFunctions[exp];
|
|
5813
6038
|
handler = exp;
|
|
5814
6039
|
exp = null;
|
|
5815
6040
|
} else if(type == 'function') {
|
|
5816
6041
|
func = exp;
|
|
5817
6042
|
exp = null;
|
|
6043
|
+
} else if(type?.type == 'function-call') {
|
|
6044
|
+
globalFunction = !!this.script.rootFunctions[type.name];
|
|
5818
6045
|
} }
|
|
5819
6046
|
|
|
5820
6047
|
// modifiers
|
|
@@ -5835,6 +6062,10 @@
|
|
|
5835
6062
|
let mods = [];
|
|
5836
6063
|
let preventInserted;
|
|
5837
6064
|
modList.forEach(opt => {
|
|
6065
|
+
if(opt == 'root') {
|
|
6066
|
+
rootModifier = true;
|
|
6067
|
+
return;
|
|
6068
|
+
}
|
|
5838
6069
|
if(opt == 'preventDefault' || opt == 'prevent') {
|
|
5839
6070
|
if(preventInserted) return;
|
|
5840
6071
|
mods.push('$event.preventDefault();');
|
|
@@ -5873,7 +6104,8 @@
|
|
|
5873
6104
|
exp,
|
|
5874
6105
|
handlerName: handler,
|
|
5875
6106
|
func,
|
|
5876
|
-
mods
|
|
6107
|
+
mods,
|
|
6108
|
+
globalFunction
|
|
5877
6109
|
}, (ctx, n) => {
|
|
5878
6110
|
if(n.handlerName && !ctx.inuse.apply && !n.mods) return ctx.write(n.handlerName);
|
|
5879
6111
|
ctx.write(`($event) => { `);
|
|
@@ -5883,14 +6115,14 @@
|
|
|
5883
6115
|
if(last(n.exp) != ';') n.exp += ';';
|
|
5884
6116
|
ctx.write(`${n.exp}`);
|
|
5885
6117
|
} else if(n.func) ctx.write(`(${n.func})($event);`);
|
|
5886
|
-
if(ctx.inuse.apply) ctx.write(` $$apply();`);
|
|
6118
|
+
if(ctx.inuse.apply && !n.globalFunction) ctx.write(` $$apply();`);
|
|
5887
6119
|
ctx.write(`}`);
|
|
5888
6120
|
});
|
|
5889
6121
|
|
|
5890
|
-
return {event, fn};
|
|
6122
|
+
return {event, fn, rootModifier};
|
|
5891
6123
|
}
|
|
5892
6124
|
|
|
5893
|
-
const version = '0.
|
|
6125
|
+
const version = '0.7.1-alpha';
|
|
5894
6126
|
|
|
5895
6127
|
|
|
5896
6128
|
async function compile(source, config = {}) {
|
|
@@ -5923,6 +6155,7 @@
|
|
|
5923
6155
|
makeEachBlock,
|
|
5924
6156
|
makeifBlock,
|
|
5925
6157
|
makeComponent,
|
|
6158
|
+
makeComponentDyn,
|
|
5926
6159
|
makeHtmlBlock,
|
|
5927
6160
|
parseText,
|
|
5928
6161
|
makeAwaitBlock,
|
|
@@ -5938,17 +6171,27 @@
|
|
|
5938
6171
|
checkRootName: checkRootName,
|
|
5939
6172
|
|
|
5940
6173
|
inuse: {},
|
|
5941
|
-
|
|
5942
|
-
|
|
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) {
|
|
5943
6182
|
let deps = true;
|
|
5944
6183
|
if(name == '$props:no-deps') {name = '$props'; deps = false;} if(name == 'apply' && ctx.script.readOnly) name = 'blankApply';
|
|
5945
6184
|
if(ctx.inuse[name] == null) ctx.inuse[name] = 0;
|
|
5946
6185
|
ctx.inuse[name]++;
|
|
5947
6186
|
if(!deps) continue;
|
|
6187
|
+
if(name == 'apply') ctx.glob.apply.$value(true);
|
|
6188
|
+
if(name == '$component') ctx.glob.component.$value(true);
|
|
5948
6189
|
if(name == '$attributes') ctx.require('$props');
|
|
5949
6190
|
if(name == '$props' && !ctx.script.readOnly) ctx.require('apply', '$cd');
|
|
5950
|
-
if(name == '
|
|
5951
|
-
|
|
6191
|
+
if(name == '$cd') {
|
|
6192
|
+
ctx.glob.rootCD.$value(true);
|
|
6193
|
+
ctx.require('$component');
|
|
6194
|
+
}
|
|
5952
6195
|
if(name == '$onDestroy') ctx.require('$component');
|
|
5953
6196
|
if(name == '$onMount') ctx.require('$component');
|
|
5954
6197
|
}
|
|
@@ -5981,9 +6224,7 @@
|
|
|
5981
6224
|
},
|
|
5982
6225
|
|
|
5983
6226
|
xBuild: node => {
|
|
5984
|
-
|
|
5985
|
-
w.build(node);
|
|
5986
|
-
return w.toString();
|
|
6227
|
+
return xBuild(ctx, node);
|
|
5987
6228
|
}
|
|
5988
6229
|
};
|
|
5989
6230
|
|
|
@@ -6035,48 +6276,9 @@
|
|
|
6035
6276
|
result.push(`import { $$htmlToFragment } from 'malinajs/runtime.js';`);
|
|
6036
6277
|
}
|
|
6037
6278
|
result.push(ctx.module.top);
|
|
6279
|
+
result.push(makeComponentFn.call(ctx));
|
|
6038
6280
|
|
|
6039
|
-
result
|
|
6040
|
-
name: config.name,
|
|
6041
|
-
body: [ctx.module.head, ctx.module.code, ctx.module.body]
|
|
6042
|
-
}, (ctx, n) => {
|
|
6043
|
-
ctx.writeIndent();
|
|
6044
|
-
if(config.exportDefault) ctx.write('export default ');
|
|
6045
|
-
else ctx.write(`const ${n.name} = `);
|
|
6046
|
-
|
|
6047
|
-
let component = xNode('function', {
|
|
6048
|
-
args: ['$option'],
|
|
6049
|
-
inline: true,
|
|
6050
|
-
arrow: true,
|
|
6051
|
-
body: n.body
|
|
6052
|
-
});
|
|
6053
|
-
|
|
6054
|
-
if(ctx.inuse.apply) {
|
|
6055
|
-
ctx.write('$runtime.makeComponent(');
|
|
6056
|
-
component.args.push('$$apply');
|
|
6057
|
-
ctx.build(component);
|
|
6058
|
-
ctx.write(', $runtime.$base);\n');
|
|
6059
|
-
} else if(ctx.inuse.$cd || ctx.inuse.$component || ctx.inuse.$context || ctx.inuse.blankApply) {
|
|
6060
|
-
if(ctx.inuse.blankApply) {
|
|
6061
|
-
component.body[0].body.unshift(xNode('block', (ctx) => {
|
|
6062
|
-
ctx.writeLine('let $$apply = $runtime.noop;');
|
|
6063
|
-
}));
|
|
6064
|
-
}
|
|
6065
|
-
|
|
6066
|
-
ctx.write('$runtime.makeComponent(');
|
|
6067
|
-
ctx.build(component);
|
|
6068
|
-
ctx.write(', $runtime.$readOnlyBase);\n');
|
|
6069
|
-
} else {
|
|
6070
|
-
ctx.write('($element, $option={}) => {\n');
|
|
6071
|
-
ctx.goIndent(() => {
|
|
6072
|
-
ctx.inuse.$insertElementByOption = true;
|
|
6073
|
-
ctx.build(xNode('block', {body: n.body}));
|
|
6074
|
-
});
|
|
6075
|
-
ctx.write('}');
|
|
6076
|
-
}
|
|
6077
|
-
}));
|
|
6078
|
-
|
|
6079
|
-
ctx.result = ctx.xBuild(result);
|
|
6281
|
+
ctx.result = xBuild(ctx, result);
|
|
6080
6282
|
|
|
6081
6283
|
await hook(ctx, 'build');
|
|
6082
6284
|
return ctx;
|
|
@@ -6125,8 +6327,7 @@
|
|
|
6125
6327
|
|
|
6126
6328
|
if(localConfig) {
|
|
6127
6329
|
const confFn = require(localConfig);
|
|
6128
|
-
|
|
6129
|
-
else result = confFn;
|
|
6330
|
+
result = confFn(result, filename);
|
|
6130
6331
|
}
|
|
6131
6332
|
if(!result.path) result.path = filename;
|
|
6132
6333
|
if(!result.name) result.name = filename.match(/([^/\\]+)\.\w+$/)[1];
|
|
@@ -6134,6 +6335,60 @@
|
|
|
6134
6335
|
return result;
|
|
6135
6336
|
}
|
|
6136
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
|
+
|
|
6137
6392
|
exports.compile = compile;
|
|
6138
6393
|
exports.version = version;
|
|
6139
6394
|
|