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