native-document 1.0.31 → 1.0.32
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 +139 -120
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.min.js +1 -1
- package/elements.d.ts +6 -0
- package/index.d.ts +0 -5
- package/package.json +1 -1
- package/rollup.config.js +1 -0
- package/src/data/ObservableItem.js +1 -0
- package/src/data/observable-helpers/array.js +2 -1
- package/src/elements/anchor.js +20 -13
- package/src/elements/control/for-each-array.js +10 -18
- package/src/utils/args-types.js +97 -68
- package/src/utils/prototypes.js +17 -0
- package/src/wrappers/ElementCreator.js +2 -2
- package/src/wrappers/HtmlElementWrapper.js +13 -18
|
@@ -309,6 +309,7 @@ var NativeDocument = (function (exports) {
|
|
|
309
309
|
this.$currentValue = newValue;
|
|
310
310
|
PluginsManager.emit('ObservableBeforeChange', this);
|
|
311
311
|
this.trigger();
|
|
312
|
+
this.$previousValue = null;
|
|
312
313
|
PluginsManager.emit('ObservableAfterChange', this);
|
|
313
314
|
};
|
|
314
315
|
|
|
@@ -809,7 +810,7 @@ var NativeDocument = (function (exports) {
|
|
|
809
810
|
}
|
|
810
811
|
};
|
|
811
812
|
|
|
812
|
-
function Anchor(name) {
|
|
813
|
+
function Anchor(name, isUniqueChild = false) {
|
|
813
814
|
const element = document.createDocumentFragment();
|
|
814
815
|
|
|
815
816
|
const anchorStart = document.createComment('Anchor Start : '+name);
|
|
@@ -822,14 +823,25 @@ var NativeDocument = (function (exports) {
|
|
|
822
823
|
element.nativeAppendChild = element.appendChild;
|
|
823
824
|
|
|
824
825
|
const insertBefore = function(parent, child, target) {
|
|
826
|
+
const element = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
825
827
|
if(parent === element) {
|
|
826
|
-
parent.nativeInsertBefore(
|
|
828
|
+
parent.nativeInsertBefore(element, target);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if(isUniqueChild || target === anchorEnd) {
|
|
832
|
+
parent.append(element, target);
|
|
827
833
|
return;
|
|
828
834
|
}
|
|
829
|
-
parent.insertBefore(
|
|
835
|
+
parent.insertBefore(element, target);
|
|
830
836
|
};
|
|
831
837
|
|
|
832
838
|
element.appendElement = function(child, before = null) {
|
|
839
|
+
if(isUniqueChild) {
|
|
840
|
+
(before && before !== anchorEnd)
|
|
841
|
+
? anchorEnd.parentNode.insertBefore(child, anchorEnd)
|
|
842
|
+
: anchorEnd.parentNode.append(child, anchorEnd);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
833
845
|
if(anchorEnd.parentNode === element) {
|
|
834
846
|
anchorEnd.parentNode.nativeInsertBefore(child, before || anchorEnd);
|
|
835
847
|
return;
|
|
@@ -844,14 +856,6 @@ var NativeDocument = (function (exports) {
|
|
|
844
856
|
return;
|
|
845
857
|
}
|
|
846
858
|
before = before ?? anchorEnd;
|
|
847
|
-
if(Validator.isArray(child)) {
|
|
848
|
-
const fragment = document.createDocumentFragment();
|
|
849
|
-
for(let i = 0, length = child.length; i < length; i++) {
|
|
850
|
-
fragment.appendChild(ElementCreator.getChild(child[i]));
|
|
851
|
-
}
|
|
852
|
-
insertBefore(parent, fragment, before);
|
|
853
|
-
return element;
|
|
854
|
-
}
|
|
855
859
|
insertBefore(parent, child, before);
|
|
856
860
|
};
|
|
857
861
|
|
|
@@ -860,7 +864,7 @@ var NativeDocument = (function (exports) {
|
|
|
860
864
|
if(parent === element) {
|
|
861
865
|
return;
|
|
862
866
|
}
|
|
863
|
-
if(parent.firstChild === anchorStart && parent.lastChild === anchorEnd) {
|
|
867
|
+
if(isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd)) {
|
|
864
868
|
parent.replaceChildren(anchorStart, anchorEnd);
|
|
865
869
|
return;
|
|
866
870
|
}
|
|
@@ -879,6 +883,10 @@ var NativeDocument = (function (exports) {
|
|
|
879
883
|
if(parent === element) {
|
|
880
884
|
return;
|
|
881
885
|
}
|
|
886
|
+
if(isUniqueChild) {
|
|
887
|
+
parent.replaceChildren(anchorEnd, anchorEnd);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
882
890
|
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
883
891
|
while(itemToRemove !== anchorEnd) {
|
|
884
892
|
tempItem = itemToRemove.nextSibling;
|
|
@@ -898,7 +906,7 @@ var NativeDocument = (function (exports) {
|
|
|
898
906
|
if(!parent) {
|
|
899
907
|
return;
|
|
900
908
|
}
|
|
901
|
-
if(parent.firstChild === anchorStart && parent.lastChild === anchorEnd) {
|
|
909
|
+
if(isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd)) {
|
|
902
910
|
parent.replaceChildren(anchorStart, child, anchorEnd);
|
|
903
911
|
return;
|
|
904
912
|
}
|
|
@@ -1142,7 +1150,7 @@ var NativeDocument = (function (exports) {
|
|
|
1142
1150
|
*/
|
|
1143
1151
|
createObservableNode(parent, observable) {
|
|
1144
1152
|
const text = ElementCreator.createTextNode();
|
|
1145
|
-
observable.subscribe(value => text.nodeValue =
|
|
1153
|
+
observable.subscribe(value => text.nodeValue = value);
|
|
1146
1154
|
text.nodeValue = observable.val();
|
|
1147
1155
|
parent && parent.appendChild(text);
|
|
1148
1156
|
return text;
|
|
@@ -1156,7 +1164,7 @@ var NativeDocument = (function (exports) {
|
|
|
1156
1164
|
*/
|
|
1157
1165
|
createStaticTextNode(parent, value) {
|
|
1158
1166
|
let text = ElementCreator.createTextNode();
|
|
1159
|
-
text.nodeValue =
|
|
1167
|
+
text.nodeValue = value;
|
|
1160
1168
|
parent && parent.appendChild(text);
|
|
1161
1169
|
return text;
|
|
1162
1170
|
},
|
|
@@ -1270,6 +1278,9 @@ var NativeDocument = (function (exports) {
|
|
|
1270
1278
|
}
|
|
1271
1279
|
}
|
|
1272
1280
|
|
|
1281
|
+
exports.withValidation = (fn) => fn;
|
|
1282
|
+
exports.ArgTypes = {};
|
|
1283
|
+
|
|
1273
1284
|
/**
|
|
1274
1285
|
*
|
|
1275
1286
|
* @type {{string: (function(*): {name: *, type: string, validate: function(*): boolean}),
|
|
@@ -1287,85 +1298,90 @@ var NativeDocument = (function (exports) {
|
|
|
1287
1298
|
* validate: function(*): boolean})
|
|
1288
1299
|
* }}
|
|
1289
1300
|
*/
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
name,
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1301
|
+
{
|
|
1302
|
+
exports.ArgTypes = {
|
|
1303
|
+
string: (name) => ({ name, type: 'string', validate: (v) => Validator.isString(v) }),
|
|
1304
|
+
number: (name) => ({ name, type: 'number', validate: (v) => Validator.isNumber(v) }),
|
|
1305
|
+
boolean: (name) => ({ name, type: 'boolean', validate: (v) => Validator.isBoolean(v) }),
|
|
1306
|
+
observable: (name) => ({ name, type: 'observable', validate: (v) => Validator.isObservable(v) }),
|
|
1307
|
+
element: (name) => ({ name, type: 'element', validate: (v) => Validator.isElement(v) }),
|
|
1308
|
+
function: (name) => ({ name, type: 'function', validate: (v) => Validator.isFunction(v) }),
|
|
1309
|
+
object: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v)) }),
|
|
1310
|
+
objectNotNull: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v) && v !== null) }),
|
|
1311
|
+
children: (name) => ({ name, type: 'children', validate: (v) => Validator.validateChildren(v) }),
|
|
1312
|
+
attributes: (name) => ({ name, type: 'attributes', validate: (v) => Validator.validateAttributes(v) }),
|
|
1313
|
+
|
|
1314
|
+
// Optional arguments
|
|
1315
|
+
optional: (argType) => ({ ...argType, optional: true }),
|
|
1316
|
+
|
|
1317
|
+
// Union types
|
|
1318
|
+
oneOf: (name, ...argTypes) => ({
|
|
1319
|
+
name,
|
|
1320
|
+
type: 'oneOf',
|
|
1321
|
+
types: argTypes,
|
|
1322
|
+
validate: (v) => argTypes.some(type => type.validate(v))
|
|
1323
|
+
})
|
|
1324
|
+
};
|
|
1313
1325
|
|
|
1314
|
-
/**
|
|
1315
|
-
*
|
|
1316
|
-
* @param {Array} args
|
|
1317
|
-
* @param {Array} argSchema
|
|
1318
|
-
* @param {string} fnName
|
|
1319
|
-
*/
|
|
1320
|
-
const validateArgs = (args, argSchema, fnName = 'Function') => {
|
|
1321
|
-
if (!argSchema) return;
|
|
1322
1326
|
|
|
1323
|
-
|
|
1327
|
+
/**
|
|
1328
|
+
*
|
|
1329
|
+
* @param {Array} args
|
|
1330
|
+
* @param {Array} argSchema
|
|
1331
|
+
* @param {string} fnName
|
|
1332
|
+
*/
|
|
1333
|
+
const validateArgs = (args, argSchema, fnName = 'Function') => {
|
|
1334
|
+
if (!argSchema) return;
|
|
1324
1335
|
|
|
1325
|
-
|
|
1326
|
-
const requiredCount = argSchema.filter(arg => !arg.optional).length;
|
|
1327
|
-
if (args.length < requiredCount) {
|
|
1328
|
-
errors.push(`${fnName}: Expected at least ${requiredCount} arguments, got ${args.length}`);
|
|
1329
|
-
}
|
|
1336
|
+
const errors = [];
|
|
1330
1337
|
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1338
|
+
// Check the number of arguments
|
|
1339
|
+
const requiredCount = argSchema.filter(arg => !arg.optional).length;
|
|
1340
|
+
if (args.length < requiredCount) {
|
|
1341
|
+
errors.push(`${fnName}: Expected at least ${requiredCount} arguments, got ${args.length}`);
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// Validate each argument
|
|
1345
|
+
argSchema.forEach((schema, index) => {
|
|
1346
|
+
const position = index + 1;
|
|
1347
|
+
const value = args[index];
|
|
1348
|
+
|
|
1349
|
+
if (value === undefined) {
|
|
1350
|
+
if (!schema.optional) {
|
|
1351
|
+
errors.push(`${fnName}: Missing required argument '${schema.name}' at position ${position}`);
|
|
1352
|
+
}
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1335
1355
|
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
errors.push(`${fnName}:
|
|
1356
|
+
if (!schema.validate(value)) {
|
|
1357
|
+
const valueTypeOf = value?.constructor?.name || typeof value;
|
|
1358
|
+
errors.push(`${fnName}: Invalid argument '${schema.name}' at position ${position}, expected ${schema.type}, got ${valueTypeOf}`);
|
|
1339
1359
|
}
|
|
1340
|
-
|
|
1341
|
-
}
|
|
1360
|
+
});
|
|
1342
1361
|
|
|
1343
|
-
if (
|
|
1344
|
-
|
|
1345
|
-
errors.push(`${fnName}: Invalid argument '${schema.name}' at position ${position}, expected ${schema.type}, got ${valueTypeOf}`);
|
|
1362
|
+
if (errors.length > 0) {
|
|
1363
|
+
throw new ArgTypesError(`Argument validation failed`, errors);
|
|
1346
1364
|
}
|
|
1347
|
-
}
|
|
1365
|
+
};
|
|
1348
1366
|
|
|
1349
|
-
if (errors.length > 0) {
|
|
1350
|
-
throw new ArgTypesError(`Argument validation failed`, errors);
|
|
1351
|
-
}
|
|
1352
|
-
};
|
|
1353
1367
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1368
|
+
|
|
1369
|
+
/**
|
|
1370
|
+
* @param {Function} fn
|
|
1371
|
+
* @param {Array} argSchema
|
|
1372
|
+
* @param {string} fnName
|
|
1373
|
+
* @returns {Function}
|
|
1374
|
+
*/
|
|
1375
|
+
exports.withValidation = (fn, argSchema, fnName = 'Function') => {
|
|
1376
|
+
if(!Validator.isArray(argSchema)) {
|
|
1377
|
+
throw new NativeDocumentError('withValidation : argSchema must be an array');
|
|
1378
|
+
}
|
|
1379
|
+
return function(...args) {
|
|
1380
|
+
validateArgs(args, argSchema, fn.name || fnName);
|
|
1381
|
+
return fn.apply(this, args);
|
|
1382
|
+
};
|
|
1367
1383
|
};
|
|
1368
|
-
}
|
|
1384
|
+
}
|
|
1369
1385
|
|
|
1370
1386
|
const normalizeComponentArgs = function(props, children = null) {
|
|
1371
1387
|
if(!Validator.isJson(props)) {
|
|
@@ -1376,6 +1392,17 @@ var NativeDocument = (function (exports) {
|
|
|
1376
1392
|
return { props, children };
|
|
1377
1393
|
};
|
|
1378
1394
|
|
|
1395
|
+
function createHtmlElement($tagName, _attributes, _children = null, customWrapper) {
|
|
1396
|
+
const { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
|
|
1397
|
+
const element = ElementCreator.createElement($tagName);
|
|
1398
|
+
const finalElement = (typeof customWrapper === 'function') ? customWrapper(element) : element;
|
|
1399
|
+
|
|
1400
|
+
ElementCreator.processAttributes(finalElement, attributes);
|
|
1401
|
+
ElementCreator.processChildren(children, finalElement);
|
|
1402
|
+
|
|
1403
|
+
return ElementCreator.setup(finalElement, attributes, customWrapper);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1379
1406
|
/**
|
|
1380
1407
|
*
|
|
1381
1408
|
* @param {string} name
|
|
@@ -1383,26 +1410,27 @@ var NativeDocument = (function (exports) {
|
|
|
1383
1410
|
* @returns {Function}
|
|
1384
1411
|
*/
|
|
1385
1412
|
function HtmlElementWrapper(name, customWrapper) {
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
return function(_attributes, _children = null) {
|
|
1389
|
-
try {
|
|
1390
|
-
const { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
|
|
1391
|
-
const element = ElementCreator.createElement($tagName);
|
|
1392
|
-
const finalElement = (typeof customWrapper === 'function') ? customWrapper(element) : element;
|
|
1413
|
+
return (_attributes, _children = null) => createHtmlElement(name.toLowerCase(), _attributes, _children, customWrapper);
|
|
1414
|
+
}
|
|
1393
1415
|
|
|
1394
|
-
|
|
1395
|
-
|
|
1416
|
+
Function.prototype.args = function(...args) {
|
|
1417
|
+
return exports.withValidation(this, args);
|
|
1418
|
+
};
|
|
1396
1419
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1420
|
+
Function.prototype.cached = function(...args) {
|
|
1421
|
+
let $cache = null;
|
|
1422
|
+
let getCache = function(){ return $cache; };
|
|
1423
|
+
return () => {
|
|
1424
|
+
if(!$cache) {
|
|
1425
|
+
$cache = this.apply(this, args);
|
|
1426
|
+
if($cache.cloneNode) {
|
|
1427
|
+
getCache = function() { return $cache.cloneNode(true); };
|
|
1428
|
+
} else if($cache.$element) {
|
|
1429
|
+
getCache = function() { return new NDElement($cache.$element.cloneNode(true)); };
|
|
1430
|
+
}
|
|
1400
1431
|
}
|
|
1432
|
+
return getCache();
|
|
1401
1433
|
};
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
Function.prototype.args = function(...args) {
|
|
1405
|
-
return withValidation(this, args);
|
|
1406
1434
|
};
|
|
1407
1435
|
|
|
1408
1436
|
Function.prototype.errorBoundary = function(callback) {
|
|
@@ -1514,7 +1542,8 @@ var NativeDocument = (function (exports) {
|
|
|
1514
1542
|
};
|
|
1515
1543
|
|
|
1516
1544
|
observer.merge = function(values) {
|
|
1517
|
-
observer.
|
|
1545
|
+
observer.$value.push(...values);
|
|
1546
|
+
observer.trigger({ action: 'merge', args: values });
|
|
1518
1547
|
};
|
|
1519
1548
|
|
|
1520
1549
|
observer.populateAndRender = function(iteration, callback) {
|
|
@@ -2009,20 +2038,15 @@ var NativeDocument = (function (exports) {
|
|
|
2009
2038
|
cache.delete(keyId);
|
|
2010
2039
|
}
|
|
2011
2040
|
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
return child;
|
|
2022
|
-
} catch (e) {
|
|
2023
|
-
DebugManager$1.error('ForEach', `Error creating element for key ${keyId}` , e);
|
|
2024
|
-
throw e;
|
|
2025
|
-
}
|
|
2041
|
+
const indexObserver = isIndexRequired ? Observable(indexKey) : null;
|
|
2042
|
+
let child = ElementCreator.getChild(callback(item, indexObserver));
|
|
2043
|
+
cache.set(keyId, {
|
|
2044
|
+
keyId,
|
|
2045
|
+
child: child,
|
|
2046
|
+
indexObserver: (indexObserver ? new WeakRef(indexObserver) : null)
|
|
2047
|
+
});
|
|
2048
|
+
keysCache.set(item, keyId);
|
|
2049
|
+
return child;
|
|
2026
2050
|
};
|
|
2027
2051
|
const getChildByKey = function(keyId) {
|
|
2028
2052
|
const cacheItem = cache.get(keyId);
|
|
@@ -2086,10 +2110,7 @@ var NativeDocument = (function (exports) {
|
|
|
2086
2110
|
element.appendElement(fragment, blockEnd);
|
|
2087
2111
|
},
|
|
2088
2112
|
removeOne(element, index) {
|
|
2089
|
-
|
|
2090
|
-
if(child) {
|
|
2091
|
-
removeCacheItemByKey(getItemKey(element, index), true);
|
|
2092
|
-
}
|
|
2113
|
+
removeCacheItemByKey(getItemKey(element, index), true);
|
|
2093
2114
|
child = null;
|
|
2094
2115
|
},
|
|
2095
2116
|
clear,
|
|
@@ -3376,7 +3397,6 @@ var NativeDocument = (function (exports) {
|
|
|
3376
3397
|
Router: Router
|
|
3377
3398
|
});
|
|
3378
3399
|
|
|
3379
|
-
exports.ArgTypes = ArgTypes;
|
|
3380
3400
|
exports.ElementCreator = ElementCreator;
|
|
3381
3401
|
exports.HtmlElementWrapper = HtmlElementWrapper;
|
|
3382
3402
|
exports.NDElement = NDElement;
|
|
@@ -3387,7 +3407,6 @@ var NativeDocument = (function (exports) {
|
|
|
3387
3407
|
exports.elements = elements;
|
|
3388
3408
|
exports.normalizeComponentArgs = normalizeComponentArgs;
|
|
3389
3409
|
exports.router = router;
|
|
3390
|
-
exports.withValidation = withValidation;
|
|
3391
3410
|
|
|
3392
3411
|
return exports;
|
|
3393
3412
|
|