native-document 1.0.30 → 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 +156 -137
- 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 +102 -73
- package/src/utils/prototypes.js +17 -0
- package/src/wrappers/ElementCreator.js +2 -2
- package/src/wrappers/HtmlElementWrapper.js +14 -22
- package/src/wrappers/NDElement.js +4 -0
|
@@ -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
|
|
|
@@ -637,6 +638,10 @@ var NativeDocument = (function (exports) {
|
|
|
637
638
|
};
|
|
638
639
|
}
|
|
639
640
|
|
|
641
|
+
NDElement.prototype.valueOf = function() {
|
|
642
|
+
return this.$element;
|
|
643
|
+
};
|
|
644
|
+
|
|
640
645
|
NDElement.prototype.ref = function(target, name) {
|
|
641
646
|
target[name] = this.$element;
|
|
642
647
|
return this;
|
|
@@ -805,7 +810,7 @@ var NativeDocument = (function (exports) {
|
|
|
805
810
|
}
|
|
806
811
|
};
|
|
807
812
|
|
|
808
|
-
function Anchor(name) {
|
|
813
|
+
function Anchor(name, isUniqueChild = false) {
|
|
809
814
|
const element = document.createDocumentFragment();
|
|
810
815
|
|
|
811
816
|
const anchorStart = document.createComment('Anchor Start : '+name);
|
|
@@ -818,14 +823,25 @@ var NativeDocument = (function (exports) {
|
|
|
818
823
|
element.nativeAppendChild = element.appendChild;
|
|
819
824
|
|
|
820
825
|
const insertBefore = function(parent, child, target) {
|
|
826
|
+
const element = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
821
827
|
if(parent === element) {
|
|
822
|
-
parent.nativeInsertBefore(
|
|
828
|
+
parent.nativeInsertBefore(element, target);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if(isUniqueChild || target === anchorEnd) {
|
|
832
|
+
parent.append(element, target);
|
|
823
833
|
return;
|
|
824
834
|
}
|
|
825
|
-
parent.insertBefore(
|
|
835
|
+
parent.insertBefore(element, target);
|
|
826
836
|
};
|
|
827
837
|
|
|
828
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
|
+
}
|
|
829
845
|
if(anchorEnd.parentNode === element) {
|
|
830
846
|
anchorEnd.parentNode.nativeInsertBefore(child, before || anchorEnd);
|
|
831
847
|
return;
|
|
@@ -840,14 +856,6 @@ var NativeDocument = (function (exports) {
|
|
|
840
856
|
return;
|
|
841
857
|
}
|
|
842
858
|
before = before ?? anchorEnd;
|
|
843
|
-
if(Validator.isArray(child)) {
|
|
844
|
-
const fragment = document.createDocumentFragment();
|
|
845
|
-
for(let i = 0, length = child.length; i < length; i++) {
|
|
846
|
-
fragment.appendChild(ElementCreator.getChild(child[i]));
|
|
847
|
-
}
|
|
848
|
-
insertBefore(parent, fragment, before);
|
|
849
|
-
return element;
|
|
850
|
-
}
|
|
851
859
|
insertBefore(parent, child, before);
|
|
852
860
|
};
|
|
853
861
|
|
|
@@ -856,7 +864,7 @@ var NativeDocument = (function (exports) {
|
|
|
856
864
|
if(parent === element) {
|
|
857
865
|
return;
|
|
858
866
|
}
|
|
859
|
-
if(parent.firstChild === anchorStart && parent.lastChild === anchorEnd) {
|
|
867
|
+
if(isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd)) {
|
|
860
868
|
parent.replaceChildren(anchorStart, anchorEnd);
|
|
861
869
|
return;
|
|
862
870
|
}
|
|
@@ -875,6 +883,10 @@ var NativeDocument = (function (exports) {
|
|
|
875
883
|
if(parent === element) {
|
|
876
884
|
return;
|
|
877
885
|
}
|
|
886
|
+
if(isUniqueChild) {
|
|
887
|
+
parent.replaceChildren(anchorEnd, anchorEnd);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
878
890
|
let itemToRemove = anchorStart.nextSibling, tempItem;
|
|
879
891
|
while(itemToRemove !== anchorEnd) {
|
|
880
892
|
tempItem = itemToRemove.nextSibling;
|
|
@@ -894,7 +906,7 @@ var NativeDocument = (function (exports) {
|
|
|
894
906
|
if(!parent) {
|
|
895
907
|
return;
|
|
896
908
|
}
|
|
897
|
-
if(parent.firstChild === anchorStart && parent.lastChild === anchorEnd) {
|
|
909
|
+
if(isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd)) {
|
|
898
910
|
parent.replaceChildren(anchorStart, child, anchorEnd);
|
|
899
911
|
return;
|
|
900
912
|
}
|
|
@@ -1138,7 +1150,7 @@ var NativeDocument = (function (exports) {
|
|
|
1138
1150
|
*/
|
|
1139
1151
|
createObservableNode(parent, observable) {
|
|
1140
1152
|
const text = ElementCreator.createTextNode();
|
|
1141
|
-
observable.subscribe(value => text.nodeValue =
|
|
1153
|
+
observable.subscribe(value => text.nodeValue = value);
|
|
1142
1154
|
text.nodeValue = observable.val();
|
|
1143
1155
|
parent && parent.appendChild(text);
|
|
1144
1156
|
return text;
|
|
@@ -1152,7 +1164,7 @@ var NativeDocument = (function (exports) {
|
|
|
1152
1164
|
*/
|
|
1153
1165
|
createStaticTextNode(parent, value) {
|
|
1154
1166
|
let text = ElementCreator.createTextNode();
|
|
1155
|
-
text.nodeValue =
|
|
1167
|
+
text.nodeValue = value;
|
|
1156
1168
|
parent && parent.appendChild(text);
|
|
1157
1169
|
return text;
|
|
1158
1170
|
},
|
|
@@ -1260,41 +1272,15 @@ var NativeDocument = (function (exports) {
|
|
|
1260
1272
|
}
|
|
1261
1273
|
});
|
|
1262
1274
|
|
|
1263
|
-
/**
|
|
1264
|
-
*
|
|
1265
|
-
* @param {string} name
|
|
1266
|
-
* @param {?Function} customWrapper
|
|
1267
|
-
* @returns {Function}
|
|
1268
|
-
*/
|
|
1269
|
-
function HtmlElementWrapper(name, customWrapper) {
|
|
1270
|
-
const $tagName = name.toLowerCase();
|
|
1271
|
-
|
|
1272
|
-
return function(attributes, children = null) {
|
|
1273
|
-
try {
|
|
1274
|
-
if(!Validator.isJson(attributes)) {
|
|
1275
|
-
const tempChildren = children;
|
|
1276
|
-
children = attributes;
|
|
1277
|
-
attributes = tempChildren;
|
|
1278
|
-
}
|
|
1279
|
-
const element = ElementCreator.createElement($tagName);
|
|
1280
|
-
const finalElement = (typeof customWrapper === 'function') ? customWrapper(element) : element;
|
|
1281
|
-
|
|
1282
|
-
ElementCreator.processAttributes(finalElement, attributes);
|
|
1283
|
-
ElementCreator.processChildren(children, finalElement);
|
|
1284
|
-
|
|
1285
|
-
return ElementCreator.setup(finalElement, attributes, customWrapper);
|
|
1286
|
-
} catch (error) {
|
|
1287
|
-
DebugManager$1.error('ElementCreation', `Error creating ${$tagName}`, error);
|
|
1288
|
-
}
|
|
1289
|
-
};
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
1275
|
class ArgTypesError extends Error {
|
|
1293
1276
|
constructor(message, errors) {
|
|
1294
1277
|
super(`${message}\n\n${errors.join("\n")}\n\n`);
|
|
1295
1278
|
}
|
|
1296
1279
|
}
|
|
1297
1280
|
|
|
1281
|
+
exports.withValidation = (fn) => fn;
|
|
1282
|
+
exports.ArgTypes = {};
|
|
1283
|
+
|
|
1298
1284
|
/**
|
|
1299
1285
|
*
|
|
1300
1286
|
* @type {{string: (function(*): {name: *, type: string, validate: function(*): boolean}),
|
|
@@ -1312,97 +1298,139 @@ var NativeDocument = (function (exports) {
|
|
|
1312
1298
|
* validate: function(*): boolean})
|
|
1313
1299
|
* }}
|
|
1314
1300
|
*/
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
name,
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
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
|
+
};
|
|
1338
1325
|
|
|
1339
|
-
/**
|
|
1340
|
-
*
|
|
1341
|
-
* @param {Array} args
|
|
1342
|
-
* @param {Array} argSchema
|
|
1343
|
-
* @param {string} fnName
|
|
1344
|
-
*/
|
|
1345
|
-
const validateArgs = (args, argSchema, fnName = 'Function') => {
|
|
1346
|
-
if (!argSchema) return;
|
|
1347
1326
|
|
|
1348
|
-
|
|
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;
|
|
1349
1335
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1336
|
+
const errors = [];
|
|
1337
|
+
|
|
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
|
+
}
|
|
1355
1343
|
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
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
|
+
}
|
|
1360
1355
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
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}`);
|
|
1364
1359
|
}
|
|
1365
|
-
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1362
|
+
if (errors.length > 0) {
|
|
1363
|
+
throw new ArgTypesError(`Argument validation failed`, errors);
|
|
1366
1364
|
}
|
|
1365
|
+
};
|
|
1367
1366
|
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1367
|
+
|
|
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');
|
|
1371
1378
|
}
|
|
1372
|
-
|
|
1379
|
+
return function(...args) {
|
|
1380
|
+
validateArgs(args, argSchema, fn.name || fnName);
|
|
1381
|
+
return fn.apply(this, args);
|
|
1382
|
+
};
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1373
1385
|
|
|
1374
|
-
|
|
1375
|
-
|
|
1386
|
+
const normalizeComponentArgs = function(props, children = null) {
|
|
1387
|
+
if(!Validator.isJson(props)) {
|
|
1388
|
+
const temp = children;
|
|
1389
|
+
children = props;
|
|
1390
|
+
props = temp;
|
|
1376
1391
|
}
|
|
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
|
-
*
|
|
1381
|
-
* @param {
|
|
1382
|
-
* @param {
|
|
1407
|
+
*
|
|
1408
|
+
* @param {string} name
|
|
1409
|
+
* @param {?Function} customWrapper
|
|
1383
1410
|
* @returns {Function}
|
|
1384
1411
|
*/
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
}
|
|
1389
|
-
return function(...args) {
|
|
1390
|
-
validateArgs(args, argSchema, fn.name || fnName);
|
|
1391
|
-
return fn.apply(this, args);
|
|
1392
|
-
};
|
|
1393
|
-
};
|
|
1412
|
+
function HtmlElementWrapper(name, customWrapper) {
|
|
1413
|
+
return (_attributes, _children = null) => createHtmlElement(name.toLowerCase(), _attributes, _children, customWrapper);
|
|
1414
|
+
}
|
|
1394
1415
|
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
const temp = props;
|
|
1398
|
-
props = children;
|
|
1399
|
-
children = temp;
|
|
1400
|
-
}
|
|
1401
|
-
return { props, children };
|
|
1416
|
+
Function.prototype.args = function(...args) {
|
|
1417
|
+
return exports.withValidation(this, args);
|
|
1402
1418
|
};
|
|
1403
1419
|
|
|
1404
|
-
Function.prototype.
|
|
1405
|
-
|
|
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
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
return getCache();
|
|
1433
|
+
};
|
|
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
|
|