compelem 0.20.0-b2 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1,33 +1,10 @@
1
1
  /**
2
- * compelem v0.20.0-b2.1772633551
2
+ * compelem v0.20.0.1773502279
3
3
  * A modern, reactive, fast, lightweight and flexible lib for building web components
4
4
  * @holyhigh2
5
5
  * git+https://github.com/holyhigh2/compelem.git
6
6
  */
7
- import myfx, { concat, toPath, some, isString, isUndefined, isBlank, closest, defaults, isLowerCaseChar, merge, each, kebabCase, has, toArray, set, get, includes, find, debounce, throttle, once, remove, map, size, isSymbol, isFunction, isArray, isObject, eachRight, slice, flatMap, test, assign, first, walkTree, isEmpty, filter, camelCase, isNull, startsWith, isNil, bind as bind$1, isDefined, trim, isBoolean, parseJSON, cloneDeep, keys, groupBy, last, reject, toString, reduce, compact, initial, except, join, split, isEqual, replace, replaceAll, snakeCase, isMatch, clone, findIndex, call } from 'myfx';
8
-
9
- /**
10
- * 样式模板
11
- * @author holyhigh2
12
- */
13
- class CssTemplate {
14
- strings;
15
- vars;
16
- constructor(strings, vars) {
17
- this.strings = concat(strings);
18
- this.vars = vars;
19
- }
20
- getCss(comp) {
21
- let str = '';
22
- this.strings.forEach((s, i) => {
23
- str = str + s + (this.vars[i] ?? '');
24
- });
25
- return str;
26
- }
27
- destroy() {
28
- this.strings = this.vars = null;
29
- }
30
- }
7
+ import myfx, { toPath, some, isString, isUndefined, isBlank, closest, isObject, isFunction, startsWith, get, concat, toArray, isSymbol, isArray, size, eachRight, slice, defaults, isLowerCaseChar, merge, each, kebabCase, has, set, includes, find, debounce, throttle, once, remove, map, flatMap, test, assign, first, walkTree, isEmpty, filter, isNil, camelCase, isNull, isDefined, trim, isBoolean, parseJSON, cloneDeep, keys, groupBy, last, reject, toString, reduce, compact, initial, except, join, split, isEqual, replace, replaceAll, snakeCase, bind as bind$1, isMatch, clone, findIndex, call } from 'myfx';
31
8
 
32
9
  const SLOT_NAME_DEFAULT = 'default';
33
10
  /**
@@ -47,14 +24,26 @@ var Mode;
47
24
  })(Mode || (Mode = {}));
48
25
  const DefinitionCompEventMap = new Map();
49
26
  const DefinitionTagMap = {};
50
- const DefinitionWatchMap = new Map();
51
- const DefinitionComputedMap = new Map();
52
- const DefinitionStateMap = new Map();
53
- const DefinitionPropMap = new Map();
27
+ const DefinitionComputedMap = new WeakMap();
28
+ const DefinitionStateMap = new WeakMap();
29
+ const DefinitionPropMap = new WeakMap();
54
30
  const DefinitionDecoratorMap = new Map();
55
31
  const ObservedAttrsMap = new Map();
32
+ const WatchKeysOnceMap = new WeakMap();
33
+ const WatchKeysDeepListMap = new WeakMap();
34
+ const WatchKeysListMap = new WeakMap();
35
+ const WatchUpdateMap = new WeakMap();
36
+ const WatchDeepUpdateMap = new WeakMap();
37
+ const WatchImmediateListMap = new WeakMap();
38
+ const PropSyncKeySetMap = new WeakMap();
39
+ const StateShallowKeySetMap = new WeakMap();
40
+ const HasChangedPropOrStateMap = new WeakMap();
41
+ const ComputedUpdateDepsMap = new WeakMap();
42
+ const CssUpdateDepsMap = new WeakMap();
56
43
  const ComponentDynamicCssUpdaterMap = new WeakMap();
57
44
  const PATH_SEPARATOR = '-';
45
+ const PROP_NAME_SLOTS$1 = 'slots';
46
+ const DATA_KEY = '__data_';
58
47
 
59
48
  function showError(msg) {
60
49
  console.error(`[CompElem]`, msg);
@@ -146,6 +135,303 @@ function getSlotComponent(node, renderComponent) {
146
135
  return documentFragment ? documentFragment.host : undefined;
147
136
  }
148
137
 
138
+ /**
139
+ * 用于提供全局state状态管理
140
+ * @author holyhigh2
141
+ */
142
+ function getterValue(getter, propertyKey, context) {
143
+ let thisHost = context;
144
+ let v = getter ? getter.call(thisHost) : Reflect.get(thisHost[DATA_KEY], propertyKey);
145
+ if (Collector.__collecting) {
146
+ Collector.__varPathList.push(propertyKey);
147
+ }
148
+ if (PROXY_MAP.has(v)) {
149
+ let contextList = EXTRA_CONTEXT_OF_VAR.get(v);
150
+ if (!contextList) {
151
+ contextList = new Set();
152
+ EXTRA_CONTEXT_OF_VAR.set(v, contextList);
153
+ }
154
+ contextList.add(thisHost.__thisRef);
155
+ return PROXY_MAP.get(v);
156
+ }
157
+ if (isObject(v) && !isFunction(v) && !(v instanceof Node) && !Object.isFrozen(v)) {
158
+ let keySet = StateShallowKeySetMap.get(thisHost.constructor);
159
+ let shallow = keySet?.has(propertyKey);
160
+ v = shallow || propertyKey === PROP_NAME_SLOTS$1 ? v : reactive(v, thisHost, propertyKey);
161
+ }
162
+ return v;
163
+ }
164
+ function setterValue(propertyKey, v, context) {
165
+ let thisHost = context;
166
+ if (!thisHost.__inited) {
167
+ Reflect.set(thisHost[DATA_KEY], propertyKey, v);
168
+ return;
169
+ }
170
+ let oldValue = thisHost[DATA_KEY][propertyKey];
171
+ let stateMap = HasChangedPropOrStateMap.get(thisHost.constructor);
172
+ let hasChanged = stateMap?.get(propertyKey);
173
+ if (hasChanged) {
174
+ if (!hasChanged.call(thisHost, v, oldValue, [propertyKey], v, oldValue))
175
+ return true;
176
+ }
177
+ else {
178
+ //默认对比算法
179
+ if (Object.is(oldValue, v)) {
180
+ return true;
181
+ }
182
+ }
183
+ //check watch
184
+ requestWatchUpdate(thisHost, v, oldValue, propertyKey);
185
+ //check computed
186
+ requestComputedUpdate(thisHost, propertyKey);
187
+ //check css
188
+ requestCssUpdate(thisHost, propertyKey);
189
+ Reflect.set(thisHost[DATA_KEY], propertyKey, v);
190
+ thisHost._notify(oldValue, [propertyKey]);
191
+ //update sync
192
+ let syncKeySet = PropSyncKeySetMap.get(thisHost.constructor);
193
+ if (syncKeySet?.has(propertyKey)) {
194
+ thisHost.emit('update' + ":" + propertyKey, { value: v });
195
+ }
196
+ }
197
+ function requestWatchUpdate(context, newValue, oldValue, fullPath, rootObjNew, rootObjOld) {
198
+ let superComp = _getSuper(context.constructor);
199
+ let watchKeys = WatchKeysListMap.get(context.constructor) ?? WatchKeysListMap.get(superComp);
200
+ let watchKeysDeep = WatchKeysDeepListMap.get(context.constructor) ?? WatchKeysDeepListMap.get(superComp);
201
+ let watchDeepUpdateMap = WatchDeepUpdateMap.get(context.constructor) ?? WatchDeepUpdateMap.get(superComp);
202
+ let watchUpdateMap = WatchUpdateMap.get(context.constructor) ?? WatchUpdateMap.get(superComp);
203
+ let onceMap = WatchKeysOnceMap.get(context.constructor) ?? WatchKeysOnceMap.get(superComp);
204
+ watchKeys?.forEach(wk => {
205
+ if (fullPath === wk ||
206
+ (startsWith(wk, fullPath + '.') && !Object.is(get(context._getPrivateData(), wk), get(newValue, wk))) ||
207
+ (startsWith(fullPath, wk + '.') && watchKeysDeep?.includes(wk) && !Object.is(get(context._getPrivateData(), wk), get(newValue, wk)))) {
208
+ concat(toArray(watchUpdateMap[wk]), toArray(watchDeepUpdateMap[wk])).forEach(fn => {
209
+ if (!fn)
210
+ return;
211
+ if (onceMap.get(wk) === true)
212
+ return;
213
+ context._watchUpdateArgsInNextTick.set(fn, {
214
+ newValue, oldValue, chain: fullPath.split('.'), rootObjNew, rootObjOld, fullMatch: wk === fullPath
215
+ });
216
+ context._watchUpdateSetInNextTick.add(fn);
217
+ if (onceMap.has(wk))
218
+ onceMap.set(wk, true);
219
+ });
220
+ }
221
+ });
222
+ }
223
+ function requestComputedUpdate(context, fullPath) {
224
+ let depMap = ComputedUpdateDepsMap.get(context.constructor);
225
+ if (depMap?.has(fullPath)) {
226
+ depMap.get(fullPath)?.forEach(fn => {
227
+ context._computedUpdateSetInNextTick.add(fn);
228
+ });
229
+ }
230
+ }
231
+ function requestCssUpdate(context, fullPath) {
232
+ let deps = CssUpdateDepsMap.get(context.constructor);
233
+ if (!deps)
234
+ return;
235
+ let pathChain = fullPath.split('.');
236
+ let path = '';
237
+ pathChain.forEach(p => {
238
+ path = path ? path + '.' + p : p;
239
+ if (deps.has(path)) {
240
+ context._cssUpdateInNextTick = true;
241
+ }
242
+ });
243
+ }
244
+ const Collector = {
245
+ popDirectiveQ() {
246
+ let rs = this.__varPathList.reduceRight((acc, p) => {
247
+ if (!acc.includes(p)) {
248
+ acc.unshift(p);
249
+ }
250
+ return acc;
251
+ }, []);
252
+ return rs;
253
+ },
254
+ start() {
255
+ this.__collecting = true;
256
+ this.__varPathList = [];
257
+ },
258
+ end(renderComponent, up) {
259
+ if (renderComponent && up) {
260
+ renderComponent._regSubViewDeps(Collector.popVarPathList(), up);
261
+ }
262
+ this.__collecting = false;
263
+ },
264
+ popVarPathList() {
265
+ let rs = Array.from(new Set(this.__varPathList));
266
+ this.__varPathList = [];
267
+ return rs;
268
+ },
269
+ __varPathList: [],
270
+ __collecting: false,
271
+ };
272
+ //对象值在不同上下文的根路径
273
+ const OBJECT_VAR_ROOT_PATH_IN_CONTEXT = new WeakMap();
274
+ const OBJECT_VAR_PATH = new WeakMap();
275
+ //缓存已经创建的proxy对象
276
+ const PROXY_MAP = new WeakMap();
277
+ //对象值的创建上下文
278
+ const OBJECT_VAR_ROOT_CONTEXT = new WeakMap();
279
+ //上级对象所在的扩展context
280
+ const EXTRA_CONTEXT_OF_VAR = new WeakMap();
281
+ function reactive(obj, context, rootProp) {
282
+ if (PROXY_MAP.has(obj))
283
+ return PROXY_MAP.get(obj);
284
+ if (OBJECT_VAR_ROOT_CONTEXT.has(obj)) {
285
+ if (rootProp) {
286
+ let pathMap = OBJECT_VAR_ROOT_PATH_IN_CONTEXT.get(context);
287
+ if (!pathMap) {
288
+ pathMap = new WeakMap();
289
+ OBJECT_VAR_ROOT_PATH_IN_CONTEXT.set(context, pathMap);
290
+ }
291
+ pathMap.set(obj, rootProp);
292
+ let contextList = EXTRA_CONTEXT_OF_VAR.get(obj);
293
+ if (!contextList) {
294
+ contextList = new Set();
295
+ EXTRA_CONTEXT_OF_VAR.set(obj, contextList);
296
+ }
297
+ if (!contextList.values().some(v => v.deref() === context)) {
298
+ contextList.add(new WeakRef(context));
299
+ }
300
+ }
301
+ return obj;
302
+ }
303
+ const proxyObject = new Proxy(obj, {
304
+ get(target, prop, receiver) {
305
+ if (!prop)
306
+ return undefined;
307
+ const value = Reflect.get(target, prop, receiver);
308
+ if (isSymbol(prop))
309
+ return value;
310
+ if (isFunction(value))
311
+ return value;
312
+ if (prop === 'length' && isArray(target))
313
+ return value;
314
+ if (Collector.__collecting) {
315
+ let supPath = OBJECT_VAR_PATH.has(receiver) ? concat(OBJECT_VAR_PATH.get(receiver)) : [];
316
+ supPath.push(prop);
317
+ let propPath = supPath.join('.');
318
+ Collector.__varPathList.push(propPath);
319
+ }
320
+ if (PROXY_MAP.has(value))
321
+ return PROXY_MAP.get(value);
322
+ let reactiveVal = value;
323
+ if (isObject(value) && !isFunction(value) && !(value instanceof Node) && !Object.isFrozen(value)) {
324
+ reactiveVal = reactive(value, context);
325
+ let supPath = OBJECT_VAR_PATH.has(receiver) ? concat(OBJECT_VAR_PATH.get(receiver)) : [];
326
+ supPath.push(prop);
327
+ OBJECT_VAR_PATH.set(reactiveVal, supPath);
328
+ PROXY_MAP.set(value, reactiveVal);
329
+ }
330
+ return reactiveVal;
331
+ },
332
+ set(target, prop, newValue, receiver) {
333
+ if (!prop)
334
+ return false;
335
+ let ov = target[prop];
336
+ let chain = OBJECT_VAR_PATH.get(receiver) ?? [];
337
+ let subChain = concat(chain, [prop]);
338
+ let stateMap = HasChangedPropOrStateMap.get(context.constructor);
339
+ let hasChanged = stateMap?.get(subChain[0]);
340
+ let moreThan1 = subChain.length > 1;
341
+ let rootObjNew = newValue;
342
+ let rootObjOld = ov;
343
+ if (moreThan1) {
344
+ rootObjOld = rootObjNew = context._getPrivateData()[subChain[0]];
345
+ }
346
+ if (hasChanged) {
347
+ if (!hasChanged.call(context, rootObjNew, rootObjOld, subChain, newValue, ov))
348
+ return true;
349
+ }
350
+ else {
351
+ //默认对比算法
352
+ if (Object.is(ov, newValue)) {
353
+ return true;
354
+ }
355
+ }
356
+ let nv = newValue;
357
+ let rs = Reflect.set(target, prop, nv);
358
+ let extraContext = EXTRA_CONTEXT_OF_VAR.get(receiver);
359
+ let k = subChain.join('.');
360
+ //check watch
361
+ requestWatchUpdate(context, nv, ov, k, rootObjNew, rootObjOld);
362
+ //check computed
363
+ requestComputedUpdate(context, k);
364
+ //check css
365
+ requestCssUpdate(context, k);
366
+ notifyUpdate(context, rootObjOld, subChain);
367
+ extraContext?.forEach(ctxRef => {
368
+ let ctx = ctxRef.deref();
369
+ if (!ctx)
370
+ return;
371
+ let ctxRootPath = ctx._wrapperProp[subChain[0]];
372
+ let ck = subChain.join('.');
373
+ ck = ck.replace(subChain[0], ctxRootPath);
374
+ //check watch
375
+ requestWatchUpdate(ctx, nv, ov, ck);
376
+ //check computed
377
+ requestComputedUpdate(ctx, ck);
378
+ //check css
379
+ requestCssUpdate(ctx, ck);
380
+ notifyUpdate(ctx, rootObjOld, ck.split('.'));
381
+ });
382
+ return rs;
383
+ }
384
+ });
385
+ if (!OBJECT_VAR_PATH.has(proxyObject)) {
386
+ OBJECT_VAR_PATH.set(proxyObject, rootProp ? [rootProp] : []);
387
+ }
388
+ PROXY_MAP.set(obj, proxyObject);
389
+ if (rootProp) {
390
+ OBJECT_VAR_ROOT_CONTEXT.set(proxyObject, context);
391
+ if (!OBJECT_VAR_ROOT_PATH_IN_CONTEXT.has(context)) {
392
+ let pathMap = new WeakMap();
393
+ pathMap.set(proxyObject, rootProp);
394
+ OBJECT_VAR_ROOT_PATH_IN_CONTEXT.set(context, pathMap);
395
+ }
396
+ }
397
+ return proxyObject;
398
+ }
399
+ function notifyUpdate(context, oldValue, path, subNewValue, subOldValue) {
400
+ let i = size(path);
401
+ eachRight(path, (p) => {
402
+ let varPath = slice(path, 0, i--);
403
+ context._notify(oldValue, varPath);
404
+ });
405
+ }
406
+ const QMap = new Map();
407
+ class Queue {
408
+ static nextSet = new Set();
409
+ static nextPending = false;
410
+ static next;
411
+ static flush() {
412
+ Queue.nextPending = false;
413
+ let nq = Array.from(Queue.nextSet);
414
+ Queue.nextSet.clear();
415
+ QMap.clear();
416
+ nq.forEach(u => u());
417
+ nq = null;
418
+ }
419
+ static pushNext(updater) {
420
+ Queue.nextSet.add(updater);
421
+ if (!Queue.nextPending) {
422
+ Queue.nextPending = true;
423
+ Queue.next();
424
+ }
425
+ }
426
+ }
427
+ (() => {
428
+ const p = Promise.resolve();
429
+ const nextFn = Queue.flush;
430
+ Queue.next = () => {
431
+ p.then(nextFn);
432
+ };
433
+ })();
434
+
149
435
  function prop(options) {
150
436
  if (arguments.length === 1) {
151
437
  return (target, propertyKey, descriptor) => {
@@ -167,11 +453,11 @@ function defineProp(target, propertyKey, options, descriptor) {
167
453
  showError(`Prop '${propertyKey}' must be in CamelCase`);
168
454
  }
169
455
  let attrSet;
170
- if (!DefinitionPropMap.has(target.constructor.name)) {
456
+ if (!DefinitionPropMap.has(target.constructor)) {
171
457
  const mixinProps = {};
172
458
  let parentCtor = target.constructor;
173
459
  while ((parentCtor = _getSuper(parentCtor)) !== CompElem) {
174
- merge(mixinProps, DefinitionPropMap.get(parentCtor.name) ?? {});
460
+ merge(mixinProps, DefinitionPropMap.get(parentCtor) ?? {});
175
461
  }
176
462
  attrSet = new Set();
177
463
  each(mixinProps, (v, k) => {
@@ -180,8 +466,8 @@ function defineProp(target, propertyKey, options, descriptor) {
180
466
  attrSet?.add(kbb);
181
467
  }
182
468
  });
183
- ObservedAttrsMap.set(target.constructor.name, attrSet);
184
- DefinitionPropMap.set(target.constructor.name, mixinProps);
469
+ ObservedAttrsMap.set(target.constructor, attrSet);
470
+ DefinitionPropMap.set(target.constructor, mixinProps);
185
471
  }
186
472
  if (descriptor) {
187
473
  if (descriptor.get)
@@ -191,7 +477,7 @@ function defineProp(target, propertyKey, options, descriptor) {
191
477
  }
192
478
  if (options.attribute) {
193
479
  if (!attrSet) {
194
- attrSet = ObservedAttrsMap.get(target.constructor.name);
480
+ attrSet = ObservedAttrsMap.get(target.constructor);
195
481
  }
196
482
  let kbb = kebabCase(propertyKey);
197
483
  attrSet?.add(kbb);
@@ -202,12 +488,43 @@ function defineProp(target, propertyKey, options, descriptor) {
202
488
  }
203
489
  if (attrSet)
204
490
  target.constructor.observedAttributes = toArray(attrSet);
205
- set(DefinitionPropMap.get(target.constructor.name), propertyKey, options);
491
+ set(DefinitionPropMap.get(target.constructor), propertyKey, options);
492
+ //cache tags
493
+ if (options.hasChanged) {
494
+ let changeMap = HasChangedPropOrStateMap.get(target.constructor);
495
+ if (!changeMap) {
496
+ changeMap = new Map();
497
+ HasChangedPropOrStateMap.set(target.constructor, changeMap);
498
+ }
499
+ changeMap.set(propertyKey, options.hasChanged);
500
+ }
501
+ if (options.sync) {
502
+ let keySet = PropSyncKeySetMap.get(target.constructor);
503
+ if (!keySet) {
504
+ keySet = new Set();
505
+ PropSyncKeySetMap.set(target.constructor, keySet);
506
+ }
507
+ keySet.add(propertyKey);
508
+ }
509
+ //setters & getters
510
+ Reflect.defineProperty(target, propertyKey, {
511
+ get() {
512
+ return getterValue(descriptor?.get, propertyKey, this);
513
+ },
514
+ set(v) {
515
+ if (descriptor?.set) {
516
+ descriptor.set(v);
517
+ }
518
+ else {
519
+ setterValue(propertyKey, v, this);
520
+ }
521
+ },
522
+ });
206
523
  }
207
524
  //内部接口
208
525
  const emptySet = new Set;
209
526
  function _getObservedAttrs(ctor) {
210
- return ObservedAttrsMap.get(ctor.name) ?? emptySet;
527
+ return ObservedAttrsMap.get(ctor) ?? emptySet;
211
528
  }
212
529
 
213
530
  /*************************************************************
@@ -225,6 +542,7 @@ const AllResizeEls = new WeakMap;
225
542
  const AllOutsideDownEls = [];
226
543
  const AllOutsideClickEls = [];
227
544
  const AllOutsideDblClickEls = [];
545
+ const ResizeTargetInitSet = new WeakSet();
228
546
  const resizeObserver = new ResizeObserver((entries) => {
229
547
  for (const entry of entries) {
230
548
  const contentBoxSize = Array.isArray(entry.contentBoxSize)
@@ -233,17 +551,13 @@ const resizeObserver = new ResizeObserver((entries) => {
233
551
  const borderBoxSize = Array.isArray(entry.borderBoxSize)
234
552
  ? entry.borderBoxSize[0]
235
553
  : entry.borderBoxSize;
554
+ if (!ResizeTargetInitSet.has(entry.target)) {
555
+ ResizeTargetInitSet.add(entry.target);
556
+ continue;
557
+ }
236
558
  let cbk = AllResizeEls.get(entry.target);
237
559
  if (cbk) {
238
- let ev = new CustomEvent('resize', {
239
- bubbles: false,
240
- cancelable: false,
241
- detail: {
242
- borderBox: { w: borderBoxSize.inlineSize, h: borderBoxSize.blockSize },
243
- contentBox: { w: contentBoxSize.inlineSize, h: contentBoxSize.blockSize },
244
- },
245
- });
246
- cbk(ev, entry.target);
560
+ cbk({ target: entry.target, contentBoxSize, borderBoxSize, type: 'resize' });
247
561
  }
248
562
  }
249
563
  });
@@ -305,12 +619,8 @@ const mutationObserver = new MutationObserver(mutations => {
305
619
  break;
306
620
  }
307
621
  if (cbk) {
308
- let ev = new CustomEvent('mutate', {
309
- bubbles: false,
310
- cancelable: false,
311
- detail
312
- });
313
- cbk(ev);
622
+ detail.type = 'mutate';
623
+ cbk(detail);
314
624
  }
315
625
  }
316
626
  });
@@ -355,15 +665,7 @@ document.addEventListener('mousedown', e => {
355
665
  let t = get(e.composedPath(), 0, e.target);
356
666
  AllOutsideDownEls.forEach(([node, cbk]) => {
357
667
  if (!node.contains(t) && !node.contains(closest(t, (node) => node instanceof ShadowRoot, 'parentNode')?.host)) {
358
- let ev = new CustomEvent('outside', {
359
- bubbles: false,
360
- cancelable: false,
361
- detail: {
362
- currentTarget: node,
363
- event: e
364
- },
365
- });
366
- cbk(ev, node);
668
+ cbk({ type: 'outside', target: node, modifier: 'mousedown', event: e });
367
669
  }
368
670
  });
369
671
  }, false);
@@ -371,15 +673,7 @@ document.addEventListener('click', e => {
371
673
  let t = get(e.composedPath(), 0, e.target);
372
674
  AllOutsideClickEls.forEach(([node, cbk]) => {
373
675
  if (!node.contains(t) && !node.contains(closest(t, (node) => node instanceof ShadowRoot, 'parentNode')?.host)) {
374
- let ev = new CustomEvent('outside', {
375
- bubbles: false,
376
- cancelable: false,
377
- detail: {
378
- currentTarget: node,
379
- event: e
380
- },
381
- });
382
- cbk(ev, node);
676
+ cbk({ type: 'outside', target: node, modifier: 'click', event: e });
383
677
  }
384
678
  });
385
679
  }, false);
@@ -387,15 +681,7 @@ document.addEventListener('dblclick', e => {
387
681
  let t = get(e.composedPath(), 0, e.target);
388
682
  AllOutsideDblClickEls.forEach(([node, cbk]) => {
389
683
  if (!node.contains(t) && !node.contains(closest(t, (node) => node instanceof ShadowRoot, 'parentNode')?.host)) {
390
- let ev = new CustomEvent('outside', {
391
- bubbles: false,
392
- cancelable: false,
393
- detail: {
394
- currentTarget: node,
395
- event: e
396
- },
397
- });
398
- cbk(ev, node);
684
+ cbk({ type: 'outside', target: node, modifier: 'dblclick', event: e });
399
685
  }
400
686
  });
401
687
  }, false);
@@ -416,311 +702,130 @@ function addOutsideClick(node, cbk, component) {
416
702
  function addOutsideDblClick(node, cbk, component) {
417
703
  AllOutsideDblClickEls.push([node, cbk]);
418
704
  //record
419
- return (remove = false) => {
420
- myfx.remove(AllOutsideDblClickEls, el => el[0] === node && el[1] === cbk);
421
- };
422
- }
423
- function isExtEvent(evName) {
424
- return ExtEvNames.includes(evName);
425
- }
426
- function addExtEvent(evName, node, cbk, parts, component) {
427
- if (evName === 'resize') {
428
- return addResize(node, cbk);
429
- }
430
- else if (evName === 'outside') {
431
- switch (parts[0]) {
432
- case 'mousedown':
433
- return addOutsideMouseDown(node, cbk);
434
- case 'dblclick':
435
- return addOutsideDblClick(node, cbk);
436
- case 'click':
437
- default:
438
- return addOutsideClick(node, cbk);
439
- }
440
- }
441
- else if (evName === 'mutate') {
442
- return addMutation(node, cbk, parts);
443
- }
444
- }
445
-
446
- const MODI_EV_DEBOUNCE = /,|^(debounce:.+)|(debounce$)/;
447
- const MODI_EV_THROTTLE = /,|^(throttle:.+)|(throttle$)/;
448
- const MODI_EV_SELF = 'self';
449
- const MODI_EV_STOP = 'stop';
450
- const MODI_EV_PREVENT = 'prevent';
451
- const MODI_EV_ONCE = 'once';
452
- const MODI_EV_CAPTURE = 'capture';
453
- const MODI_EV_PASSIVE = 'passive';
454
- const MODI_EV_MOUSE_LEFT = 'left';
455
- const MODI_EV_MOUSE_RIGHT = 'right';
456
- const MODI_EV_MOUSE_MIDDLE = 'middle';
457
- const MODI_EV_KEYBOARD_COMBO_CTRL = 'ctrl';
458
- const MODI_EV_KEYBOARD_COMBO_ALT = 'alt';
459
- const MODI_EV_KEYBOARD_COMBO_SHIFT = 'shift';
460
- const MODI_EV_KEYBOARD_COMBO_META = 'meta';
461
- const MODI_EV_KEYBOARD_KEY_MAP = {
462
- 'esc': 'escape'
463
- };
464
- const MODI_PARAM_DIVIDER = ":";
465
- /*************************************************************
466
- * 事件修饰符
467
- * @author holyhigh2
468
- *
469
- * 全部通用 debounce/once/throttle/capture/passive 可组合
470
- * 原生通用 stop/prevent/self 可组合
471
- * 鼠标 left/right/middle 不可组合
472
- * 键盘 ctrl/alt/shift/meta 可组合 esc/letters... 不可组合,多个key并列式表示可选
473
- *
474
- * 部分修饰符支持参数,使用冒号传参如:throttle:100 / debounce:100
475
- *************************************************************/
476
- const VFN = () => { };
477
- function addEvent(fullName, cbk, node, component) {
478
- let parts = fullName.split('.');
479
- let evName = parts.shift();
480
- let isOnce = parts.includes(MODI_EV_ONCE);
481
- let c = cbk ?? VFN;
482
- let modi;
483
- if (modi = find(parts, x => MODI_EV_DEBOUNCE.test(x))) {
484
- let params = modi.split(MODI_PARAM_DIVIDER);
485
- c = debounce(c, parseInt(params[1]) || 100);
486
- }
487
- if (modi = find(parts, x => MODI_EV_THROTTLE.test(x))) {
488
- let params = modi.split(MODI_PARAM_DIVIDER);
489
- c = throttle(c, parseInt(params[1]) || 100);
490
- }
491
- if (isOnce) {
492
- c = once(c);
493
- }
494
- if (isExtEvent(evName)) {
495
- return addExtEvent(evName, node, c, parts);
496
- }
497
- let listener = (e) => {
498
- if (parts.includes(MODI_EV_PREVENT))
499
- e.preventDefault();
500
- if (parts.includes(MODI_EV_STOP))
501
- e.stopPropagation();
502
- if (parts.includes(MODI_EV_SELF) && e.target !== e.currentTarget)
503
- return;
504
- if (e instanceof MouseEvent) {
505
- if (parts.includes(MODI_EV_MOUSE_LEFT) && e.button != 0)
506
- return;
507
- if (parts.includes(MODI_EV_MOUSE_RIGHT) && e.button != 2)
508
- return;
509
- if (parts.includes(MODI_EV_MOUSE_MIDDLE) && e.button != 1)
510
- return;
511
- }
512
- else if (e instanceof KeyboardEvent) {
513
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_CTRL)[0] && !e.ctrlKey)
514
- return;
515
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_ALT)[0] && !e.altKey)
516
- return;
517
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_SHIFT)[0] && !e.shiftKey)
518
- return;
519
- if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_META)[0] && !e.metaKey)
520
- return;
521
- let checkKeys = map(parts, k => MODI_EV_KEYBOARD_KEY_MAP[k] || k);
522
- if (size(checkKeys) > 0 && !checkKeys.includes(e.key.toLowerCase()))
523
- return;
524
- }
525
- console.debug(evName, c.name, node.tagName);
526
- c(e);
527
- };
528
- let capture = parts.includes(MODI_EV_CAPTURE) || false;
529
- let passive = parts.includes(MODI_EV_PASSIVE) || false;
530
- let options = { capture, passive };
531
- node.addEventListener(evName, listener, options);
532
- //record
533
- return (remove = false) => {
534
- node.removeEventListener(evName, listener, options);
535
- if (remove)
536
- node = null;
537
- };
538
- }
539
-
540
- /**
541
- * 用于提供全局state状态管理
542
- * @author holyhigh2
543
- */
544
- const Collector = {
545
- popDirectiveQ() {
546
- let rs = this.__varPathList.reduceRight((acc, p) => {
547
- if (!acc.includes(p)) {
548
- acc.unshift(p);
549
- }
550
- return acc;
551
- }, []);
552
- return rs;
553
- },
554
- start() {
555
- this.__collecting = true;
556
- this.__varPathList = [];
557
- },
558
- end(renderComponent, up) {
559
- if (renderComponent && up) {
560
- renderComponent._regSubViewDeps(Collector.popVarPathList(), up);
561
- }
562
- this.__collecting = false;
563
- },
564
- popVarPathList() {
565
- let rs = Array.from(new Set(this.__varPathList));
566
- this.__varPathList = [];
567
- return rs;
568
- },
569
- __varPathList: [],
570
- __collecting: false,
571
- };
572
- //对象值在不同上下文的根路径
573
- const OBJECT_VAR_ROOT_PATH_IN_CONTEXT = new WeakMap();
574
- const OBJECT_VAR_PATH = new WeakMap();
575
- //缓存已经创建的proxy对象
576
- const PROXY_MAP = new WeakMap();
577
- //对象值的创建上下文
578
- const OBJECT_VAR_ROOT_CONTEXT = new WeakMap();
579
- //上级对象所在的扩展context
580
- const EXTRA_CONTEXT_OF_VAR = new WeakMap();
581
- function reactive(obj, context, rootProp) {
582
- if (PROXY_MAP.has(obj))
583
- return PROXY_MAP.get(obj);
584
- if (OBJECT_VAR_ROOT_CONTEXT.has(obj)) {
585
- if (rootProp) {
586
- let pathMap = OBJECT_VAR_ROOT_PATH_IN_CONTEXT.get(context);
587
- if (!pathMap) {
588
- pathMap = new WeakMap();
589
- OBJECT_VAR_ROOT_PATH_IN_CONTEXT.set(context, pathMap);
590
- }
591
- pathMap.set(obj, rootProp);
592
- let contextList = EXTRA_CONTEXT_OF_VAR.get(obj);
593
- if (!contextList) {
594
- contextList = new Set();
595
- EXTRA_CONTEXT_OF_VAR.set(obj, contextList);
596
- }
597
- contextList.add(context);
598
- }
599
- return obj;
600
- }
601
- const proxyObject = new Proxy(obj, {
602
- get(target, prop, receiver) {
603
- if (!prop)
604
- return undefined;
605
- const value = Reflect.get(target, prop, receiver);
606
- if (isSymbol(prop))
607
- return value;
608
- if (isFunction(value))
609
- return value;
610
- if (prop === 'length' && isArray(target))
611
- return value;
612
- if (Collector.__collecting) {
613
- let supPath = OBJECT_VAR_PATH.has(receiver) ? concat(OBJECT_VAR_PATH.get(receiver)) : [];
614
- supPath.push(prop);
615
- let propPath = supPath.join('.');
616
- Collector.__varPathList.push(propPath);
617
- }
618
- if (PROXY_MAP.has(value))
619
- return PROXY_MAP.get(value);
620
- let reactiveVal = value;
621
- if (isObject(value) && !isFunction(value) && !(value instanceof Node) && !Object.isFrozen(value)) {
622
- reactiveVal = reactive(value, context);
623
- let supPath = OBJECT_VAR_PATH.has(receiver) ? concat(OBJECT_VAR_PATH.get(receiver)) : [];
624
- supPath.push(prop);
625
- OBJECT_VAR_PATH.set(reactiveVal, supPath);
626
- PROXY_MAP.set(value, reactiveVal);
627
- }
628
- return reactiveVal;
629
- },
630
- set(target, prop, newValue, receiver) {
631
- if (!prop)
632
- return false;
633
- let ov = target[prop];
634
- let chain = OBJECT_VAR_PATH.get(receiver) ?? [];
635
- let subChain = concat(chain, [prop]);
636
- let hasChanged = context._hasChangedPropOrStateMap?.get(subChain[0]);
637
- let moreThan1 = subChain.length > 1;
638
- let rootObjNew = newValue;
639
- let rootObjOld = ov;
640
- if (moreThan1) {
641
- rootObjOld = rootObjNew = context._getPrivateData()[subChain[0]];
642
- }
643
- if (hasChanged) {
644
- if (!hasChanged.call(context, rootObjNew, rootObjOld, subChain, newValue, ov))
645
- return true;
646
- }
647
- else {
648
- //默认对比算法
649
- if (Object.is(ov, newValue)) {
650
- return true;
651
- }
652
- }
653
- let nv = newValue;
654
- let rs = Reflect.set(target, prop, nv);
655
- let extraContext = EXTRA_CONTEXT_OF_VAR.get(receiver);
656
- let k = subChain.join('.');
657
- //check watch
658
- context._requestWatchUpdate(nv, ov, k, rootObjNew, rootObjOld);
659
- //check computed
660
- context._requestComputedUpdate(k);
661
- notifyUpdate(context, rootObjOld, subChain);
662
- each(extraContext, ctx => {
663
- let ctxRootPath = ctx._wrapperProp[subChain[0]];
664
- let ck = subChain.join('.');
665
- ck = ck.replace(subChain[0], ctxRootPath);
666
- //check watch
667
- ctx._requestWatchUpdate(nv, ov, ck);
668
- //check computed
669
- ctx._requestComputedUpdate(ck);
670
- notifyUpdate(ctx, rootObjOld, ck.split('.'));
671
- });
672
- return rs;
673
- }
674
- });
675
- if (!OBJECT_VAR_PATH.has(proxyObject)) {
676
- OBJECT_VAR_PATH.set(proxyObject, rootProp ? [rootProp] : []);
677
- }
678
- PROXY_MAP.set(obj, proxyObject);
679
- if (rootProp) {
680
- OBJECT_VAR_ROOT_CONTEXT.set(proxyObject, context);
681
- if (!OBJECT_VAR_ROOT_PATH_IN_CONTEXT.has(context)) {
682
- let pathMap = new WeakMap();
683
- pathMap.set(proxyObject, rootProp);
684
- OBJECT_VAR_ROOT_PATH_IN_CONTEXT.set(context, pathMap);
685
- }
686
- }
687
- return proxyObject;
688
- }
689
- function notifyUpdate(context, oldValue, path, subNewValue, subOldValue) {
690
- let i = size(path);
691
- eachRight(path, (p) => {
692
- let varPath = slice(path, 0, i--);
693
- context._notify(oldValue, varPath);
694
- });
695
- }
696
- const QMap = new Map();
697
- class Queue {
698
- static nextSet = new Set();
699
- static nextPending = false;
700
- static next;
701
- static flush() {
702
- Queue.nextPending = false;
703
- let nq = Array.from(Queue.nextSet);
704
- Queue.nextSet.clear();
705
- QMap.clear();
706
- nq.forEach(u => u());
707
- nq = null;
705
+ return (remove = false) => {
706
+ myfx.remove(AllOutsideDblClickEls, el => el[0] === node && el[1] === cbk);
707
+ };
708
+ }
709
+ function isExtEvent(evName) {
710
+ return ExtEvNames.includes(evName);
711
+ }
712
+ function addExtEvent(evName, node, cbk, parts, component) {
713
+ if (evName === 'resize') {
714
+ return addResize(node, cbk);
708
715
  }
709
- static pushNext(updater) {
710
- Queue.nextSet.add(updater);
711
- if (!Queue.nextPending) {
712
- Queue.nextPending = true;
713
- Queue.next();
716
+ else if (evName === 'outside') {
717
+ switch (parts[0]) {
718
+ case 'mousedown':
719
+ return addOutsideMouseDown(node, cbk);
720
+ case 'dblclick':
721
+ return addOutsideDblClick(node, cbk);
722
+ case 'click':
723
+ default:
724
+ return addOutsideClick(node, cbk);
714
725
  }
715
726
  }
727
+ else if (evName === 'mutate') {
728
+ return addMutation(node, cbk, parts);
729
+ }
716
730
  }
717
- (() => {
718
- const p = Promise.resolve();
719
- const nextFn = Queue.flush;
720
- Queue.next = () => {
721
- p.then(nextFn);
731
+
732
+ const MODI_EV_DEBOUNCE = /,|^(debounce:.+)|(debounce$)/;
733
+ const MODI_EV_THROTTLE = /,|^(throttle:.+)|(throttle$)/;
734
+ const MODI_EV_NATIVE = 'native';
735
+ const MODI_EV_SELF = 'self';
736
+ const MODI_EV_STOP = 'stop';
737
+ const MODI_EV_PREVENT = 'prevent';
738
+ const MODI_EV_ONCE = 'once';
739
+ const MODI_EV_CAPTURE = 'capture';
740
+ const MODI_EV_PASSIVE = 'passive';
741
+ const MODI_EV_MOUSE_LEFT = 'left';
742
+ const MODI_EV_MOUSE_RIGHT = 'right';
743
+ const MODI_EV_MOUSE_MIDDLE = 'middle';
744
+ const MODI_EV_KEYBOARD_COMBO_CTRL = 'ctrl';
745
+ const MODI_EV_KEYBOARD_COMBO_ALT = 'alt';
746
+ const MODI_EV_KEYBOARD_COMBO_SHIFT = 'shift';
747
+ const MODI_EV_KEYBOARD_COMBO_META = 'meta';
748
+ const MODI_EV_KEYBOARD_KEY_MAP = {
749
+ 'esc': 'escape'
750
+ };
751
+ const MODI_PARAM_DIVIDER = ":";
752
+ /*************************************************************
753
+ * 事件修饰符
754
+ * @author holyhigh2
755
+ *
756
+ * 全部通用 debounce/once/throttle/capture/passive 可组合
757
+ * 原生通用 stop/prevent/self 可组合
758
+ * 鼠标 left/right/middle 不可组合
759
+ * 键盘 ctrl/alt/shift/meta 可组合 esc/letters... 不可组合,多个key并列式表示可选
760
+ * 组件 native 监听组件元素原生事件
761
+ *
762
+ * 部分修饰符支持参数,使用冒号传参如:throttle:100 / debounce:100
763
+ *************************************************************/
764
+ const VFN = () => { };
765
+ function addEvent(fullName, cbk, node, component) {
766
+ let parts = fullName.split('.');
767
+ let evName = parts.shift();
768
+ let isOnce = parts.includes(MODI_EV_ONCE);
769
+ let c = cbk ?? VFN;
770
+ let modi;
771
+ if (modi = find(parts, x => MODI_EV_DEBOUNCE.test(x))) {
772
+ let params = modi.split(MODI_PARAM_DIVIDER);
773
+ c = debounce(c, parseInt(params[1]) || 100);
774
+ }
775
+ if (modi = find(parts, x => MODI_EV_THROTTLE.test(x))) {
776
+ let params = modi.split(MODI_PARAM_DIVIDER);
777
+ c = throttle(c, parseInt(params[1]) || 100);
778
+ }
779
+ if (isOnce) {
780
+ c = once(c);
781
+ }
782
+ if (node instanceof CompElem && !parts.includes(MODI_EV_NATIVE)) {
783
+ return node._addEvent(evName, cbk);
784
+ }
785
+ if (isExtEvent(evName)) {
786
+ return addExtEvent(evName, node, c, parts);
787
+ }
788
+ let listener = (e) => {
789
+ if (parts.includes(MODI_EV_PREVENT))
790
+ e.preventDefault();
791
+ if (parts.includes(MODI_EV_STOP))
792
+ e.stopPropagation();
793
+ if (parts.includes(MODI_EV_SELF) && e.target !== e.currentTarget)
794
+ return;
795
+ if (e instanceof MouseEvent) {
796
+ if (parts.includes(MODI_EV_MOUSE_LEFT) && e.button != 0)
797
+ return;
798
+ if (parts.includes(MODI_EV_MOUSE_RIGHT) && e.button != 2)
799
+ return;
800
+ if (parts.includes(MODI_EV_MOUSE_MIDDLE) && e.button != 1)
801
+ return;
802
+ }
803
+ else if (e instanceof KeyboardEvent) {
804
+ if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_CTRL)[0] && !e.ctrlKey)
805
+ return;
806
+ if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_ALT)[0] && !e.altKey)
807
+ return;
808
+ if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_SHIFT)[0] && !e.shiftKey)
809
+ return;
810
+ if (remove(parts, p => p == MODI_EV_KEYBOARD_COMBO_META)[0] && !e.metaKey)
811
+ return;
812
+ let checkKeys = map(parts, k => MODI_EV_KEYBOARD_KEY_MAP[k] || k);
813
+ if (size(checkKeys) > 0 && !checkKeys.includes(e.key.toLowerCase()))
814
+ return;
815
+ }
816
+ c(e);
722
817
  };
723
- })();
818
+ let capture = parts.includes(MODI_EV_CAPTURE) || false;
819
+ let passive = parts.includes(MODI_EV_PASSIVE) || false;
820
+ let options = { capture, passive };
821
+ node.addEventListener(evName, listener, options);
822
+ //record
823
+ return (remove = false) => {
824
+ node.removeEventListener(evName, listener, options);
825
+ if (remove)
826
+ node = null;
827
+ };
828
+ }
724
829
 
725
830
  const PropTypeMap = {
726
831
  boolean: Boolean,
@@ -767,29 +872,21 @@ class CompElem extends HTMLElement {
767
872
  }
768
873
  #cid;
769
874
  #slotPropsMap = {};
770
- #data = {};
875
+ __data_ = {};
771
876
  #updateSources = {};
772
877
  #shadow;
773
878
  //保存所有渲染上下文 {CompElem/Directive}
774
879
  __updateTree;
775
- __cssSheets;
776
- _eventList;
880
+ _eventBindList;
881
+ _listerners = {};
777
882
  __docoEventMap;
778
- __updateCssDeps;
779
883
  __updateSubViewDeps;
780
- __updateViewDeps;
781
- _watchUpdateMap;
782
- _watchDeepUpdateMap;
783
- _watchKeys;
784
- _watchKeysOnceMap;
785
- _watchKeysDeep;
884
+ _cssUpdateInNextTick = false;
885
+ _cssVarOldValueMap;
886
+ __cssSheets;
786
887
  _watchUpdateSetInNextTick;
787
888
  _watchUpdateArgsInNextTick;
788
- _computedUpdateDeps;
789
889
  _computedUpdateSetInNextTick;
790
- _hasChangedPropOrStateMap;
791
- _hasSyncPropSet;
792
- _hasShallowStateSet;
793
890
  get [Symbol.toStringTag]() {
794
891
  return this.constructor.name;
795
892
  }
@@ -812,29 +909,29 @@ class CompElem extends HTMLElement {
812
909
  return this.#parentComponent?.deref();
813
910
  }
814
911
  get wrapperComponent() {
815
- return this.#wrapperComponent?.deref();
912
+ return this.__wrapperComponent?.deref();
913
+ }
914
+ get slots() {
915
+ return EMPTY_SLOTS;
816
916
  }
817
917
  get slotHooks() {
818
918
  return this.#slotHooks;
819
919
  }
820
- get styleSheets() {
821
- return ComponentStaticStyleMap.get(this);
920
+ get cssSheets() {
921
+ return ComponentStaticStyleMap.get(this.constructor);
822
922
  }
823
- get globalStyleSheet() {
923
+ get globalCssSheet() {
824
924
  return CompElem.__l_globalRule.sheet;
825
925
  }
826
926
  get isMounted() {
827
927
  return this.#mounted;
828
928
  }
829
- get slots() {
830
- return EMPTY_SLOTS;
831
- }
832
929
  #attrs;
833
930
  #props;
834
931
  #renderRoot;
835
932
  #renderRoots;
836
933
  #parentComponent;
837
- #wrapperComponent;
934
+ __wrapperComponent;
838
935
  #slotsEl = {};
839
936
  #slotHooks = {};
840
937
  #slotNodes = {};
@@ -845,33 +942,46 @@ class CompElem extends HTMLElement {
845
942
  /**
846
943
  * 组件样式,CSSStyleSheet可动态变更
847
944
  */
848
- static get styles() {
945
+ static get css() {
849
946
  return [];
850
947
  }
851
- static get globalStyle() {
948
+ static get globalCss() {
852
949
  return undefined;
853
950
  }
854
- static get hostStyle() {
951
+ static get hostCss() {
855
952
  return undefined;
856
953
  }
857
- get styles() {
858
- return [];
954
+ get cssVars() {
955
+ return {};
859
956
  }
860
- #inited = false;
957
+ __inited = false;
861
958
  #initiating = false;
959
+ #onSlotChangeHookBindThis;
960
+ __thisRef;
862
961
  constructor(...args) {
863
962
  super();
864
963
  this.#cid = CompElemSn++;
865
964
  this.__updateTree = [];
965
+ this.__thisRef = new WeakRef(this);
966
+ this.#onSlotChangeHookBindThis = this.#onSlotChangeHook.bind(this);
866
967
  //init props via constructor
867
968
  if (size(args) === 1) {
868
969
  this.#props = {};
869
970
  assign(this.#props, first(args));
870
971
  }
871
972
  /////////////////////////////////////////////////// slots
872
- // this.#updateSlotsAry()
973
+ if (!Reflect.getOwnPropertyDescriptor(this.constructor.prototype, 'slots')) {
974
+ Reflect.defineProperty(this.constructor.prototype, 'slots', {
975
+ get() {
976
+ return getterValue(undefined, 'slots', this);
977
+ },
978
+ set(v) {
979
+ setterValue('slots', v, this);
980
+ }
981
+ });
982
+ }
873
983
  /////////////////////////////////////////////////// decorators create
874
- let ary = DefinitionDecoratorMap.get(this.constructor.name) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor).name);
984
+ let ary = DefinitionDecoratorMap.get(this.constructor) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor));
875
985
  ary && ary.sort((a, b) => b.priority - a.priority).forEach(dw => dw.create(this));
876
986
  this.#updatedD = this.#update.bind(this);
877
987
  }
@@ -894,7 +1004,7 @@ class CompElem extends HTMLElement {
894
1004
  }
895
1005
  this.#shadow.adoptedStyleSheets = [...this.#shadow.adoptedStyleSheets, cssSheet];
896
1006
  // Keep ComponentStyleMap in sync for this constructor
897
- const cur = ComponentStaticStyleMap.get(this) ?? [];
1007
+ const cur = ComponentStaticStyleMap.get(this.constructor) ?? [];
898
1008
  cur.push(cssSheet);
899
1009
  return cssSheet;
900
1010
  }
@@ -921,8 +1031,8 @@ class CompElem extends HTMLElement {
921
1031
  document.head.appendChild(CompElem.__l_globalRule);
922
1032
  }
923
1033
  //host styles
924
- let hostStyle = get(this.constructor, "hostStyle");
925
- let styleSheet = get(this.constructor, 'hostStyleSheet');
1034
+ let hostStyle = get(this.constructor, "hostCss");
1035
+ let styleSheet = get(this.constructor, 'hostCssSheet');
926
1036
  if (hostStyle) {
927
1037
  if (!styleSheet) {
928
1038
  if (isString(hostStyle)) {
@@ -932,11 +1042,11 @@ class CompElem extends HTMLElement {
932
1042
  else {
933
1043
  styleSheet = hostStyle;
934
1044
  }
935
- set(this.constructor, 'hostStyleSheet', styleSheet);
1045
+ set(this.constructor, 'hostCssSheet', styleSheet);
936
1046
  }
937
- let styleRoot = this.#wrapperComponent?.deref()?.shadowRoot ?? this.#parentComponent?.deref()?.shadowRoot ?? this.ownerDocument;
1047
+ let styleRoot = this.__wrapperComponent?.deref()?.shadowRoot ?? this.#parentComponent?.deref()?.shadowRoot ?? this.ownerDocument;
938
1048
  //detached el
939
- if (this.#wrapperComponent && !this.#wrapperComponent.deref()?.shadowRoot?.contains(this)) {
1049
+ if (this.__wrapperComponent && !this.__wrapperComponent.deref()?.shadowRoot?.contains(this)) {
940
1050
  styleRoot = closest(this, n => n instanceof HTMLDocument || n instanceof ShadowRoot, 'parentNode');
941
1051
  }
942
1052
  if (styleRoot && styleSheet && !styleRoot.adoptedStyleSheets.includes(styleSheet)) {
@@ -950,7 +1060,7 @@ class CompElem extends HTMLElement {
950
1060
  this.__unbindEvents();
951
1061
  }
952
1062
  __bindEvents() {
953
- let evs = this._eventList;
1063
+ let evs = this._eventBindList;
954
1064
  each(evs, (v) => {
955
1065
  let [evName, cbk, node, binded] = v;
956
1066
  if (binded)
@@ -962,7 +1072,7 @@ class CompElem extends HTMLElement {
962
1072
  v[3] = unbinder;
963
1073
  });
964
1074
  //event decoration
965
- let events = DefinitionCompEventMap.get(this.constructor.name);
1075
+ let events = DefinitionCompEventMap.get(this.constructor);
966
1076
  if (size(events) > 0) {
967
1077
  if (!this.__docoEventMap)
968
1078
  this.__docoEventMap = new Map();
@@ -978,7 +1088,7 @@ class CompElem extends HTMLElement {
978
1088
  }
979
1089
  }
980
1090
  __unbindEvents() {
981
- each(this._eventList, (v) => {
1091
+ each(this._eventBindList, (v) => {
982
1092
  let [, , , unbinder] = v;
983
1093
  if (unbinder)
984
1094
  unbinder();
@@ -1004,45 +1114,26 @@ class CompElem extends HTMLElement {
1004
1114
  if (this.#destroyed)
1005
1115
  return;
1006
1116
  this.#destroyed = true;
1007
- let ary = DefinitionDecoratorMap.get(this.constructor.name) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor).name);
1117
+ let ary = DefinitionDecoratorMap.get(this.constructor) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor));
1008
1118
  ary && ary.sort((a, b) => b.priority - a.priority).forEach(dw => {
1009
1119
  dw.destroy(this);
1010
1120
  });
1011
1121
  this.beforeDestroyed();
1012
1122
  //events
1013
1123
  this.__unbindEvents();
1014
- each(this.#rootEvs, (hooks, evName) => {
1015
- each(hooks, hook => {
1016
- this.removeEventListener(evName, hook);
1017
- });
1018
- this.#rootEvs[evName] = null;
1019
- });
1020
- each(this.#nodeEvs, (hooks, evName) => {
1021
- each(hooks, ([hook, ref]) => {
1022
- ref.deref()?.removeEventListener(evName, hook);
1023
- });
1024
- this.#nodeEvs[evName] = null;
1025
- });
1124
+ this._listerners = null;
1026
1125
  this.__docoEventMap?.clear();
1027
- this.__docoEventMap = this._eventList = null;
1126
+ this.__docoEventMap = this._eventBindList = null;
1028
1127
  //styles
1029
- ComponentStaticStyleMap.delete(this);
1030
1128
  ComponentDynamicCssUpdaterMap.get(this)?.clear();
1031
1129
  ComponentDynamicCssUpdaterMap.delete(this);
1032
1130
  //reactive
1033
1131
  this._watchUpdateArgsInNextTick?.clear();
1034
1132
  this._watchUpdateSetInNextTick?.clear();
1035
- this._watchKeysOnceMap?.clear();
1036
- this._watchUpdateMap = this._watchDeepUpdateMap = this._watchKeys = this._watchKeysDeep = this._watchKeysOnceMap = null;
1037
- this._computedUpdateDeps?.clear();
1038
1133
  this._computedUpdateSetInNextTick?.clear();
1039
- this._computedUpdateDeps = this._computedUpdateSetInNextTick = null;
1040
- this.__updateCssDeps = this.__updateViewDeps = null;
1134
+ this._computedUpdateSetInNextTick = null;
1135
+ this.__cssSheets = null;
1041
1136
  this.__updateSubViewDeps?.clear();
1042
- this._hasChangedPropOrStateMap?.clear();
1043
- this._hasShallowStateSet?.clear();
1044
- this._hasSyncPropSet?.clear();
1045
- this._hasChangedPropOrStateMap = this._hasShallowStateSet = this._hasSyncPropSet = null;
1046
1137
  //sup scope
1047
1138
  if (this.#parentComponent) {
1048
1139
  let pComp = this.#parentComponent.deref();
@@ -1065,32 +1156,28 @@ class CompElem extends HTMLElement {
1065
1156
  each(this.#slotNodes, (nodes) => {
1066
1157
  each(nodes, (node) => node.remove());
1067
1158
  });
1068
- each(this.#data.slots, (nodes, k) => {
1159
+ each(this.__data_.slots, (nodes, k) => {
1069
1160
  each(nodes, (node) => node.remove());
1070
1161
  });
1071
1162
  this.#updateSlots.clear();
1072
- this.#updateSlots = this.#slotPropsMap = this.#data.slots = null;
1163
+ this.#slotNodes = this.#slotsEl = this.#updateSlots = this.#slotPropsMap = this.__data_.slots = null;
1073
1164
  this.remove();
1074
1165
  //data
1075
1166
  this._wrapperProp =
1076
- this.#slotNodes =
1077
- this.#propsReady =
1078
- this.#renderRoot = this.#renderRoots = this.#shadow =
1079
- this.#rootEvs =
1080
- this.#nodeEvs =
1081
- this.#updateSources =
1082
- this.#attrs =
1083
- this.#props =
1084
- this.#renderRoot =
1085
- this.#renderRoots =
1086
- this.#slotHooks =
1087
- this.#updatedD =
1088
- this.#data =
1089
- this.#slotsEl =
1090
- this.__updateTree =
1091
- this.#parentComponent =
1092
- this._asyncDirectives =
1093
- this.#wrapperComponent = null;
1167
+ this.#propsReady =
1168
+ this.#renderRoot = this.#renderRoots = this.#shadow =
1169
+ this.#updateSources =
1170
+ this.#attrs =
1171
+ this.#props =
1172
+ this.#renderRoot =
1173
+ this.#renderRoots =
1174
+ this.#slotHooks =
1175
+ this.#updatedD =
1176
+ this.__data_ =
1177
+ this.__updateTree =
1178
+ this.#parentComponent =
1179
+ this._asyncDirectives =
1180
+ this.__wrapperComponent = null;
1094
1181
  //unmount
1095
1182
  this.destroyed();
1096
1183
  }
@@ -1098,24 +1185,23 @@ class CompElem extends HTMLElement {
1098
1185
  //********************************** 首次渲染
1099
1186
  //构造时上级传递的参数
1100
1187
  __init() {
1101
- if (this.#inited)
1188
+ if (this.__inited)
1102
1189
  return;
1103
1190
  //防止在钩子中出现重新挂载的情况
1104
1191
  if (this.#initiating)
1105
1192
  return;
1106
1193
  this.#initiating = true;
1107
- let thisRef = new WeakRef(this);
1108
1194
  //global styles
1109
- let globalTextContent = get(this.constructor, "globalStyle");
1195
+ let globalTextContent = get(this.constructor, "globalCss");
1110
1196
  if (!isEmpty(globalTextContent) && isString(globalTextContent) && !get(this.constructor, '_globalRuleInserted')) {
1111
1197
  CompElem.__l_globalRule.textContent += globalTextContent; //.sheet?.insertRule(globalTextContent, 0)
1112
1198
  set(this.constructor, '_globalRuleInserted', true);
1113
1199
  }
1114
1200
  //component styles
1115
- let beAttached2 = ComponentStaticStyleMap.get(this);
1201
+ let beAttached2 = ComponentStaticStyleMap.get(this.constructor);
1116
1202
  let styleSheets = beAttached2 ?? [];
1117
1203
  if (!beAttached2) {
1118
- each(get(this.constructor, "styles"), (st) => {
1204
+ each(get(this.constructor, "css"), (st) => {
1119
1205
  if (isString(st)) {
1120
1206
  let sheet = new CSSStyleSheet();
1121
1207
  sheet.replaceSync(st);
@@ -1126,156 +1212,78 @@ class CompElem extends HTMLElement {
1126
1212
  styleSheets.push(st);
1127
1213
  }
1128
1214
  });
1129
- ComponentStaticStyleMap.set(this, styleSheets);
1215
+ ComponentStaticStyleMap.set(this.constructor, styleSheets);
1130
1216
  }
1131
1217
  ////////////////////////////////////////////////// Props & States
1132
1218
  const props = this.#initProps();
1133
1219
  this.propsReady(props);
1134
1220
  for (const key in props) {
1135
1221
  const v = props[key];
1136
- this.#data[key] = v;
1222
+ this.__data_[key] = v;
1137
1223
  }
1138
1224
  this.#initStates();
1139
1225
  //2. Data
1140
- this.#data.slots = {};
1141
- each(this.#data, (v, k) => {
1142
- let descr = Reflect.getOwnPropertyDescriptor(this.#data, k);
1143
- Reflect.defineProperty(this, k, {
1144
- get() {
1145
- let thisHost = thisRef.deref();
1146
- let v = descr?.get ? descr?.get() : Reflect.get(thisHost.#data, k);
1147
- if (Collector.__collecting) {
1148
- Collector.__varPathList.push(k);
1149
- }
1150
- if (PROXY_MAP.has(v)) {
1151
- let contextList = EXTRA_CONTEXT_OF_VAR.get(v);
1152
- if (!contextList) {
1153
- contextList = new Set();
1154
- EXTRA_CONTEXT_OF_VAR.set(v, contextList);
1155
- }
1156
- contextList.add(thisHost);
1157
- return PROXY_MAP.get(v);
1158
- }
1159
- if (isObject(v) && !isFunction(v) && !(v instanceof Node) && !Object.isFrozen(v)) {
1160
- let shallow = thisHost._hasShallowStateSet?.has(k);
1161
- v = shallow || k === PROP_NAME_SLOTS ? v : reactive(v, this, k);
1162
- }
1163
- return v;
1164
- },
1165
- set(v) {
1166
- if (descr?.set) {
1167
- descr?.set(v);
1168
- }
1169
- else {
1170
- let thisHost = thisRef.deref();
1171
- if (!thisHost.#inited) {
1172
- Reflect.set(thisHost.#data, k, v);
1173
- return;
1174
- }
1175
- let oldValue = thisHost.#data[k];
1176
- let hasChanged = thisHost._hasChangedPropOrStateMap?.get(k);
1177
- if (hasChanged) {
1178
- if (!hasChanged.call(thisHost, v, oldValue, [k], v, oldValue))
1179
- return true;
1180
- }
1181
- else {
1182
- //默认对比算法
1183
- if (Object.is(oldValue, v)) {
1184
- return true;
1185
- }
1186
- }
1187
- //check watch
1188
- thisHost._requestWatchUpdate(v, oldValue, k);
1189
- //check computed
1190
- thisHost._requestComputedUpdate(k);
1191
- Reflect.set(thisHost.#data, k, v);
1192
- thisHost._notify(oldValue, [k]);
1193
- //update sync
1194
- if (thisHost._hasSyncPropSet?.has(k)) {
1195
- thisHost.emit('update' + ":" + k, { value: v });
1196
- }
1197
- }
1198
- },
1199
- });
1200
- });
1201
- Reflect.defineProperty(this.#data, '__isData', {
1226
+ this.__data_.slots = {};
1227
+ Reflect.defineProperty(this.__data_, '__isData', {
1202
1228
  enumerable: false,
1203
1229
  value: true
1204
1230
  });
1205
1231
  //3. Watch
1206
- let watchMap = DefinitionWatchMap.get(this.constructor.name) ?? DefinitionWatchMap.get(_getSuper(this.constructor).name);
1207
- if (watchMap) {
1208
- this._watchUpdateMap = {};
1209
- this._watchDeepUpdateMap = {};
1210
- this._watchKeys = [];
1211
- this._watchKeysDeep = [];
1232
+ let superComp = _getSuper(this.constructor);
1233
+ let watchKeys = WatchKeysListMap.get(this.constructor) ?? WatchKeysListMap.get(superComp);
1234
+ if (watchKeys) {
1212
1235
  this._watchUpdateSetInNextTick = new Set();
1213
1236
  this._watchUpdateArgsInNextTick = new Map();
1214
- this._watchKeysOnceMap = new Map();
1215
- each(watchMap, (watchList, k) => {
1216
- watchList.forEach(v => {
1217
- let { source, options, handler } = v;
1218
- let fn = handler;
1219
- let onceWatch = get(options, "once", false);
1220
- if (onceWatch) {
1221
- this._watchKeysOnceMap.set(k, false);
1222
- }
1223
- let deep = get(options, "deep", false);
1224
- this._watchKeys.push(k);
1225
- if (deep) {
1226
- this._watchDeepUpdateMap[k] = this._watchDeepUpdateMap[k] ?? new Set();
1227
- this._watchDeepUpdateMap[k].add(fn);
1228
- this._watchKeysDeep.push(k);
1229
- }
1230
- else {
1231
- this._watchUpdateMap[k] = this._watchUpdateMap[k] ?? new Set();
1232
- this._watchUpdateMap[k].add(fn);
1233
- }
1234
- let immediate = get(options, "immediate", false);
1235
- if (!immediate)
1236
- return;
1237
- let nv = get(this, source);
1238
- fn.call(this, nv, undefined, source);
1239
- if (onceWatch) {
1240
- this._watchKeysOnceMap.set(k, true);
1241
- }
1237
+ let onceMap = WatchKeysOnceMap.get(this.constructor) ?? WatchKeysOnceMap.get(superComp);
1238
+ let watchImmediateList = WatchImmediateListMap.get(this.constructor) ?? WatchImmediateListMap.get(superComp);
1239
+ each(watchImmediateList, (fns, k) => {
1240
+ let nv = get(this, k);
1241
+ fns.forEach(fn => {
1242
+ fn.call(this, nv, undefined, k);
1242
1243
  });
1244
+ if (onceMap.has(k)) {
1245
+ onceMap.set(k, true);
1246
+ }
1243
1247
  });
1244
1248
  }
1245
1249
  //4. Computed
1246
- let computedMap = DefinitionComputedMap.get(this.constructor.name) ?? DefinitionComputedMap.get(_getSuper(this.constructor).name);
1250
+ let computedMap = assign({}, DefinitionComputedMap.get(this.constructor), DefinitionComputedMap.get(superComp));
1247
1251
  if (computedMap) {
1248
- this._computedUpdateDeps = new Map();
1249
1252
  this._computedUpdateSetInNextTick = new Set();
1250
- each(computedMap, (getter, propKey) => {
1251
- set(getter, 'key', propKey);
1252
- Collector.start();
1253
- this.#data[propKey] = getter.call(this);
1254
- Collector.end();
1255
- let computedDeps = Collector.popVarPathList();
1256
- computedDeps.forEach(dep => {
1257
- let list = this._computedUpdateDeps.get(dep);
1258
- if (!list) {
1259
- list = new Set();
1260
- this._computedUpdateDeps.set(dep, list);
1261
- }
1262
- list.add(getter);
1263
- });
1264
- Reflect.defineProperty(this, propKey, {
1265
- get() {
1266
- let v = Reflect.get(thisRef.deref().#data, propKey);
1267
- if (Collector.__collecting) {
1268
- Collector.__varPathList.push(propKey);
1253
+ let depMap = ComputedUpdateDepsMap.get(this.constructor);
1254
+ if (!depMap) {
1255
+ depMap = new Map();
1256
+ ComputedUpdateDepsMap.set(this.constructor, depMap);
1257
+ each(computedMap, (getter, propKey) => {
1258
+ set(getter, 'key', propKey);
1259
+ Collector.start();
1260
+ this[DATA_KEY][propKey] = getter.call(this);
1261
+ Collector.end();
1262
+ let computedDeps = Collector.popVarPathList();
1263
+ computedDeps.forEach(dep => {
1264
+ let list = depMap.get(dep);
1265
+ if (!list) {
1266
+ list = new Set();
1267
+ depMap.set(dep, list);
1269
1268
  }
1270
- return v;
1271
- }
1269
+ list.add(getter);
1270
+ });
1272
1271
  });
1273
- });
1272
+ }
1273
+ else {
1274
+ each(computedMap, (getter, propKey) => {
1275
+ this[DATA_KEY][propKey] = getter.call(this);
1276
+ });
1277
+ }
1274
1278
  }
1275
1279
  //5. Render
1276
1280
  Collector.start();
1277
1281
  let tmpl = this.render();
1278
1282
  Collector.end();
1283
+ let viewDeps = Collector.popVarPathList();
1284
+ if (!this.constructor.prototype._viewDeps) {
1285
+ this.constructor.prototype._viewDeps = viewDeps;
1286
+ }
1279
1287
  let nodes;
1280
1288
  if (tmpl === null) {
1281
1289
  this.#renderRoots = [];
@@ -1286,16 +1294,14 @@ class CompElem extends HTMLElement {
1286
1294
  this.#shadow = this.attachShadow({
1287
1295
  mode: "open"
1288
1296
  });
1289
- let viewDeps = Collector.popVarPathList();
1290
- this.__updateViewDeps = viewDeps;
1291
- this.#shadow.adoptedStyleSheets = [...DefaultCss, ...(ComponentStaticStyleMap.get(this) ?? [])];
1297
+ this.#shadow.adoptedStyleSheets = [...DefaultCss, ...(ComponentStaticStyleMap.get(this.constructor) ?? [])];
1292
1298
  nodes = buildView(tmpl, this);
1293
1299
  if (nodes) {
1294
1300
  this.#renderRoots = filter(nodes, (n) => n.nodeType === Node.ELEMENT_NODE).map(n => new WeakRef(n));
1295
- this.#renderRoot = new WeakRef(nodes[0]);
1301
+ this.#renderRoot = this.#renderRoots[0];
1296
1302
  }
1297
1303
  }
1298
- this.#inited = true;
1304
+ this.__inited = true;
1299
1305
  /////////////////////////////////////////////////// slots
1300
1306
  this.#updateSlotsAry();
1301
1307
  //slot hook
@@ -1303,11 +1309,11 @@ class CompElem extends HTMLElement {
1303
1309
  this.#updateSlot(k);
1304
1310
  });
1305
1311
  const that = this;
1306
- let ary = DefinitionDecoratorMap.get(this.constructor.name) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor).name);
1312
+ let ary = DefinitionDecoratorMap.get(this.constructor) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor));
1307
1313
  ary && ary.sort((a, b) => b.priority - a.priority).forEach(dw => {
1308
1314
  dw.beforeMount(this, (key, value) => {
1309
- that.#data[key] = value;
1310
- return that.#data[key];
1315
+ that.__data_[key] = value;
1316
+ return that.__data_[key];
1311
1317
  });
1312
1318
  });
1313
1319
  this.beforeMount();
@@ -1319,30 +1325,34 @@ class CompElem extends HTMLElement {
1319
1325
  this.#mounted = true;
1320
1326
  if (this.#shadow) {
1321
1327
  //instance dynamic style
1322
- let cssAry = [];
1323
1328
  Collector.start();
1324
- let cssTmpls = this.styles;
1329
+ let cssVarObj = this.cssVars;
1325
1330
  Collector.end();
1326
- this.__updateCssDeps = Collector.popVarPathList();
1327
- cssTmpls.forEach(cssTmpl => {
1328
- let cssss = new CSSStyleSheet();
1329
- cssAry.push(cssss);
1330
- let css = cssTmpl.getCss(this);
1331
- if (isBlank(css))
1332
- return;
1333
- cssss.replaceSync(css);
1334
- });
1335
- if (cssAry.length > 0) {
1336
- this.__cssSheets = cssAry;
1337
- this.#shadow.adoptedStyleSheets = [...this.#shadow.adoptedStyleSheets, ...cssAry];
1331
+ if (!isEmpty(cssVarObj)) {
1332
+ this._cssVarOldValueMap = {};
1333
+ let deps = CssUpdateDepsMap.get(this.constructor);
1334
+ if (!deps) {
1335
+ deps = new Set(Collector.popVarPathList());
1336
+ CssUpdateDepsMap.set(this.constructor, deps);
1337
+ }
1338
+ let cssStr = '';
1339
+ each(cssVarObj, (v, k) => {
1340
+ let cssVarKey = '--' + kebabCase(k).replace(/^-+/, '');
1341
+ if (isBlank(v) || isNil(v)) {
1342
+ v = 'initial'; // invalid value
1343
+ }
1344
+ this._cssVarOldValueMap[cssVarKey] = v;
1345
+ cssStr += ';' + cssVarKey + ':' + v;
1346
+ });
1347
+ this.style.cssText += cssStr;
1338
1348
  }
1339
1349
  }
1340
1350
  if (nodes)
1341
1351
  this.#shadow.append(...nodes);
1342
1352
  ary && ary.forEach(dw => {
1343
1353
  dw.mounted(this, (key, value) => {
1344
- that.#data[key] = value;
1345
- return that.#data[key];
1354
+ that.__data_[key] = value;
1355
+ return that.__data_[key];
1346
1356
  });
1347
1357
  });
1348
1358
  if (this.#updateNextImmediatelyQ) {
@@ -1361,7 +1371,7 @@ class CompElem extends HTMLElement {
1361
1371
  }
1362
1372
  beforeMount() { }
1363
1373
  mounted() { }
1364
- __onSlotChangeHook(e) {
1374
+ #onSlotChangeHook(e) {
1365
1375
  let t = e.currentTarget;
1366
1376
  let name = '';
1367
1377
  each(this.#slotsEl, (el, n) => {
@@ -1370,7 +1380,7 @@ class CompElem extends HTMLElement {
1370
1380
  return false;
1371
1381
  }
1372
1382
  });
1373
- if (this.#inited)
1383
+ if (this.__inited)
1374
1384
  this.#onSlotChange(t, name === SLOT_NAME_DEFAULT ? '' : name);
1375
1385
  }
1376
1386
  #onSlotChange(slot, name) {
@@ -1413,18 +1423,18 @@ class CompElem extends HTMLElement {
1413
1423
  }
1414
1424
  slotChange(slot, name) { }
1415
1425
  attributeChangedCallback(attributeName, oldValue, newValue) {
1416
- if (!this.#inited)
1426
+ if (!this.__inited)
1417
1427
  return;
1418
1428
  if (Object.is(newValue, oldValue))
1419
1429
  return;
1420
1430
  let propName = camelCase(attributeName);
1421
- let propDef = DefinitionPropMap.get(this.constructor.name)[propName];
1431
+ let propDef = DefinitionPropMap.get(this.constructor)[propName];
1422
1432
  if (isBooleanProp(propDef.type)) {
1423
1433
  let v = isNull(newValue) ? false : getBooleanValue(newValue);
1424
1434
  if (get(this, propName) === v)
1425
1435
  return;
1426
1436
  }
1427
- this.__attrChanged(attributeName, oldValue, newValue);
1437
+ this.#attrChanged(attributeName, oldValue, newValue);
1428
1438
  }
1429
1439
  //********************************** 更新
1430
1440
  /**
@@ -1442,8 +1452,6 @@ class CompElem extends HTMLElement {
1442
1452
  * @param changed
1443
1453
  */
1444
1454
  updated(changed) { }
1445
- #rootEvs = {};
1446
- #nodeEvs = {};
1447
1455
  /**
1448
1456
  * 由监控变量调用
1449
1457
  * @param stateKey
@@ -1467,33 +1475,6 @@ class CompElem extends HTMLElement {
1467
1475
  }
1468
1476
  Queue.pushNext(this.#updatedD);
1469
1477
  }
1470
- _requestWatchUpdate(newValue, oldValue, fullPath, rootObjNew, rootObjOld) {
1471
- this._watchKeys?.forEach(wk => {
1472
- if (fullPath === wk ||
1473
- (startsWith(wk, fullPath + '.') && !Object.is(get(this._getPrivateData(), wk), get(newValue, wk))) ||
1474
- (startsWith(fullPath, wk + '.') && this._watchKeysDeep.includes(wk) && !Object.is(get(this._getPrivateData(), wk), get(newValue, wk)))) {
1475
- concat(toArray(this._watchUpdateMap[wk]), toArray(this._watchDeepUpdateMap[wk])).forEach(fn => {
1476
- if (!fn)
1477
- return;
1478
- if (this._watchKeysOnceMap.get(wk) === true)
1479
- return;
1480
- this._watchUpdateArgsInNextTick.set(fn, {
1481
- newValue, oldValue, chain: fullPath.split('.'), rootObjNew, rootObjOld, fullMatch: wk === fullPath
1482
- });
1483
- this._watchUpdateSetInNextTick.add(fn);
1484
- if (this._watchKeysOnceMap.has(wk))
1485
- this._watchKeysOnceMap.set(wk, true);
1486
- });
1487
- }
1488
- });
1489
- }
1490
- _requestComputedUpdate(fullPath) {
1491
- if (this._computedUpdateDeps?.has(fullPath)) {
1492
- this._computedUpdateDeps.get(fullPath)?.forEach(fn => {
1493
- this._computedUpdateSetInNextTick.add(fn);
1494
- });
1495
- }
1496
- }
1497
1478
  #update() {
1498
1479
  if (size(this.#updateSources) < 1)
1499
1480
  return;
@@ -1505,19 +1486,16 @@ class CompElem extends HTMLElement {
1505
1486
  if (toBreak)
1506
1487
  return;
1507
1488
  //update decorators
1508
- let ary = DefinitionDecoratorMap.get(this.constructor.name) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor).name);
1489
+ let ary = DefinitionDecoratorMap.get(this.constructor) ?? DefinitionDecoratorMap.get(_getSuper(this.constructor));
1509
1490
  ary && ary.sort((a, b) => b.priority - a.priority).forEach(dw => {
1510
1491
  dw.updated(this, changed);
1511
1492
  });
1512
1493
  //1. filter update point
1513
- let toUpdateCss = false;
1514
1494
  let toUpdateView = false;
1515
1495
  let toUpdateUps = new Set();
1496
+ let viewDeps = this.constructor.prototype._viewDeps;
1516
1497
  each(changed, (x, k) => {
1517
- if (this.__updateCssDeps?.includes(k)) {
1518
- toUpdateCss = true;
1519
- }
1520
- if (!toUpdateView && this.__updateViewDeps?.includes(k)) {
1498
+ if (!toUpdateView && viewDeps?.includes(k)) {
1521
1499
  toUpdateView = true;
1522
1500
  }
1523
1501
  if (this.__updateSubViewDeps?.has(k)) {
@@ -1538,18 +1516,32 @@ class CompElem extends HTMLElement {
1538
1516
  // update computed
1539
1517
  this._computedUpdateSetInNextTick?.forEach(fn => {
1540
1518
  let k = get(fn, 'key');
1541
- let oldValue = this.#data[k];
1519
+ let oldValue = this.__data_[k];
1542
1520
  let newValue = fn.call(this);
1543
1521
  if (!isObject(newValue) && newValue === oldValue)
1544
1522
  return;
1545
- this.#data[k] = newValue;
1523
+ this.__data_[k] = newValue;
1546
1524
  this._notify(oldValue, [k]);
1547
1525
  });
1548
1526
  this._computedUpdateSetInNextTick?.clear();
1527
+ // update css
1528
+ if (this._cssUpdateInNextTick) {
1529
+ let cssVarObj = this.cssVars;
1530
+ each(cssVarObj, (v, k) => {
1531
+ let cssVarKey = '--' + kebabCase(k).replace(/^-+/, '');
1532
+ if (this._cssVarOldValueMap[cssVarKey] == v) {
1533
+ return;
1534
+ }
1535
+ if (isBlank(v) || isNil(v)) {
1536
+ v = 'initial'; // invalid value
1537
+ }
1538
+ this._cssVarOldValueMap[cssVarKey] = v;
1539
+ this.style.setProperty(cssVarKey, v + '');
1540
+ });
1541
+ }
1549
1542
  //2. update view
1550
1543
  if (this.#renderRoot?.deref()) {
1551
1544
  if (toUpdateView) {
1552
- console.debug('update view....', this.constructor.name);
1553
1545
  updateView(this.render(), this, this.__updateTree);
1554
1546
  }
1555
1547
  if (size(toUpdateUps) > 0) {
@@ -1562,10 +1554,6 @@ class CompElem extends HTMLElement {
1562
1554
  this.#updateSlots.forEach((v) => {
1563
1555
  this.#updateSlot(v);
1564
1556
  });
1565
- //update dcss
1566
- if (toUpdateCss) {
1567
- this.#updateCss();
1568
- }
1569
1557
  this.updated(changed);
1570
1558
  }
1571
1559
  /**
@@ -1575,7 +1563,7 @@ class CompElem extends HTMLElement {
1575
1563
  * @returns 非props的attr集合
1576
1564
  */
1577
1565
  #initProps() {
1578
- let propDefs = DefinitionPropMap.get(this.constructor.name) ?? DefinitionPropMap.get(_getSuper(this.constructor).name);
1566
+ let propDefs = DefinitionPropMap.get(this.constructor) ?? DefinitionPropMap.get(_getSuper(this.constructor));
1579
1567
  let attrs = this.attributes;
1580
1568
  let tagName = this.tagName;
1581
1569
  let parentProps = this.#props;
@@ -1594,7 +1582,7 @@ class CompElem extends HTMLElement {
1594
1582
  this.#attrs = this.#attrs ? assign(this.#attrs, filterAttrs) : filterAttrs;
1595
1583
  let rs = {};
1596
1584
  if (!propDefs)
1597
- return Object.seal(rs);
1585
+ return rs;
1598
1586
  let keys = Object.keys(propDefs);
1599
1587
  let size = keys.length;
1600
1588
  for (let i = 0; i < size; i++) {
@@ -1618,18 +1606,6 @@ class CompElem extends HTMLElement {
1618
1606
  propDef.type = inferredType;
1619
1607
  }
1620
1608
  }
1621
- if (propDef.hasChanged) {
1622
- if (!this._hasChangedPropOrStateMap) {
1623
- this._hasChangedPropOrStateMap = new Map();
1624
- }
1625
- this._hasChangedPropOrStateMap.set(key, propDef.hasChanged);
1626
- }
1627
- if (propDef.sync) {
1628
- if (!this._hasSyncPropSet) {
1629
- this._hasSyncPropSet = new Set();
1630
- }
1631
- this._hasSyncPropSet.add(key);
1632
- }
1633
1609
  let val = undefined;
1634
1610
  if (isInited) {
1635
1611
  val = isNil(parentProps[key]) ? defaultVal : parentProps[key];
@@ -1650,25 +1626,14 @@ class CompElem extends HTMLElement {
1650
1626
  break;
1651
1627
  }
1652
1628
  val = this.#propTypeCheck(propDefs, key, val, hasAttr);
1653
- let getter = get(propDefs, [key, 'getter']);
1654
- if (getter)
1655
- getter = bind$1(getter, this);
1656
- let setter = get(propDefs, [key, 'setter']);
1657
- if (setter)
1658
- setter = bind$1(setter, this);
1659
- if (getter || setter) {
1660
- Reflect.defineProperty(this.#data, key, {
1661
- set: setter || function (v) { },
1662
- get: getter
1663
- });
1664
- }
1665
1629
  if (propDef.attribute && isDefined(val) && !isObject(val)) {
1666
1630
  this.#updateAttribute(propDef, key, val);
1667
1631
  }
1668
- this.#data[key] = val;
1632
+ this.__data_[key] = val;
1669
1633
  rs[key] = val;
1634
+ delete this[key];
1670
1635
  }
1671
- return Object.seal(rs);
1636
+ return rs;
1672
1637
  }
1673
1638
  #updateAttribute(propDef, key, val) {
1674
1639
  let k = kebabCase(key);
@@ -1766,35 +1731,24 @@ class CompElem extends HTMLElement {
1766
1731
  showTagError(this.tagName, `Invalid prop '${propKey}'. expected '${expectTypeAry.map((t) => t.name || t)}' but got '${realType}'`);
1767
1732
  }
1768
1733
  if (validator) {
1769
- if (!validator.call(this, val, this.#data)) {
1734
+ if (!validator.call(this, val, this.__data_)) {
1770
1735
  showTagError(this.tagName, `Invalid prop '${propKey}'. IsValid() check failed`);
1771
1736
  }
1772
1737
  }
1773
1738
  return val;
1774
1739
  }
1775
1740
  #initStates() {
1776
- let stateDefs = DefinitionStateMap.get(this.constructor.name) ?? DefinitionStateMap.get(_getSuper(this.constructor).name);
1741
+ let stateDefs = DefinitionStateMap.get(this.constructor) ?? DefinitionStateMap.get(_getSuper(this.constructor));
1777
1742
  if (stateDefs)
1778
1743
  each(stateDefs, (def, key) => {
1779
1744
  let stateDef = stateDefs[key];
1780
1745
  let val = get(this, key);
1781
1746
  if (stateDef) {
1782
1747
  let propName = stateDef.prop;
1783
- val = propName ? cloneDeep(this.#data[propName]) : get(this, key);
1784
- }
1785
- if (stateDef.hasChanged) {
1786
- if (!this._hasChangedPropOrStateMap) {
1787
- this._hasChangedPropOrStateMap = new Map();
1788
- }
1789
- this._hasChangedPropOrStateMap.set(key, stateDef.hasChanged);
1790
- }
1791
- if (stateDef.shallow) {
1792
- if (!this._hasShallowStateSet) {
1793
- this._hasShallowStateSet = new Set();
1794
- }
1795
- this._hasShallowStateSet.add(key);
1748
+ val = propName ? cloneDeep(this.__data_[propName]) : get(this, key);
1796
1749
  }
1797
- this.#data[key] = val;
1750
+ this.__data_[key] = val;
1751
+ delete this[key];
1798
1752
  });
1799
1753
  }
1800
1754
  /**
@@ -1803,9 +1757,8 @@ class CompElem extends HTMLElement {
1803
1757
  * @param attrs
1804
1758
  */
1805
1759
  #propsReady = debounce(this.propsReady, 100);
1806
- //todo 这里需要直接修改prop
1807
1760
  _updateProps(props) {
1808
- let propDefs = DefinitionPropMap.get(this.constructor.name);
1761
+ let propDefs = DefinitionPropMap.get(this.constructor);
1809
1762
  if (!propDefs)
1810
1763
  return;
1811
1764
  let need2UpdateAttrs = [];
@@ -1838,10 +1791,10 @@ class CompElem extends HTMLElement {
1838
1791
  if (fromPath) {
1839
1792
  let propPath = fromPath.join(PATH_SEPARATOR);
1840
1793
  this._wrapperProp[propPath] = k;
1841
- let parentStateDefs = this.wrapperComponent ? DefinitionStateMap.get(this.wrapperComponent?.constructor.name) : null;
1794
+ let parentStateDefs = this.wrapperComponent ? DefinitionStateMap.get(this.wrapperComponent?.constructor) : null;
1842
1795
  let parentStateKey = fromPath[0];
1843
1796
  if (parentStateDefs && parentStateDefs[parentStateKey]) {
1844
- let propDefs = DefinitionPropMap.get(this.constructor.name);
1797
+ let propDefs = DefinitionPropMap.get(this.constructor);
1845
1798
  set(propDefs, [k, 'shallow'], parentStateDefs[parentStateKey].shallow);
1846
1799
  }
1847
1800
  }
@@ -1857,7 +1810,9 @@ class CompElem extends HTMLElement {
1857
1810
  this.#slotsEl[name] = slot;
1858
1811
  SlotCompMap.set(slot, this);
1859
1812
  }
1860
- this.addEvent(slot, 'slotchange', this.__onSlotChangeHook);
1813
+ let evName = 'slotchange';
1814
+ let unbinder = addEvent(evName, this.#onSlotChangeHookBindThis, slot);
1815
+ this._eventBindList.push([evName, this.#onSlotChangeHookBindThis, slot, unbinder]);
1861
1816
  //3. 保存参数
1862
1817
  if (!isEmpty(props)) {
1863
1818
  let slotMap = this.#slotPropsMap[name];
@@ -1957,9 +1912,9 @@ class CompElem extends HTMLElement {
1957
1912
  if (!hook)
1958
1913
  return;
1959
1914
  let slotMap = this.#slotPropsMap[name];
1960
- if (!this.#data.slots)
1915
+ if (!this.__data_.slots)
1961
1916
  return;
1962
- let slot = this.#data.slots[name];
1917
+ let slot = this.__data_.slots[name];
1963
1918
  //slot not ready yet
1964
1919
  //1. 可能是if/each等指令还未插入
1965
1920
  if (!slot)
@@ -1986,22 +1941,14 @@ class CompElem extends HTMLElement {
1986
1941
  _asyncDirectives = new WeakMap();
1987
1942
  renderAsync(cbk, ...args) {
1988
1943
  }
1989
- #updateCss() {
1990
- let cssTmpls = this.styles;
1991
- cssTmpls.forEach((cssTmpl, i) => {
1992
- let cssss = this.__cssSheets[i];
1993
- let css = cssTmpl.getCss(this);
1994
- cssss.replaceSync(css);
1995
- });
1996
- }
1997
- __attrChanged(name, oldValue, newValue) {
1998
- if (!this.#inited)
1944
+ #attrChanged(name, oldValue, newValue) {
1945
+ if (!this.__inited)
1999
1946
  return;
2000
1947
  let observedAttrs = _getObservedAttrs(this.constructor);
2001
1948
  if (observedAttrs.has(name)) {
2002
1949
  let camelName = camelCase(name);
2003
1950
  if (isNull(newValue)) {
2004
- let propDefs = DefinitionPropMap.get(this.constructor.name);
1951
+ let propDefs = DefinitionPropMap.get(this.constructor);
2005
1952
  //使用默认值
2006
1953
  if (propDefs)
2007
1954
  newValue = propDefs[camelName]._defaultValue;
@@ -2009,9 +1956,6 @@ class CompElem extends HTMLElement {
2009
1956
  this._updateProps({ [camelName]: newValue });
2010
1957
  }
2011
1958
  }
2012
- _regWrapper(wrapperComponent) {
2013
- this.#wrapperComponent = new WeakRef(wrapperComponent);
2014
- }
2015
1959
  _regSubViewDeps(props, up) {
2016
1960
  if (!this.__updateSubViewDeps) {
2017
1961
  this.__updateSubViewDeps = new Map();
@@ -2026,78 +1970,38 @@ class CompElem extends HTMLElement {
2026
1970
  });
2027
1971
  }
2028
1972
  _getPrivateData() {
2029
- return this.#data;
1973
+ return this.__data_;
2030
1974
  }
2031
1975
  ////////////////////----------------------------/////////////// APIs
2032
1976
  /**
2033
- * 抛出自定义事件
1977
+ * 发出组件事件
2034
1978
  * @param evName 事件名称
2035
1979
  * @param args 自定义参数
2036
1980
  */
2037
- emit(evName, arg = {}, options) {
2038
- if (options && options.event) {
2039
- arg.event = options.event;
1981
+ emit(evName, arg = {}, event) {
1982
+ if (event) {
1983
+ arg.event = event;
2040
1984
  }
2041
1985
  arg.target = this;
2042
- this.dispatchEvent(new CustomEvent(evName, {
2043
- bubbles: get(options, "bubbles", false),
2044
- composed: get(options, "composed", false),
2045
- cancelable: true,
2046
- detail: arg,
2047
- }));
2048
- }
2049
- /**
2050
- * 在root上绑定事件
2051
- * @param evName
2052
- * @param hook
2053
- * @returns 函数钩子,用于卸载
2054
- */
2055
- on(evName, hook) {
2056
- if (!this.#rootEvs[evName]) {
2057
- this.#rootEvs[evName] = [];
2058
- }
2059
- let cbk = hook.bind(this);
2060
- this.#rootEvs[evName].push(cbk);
2061
- this.addEventListener(evName, cbk);
2062
- return cbk;
2063
- }
2064
- /**
2065
- * 从root上移除事件
2066
- * @param evName
2067
- * @param hook on函数返回的钩子,可选。为空时移除所有evName事件
2068
- */
2069
- off(evName, hook) {
2070
- if (hook) {
2071
- this.removeEventListener(evName, hook);
2072
- remove(this.#rootEvs[evName], cbk => cbk === hook);
1986
+ if (has(this.#attrs, 'emit-native')) {
1987
+ this.dispatchEvent(new CustomEvent(evName, {
1988
+ bubbles: false,
1989
+ composed: false,
1990
+ cancelable: true,
1991
+ detail: arg,
1992
+ }));
2073
1993
  }
2074
1994
  else {
2075
- each(this.#rootEvs[evName], cbk => {
2076
- this.removeEventListener(evName, cbk);
2077
- });
2078
- this.#rootEvs[evName] = [];
2079
- }
2080
- }
2081
- addEvent(node, evName, hook) {
2082
- if (!this.#nodeEvs[evName]) {
2083
- this.#nodeEvs[evName] = [];
1995
+ if (this._listerners[evName]) {
1996
+ this._listerners[evName](arg);
1997
+ }
2084
1998
  }
2085
- let cbk = hook.bind(this);
2086
- this.#nodeEvs[evName].push([cbk, new WeakRef(node)]);
2087
- node.addEventListener(evName, cbk);
2088
- return cbk;
2089
1999
  }
2090
- removeEvent(node, evName, hook) {
2091
- if (hook) {
2092
- node.removeEventListener(evName, hook);
2093
- remove(this.#nodeEvs[evName], ([cbk]) => cbk === hook);
2094
- }
2095
- else {
2096
- each(this.#nodeEvs[evName], ([cbk]) => {
2097
- node.removeEventListener(evName, cbk);
2098
- });
2099
- this.#nodeEvs[evName] = [];
2000
+ _addEvent(evName, hook) {
2001
+ if (!this._listerners) {
2002
+ this._listerners = {};
2100
2003
  }
2004
+ this._listerners[evName] = hook;
2101
2005
  }
2102
2006
  /**
2103
2007
  * 下一帧执行
@@ -2118,7 +2022,7 @@ class CompElem extends HTMLElement {
2118
2022
  * 强制更新一次视图
2119
2023
  */
2120
2024
  forceUpdate() {
2121
- each(this.#data, (v, k) => {
2025
+ each(this.__data_, (v, k) => {
2122
2026
  this.#updateSources[k] = {
2123
2027
  value: undefined,
2124
2028
  chain: undefined,
@@ -2686,7 +2590,7 @@ const EXP_ATTR_CONVERT = /\s+([\.?@*])?((?:[a-zA-Z]*[A-Z][^\s<>="']+))(?=[\s=>])
2686
2590
  const EXP_ATTR_CHECK = /[.?-a-z]+\s*=\s*(['"])\s*([^='"]*<\!--c_ui-pl_df-->){2,}.*?\1/ims;
2687
2591
  const EXP_PLACEHOLDER = /<\s*[a-z0-9-]+([^>]*<\!--c_ui-pl_df-->)*[^>]*?(?<!-)>/imgs;
2688
2592
  const SLOT_KEY_PROPS = 'slot-props';
2689
- const HTML_TMPL_CACHE = {};
2593
+ const HTML_TMPL_CACHE = new Map();
2690
2594
  /**
2691
2595
  * 提供渲染函数相关操作
2692
2596
  * @author holyhigh2
@@ -2764,12 +2668,12 @@ const PLACEHOLDER_EXP = /<!--c_ui-pl_df\d*(-->)?/;
2764
2668
  * 构建模板为DOM结构
2765
2669
  * @param html
2766
2670
  */
2767
- function buildTmplate(updatePoints, html, vars, renderComponent, isDirective = false) {
2671
+ function buildTmplate(updatePoints, html, vars, renderComponent) {
2768
2672
  const container = document.createElement("div");
2769
2673
  container.innerHTML = html;
2770
- let evList = renderComponent._eventList;
2674
+ let evList = renderComponent._eventBindList;
2771
2675
  if (!evList) {
2772
- evList = renderComponent._eventList = [];
2676
+ evList = renderComponent._eventBindList = [];
2773
2677
  }
2774
2678
  //遍历dom
2775
2679
  const nodeIterator = document.createNodeIterator(container, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);
@@ -2977,7 +2881,7 @@ function buildTmplate(updatePoints, html, vars, renderComponent, isDirective = f
2977
2881
  } //endif
2978
2882
  } //endfor
2979
2883
  if (currentNode instanceof CompElem) {
2980
- currentNode._regWrapper(renderComponent);
2884
+ setWrapper(currentNode, renderComponent);
2981
2885
  if (size(props) > 0)
2982
2886
  currentNode._initProps(props);
2983
2887
  }
@@ -3051,14 +2955,14 @@ function buildTmplate(updatePoints, html, vars, renderComponent, isDirective = f
3051
2955
  function buildView(tmpl, component) {
3052
2956
  let updatePoints = [];
3053
2957
  let nodes;
3054
- if (HTML_TMPL_CACHE[component.tagName]) {
3055
- let htmlTmpl = HTML_TMPL_CACHE[component.tagName];
2958
+ if (HTML_TMPL_CACHE.has(component.constructor)) {
2959
+ let htmlTmpl = HTML_TMPL_CACHE.get(component.constructor);
3056
2960
  let vars = buildVars(component, tmpl);
3057
2961
  nodes = buildTmplate(updatePoints, htmlTmpl, vars, component);
3058
2962
  }
3059
2963
  else {
3060
2964
  let [html, vars] = buildHTML(component, tmpl);
3061
- HTML_TMPL_CACHE[component.tagName] = html;
2965
+ HTML_TMPL_CACHE.set(component.constructor, html);
3062
2966
  nodes = buildTmplate(updatePoints, html, vars, component);
3063
2967
  }
3064
2968
  component.__updateTree = updatePoints;
@@ -3067,7 +2971,7 @@ function buildView(tmpl, component) {
3067
2971
  function buildSubView(pointNode, tmpl, component, po, bindEvent = false) {
3068
2972
  let [html, vars] = buildHTML(component, tmpl);
3069
2973
  let updatePoints = [];
3070
- let nodes = buildTmplate(updatePoints, html, vars, component, true);
2974
+ let nodes = buildTmplate(updatePoints, html, vars, component);
3071
2975
  if (bindEvent)
3072
2976
  component.__bindEvents();
3073
2977
  updatePoints.forEach(up => {
@@ -3192,14 +3096,6 @@ function updateSubScopeView(subScopeUpdatePoint, renderComponent, tmpl, changedK
3192
3096
  function html(strings, ...vars) {
3193
3097
  return new Template(isString(strings) ? [strings] : strings, vars);
3194
3098
  }
3195
- /**
3196
- * 标签函数,用于构建样式
3197
- * @param strings
3198
- * @param vars
3199
- */
3200
- function css(strings, ...vars) {
3201
- return new CssTemplate(isString(strings) ? [strings] : strings, vars);
3202
- }
3203
3099
  const EXP_STR = /([a-z0-9"'])\s*>\s*</img;
3204
3100
  class RefObject {
3205
3101
  #ref;
@@ -3218,6 +3114,9 @@ class RefObject {
3218
3114
  function createRef() {
3219
3115
  return new RefObject();
3220
3116
  }
3117
+ function setWrapper(target, wrapperComponent) {
3118
+ target.__wrapperComponent = new WeakRef(wrapperComponent);
3119
+ }
3221
3120
 
3222
3121
  //装饰器类型
3223
3122
  var DecoratorType;
@@ -3316,12 +3215,12 @@ function decorator(decoClass) {
3316
3215
  let fn = (...args) => {
3317
3216
  return (...metadata) => {
3318
3217
  let ctor = metadata[0].constructor;
3319
- let ary = DefinitionDecoratorMap.get(ctor.name); // ctor[_DecoratorsKey]
3320
- if (!DefinitionDecoratorMap.has(ctor.name)) {
3218
+ let ary = DefinitionDecoratorMap.get(ctor); // ctor[_DecoratorsKey]
3219
+ if (!DefinitionDecoratorMap.has(ctor)) {
3321
3220
  //继承父类
3322
3221
  let proto = Object.getPrototypeOf(ctor);
3323
- ary = proto ? concat(DefinitionDecoratorMap.get(proto.name) ?? []) : [];
3324
- DefinitionDecoratorMap.set(ctor.name, ary);
3222
+ ary = proto ? concat(DefinitionDecoratorMap.get(proto) ?? []) : [];
3223
+ DefinitionDecoratorMap.set(ctor, ary);
3325
3224
  }
3326
3225
  let dw = new DecoratorWrapper(args, metadata.splice(1), decoClass);
3327
3226
  ary?.push(dw);
@@ -3335,12 +3234,12 @@ function decoratorWithNoArgs(decoClass) {
3335
3234
  if (!metadata || metadata.length < 1)
3336
3235
  return;
3337
3236
  let ctor = metadata[0].constructor;
3338
- let ary = DefinitionDecoratorMap.get(ctor.name); // ctor[_DecoratorsKey]
3339
- if (!DefinitionDecoratorMap.has(ctor.name)) {
3237
+ let ary = DefinitionDecoratorMap.get(ctor); // ctor[_DecoratorsKey]
3238
+ if (!DefinitionDecoratorMap.has(ctor)) {
3340
3239
  //继承父类
3341
3240
  let proto = Object.getPrototypeOf(ctor);
3342
- ary = proto ? concat(DefinitionDecoratorMap.get(proto.name) ?? []) : [];
3343
- DefinitionDecoratorMap.set(ctor.name, ary);
3241
+ ary = proto ? concat(DefinitionDecoratorMap.get(proto) ?? []) : [];
3242
+ DefinitionDecoratorMap.set(ctor, ary);
3344
3243
  }
3345
3244
  let dw = new DecoratorWrapper([], metadata.splice(1), decoClass);
3346
3245
  ary?.push(dw);
@@ -3353,10 +3252,22 @@ function computed(target, propertyKey, descriptor) {
3353
3252
  if (!descriptor.get) {
3354
3253
  showError(`Computed '${propertyKey}' must be a getter`);
3355
3254
  }
3356
- if (!DefinitionComputedMap.has(target.constructor.name)) {
3357
- DefinitionComputedMap.set(target.constructor.name, {});
3255
+ if (!DefinitionComputedMap.has(target.constructor)) {
3256
+ DefinitionComputedMap.set(target.constructor, {});
3358
3257
  }
3359
- DefinitionComputedMap.get(target.constructor.name)[propertyKey] = descriptor.get;
3258
+ DefinitionComputedMap.get(target.constructor)[propertyKey] = descriptor.get;
3259
+ //getter
3260
+ delete target[propertyKey];
3261
+ Reflect.defineProperty(target, propertyKey, {
3262
+ get() {
3263
+ if (Collector.__collecting) {
3264
+ Collector.__varPathList.push(propertyKey);
3265
+ }
3266
+ let v = Reflect.get(this[DATA_KEY], propertyKey);
3267
+ return v;
3268
+ }
3269
+ });
3270
+ return Reflect.getOwnPropertyDescriptor(target, propertyKey);
3360
3271
  }
3361
3272
 
3362
3273
  /**
@@ -3401,15 +3312,15 @@ const debounced = decorator(DebouncedDecorator);
3401
3312
  */
3402
3313
  function event(eventName, eventTarget) {
3403
3314
  return (target, name, descriptor) => {
3404
- if (!DefinitionCompEventMap.has(target.constructor.name)) {
3315
+ if (!DefinitionCompEventMap.has(target.constructor)) {
3405
3316
  let mixinEvents = [];
3406
3317
  let parentCtor = target.constructor;
3407
3318
  while ((parentCtor = _getSuper(parentCtor)) !== CompElem) {
3408
- mixinEvents = concat(mixinEvents, DefinitionCompEventMap.get(parentCtor.name) ?? []);
3319
+ mixinEvents = concat(mixinEvents, DefinitionCompEventMap.get(parentCtor) ?? []);
3409
3320
  }
3410
- DefinitionCompEventMap.set(target.constructor.name, mixinEvents);
3321
+ DefinitionCompEventMap.set(target.constructor, mixinEvents);
3411
3322
  }
3412
- DefinitionCompEventMap.get(target.constructor.name)?.push({ name: eventName, targetFn: eventTarget, fnName: name });
3323
+ DefinitionCompEventMap.get(target.constructor)?.push({ name: eventName, targetFn: eventTarget, fnName: name });
3413
3324
  };
3414
3325
  }
3415
3326
 
@@ -3527,16 +3438,42 @@ function state(options) {
3527
3438
  defineState(target, stateKey, { prop: "" });
3528
3439
  }
3529
3440
  function defineState(target, stateKey, options) {
3530
- if (!DefinitionStateMap.has(target.constructor.name)) {
3441
+ if (!DefinitionStateMap.has(target.constructor)) {
3531
3442
  const mixinStates = {};
3532
3443
  let parentCtor = target.constructor;
3533
3444
  while ((parentCtor = _getSuper(parentCtor)) !== CompElem) {
3534
- merge(mixinStates, DefinitionStateMap.get(parentCtor.name) ?? {});
3445
+ merge(mixinStates, DefinitionStateMap.get(parentCtor) ?? {});
3535
3446
  }
3536
- DefinitionStateMap.set(target.constructor.name, mixinStates);
3447
+ DefinitionStateMap.set(target.constructor, mixinStates);
3537
3448
  }
3538
3449
  options.shallow = options.shallow || false;
3539
- set(DefinitionStateMap.get(target.constructor.name), stateKey, options);
3450
+ set(DefinitionStateMap.get(target.constructor), stateKey, options);
3451
+ //cache tags
3452
+ if (options.hasChanged) {
3453
+ let changeMap = HasChangedPropOrStateMap.get(target.constructor);
3454
+ if (!changeMap) {
3455
+ changeMap = new Map();
3456
+ HasChangedPropOrStateMap.set(target.constructor, changeMap);
3457
+ }
3458
+ changeMap.set(stateKey, options.hasChanged);
3459
+ }
3460
+ if (options.shallow) {
3461
+ let keySet = StateShallowKeySetMap.get(target.constructor);
3462
+ if (!keySet) {
3463
+ keySet = new Set();
3464
+ StateShallowKeySetMap.set(target.constructor, keySet);
3465
+ }
3466
+ keySet.add(stateKey);
3467
+ }
3468
+ //setters & getters
3469
+ Reflect.defineProperty(target.constructor.prototype, stateKey, {
3470
+ get() {
3471
+ return getterValue(undefined, stateKey, this);
3472
+ },
3473
+ set(v) {
3474
+ setterValue(stateKey, v, this);
3475
+ },
3476
+ });
3540
3477
  }
3541
3478
  /**
3542
3479
  * 同@state装饰器,但可用于构造器中调用
@@ -3601,27 +3538,67 @@ const throttled = decorator(ThrottledDecorator);
3601
3538
  */
3602
3539
  function watch(source, options) {
3603
3540
  return (target, name) => {
3604
- if (!DefinitionWatchMap.has(target.constructor.name)) {
3605
- const watchMap = {};
3606
- let parentCtor = target.constructor;
3607
- while ((parentCtor = _getSuper(parentCtor)) !== CompElem) {
3608
- if (DefinitionWatchMap.has(parentCtor.name)) {
3609
- let parentMap = DefinitionWatchMap.get(parentCtor.name);
3610
- each(parentMap, (list, k) => {
3611
- watchMap[k] = list;
3541
+ let watchDeepUpdateMap = WatchDeepUpdateMap.get(target.constructor);
3542
+ let watchUpdateMap = WatchUpdateMap.get(target.constructor);
3543
+ let onceMap = WatchKeysOnceMap.get(target.constructor);
3544
+ let watchKeysDeep = WatchKeysDeepListMap.get(target.constructor);
3545
+ let watchKeys = WatchKeysListMap.get(target.constructor);
3546
+ let watchImmediateList = WatchImmediateListMap.get(target.constructor);
3547
+ if (!watchKeys) {
3548
+ watchKeys = [];
3549
+ WatchKeysListMap.set(target.constructor, watchKeys);
3550
+ watchKeysDeep = [];
3551
+ WatchKeysDeepListMap.set(target.constructor, watchKeysDeep);
3552
+ onceMap = new Map();
3553
+ WatchKeysOnceMap.set(target.constructor, onceMap);
3554
+ watchDeepUpdateMap = {};
3555
+ WatchDeepUpdateMap.set(target.constructor, watchDeepUpdateMap);
3556
+ watchUpdateMap = {};
3557
+ WatchUpdateMap.set(target.constructor, watchUpdateMap);
3558
+ watchImmediateList = {};
3559
+ WatchImmediateListMap.set(target.constructor, watchImmediateList);
3560
+ let parentCtor = _getSuper(target.constructor);
3561
+ while (parentCtor) {
3562
+ if (WatchKeysListMap.has(parentCtor)) {
3563
+ watchKeys.push(...WatchKeysListMap.get(parentCtor));
3564
+ watchKeysDeep.push(...WatchKeysDeepListMap.get(parentCtor));
3565
+ WatchKeysOnceMap.get(parentCtor)?.forEach((v, k) => {
3566
+ onceMap.set(k, v);
3612
3567
  });
3568
+ assign(watchDeepUpdateMap, WatchDeepUpdateMap.get(parentCtor));
3569
+ assign(watchUpdateMap, WatchUpdateMap.get(parentCtor));
3570
+ assign(watchImmediateList, WatchImmediateListMap.get(parentCtor));
3613
3571
  }
3572
+ parentCtor = _getSuper(parentCtor);
3614
3573
  }
3615
- DefinitionWatchMap.set(target.constructor.name, watchMap);
3616
3574
  }
3617
3575
  const sources = isArray(source) ? source : [source];
3618
3576
  sources.forEach(src => {
3619
- let srcList = DefinitionWatchMap.get(target.constructor.name)[src];
3620
- if (!isArray(srcList)) {
3621
- srcList = [];
3622
- DefinitionWatchMap.get(target.constructor.name)[src] = srcList;
3577
+ let handler = target[name];
3578
+ //////////////////////////////
3579
+ let onceWatch = get(options, "once", false);
3580
+ if (onceWatch) {
3581
+ onceMap.set(src, false);
3582
+ }
3583
+ let deep = get(options, "deep", false);
3584
+ watchKeys.push(src);
3585
+ if (deep) {
3586
+ watchDeepUpdateMap[src] = watchDeepUpdateMap[src] ?? new Set();
3587
+ watchDeepUpdateMap[src].add(handler);
3588
+ watchKeysDeep.push(src);
3589
+ }
3590
+ else {
3591
+ watchUpdateMap[src] = watchUpdateMap[src] ?? new Set();
3592
+ watchUpdateMap[src].add(handler);
3593
+ }
3594
+ let immediate = get(options, "immediate", false);
3595
+ if (immediate) {
3596
+ let handlerSet = watchImmediateList[src];
3597
+ if (!handlerSet) {
3598
+ handlerSet = watchImmediateList[src] = new Set();
3599
+ }
3600
+ handlerSet.add(handler);
3623
3601
  }
3624
- srcList.push({ source: src, options, handler: target[name] });
3625
3602
  });
3626
3603
  };
3627
3604
  }
@@ -3644,7 +3621,7 @@ const bind = directive(function Bind(obj) {
3644
3621
  //判断是否prop
3645
3622
  let props = {};
3646
3623
  let attrs = {};
3647
- let propDefs = DefinitionPropMap.get(el.constructor.name);
3624
+ let propDefs = DefinitionPropMap.get(el.constructor);
3648
3625
  each(obj, (v, k) => {
3649
3626
  if (Ignores.includes(k))
3650
3627
  return;
@@ -3944,13 +3921,13 @@ const model = directive(function Model(modelValue, updateProp = 'value', modelPr
3944
3921
  if (!(rootPath in renderComponent) && !renderComponent._wrapperProp[rootPath]) {
3945
3922
  showError(`model - property '${rootPath}' is not defined on the instance of ` + renderComponent.tagName);
3946
3923
  }
3947
- let evList = renderComponent._eventList;
3924
+ let evList = renderComponent._eventBindList;
3948
3925
  if (!isObject(modelValue) && !trim(modelValue))
3949
3926
  modelValue = '';
3950
3927
  if (node instanceof CompElem) {
3951
3928
  node._initProps({ [updateProp]: modelValue });
3952
3929
  let evName = 'update:' + updateProp;
3953
- evList.push([evName, function (e) {
3930
+ evList.push([evName, function (obj) {
3954
3931
  console.debug('Model =>', path);
3955
3932
  let ctx = this;
3956
3933
  let pathFromWrapperComponent = ctx._wrapperProp[rootPath];
@@ -3958,7 +3935,7 @@ const model = directive(function Model(modelValue, updateProp = 'value', modelPr
3958
3935
  if (!hasPath && pathFromWrapperComponent && get(ctx.wrapperComponent, rootPath) === get(ctx, pathFromWrapperComponent)) {
3959
3936
  ctx = ctx.wrapperComponent || ctx;
3960
3937
  }
3961
- set(ctx, path, e.detail.value);
3938
+ set(ctx, path, obj.value);
3962
3939
  }, node]);
3963
3940
  }
3964
3941
  else if (node instanceof HTMLTextAreaElement) {
@@ -4178,4 +4155,4 @@ const when = directive(function When(value, cases) {
4178
4155
  };
4179
4156
  }, [EnterPointType.TEXT, EnterPointType.SLOT]);
4180
4157
 
4181
- export { CompElem, CssHelper, CssTemplate, DI_COMMENT_START_NODE_MAP, Decorator, DecoratorType, DecoratorWrapper, DirectiveUpdateTag, DomUtil, EnterPointType, ModelTriggerType, QueryCache, Template, TextOrSlotDirectiveExecutorMap, UpdatePoint, _getObservedAttrs, _getSuper, _toUpdatePath, bind, buildHTML, classes, computed, createRef, css, debounced, decorator, decoratorWithNoArgs, directive, event, forEach, getBooleanValue, getSlotComponent, html, htmlC, htmlD, ifElse, ifTrue, isBooleanProp, makeState, model, onced, prop, query, queryAll, show, showError, showTagError, showTagWarn, showWarn, slot, state, styles, sync, tag, throttled, updateDirective, watch, when };
4158
+ export { CompElem, CssHelper, DI_COMMENT_START_NODE_MAP, Decorator, DecoratorType, DecoratorWrapper, DirectiveUpdateTag, DomUtil, EnterPointType, ModelTriggerType, QueryCache, Template, TextOrSlotDirectiveExecutorMap, UpdatePoint, _getObservedAttrs, _getSuper, _toUpdatePath, bind, buildHTML, classes, computed, createRef, debounced, decorator, decoratorWithNoArgs, directive, event, forEach, getBooleanValue, getSlotComponent, html, htmlC, htmlD, ifElse, ifTrue, isBooleanProp, makeState, model, onced, prop, query, queryAll, show, showError, showTagError, showTagWarn, showWarn, slot, state, styles, sync, tag, throttled, updateDirective, watch, when };