native-document 1.0.107 → 1.0.109
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/dist/native-document.components.min.js +27 -19
- package/dist/native-document.dev.js +110 -64
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.min.js +1 -1
- package/package.json +1 -1
- package/src/core/utils/validator.js +5 -6
- package/src/core/wrappers/AttributesWrapper.js +3 -1
- package/src/core/wrappers/NDElement.js +12 -8
- package/src/core/wrappers/TemplateCloner.js +177 -67
- package/src/core/wrappers/prototypes/nd-element-extensions.js +0 -1
- package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +15 -11
- package/src/router/Router.js +11 -0
- package/src/router/RouterComponent.js +2 -1
- package/types/template-cloner.ts +1 -0
|
@@ -4,94 +4,181 @@ import TemplateBinding from "./TemplateBinding";
|
|
|
4
4
|
const cloneBindingsDataCache = new WeakMap();
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
7
|
+
const hydrateFull = (node, bindDingData, data) => {
|
|
8
|
+
const cacheAttributes = bindDingData._cache;
|
|
9
|
+
|
|
10
|
+
for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
|
|
11
|
+
const attr = bindDingData._flatAttributes[i];
|
|
12
|
+
cacheAttributes[attr.name] = attr.value.apply(null, data);
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
for (const className in bindDingData.classes) {
|
|
20
|
-
attributes.class[className] = bindDingData.classes[className].apply(null, data);
|
|
21
|
-
}
|
|
15
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
16
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
17
|
+
cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
|
|
22
18
|
}
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
ElementCreator.processAttributesDirect(node, cacheAttributes);
|
|
21
|
+
return true;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const hydrateDynamic = (node, bindDingData, data) => {
|
|
25
|
+
const cacheAttributes = bindDingData._cache;
|
|
26
|
+
|
|
27
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
28
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
29
|
+
cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
ElementCreator.processAttributesDirect(node, cacheAttributes);
|
|
33
|
+
return true;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const hydrateAttributes = (node, bindDingData, data) => {
|
|
37
|
+
const cacheAttributes = bindDingData._cache;
|
|
38
|
+
|
|
39
|
+
for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
|
|
40
|
+
const attr = bindDingData._flatAttributes[i];
|
|
41
|
+
cacheAttributes[attr.name] = attr.value.apply(null, data);
|
|
35
42
|
}
|
|
36
43
|
|
|
37
|
-
|
|
44
|
+
ElementCreator.processAttributesDirect(node, cacheAttributes);
|
|
45
|
+
return true;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const getHydrator = (bindDingData) => {
|
|
49
|
+
if(!bindDingData._cache) {
|
|
50
|
+
return noUpdate;
|
|
51
|
+
}
|
|
52
|
+
if(bindDingData._flatAttributesLength && bindDingData._flatDynamiqueLength) {
|
|
53
|
+
return hydrateFull;
|
|
54
|
+
}
|
|
55
|
+
if(bindDingData._flatAttributesLength) {
|
|
56
|
+
return hydrateAttributes;
|
|
57
|
+
}
|
|
58
|
+
return hydrateDynamic;
|
|
38
59
|
};
|
|
39
60
|
|
|
40
61
|
const $hydrateFn = function(hydrateFunction, targetType, element, property) {
|
|
41
62
|
if(!cloneBindingsDataCache.has(element)) {
|
|
42
|
-
|
|
43
|
-
cloneBindingsDataCache.set(element, {});
|
|
63
|
+
cloneBindingsDataCache.set(element, { attach: [] });
|
|
44
64
|
}
|
|
45
65
|
const hydrationState = cloneBindingsDataCache.get(element);
|
|
66
|
+
|
|
46
67
|
if(targetType === 'value') {
|
|
47
68
|
hydrationState.value = hydrateFunction;
|
|
48
69
|
return;
|
|
49
70
|
}
|
|
71
|
+
if(targetType === 'attach') {
|
|
72
|
+
hydrationState.attach = hydrationState.attach || [];
|
|
73
|
+
hydrationState.attach.push({ methodName: property, fn: hydrateFunction});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
50
76
|
hydrationState[targetType] = hydrationState[targetType] || {};
|
|
51
77
|
hydrationState[targetType][property] = hydrateFunction;
|
|
52
|
-
}
|
|
78
|
+
};
|
|
53
79
|
|
|
54
80
|
const bindAttachMethods = (node, bindDingData, data) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
node.nd[methodName](function(...args) {
|
|
60
|
-
bindDingData.attach[methodName].apply(this, [...args, ...data]);
|
|
81
|
+
for(let i = 0, length = bindDingData._attachLength; i < length; i++) {
|
|
82
|
+
const method = bindDingData.attach[i];
|
|
83
|
+
node.nd[method.methodName](function() {
|
|
84
|
+
method.fn.call(this, ...arguments, ...data);
|
|
61
85
|
});
|
|
62
86
|
}
|
|
63
87
|
};
|
|
64
88
|
|
|
65
89
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
90
|
+
const $applyBindingParents = [];
|
|
91
|
+
const applyBindingTreePath = (root, data, paths, pathSize) => {
|
|
92
|
+
const rootPath = paths.at(-1);
|
|
93
|
+
$applyBindingParents[rootPath.id] = root;
|
|
94
|
+
const rootPathFn = rootPath.fn;
|
|
95
|
+
rootPathFn(data, root, root);
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
for(let i = 0; i < pathSize; i++) {
|
|
99
|
+
const path = paths[i];
|
|
100
|
+
const target = $applyBindingParents[path.parentId].childNodes[path.index];
|
|
101
|
+
|
|
102
|
+
$applyBindingParents[path.id] = target;
|
|
103
|
+
const pathFn = path.fn;
|
|
104
|
+
pathFn(data, target, root);
|
|
105
|
+
}
|
|
106
|
+
$applyBindingParents.length = 0;
|
|
107
|
+
};
|
|
108
|
+
const buildAttributesCache = (bindDingData) => {
|
|
109
|
+
const cache = { };
|
|
110
|
+
if(bindDingData.attributes) cache.attributes = {};
|
|
111
|
+
if(bindDingData.classes) cache.class = {};
|
|
112
|
+
if(bindDingData.styles) cache.style = {};
|
|
113
|
+
bindDingData._cache = cache;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const prepareBindingMetadata = (bindDingData) => {
|
|
117
|
+
const attributes = [];
|
|
118
|
+
const classAndStyles = [];
|
|
119
|
+
|
|
120
|
+
if(bindDingData.attributes) {
|
|
121
|
+
for (const attr in bindDingData.attributes) {
|
|
122
|
+
attributes.push({
|
|
123
|
+
name: attr,
|
|
124
|
+
value: bindDingData.attributes[attr]
|
|
125
|
+
});
|
|
70
126
|
}
|
|
71
|
-
|
|
72
|
-
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if(bindDingData.classes) {
|
|
130
|
+
for (const className in bindDingData.classes) {
|
|
131
|
+
classAndStyles.push({
|
|
132
|
+
name: 'class',
|
|
133
|
+
key: className,
|
|
134
|
+
value: bindDingData.classes[className]
|
|
135
|
+
});
|
|
73
136
|
}
|
|
74
137
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
138
|
+
|
|
139
|
+
if(bindDingData.styles) {
|
|
140
|
+
for (const property in bindDingData.styles) {
|
|
141
|
+
classAndStyles.push({
|
|
142
|
+
name: 'style',
|
|
143
|
+
key: property,
|
|
144
|
+
value: bindDingData.styles[property]
|
|
145
|
+
});
|
|
80
146
|
}
|
|
81
147
|
}
|
|
148
|
+
|
|
149
|
+
bindDingData._flatAttributes = attributes;
|
|
150
|
+
bindDingData._flatAttributesLength = attributes.length;
|
|
151
|
+
bindDingData._flatDynamique = classAndStyles;
|
|
152
|
+
bindDingData._flatDynamiqueLength = classAndStyles.length;
|
|
153
|
+
bindDingData._attachLength = bindDingData.attach.length;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const optimizeBindingData = (bindDingData) => {
|
|
157
|
+
if(!bindDingData) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
buildAttributesCache(bindDingData);
|
|
161
|
+
prepareBindingMetadata(bindDingData);
|
|
82
162
|
};
|
|
83
163
|
|
|
164
|
+
const noUpdate = () => {};
|
|
84
165
|
export function TemplateCloner($fn) {
|
|
85
166
|
let $node = null;
|
|
86
167
|
let $hasBindingData = false;
|
|
87
168
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
169
|
+
let $bindingTreePathSize = 0;
|
|
170
|
+
const $bindingTreePath = [
|
|
171
|
+
{
|
|
172
|
+
id: 0,
|
|
173
|
+
parentId: null,
|
|
174
|
+
fn: noUpdate,
|
|
175
|
+
}
|
|
176
|
+
];
|
|
92
177
|
|
|
178
|
+
let pathCounter = 0;
|
|
93
179
|
const clone = (node, data, currentPath) => {
|
|
94
180
|
const bindDingData = cloneBindingsDataCache.get(node);
|
|
181
|
+
optimizeBindingData(bindDingData);
|
|
95
182
|
if(node.nodeType === 3) {
|
|
96
183
|
if(bindDingData && bindDingData.value) {
|
|
97
184
|
currentPath.fn = bindDingData.value;
|
|
@@ -107,35 +194,51 @@ export function TemplateCloner($fn) {
|
|
|
107
194
|
}
|
|
108
195
|
const nodeCloned = node.cloneNode();
|
|
109
196
|
if(bindDingData) {
|
|
110
|
-
|
|
197
|
+
const hydrator = getHydrator(bindDingData);
|
|
198
|
+
hydrator(nodeCloned, bindDingData, data);
|
|
111
199
|
bindAttachMethods(nodeCloned, bindDingData, data);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
200
|
+
|
|
201
|
+
const hasAttributes = bindDingData.classes || bindDingData.styles || bindDingData.attributes;
|
|
202
|
+
const hasAttachMethods = bindDingData.attach.length;
|
|
203
|
+
|
|
204
|
+
currentPath.fn = noUpdate;
|
|
205
|
+
if(hasAttributes && hasAttachMethods) {
|
|
206
|
+
currentPath.fn = (data, targetNode) => {
|
|
207
|
+
hydrator(targetNode, bindDingData, data);
|
|
208
|
+
bindAttachMethods(targetNode, bindDingData, data);
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
else if(hasAttributes) {
|
|
212
|
+
currentPath.fn = (data, targetNode) => {
|
|
213
|
+
hydrator(targetNode, bindDingData, data);
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
else if(hasAttachMethods) {
|
|
217
|
+
currentPath.fn = (data, targetNode) => {
|
|
218
|
+
bindAttachMethods(targetNode, bindDingData, data);
|
|
219
|
+
};
|
|
220
|
+
}
|
|
116
221
|
}
|
|
117
222
|
const childNodes = node.childNodes;
|
|
118
|
-
const
|
|
223
|
+
const parentId = currentPath.id;
|
|
224
|
+
|
|
119
225
|
for(let i = 0, length = childNodes.length; i < length; i++) {
|
|
120
226
|
const childNode = childNodes[i];
|
|
121
|
-
const path = { index: i, fn:
|
|
227
|
+
const path = { parentId, id: ++pathCounter, index: i, fn: noUpdate };
|
|
122
228
|
const childNodeCloned = clone(childNode, data, path);
|
|
123
|
-
if(path.
|
|
124
|
-
|
|
229
|
+
if(path.hasChildren || path.fn !== noUpdate) {
|
|
230
|
+
$bindingTreePath.push(path);
|
|
231
|
+
currentPath.hasChildren = true;
|
|
125
232
|
}
|
|
126
233
|
nodeCloned.appendChild(childNodeCloned);
|
|
127
234
|
}
|
|
128
|
-
if(bindingPathChildren.length) {
|
|
129
|
-
currentPath.children = currentPath.children || [];
|
|
130
|
-
currentPath.children = bindingPathChildren;
|
|
131
|
-
}
|
|
132
235
|
return nodeCloned;
|
|
133
236
|
};
|
|
134
237
|
|
|
135
238
|
const cloneWithBindingPaths = (data) => {
|
|
136
239
|
let root = $node.cloneNode(true);
|
|
137
240
|
|
|
138
|
-
applyBindingTreePath(root,
|
|
241
|
+
applyBindingTreePath(root, data, $bindingTreePath, $bindingTreePathSize);
|
|
139
242
|
return root;
|
|
140
243
|
};
|
|
141
244
|
|
|
@@ -146,7 +249,10 @@ export function TemplateCloner($fn) {
|
|
|
146
249
|
return $node.cloneNode(true);
|
|
147
250
|
}
|
|
148
251
|
|
|
149
|
-
const firstClone = clone($node, data, $bindingTreePath);
|
|
252
|
+
const firstClone = clone($node, data, $bindingTreePath[0]);
|
|
253
|
+
$bindingTreePath.reverse();
|
|
254
|
+
$bindingTreePathSize = $bindingTreePath.length - 1;
|
|
255
|
+
|
|
150
256
|
this.clone = cloneWithBindingPaths;
|
|
151
257
|
return firstClone;
|
|
152
258
|
};
|
|
@@ -170,7 +276,9 @@ export function TemplateCloner($fn) {
|
|
|
170
276
|
}
|
|
171
277
|
this.value = (callbackOrProperty) => {
|
|
172
278
|
if(typeof callbackOrProperty !== 'function') {
|
|
173
|
-
return createBinding(
|
|
279
|
+
return createBinding((data, textNode) => {
|
|
280
|
+
ElementCreator.bindTextNode(textNode, data[0][callbackOrProperty]);
|
|
281
|
+
}, 'value');
|
|
174
282
|
}
|
|
175
283
|
return createBinding((data, textNode) => {
|
|
176
284
|
ElementCreator.bindTextNode(textNode, callbackOrProperty(...data));
|
|
@@ -183,16 +291,18 @@ export function TemplateCloner($fn) {
|
|
|
183
291
|
this.attach = (fn) => {
|
|
184
292
|
return createBinding(fn, 'attach');
|
|
185
293
|
};
|
|
294
|
+
this.callback = this.attach;
|
|
186
295
|
|
|
187
296
|
}
|
|
188
297
|
|
|
189
298
|
export function useCache(fn) {
|
|
190
299
|
let $cache = null;
|
|
191
300
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
301
|
+
let wrapper = function(args) {
|
|
302
|
+
$cache = new TemplateCloner(fn);
|
|
303
|
+
wrapper = function(args) {
|
|
304
|
+
return $cache.clone(args);
|
|
305
|
+
};
|
|
196
306
|
return $cache.clone(args);
|
|
197
307
|
};
|
|
198
308
|
|
|
@@ -3,7 +3,6 @@ import {NDElement} from "../NDElement";
|
|
|
3
3
|
import TemplateBinding from "../TemplateBinding";
|
|
4
4
|
import {ElementCreator} from "../ElementCreator";
|
|
5
5
|
import PluginsManager from "../../utils/plugins-manager";
|
|
6
|
-
import Validator from "../../utils/validator";
|
|
7
6
|
import ObservableChecker from "../../data/ObservableChecker";
|
|
8
7
|
|
|
9
8
|
String.prototype.toNdElement = function () {
|
|
@@ -36,10 +36,11 @@ const waitForVisualEnd = (el, timeout = 1000) => {
|
|
|
36
36
|
|
|
37
37
|
NDElement.prototype.transitionOut = function(transitionName) {
|
|
38
38
|
const exitClass = transitionName + '-exit';
|
|
39
|
+
const el = this.$element;
|
|
39
40
|
this.beforeUnmount('transition-exit', async function() {
|
|
40
|
-
|
|
41
|
-
await waitForVisualEnd(
|
|
42
|
-
|
|
41
|
+
el.classes.add(exitClass);
|
|
42
|
+
await waitForVisualEnd(el);
|
|
43
|
+
el.classes.remove(exitClass);
|
|
43
44
|
});
|
|
44
45
|
return this;
|
|
45
46
|
};
|
|
@@ -48,16 +49,18 @@ NDElement.prototype.transitionIn = function(transitionName) {
|
|
|
48
49
|
const startClass = transitionName + '-enter-from';
|
|
49
50
|
const endClass = transitionName + '-enter-to';
|
|
50
51
|
|
|
51
|
-
this.$element
|
|
52
|
+
const el = this.$element;
|
|
53
|
+
|
|
54
|
+
el.classes.add(startClass);
|
|
52
55
|
|
|
53
56
|
this.mounted(() => {
|
|
54
57
|
requestAnimationFrame(() => {
|
|
55
58
|
requestAnimationFrame(() => {
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
el.classes.remove(startClass);
|
|
60
|
+
el.classes.add(endClass);
|
|
58
61
|
|
|
59
|
-
waitForVisualEnd(
|
|
60
|
-
|
|
62
|
+
waitForVisualEnd(el).then(() => {
|
|
63
|
+
el.classes.remove(endClass);
|
|
61
64
|
});
|
|
62
65
|
});
|
|
63
66
|
});
|
|
@@ -73,10 +76,11 @@ NDElement.prototype.transition = function (transitionName) {
|
|
|
73
76
|
};
|
|
74
77
|
|
|
75
78
|
NDElement.prototype.animate = function(animationName) {
|
|
76
|
-
this.$element
|
|
79
|
+
const el = this.$element;
|
|
80
|
+
el.classes.add(animationName);
|
|
77
81
|
|
|
78
|
-
waitForVisualEnd(
|
|
79
|
-
|
|
82
|
+
waitForVisualEnd(el).then(() => {
|
|
83
|
+
el.classes.remove(animationName);
|
|
80
84
|
});
|
|
81
85
|
|
|
82
86
|
return this;
|
package/src/router/Router.js
CHANGED
|
@@ -268,3 +268,14 @@ Router.forward = function(name = null) {
|
|
|
268
268
|
Router.back = function(name = null) {
|
|
269
269
|
return Router.get(name).back();
|
|
270
270
|
};
|
|
271
|
+
|
|
272
|
+
Router.redirectTo = function(pathOrRouteName, params = null, name = null) {
|
|
273
|
+
let target = pathOrRouteName;
|
|
274
|
+
const router = Router.get(name);
|
|
275
|
+
const route = router.resolve({ name: pathOrRouteName, params });
|
|
276
|
+
if(route) {
|
|
277
|
+
target = { name: pathOrRouteName, params}
|
|
278
|
+
}
|
|
279
|
+
console.log(target);
|
|
280
|
+
return router.push(target);
|
|
281
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Validator from "../core/utils/validator";
|
|
2
2
|
import {Anchor} from "../../elements";
|
|
3
|
+
import {ElementCreator} from "../core/wrappers/ElementCreator";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
*
|
|
@@ -73,7 +74,7 @@ export function RouterComponent(router, container) {
|
|
|
73
74
|
cleanContainer();
|
|
74
75
|
const anchor = getNodeAnchorForLayout(nodeToInsert, path);
|
|
75
76
|
|
|
76
|
-
$currentLayout = layout(anchor);
|
|
77
|
+
$currentLayout = ElementCreator.getChild(layout(anchor));
|
|
77
78
|
$layoutCache.set(nodeToInsert, $currentLayout);
|
|
78
79
|
container.appendChild($currentLayout);
|
|
79
80
|
}
|
package/types/template-cloner.ts
CHANGED
|
@@ -37,6 +37,7 @@ export declare class TemplateCloner {
|
|
|
37
37
|
property(fn: (...data: any[]) => any): BindingHydrator;
|
|
38
38
|
|
|
39
39
|
attach(fn: (element: Element, ...data: any[]) => void): BindingHydrator;
|
|
40
|
+
callback(fn: (element: Element, ...data: any[]) => void): BindingHydrator;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export declare function useCache(fn: TemplateBuilder): CachedTemplateFunction;
|