native-document 1.0.86 → 1.0.88

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.
@@ -256,16 +256,16 @@ var NativeComponents = (function (exports) {
256
256
  return this.$build();
257
257
  };
258
258
 
259
- let DebugManager = {};
259
+ let DebugManager$1 = {};
260
260
  {
261
- DebugManager = {
261
+ DebugManager$1 = {
262
262
  log() {},
263
263
  warn() {},
264
264
  error() {},
265
265
  disable() {}
266
266
  };
267
267
  }
268
- var DebugManager$1 = DebugManager;
268
+ var DebugManager = DebugManager$1;
269
269
 
270
270
  const MemoryManager = (function() {
271
271
 
@@ -314,7 +314,7 @@ var NativeComponents = (function (exports) {
314
314
  }
315
315
  }
316
316
  if (cleanedCount > 0) {
317
- DebugManager$1.log('Memory Auto Clean', `🧹 Cleaned ${cleanedCount} orphaned observables`);
317
+ DebugManager.log('Memory Auto Clean', `🧹 Cleaned ${cleanedCount} orphaned observables`);
318
318
  }
319
319
  }
320
320
  };
@@ -662,7 +662,7 @@ var NativeComponents = (function (exports) {
662
662
  ObservableItem.prototype.subscribe = function(callback, target = null) {
663
663
  this.$listeners = this.$listeners ?? [];
664
664
  if (this.$isCleanedUp) {
665
- DebugManager$1.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
665
+ DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
666
666
  return () => {};
667
667
  }
668
668
  if (typeof callback !== 'function') {
@@ -1035,17 +1035,17 @@ var NativeComponents = (function (exports) {
1035
1035
  const method = methods[name];
1036
1036
 
1037
1037
  if (typeof method !== 'function') {
1038
- DebugManager$1.warn('NDElement.extend', `"${name}" is not a function, skipping`);
1038
+ DebugManager.warn('NDElement.extend', `"${name}" is not a function, skipping`);
1039
1039
  continue;
1040
1040
  }
1041
1041
 
1042
1042
  if (protectedMethods.has(name)) {
1043
- DebugManager$1.error('NDElement.extend', `Cannot override protected method "${name}"`);
1043
+ DebugManager.error('NDElement.extend', `Cannot override protected method "${name}"`);
1044
1044
  throw new NativeDocumentError(`Cannot override protected method "${name}"`);
1045
1045
  }
1046
1046
 
1047
1047
  if (NDElement.prototype[name]) {
1048
- DebugManager$1.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
1048
+ DebugManager.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
1049
1049
  }
1050
1050
 
1051
1051
  NDElement.prototype[name] = method;
@@ -1227,7 +1227,7 @@ var NativeComponents = (function (exports) {
1227
1227
  anchorFragment.appendChild = function(child, before = null) {
1228
1228
  const parent = anchorEnd.parentNode;
1229
1229
  if(!parent) {
1230
- DebugManager$1.error('Anchor', 'Anchor : parent not found', child);
1230
+ DebugManager.error('Anchor', 'Anchor : parent not found', child);
1231
1231
  return;
1232
1232
  }
1233
1233
  before = before ?? anchorEnd;
@@ -1440,26 +1440,6 @@ var NativeComponents = (function (exports) {
1440
1440
  element.classes.toggle(className, shouldAdd);
1441
1441
  }
1442
1442
 
1443
- function toggleElementStyle(element, styleName, newValue) {
1444
- element.style[styleName] = newValue;
1445
- }
1446
-
1447
- function updateInputFromObserver(element, attributeName, newValue) {
1448
- if(Validator.isBoolean(newValue)) {
1449
- element[attributeName] = newValue;
1450
- return;
1451
- }
1452
- element[attributeName] = newValue === element.value;
1453
- }
1454
-
1455
- function updateObserverFromInput(element, attributeName, defaultValue, value) {
1456
- if(Validator.isBoolean(defaultValue)) {
1457
- value.set(element[attributeName]);
1458
- return;
1459
- }
1460
- value.set(element.value);
1461
- }
1462
-
1463
1443
  /**
1464
1444
  *
1465
1445
  * @param {HTMLElement} element
@@ -1468,12 +1448,12 @@ var NativeComponents = (function (exports) {
1468
1448
  function bindClassAttribute(element, data) {
1469
1449
  for(let className in data) {
1470
1450
  const value = data[className];
1471
- if(Validator.isObservable(value)) {
1451
+ if(value.__$isObservable) {
1472
1452
  element.classes.toggle(className, value.val());
1473
1453
  value.subscribe(toggleElementClass.bind(null, element, className));
1474
1454
  continue;
1475
1455
  }
1476
- if(Validator.isObservableWhenResult(value)) {
1456
+ if(value.__$isObservableWhen) {
1477
1457
  element.classes.toggle(className, value.isMath());
1478
1458
  value.subscribe(toggleElementClass.bind(null, element, className));
1479
1459
  continue;
@@ -1495,9 +1475,9 @@ var NativeComponents = (function (exports) {
1495
1475
  function bindStyleAttribute(element, data) {
1496
1476
  for(let styleName in data) {
1497
1477
  const value = data[styleName];
1498
- if(Validator.isObservable(value)) {
1478
+ if(value.__$isObservable) {
1499
1479
  element.style[styleName] = value.val();
1500
- value.subscribe(toggleElementStyle.bind(null, element, styleName));
1480
+ value.subscribe((newValue) => element.style[styleName] = newValue);
1501
1481
  continue;
1502
1482
  }
1503
1483
  element.style[styleName] = value;
@@ -1511,18 +1491,26 @@ var NativeComponents = (function (exports) {
1511
1491
  * @param {boolean|number|Observable} value
1512
1492
  */
1513
1493
  function bindBooleanAttribute(element, attributeName, value) {
1514
- const defaultValue = Validator.isObservable(value) ? value.val() : value;
1494
+ const isObservable = value.__$isObservable;
1495
+ const defaultValue = isObservable? value.val() : value;
1515
1496
  if(Validator.isBoolean(defaultValue)) {
1516
1497
  element[attributeName] = defaultValue;
1517
1498
  }
1518
1499
  else {
1519
1500
  element[attributeName] = defaultValue === element.value;
1520
1501
  }
1521
- if(Validator.isObservable(value)) {
1522
- if(['checked'].includes(attributeName)) {
1523
- element.addEventListener('input', updateObserverFromInput.bind(null, element, attributeName, defaultValue, value));
1502
+ if(isObservable) {
1503
+ if(attributeName === 'checked') {
1504
+ if(typeof defaultValue === 'boolean') {
1505
+ element.addEventListener('input', () => value.set(element[attributeName]));
1506
+ }
1507
+ else {
1508
+ element.addEventListener('input', () => value.set(element.value));
1509
+ }
1510
+ value.subscribe((newValue) => element[attributeName] = newValue);
1511
+ return;
1524
1512
  }
1525
- value.subscribe(updateInputFromObserver.bind(null, element, attributeName));
1513
+ value.subscribe((newValue) => element[attributeName] = (newValue === element.value));
1526
1514
  }
1527
1515
  }
1528
1516
 
@@ -1534,19 +1522,15 @@ var NativeComponents = (function (exports) {
1534
1522
  * @param {Observable} value
1535
1523
  */
1536
1524
  function bindAttributeWithObservable(element, attributeName, value) {
1537
- const applyValue = (newValue) => {
1538
- if(attributeName === 'value') {
1539
- element.value = newValue;
1540
- return;
1541
- }
1542
- element.setAttribute(attributeName, newValue);
1543
- };
1544
- applyValue(value.val());
1525
+ const applyValue = attributeName === 'value' ? (newValue) => element.value = newValue : (newValue) => element.setAttribute(attributeName, newValue);
1545
1526
  value.subscribe(applyValue);
1546
1527
 
1547
1528
  if(attributeName === 'value') {
1529
+ element.value = value.val();
1548
1530
  element.addEventListener('input', () => value.set(element.value));
1531
+ return;
1549
1532
  }
1533
+ element.setAttribute(attributeName, value.val());
1550
1534
  }
1551
1535
 
1552
1536
  /**
@@ -1556,10 +1540,6 @@ var NativeComponents = (function (exports) {
1556
1540
  */
1557
1541
  function AttributesWrapper(element, attributes) {
1558
1542
 
1559
- if(!Validator.isObject(attributes)) {
1560
- throw new NativeDocumentError('Attributes must be an object');
1561
- }
1562
-
1563
1543
  for(let key in attributes) {
1564
1544
  const attributeName = key.toLowerCase();
1565
1545
  let value = attributes[attributeName];
@@ -1714,6 +1694,14 @@ var NativeComponents = (function (exports) {
1714
1694
  }
1715
1695
  return Anchor('Fragment');
1716
1696
  },
1697
+ bindTextNode(textNode, value) {
1698
+ if(value?.__$isObservable) {
1699
+ value.subscribe(newValue => textNode.nodeValue = newValue);
1700
+ textNode.nodeValue = value.val();
1701
+ return;
1702
+ }
1703
+ textNode.nodeValue = value;
1704
+ },
1717
1705
  /**
1718
1706
  *
1719
1707
  * @param {*} children
@@ -141,10 +141,10 @@ var NativeDocument = (function (exports) {
141
141
  return this.observable.cleanup();
142
142
  };
143
143
 
144
- let PluginsManager = null;
144
+ let PluginsManager$1 = null;
145
145
 
146
146
  {
147
- PluginsManager = (function() {
147
+ PluginsManager$1 = (function() {
148
148
 
149
149
  const $plugins = new Map();
150
150
  const $pluginByEvents = new Map();
@@ -219,7 +219,7 @@ var NativeDocument = (function (exports) {
219
219
  }());
220
220
  }
221
221
 
222
- var PluginsManager$1 = PluginsManager;
222
+ var PluginsManager = PluginsManager$1;
223
223
 
224
224
  const ObservableWhen = function(observer, value) {
225
225
  this.$target = value;
@@ -341,7 +341,7 @@ var NativeDocument = (function (exports) {
341
341
  }
342
342
  }
343
343
  {
344
- PluginsManager$1.emit('CreateObservable', this);
344
+ PluginsManager.emit('CreateObservable', this);
345
345
  }
346
346
  }
347
347
 
@@ -468,12 +468,12 @@ var NativeDocument = (function (exports) {
468
468
  this.$previousValue = this.$currentValue;
469
469
  this.$currentValue = newValue;
470
470
  {
471
- PluginsManager$1.emit('ObservableBeforeChange', this);
471
+ PluginsManager.emit('ObservableBeforeChange', this);
472
472
  }
473
473
  this.trigger();
474
474
  this.$previousValue = null;
475
475
  {
476
- PluginsManager$1.emit('ObservableAfterChange', this);
476
+ PluginsManager.emit('ObservableAfterChange', this);
477
477
  }
478
478
  };
479
479
 
@@ -535,13 +535,13 @@ var NativeDocument = (function (exports) {
535
535
  this.$listeners.push(callback);
536
536
  this.assocTrigger();
537
537
  {
538
- PluginsManager$1.emit('ObservableSubscribe', this, target);
538
+ PluginsManager.emit('ObservableSubscribe', this, target);
539
539
  }
540
540
  return () => {
541
541
  this.unsubscribe(callback);
542
542
  this.assocTrigger();
543
543
  {
544
- PluginsManager$1.emit('ObservableUnsubscribe', this);
544
+ PluginsManager.emit('ObservableUnsubscribe', this);
545
545
  }
546
546
  };
547
547
  };
@@ -763,7 +763,7 @@ var NativeDocument = (function (exports) {
763
763
  this.$element = element;
764
764
  this.$observer = null;
765
765
  {
766
- PluginsManager$1.emit('NDElementCreated', element, this);
766
+ PluginsManager.emit('NDElementCreated', element, this);
767
767
  }
768
768
  }
769
769
 
@@ -934,7 +934,7 @@ var NativeDocument = (function (exports) {
934
934
  NDElement.prototype[name] = method;
935
935
  }
936
936
  {
937
- PluginsManager$1.emit('NDElementExtended', methods);
937
+ PluginsManager.emit('NDElementExtended', methods);
938
938
  }
939
939
 
940
940
  return NDElement;
@@ -1079,7 +1079,6 @@ var NativeDocument = (function (exports) {
1079
1079
  };
1080
1080
  {
1081
1081
  Validator.validateAttributes = function(attributes) {
1082
- console.log('AttributesWrapper', attributes);
1083
1082
  if (!attributes || typeof attributes !== 'object') {
1084
1083
  return attributes;
1085
1084
  }
@@ -1368,26 +1367,6 @@ var NativeDocument = (function (exports) {
1368
1367
  element.classes.toggle(className, shouldAdd);
1369
1368
  }
1370
1369
 
1371
- function toggleElementStyle(element, styleName, newValue) {
1372
- element.style[styleName] = newValue;
1373
- }
1374
-
1375
- function updateInputFromObserver(element, attributeName, newValue) {
1376
- if(Validator.isBoolean(newValue)) {
1377
- element[attributeName] = newValue;
1378
- return;
1379
- }
1380
- element[attributeName] = newValue === element.value;
1381
- }
1382
-
1383
- function updateObserverFromInput(element, attributeName, defaultValue, value) {
1384
- if(Validator.isBoolean(defaultValue)) {
1385
- value.set(element[attributeName]);
1386
- return;
1387
- }
1388
- value.set(element.value);
1389
- }
1390
-
1391
1370
  /**
1392
1371
  *
1393
1372
  * @param {HTMLElement} element
@@ -1396,12 +1375,12 @@ var NativeDocument = (function (exports) {
1396
1375
  function bindClassAttribute(element, data) {
1397
1376
  for(let className in data) {
1398
1377
  const value = data[className];
1399
- if(Validator.isObservable(value)) {
1378
+ if(value.__$isObservable) {
1400
1379
  element.classes.toggle(className, value.val());
1401
1380
  value.subscribe(toggleElementClass.bind(null, element, className));
1402
1381
  continue;
1403
1382
  }
1404
- if(Validator.isObservableWhenResult(value)) {
1383
+ if(value.__$isObservableWhen) {
1405
1384
  element.classes.toggle(className, value.isMath());
1406
1385
  value.subscribe(toggleElementClass.bind(null, element, className));
1407
1386
  continue;
@@ -1423,9 +1402,9 @@ var NativeDocument = (function (exports) {
1423
1402
  function bindStyleAttribute(element, data) {
1424
1403
  for(let styleName in data) {
1425
1404
  const value = data[styleName];
1426
- if(Validator.isObservable(value)) {
1405
+ if(value.__$isObservable) {
1427
1406
  element.style[styleName] = value.val();
1428
- value.subscribe(toggleElementStyle.bind(null, element, styleName));
1407
+ value.subscribe((newValue) => element.style[styleName] = newValue);
1429
1408
  continue;
1430
1409
  }
1431
1410
  element.style[styleName] = value;
@@ -1439,18 +1418,26 @@ var NativeDocument = (function (exports) {
1439
1418
  * @param {boolean|number|Observable} value
1440
1419
  */
1441
1420
  function bindBooleanAttribute(element, attributeName, value) {
1442
- const defaultValue = Validator.isObservable(value) ? value.val() : value;
1421
+ const isObservable = value.__$isObservable;
1422
+ const defaultValue = isObservable? value.val() : value;
1443
1423
  if(Validator.isBoolean(defaultValue)) {
1444
1424
  element[attributeName] = defaultValue;
1445
1425
  }
1446
1426
  else {
1447
1427
  element[attributeName] = defaultValue === element.value;
1448
1428
  }
1449
- if(Validator.isObservable(value)) {
1450
- if(['checked'].includes(attributeName)) {
1451
- element.addEventListener('input', updateObserverFromInput.bind(null, element, attributeName, defaultValue, value));
1429
+ if(isObservable) {
1430
+ if(attributeName === 'checked') {
1431
+ if(typeof defaultValue === 'boolean') {
1432
+ element.addEventListener('input', () => value.set(element[attributeName]));
1433
+ }
1434
+ else {
1435
+ element.addEventListener('input', () => value.set(element.value));
1436
+ }
1437
+ value.subscribe((newValue) => element[attributeName] = newValue);
1438
+ return;
1452
1439
  }
1453
- value.subscribe(updateInputFromObserver.bind(null, element, attributeName));
1440
+ value.subscribe((newValue) => element[attributeName] = (newValue === element.value));
1454
1441
  }
1455
1442
  }
1456
1443
 
@@ -1462,19 +1449,15 @@ var NativeDocument = (function (exports) {
1462
1449
  * @param {Observable} value
1463
1450
  */
1464
1451
  function bindAttributeWithObservable(element, attributeName, value) {
1465
- const applyValue = (newValue) => {
1466
- if(attributeName === 'value') {
1467
- element.value = newValue;
1468
- return;
1469
- }
1470
- element.setAttribute(attributeName, newValue);
1471
- };
1472
- applyValue(value.val());
1452
+ const applyValue = attributeName === 'value' ? (newValue) => element.value = newValue : (newValue) => element.setAttribute(attributeName, newValue);
1473
1453
  value.subscribe(applyValue);
1474
1454
 
1475
1455
  if(attributeName === 'value') {
1456
+ element.value = value.val();
1476
1457
  element.addEventListener('input', () => value.set(element.value));
1458
+ return;
1477
1459
  }
1460
+ element.setAttribute(attributeName, value.val());
1478
1461
  }
1479
1462
 
1480
1463
  /**
@@ -1486,10 +1469,6 @@ var NativeDocument = (function (exports) {
1486
1469
 
1487
1470
  Validator.validateAttributes(attributes);
1488
1471
 
1489
- if(!Validator.isObject(attributes)) {
1490
- throw new NativeDocumentError('Attributes must be an object');
1491
- }
1492
-
1493
1472
  for(let key in attributes) {
1494
1473
  const attributeName = key.toLowerCase();
1495
1474
  let value = attributes[attributeName];
@@ -1565,7 +1544,7 @@ var NativeDocument = (function (exports) {
1565
1544
  Function.prototype.toNdElement = function () {
1566
1545
  const child = this;
1567
1546
  {
1568
- PluginsManager$1.emit('BeforeProcessComponent', child);
1547
+ PluginsManager.emit('BeforeProcessComponent', child);
1569
1548
  }
1570
1549
  return ElementCreator.getChild(child());
1571
1550
  };
@@ -1655,6 +1634,14 @@ var NativeDocument = (function (exports) {
1655
1634
  }
1656
1635
  return Anchor('Fragment');
1657
1636
  },
1637
+ bindTextNode(textNode, value) {
1638
+ if(value?.__$isObservable) {
1639
+ value.subscribe(newValue => textNode.nodeValue = newValue);
1640
+ textNode.nodeValue = value.val();
1641
+ return;
1642
+ }
1643
+ textNode.nodeValue = value;
1644
+ },
1658
1645
  /**
1659
1646
  *
1660
1647
  * @param {*} children
@@ -1663,14 +1650,14 @@ var NativeDocument = (function (exports) {
1663
1650
  processChildren(children, parent) {
1664
1651
  if(children === null) return;
1665
1652
  {
1666
- PluginsManager$1.emit('BeforeProcessChildren', parent);
1653
+ PluginsManager.emit('BeforeProcessChildren', parent);
1667
1654
  }
1668
1655
  let child = this.getChild(children);
1669
1656
  if(child) {
1670
1657
  parent.appendChild(child);
1671
1658
  }
1672
1659
  {
1673
- PluginsManager$1.emit('AfterProcessChildren', parent);
1660
+ PluginsManager.emit('AfterProcessChildren', parent);
1674
1661
  }
1675
1662
  },
1676
1663
  getChild(child) {
@@ -2190,9 +2177,8 @@ var NativeDocument = (function (exports) {
2190
2177
 
2191
2178
 
2192
2179
  const applyBindingTreePath = (root, target, data, path) => {
2193
- let newTarget = null;
2194
2180
  if(path.fn) {
2195
- newTarget = path.fn(data, target, root);
2181
+ path.fn(data, target, root);
2196
2182
  }
2197
2183
  if(path.children) {
2198
2184
  for(let i = 0, length = path.children.length; i < length; i++) {
@@ -2201,7 +2187,6 @@ var NativeDocument = (function (exports) {
2201
2187
  applyBindingTreePath(root, pathTargetNode, data, currentPath);
2202
2188
  }
2203
2189
  }
2204
- return newTarget;
2205
2190
  };
2206
2191
 
2207
2192
  function TemplateCloner($fn) {
@@ -2217,15 +2202,10 @@ var NativeDocument = (function (exports) {
2217
2202
  const bindDingData = cloneBindingsDataCache.get(node);
2218
2203
  if(node.nodeType === 3) {
2219
2204
  if(bindDingData && bindDingData.value) {
2220
- currentPath.fn = (data, targetNode, currentRoot) => {
2221
- const newNode = bindDingData.value(data);
2222
- if (targetNode === currentRoot) {
2223
- return newNode;
2224
- }
2225
- targetNode.replaceWith(newNode);
2226
- return null;
2227
- };
2228
- return bindDingData.value(data);
2205
+ currentPath.fn = bindDingData.value;
2206
+ const textNode = node.cloneNode();
2207
+ bindDingData.value(data, textNode);
2208
+ return textNode;
2229
2209
  }
2230
2210
  return node.cloneNode(true);
2231
2211
  }
@@ -2262,11 +2242,7 @@ var NativeDocument = (function (exports) {
2262
2242
  const cloneWithBindingPaths = (data) => {
2263
2243
  let root = $node.cloneNode(true);
2264
2244
 
2265
- const newRoot = applyBindingTreePath(root, root, data, $bindingTreePath);
2266
- if(newRoot) {
2267
- root = newRoot;
2268
- }
2269
-
2245
+ applyBindingTreePath(root, root, data, $bindingTreePath);
2270
2246
  return root;
2271
2247
  };
2272
2248
 
@@ -2301,13 +2277,13 @@ var NativeDocument = (function (exports) {
2301
2277
  };
2302
2278
  this.value = (callbackOrProperty) => {
2303
2279
  if(typeof callbackOrProperty !== 'function') {
2304
- return createBinding(function(data) {
2280
+ return createBinding(function(data, textNode) {
2305
2281
  const firstArgument = data[0];
2306
- return createTextNode(firstArgument[callbackOrProperty]);
2282
+ ElementCreator.bindTextNode(textNode, firstArgument[callbackOrProperty]);
2307
2283
  }, 'value');
2308
2284
  }
2309
- return createBinding(function(data) {
2310
- return createTextNode(callbackOrProperty(...data));
2285
+ return createBinding(function(data, textNode) {
2286
+ ElementCreator.bindTextNode(textNode, callbackOrProperty(...data));
2311
2287
  }, 'value');
2312
2288
  };
2313
2289
  this.attr = (fn) => {
@@ -2906,7 +2882,7 @@ var NativeDocument = (function (exports) {
2906
2882
 
2907
2883
  ObservableItem.call(this, target, configs);
2908
2884
  {
2909
- PluginsManager$1.emit('CreateObservableArray', this);
2885
+ PluginsManager.emit('CreateObservableArray', this);
2910
2886
  }
2911
2887
  };
2912
2888
 
@@ -3307,7 +3283,7 @@ var NativeDocument = (function (exports) {
3307
3283
  const observable = new ObservableItem(initialValue);
3308
3284
  const updatedValue = nextTick(() => observable.set(callback()));
3309
3285
  {
3310
- PluginsManager$1.emit('CreateObservableComputed', observable, dependencies);
3286
+ PluginsManager.emit('CreateObservableComputed', observable, dependencies);
3311
3287
  }
3312
3288
 
3313
3289
  if(Validator.isFunction(dependencies)) {
@@ -4728,22 +4704,84 @@ var NativeDocument = (function (exports) {
4728
4704
  function RouterComponent(router, container) {
4729
4705
 
4730
4706
  const $cache = new Map();
4707
+ const $layoutCache = new WeakMap();
4708
+ const $routeInstanceAnchors = new WeakMap();
4709
+ let $currentLayout = null;
4710
+
4731
4711
  let $lastNodeInserted = null;
4732
4712
 
4733
- const updateContainer = function(node, route) {
4734
- container.innerHTML = '';
4713
+ const getNodeAnchorForLayout = (node, path) => {
4714
+ const existingAnchor = $routeInstanceAnchors.get(node);
4715
+ if(existingAnchor) {
4716
+ return existingAnchor;
4717
+ }
4718
+
4719
+ let anchor = node;
4720
+ if(!Validator.isAnchor(node)) {
4721
+ anchor = Anchor(path);
4722
+ anchor.appendChild(node);
4723
+ }
4724
+ $routeInstanceAnchors.set(node, anchor);
4725
+ return anchor;
4726
+ };
4727
+
4728
+ const removeLastNodeInserted = () => {
4729
+ if(Validator.isAnchor($lastNodeInserted)) {
4730
+ $lastNodeInserted.remove();
4731
+ }
4732
+ };
4733
+ const cleanContainer = () => {
4734
+ container.nodeValue = '';
4735
+ removeLastNodeInserted();
4736
+
4737
+ if($currentLayout) {
4738
+ $currentLayout.remove();
4739
+ }
4740
+ };
4741
+
4742
+ const getNodeToInsert = (node) => {
4735
4743
  let nodeToInsert = node;
4736
- const layout = route.layout();
4737
4744
  if(Validator.isNDElement(node)) {
4738
4745
  nodeToInsert = node.node();
4739
4746
  }
4740
- if(layout) {
4741
- container.appendChild(layout(nodeToInsert));
4747
+ return nodeToInsert;
4748
+ };
4749
+
4750
+ const updateContainerByLayout = (layout, node, route, path) => {
4751
+ let nodeToInsert = getNodeToInsert(node);
4752
+
4753
+ const cachedLayout = $layoutCache.get(nodeToInsert);
4754
+ if(cachedLayout) {
4755
+ if(cachedLayout === $currentLayout) {
4756
+ const layoutAnchor = getNodeAnchorForLayout(nodeToInsert, path);
4757
+ removeLastNodeInserted();
4758
+ layoutAnchor.replaceContent(nodeToInsert);
4759
+ return;
4760
+ }
4761
+ cleanContainer();
4762
+ $currentLayout = cachedLayout;
4763
+ const layoutAnchor = getNodeAnchorForLayout(nodeToInsert, path);
4764
+ layoutAnchor.replaceContent(nodeToInsert);
4765
+ container.appendChild($currentLayout);
4742
4766
  return;
4743
4767
  }
4744
- if(Validator.isAnchor($lastNodeInserted)) {
4745
- $lastNodeInserted.remove();
4768
+ cleanContainer();
4769
+ const anchor = getNodeAnchorForLayout(nodeToInsert, path);
4770
+
4771
+ $currentLayout = layout(anchor);
4772
+ $layoutCache.set(nodeToInsert, $currentLayout);
4773
+ container.appendChild($currentLayout);
4774
+ };
4775
+
4776
+ const updateContainer = function(node, route, path) {
4777
+ const layout = route.layout();
4778
+ if(layout) {
4779
+ updateContainerByLayout(layout, node, route, path);
4780
+ return;
4746
4781
  }
4782
+ let nodeToInsert = getNodeToInsert(node);
4783
+
4784
+ cleanContainer();
4747
4785
  container.appendChild(nodeToInsert);
4748
4786
  $lastNodeInserted = node;
4749
4787
  };
@@ -4761,7 +4799,7 @@ var NativeDocument = (function (exports) {
4761
4799
  const Component = route.component();
4762
4800
  const node = Component({ params, query });
4763
4801
  $cache.set(path, node);
4764
- updateContainer(node, route);
4802
+ updateContainer(node, route, path);
4765
4803
  };
4766
4804
 
4767
4805
  router.subscribe(handleCurrentRouterState);
@@ -5146,7 +5184,7 @@ var NativeDocument = (function (exports) {
5146
5184
  exports.HtmlElementWrapper = HtmlElementWrapper;
5147
5185
  exports.NDElement = NDElement;
5148
5186
  exports.Observable = Observable;
5149
- exports.PluginsManager = PluginsManager$1;
5187
+ exports.PluginsManager = PluginsManager;
5150
5188
  exports.SingletonView = SingletonView;
5151
5189
  exports.Store = Store;
5152
5190
  exports.TemplateCloner = TemplateCloner;