native-document 1.0.16-8.3 → 1.0.16-8.5
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 +1 -1
- package/src/core/elements/content-formatter.js +2 -2
- package/src/core/elements/form.js +1 -1
- package/src/core/elements/img.js +1 -1
- package/src/core/elements/medias.js +2 -2
- package/src/core/elements/meta-data.js +1 -1
- package/src/core/wrappers/AttributesWrapper.js +29 -3
- package/src/core/wrappers/ElementCreator.js +1 -7
- package/src/core/wrappers/HtmlElementWrapper.js +24 -7
- package/src/core/wrappers/NDElement.js +8 -0
- package/src/core/wrappers/prototypes/attributes-extensions.js +19 -184
- package/src/core/wrappers/prototypes/nd-element-extensions.js +57 -83
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "native-document",
|
|
3
|
-
"version": "1.0.168.
|
|
3
|
+
"version": "1.0.168.05",
|
|
4
4
|
"description": "A reactive JavaScript framework that preserves native DOM simplicity without sacrificing modern features",
|
|
5
5
|
"author": "AfroCodeur <https://github.com/afrocodeur>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -76,7 +76,7 @@ export const H6 = HtmlElementWrapper('h6');
|
|
|
76
76
|
* Creates a `<br>` element.
|
|
77
77
|
* @type {function(GlobalAttributes=): HTMLBRElement}
|
|
78
78
|
*/
|
|
79
|
-
export const Br = HtmlElementWrapper('br');
|
|
79
|
+
export const Br = HtmlElementWrapper('br', null, true);
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
82
|
* Creates an `<a>` element.
|
|
@@ -106,7 +106,7 @@ export const Blockquote = HtmlElementWrapper('blockquote');
|
|
|
106
106
|
* Creates an `<hr>` element.
|
|
107
107
|
* @type {function(GlobalAttributes=): HTMLHRElement}
|
|
108
108
|
*/
|
|
109
|
-
export const Hr = HtmlElementWrapper('hr');
|
|
109
|
+
export const Hr = HtmlElementWrapper('hr', null, true);
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
112
|
* Creates an `<em>` element.
|
|
@@ -44,7 +44,7 @@ export const Form = HtmlElementWrapper('form', (el) => {
|
|
|
44
44
|
* Creates an `<input>` element.
|
|
45
45
|
* @type {function(InputAttributes=): HTMLInputElement}
|
|
46
46
|
*/
|
|
47
|
-
export const Input = HtmlElementWrapper('input');
|
|
47
|
+
export const Input = HtmlElementWrapper('input', null, true);
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Creates a `<textarea>` element.
|
package/src/core/elements/img.js
CHANGED
|
@@ -6,7 +6,7 @@ import NativeDocumentError from '../errors/NativeDocumentError';
|
|
|
6
6
|
* Creates an `<img>` element.
|
|
7
7
|
* @type {function(ImgAttributes=): HTMLImageElement}
|
|
8
8
|
*/
|
|
9
|
-
export const BaseImage = HtmlElementWrapper('img');
|
|
9
|
+
export const BaseImage = HtmlElementWrapper('img', null, true);
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Creates an `<img>` element.
|
|
@@ -16,13 +16,13 @@ export const Video = HtmlElementWrapper('video');
|
|
|
16
16
|
* Creates a `<source>` element.
|
|
17
17
|
* @type {function(SourceAttributes=): HTMLSourceElement}
|
|
18
18
|
*/
|
|
19
|
-
export const Source = HtmlElementWrapper('source');
|
|
19
|
+
export const Source = HtmlElementWrapper('source', null, true);
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Creates a `<track>` element.
|
|
23
23
|
* @type {function(TrackAttributes=): HTMLTrackElement}
|
|
24
24
|
*/
|
|
25
|
-
export const Track = HtmlElementWrapper('track');
|
|
25
|
+
export const Track = HtmlElementWrapper('track', null, true);
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Creates a `<canvas>` element.
|
|
@@ -97,7 +97,7 @@ export const bindBooleanAttribute = (element, attributeName, value) => {
|
|
|
97
97
|
|
|
98
98
|
const attributeRealName = BOOL_ATTRIBUTES_NAME[attributeName];
|
|
99
99
|
|
|
100
|
-
if(
|
|
100
|
+
if(Validator.isBoolean(defaultValue)) {
|
|
101
101
|
element[attributeRealName] = defaultValue;
|
|
102
102
|
}
|
|
103
103
|
else {
|
|
@@ -149,12 +149,38 @@ const AttributesWrapper = (element, attributes) => {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
for(const originalAttributeName in attributes) {
|
|
152
|
+
const attributeName = originalAttributeName.toLowerCase();
|
|
152
153
|
const value = attributes[originalAttributeName];
|
|
153
154
|
if(value == null) {
|
|
154
155
|
continue;
|
|
155
156
|
}
|
|
156
|
-
|
|
157
|
-
|
|
157
|
+
if(typeof value === 'string' || typeof value === 'number') {
|
|
158
|
+
element.setAttribute(attributeName, value);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if(value.__$Observable) {
|
|
162
|
+
bindAttributeWithObservable(element, attributeName, value);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if(typeof value === 'object') {
|
|
166
|
+
if(attributeName === 'class') {
|
|
167
|
+
bindClassAttribute(element, value);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if(attributeName === 'style') {
|
|
171
|
+
bindStyleAttribute(element, value);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if(BOOLEAN_ATTRIBUTES.has(attributeName)) {
|
|
176
|
+
bindBooleanAttribute(element, attributeName, value);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if(value.__$isTemplateBinding) {
|
|
180
|
+
value.$hydrate(element, attributeName);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
element.setAttribute(attributeName, value);
|
|
158
184
|
}
|
|
159
185
|
return element;
|
|
160
186
|
};
|
|
@@ -98,19 +98,13 @@ export const ElementCreator = {
|
|
|
98
98
|
return child;
|
|
99
99
|
}
|
|
100
100
|
} while (child.toNdElement);
|
|
101
|
-
|
|
102
|
-
return ElementCreator.createStaticTextNode(null, child);
|
|
103
101
|
},
|
|
104
102
|
/**
|
|
105
103
|
*
|
|
106
104
|
* @param {HTMLElement} element
|
|
107
105
|
* @param {Object} attributes
|
|
108
106
|
*/
|
|
109
|
-
processAttributes:
|
|
110
|
-
if (attributes) {
|
|
111
|
-
AttributesWrapper(element, attributes);
|
|
112
|
-
}
|
|
113
|
-
},
|
|
107
|
+
processAttributes: AttributesWrapper,
|
|
114
108
|
/**
|
|
115
109
|
*
|
|
116
110
|
* @param {HTMLElement} element
|
|
@@ -3,7 +3,6 @@ import {ElementCreator} from './ElementCreator';
|
|
|
3
3
|
import {normalizeComponentArgs} from '../utils/args-types';
|
|
4
4
|
import './NdPrototype';
|
|
5
5
|
|
|
6
|
-
import './NdPrototype';
|
|
7
6
|
import '../../core/utils/prototypes.js';
|
|
8
7
|
import '../wrappers/prototypes/nd-element-extensions';
|
|
9
8
|
import '../wrappers/prototypes/bind-class-extensions';
|
|
@@ -27,6 +26,19 @@ export const createTextNode = (value) => {
|
|
|
27
26
|
};
|
|
28
27
|
|
|
29
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Applies attributes to an existing HTMLElement.
|
|
31
|
+
* Used internally by HtmlElementWrapper on each cloned node.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
* @param {HTMLElement} element - Element to configure
|
|
35
|
+
* @param {Object|null} attributes - Attributes object or children if no attrs provided
|
|
36
|
+
* @returns {HTMLElement} The configured element
|
|
37
|
+
*/
|
|
38
|
+
export const createVoidHtmlElement = (element, attributes) => {
|
|
39
|
+
ElementCreator.processAttributes(element, attributes);
|
|
40
|
+
return element;
|
|
41
|
+
};
|
|
30
42
|
/**
|
|
31
43
|
* Applies attributes and children to an existing HTMLElement.
|
|
32
44
|
* Used internally by HtmlElementWrapper on each cloned node.
|
|
@@ -38,7 +50,11 @@ export const createTextNode = (value) => {
|
|
|
38
50
|
* @returns {HTMLElement} The configured element
|
|
39
51
|
*/
|
|
40
52
|
export const createHtmlElement = (element, _attributes, _children = null) => {
|
|
41
|
-
|
|
53
|
+
let attributes = _attributes, children = _children;
|
|
54
|
+
if((!_attributes || !_children) && (typeof _attributes !== 'object' || Array.isArray(_attributes) || _attributes === null || Object.getPrototypeOf(_attributes) !== Object.prototype || _attributes.$hydrate)) { // IF it's not a JSON
|
|
55
|
+
attributes = _children;
|
|
56
|
+
children = _attributes;
|
|
57
|
+
}
|
|
42
58
|
|
|
43
59
|
ElementCreator.processAttributes(element, attributes);
|
|
44
60
|
ElementCreator.processChildren(children, element);
|
|
@@ -63,16 +79,17 @@ export const createHtmlElement = (element, _attributes, _children = null) => {
|
|
|
63
79
|
* return el;
|
|
64
80
|
* });
|
|
65
81
|
*/
|
|
66
|
-
export default function HtmlElementWrapper(name, customWrapper = null) {
|
|
82
|
+
export default function HtmlElementWrapper(name, customWrapper = null, isVoid = false) {
|
|
83
|
+
const elementCreator = isVoid ? createVoidHtmlElement : createHtmlElement;
|
|
67
84
|
if(name) {
|
|
68
85
|
if(customWrapper) {
|
|
69
86
|
let node = null;
|
|
70
87
|
let createElement = (attr, children) => {
|
|
71
88
|
node = document.createElement(name);
|
|
72
89
|
createElement = (attr, children) => {
|
|
73
|
-
return
|
|
90
|
+
return elementCreator(customWrapper(node.cloneNode()), attr, children);
|
|
74
91
|
};
|
|
75
|
-
return
|
|
92
|
+
return elementCreator(customWrapper(node.cloneNode()), attr, children);;
|
|
76
93
|
};
|
|
77
94
|
|
|
78
95
|
return (attr, children) => createElement(attr, children);
|
|
@@ -82,9 +99,9 @@ export default function HtmlElementWrapper(name, customWrapper = null) {
|
|
|
82
99
|
let createElement = (attr, children) => {
|
|
83
100
|
node = document.createElement(name);
|
|
84
101
|
createElement = (attr, children) => {
|
|
85
|
-
return
|
|
102
|
+
return elementCreator(node.cloneNode(), attr, children);
|
|
86
103
|
};
|
|
87
|
-
return
|
|
104
|
+
return elementCreator(node.cloneNode(), attr, children);
|
|
88
105
|
};
|
|
89
106
|
|
|
90
107
|
return (attr, children) => createElement(attr, children);
|
|
@@ -38,6 +38,14 @@ NDElement.$getChild = (el) => el;
|
|
|
38
38
|
NDElement.prototype.ghostDom = function(element) {
|
|
39
39
|
if(!this.$attachements) {
|
|
40
40
|
this.$attachements = document.createDocumentFragment();
|
|
41
|
+
this.toNdElement = () => {
|
|
42
|
+
const fragment = document.createDocumentFragment();
|
|
43
|
+
if(!this.$attachements.contains(this.$element)) {
|
|
44
|
+
fragment.appendChild(this.$element);
|
|
45
|
+
}
|
|
46
|
+
fragment.appendChild(this.$attachements);
|
|
47
|
+
return fragment;
|
|
48
|
+
};
|
|
41
49
|
}
|
|
42
50
|
this.$attachements.appendChild(NDElement.$getChild(element));
|
|
43
51
|
return this;
|
|
@@ -1,189 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import ObservableChecker from '../../data/ObservableChecker';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* the property overridable and deletable.
|
|
15
|
-
*
|
|
16
|
-
* @param {Function} Constructor - The constructor whose prototype to extend
|
|
17
|
-
* @param {string} name - Property name
|
|
18
|
-
* @param {Function} fn - Implementation
|
|
19
|
-
*/
|
|
20
|
-
const extendsPrototype = (Constructor, name, fn) => {
|
|
21
|
-
Object.defineProperty(Constructor.prototype, name, {
|
|
22
|
-
value: fn,
|
|
23
|
-
enumerable: false,
|
|
24
|
-
configurable: true,
|
|
25
|
-
writable: true,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// -- handleNdAttribute --------------------------------------------------------
|
|
30
|
-
|
|
31
|
-
extendsPrototype(Object, 'handleNdAttribute', function(element, attributeName) {
|
|
32
|
-
if (attributeName === 'class') {
|
|
33
|
-
bindClassAttribute(element, this);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (attributeName === 'style') {
|
|
37
|
-
bindStyleAttribute(element, this);
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
element.setAttribute(attributeName, JSON.stringify(this));
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const handleAttributeFn = function(element, attributeName) {
|
|
44
|
-
if (BOOLEAN_ATTRIBUTES.has(attributeName)) {
|
|
45
|
-
this.handleNdBooleanAttribute(element, attributeName);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
bindAttributeWithObservable(element, attributeName, this);
|
|
49
|
-
};
|
|
50
|
-
extendsPrototype(ObservableItem, 'handleNdAttribute', handleAttributeFn);
|
|
51
|
-
extendsPrototype(ObservableWhen, 'handleNdAttribute', handleAttributeFn);
|
|
52
|
-
|
|
53
|
-
extendsPrototype(TemplateBinding, 'handleNdAttribute', function(element, attributeName) {
|
|
54
|
-
this.$hydrate(element, attributeName);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
extendsPrototype(Number, 'handleNdAttribute', function(element, attributeName) {
|
|
58
|
-
element.setAttribute(attributeName, this.toString());
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
extendsPrototype(String, 'handleNdAttribute', function(element, attributeName) {
|
|
62
|
-
element.setAttribute(attributeName, this.toString());
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
extendsPrototype(Array, 'handleNdAttribute', function(element, attributeName) {
|
|
66
|
-
element.setAttribute(attributeName, this.toString());
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
extendsPrototype(Boolean, 'handleNdAttribute', function(element, attributeName) {
|
|
70
|
-
element[attributeName] = this;
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// -- handleNdBooleanAttribute -------------------------------------------------
|
|
74
|
-
|
|
75
|
-
extendsPrototype(Boolean, 'handleNdBooleanAttribute', function(element, attributeName) {
|
|
76
|
-
element[attributeName] = this;
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
extendsPrototype(String, 'handleNdBooleanAttribute', function(element, attributeName) {
|
|
80
|
-
element[attributeName] = this === element.value;
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const booleanAttributeFn = function(element, attributeName) {
|
|
84
|
-
const defaultValue = this.val();
|
|
85
|
-
defaultValue.handleNdBooleanAttribute(element, attributeName);
|
|
86
|
-
|
|
87
|
-
if (attributeName === 'checked') {
|
|
88
|
-
if (typeof defaultValue === 'boolean') {
|
|
89
|
-
element.addEventListener('input', () => this.set(element[attributeName]));
|
|
90
|
-
} else {
|
|
91
|
-
element.addEventListener('input', () => this.set(element.value));
|
|
92
|
-
}
|
|
93
|
-
this.subscribe((newValue) => element[attributeName] = newValue);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
this.subscribe((newValue) => element[attributeName] = (newValue === element.value));
|
|
98
|
-
};
|
|
99
|
-
extendsPrototype(ObservableItem, 'handleNdBooleanAttribute', booleanAttributeFn);
|
|
100
|
-
extendsPrototype(ObservableWhen, 'handleNdBooleanAttribute', booleanAttributeFn);
|
|
101
|
-
|
|
102
|
-
// -- handleStyleProperty ------------------------------------------------------
|
|
103
|
-
//
|
|
104
|
-
// extendsPrototype(String, 'handleStyleProperty', function(element, styleName) {
|
|
105
|
-
// const isCustomProperty = styleName.startsWith('--');
|
|
106
|
-
// if (isCustomProperty) {
|
|
107
|
-
// element.style.setProperty(styleName, this);
|
|
108
|
-
// return;
|
|
109
|
-
// }
|
|
110
|
-
// element.style[styleName] = this;
|
|
111
|
-
// });
|
|
112
|
-
//
|
|
113
|
-
// extendsPrototype(Number, 'handleStyleProperty', String.prototype.handleStyleProperty);
|
|
114
|
-
//
|
|
115
|
-
// extendsPrototype(ObservableItem, 'handleStyleProperty', function(element, styleName) {
|
|
116
|
-
// const isCustomProperty = styleName.startsWith('--');
|
|
117
|
-
//
|
|
118
|
-
// if (isCustomProperty) {
|
|
119
|
-
// element.style.setProperty(styleName, this.val());
|
|
120
|
-
// this.subscribe((newValue) => {
|
|
121
|
-
// if (newValue === false) {
|
|
122
|
-
// element.style.removeProperty(styleName);
|
|
123
|
-
// return;
|
|
124
|
-
// }
|
|
125
|
-
// element.style.setProperty(styleName, newValue);
|
|
126
|
-
// });
|
|
127
|
-
// return;
|
|
128
|
-
// }
|
|
129
|
-
//
|
|
130
|
-
// element.style[styleName] = this.val();
|
|
131
|
-
// this.subscribe((newValue) => {
|
|
132
|
-
// if (newValue === false) {
|
|
133
|
-
// element.style.removeProperty(styleName);
|
|
134
|
-
// return;
|
|
135
|
-
// }
|
|
136
|
-
// element.style[styleName] = newValue;
|
|
137
|
-
// });
|
|
138
|
-
// });
|
|
139
|
-
//
|
|
140
|
-
// extendsPrototype(Array, 'handleStyleProperty', function(element, styleName) {
|
|
141
|
-
// const dependencies = this.filter((item) => item.__$Observable);
|
|
142
|
-
// if (dependencies.length) {
|
|
143
|
-
// const style = Observable.computed(
|
|
144
|
-
// () => this.map((item) => item.valueOf()).join(', '),
|
|
145
|
-
// dependencies,
|
|
146
|
-
// );
|
|
147
|
-
// style.handleStyleProperty(element, styleName);
|
|
148
|
-
// return;
|
|
149
|
-
// }
|
|
150
|
-
// element.style[styleName] = this.join(', ');
|
|
151
|
-
// });
|
|
152
|
-
|
|
153
|
-
// -- handleClassValue ------------------------------------------------------
|
|
154
|
-
// extendsPrototype(ObservableItem, 'handleClassValue', function(element, className) {
|
|
155
|
-
// element.classes.toggle(className, this.val());
|
|
156
|
-
// this.subscribe((shouldAdd) => element.classes.toggle(className, shouldAdd));
|
|
157
|
-
// });
|
|
158
|
-
//
|
|
159
|
-
// extendsPrototype(ObservableWhen, 'handleClassValue', function(element, className) {
|
|
160
|
-
// element.classes.toggle(className, this.val());
|
|
161
|
-
// this.subscribe((shouldAdd) => element.classes.toggle(className, shouldAdd));
|
|
162
|
-
// });
|
|
163
|
-
//
|
|
164
|
-
// extendsPrototype(ObservableChecker, 'handleClassValue', function(element, className) {
|
|
165
|
-
// let lastClass = this.val();
|
|
166
|
-
// if(typeof lastClass === 'string') {
|
|
167
|
-
// element.classes.toggle(lastClass, true);
|
|
168
|
-
// this.subscribe((currentValue) => {
|
|
169
|
-
// element.classes.remove(lastClass);
|
|
170
|
-
// element.classes.toggle(currentValue, true);
|
|
171
|
-
// lastClass = currentValue;
|
|
172
|
-
// });
|
|
1
|
+
// import {
|
|
2
|
+
// bindAttributeWithObservable,
|
|
3
|
+
// bindBooleanAttribute,
|
|
4
|
+
// } from '../AttributesWrapper';
|
|
5
|
+
// import ObservableItem from '../../data/ObservableItem';
|
|
6
|
+
// import TemplateBinding from '../TemplateBinding';
|
|
7
|
+
// import {BOOLEAN_ATTRIBUTES} from '../constants';
|
|
8
|
+
// import ObservableChecker from '../../data/ObservableChecker';
|
|
9
|
+
//
|
|
10
|
+
//
|
|
11
|
+
// ObservableItem.prototype.handleNdAttribute = function(element, attributeName) {
|
|
12
|
+
// if(BOOLEAN_ATTRIBUTES.has(attributeName)) {
|
|
13
|
+
// bindBooleanAttribute(element, attributeName, this);
|
|
173
14
|
// return;
|
|
174
15
|
// }
|
|
175
|
-
// element.classes.toggle(className, this.val());
|
|
176
|
-
// this.subscribe((shouldAdd) => element.classes.toggle(className, shouldAdd));
|
|
177
|
-
// });
|
|
178
16
|
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
// });
|
|
17
|
+
// bindAttributeWithObservable(element, attributeName, this);
|
|
18
|
+
// };
|
|
182
19
|
//
|
|
183
|
-
//
|
|
184
|
-
// element.classes.toggle(className, this);
|
|
185
|
-
// });
|
|
20
|
+
// ObservableChecker.prototype.handleNdAttribute = ObservableItem.prototype.handleNdAttribute;
|
|
186
21
|
//
|
|
187
|
-
//
|
|
188
|
-
// element
|
|
189
|
-
// }
|
|
22
|
+
// TemplateBinding.prototype.handleNdAttribute = function(element, attributeName) {
|
|
23
|
+
// this.$hydrate(element, attributeName);
|
|
24
|
+
// };
|
|
@@ -1,157 +1,131 @@
|
|
|
1
1
|
import ObservableItem from '../../data/ObservableItem';
|
|
2
|
-
import {
|
|
2
|
+
import {NDElement} from '../NDElement';
|
|
3
3
|
import TemplateBinding from '../TemplateBinding';
|
|
4
|
-
import {
|
|
4
|
+
import {ElementCreator} from '../ElementCreator';
|
|
5
5
|
import PluginsManager from '../../utils/plugins-manager';
|
|
6
6
|
import ObservableChecker from '../../data/ObservableChecker';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Extends a prototype with a non-enumerable, configurable, writable property.
|
|
10
|
-
*
|
|
11
|
-
* @param {Function} Constructor - The constructor whose prototype to extend
|
|
12
|
-
* @param {string} name - Property name
|
|
13
|
-
* @param {Function} fn - Implementation
|
|
14
|
-
*/
|
|
15
|
-
function extendsPrototype(Constructor, name, fn) {
|
|
16
|
-
Object.defineProperty(Constructor.prototype, name, {
|
|
17
|
-
value: fn,
|
|
18
|
-
enumerable: false,
|
|
19
|
-
configurable: true,
|
|
20
|
-
writable: true,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// -- Static assignment (not a prototype method) -------------------------------
|
|
25
8
|
|
|
26
9
|
NDElement.$getChild = ElementCreator.getChild;
|
|
27
10
|
|
|
28
|
-
// -- toNdElement --------------------------------------------------------------
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Converts a string to a static text node.
|
|
32
|
-
* @returns {Text}
|
|
33
|
-
*/
|
|
34
|
-
extendsPrototype(Object, 'toNdElement', function() {
|
|
35
|
-
return ElementCreator.createStaticTextNode(null, JSON.stringify(this));
|
|
36
|
-
});
|
|
37
|
-
|
|
38
11
|
/**
|
|
39
|
-
* Converts a string to a
|
|
40
|
-
*
|
|
12
|
+
* Converts a string to a reactive text node.
|
|
13
|
+
*
|
|
14
|
+
* @returns {Text} Static text node containing the string value
|
|
41
15
|
*/
|
|
42
|
-
|
|
16
|
+
String.prototype.toNdElement = function () {
|
|
43
17
|
return ElementCreator.createStaticTextNode(null, this);
|
|
44
|
-
}
|
|
18
|
+
};
|
|
45
19
|
|
|
46
20
|
/**
|
|
47
21
|
* Converts a number to a static text node.
|
|
48
|
-
*
|
|
22
|
+
*
|
|
23
|
+
* @returns {Text} Static text node containing the number as a string
|
|
49
24
|
*/
|
|
50
|
-
|
|
25
|
+
Number.prototype.toNdElement = function () {
|
|
51
26
|
return ElementCreator.createStaticTextNode(null, this.toString());
|
|
52
|
-
}
|
|
27
|
+
};
|
|
53
28
|
|
|
54
29
|
/**
|
|
55
30
|
* Returns the element itself (identity for DOM compatibility).
|
|
56
|
-
*
|
|
31
|
+
*
|
|
32
|
+
* @returns {Element} this
|
|
57
33
|
*/
|
|
58
|
-
|
|
34
|
+
Element.prototype.toNdElement = function () {
|
|
59
35
|
return this;
|
|
60
|
-
}
|
|
36
|
+
};
|
|
61
37
|
|
|
62
38
|
/**
|
|
63
39
|
* Returns the text node itself (identity for DOM compatibility).
|
|
64
|
-
*
|
|
40
|
+
*
|
|
41
|
+
* @returns {Text} this
|
|
65
42
|
*/
|
|
66
|
-
|
|
43
|
+
Text.prototype.toNdElement = function () {
|
|
67
44
|
return this;
|
|
68
|
-
}
|
|
45
|
+
};
|
|
69
46
|
|
|
70
47
|
/**
|
|
71
48
|
* Returns the comment node itself (identity for DOM compatibility).
|
|
72
|
-
*
|
|
49
|
+
*
|
|
50
|
+
* @returns {Comment} this
|
|
73
51
|
*/
|
|
74
|
-
|
|
52
|
+
Comment.prototype.toNdElement = function () {
|
|
75
53
|
return this;
|
|
76
|
-
}
|
|
54
|
+
};
|
|
77
55
|
|
|
78
56
|
/**
|
|
79
57
|
* Returns the document itself (identity for DOM compatibility).
|
|
80
|
-
*
|
|
58
|
+
*
|
|
59
|
+
* @returns {Document} this
|
|
81
60
|
*/
|
|
82
|
-
|
|
61
|
+
Document.prototype.toNdElement = function () {
|
|
83
62
|
return this;
|
|
84
|
-
}
|
|
63
|
+
};
|
|
85
64
|
|
|
86
65
|
/**
|
|
87
66
|
* Returns the document fragment itself (identity for DOM compatibility).
|
|
88
|
-
*
|
|
67
|
+
*
|
|
68
|
+
* @returns {DocumentFragment} this
|
|
89
69
|
*/
|
|
90
|
-
|
|
70
|
+
DocumentFragment.prototype.toNdElement = function () {
|
|
91
71
|
return this;
|
|
92
|
-
}
|
|
72
|
+
};
|
|
93
73
|
|
|
94
74
|
/**
|
|
95
75
|
* Converts the ObservableItem to a reactive text node that updates automatically when the value changes.
|
|
96
|
-
*
|
|
76
|
+
*
|
|
77
|
+
* @returns {Text} Reactive text node bound to this observable
|
|
97
78
|
*/
|
|
98
|
-
|
|
79
|
+
ObservableItem.prototype.toNdElement = function () {
|
|
99
80
|
return ElementCreator.createObservableNode(null, this);
|
|
100
|
-
}
|
|
81
|
+
};
|
|
101
82
|
|
|
102
|
-
|
|
103
|
-
* ObservableChecker shares the same reactive text node behaviour as ObservableItem.
|
|
104
|
-
* @returns {Text}
|
|
105
|
-
*/
|
|
106
|
-
extendsPrototype(ObservableChecker, 'toNdElement', ObservableItem.prototype.toNdElement);
|
|
83
|
+
ObservableChecker.prototype.toNdElement = ObservableItem.prototype.toNdElement;
|
|
107
84
|
|
|
108
85
|
/**
|
|
109
86
|
* Converts the NDElement to its underlying HTMLElement (or ghost DOM fragment if ghostDom was used).
|
|
110
|
-
*
|
|
87
|
+
*
|
|
88
|
+
* @returns {HTMLElement|DocumentFragment} The underlying DOM node
|
|
111
89
|
*/
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (!this.$attachements.contains(this.$element)) {
|
|
116
|
-
this.$attachements.append(this.$element);
|
|
117
|
-
}
|
|
118
|
-
return this.$attachements;
|
|
119
|
-
}
|
|
120
|
-
return element;
|
|
121
|
-
});
|
|
90
|
+
NDElement.prototype.toNdElement = function () {
|
|
91
|
+
return this.$element;
|
|
92
|
+
};
|
|
122
93
|
|
|
123
94
|
/**
|
|
124
|
-
* Converts the array to a DocumentFragment containing all
|
|
95
|
+
* Converts the array to a DocumentFragment containing all elements.
|
|
125
96
|
* Each item is processed through ElementCreator.getChild().
|
|
126
|
-
*
|
|
97
|
+
*
|
|
98
|
+
* @returns {DocumentFragment} Fragment containing all array children
|
|
127
99
|
*/
|
|
128
|
-
|
|
100
|
+
Array.prototype.toNdElement = function () {
|
|
129
101
|
const fragment = document.createDocumentFragment();
|
|
130
|
-
for
|
|
102
|
+
for(let i = 0, length = this.length; i < length; i++) {
|
|
131
103
|
const child = ElementCreator.getChild(this[i]);
|
|
132
|
-
if
|
|
104
|
+
if(child === null) continue;
|
|
133
105
|
fragment.appendChild(child);
|
|
134
106
|
}
|
|
135
107
|
return fragment;
|
|
136
|
-
}
|
|
108
|
+
};
|
|
137
109
|
|
|
138
110
|
/**
|
|
139
111
|
* Calls the function and converts its return value to a DOM node.
|
|
140
112
|
* Used internally by ElementCreator to process function-based children.
|
|
141
|
-
*
|
|
113
|
+
*
|
|
114
|
+
* @returns {Node} The DOM node returned by the function
|
|
142
115
|
*/
|
|
143
|
-
|
|
116
|
+
Function.prototype.toNdElement = function () {
|
|
144
117
|
const child = this;
|
|
145
|
-
if
|
|
118
|
+
if(process.env.NODE_ENV === 'development') {
|
|
146
119
|
PluginsManager.emit('BeforeProcessComponent', child);
|
|
147
120
|
}
|
|
148
121
|
return ElementCreator.getChild(child());
|
|
149
|
-
}
|
|
122
|
+
};
|
|
150
123
|
|
|
151
124
|
/**
|
|
152
125
|
* Converts the TemplateBinding to a hydratable DOM node for use in TemplateCloner.
|
|
153
|
-
*
|
|
126
|
+
*
|
|
127
|
+
* @returns {Node} Hydratable node
|
|
154
128
|
*/
|
|
155
|
-
|
|
129
|
+
TemplateBinding.prototype.toNdElement = function () {
|
|
156
130
|
return ElementCreator.createHydratableNode(null, this);
|
|
157
|
-
}
|
|
131
|
+
};
|