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/CompElem.d.ts +19 -47
- package/IComponent.d.ts +4 -19
- package/README.md +63 -41
- package/compelem.umd.js +814 -839
- package/constants.d.ts +19 -7
- package/decorators/event.d.ts +1 -1
- package/events/event.d.ts +1 -1
- package/index.d.ts +2 -3
- package/index.js +816 -839
- package/package.json +1 -1
- package/reactive.d.ts +3 -1
- package/render/CssTemplate.d.ts +3 -3
- package/render/render.d.ts +1 -8
package/index.js
CHANGED
|
@@ -1,33 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* compelem v0.20.0
|
|
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, {
|
|
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
|
|
51
|
-
const
|
|
52
|
-
const
|
|
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
|
|
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
|
|
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
|
|
184
|
-
DefinitionPropMap.set(target.constructor
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
309
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
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
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
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
|
-
|
|
875
|
+
__data_ = {};
|
|
771
876
|
#updateSources = {};
|
|
772
877
|
#shadow;
|
|
773
878
|
//保存所有渲染上下文 {CompElem/Directive}
|
|
774
879
|
__updateTree;
|
|
775
|
-
|
|
776
|
-
|
|
880
|
+
_eventBindList;
|
|
881
|
+
_listerners = {};
|
|
777
882
|
__docoEventMap;
|
|
778
|
-
__updateCssDeps;
|
|
779
883
|
__updateSubViewDeps;
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
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
|
|
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
|
|
821
|
-
return ComponentStaticStyleMap.get(this);
|
|
920
|
+
get cssSheets() {
|
|
921
|
+
return ComponentStaticStyleMap.get(this.constructor);
|
|
822
922
|
}
|
|
823
|
-
get
|
|
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
|
-
|
|
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
|
|
945
|
+
static get css() {
|
|
849
946
|
return [];
|
|
850
947
|
}
|
|
851
|
-
static get
|
|
948
|
+
static get globalCss() {
|
|
852
949
|
return undefined;
|
|
853
950
|
}
|
|
854
|
-
static get
|
|
951
|
+
static get hostCss() {
|
|
855
952
|
return undefined;
|
|
856
953
|
}
|
|
857
|
-
get
|
|
858
|
-
return
|
|
954
|
+
get cssVars() {
|
|
955
|
+
return {};
|
|
859
956
|
}
|
|
860
|
-
|
|
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
|
-
|
|
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
|
|
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, "
|
|
925
|
-
let styleSheet = get(this.constructor, '
|
|
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, '
|
|
1045
|
+
set(this.constructor, 'hostCssSheet', styleSheet);
|
|
936
1046
|
}
|
|
937
|
-
let styleRoot = this
|
|
1047
|
+
let styleRoot = this.__wrapperComponent?.deref()?.shadowRoot ?? this.#parentComponent?.deref()?.shadowRoot ?? this.ownerDocument;
|
|
938
1048
|
//detached el
|
|
939
|
-
if (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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
-
|
|
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.
|
|
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.
|
|
1040
|
-
this.
|
|
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
|
|
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
|
|
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.#
|
|
1077
|
-
this.#
|
|
1078
|
-
this.#
|
|
1079
|
-
this.#
|
|
1080
|
-
this.#
|
|
1081
|
-
this.#
|
|
1082
|
-
this.#
|
|
1083
|
-
this.#
|
|
1084
|
-
this.#
|
|
1085
|
-
this
|
|
1086
|
-
this
|
|
1087
|
-
this.#
|
|
1088
|
-
this
|
|
1089
|
-
this
|
|
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
|
|
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, "
|
|
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, "
|
|
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
|
|
1222
|
+
this.__data_[key] = v;
|
|
1137
1223
|
}
|
|
1138
1224
|
this.#initStates();
|
|
1139
1225
|
//2. Data
|
|
1140
|
-
this
|
|
1141
|
-
|
|
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
|
|
1207
|
-
|
|
1208
|
-
|
|
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.
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
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
|
|
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
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
1301
|
+
this.#renderRoot = this.#renderRoots[0];
|
|
1296
1302
|
}
|
|
1297
1303
|
}
|
|
1298
|
-
this
|
|
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
|
|
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
|
|
1310
|
-
return that
|
|
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
|
|
1329
|
+
let cssVarObj = this.cssVars;
|
|
1325
1330
|
Collector.end();
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
let
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
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
|
|
1345
|
-
return that
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1632
|
+
this.__data_[key] = val;
|
|
1669
1633
|
rs[key] = val;
|
|
1634
|
+
delete this[key];
|
|
1670
1635
|
}
|
|
1671
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
1915
|
+
if (!this.__data_.slots)
|
|
1961
1916
|
return;
|
|
1962
|
-
let slot = this
|
|
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
|
-
#
|
|
1990
|
-
|
|
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
|
|
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
|
|
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 = {},
|
|
2038
|
-
if (
|
|
2039
|
-
arg.event =
|
|
1981
|
+
emit(evName, arg = {}, event) {
|
|
1982
|
+
if (event) {
|
|
1983
|
+
arg.event = event;
|
|
2040
1984
|
}
|
|
2041
1985
|
arg.target = this;
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
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
|
-
|
|
2076
|
-
this.
|
|
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
|
-
|
|
2091
|
-
if (
|
|
2092
|
-
|
|
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
|
|
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
|
|
2671
|
+
function buildTmplate(updatePoints, html, vars, renderComponent) {
|
|
2768
2672
|
const container = document.createElement("div");
|
|
2769
2673
|
container.innerHTML = html;
|
|
2770
|
-
let evList = renderComponent.
|
|
2674
|
+
let evList = renderComponent._eventBindList;
|
|
2771
2675
|
if (!evList) {
|
|
2772
|
-
evList = renderComponent.
|
|
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
|
|
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
|
|
3055
|
-
let htmlTmpl = HTML_TMPL_CACHE
|
|
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
|
|
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
|
|
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
|
|
3320
|
-
if (!DefinitionDecoratorMap.has(ctor
|
|
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
|
|
3324
|
-
DefinitionDecoratorMap.set(ctor
|
|
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
|
|
3339
|
-
if (!DefinitionDecoratorMap.has(ctor
|
|
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
|
|
3343
|
-
DefinitionDecoratorMap.set(ctor
|
|
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
|
|
3357
|
-
DefinitionComputedMap.set(target.constructor
|
|
3255
|
+
if (!DefinitionComputedMap.has(target.constructor)) {
|
|
3256
|
+
DefinitionComputedMap.set(target.constructor, {});
|
|
3358
3257
|
}
|
|
3359
|
-
DefinitionComputedMap.get(target.constructor
|
|
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
|
|
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
|
|
3319
|
+
mixinEvents = concat(mixinEvents, DefinitionCompEventMap.get(parentCtor) ?? []);
|
|
3409
3320
|
}
|
|
3410
|
-
DefinitionCompEventMap.set(target.constructor
|
|
3321
|
+
DefinitionCompEventMap.set(target.constructor, mixinEvents);
|
|
3411
3322
|
}
|
|
3412
|
-
DefinitionCompEventMap.get(target.constructor
|
|
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
|
|
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
|
|
3445
|
+
merge(mixinStates, DefinitionStateMap.get(parentCtor) ?? {});
|
|
3535
3446
|
}
|
|
3536
|
-
DefinitionStateMap.set(target.constructor
|
|
3447
|
+
DefinitionStateMap.set(target.constructor, mixinStates);
|
|
3537
3448
|
}
|
|
3538
3449
|
options.shallow = options.shallow || false;
|
|
3539
|
-
set(DefinitionStateMap.get(target.constructor
|
|
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
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
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
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
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
|
|
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.
|
|
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 (
|
|
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,
|
|
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,
|
|
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 };
|