native-document 1.0.110 → 1.0.112

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.
@@ -887,12 +887,11 @@ var NativeComponents = (function (exports) {
887
887
  DOCUMENT_FRAGMENT: 11
888
888
  };
889
889
 
890
- const VALID_TYPES = {
891
- [COMMON_NODE_TYPES.ELEMENT]: true,
892
- [COMMON_NODE_TYPES.TEXT]: true,
893
- [COMMON_NODE_TYPES.DOCUMENT_FRAGMENT]: true,
894
- [COMMON_NODE_TYPES.COMMENT]: true
895
- };
890
+ const VALID_TYPES = [];
891
+ VALID_TYPES[COMMON_NODE_TYPES.ELEMENT] = true;
892
+ VALID_TYPES[COMMON_NODE_TYPES.TEXT] = true;
893
+ VALID_TYPES[COMMON_NODE_TYPES.DOCUMENT_FRAGMENT] = true;
894
+ VALID_TYPES[COMMON_NODE_TYPES.COMMENT] = true;
896
895
 
897
896
  const Validator = {
898
897
  isObservable(value) {
@@ -2906,7 +2905,15 @@ var NativeComponents = (function (exports) {
2906
2905
  if (attributes) {
2907
2906
  AttributesWrapper(element, attributes);
2908
2907
  }
2909
- }
2908
+ },
2909
+ /**
2910
+ *
2911
+ * @param {HTMLElement} element
2912
+ * @param {Object} attributes
2913
+ */
2914
+ processAttributesDirect: AttributesWrapper,
2915
+ processClassAttribute: bindClassAttribute,
2916
+ processStyleAttribute: bindStyleAttribute,
2910
2917
  };
2911
2918
 
2912
2919
  const EVENTS = [
@@ -656,12 +656,11 @@ var NativeDocument = (function (exports) {
656
656
  DOCUMENT_FRAGMENT: 11
657
657
  };
658
658
 
659
- const VALID_TYPES = {
660
- [COMMON_NODE_TYPES.ELEMENT]: true,
661
- [COMMON_NODE_TYPES.TEXT]: true,
662
- [COMMON_NODE_TYPES.DOCUMENT_FRAGMENT]: true,
663
- [COMMON_NODE_TYPES.COMMENT]: true
664
- };
659
+ const VALID_TYPES = [];
660
+ VALID_TYPES[COMMON_NODE_TYPES.ELEMENT] = true;
661
+ VALID_TYPES[COMMON_NODE_TYPES.TEXT] = true;
662
+ VALID_TYPES[COMMON_NODE_TYPES.DOCUMENT_FRAGMENT] = true;
663
+ VALID_TYPES[COMMON_NODE_TYPES.COMMENT] = true;
665
664
 
666
665
  const Validator = {
667
666
  isObservable(value) {
@@ -2453,7 +2452,9 @@ var NativeDocument = (function (exports) {
2453
2452
  */
2454
2453
  function AttributesWrapper(element, attributes) {
2455
2454
 
2456
- Validator.validateAttributes(attributes);
2455
+ {
2456
+ Validator.validateAttributes(attributes);
2457
+ }
2457
2458
 
2458
2459
  for(const originalAttributeName in attributes) {
2459
2460
  const attributeName = originalAttributeName.toLowerCase();
@@ -2764,7 +2765,15 @@ var NativeDocument = (function (exports) {
2764
2765
  if (attributes) {
2765
2766
  AttributesWrapper(element, attributes);
2766
2767
  }
2767
- }
2768
+ },
2769
+ /**
2770
+ *
2771
+ * @param {HTMLElement} element
2772
+ * @param {Object} attributes
2773
+ */
2774
+ processAttributesDirect: AttributesWrapper,
2775
+ processClassAttribute: bindClassAttribute,
2776
+ processStyleAttribute: bindStyleAttribute,
2768
2777
  };
2769
2778
 
2770
2779
  const EVENTS = [
@@ -3210,46 +3219,83 @@ var NativeDocument = (function (exports) {
3210
3219
 
3211
3220
  const cloneBindingsDataCache = new WeakMap();
3212
3221
 
3222
+ const pathProcess = (target, path, data) => {
3223
+ if(path.HYDRATE_TEXT) {
3224
+ const value = path.value;
3225
+ ElementCreator.bindTextNode(target, path.isString ? data[0][value] : value.apply(null, data));
3226
+ return;
3227
+ }
3228
+ if(path.ATTACH_METHOD) {
3229
+ const bindingData = path.bindingData;
3230
+ for(let i = 0, length = bindingData._attachLength; i < length; i++) {
3231
+ const method = bindingData.attach[i];
3232
+ target.nd[method.methodName](function() {
3233
+ method.fn.call(this, ...data, ...arguments);
3234
+ });
3235
+ }
3236
+ }
3237
+ if(path.HYDRATE_ATTRIBUTES) {
3238
+ path.hydrator(target, path.bindingData, data);
3239
+ }
3240
+ };
3241
+
3242
+ const buildAttributesCache = (bindDingData) => {
3243
+ const cache = { };
3244
+ if(bindDingData.attributes) cache.attributes = {};
3245
+ if(bindDingData.classes) cache.class = {};
3246
+ if(bindDingData.styles) cache.style = {};
3247
+ bindDingData._cache = cache;
3248
+ };
3249
+
3250
+ const prepareBindingMetadata = (bindDingData) => {
3251
+ const attributes = [];
3252
+ const classAndStyles = [];
3213
3253
 
3214
- const bindAttributes = (node, bindDingData, data) => {
3215
- let attributes = null;
3216
3254
  if(bindDingData.attributes) {
3217
- attributes = {};
3218
3255
  for (const attr in bindDingData.attributes) {
3219
- attributes[attr] = bindDingData.attributes[attr].apply(null, data);
3256
+ attributes.push({
3257
+ name: attr,
3258
+ value: bindDingData.attributes[attr]
3259
+ });
3220
3260
  }
3221
3261
  }
3222
3262
 
3223
3263
  if(bindDingData.classes) {
3224
- attributes = attributes || {};
3225
- attributes.class = {};
3226
3264
  for (const className in bindDingData.classes) {
3227
- attributes.class[className] = bindDingData.classes[className].apply(null, data);
3265
+ bindDingData._hasClassAttribute = true;
3266
+ classAndStyles.push({
3267
+ name: 'class',
3268
+ key: className,
3269
+ value: bindDingData.classes[className]
3270
+ });
3228
3271
  }
3229
3272
  }
3230
3273
 
3231
3274
  if(bindDingData.styles) {
3232
- attributes = attributes || {};
3233
- attributes.style = {};
3234
3275
  for (const property in bindDingData.styles) {
3235
- attributes.style[property] = bindDingData.styles[property].apply(null, data);
3276
+ bindDingData._hasStyleAttribute = true;
3277
+ classAndStyles.push({
3278
+ name: 'style',
3279
+ key: property,
3280
+ value: bindDingData.styles[property]
3281
+ });
3236
3282
  }
3237
3283
  }
3238
3284
 
3239
- if(attributes) {
3240
- ElementCreator.processAttributes(node, attributes);
3241
- return true;
3242
- }
3243
-
3244
- return null;
3285
+ bindDingData._flatAttributes = attributes;
3286
+ bindDingData._flatAttributesLength = attributes.length;
3287
+ bindDingData._flatDynamique = classAndStyles;
3288
+ bindDingData._flatDynamiqueLength = classAndStyles.length;
3289
+ bindDingData._attachLength = bindDingData.attach.length;
3245
3290
  };
3246
3291
 
3292
+
3247
3293
  const $hydrateFn = function(hydrateFunction, targetType, element, property) {
3248
3294
  if(!cloneBindingsDataCache.has(element)) {
3249
- // { classes, styles, attributes, value, attach }
3250
3295
  cloneBindingsDataCache.set(element, { attach: [] });
3251
3296
  }
3252
3297
  const hydrationState = cloneBindingsDataCache.get(element);
3298
+
3253
3299
  if(targetType === 'value') {
3254
3300
  hydrationState.value = hydrateFunction;
3255
3301
  return;
@@ -3264,87 +3310,191 @@ var NativeDocument = (function (exports) {
3264
3310
  };
3265
3311
 
3266
3312
  const bindAttachMethods = (node, bindDingData, data) => {
3267
- for(let i = 0, length = bindDingData.attach.length; i < length; i++) {
3268
- const { methodName, fn } = bindDingData.attach[i];
3269
- node.nd[methodName](function(...args) {
3270
- fn.apply(this, [...args, ...data]);
3313
+ for(let i = 0, length = bindDingData._attachLength; i < length; i++) {
3314
+ const method = bindDingData.attach[i];
3315
+ node.nd[method.methodName](function() {
3316
+ method.fn.call(this, ...data, ...arguments);
3271
3317
  });
3272
3318
  }
3273
3319
  };
3274
3320
 
3321
+ const optimizeBindingData = (bindDingData) => {
3322
+ buildAttributesCache(bindDingData);
3323
+ prepareBindingMetadata(bindDingData);
3324
+ };
3275
3325
 
3276
- const applyBindingTreePath = (root, data, paths) => {
3277
- const rootPath = paths.at(-1);
3278
- const parents = [];
3279
- parents[rootPath.id] = root;
3280
- data[0];
3281
- const rootPathFn = rootPath.fn;
3282
- rootPathFn(data, root, root);
3283
3326
 
3327
+ const $applyBindingParents = [];
3328
+ const hydrateClonedNode = (root, data, paths, pathSize) => {
3329
+ const rootPath = paths[pathSize];
3330
+ $applyBindingParents[rootPath.id] = root;
3331
+ pathProcess(root, rootPath, data);
3284
3332
 
3285
- for(let i = 0, length = paths.length - 1; i < length; i++) {
3286
- const path = paths[i];
3287
- const target = parents[path.parentId].childNodes[path.index];
3333
+ let target = null, path = null;
3334
+ for(let i = 0; i < pathSize; i++) {
3335
+ path = paths[i];
3336
+ target = $applyBindingParents[path.parentId].childNodes[path.index];
3337
+ $applyBindingParents[path.id] = target;
3288
3338
 
3289
- parents[path.id] = target;
3290
- const pathFn = path.fn;
3291
- pathFn(data, target, root);
3339
+ if(path.HYDRATE_TEXT) {
3340
+ const value = path.value;
3341
+ ElementCreator.bindTextNode(target, path.isString ? data[0][value] : value.apply(null, data));
3342
+ continue;
3343
+ }
3344
+ if(path.ATTACH_METHOD) {
3345
+ const bindingData = path.bindingData;
3346
+ for(let i = 0, length = bindingData._attachLength; i < length; i++) {
3347
+ const method = bindingData.attach[i];
3348
+ target.nd[method.methodName](function() {
3349
+ method.fn.call(this, ...data, ...arguments);
3350
+ });
3351
+ }
3352
+ }
3353
+ if(path.HYDRATE_ATTRIBUTES) {
3354
+ path.hydrator(target, path.bindingData, data);
3355
+ }
3356
+ }
3357
+
3358
+ for (let i = 0; i <= pathSize; i++) {
3359
+ $applyBindingParents[i] = null;
3292
3360
  }
3293
- parents.length = 0;
3294
3361
  };
3295
3362
 
3296
- const noUpdate = () => {};
3363
+ const hydrateFull = (node, bindDingData, data) => {
3364
+ const cacheAttributes = bindDingData._cache;
3365
+
3366
+ for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
3367
+ const attr = bindDingData._flatAttributes[i];
3368
+ cacheAttributes[attr.name] = attr.value.apply(null, data);
3369
+ }
3370
+
3371
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
3372
+ const dyn = bindDingData._flatDynamique[i];
3373
+ cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
3374
+ }
3375
+
3376
+ ElementCreator.processAttributesDirect(node, cacheAttributes);
3377
+ return true;
3378
+ };
3379
+
3380
+ const hydrateDynamic = (node, bindDingData, data) => {
3381
+ const cacheAttributes = bindDingData._cache;
3382
+
3383
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
3384
+ const dyn = bindDingData._flatDynamique[i];
3385
+ cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
3386
+ }
3387
+
3388
+ ElementCreator.processClassAttribute(node, cacheAttributes.class);
3389
+ ElementCreator.processStyleAttribute(node, cacheAttributes.style);
3390
+ return true;
3391
+ };
3392
+
3393
+ const hydrateClassAttribute = (node, bindDingData, data) => {
3394
+ const classAttributes = bindDingData._cache.class;
3395
+
3396
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
3397
+ const dyn = bindDingData._flatDynamique[i];
3398
+ classAttributes[dyn.key] = dyn.value.apply(null, data);
3399
+ }
3400
+
3401
+ ElementCreator.processClassAttribute(node, classAttributes);
3402
+ return true;
3403
+ };
3404
+
3405
+ const hydrateStyleAttribute = (node, bindDingData, data) => {
3406
+ const styleAttributes = bindDingData._cache;
3407
+
3408
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
3409
+ const dyn = bindDingData._flatDynamique[i];
3410
+ styleAttributes[dyn.key] = dyn.value.apply(null, data);
3411
+ }
3412
+
3413
+ ElementCreator.processStyleAttribute(node, styleAttributes);
3414
+ return true;
3415
+ };
3416
+
3417
+ const hydrateAttributes = (node, bindDingData, data) => {
3418
+ const cacheAttributes = bindDingData._cache;
3419
+
3420
+ for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
3421
+ const attr = bindDingData._flatAttributes[i];
3422
+ cacheAttributes[attr.name] = attr.value.apply(null, data);
3423
+ }
3424
+
3425
+ ElementCreator.processAttributesDirect(node, cacheAttributes);
3426
+ return true;
3427
+ };
3428
+
3429
+ const getHydrator = (bindDingData) => {
3430
+ if(!bindDingData._cache) {
3431
+ return noUpdate;
3432
+ }
3433
+ if(bindDingData._flatAttributesLength && bindDingData._flatDynamiqueLength) {
3434
+ return hydrateFull;
3435
+ }
3436
+ if(bindDingData._flatAttributesLength) {
3437
+ return hydrateAttributes;
3438
+ }
3439
+ if(bindDingData._hasClassAttribute && bindDingData._hasStyleAttribute) {
3440
+ return hydrateDynamic;
3441
+ }
3442
+ if(bindDingData._hasClassAttribute) {
3443
+ return hydrateClassAttribute;
3444
+ }
3445
+ return hydrateStyleAttribute;
3446
+ };
3447
+
3297
3448
  function TemplateCloner($fn) {
3298
3449
  let $node = null;
3299
3450
  let $hasBindingData = false;
3300
3451
 
3452
+ let $bindingTreePathSize = 0;
3301
3453
  const $bindingTreePath = [
3302
3454
  {
3303
3455
  id: 0,
3304
- parentId: null,
3305
- fn: noUpdate,
3456
+ parentId: null
3306
3457
  }
3307
3458
  ];
3308
3459
 
3309
3460
  let pathCounter = 0;
3310
3461
  const clone = (node, data, currentPath) => {
3311
3462
  const bindDingData = cloneBindingsDataCache.get(node);
3463
+ if(bindDingData) {
3464
+ optimizeBindingData(bindDingData);
3465
+ }
3312
3466
  if(node.nodeType === 3) {
3313
3467
  if(bindDingData && bindDingData.value) {
3314
- currentPath.fn = bindDingData.value;
3468
+ const value = bindDingData.value;
3315
3469
  const textNode = node.cloneNode();
3316
- if(typeof bindDingData.value === 'string') {
3317
- ElementCreator.bindTextNode(textNode, data[0][bindDingData.value]);
3318
- return textNode;
3319
- }
3320
- bindDingData.value(data, textNode);
3470
+ currentPath.value = value;
3471
+ currentPath.HYDRATE_TEXT = true;
3472
+ currentPath.operation = true;
3473
+ currentPath.isString = (typeof value === 'string');
3474
+ ElementCreator.bindTextNode(textNode, (currentPath.isString ? data[0][value] : value.apply(null, data)));
3321
3475
  return textNode;
3322
3476
  }
3323
3477
  return node.cloneNode(true);
3324
3478
  }
3325
3479
  const nodeCloned = node.cloneNode();
3326
3480
  if(bindDingData) {
3327
- bindAttributes(nodeCloned, bindDingData, data);
3481
+ const hydrator = getHydrator(bindDingData);
3482
+ hydrator(nodeCloned, bindDingData, data);
3328
3483
  bindAttachMethods(nodeCloned, bindDingData, data);
3329
3484
 
3330
3485
  const hasAttributes = bindDingData.classes || bindDingData.styles || bindDingData.attributes;
3331
3486
  const hasAttachMethods = bindDingData.attach.length;
3332
3487
 
3333
- if(hasAttributes && hasAttachMethods) {
3334
- currentPath.fn = (data, targetNode) => {
3335
- bindAttributes(targetNode, bindDingData, data);
3336
- bindAttachMethods(targetNode, bindDingData, data);
3337
- };
3338
- }
3339
- else if(hasAttributes) {
3340
- currentPath.fn = (data, targetNode) => {
3341
- bindAttributes(targetNode, bindDingData, data);
3342
- };
3488
+ currentPath.bindingData = bindDingData;
3489
+ currentPath.hydrator = hydrator;
3490
+
3491
+ if(hasAttributes) {
3492
+ currentPath.HYDRATE_ATTRIBUTES = true;
3493
+ currentPath.operation = true;
3343
3494
  }
3344
- else if(hasAttachMethods) {
3345
- currentPath.fn = (data, targetNode) => {
3346
- bindAttachMethods(targetNode, bindDingData, data);
3347
- };
3495
+ if(hasAttachMethods) {
3496
+ currentPath.ATTACH_METHOD = true;
3497
+ currentPath.operation = true;
3348
3498
  }
3349
3499
  }
3350
3500
  const childNodes = node.childNodes;
@@ -3352,10 +3502,10 @@ var NativeDocument = (function (exports) {
3352
3502
 
3353
3503
  for(let i = 0, length = childNodes.length; i < length; i++) {
3354
3504
  const childNode = childNodes[i];
3355
- const path = { parentId, id: ++pathCounter, index: i, fn: noUpdate };
3505
+ const path = { parentId, id: ++pathCounter, index: i };
3356
3506
  const childNodeCloned = clone(childNode, data, path);
3357
- if(path.hasChildren || path.fn) {
3358
- $bindingTreePath.unshift(path);
3507
+ if(path.hasChildren || path.operation) {
3508
+ $bindingTreePath.push(path);
3359
3509
  currentPath.hasChildren = true;
3360
3510
  }
3361
3511
  nodeCloned.appendChild(childNodeCloned);
@@ -3366,18 +3516,22 @@ var NativeDocument = (function (exports) {
3366
3516
  const cloneWithBindingPaths = (data) => {
3367
3517
  let root = $node.cloneNode(true);
3368
3518
 
3369
- applyBindingTreePath(root, data, $bindingTreePath);
3519
+ hydrateClonedNode(root, data, $bindingTreePath, $bindingTreePathSize);
3370
3520
  return root;
3371
3521
  };
3372
3522
 
3373
3523
  this.clone = (data) => {
3374
- $node = $fn(this);
3524
+ const binder = createTemplateCloner(this);
3525
+ $node = $fn(binder);
3375
3526
  if(!$hasBindingData) {
3376
3527
  this.clone = () => $node.cloneNode(true);
3377
3528
  return $node.cloneNode(true);
3378
3529
  }
3379
3530
 
3380
3531
  const firstClone = clone($node, data, $bindingTreePath[0]);
3532
+ $bindingTreePath.reverse();
3533
+ $bindingTreePathSize = $bindingTreePath.length - 1;
3534
+
3381
3535
  this.clone = cloneWithBindingPaths;
3382
3536
  return firstClone;
3383
3537
  };
@@ -3400,14 +3554,7 @@ var NativeDocument = (function (exports) {
3400
3554
  return this.value(propertyName);
3401
3555
  };
3402
3556
  this.value = (callbackOrProperty) => {
3403
- if(typeof callbackOrProperty !== 'function') {
3404
- return createBinding((data, textNode) => {
3405
- ElementCreator.bindTextNode(textNode, data[0][callbackOrProperty]);
3406
- }, 'value');
3407
- }
3408
- return createBinding((data, textNode) => {
3409
- ElementCreator.bindTextNode(textNode, callbackOrProperty(...data));
3410
- }, 'value');
3557
+ return createBinding(callbackOrProperty, 'value');
3411
3558
  };
3412
3559
  this.text = this.value;
3413
3560
  this.attr = (fn) => {
@@ -3416,26 +3563,40 @@ var NativeDocument = (function (exports) {
3416
3563
  this.attach = (fn) => {
3417
3564
  return createBinding(fn, 'attach');
3418
3565
  };
3566
+ this.callback = this.attach;
3567
+ }
3419
3568
 
3569
+
3570
+ function createTemplateCloner($binder) {
3571
+ return new Proxy($binder, {
3572
+ get(target, prop) {
3573
+ if(prop in target) {
3574
+ return target[prop];
3575
+ }
3576
+ if (typeof prop === 'symbol') return target[prop];
3577
+ return target.value(prop);
3578
+ }
3579
+ });
3420
3580
  }
3421
3581
 
3422
3582
  function useCache(fn) {
3423
3583
  let $cache = null;
3424
3584
 
3425
- let wrapper = function(args) {
3585
+ let wrapper = (args) => {
3426
3586
  $cache = new TemplateCloner(fn);
3427
- wrapper = function(args) {
3587
+
3588
+ wrapper = (args) => {
3428
3589
  return $cache.clone(args);
3429
3590
  };
3430
3591
  return $cache.clone(args);
3431
3592
  };
3432
3593
 
3433
3594
  if(fn.length < 2) {
3434
- return function(...args) {
3595
+ return (...args) => {
3435
3596
  return wrapper(args);
3436
3597
  };
3437
3598
  }
3438
- return function(_, __, ...args) {
3599
+ return (_, __, ...args) => {
3439
3600
  return wrapper([_, __, ...args]);
3440
3601
  };
3441
3602
  }