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