native-document 1.0.76 → 1.0.78

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 (154) hide show
  1. package/components.js +26 -1
  2. package/dist/native-document.components.min.js +6447 -1984
  3. package/dist/native-document.dev.js +309 -196
  4. package/dist/native-document.dev.js.map +1 -1
  5. package/dist/native-document.devtools.min.js +1 -1
  6. package/dist/native-document.min.js +1 -1
  7. package/package.json +1 -1
  8. package/rollup.config.js +0 -14
  9. package/src/components/$traits/HasItems.js +38 -0
  10. package/src/components/BaseComponent.js +70 -0
  11. package/src/components/accordion/Accordion.js +133 -0
  12. package/src/components/accordion/AccordionItem.js +119 -0
  13. package/src/components/accordion/index.js +7 -0
  14. package/src/components/alert/Alert.js +155 -0
  15. package/src/components/alert/index.js +6 -0
  16. package/src/components/avatar/Avatar.js +178 -0
  17. package/src/components/avatar/index.js +5 -0
  18. package/src/components/badge/Badge.js +103 -0
  19. package/src/components/badge/index.js +6 -0
  20. package/src/components/breadcrumb/BreadCrumb.js +70 -0
  21. package/src/components/breadcrumb/index.js +5 -0
  22. package/src/components/button/Button.js +174 -0
  23. package/src/components/button/index.js +5 -0
  24. package/src/components/card/Card.js +110 -0
  25. package/src/components/card/index.js +5 -0
  26. package/src/components/context-menu/ContextMenu.js +60 -0
  27. package/src/components/context-menu/ContextMenuGroup.js +16 -0
  28. package/src/components/context-menu/ContextMenuItem.js +16 -0
  29. package/src/components/context-menu/index.js +10 -0
  30. package/src/components/divider/Divider.js +126 -0
  31. package/src/components/divider/index.js +6 -0
  32. package/src/components/dropdown/Dropdown.js +170 -0
  33. package/src/components/dropdown/DropdownDivider.js +24 -0
  34. package/src/components/dropdown/DropdownGroup.js +44 -0
  35. package/src/components/dropdown/DropdownItem.js +71 -0
  36. package/src/components/dropdown/DropdownTrigger.js +64 -0
  37. package/src/components/dropdown/index.js +13 -0
  38. package/src/components/{fom-control → form}/FormControl.js +28 -20
  39. package/src/components/{fom-control → form}/field/DefaultRender.js +1 -15
  40. package/src/components/{fom-control → form}/field/Field.js +64 -137
  41. package/src/components/{fom-control → form}/field/FieldCollection.js +39 -19
  42. package/src/components/{fom-control → form}/field/types/AutocompleteField.js +11 -0
  43. package/src/components/form/field/types/CheckboxField.js +36 -0
  44. package/src/components/{fom-control → form}/field/types/CheckboxGroupField.js +10 -0
  45. package/src/components/{fom-control → form}/field/types/ColorField.js +10 -0
  46. package/src/components/{fom-control → form}/field/types/DateField.js +10 -0
  47. package/src/components/{fom-control → form}/field/types/EmailField.js +10 -0
  48. package/src/components/{fom-control → form}/field/types/FileField.js +10 -0
  49. package/src/components/form/field/types/HiddenField.js +18 -0
  50. package/src/components/{fom-control → form}/field/types/ImageField.js +10 -0
  51. package/src/components/{fom-control → form}/field/types/NumberField.js +10 -0
  52. package/src/components/{fom-control → form}/field/types/PasswordField.js +10 -0
  53. package/src/components/{fom-control → form}/field/types/RadioField.js +28 -2
  54. package/src/components/{fom-control → form}/field/types/RangeField.js +10 -0
  55. package/src/components/{fom-control → form}/field/types/SearchField.js +10 -0
  56. package/src/components/{fom-control → form}/field/types/SelectField.js +10 -0
  57. package/src/components/{fom-control → form}/field/types/StringField.js +10 -0
  58. package/src/components/{fom-control → form}/field/types/TelField.js +10 -1
  59. package/src/components/{fom-control → form}/field/types/TextAreaField.js +10 -0
  60. package/src/components/{fom-control → form}/field/types/TimeField.js +10 -1
  61. package/src/components/{fom-control → form}/field/types/UrlField.js +9 -1
  62. package/src/components/form/index.js +49 -0
  63. package/src/components/list/List.js +106 -0
  64. package/src/components/list/ListGroup.js +67 -0
  65. package/src/components/list/ListItem.js +103 -0
  66. package/src/components/list/index.js +10 -0
  67. package/src/components/menu/Menu.js +82 -0
  68. package/src/components/menu/MenuDivider.js +22 -0
  69. package/src/components/menu/MenuGroup.js +42 -0
  70. package/src/components/menu/MenuItem.js +71 -0
  71. package/src/components/menu/index.js +13 -0
  72. package/src/components/modal/Modal.js +153 -0
  73. package/src/components/modal/index.js +5 -0
  74. package/src/components/pagination/Pagination.js +229 -0
  75. package/src/components/pagination/index.js +5 -0
  76. package/src/components/popover/Popover.js +185 -0
  77. package/src/components/popover/PopoverFooter.js +37 -0
  78. package/src/components/popover/PopoverHeader.js +43 -0
  79. package/src/components/popover/index.js +10 -0
  80. package/src/components/progress/Progress.js +220 -0
  81. package/src/components/progress/index.js +6 -0
  82. package/src/components/skeleton/Skeleton.js +98 -0
  83. package/src/components/skeleton/SkeletonCard.js +0 -0
  84. package/src/components/skeleton/SkeletonList.js +0 -0
  85. package/src/components/skeleton/SkeletonParagraph.js +0 -0
  86. package/src/components/skeleton/SkeletonTable.js +0 -0
  87. package/src/components/skeleton/index.js +6 -0
  88. package/src/components/slider/Slider.js +183 -0
  89. package/src/components/slider/index.js +5 -0
  90. package/src/components/spinner/Spinner.js +160 -0
  91. package/src/components/spinner/index.js +5 -0
  92. package/src/components/splitter/Splitter.js +94 -0
  93. package/src/components/splitter/SplitterGutter.js +57 -0
  94. package/src/components/splitter/SplitterPanel.js +82 -0
  95. package/src/components/splitter/index.js +8 -0
  96. package/src/components/stepper/Stepper.js +229 -0
  97. package/src/components/stepper/StepperStep.js +103 -0
  98. package/src/components/stepper/index.js +8 -0
  99. package/src/components/switch/Switch.js +99 -0
  100. package/src/components/switch/index.js +0 -0
  101. package/src/components/table/SimpleTable.js +36 -32
  102. package/src/components/tabs/Tabs.js +110 -0
  103. package/src/components/tabs/index.js +6 -0
  104. package/src/components/toast/Toast.js +129 -0
  105. package/src/components/toast/ToastError.js +0 -0
  106. package/src/components/toast/ToastInfo.js +0 -0
  107. package/src/components/toast/ToastSuccess.js +0 -0
  108. package/src/components/toast/ToastWarning.js +0 -0
  109. package/src/components/toast/index.js +5 -0
  110. package/src/components/tooltip/Tooltip.js +98 -0
  111. package/src/components/tooltip/index.js +5 -0
  112. package/src/components/tooltip/prototypes.js +6 -0
  113. package/src/core/data/MemoryManager.js +1 -2
  114. package/src/core/data/Observable.js +1 -1
  115. package/src/core/data/ObservableArray.js +10 -4
  116. package/src/core/data/ObservableItem.js +5 -5
  117. package/src/core/data/observable-helpers/array.js +1 -1
  118. package/src/core/data/observable-helpers/batch.js +1 -1
  119. package/src/core/data/observable-helpers/computed.js +1 -1
  120. package/src/core/elements/control/for-each-array.js +37 -64
  121. package/src/core/elements/control/for-each.js +1 -1
  122. package/src/core/elements/control/show-if.js +1 -1
  123. package/src/core/elements/control/switch.js +1 -1
  124. package/src/core/utils/events.js +68 -0
  125. package/src/core/utils/filters/standard.js +1 -1
  126. package/src/core/utils/filters/utils.js +1 -1
  127. package/src/core/utils/helpers.js +10 -7
  128. package/src/core/utils/validator.js +1 -0
  129. package/src/core/wrappers/AttributesWrapper.js +18 -35
  130. package/src/core/wrappers/DocumentObserver.js +0 -1
  131. package/src/core/wrappers/ElementCreator.js +6 -11
  132. package/src/core/wrappers/NdPrototype.js +24 -31
  133. package/src/core/wrappers/TemplateCloner.js +60 -18
  134. package/src/core/wrappers/constants.js +32 -1
  135. package/src/core/wrappers/prototypes/attributes-extensions.js +16 -3
  136. package/src/core/wrappers/prototypes/bind-class-extensions.js +18 -0
  137. package/src/devtools/app/App.js +1 -1
  138. package/src/devtools/hrm/ComponentRegistry.js +1 -1
  139. package/src/router/Router.js +1 -1
  140. package/src/router/link.js +4 -4
  141. package/src/router/modes/HistoryRouter.js +0 -1
  142. package/types/control-flow.d.ts +0 -1
  143. package/types/filters/standard.d.ts +0 -1
  144. package/src/components/fom-control/default/DefaultLayout.js +0 -8
  145. package/src/components/fom-control/default/collection/DefaultCollectionLayout.js +0 -12
  146. package/src/components/fom-control/default/collection/DefaultCollectionTemplate.js +0 -6
  147. package/src/components/fom-control/field/types/CheckboxField.js +0 -17
  148. package/src/components/fom-control/field/types/HiddenField.js +0 -8
  149. package/src/components/fom-control/index.js +0 -8
  150. /package/src/components/{fom-control → form}/field/FieldFactory.js +0 -0
  151. /package/src/components/{fom-control → form}/merge +0 -0
  152. /package/src/components/{fom-control → form}/utils.js +0 -0
  153. /package/src/components/{fom-control → form}/validation/Validation.js +0 -0
  154. /package/src/{core → router}/errors/RouterError.js +0 -0
@@ -28,6 +28,13 @@ ObservableArray.prototype = Object.create(ObservableItem.prototype);
28
28
  ObservableArray.prototype.constructor = ObservableArray;
29
29
  ObservableArray.prototype.__$isObservableArray = true;
30
30
 
31
+
32
+ Object.defineProperty(ObservableArray.prototype, 'length', {
33
+ get() {
34
+ return this.$currentValue.length;
35
+ }
36
+ })
37
+
31
38
  mutationMethods.forEach((method) => {
32
39
  ObservableArray.prototype[method] = function(...values) {
33
40
  const result = this.$currentValue[method](...values);
@@ -43,6 +50,9 @@ noMutationMethods.forEach((method) => {
43
50
  });
44
51
 
45
52
  ObservableArray.prototype.clear = function() {
53
+ if(this.$currentValue.length === 0) {
54
+ return;
55
+ }
46
56
  this.$currentValue.length = 0;
47
57
  this.trigger({ action: 'clear' });
48
58
  return true;
@@ -72,10 +82,6 @@ ObservableArray.prototype.count = function(condition) {
72
82
  return count;
73
83
  };
74
84
 
75
- ObservableArray.prototype.length = function() {
76
- return this.$currentValue.length;
77
- };
78
-
79
85
  ObservableArray.prototype.swap = function(indexA, indexB) {
80
86
  const value = this.$currentValue;
81
87
  const length = value.length;
@@ -1,11 +1,11 @@
1
- import DebugManager from "../utils/debug-manager";
1
+ import DebugManager from "../../core/utils/debug-manager";
2
2
  import MemoryManager from "./MemoryManager";
3
- import NativeDocumentError from "../errors/NativeDocumentError";
3
+ import NativeDocumentError from "../../core/errors/NativeDocumentError";
4
4
  import ObservableChecker from "./ObservableChecker";
5
- import PluginsManager from "../utils/plugins-manager";
6
- import Validator from "../utils/validator";
5
+ import PluginsManager from "../../core/utils/plugins-manager";
6
+ import Validator from "../../core/utils/validator";
7
7
  import {ObservableWhen} from "./ObservableWhen";
8
- import {deepClone} from "../utils/helpers.js";
8
+ import {deepClone} from "../utils/helpers";
9
9
 
10
10
  /**
11
11
  *
@@ -1,5 +1,5 @@
1
1
  import {Observable} from "../Observable";
2
- import ObservableArray from "../ObservableArray.js";
2
+ import ObservableArray from "../ObservableArray";
3
3
 
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import Validator from "../../utils/validator";
1
+ import Validator from "../../../core/utils/validator";
2
2
  import {Observable} from "../Observable";
3
3
 
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import ObservableItem from "../ObservableItem";
2
2
  import Validator from "../../utils/validator";
3
- import NativeDocumentError from "../../errors/NativeDocumentError";
3
+ import NativeDocumentError from "../..//errors/NativeDocumentError";
4
4
  import {Observable} from "../Observable";
5
5
  import PluginsManager from "../../utils/plugins-manager";
6
6
  import {nextTick} from "../../utils/helpers";
@@ -1,11 +1,10 @@
1
- import Anchor from "../anchor";
1
+ import Anchor from "../../elements/anchor";
2
2
  import {Observable} from "../../data/Observable";
3
3
  import Validator from "../../utils/validator";
4
- import {getKey} from "../../utils/helpers";
5
4
  import { ElementCreator } from "../../wrappers/ElementCreator";
6
5
  import NativeDocumentError from "../../errors/NativeDocumentError";
7
6
 
8
- export function ForEachArray(data, callback, key, configs = {}) {
7
+ export function ForEachArray(data, callback, configs = {}) {
9
8
  const element = Anchor('ForEach Array');
10
9
  const blockEnd = element.endElement();
11
10
  const blockStart = element.startElement();
@@ -14,23 +13,14 @@ export function ForEachArray(data, callback, key, configs = {}) {
14
13
  let lastNumberOfItems = 0;
15
14
  const isIndexRequired = callback.length >= 2;
16
15
 
17
- const keysCache = new WeakMap();
18
-
19
- const clear = () => {
16
+ const clear = (items) => {
20
17
  element.removeChildren();
21
- cleanCache();
18
+ cleanCache(items);
22
19
  lastNumberOfItems = 0;
23
20
  };
24
21
 
25
- const getItemKey = (item, indexKey) => {
26
- if(keysCache.has(item)) {
27
- return keysCache.get(item);
28
- }
29
- return getKey(item, indexKey, key);
30
- };
31
-
32
22
  const getItemChild = (item) => {
33
- return getChildByKey(getItemKey(item));
23
+ return cache.get(item)?.child;
34
24
  };
35
25
 
36
26
  const updateIndexObservers = (items, startFrom = 0) => {
@@ -39,16 +29,17 @@ export function ForEachArray(data, callback, key, configs = {}) {
39
29
  }
40
30
  let index = startFrom;
41
31
  for(let i = startFrom, length = items?.length; i < length; i++) {
42
- const cacheItem = cache.get(getItemKey(items[i], i));
32
+ const cacheItem = cache.get(items[i]);
43
33
  if(!cacheItem) {
44
34
  continue;
45
35
  }
46
- cacheItem.indexObserver?.deref()?.set(index);
36
+ cacheItem.indexObserver?.set(index);
47
37
  index++;
48
38
  }
49
39
  };
50
40
 
51
- const removeCacheItem = (cacheItem, removeChild = true) => {
41
+ const removeCacheItem = (item, removeChild = true) => {
42
+ const cacheItem = cache.get(item);
52
43
  if(!cacheItem) {
53
44
  return;
54
45
  }
@@ -57,14 +48,10 @@ export function ForEachArray(data, callback, key, configs = {}) {
57
48
  child?.remove();
58
49
  cache.delete(cacheItem.keyId);
59
50
  }
60
- cacheItem.indexObserver?.deref()?.cleanup();
61
- }
62
-
63
- const removeCacheItemByKey = (keyId, removeChild = true) => {
64
- removeCacheItem(cache.get(keyId), removeChild);
51
+ cacheItem.indexObserver?.cleanup();
65
52
  };
66
53
 
67
- const cleanCache = () => {
54
+ const cleanCache = (items) => {
68
55
  if(configs.shouldKeepItemsInCache) {
69
56
  return;
70
57
  }
@@ -72,53 +59,41 @@ export function ForEachArray(data, callback, key, configs = {}) {
72
59
  cache.clear();
73
60
  return;
74
61
  }
75
- for (const [keyId, cacheItem] of cache.entries()) {
76
- removeCacheItem(cacheItem, false);
62
+ for (const [itemAsKey, _] of cache.entries()) {
63
+ if(items && items.contains(itemAsKey)) {
64
+ continue;
65
+ }
66
+ removeCacheItem(itemAsKey, false);
77
67
  }
78
68
  cache.clear();
79
69
  }
80
70
 
81
71
  const buildItem = (item, indexKey) => {
82
- const keyId = getItemKey(item, indexKey);
83
-
84
- if(cache.has(keyId)) {
85
- const cacheItem = cache.get(keyId);
86
- cacheItem.indexObserver?.deref()?.set(indexKey);
72
+ const cacheItem = cache.get(item);
73
+ if(cacheItem) {
74
+ cacheItem.indexObserver?.set(indexKey);
87
75
  const child = cacheItem.child;
88
76
  if(child) {
89
77
  return child;
90
78
  }
91
- cache.delete(keyId);
79
+ cache.delete(item);
92
80
  }
93
81
 
94
82
  const indexObserver = isIndexRequired ? Observable(indexKey) : null;
95
83
  let child = ElementCreator.getChild(callback(item, indexObserver));
96
- if(!child) {
97
- throw new NativeDocumentError("ForEachArray child can't be null or undefined!");
84
+ if(child) {
85
+ cache.set(item, {
86
+ child,
87
+ indexObserver: (indexObserver ? new WeakRef(indexObserver) : null)
88
+ });
89
+ return child;
98
90
  }
99
- cache.set(keyId, {
100
- keyId,
101
- child: child,
102
- indexObserver: (indexObserver ? new WeakRef(indexObserver) : null)
103
- });
104
- keysCache.set(item, keyId);
105
- return child;
106
- };
107
- const getChildByKey = function(keyId) {
108
- const cacheItem = cache.get(keyId);
109
- if(!cacheItem) {
110
- return null;
111
- }
112
- const child = cacheItem.child;
113
- if(!child) {
114
- removeCacheItem(cacheItem, false);
115
- return null;
116
- }
117
- return child;
91
+
92
+ throw new NativeDocumentError("ForEachArray child can't be null or undefined!");
118
93
  };
119
94
 
120
- const removeByKey = function(keyId, fragment) {
121
- const cacheItem = cache.get(keyId);
95
+ const removeByItem = function(item, fragment) {
96
+ const cacheItem = cache.get(item);
122
97
  if(!cacheItem) {
123
98
  return null;
124
99
  }
@@ -144,11 +119,10 @@ export function ForEachArray(data, callback, key, configs = {}) {
144
119
  return fragment;
145
120
  },
146
121
  add(items, delay = 2) {
147
- const fragment = Actions.toFragment(items);
148
- element.appendElement(fragment);
122
+ element.appendElement(Actions.toFragment(items));
149
123
  },
150
124
  replace(items) {
151
- clear();
125
+ clear(items);
152
126
  Actions.add(items);
153
127
  },
154
128
  reOrder(items) {
@@ -164,7 +138,7 @@ export function ForEachArray(data, callback, key, configs = {}) {
164
138
  element.appendElement(fragment, blockEnd);
165
139
  },
166
140
  removeOne(element, index) {
167
- removeCacheItemByKey(getItemKey(element, index), true);
141
+ removeCacheItem(element, true);
168
142
  },
169
143
  clear,
170
144
  merge(items) {
@@ -198,16 +172,15 @@ export function ForEachArray(data, callback, key, configs = {}) {
198
172
  const garbageFragment = document.createDocumentFragment();
199
173
 
200
174
  if(deleted.length > 0) {
201
- let firstKey = getItemKey(deleted[0], start);
175
+ let firstItem = deleted[0];
202
176
  if(deleted.length === 1) {
203
- removeByKey(firstKey, garbageFragment);
177
+ removeByItem(firstItem, garbageFragment);
204
178
  } else if(deleted.length > 1) {
205
- const firstChildRemoved = getChildByKey(firstKey);
179
+ const firstChildRemoved = getItemChild(deleted[0]);
206
180
  elementBeforeFirst = firstChildRemoved?.previousSibling;
207
181
 
208
182
  for(let i = 0; i < deleted.length; i++) {
209
- const keyId = getItemKey(deleted[i], start + i, key);
210
- removeByKey(keyId, garbageFragment);
183
+ firstItem(deleted[i], garbageFragment);
211
184
  }
212
185
  }
213
186
  } else {
@@ -1,6 +1,6 @@
1
1
  import {Observable} from "../../data/Observable";
2
2
  import Validator from "../../utils/validator";
3
- import Anchor from "../anchor";
3
+ import Anchor from "../../elements/anchor";
4
4
  import DebugManager from "../../utils/debug-manager";
5
5
  import {getKey} from "../../utils/helpers";
6
6
  import { ElementCreator } from "../../wrappers/ElementCreator";
@@ -1,7 +1,7 @@
1
1
  import { Observable } from "../../data/Observable";
2
2
  import Validator from "../../utils/validator";
3
3
  import DebugManager from "../../utils/debug-manager.js";
4
- import Anchor from "../anchor";
4
+ import Anchor from "../../elements/anchor";
5
5
  import {ElementCreator} from "../../wrappers/ElementCreator";
6
6
 
7
7
  /**
@@ -1,6 +1,6 @@
1
1
  import NativeDocumentError from "../../errors/NativeDocumentError";
2
2
  import Validator from "../../utils/validator";
3
- import Anchor from "../anchor";
3
+ import Anchor from "../../elements/anchor";
4
4
  import {ElementCreator} from "../../wrappers/ElementCreator";
5
5
 
6
6
 
@@ -63,6 +63,74 @@ export const EVENTS = [
63
63
  "VolumeChange",
64
64
  "Waiting",
65
65
 
66
+ "TouchCancel",
67
+ "TouchEnd",
68
+ "TouchMove",
69
+ "TouchStart",
70
+ "AnimationEnd",
71
+ "AnimationIteration",
72
+ "AnimationStart",
73
+ "TransitionEnd",
74
+ "Copy",
75
+ "Cut",
76
+ "Paste",
77
+ "FocusIn",
78
+ "FocusOut",
79
+ "ContextMenu"
80
+ ];
81
+
82
+ export const EVENTS_WITH_PREVENT = [
83
+ "Click",
84
+ "DblClick",
85
+ "MouseDown",
86
+ "MouseUp",
87
+ "Wheel",
88
+ "KeyDown",
89
+ "KeyPress",
90
+ "Invalid",
91
+ "Reset",
92
+ "Submit",
93
+ "DragOver",
94
+ "Drop",
95
+ "BeforeUnload",
96
+ "TouchCancel",
97
+ "TouchEnd",
98
+ "TouchMove",
99
+ "TouchStart",
100
+ "Copy",
101
+ "Cut",
102
+ "Paste",
103
+ "ContextMenu"
104
+ ];
105
+
106
+ export const EVENTS_WITH_STOP = [
107
+ "Click",
108
+ "DblClick",
109
+ "MouseDown",
110
+ "MouseMove",
111
+ "MouseOut",
112
+ "MouseOver",
113
+ "MouseUp",
114
+ "Wheel",
115
+ "KeyDown",
116
+ "KeyPress",
117
+ "KeyUp",
118
+ "Change",
119
+ "Input",
120
+ "Invalid",
121
+ "Reset",
122
+ "Search",
123
+ "Select",
124
+ "Submit",
125
+ "Drag",
126
+ "DragEnd",
127
+ "DragEnter",
128
+ "DragLeave",
129
+ "DragOver",
130
+ "DragStart",
131
+ "Drop",
132
+ "BeforeUnload",
133
+ "HashChange",
66
134
  "TouchCancel",
67
135
  "TouchEnd",
68
136
  "TouchMove",
@@ -1,4 +1,4 @@
1
- import Validator from "../validator";
1
+ import Validator from "../../utils/validator";
2
2
  import { createFilter, createMultiSourceFilter } from "./utils";
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- import Validator from "../validator";
1
+ import Validator from "../../utils/validator";
2
2
 
3
3
  export function toDate(value) {
4
4
  if (value instanceof Date) return value;
@@ -56,15 +56,18 @@ export const nextTick = function(fn) {
56
56
  * @returns {*}
57
57
  */
58
58
  export const getKey = (item, defaultKey, key) => {
59
- if(Validator.isFunction(key)) return key(item, defaultKey);
60
- if(Validator.isObservable(item)) {
61
- const val = item.val();
62
- return (val && key) ? val[key] : defaultKey;
59
+ if (Validator.isString(key)) {
60
+ const val = Validator.isObservable(item) ? item.val() : item;
61
+ const result = val?.[key];
62
+ return Validator.isObservable(result) ? result.val() : (result ?? defaultKey);
63
63
  }
64
- if(!Validator.isObject(item)) {
65
- return item;
64
+
65
+ if (Validator.isFunction(key)) {
66
+ return key(item, defaultKey);
66
67
  }
67
- return item[key]?.val?.() ?? item[key] ?? defaultKey;
68
+
69
+ const val = Validator.isObservable(item) ? item.val() : item;
70
+ return val ?? defaultKey;
68
71
  };
69
72
 
70
73
  export const trim = function(str, char) {
@@ -139,6 +139,7 @@ const Validator = {
139
139
  };
140
140
  if(process.env.NODE_ENV === 'development') {
141
141
  Validator.validateAttributes = function(attributes) {
142
+ console.log('AttributesWrapper', attributes);
142
143
  if (!attributes || typeof attributes !== 'object') {
143
144
  return attributes;
144
145
  }
@@ -2,6 +2,7 @@ import Validator from "../utils/validator";
2
2
  import NativeDocumentError from "../errors/NativeDocumentError";
3
3
  import {BOOLEAN_ATTRIBUTES} from "./constants.js";
4
4
  import {Observable} from "../data/Observable";
5
+ import './prototypes/bind-class-extensions';
5
6
 
6
7
 
7
8
  export function toggleElementClass(element, className, shouldAdd) {
@@ -36,18 +37,8 @@ export function updateObserverFromInput(element, attributeName, defaultValue, va
36
37
  export function bindClassAttribute(element, data) {
37
38
  for(let className in data) {
38
39
  const value = data[className];
39
- if(Validator.isObservable(value)) {
40
- element.classes.toggle(className, value.val());
41
- value.subscribe(toggleElementClass.bind(null, element, className));
42
- continue;
43
- }
44
- if(Validator.isObservableWhenResult(value)) {
45
- element.classes.toggle(className, value.isMath());
46
- value.subscribe(toggleElementClass.bind(null, element, className));
47
- continue;
48
- }
49
- if(value.$hydrate) {
50
- value.$hydrate(element, className);
40
+ if(value?.bindNdClass) {
41
+ value.bindNdClass(element, className);
51
42
  continue;
52
43
  }
53
44
  element.classes.toggle(className, value)
@@ -117,6 +108,12 @@ export function bindAttributeWithObservable(element, attributeName, value) {
117
108
  }
118
109
  }
119
110
 
111
+ const NdBindings = {
112
+ class: (element, value) => bindClassAttribute(element, value),
113
+ style: (element, value) => bindStyleAttribute(element, value),
114
+ };
115
+
116
+
120
117
  /**
121
118
  *
122
119
  * @param {HTMLElement} element
@@ -132,41 +129,27 @@ export default function AttributesWrapper(element, attributes) {
132
129
 
133
130
  for(let key in attributes) {
134
131
  const attributeName = key.toLowerCase();
135
- let value = attributes[attributeName];
136
- if(value === null || value === undefined) {
132
+ let value = attributes[key];
133
+ if(value == null) {
137
134
  continue;
138
135
  }
139
136
  if(value.handleNdAttribute) {
140
137
  value.handleNdAttribute(element, attributeName, value)
141
138
  continue;
142
139
  }
143
- if(Validator.isString(value)) {
144
- element.setAttribute(attributeName, value);
145
- return;
146
- }
147
- if(attributeName === 'class' && Validator.isObject(value)) {
148
- bindClassAttribute(element, value);
149
- continue;
150
- }
151
- if(attributeName === 'style' && Validator.isObject(value)) {
152
- bindStyleAttribute(element, value);
153
- continue;
140
+ if(typeof value === 'object') {
141
+ const binding = NdBindings[attributeName];
142
+ if(binding) {
143
+ binding(element, value);
144
+ continue;
145
+ }
154
146
  }
155
- if(BOOLEAN_ATTRIBUTES.includes(attributeName)) {
147
+ if(BOOLEAN_ATTRIBUTES.has(attributeName)) {
156
148
  bindBooleanAttribute(element, attributeName, value);
157
149
  continue;
158
150
  }
159
- if(Validator.isObservable(value)) {
160
- bindAttributeWithObservable(element, attributeName, value);
161
- continue;
162
- }
163
- if(value.$hydrate) {
164
- value.$hydrate(element, attributeName);
165
- continue;
166
- }
167
151
 
168
152
  element.setAttribute(attributeName, value);
169
-
170
153
  }
171
154
  return element;
172
155
  }
@@ -1,4 +1,3 @@
1
- import {debounce} from "../utils/helpers";
2
1
 
3
2
  const DocumentObserver = {
4
3
  mounted: new WeakMap(),
@@ -83,19 +83,14 @@ export const ElementCreator = {
83
83
  PluginsManager.emit('AfterProcessChildren', parent);
84
84
  },
85
85
  getChild(child) {
86
- if(child == null) {
87
- return null;
88
- }
89
- if(child.toNdElement) {
90
- do {
91
- child = child.toNdElement();
92
- if(Validator.isElement(child)) {
93
- return child;
94
- }
95
- } while (child.toNdElement);
86
+ while (child?.toNdElement) {
87
+ child = child.toNdElement();
88
+
89
+ if (Validator.isElement(child)) return child;
90
+ if (!child) return null;
96
91
  }
97
92
 
98
- return ElementCreator.createStaticTextNode(null, child);
93
+ return child ? ElementCreator.createStaticTextNode(null, child) : null;
99
94
  },
100
95
  /**
101
96
  *
@@ -1,22 +1,17 @@
1
1
  import { NDElement } from "./NDElement";
2
- import {EVENTS} from "../utils/events";
2
+ import {EVENTS, EVENTS_WITH_PREVENT, EVENTS_WITH_STOP} from "../utils/events";
3
3
 
4
- let createNdElementInstance = (target) => {
5
- attachEventPrototypes && attachEventPrototypes();
6
- attachEventPrototypes = null;
7
- createNdElementInstance = (target) => new NDElement(target);
8
- return new NDElement(target);
9
- };
10
4
  const property = {
11
5
  configurable: true,
12
6
  get() {
13
- return createNdElementInstance(this);
7
+ return new NDElement(this);
14
8
  }
15
9
  };
16
10
 
17
11
  Object.defineProperty(HTMLElement.prototype, 'nd', property);
18
12
 
19
13
  Object.defineProperty(DocumentFragment.prototype, 'nd', property);
14
+
20
15
  Object.defineProperty(NDElement.prototype, 'nd', {
21
16
  configurable: true,
22
17
  get: function() {
@@ -29,31 +24,29 @@ Object.defineProperty(NDElement.prototype, 'nd', {
29
24
  // ----------------------------------------------------------------
30
25
  // Events helpers
31
26
  // ----------------------------------------------------------------
27
+ EVENTS.forEach(eventSourceName => {
28
+ const eventName = eventSourceName.toLowerCase();
29
+ NDElement.prototype['on'+eventSourceName] = function(callback = null) {
30
+ this.$element.addEventListener(eventName, callback);
31
+ return this;
32
+ };
33
+ })
32
34
 
33
- let attachEventPrototypes = () => {
34
- EVENTS.forEach(eventSourceName => {
35
- const eventName = eventSourceName.toLowerCase();
36
- NDElement.prototype['on'+eventSourceName] = function(callback) {
37
- this.$element.addEventListener(eventName, callback);
38
- return this;
39
- };
40
-
41
- NDElement.prototype['onPrevent'+eventSourceName] = function(callback) {
42
- _prevent(this.$element, eventName, callback);
43
- return this;
44
- };
45
-
46
- NDElement.prototype['onStop'+eventSourceName] = function(callback) {
47
- _stop(this.$element, eventName, callback);
48
- return this;
49
- };
35
+ EVENTS_WITH_STOP.forEach(eventSourceName => {
36
+ const eventName = eventSourceName.toLowerCase();
37
+ NDElement.prototype['onStop'+eventSourceName] = function(callback = null) {
38
+ _stop(this.$element, eventName, callback);
39
+ return this;
40
+ };
41
+ });
50
42
 
51
- NDElement.prototype['onPreventStop'+eventSourceName] = function(callback) {
52
- _preventStop(this.$element, eventName, callback);
53
- return this;
54
- };
55
- })
56
- };
43
+ EVENTS_WITH_PREVENT.forEach(eventSourceName => {
44
+ const eventName = eventSourceName.toLowerCase();
45
+ NDElement.prototype['onPrevent'+eventSourceName] = function(callback = null) {
46
+ _prevent(this.$element, eventName, callback);
47
+ return this;
48
+ };
49
+ });
57
50
 
58
51
  NDElement.prototype.on = function(name, callback, options) {
59
52
  this.$element.addEventListener(name.toLowerCase(), callback, options);