native-document 1.0.79 → 1.0.81

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.
@@ -37,8 +37,18 @@ export function updateObserverFromInput(element, attributeName, defaultValue, va
37
37
  export function bindClassAttribute(element, data) {
38
38
  for(let className in data) {
39
39
  const value = data[className];
40
- if(value?.bindNdClass) {
41
- value.bindNdClass(element, className);
40
+ if(Validator.isObservable(value)) {
41
+ element.classes.toggle(className, value.val());
42
+ value.subscribe(toggleElementClass.bind(null, element, className));
43
+ continue;
44
+ }
45
+ if(Validator.isObservableWhenResult(value)) {
46
+ element.classes.toggle(className, value.isMath());
47
+ value.subscribe(toggleElementClass.bind(null, element, className));
48
+ continue;
49
+ }
50
+ if(value.$hydrate) {
51
+ value.$hydrate(element, className);
42
52
  continue;
43
53
  }
44
54
  element.classes.toggle(className, value)
@@ -108,12 +118,6 @@ export function bindAttributeWithObservable(element, attributeName, value) {
108
118
  }
109
119
  }
110
120
 
111
- const NdBindings = {
112
- class: (element, value) => bindClassAttribute(element, value),
113
- style: (element, value) => bindStyleAttribute(element, value),
114
- };
115
-
116
-
117
121
  /**
118
122
  *
119
123
  * @param {HTMLElement} element
@@ -129,7 +133,7 @@ export default function AttributesWrapper(element, attributes) {
129
133
 
130
134
  for(let key in attributes) {
131
135
  const attributeName = key.toLowerCase();
132
- let value = attributes[key];
136
+ let value = attributes[attributeName];
133
137
  if(value == null) {
134
138
  continue;
135
139
  }
@@ -137,10 +141,13 @@ export default function AttributesWrapper(element, attributes) {
137
141
  value.handleNdAttribute(element, attributeName, value)
138
142
  continue;
139
143
  }
140
- if(typeof value === 'object') {
141
- const binding = NdBindings[attributeName];
142
- if(binding) {
143
- binding(element, value);
144
+ if(typeof value === 'object') {
145
+ if(attributeName === 'class') {
146
+ bindClassAttribute(element, value);
147
+ continue;
148
+ }
149
+ if(attributeName === 'style') {
150
+ bindStyleAttribute(element, value);
144
151
  continue;
145
152
  }
146
153
  }
@@ -83,14 +83,19 @@ export const ElementCreator = {
83
83
  PluginsManager.emit('AfterProcessChildren', parent);
84
84
  },
85
85
  getChild(child) {
86
- while (child?.toNdElement) {
87
- child = child.toNdElement();
88
-
89
- if (Validator.isElement(child)) return child;
90
- if (!child) return null;
86
+ if(child == null) {
87
+ return null;
88
+ }
89
+ if(child.toNdElement) {
90
+ do {
91
+ child = child.toNdElement();
92
+ if(Validator.isElement(child)) {
93
+ return child;
94
+ }
95
+ } while (child.toNdElement);
91
96
  }
92
97
 
93
- return child ? ElementCreator.createStaticTextNode(null, child) : null;
98
+ return ElementCreator.createStaticTextNode(null, child);
94
99
  },
95
100
  /**
96
101
  *
@@ -38,14 +38,6 @@ const bindAttributes = (node, bindDingData, data) => {
38
38
  return null;
39
39
  };
40
40
 
41
- const findByPath = (root, path) => {
42
- let target = root;
43
- for (let i = 0, len = path.length; i < len; i++) {
44
- target = target.childNodes[path[i]];
45
- }
46
- return target;
47
- };
48
-
49
41
  const $hydrateFn = function(hydrateFunction, targetType, element, property) {
50
42
  if(!cloneBindingsDataCache.has(element)) {
51
43
  // { classes, styles, attributes, value, attach }
@@ -71,27 +63,43 @@ const bindAttachMethods = function(node, bindDingData, data) {
71
63
  }
72
64
  };
73
65
 
66
+
67
+ const applyBindingTreePath = (root, target, data, path) => {
68
+ let newTarget = null;
69
+ if(path.fn) {
70
+ newTarget = path.fn(data, target, root);
71
+ }
72
+ if(path.children) {
73
+ for(let i = 0, length = path.children.length; i < length; i++) {
74
+ const currentPath = path.children[i];
75
+ const pathTargetNode = target.childNodes[currentPath.index];
76
+ applyBindingTreePath(root, pathTargetNode, data, currentPath);
77
+ }
78
+ }
79
+ return newTarget;
80
+ };
81
+
74
82
  export function TemplateCloner($fn) {
75
83
  let $node = null;
76
84
  let $hasBindingData = false;
77
85
 
78
- const $bindingPaths = [];
86
+ const $bindingTreePath = {
87
+ fn: null,
88
+ children: [],
89
+ };
79
90
 
80
- const clone = (node, data, path) => {
91
+ const clone = (node, data, currentPath) => {
81
92
  const bindDingData = cloneBindingsDataCache.get(node);
82
93
  if(node.nodeType === 3) {
83
94
  if(bindDingData && bindDingData.value) {
84
- $bindingPaths.push({
85
- path: [...path],
86
- fn: (data, targetNode, currentRoot) => {
87
- const newNode = bindDingData.value(data);
88
- targetNode.replaceWith(newNode);
89
- if (targetNode === currentRoot) {
90
- return newNode;
91
- }
92
- return null;
95
+ currentPath.fn = (data, targetNode, currentRoot) => {
96
+ const newNode = bindDingData.value(data);
97
+ if (targetNode === currentRoot) {
98
+ return newNode;
93
99
  }
94
- });
100
+ targetNode.replaceWith(newNode);
101
+ return null;
102
+ };
95
103
  return bindDingData.value(data);
96
104
  }
97
105
  return node.cloneNode(true);
@@ -103,35 +111,35 @@ export function TemplateCloner($fn) {
103
111
  if(bindDingData) {
104
112
  bindAttributes(nodeCloned, bindDingData, data);
105
113
  bindAttachMethods(nodeCloned, bindDingData, data);
106
- $bindingPaths.push({
107
- path: [...path],
108
- fn: (data, targetNode) => {
109
- bindAttributes(targetNode, bindDingData, data);
110
- bindAttachMethods(targetNode, bindDingData, data);
111
- }
112
- })
114
+ currentPath.fn = (data, targetNode) => {
115
+ bindAttributes(targetNode, bindDingData, data);
116
+ bindAttachMethods(targetNode, bindDingData, data);
117
+ };
113
118
  }
114
119
  const childNodes = node.childNodes;
120
+ const bindingPathChildren = [];
115
121
  for(let i = 0, length = childNodes.length; i < length; i++) {
116
122
  const childNode = childNodes[i];
117
- path.push(i);
123
+ const path = { index: i, fn: null };
118
124
  const childNodeCloned = clone(childNode, data, path);
119
- path.pop();
125
+ if(path.children || path.fn) {
126
+ bindingPathChildren.push(path);
127
+ }
120
128
  nodeCloned.appendChild(childNodeCloned);
121
129
  }
130
+ if(bindingPathChildren.length) {
131
+ currentPath.children = currentPath.children || [];
132
+ currentPath.children = bindingPathChildren;
133
+ }
122
134
  return nodeCloned;
123
135
  };
124
136
 
125
137
  const cloneWithBindingPaths = (data) => {
126
138
  let root = $node.cloneNode(true);
127
139
 
128
- for (let i = 0, len = $bindingPaths.length; i < len; i++) {
129
- const binding = $bindingPaths[i];
130
- const target = findByPath(root, binding.path);
131
- const newRoot = binding.fn(data, target, root);
132
- if(newRoot) {
133
- root = newRoot;
134
- }
140
+ const newRoot = applyBindingTreePath(root, root, data, $bindingTreePath);
141
+ if(newRoot) {
142
+ root = newRoot;
135
143
  }
136
144
 
137
145
  return root;
@@ -144,7 +152,7 @@ export function TemplateCloner($fn) {
144
152
  return $node.cloneNode(true);
145
153
  }
146
154
 
147
- const firstClone = clone($node, data, []);
155
+ const firstClone = clone($node, data, $bindingTreePath);
148
156
  this.clone = cloneWithBindingPaths;
149
157
  return firstClone;
150
158
  };
@@ -8,14 +8,6 @@ String.prototype.handleNdAttribute = function(element, attributeName) {
8
8
  element.setAttribute(attributeName, this);
9
9
  };
10
10
 
11
- Number.prototype.handleNdAttribute = function(element, attributeName) {
12
- element.setAttribute(attributeName, this);
13
- };
14
-
15
- Boolean.prototype.handleNdAttribute = function(element, attrName) {
16
- bindBooleanAttribute(element, attrName, this);
17
- };
18
-
19
11
  ObservableItem.prototype.handleNdAttribute = function(element, attributeName) {
20
12
  if(BOOLEAN_ATTRIBUTES.has(attributeName)) {
21
13
  bindBooleanAttribute(element, attributeName, this);