native-document 1.0.115 → 1.0.117

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.
@@ -1,112 +1,76 @@
1
- import {ElementCreator} from "../ElementCreator";
2
1
  import TemplateBinding from "../TemplateBinding";
3
- import { hydrateClonedNode, optimizeBindingData, $hydrateFn, bindAttachMethods, cloneBindingsDataCache } from './utils';
4
- import { getHydrator } from './attributes-hydrator';
2
+ import { $hydrateFn} from './utils';
3
+ import NodeCloner from "./NodeCloner";
5
4
 
6
5
  export function TemplateCloner($fn) {
7
6
  let $node = null;
8
- let $hasBindingData = false;
9
7
 
10
- let $bindingTreePathSize = 0;
11
- const $bindingTreePath = [
12
- {
13
- id: 0,
14
- parentId: null
15
- }
16
- ];
17
-
18
- let pathCounter = 0;
19
- const clone = (node, data, currentPath) => {
20
- const bindDingData = cloneBindingsDataCache.get(node);
21
- if(bindDingData) {
22
- optimizeBindingData(bindDingData);
23
- }
24
- if(node.nodeType === 3) {
25
- if(bindDingData && bindDingData.value) {
26
- const value = bindDingData.value;
27
- const textNode = node.cloneNode();
28
- currentPath.value = value;
29
- currentPath.HYDRATE_TEXT = true;
30
- currentPath.operation = true;
31
- currentPath.isString = (typeof value === 'string');
32
- ElementCreator.bindTextNode(textNode, (currentPath.isString ? data[0][value] : value.apply(null, data)));
33
- return textNode;
8
+ const assignClonerToNode = ($node) => {
9
+ const childNodes = $node.childNodes;
10
+ let containDynamicNode = !!$node.nodeCloner;
11
+ const childNodesLength = childNodes.length;
12
+ for(let i = 0; i < childNodesLength; i++) {
13
+ const child = childNodes[i];
14
+ if(child.nodeCloner) {
15
+ containDynamicNode = true;
34
16
  }
35
- return node.cloneNode(true);
36
- }
37
- const nodeCloned = node.cloneNode();
38
- if(bindDingData) {
39
- const hydrator = getHydrator(bindDingData);
40
- hydrator(nodeCloned, bindDingData, data);
41
- bindAttachMethods(nodeCloned, bindDingData, data);
42
-
43
- const hasAttributes = bindDingData.classes || bindDingData.styles || bindDingData.attributes;
44
- const hasAttachMethods = bindDingData.attach.length;
45
-
46
- currentPath.bindingData = bindDingData;
47
- currentPath.hydrator = hydrator;
48
-
49
- if(hasAttributes) {
50
- currentPath.HYDRATE_ATTRIBUTES = true;
51
- currentPath.operation = true;
52
- }
53
- if(hasAttachMethods) {
54
- currentPath.ATTACH_METHOD = true;
55
- currentPath.operation = true;
17
+ const localContainDynamicNode = assignClonerToNode(child);
18
+ if(localContainDynamicNode) {
19
+ containDynamicNode = true;
56
20
  }
57
21
  }
58
- const childNodes = node.childNodes;
59
- const parentId = currentPath.id;
60
22
 
61
- for(let i = 0, length = childNodes.length; i < length; i++) {
62
- const childNode = childNodes[i];
63
- const path = { parentId, id: ++pathCounter, index: i };
64
- const childNodeCloned = clone(childNode, data, path);
65
- if(path.hasChildren || path.operation) {
66
- $bindingTreePath.push(path);
67
- currentPath.hasChildren = true;
23
+ if(!containDynamicNode) {
24
+ $node.dynamicCloneNode = $node.cloneNode.bind($node, true);
25
+ } else {
26
+ if($node.nodeCloner) {
27
+ $node.nodeCloner.resolve();
28
+ $node.dynamicCloneNode = (data) => {
29
+ const clonedNode = $node.nodeCloner.cloneNode(data);
30
+ for(let i = 0; i < childNodesLength; i++) {
31
+ const child = childNodes[i].dynamicCloneNode(data);
32
+ clonedNode.appendChild(child);
33
+ }
34
+ return clonedNode;
35
+ };
36
+ } else {
37
+ $node.dynamicCloneNode = (data) => {
38
+ const clonedNode = $node.cloneNode();
39
+ for(let i = 0; i < childNodesLength; i++) {
40
+ const child = childNodes[i].dynamicCloneNode(data);
41
+ clonedNode.appendChild(child);
42
+ }
43
+ return clonedNode;
44
+ };
68
45
  }
69
- nodeCloned.appendChild(childNodeCloned);
70
46
  }
71
- return nodeCloned;
72
- };
73
-
74
- const cloneWithBindingPaths = (data) => {
75
- let root = $node.cloneNode(true);
76
47
 
77
- hydrateClonedNode(root, data, $bindingTreePath, $bindingTreePathSize);
78
- return root;
48
+ return containDynamicNode;
79
49
  };
80
50
 
81
51
  this.clone = (data) => {
82
52
  const binder = createTemplateCloner(this);
83
53
  $node = $fn(binder);
84
- if(!$hasBindingData) {
85
- this.clone = () => $node.cloneNode(true);
86
- return $node.cloneNode(true);
54
+ if(!$node.nodeCloner) {
55
+ $node.nodeCloner = new NodeCloner($node);
87
56
  }
88
-
89
- const firstClone = clone($node, data, $bindingTreePath[0]);
90
- $bindingTreePath.reverse();
91
- $bindingTreePathSize = $bindingTreePath.length - 1;
92
-
93
- this.clone = cloneWithBindingPaths;
94
- return firstClone;
57
+ assignClonerToNode($node);
58
+ this.clone = $node.dynamicCloneNode;
59
+ return $node.dynamicCloneNode(data);
95
60
  };
96
61
 
97
62
 
98
63
  const createBinding = (hydrateFunction, targetType) => {
99
64
  return new TemplateBinding((element, property) => {
100
- $hasBindingData = true;
101
65
  $hydrateFn(hydrateFunction, targetType, element, property)
102
66
  });
103
67
  };
104
68
 
105
69
  this.style = (fn) => {
106
- return createBinding(fn, 'styles');
70
+ return createBinding(fn, 'style');
107
71
  };
108
72
  this.class = (fn) => {
109
- return createBinding(fn, 'classes');
73
+ return createBinding(fn, 'class');
110
74
  };
111
75
  this.property = (propertyName) => {
112
76
  return this.value(propertyName);
@@ -143,10 +107,9 @@ export function useCache(fn) {
143
107
  let wrapper = (args) => {
144
108
  $cache = new TemplateCloner(fn);
145
109
 
146
- wrapper = (args) => {
147
- return $cache.clone(args);
148
- };
149
- return $cache.clone(args);
110
+ const node = $cache.clone(args);
111
+ wrapper = $cache.clone;
112
+ return node;
150
113
  };
151
114
 
152
115
  if(fn.length < 2) {
@@ -1,7 +1,5 @@
1
1
  import { ElementCreator } from "../ElementCreator";
2
-
3
-
4
- export const cloneBindingsDataCache = new WeakMap();
2
+ import NodeCloner from "./NodeCloner";
5
3
 
6
4
  const pathProcess = (target, path, data) => {
7
5
  if(path.HYDRATE_TEXT) {
@@ -74,23 +72,17 @@ const prepareBindingMetadata = (bindDingData) => {
74
72
  };
75
73
 
76
74
 
77
- export const $hydrateFn = function(hydrateFunction, targetType, element, property) {
78
- if(!cloneBindingsDataCache.has(element)) {
79
- cloneBindingsDataCache.set(element, { attach: [] });
80
- }
81
- const hydrationState = cloneBindingsDataCache.get(element);
82
-
75
+ export const $hydrateFn = function(value, targetType, element, property) {
76
+ element.nodeCloner = element.nodeCloner || new NodeCloner(element);
83
77
  if(targetType === 'value') {
84
- hydrationState.value = hydrateFunction;
78
+ element.nodeCloner.text(value);
85
79
  return;
86
80
  }
87
81
  if(targetType === 'attach') {
88
- hydrationState.attach = hydrationState.attach || [];
89
- hydrationState.attach.push({ methodName: property, fn: hydrateFunction});
82
+ element.nodeCloner.attach(property, value);
90
83
  return;
91
84
  }
92
- hydrationState[targetType] = hydrationState[targetType] || {};
93
- hydrationState[targetType][property] = hydrateFunction;
85
+ element.nodeCloner.attr(targetType, { property, value });
94
86
  };
95
87
 
96
88
  export const bindAttachMethods = (node, bindDingData, data) => {