native-document 1.0.32 → 1.0.34

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.
@@ -264,14 +264,29 @@ var NativeDocument = (function (exports) {
264
264
  const $currentValue = this.$currentValue;
265
265
 
266
266
  if($watchers.has($currentValue)) {
267
- $watchers.get($currentValue).forEach(callback => {
268
- callback.set ? callback.set(true) : callback(true);
269
- });
267
+ const $currentValueCallbacks = $watchers.get($currentValue);
268
+ if(typeof $currentValueCallbacks === "function") {
269
+ $currentValueCallbacks(true);
270
+ } else if ($currentValueCallbacks.set) {
271
+ $currentValueCallbacks.set(true);
272
+ }
273
+ else {
274
+ $currentValueCallbacks.forEach(callback => {
275
+ callback.set ? callback.set(true) : callback(true);
276
+ });
277
+ }
270
278
  }
271
279
  if($watchers.has($previousValue)) {
272
- $watchers.get($previousValue).forEach(callback => {
273
- callback.set ? callback.set(false) : callback(false);
274
- });
280
+ const $previousValueCallbacks = $watchers.get($previousValue);
281
+ if(typeof $previousValueCallbacks === "function") {
282
+ $previousValueCallbacks(false);
283
+ } else if($previousValueCallbacks.set) {
284
+ $previousValueCallbacks.set(false);
285
+ } else {
286
+ $previousValueCallbacks.forEach(callback => {
287
+ callback.set ? callback.set(false) : callback(false);
288
+ });
289
+ }
275
290
  }
276
291
  };
277
292
 
@@ -323,7 +338,9 @@ var NativeDocument = (function (exports) {
323
338
  this.$currentValue = null;
324
339
  if(this.$watchers) {
325
340
  for (const [_, watchValueList] of this.$watchers) {
326
- watchValueList.splice(0);
341
+ if(Validator.isArray(watchValueList)) {
342
+ watchValueList.splice(0);
343
+ }
327
344
  }
328
345
  }
329
346
  this.$watchers?.clear();
@@ -369,17 +386,25 @@ var NativeDocument = (function (exports) {
369
386
  this.$watchers = this.$watchers ?? new Map();
370
387
 
371
388
  let watchValueList = this.$watchers.get(value);
389
+
372
390
  if(!watchValueList) {
373
- watchValueList = [];
391
+ this.$watchers.set(value, callback);
392
+ } else if(!Validator.isArray(watchValueList)) {
393
+ watchValueList = [watchValueList];
374
394
  this.$watchers.set(value, watchValueList);
395
+ return;
396
+ } else {
397
+ watchValueList.push(callback);
375
398
  }
376
399
 
377
- watchValueList.push(callback);
378
400
  this.assocTrigger();
379
401
  return () => {
380
402
  const index = watchValueList.indexOf(callback);
381
403
  watchValueList?.splice(index, 1);
382
- if(watchValueList.size === 0) {
404
+ if(watchValueList.size === 1) {
405
+ this.$watchers.set(value, watchValueList[0]);
406
+ }
407
+ else if(watchValueList.size === 0) {
383
408
  this.$watchers?.delete(value);
384
409
  watchValueList = null;
385
410
  }
@@ -692,6 +717,11 @@ var NativeDocument = (function (exports) {
692
717
 
693
718
  NDElement.prototype.node = NDElement.prototype.htmlElement;
694
719
 
720
+ NDElement.prototype.attach = function(methodName, bindingHydrator) {
721
+ bindingHydrator.$hydrate(this.$element, methodName);
722
+ return this.$element;
723
+ };
724
+
695
725
  const Validator = {
696
726
  isObservable(value) {
697
727
  return value instanceof ObservableItem || value instanceof ObservableChecker || value?.__$isObservable;
@@ -1003,6 +1033,10 @@ var NativeDocument = (function (exports) {
1003
1033
  });
1004
1034
  continue;
1005
1035
  }
1036
+ if(value.$hydrate) {
1037
+ value.$hydrate(element, className);
1038
+ continue;
1039
+ }
1006
1040
  element.classList.toggle(className, value);
1007
1041
  }
1008
1042
  }
@@ -1155,6 +1189,17 @@ var NativeDocument = (function (exports) {
1155
1189
  parent && parent.appendChild(text);
1156
1190
  return text;
1157
1191
  },
1192
+ /**
1193
+ *
1194
+ * @param {HTMLElement|DocumentFragment} parent
1195
+ * @param {{$hydrate: Function}} item
1196
+ * @returns {Text}
1197
+ */
1198
+ createHydratableNode(parent, item) {
1199
+ const text = ElementCreator.createTextNode();
1200
+ item.$hydrate(text);
1201
+ return text;
1202
+ },
1158
1203
 
1159
1204
  /**
1160
1205
  *
@@ -1233,6 +1278,9 @@ var NativeDocument = (function (exports) {
1233
1278
  PluginsManager.emit('BeforeProcessComponent', child);
1234
1279
  return this.getChild(child());
1235
1280
  }
1281
+ if(child?.$hydrate) {
1282
+ return ElementCreator.createHydratableNode(null, child);
1283
+ }
1236
1284
  return ElementCreator.createStaticTextNode(null, child);
1237
1285
  },
1238
1286
  /**
@@ -1384,7 +1432,7 @@ var NativeDocument = (function (exports) {
1384
1432
  }
1385
1433
 
1386
1434
  const normalizeComponentArgs = function(props, children = null) {
1387
- if(!Validator.isJson(props)) {
1435
+ if(!Validator.isJson(props) || props?.$hydrate) {
1388
1436
  const temp = children;
1389
1437
  children = props;
1390
1438
  props = temp;
@@ -1392,6 +1440,18 @@ var NativeDocument = (function (exports) {
1392
1440
  return { props, children };
1393
1441
  };
1394
1442
 
1443
+ /**
1444
+ *
1445
+ * @param {*} value
1446
+ * @returns {Text}
1447
+ */
1448
+ const createTextNode = function(value) {
1449
+ return (Validator.isObservable(value))
1450
+ ? ElementCreator.createObservableNode(null, value)
1451
+ : ElementCreator.createStaticTextNode(null, value);
1452
+ };
1453
+
1454
+
1395
1455
  function createHtmlElement($tagName, _attributes, _children = null, customWrapper) {
1396
1456
  const { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
1397
1457
  const element = ElementCreator.createElement($tagName);
@@ -1413,6 +1473,133 @@ var NativeDocument = (function (exports) {
1413
1473
  return (_attributes, _children = null) => createHtmlElement(name.toLowerCase(), _attributes, _children, customWrapper);
1414
1474
  }
1415
1475
 
1476
+ const cloneBindingsDataCache = new WeakMap();
1477
+
1478
+
1479
+ const bindAttributes = (node, bindDingData, data) => {
1480
+ if(!bindDingData) {
1481
+ return null;
1482
+ }
1483
+ const attributes = { };
1484
+ if(bindDingData.attributes) {
1485
+ for (const attr in bindDingData.attributes) {
1486
+ attributes[attr] = bindDingData.attributes[attr](...data);
1487
+ }
1488
+ }
1489
+
1490
+ if(bindDingData.classes) {
1491
+ attributes.class = {};
1492
+ for (const className in bindDingData.classes) {
1493
+ attributes.class[className] = bindDingData.classes[className](...data);
1494
+ }
1495
+ }
1496
+
1497
+ if(bindDingData.styles) {
1498
+ attributes.style = {};
1499
+ for (const property in bindDingData.styles) {
1500
+ attributes.style[property] = bindDingData.styles[property](...data);
1501
+ }
1502
+ }
1503
+
1504
+ if(Object.keys(attributes)) {
1505
+ ElementCreator.processAttributes(node, attributes);
1506
+ return attributes;
1507
+ }
1508
+
1509
+ return null;
1510
+ };
1511
+
1512
+
1513
+ const bindAttachesMethods = function(node, bindDingData, data) {
1514
+ if(!bindDingData?.attaches) {
1515
+ return null;
1516
+ }
1517
+ for(const methodName in bindDingData.attaches) {
1518
+ node.nd[methodName](function(...args) {
1519
+ bindDingData.attaches[methodName].call(this, ...[...args, ...data]);
1520
+ });
1521
+ }
1522
+ };
1523
+
1524
+ function TemplateCloner($fn) {
1525
+ let $node = null;
1526
+
1527
+ const clone = (node, data) => {
1528
+ const bindDingData = cloneBindingsDataCache.get(node);
1529
+ if(node instanceof Text) {
1530
+ if(bindDingData?.value) {
1531
+ return bindDingData.value(data);
1532
+ }
1533
+ return node.cloneNode(true);
1534
+ }
1535
+ const nodeCloned = node.cloneNode();
1536
+ bindAttributes(nodeCloned, bindDingData, data);
1537
+ bindAttachesMethods(nodeCloned, bindDingData, data);
1538
+
1539
+ for(let i = 0, length = node.childNodes.length; i < length; i++) {
1540
+ const childNode = node.childNodes[i];
1541
+ const childNodeCloned = clone(childNode, data);
1542
+ nodeCloned.appendChild(childNodeCloned);
1543
+ }
1544
+ return nodeCloned;
1545
+ };
1546
+
1547
+ this.clone = (data) => {
1548
+ if(!$node) {
1549
+ $node = $fn(this);
1550
+ }
1551
+ return clone($node, data);
1552
+ };
1553
+
1554
+ const createBinding = (hydrateFunction, target) => {
1555
+ return {
1556
+ $hydrate : function(element, property) {
1557
+ if(!cloneBindingsDataCache.has(element)) {
1558
+ // { classes, styles, attributes, value, attaches }
1559
+ cloneBindingsDataCache.set(element, {});
1560
+ }
1561
+ const hydrationState = cloneBindingsDataCache.get(element);
1562
+ if(target === 'value') {
1563
+ hydrationState.value = hydrateFunction;
1564
+ return;
1565
+ }
1566
+ hydrationState[target] = hydrationState[target] || {};
1567
+ hydrationState[target][property] = hydrateFunction;
1568
+ }
1569
+ }
1570
+ };
1571
+
1572
+ this.style = (fn) => {
1573
+ return createBinding(fn, 'styles');
1574
+ };
1575
+ this.class = (fn) => {
1576
+ return createBinding(fn, 'classes');
1577
+ };
1578
+ this.value = (fn) => {
1579
+ return createBinding(function(data) {
1580
+ return createTextNode(fn(...data));
1581
+ }, 'value');
1582
+ };
1583
+ this.attr = (fn) => {
1584
+ return createBinding(fn, 'attributes');
1585
+ };
1586
+ this.attach = (fn) => {
1587
+ return createBinding(fn, 'attaches');
1588
+ };
1589
+ }
1590
+
1591
+ function useCache(fn) {
1592
+ let $cache = null;
1593
+
1594
+ return function(...args) {
1595
+ if(!$cache) {
1596
+ $cache = new TemplateCloner(fn);
1597
+ }
1598
+
1599
+ return $cache.clone(args);
1600
+ };
1601
+ }
1602
+
1416
1603
  Function.prototype.args = function(...args) {
1417
1604
  return exports.withValidation(this, args);
1418
1605
  };
@@ -2111,7 +2298,6 @@ var NativeDocument = (function (exports) {
2111
2298
  },
2112
2299
  removeOne(element, index) {
2113
2300
  removeCacheItemByKey(getItemKey(element, index), true);
2114
- child = null;
2115
2301
  },
2116
2302
  clear,
2117
2303
  merge(items) {
@@ -3402,11 +3588,14 @@ var NativeDocument = (function (exports) {
3402
3588
  exports.NDElement = NDElement;
3403
3589
  exports.Observable = Observable;
3404
3590
  exports.Store = Store;
3591
+ exports.TemplateCloner = TemplateCloner;
3405
3592
  exports.classPropertyAccumulator = classPropertyAccumulator;
3593
+ exports.createTextNode = createTextNode;
3406
3594
  exports.cssPropertyAccumulator = cssPropertyAccumulator;
3407
3595
  exports.elements = elements;
3408
3596
  exports.normalizeComponentArgs = normalizeComponentArgs;
3409
3597
  exports.router = router;
3598
+ exports.useCache = useCache;
3410
3599
 
3411
3600
  return exports;
3412
3601