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