compelem 0.3.0-b1 → 0.3.1-b1

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.
Files changed (2) hide show
  1. package/index.js +2 -3644
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,3649 +1,7 @@
1
1
  /**
2
- * compelem v0.3.0-b1.1738940769
2
+ * compelem v0.3.1-b1.1739106920
3
3
  * A modern, reactive, fast, lightweight and flexible lib for building web components
4
4
  * @holyhigh2
5
5
  * https://github.com/holyhigh2/compelem
6
6
  */
7
- import { toPath, get, isObject, isDefined, isUndefined, isEmpty, has, concat, defaults, merge, cloneDeep, each, kebabCase, toArray, last, startsWith, isFunction, isArray, initial, isBlank, join, split, set, camelCase, isEqual, replace, isPlainObject, flatMap, isString, test, size, assign, first, debounce, closest, once, bind as bind$1, isNil, trim, some, isNull, fval, omit, groupBy, reject, filter, slice, compact, remove, includes, find, throttle, map, replaceAll, snakeCase, toString, reduce, isMatch, clone, findIndex, call } from 'myfx';
8
-
9
- /**
10
- * 共享内容
11
- */
12
- const ChangedMap = new WeakMap;
13
- const EXP_KEY = /\s+\.?key\s*=/;
14
- var CollectorType;
15
- (function (CollectorType) {
16
- CollectorType[CollectorType["CSS"] = 1] = "CSS";
17
- CollectorType[CollectorType["COMPUTED"] = 2] = "COMPUTED";
18
- })(CollectorType || (CollectorType = {}));
19
- var DecoratorKey;
20
- (function (DecoratorKey) {
21
- DecoratorKey["PROPS"] = "__deco_props";
22
- DecoratorKey["STATES"] = "__deco_states";
23
- DecoratorKey["COMPUTED"] = "__deco_computed";
24
- DecoratorKey["WATCH"] = "__deco_watch";
25
- DecoratorKey["EVENTS"] = "__deco_events";
26
- })(DecoratorKey || (DecoratorKey = {}));
27
-
28
- function showError(msg) {
29
- console.error(`[CompElem]`, msg);
30
- }
31
- function showTagError(tagName, msg) {
32
- console.error(`[CompElem <${tagName}>]`, msg);
33
- }
34
- function showWarn(...args) {
35
- console.warn(`[CompElem]`, ...args);
36
- }
37
- //为依赖收集提供标准地址
38
- function _toUpdatePath(varPath) {
39
- return toPath(varPath).join("-");
40
- }
41
- //获取父类构造
42
- function _getSuper(cls) {
43
- return Object.getPrototypeOf(cls);
44
- }
45
-
46
- //装饰器类型
47
- var DecoratorType;
48
- (function (DecoratorType) {
49
- DecoratorType["CLASS"] = "class";
50
- DecoratorType["FIELD"] = "field";
51
- DecoratorType["METHOD"] = "method";
52
- })(DecoratorType || (DecoratorType = {}));
53
- /**
54
- * 用于构造装饰器
55
- * @author holyhigh2
56
- */
57
- class Decorator {
58
- /**
59
- * 优先级,越大越先执行
60
- */
61
- static get priority() {
62
- return 0;
63
- }
64
- }
65
-
66
- const GetKeyFnName = 'getKey';
67
- const _DecoratorsKey = '__decorators';
68
- const _DecoratorMap = new WeakMap;
69
- /**
70
- * 装饰器包装类
71
- * 用于框架内部,表示class上的一个装饰器属性定义
72
- * 该定义在实例初始化时会产生装饰器实例属性
73
- */
74
- class DecoratorWrapper {
75
- //execute 参数
76
- args;
77
- //装饰器参数
78
- metadata;
79
- decoratorClass;
80
- instanceMap;
81
- key; //装饰器唯一key
82
- priority = 0;
83
- constructor(args, metadata, decoratorClass) {
84
- this.args = args;
85
- this.metadata = metadata;
86
- this.decoratorClass = decoratorClass;
87
- this.priority = get(decoratorClass, 'priority', 0);
88
- this.instanceMap = new WeakMap;
89
- }
90
- //在组件构造时调用
91
- create(comp) {
92
- let ins = new this.decoratorClass(...this.args);
93
- //1. 校验targets
94
- let targets = ins.targets;
95
- let decoType = undefined;
96
- let descriptor = this.metadata[2];
97
- if (isObject(descriptor) && isDefined(get(descriptor, 'configurable'))) {
98
- decoType = DecoratorType.METHOD;
99
- }
100
- else if (isUndefined(this.metadata[2])) {
101
- decoType = DecoratorType.FIELD;
102
- }
103
- if (isEmpty(targets) || !decoType || !targets.includes(decoType)) {
104
- showError(`Decorator '${this.decoratorClass.name}' is out of targets, expect '${targets.join(',')}' bug got '${decoType}'`);
105
- return;
106
- }
107
- ins.created(comp, ...this.metadata);
108
- this.instanceMap.set(comp, ins);
109
- }
110
- beforeMount(comp, setReactive) {
111
- let ins = this.instanceMap.get(comp);
112
- ins.beforeMount(comp, setReactive, ...this.metadata);
113
- }
114
- mounted(comp, setReactive) {
115
- let ins = this.instanceMap.get(comp);
116
- ins.mounted(comp, setReactive, ...this.metadata);
117
- }
118
- updated(comp, changed) {
119
- this.instanceMap.get(comp).updated(comp, changed);
120
- }
121
- }
122
- //每个装饰器类中不同组件类中的重复key
123
- const DecoKeyMap = new WeakMap();
124
- /**
125
- * 该函数用于创建一个装饰器
126
- * @param decoClass 装饰器构造
127
- * @returns 装饰器函数
128
- */
129
- function decorator(decoClass) {
130
- let fn = (...args) => {
131
- return (...metadata) => {
132
- let ctor = metadata[0].constructor;
133
- let ary = get(ctor, _DecoratorsKey);
134
- if (!has(ctor, _DecoratorsKey)) {
135
- //继承父类
136
- let parentAry = get(Object.getPrototypeOf(ctor), _DecoratorsKey);
137
- ary = parentAry ? concat(parentAry) : [];
138
- Reflect.defineProperty(ctor, _DecoratorsKey, {
139
- configurable: false,
140
- enumerable: false,
141
- value: ary
142
- });
143
- }
144
- let kMap = {};
145
- let k;
146
- let getKey = get(decoClass, GetKeyFnName);
147
- if (getKey) {
148
- let compMap = DecoKeyMap.get(decoClass);
149
- if (!compMap) {
150
- compMap = new WeakMap;
151
- DecoKeyMap.set(decoClass, compMap);
152
- }
153
- kMap = compMap.get(ctor);
154
- if (!kMap) {
155
- kMap = {};
156
- compMap.set(ctor, kMap);
157
- }
158
- k = getKey(...args);
159
- if (kMap[k])
160
- return kMap[k];
161
- }
162
- let dw = new DecoratorWrapper(args, metadata, decoClass);
163
- kMap[k] = dw;
164
- ary?.push(dw);
165
- return dw;
166
- };
167
- };
168
- _DecoratorMap.set(fn, true);
169
- return fn;
170
- }
171
-
172
- //每个类需要监控的属性
173
- const ObservedAttrsMap = new WeakMap;
174
- function prop(options) {
175
- if (arguments.length === 1) {
176
- return (target, propertyKey, descriptor) => {
177
- options.required = options.required || false;
178
- options.attribute = options.attribute === false ? false : true;
179
- defineProp(target, propertyKey, options, descriptor);
180
- };
181
- }
182
- let target = arguments[0], propertyKey = arguments[1], descriptor = arguments[2];
183
- options = { type: undefined, required: false, attribute: true };
184
- if (descriptor && typeof descriptor.type === 'function') {
185
- options = defaults(descriptor, options);
186
- descriptor = undefined;
187
- }
188
- defineProp(target, propertyKey, options, descriptor);
189
- }
190
- function defineProp(target, propertyKey, options, descriptor) {
191
- if (!/[a-z]/.test(propertyKey[0])) {
192
- showError(`Prop '${propertyKey}' must be in CamelCase`);
193
- }
194
- let attrSet;
195
- if (!has(target.constructor, DecoratorKey.PROPS)) {
196
- const mixinProps = {};
197
- let parentCtor = target.constructor;
198
- while ((parentCtor = _getSuper(parentCtor)) !== CompElem) {
199
- merge(mixinProps, parentCtor[DecoratorKey.PROPS] ? cloneDeep(parentCtor[DecoratorKey.PROPS]) : {});
200
- }
201
- Reflect.defineProperty(target.constructor, DecoratorKey.PROPS, {
202
- configurable: false,
203
- enumerable: false,
204
- value: mixinProps
205
- });
206
- attrSet = new Set();
207
- each(mixinProps, (v, k) => {
208
- if (v.attribute) {
209
- let kbb = kebabCase(k);
210
- attrSet?.add(kbb);
211
- }
212
- });
213
- ObservedAttrsMap.set(target.constructor, attrSet);
214
- }
215
- if (descriptor) {
216
- if (descriptor.get)
217
- options.getter = descriptor.get;
218
- if (descriptor.set)
219
- options.setter = descriptor.set;
220
- }
221
- if (options.attribute) {
222
- if (!attrSet) {
223
- attrSet = ObservedAttrsMap.get(target.constructor);
224
- }
225
- let kbb = kebabCase(propertyKey);
226
- attrSet?.add(kbb);
227
- }
228
- //observeAttrs
229
- if (!has(target.constructor, 'observedAttributes')) {
230
- target.constructor.observedAttributes = [];
231
- }
232
- target.constructor.observedAttributes = toArray(attrSet);
233
- target.constructor[DecoratorKey.PROPS][propertyKey] = options;
234
- }
235
- //内部接口
236
- const emptySet = new Set;
237
- function _getObservedAttrs(ctor) {
238
- return ObservedAttrsMap.get(ctor) ?? emptySet;
239
- }
240
-
241
- /**
242
- * 用于提供全局state状态管理
243
- * @author holyhigh2
244
- */
245
- const EVENT_UPDATE = 'update';
246
- const Collector = {
247
- collectWatch(comp, updater, subPath) {
248
- let collectVarMap = WATCH_MAP.get(comp);
249
- if (!collectVarMap) {
250
- collectVarMap = {};
251
- WATCH_MAP.set(comp, collectVarMap);
252
- }
253
- let list = collectVarMap[subPath];
254
- if (!list)
255
- list = collectVarMap[subPath] = [];
256
- list.push(updater);
257
- },
258
- startCollect(comp, type) {
259
- this.__collectType = type;
260
- this.__collecting = comp;
261
- },
262
- setUpdater(updater) {
263
- this.__updater = updater;
264
- },
265
- endCollect() {
266
- this.__collecting = null;
267
- },
268
- //仅用于指令在构造时获取
269
- __directiveQ: [],
270
- setDirectiveQ(val) {
271
- let lastVar = last(this.__directiveQ);
272
- const vj = val ? val.join(',') : '';
273
- const lj = lastVar ? lastVar.join(',') : '';
274
- if (lastVar && vj === lj)
275
- return;
276
- if (lastVar && lastVar.length < val.length && startsWith(vj, lj)) {
277
- this.__directiveQ[this.__directiveQ.length - 1] = val;
278
- return;
279
- }
280
- this.__directiveQ.push(val);
281
- },
282
- popDirectiveQ() {
283
- let rs = concat(this.__directiveQ);
284
- this.__directiveQ = [];
285
- return rs;
286
- },
287
- startRender(context) {
288
- this.__renderCollecting = true;
289
- this.__renderContext = context;
290
- },
291
- endRender(component) {
292
- //注册依赖
293
- this.__renderCollection.forEach((varPath) => {
294
- component._regDeps(varPath, this.__renderContext);
295
- });
296
- this.__renderCollection.clear();
297
- this.__renderCollecting = false;
298
- this.__renderContext = null;
299
- },
300
- collect(prop) {
301
- this.__renderCollection.add(prop);
302
- },
303
- clear() {
304
- this.__directiveQ = [];
305
- },
306
- __updater: null,
307
- __collecting: null,
308
- __collectType: -1,
309
- __renderCollection: new Set(),
310
- __renderContext: null,
311
- __renderCollecting: false,
312
- __skipCheck: false
313
- };
314
- const OBJECT_META_DATA = new WeakMap();
315
- const OBJECT_VAR_PATH = new WeakMap();
316
- const COMPUTED_MAP = new WeakMap();
317
- const CSS_MAP = new WeakMap();
318
- const WATCH_MAP = new WeakMap();
319
- /**
320
- * 1. 初始化时obj都是普通对象
321
- * 2. OBJECT_VAR_PATH 首次是普通对象
322
- * 3. OBJECT_META_DATA 直接绑定代理对象
323
- * @param obj
324
- * @param context
325
- * @returns
326
- */
327
- function reactive(obj, context) {
328
- if (!isObject(obj))
329
- return obj;
330
- const proxyObject = obj.__proxy ? obj : new Proxy(obj, {
331
- get(target, prop, receiver) {
332
- if (!prop)
333
- return undefined;
334
- const value = Reflect.get(target, prop, receiver);
335
- if ((Collector.__renderCollecting || Collector.__collecting) && target.hasOwnProperty(prop)) {
336
- let chain = OBJECT_VAR_PATH.get(receiver) ?? [];
337
- let subChain = concat(chain, [prop]);
338
- let subChainStr = subChain.join('-');
339
- if (Collector.__renderCollecting) {
340
- Collector.collect(_toUpdatePath(subChain));
341
- Collector.setDirectiveQ(subChain);
342
- }
343
- else if (Collector.__collecting) {
344
- let collectVarMap;
345
- switch (Collector.__collectType) {
346
- case CollectorType.COMPUTED:
347
- collectVarMap = COMPUTED_MAP.get(Collector.__collecting);
348
- if (!collectVarMap) {
349
- collectVarMap = {};
350
- COMPUTED_MAP.set(Collector.__collecting, collectVarMap);
351
- }
352
- break;
353
- case CollectorType.CSS:
354
- collectVarMap = CSS_MAP.get(Collector.__collecting);
355
- if (!collectVarMap) {
356
- collectVarMap = {};
357
- CSS_MAP.set(Collector.__collecting, collectVarMap);
358
- }
359
- break;
360
- }
361
- let list = collectVarMap[subChainStr];
362
- if (!list)
363
- list = collectVarMap[subChainStr] = [];
364
- list.push(Collector.__updater);
365
- }
366
- }
367
- return value;
368
- },
369
- set(target, prop, newValue, receiver) {
370
- if (!prop)
371
- return false;
372
- let ov = target[prop];
373
- if (!isObject(ov) && ov === newValue)
374
- return true;
375
- if (Number.isNaN(newValue) && Number.isNaN(ov))
376
- return true;
377
- let chain = OBJECT_VAR_PATH.get(receiver) ?? [];
378
- let subChain = concat(chain, [prop]);
379
- let sourceContext = OBJECT_META_DATA.get(receiver).from;
380
- let propDefs = get(sourceContext.constructor, DecoratorKey.PROPS);
381
- let stateDefs = get(sourceContext.constructor, DecoratorKey.STATES);
382
- let hasChanged = get(propDefs, [subChain[0], 'hasChanged']) || get(stateDefs, [subChain[0], 'hasChanged']);
383
- if (hasChanged) {
384
- if (!hasChanged.call(sourceContext, newValue, ov))
385
- return true;
386
- }
387
- else {
388
- //默认对比算法
389
- if (ov === newValue && !ChangedMap.has(ov)) {
390
- return true;
391
- }
392
- }
393
- if (propDefs && propDefs[prop] && target.__isData) {
394
- if (propDefs[prop].sync) {
395
- sourceContext.emit(EVENT_UPDATE + ":" + prop, { value: newValue });
396
- }
397
- }
398
- let deps = OBJECT_META_DATA.get(receiver)?.contextSet;
399
- //get oldValue from sourceContext
400
- let nv = newValue;
401
- if (isObject(newValue) && !isFunction(newValue) && !(newValue instanceof Node) && !Object.isFrozen(newValue)) {
402
- deps.forEach(dep => {
403
- let pathMap = OBJECT_META_DATA.get(receiver)?.pathMap;
404
- let pathAry = pathMap?.get(dep);
405
- if (!pathAry)
406
- return;
407
- subChain = concat(pathAry, [prop]);
408
- OBJECT_VAR_PATH.set(nv, subChain);
409
- nv = reactive(nv, dep);
410
- OBJECT_VAR_PATH.set(nv, subChain);
411
- });
412
- }
413
- let rs = Reflect.set(target, prop, nv);
414
- let pathMap = OBJECT_META_DATA.get(receiver).pathMap;
415
- deps.forEach(dep => {
416
- //view update
417
- let pathAry = pathMap.get(dep);
418
- if (!pathAry)
419
- return;
420
- if (dep === sourceContext) {
421
- //fix the index change of array item
422
- if (chain.length > 1 && pathAry.length > 1 && chain[0] === pathAry[0]) {
423
- pathAry = chain;
424
- }
425
- }
426
- //数组length属性变动直接通知为数组自身变动
427
- subChain = concat(pathAry, prop == 'length' && isArray(receiver) ? [] : [prop]);
428
- //computed
429
- let computedMap = COMPUTED_MAP.get(dep);
430
- //css
431
- let cssMap = CSS_MAP.get(dep);
432
- //watch
433
- let watchMap = WATCH_MAP.get(dep);
434
- //recur path
435
- if (computedMap || cssMap || watchMap) {
436
- let i = subChain.length;
437
- while (i) {
438
- let subPath = subChain.slice(0, i).join('-');
439
- if (watchMap) {
440
- const watchList = watchMap[subPath];
441
- if (i === subChain.length) {
442
- watchList?.forEach((wk) => {
443
- let updater = wk();
444
- updater.ov = ov;
445
- // wk()(ov)
446
- Queue.pushWatch(updater);
447
- });
448
- }
449
- else {
450
- watchList?.forEach((wk) => {
451
- let updater = wk();
452
- if (get(updater, 'deep')) {
453
- // updater(ov)
454
- updater.ov = ov;
455
- Queue.pushWatch(updater);
456
- }
457
- });
458
- }
459
- }
460
- if (computedMap) {
461
- let computedList = computedMap[subPath];
462
- if (!isEmpty(computedList)) {
463
- for (let l = 0; l < computedList.length; l++) {
464
- const updater = computedList[l];
465
- // updater()
466
- Queue.pushComputed(updater);
467
- }
468
- }
469
- }
470
- if (cssMap) {
471
- let computedCssList = cssMap[subPath];
472
- if (!isEmpty(computedCssList)) {
473
- for (let l = 0; l < computedCssList.length; l++) {
474
- const updater = computedCssList[l];
475
- // updater()
476
- Queue.pushCss(updater);
477
- }
478
- }
479
- }
480
- i--;
481
- }
482
- }
483
- let updater = dep._notify(ov, subChain);
484
- Queue.pushNext(updater);
485
- });
486
- return rs;
487
- }
488
- });
489
- if (!obj.__proxy) {
490
- Reflect.defineProperty(obj, "__proxy", {
491
- enumerable: false,
492
- writable: false,
493
- configurable: false,
494
- value: true,
495
- });
496
- }
497
- let chain = OBJECT_VAR_PATH.get(obj) ?? [];
498
- if (Object.isExtensible(obj) && !OBJECT_META_DATA.get(proxyObject)) {
499
- let contextSet = new Set();
500
- contextSet.add(context);
501
- //对象所属context
502
- let pathMap = new WeakMap();
503
- pathMap.set(context, chain);
504
- OBJECT_META_DATA.set(proxyObject, {
505
- from: context,
506
- contextSet,
507
- pathMap
508
- });
509
- }
510
- else {
511
- let deps = OBJECT_META_DATA.get(proxyObject).contextSet;
512
- deps.add(context);
513
- let pathMap = OBJECT_META_DATA.get(proxyObject).pathMap;
514
- let chains = pathMap.get(context);
515
- let subChain = concat(chain);
516
- if (chains && chains.join('') !== subChain.join('')) {
517
- let parentVar = get(context, initial(chains));
518
- //处理数组元素更新,如 ary.1 -> ary.0
519
- if (!isArray(parentVar)) {
520
- showWarn(`The object is referenced by more than one @state '${subChain.join('.')},${chains.join('.')}'`);
521
- }
522
- chains = subChain;
523
- }
524
- else {
525
- pathMap.set(context, subChain);
526
- }
527
- }
528
- for (let k in obj) {
529
- const v = obj[k];
530
- if (isObject(v) && !v.__proxy && !isFunction(v) && !(v instanceof Node) && !Object.isFrozen(v)) {
531
- OBJECT_VAR_PATH.set(v, concat(chain, [k]));
532
- obj[k] = reactive(v, context);
533
- OBJECT_VAR_PATH.set(obj[k], concat(chain, [k]));
534
- }
535
- }
536
- return proxyObject;
537
- }
538
- class Queue {
539
- static watchSet = new Set();
540
- static computedSet = new Set();
541
- static cssSet = new Set();
542
- static nextSet = new Set();
543
- static nextPending = false;
544
- static next;
545
- static {
546
- const p = Promise.resolve();
547
- const nextFn = Queue.flush;
548
- Queue.next = () => {
549
- p.then(nextFn);
550
- };
551
- }
552
- static flush() {
553
- Queue.nextPending = false;
554
- let wq = Array.from(Queue.watchSet);
555
- Queue.watchSet.clear();
556
- let cq = Array.from(Queue.computedSet);
557
- Queue.computedSet.clear();
558
- let sq = Array.from(Queue.cssSet);
559
- Queue.cssSet.clear();
560
- let nq = Array.from(Queue.nextSet);
561
- Queue.nextSet.clear();
562
- wq.forEach(u => u(get(u, 'ov')));
563
- cq.forEach(u => u());
564
- sq.forEach(u => u());
565
- nq.forEach(u => u());
566
- }
567
- static pushWatch(updater) {
568
- Queue.watchSet.add(updater);
569
- }
570
- static pushComputed(updater) {
571
- Queue.computedSet.add(updater);
572
- }
573
- static pushCss(updater) {
574
- Queue.cssSet.add(updater);
575
- }
576
- static pushNext(updater) {
577
- Queue.nextSet.add(updater);
578
- if (!Queue.nextPending) {
579
- Queue.nextPending = true;
580
- Queue.next();
581
- }
582
- }
583
- }
584
-
585
- /**
586
- * 视图基类 为组件视图及指令子视图提供统一服务
587
- * @param spuerClass
588
- * @returns
589
- */
590
- function View(spuerClass) {
591
- //mixin class
592
- return class extends spuerClass {
593
- __updatePoints;
594
- /**
595
- * 渲染上下文所属组件,仅用于指令
596
- */
597
- renderComponent;
598
- buildView(tmpl) {
599
- let comp = this instanceof CompElem ? this : this.renderComponent;
600
- let [html, vars] = buildHTML(comp, tmpl);
601
- let updatePoints = [];
602
- let nodes = buildTmplate(updatePoints, html, vars, comp, this);
603
- this.__updatePoints = updatePoints;
604
- return nodes;
605
- }
606
- updateView(tmpl) {
607
- if (isBlank(join(tmpl.strings)))
608
- return;
609
- if (!this.__updatePoints)
610
- return;
611
- let { vars } = tmpl;
612
- let comp = this instanceof CompElem ? this : this.renderComponent;
613
- for (let i = 0; i < this.__updatePoints.length; i++) {
614
- const up = this.__updatePoints[i];
615
- let varIndex = up.varIndex;
616
- let oldValue = up.value;
617
- let newValue = vars;
618
- let node = up.node;
619
- let indexSegs = split(varIndex, '-');
620
- for (let l = 0; l < indexSegs.length; l++) {
621
- const seg = indexSegs[l];
622
- newValue = get(newValue, seg);
623
- if (newValue && newValue.vars && i < indexSegs.length - 1) {
624
- newValue = newValue.vars;
625
- }
626
- }
627
- //check
628
- if (!isObject(oldValue) && oldValue === newValue)
629
- continue;
630
- let elNode = node;
631
- if (up.isDirective) {
632
- if (!oldValue.di)
633
- continue; //指令还在异步执行中,不更新
634
- //指令
635
- newValue.di = oldValue.di;
636
- newValue.di.renderParams = newValue.varChain;
637
- newValue.di._renderArgs = newValue.args;
638
- newValue.point = oldValue.point;
639
- newValue.varPath = oldValue.varPath;
640
- oldValue.update(oldValue.point, newValue.args, oldValue.args);
641
- }
642
- else if (up.isToggleProp) {
643
- //布尔特性
644
- if ((!!newValue) === oldValue)
645
- continue;
646
- elNode.toggleAttribute(up.attrName, !!newValue);
647
- set(elNode, up.attrName, !!newValue);
648
- }
649
- else if (up.isProp) {
650
- //子组件属性
651
- if (!isObject(newValue) && newValue === oldValue)
652
- continue;
653
- let ck = camelCase(up.attrName);
654
- let propDefs = get(up.node.constructor, DecoratorKey.PROPS);
655
- if (propDefs) {
656
- let propDef = propDefs[ck];
657
- if (propDef && propDef.hasChanged && !propDef.hasChanged.call(this, newValue, oldValue))
658
- continue;
659
- }
660
- // if (isPlainObject(newValue) && isEqual(newValue, oldValue)) continue;
661
- // if (isArray(newValue) && isArray(oldValue) && isEqual(newValue, oldValue)) continue;
662
- //如果node是slot则触发组件的slot更新
663
- if (node instanceof CompElem) {
664
- node._updateProps({ [up.attrName]: newValue });
665
- }
666
- else if (node instanceof HTMLSlotElement) {
667
- comp._updateSlot(node.getAttribute('name') || 'default', up.attrName, newValue);
668
- }
669
- }
670
- else if (up.attrName && !up.isEvent) {
671
- //特性
672
- if (!isEqual(oldValue, newValue)) {
673
- switch (up.attrName) {
674
- case 'value':
675
- if (node instanceof HTMLInputElement) {
676
- node.value = newValue;
677
- break;
678
- }
679
- default:
680
- node.setAttribute(up.attrName, replace(up.attrTmpl, PLACEHOLDER_EXP, newValue + ''));
681
- }
682
- }
683
- }
684
- else if (up.isTmpl) {
685
- //这里一定是子视图更新,子视图仅更新内部__expose
686
- if (newValue.strings.join() !== oldValue.tmpl.strings.join()) {
687
- up.value.updateView(newValue);
688
- }
689
- else if (newValue.vars.some((v) => isObject(v) && !isPlainObject(v)) || oldValue.tmpl.vars.some((v) => isObject(v) && !isPlainObject(v)) || !isEqual(newValue.vars, oldValue.tmpl.vars)) {
690
- up.value.updateView(newValue);
691
- }
692
- oldValue.tmpl = newValue;
693
- newValue = oldValue; //new SubView(newValue)
694
- }
695
- else if (up.isText) {
696
- let textNode = up.textNode.nextSibling;
697
- if (textNode && textNode === up.node.previousSibling) {
698
- textNode.textContent = newValue;
699
- }
700
- else {
701
- DomUtil.remove(up.textNode, up.node);
702
- DomUtil.insertBefore(up.node, [newValue]);
703
- }
704
- }
705
- up.value = newValue;
706
- } //endfor
707
- }
708
- };
709
- }
710
- /**
711
- * 子视图,用于组件视图模板中的非指令子模版
712
- */
713
- class SubView extends View(Object) {
714
- tmpl;
715
- constructor(tmpl) {
716
- super();
717
- this._renderVars = get(tmpl, '_renderVars');
718
- this.tmpl = tmpl;
719
- }
720
- }
721
-
722
- const ATTR_CSS_LINK = "css-link";
723
- const PropTypeMap = {
724
- boolean: Boolean,
725
- string: String,
726
- number: Number,
727
- object: Object,
728
- array: Array,
729
- function: Function,
730
- bigint: BigInt,
731
- symbol: Symbol,
732
- undefined: Object
733
- };
734
- const PrivatePreffix = '#';
735
- //组件静态样式
736
- const ComponentStyleMap = new WeakMap();
737
- let DefaultCss = [];
738
- /**
739
- * CompElem基类,意为组件元素。提供了基本内置属性及生命周期等必备接口
740
- * 每个组件都需要继承自该类
741
- *
742
- * @author holyhigh2
743
- */
744
- class CompElem extends View(HTMLElement) {
745
- static __l_globalRule = document.createElement("style");
746
- static {
747
- document.head.appendChild(CompElem.__l_globalRule);
748
- }
749
- //设置全局/组件默认属性
750
- static defaults(options) {
751
- DefaultCss = flatMap(options.css, c => {
752
- if (isString(c)) {
753
- let sheet = new CSSStyleSheet();
754
- sheet.replaceSync(c);
755
- return sheet;
756
- }
757
- else if (c instanceof CSSStyleSheet) {
758
- return c;
759
- }
760
- return [];
761
- });
762
- //todo...
763
- options.global;
764
- each(options, (v, k) => {
765
- if (test(k[0], /[A-Z]/)) ;
766
- });
767
- }
768
- #slotPropsMap = {};
769
- #data = { '#slots': {} };
770
- #reactiveData = {};
771
- #updateSources = {};
772
- #shadow;
773
- #selfObserver;
774
- //保存所有渲染上下文 {CompElem/Directive}
775
- #renderContextList = {};
776
- __events = {};
777
- get [Symbol.toStringTag]() {
778
- return this.constructor.name;
779
- }
780
- get reactiveData() {
781
- return this.#reactiveData;
782
- }
783
- get attrs() {
784
- return this.#attrs;
785
- }
786
- get props() {
787
- return this.#props;
788
- }
789
- get renderRoot() {
790
- return this.#renderRoot;
791
- }
792
- get renderRoots() {
793
- return this.#renderRoots;
794
- }
795
- get parentComponent() {
796
- return this.#parentComponent;
797
- }
798
- get slotHooks() {
799
- return this.#slotHooks;
800
- }
801
- get css() {
802
- return ComponentStyleMap.get(this.constructor);
803
- }
804
- get isMounted() {
805
- return this.#mounted;
806
- }
807
- //slots列表中绝对不会出现slot元素
808
- get slots() {
809
- return this.#data['#slots'];
810
- }
811
- #attrs;
812
- #props;
813
- #renderRoot;
814
- #renderRoots;
815
- #parentComponent;
816
- #slotsEl = {};
817
- #slotHooks = {};
818
- #slotNodes = {};
819
- #mounted = false;
820
- /**
821
- * 是否自动插入插槽,如果需要控制插槽类型时,可以设置为false
822
- */
823
- static get autoSlot() {
824
- return true;
825
- }
826
- //////////////////////////////////// styles
827
- /**
828
- * 组件样式,CSSStyleSheet可动态变更
829
- */
830
- static get styles() {
831
- return [];
832
- }
833
- static get globalStyles() {
834
- return [];
835
- }
836
- get styles() {
837
- return [];
838
- }
839
- #inited = false;
840
- constructor(...args) {
841
- super();
842
- //init props via constructor
843
- if (size(args) === 1) {
844
- this.#props = {};
845
- assign(this.#props, first(args));
846
- }
847
- let render = this.render.bind(this);
848
- this.render = function () {
849
- let rs;
850
- Collector.startRender(this);
851
- rs = render();
852
- Collector.endRender(this);
853
- return rs;
854
- };
855
- /////////////////////////////////////////////////// styles
856
- //global styles
857
- let globalStyles = get(this.constructor, "globalStyles");
858
- let beAttached = get(this.constructor, '_global_style_attached');
859
- if (!isEmpty(globalStyles) && beAttached !== '1') {
860
- let globalTextContent = "";
861
- globalStyles.forEach((st) => {
862
- if (isString(st)) {
863
- globalTextContent += st + "\n";
864
- }
865
- });
866
- CompElem.__l_globalRule.textContent += globalTextContent;
867
- set(this.constructor, '_global_style_attached', '1');
868
- }
869
- //component styles
870
- let beAttached2 = ComponentStyleMap.get(this.constructor);
871
- let styleSheets = beAttached2 ?? [];
872
- if (!beAttached2) {
873
- each(get(this.constructor, "styles"), (st) => {
874
- if (isString(st)) {
875
- let sheet = new CSSStyleSheet();
876
- sheet.replaceSync(st);
877
- styleSheets.push(sheet);
878
- }
879
- else {
880
- styleSheets.push(st);
881
- }
882
- });
883
- ComponentStyleMap.set(this.constructor, styleSheets);
884
- }
885
- /////////////////////////////////////////////////// shadow
886
- this.#shadow = this.attachShadow({
887
- mode: "open",
888
- slotAssignment: get(this.constructor, "autoSlot", true) ? "named" : "manual",
889
- });
890
- this.#shadow.adoptedStyleSheets = [...DefaultCss, ...styleSheets];
891
- //check link
892
- let cssLink = this.attributes.getNamedItem(ATTR_CSS_LINK)?.value;
893
- if (cssLink) {
894
- const link = document.createElement("style");
895
- link.textContent = `@import "${cssLink}"`;
896
- this.#shadow.appendChild(link);
897
- }
898
- let filterSlotFn = debounce(this.#filterSlot, 20);
899
- this.#selfObserver = new MutationObserver(mutations => {
900
- for (let i = 0; i < mutations.length; i++) {
901
- const mutation = mutations[i];
902
- if (mutation.type === 'childList') {
903
- filterSlotFn.call(this);
904
- }
905
- }
906
- });
907
- //slots prop map
908
- this._slotsPropMap = { default: [] };
909
- /////////////////////////////////////////////////// decorators create
910
- let ary = get(this.constructor, _DecoratorsKey);
911
- ary && ary.sort((a, b) => b.priority - a.priority).forEach(dw => dw.create(this));
912
- this.#updatedD = this.#update.bind(this);
913
- }
914
- #updatedD;
915
- connectedCallback() {
916
- //parent
917
- let node = closest(this.parentNode, (node) => node instanceof CompElem || node.host instanceof CompElem, "parentNode");
918
- this.#parentComponent = node
919
- ? node instanceof CompElem
920
- ? node
921
- : node.host
922
- : null;
923
- this.__init();
924
- }
925
- disconnectedCallback() {
926
- this.#selfObserver.disconnect();
927
- }
928
- //////////////////////////////////// lifecycles
929
- //********************************** 首次渲染
930
- //构造时上级传递的参数
931
- __init() {
932
- if (this.#inited)
933
- return;
934
- /////////////////////////////////////////////////// slots
935
- this.#updateSlotsAry();
936
- //check props
937
- const props = this.#initProps();
938
- this.propsReady(props);
939
- for (const key in props) {
940
- const v = props[key];
941
- this.#data[key] = v;
942
- }
943
- this.#initStates();
944
- //define reactive
945
- each(this.#data, (v, k) => {
946
- let descr = Reflect.getOwnPropertyDescriptor(this.#data, k);
947
- Reflect.defineProperty(this, k, {
948
- get() {
949
- let v = Reflect.get(this.#reactiveData, k);
950
- return descr?.get ? descr?.get() : v;
951
- },
952
- set(v) {
953
- if (descr?.set) {
954
- descr?.set(v);
955
- }
956
- else {
957
- Reflect.set(this.#reactiveData, k, v);
958
- }
959
- },
960
- });
961
- });
962
- Reflect.defineProperty(this.#data, '__isData', {
963
- enumerable: false,
964
- value: true
965
- });
966
- this.#reactiveData = reactive(this.#data, this);
967
- //render
968
- let tmpl = this.render();
969
- let nodes = this.buildView(tmpl);
970
- if (nodes) {
971
- let children = toArray(nodes);
972
- children.forEach((c) => {
973
- this.#shadow.appendChild(c);
974
- });
975
- this.#renderRoots = children;
976
- this.#renderRoot = children[0];
977
- }
978
- //filter slot before append to dom
979
- this.#filterSlot();
980
- this.beforeMount();
981
- this.#selfObserver.observe(this, { childList: true });
982
- /////////////////////////////////////////////////// before mount
983
- const that = this;
984
- let ary = get(this.constructor, _DecoratorsKey);
985
- ary && ary.sort((a, b) => b.priority - a.priority).forEach(dw => {
986
- dw.beforeMount(this, (key, value) => {
987
- that.#reactiveData[key] = value;
988
- return that.#reactiveData[key];
989
- });
990
- });
991
- //watch
992
- let watchMap = get(this.constructor, DecoratorKey.WATCH);
993
- each(watchMap, (watchList, k) => {
994
- watchList.forEach(v => {
995
- let { source, options, handler } = v;
996
- let fn = handler.bind(this);
997
- let onceWatch = get(options, "once", false);
998
- if (onceWatch) {
999
- fn = once(fn);
1000
- }
1001
- const updater = (function (ov) {
1002
- let nv = get(this, source.replaceAll('-', '.'));
1003
- fn(nv, ov, source);
1004
- }).bind(this);
1005
- let deep = get(options, "deep", false);
1006
- updater.deep = deep;
1007
- Collector.collectWatch(this, () => updater, k);
1008
- let immediate = get(options, "immediate", false);
1009
- if (!immediate)
1010
- return;
1011
- let nv = get(this, source.replaceAll('-', '.'));
1012
- fn(nv, nv, source);
1013
- });
1014
- });
1015
- //computed
1016
- let computedMap = get(this.constructor, DecoratorKey.COMPUTED);
1017
- each(computedMap, (getter, propKey) => {
1018
- Collector.startCollect(this, CollectorType.COMPUTED);
1019
- Collector.setUpdater(() => {
1020
- this.#reactiveData[propKey] = getter.call(this);
1021
- });
1022
- this.#data[propKey] = getter.call(this);
1023
- Collector.endCollect();
1024
- Reflect.defineProperty(this, propKey, {
1025
- get() {
1026
- return Reflect.get(this.#reactiveData, propKey);
1027
- },
1028
- set(v) {
1029
- showTagError(this.tagName, "Cannot set a computed property '" + propKey + "'");
1030
- },
1031
- });
1032
- });
1033
- //events
1034
- let eventList = get(this.constructor, DecoratorKey.EVENTS);
1035
- eventList && eventList.forEach((ev) => {
1036
- let name = ev.name;
1037
- let options = assign({ target: document, once: false, passive: false, capture: false }, ev.options);
1038
- let listener = bind$1(ev.fn, this);
1039
- let target = options.target;
1040
- if (isFunction(target)) {
1041
- target = target.call(this, this);
1042
- }
1043
- if (!target) {
1044
- showTagError(this.tagName, "The target of @event('" + name + "',...) is invalid");
1045
- return;
1046
- }
1047
- target.addEventListener(name, listener, options);
1048
- });
1049
- //slot hook
1050
- each(this.#slotHooks, (v, k) => {
1051
- this.#updateSlot(k);
1052
- });
1053
- //instance dynamic style
1054
- Collector.startCollect(this, CollectorType.CSS);
1055
- let cssAry = [];
1056
- this.styles.forEach(st => {
1057
- if (!isFunction(st))
1058
- return;
1059
- let cssss = new CSSStyleSheet();
1060
- cssAry.push(cssss);
1061
- Collector.setUpdater(() => {
1062
- let css = st() ?? '';
1063
- cssss.replaceSync(css);
1064
- });
1065
- let css = st();
1066
- if (isBlank(css))
1067
- return;
1068
- cssss.replaceSync(css);
1069
- });
1070
- Collector.endCollect();
1071
- this.#shadow.adoptedStyleSheets = [...this.#shadow.adoptedStyleSheets, ...cssAry];
1072
- setTimeout(() => {
1073
- this.#mounted = true;
1074
- this.mounted();
1075
- ary && ary.forEach(dw => {
1076
- dw.mounted(this, (key, value) => {
1077
- that.#reactiveData[key] = value;
1078
- return that.#reactiveData[key];
1079
- });
1080
- });
1081
- }, 0);
1082
- this.#inited = true;
1083
- }
1084
- propsReady(props) { }
1085
- render() {
1086
- throw Error(`[CompElem <${this.tagName}>] Missing render()`);
1087
- }
1088
- beforeMount() { }
1089
- mounted() { }
1090
- #onSlogChange(slot, name) {
1091
- //1. 更新 _slotsPropMap & slots
1092
- this.#updateSlotsAry();
1093
- //2. 设置attrs
1094
- let props = get(this.#slotPropsMap[name], 'props');
1095
- if (props) {
1096
- each(this.slots, (nodeAry, k) => {
1097
- nodeAry.filter(node => node.nodeType === Node.ELEMENT_NODE).forEach((node) => {
1098
- if (node instanceof CompElem) {
1099
- // node._setParentProps(props)
1100
- node._updateProps(props);
1101
- return;
1102
- }
1103
- each(props, (v, k) => {
1104
- if (node instanceof HTMLSlotElement) {
1105
- let compOfSlot = get(node, '__l_comp');
1106
- if (compOfSlot) {
1107
- let sname = node.name || 'default';
1108
- let slotMap = compOfSlot.#slotPropsMap[sname];
1109
- if (!slotMap) {
1110
- slotMap = compOfSlot.#slotPropsMap[sname] = { props: {} };
1111
- }
1112
- if (!slotMap.props) {
1113
- slotMap.props = {};
1114
- }
1115
- slotMap.props[k] = v;
1116
- compOfSlot.#onSlogChange(node, sname);
1117
- }
1118
- }
1119
- else {
1120
- node.setAttribute(k, v);
1121
- }
1122
- });
1123
- });
1124
- });
1125
- }
1126
- //3. callback
1127
- this.slotChange(slot, name);
1128
- }
1129
- slotChange(slot, name) { }
1130
- attributeChangedCallback(attributeName, oldValue, newValue) {
1131
- this.#attrChanged(attributeName, oldValue, newValue);
1132
- }
1133
- //********************************** 更新
1134
- /**
1135
- * 是否需要更新,可获取变更属性
1136
- * 返回true时更新
1137
- */
1138
- shouldUpdate(changed) {
1139
- return true;
1140
- }
1141
- /**
1142
- * 1. 调用render
1143
- * 2. 更新@query/all
1144
- * 3. 更新ref
1145
- * 4. 更新prop到attr的映射
1146
- * @param changed
1147
- */
1148
- updated(changed) { }
1149
- /**
1150
- * 抛出自定义事件
1151
- * @param evName 事件名称
1152
- * @param args 自定义参数
1153
- */
1154
- emit(evName, arg = {}, options) {
1155
- if (options && options.event) {
1156
- arg.event = options.event;
1157
- }
1158
- arg.target = this;
1159
- this.dispatchEvent(new CustomEvent(evName, {
1160
- bubbles: get(options, "bubbles", false),
1161
- composed: get(options, "composed", false),
1162
- cancelable: true,
1163
- detail: arg,
1164
- }));
1165
- }
1166
- #rootEvs = {};
1167
- /**
1168
- * 在root上绑定事件
1169
- * @param evName
1170
- * @param hook
1171
- */
1172
- on(evName, hook) {
1173
- if (!this.#rootEvs[evName]) {
1174
- this.#rootEvs[evName] = [];
1175
- }
1176
- let cbk = hook.bind(this);
1177
- this.#rootEvs[evName].push(cbk);
1178
- this.addEventListener(evName, cbk);
1179
- }
1180
- /**
1181
- * 下一帧执行
1182
- * @param cbk
1183
- */
1184
- nextTick(cbk) {
1185
- Queue.pushNext(cbk);
1186
- }
1187
- /**
1188
- * 强制更新一次视图
1189
- */
1190
- forceUpdate() {
1191
- each(this.#reactiveData, (v, k) => {
1192
- this.#updateSources[k] = {
1193
- value: undefined,
1194
- chain: undefined,
1195
- };
1196
- });
1197
- this.#update();
1198
- }
1199
- /**
1200
- * 由监控变量调用
1201
- * @param stateKey
1202
- * @param ov
1203
- * @param rootStateKey 如果是对象内部属性变更,会返回根属性名
1204
- * @returns
1205
- */
1206
- _notify(ov, chain) {
1207
- //todo 1. 取消data - 0这个层级的监控;需要验证删除行时的路径
1208
- let varPath = [];
1209
- for (let i = 0; i < chain.length; i++) {
1210
- const seg = chain[i];
1211
- varPath.push(seg);
1212
- let v = get(this, varPath);
1213
- let pathStr = _toUpdatePath(varPath);
1214
- this.#updateSources[pathStr] = { value: v, chain: pathStr === "slots" ? ['slots'] : varPath, oldValue: ov, end: varPath.length === chain.length };
1215
- if (isObject(v) && pathStr[0] != PrivatePreffix) {
1216
- ChangedMap.set(v, pathStr);
1217
- }
1218
- }
1219
- return this.#updatedD;
1220
- }
1221
- #update() {
1222
- if (size(this.#updateSources) < 1)
1223
- return;
1224
- const changed = this.#updateSources;
1225
- this.#updateSources = {};
1226
- //update decorators
1227
- let ary = get(this.constructor, _DecoratorsKey);
1228
- ary && ary.sort((a, b) => b.priority - a.priority).forEach(dw => {
1229
- dw.updated(this, changed);
1230
- });
1231
- let toBreak = !this.shouldUpdate(changed);
1232
- if (toBreak)
1233
- return;
1234
- let renderContextList = new Set();
1235
- //1. filter context
1236
- each(changed, ({ value, chain, oldValue }, k) => {
1237
- if (this.#renderContextList[k]) {
1238
- this.#renderContextList[k].forEach(cx => {
1239
- renderContextList.add(cx);
1240
- });
1241
- }
1242
- });
1243
- //2. update context
1244
- renderContextList.forEach(context => {
1245
- if (context === this) {
1246
- this.updateView(this.render());
1247
- }
1248
- else {
1249
- //指令在这里仅更新视图
1250
- let rs = context.render(...(context._renderArgs ? context._renderArgs : []));
1251
- if (rs)
1252
- context.updateView(rs);
1253
- }
1254
- });
1255
- //update slot view
1256
- this.#updateSlots.forEach((v) => {
1257
- this.#updateSlot(v);
1258
- });
1259
- this.updated(changed);
1260
- each(changed, ({ value, chain, oldValue }, k) => {
1261
- if (isObject(value) && ChangedMap.has(value)) {
1262
- ChangedMap.delete(value);
1263
- }
1264
- });
1265
- }
1266
- /**
1267
- * 1. 初始props中并未包含的属性,可从attributes取,且定义类型不是string时自动转换
1268
- * 2. 如果attributes中也未出现且必填报错
1269
- * 3. 否则设置默认值
1270
- * @returns 非props的attr集合
1271
- */
1272
- #initProps() {
1273
- let propDefs = get(this.constructor, DecoratorKey.PROPS);
1274
- let attrs = this.attributes;
1275
- let tagName = this.tagName;
1276
- let parentProps = this.#props;
1277
- let filterAttrs = {};
1278
- each(attrs, ({ name, value }) => {
1279
- if (name[0] === ATTR_PREFIX_EVENT ||
1280
- name[0] === ATTR_PREFIX_PROP ||
1281
- name[0] === ATTR_PREFIX_BOOLEAN ||
1282
- name === ATTR_REF || name === 'slot')
1283
- return;
1284
- let camelName = camelCase(name);
1285
- if (propDefs && !propDefs[camelName]) {
1286
- filterAttrs[name] = value;
1287
- }
1288
- });
1289
- this.#attrs = this.#attrs ? assign(this.#attrs, filterAttrs) : filterAttrs;
1290
- let rs = {};
1291
- each(propDefs, (def, key) => {
1292
- let propDef = propDefs[key];
1293
- let isInited = has(parentProps, key);
1294
- let defaultVal = get(this, key);
1295
- if (!('_defaultValue' in propDef)) {
1296
- //在构造结束后
1297
- propDef._defaultValue = defaultVal;
1298
- if (!propDef.type) {
1299
- if (isUndefined(defaultVal)) {
1300
- showTagError(tagName, "Prop '" + key + "' has neither propType nor defaultValue be used for type inference");
1301
- }
1302
- let type = typeof defaultVal;
1303
- if (isArray(defaultVal))
1304
- type = 'array';
1305
- let inferredType = PropTypeMap[type];
1306
- propDef.type = inferredType;
1307
- }
1308
- }
1309
- let val = undefined;
1310
- if (isInited) {
1311
- val = isNil(parentProps[key]) ? defaultVal : parentProps[key];
1312
- }
1313
- else {
1314
- val = defaultVal;
1315
- let attr = attrs.getNamedItem(kebabCase(key)) ||
1316
- attrs.getNamedItem(ATTR_PREFIX_PROP + kebabCase(key));
1317
- if (attr) {
1318
- isInited = true;
1319
- val = attr.value;
1320
- }
1321
- }
1322
- //required check
1323
- let isRequired = propDef.required;
1324
- if (isRequired && !isInited) {
1325
- showTagError(tagName, "Prop '" + key + "' is required");
1326
- return false;
1327
- }
1328
- val = this.#propTypeCheck(propDefs, key, val);
1329
- let getter = get(propDefs, [key, 'getter']);
1330
- if (getter)
1331
- getter = bind$1(getter, this);
1332
- let setter = get(propDefs, [key, 'setter']);
1333
- if (setter)
1334
- setter = bind$1(setter, this);
1335
- if (getter || setter) {
1336
- Reflect.defineProperty(this.#data, key, {
1337
- set: setter || function (v) { },
1338
- get: getter
1339
- });
1340
- }
1341
- if (propDef.attribute && isDefined(val) && !isObject(val)) {
1342
- this.setAttribute(kebabCase(key), trim(val));
1343
- }
1344
- this.#data[key] = val;
1345
- rs[key] = val;
1346
- });
1347
- return Object.seal(rs);
1348
- }
1349
- //属性值检测
1350
- #propTypeCheck(propDefs, propKey, newValue) {
1351
- let propDef = propDefs[propKey];
1352
- if (!propDef)
1353
- return newValue;
1354
- let validator = propDef.isValid;
1355
- let expectType = propDef.type;
1356
- let expectTypeAry = isArray(expectType) ? expectType : [expectType];
1357
- let typeConverter = propDef.converter;
1358
- let val = newValue;
1359
- if (!some(expectTypeAry, (et) => et === String) && isString(val) && !isNull(val)) {
1360
- try {
1361
- val = typeConverter ? typeConverter(val) : fval(val, { html });
1362
- }
1363
- catch (error) {
1364
- showTagError(this.tagName, `Convert attribute '${propKey}' error with ` + val);
1365
- }
1366
- } //endif
1367
- //extra work
1368
- for (let i = 0; i < expectTypeAry.length; i++) {
1369
- const et = expectTypeAry[i];
1370
- if (et.name === 'Boolean') {
1371
- if (isString(val) && /(?:^true$)|(?:^false$)/.test(val)) {
1372
- val = fval(val);
1373
- }
1374
- else if (isUndefined(val) || isBlank(val)) {
1375
- val = true;
1376
- }
1377
- }
1378
- }
1379
- let realType = typeof val;
1380
- let matched = isDefined(val) ? false : true;
1381
- for (let i = 0; i < expectTypeAry.length; i++) {
1382
- const et = expectTypeAry[i];
1383
- if (
1384
- //base form
1385
- test(realType, et.name, "i") ||
1386
- //object form
1387
- val instanceof et || (Object.prototype.toString.call(val) === Object.prototype.toString.call(et.prototype))) {
1388
- matched = true;
1389
- break;
1390
- }
1391
- }
1392
- if (!matched) {
1393
- showTagError(this.tagName, `Invalid prop '${propKey}'. expected '${expectTypeAry.map((t) => t.name || t)}' but got '${realType}'`);
1394
- }
1395
- if (validator) {
1396
- if (!validator.call(this, val, this.#data)) {
1397
- showTagError(this.tagName, `Invalid prop '${propKey}'. IsValid() check failed`);
1398
- }
1399
- }
1400
- return val;
1401
- }
1402
- #initStates() {
1403
- let stateDefs = get(this.constructor, DecoratorKey.STATES);
1404
- each(stateDefs, (def, key) => {
1405
- let stateDef = stateDefs[key];
1406
- let val = get(this, key);
1407
- if (stateDef) {
1408
- let propName = stateDef.prop;
1409
- val = propName ? cloneDeep(this.#data[propName]) : get(this, key);
1410
- }
1411
- this.#data[key] = val;
1412
- });
1413
- }
1414
- /**
1415
- * 由外部调用,在初始化及更新时。
1416
- * @param props
1417
- * @param attrs
1418
- */
1419
- #propsReady = debounce(this.propsReady, 100);
1420
- /**
1421
- * @deprecated
1422
- */
1423
- _setParentProps(props, attrs) {
1424
- if (this.#inited) {
1425
- let propDefs = get(this.constructor, DecoratorKey.PROPS);
1426
- //存在attrs表示已初始化完成
1427
- each(props, (v, k) => {
1428
- let ck = camelCase(k);
1429
- let propDef = propDefs[ck];
1430
- if (!propDef)
1431
- return;
1432
- let ov = this.#data[ck];
1433
- v = this.#propTypeCheck(propDefs, ck, v);
1434
- if (propDef.hasChanged && !propDef.hasChanged.call(this, v, ov))
1435
- return;
1436
- this.#data[ck] = v;
1437
- this._notify(ov, [ck]);
1438
- });
1439
- assign(this.#props, props);
1440
- assign(this.#attrs, attrs);
1441
- this.#propsReady(this.#props);
1442
- }
1443
- }
1444
- //todo 这里需要直接修改prop
1445
- _updateProps(props) {
1446
- let propDefs = get(this.constructor, DecoratorKey.PROPS);
1447
- //存在attrs表示已初始化完成
1448
- each(props, (v, k) => {
1449
- let ck = camelCase(k);
1450
- let propDef = propDefs[ck];
1451
- if (!propDef)
1452
- return;
1453
- let ov = this.#data[ck];
1454
- v = this.#propTypeCheck(propDefs, ck, v);
1455
- if (propDef.hasChanged && !propDef.hasChanged.call(this, v, ov))
1456
- return;
1457
- Collector.__skipCheck = true;
1458
- set(this, ck, v);
1459
- Collector.__skipCheck = false;
1460
- });
1461
- assign(this.#props, props);
1462
- this.#propsReady(this.#props);
1463
- }
1464
- _initProps(props, attrs) {
1465
- this.#props = merge(this.#props || {}, props);
1466
- this.#attrs = merge({}, attrs);
1467
- }
1468
- /**
1469
- * 绑定slot标签,render时调用
1470
- */
1471
- _bindSlot(slot, name, props) {
1472
- //1. 设置map
1473
- if (!this.#slotsEl[name]) {
1474
- this.#slotsEl[name] = slot;
1475
- Reflect.defineProperty(slot, '__l_comp', {
1476
- value: this
1477
- });
1478
- }
1479
- slot.addEventListener('slotchange', (e) => {
1480
- if (this.#inited)
1481
- this.#onSlogChange(slot, name === 'default' ? '' : name);
1482
- });
1483
- //3. 保存参数
1484
- if (!isEmpty(props)) {
1485
- let slotMap = this.#slotPropsMap[name];
1486
- if (!slotMap) {
1487
- slotMap = this.#slotPropsMap[name] = {};
1488
- }
1489
- if (props.nodeFilter) {
1490
- slotMap.filter = props.nodeFilter;
1491
- }
1492
- slotMap.props = omit(props, 'nodeFilter');
1493
- }
1494
- }
1495
- _bindSlotHook(name, hook) {
1496
- this.#slotHooks[name] = hook;
1497
- }
1498
- //slot变量变动时触发
1499
- #updateSlots = new Set();
1500
- _updateSlot(name, propName, value) {
1501
- let slotEl = this.#slotsEl[name];
1502
- let hook = this.#slotHooks[name];
1503
- if (!hook && !slotEl)
1504
- return;
1505
- let slotMap = this.#slotPropsMap[name];
1506
- if (propName) {
1507
- if (!slotMap.props) {
1508
- slotMap.props = {};
1509
- }
1510
- slotMap.props[propName] = value;
1511
- }
1512
- if (!!hook) {
1513
- this.#updateSlots.add(name);
1514
- }
1515
- else {
1516
- //update nodes
1517
- let els = slotEl.assignedElements({ flatten: true });
1518
- for (let i = 0; i < els.length; i++) {
1519
- const el = els[i];
1520
- el.setAttribute(propName, value + '');
1521
- }
1522
- }
1523
- }
1524
- #updateSlotsAry() {
1525
- const cs = flatMap(this.childNodes, node => {
1526
- if (node.nodeType === Node.COMMENT_NODE)
1527
- return [];
1528
- if (node instanceof HTMLSlotElement)
1529
- return node.assignedNodes({ flatten: true });
1530
- return node;
1531
- });
1532
- let groups = groupBy(cs, node => {
1533
- // if (node.nodeType === Node.COMMENT_NODE) return ''
1534
- if (node.nodeType === Node.TEXT_NODE)
1535
- return 'default';
1536
- if (node instanceof Element) {
1537
- return node.getAttribute('slot') || 'default';
1538
- }
1539
- });
1540
- if (isEmpty(groups)) {
1541
- if (!isEmpty(this.#data['#slots'])) {
1542
- this.#inited ? this.#reactiveData['#slots'] = {} : this.#data['#slots'] = {};
1543
- }
1544
- return;
1545
- }
1546
- each(groups, (nodeAry, k) => {
1547
- if (!k)
1548
- return;
1549
- while (nodeAry.length > 0) {
1550
- let node = nodeAry[0];
1551
- if ((node.nodeType === Node.TEXT_NODE && isBlank(node.textContent)) ||
1552
- (node instanceof HTMLSlotElement && isEmpty(node.assignedNodes({ flatten: true })))) {
1553
- nodeAry.shift();
1554
- continue;
1555
- }
1556
- break;
1557
- }
1558
- while (nodeAry.length > 0) {
1559
- let node = last(nodeAry);
1560
- if ((node.nodeType === Node.TEXT_NODE && isBlank(node.textContent)) ||
1561
- (node instanceof HTMLSlotElement && isEmpty(node.assignedNodes({ flatten: true })))) {
1562
- nodeAry.pop();
1563
- continue;
1564
- }
1565
- break;
1566
- }
1567
- });
1568
- let rs = {};
1569
- each(groups, (v, k) => {
1570
- if (!isEmpty(v)) {
1571
- rs[k] = v;
1572
- }
1573
- });
1574
- this.#inited ? this.#reactiveData['#slots'] = rs : this.#data['#slots'] = rs;
1575
- }
1576
- #updateSlot(name) {
1577
- let hook = this.#slotHooks[name];
1578
- if (!hook)
1579
- return;
1580
- let slotMap = this.#slotPropsMap[name];
1581
- let slot = this.#data['#slots'][name];
1582
- //slot not ready yet
1583
- //1. 可能是if/each等指令还未插入
1584
- if (!slot)
1585
- return;
1586
- //组件通知渲染异步指令
1587
- this.renderAsync(hook, get(slotMap, 'props'));
1588
- const rc = this._asyncDirectives.get(hook);
1589
- //todo 如果要做成通用异步指令,元素必须插入到指令挂载的位置,并且slot的插入节点还要去掉注释
1590
- let nodes = rc?.buildView(hook(get(slotMap, 'props')));
1591
- let nnodes = reject(toArray(nodes), n => n.nodeType === Node.COMMENT_NODE);
1592
- if (nnodes) {
1593
- let slottedNodes = this.#slotNodes[name];
1594
- if (!isEmpty(slottedNodes)) {
1595
- for (let i = 0; i < slottedNodes.length; i++) {
1596
- const n = slottedNodes[i];
1597
- n.parentNode?.removeChild(n);
1598
- }
1599
- }
1600
- this.#slotNodes[name] = nnodes;
1601
- this.append(...nnodes);
1602
- this.#updateSlots.clear();
1603
- }
1604
- }
1605
- _asyncDirectives = new WeakMap();
1606
- renderAsync(cbk, ...args) {
1607
- }
1608
- //children变化时触发
1609
- #filterSlot() {
1610
- if (isEmpty(this.#slotPropsMap))
1611
- return;
1612
- each(this.slots, (slottedNodes, k) => {
1613
- if (isEmpty(slottedNodes))
1614
- return;
1615
- let slotMap = this.#slotPropsMap[k];
1616
- let filterNodes = slottedNodes;
1617
- if (slotMap) {
1618
- let filterFn = slotMap.filter;
1619
- if (isFunction(filterFn)) {
1620
- filterNodes = filterFn(slottedNodes);
1621
- }
1622
- else if (isObject(filterFn)) {
1623
- let type = filterFn.type;
1624
- let maxCount = filterFn.maxCount;
1625
- if (type) {
1626
- let ts = isArray(type) ? type : [type];
1627
- filterNodes = filter(slottedNodes, n => some(ts, t => n instanceof t));
1628
- }
1629
- if (maxCount > 0) {
1630
- filterNodes = slice(slottedNodes, 0, maxCount);
1631
- }
1632
- }
1633
- }
1634
- if (this.#shadow.slotAssignment === 'named') {
1635
- let removeNodes = [];
1636
- for (let i = 0; i < slottedNodes.length; i++) {
1637
- const c = slottedNodes[i];
1638
- if (!filterNodes.includes(c)) {
1639
- removeNodes.push(c);
1640
- }
1641
- }
1642
- while (removeNodes.length > 0) {
1643
- let n = removeNodes.pop();
1644
- n.parentNode?.removeChild(n);
1645
- }
1646
- }
1647
- else {
1648
- this.#slotsEl[k].assign(...filterNodes);
1649
- }
1650
- if (this.#inited)
1651
- this.#onSlogChange(this.#slotsEl[k], k === 'default' ? '' : k);
1652
- });
1653
- }
1654
- #attrChanged(name, oldValue, newValue) {
1655
- if (!this.isMounted)
1656
- return;
1657
- let observedAttrs = _getObservedAttrs(this.constructor);
1658
- if (observedAttrs.has(name)) {
1659
- let camelName = camelCase(name);
1660
- if (isNull(newValue)) {
1661
- let propDefs = get(this.constructor, DecoratorKey.PROPS);
1662
- //使用默认值
1663
- newValue = propDefs[camelName]._defaultValue;
1664
- }
1665
- this._updateProps({ [camelName]: newValue });
1666
- }
1667
- }
1668
- /**
1669
- * todo
1670
- * 1. 取消上溯递归路径
1671
- */
1672
- _regDeps(varPath, renderContext) {
1673
- let list = this.#renderContextList[varPath];
1674
- if (!list) {
1675
- list = this.#renderContextList[varPath] = new Set();
1676
- }
1677
- list.add(renderContext);
1678
- let restPath = varPath.split('-');
1679
- restPath.pop();
1680
- if (restPath.length < 1)
1681
- return;
1682
- let upperPath = restPath.join('-');
1683
- list = this.#renderContextList[upperPath];
1684
- if (!list) {
1685
- list = this.#renderContextList[upperPath] = new Set();
1686
- }
1687
- list.add(renderContext);
1688
- }
1689
- }
1690
-
1691
- /**
1692
- * @author holyhigh2
1693
- */
1694
- var DirectiveUpdateTag;
1695
- (function (DirectiveUpdateTag) {
1696
- DirectiveUpdateTag["NONE"] = "NONE";
1697
- DirectiveUpdateTag["REMOVE"] = "REMOVE";
1698
- DirectiveUpdateTag["REPLACE"] = "REPLACE";
1699
- DirectiveUpdateTag["UPDATE"] = "UPDATE";
1700
- DirectiveUpdateTag["APPEND"] = "APPEND";
1701
- })(DirectiveUpdateTag || (DirectiveUpdateTag = {}));
1702
- /**
1703
- * 视图更新点
1704
- */
1705
- class UpdatePoint {
1706
- //在子视图中的平级key
1707
- key;
1708
- //表达式对应的vars位置
1709
- varIndex;
1710
- value;
1711
- isText = false;
1712
- //是否模板
1713
- isTmpl = false;
1714
- isDirective = false;
1715
- //表达式所在节点,可能是元素/文本
1716
- node;
1717
- //如果是文本位置,与node一起构成插入范围
1718
- textNode;
1719
- //是否组件
1720
- isComponent = false;
1721
- //如果在属性中,属性名
1722
- attrName;
1723
- //属性值模板
1724
- attrTmpl;
1725
- //是否组件属性
1726
- isProp = false;
1727
- //是否布尔属性
1728
- isToggleProp = false;
1729
- //是否事件
1730
- isEvent;
1731
- constructor(varIndex, node, attrName, attrTmpl) {
1732
- this.varIndex = varIndex;
1733
- this.node = node;
1734
- if (attrName)
1735
- this.attrName = attrName;
1736
- if (attrTmpl) {
1737
- this.attrTmpl = attrTmpl;
1738
- }
1739
- }
1740
- }
1741
-
1742
- /**
1743
- * 属性定义
1744
- */
1745
- var EnterPointType;
1746
- (function (EnterPointType) {
1747
- EnterPointType["ATTR"] = "attr";
1748
- EnterPointType["PROP"] = "prop";
1749
- EnterPointType["TEXT"] = "text";
1750
- EnterPointType["CLASS"] = "class";
1751
- EnterPointType["STYLE"] = "style";
1752
- EnterPointType["SLOT"] = "slot";
1753
- EnterPointType["TAG"] = "tag"; //在标签内但不是属性内
1754
- })(EnterPointType || (EnterPointType = {}));
1755
- /**
1756
- * 交互点信息
1757
- */
1758
- class EnterPoint {
1759
- startNode; //依赖节点
1760
- endNode; //依赖节点2
1761
- type; //依赖类型
1762
- attrName; //依赖属性名
1763
- varIndex;
1764
- expressionChain; //所在层级序号 [parentVarIndex-varIndex-]+,如1-6 表示根的第2个表达式下的context的第7个表达式
1765
- nodes; //如果是插入节点,保存插入的节点数组
1766
- constructor(node, attrName, type) {
1767
- this.startNode = node;
1768
- this.attrName = attrName;
1769
- this.type = type;
1770
- }
1771
- setVarIndex(varIndex) {
1772
- this.varIndex = varIndex;
1773
- }
1774
- getNodes() {
1775
- let nextNode = this.startNode.nextSibling;
1776
- if (!this.endNode)
1777
- return [nextNode];
1778
- let rs = [];
1779
- while (nextNode && nextNode !== this.endNode) {
1780
- rs.push(nextNode);
1781
- nextNode = nextNode?.nextSibling;
1782
- }
1783
- return rs;
1784
- }
1785
- }
1786
- var MovePosition;
1787
- (function (MovePosition) {
1788
- MovePosition["AFTER_BEGIN"] = "afterbegin";
1789
- })(MovePosition || (MovePosition = {}));
1790
- /**
1791
- * Delay the actual time of execution of directive
1792
- */
1793
- class DirectiveWrapper extends Function {
1794
- diClass;
1795
- args;
1796
- di;
1797
- varPath;
1798
- point;
1799
- slotComponent;
1800
- varChain;
1801
- constructor(diClass, ...args) {
1802
- super();
1803
- this.diClass = diClass;
1804
- this.args = args;
1805
- this.varChain = Collector.popDirectiveQ();
1806
- this.di = new this.diClass();
1807
- this.di.renderParams = this.varChain;
1808
- }
1809
- //校验scope
1810
- checkScope(scopeType) {
1811
- let scopes = get(this.diClass, 'scopes');
1812
- if (!isEmpty(scopes) && !test(scopes.join(','), scopeType)) {
1813
- showError(`Directive '${this.diClass.name}' is out of scopes, expect '${scopes.join(',')}' bug got '${scopeType}'`);
1814
- return;
1815
- }
1816
- }
1817
- render(component) {
1818
- let di = this.di;
1819
- this.args;
1820
- if (!di.renderComponent) {
1821
- di.renderComponent = component;
1822
- // for (let i = 0; i < args.length; i++) {
1823
- // const arg = args[i];
1824
- // if (isFunction(arg)) {
1825
- // args[i] = arg.bind(component)
1826
- // }
1827
- // }
1828
- }
1829
- this.di = di;
1830
- di._renderArgs = this.args;
1831
- // let [nodes, expPos, expPosMap] = di.renderContext(...this.args)
1832
- // if (expPosMap) {
1833
- // di.__expPosMap = expPosMap
1834
- // } else if (expPos) {
1835
- // di.__expPos = expPos
1836
- // }
1837
- return this.di.render(...this.args);
1838
- }
1839
- update(point, newArgs, oldArgs) {
1840
- let tag = this.di.update(point, newArgs, oldArgs);
1841
- if (tag === DirectiveUpdateTag.NONE)
1842
- return;
1843
- let nodes = point.getNodes();
1844
- if (tag === DirectiveUpdateTag.REMOVE) {
1845
- for (let i = 0; i < nodes.length; i++) {
1846
- const n = nodes[i];
1847
- n.parentNode?.removeChild(n);
1848
- }
1849
- }
1850
- else if (tag === DirectiveUpdateTag.REPLACE) {
1851
- let newNodes = [];
1852
- for (let i = 0; i < nodes.length; i++) {
1853
- const n = nodes[i];
1854
- n.parentNode?.removeChild(n);
1855
- }
1856
- let rs = this.di.render(...newArgs);
1857
- let nnodes = this.di.buildView(rs);
1858
- newNodes = toArray(nnodes);
1859
- let fragment = document.createDocumentFragment();
1860
- fragment.append(...newNodes);
1861
- point.endNode.parentNode.insertBefore(fragment, point.endNode);
1862
- }
1863
- else if (tag === DirectiveUpdateTag.UPDATE) {
1864
- let newKeys = {};
1865
- let nodesToUpdate;
1866
- //原节点顺序
1867
- let oldSeq = [];
1868
- let newSeq = [];
1869
- let updateRs = this.di.render(...newArgs);
1870
- if (!updateRs) {
1871
- updateRs = new Template([], []);
1872
- }
1873
- if (isEmpty(nodes)) {
1874
- let nodes = this.di.buildView(updateRs);
1875
- point.startNode.after(...nodes);
1876
- return;
1877
- }
1878
- let newTmpls = {};
1879
- if (updateRs instanceof Template) {
1880
- updateRs.vars.forEach(v => {
1881
- if (v instanceof Template) {
1882
- const k = v.getKey();
1883
- newTmpls[k] = v;
1884
- newKeys[k] = true;
1885
- newSeq.push(k);
1886
- }
1887
- });
1888
- }
1889
- //UPDATE仅处理元素节点
1890
- nodes = filter(compact(nodes), n => n.nodeType === Node.ELEMENT_NODE);
1891
- nodesToUpdate = filter(compact(toArray(nodesToUpdate)), n => n.nodeType === Node.ELEMENT_NODE);
1892
- let oldNodeMap = {};
1893
- let dupKey = '';
1894
- let keyQ = {};
1895
- for (let i = 0; i < nodes.length; i++) {
1896
- const node = nodes[i];
1897
- let treeNode = node;
1898
- let k = treeNode.getAttribute("key");
1899
- if (!k)
1900
- continue;
1901
- if (oldNodeMap[k]) {
1902
- dupKey = k;
1903
- break;
1904
- }
1905
- oldNodeMap[k] = treeNode;
1906
- oldSeq.push(k);
1907
- keyQ[k] = true;
1908
- }
1909
- if (dupKey) {
1910
- showError(`${camelCase(this.diClass.name)} - duplicate key '${dupKey}'`);
1911
- return;
1912
- }
1913
- let updateQ = newKeys;
1914
- const parentNode = point.startNode.parentNode;
1915
- //compare
1916
- let adds = [];
1917
- let dels = [];
1918
- //计算del
1919
- each(keyQ, (v, k) => {
1920
- if (!updateQ[k]) {
1921
- dels.push(k);
1922
- delete keyQ[k];
1923
- remove(oldSeq, k);
1924
- }
1925
- });
1926
- //计算move
1927
- if (!isEmpty(newSeq)) {
1928
- let lastMoveNodeId = '';
1929
- let lastMoveIndex = -1;
1930
- let lastGroup = [];
1931
- let idWeightMap = new Map();
1932
- for (let i = 0; i < newSeq.length; i++) {
1933
- const nodeId = newSeq[i];
1934
- let oldI = oldSeq.findIndex(c => c === nodeId);
1935
- if (oldI > -1 && oldI !== i) {
1936
- if (lastMoveIndex < 0 || lastMoveIndex - oldI == 1) {
1937
- let lastEl = last(lastGroup);
1938
- lastGroup.push({ nodeId, targetId: i === 0 ? MovePosition.AFTER_BEGIN : (lastEl ? lastEl.nodeId : newSeq[i - 1]) });
1939
- }
1940
- else {
1941
- idWeightMap.set(lastGroup.length, { group: lastGroup, targetId: '' });
1942
- // idWeightMap[lastGroup.length] = { group: lastGroup, targetId: '' }
1943
- lastGroup = [];
1944
- lastGroup.push({ nodeId, targetId: oldSeq[oldI] });
1945
- }
1946
- lastMoveIndex = oldI;
1947
- }
1948
- else if (oldI < 0) {
1949
- let prev = lastMoveNodeId ? oldNodeMap[lastMoveNodeId] || point.endNode : point.startNode;
1950
- //add
1951
- adds.push({ prevNode: prev, newkey: nodeId });
1952
- }
1953
- lastMoveNodeId = nodeId;
1954
- }
1955
- if (isEmpty(idWeightMap) && lastGroup.length > 0) {
1956
- idWeightMap.set(lastGroup.length, { group: lastGroup, targetId: '' });
1957
- // idWeightMap[lastGroup.length] = { group: lastGroup, targetId: '' }
1958
- }
1959
- let keys = idWeightMap.keys().toArray();
1960
- let keyNums = keys.sort((a, b) => a - b);
1961
- if (keys.length > 0) {
1962
- if (keys.length < 2) {
1963
- //如果仅有一组,留最后一个节点
1964
- let { group } = idWeightMap.get(keyNums[0]); //idWeightMap[keyNums[0]]
1965
- initial(group).forEach(({ targetId, nodeId }) => {
1966
- let srcEl = oldNodeMap[nodeId];
1967
- let target;
1968
- if (targetId === MovePosition.AFTER_BEGIN) {
1969
- target = point.startNode;
1970
- target.after(srcEl);
1971
- }
1972
- else {
1973
- target = oldNodeMap[targetId];
1974
- target.after(srcEl);
1975
- }
1976
- });
1977
- }
1978
- else {
1979
- //如果多组,留最后一组
1980
- console.debug('todo....');
1981
- }
1982
- } //endif
1983
- console.debug('test....');
1984
- }
1985
- if (adds.length > 0) {
1986
- this.#addNodes(adds, newTmpls, newSeq);
1987
- }
1988
- adds.forEach(v => {
1989
- let k = v.newkey;
1990
- let treeNode = this.newNodeMap[k];
1991
- let prevNode = v.prevNode;
1992
- if (prevNode === point.endNode) {
1993
- prevNode.before(treeNode);
1994
- }
1995
- else if (prevNode === point.startNode) {
1996
- prevNode.after(treeNode);
1997
- }
1998
- else {
1999
- prevNode.after(treeNode);
2000
- }
2001
- });
2002
- dels.forEach(k => {
2003
- let vi = oldSeq.findIndex(s => s == k);
2004
- this.#removeNode(vi);
2005
- // remove(adjustedQ, ak => ak === k)
2006
- let treeNode = oldNodeMap[k];
2007
- if (treeNode && treeNode.parentNode) {
2008
- parentNode.removeChild(treeNode);
2009
- }
2010
- });
2011
- //reset varIndex
2012
- this.di.__updatePoints.forEach(up => {
2013
- if (!up.key) {
2014
- up.key = up.value.tmpl.getKey();
2015
- }
2016
- const i = newSeq.findIndex(s => s == up.key);
2017
- up.varIndex = i;
2018
- });
2019
- this.di.updateView(updateRs);
2020
- }
2021
- }
2022
- getDirective() {
2023
- return this.di;
2024
- }
2025
- newNodeMap = {};
2026
- #addNodes(adds, newTmpls, newSeq) {
2027
- const combStrings = [];
2028
- const combVars = [];
2029
- adds.forEach(add => {
2030
- let k = add.newkey;
2031
- combStrings.push('');
2032
- combVars.push(newTmpls[k]);
2033
- });
2034
- combStrings.push('');
2035
- let tmpl = new Template(combStrings, combVars);
2036
- let originalUps = this.di.__updatePoints;
2037
- let nodes = this.di.buildView(tmpl);
2038
- this.di.__updatePoints.forEach((up, i) => {
2039
- const k = up.value.tmpl.getKey();
2040
- up.key = k;
2041
- });
2042
- this.di.__updatePoints.push(...originalUps);
2043
- nodes.forEach((n) => {
2044
- if (n instanceof HTMLElement)
2045
- this.newNodeMap[n.getAttribute('key')] = n;
2046
- });
2047
- }
2048
- //对于foreach指令,key就是序号
2049
- #removeNode(key) {
2050
- remove(this.di.__updatePoints, (v, k) => {
2051
- if (v.varIndex == key) {
2052
- DomUtil.remove(v.node, v.textNode);
2053
- return true;
2054
- }
2055
- });
2056
- }
2057
- }
2058
- /**
2059
- * 返回指令调用函数
2060
- * @param di
2061
- * @returns
2062
- */
2063
- function directive(diClass) {
2064
- return (...args) => {
2065
- let wrapper = null;
2066
- //todo 可能存在非返回模板函数开启了依赖监控
2067
- args.forEach((v, i) => {
2068
- if (isFunction(v)) {
2069
- let cbk = v;
2070
- args[i] = function (...ps) {
2071
- let di = wrapper.di;
2072
- Collector.startRender(di);
2073
- let rs = cbk.call(di.renderComponent, ...ps);
2074
- Collector.endRender(di.renderComponent);
2075
- return rs;
2076
- };
2077
- }
2078
- });
2079
- wrapper = new DirectiveWrapper(diClass, ...args);
2080
- return wrapper;
2081
- };
2082
- }
2083
-
2084
- /*************************************************************
2085
- * 扩展事件
2086
- * @author holyhigh2
2087
- *
2088
- * resize
2089
- * outside[.mousedown/up/click/dblclick] 默认click
2090
- * mutate[.attr/child/char/tree]
2091
- *
2092
- *************************************************************/
2093
- const ExtEvNames = ['resize', 'outside', 'mutate'];
2094
- ///////////////////////////////////////////////// resize
2095
- const AllResizeEls = new WeakMap;
2096
- const AllOutsideDownEls = [];
2097
- const resizeObserver = new ResizeObserver((entries) => {
2098
- for (const entry of entries) {
2099
- const contentBoxSize = Array.isArray(entry.contentBoxSize)
2100
- ? entry.contentBoxSize[0]
2101
- : entry.contentBoxSize;
2102
- const borderBoxSize = Array.isArray(entry.borderBoxSize)
2103
- ? entry.borderBoxSize[0]
2104
- : entry.borderBoxSize;
2105
- let cbk = AllResizeEls.get(entry.target);
2106
- if (cbk) {
2107
- let ev = new CustomEvent('resize', {
2108
- bubbles: false,
2109
- cancelable: false,
2110
- detail: {
2111
- borderBox: { w: borderBoxSize.inlineSize, h: borderBoxSize.blockSize },
2112
- contentBox: { w: contentBoxSize.inlineSize, h: contentBoxSize.blockSize },
2113
- },
2114
- });
2115
- cbk(ev, entry.target);
2116
- }
2117
- }
2118
- });
2119
- function addResize(node, cbk) {
2120
- if (AllResizeEls.has(node))
2121
- return;
2122
- AllResizeEls.set(node, cbk);
2123
- resizeObserver.observe(node);
2124
- }
2125
- ///////////////////////////////////////////////// mutate
2126
- var MutationType;
2127
- (function (MutationType) {
2128
- MutationType["Child"] = "child";
2129
- MutationType["Tree"] = "tree";
2130
- MutationType["Attr"] = "attr";
2131
- MutationType["Char"] = "char";
2132
- })(MutationType || (MutationType = {}));
2133
- const AllMutationEls = new WeakMap;
2134
- const mutationObserver = new MutationObserver(mutations => {
2135
- for (let i = 0; i < mutations.length; i++) {
2136
- const mutation = mutations[i];
2137
- let map = AllMutationEls.get(mutation.target);
2138
- if (!map)
2139
- return;
2140
- let detail = {
2141
- target: mutation.target
2142
- };
2143
- let cbk = null;
2144
- switch (mutation.type) {
2145
- case 'subtree':
2146
- detail.type = MutationType.Tree;
2147
- cbk = map[MutationType.Tree];
2148
- break;
2149
- case "childList":
2150
- detail.type = MutationType.Child;
2151
- detail.addedNodes = mutation.addedNodes;
2152
- detail.removedNodes = mutation.removedNodes;
2153
- cbk = map[MutationType.Child];
2154
- break;
2155
- case "attributes":
2156
- detail.type = MutationType.Attr;
2157
- detail.attributeName = mutation.attributeName;
2158
- detail.oldValue = mutation.oldValue;
2159
- cbk = map[MutationType.Attr];
2160
- break;
2161
- case "characterData":
2162
- detail.type = MutationType.Char;
2163
- detail.oldValue = mutation.oldValue;
2164
- cbk = map[MutationType.Char];
2165
- break;
2166
- }
2167
- if (cbk) {
2168
- let ev = new CustomEvent('mutate', {
2169
- bubbles: false,
2170
- cancelable: false,
2171
- detail
2172
- });
2173
- cbk(ev, mutation.target);
2174
- }
2175
- }
2176
- });
2177
- function addMutation(node, cbk, parts) {
2178
- let child = includes(parts, 'child');
2179
- let attr = includes(parts, 'attr');
2180
- let char = includes(parts, 'char');
2181
- let tree = includes(parts, 'tree');
2182
- let map = AllMutationEls.get(node);
2183
- if (map)
2184
- return;
2185
- map = {};
2186
- AllMutationEls.set(node, map);
2187
- if (child) {
2188
- map[MutationType.Child] = cbk;
2189
- }
2190
- if (attr) {
2191
- map[MutationType.Attr] = cbk;
2192
- }
2193
- if (char) {
2194
- map[MutationType.Char] = cbk;
2195
- }
2196
- if (tree) {
2197
- map[MutationType.Tree] = cbk;
2198
- }
2199
- mutationObserver.observe(node, {
2200
- childList: child,
2201
- attributes: attr,
2202
- characterData: char,
2203
- subtree: tree
2204
- });
2205
- }
2206
- ///////////////////////////////////////////////// outside
2207
- document.addEventListener('mousedown', e => {
2208
- let t = e.target;
2209
- AllOutsideDownEls.forEach(([node, cbk]) => {
2210
- if (!node.contains(t)) {
2211
- let ev = new CustomEvent('outside', {
2212
- bubbles: false,
2213
- cancelable: false,
2214
- detail: {
2215
- currentTarget: node,
2216
- event: e
2217
- },
2218
- });
2219
- cbk(ev, node);
2220
- }
2221
- });
2222
- }, false);
2223
- function addOutsideMouseDown(node, cbk) {
2224
- AllOutsideDownEls.push([node, cbk]);
2225
- }
2226
- function isExtEvent(evName) {
2227
- return ExtEvNames.includes(evName);
2228
- }
2229
- function addExtEvent(evName, node, cbk, parts) {
2230
- if (evName === 'resize') {
2231
- addResize(node, cbk);
2232
- }
2233
- else if (evName === 'outside') {
2234
- switch (parts[0]) {
2235
- case 'mousedown':
2236
- addOutsideMouseDown(node, cbk);
2237
- break;
2238
- }
2239
- }
2240
- else if (evName === 'mutate') {
2241
- addMutation(node, cbk, parts);
2242
- }
2243
- }
2244
-
2245
- const MODI_EV_DEBOUNCE = /,|^(debounce:.+)|(debounce$)/;
2246
- const MODI_EV_THROTTLE = /,|^(throttle:.+)|(throttle$)/;
2247
- const MODI_EV_SELF = 'self';
2248
- const MODI_EV_STOP = 'stop';
2249
- const MODI_EV_PREVENT = 'prevent';
2250
- const MODI_EV_ONCE = 'once';
2251
- const MODI_EV_MOUSE_LEFT = 'left';
2252
- const MODI_EV_MOUSE_RIGHT = 'right';
2253
- const MODI_EV_MOUSE_MIDDLE = 'middle';
2254
- const MODI_EV_KEYBOARD_COMBO_CTRL = 'ctrl';
2255
- const MODI_EV_KEYBOARD_COMBO_ALT = 'alt';
2256
- const MODI_EV_KEYBOARD_COMBO_SHIFT = 'shift';
2257
- const MODI_EV_KEYBOARD_COMBO_META = 'meta';
2258
- const MODI_EV_KEYBOARD_KEY_MAP = {
2259
- 'esc': 'escape'
2260
- };
2261
- const MODI_PARAM_DIVIDER = ":";
2262
- function addEvent(fullName, cbk, node, component) {
2263
- let parts = fullName.split('.');
2264
- let evName = parts.shift();
2265
- let isOnce = parts.includes(MODI_EV_ONCE);
2266
- let c = cbk;
2267
- let modi;
2268
- if (modi = find(parts, x => MODI_EV_DEBOUNCE.test(x))) {
2269
- let params = modi.split(MODI_PARAM_DIVIDER);
2270
- c = debounce(c, parseInt(params[1]) || 100);
2271
- }
2272
- if (modi = find(parts, x => MODI_EV_THROTTLE.test(x))) {
2273
- let params = modi.split(MODI_PARAM_DIVIDER);
2274
- c = throttle(c, parseInt(params[1]) || 100);
2275
- }
2276
- if (isOnce) {
2277
- c = once(c);
2278
- }
2279
- if (isExtEvent(evName)) {
2280
- addExtEvent(evName, node, c, parts);
2281
- return c;
2282
- }
2283
- let listener = (e) => {
2284
- if (parts.includes(MODI_EV_PREVENT))
2285
- e.preventDefault();
2286
- if (parts.includes(MODI_EV_STOP))
2287
- e.stopPropagation();
2288
- if (parts.includes(MODI_EV_SELF) && e.target !== e.currentTarget)
2289
- return;
2290
- if (e instanceof MouseEvent) {
2291
- if (parts.includes(MODI_EV_MOUSE_LEFT) && e.button != 0)
2292
- return;
2293
- if (parts.includes(MODI_EV_MOUSE_RIGHT) && e.button != 2)
2294
- return;
2295
- if (parts.includes(MODI_EV_MOUSE_MIDDLE) && e.button != 1)
2296
- return;
2297
- }
2298
- else if (e instanceof KeyboardEvent) {
2299
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_CTRL)[0] && !e.ctrlKey)
2300
- return;
2301
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_ALT)[0] && !e.altKey)
2302
- return;
2303
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_SHIFT)[0] && !e.shiftKey)
2304
- return;
2305
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_META)[0] && !e.metaKey)
2306
- return;
2307
- let checkKeys = map(parts, k => MODI_EV_KEYBOARD_KEY_MAP[k] || k);
2308
- if (!checkKeys.includes(e.key.toLowerCase()))
2309
- return;
2310
- }
2311
- c(e, node);
2312
- };
2313
- node.addEventListener(evName, listener);
2314
- //record
2315
- let evAry = component.__events[evName];
2316
- if (!evAry)
2317
- evAry = component.__events[evName] = [];
2318
- evAry.push([node, listener]);
2319
- return listener;
2320
- }
2321
-
2322
- const ATTR_PREFIX_EVENT = "@";
2323
- const ATTR_PREFIX_PROP = ".";
2324
- const ATTR_PREFIX_BOOLEAN = "?";
2325
- const ATTR_PREFIX_REF = "*";
2326
- const ATTR_PROP_DELIMITER = ":";
2327
- const ATTR_REF = "ref";
2328
- const EXP_ATTR_CHECK = /[.?-a-z]+\s*=\s*(['"])\s*([^='"]*<\!--c_ui-pl_df-->){2,}.*?\1/ims;
2329
- const EXP_PLACEHOLDER = /<\s*[a-z0-9-]+([^>]*<\!--c_ui-pl_df-->)*[^>]*?(?<!-)>/imgs;
2330
- const SLOT_KEY_PROPS = 'slot-props';
2331
- /**
2332
- * 提供渲染函数相关操作
2333
- * @author holyhigh2
2334
- */
2335
- /**
2336
- * 高性能dom生成及变量绑定算法
2337
- * 1. 使用占位符拼接HTML字符串,占位符与变量需要按照顺序对应
2338
- * 2. 插入dom片段,并遍历元素+注释节点, 搜索占位符
2339
- * 1. 按顺序遍历所有attr,发现一个属性值含有占位符时,标记节点及属性名,以便变量可以进行绑定( 如果key是事件/ref则内容仅允许一个占位符)
2340
- * 2. 如果是注释节点
2341
- * 1. 在后面追加同内容注释节点,标记两个节点,以便变量可以进行绑定
2342
- * 2. 在中间插入变量内容
2343
- * 3. 只有表达式是一个指令时才能绑定依赖
2344
- * @param component
2345
- * @param tmpl
2346
- * @returns [html,vars]
2347
- */
2348
- function buildHTML(component, tmpl) {
2349
- let html = "";
2350
- let vars = concat(tmpl.vars);
2351
- let l = tmpl.strings.length - 1;
2352
- let vl = tmpl.vars.length - 1;
2353
- for (let i = 0; i <= l; i++) {
2354
- const str = tmpl.strings[i];
2355
- let val = get(tmpl.vars, i, '');
2356
- if (val && val.di) {
2357
- let rs = val.render(component);
2358
- if (rs instanceof Template) {
2359
- let [h, v] = buildHTML(component, rs);
2360
- Reflect.defineProperty(val, '_renderVars', { value: v });
2361
- // set(val, '_renderVars', v)
2362
- val = PLACEHOLDER_DI_START + h + PLACEHOLDER_DI_END;
2363
- }
2364
- else {
2365
- val = rs ?? PLACEHOLDER;
2366
- }
2367
- }
2368
- else if (val instanceof Template) {
2369
- let [h, v] = buildHTML(component, val);
2370
- Reflect.defineProperty(val, '_renderVars', { value: v });
2371
- // set(val, '_renderVars', v)
2372
- val = PLACEHOLDER_TMPL_START + h + PLACEHOLDER_TMPL_END;
2373
- // vars.splice(i + offset, 1, ...v)
2374
- // offset += v.length
2375
- }
2376
- else {
2377
- val = i > vl ? "" : PLACEHOLDER;
2378
- }
2379
- html += str + val;
2380
- }
2381
- //attr check
2382
- let rs = html.match(EXP_ATTR_CHECK);
2383
- if (rs) {
2384
- let errorMsg = replaceAll(rs[0], PLACEHOLDER, '${...}');
2385
- showError(`Parse error: attribute value can be set only one interpolation —— \n ${errorMsg}`);
2386
- return ['', vars];
2387
- }
2388
- let i = 0;
2389
- html = html.replace(EXP_PLACEHOLDER, (a, b) => {
2390
- let rs = replaceAll(a, PLACEHOLDER, () => PLACEHOLDER.replace('-->', '') + (i++));
2391
- return rs;
2392
- });
2393
- html = html.replace(EXP_STR, '$1><').trim();
2394
- return [html, vars];
2395
- }
2396
- const PLACEHOLDER_DI_START = "<!--c_ui-pl_di-start-->";
2397
- const PLACEHOLDER_DI_END = "<!--c_ui-pl_di-end-->";
2398
- const PLACEHOLDER_TMPL_START = "<!--c_ui-pl_tmpl-start-->";
2399
- const PLACEHOLDER_TMPL_END = "<!--c_ui-pl_tmpl-end-->";
2400
- const PLACEHOLDER = "<!--c_ui-pl_df-->";
2401
- const PLACEHOLDER_PREFFIX = "<!--c_ui-pl_df";
2402
- const PLACEHOLDER_EXP = /<!--c_ui-pl_df\d*(-->)?/;
2403
- /**
2404
- * 构建模板为DOM结构
2405
- * @param html
2406
- */
2407
- function buildTmplate(updatePoints, html, vars, component, viewContext) {
2408
- const container = document.createElement("div");
2409
- container.innerHTML = html;
2410
- //遍历dom
2411
- const nodeIterator = document.createNodeIterator(container, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);
2412
- let currentNode;
2413
- let varIndex = 0;
2414
- let slotComponent = null;
2415
- let startDiCommentNode;
2416
- let startDiCommentNodeStack = [];
2417
- let startDiStack = [];
2418
- let startDiUpdatePointStack = [];
2419
- let updatePointsStack = [updatePoints];
2420
- let varStack = [];
2421
- let varIndexStack = [];
2422
- while ((currentNode = nodeIterator.nextNode())) {
2423
- if (currentNode instanceof HTMLElement || currentNode instanceof SVGElement) {
2424
- if (currentNode instanceof CompElem) {
2425
- slotComponent = currentNode;
2426
- }
2427
- else {
2428
- if (!slotComponent?.contains(currentNode)) {
2429
- slotComponent = null;
2430
- }
2431
- }
2432
- let props = {};
2433
- let attrs = toArray(currentNode.attributes);
2434
- for (let i = 0; i < attrs.length; i++) {
2435
- const attr = attrs[i];
2436
- let { name, value } = attr;
2437
- if (name === SLOT_KEY_PROPS) {
2438
- let slotName = currentNode.getAttribute('name') || 'default';
2439
- if (slotComponent) {
2440
- let ary = slotComponent._slotsPropMap[slotName];
2441
- if (!ary) {
2442
- ary = slotComponent._slotsPropMap[slotName] = [];
2443
- }
2444
- ary.push(currentNode);
2445
- }
2446
- } //endif
2447
- if (startsWith(name, PLACEHOLDER_PREFFIX)) {
2448
- let val = vars[varIndex];
2449
- //support directive only for now
2450
- if (val instanceof DirectiveWrapper) {
2451
- val.checkScope(EnterPointType.TAG);
2452
- let point = new EnterPoint(currentNode, name.substring(1), EnterPointType.TAG);
2453
- val.point = point;
2454
- val.di.slotComponent = slotComponent;
2455
- val.di.renderComponent = component;
2456
- let po = new UpdatePoint(varIndex, currentNode);
2457
- po.isDirective = true;
2458
- po.value = val;
2459
- po.isComponent = !!slotComponent;
2460
- updatePoints.push(po);
2461
- varIndex++;
2462
- val.di.created(point, ...val.args);
2463
- }
2464
- currentNode.removeAttribute(name);
2465
- continue;
2466
- } //endif
2467
- //@event.stop.prevent.debounce
2468
- if (name[0] === ATTR_PREFIX_EVENT) {
2469
- let cbk = (e) => { };
2470
- if (PLACEHOLDER_EXP.test(value)) {
2471
- let val = vars[varIndex];
2472
- if (!isFunction(val)) {
2473
- showTagError(currentNode.tagName, `Event '${name}' must be a function`);
2474
- continue;
2475
- }
2476
- cbk = val.bind(component);
2477
- let po = new UpdatePoint(varIndex, currentNode, name.replace(/\.|\?|@/, ''), value);
2478
- po.isComponent = !!slotComponent;
2479
- po.isEvent = true;
2480
- updatePoints.push(po);
2481
- varIndex++;
2482
- }
2483
- addEvent(name.substring(1), cbk, currentNode, component);
2484
- currentNode.removeAttribute(name);
2485
- continue;
2486
- } //endif
2487
- if (name === ATTR_REF) {
2488
- if (PLACEHOLDER_EXP.test(value)) {
2489
- let val = vars[varIndex];
2490
- if (!has(val, 'current')) {
2491
- showTagError(currentNode.tagName, `Ref must be a RefObject`);
2492
- continue;
2493
- }
2494
- varIndex++;
2495
- val.current = currentNode;
2496
- }
2497
- currentNode.removeAttribute(name);
2498
- continue;
2499
- } //endif
2500
- //校验变量必须是表达式
2501
- if (name[0] === ATTR_PREFIX_PROP && !PLACEHOLDER_EXP.test(value)) {
2502
- showTagError(currentNode.tagName, `Prop '${name}' must be an interpolation`);
2503
- continue;
2504
- }
2505
- if (PLACEHOLDER_EXP.test(value)) {
2506
- let val = vars[varIndex];
2507
- let po = new UpdatePoint(varIndex, currentNode, name.replace(/\.|\?|@/, ''), value);
2508
- updatePoints.push(po);
2509
- po.isComponent = !!slotComponent;
2510
- if (name[0] === ATTR_PREFIX_PROP ||
2511
- name[0] === ATTR_PREFIX_BOOLEAN ||
2512
- name[0] === ATTR_PREFIX_REF) {
2513
- if (val instanceof DirectiveWrapper) {
2514
- val.checkScope(EnterPointType.PROP);
2515
- let point = new EnterPoint(currentNode, name.substring(1), EnterPointType.PROP);
2516
- val.point = point;
2517
- val.slotComponent = slotComponent;
2518
- po.value = val;
2519
- po.isDirective = true;
2520
- if (val) {
2521
- val.di.created(val.point, ...val.args);
2522
- }
2523
- }
2524
- else if (name[0] === ATTR_PREFIX_BOOLEAN) {
2525
- po.isToggleProp = true;
2526
- po.value = !!val;
2527
- if (po.value)
2528
- currentNode.setAttribute(name.substring(1), '');
2529
- }
2530
- else if (name[0] === ATTR_PREFIX_REF) {
2531
- po.value = val;
2532
- let refNames = name.substring(1);
2533
- const [refNamec, prop] = refNames.split(ATTR_PROP_DELIMITER);
2534
- let refName = refNamec;
2535
- switch (prop) {
2536
- case 'camel':
2537
- refName = camelCase(refName);
2538
- break;
2539
- case 'kebab':
2540
- refName = kebabCase(refName);
2541
- break;
2542
- case 'snake':
2543
- refName = snakeCase(refName);
2544
- break;
2545
- }
2546
- po.attrName = refName;
2547
- currentNode.setAttribute(refName, val);
2548
- }
2549
- else {
2550
- if (!(currentNode instanceof CompElem) && currentNode.tagName !== 'SLOT') {
2551
- showTagError(currentNode.tagName, `Prop '${name}' can only be set on a CompElem or a slot`);
2552
- }
2553
- else {
2554
- let propName = camelCase(name.substring(1));
2555
- if (!(propName in currentNode) && currentNode.tagName !== 'SLOT') {
2556
- showTagError(currentNode.tagName, `Prop '${name}' is not defined in ${currentNode.tagName}`);
2557
- }
2558
- po.value = val;
2559
- po.isProp = true;
2560
- props[propName] = val;
2561
- }
2562
- }
2563
- currentNode.removeAttribute(name);
2564
- val = '';
2565
- }
2566
- else {
2567
- po.value = val;
2568
- let dw;
2569
- if (val instanceof DirectiveWrapper) {
2570
- let type = EnterPointType.ATTR;
2571
- if (name === "class") {
2572
- type = EnterPointType.CLASS;
2573
- }
2574
- else if (name === "style") {
2575
- type = EnterPointType.STYLE;
2576
- }
2577
- val.checkScope(type);
2578
- po.isDirective = true;
2579
- let point = new EnterPoint(currentNode, name, type);
2580
- val.point = point;
2581
- val.di.slotComponent = slotComponent;
2582
- val.di.renderComponent = component;
2583
- dw = val;
2584
- // val.di.created(point, ...val.args)
2585
- val = '';
2586
- }
2587
- value = replace(value, PLACEHOLDER_EXP, val);
2588
- //回填
2589
- attr.value = value;
2590
- if (dw) {
2591
- dw.di.created(dw.point, ...dw.args);
2592
- }
2593
- }
2594
- varIndex++;
2595
- } //endif
2596
- } //endfor
2597
- if (currentNode instanceof CompElem) {
2598
- currentNode._initProps(props);
2599
- }
2600
- else if (currentNode instanceof HTMLSlotElement) {
2601
- component._bindSlot(currentNode, currentNode.name || 'default', props);
2602
- }
2603
- }
2604
- else {
2605
- let comment = currentNode;
2606
- let ph = `<!--${comment.nodeValue}-->`;
2607
- if (ph === PLACEHOLDER_DI_START) {
2608
- if (startDiCommentNode) {
2609
- startDiCommentNodeStack.push(startDiCommentNode);
2610
- }
2611
- startDiCommentNode = comment;
2612
- let val = vars[varIndex];
2613
- let po = new UpdatePoint(varIndex, currentNode);
2614
- po.isComponent = !!slotComponent;
2615
- po.isDirective = true;
2616
- po.value = val;
2617
- let pType = slotComponent ? EnterPointType.SLOT : EnterPointType.TEXT;
2618
- let point = new EnterPoint(startDiCommentNode, "", pType);
2619
- val.point = point;
2620
- val.di.slotComponent = slotComponent;
2621
- val.di.renderComponent = component;
2622
- startDiStack.push(val);
2623
- updatePoints.push(po);
2624
- startDiUpdatePointStack.push(po);
2625
- //stack updatePoints
2626
- updatePoints = [];
2627
- updatePointsStack.push(updatePoints);
2628
- varIndex++;
2629
- //stack vars
2630
- varIndexStack.push(varIndex);
2631
- varStack.push(vars);
2632
- vars = val._renderVars;
2633
- varIndex = 0;
2634
- continue;
2635
- }
2636
- else if (ph === PLACEHOLDER_DI_END) {
2637
- startDiUpdatePointStack.pop().textNode = comment;
2638
- let startDi = startDiStack.pop();
2639
- startDi.point.endNode = comment;
2640
- //结束时调用created
2641
- startDi.di.created(startDi.point, ...startDi.args);
2642
- startDiCommentNode = startDiCommentNodeStack.pop();
2643
- startDi.di.__updatePoints = updatePoints;
2644
- updatePointsStack.pop();
2645
- updatePoints = last(updatePointsStack);
2646
- //restore vars
2647
- vars = varStack.pop();
2648
- varIndex = varIndexStack.pop();
2649
- }
2650
- else if (ph === PLACEHOLDER_TMPL_START) {
2651
- if (startDiCommentNode) {
2652
- startDiCommentNodeStack.push(startDiCommentNode);
2653
- }
2654
- startDiCommentNode = comment;
2655
- let val = vars[varIndex];
2656
- let po = new UpdatePoint(varIndex, currentNode);
2657
- po.isComponent = !!slotComponent;
2658
- po.isTmpl = true;
2659
- let parentDi = last(startDiStack);
2660
- if (parentDi && get(parentDi, 'diClass.name') === 'ForEach') {
2661
- po.key = val.getKey();
2662
- }
2663
- else if (viewContext.constructor.name == 'ForEach') {
2664
- po.key = val.getKey();
2665
- }
2666
- val = po.value = new SubView(val);
2667
- let pType = slotComponent ? EnterPointType.SLOT : EnterPointType.TEXT;
2668
- let point = new EnterPoint(startDiCommentNode, "", pType);
2669
- val.point = point;
2670
- val.slotComponent = slotComponent;
2671
- val.renderComponent = component;
2672
- startDiStack.push(val);
2673
- updatePoints.push(po);
2674
- startDiUpdatePointStack.push(po);
2675
- //stack updatePoints
2676
- updatePoints = [];
2677
- updatePointsStack.push(updatePoints);
2678
- varIndex++;
2679
- //stack vars
2680
- varIndexStack.push(varIndex);
2681
- varStack.push(vars);
2682
- vars = val._renderVars;
2683
- varIndex = 0;
2684
- continue;
2685
- }
2686
- else if (ph === PLACEHOLDER_TMPL_END) {
2687
- startDiUpdatePointStack.pop().textNode = comment;
2688
- let startDi = startDiStack.pop();
2689
- startDi.point.endNode = comment;
2690
- startDiCommentNode = startDiCommentNodeStack.pop();
2691
- startDi.__updatePoints = updatePoints;
2692
- updatePointsStack.pop();
2693
- updatePoints = last(updatePointsStack);
2694
- //restore vars
2695
- vars = varStack.pop();
2696
- varIndex = varIndexStack.pop();
2697
- }
2698
- if (ph !== PLACEHOLDER) {
2699
- continue;
2700
- }
2701
- let po = new UpdatePoint(varIndex, currentNode);
2702
- updatePoints.push(po);
2703
- po.isComponent = !!slotComponent;
2704
- po.isText = true;
2705
- let val = vars[varIndex];
2706
- let startComment;
2707
- //插入start占位符
2708
- startComment = document.createComment(`compelem-ui-${varIndex}-child-start`);
2709
- comment.parentNode.insertBefore(startComment, comment);
2710
- comment.nodeValue = `compelem-ui-${varIndex}-child-end`;
2711
- po.textNode = startComment;
2712
- if (val instanceof DirectiveWrapper) {
2713
- po.isDirective = true;
2714
- po.value = val;
2715
- let pType = slotComponent ? EnterPointType.SLOT : EnterPointType.TEXT;
2716
- // directives.push(val)
2717
- let point = new EnterPoint(startComment, "", pType);
2718
- point.endNode = comment;
2719
- val.point = point;
2720
- val.di.slotComponent = slotComponent;
2721
- val.di.renderComponent = component;
2722
- val.di.created(point, ...val.args);
2723
- val = '';
2724
- }
2725
- else if (val instanceof Template) {
2726
- po.isTmpl = true;
2727
- po.value = val;
2728
- let [html, vars] = buildHTML(component, val);
2729
- val = buildTmplate(updatePoints, html, vars, component, viewContext);
2730
- }
2731
- else {
2732
- po.value = val;
2733
- }
2734
- varIndex++;
2735
- if (isUndefined(val))
2736
- continue;
2737
- if (val instanceof NodeList) {
2738
- let fragment = document.createDocumentFragment();
2739
- fragment.append(...val);
2740
- comment.parentNode.insertBefore(fragment, comment);
2741
- }
2742
- else if (val instanceof Element) {
2743
- comment.parentNode.insertBefore(val, comment);
2744
- }
2745
- else if (trim(val)) {
2746
- let text = document.createTextNode(val);
2747
- comment.parentNode.insertBefore(text, comment);
2748
- }
2749
- }
2750
- }
2751
- return container.childNodes;
2752
- }
2753
- const DomUtil = {
2754
- insertBefore: function (node, newNodes) {
2755
- if (!node.parentNode)
2756
- return;
2757
- let fragment = document.createDocumentFragment();
2758
- fragment.append(...newNodes);
2759
- node.parentNode.insertBefore(fragment, node);
2760
- },
2761
- remove: function (startNode, endNode) {
2762
- if (startNode === endNode) {
2763
- startNode?.parentNode?.removeChild(startNode);
2764
- return;
2765
- }
2766
- let nextNode = startNode.nextSibling;
2767
- while (nextNode && nextNode !== endNode) {
2768
- nextNode?.parentNode?.removeChild(nextNode);
2769
- nextNode = startNode.nextSibling;
2770
- }
2771
- }
2772
- };
2773
- //////////////////////////////////////////////////// interfaces
2774
- /**
2775
- * 标签函数,用于构建模板
2776
- * @param strings
2777
- * @param vars
2778
- */
2779
- function html(strings, ...vars) {
2780
- return new Template(isString(strings) ? [strings] : strings, vars);
2781
- }
2782
- const EXP_STR = /([a-z0-9"'])\s*>\s*</img;
2783
- /**
2784
- * 使用初始值创建一个引用对象
2785
- * @param initValue
2786
- * @returns
2787
- */
2788
- function createRef(initValue) {
2789
- return { current: initValue };
2790
- }
2791
-
2792
- /**
2793
- * 视图模板
2794
- * @author holyhigh2
2795
- */
2796
- class Template {
2797
- strings;
2798
- vars;
2799
- constructor(strings, vars) {
2800
- this.strings = concat(strings);
2801
- this.vars = vars;
2802
- }
2803
- //解析模板中的key
2804
- getKey() {
2805
- let vars = this.vars;
2806
- let k = '';
2807
- each(this.strings, (str, i) => {
2808
- if (EXP_KEY.test(str)) {
2809
- k = toString(vars[i]);
2810
- return false;
2811
- }
2812
- });
2813
- return k;
2814
- }
2815
- getKeys() {
2816
- let vars = this.vars;
2817
- let ks = [];
2818
- for (let i = 0; i < this.strings.length; i++) {
2819
- const str = this.strings[i];
2820
- if (EXP_KEY.test(str)) {
2821
- let k = toString(vars[i]);
2822
- ks.push(k);
2823
- }
2824
- }
2825
- if (isEmpty(ks)) {
2826
- vars.forEach(v => {
2827
- if (v instanceof Template) {
2828
- let k = v.getKey();
2829
- ks.push(k);
2830
- }
2831
- });
2832
- }
2833
- return ks;
2834
- }
2835
- /**
2836
- * 追加tmpl
2837
- * 交接处模板进行合并
2838
- * @param tmpl
2839
- */
2840
- append(tmpl) {
2841
- let lastStr = last(this.strings);
2842
- tmpl.strings.forEach((str, i) => {
2843
- if (i == 0) {
2844
- this.strings[this.strings.length - 1] = lastStr + str;
2845
- return;
2846
- }
2847
- this.strings.push(str);
2848
- });
2849
- this.vars = concat(this.vars, tmpl.vars);
2850
- return this;
2851
- }
2852
- /**
2853
- * 指定位置插入模板
2854
- * @param position 字符模板位置
2855
- * @param tmpl
2856
- * @returns
2857
- */
2858
- insert(position, tmpl) {
2859
- let firstStr = tmpl.strings.shift();
2860
- this.strings[position] += firstStr;
2861
- this.strings.splice(position + 1, 0, ...tmpl.strings);
2862
- this.vars.splice(position, 0, ...tmpl.vars);
2863
- return this;
2864
- }
2865
- getHTML(comp) {
2866
- let [html, vars] = buildHTML(comp, this);
2867
- let nodes = buildTmplate([], html, vars, comp, comp);
2868
- return reduce(nodes, (a, v) => a + v.outerHTML, '');
2869
- }
2870
- }
2871
-
2872
- function computed(target, propertyKey, descriptor) {
2873
- if (!descriptor.get) {
2874
- showError(`Computed '${propertyKey}' must be a getter`);
2875
- }
2876
- if (!has(target.constructor, DecoratorKey.COMPUTED)) {
2877
- target.constructor[DecoratorKey.COMPUTED] = isEmpty(target.constructor[DecoratorKey.COMPUTED]) ? {} : cloneDeep(target.constructor[DecoratorKey.COMPUTED]);
2878
- }
2879
- target.constructor[DecoratorKey.COMPUTED][propertyKey] = descriptor.get;
2880
- }
2881
-
2882
- /**
2883
- * 绑定非视图事件,如window/document等
2884
- * @param eventName 事件名
2885
- * @param immediate 立即执行
2886
- * @param deep 深度监控
2887
- */
2888
- function event(eventName, options) {
2889
- return (target, name, descriptor) => {
2890
- if (!has(target.constructor, DecoratorKey.EVENTS)) {
2891
- target.constructor[DecoratorKey.EVENTS] = isEmpty(target.constructor[DecoratorKey.EVENTS]) ? [] : cloneDeep(target.constructor[DecoratorKey.EVENTS]);
2892
- }
2893
- target.constructor[DecoratorKey.EVENTS].push({ name: eventName, options, fn: target[name] });
2894
- };
2895
- }
2896
-
2897
- /**
2898
- * 缓存策略
2899
- */
2900
- var QueryCache;
2901
- (function (QueryCache) {
2902
- QueryCache["ONCE"] = "once";
2903
- QueryCache["UPDATABLE"] = "updatable"; //每次update结束都会更新缓存
2904
- })(QueryCache || (QueryCache = {}));
2905
- /**
2906
- * css查询装饰器
2907
- * @example
2908
- * @query('l-popup', QueryCache.ONCE)
2909
- */
2910
- class QueryDecorator extends Decorator {
2911
- static get priority() {
2912
- return Number.MAX_VALUE;
2913
- }
2914
- created(component, classProto, fieldName, ...args) {
2915
- }
2916
- mounted(component, setReactive, ...args) {
2917
- }
2918
- get targets() {
2919
- return [DecoratorType.FIELD];
2920
- }
2921
- selector;
2922
- cache;
2923
- result;
2924
- constructor(selector, cache) {
2925
- super();
2926
- this.selector = selector;
2927
- this.cache = cache;
2928
- }
2929
- static getKey(selector) {
2930
- return selector;
2931
- }
2932
- getter(component) {
2933
- this.result = component.shadowRoot?.querySelector(this.selector);
2934
- }
2935
- beforeMount(component, setReactive, classProto, fieldName, ...args) {
2936
- const that = this;
2937
- Reflect.defineProperty(component, fieldName, {
2938
- get() {
2939
- if (that.result && that.cache) {
2940
- return that.result;
2941
- }
2942
- that.getter(component);
2943
- return that.result;
2944
- }
2945
- });
2946
- }
2947
- updated(component, changed) {
2948
- if (this.cache !== QueryCache.UPDATABLE)
2949
- return;
2950
- this.getter(component);
2951
- }
2952
- }
2953
- class QueryAllDecorator extends QueryDecorator {
2954
- getter(component) {
2955
- this.result = component.shadowRoot?.querySelectorAll(this.selector);
2956
- }
2957
- }
2958
- const query = decorator(QueryDecorator);
2959
- const queryAll = decorator(QueryAllDecorator);
2960
-
2961
- function state(options) {
2962
- if (arguments.length === 1) {
2963
- return (target, stateKey) => {
2964
- defineState(target, stateKey, options);
2965
- };
2966
- }
2967
- let target = arguments[0], stateKey = arguments[1];
2968
- defineState(target, stateKey, { prop: "" });
2969
- }
2970
- function defineState(target, stateKey, options) {
2971
- if (!has(target.constructor, DecoratorKey.STATES)) {
2972
- const mixinStates = {};
2973
- let parentCtor = target.constructor;
2974
- while ((parentCtor = _getSuper(parentCtor)) !== CompElem) {
2975
- merge(mixinStates, parentCtor[DecoratorKey.STATES] ? cloneDeep(parentCtor[DecoratorKey.STATES]) : {});
2976
- }
2977
- Reflect.defineProperty(target.constructor, DecoratorKey.STATES, {
2978
- configurable: false,
2979
- enumerable: false,
2980
- value: mixinStates
2981
- });
2982
- }
2983
- target.constructor[DecoratorKey.STATES][stateKey] = options;
2984
- }
2985
- /**
2986
- * 同@state装饰器,但可用于构造器中调用
2987
- * @param ctor 类构造函数
2988
- * @param stateKey state 名称
2989
- * @param options
2990
- */
2991
- function makeState(ctor, stateKey, options) {
2992
- defineState(ctor.prototype, stateKey, options || { prop: "" });
2993
- }
2994
-
2995
- /**
2996
- * class用注解,用于自动注册自定义组件
2997
- * @param name 自定义组件名称
2998
- */
2999
- function tag(name) {
3000
- return (target) => {
3001
- if (target) {
3002
- //attrChange
3003
- if (target.prototype.hasOwnProperty('attributeChangedCallback')) {
3004
- let cbk = target.prototype.attributeChangedCallback;
3005
- target.prototype.attributeChangedCallback = function (name, oldValue, newValue) {
3006
- CompElem.prototype.attributeChangedCallback.call(this, name, oldValue, newValue);
3007
- cbk.call(this, name, oldValue, newValue);
3008
- };
3009
- }
3010
- //connectedCallback
3011
- if (target.prototype.hasOwnProperty('connectedCallback')) {
3012
- let cbk = target.prototype.connectedCallback;
3013
- target.prototype.connectedCallback = function () {
3014
- CompElem.prototype.connectedCallback.call(this);
3015
- cbk.call(this);
3016
- };
3017
- }
3018
- //disconnectedCallback
3019
- if (target.prototype.hasOwnProperty('disconnectedCallback')) {
3020
- let cbk = target.prototype.connectedCallback;
3021
- target.prototype.disconnectedCallback = function () {
3022
- CompElem.prototype.disconnectedCallback.call(this);
3023
- cbk.call(this);
3024
- };
3025
- }
3026
- customElements.define(name, target);
3027
- }
3028
- };
3029
- }
3030
-
3031
- function watch(source, options) {
3032
- return (target, name) => {
3033
- if (!has(target.constructor, DecoratorKey.WATCH)) {
3034
- target.constructor[DecoratorKey.WATCH] = isEmpty(target.constructor[DecoratorKey.WATCH]) ? {} : cloneDeep(target.constructor[DecoratorKey.WATCH]);
3035
- }
3036
- const sources = isArray(source) ? source : [source];
3037
- sources.forEach(src => {
3038
- let watchKey = src.replaceAll('.', '-');
3039
- let srcList = target.constructor[DecoratorKey.WATCH][watchKey];
3040
- if (!isArray(srcList)) {
3041
- srcList = target.constructor[DecoratorKey.WATCH][watchKey] = [];
3042
- }
3043
- srcList.push({ source: src, options, handler: target[name] });
3044
- });
3045
- };
3046
- }
3047
-
3048
- /**
3049
- * 用于解析HTML模板
3050
- * @author holyhigh2
3051
- */
3052
- class Directive extends View(Object) {
3053
- //render参数,仅保存上次指令所在context变更时的数据,用于指令内部context更新时
3054
- _renderArgs;
3055
- /**
3056
- * 指令使用范围,超出范围会报错
3057
- */
3058
- static get scopes() {
3059
- return [];
3060
- }
3061
- /**
3062
- * 指令渲染参数变量链
3063
- */
3064
- renderParams;
3065
- }
3066
-
3067
- const Ignores = ['key'];
3068
- /**
3069
- * 绑定属性到节点上,如果节点是组件会使用in操作符判断是否props
3070
- * @param styles 对象/数组/字符串
3071
- */
3072
- class Bind extends Directive {
3073
- created(point, obj) {
3074
- let el = point.startNode;
3075
- if (el instanceof CompElem) {
3076
- //判断是否prop
3077
- let props = {};
3078
- let attrs = {};
3079
- each(obj, (v, k) => {
3080
- if (Ignores.includes(k))
3081
- return;
3082
- if (k in el) {
3083
- props[k] = v;
3084
- }
3085
- else {
3086
- attrs[k] = v + '';
3087
- }
3088
- });
3089
- // el._setParentProps(props, attrs)
3090
- el._initProps(props, attrs);
3091
- }
3092
- else {
3093
- each(obj, (v, k) => {
3094
- el.setAttribute(k, v);
3095
- });
3096
- }
3097
- }
3098
- update(point, newArgs, oldArgs) {
3099
- return DirectiveUpdateTag.NONE;
3100
- }
3101
- static get scopes() {
3102
- return [EnterPointType.TAG];
3103
- }
3104
- render(obj) {
3105
- }
3106
- }
3107
- const bind = directive(Bind);
3108
-
3109
- /**
3110
- * 根据变量内容自动插入class,仅能用于class属性
3111
- * @param styles 对象/数组/字符串
3112
- */
3113
- class Classes extends Directive {
3114
- created(point, clazz) {
3115
- let rs = [];
3116
- if (isArray(clazz)) {
3117
- rs = compact(clazz);
3118
- }
3119
- else if (isObject(clazz)) {
3120
- rs = flatMap(clazz, (v, k) => v ? k : []);
3121
- }
3122
- else if (isString(clazz)) {
3123
- rs = clazz.split(' ');
3124
- }
3125
- let el = point.startNode;
3126
- each(this.lastCls, cls => {
3127
- el.classList.remove(cls);
3128
- });
3129
- each(rs, cls => {
3130
- el.classList.add(cls);
3131
- });
3132
- this.lastCls = concat(rs);
3133
- }
3134
- update(point, newArgs, oldArgs) {
3135
- this.created(point, newArgs[0]);
3136
- return DirectiveUpdateTag.NONE;
3137
- }
3138
- static get scopes() {
3139
- return [EnterPointType.CLASS];
3140
- }
3141
- lastCls;
3142
- render(clazz) {
3143
- }
3144
- }
3145
- const classes = directive(Classes);
3146
-
3147
- /**
3148
- * 循环列表并自动优化列表更新
3149
- * foreach循环的只能是节点,且必须有key属性。非节点元素会被过滤掉
3150
- * 使用序号作为key时可能会导致异常问题
3151
- */
3152
- class ForEach extends Directive {
3153
- created(point, ...args) {
3154
- }
3155
- update(point, newArgs, oldArgs) {
3156
- if (isEmpty(point.getNodes()) && (!newArgs || isEmpty(newArgs[0])))
3157
- return DirectiveUpdateTag.NONE;
3158
- if (isMatch(this.lastAry, newArgs[0]) && this.lastAry.length === newArgs[0].length)
3159
- return DirectiveUpdateTag.NONE;
3160
- if (!isEmpty(this.renderParams)) {
3161
- let rp = last(this.renderParams);
3162
- if (!isArray(rp)) {
3163
- rp = [rp];
3164
- }
3165
- this.renderParams = rp;
3166
- }
3167
- this.lastAry = clone(newArgs[0]);
3168
- return DirectiveUpdateTag.UPDATE;
3169
- }
3170
- constructor(point) {
3171
- super();
3172
- if (!isEmpty(this.renderParams))
3173
- this.renderParams = toArray(last(this.renderParams));
3174
- }
3175
- static get scopes() {
3176
- return [EnterPointType.TEXT, EnterPointType.SLOT];
3177
- }
3178
- lastAry;
3179
- lastRenderTmpl;
3180
- render(value, cbk) {
3181
- //1. 产生模板
3182
- let tmpls = map(value, (v, k) => {
3183
- return cbk(v, k);
3184
- });
3185
- if (tmpls.length < 1) {
3186
- this.lastRenderTmpl = new Template([], []);
3187
- return this.lastRenderTmpl;
3188
- }
3189
- //2. 检查 & 合并模板
3190
- let keyAry = [];
3191
- let strs = [];
3192
- const combStrings = [];
3193
- const combVars = [];
3194
- for (let l = 0; l < tmpls.length; l++) {
3195
- const tmpl = tmpls[l];
3196
- let lastStr = last(strs);
3197
- let vars = tmpl.vars;
3198
- let hasNoKey = true;
3199
- let tmplStrs = tmpl.strings;
3200
- for (let i = 0; i < tmplStrs.length; i++) {
3201
- const str = tmplStrs[i];
3202
- if (EXP_KEY.test(str)) {
3203
- let key = vars[i] + '';
3204
- if (keyAry.includes(key)) {
3205
- showError(`forEach - duplicate key '${key}'`);
3206
- return;
3207
- }
3208
- keyAry.push(key);
3209
- hasNoKey = false;
3210
- }
3211
- if (i == 0 && lastStr) {
3212
- strs[strs.length - 1] = lastStr + str;
3213
- continue;
3214
- }
3215
- strs.push(str);
3216
- }
3217
- if (hasNoKey) {
3218
- showError("forEach - missing 'key' prop");
3219
- return;
3220
- }
3221
- let lastVar = last(combStrings);
3222
- if (lastVar && tmplStrs.length > 0) {
3223
- combStrings[combStrings.length - 1] = trim(lastVar) + tmplStrs.shift();
3224
- }
3225
- combStrings.push('');
3226
- combVars.push(tmpl);
3227
- }
3228
- this.lastAry = clone(value);
3229
- combStrings.push('');
3230
- this.lastRenderTmpl = new Template(combStrings, combVars);
3231
- return this.lastRenderTmpl;
3232
- }
3233
- }
3234
- const forEach = directive(ForEach);
3235
-
3236
- /**
3237
- * 条件为真时返回参数1,否则返回参数2,仅能用于文本节点
3238
- * @param condition 条件
3239
- * @param tmpl 模板
3240
- */
3241
- class IfElse extends Directive {
3242
- created(point, ...args) {
3243
- }
3244
- //todo 缓存后会导致缓存内容无法更新,需要按照新的结构修改后进行缓存
3245
- ifNodes;
3246
- elseNodes;
3247
- static get scopes() {
3248
- return [EnterPointType.TEXT, EnterPointType.SLOT];
3249
- }
3250
- update(point, newArgs, oldArgs) {
3251
- if (!!newArgs[0] === !!oldArgs[0]) {
3252
- return DirectiveUpdateTag.NONE;
3253
- }
3254
- if (newArgs[0]) {
3255
- //缓存else
3256
- // if (isEmpty(this.elseNodes)) {
3257
- // this.elseNodes = concat(nodes)
3258
- // }
3259
- return DirectiveUpdateTag.REPLACE;
3260
- }
3261
- else {
3262
- //缓存if
3263
- // if (isEmpty(this.ifNodes)) {
3264
- // this.ifNodes = concat(nodes)
3265
- // }
3266
- return DirectiveUpdateTag.REPLACE;
3267
- }
3268
- }
3269
- render(condition, tmplFn1, tmplFn2) {
3270
- return condition ? tmplFn1(condition) : tmplFn2(condition);
3271
- }
3272
- }
3273
- const ifElse = directive(IfElse);
3274
-
3275
- /**
3276
- * 条件为真时返回内容,仅能用于文本节点
3277
- * @param condition 条件
3278
- * @param tmpl 模板
3279
- */
3280
- class IfTrue extends Directive {
3281
- created(point, ...args) {
3282
- }
3283
- static get scopes() {
3284
- return [EnterPointType.TEXT, EnterPointType.SLOT];
3285
- }
3286
- update(point, newArgs, oldArgs) {
3287
- if (newArgs[0] === oldArgs[0])
3288
- return DirectiveUpdateTag.NONE;
3289
- if (newArgs[0]) {
3290
- return DirectiveUpdateTag.REPLACE;
3291
- }
3292
- // this.cacheNodes = nodes;
3293
- return DirectiveUpdateTag.REMOVE;
3294
- }
3295
- render(condition, tmplFn) {
3296
- return condition ? tmplFn() : html ``;
3297
- }
3298
- }
3299
- const ifTrue = directive(IfTrue);
3300
-
3301
- var ModelTriggerType;
3302
- (function (ModelTriggerType) {
3303
- ModelTriggerType["CHANGE"] = "change";
3304
- ModelTriggerType["INPUT"] = "input";
3305
- })(ModelTriggerType || (ModelTriggerType = {}));
3306
- /**
3307
- * 实现双向绑定(仅支持静态路径,动态增加的属性路径无法识别)
3308
- * 当用于组件时,监控 @update:value 事件
3309
- * 当用于元素时,
3310
- * - 对于 input/textarea 监控 @input,并设置 value 属性
3311
- * - 对于 checkbox/radio 监控 @change,并设置 checked 属性
3312
- * - 对于 select 监控 @change,并设置 value 属性
3313
- * @param modelValue 双向绑定的组件变量
3314
- */
3315
- class Model extends Directive {
3316
- created(point, modelValue, modelPath) {
3317
- if (!this.modelPath)
3318
- this.modelPath = last(this.renderParams);
3319
- if (modelPath) {
3320
- this.modelPath = toPath(modelPath);
3321
- }
3322
- const node = point.startNode;
3323
- if (get(node, '_model') === 'binded')
3324
- return;
3325
- if (!isObject(modelValue) && !trim(modelValue))
3326
- modelValue = '';
3327
- if (node instanceof CompElem) {
3328
- node._initProps({ value: modelValue });
3329
- node.addEventListener('update:value', (e) => {
3330
- console.debug('Model =>', this.modelPath);
3331
- set(this.renderComponent, this.modelPath, e.detail.value);
3332
- });
3333
- set(node, '_model', 'binded');
3334
- }
3335
- else if (node instanceof HTMLTextAreaElement) {
3336
- node.setAttribute('value', modelValue + '');
3337
- node.addEventListener('input', (e) => {
3338
- console.debug('Model =>', this.modelPath);
3339
- let t = e.target;
3340
- set(this.renderComponent, this.modelPath, t.value);
3341
- });
3342
- set(node, '_model', 'binded');
3343
- }
3344
- else if (node instanceof HTMLInputElement) {
3345
- let propName = '';
3346
- let evName = '';
3347
- switch (node.type) {
3348
- case 'checkbox':
3349
- case 'radio':
3350
- propName = 'checked';
3351
- evName = 'change';
3352
- break;
3353
- case 'text':
3354
- case 'email':
3355
- case 'number':
3356
- case 'password':
3357
- case 'search':
3358
- case 'tel':
3359
- case 'url':
3360
- propName = 'value';
3361
- evName = 'input';
3362
- break;
3363
- default:
3364
- propName = 'value';
3365
- evName = 'input';
3366
- break;
3367
- }
3368
- node.setAttribute(propName, modelValue + '');
3369
- node.addEventListener(evName, (e) => {
3370
- console.debug('Model =>', this.modelPath);
3371
- let t = e.target;
3372
- set(this.renderComponent, this.modelPath, t.value);
3373
- });
3374
- set(node, '_model', 'binded');
3375
- }
3376
- else if (node instanceof HTMLSelectElement) {
3377
- node.setAttribute('value', modelValue + '');
3378
- node.addEventListener('change', (e) => {
3379
- console.debug('Model =>', this.modelPath);
3380
- let t = e.target;
3381
- set(this.renderComponent, this.modelPath, t.value);
3382
- });
3383
- set(node, '_model', 'binded');
3384
- }
3385
- }
3386
- update(point, newArgs, oldArgs) {
3387
- if (!this.modelPath)
3388
- this.modelPath = last(this.renderParams);
3389
- if (!isEqual(newArgs, oldArgs)) {
3390
- const node = point.startNode;
3391
- if (node instanceof CompElem) {
3392
- node._updateProps({ value: newArgs[0] });
3393
- }
3394
- else if (node instanceof HTMLTextAreaElement || node instanceof HTMLSelectElement) {
3395
- node.setAttribute('value', newArgs[0] + '');
3396
- }
3397
- else if (node instanceof HTMLInputElement) {
3398
- switch (node.type) {
3399
- case 'checkbox':
3400
- case 'radio':
3401
- if (!!newArgs[0]) {
3402
- node.setAttribute('checked', '');
3403
- }
3404
- else {
3405
- node.removeAttribute('checked');
3406
- }
3407
- break;
3408
- case 'text':
3409
- case 'email':
3410
- case 'number':
3411
- case 'password':
3412
- case 'search':
3413
- case 'tel':
3414
- case 'url':
3415
- node.setAttribute('value', newArgs[0] + '');
3416
- break;
3417
- default:
3418
- node.setAttribute('value', newArgs[0] + '');
3419
- break;
3420
- }
3421
- }
3422
- }
3423
- return DirectiveUpdateTag.NONE;
3424
- }
3425
- static get scopes() {
3426
- return [EnterPointType.TAG];
3427
- }
3428
- modelPath;
3429
- render(modelValue, modelPath) {
3430
- }
3431
- }
3432
- const model = directive(Model);
3433
-
3434
- /**
3435
- * display的快捷指令
3436
- * 如果
3437
- * @param isvisible 是否显示
3438
- */
3439
- class Show extends Directive {
3440
- created(point, isVisible) {
3441
- let el = point.startNode;
3442
- if (isUndefined(this.display)) {
3443
- this.display = el.style.display;
3444
- }
3445
- this.renderComponent.nextTick(() => {
3446
- el.style.display = isVisible ? this.display : 'none';
3447
- });
3448
- }
3449
- update(point, newArgs, oldArgs) {
3450
- this.created(point, newArgs[0]);
3451
- return DirectiveUpdateTag.NONE;
3452
- }
3453
- display = undefined;
3454
- static get scopes() {
3455
- return [EnterPointType.TAG];
3456
- }
3457
- constructor(point) {
3458
- super();
3459
- this.point = point;
3460
- }
3461
- render(isVisible) {
3462
- }
3463
- }
3464
- const show = directive(Show);
3465
-
3466
- /**
3467
- * 创建一个动态插槽内容
3468
- * @param cbk 回调函数,函数接收插槽上定义得变量
3469
- * @param slotName 插槽名词,默认default
3470
- */
3471
- class Slot extends Directive {
3472
- created(point, cbk, slotName) {
3473
- cbk = cbk.bind(this.renderComponent);
3474
- this.slotComponent._bindSlotHook(slotName || 'default', cbk);
3475
- }
3476
- update(point, newArgs, oldArgs) {
3477
- return DirectiveUpdateTag.NONE;
3478
- }
3479
- static get scopes() {
3480
- return [EnterPointType.SLOT];
3481
- }
3482
- render(cbk, slotName) {
3483
- }
3484
- }
3485
- const slot = directive(Slot);
3486
-
3487
- /**
3488
- * Css 辅助类
3489
- */
3490
- class CssHelper {
3491
- /**
3492
- * 用于转换style对象为标准style字符串,会自动转换对象key为短横线格式
3493
- * @param styles 样式对象
3494
- * @returns
3495
- */
3496
- static getCssText(styles) {
3497
- if (isString(styles))
3498
- return styles;
3499
- return join(map(styles, (v, k) => kebabCase(k) + ":" + v), ';');
3500
- }
3501
- /**
3502
- * 设置样式
3503
- * @param styles 样式字符串或样式对象
3504
- * @param node HTML元素
3505
- * @returns 每个样式的旧值map
3506
- */
3507
- static setStyle(styles, node) {
3508
- if (isString(styles) && !trim(styles))
3509
- return {};
3510
- let css = CssHelper.getCssText(styles);
3511
- let oldValueMap = {};
3512
- each(css.split(';'), prop => {
3513
- let kv = prop.split(':');
3514
- let k = trim(kv[0]);
3515
- let v = trim(kv[1]);
3516
- oldValueMap[k] = node.style.getPropertyValue(k);
3517
- node.style.setProperty(k, v);
3518
- });
3519
- return oldValueMap;
3520
- }
3521
- }
3522
-
3523
- /**
3524
- * 根据变量内容自动插入class,仅能用于style属性
3525
- * @param styles 对象/字符串
3526
- */
3527
- class Styles extends Directive {
3528
- created(point, styles) {
3529
- CssHelper.setStyle(styles, point.startNode);
3530
- }
3531
- update(point, newArgs, oldArgs) {
3532
- this.created(point, newArgs[0]);
3533
- return DirectiveUpdateTag.NONE;
3534
- }
3535
- constructor(point) {
3536
- super();
3537
- this.point = point;
3538
- }
3539
- static get scopes() {
3540
- return [EnterPointType.STYLE];
3541
- }
3542
- render(styles) {
3543
- }
3544
- }
3545
- const styles = directive(Styles);
3546
-
3547
- /**
3548
- * 类似Model,实现属性的同步跟踪
3549
- * 设置组件prop,并监控 @update:prop 事件
3550
- * @param syncValue 双向绑定的组件变量
3551
- */
3552
- class Sync extends Directive {
3553
- created(point, syncValue) {
3554
- if (!this.modelPath)
3555
- this.modelPath = last(this.renderParams);
3556
- const targetComponent = point.startNode;
3557
- let attrName = point.attrName;
3558
- //todo _setParentProps接口不应该外部使用
3559
- targetComponent._initProps({ [attrName]: syncValue });
3560
- targetComponent.addEventListener('update:' + attrName, (e) => {
3561
- set(this.renderComponent, this.modelPath, e.detail.value);
3562
- });
3563
- }
3564
- update(point, newArgs, oldArgs) {
3565
- if (!isEqual(newArgs, oldArgs)) {
3566
- const targetComponent = point.startNode;
3567
- let attrName = point.attrName;
3568
- targetComponent._updateProps({ [attrName]: newArgs[0] });
3569
- }
3570
- return DirectiveUpdateTag.NONE;
3571
- }
3572
- static get scopes() {
3573
- return [EnterPointType.PROP];
3574
- }
3575
- modelPath;
3576
- constructor(point) {
3577
- super();
3578
- }
3579
- render(syncValue) {
3580
- }
3581
- }
3582
- const sync = directive(Sync);
3583
-
3584
- /**
3585
- * 分支指令,具有switch / if else 两种模式
3586
- * @example
3587
- * switch 模式
3588
- * ${when(var, {
3589
- closed: () => html``, //case 1
3590
- connecting: () => html``, //case 2
3591
- default: () => html``// default
3592
- })}
3593
-
3594
- if else 模式
3595
- * ${when(this.editingTitle, [
3596
- [(v: any) => v.substring(2) > 0, () => html`<div style="${PageHome.tunnelLight}"></div>`],
3597
- [(v: any) => v == 'closed', () => html`<div style="${PageHome.tunnelLight}"></div>`],
3598
- [() => true, () => html`默认`]
3599
- ])}
3600
- *
3601
- * @param condition 条件
3602
- * @param tmpl 模板
3603
- */
3604
- class When extends Directive {
3605
- created(point, ...args) {
3606
- }
3607
- static get scopes() {
3608
- return [EnterPointType.TEXT, EnterPointType.SLOT];
3609
- }
3610
- update(point, newArgs, oldArgs) {
3611
- if (isEqual(newArgs, oldArgs)) {
3612
- return DirectiveUpdateTag.NONE;
3613
- }
3614
- //todo 缓存
3615
- return DirectiveUpdateTag.REPLACE;
3616
- }
3617
- render(value, cases) {
3618
- let defaultFn = () => html ``;
3619
- let conditionList = [];
3620
- let tmplList = [];
3621
- each(cases, (v, k) => {
3622
- if (isFunction(v)) {
3623
- conditionList.push(k);
3624
- tmplList.push(v);
3625
- }
3626
- else {
3627
- let condiFn = v[0];
3628
- let tmplFn = v[1];
3629
- conditionList.push(condiFn);
3630
- tmplList.push(tmplFn);
3631
- }
3632
- if (k === 'default') {
3633
- defaultFn = v;
3634
- }
3635
- });
3636
- let i = findIndex(conditionList, c => {
3637
- if (isFunction(c)) {
3638
- return c(value);
3639
- }
3640
- else {
3641
- return c == value;
3642
- }
3643
- });
3644
- return call(tmplList[i] ?? defaultFn);
3645
- }
3646
- }
3647
- const when = directive(When);
3648
-
3649
- export { CompElem, CssHelper, Decorator, DecoratorType, DecoratorWrapper, Directive, DirectiveUpdateTag, DirectiveWrapper, EnterPoint, EnterPointType, GetKeyFnName, ModelTriggerType, QueryCache, Template, UpdatePoint, _DecoratorMap, _DecoratorsKey, _getObservedAttrs, bind, buildHTML, classes, computed, createRef, decorator, directive, event, forEach, html, ifElse, ifTrue, makeState, model, prop, query, queryAll, show, slot, state, styles, sync, tag, watch, when };
7
+ import{toPath as t,get as e,isObject as s,isDefined as r,isUndefined as n,isEmpty as i,has as o,concat as a,defaults as l,merge as c,cloneDeep as d,each as h,kebabCase as u,toArray as p,last as f,startsWith as g,isFunction as m,isArray as _,initial as E,isBlank as b,join as v,split as C,set as y,camelCase as S,isEqual as N,replace as T,isPlainObject as P,flatMap as x,isString as w,test as A,size as M,assign as O,first as k,debounce as R,closest as L,once as D,bind as V,isNil as H,trim as I,some as $,isNull as W,fval as j,omit as U,groupBy as B,reject as z,filter as F,slice as K,compact as Q,remove as X,includes as G,find as q,throttle as Y,map as Z,replaceAll as J,snakeCase as tt,toString as et,reduce as st,isMatch as rt,clone as nt,findIndex as it,call as ot}from"myfx";const at=new WeakMap,lt=/\s+\.?key\s*=/;var ct,dt,ht;function ut(t){console.error("[CompElem]",t)}function pt(t,e){console.error(`[CompElem <${t}>]`,e)}function ft(e){return t(e).join("-")}function gt(t){return Object.getPrototypeOf(t)}!function(t){t[t.CSS=1]="CSS",t[t.COMPUTED=2]="COMPUTED"}(ct||(ct={})),function(t){t.PROPS="__deco_props",t.STATES="__deco_states",t.COMPUTED="__deco_computed",t.WATCH="__deco_watch",t.EVENTS="__deco_events"}(dt||(dt={})),function(t){t.CLASS="class",t.FIELD="field",t.METHOD="method"}(ht||(ht={}));class mt{static get priority(){return 0}}const _t="getKey",Et="__decorators",bt=new WeakMap;class vt{args;metadata;decoratorClass;instanceMap;key;priority=0;constructor(t,s,r){this.args=t,this.metadata=s,this.decoratorClass=r,this.priority=e(r,"priority",0),this.instanceMap=new WeakMap}create(t){let o,a=new this.decoratorClass(...this.args),l=a.targets,c=this.metadata[2];s(c)&&r(e(c,"configurable"))?o=ht.METHOD:n(this.metadata[2])&&(o=ht.FIELD),!i(l)&&o&&l.includes(o)?(a.created(t,...this.metadata),this.instanceMap.set(t,a)):ut(`Decorator '${this.decoratorClass.name}' is out of targets, expect '${l.join(",")}' bug got '${o}'`)}beforeMount(t,e){this.instanceMap.get(t).beforeMount(t,e,...this.metadata)}mounted(t,e){this.instanceMap.get(t).mounted(t,e,...this.metadata)}updated(t,e){this.instanceMap.get(t).updated(t,e)}}const Ct=new WeakMap;function yt(t){let s=(...s)=>(...r)=>{let n=r[0].constructor,i=e(n,Et);if(!o(n,Et)){let t=e(Object.getPrototypeOf(n),Et);i=t?a(t):[],Reflect.defineProperty(n,Et,{configurable:!1,enumerable:!1,value:i})}let l,c={},d=e(t,_t);if(d){let e=Ct.get(t);if(e||(e=new WeakMap,Ct.set(t,e)),c=e.get(n),c||(c={},e.set(n,c)),l=d(...s),c[l])return c[l]}let h=new vt(s,r,t);return c[l]=h,i?.push(h),h};return bt.set(s,!0),s}const St=new WeakMap;function Nt(t){if(1===arguments.length)return(e,s,r)=>{t.required=t.required||!1,t.attribute=!1!==t.attribute,Tt(e,s,t,r)};let e=arguments[0],s=arguments[1],r=arguments[2];t={type:void 0,required:!1,attribute:!0},r&&"function"==typeof r.type&&(t=l(r,t),r=void 0),Tt(e,s,t,r)}function Tt(t,e,s,r){let n;if(/[a-z]/.test(e[0])||ut(`Prop '${e}' must be in CamelCase`),!o(t.constructor,dt.PROPS)){const e={};let s=t.constructor;for(;(s=gt(s))!==jt;)c(e,s[dt.PROPS]?d(s[dt.PROPS]):{});Reflect.defineProperty(t.constructor,dt.PROPS,{configurable:!1,enumerable:!1,value:e}),n=new Set,h(e,((t,e)=>{if(t.attribute){let t=u(e);n?.add(t)}})),St.set(t.constructor,n)}if(r&&(r.get&&(s.getter=r.get),r.set&&(s.setter=r.set)),s.attribute){n||(n=St.get(t.constructor));let s=u(e);n?.add(s)}o(t.constructor,"observedAttributes")||(t.constructor.observedAttributes=[]),t.constructor.observedAttributes=p(n),t.constructor[dt.PROPS][e]=s}const Pt=new Set;function xt(t){return St.get(t)??Pt}const wt={collectWatch(t,e,s){let r=Rt.get(t);r||(r={},Rt.set(t,r));let n=r[s];n||(n=r[s]=[]),n.push(e)},startCollect(t,e){this.__collectType=e,this.__collecting=t},setUpdater(t){this.__updater=t},endCollect(){this.__collecting=null},__directiveQ:[],setDirectiveQ(t){let e=f(this.__directiveQ);const s=t?t.join(","):"",r=e?e.join(","):"";e&&s===r||(e&&e.length<t.length&&g(s,r)?this.__directiveQ[this.__directiveQ.length-1]=t:this.__directiveQ.push(t))},popDirectiveQ(){let t=a(this.__directiveQ);return this.__directiveQ=[],t},startRender(t){this.__renderCollecting=!0,this.__renderContext=t},endRender(t){this.__renderCollection.forEach((e=>{t._regDeps(e,this.__renderContext)})),this.__renderCollection.clear(),this.__renderCollecting=!1,this.__renderContext=null},collect(t){this.__renderCollection.add(t)},clear(){this.__directiveQ=[]},__updater:null,__collecting:null,__collectType:-1,__renderCollection:new Set,__renderContext:null,__renderCollecting:!1,__skipCheck:!1},At=new WeakMap,Mt=new WeakMap,Ot=new WeakMap,kt=new WeakMap,Rt=new WeakMap;function Lt(t,r){if(!s(t))return t;const n=t.__proxy?t:new Proxy(t,{get(t,e,s){if(!e)return;const r=Reflect.get(t,e,s);if("string"!=typeof e&&"number"!=typeof e)return r;let n=e in t;if((wt.__renderCollecting||wt.__collecting)&&(n&&t.hasOwnProperty(e)||!n)){let t=Mt.get(s)??[],r=a(t,[e]),n=r.join("-");if(wt.__renderCollecting)wt.collect(ft(r)),wt.setDirectiveQ(r);else if(wt.__collecting){let t;switch(wt.__collectType){case ct.COMPUTED:t=Ot.get(wt.__collecting),t||(t={},Ot.set(wt.__collecting,t));break;case ct.CSS:t=kt.get(wt.__collecting),t||(t={},kt.set(wt.__collecting,t))}let e=t[n];e||(e=t[n]=[]),e.push(wt.__updater)}}return r},set(t,r,n,o){if(!r)return!1;let l=t[r];if(!s(l)&&l===n)return!0;if(Number.isNaN(n)&&Number.isNaN(l))return!0;let c=Mt.get(o)??[],d=a(c,[r]),h=At.get(o).from,u=e(h.constructor,dt.PROPS),p=e(h.constructor,dt.STATES),f=e(u,[d[0],"hasChanged"])||e(p,[d[0],"hasChanged"]);if(f){if(!f.call(h,n,l))return!0}else if(l===n&&!at.has(l))return!0;u&&u[r]&&t.__isData&&u[r].sync&&h.emit("update:"+r,{value:n});let g=At.get(o)?.contextSet,E=n;!s(n)||m(n)||n instanceof Node||Object.isFrozen(n)||g.forEach((t=>{let e=At.get(o)?.pathMap,s=e?.get(t);s&&(d=a(s,[r]),Mt.set(E,d),E=Lt(E,t),Mt.set(E,d))}));let b=Reflect.set(t,r,E),v=At.get(o).pathMap;return g.forEach((t=>{let s=v.get(t);if(!s)return;t===h&&c.length>1&&s.length>1&&c[0]===s[0]&&(s=c),d=a(s,"length"==r&&_(o)?[]:[r]);let n=Ot.get(t),u=kt.get(t),p=Rt.get(t);if(n||u||p){let t=d.length;for(;t;){let s=d.slice(0,t).join("-");if(p){const r=p[s];t===d.length?r?.forEach((t=>{let e=t();e.ov=l,Dt.pushWatch(e)})):r?.forEach((t=>{let s=t();e(s,"deep")&&(s.ov=l,Dt.pushWatch(s))}))}if(n){let t=n[s];if(!i(t))for(let e=0;e<t.length;e++){const s=t[e];Dt.pushComputed(s)}}if(u){let t=u[s];if(!i(t))for(let e=0;e<t.length;e++){const s=t[e];Dt.pushCss(s)}}t--}}let f=t._notify(l,d);Dt.pushNext(f)})),b}});t.__proxy||Reflect.defineProperty(t,"__proxy",{enumerable:!1,writable:!1,configurable:!1,value:!0});let o=Mt.get(t)??[];if(Object.isExtensible(t)&&!At.get(n)){let t=new Set;t.add(r);let e=new WeakMap;e.set(r,o),At.set(n,{from:r,contextSet:t,pathMap:e})}else{At.get(n).contextSet.add(r);let t=At.get(n).pathMap,s=t.get(r),i=a(o);if(s&&s.join("")!==i.join("")){let t=e(r,E(s));_(t)||function(...t){console.warn("[CompElem]",...t)}(`The object is referenced by more than one @state '${i.join(".")},${s.join(".")}'`),s=i}else t.set(r,i)}for(let e in t){const n=t[e];!s(n)||n.__proxy||m(n)||n instanceof Node||Object.isFrozen(n)||(Mt.set(n,a(o,[e])),t[e]=Lt(n,r),Mt.set(t[e],a(o,[e])))}return n}class Dt{static watchSet=new Set;static computedSet=new Set;static cssSet=new Set;static nextSet=new Set;static nextPending=!1;static next;static{const t=Promise.resolve(),e=Dt.flush;Dt.next=()=>{t.then(e)}}static flush(){Dt.nextPending=!1;let t=Array.from(Dt.watchSet);Dt.watchSet.clear();let s=Array.from(Dt.computedSet);Dt.computedSet.clear();let r=Array.from(Dt.cssSet);Dt.cssSet.clear();let n=Array.from(Dt.nextSet);Dt.nextSet.clear(),t.forEach((t=>t(e(t,"ov")))),s.forEach((t=>t())),r.forEach((t=>t())),n.forEach((t=>t()))}static pushWatch(t){Dt.watchSet.add(t)}static pushComputed(t){Dt.computedSet.add(t)}static pushCss(t){Dt.cssSet.add(t)}static pushNext(t){Dt.nextSet.add(t),Dt.nextPending||(Dt.nextPending=!0,Dt.next())}}function Vt(t){return class extends t{__updatePoints;renderComponent;buildView(t){let e=this instanceof jt?this:this.renderComponent,[s,r]=we(e,t),n=[],i=Ve(n,s,r,e,this);return this.__updatePoints=n,i}updateView(t){if(b(v(t.strings)))return;if(!this.__updatePoints)return;let{vars:r}=t,n=this instanceof jt?this:this.renderComponent;for(let t=0;t<this.__updatePoints.length;t++){const i=this.__updatePoints[t];let o=i.varIndex,a=i.value,l=r,c=i.node,d=C(o,"-");for(let s=0;s<d.length;s++){const r=d[s];l=e(l,r),l&&l.vars&&t<d.length-1&&(l=l.vars)}if(!s(a)&&a===l)continue;let h=c;if(i.isDirective){if(!a.di)continue;l.di=a.di,l.di.renderParams=l.varChain,l.di._renderArgs=l.args,l.point=a.point,l.varPath=a.varPath,a.update(a.point,l.args,a.args)}else if(i.isToggleProp){if(!!l===a)continue;h.toggleAttribute(i.attrName,!!l),y(h,i.attrName,!!l)}else if(i.isProp){if(!s(l)&&l===a)continue;let t=S(i.attrName),r=e(i.node.constructor,dt.PROPS);if(r){let e=r[t];if(e&&e.hasChanged&&!e.hasChanged.call(this,l,a))continue}c instanceof jt?c._updateProps({[i.attrName]:l}):c instanceof HTMLSlotElement&&n._updateSlot(c.getAttribute("name")||"default",i.attrName,l)}else if(i.attrName&&!i.isEvent){if(!N(a,l))switch(i.attrName){case"value":if(c instanceof HTMLInputElement){c.value=l;break}default:c.setAttribute(i.attrName,T(i.attrTmpl,De,l+""))}}else if(i.isTmpl)(l.strings.join()!==a.tmpl.strings.join()||l.vars.some((t=>s(t)&&!P(t)))||a.tmpl.vars.some((t=>s(t)&&!P(t)))||!N(l.vars,a.tmpl.vars))&&i.value.updateView(l),a.tmpl=l,l=a;else if(i.isText){let t=i.textNode.nextSibling;t&&t===i.node.previousSibling?t.textContent=l:(He.remove(i.textNode,i.node),He.insertBefore(i.node,[l]))}i.value=l}}}}class Ht extends(Vt(Object)){tmpl;constructor(t){super(),this._renderVars=e(t,"_renderVars"),this.tmpl=t}}const It={boolean:Boolean,string:String,number:Number,object:Object,array:Array,function:Function,bigint:BigInt,symbol:Symbol,undefined:Object},$t=new WeakMap;let Wt=[];class jt extends(Vt(HTMLElement)){static __l_globalRule=document.createElement("style");static{document.head.appendChild(jt.__l_globalRule)}static defaults(t){Wt=x(t.css,(t=>{if(w(t)){let e=new CSSStyleSheet;return e.replaceSync(t),e}return t instanceof CSSStyleSheet?t:[]})),t.global,h(t,((t,e)=>{A(e[0],/[A-Z]/)}))}#t={};#e={"#slots":{}};#s={};#r={};#n;#i;#o={};__events={};get[Symbol.toStringTag](){return this.constructor.name}get reactiveData(){return this.#s}get attrs(){return this.#a}get props(){return this.#l}get renderRoot(){return this.#c}get renderRoots(){return this.#d}get parentComponent(){return this.#h}get slotHooks(){return this.#u}get css(){return $t.get(this.constructor)}get isMounted(){return this.#p}get slots(){return this.#e["#slots"]}#a;#l;#c;#d;#h;#f={};#u={};#g={};#p=!1;static get autoSlot(){return!0}static get styles(){return[]}static get globalStyles(){return[]}get styles(){return[]}#m=!1;constructor(...t){super(),1===M(t)&&(this.#l={},O(this.#l,k(t)));let s=this.render.bind(this);this.render=function(){let t;return wt.startRender(this),t=s(),wt.endRender(this),t};let r=e(this.constructor,"globalStyles"),n=e(this.constructor,"_global_style_attached");if(!i(r)&&"1"!==n){let t="";r.forEach((e=>{w(e)&&(t+=e+"\n")})),jt.__l_globalRule.textContent+=t,y(this.constructor,"_global_style_attached","1")}let o=$t.get(this.constructor),a=o??[];o||(h(e(this.constructor,"styles"),(t=>{if(w(t)){let e=new CSSStyleSheet;e.replaceSync(t),a.push(e)}else a.push(t)})),$t.set(this.constructor,a)),this.#n=this.attachShadow({mode:"open",slotAssignment:e(this.constructor,"autoSlot",!0)?"named":"manual"}),this.#n.adoptedStyleSheets=[...Wt,...a];let l=this.attributes.getNamedItem("css-link")?.value;if(l){const t=document.createElement("style");t.textContent=`@import "${l}"`,this.#n.appendChild(t)}let c=R(this.#_,20);this.#i=new MutationObserver((t=>{for(let e=0;e<t.length;e++){"childList"===t[e].type&&c.call(this)}})),this._slotsPropMap={default:[]};let d=e(this.constructor,Et);d&&d.sort(((t,e)=>e.priority-t.priority)).forEach((t=>t.create(this))),this.#E=this.#b.bind(this)}#E;connectedCallback(){let t=L(this.parentNode,(t=>t instanceof jt||t.host instanceof jt),"parentNode");this.#h=t?t instanceof jt?t:t.host:null,this.__init()}disconnectedCallback(){this.#i.disconnect()}__init(){if(this.#m)return;this.#v();const t=this.#C();this.propsReady(t);for(const e in t){const s=t[e];this.#e[e]=s}this.#y(),h(this.#e,((t,e)=>{let s=Reflect.getOwnPropertyDescriptor(this.#e,e);Reflect.defineProperty(this,e,{get(){let t=Reflect.get(this.#s,e);return s?.get?s?.get():t},set(t){s?.set?s?.set(t):Reflect.set(this.#s,e,t)}})})),Reflect.defineProperty(this.#e,"__isData",{enumerable:!1,value:!0}),this.#s=Lt(this.#e,this);let s=this.render(),r=this.buildView(s);if(r){let t=p(r);t.forEach((t=>{this.#n.appendChild(t)})),this.#d=t,this.#c=t[0]}this.#_(),this.beforeMount(),this.#i.observe(this,{childList:!0});const n=this;let i=e(this.constructor,Et);i&&i.sort(((t,e)=>e.priority-t.priority)).forEach((t=>{t.beforeMount(this,((t,e)=>(n.#s[t]=e,n.#s[t])))}));let o=e(this.constructor,dt.WATCH);h(o,((t,s)=>{t.forEach((t=>{let{source:r,options:n,handler:i}=t,o=i.bind(this);e(n,"once",!1)&&(o=D(o));const a=function(t){let s=e(this,r.replaceAll("-","."));o(s,t,r)}.bind(this);let l=e(n,"deep",!1);if(a.deep=l,wt.collectWatch(this,(()=>a),s),!e(n,"immediate",!1))return;let c=e(this,r.replaceAll("-","."));o(c,c,r)}))}));let a=e(this.constructor,dt.COMPUTED);h(a,((t,e)=>{wt.startCollect(this,ct.COMPUTED),wt.setUpdater((()=>{this.#s[e]=t.call(this)})),this.#e[e]=t.call(this),wt.endCollect(),Reflect.defineProperty(this,e,{get(){return Reflect.get(this.#s,e)},set(t){pt(this.tagName,"Cannot set a computed property '"+e+"'")}})}));let l=e(this.constructor,dt.EVENTS);l&&l.forEach((t=>{let e=t.name,s=O({target:document,once:!1,passive:!1,capture:!1},t.options),r=V(t.fn,this),n=s.target;m(n)&&(n=n.call(this,this)),n?n.addEventListener(e,r,s):pt(this.tagName,"The target of @event('"+e+"',...) is invalid")})),h(this.#u,((t,e)=>{this.#S(e)})),wt.startCollect(this,ct.CSS);let c=[];this.styles.forEach((t=>{if(!m(t))return;let e=new CSSStyleSheet;c.push(e),wt.setUpdater((()=>{let s=t()??"";e.replaceSync(s)}));let s=t();b(s)||e.replaceSync(s)})),wt.endCollect(),this.#n.adoptedStyleSheets=[...this.#n.adoptedStyleSheets,...c],setTimeout((()=>{this.#p=!0,this.mounted(),i&&i.forEach((t=>{t.mounted(this,((t,e)=>(n.#s[t]=e,n.#s[t])))}))}),0),this.#m=!0}propsReady(t){}render(){throw Error(`[CompElem <${this.tagName}>] Missing render()`)}beforeMount(){}mounted(){}#N(t,s){this.#v();let r=e(this.#t[s],"props");r&&h(this.slots,((t,s)=>{t.filter((t=>t.nodeType===Node.ELEMENT_NODE)).forEach((t=>{t instanceof jt?t._updateProps(r):h(r,((s,r)=>{if(t instanceof HTMLSlotElement){let n=e(t,"__l_comp");if(n){let e=t.name||"default",i=n.#t[e];i||(i=n.#t[e]={props:{}}),i.props||(i.props={}),i.props[r]=s,n.#N(t,e)}}else t.setAttribute(r,s)}))}))})),this.slotChange(t,s)}slotChange(t,e){}attributeChangedCallback(t,e,s){this.#T(t,e,s)}shouldUpdate(t){return!0}updated(t){}emit(t,s={},r){r&&r.event&&(s.event=r.event),s.target=this,this.dispatchEvent(new CustomEvent(t,{bubbles:e(r,"bubbles",!1),composed:e(r,"composed",!1),cancelable:!0,detail:s}))}#P={};on(t,e){this.#P[t]||(this.#P[t]=[]);let s=e.bind(this);this.#P[t].push(s),this.addEventListener(t,s)}nextTick(t){Dt.pushNext(t)}forceUpdate(){h(this.#s,((t,e)=>{this.#r[e]={value:void 0,chain:void 0}})),this.#b()}_notify(t,r){let n=[];for(let i=0;i<r.length;i++){const o=r[i];n.push(o);let a=e(this,n),l=ft(n);this.#r[l]={value:a,chain:"slots"===l?["slots"]:n,oldValue:t,end:n.length===r.length},s(a)&&"#"!=l[0]&&at.set(a,l)}return this.#E}#b(){if(M(this.#r)<1)return;const t=this.#r;this.#r={};let r=e(this.constructor,Et);if(r&&r.sort(((t,e)=>e.priority-t.priority)).forEach((e=>{e.updated(this,t)})),!this.shouldUpdate(t))return;let n=new Set;h(t,(({value:t,chain:e,oldValue:s},r)=>{this.#o[r]&&this.#o[r].forEach((t=>{n.add(t)}))})),n.forEach((t=>{if(t===this)this.updateView(this.render());else{let e=t.render(...t._renderArgs?t._renderArgs:[]);e&&t.updateView(e)}})),this.#x.forEach((t=>{this.#S(t)})),this.updated(t),h(t,(({value:t,chain:e,oldValue:r},n)=>{s(t)&&at.has(t)&&at.delete(t)}))}#C(){let t=e(this.constructor,dt.PROPS),i=this.attributes,a=this.tagName,l=this.#l,c={};h(i,(({name:e,value:s})=>{if(e[0]===be||e[0]===ve||e[0]===Ce||e===Ne||"slot"===e)return;let r=S(e);t&&!t[r]&&(c[e]=s)})),this.#a=this.#a?O(this.#a,c):c;let d={};return h(t,((c,h)=>{let p,f=t[h],g=o(l,h),m=e(this,h);if(!("_defaultValue"in f)&&(f._defaultValue=m,!f.type)){n(m)&&pt(a,"Prop '"+h+"' has neither propType nor defaultValue be used for type inference");let t=typeof m;_(m)&&(t="array");let e=It[t];f.type=e}if(g)p=H(l[h])?m:l[h];else{p=m;let t=i.getNamedItem(u(h))||i.getNamedItem(ve+u(h));t&&(g=!0,p=t.value)}if(f.required&&!g)return pt(a,"Prop '"+h+"' is required"),!1;p=this.#w(t,h,p);let E=e(t,[h,"getter"]);E&&(E=V(E,this));let b=e(t,[h,"setter"]);b&&(b=V(b,this)),(E||b)&&Reflect.defineProperty(this.#e,h,{set:b||function(t){},get:E}),f.attribute&&r(p)&&!s(p)&&this.setAttribute(u(h),I(p)),this.#e[h]=p,d[h]=p})),Object.seal(d)}#w(t,e,s){let i=t[e];if(!i)return s;let o=i.isValid,a=i.type,l=_(a)?a:[a],c=i.converter,d=s;if(!$(l,(t=>t===String))&&w(d)&&!W(d))try{d=c?c(d):j(d,{html:Ie})}catch(t){pt(this.tagName,`Convert attribute '${e}' error with `+d)}for(let t=0;t<l.length;t++){"Boolean"===l[t].name&&(w(d)&&/(?:^true$)|(?:^false$)/.test(d)?d=j(d):(n(d)||b(d))&&(d=!0))}let h=typeof d,u=!r(d);for(let t=0;t<l.length;t++){const e=l[t];if(A(h,e.name,"i")||d instanceof e||Object.prototype.toString.call(d)===Object.prototype.toString.call(e.prototype)){u=!0;break}}return u||pt(this.tagName,`Invalid prop '${e}'. expected '${l.map((t=>t.name||t))}' but got '${h}'`),o&&(o.call(this,d,this.#e)||pt(this.tagName,`Invalid prop '${e}'. IsValid() check failed`)),d}#y(){let t=e(this.constructor,dt.STATES);h(t,((s,r)=>{let n=t[r],i=e(this,r);if(n){let t=n.prop;i=t?d(this.#e[t]):e(this,r)}this.#e[r]=i}))}#A=R(this.propsReady,100);_setParentProps(t,s){if(this.#m){let r=e(this.constructor,dt.PROPS);h(t,((t,e)=>{let s=S(e),n=r[s];if(!n)return;let i=this.#e[s];t=this.#w(r,s,t),n.hasChanged&&!n.hasChanged.call(this,t,i)||(this.#e[s]=t,this._notify(i,[s]))})),O(this.#l,t),O(this.#a,s),this.#A(this.#l)}}_updateProps(t){let s=e(this.constructor,dt.PROPS);h(t,((t,e)=>{let r=S(e),n=s[r];if(!n)return;let i=this.#e[r];t=this.#w(s,r,t),n.hasChanged&&!n.hasChanged.call(this,t,i)||(wt.__skipCheck=!0,y(this,r,t),wt.__skipCheck=!1)})),O(this.#l,t),this.#A(this.#l)}_initProps(t,e){this.#l=c(this.#l||{},t),this.#a=c({},e)}_bindSlot(t,e,s){if(this.#f[e]||(this.#f[e]=t,Reflect.defineProperty(t,"__l_comp",{value:this})),t.addEventListener("slotchange",(s=>{this.#m&&this.#N(t,"default"===e?"":e)})),!i(s)){let t=this.#t[e];t||(t=this.#t[e]={}),s.nodeFilter&&(t.filter=s.nodeFilter),t.props=U(s,"nodeFilter")}}_bindSlotHook(t,e){this.#u[t]=e}#x=new Set;_updateSlot(t,e,s){let r=this.#f[t],n=this.#u[t];if(!n&&!r)return;let i=this.#t[t];if(e&&(i.props||(i.props={}),i.props[e]=s),n)this.#x.add(t);else{let t=r.assignedElements({flatten:!0});for(let r=0;r<t.length;r++){t[r].setAttribute(e,s+"")}}}#v(){const t=x(this.childNodes,(t=>t.nodeType===Node.COMMENT_NODE?[]:t instanceof HTMLSlotElement?t.assignedNodes({flatten:!0}):t));let e=B(t,(t=>t.nodeType===Node.TEXT_NODE?"default":t instanceof Element?t.getAttribute("slot")||"default":void 0));if(i(e))return void(i(this.#e["#slots"])||(this.#m?this.#s["#slots"]={}:this.#e["#slots"]={}));h(e,((t,e)=>{if(e){for(;t.length>0;){let e=t[0];if(!(e.nodeType===Node.TEXT_NODE&&b(e.textContent)||e instanceof HTMLSlotElement&&i(e.assignedNodes({flatten:!0}))))break;t.shift()}for(;t.length>0;){let e=f(t);if(!(e.nodeType===Node.TEXT_NODE&&b(e.textContent)||e instanceof HTMLSlotElement&&i(e.assignedNodes({flatten:!0}))))break;t.pop()}}}));let s={};h(e,((t,e)=>{i(t)||(s[e]=t)})),this.#m?this.#s["#slots"]=s:this.#e["#slots"]=s}#S(t){let s=this.#u[t];if(!s)return;let r=this.#t[t];if(!this.#e["#slots"][t])return;this.renderAsync(s,e(r,"props"));const n=this._asyncDirectives.get(s);let o=n?.buildView(s(e(r,"props"))),a=z(p(o),(t=>t.nodeType===Node.COMMENT_NODE));if(a){let e=this.#g[t];if(!i(e))for(let t=0;t<e.length;t++){const s=e[t];s.parentNode?.removeChild(s)}this.#g[t]=a,this.append(...a),this.#x.clear()}}_asyncDirectives=new WeakMap;renderAsync(t,...e){}#_(){i(this.#t)||h(this.slots,((t,e)=>{if(i(t))return;let r=this.#t[e],n=t;if(r){let e=r.filter;if(m(e))n=e(t);else if(s(e)){let s=e.type,r=e.maxCount;if(s){let e=_(s)?s:[s];n=F(t,(t=>$(e,(e=>t instanceof e))))}r>0&&(n=K(t,0,r))}}if("named"===this.#n.slotAssignment){let e=[];for(let s=0;s<t.length;s++){const r=t[s];n.includes(r)||e.push(r)}for(;e.length>0;){let t=e.pop();t.parentNode?.removeChild(t)}}else this.#f[e].assign(...n);this.#m&&this.#N(this.#f[e],"default"===e?"":e)}))}#T(t,s,r){if(!this.isMounted)return;if(xt(this.constructor).has(t)){let s=S(t);if(W(r)){r=e(this.constructor,dt.PROPS)[s]._defaultValue}this._updateProps({[s]:r})}}_regDeps(t,e){let s=this.#o[t];s||(s=this.#o[t]=new Set),s.add(e);let r=t.split("-");if(r.pop(),r.length<1)return;let n=r.join("-");s=this.#o[n],s||(s=this.#o[n]=new Set),s.add(e)}}var Ut,Bt,zt;!function(t){t.NONE="NONE",t.REMOVE="REMOVE",t.REPLACE="REPLACE",t.UPDATE="UPDATE",t.APPEND="APPEND"}(Ut||(Ut={}));class Ft{key;varIndex;value;isText=!1;isTmpl=!1;isDirective=!1;node;textNode;isComponent=!1;attrName;attrTmpl;isProp=!1;isToggleProp=!1;isEvent;constructor(t,e,s,r){this.varIndex=t,this.node=e,s&&(this.attrName=s),r&&(this.attrTmpl=r)}}!function(t){t.ATTR="attr",t.PROP="prop",t.TEXT="text",t.CLASS="class",t.STYLE="style",t.SLOT="slot",t.TAG="tag"}(Bt||(Bt={}));class Kt{startNode;endNode;type;attrName;varIndex;expressionChain;nodes;constructor(t,e,s){this.startNode=t,this.attrName=e,this.type=s}setVarIndex(t){this.varIndex=t}getNodes(){let t=this.startNode.nextSibling;if(!this.endNode)return[t];let e=[];for(;t&&t!==this.endNode;)e.push(t),t=t?.nextSibling;return e}}!function(t){t.AFTER_BEGIN="afterbegin"}(zt||(zt={}));class Qt extends Function{diClass;args;di;varPath;point;slotComponent;varChain;constructor(t,...e){super(),this.diClass=t,this.args=e,this.varChain=wt.popDirectiveQ(),this.di=new this.diClass,this.di.renderParams=this.varChain}checkScope(t){let s=e(this.diClass,"scopes");i(s)||A(s.join(","),t)||ut(`Directive '${this.diClass.name}' is out of scopes, expect '${s.join(",")}' bug got '${t}'`)}render(t){let e=this.di;return this.args,e.renderComponent||(e.renderComponent=t),this.di=e,e._renderArgs=this.args,this.di.render(...this.args)}update(t,e,s){let r=this.di.update(t,e,s);if(r===Ut.NONE)return;let n=t.getNodes();if(r===Ut.REMOVE)for(let t=0;t<n.length;t++){const e=n[t];e.parentNode?.removeChild(e)}else if(r===Ut.REPLACE){let s=[];for(let t=0;t<n.length;t++){const e=n[t];e.parentNode?.removeChild(e)}let r=this.di.render(...e),i=this.di.buildView(r);s=p(i);let o=document.createDocumentFragment();o.append(...s),t.endNode.parentNode.insertBefore(o,t.endNode)}else if(r===Ut.UPDATE){let s,r={},o=[],a=[],l=this.di.render(...e);if(l||(l=new je([],[])),i(n)){let e=this.di.buildView(l);return void t.startNode.after(...e)}let c={};l instanceof je&&l.vars.forEach((t=>{if(t instanceof je){const e=t.getKey();c[e]=t,r[e]=!0,a.push(e)}})),n=F(Q(n),(t=>t.nodeType===Node.ELEMENT_NODE)),s=F(Q(p(s)),(t=>t.nodeType===Node.ELEMENT_NODE));let d={},u="",g={};for(let t=0;t<n.length;t++){let e=n[t],s=e.getAttribute("key");if(s){if(d[s]){u=s;break}d[s]=e,o.push(s),g[s]=!0}}if(u)return void ut(`${S(this.diClass.name)} - duplicate key '${u}'`);let m=r;const _=t.startNode.parentNode;let b=[],v=[];if(h(g,((t,e)=>{m[e]||(v.push(e),delete g[e],X(o,e))})),!i(a)){let e="",s=-1,r=[],n=new Map;for(let i=0;i<a.length;i++){const l=a[i];let c=o.findIndex((t=>t===l));if(c>-1&&c!==i){if(s<0||s-c==1){let t=f(r);r.push({nodeId:l,targetId:0===i?zt.AFTER_BEGIN:t?t.nodeId:a[i-1]})}else n.set(r.length,{group:r,targetId:""}),r=[],r.push({nodeId:l,targetId:o[c]});s=c}else if(c<0){let s=e?d[e]||t.endNode:t.startNode;b.push({prevNode:s,newkey:l})}e=l}i(n)&&r.length>0&&n.set(r.length,{group:r,targetId:""});let l=n.keys().toArray(),c=l.sort(((t,e)=>t-e));if(l.length>0&&l.length<2){let{group:e}=n.get(c[0]);E(e).forEach((({targetId:e,nodeId:s})=>{let r,n=d[s];e===zt.AFTER_BEGIN?(r=t.startNode,r.after(n)):(r=d[e],r.after(n))}))}}b.length>0&&this.#M(b,c,a),b.forEach((e=>{let s=e.newkey,r=this.newNodeMap[s],n=e.prevNode;n===t.endNode?n.before(r):(t.startNode,n.after(r))})),v.forEach((t=>{let e=o.findIndex((e=>e==t));this.#O(e);let s=d[t];s&&s.parentNode&&_.removeChild(s)})),this.di.__updatePoints.forEach((t=>{t.key||(t.key=t.value.tmpl.getKey());const e=a.findIndex((e=>e==t.key));t.varIndex=e})),this.di.updateView(l)}}getDirective(){return this.di}newNodeMap={};#M(t,e,s){const r=[],n=[];t.forEach((t=>{let s=t.newkey;r.push(""),n.push(e[s])})),r.push("");let i=new je(r,n),o=this.di.__updatePoints,a=this.di.buildView(i);this.di.__updatePoints.forEach(((t,e)=>{const s=t.value.tmpl.getKey();t.key=s})),this.di.__updatePoints.push(...o),a.forEach((t=>{t instanceof HTMLElement&&(this.newNodeMap[t.getAttribute("key")]=t)}))}#O(t){X(this.di.__updatePoints,((e,s)=>{if(e.varIndex==t)return He.remove(e.node,e.textNode),!0}))}}function Xt(t){return(...e)=>{let s=null;return e.forEach(((t,r)=>{if(m(t)){let n=t;e[r]=function(...t){let e=s.di;wt.startRender(e);let r=n.call(e.renderComponent,...t);return wt.endRender(e.renderComponent),r}}})),s=new Qt(t,...e),s}}const Gt=["resize","outside","mutate"],qt=new WeakMap,Yt=[],Zt=new ResizeObserver((t=>{for(const e of t){const t=Array.isArray(e.contentBoxSize)?e.contentBoxSize[0]:e.contentBoxSize,s=Array.isArray(e.borderBoxSize)?e.borderBoxSize[0]:e.borderBoxSize;let r=qt.get(e.target);if(r){r(new CustomEvent("resize",{bubbles:!1,cancelable:!1,detail:{borderBox:{w:s.inlineSize,h:s.blockSize},contentBox:{w:t.inlineSize,h:t.blockSize}}}),e.target)}}}));var Jt;!function(t){t.Child="child",t.Tree="tree",t.Attr="attr",t.Char="char"}(Jt||(Jt={}));const te=new WeakMap,ee=new MutationObserver((t=>{for(let e=0;e<t.length;e++){const s=t[e];let r=te.get(s.target);if(!r)return;let n={target:s.target},i=null;switch(s.type){case"subtree":n.type=Jt.Tree,i=r[Jt.Tree];break;case"childList":n.type=Jt.Child,n.addedNodes=s.addedNodes,n.removedNodes=s.removedNodes,i=r[Jt.Child];break;case"attributes":n.type=Jt.Attr,n.attributeName=s.attributeName,n.oldValue=s.oldValue,i=r[Jt.Attr];break;case"characterData":n.type=Jt.Char,n.oldValue=s.oldValue,i=r[Jt.Char]}if(i){i(new CustomEvent("mutate",{bubbles:!1,cancelable:!1,detail:n}),s.target)}}}));function se(t,e,s,r){if("resize"===t)!function(t,e){qt.has(t)||(qt.set(t,e),Zt.observe(t))}(e,s);else if("outside"===t){if("mousedown"===r[0])!function(t,e){Yt.push([t,e])}(e,s)}else"mutate"===t&&function(t,e,s){let r=G(s,"child"),n=G(s,"attr"),i=G(s,"char"),o=G(s,"tree"),a=te.get(t);a||(a={},te.set(t,a),r&&(a[Jt.Child]=e),n&&(a[Jt.Attr]=e),i&&(a[Jt.Char]=e),o&&(a[Jt.Tree]=e),ee.observe(t,{childList:r,attributes:n,characterData:i,subtree:o}))}(e,s,r)}document.addEventListener("mousedown",(t=>{let e=t.target;Yt.forEach((([s,r])=>{if(!s.contains(e)){r(new CustomEvent("outside",{bubbles:!1,cancelable:!1,detail:{currentTarget:s,event:t}}),s)}}))}),!1);const re=/,|^(debounce:.+)|(debounce$)/,ne=/,|^(throttle:.+)|(throttle$)/,ie="self",oe="stop",ae="prevent",le="once",ce="left",de="right",he="middle",ue="ctrl",pe="alt",fe="shift",ge="meta",me={esc:"escape"},_e=":";function Ee(t,e,s,r){let n,i=t.split("."),o=i.shift(),a=i.includes(le),l=e;if(n=q(i,(t=>re.test(t)))){let t=n.split(_e);l=R(l,parseInt(t[1])||100)}if(n=q(i,(t=>ne.test(t)))){let t=n.split(_e);l=Y(l,parseInt(t[1])||100)}if(a&&(l=D(l)),function(t){return Gt.includes(t)}(o))return se(o,s,l,i),l;let c=t=>{if(i.includes(ae)&&t.preventDefault(),i.includes(oe)&&t.stopPropagation(),!i.includes(ie)||t.target===t.currentTarget){if(t instanceof MouseEvent){if(i.includes(ce)&&0!=t.button)return;if(i.includes(de)&&2!=t.button)return;if(i.includes(he)&&1!=t.button)return}else if(t instanceof KeyboardEvent){if(X(i,(t=>t==ue))[0]&&!t.ctrlKey)return;if(X(i,(t=>t==pe))[0]&&!t.altKey)return;if(X(i,(t=>t==fe))[0]&&!t.shiftKey)return;if(X(i,(t=>t==ge))[0]&&!t.metaKey)return;if(!Z(i,(t=>me[t]||t)).includes(t.key.toLowerCase()))return}l(t,s)}};s.addEventListener(o,c);let d=r.__events[o];return d||(d=r.__events[o]=[]),d.push([s,c]),c}const be="@",ve=".",Ce="?",ye="*",Se=":",Ne="ref",Te=/[.?-a-z]+\s*=\s*(['"])\s*([^='"]*<\!--c_ui-pl_df-->){2,}.*?\1/ims,Pe=/<\s*[a-z0-9-]+([^>]*<\!--c_ui-pl_df-->)*[^>]*?(?<!-)>/gims,xe="slot-props";function we(t,s){let r="",n=a(s.vars),i=s.strings.length-1,o=s.vars.length-1;for(let n=0;n<=i;n++){const i=s.strings[n];let a=e(s.vars,n,"");if(a&&a.di){let e=a.render(t);if(e instanceof je){let[s,r]=we(t,e);Reflect.defineProperty(a,"_renderVars",{value:r}),a=Ae+s+Me}else a=e??Re}else if(a instanceof je){let[e,s]=we(t,a);Reflect.defineProperty(a,"_renderVars",{value:s}),a=Oe+e+ke}else a=n>o?"":Re;r+=i+a}let l=r.match(Te);if(l){return ut(`Parse error: attribute value can be set only one interpolation —— \n ${J(l[0],Re,"${...}")}`),["",n]}let c=0;return r=r.replace(Pe,((t,e)=>J(t,Re,(()=>Re.replace("--\x3e","")+c++)))),r=r.replace($e,"$1><").trim(),[r,n]}const Ae="\x3c!--c_ui-pl_di-start--\x3e",Me="\x3c!--c_ui-pl_di-end--\x3e",Oe="\x3c!--c_ui-pl_tmpl-start--\x3e",ke="\x3c!--c_ui-pl_tmpl-end--\x3e",Re="\x3c!--c_ui-pl_df--\x3e",Le="\x3c!--c_ui-pl_df",De=/<!--c_ui-pl_df\d*(-->)?/;function Ve(t,s,r,i,a){const l=document.createElement("div");l.innerHTML=s;const c=document.createNodeIterator(l,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT);let d,h,_=0,E=null,b=[],v=[],C=[],y=[t],N=[],P=[];for(;d=c.nextNode();)if(d instanceof HTMLElement||d instanceof SVGElement){d instanceof jt?E=d:E?.contains(d)||(E=null);let e={},s=p(d.attributes);for(let n=0;n<s.length;n++){const a=s[n];let{name:l,value:c}=a;if(l===xe){let t=d.getAttribute("name")||"default";if(E){let e=E._slotsPropMap[t];e||(e=E._slotsPropMap[t]=[]),e.push(d)}}if(g(l,Le)){let e=r[_];if(e instanceof Qt){e.checkScope(Bt.TAG);let s=new Kt(d,l.substring(1),Bt.TAG);e.point=s,e.di.slotComponent=E,e.di.renderComponent=i;let r=new Ft(_,d);r.isDirective=!0,r.value=e,r.isComponent=!!E,t.push(r),_++,e.di.created(s,...e.args)}d.removeAttribute(l)}else if(l[0]!==be)if(l!==Ne)if(l[0]!==ve||De.test(c)){if(De.test(c)){let s=r[_],n=new Ft(_,d,l.replace(/\.|\?|@/,""),c);if(t.push(n),n.isComponent=!!E,l[0]===ve||l[0]===Ce||l[0]===ye){if(s instanceof Qt){s.checkScope(Bt.PROP);let t=new Kt(d,l.substring(1),Bt.PROP);s.point=t,s.slotComponent=E,n.value=s,n.isDirective=!0,s&&s.di.created(s.point,...s.args)}else if(l[0]===Ce)n.isToggleProp=!0,n.value=!!s,n.value&&d.setAttribute(l.substring(1),"");else if(l[0]===ye){n.value=s;let t=l.substring(1);const[e,r]=t.split(Se);let i=e;switch(r){case"camel":i=S(i);break;case"kebab":i=u(i);break;case"snake":i=tt(i)}n.attrName=i,d.setAttribute(i,s)}else if(d instanceof jt||"SLOT"===d.tagName){let t=S(l.substring(1));t in d||"SLOT"===d.tagName||pt(d.tagName,`Prop '${l}' is not defined in ${d.tagName}`),n.value=s,n.isProp=!0,e[t]=s}else pt(d.tagName,`Prop '${l}' can only be set on a CompElem or a slot`);d.removeAttribute(l),s=""}else{let t;if(n.value=s,s instanceof Qt){let e=Bt.ATTR;"class"===l?e=Bt.CLASS:"style"===l&&(e=Bt.STYLE),s.checkScope(e),n.isDirective=!0;let r=new Kt(d,l,e);s.point=r,s.di.slotComponent=E,s.di.renderComponent=i,t=s,s=""}c=T(c,De,s),a.value=c,t&&t.di.created(t.point,...t.args)}_++}}else pt(d.tagName,`Prop '${l}' must be an interpolation`);else{if(De.test(c)){let t=r[_];if(!o(t,"current")){pt(d.tagName,"Ref must be a RefObject");continue}_++,t.current=d}d.removeAttribute(l)}else{let e=t=>{};if(De.test(c)){let s=r[_];if(!m(s)){pt(d.tagName,`Event '${l}' must be a function`);continue}e=s.bind(i);let n=new Ft(_,d,l.replace(/\.|\?|@/,""),c);n.isComponent=!!E,n.isEvent=!0,t.push(n),_++}Ee(l.substring(1),e,d,i),d.removeAttribute(l)}}d instanceof jt?d._initProps(e):d instanceof HTMLSlotElement&&i._bindSlot(d,d.name||"default",e)}else{let s=d,o=`\x3c!--${s.nodeValue}--\x3e`;if(o===Ae){h&&b.push(h),h=s;let e=r[_],n=new Ft(_,d);n.isComponent=!!E,n.isDirective=!0,n.value=e;let o=E?Bt.SLOT:Bt.TEXT,a=new Kt(h,"",o);e.point=a,e.di.slotComponent=E,e.di.renderComponent=i,v.push(e),t.push(n),C.push(n),t=[],y.push(t),_++,P.push(_),N.push(r),r=e._renderVars,_=0;continue}if(o===Me){C.pop().textNode=s;let e=v.pop();e.point.endNode=s,e.di.created(e.point,...e.args),h=b.pop(),e.di.__updatePoints=t,y.pop(),t=f(y),r=N.pop(),_=P.pop()}else{if(o===Oe){h&&b.push(h),h=s;let n=r[_],o=new Ft(_,d);o.isComponent=!!E,o.isTmpl=!0;let l=f(v);(l&&"ForEach"===e(l,"diClass.name")||"ForEach"==a.constructor.name)&&(o.key=n.getKey()),n=o.value=new Ht(n);let c=E?Bt.SLOT:Bt.TEXT,u=new Kt(h,"",c);n.point=u,n.slotComponent=E,n.renderComponent=i,v.push(n),t.push(o),C.push(o),t=[],y.push(t),_++,P.push(_),N.push(r),r=n._renderVars,_=0;continue}if(o===ke){C.pop().textNode=s;let e=v.pop();e.point.endNode=s,h=b.pop(),e.__updatePoints=t,y.pop(),t=f(y),r=N.pop(),_=P.pop()}}if(o!==Re)continue;let l=new Ft(_,d);t.push(l),l.isComponent=!!E,l.isText=!0;let c,u=r[_];if(c=document.createComment(`compelem-ui-${_}-child-start`),s.parentNode.insertBefore(c,s),s.nodeValue=`compelem-ui-${_}-child-end`,l.textNode=c,u instanceof Qt){l.isDirective=!0,l.value=u;let t=E?Bt.SLOT:Bt.TEXT,e=new Kt(c,"",t);e.endNode=s,u.point=e,u.di.slotComponent=E,u.di.renderComponent=i,u.di.created(e,...u.args),u=""}else if(u instanceof je){l.isTmpl=!0,l.value=u;let[e,s]=we(i,u);u=Ve(t,e,s,i,a)}else l.value=u;if(_++,n(u))continue;if(u instanceof NodeList){let t=document.createDocumentFragment();t.append(...u),s.parentNode.insertBefore(t,s)}else if(u instanceof Element)s.parentNode.insertBefore(u,s);else if(I(u)){let t=document.createTextNode(u);s.parentNode.insertBefore(t,s)}}return l.childNodes}const He={insertBefore:function(t,e){if(!t.parentNode)return;let s=document.createDocumentFragment();s.append(...e),t.parentNode.insertBefore(s,t)},remove:function(t,e){if(t===e)return void t?.parentNode?.removeChild(t);let s=t.nextSibling;for(;s&&s!==e;)s?.parentNode?.removeChild(s),s=t.nextSibling}};function Ie(t,...e){return new je(w(t)?[t]:t,e)}const $e=/([a-z0-9"'])\s*>\s*</gim;function We(t){return{current:t}}class je{strings;vars;constructor(t,e){this.strings=a(t),this.vars=e}getKey(){let t=this.vars,e="";return h(this.strings,((s,r)=>{if(lt.test(s))return e=et(t[r]),!1})),e}getKeys(){let t=this.vars,e=[];for(let s=0;s<this.strings.length;s++){const r=this.strings[s];if(lt.test(r)){let r=et(t[s]);e.push(r)}}return i(e)&&t.forEach((t=>{if(t instanceof je){let s=t.getKey();e.push(s)}})),e}append(t){let e=f(this.strings);return t.strings.forEach(((t,s)=>{0!=s?this.strings.push(t):this.strings[this.strings.length-1]=e+t})),this.vars=a(this.vars,t.vars),this}insert(t,e){let s=e.strings.shift();return this.strings[t]+=s,this.strings.splice(t+1,0,...e.strings),this.vars.splice(t,0,...e.vars),this}getHTML(t){let[e,s]=we(t,this),r=Ve([],e,s,t,t);return st(r,((t,e)=>t+e.outerHTML),"")}}function Ue(t,e,s){s.get||ut(`Computed '${e}' must be a getter`),o(t.constructor,dt.COMPUTED)||(t.constructor[dt.COMPUTED]=i(t.constructor[dt.COMPUTED])?{}:d(t.constructor[dt.COMPUTED])),t.constructor[dt.COMPUTED][e]=s.get}function Be(t,e){return(s,r,n)=>{o(s.constructor,dt.EVENTS)||(s.constructor[dt.EVENTS]=i(s.constructor[dt.EVENTS])?[]:d(s.constructor[dt.EVENTS])),s.constructor[dt.EVENTS].push({name:t,options:e,fn:s[r]})}}var ze;!function(t){t.ONCE="once",t.UPDATABLE="updatable"}(ze||(ze={}));class Fe extends mt{static get priority(){return Number.MAX_VALUE}created(t,e,s,...r){}mounted(t,e,...s){}get targets(){return[ht.FIELD]}selector;cache;result;constructor(t,e){super(),this.selector=t,this.cache=e}static getKey(t){return t}getter(t){this.result=t.shadowRoot?.querySelector(this.selector)}beforeMount(t,e,s,r,...n){const i=this;Reflect.defineProperty(t,r,{get:()=>(i.result&&i.cache||i.getter(t),i.result)})}updated(t,e){this.cache===ze.UPDATABLE&&this.getter(t)}}const Ke=yt(Fe),Qe=yt(class extends Fe{getter(t){this.result=t.shadowRoot?.querySelectorAll(this.selector)}});function Xe(t){if(1===arguments.length)return(e,s)=>{Ge(e,s,t)};Ge(arguments[0],arguments[1],{prop:""})}function Ge(t,e,s){if(!o(t.constructor,dt.STATES)){const e={};let s=t.constructor;for(;(s=gt(s))!==jt;)c(e,s[dt.STATES]?d(s[dt.STATES]):{});Reflect.defineProperty(t.constructor,dt.STATES,{configurable:!1,enumerable:!1,value:e})}t.constructor[dt.STATES][e]=s}function qe(t,e,s){Ge(t.prototype,e,s||{prop:""})}function Ye(t){return e=>{if(e){if(e.prototype.hasOwnProperty("attributeChangedCallback")){let t=e.prototype.attributeChangedCallback;e.prototype.attributeChangedCallback=function(e,s,r){jt.prototype.attributeChangedCallback.call(this,e,s,r),t.call(this,e,s,r)}}if(e.prototype.hasOwnProperty("connectedCallback")){let t=e.prototype.connectedCallback;e.prototype.connectedCallback=function(){jt.prototype.connectedCallback.call(this),t.call(this)}}if(e.prototype.hasOwnProperty("disconnectedCallback")){let t=e.prototype.connectedCallback;e.prototype.disconnectedCallback=function(){jt.prototype.disconnectedCallback.call(this),t.call(this)}}customElements.define(t,e)}}}function Ze(t,e){return(s,r)=>{o(s.constructor,dt.WATCH)||(s.constructor[dt.WATCH]=i(s.constructor[dt.WATCH])?{}:d(s.constructor[dt.WATCH]));(_(t)?t:[t]).forEach((t=>{let n=t.replaceAll(".","-"),i=s.constructor[dt.WATCH][n];_(i)||(i=s.constructor[dt.WATCH][n]=[]),i.push({source:t,options:e,handler:s[r]})}))}}class Je extends(Vt(Object)){_renderArgs;static get scopes(){return[]}renderParams}const ts=["key"];const es=Xt(class extends Je{created(t,e){let s=t.startNode;if(s instanceof jt){let t={},r={};h(e,((e,n)=>{ts.includes(n)||(n in s?t[n]=e:r[n]=e+"")})),s._initProps(t,r)}else h(e,((t,e)=>{s.setAttribute(e,t)}))}update(t,e,s){return Ut.NONE}static get scopes(){return[Bt.TAG]}render(t){}});const ss=Xt(class extends Je{created(t,e){let r=[];_(e)?r=Q(e):s(e)?r=x(e,((t,e)=>t?e:[])):w(e)&&(r=e.split(" "));let n=t.startNode;h(this.lastCls,(t=>{n.classList.remove(t)})),h(r,(t=>{n.classList.add(t)})),this.lastCls=a(r)}update(t,e,s){return this.created(t,e[0]),Ut.NONE}static get scopes(){return[Bt.CLASS]}lastCls;render(t){}});const rs=Xt(class extends Je{created(t,...e){}update(t,e,s){if(i(t.getNodes())&&(!e||i(e[0])))return Ut.NONE;if(rt(this.lastAry,e[0])&&this.lastAry.length===e[0].length)return Ut.NONE;if(!i(this.renderParams)){let t=f(this.renderParams);_(t)||(t=[t]),this.renderParams=t}return this.lastAry=nt(e[0]),Ut.UPDATE}constructor(t){super(),i(this.renderParams)||(this.renderParams=p(f(this.renderParams)))}static get scopes(){return[Bt.TEXT,Bt.SLOT]}lastAry;lastRenderTmpl;render(t,e){let s=Z(t,((t,s)=>e(t,s)));if(s.length<1)return this.lastRenderTmpl=new je([],[]),this.lastRenderTmpl;let r=[],n=[];const i=[],o=[];for(let t=0;t<s.length;t++){const e=s[t];let a=f(n),l=e.vars,c=!0,d=e.strings;for(let t=0;t<d.length;t++){const e=d[t];if(lt.test(e)){let e=l[t]+"";if(r.includes(e))return void ut(`forEach - duplicate key '${e}'`);r.push(e),c=!1}0==t&&a?n[n.length-1]=a+e:n.push(e)}if(c)return void ut("forEach - missing 'key' prop");let h=f(i);h&&d.length>0&&(i[i.length-1]=I(h)+d.shift()),i.push(""),o.push(e)}return this.lastAry=nt(t),i.push(""),this.lastRenderTmpl=new je(i,o),this.lastRenderTmpl}});const ns=Xt(class extends Je{created(t,...e){}ifNodes;elseNodes;static get scopes(){return[Bt.TEXT,Bt.SLOT]}update(t,e,s){return!!e[0]==!!s[0]?Ut.NONE:(e[0],Ut.REPLACE)}render(t,e,s){return t?e(t):s(t)}});const is=Xt(class extends Je{created(t,...e){}static get scopes(){return[Bt.TEXT,Bt.SLOT]}update(t,e,s){return e[0]===s[0]?Ut.NONE:e[0]?Ut.REPLACE:Ut.REMOVE}render(t,e){return t?e():Ie``}});var os;!function(t){t.CHANGE="change",t.INPUT="input"}(os||(os={}));const as=Xt(class extends Je{created(r,n,i){this.modelPath||(this.modelPath=f(this.renderParams)),i&&(this.modelPath=t(i));const o=r.startNode;if("binded"!==e(o,"_model"))if(s(n)||I(n)||(n=""),o instanceof jt)o._initProps({value:n}),o.addEventListener("update:value",(t=>{y(this.renderComponent,this.modelPath,t.detail.value)})),y(o,"_model","binded");else if(o instanceof HTMLTextAreaElement)o.setAttribute("value",n+""),o.addEventListener("input",(t=>{let e=t.target;y(this.renderComponent,this.modelPath,e.value)})),y(o,"_model","binded");else if(o instanceof HTMLInputElement){let t="",e="";switch(o.type){case"checkbox":case"radio":t="checked",e="change";break;default:t="value",e="input"}o.setAttribute(t,n+""),o.addEventListener(e,(t=>{let e=t.target;y(this.renderComponent,this.modelPath,e.value)})),y(o,"_model","binded")}else o instanceof HTMLSelectElement&&(o.setAttribute("value",n+""),o.addEventListener("change",(t=>{let e=t.target;y(this.renderComponent,this.modelPath,e.value)})),y(o,"_model","binded"))}update(t,e,s){if(this.modelPath||(this.modelPath=f(this.renderParams)),!N(e,s)){const s=t.startNode;if(s instanceof jt)s._updateProps({value:e[0]});else if(s instanceof HTMLTextAreaElement||s instanceof HTMLSelectElement)s.setAttribute("value",e[0]+"");else if(s instanceof HTMLInputElement)switch(s.type){case"checkbox":case"radio":e[0]?s.setAttribute("checked",""):s.removeAttribute("checked");break;default:s.setAttribute("value",e[0]+"")}}return Ut.NONE}static get scopes(){return[Bt.TAG]}modelPath;render(t,e){}});const ls=Xt(class extends Je{created(t,e){let s=t.startNode;n(this.display)&&(this.display=s.style.display),this.renderComponent.nextTick((()=>{s.style.display=e?this.display:"none"}))}update(t,e,s){return this.created(t,e[0]),Ut.NONE}display=void 0;static get scopes(){return[Bt.TAG]}constructor(t){super(),this.point=t}render(t){}});const cs=Xt(class extends Je{created(t,e,s){e=e.bind(this.renderComponent),this.slotComponent._bindSlotHook(s||"default",e)}update(t,e,s){return Ut.NONE}static get scopes(){return[Bt.SLOT]}render(t,e){}});class ds{static getCssText(t){return w(t)?t:v(Z(t,((t,e)=>u(e)+":"+t)),";")}static setStyle(t,e){if(w(t)&&!I(t))return{};let s=ds.getCssText(t),r={};return h(s.split(";"),(t=>{let s=t.split(":"),n=I(s[0]),i=I(s[1]);r[n]=e.style.getPropertyValue(n),e.style.setProperty(n,i)})),r}}const hs=Xt(class extends Je{created(t,e){ds.setStyle(e,t.startNode)}update(t,e,s){return this.created(t,e[0]),Ut.NONE}constructor(t){super(),this.point=t}static get scopes(){return[Bt.STYLE]}render(t){}});const us=Xt(class extends Je{created(t,e){this.modelPath||(this.modelPath=f(this.renderParams));const s=t.startNode;let r=t.attrName;s._initProps({[r]:e}),s.addEventListener("update:"+r,(t=>{y(this.renderComponent,this.modelPath,t.detail.value)}))}update(t,e,s){if(!N(e,s)){const s=t.startNode;let r=t.attrName;s._updateProps({[r]:e[0]})}return Ut.NONE}static get scopes(){return[Bt.PROP]}modelPath;constructor(t){super()}render(t){}});const ps=Xt(class extends Je{created(t,...e){}static get scopes(){return[Bt.TEXT,Bt.SLOT]}update(t,e,s){return N(e,s)?Ut.NONE:Ut.REPLACE}render(t,e){let s=()=>Ie``,r=[],n=[];h(e,((t,e)=>{if(m(t))r.push(e),n.push(t);else{let e=t[0],s=t[1];r.push(e),n.push(s)}"default"===e&&(s=t)}));let i=it(r,(e=>m(e)?e(t):e==t));return ot(n[i]??s)}});export{jt as CompElem,ds as CssHelper,mt as Decorator,ht as DecoratorType,vt as DecoratorWrapper,Je as Directive,Ut as DirectiveUpdateTag,Qt as DirectiveWrapper,Kt as EnterPoint,Bt as EnterPointType,_t as GetKeyFnName,os as ModelTriggerType,ze as QueryCache,je as Template,Ft as UpdatePoint,bt as _DecoratorMap,Et as _DecoratorsKey,xt as _getObservedAttrs,es as bind,we as buildHTML,ss as classes,Ue as computed,We as createRef,yt as decorator,Xt as directive,Be as event,rs as forEach,Ie as html,ns as ifElse,is as ifTrue,qe as makeState,as as model,Nt as prop,Ke as query,Qe as queryAll,ls as show,cs as slot,Xe as state,hs as styles,us as sync,Ye as tag,Ze as watch,ps as when};