native-document 1.0.14 → 1.0.15

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.
Files changed (37) hide show
  1. package/dist/native-document.dev.js +1262 -839
  2. package/dist/native-document.min.js +1 -1
  3. package/docs/anchor.md +216 -53
  4. package/docs/conditional-rendering.md +25 -24
  5. package/docs/core-concepts.md +20 -19
  6. package/docs/elements.md +21 -20
  7. package/docs/getting-started.md +28 -27
  8. package/docs/lifecycle-events.md +2 -2
  9. package/docs/list-rendering.md +607 -0
  10. package/docs/memory-management.md +1 -1
  11. package/docs/observables.md +15 -14
  12. package/docs/routing.md +22 -22
  13. package/docs/state-management.md +8 -8
  14. package/docs/validation.md +0 -2
  15. package/index.js +6 -1
  16. package/package.json +1 -1
  17. package/readme.md +5 -4
  18. package/src/data/MemoryManager.js +8 -20
  19. package/src/data/Observable.js +2 -180
  20. package/src/data/ObservableChecker.js +25 -24
  21. package/src/data/ObservableItem.js +158 -79
  22. package/src/data/observable-helpers/array.js +74 -0
  23. package/src/data/observable-helpers/batch.js +22 -0
  24. package/src/data/observable-helpers/computed.js +28 -0
  25. package/src/data/observable-helpers/object.js +111 -0
  26. package/src/elements/anchor.js +54 -9
  27. package/src/elements/control/for-each-array.js +280 -0
  28. package/src/elements/control/for-each.js +87 -110
  29. package/src/elements/index.js +1 -0
  30. package/src/elements/list.js +4 -0
  31. package/src/utils/helpers.js +44 -21
  32. package/src/wrappers/AttributesWrapper.js +5 -18
  33. package/src/wrappers/DocumentObserver.js +58 -29
  34. package/src/wrappers/ElementCreator.js +114 -0
  35. package/src/wrappers/HtmlElementEventsWrapper.js +52 -65
  36. package/src/wrappers/HtmlElementWrapper.js +11 -167
  37. package/src/wrappers/NdPrototype.js +109 -0
@@ -1,44 +1,73 @@
1
- import {throttle} from "../utils/helpers";
1
+ import {debounce} from "../utils/helpers";
2
2
 
3
3
  const DocumentObserver = {
4
- elements: new Map(),
4
+ mounted: new WeakMap(),
5
+ mountedSupposedSize: 0,
6
+ unmounted: new WeakMap(),
7
+ unmountedSupposedSize: 0,
5
8
  observer: null,
6
- checkMutation: throttle(function() {
7
- for(const [element, data] of DocumentObserver.elements.entries()) {
8
- const isCurrentlyInDom = document.body.contains(element);
9
- if(isCurrentlyInDom && !data.inDom) {
10
- data.inDom = true;
11
- data.mounted.forEach(callback => callback(element));
12
- } else if(!isCurrentlyInDom && data.inDom) {
13
- data.inDom = false;
14
- data.unmounted.forEach(callback => callback(element));
9
+ checkMutation: debounce(function(mutationsList) {
10
+ let i = 0;
11
+ for(const mutation of mutationsList) {
12
+ if(DocumentObserver.mountedSupposedSize > 0 ) {
13
+ for(const node of mutation.addedNodes) {
14
+ const data = DocumentObserver.mounted.get(node);
15
+ if(!data) {
16
+ continue;
17
+ }
18
+ data.inDom = true;
19
+ data.mounted && data.mounted(node);
20
+ }
21
+ }
22
+
23
+ if(DocumentObserver.unmountedSupposedSize > 0 ) {
24
+ for(const node of mutation.removedNodes) {
25
+ const data = DocumentObserver.unmounted.get(node);
26
+ if(!data) {
27
+ continue;
28
+ }
29
+
30
+ data.inDom = false;
31
+ if(data.unmounted && data.unmounted(node) === true) {
32
+ data.disconnect();
33
+ node.nd?.remove();
34
+ }
35
+ }
15
36
  }
16
37
  }
17
- }, 10, { debounce: true }),
38
+ }, 16),
18
39
  /**
19
40
  *
20
41
  * @param {HTMLElement} element
42
+ * @param {boolean} inDom
21
43
  * @returns {{watch: (function(): Map<any, any>), disconnect: (function(): boolean), mounted: (function(*): Set<any>), unmounted: (function(*): Set<any>)}}
22
44
  */
23
- watch: function(element) {
24
- let data = {};
25
- if(DocumentObserver.elements.has(element)) {
26
- data = DocumentObserver.elements.get(element);
27
- } else {
28
- const inDom = document.body.contains(element);
29
- data = {
30
- inDom,
31
- mounted: new Set(),
32
- unmounted: new Set(),
33
- };
34
- DocumentObserver.elements.set(element, data);
35
- }
45
+ watch: function(element, inDom = false) {
46
+ let data = {
47
+ inDom,
48
+ mounted: null,
49
+ unmounted: null,
50
+ disconnect: () => {
51
+ DocumentObserver.mounted.delete(element);
52
+ DocumentObserver.unmounted.delete(element);
53
+ DocumentObserver.mountedSupposedSize--;
54
+ DocumentObserver.unmountedSupposedSize--;
55
+ data = null;
56
+ }
57
+ };
36
58
 
37
59
  return {
38
- watch: () => DocumentObserver.elements.set(element, data),
39
- disconnect: () => DocumentObserver.elements.delete(element),
40
- mounted: (callback) => data.mounted.add(callback),
41
- unmounted: (callback) => data.unmounted.add(callback)
60
+ disconnect: data.disconnect,
61
+ mounted: (callback) => {
62
+ data.mounted = callback;
63
+ DocumentObserver.mounted.set(element, data);
64
+ DocumentObserver.mountedSupposedSize++;
65
+ },
66
+ unmounted: (callback) => {
67
+ data.unmounted = callback;
68
+ DocumentObserver.unmounted.set(element, data);
69
+ DocumentObserver.unmountedSupposedSize++;
70
+ }
42
71
  };
43
72
  }
44
73
  };
@@ -0,0 +1,114 @@
1
+ import Anchor from "../elements/anchor";
2
+ import Validator from "../utils/validator";
3
+ import AttributesWrapper from "./AttributesWrapper";
4
+
5
+ const $nodeCache = new Map();
6
+ let $textNodeCache = null;
7
+
8
+ export const ElementCreator = {
9
+ createTextNode() {
10
+ if(!$textNodeCache) {
11
+ $textNodeCache = document.createTextNode('');
12
+ }
13
+ return $textNodeCache.cloneNode();
14
+ },
15
+ /**
16
+ *
17
+ * @param {HTMLElement|DocumentFragment} parent
18
+ * @param {ObservableItem} observable
19
+ * @returns {Text}
20
+ */
21
+ createObservableNode(parent, observable) {
22
+ const text = ElementCreator.createTextNode();
23
+ observable.subscribe(value => text.nodeValue = String(value));
24
+ text.nodeValue = observable.val();
25
+ parent && parent.appendChild(text);
26
+ return text;
27
+ },
28
+
29
+ /**
30
+ *
31
+ * @param {HTMLElement|DocumentFragment} parent
32
+ * @param {*} value
33
+ * @returns {Text}
34
+ */
35
+ createStaticTextNode(parent, value) {
36
+ let text = ElementCreator.createTextNode();
37
+ text.nodeValue = String(value);
38
+ parent && parent.appendChild(text);
39
+ return text;
40
+ },
41
+ /**
42
+ *
43
+ * @param {string} name
44
+ * @returns {HTMLElement|DocumentFragment}
45
+ */
46
+ createElement(name) {
47
+ if(name) {
48
+ if($nodeCache.has(name)) {
49
+ return $nodeCache.get(name).cloneNode();
50
+ }
51
+ const node = document.createElement(name);
52
+ $nodeCache.set(name, node);
53
+ return node.cloneNode();
54
+ }
55
+ return new Anchor('Fragment');
56
+ },
57
+ /**
58
+ *
59
+ * @param {*} children
60
+ * @param {HTMLElement|DocumentFragment} parent
61
+ */
62
+ processChildren(children, parent) {
63
+ if(children === null) return;
64
+ const childrenArray = Array.isArray(children) ? children : [children];
65
+
66
+ for(let i = 0, length = childrenArray.length; i < length; i++) {
67
+ let child = childrenArray[i];
68
+ if (child === null) continue;
69
+ if(Validator.isString(child) && Validator.isFunction(child.resolveObservableTemplate)) {
70
+ child = child.resolveObservableTemplate();
71
+ }
72
+ if(Validator.isFunction(child)) {
73
+ this.processChildren(child(), parent);
74
+ continue;
75
+ }
76
+ if(Validator.isArray(child)) {
77
+ this.processChildren(child, parent);
78
+ continue;
79
+ }
80
+ if (Validator.isElement(child)) {
81
+ parent.appendChild(child);
82
+ continue;
83
+ }
84
+ if (Validator.isObservable(child)) {
85
+ ElementCreator.createObservableNode(parent, child);
86
+ continue;
87
+ }
88
+ if (child) {
89
+ ElementCreator.createStaticTextNode(parent, child);
90
+ }
91
+ }
92
+ },
93
+ /**
94
+ *
95
+ * @param {HTMLElement} element
96
+ * @param {Object} attributes
97
+ */
98
+ processAttributes(element, attributes) {
99
+ if(Validator.isFragment(element)) return;
100
+ if (attributes) {
101
+ AttributesWrapper(element, attributes);
102
+ }
103
+ },
104
+ /**
105
+ *
106
+ * @param {HTMLElement} element
107
+ * @param {Object} attributes
108
+ * @param {?Function} customWrapper
109
+ * @returns {HTMLElement|DocumentFragment}
110
+ */
111
+ setup(element, attributes, customWrapper) {
112
+ return element;
113
+ }
114
+ };
@@ -1,6 +1,32 @@
1
- function eventWrapper(element, name, callback) {
2
- element.addEventListener(name, callback);
3
- return element;
1
+
2
+
3
+ /**
4
+ *
5
+ * @param {HTMLElement} element
6
+ * @returns {HTMLElement}
7
+ */
8
+ function HtmlElementPreventEventsWrapper(element) {
9
+ const events = {};
10
+ return new Proxy(events, {
11
+ get(target, property) {
12
+ if(events[property]) {
13
+ return events[property];
14
+ }
15
+ events[property] = function(callback) {
16
+ element.addEventListener(property.toLowerCase(), function(event) {
17
+ event.preventDefault();
18
+ callback.apply(this, [event]);
19
+ });
20
+ return element
21
+ };
22
+ return events[property];
23
+ },
24
+ set(target, property, newValue, receiver) {
25
+ //...
26
+ this.get(target, property)(newValue);
27
+ return element;
28
+ }
29
+ });
4
30
  }
5
31
 
6
32
  /**
@@ -9,69 +35,30 @@ function eventWrapper(element, name, callback) {
9
35
  * @returns {HTMLElement}
10
36
  */
11
37
  export default function HtmlElementEventsWrapper(element) {
38
+ const events = {};
39
+ return new Proxy(events, {
40
+ get(target, property) {
41
+ if(events[property]) {
42
+ return events[property];
43
+ }
44
+ if(property === 'prevent') {
45
+ events[property] = HtmlElementPreventEventsWrapper(element);
46
+ return events[property];
47
+ }
48
+ if(property === 'removeAll') {
12
49
 
13
- if(!element.nd) {
14
- element.nd = {};
15
- }
16
-
17
- /**
18
- * @param {Object<string,Function>} events
19
- */
20
- element.nd.on = function(events) {
21
- for(const event in events) {
22
- const callback = events[event];
23
- eventWrapper(element, event, callback);
24
- }
25
- return element;
26
- };
27
- element.nd.on.prevent = function(events) {
28
- for(const event in events) {
29
- const callback = events[event];
30
- eventWrapper(element, event, (event) => {
31
- event.preventDefault();
32
- callback && callback(event);
33
- return element;
34
- });
35
- }
36
- return element;
37
- };
38
- const events = {
39
- click: (callback) => eventWrapper(element, 'click', callback),
40
- focus: (callback) => eventWrapper(element, 'focus', callback),
41
- blur: (callback) => eventWrapper(element, 'blur', callback),
42
- input: (callback) => eventWrapper(element, 'input', callback),
43
- change: (callback) => eventWrapper(element, 'change', callback),
44
- keyup: (callback) => eventWrapper(element, 'keyup', callback),
45
- keydown: (callback) => eventWrapper(element, 'keydown', callback),
46
- beforeInput: (callback) => eventWrapper(element, 'beforeinput', callback),
47
- mouseOver: (callback) => eventWrapper(element, 'mouseover', callback),
48
- mouseOut: (callback) => eventWrapper(element, 'mouseout', callback),
49
- mouseDown: (callback) => eventWrapper(element, 'mousedown', callback),
50
- mouseUp: (callback) => eventWrapper(element, 'mouseup', callback),
51
- mouseMove: (callback) => eventWrapper(element, 'mousemove', callback),
52
- hover: (mouseInCallback, mouseOutCallback) => {
53
- element.addEventListener('mouseover', mouseInCallback);
54
- element.addEventListener('mouseout', mouseOutCallback);
50
+ return;
51
+ }
52
+ events[property] = function(callback) {
53
+ element.addEventListener(property.toLowerCase(), callback);
54
+ return element
55
+ };
56
+ return events[property];
55
57
  },
56
- dropped: (callback) => eventWrapper(element, 'drop', callback),
57
- submit: (callback) => eventWrapper(element, 'submit', callback),
58
- dragEnd: (callback) => eventWrapper(element, 'dragend', callback),
59
- dragStart: (callback) => eventWrapper(element, 'dragstart', callback),
60
- drop: (callback) => eventWrapper(element, 'drop', callback),
61
- dragOver: (callback) => eventWrapper(element, 'dragover', callback),
62
- dragEnter: (callback) => eventWrapper(element, 'dragenter', callback),
63
- dragLeave: (callback) => eventWrapper(element, 'dragleave', callback),
64
- };
65
- for(let event in events) {
66
- element.nd.on[event] = events[event];
67
- element.nd.on.prevent[event] = function(callback) {
68
- eventWrapper(element, event.toLowerCase(), (event) => {
69
- event.preventDefault();
70
- callback && callback(event);
71
- });
58
+ set(target, property, newValue, receiver) {
59
+ //...
60
+ this.get(target, property)(newValue);
72
61
  return element;
73
- };
74
- }
75
-
76
- return element;
62
+ }
63
+ });
77
64
  }
@@ -1,91 +1,7 @@
1
- import HtmlElementEventsWrapper from "./HtmlElementEventsWrapper";
2
- import AttributesWrapper from "./AttributesWrapper";
3
- import NativeDocumentError from "../errors/NativeDocumentError";
4
- import DocumentObserver from "./DocumentObserver";
5
1
  import Validator from "../utils/validator";
6
2
  import DebugManager from "../utils/debug-manager";
7
- import Anchor from "../elements/anchor";
8
- import PluginsManager from "../utils/plugins-manager";
9
-
10
- /**
11
- *
12
- * @param {HTMLElement|DocumentFragment} parent
13
- * @param {ObservableItem} observable
14
- * @returns {Text}
15
- */
16
- const createObservableNode = function(parent, observable) {
17
- const text = document.createTextNode('');
18
- observable.subscribe(value => text.textContent = String(value));
19
- text.textContent = observable.val();
20
- parent && parent.appendChild(text);
21
- return text;
22
- }
23
-
24
- /**
25
- *
26
- * @param {HTMLElement|DocumentFragment} parent
27
- * @param {*} value
28
- * @returns {Text}
29
- */
30
- const createStaticTextNode = function(parent, value) {
31
- const text = document.createTextNode('');
32
- text.textContent = String(value);
33
- parent && parent.appendChild(text);
34
- return text;
35
- }
36
-
37
- /**
38
- *
39
- * @param {HTMLElement} element
40
- */
41
- const addUtilsMethods = function(element) {
42
- element.nd.wrap = (callback) => {
43
- if(!Validator.isFunction(callback)) {
44
- throw new NativeDocumentError('Callback must be a function');
45
- }
46
- callback && callback(element);
47
- return element;
48
- };
49
- element.nd.ref = (target, name) => {
50
- target[name] = element;
51
- return element;
52
- };
53
-
54
- let $observer = null;
55
-
56
- element.nd.appendChild = function(child) {
57
- if(Validator.isArray(child)) {
58
- ElementCreator.processChildren(child, element);
59
- return;
60
- }
61
- if(Validator.isFunction(child)) {
62
- child = child();
63
- ElementCreator.processChildren(child(), element);
64
- }
65
- if(Validator.isElement(child)) {
66
- ElementCreator.processChildren(child, element);
67
- }
68
- };
69
-
70
- element.nd.lifecycle = function(states) {
71
- $observer = $observer || DocumentObserver.watch(element);
72
-
73
- states.mounted && $observer.mounted(states.mounted);
74
- states.unmounted && $observer.unmounted(states.unmounted);
75
- return element;
76
- };
77
-
78
- element.nd.mounted = (callback) => {
79
- $observer = $observer || DocumentObserver.watch(element);
80
- $observer.mounted(callback);
81
- return element;
82
- };
83
- element.nd.unmounted = (callback) => {
84
- $observer = $observer || DocumentObserver.watch(element);
85
- $observer.unmounted(callback);
86
- return element;
87
- };
88
- };
3
+ import {ElementCreator} from "./ElementCreator";
4
+ import './NdPrototype';
89
5
 
90
6
  /**
91
7
  *
@@ -94,84 +10,10 @@ const addUtilsMethods = function(element) {
94
10
  */
95
11
  export const createTextNode = function(value) {
96
12
  return (Validator.isObservable(value))
97
- ? createObservableNode(null, value)
98
- : createStaticTextNode(null, value);
13
+ ? ElementCreator.createObservableNode(null, value)
14
+ : ElementCreator.createStaticTextNode(null, value);
99
15
  };
100
16
 
101
- export const ElementCreator = {
102
- /**
103
- *
104
- * @param {string} name
105
- * @returns {HTMLElement|DocumentFragment}
106
- */
107
- createElement(name) {
108
- return name ? document.createElement(name) : new Anchor('Fragment');
109
- },
110
- /**
111
- *
112
- * @param {*} children
113
- * @param {HTMLElement|DocumentFragment} parent
114
- */
115
- processChildren(children, parent) {
116
- if(children === null) return;
117
- const childrenArray = Array.isArray(children) ? children : [children];
118
- childrenArray.forEach(child => {
119
- if (child === null) return;
120
- if(Validator.isString(child) && Validator.isFunction(child.resolveObservableTemplate)) {
121
- child = child.resolveObservableTemplate();
122
- }
123
- if(Validator.isFunction(child)) {
124
- this.processChildren(child(), parent);
125
- return;
126
- }
127
- if(Validator.isArray(child)) {
128
- this.processChildren(child, parent);
129
- return;
130
- }
131
- if (Validator.isElement(child)) {
132
- parent.appendChild(child);
133
- return;
134
- }
135
- if (Validator.isObservable(child)) {
136
- createObservableNode(parent, child);
137
- return;
138
- }
139
- if (child) {
140
- createStaticTextNode(parent, child);
141
- }
142
- });
143
- },
144
- /**
145
- *
146
- * @param {HTMLElement} element
147
- * @param {Object} attributes
148
- */
149
- processAttributes(element, attributes) {
150
- if(Validator.isFragment(element)) return;
151
- if (attributes) {
152
- AttributesWrapper(element, attributes);
153
- }
154
- },
155
- /**
156
- *
157
- * @param {HTMLElement} element
158
- * @param {Object} attributes
159
- * @param {?Function} customWrapper
160
- * @returns {HTMLElement|DocumentFragment}
161
- */
162
- setup(element, attributes, customWrapper) {
163
- element.nd = {};
164
- HtmlElementEventsWrapper(element);
165
- const item = (typeof customWrapper === 'function') ? customWrapper(element) : element;
166
- addUtilsMethods(item);
167
-
168
- PluginsManager.list().forEach(plugin => {
169
- plugin?.element?.setup && plugin.element.setup(item, attributes);
170
- });
171
-
172
- return item;
173
- }
174
- };
175
17
 
176
18
  /**
177
19
  *
@@ -180,7 +22,7 @@ export const ElementCreator = {
180
22
  * @returns {Function}
181
23
  */
182
24
  export default function HtmlElementWrapper(name, customWrapper) {
183
- const $tagName = name.toLowerCase().trim();
25
+ const $tagName = name.toLowerCase();
184
26
 
185
27
  const builder = function(attributes, children = null) {
186
28
  try {
@@ -190,11 +32,12 @@ export default function HtmlElementWrapper(name, customWrapper) {
190
32
  attributes = tempChildren;
191
33
  }
192
34
  const element = ElementCreator.createElement($tagName);
35
+ const finalElement = (typeof customWrapper === 'function') ? customWrapper(element) : element;
193
36
 
194
- ElementCreator.processAttributes(element, attributes);
195
- ElementCreator.processChildren(children, element);
37
+ ElementCreator.processAttributes(finalElement, attributes);
38
+ ElementCreator.processChildren(children, finalElement);
196
39
 
197
- return ElementCreator.setup(element, attributes, customWrapper);
40
+ return ElementCreator.setup(finalElement, attributes, customWrapper);
198
41
  } catch (error) {
199
42
  DebugManager.error('ElementCreation', `Error creating ${$tagName}`, error);
200
43
  }
@@ -203,4 +46,5 @@ export default function HtmlElementWrapper(name, customWrapper) {
203
46
  builder.hold = (children, attributes) => (() => builder(children, attributes));
204
47
 
205
48
  return builder;
206
- }
49
+ }
50
+
@@ -0,0 +1,109 @@
1
+ import DocumentObserver from "./DocumentObserver";
2
+
3
+ Object.defineProperty(HTMLElement.prototype, 'nd', {
4
+ get() {
5
+ if(this.$ndProx) {
6
+ return this.$ndProx;
7
+ }
8
+ let element = this;
9
+ let lifecycle = null;
10
+
11
+ this.$ndProx = new Proxy({}, {
12
+ get(target, property) {
13
+ if(/^on[A-Z]/.test(property)) {
14
+ const event = property.replace(/^on/, '').toLowerCase();
15
+ const shouldPrevent = event.toLowerCase().startsWith('prevent');
16
+ let eventName = event.replace(/^prevent/i, '');
17
+ const shouldStop = event.toLowerCase().startsWith('stop');
18
+ eventName = eventName.replace(/^stop/i, '');
19
+
20
+ return function(callback) {
21
+ if(shouldPrevent && !shouldStop) {
22
+ element.addEventListener(eventName, function(event) {
23
+ event.preventDefault();
24
+ callback(event);
25
+ });
26
+ return element;
27
+ }
28
+ if(!shouldPrevent && shouldStop) {
29
+ element.addEventListener(eventName, function(event) {
30
+ event.stopPropagation();
31
+ callback(event);
32
+ });
33
+ return element;
34
+ }
35
+ if(shouldPrevent && shouldStop) {
36
+ element.addEventListener(eventName, function(event) {
37
+ event.preventDefault();
38
+ event.stopPropagation();
39
+ callback(event);
40
+ });
41
+ return element;
42
+ }
43
+ element.addEventListener(eventName, callback);
44
+ return element;
45
+ };
46
+ return fn;
47
+ }
48
+ if(property === 'ref') {
49
+ if(ref) {
50
+ return ref;
51
+ }
52
+ return function(target, name) {
53
+ target[name] = element;
54
+ return element;
55
+ };
56
+ }
57
+ if(property === 'unmountChildren') {
58
+ return () => {
59
+ for(let i = 0, length = element.children.length; i < length; i++) {
60
+ let elementchildren = element.children[i];
61
+ if(!elementchildren.$ndProx) {
62
+ elementchildren.nd?.remove();
63
+ }
64
+ elementchildren = null;
65
+ }
66
+ };
67
+ }
68
+ if(property === 'remove') {
69
+ return function() {
70
+ element.nd.unmountChildren();
71
+ lifecycle = null;
72
+ element.$ndProx = null;
73
+ delete element.nd?.on?.prevent;
74
+ delete element.nd?.on;
75
+ delete element.nd;
76
+ };
77
+ }
78
+ if(property === 'hasLifecycle') {
79
+ return lifecycle !== null;
80
+ }
81
+ if(property === 'lifecycle') {
82
+ if(lifecycle) {
83
+ return lifecycle;
84
+ }
85
+ let $observer = null;
86
+ lifecycle = function(states) {
87
+ $observer = $observer || DocumentObserver.watch(element);
88
+
89
+ states.mounted && $observer.mounted(states.mounted);
90
+ states.unmounted && $observer.unmounted(states.unmounted);
91
+ return element;
92
+ };
93
+ return lifecycle;
94
+ }
95
+ if(property === 'mounted' || property === 'unmounted') {
96
+ return function(callback) {
97
+ element.nd.lifecycle({ [property]: callback});
98
+ return element;
99
+ };
100
+ }
101
+ },
102
+ set(target, p, newValue, receiver) {
103
+
104
+ },
105
+ configurable: true
106
+ });
107
+ return this.$ndProx;
108
+ }
109
+ });