native-document 1.0.93 → 1.0.95

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.components.min.js +667 -62
  2. package/dist/native-document.dev.js +878 -111
  3. package/dist/native-document.dev.js.map +1 -1
  4. package/dist/native-document.devtools.min.js +1 -1
  5. package/dist/native-document.min.js +1 -1
  6. package/elements.js +1 -0
  7. package/index.def.js +1086 -0
  8. package/package.json +1 -1
  9. package/src/core/elements/anchor.js +28 -20
  10. package/src/core/elements/content-formatter.js +138 -1
  11. package/src/core/elements/control/for-each-array.js +1 -1
  12. package/src/core/elements/control/for-each.js +2 -2
  13. package/src/core/elements/control/show-if.js +3 -3
  14. package/src/core/elements/control/show-when.js +2 -2
  15. package/src/core/elements/control/switch.js +1 -1
  16. package/src/core/elements/description-list.js +14 -0
  17. package/src/core/elements/form.js +188 -4
  18. package/src/core/elements/html5-semantics.js +44 -1
  19. package/src/core/elements/img.js +22 -10
  20. package/src/core/elements/index.js +5 -0
  21. package/src/core/elements/interactive.js +19 -1
  22. package/src/core/elements/list.js +28 -1
  23. package/src/core/elements/medias.js +29 -0
  24. package/src/core/elements/meta-data.js +34 -0
  25. package/src/core/elements/table.js +59 -0
  26. package/src/core/utils/helpers.js +7 -2
  27. package/src/core/utils/memoize.js +1 -1
  28. package/src/core/wrappers/DocumentObserver.js +102 -31
  29. package/src/core/wrappers/ElementCreator.js +5 -0
  30. package/src/core/wrappers/HtmlElementWrapper.js +2 -2
  31. package/src/core/wrappers/NDElement.js +33 -2
  32. package/src/core/wrappers/TemplateCloner.js +1 -1
  33. package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +83 -0
  34. package/types/elements.d.ts +1073 -113
  35. package/types/forms.d.ts +85 -48
  36. package/types/images.d.ts +16 -9
  37. package/types/nd-element.d.ts +6 -0
@@ -2,18 +2,30 @@ import HtmlElementWrapper from "../wrappers/HtmlElementWrapper"
2
2
  import Validator from "../utils/validator";
3
3
  import NativeDocumentError from "../errors/NativeDocumentError";
4
4
 
5
+ /**
6
+ * Creates an `<img>` element.
7
+ * @type {function(ImgAttributes=): HTMLImageElement}
8
+ */
5
9
  export const BaseImage = HtmlElementWrapper('img');
10
+
11
+ /**
12
+ * Creates an `<img>` element.
13
+ * @param {Observable<string>|string} src
14
+ * @param {Omit<ImgAttributes, 'src'>} [attributes]
15
+ * @returns {HTMLImageElement}
16
+ */
6
17
  export const Img = function(src, attributes) {
7
18
  return BaseImage({ src, ...attributes });
8
19
  };
9
20
 
10
21
  /**
11
- *
12
- * @param {string} src
13
- * @param {string|null} defaultImage
14
- * @param {Object} attributes
15
- * @param {?Function} callback
16
- * @returns {Image}
22
+ * Creates an `<img>` that loads asynchronously, showing a placeholder until the image is ready.
23
+ * Supports reactive `src` — automatically updates when the observable changes.
24
+ * @param {Observable<string>|string} src - Final image URL
25
+ * @param {string|null} defaultImage - Placeholder shown while loading
26
+ * @param {Omit<ImgAttributes, 'src'>} attributes
27
+ * @param {(error: NativeDocumentError|null, img: HTMLImageElement) => void} [callback]
28
+ * @returns {HTMLImageElement}
17
29
  */
18
30
  export const AsyncImg = function(src, defaultImage, attributes, callback) {
19
31
  const defaultSrc = Validator.isObservable(src) ? src.val() : src;
@@ -37,10 +49,10 @@ export const AsyncImg = function(src, defaultImage, attributes, callback) {
37
49
  };
38
50
 
39
51
  /**
40
- *
41
- * @param {string} src
42
- * @param {Object} attributes
43
- * @returns {Image}
52
+ * Creates an `<img loading="lazy">` element.
53
+ * @param {Observable<string>|string} src
54
+ * @param {Omit<ImgAttributes, 'src'|'loading'>} [attributes]
55
+ * @returns {HTMLImageElement}
44
56
  */
45
57
  export const LazyImg = function(src, attributes) {
46
58
  return Img(src, { ...attributes, loading: 'lazy' });
@@ -16,6 +16,11 @@ export * from './medias';
16
16
  export * from './meta-data';
17
17
  export * from './table';
18
18
 
19
+ /**
20
+ * Creates an empty `DocumentFragment` wrapper.
21
+ * Useful for grouping elements without adding a DOM node.
22
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): DocumentFragment}
23
+ */
19
24
  export const Fragment = HtmlElementWrapper('');
20
25
 
21
26
 
@@ -1,7 +1,25 @@
1
1
  import HtmlElementWrapper from "../wrappers/HtmlElementWrapper";
2
2
 
3
-
3
+ /**
4
+ * Creates a `<details>` element.
5
+ * @type {function(DetailsAttributes=, NdChild|NdChild[]=): HTMLDetailsElement}
6
+ */
4
7
  export const Details = HtmlElementWrapper('details');
8
+
9
+ /**
10
+ * Creates a `<summary>` element.
11
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLElement}
12
+ */
5
13
  export const Summary = HtmlElementWrapper('summary');
14
+
15
+ /**
16
+ * Creates a `<dialog>` element.
17
+ * @type {function(DialogAttributes=, NdChild|NdChild[]=): HTMLDialogElement}
18
+ */
6
19
  export const Dialog = HtmlElementWrapper('dialog');
20
+
21
+ /**
22
+ * Creates a `<menu>` element.
23
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLMenuElement}
24
+ */
7
25
  export const Menu = HtmlElementWrapper('menu');
@@ -1,10 +1,37 @@
1
1
  import HtmlElementWrapper from "../wrappers/HtmlElementWrapper";
2
2
 
3
+ /**
4
+ * Creates an `<ol>` element.
5
+ * @type {function(OlAttributes=, NdChild|NdChild[]=): HTMLOListElement}
6
+ */
3
7
  export const OrderedList = HtmlElementWrapper('ol');
8
+
9
+ /**
10
+ * Creates a `<ul>` element.
11
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLUListElement}
12
+ */
4
13
  export const UnorderedList = HtmlElementWrapper('ul');
14
+
15
+ /**
16
+ * Creates a `<li>` element.
17
+ * @type {function(GlobalAttributes & { value?: number }=, NdChild|NdChild[]=): HTMLLIElement}
18
+ */
5
19
  export const ListItem = HtmlElementWrapper('li');
6
20
 
21
+ /**
22
+ * Alias for {@link ListItem}.
23
+ * @type {typeof ListItem}
24
+ */
7
25
  export const Li = ListItem;
26
+
27
+ /**
28
+ * Alias for {@link OrderedList}.
29
+ * @type {typeof OrderedList}
30
+ */
8
31
  export const Ol = OrderedList;
9
- export const Ul = UnorderedList;
10
32
 
33
+ /**
34
+ * Alias for {@link UnorderedList}.
35
+ * @type {typeof UnorderedList}
36
+ */
37
+ export const Ul = UnorderedList;
@@ -1,8 +1,37 @@
1
1
  import HtmlElementWrapper from "../wrappers/HtmlElementWrapper";
2
2
 
3
+ /**
4
+ * Creates an `<audio>` element.
5
+ * @type {function(AudioAttributes=, NdChild|NdChild[]=): HTMLAudioElement}
6
+ */
3
7
  export const Audio = HtmlElementWrapper('audio');
8
+
9
+ /**
10
+ * Creates a `<video>` element.
11
+ * @type {function(VideoAttributes=, NdChild|NdChild[]=): HTMLVideoElement}
12
+ */
4
13
  export const Video = HtmlElementWrapper('video');
14
+
15
+ /**
16
+ * Creates a `<source>` element.
17
+ * @type {function(SourceAttributes=): HTMLSourceElement}
18
+ */
5
19
  export const Source = HtmlElementWrapper('source');
20
+
21
+ /**
22
+ * Creates a `<track>` element.
23
+ * @type {function(TrackAttributes=): HTMLTrackElement}
24
+ */
6
25
  export const Track = HtmlElementWrapper('track');
26
+
27
+ /**
28
+ * Creates a `<canvas>` element.
29
+ * @type {function(CanvasAttributes=, NdChild|NdChild[]=): HTMLCanvasElement}
30
+ */
7
31
  export const Canvas = HtmlElementWrapper('canvas');
32
+
33
+ /**
34
+ * Creates an `<svg>` element.
35
+ * @type {function(SvgAttributes=, NdChild|NdChild[]=): SVGSVGElement}
36
+ */
8
37
  export const Svg = HtmlElementWrapper('svg');
@@ -1,9 +1,43 @@
1
1
  import HtmlElementWrapper from "../wrappers/HtmlElementWrapper";
2
2
 
3
+ /**
4
+ * Creates a `<time>` element.
5
+ * @type {function(TimeAttributes=, NdChild|NdChild[]=): HTMLTimeElement}
6
+ */
3
7
  export const Time = HtmlElementWrapper('time');
8
+
9
+ /**
10
+ * Creates a `<data>` element.
11
+ * @type {function(GlobalAttributes & { value?: Observable<string>|string }=, NdChild|NdChild[]=): HTMLDataElement}
12
+ */
4
13
  export const Data = HtmlElementWrapper('data');
14
+
15
+ /**
16
+ * Creates an `<address>` element.
17
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLElement}
18
+ */
5
19
  export const Address = HtmlElementWrapper('address');
20
+
21
+ /**
22
+ * Creates a `<kbd>` element.
23
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLElement}
24
+ */
6
25
  export const Kbd = HtmlElementWrapper('kbd');
26
+
27
+ /**
28
+ * Creates a `<samp>` element.
29
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLElement}
30
+ */
7
31
  export const Samp = HtmlElementWrapper('samp');
32
+
33
+ /**
34
+ * Creates a `<var>` element.
35
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLElement}
36
+ */
8
37
  export const Var = HtmlElementWrapper('var');
38
+
39
+ /**
40
+ * Creates a `<wbr>` element.
41
+ * @type {function(GlobalAttributes=): HTMLElement}
42
+ */
9
43
  export const Wbr = HtmlElementWrapper('wbr');
@@ -1,14 +1,73 @@
1
1
  import HtmlElementWrapper from "../wrappers/HtmlElementWrapper";
2
2
 
3
+ /**
4
+ * Creates a `<caption>` element.
5
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLTableCaptionElement}
6
+ */
3
7
  export const Caption = HtmlElementWrapper('caption');
8
+
9
+ /**
10
+ * Creates a `<table>` element.
11
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLTableElement}
12
+ */
4
13
  export const Table = HtmlElementWrapper('table');
14
+
15
+ /**
16
+ * Creates a `<thead>` element.
17
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLTableSectionElement}
18
+ */
5
19
  export const THead = HtmlElementWrapper('thead');
20
+
21
+ /**
22
+ * Creates a `<tfoot>` element.
23
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLTableSectionElement}
24
+ */
6
25
  export const TFoot = HtmlElementWrapper('tfoot');
26
+
27
+ /**
28
+ * Creates a `<tbody>` element.
29
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLTableSectionElement}
30
+ */
7
31
  export const TBody = HtmlElementWrapper('tbody');
32
+
33
+ /**
34
+ * Creates a `<tr>` element.
35
+ * @type {function(GlobalAttributes=, NdChild|NdChild[]=): HTMLTableRowElement}
36
+ */
8
37
  export const Tr = HtmlElementWrapper('tr');
38
+
39
+ /**
40
+ * Alias for {@link Tr}.
41
+ * @type {typeof Tr}
42
+ */
9
43
  export const TRow = Tr;
44
+
45
+ /**
46
+ * Creates a `<th>` element.
47
+ * @type {function(ThAttributes=, NdChild|NdChild[]=): HTMLTableCellElement}
48
+ */
10
49
  export const Th = HtmlElementWrapper('th');
50
+
51
+ /**
52
+ * Alias for {@link Th}.
53
+ * @type {typeof Th}
54
+ */
11
55
  export const THeadCell = Th;
56
+
57
+ /**
58
+ * Alias for {@link Th}.
59
+ * @type {typeof Th}
60
+ */
12
61
  export const TFootCell = Th;
62
+
63
+ /**
64
+ * Creates a `<td>` element.
65
+ * @type {function(TdAttributes=, NdChild|NdChild[]=): HTMLTableCellElement}
66
+ */
13
67
  export const Td = HtmlElementWrapper('td');
68
+
69
+ /**
70
+ * Alias for {@link Td}.
71
+ * @type {typeof Td}
72
+ */
14
73
  export const TBodyCell = Td;
@@ -75,7 +75,12 @@ export const trim = function(str, char) {
75
75
  }
76
76
 
77
77
  export const deepClone = (value, onObservableFound) => {
78
- // Primitives
78
+ try {
79
+ if(window.structuredClone !== undefined) {
80
+ return window.structuredClone(value);
81
+ }
82
+ } catch (e){}
83
+
79
84
  if (value === null || typeof value !== 'object') {
80
85
  return value;
81
86
  }
@@ -99,7 +104,7 @@ export const deepClone = (value, onObservableFound) => {
99
104
  // Objects
100
105
  const cloned = {};
101
106
  for (const key in value) {
102
- if (value.hasOwnProperty(key)) {
107
+ if (Object.hasOwn(value, key)) {
103
108
  cloned[key] = deepClone(value[key]);
104
109
  }
105
110
  }
@@ -3,7 +3,7 @@
3
3
  export const once = (fn) => {
4
4
  let result = null;
5
5
  return (...args) => {
6
- if(result) {
6
+ if(result != null) {
7
7
  return result;
8
8
  }
9
9
  result = fn(...args);
@@ -1,97 +1,167 @@
1
-
2
1
  const DocumentObserver = {
3
2
  mounted: new WeakMap(),
3
+ beforeUnmount: new WeakMap(),
4
4
  mountedSupposedSize: 0,
5
5
  unmounted: new WeakMap(),
6
6
  unmountedSupposedSize: 0,
7
7
  observer: null,
8
+
8
9
  executeMountedCallback(node) {
9
10
  const data = DocumentObserver.mounted.get(node);
10
11
  if(!data) {
11
12
  return;
12
13
  }
13
14
  data.inDom = true;
14
- data.mounted && data.mounted(node);
15
+ if(!data.mounted) {
16
+ return;
17
+ }
18
+ if(Array.isArray(data.mounted)) {
19
+ for(const cb of data.mounted) {
20
+ cb(node);
21
+ }
22
+ return;
23
+ }
24
+ data.mounted(node);
15
25
  },
26
+
16
27
  executeUnmountedCallback(node) {
17
28
  const data = DocumentObserver.unmounted.get(node);
18
29
  if(!data) {
19
30
  return;
20
31
  }
21
-
22
32
  data.inDom = false;
23
- if(data.unmounted && data.unmounted(node) === true) {
33
+ if(!data.unmounted) {
34
+ return;
35
+ }
36
+
37
+ let shouldRemove = false;
38
+ if(Array.isArray(data.unmounted)) {
39
+ for(const cb of data.unmounted) {
40
+ if(cb(node) === true) {
41
+ shouldRemove = true;
42
+ }
43
+ }
44
+ } else {
45
+ shouldRemove = data.unmounted(node) === true;
46
+ }
47
+
48
+ if(shouldRemove) {
24
49
  data.disconnect();
25
50
  node.nd?.remove();
26
51
  }
27
52
  },
53
+
28
54
  checkMutation: function(mutationsList) {
29
- let i = 0;
30
55
  for(const mutation of mutationsList) {
31
- if(DocumentObserver.mountedSupposedSize > 0 ) {
56
+ if(DocumentObserver.mountedSupposedSize > 0) {
32
57
  for(const node of mutation.addedNodes) {
33
58
  DocumentObserver.executeMountedCallback(node);
34
59
  if(!node.querySelectorAll) {
35
- return;
60
+ continue;
36
61
  }
37
62
  const children = node.querySelectorAll('[data--nd-mounted]');
38
- if(!children.length) {
39
- return;
40
- }
41
- for(const node of children) {
42
- DocumentObserver.executeMountedCallback(node);
63
+ for(const child of children) {
64
+ DocumentObserver.executeMountedCallback(child);
43
65
  }
44
66
  }
45
67
  }
46
68
 
47
- if(DocumentObserver.unmountedSupposedSize > 0 ) {
48
- for(const node of mutation.removedNodes) {
69
+ if (DocumentObserver.unmountedSupposedSize > 0) {
70
+ for (const node of mutation.removedNodes) {
49
71
  DocumentObserver.executeUnmountedCallback(node);
50
72
  if(!node.querySelectorAll) {
51
- return;
73
+ continue;
52
74
  }
53
75
  const children = node.querySelectorAll('[data--nd-unmounted]');
54
- if(!children.length) {
55
- return;
56
- }
57
- for(const node of children) {
58
- DocumentObserver.executeUnmountedCallback(node);
76
+ for(const child of children) {
77
+ DocumentObserver.executeUnmountedCallback(child);
59
78
  }
60
79
  }
61
80
  }
62
81
  }
63
82
  },
83
+
64
84
  /**
65
- *
66
85
  * @param {HTMLElement} element
67
86
  * @param {boolean} inDom
68
- * @returns {{watch: (function(): Map<any, any>), disconnect: (function(): boolean), mounted: (function(*): Set<any>), unmounted: (function(*): Set<any>)}}
87
+ * @returns {{ disconnect: Function, mounted: Function, unmounted: Function, off: Function }}
69
88
  */
70
89
  watch: function(element, inDom = false) {
90
+ let mountedRegistered = false;
91
+ let unmountedRegistered = false;
92
+
71
93
  let data = {
72
94
  inDom,
73
95
  mounted: null,
74
96
  unmounted: null,
75
97
  disconnect: () => {
76
- DocumentObserver.mounted.delete(element);
77
- DocumentObserver.unmounted.delete(element);
78
- DocumentObserver.mountedSupposedSize--;
79
- DocumentObserver.unmountedSupposedSize--;
98
+ if (mountedRegistered) {
99
+ DocumentObserver.mounted.delete(element);
100
+ DocumentObserver.mountedSupposedSize--;
101
+ }
102
+ if (unmountedRegistered) {
103
+ DocumentObserver.unmounted.delete(element);
104
+ DocumentObserver.unmountedSupposedSize--;
105
+ }
80
106
  data = null;
81
107
  }
82
108
  };
83
109
 
110
+ const addListener = (type, callback) => {
111
+ if (!data[type]) {
112
+ data[type] = callback;
113
+ return;
114
+ }
115
+ if (!Array.isArray(data[type])) {
116
+ data[type] = [data[type], callback];
117
+ return;
118
+ }
119
+ data[type].push(callback);
120
+ };
121
+
122
+ const removeListener = (type, callback) => {
123
+ if(!data?.[type]) {
124
+ return;
125
+ }
126
+ if(Array.isArray(data[type])) {
127
+ const index = data[type].indexOf(callback);
128
+ if(index > -1) {
129
+ data[type].splice(index, 1);
130
+ }
131
+ if(data[type].length === 1) {
132
+ data[type] = data[type][0];
133
+ }
134
+ if(data[type].length === 0) {
135
+ data[type] = null;
136
+ }
137
+ return;
138
+ }
139
+ data[type] = null;
140
+ };
141
+
84
142
  return {
85
- disconnect: data.disconnect,
143
+ disconnect: () => data?.disconnect(),
144
+
86
145
  mounted: (callback) => {
87
- data.mounted = callback;
146
+ addListener('mounted', callback);
88
147
  DocumentObserver.mounted.set(element, data);
89
- DocumentObserver.mountedSupposedSize++;
148
+ if (!mountedRegistered) {
149
+ DocumentObserver.mountedSupposedSize++;
150
+ mountedRegistered = true;
151
+ }
90
152
  },
153
+
91
154
  unmounted: (callback) => {
92
- data.unmounted = callback;
155
+ addListener('unmounted', callback);
93
156
  DocumentObserver.unmounted.set(element, data);
94
- DocumentObserver.unmountedSupposedSize++;
157
+ if (!unmountedRegistered) {
158
+ DocumentObserver.unmountedSupposedSize++;
159
+ unmountedRegistered = true;
160
+ }
161
+ },
162
+
163
+ off: (type, callback) => {
164
+ removeListener(type, callback);
95
165
  }
96
166
  };
97
167
  }
@@ -102,4 +172,5 @@ DocumentObserver.observer.observe(document.body, {
102
172
  childList: true,
103
173
  subtree: true,
104
174
  });
175
+
105
176
  export default DocumentObserver;
@@ -3,6 +3,7 @@ import Validator from "../utils/validator";
3
3
  import AttributesWrapper from "./AttributesWrapper";
4
4
  import PluginsManager from "../utils/plugins-manager";
5
5
  import './prototypes/nd-element-extensions';
6
+ import './prototypes/nd-element.transition.extensions';
6
7
  import './prototypes/attributes-extensions';
7
8
 
8
9
  const $nodeCache = new Map();
@@ -95,6 +96,10 @@ export const ElementCreator = {
95
96
  PluginsManager.emit('AfterProcessChildren', parent);
96
97
  }
97
98
  },
99
+ async safeRemove(element) {
100
+ await element.remove();
101
+
102
+ },
98
103
  getChild(child) {
99
104
  if(child == null) {
100
105
  return null;
@@ -28,10 +28,10 @@ function createHtmlElement($tagName, customWrapper, _attributes, _children = nul
28
28
  /**
29
29
  *
30
30
  * @param {string} name
31
- * @param {?Function} customWrapper
31
+ * @param {?Function=} customWrapper
32
32
  * @returns {Function}
33
33
  */
34
- export default function HtmlElementWrapper(name, customWrapper) {
34
+ export default function HtmlElementWrapper(name, customWrapper = null) {
35
35
  return createHtmlElement.bind(null, name, customWrapper);
36
36
  };
37
37
 
@@ -73,6 +73,37 @@ NDElement.prototype.unmounted = function(callback) {
73
73
  return this.lifecycle({ unmounted: callback });
74
74
  };
75
75
 
76
+ NDElement.prototype.beforeUnmount = function(id, callback) {
77
+ const el = this.$element;
78
+
79
+ if(!DocumentObserver.beforeUnmount.has(el)) {
80
+ DocumentObserver.beforeUnmount.set(el, new Map());
81
+ const originalRemove = el.remove.bind(el);
82
+
83
+ let $isUnmounting = false
84
+
85
+ el.remove = async () => {
86
+ if($isUnmounting) {
87
+ return;
88
+ }
89
+ $isUnmounting = true;
90
+
91
+ try {
92
+ const callbacks = DocumentObserver.beforeUnmount.get(el);
93
+ for (const cb of callbacks.values()) {
94
+ await cb.call(this, el);
95
+ }
96
+ } finally {
97
+ originalRemove();
98
+ $isUnmounting = false;
99
+ }
100
+ };
101
+ }
102
+
103
+ DocumentObserver.beforeUnmount.get(el).set(id, callback);
104
+ return this;
105
+ };
106
+
76
107
  NDElement.prototype.htmlElement = function() {
77
108
  return this.$element;
78
109
  };
@@ -160,7 +191,7 @@ NDElement.prototype.with = function(methods) {
160
191
  }
161
192
 
162
193
  return this;
163
- }
194
+ };
164
195
 
165
196
  /**
166
197
  * Extends the NDElement prototype with new methods available to all NDElement instances.
@@ -195,7 +226,7 @@ NDElement.extend = function(methods) {
195
226
  ]);
196
227
 
197
228
  for (const name in methods) {
198
- if (!methods.hasOwnProperty(name)) {
229
+ if (!Object.hasOwn(methods, name)) {
199
230
  continue;
200
231
  }
201
232
 
@@ -51,7 +51,7 @@ const $hydrateFn = function(hydrateFunction, targetType, element, property) {
51
51
  hydrationState[targetType][property] = hydrateFunction;
52
52
  }
53
53
 
54
- const bindAttachMethods = function(node, bindDingData, data) {
54
+ const bindAttachMethods = (node, bindDingData, data) => {
55
55
  if(!bindDingData.attach) {
56
56
  return null;
57
57
  }