native-document 1.0.109 → 1.0.110
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Anchor from "../elements/anchor";
|
|
2
2
|
import Validator from "../utils/validator";
|
|
3
|
-
import AttributesWrapper from "./AttributesWrapper";
|
|
3
|
+
import AttributesWrapper, { bindClassAttribute, bindStyleAttribute } from "./AttributesWrapper";
|
|
4
4
|
import PluginsManager from "../utils/plugins-manager";
|
|
5
5
|
import './prototypes/nd-element-extensions';
|
|
6
6
|
import './prototypes/nd-element.transition.extensions';
|
|
@@ -124,5 +124,13 @@ export const ElementCreator = {
|
|
|
124
124
|
if (attributes) {
|
|
125
125
|
AttributesWrapper(element, attributes);
|
|
126
126
|
}
|
|
127
|
-
}
|
|
127
|
+
},
|
|
128
|
+
/**
|
|
129
|
+
*
|
|
130
|
+
* @param {HTMLElement} element
|
|
131
|
+
* @param {Object} attributes
|
|
132
|
+
*/
|
|
133
|
+
processAttributesDirect: AttributesWrapper,
|
|
134
|
+
processClassAttribute: bindClassAttribute,
|
|
135
|
+
processStyleAttribute: bindStyleAttribute,
|
|
128
136
|
};
|
|
@@ -3,6 +3,12 @@ import TemplateBinding from "./TemplateBinding";
|
|
|
3
3
|
|
|
4
4
|
const cloneBindingsDataCache = new WeakMap();
|
|
5
5
|
|
|
6
|
+
const OPERATIONS = {
|
|
7
|
+
HYDRATE_TEXT: 1,
|
|
8
|
+
ATTACH_METHOD: 2,
|
|
9
|
+
HYDRATE_ATTRIBUTES: 3,
|
|
10
|
+
HYDRATE_FULL: 4,
|
|
11
|
+
};
|
|
6
12
|
|
|
7
13
|
const hydrateFull = (node, bindDingData, data) => {
|
|
8
14
|
const cacheAttributes = bindDingData._cache;
|
|
@@ -29,7 +35,32 @@ const hydrateDynamic = (node, bindDingData, data) => {
|
|
|
29
35
|
cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
ElementCreator.
|
|
38
|
+
ElementCreator.processClassAttribute(node, cacheAttributes.class);
|
|
39
|
+
ElementCreator.processStyleAttribute(node, cacheAttributes.style);
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const hydrateClassAttribute = (node, bindDingData, data) => {
|
|
44
|
+
const classAttributes = bindDingData._cache.class;
|
|
45
|
+
|
|
46
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
47
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
48
|
+
classAttributes[dyn.key] = dyn.value.apply(null, data);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ElementCreator.processClassAttribute(node, classAttributes);
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const hydrateStyleAttribute = (node, bindDingData, data) => {
|
|
56
|
+
const styleAttributes = bindDingData._cache;
|
|
57
|
+
|
|
58
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
59
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
60
|
+
styleAttributes[dyn.key] = dyn.value.apply(null, data);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
ElementCreator.processStyleAttribute(node, styleAttributes);
|
|
33
64
|
return true;
|
|
34
65
|
};
|
|
35
66
|
|
|
@@ -55,7 +86,13 @@ const getHydrator = (bindDingData) => {
|
|
|
55
86
|
if(bindDingData._flatAttributesLength) {
|
|
56
87
|
return hydrateAttributes;
|
|
57
88
|
}
|
|
58
|
-
|
|
89
|
+
if(bindDingData._hasClassAttribute && bindDingData._hasStyleAttribute) {
|
|
90
|
+
return hydrateDynamic;
|
|
91
|
+
}
|
|
92
|
+
if(bindDingData._hasClassAttribute) {
|
|
93
|
+
return hydrateClassAttribute;
|
|
94
|
+
}
|
|
95
|
+
return hydrateStyleAttribute;
|
|
59
96
|
};
|
|
60
97
|
|
|
61
98
|
const $hydrateFn = function(hydrateFunction, targetType, element, property) {
|
|
@@ -81,29 +118,50 @@ const bindAttachMethods = (node, bindDingData, data) => {
|
|
|
81
118
|
for(let i = 0, length = bindDingData._attachLength; i < length; i++) {
|
|
82
119
|
const method = bindDingData.attach[i];
|
|
83
120
|
node.nd[method.methodName](function() {
|
|
84
|
-
method.fn.call(this, ...
|
|
121
|
+
method.fn.call(this, ...data, ...arguments);
|
|
85
122
|
});
|
|
86
123
|
}
|
|
87
124
|
};
|
|
88
125
|
|
|
89
126
|
|
|
90
127
|
const $applyBindingParents = [];
|
|
128
|
+
const pathProcess = (target, path, data) => {
|
|
129
|
+
if(path.operation === OPERATIONS.HYDRATE_TEXT) {
|
|
130
|
+
const value = path.value;
|
|
131
|
+
ElementCreator.bindTextNode(target, path.isString ? data[0][value] : value.apply(null, data));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if(path.operation === OPERATIONS.ATTACH_METHOD || path.operation === OPERATIONS.HYDRATE_FULL) {
|
|
135
|
+
const bindingData = path.bindingData;
|
|
136
|
+
for(let i = 0, length = bindingData._attachLength; i < length; i++) {
|
|
137
|
+
const method = bindingData.attach[i];
|
|
138
|
+
target.nd[method.methodName](function() {
|
|
139
|
+
method.fn.call(this, ...data, ...arguments);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if(path.operation === OPERATIONS.HYDRATE_ATTRIBUTES || path.operation === OPERATIONS.HYDRATE_FULL) {
|
|
144
|
+
path.hydrator(target, path.bindingData, data);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
91
148
|
const applyBindingTreePath = (root, data, paths, pathSize) => {
|
|
92
|
-
const rootPath = paths
|
|
149
|
+
const rootPath = paths[pathSize];
|
|
93
150
|
$applyBindingParents[rootPath.id] = root;
|
|
94
|
-
|
|
95
|
-
rootPathFn(data, root, root);
|
|
96
|
-
|
|
151
|
+
pathProcess(root, rootPath, data);
|
|
97
152
|
|
|
153
|
+
let target = null, path = null;
|
|
98
154
|
for(let i = 0; i < pathSize; i++) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
155
|
+
path = paths[i];
|
|
156
|
+
target = $applyBindingParents[path.parentId].childNodes[path.index];
|
|
102
157
|
$applyBindingParents[path.id] = target;
|
|
103
|
-
|
|
104
|
-
|
|
158
|
+
|
|
159
|
+
pathProcess(target, path, data);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
for (let i = 0; i <= pathSize; i++) {
|
|
163
|
+
$applyBindingParents[i] = null;
|
|
105
164
|
}
|
|
106
|
-
$applyBindingParents.length = 0;
|
|
107
165
|
};
|
|
108
166
|
const buildAttributesCache = (bindDingData) => {
|
|
109
167
|
const cache = { };
|
|
@@ -128,6 +186,7 @@ const prepareBindingMetadata = (bindDingData) => {
|
|
|
128
186
|
|
|
129
187
|
if(bindDingData.classes) {
|
|
130
188
|
for (const className in bindDingData.classes) {
|
|
189
|
+
bindDingData._hasClassAttribute = true;
|
|
131
190
|
classAndStyles.push({
|
|
132
191
|
name: 'class',
|
|
133
192
|
key: className,
|
|
@@ -138,6 +197,7 @@ const prepareBindingMetadata = (bindDingData) => {
|
|
|
138
197
|
|
|
139
198
|
if(bindDingData.styles) {
|
|
140
199
|
for (const property in bindDingData.styles) {
|
|
200
|
+
bindDingData._hasStyleAttribute = true;
|
|
141
201
|
classAndStyles.push({
|
|
142
202
|
name: 'style',
|
|
143
203
|
key: property,
|
|
@@ -154,9 +214,6 @@ const prepareBindingMetadata = (bindDingData) => {
|
|
|
154
214
|
};
|
|
155
215
|
|
|
156
216
|
const optimizeBindingData = (bindDingData) => {
|
|
157
|
-
if(!bindDingData) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
217
|
buildAttributesCache(bindDingData);
|
|
161
218
|
prepareBindingMetadata(bindDingData);
|
|
162
219
|
};
|
|
@@ -170,24 +227,24 @@ export function TemplateCloner($fn) {
|
|
|
170
227
|
const $bindingTreePath = [
|
|
171
228
|
{
|
|
172
229
|
id: 0,
|
|
173
|
-
parentId: null
|
|
174
|
-
fn: noUpdate,
|
|
230
|
+
parentId: null
|
|
175
231
|
}
|
|
176
232
|
];
|
|
177
233
|
|
|
178
234
|
let pathCounter = 0;
|
|
179
235
|
const clone = (node, data, currentPath) => {
|
|
180
236
|
const bindDingData = cloneBindingsDataCache.get(node);
|
|
181
|
-
|
|
237
|
+
if(bindDingData) {
|
|
238
|
+
optimizeBindingData(bindDingData);
|
|
239
|
+
}
|
|
182
240
|
if(node.nodeType === 3) {
|
|
183
241
|
if(bindDingData && bindDingData.value) {
|
|
184
|
-
|
|
242
|
+
const value = bindDingData.value;
|
|
185
243
|
const textNode = node.cloneNode();
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
bindDingData.value(data, textNode);
|
|
244
|
+
currentPath.value = value;
|
|
245
|
+
currentPath.operation = OPERATIONS.HYDRATE_TEXT;
|
|
246
|
+
currentPath.isString = (typeof value === 'string');
|
|
247
|
+
ElementCreator.bindTextNode(textNode, (currentPath.isString ? data[0][value] : value.apply(null, data)));
|
|
191
248
|
return textNode;
|
|
192
249
|
}
|
|
193
250
|
return node.cloneNode(true);
|
|
@@ -201,22 +258,17 @@ export function TemplateCloner($fn) {
|
|
|
201
258
|
const hasAttributes = bindDingData.classes || bindDingData.styles || bindDingData.attributes;
|
|
202
259
|
const hasAttachMethods = bindDingData.attach.length;
|
|
203
260
|
|
|
204
|
-
currentPath.
|
|
261
|
+
currentPath.bindingData = bindDingData;
|
|
262
|
+
currentPath.hydrator = hydrator;
|
|
263
|
+
|
|
205
264
|
if(hasAttributes && hasAttachMethods) {
|
|
206
|
-
currentPath.
|
|
207
|
-
hydrator(targetNode, bindDingData, data);
|
|
208
|
-
bindAttachMethods(targetNode, bindDingData, data);
|
|
209
|
-
};
|
|
265
|
+
currentPath.operation = OPERATIONS.HYDRATE_FULL;
|
|
210
266
|
}
|
|
211
267
|
else if(hasAttributes) {
|
|
212
|
-
currentPath.
|
|
213
|
-
hydrator(targetNode, bindDingData, data);
|
|
214
|
-
};
|
|
268
|
+
currentPath.operation = OPERATIONS.HYDRATE_ATTRIBUTES;
|
|
215
269
|
}
|
|
216
270
|
else if(hasAttachMethods) {
|
|
217
|
-
currentPath.
|
|
218
|
-
bindAttachMethods(targetNode, bindDingData, data);
|
|
219
|
-
};
|
|
271
|
+
currentPath.operation = OPERATIONS.ATTACH_METHOD;
|
|
220
272
|
}
|
|
221
273
|
}
|
|
222
274
|
const childNodes = node.childNodes;
|
|
@@ -224,9 +276,9 @@ export function TemplateCloner($fn) {
|
|
|
224
276
|
|
|
225
277
|
for(let i = 0, length = childNodes.length; i < length; i++) {
|
|
226
278
|
const childNode = childNodes[i];
|
|
227
|
-
const path = { parentId, id: ++pathCounter, index: i
|
|
279
|
+
const path = { parentId, id: ++pathCounter, index: i };
|
|
228
280
|
const childNodeCloned = clone(childNode, data, path);
|
|
229
|
-
if(path.hasChildren || path.
|
|
281
|
+
if(path.hasChildren || path.operation) {
|
|
230
282
|
$bindingTreePath.push(path);
|
|
231
283
|
currentPath.hasChildren = true;
|
|
232
284
|
}
|
|
@@ -243,7 +295,8 @@ export function TemplateCloner($fn) {
|
|
|
243
295
|
};
|
|
244
296
|
|
|
245
297
|
this.clone = (data) => {
|
|
246
|
-
|
|
298
|
+
const binder = createTemplateCloner(this);
|
|
299
|
+
$node = $fn(binder);
|
|
247
300
|
if(!$hasBindingData) {
|
|
248
301
|
this.clone = () => $node.cloneNode(true);
|
|
249
302
|
return $node.cloneNode(true);
|
|
@@ -275,14 +328,7 @@ export function TemplateCloner($fn) {
|
|
|
275
328
|
return this.value(propertyName);
|
|
276
329
|
}
|
|
277
330
|
this.value = (callbackOrProperty) => {
|
|
278
|
-
|
|
279
|
-
return createBinding((data, textNode) => {
|
|
280
|
-
ElementCreator.bindTextNode(textNode, data[0][callbackOrProperty]);
|
|
281
|
-
}, 'value');
|
|
282
|
-
}
|
|
283
|
-
return createBinding((data, textNode) => {
|
|
284
|
-
ElementCreator.bindTextNode(textNode, callbackOrProperty(...data));
|
|
285
|
-
}, 'value');
|
|
331
|
+
return createBinding(callbackOrProperty, 'value');
|
|
286
332
|
};
|
|
287
333
|
this.text = this.value;
|
|
288
334
|
this.attr = (fn) => {
|
|
@@ -295,11 +341,24 @@ export function TemplateCloner($fn) {
|
|
|
295
341
|
|
|
296
342
|
}
|
|
297
343
|
|
|
344
|
+
function createTemplateCloner($binder) {
|
|
345
|
+
return new Proxy($binder, {
|
|
346
|
+
get(target, prop) {
|
|
347
|
+
if(prop in target) {
|
|
348
|
+
return target[prop];
|
|
349
|
+
}
|
|
350
|
+
if (typeof prop === 'symbol') return target[prop];
|
|
351
|
+
return target.value(prop);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
298
356
|
export function useCache(fn) {
|
|
299
357
|
let $cache = null;
|
|
300
358
|
|
|
301
359
|
let wrapper = function(args) {
|
|
302
360
|
$cache = new TemplateCloner(fn);
|
|
361
|
+
|
|
303
362
|
wrapper = function(args) {
|
|
304
363
|
return $cache.clone(args);
|
|
305
364
|
};
|