native-document 1.0.169 → 1.0.173
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/CHANGELOG.md +100 -2
- package/docs/vitepress-conventions.md +2 -2
- package/index.d.ts +1 -1
- package/package.json +11 -4
- package/src/components/BaseComponent.js +43 -1
- package/src/components/accordion/Accordion.js +1 -0
- package/src/components/accordion/AccordionItem.js +1 -0
- package/src/components/alert/Alert.js +4 -0
- package/src/components/avatar/Avatar.js +1 -0
- package/src/components/avatar/AvatarGroup.js +1 -0
- package/src/components/badge/Badge.js +1 -0
- package/src/components/breadcrumb/BreadCrumb.js +4 -0
- package/src/components/button/Button.js +1 -0
- package/src/components/card/Card.js +1 -0
- package/src/components/context-menu/ContextMenu.js +2 -0
- package/src/components/context-menu/ContextMenuGroup.js +2 -0
- package/src/components/context-menu/ContextMenuItem.js +2 -0
- package/src/components/divider/Divider.js +2 -0
- package/src/components/dropdown/Dropdown.js +1 -0
- package/src/components/dropdown/DropdownDivider.js +1 -0
- package/src/components/dropdown/DropdownGroup.js +1 -0
- package/src/components/dropdown/DropdownItem.js +1 -0
- package/src/components/dropdown/DropdownTrigger.js +1 -0
- package/src/components/form/FormControl.js +1 -0
- package/src/components/form/field/Field.js +1 -0
- package/src/components/form/field/types/StringField.js +1 -1
- package/src/components/icon/Icon.js +1 -0
- package/src/components/list/ListItem.js +1 -0
- package/src/components/menu/Menu.js +3 -0
- package/src/components/menu/MenuDivider.js +1 -0
- package/src/components/menu/MenuGroup.js +1 -0
- package/src/components/menu/MenuItem.js +1 -0
- package/src/components/menu/MenuLink.js +1 -0
- package/src/components/modal/Modal.js +4 -0
- package/src/components/pagination/Pagination.js +1 -0
- package/src/components/popover/Popover.js +1 -0
- package/src/components/popover/PopoverFooter.js +1 -0
- package/src/components/popover/PopoverHeader.js +1 -0
- package/src/components/progress/Progress.js +5 -0
- package/src/components/skeleton/Skeleton.js +4 -0
- package/src/components/slider/Slider.js +1 -0
- package/src/components/spacer/Spacer.js +1 -0
- package/src/components/spinner/Spinner.js +1 -0
- package/src/components/splitter/Splitter.js +1 -0
- package/src/components/splitter/SplitterGutter.js +6 -0
- package/src/components/splitter/SplitterPanel.js +1 -0
- package/src/components/stacks/AbsoluteStack.js +1 -0
- package/src/components/stacks/FixedStack.js +1 -0
- package/src/components/stacks/HStack.js +1 -0
- package/src/components/stacks/PositionStack.js +1 -0
- package/src/components/stacks/RelativeStack.js +1 -0
- package/src/components/stacks/Stack.js +1 -0
- package/src/components/stacks/VStack.js +1 -0
- package/src/components/stepper/Stepper.js +1 -0
- package/src/components/stepper/StepperStep.js +1 -0
- package/src/components/switch/Switch.js +1 -0
- package/src/components/table/DataTable.js +1 -0
- package/src/components/table/SimpleTable.js +1 -0
- package/src/components/tabs/Tabs.js +1 -0
- package/src/components/toast/Toast.js +1 -0
- package/src/components/tooltip/Tooltip.js +1 -0
- package/src/core/data/MemoryManager.js +6 -1
- package/src/core/data/ObservableItem.js +33 -15
- package/src/core/data/ObservableObject.js +1 -2
- package/src/core/elements/anchor/anchor.js +4 -3
- package/src/core/elements/anchor/one-child-anchor-overwriting.js +4 -4
- package/src/core/elements/content-formatter.js +19 -0
- package/src/core/elements/control/for-each-array-cache.js +59 -0
- package/src/core/elements/control/for-each-array.js +15 -23
- package/src/core/wrappers/AttributesWrapper.js +12 -12
- package/src/core/wrappers/ElementCreator.js +33 -10
- package/src/core/wrappers/HtmlElementWrapper.js +17 -13
- package/src/core/wrappers/NDElement.js +23 -8
- package/src/core/wrappers/NdPrototype.js +64 -39
- package/src/core/wrappers/constants.js +12 -12
- package/src/core/wrappers/prototypes/nd-element-extensions.js +127 -57
- package/src/core/wrappers/template-cloner/NodeCloner.js +10 -6
- package/src/core/wrappers/template-cloner/TemplateCloner.js +7 -4
- package/src/fetch/NativeFetch.js +1 -0
- package/src/ui/components/accordion/AccordionItemRender.js +29 -7
- package/src/ui/components/alert/AlertRender.js +6 -0
- package/src/ui/components/breadcrumb/BreadcrumbRender.js +9 -1
- package/src/ui/components/button/ButtonRender.js +3 -0
- package/src/ui/components/contextmenu/ContextmenuRender.js +2 -0
- package/src/ui/components/dropdown/DropdownRender.js +3 -0
- package/src/ui/components/dropdown/item/DropdownItemRender.js +6 -1
- package/src/ui/components/form/FieldCollectionRender.js +4 -0
- package/src/ui/components/form/fields/CheckboxFieldRender.js +4 -0
- package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +4 -0
- package/src/ui/components/form/fields/FieldRender.js +1 -1
- package/src/ui/components/form/fields/RadioFieldRender.js +4 -0
- package/src/ui/components/form/fields/RangeFieldRender.js +4 -0
- package/src/ui/components/form/fields/SelectFieldRender.js +5 -0
- package/src/ui/components/form/fields/SliderFieldRender.js +3 -0
- package/src/ui/components/icon/tabler/TablerIconRender.js +0 -1
- package/src/ui/components/list/item/ListItemRender.js +4 -0
- package/src/ui/components/menu/MenuItemRender.js +8 -0
- package/src/ui/components/menu/MenuLinkRender.js +11 -0
- package/src/ui/components/menu/MenuRender.js +5 -0
- package/src/ui/components/menu/helpers.js +2 -1
- package/src/ui/components/modal/ModalRender.js +8 -2
- package/src/ui/components/progress/ProgressRender.js +9 -0
- package/src/ui/components/skeleton/SkeletonRender.js +2 -0
- package/src/ui/components/spinner/SpinnerRender.js +3 -0
- package/src/ui/components/splitter/SplitterGutterRender.js +4 -0
- package/src/ui/components/splitter/SplitterPanelRender.js +4 -0
- package/src/ui/components/splitter/SplitterRender.js +2 -0
- package/src/ui/components/stepper/StepperRender.js +2 -1
- package/src/ui/components/stepper/StepperStepRender.js +8 -1
- package/src/ui/components/switch/SwitchRender.js +3 -0
- package/src/ui/components/table/data-table/DataTableRender.js +4 -0
- package/src/ui/components/table/simple-table/SimpleTableRender.js +2 -0
- package/src/ui/components/toast/ToastRender.js +4 -0
- package/src/ui/utils/aria.js +19 -0
- package/tests/integration/ui/attributes-wrapper.test.js +177 -0
- package/tests/integration/ui/for-each-array.test.js +167 -0
- package/tests/integration/ui/lifecycle.test.js +146 -0
- package/tests/integration/ui/show-if.test.js +168 -0
- package/tests/unit/core/observable-array.test.js +404 -0
- package/tests/unit/core/observable-item.test.js +428 -0
- package/tests/unit/core/observable-object.test.js +239 -0
- package/tests/unit/core/observable-resource.test.js +323 -0
- package/tests/unit/core/store.test.js +347 -0
- package/tests/unit/router/route-matching.test.js +169 -0
- package/tests/unit/router/router-guards.test.js +189 -0
- package/tests/unit/utils/cache.test.js +120 -0
- package/tests/unit/utils/filters.test.js +394 -0
- package/types/elements.d.ts +5 -0
- package/types/native-fetch.d.ts +1 -1
- package/types/observable-resource.d.ts +2 -2
- package/types/observable.d.ts +137 -21
- package/types/service.d.ts +2 -1
- package/utils.js +7 -4
- package/vitest.config.js +15 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Validator from '../utils/validator';
|
|
2
1
|
import AttributesWrapper, { bindClassAttribute, bindStyleAttribute } from './AttributesWrapper';
|
|
3
2
|
import PluginsManager from '../utils/plugins-manager';
|
|
4
3
|
|
|
@@ -8,7 +7,7 @@ export const ElementCreator = {
|
|
|
8
7
|
createTextNode() {
|
|
9
8
|
if(!$textNodeCache) {
|
|
10
9
|
$textNodeCache = document.createTextNode('');
|
|
11
|
-
ElementCreator.createTextNode =
|
|
10
|
+
ElementCreator.createTextNode = $textNodeCache.cloneNode.bind($textNodeCache);
|
|
12
11
|
}
|
|
13
12
|
return $textNodeCache.cloneNode();
|
|
14
13
|
},
|
|
@@ -19,10 +18,19 @@ export const ElementCreator = {
|
|
|
19
18
|
* @returns {Text}
|
|
20
19
|
*/
|
|
21
20
|
createObservableNode: (parent, observable) => {
|
|
21
|
+
const text = ElementCreator.createObservableNodeWithoutParent(observable);
|
|
22
|
+
parent && parent.appendChild(text);
|
|
23
|
+
return text;
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {ObservableItem} observable
|
|
28
|
+
* @returns {Text}
|
|
29
|
+
*/
|
|
30
|
+
createObservableNodeWithoutParent: (observable) => {
|
|
22
31
|
const text = ElementCreator.createTextNode();
|
|
23
32
|
observable.subscribe(value => text.nodeValue = value);
|
|
24
33
|
text.nodeValue = observable.val();
|
|
25
|
-
parent && parent.appendChild(text);
|
|
26
34
|
return text;
|
|
27
35
|
},
|
|
28
36
|
/**
|
|
@@ -49,6 +57,11 @@ export const ElementCreator = {
|
|
|
49
57
|
parent && parent.appendChild(text);
|
|
50
58
|
return text;
|
|
51
59
|
},
|
|
60
|
+
createStaticTextNodeWithoutParent: (value) => {
|
|
61
|
+
const text = ElementCreator.createTextNode();
|
|
62
|
+
text.nodeValue = value;
|
|
63
|
+
return text;
|
|
64
|
+
},
|
|
52
65
|
/**
|
|
53
66
|
*
|
|
54
67
|
* @param {string} name
|
|
@@ -72,27 +85,37 @@ export const ElementCreator = {
|
|
|
72
85
|
* @param {HTMLElement|DocumentFragment} parent
|
|
73
86
|
*/
|
|
74
87
|
processChildren: (children, parent) => {
|
|
75
|
-
if(children === null) return;
|
|
76
88
|
if(process.env.NODE_ENV === 'development') {
|
|
77
89
|
PluginsManager.emit('BeforeProcessChildren', parent);
|
|
78
90
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
if(Array.isArray(children)) {
|
|
92
|
+
for(let i = 0, length = children.length; i < length; i++) {
|
|
93
|
+
const child = ElementCreator.getChild(children[i]);
|
|
94
|
+
if(child === null) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
parent.appendChild(child);
|
|
98
|
+
}
|
|
99
|
+
return;
|
|
82
100
|
}
|
|
101
|
+
const child = ElementCreator.getChild(children);
|
|
102
|
+
parent.appendChild(child);
|
|
83
103
|
if(process.env.NODE_ENV === 'development') {
|
|
84
104
|
PluginsManager.emit('AfterProcessChildren', parent);
|
|
85
105
|
}
|
|
86
106
|
},
|
|
87
107
|
async safeRemove(element) {
|
|
88
108
|
await element.remove();
|
|
89
|
-
|
|
90
109
|
},
|
|
91
110
|
getChild: (child) => {
|
|
92
|
-
if (child == null)
|
|
111
|
+
if (child == null) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
93
114
|
|
|
94
115
|
child = child.toNdElement();
|
|
95
|
-
if (child instanceof Node)
|
|
116
|
+
if (child && (child instanceof Node)) {
|
|
117
|
+
return child;
|
|
118
|
+
}
|
|
96
119
|
|
|
97
120
|
while (child != null && !(child instanceof Node)) {
|
|
98
121
|
child = child.toNdElement?.();
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Anchor from '../elements/anchor/anchor';
|
|
2
2
|
import {ElementCreator} from './ElementCreator';
|
|
3
|
-
import {normalizeComponentArgs} from '../utils/args-types';
|
|
4
3
|
import './NdPrototype';
|
|
5
4
|
|
|
6
5
|
import '../../core/utils/prototypes.js';
|
|
@@ -19,7 +18,7 @@ import '../wrappers/prototypes/attributes-extensions';
|
|
|
19
18
|
* @returns {Text} Text node, reactive if value is an ObservableItem
|
|
20
19
|
*/
|
|
21
20
|
export const createTextNode = (value) => {
|
|
22
|
-
if(value) {
|
|
21
|
+
if(value != null) {
|
|
23
22
|
return value.toNdElement();
|
|
24
23
|
}
|
|
25
24
|
return ElementCreator.createTextNode();
|
|
@@ -36,10 +35,11 @@ export const createTextNode = (value) => {
|
|
|
36
35
|
* @returns {HTMLElement} The configured element
|
|
37
36
|
*/
|
|
38
37
|
export const createVoidHtmlElement = (element, attributes) => {
|
|
39
|
-
ElementCreator.processAttributes(element, attributes);
|
|
38
|
+
attributes && ElementCreator.processAttributes(element, attributes);
|
|
40
39
|
return element;
|
|
41
40
|
};
|
|
42
41
|
|
|
42
|
+
|
|
43
43
|
const OBJECT_PROTOTYPE = Object.prototype;
|
|
44
44
|
/**
|
|
45
45
|
* Applies attributes and children to an existing HTMLElement.
|
|
@@ -53,13 +53,18 @@ const OBJECT_PROTOTYPE = Object.prototype;
|
|
|
53
53
|
*/
|
|
54
54
|
export const createHtmlElement = (element, _attributes, _children = null) => {
|
|
55
55
|
let attributes = _attributes, children = _children;
|
|
56
|
-
if(
|
|
56
|
+
if(_attributes?.__$isValidNdChild) { // If attributes is a ValidChild
|
|
57
57
|
attributes = _children;
|
|
58
58
|
children = _attributes;
|
|
59
59
|
}
|
|
60
|
+
element = element.cloneNode();
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
if(attributes != null) {
|
|
63
|
+
ElementCreator.processAttributes(element, attributes);
|
|
64
|
+
}
|
|
65
|
+
if(children != null) {
|
|
66
|
+
ElementCreator.processChildren(children, element);
|
|
67
|
+
}
|
|
63
68
|
return element;
|
|
64
69
|
};
|
|
65
70
|
|
|
@@ -70,6 +75,7 @@ export const createHtmlElement = (element, _attributes, _children = null) => {
|
|
|
70
75
|
*
|
|
71
76
|
* @param {string} name - HTML tag name (e.g. 'div', 'button', 'input'). Pass empty string to create a Fragment.
|
|
72
77
|
* @param {((element: HTMLElement) => HTMLElement)|null} [customWrapper=null] - Optional function to augment the element before returning
|
|
78
|
+
* @param {boolean} [isVoid=false] - If true, the element is a void element (no children allowed, e.g. input, img)
|
|
73
79
|
* @returns {(attr?: Object, children?: ValidChild) => HTMLElement} Element factory function
|
|
74
80
|
* @example
|
|
75
81
|
* const Div = HtmlElementWrapper('div');
|
|
@@ -84,14 +90,12 @@ export const createHtmlElement = (element, _attributes, _children = null) => {
|
|
|
84
90
|
export default function HtmlElementWrapper(name, customWrapper = null, isVoid = false) {
|
|
85
91
|
const elementCreator = isVoid ? createVoidHtmlElement : createHtmlElement;
|
|
86
92
|
if(name) {
|
|
87
|
-
if(customWrapper) {
|
|
93
|
+
if(customWrapper == null) {
|
|
88
94
|
let node = null;
|
|
89
95
|
let createElement = (attr, children) => {
|
|
90
96
|
node = document.createElement(name);
|
|
91
|
-
createElement = (
|
|
92
|
-
|
|
93
|
-
};
|
|
94
|
-
return elementCreator(customWrapper(node.cloneNode()), attr, children);;
|
|
97
|
+
createElement = elementCreator.bind(null, node);
|
|
98
|
+
return elementCreator(node.cloneNode(), attr, children);
|
|
95
99
|
};
|
|
96
100
|
|
|
97
101
|
return (attr, children) => createElement(attr, children);
|
|
@@ -101,9 +105,9 @@ export default function HtmlElementWrapper(name, customWrapper = null, isVoid =
|
|
|
101
105
|
let createElement = (attr, children) => {
|
|
102
106
|
node = document.createElement(name);
|
|
103
107
|
createElement = (attr, children) => {
|
|
104
|
-
return elementCreator(node.cloneNode(), attr, children);
|
|
108
|
+
return elementCreator(customWrapper(node.cloneNode()), attr, children);
|
|
105
109
|
};
|
|
106
|
-
return elementCreator(node.cloneNode(), attr, children)
|
|
110
|
+
return elementCreator(customWrapper(node.cloneNode()), attr, children);;
|
|
107
111
|
};
|
|
108
112
|
|
|
109
113
|
return (attr, children) => createElement(attr, children);
|
|
@@ -187,16 +187,32 @@ NDElement.prototype.destroyOnUnmount = function() {
|
|
|
187
187
|
* @returns {this}
|
|
188
188
|
*/
|
|
189
189
|
NDElement.prototype.destroy = function() {
|
|
190
|
-
this.$element
|
|
190
|
+
if(!this.$element) {
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
const observer = $lifeCycleObservers.get(this.$element);
|
|
194
|
+
if(observer) {
|
|
195
|
+
observer.disconnect();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const treewalk = document.createTreeWalker(this.$element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
|
|
199
|
+
const nodes = [];
|
|
200
|
+
while(treewalk.nextNode()) {
|
|
201
|
+
nodes.push(treewalk.currentNode);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
for(let i = 0, length = nodes.length; i < length; i++) {
|
|
205
|
+
const child = nodes[i];
|
|
191
206
|
child.remove();
|
|
192
|
-
|
|
193
|
-
|
|
207
|
+
const childObserver = $lifeCycleObservers.get(child);
|
|
208
|
+
if(childObserver) {
|
|
209
|
+
childObserver.disconnect();
|
|
210
|
+
}
|
|
194
211
|
$lifeCycleObservers.delete(child);
|
|
195
|
-
}
|
|
212
|
+
}
|
|
196
213
|
|
|
197
|
-
this.$element.__$controller?.abort();
|
|
198
|
-
this.$element.__$controller = null;
|
|
199
214
|
$lifeCycleObservers.delete(this.$element);
|
|
215
|
+
this.$element.remove();
|
|
200
216
|
this.$element = null;
|
|
201
217
|
};
|
|
202
218
|
|
|
@@ -418,7 +434,6 @@ NDElement.prototype.style = function(style) {
|
|
|
418
434
|
return this;
|
|
419
435
|
};
|
|
420
436
|
|
|
421
|
-
|
|
422
437
|
/**
|
|
423
438
|
* Extends the NDElement prototype with new methods available to all NDElement instances.
|
|
424
439
|
* Use this to add global methods to all NDElements.
|
|
@@ -618,7 +633,7 @@ NDElement.prototype.contentEditable = function($obs, {format = 'html'} = {}) {
|
|
|
618
633
|
|
|
619
634
|
this.$element.addEventListener('input', () => {
|
|
620
635
|
$obs?.set(getValue());
|
|
621
|
-
}
|
|
636
|
+
});
|
|
622
637
|
|
|
623
638
|
return this;
|
|
624
639
|
};
|
|
@@ -20,64 +20,74 @@ Object.defineProperty(NDElement.prototype, 'nd', {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
|
|
24
23
|
// ----------------------------------------------------------------
|
|
25
24
|
// Events helpers
|
|
26
25
|
// ----------------------------------------------------------------
|
|
27
26
|
EVENTS.forEach(eventSourceName => {
|
|
28
27
|
const eventName = eventSourceName.toLowerCase();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
const inlineHandler = 'on'+eventName;
|
|
29
|
+
const fnName = 'on'+eventSourceName;
|
|
30
|
+
NDElement.prototype[fnName] = function(callback = null, options = null) {
|
|
31
|
+
if(!this.$element[inlineHandler] && !options) {
|
|
32
|
+
this.$element[inlineHandler] = callback;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
this.$element.addEventListener(eventName, callback, options);
|
|
34
36
|
return this;
|
|
35
37
|
};
|
|
38
|
+
if(!HTMLElement.prototype[fnName]) {
|
|
39
|
+
HTMLElement.prototype[fnName] = function(callback, options) {
|
|
40
|
+
if(!this[inlineHandler] && !options) {
|
|
41
|
+
this[inlineHandler] = callback;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
this.addEventListener(eventName, callback, options);
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
36
48
|
});
|
|
37
49
|
|
|
38
50
|
EVENTS_WITH_STOP.forEach(eventSourceName => {
|
|
39
51
|
const eventName = eventSourceName.toLowerCase();
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
const stopFnName = 'onStop'+eventSourceName;
|
|
53
|
+
const preventStopFnName = 'onPreventStop'+eventSourceName;
|
|
54
|
+
|
|
55
|
+
NDElement.prototype[stopFnName] = function(callback = null, options = null) {
|
|
56
|
+
_stop(this.$element, eventName, callback, options);
|
|
45
57
|
return this;
|
|
46
58
|
};
|
|
47
|
-
NDElement.prototype[
|
|
48
|
-
_preventStop(this.$element, eventName, callback,
|
|
49
|
-
signal: this.$getSignal(),
|
|
50
|
-
...options,
|
|
51
|
-
});
|
|
59
|
+
NDElement.prototype[preventStopFnName] = function(callback = null, options = null) {
|
|
60
|
+
_preventStop(this.$element, eventName, callback, options);
|
|
52
61
|
return this;
|
|
53
62
|
};
|
|
63
|
+
if(HTMLElement.prototype[stopFnName]) {
|
|
64
|
+
HTMLElement.prototype[stopFnName] = function(callback = null, options = null) {
|
|
65
|
+
_stop(this, eventName, callback, options);
|
|
66
|
+
return this;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if(!HTMLElement.prototype[preventStopFnName]) {
|
|
70
|
+
HTMLElement.prototype[preventStopFnName] = function(callback = null, options = null) {
|
|
71
|
+
_preventStop(this, eventName, callback, options);
|
|
72
|
+
return this;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
54
75
|
});
|
|
55
76
|
|
|
56
77
|
EVENTS_WITH_PREVENT.forEach(eventSourceName => {
|
|
57
78
|
const eventName = eventSourceName.toLowerCase();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
...options,
|
|
62
|
-
});
|
|
79
|
+
const preventFnName = 'onPrevent'+eventSourceName;
|
|
80
|
+
NDElement.prototype[preventFnName] = function(callback = null, options = null) {
|
|
81
|
+
_prevent(this.$element, eventName, callback, options);
|
|
63
82
|
return this;
|
|
64
83
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
* Used internally by all event listeners (onClick, onInput, etc.) to auto-cleanup on unmount.
|
|
71
|
-
*
|
|
72
|
-
* @internal
|
|
73
|
-
* @returns {AbortSignal} The signal for this element's AbortController
|
|
74
|
-
*/
|
|
75
|
-
NDElement.prototype.$getSignal = function() {
|
|
76
|
-
if(!this.$element.__$controller) {
|
|
77
|
-
this.$element.__$controller = new AbortController();
|
|
84
|
+
if(HTMLElement.prototype[preventFnName]) {
|
|
85
|
+
HTMLElement.prototype[preventFnName] = function(callback = null, options = null) {
|
|
86
|
+
_prevent(this, eventName, callback, options);
|
|
87
|
+
return this;
|
|
88
|
+
};
|
|
78
89
|
}
|
|
79
|
-
|
|
80
|
-
};
|
|
90
|
+
});
|
|
81
91
|
|
|
82
92
|
|
|
83
93
|
/**
|
|
@@ -91,7 +101,6 @@ NDElement.prototype.$getSignal = function() {
|
|
|
91
101
|
*/
|
|
92
102
|
NDElement.prototype.on = function(name, callback, options) {
|
|
93
103
|
this.$element.addEventListener(name.toLowerCase(), callback, {
|
|
94
|
-
signal: this.$getSignal(),
|
|
95
104
|
...options,
|
|
96
105
|
});
|
|
97
106
|
return this;
|
|
@@ -119,7 +128,6 @@ NDElement.prototype.off = function(name, callback) {
|
|
|
119
128
|
*/
|
|
120
129
|
NDElement.prototype.once = function(name, callback) {
|
|
121
130
|
this.$element.addEventListener(name.toLowerCase(), callback, {
|
|
122
|
-
signal: this.$getSignal(),
|
|
123
131
|
once: true,
|
|
124
132
|
});
|
|
125
133
|
return this;
|
|
@@ -151,8 +159,13 @@ const _prevent = function(element, eventName, callback, options) {
|
|
|
151
159
|
event.preventDefault();
|
|
152
160
|
callback && callback.call(element, event);
|
|
153
161
|
};
|
|
162
|
+
|
|
163
|
+
const inlineHandler = 'on' + eventName;
|
|
164
|
+
if(!element[inlineHandler] && !options) {
|
|
165
|
+
element[inlineHandler] = handler;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
154
168
|
element.addEventListener(eventName, handler, options);
|
|
155
|
-
return this;
|
|
156
169
|
};
|
|
157
170
|
|
|
158
171
|
const _stop = function(element, eventName, callback, options) {
|
|
@@ -160,6 +173,13 @@ const _stop = function(element, eventName, callback, options) {
|
|
|
160
173
|
event.stopPropagation();
|
|
161
174
|
callback && callback.call(element, event);
|
|
162
175
|
};
|
|
176
|
+
|
|
177
|
+
const inlineHandler = 'on' + eventName;
|
|
178
|
+
if(!element[inlineHandler] && !options) {
|
|
179
|
+
element[inlineHandler] = handler;
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
163
183
|
element.addEventListener(eventName, handler, options);
|
|
164
184
|
return this;
|
|
165
185
|
};
|
|
@@ -170,6 +190,11 @@ const _preventStop = function(element, eventName, callback, options) {
|
|
|
170
190
|
event.preventDefault();
|
|
171
191
|
callback && callback.call(element, event);
|
|
172
192
|
};
|
|
193
|
+
const inlineHandler = 'on' + eventName;
|
|
194
|
+
if(!element[inlineHandler] && !options) {
|
|
195
|
+
element[inlineHandler] = handler;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
173
198
|
element.addEventListener(eventName, handler, options);
|
|
174
199
|
return this;
|
|
175
200
|
};
|
|
@@ -3,19 +3,19 @@ export const BOOLEAN_ATTRIBUTES = new Set([
|
|
|
3
3
|
'checked',
|
|
4
4
|
'selected',
|
|
5
5
|
'disabled',
|
|
6
|
-
'readonly',
|
|
6
|
+
'readonly', 'readOnly',
|
|
7
7
|
'required',
|
|
8
|
-
'autofocus',
|
|
8
|
+
'autofocus', 'autoFocus',
|
|
9
9
|
'multiple',
|
|
10
|
-
'autocomplete',
|
|
10
|
+
'autocomplete', 'autoComplete',
|
|
11
11
|
'hidden',
|
|
12
|
-
'contenteditable',
|
|
13
|
-
'spellcheck',
|
|
12
|
+
'contenteditable', 'contentEditable',
|
|
13
|
+
'spellcheck', 'spellCheck',
|
|
14
14
|
'translate',
|
|
15
15
|
'draggable',
|
|
16
16
|
'async',
|
|
17
17
|
'defer',
|
|
18
|
-
'autoplay',
|
|
18
|
+
'autoplay', 'autoPlay',
|
|
19
19
|
'controls',
|
|
20
20
|
'loop',
|
|
21
21
|
'muted',
|
|
@@ -23,13 +23,13 @@ export const BOOLEAN_ATTRIBUTES = new Set([
|
|
|
23
23
|
'reversed',
|
|
24
24
|
'open',
|
|
25
25
|
'default',
|
|
26
|
-
'formnovalidate',
|
|
27
|
-
'novalidate',
|
|
26
|
+
'formnovalidate', 'formNoValidate',
|
|
27
|
+
'novalidate', 'noValidate',
|
|
28
28
|
'scoped',
|
|
29
|
-
'itemscope',
|
|
30
|
-
'allowfullscreen',
|
|
31
|
-
'allowpaymentrequest',
|
|
32
|
-
'playsinline',
|
|
29
|
+
'itemscope', 'itemScope',
|
|
30
|
+
'allowfullscreen', 'allowFullscreen',
|
|
31
|
+
'allowpaymentrequest', 'allowPaymentRequest',
|
|
32
|
+
'playsinline', 'playsInline',
|
|
33
33
|
]);
|
|
34
34
|
|
|
35
35
|
export const BOOL_ATTRIBUTES_NAME = {
|