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.
@@ -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(ElementCreator.getChild(child), target);
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(ElementCreator.getChild(child), target);
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 = String(value));
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 = String(value);
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
- const ArgTypes = {
1316
- string: (name) => ({ name, type: 'string', validate: (v) => Validator.isString(v) }),
1317
- number: (name) => ({ name, type: 'number', validate: (v) => Validator.isNumber(v) }),
1318
- boolean: (name) => ({ name, type: 'boolean', validate: (v) => Validator.isBoolean(v) }),
1319
- observable: (name) => ({ name, type: 'observable', validate: (v) => Validator.isObservable(v) }),
1320
- element: (name) => ({ name, type: 'element', validate: (v) => Validator.isElement(v) }),
1321
- function: (name) => ({ name, type: 'function', validate: (v) => Validator.isFunction(v) }),
1322
- object: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v)) }),
1323
- objectNotNull: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v) && v !== null) }),
1324
- children: (name) => ({ name, type: 'children', validate: (v) => Validator.validateChildren(v) }),
1325
- attributes: (name) => ({ name, type: 'attributes', validate: (v) => Validator.validateAttributes(v) }),
1326
-
1327
- // Optional arguments
1328
- optional: (argType) => ({ ...argType, optional: true }),
1329
-
1330
- // Union types
1331
- oneOf: (name, ...argTypes) => ({
1332
- name,
1333
- type: 'oneOf',
1334
- types: argTypes,
1335
- validate: (v) => argTypes.some(type => type.validate(v))
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
- const errors = [];
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
- // Check the number of arguments
1351
- const requiredCount = argSchema.filter(arg => !arg.optional).length;
1352
- if (args.length < requiredCount) {
1353
- errors.push(`${fnName}: Expected at least ${requiredCount} arguments, got ${args.length}`);
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
- // Validate each argument
1357
- argSchema.forEach((schema, index) => {
1358
- const position = index + 1;
1359
- const value = args[index];
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
- if (value === undefined) {
1362
- if (!schema.optional) {
1363
- errors.push(`${fnName}: Missing required argument '${schema.name}' at position ${position}`);
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
- return;
1360
+ });
1361
+
1362
+ if (errors.length > 0) {
1363
+ throw new ArgTypesError(`Argument validation failed`, errors);
1366
1364
  }
1365
+ };
1367
1366
 
1368
- if (!schema.validate(value)) {
1369
- const valueTypeOf = value?.constructor?.name || typeof value;
1370
- errors.push(`${fnName}: Invalid argument '${schema.name}' at position ${position}, expected ${schema.type}, got ${valueTypeOf}`);
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
- if (errors.length > 0) {
1375
- throw new ArgTypesError(`Argument validation failed`, errors);
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
- * @param {Function} fn
1381
- * @param {Array} argSchema
1382
- * @param {string} fnName
1407
+ *
1408
+ * @param {string} name
1409
+ * @param {?Function} customWrapper
1383
1410
  * @returns {Function}
1384
1411
  */
1385
- const withValidation = (fn, argSchema, fnName = 'Function') => {
1386
- if(!Validator.isArray(argSchema)) {
1387
- throw new NativeDocumentError('withValidation : argSchema must be an array');
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
- const normalizeComponentArgs = function(props, children) {
1396
- if(!Validator.isJson(children)) {
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.args = function(...args) {
1405
- return withValidation(this, args);
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.set([...observer.val(), ...values]);
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
- try {
2013
- const indexObserver = isIndexRequired ? Observable(indexKey) : null;
2014
- let child = ElementCreator.getChild(callback(item, indexObserver));
2015
- cache.set(keyId, {
2016
- keyId,
2017
- child: child,
2018
- indexObserver: (indexObserver ? new WeakRef(indexObserver) : null)
2019
- });
2020
- keysCache.set(item, keyId);
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
- let child = getItemChild(element);
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