efront 4.22.19 → 4.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/#/345/233/275/351/231/205/345/214/226.yml +6 -0
  2. package/apps/kugou/search/search.js +4 -3
  3. package/apps/noice/main.js +1 -1
  4. package/apps/pivot/auth/login.js +4 -4
  5. package/apps/pivot/dht/list.js +5 -5
  6. package/apps/pivot/link/chat.js +1 -1
  7. package/apps/pivot/link/index.js +1 -1
  8. package/apps/pivot/link/list.js +5 -4
  9. package/apps/pivot/share/list.js +6 -5
  10. package/apps/pivot/wow/root.js +3 -2
  11. package/coms/basic/ArrayFill.js +5 -1
  12. package/coms/basic/BigNumber.js +2 -2
  13. package/coms/basic/LoadingArray.js +1 -0
  14. package/coms/basic/cross_.js +4 -1
  15. package/coms/basic/data.js +27 -23
  16. package/coms/basic/extend.js +18 -1
  17. package/coms/basic/isFinit.js +1 -0
  18. package/coms/basic_/&ArrayFill.js +1 -5
  19. package/coms/basic_/&extend.js +1 -18
  20. package/coms/basic_/WeakMap.js +36 -0
  21. package/coms/compile/Javascript.js +2 -1
  22. package/coms/explorer/context.js +10 -7
  23. package/coms/explorer/edit.js +1 -1
  24. package/coms/explorer/fileitem.js +9 -7
  25. package/coms/explorer/main.js +20 -17
  26. package/coms/frame/chat.js +17 -16
  27. package/coms/frame/list.js +6 -5
  28. package/coms/kugou/bindScroll.js +0 -1
  29. package/coms/kugou/buildScroll.js +5 -4
  30. package/coms/kugou/krc.js +2 -2
  31. package/coms/kugou/player.js +2 -2
  32. package/coms/kugou/song.js +1 -1
  33. package/coms/layer/leftCenter.js +5 -5
  34. package/coms/pivot/checkGeo.js +0 -1
  35. package/coms/reptile/alert.js +5 -1
  36. package/coms/reptile/data.js +3 -0
  37. package/coms/zimoli/$cared.js +1 -0
  38. package/coms/zimoli/$casted.js +1 -0
  39. package/coms/zimoli/$eval.js +1 -0
  40. package/coms/zimoli/$mounted.js +1 -0
  41. package/coms/zimoli/$parented.js +1 -0
  42. package/coms/zimoli/$renders.js +1 -0
  43. package/coms/zimoli/$scoped.js +1 -0
  44. package/coms/zimoli/$structed.js +1 -0
  45. package/coms/zimoli/$upwith.js +1 -0
  46. package/coms/zimoli/$watches.js +1 -0
  47. package/coms/zimoli/HexEditor.js +1 -1
  48. package/coms/zimoli/alert.js +4 -2
  49. package/coms/zimoli/appendChild.js +2 -2
  50. package/coms/zimoli/autodragchildren_test.js +1 -1
  51. package/coms/zimoli/care.js +27 -9
  52. package/coms/zimoli/cast.js +13 -14
  53. package/coms/zimoli/checkbox.js +1 -1
  54. package/coms/zimoli/container.js +4 -3
  55. package/coms/zimoli/createItemTarget.js +10 -6
  56. package/coms/zimoli/cross.js +1 -1
  57. package/coms/zimoli/data.js +16 -0
  58. package/coms/zimoli/field.js +3 -3
  59. package/coms/zimoli/gallery_test.js +4 -3
  60. package/coms/zimoli/getArgsChildren.js +1 -1
  61. package/coms/zimoli/getChanged.js +8 -0
  62. package/coms/zimoli/getGenerator.js +36 -28
  63. package/coms/zimoli/grid.js +2 -2
  64. package/coms/zimoli/isMounted.js +6 -3
  65. package/coms/zimoli/lattice.js +2 -4
  66. package/coms/zimoli/maps.js +1 -2
  67. package/coms/zimoli/menu.js +1 -0
  68. package/coms/zimoli/menuItem.js +4 -3
  69. package/coms/zimoli/menuList.js +7 -8
  70. package/coms/zimoli/menu_test.js +4 -3
  71. package/coms/zimoli/model.js +15 -10
  72. package/coms/zimoli/on.js +39 -23
  73. package/coms/zimoli/picture.js +0 -7
  74. package/coms/zimoli/popup.js +5 -5
  75. package/coms/zimoli/radio.js +1 -1
  76. package/coms/zimoli/remove.js +3 -3
  77. package/coms/zimoli/render.js +397 -223
  78. package/coms/zimoli/scrollbar.js +90 -42
  79. package/coms/zimoli/scrollbar.less +5 -3
  80. package/coms/zimoli/select.js +3 -3
  81. package/coms/zimoli/selectList.js +1 -1
  82. package/coms/zimoli/selectListEdit.js +5 -4
  83. package/coms/zimoli/table.html +6 -4
  84. package/coms/zimoli/table.js +82 -41
  85. package/coms/zimoli/table.less +22 -0
  86. package/coms/zimoli/vbox.less +2 -2
  87. package/coms/zimoli/view.js +1 -1
  88. package/coms/zimoli/watch.js +7 -5
  89. package/coms/zimoli/zimoli.js +78 -60
  90. package/docs/version-desc.md +3 -1
  91. package/docs//347/211/210/346/234/254/350/257/264/346/230/216.md +3 -1
  92. package/docs//347/273/204/344/273/266.xht +14 -1
  93. package/package.json +1 -1
  94. package/public/efront.js +1 -1
  95. package/public/pivot/api.yml +46 -0
  96. package/public/pivot/menu.yml +16 -0
  97. package/public/pivot/page/auth/login.txt +1 -0
  98. package/public/pivot/page/cert/main.txt +1 -0
  99. package/public/pivot/page/cert/orders.txt +1 -0
  100. package/public/pivot/page/cert/update.txt +1 -0
  101. package/public/pivot/page/db/act.txt +1 -0
  102. package/public/pivot/page/db/config.txt +1 -0
  103. package/public/pivot/page/db/edit.txt +1 -0
  104. package/public/pivot/page/db/list.txt +1 -0
  105. package/public/pivot//344/270/273/351/241/265.html +46 -0
  106. package/coms/reptile/on.js +0 -4
  107. package/coms/reptile/onmounted.js +0 -1
  108. /package/coms/{zimoli → basic}/encode62.js +0 -0
@@ -1,6 +1,7 @@
1
1
  var hasOwnProperty = {}.hasOwnProperty;
2
- var renderElements = Object.create(null);
2
+ var elementRenders = [];
3
3
  var presets = Object.create(null);
4
+ var renderIds = new WeakMap;
4
5
  var copyAttribute = function (node, copys) {
5
6
  for (var { name, value } of copys) switch (name.toLowerCase()) {
6
7
  case "class":
@@ -24,8 +25,9 @@ var createTemplateNodes = function (text) {
24
25
  if (isEmpty(text)) return;
25
26
  if (isNode(text)) {
26
27
  var node = text;
27
- if (isElement(node) && this.$struct.copys) {
28
- copyAttribute(node, this.$struct.copys);
28
+ var struct = $structed.get(this);
29
+ if (isElement(node) && struct.copys) {
30
+ copyAttribute(node, struct.copys);
29
31
  }
30
32
  this.with = [node];
31
33
  return;
@@ -35,14 +37,27 @@ var createTemplateNodes = function (text) {
35
37
  this.with = Array.apply(null, node.childNodes);
36
38
  }
37
39
  appendChild.after(this, this.with);
38
- this.with = render(this.with, this.$scope, this.$parentScopes, this.$renderid !== 9);
40
+ this.with = render(this.with, $scoped.get(this), $parented.get(this), renderIds.get(this) !== 9);
39
41
  };
42
+ var createCloner = function (node) {
43
+ var $struct = $structed.get(node);
44
+ var parentScopes = getScopeList(node);
45
+ return function (id, scope) {
46
+ var clone = node.cloneNode(true);
47
+ $scoped.set(clone, scope);
48
+ $parented.set(clone, parentScopes);
49
+ $structed.set(clone, $struct);
50
+ renderIds.set(clone, id);
51
+ return clone;
52
+ }
53
+ };
54
+
40
55
  presets.template = function (t) {
41
56
  var comment = document.createComment('template');
42
- comment.$scope = t.$scope;
43
- comment.$parentScopes = t.$parentScopes;
57
+ $scoped.set(comment, $scoped.get(t));
58
+ $parented.set(comment, $parented.get(t));
44
59
  t.$comment = comment;
45
- if (t.$struct.binds.src) {
60
+ if ($structed.get(t).binds.src) {
46
61
  care(comment, createTemplateNodes)
47
62
  }
48
63
  else {
@@ -53,43 +68,44 @@ presets.template = function (t) {
53
68
  return comment;
54
69
  };
55
70
  // <!--
56
- window.renderElements = renderElements;
71
+ window.elementRenders = elementRenders;
57
72
  // -->
73
+ var isLe = function (a, b) {
74
+ return a.id <= b.id;
75
+ };
58
76
  var renderidOffset = 10;
59
77
  var renderidClosed = 0;
60
78
  var addRenderElement = function () {
61
79
  var element = this;
62
- if (!isNode(element)) return;
63
- buildFirst(element);
64
- if (element.$renderid > 10) {
65
- renderElements[element.$renderid] = element;
80
+ var renders = $renders.get(element);
81
+ buildFirst(renders);
82
+ if (renders.id > 10) {
83
+ saveToOrderedArray(elementRenders, renders, isLe);
66
84
  }
67
85
  };
68
86
  var removeRenderElement = function () {
69
- var element = this;
70
- delete renderElements[element.$renderid];
87
+ if (removing) {
88
+ removing.push(this);
89
+ return;
90
+ }
91
+ var renders = $renders.get(this);
92
+ var i = getIndexFromOrderedArray(elementRenders, renders, isLe);
93
+ if (elementRenders[i] === renders) elementRenders.splice(i, 1);
94
+ };
95
+ var buildI = function (renders) {
96
+ if (getTargetIn(this, renders.el)) rebuild(renders);
97
+ };
98
+ var buildO = function (renders) {
99
+ rebuild(renders);
71
100
  };
72
101
  function refresh(root) {
73
- var rest = [];
74
- var body = document.documentElement;
75
- if (root && root.$renders) {
76
- for (var k in renderElements) {
77
- var element = renderElements[k];
78
- if (
79
- getTargetIn(root, element)
80
- ) rebuild(element);
81
- }
102
+ removing = [];
103
+ if (root && $renders.has(root)) {
104
+ elementRenders.forEach(buildI, root);
82
105
  } else {
83
- for (var k in renderElements) {
84
- var element = renderElements[k];
85
- rebuild(element);
86
- if (!getTargetIn(body, element)) {
87
- rest.push(element);
88
- }
89
- }
106
+ elementRenders.forEach(buildO);
90
107
  }
91
108
  callDigest();
92
- if (rest.length) rest.forEach(a => removeRenderElement.call(a));
93
109
  }
94
110
  function fireChanges(element, changes) {
95
111
  var event = createEvent('changes');
@@ -97,50 +113,71 @@ function fireChanges(element, changes) {
97
113
  dispatch(event, element);
98
114
  }
99
115
 
100
- function buildFirst(element) {
101
- rebuild(element, '$ready' in element);
116
+ function buildFirst(renders) {
117
+ rebuild(renders, '$ready' in renders);
102
118
  }
103
119
  var digests = [];
120
+ var removing = null;
121
+ var digestA = a => a.$digest();
122
+ var removeA = a => removeRenderElement.call(a);
123
+ var addA = a => buildFirst(a);
104
124
  function callDigest() {
105
- var d = digests;
125
+ var d;
126
+ d = digests;
106
127
  digests = [];
107
- d.forEach(a => {
108
- a.$digest();
109
- });
128
+ d.forEach(digestA);
129
+ if (removing) {
130
+ d = removing;
131
+ removing = null;
132
+ d.forEach(removeA);
133
+ }
110
134
  }
111
- function getWatchData(element) {
112
- var { $watches } = element;
135
+ function getWatchData(element, w) {
113
136
  var props = {};
114
- for (var key in $watches) {
137
+ for (var key in w) {
115
138
  var data = element[key];
116
139
  props[key] = data;
117
140
  }
118
141
  return props;
119
142
  }
120
- function rebuild(element, isFirstRender) {
121
- if (isFirstRender) delete element.$ready;
122
- if (element.$digest) digests.push(element);
123
- if (!element.$needchanges) {
124
- element.$renders.forEach(a => a.call(element));
143
+ var buildThisA = function (f) {
144
+ f.call(this);
145
+ };
146
+ function rebuild(renders, isFirstRender) {
147
+ if (isFirstRender) delete renders.$ready;
148
+ var el = renders.el;
149
+ var w = $watches.get(el);
150
+ if (el.$digest) digests.push(el);
151
+ if (!w) {
152
+ renders.forEach(buildThisA, el);
125
153
  return;
126
154
  }
127
- var props = getWatchData(isFirstRender ? { $watches: element.$watches } : element);
128
- element.$renders.forEach(a => a.call(element));
155
+ var props = isFirstRender ? {} : getWatchData(el, w);
156
+ renders.forEach(buildThisA, el);
129
157
  var capture = null;
130
- for (var k in props) {
131
- var current = element[k];
158
+ for (var k in w) {
159
+ var current = el[k];
132
160
  var previous = props[k];
133
161
  if (isSame(current, previous)) continue;
134
162
  if (!capture) capture = {};
135
163
  capture[k] = { current, previous };
136
164
  }
137
- if (capture) fireChanges(element, capture);
165
+ if (capture) fireChanges(el, capture);
138
166
  }
139
167
  var variableReg = /([^\:\,\+\=\-\!%\^\|\/\&\*\!\;\?\>\<~\{\}\s\[\]\(\)]|\?\s*\.(?=[^\d])|\s*\.\s*)+/g;
140
168
  var variableOnlyReg = new RegExp(`^${variableReg.source}$`);
169
+ var scopeList = null;
170
+ var makeScopeList = function (s, scopes) {
171
+ if (s) {
172
+ if (scopes) scopes = scopes.slice(), scopes.push(s);
173
+ else scopes = [s];
174
+ }
175
+ return scopes;
176
+ }
141
177
  var getScopeList = function (element) {
142
- var scopes = (element.$parentScopes || []).concat();
143
- if (element.$scope) scopes.push(element.$scope);
178
+ var scopes = $parented.get(element);
179
+ var s = $scoped.get(element);
180
+ scopes = makeScopeList(s, scopes);
144
181
  return scopes;
145
182
  };
146
183
  var toNull = () => null;
@@ -167,7 +204,7 @@ var createGetter = function (target, search, isprop = true) {
167
204
  if (!search) return toUndefined;
168
205
  if (/^\{/.test(search)) search = `(${search})`;
169
206
  search = renderExpress(search);
170
- if (isprop) var getter = $$eval.bind(target, search, getScopeList(target));
207
+ if (isprop) var getter = $$eval.bind(target, search, scopeList);
171
208
  else if (variableOnlyReg.test(search)) getter = $$eval.bind(target, search + "(event)");
172
209
  else getter = $$eval.bind(target, search);
173
210
  return getter;
@@ -177,12 +214,11 @@ var createGetter = function (target, search, isprop = true) {
177
214
  }
178
215
  return toUndefined;
179
216
  };
180
- var createComment = function (renders, type, expression) {
217
+ var createComment = function (type, expression) {
181
218
  var comment = document.createComment(`${type} ${expression}`);
182
- comment.$renders = renders;
183
- comment.$scope = this.$scope;
184
- comment.$struct = this.$struct;
185
- comment.$parentScopes = this.$parentScopes;
219
+ $scoped.set(comment, $scoped.get(this));
220
+ $structed.set(comment, $structed.get(this));
221
+ $parented.set(comment, $parented.get(this));
186
222
  if (this.parentNode) {
187
223
  appendChild.after(this, comment);
188
224
  if (!/^if|^else/i.test(type)) remove(this);
@@ -192,11 +228,11 @@ var createComment = function (renders, type, expression) {
192
228
  return comment;
193
229
  };
194
230
 
195
- var initialComment = function (comment) {
196
- if (comment.$struct.once) {
197
- comment.$renderid = 9;
198
- }
199
- renderlock.push(comment);
231
+ var initialComment = function (el, renders, struct) {
232
+ renders.el = el;
233
+ if (struct.once) renders.r1 = true;
234
+ $renders.set(el, renders);
235
+ renderlock.push(renders);
200
236
  };
201
237
 
202
238
  class Repeater {
@@ -261,7 +297,7 @@ var getClonedElements = function (clones, repsrc) {
261
297
  var newmap = [];
262
298
  var inc = 0;
263
299
  clones.forEach((c, i) => {
264
- var m = c.$scope.$item;
300
+ var m = $scoped.get(c).$item;
265
301
  switch (m) {
266
302
  case repsrc[inc]: delete clones[i]; newmap[inc++] = c; break;
267
303
  case repsrc[inc + 1]: delete clones[i]; inc++; newmap[inc++] = c; break;
@@ -269,7 +305,9 @@ var getClonedElements = function (clones, repsrc) {
269
305
  });
270
306
  return newmap;
271
307
  }
272
- var createRepeat = function (search, id = 0) {
308
+ var repeats = new WeakMap;
309
+ var currentScope = null;
310
+ var createRepeat = function (search, id = 0, struct) {
273
311
  // 懒渲染
274
312
  // throw new Error("repeat is not supported! use list component instead");
275
313
  var expression = search;
@@ -279,26 +317,32 @@ var createRepeat = function (search, id = 0) {
279
317
  // 懒渲染
280
318
  var getter = createGetter(this, srcName);
281
319
  var element = this, clonedElements = [], savedValue, savedOrigin;
282
- if (this.$struct.if) id = -7;
320
+ if (struct.if) id = -7;
321
+ var renderA = function (a, i) {
322
+ a = render(a);
323
+ repeats.set(a, this[i]);
324
+ return a;
325
+ };
326
+ var reps = [];
283
327
  var renders = [function () {
284
328
  var result = getter(this);
285
329
  var origin = result;
286
- result = extend(result instanceof Array ? [] : {}, result);
330
+ var isArrayResult = origin instanceof Array;
331
+ result = extend(isArrayResult ? [] : {}, result);
287
332
  if (savedOrigin === origin && shallowEqual(savedValue, result)) return;
288
- var changes = getChanges(result, savedValue);
289
- if (!changes) return;
333
+ if (savedOrigin !== origin && isObject(origin) && isObject(savedOrigin)) {
334
+ var changed = getChanged(result, savedOrigin);
335
+ if (!changed.length) return;
336
+ var changes = Object.create(null);
337
+ changed.forEach(k => changes[k] = true);
338
+ }
290
339
  savedValue = result;
291
340
  savedOrigin = origin;
292
- var isArrayResult = result instanceof Array;
293
341
  var keys = isArrayResult ? result.map((_, i) => i) : Object.keys(result);
294
342
  if (keys.length > 600) {
295
343
  throw new Error(i18n`数据量过大,取消绘制!`);
296
344
  }
297
- var $parentScopes = element.$parentScopes || [];
298
- var $struct = element.$struct;
299
- if (element.$scope) {
300
- $parentScopes = $parentScopes.slice(), $parentScopes.push(element.$scope);
301
- }
345
+ var cloner = createCloner(element);
302
346
  var clonedElements1 = isArrayResult ? [] : Object.create(null);
303
347
  if (isArrayResult && !trackBy && clonedElements instanceof Array) {
304
348
  clonedElements1 = getClonedElements(clonedElements, result);
@@ -309,7 +353,7 @@ var createRepeat = function (search, id = 0) {
309
353
  if (trackBy) {
310
354
  k = seek($scope, trackBy);
311
355
  if (clonedElements[k]) {
312
- Object.assign(clonedElements[k].$repeat, $scope)
356
+ Object.assign(repeats.get(clonedElements[k]), $scope)
313
357
  return clonedElements1[k] = clonedElements[k];
314
358
  }
315
359
  }
@@ -317,25 +361,22 @@ var createRepeat = function (search, id = 0) {
317
361
  if (isArrayResult) {
318
362
  var c = clonedElements1[k];
319
363
  if (c) {
320
- Object.assign(c.$repeat, $scope);
364
+ Object.assign(repeats.get(c), $scope);
321
365
  return c;
322
366
  }
323
367
  }
324
- else {
368
+ else if (changes) {
325
369
  var c = changes[k];
326
370
  if (!c) c = clonedElements[k];
327
371
  else c = null;
328
372
  if (c) {
329
- Object.assign(c.$repeat, $scope);
373
+ Object.assign(repeats.get(c), $scope);
330
374
  return clonedElements1[k] = c;
331
375
  }
332
376
  }
333
377
  }
334
- var clone = element.cloneNode(true);
335
- clone.$renderid = id;
336
- clone.$repeat = clone.$scope = $scope;
337
- clone.$parentScopes = $parentScopes;
338
- clone.$struct = $struct;
378
+ reps[cx] = $scope;
379
+ var clone = cloner(id, $scope);
339
380
  clonedElements1[k] = clone;
340
381
  return clone;
341
382
  }, this);
@@ -344,7 +385,7 @@ var createRepeat = function (search, id = 0) {
344
385
  if (a.previousSibling !== last) appendChild.after(last, a);
345
386
  last = a;
346
387
  }, this);
347
- cloned.forEach(a => render(a));
388
+ clonedElements1 = cloned.map(renderA, reps);
348
389
  for (var k in clonedElements) {
349
390
  if (clonedElements1[k] !== clonedElements[k]) {
350
391
  var selected = clonedElements[k].selected;
@@ -357,8 +398,8 @@ var createRepeat = function (search, id = 0) {
357
398
  clonedElements = clonedElements1;
358
399
  this.with = cloned;
359
400
  }];
360
- var comment = createComment.call(this, renders, 'repeat', expression);
361
- initialComment(comment);
401
+ var comment = createComment.call(this, 'repeat', expression);
402
+ initialComment(comment, renders, struct);
362
403
  return comment;
363
404
  };
364
405
 
@@ -381,8 +422,8 @@ var ifset = function (shouldMount) {
381
422
  if (cx === shouldMount) {
382
423
  var e = c.$template;
383
424
  if (c.nextSibling !== e) appendChild.after(c, e);
384
- if (e.$renderid < 0) {
385
- e.$renderid = this.$id;
425
+ if (renderIds.get(e) < 0) {
426
+ renderIds.set(e, this.$id);
386
427
  e = c.$template = render(e);
387
428
  e.$comment = c;
388
429
  }
@@ -392,18 +433,20 @@ var ifset = function (shouldMount) {
392
433
  }
393
434
  }
394
435
  };
395
- var createIf = function (search, id = 0) {
436
+ var createIf = function (search, id = 0, struct) {
396
437
  // 懒渲染
397
438
  var getter = createGetter(this, search);
398
439
  var element = this;
399
440
  var elements = [element, getter];
400
441
  if_top.push(elements);
401
442
  elements.parent = this.parentNode;
402
- if (this.$struct.repeat) id = -3;
403
- var comment = elements[0] = createComment.call(element, [new Binder2(ifget, ifset)], 'if', search);
443
+ if (struct.repeat) id = -3;
444
+ var renders = [new Binder2(ifget, ifset)];
445
+ var comment = elements[0] = createComment.call(element, 'if', search);
404
446
  comment.$id = id;
405
447
  comment.$elements = elements;
406
- initialComment(comment);
448
+ if (struct.once) renders.r1 = true;
449
+ initialComment(comment, renders, struct);
407
450
  return comment;
408
451
  };
409
452
  var parseIfWithRepeat = function (ifExpression, repeatExpression) {
@@ -470,22 +513,19 @@ var parseIfWithRepeat = function (ifExpression, repeatExpression) {
470
513
  };
471
514
  };
472
515
 
473
- var mountElementIds = function (element, ids) {
474
- var scope = element.$scope;
475
- if (!scope) return;
516
+ var mountElementIds = function (scope, element, ids) {
476
517
  for (var id of ids) {
477
518
  if (isHandled(scope[id]) && scope[id] !== element) throw new Error(i18n`同一个id不能使用两次:` + id);
478
519
  scope[id] = element;
479
520
  }
480
521
  }
481
- var renderStructure = function (element) {
482
- var $struct = element.$struct;
522
+ var renderStructure = function (element, $struct) {
483
523
  if ($struct.if) var { name: ifkey, key, value: ifexp } = $struct.if;
484
524
  if ($struct.repeat) var { value: repeat } = $struct.repeat;
485
- if (!ifkey) return createRepeat.call(element, repeat);
525
+ if (!ifkey) return createRepeat.call(element, repeat, undefined, $struct);
486
526
  if (!ifexp || !repeat) {
487
527
  if (repeat) delete $struct.if;
488
- return structures[key].call(element, ifexp);
528
+ return structures[key].call(element, ifexp, $struct);
489
529
  }
490
530
  var { before, after } = parseIfWithRepeat(ifexp, repeat);
491
531
  if (after.length) {
@@ -495,18 +535,18 @@ var renderStructure = function (element) {
495
535
  delete $struct.if;
496
536
  }
497
537
  if (before.length > 0) {
498
- return createIf.call(element, before.join("&&"), null);
538
+ return createIf.call(element, before.join("&&"), null, $struct);
499
539
  } else {
500
540
  delete $struct.repeat;
501
541
  if (!repeat) debugger;
502
- return createRepeat.call(element, repeat, null);
542
+ return createRepeat.call(element, repeat, null, $struct);
503
543
  }
504
544
  };
505
545
 
506
546
  var if_top = [];
507
547
  var structures = {
508
- "if"(search) {
509
- return createIf.call(this, search);
548
+ "if"(search, struct) {
549
+ return createIf.call(this, search, undefined, struct);
510
550
  },
511
551
  "else"(search) {
512
552
  for (var cx = if_top.length - 1; cx >= 0; cx--) {
@@ -518,30 +558,34 @@ var structures = {
518
558
  if (cx + 1 < if_top.length) if_top.splice(cx + 1, if_top.length - cx - 1);
519
559
  var top = if_top[cx];
520
560
  if (search) var getter = createGetter(this, search);
521
- var comment = createComment.call(this, undefined, search ? 'elseif' : 'else', search);
561
+ var comment = createComment.call(this, search ? 'elseif' : 'else', search);
522
562
  top.push(comment, getter);
523
563
  },
524
- repeat(search) {
525
- return createRepeat.call(this, search);
564
+ repeat(search, struct) {
565
+ return createRepeat.call(this, search, undefined, struct);
526
566
  },
527
567
  };
528
568
  structures["else-if"] = structures.elseif = structures.else;
529
569
  structures["for-each"] = structures.foreach = structures.for = structures.each = structures.repeat;
570
+ var callThis = function (f) {
571
+ return f(this);
572
+ };
530
573
  var createMapper = function (write, mapper) {
531
574
  return function (search) {
575
+ var capValue = mapper();
576
+ var copyC = function (key) {
577
+ this[key] = capValue[key];
578
+ };
532
579
  var getter = isArray(search) ? search.map(s => createGetter(this, s)) : createGetter(this, search);
533
- var oldValue = mapper();
534
- this.$renders.push(function () {
535
- var value = mapper(isArray(getter) ? getter.map(g => g(this)) : getter(this));
536
- var changes = getChanges(value, oldValue);
537
- if (!changes) return;
538
- oldValue = value;
539
- var targetValue = Object.create(null);
540
- for (var k in changes) {
541
- targetValue[k] = !isHandled(value[k]) ? "" : value[k];
542
- }
580
+ return function () {
581
+ var value = mapper(isArray(getter) ? getter.map(callThis, this) : getter(this));
582
+ var changed = getChanged(value, capValue);
583
+ if (!changed.length) return;
584
+ capValue = value;
585
+ var targetValue = {};
586
+ changed.forEach(copyC, targetValue);
543
587
  write(this, targetValue);
544
- });
588
+ };
545
589
  }
546
590
  }
547
591
 
@@ -579,7 +623,7 @@ var createBinder2 = function (write, read) {
579
623
  return function (search) {
580
624
  var getter = createGetter(this, search);
581
625
  var oldValue = isFunction(read) ? read.call(this) : undefined;
582
- this.$renders.push(new Binder2(getter, write, oldValue));
626
+ return new Binder2(getter, write, oldValue);
583
627
  };
584
628
  }
585
629
 
@@ -590,7 +634,7 @@ var src2 = function (search) {
590
634
  // 非直传数组的数据源变动后,不再检查其所有属性是否相同,直接同步到组件,
591
635
  // 直传数组的数据源以数组中的子项是否变动为准,
592
636
  // 直传数组的判别标准为表达式以“[”开头以“]”结尾,且表达式中间不含“]”
593
- this.$renders.push(function () {
637
+ return function () {
594
638
  var origin = getter(this);
595
639
  if (isArray(origin)) {
596
640
  if (isArray(savedValue)) {
@@ -616,7 +660,7 @@ var src2 = function (search) {
616
660
  if (!isHandled(origin) && !isHandled(this.src));
617
661
  else this.src = origin;
618
662
  cast(this, origin);
619
- });
663
+ };
620
664
  }
621
665
  var gtValue = function () { return this.value };
622
666
  var stValue = function (v) { this.value = v };
@@ -669,7 +713,6 @@ class Model {
669
713
  }
670
714
  hook(elem, emit) {
671
715
  var binder = new Binder2(this.gs, this.target !== elem ? this.sv.bind(this.target) : this.sv);
672
- elem.$renders.push(binder);
673
716
  binder.call(elem);
674
717
  this.bd = binder;
675
718
  if (emit !== false) {
@@ -682,7 +725,7 @@ class Model {
682
725
  }
683
726
  }
684
727
  var createSetter = function (elem, search) {
685
- return $$eval.bind(elem, search + "=arguments[2]", getScopeList(elem), elem);
728
+ return $$eval.bind(elem, search + "=arguments[2]", scopeList, elem);
686
729
  };
687
730
  var directives = {
688
731
  text: createBinder2(function (value) {
@@ -731,10 +774,10 @@ var directives = {
731
774
  var getter = createGetter(this, search);
732
775
  var setter = createSetter(this, search);
733
776
  var model = new Model(getter, setter, target);
734
- model.hook(this, change !== false);
777
+ return model.hook(this, change !== false);
735
778
  },
736
779
  value(search, target) {
737
- directives.model.call(this, search, target, false);
780
+ return directives.model.call(this, search, target, false);
738
781
  },
739
782
 
740
783
  };
@@ -754,7 +797,6 @@ var binders = {
754
797
  this[attr] = this[attr.replace(/\-[a-z]/g, a => a.toUpperCase())] = value;
755
798
  }
756
799
  };
757
- this.$renders.push(hook);
758
800
  return hook;
759
801
  },
760
802
  ""(attr, search) {
@@ -774,7 +816,6 @@ var binders = {
774
816
  }
775
817
  } else if (this.getAttribute(attr) !== value) this.setAttribute(attr, value);
776
818
  }
777
- this.$renders.push(hook);
778
819
  return hook;
779
820
  }
780
821
  };
@@ -791,23 +832,28 @@ class Emitter {
791
832
  if (parsedSrc instanceof Repeater) {
792
833
  if (e.active || e.currentTarget) var target = e.active || (e.currentTarget === elem ? e.target || e.srcElem || e.currentTarget : e.currentTarget);
793
834
  else var target = e.target;
835
+ var es = $scoped.get(elem);
794
836
  if (target === elem) {
795
837
  scope = parsedSrc.createScope();
796
838
  }
797
839
  else {
798
- let scopes = target && target.$parentScopes;
840
+ let scopes = target && $parented.get(target);
799
841
  if (scopes) {
800
842
  var scope = null;
801
843
  for (var cx = scopes.length - 1; cx >= 0; cx--) {
802
844
  var s = scopes[cx];
803
- if (s === elem.$scope) {
845
+ if (s === es) {
804
846
  scope = scopes[cx + 1];
805
847
  break;
806
848
  }
807
849
  }
808
850
  }
809
851
  }
810
- if (!scope && target.$scope !== elem.$scope) scope = target.$scope;
852
+
853
+ if (!scope) {
854
+ var ts = $scoped.get(target);
855
+ if (es !== ts) scope = ts;
856
+ }
811
857
  }
812
858
  var res;
813
859
  if (scope) {
@@ -839,7 +885,7 @@ var createEmiter = function (on) {
839
885
  else {
840
886
  onkey = on(key);
841
887
  }
842
- onkey(target, new Emitter(emit, getScopeList(this)));
888
+ onkey(target, new Emitter(emit, scopeList));
843
889
  };
844
890
  };
845
891
  var emiters = {
@@ -855,16 +901,18 @@ var keyAdapters = [
855
901
  key => key.replace(/\-+([a-z])/g, (_, w) => w.toUpperCase()),
856
902
  key => key.replace(/^([a-z])/g, (_, w) => w.toUpperCase())
857
903
  ];
904
+ var foundScope = null;
858
905
  function getFromScopes(key, scope, parentScopes) {
906
+ foundScope = null;
859
907
  if (!isHandled(key)) return;
860
908
  for (var ka of keyAdapters) {
861
909
  key = ka(key);
862
- if (scope && key in scope) return scope[key];
910
+ if (scope && key in scope) return foundScope = scope, scope[key];
863
911
  if (parentScopes) for (var cx = parentScopes.length - 1; cx >= 0; cx--) {
864
912
  var o = parentScopes[cx];
865
- if (o && key in o) return o[key];
913
+ if (o && key in o) return foundScope = o, o[key];
866
914
  }
867
- if (key in presets) return presets[key];
915
+ if (key in presets) return foundScope = presets, presets[key];
868
916
  }
869
917
  }
870
918
  function renderProp(elem, props) {
@@ -875,50 +923,61 @@ function renderProp(elem, props) {
875
923
  }
876
924
  }
877
925
 
878
- function renderBinds(element, binds) {
926
+ function renderBinds(element, binds, renders) {
879
927
  var bind = binders._;
880
928
  for (var k in binds) {
881
929
  if (directives.hasOwnProperty(k)) continue;
882
930
  var h = bind.call(element, k, binds[k]);
883
931
  h.call(element);
932
+ renders.push(h);
884
933
  }
885
934
  }
886
- function renderDynamics(element, replacer, binds, attrs) {
887
- var renders = element.$renders;
935
+ var getUserRenders = function (element, renders) {
888
936
  if (element.renders) {
889
- if (!renders) renders = [];
890
937
  renders.push.apply(renders, element.renders);
891
938
  delete element.renders;
892
939
  }
893
- element.$renders = [];
894
- var bindWatch = !!element.$needchanges;
940
+ if (element.$renders) {
941
+ renders.push.apply(renders, element.$renders);
942
+ delete element.$renders;
943
+ }
944
+ return renders;
945
+ }
946
+ function renderDynamics(element, replacer, binds, attrs, renders) {
947
+ getUserRenders(element, renders);
948
+ var watches = $watches.get(element);
895
949
  for (var k in binds) {
896
950
  if (k in directives) {
897
- if (k !== 'src') directives[k].call(element, binds[k], replacer);
951
+ if (k !== 'src') {
952
+ var f = directives[k].call(element, binds[k], replacer);
953
+ if (f) renders.push(f);
954
+ }
898
955
  }
899
956
  else {
900
957
  if (element !== replacer) replacer[k] = element[k];
901
- if (bindWatch) {
902
- var watches = element.$watches;
903
- if (!watches) watches = element.$watches = {};
958
+ if (watches) {
904
959
  if (!watches[k]) watches[k] = true;
905
960
  }
906
961
  }
907
962
  }
963
+ var ba = binders[''];
908
964
  for (var k in attrs) {
909
- binders[""].call(element, k, attrs[k]);
965
+ var f = ba.call(element, k, attrs[k]);
966
+ renders.push(f);
967
+ }
968
+ if (binds.src) {
969
+ var f = directives.src.call(element, binds.src);
970
+ renders.push(f);
910
971
  }
911
- if (renders && renders.length) element.$renders.push.apply(element.$renders, renders);
912
- if (binds.src) directives.src.call(element, binds.src);
913
972
  }
914
973
 
915
974
  function renderEmits(replacer, emits, on) {
916
975
  for (var k in emits) on.call(this, replacer, k, emits[k]);
917
976
  }
918
977
 
919
- function renderRest(element, struct, replacer = element) {
978
+ function renderRest(renders, element, struct, replacer = element) {
920
979
  var { attrs, binds, emits, waits } = struct;
921
- renderDynamics(element, replacer, binds, attrs);
980
+ renderDynamics(element, replacer, binds, attrs, renders);
922
981
  if (!isElement(replacer)) replacer = element;
923
982
  renderEmits.call(element, replacer, emits, emiters.on);
924
983
  renderEmits.call(element, replacer, waits, emiters.once);
@@ -939,98 +998,126 @@ function renderArray(children, scope, parentScopes, once) {
939
998
  function getChildren(element) {
940
999
  var children = element.children;
941
1000
  if (!children || !children.length) return;
942
- var children = Array.prototype.filter.call(children, a => !a.$renderid);
943
- return children
1001
+ var children = Array.prototype.filter.call(children, a => !renderIds.get(a));
1002
+ return children;
944
1003
  }
945
- function renderElement(element, scope = element.$scope, parentScopes = element.$parentScopes, once) {
1004
+ function renderElement(element, scope = $scoped.get(element), parentScopes = $parented.get(element), once) {
946
1005
  if (isArrayLike(element)) {
947
1006
  return renderArray(Array.apply(null, element), scope, parentScopes, once);
948
1007
  }
949
1008
  if (!isElement(element)) {
950
1009
  return element;
951
1010
  }
952
- if (!isNumber(element.$renderid)) {
953
- element.$renderid = 0;
954
- element.$scope = scope;
1011
+ var $struct;
1012
+ if (!renderIds.get(element)) {
1013
+ renderIds.set(element, 0);
955
1014
  if (isHandled(parentScopes) && !isArray(parentScopes)) {
956
1015
  throw new Error(i18n`父级作用域链应以数组的类型传入`);
957
1016
  }
958
1017
  if (parentScopes) {
959
- if (element.$renderid && !element.$parentScopes || element.$parentScopes && element.$parentScopes.length !== parentScopes.length) {
1018
+ var eps = $parented.get(element);
1019
+ if (eps && eps.length !== parentScopes.length) {
960
1020
  throw new Error(i18n`父作用域链的长度必须相等着`);
961
1021
  }
962
1022
  }
963
- var s = createStructure(element);
964
- element.$struct = s;
965
- mountElementIds(element, s.ids);
966
- if (isEmpty(s.once)) s.once = once;
967
- element.$eval = $eval;
968
- }
969
- element.$scope = scope;
970
- element.$parentScopes = parentScopes || [];
971
- if (element.$renderid <= -1) element = renderStructure(element);
972
- if (!element) return;
973
- if (element.$renderid < 0 || element.nodeType !== 1) {
1023
+ $struct = createStructure(element);
1024
+ if ($struct && !isHandled($struct.once)) $struct.once = once;
1025
+ }
1026
+ else {
1027
+ $struct = $structed.get(element);
1028
+ }
1029
+ if (!parentScopes) parentScopes = [];
1030
+ $scoped.set(element, scope);
1031
+ $parented.set(element, parentScopes);
1032
+ var savedScopeList = scopeList;
1033
+ scopeList = makeScopeList(scope, parentScopes);
1034
+ if (renderIds.get(element) <= -1) element = renderStructure(element, $struct);
1035
+ if (!element) {
1036
+ scopeList = savedScopeList;
1037
+ return;
1038
+ }
1039
+ if (renderIds.get(element) < 0 || element.nodeType !== 1) {
1040
+ scopeList = savedScopeList;
974
1041
  return element;
975
1042
  }
976
- var isFirstRender = !element.$renderid;
1043
+ if ($struct) mountElementIds(scope, element, $struct.ids);
1044
+ var isFirstRender = !renderIds.get(element);
977
1045
  if (isFirstRender) {
978
1046
  var lockid = renderlock.length;
979
1047
  renderlock[lockid] = null;
980
- element.$renderid = 1;
1048
+ renderIds.set(element, 1);
981
1049
  var parentNode = element.parentNode;
982
1050
  if (parentNode) {
983
- if (parentNode.$renderid > 1 || isMounted(parentNode)) element.$renderid = 2;
1051
+ if (renderIds.get(parentNode) > 1 || isMounted(parentNode)) renderIds.set(element, 2);
984
1052
  }
985
- var $struct = element.$struct;
986
- element.$renders = element.$renders || element.renders ? [].concat(element.$renders || [], element.renders || []) : [];
987
- var { copys, binds, once, props } = $struct;
988
- if (once) element.$renderid = 9;
989
- if (binds.src) {
990
- element.$src = parseRepeat(binds.src);
1053
+ var renders = initRenders(element);
1054
+ getUserRenders(element, renders);
1055
+ if ($struct) {
1056
+ var { copys, binds, once, props } = $struct;
1057
+ if (once) renders.r1 = true;
1058
+ if (binds.src) {
1059
+ element.$src = parseRepeat(binds.src);
1060
+ }
1061
+ renderProp(element, props);
1062
+ renderBinds(element, binds, renders);
991
1063
  }
992
1064
  var { tagName, parentNode, nextSibling } = element;
993
1065
  // 替换元素
994
1066
  var constructor = getFromScopes(tagName, scope, parentScopes);
995
- renderProp(element, props);
996
- renderBinds(element, binds);
1067
+ var conScope = foundScope;
997
1068
  if (isFunction(constructor)) {
998
- var replacer = constructor.call(scope, element, scope, parentScopes);
1069
+ var scopeList0 = scopeList;
1070
+ var scope0 = scope;
1071
+ var replacer = constructor.call(conScope, element, scope, parentScopes);
999
1072
  if (element === replacer) {
1000
1073
  var struct1 = createStructure(element, false);
1001
- renderRest(element, struct1);
1002
- element.$scope = scope;
1074
+ scope = $scoped.get(element) || scope;
1075
+ parentScopes = $parented.get(element) || parentScopes;
1076
+ scopeList = makeScopeList(scope, parentScopes);
1077
+ if (struct1) renderRest(renders, element, struct1);
1003
1078
  }
1004
1079
  else if (isNode(replacer)) {
1005
- if (isElement(replacer) && !replacer.$renderid) {
1006
- if (!replacer.$scope) replacer.$scope = scope;
1007
- if (!replacer.$parentScopes) replacer.$parentScopes = parentScopes;
1008
- createStructure(replacer);
1009
- renderRest(replacer, replacer.$struct);
1080
+ if (isElement(replacer) && !renderIds.get(replacer)) {
1081
+ if (!$scoped.has(replacer)) $scoped.set(replacer, scope);
1082
+ if (!$parented.has(replacer)) $parented.set(replacer, parentScopes);
1083
+ var struct2 = createStructure(replacer);
1084
+ scope = $scoped.get(replacer) || scope;
1085
+ parentScopes = $parented.get(replacer) || parentScopes;
1086
+ scopeList = makeScopeList(scope, parentScopes);
1087
+ if (struct2) renderRest(renders, replacer, struct2);
1088
+ }
1089
+ if ($struct) {
1090
+ copyAttribute(replacer, copys);
1091
+ for (var id of $struct.ids) {
1092
+ scope0[id] = replacer;
1093
+ }
1010
1094
  }
1011
- copyAttribute(replacer, copys);
1012
1095
  if (nextSibling) appendChild.before(nextSibling, replacer);
1013
1096
  else if (parentNode) appendChild(parentNode, replacer);
1014
1097
  if (element.parentNode === parentNode) remove(element);
1015
- if (!replacer.$renderid) replacer.$renderid = element.$renderid;
1016
- for (var id of element.$struct.ids) {
1017
- scope[id] = replacer;
1018
- }
1098
+ if (!renderIds.get(replacer)) renderIds.set(replacer, renderIds.get(element));
1019
1099
  }
1100
+ scopeList = scopeList0;
1020
1101
  }
1021
- renderRest(element, $struct, replacer);
1102
+ if ($struct) renderRest(renders, element, $struct, replacer);
1022
1103
  if (isNode(replacer) && replacer !== element) {
1023
- if (!replacer.$renders) replacer.$renders = [];
1024
- replacer.$renders.push.apply(replacer.$renders, element.$renders);
1104
+ $renders.delete(element);
1105
+ var reprenders = initRenders(replacer);
1106
+ reprenders.push.apply(reprenders, renders);
1107
+ renders = reprenders;
1025
1108
  element = replacer;
1109
+ scope = $scoped.get(element);
1110
+ parentScopes = $parented.get(element);
1026
1111
  }
1027
- if (element.$digest || element.$renders.length) {
1028
- element.$ready = true;
1029
- renderlock[lockid] = element;
1112
+ if (element.$digest || renders.length) {
1113
+ if ($struct && $struct.once) renders.r1 = $struct.once;
1114
+ renders.$ready = true;
1115
+ renderlock[lockid] = renders;
1030
1116
  }
1031
- else if (renderlock.length === lockid) renderlock.pop();
1117
+ else if (renderlock.length === lockid + 1) renderlock.pop(), $renders.delete(element);
1032
1118
  }
1033
- renderArray(getChildren(element), element.$scope || scope, element.$parentScopes || parentScopes, once);
1119
+ renderArray(getChildren(element), scope, parentScopes, once);
1120
+ scopeList = savedScopeList;
1034
1121
  return element;
1035
1122
  }
1036
1123
  var deepcontexts = [];
@@ -1058,7 +1145,7 @@ function $$eval(search, scopes, target = this, event) {
1058
1145
 
1059
1146
  function $eval(search, scope, event) {
1060
1147
  var scopes = getScopeList(this);
1061
- if (isHandled(scope) && scope !== this.$scope) scopes.push(scope);
1148
+ if (isHandled(scope) && scope !== $scoped.get(this)) scopes.push(scope);
1062
1149
  return $$eval.call(this, search, scopes, this, event);
1063
1150
  }
1064
1151
 
@@ -1124,7 +1211,10 @@ var pushid = function (ids, name) {
1124
1211
 
1125
1212
  function createStructure(element, useExists) {
1126
1213
  if (isArrayLike(element)) return Array.prototype.map.call(element, createStructure);
1127
- if (useExists !== false && element.$struct) return element.$struct;
1214
+ if (useExists !== false) {
1215
+ var s = $structed.get(element);
1216
+ if (s) return s;
1217
+ }
1128
1218
  if (element.nodeType !== 1) return;
1129
1219
  // 处理结构流
1130
1220
  var attributes = element.attributes;
@@ -1142,16 +1232,19 @@ function createStructure(element, useExists) {
1142
1232
  var attr1 = {};
1143
1233
  var props = {};
1144
1234
  var ids = [];
1235
+ var inc = 0;
1145
1236
  for (var attr of attrs) {
1146
1237
  var { name, value } = attr;
1147
1238
  if (/^\$/.test(name)) continue;
1148
1239
  if (name === 'elementid' || name === 'renderid' || name === 'id') {
1149
1240
  pushid(ids, value);
1241
+ inc++;
1150
1242
  continue;
1151
1243
  }
1152
1244
  if (/^#/.test(name)) {
1153
1245
  pushid(ids, name.slice(1));
1154
1246
  element.removeAttribute(name);
1247
+ inc++;
1155
1248
  continue;
1156
1249
  };
1157
1250
  if (/^\./.test(name) && !value) {
@@ -1165,11 +1258,12 @@ function createStructure(element, useExists) {
1165
1258
  }
1166
1259
  if (/^(?:class|style|src|\:|placeholder)$/i.test(name)) {
1167
1260
  copys.push(attr);
1261
+ inc++;
1168
1262
  continue;
1169
1263
  }
1170
1264
  var key = name.replace(/^(ng|v|.*?)\-/i, "").toLowerCase();
1171
1265
  if (structures.hasOwnProperty(key)) {
1172
- if (element.$renderid <= -2) {
1266
+ if (renderIds.get(element) <= -2) {
1173
1267
  if (/^if$|^else/i.test(key)) {
1174
1268
  if (types.if) {
1175
1269
  throw new Error(i18n`暂不支持在同一元素上使用多次if结构!`);
@@ -1186,9 +1280,10 @@ function createStructure(element, useExists) {
1186
1280
  else {
1187
1281
  types.repeat = attr;
1188
1282
  }
1189
- if (!element.$renderid) element.$renderid = -1;
1190
- else element.$renderid = -2;
1283
+ if (!renderIds.get(element)) renderIds.set(element, -1);
1284
+ else renderIds.set(element, -2);
1191
1285
  element.removeAttribute(name);
1286
+ inc++
1192
1287
  continue;
1193
1288
  }
1194
1289
  // ng-html,ng-src,ng-text,ng-model,ng-style,ng-class,...
@@ -1216,6 +1311,7 @@ function createStructure(element, useExists) {
1216
1311
  break;
1217
1312
  }
1218
1313
  }
1314
+ inc++;
1219
1315
  element.removeAttribute(name);
1220
1316
  }
1221
1317
  // ng-click on-click v-click @click @mousedown ...
@@ -1231,6 +1327,7 @@ function createStructure(element, useExists) {
1231
1327
  else {
1232
1328
  emits[key] = value;
1233
1329
  }
1330
+ inc++;
1234
1331
  }
1235
1332
  }
1236
1333
  // placeholder_ href_ checked_ ...
@@ -1261,6 +1358,7 @@ function createStructure(element, useExists) {
1261
1358
  }
1262
1359
  element.setAttribute(key.replace(/\./g, '-'), '');
1263
1360
  }
1361
+ inc++;
1264
1362
  element.removeAttribute(name);
1265
1363
  }
1266
1364
  // title alt name type placeholder href checked ...
@@ -1275,45 +1373,61 @@ function createStructure(element, useExists) {
1275
1373
  else {
1276
1374
  props[k] = element[k];
1277
1375
  }
1376
+ inc++;
1278
1377
  }
1279
1378
  }
1379
+ if (inc === 0) return;
1280
1380
  if (props["zimoli"] || props["fresh"] || props["once"]) once = true;
1281
1381
  else if (props["refresh"] || props["digest"] || props["mount"]) once = false;
1282
- element.$eval = $eval;
1283
- return element.$struct = new Struct(emits, waits, types, copys, binds, attr1, props, ids, once);
1382
+ var s = new Struct(emits, waits, types, copys, binds, attr1, props, ids, once);
1383
+ $structed.set(element, s);
1384
+ return s;
1284
1385
  }
1285
- function unlock(element) {
1286
- if (!element) return;
1287
- var { $renderid = 0 } = element;
1288
- if ($renderid !== 9) {
1289
- if ($renderid < 10) element.$renderid = ++renderidOffset;
1290
- on("append")(element, addRenderElement);
1291
- onremove(element, removeRenderElement);
1292
- if (element.nodeType === 8);
1293
- else if (eagermount) buildFirst(element);
1386
+ function unlock(renders) {
1387
+ if (!renders) return;
1388
+ if (!isOnce(renders)) {
1389
+ var node = renders.el;
1390
+ var rid = renderIds.get(node) || 0;
1391
+ if (rid < 10) {
1392
+ rid = ++renderidOffset;
1393
+ renders.id = rid;
1394
+ renderIds.set(node, rid);
1395
+ }
1396
+ on("append")(node, addRenderElement);
1397
+ onremove(node, removeRenderElement);
1294
1398
  }
1295
1399
  else {
1296
- buildFirst(element);
1400
+ buildFirst(node);
1297
1401
  }
1298
1402
  }
1403
+ var notNull = a => a;
1404
+ var isOnce = a => a.r1;
1405
+ var notComment = a => !isOnce(a) && a.el.nodeType !== 8;
1299
1406
  function renderUnlock(element) {
1300
- var locked = renderlock;
1407
+ var locked = renderlock.filter(notNull);
1301
1408
  renderlock = null;
1302
1409
  locked.forEach(unlock);
1410
+ var eagger = eagermount;
1303
1411
  eagermount = false;
1304
1412
  var parentNode = element.parentNode;
1305
1413
  if (parentNode && isMounted(parentNode)) appendChild.dispatch(element);
1414
+ else if (eagger) {
1415
+ locked.filter(notComment).forEach(buildFirst);
1416
+ }
1306
1417
  }
1307
1418
  function renderLock(element) {
1308
1419
  if (!renderlock) {
1309
1420
  renderlock = [];
1310
- element.$mounted = false;
1421
+ $mounted.set(element, false);
1311
1422
  return true;
1312
1423
  }
1313
1424
  return false;
1314
1425
  }
1315
1426
  var eagermount = false, renderlock = null;
1316
1427
  function render(element, scope, parentScopes, lazy = true) {
1428
+ // <!--
1429
+ if (isNode(element)) Object.defineProperties(element, $weaks);
1430
+ // -->
1317
1431
  var haslock = renderLock(element);
1318
1432
  var if_top_length = if_top.length;
1319
1433
  if (isFinite(scope) && arguments.length === 2) lazy = scope, scope = undefined;
@@ -1326,6 +1440,34 @@ function render(element, scope, parentScopes, lazy = true) {
1326
1440
  if (haslock) callDigest();
1327
1441
  return e;
1328
1442
  }
1443
+ // <!--
1444
+ var $weaks = (key, weak, tip = key + '(element)') => {
1445
+ var warn = gs => {
1446
+ if (tip) {
1447
+ console.warn(i18n`${`%c ${key} %c`}仅在开发环境存在,供开发者调试查看,${`%c${i18n`项目发布后将没有这个属性!`}%c`}`, 'color:red', 'color', 'color:cyan', 'color:');
1448
+ console.info(`要在代码中访问 ${"element." + key},可以用 ${tip + "." + gs + "(element)"} 代替!`);
1449
+ tip = null;
1450
+ }
1451
+ };
1452
+ return {
1453
+ configurable: true,
1454
+ enumerable: false,
1455
+ get() {
1456
+ warn("get");
1457
+ return weak.get(this);
1458
+ },
1459
+ set(v) {
1460
+ warn("set");
1461
+ return weak.set(this, v);
1462
+ }
1463
+ };
1464
+ };
1465
+ $weaks = {
1466
+ $scope: $weaks('$scope', $scoped, "$scoped"),
1467
+ $struct: $weaks('$struct', $structed, "$structed"),
1468
+ $parentScopes: $weaks('$parentScopes', $parented, "$parented"),
1469
+ };
1470
+ // -->
1329
1471
  var digest = lazy(refresh, -{});
1330
1472
  render.digest = render.apply = render.refresh = digest;
1331
1473
  render.parseRepeat = parseRepeat;
@@ -1354,19 +1496,41 @@ render.register = function (key, name) {
1354
1496
  }
1355
1497
  };
1356
1498
  render.getFromScopes = getFromScopes;
1499
+ render.findKey = function (express, element) {
1500
+ var scopes = getScopeList(element);
1501
+ return getFromScopes(express, null, scopes);
1502
+ };
1503
+ var $renderid = {
1504
+ get() {
1505
+ return renderIds.get(this);
1506
+ },
1507
+ set(v) {
1508
+ return renderIds.set(this, v);
1509
+ },
1510
+ configurable: true,
1511
+ enumerable: false
1512
+ };
1357
1513
  render.struct = createStructure;
1514
+ render.stepId = renderIds;
1358
1515
  render.mergeStruct = mergeStruct;
1359
1516
  render.Binder = Binder;
1360
1517
  render.Model = Model;
1361
1518
  render.attribute = function (target, attrs) {
1362
- return renderDynamics(target, target, null, attrs);
1519
+ return renderDynamics(target, target, null, attrs, $renders.get(target));
1363
1520
  };
1364
1521
  render.dynamic = function (target, binds, attrs) {
1365
- renderBinds(target, binds);
1366
- renderDynamics(target, target, binds, attrs);
1522
+ var renders = $renders.get(target);
1523
+ renderBinds(target, binds, renders);
1524
+ renderDynamics(target, target, binds, attrs, renders);
1367
1525
  };
1368
1526
  var initRenders = function (target) {
1369
- if (!target.$renders) target.$renders = [];
1527
+ var renders = $renders.get(target);
1528
+ if (!renders) {
1529
+ renders = [];
1530
+ renders.el = target;
1531
+ $renders.set(target, renders);
1532
+ }
1533
+ return renders;
1370
1534
  };
1371
1535
  render.class = function (target, map) {
1372
1536
  initRenders(target);
@@ -1382,4 +1546,14 @@ render.on = function (target, map) {
1382
1546
  render.once = function (target, map) {
1383
1547
  return renderEmits.call(this, target, map, emiters.once);
1384
1548
  };
1385
- render.mount = unlock;
1549
+ render.eval = $eval;
1550
+ render.mount = unlock;
1551
+ render.getScopes = getScopeList;
1552
+ render.clone = function (template, id = renderIds.get(template)) {
1553
+ var clone = template.cloneNode(true);
1554
+ $structed.set(clone, $structed.get(template));
1555
+ renderIds.set(clone, id);
1556
+ $scoped.set(clone, $scoped.get(template));
1557
+ $parented.set(clone, $parented.get(template));
1558
+ return clone;
1559
+ }