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.
- package/dist/native-document.dev.js +201 -12
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.min.js +1 -1
- package/index.d.ts +1 -0
- package/index.js +2 -1
- package/package.json +1 -1
- package/src/data/ObservableItem.js +36 -10
- package/src/elements/control/for-each-array.js +0 -1
- package/src/utils/args-types.js +1 -1
- package/src/wrappers/AttributesWrapper.js +4 -0
- package/src/wrappers/ElementCreator.js +14 -0
- package/src/wrappers/NDElement.js +6 -1
- package/src/wrappers/TemplateCloner.js +129 -0
- package/types/elements.d.ts +2 -0
- package/types/template-cloner.ts +36 -0
|
@@ -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)
|
|
268
|
-
|
|
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)
|
|
273
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 ===
|
|
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
|
|