@schukai/monster 3.71.2 → 3.72.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/package.json +1 -1
  3. package/source/components/datatable/dataset.mjs +272 -272
  4. package/source/components/datatable/datasource/dom.mjs +1 -1
  5. package/source/components/datatable/datasource/rest.mjs +408 -410
  6. package/source/components/datatable/filter.mjs +0 -1
  7. package/source/components/datatable/style/datatable.pcss +7 -5
  8. package/source/components/datatable/style/embedded-pagination.pcss +1 -1
  9. package/source/components/datatable/style/pagination.pcss +1 -1
  10. package/source/components/datatable/stylesheet/change-button.mjs +2 -4
  11. package/source/components/datatable/stylesheet/column-bar.mjs +2 -4
  12. package/source/components/datatable/stylesheet/dataset.mjs +2 -4
  13. package/source/components/datatable/stylesheet/datasource.mjs +1 -3
  14. package/source/components/datatable/stylesheet/datatable.mjs +2 -4
  15. package/source/components/datatable/stylesheet/embedded-pagination.mjs +1 -1
  16. package/source/components/datatable/stylesheet/filter-button.mjs +1 -3
  17. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +14 -7
  18. package/source/components/datatable/stylesheet/filter-date-range.mjs +1 -3
  19. package/source/components/datatable/stylesheet/filter-range.mjs +1 -3
  20. package/source/components/datatable/stylesheet/filter.mjs +2 -4
  21. package/source/components/datatable/stylesheet/pagination.mjs +2 -4
  22. package/source/components/datatable/stylesheet/save-button.mjs +2 -4
  23. package/source/components/datatable/stylesheet/select-filter.mjs +2 -4
  24. package/source/components/datatable/stylesheet/status.mjs +2 -4
  25. package/source/components/form/context-error.mjs +0 -2
  26. package/source/components/form/context-help.mjs +1 -2
  27. package/source/components/form/field-set.mjs +219 -219
  28. package/source/components/form/form.mjs +137 -187
  29. package/source/components/form/reload.mjs +211 -211
  30. package/source/components/form/select.mjs +12 -13
  31. package/source/components/form/style/field-set.pcss +2 -2
  32. package/source/components/form/style/form.pcss +8 -0
  33. package/source/components/form/stylesheet/action-button.mjs +2 -4
  34. package/source/components/form/stylesheet/api-button.mjs +1 -3
  35. package/source/components/form/stylesheet/button-bar.mjs +2 -4
  36. package/source/components/form/stylesheet/button.mjs +2 -4
  37. package/source/components/form/stylesheet/confirm-button.mjs +2 -4
  38. package/source/components/form/stylesheet/context-error.mjs +2 -4
  39. package/source/components/form/stylesheet/context-help.mjs +2 -4
  40. package/source/components/form/stylesheet/field-set.mjs +14 -7
  41. package/source/components/form/stylesheet/form.mjs +1 -1
  42. package/source/components/form/stylesheet/message-state-button.mjs +1 -3
  43. package/source/components/form/stylesheet/popper-button.mjs +2 -4
  44. package/source/components/form/stylesheet/select.mjs +14 -7
  45. package/source/components/form/stylesheet/state-button.mjs +2 -4
  46. package/source/components/form/stylesheet/tree-select.mjs +1 -3
  47. package/source/components/host/stylesheet/call-button.mjs +2 -4
  48. package/source/components/host/stylesheet/config-manager.mjs +1 -3
  49. package/source/components/host/stylesheet/host.mjs +2 -4
  50. package/source/components/host/stylesheet/overlay.mjs +2 -4
  51. package/source/components/host/stylesheet/toggle-button.mjs +2 -4
  52. package/source/components/host/stylesheet/viewer.mjs +2 -4
  53. package/source/components/layout/style/collapse.pcss +2 -2
  54. package/source/components/layout/style/details.pcss +2 -2
  55. package/source/components/layout/stylesheet/collapse.mjs +14 -7
  56. package/source/components/layout/stylesheet/details.mjs +2 -4
  57. package/source/components/layout/stylesheet/panel.mjs +2 -4
  58. package/source/components/layout/stylesheet/popper.mjs +2 -4
  59. package/source/components/layout/stylesheet/split-panel.mjs +1 -3
  60. package/source/components/layout/stylesheet/tabs.mjs +2 -4
  61. package/source/components/layout/stylesheet/width-toggle.mjs +1 -3
  62. package/source/components/navigation/stylesheet/table-of-content.mjs +2 -4
  63. package/source/components/notify/stylesheet/message.mjs +2 -4
  64. package/source/components/notify/stylesheet/notify.mjs +2 -4
  65. package/source/components/state/stylesheet/log.mjs +2 -4
  66. package/source/components/state/stylesheet/state.mjs +2 -4
  67. package/source/components/style/control.pcss +5 -0
  68. package/source/components/style/data-grid.pcss +2 -2
  69. package/source/components/style/mixin/typography.pcss +7 -1
  70. package/source/components/style/normalize.pcss +1 -1
  71. package/source/components/stylesheet/badge.mjs +1 -3
  72. package/source/components/stylesheet/border.mjs +1 -3
  73. package/source/components/stylesheet/button.mjs +1 -3
  74. package/source/components/stylesheet/card.mjs +1 -3
  75. package/source/components/stylesheet/color.mjs +1 -3
  76. package/source/components/stylesheet/common.mjs +1 -3
  77. package/source/components/stylesheet/control.mjs +2 -4
  78. package/source/components/stylesheet/data-grid.mjs +2 -4
  79. package/source/components/stylesheet/display.mjs +1 -3
  80. package/source/components/stylesheet/floating-ui.mjs +1 -3
  81. package/source/components/stylesheet/form.mjs +13 -6
  82. package/source/components/stylesheet/host.mjs +1 -3
  83. package/source/components/stylesheet/icons.mjs +1 -3
  84. package/source/components/stylesheet/mixin/badge.mjs +1 -3
  85. package/source/components/stylesheet/mixin/button.mjs +1 -3
  86. package/source/components/stylesheet/mixin/form.mjs +13 -6
  87. package/source/components/stylesheet/mixin/hover.mjs +1 -3
  88. package/source/components/stylesheet/mixin/icon.mjs +1 -3
  89. package/source/components/stylesheet/mixin/media.mjs +1 -3
  90. package/source/components/stylesheet/mixin/property.mjs +13 -6
  91. package/source/components/stylesheet/mixin/skeleton.mjs +1 -3
  92. package/source/components/stylesheet/mixin/spinner.mjs +1 -3
  93. package/source/components/stylesheet/mixin/typography.mjs +1 -3
  94. package/source/components/stylesheet/normalize.mjs +1 -3
  95. package/source/components/stylesheet/popper.mjs +1 -3
  96. package/source/components/stylesheet/property.mjs +2 -4
  97. package/source/components/stylesheet/ripple.mjs +1 -3
  98. package/source/components/stylesheet/skeleton.mjs +1 -3
  99. package/source/components/stylesheet/space.mjs +1 -3
  100. package/source/components/stylesheet/spinner.mjs +1 -3
  101. package/source/components/stylesheet/table.mjs +1 -3
  102. package/source/components/stylesheet/theme.mjs +1 -3
  103. package/source/components/stylesheet/typography.mjs +13 -6
  104. package/source/components/tree-menu/dragable-tree-menu.mjs +693 -0
  105. package/source/components/tree-menu/style/tree-menu.pcss +69 -42
  106. package/source/components/tree-menu/stylesheet/tree-menu.mjs +8 -17
  107. package/source/components/tree-menu/tree-menu.mjs +468 -532
  108. package/source/data/datasource/server/restapi.mjs +194 -191
  109. package/source/data/datasource/server.mjs +107 -105
  110. package/source/data/diff.mjs +1 -1
  111. package/source/dom/customelement.mjs +2 -6
  112. package/source/dom/slotted.mjs +89 -85
  113. package/test/cases/components/host/details.mjs +1 -1
  114. package/test/cases/components/host/host.mjs +1 -1
  115. package/test/cases/components/host/overlay.mjs +1 -1
  116. package/test/cases/dom/customcontrol.mjs +1 -1
  117. package/test/cases/dom/customelement.mjs +2 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
 
4
4
 
5
+ ## [3.72.0] - 2024-06-27
6
+
7
+ ### Add Features
8
+
9
+ - optimize tree menu [#191](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/191)
10
+ ### Bug Fixes
11
+
12
+ - remove style=display: block;
13
+ - remove display property [#219](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/219)
14
+ ### Changes
15
+
16
+ - tidy and stylings
17
+ ### Code Refactoring
18
+
19
+ - paragraph mixin without text-alignment [#220](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/220)
20
+
21
+
22
+
23
+ ## [3.71.3] - 2024-06-26
24
+
25
+ ### Bug Fixes
26
+
27
+ - remove display property [#219](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/219)
28
+
29
+
30
+
5
31
  ## [3.71.2] - 2024-06-25
6
32
 
7
33
  ### Bug Fixes
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.6","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"3.71.2"}
1
+ {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.6","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"3.72.0"}
@@ -12,33 +12,33 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- import {instanceSymbol, internalSymbol} from "../../constants.mjs";
16
- import {Pathfinder} from "../../data/pathfinder.mjs";
17
- import {getLinkedObjects, hasObjectLink} from "../../dom/attributes.mjs";
18
- import {customElementUpdaterLinkSymbol} from "../../dom/constants.mjs";
15
+ import { instanceSymbol, internalSymbol } from "../../constants.mjs";
16
+ import { Pathfinder } from "../../data/pathfinder.mjs";
17
+ import { getLinkedObjects, hasObjectLink } from "../../dom/attributes.mjs";
18
+ import { customElementUpdaterLinkSymbol } from "../../dom/constants.mjs";
19
19
  import {
20
- assembleMethodSymbol,
21
- CustomElement,
22
- attributeObserverSymbol,
23
- registerCustomElement,
20
+ assembleMethodSymbol,
21
+ CustomElement,
22
+ attributeObserverSymbol,
23
+ registerCustomElement,
24
24
  } from "../../dom/customelement.mjs";
25
- import {findElementWithSelectorUpwards} from "../../dom/util.mjs";
26
- import {isString} from "../../types/is.mjs";
27
- import {Observer} from "../../types/observer.mjs";
28
- import {clone} from "../../util/clone.mjs";
25
+ import { findElementWithSelectorUpwards } from "../../dom/util.mjs";
26
+ import { isString } from "../../types/is.mjs";
27
+ import { Observer } from "../../types/observer.mjs";
28
+ import { clone } from "../../util/clone.mjs";
29
29
  import {
30
- ATTRIBUTE_DATASOURCE_SELECTOR,
31
- ATTRIBUTE_DATATABLE_INDEX,
30
+ ATTRIBUTE_DATASOURCE_SELECTOR,
31
+ ATTRIBUTE_DATATABLE_INDEX,
32
32
  } from "./constants.mjs";
33
- import {Datasource} from "./datasource.mjs";
34
- import {DatasetStyleSheet} from "./stylesheet/dataset.mjs";
33
+ import { Datasource } from "./datasource.mjs";
34
+ import { DatasetStyleSheet } from "./stylesheet/dataset.mjs";
35
35
  import {
36
- handleDataSourceChanges,
37
- datasourceLinkedElementSymbol,
36
+ handleDataSourceChanges,
37
+ datasourceLinkedElementSymbol,
38
38
  } from "./util.mjs";
39
- import {FormStyleSheet} from "../stylesheet/form.mjs";
39
+ import { FormStyleSheet } from "../stylesheet/form.mjs";
40
40
 
41
- export {DataSet};
41
+ export { DataSet };
42
42
 
43
43
  /**
44
44
  * The data set component is used to show the data of a data source.
@@ -79,219 +79,221 @@ export {DataSet};
79
79
  * @summary A data set
80
80
  */
81
81
  class DataSet extends CustomElement {
82
- /**
83
- * This method is called by the `instanceof` operator.
84
- * @returns {symbol}
85
- */
86
- static get [instanceSymbol]() {
87
- return Symbol.for("@schukai/monster/components/dataset@@instance");
88
- }
89
-
90
- /**
91
- * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
92
- *
93
- * @return {string[]}
94
- * @since 1.15.0
95
- */
96
- static get observedAttributes() {
97
- const attributes = super.observedAttributes;
98
- attributes.push(ATTRIBUTE_DATATABLE_INDEX);
99
- return attributes;
100
- }
101
-
102
- /**
103
- * To set the options via the html tag the attribute `data-monster-options` must be used.
104
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
105
- *
106
- * The individual configuration values can be found in the table.
107
- *
108
- * @property {Object} templates Template definitions
109
- * @property {string} templates.main Main template
110
- * @property {object} datasource The datasource
111
- * @property {string} datasource.selector The selector of the datasource
112
- * @property {object} mapping The mapping
113
- * @property {string} mapping.data The data
114
- * @property {number} mapping.index The index
115
- * @property {Array} data The data
116
- */
117
- get defaults() {
118
- const obj = Object.assign({}, super.defaults, {
119
- templates: {
120
- main: getTemplate(),
121
- },
122
-
123
- datasource: {
124
- selector: null,
125
- },
126
-
127
- mapping: {
128
- data: "dataset",
129
- index: 0,
130
- },
131
-
132
- features: {
133
- /**
134
- * @since 3.70.0
135
- * @type {boolean}
136
- */
137
- refreshOnMutation: true,
138
- },
139
-
140
- /**
141
- * @since 3.70.0
142
- * @type {boolean}
143
- */
144
- refreshOnMutation: {
145
- selector: "input, select, textarea"
146
- },
147
-
148
- data: {},
149
- });
150
-
151
- updateOptionsFromArguments.call(this, obj);
152
- return obj;
153
- }
154
-
155
- /**
156
- *
157
- * @return {string}
158
- */
159
- static getTag() {
160
- return "monster-dataset";
161
- }
162
-
163
- /**
164
- * This method is called when the component is created.
165
- * @since 3.70.0
166
- * @returns {DataSet}
167
- */
168
- refresh() {
169
- // makes sure that handleDataSourceChanges is called
170
- this.setOption("data", {});
171
- return this;
172
- }
173
-
174
- /**
175
- *
176
- * @returns {Promise<unknown>}
177
- */
178
- write() {
179
- return new Promise((resolve, reject) => {
180
- if (!this[datasourceLinkedElementSymbol]) {
181
- reject(new Error("No datasource"));
182
- return;
183
- }
184
-
185
- const internalUpdateCloneData = this.getInternalUpdateCloneData();
186
- if (!internalUpdateCloneData) {
187
- reject(new Error("No update data"));
188
- return;
189
- }
190
-
191
- const internalData = internalUpdateCloneData?.["data"];
192
- if (
193
- internalData === undefined ||
194
- internalData === null ||
195
- internalData === ""
196
- ) {
197
- reject(new Error("No data"));
198
- return;
199
- }
200
-
201
- setTimeout(() => {
202
- const path = this.getOption("mapping.data");
203
- const index = this.getOption("mapping.index");
204
-
205
- let pathWithIndex;
206
-
207
- if (isString(path) && path !== "") {
208
- pathWithIndex = path + "." + index;
209
- } else {
210
- pathWithIndex = String(index);
211
- }
212
-
213
- const data = this[datasourceLinkedElementSymbol].data;
214
- const unref = JSON.stringify(data);
215
- const ref = JSON.parse(unref);
216
-
217
- new Pathfinder(ref).setVia(pathWithIndex, internalData);
218
-
219
- this[datasourceLinkedElementSymbol].data = ref;
220
-
221
- resolve();
222
- }, 0);
223
- });
224
- }
225
-
226
- /**
227
- * This method is responsible for assembling the component.
228
- *
229
- * It calls the parent's assemble method first, then initializes control references and event handlers.
230
- * If the `datasource.selector` option is provided and is a string, it searches for the corresponding
231
- * element in the DOM using that selector.
232
- *
233
- * If the selector matches exactly one element, it checks if the element is an instance of the `Datasource` class.
234
- *
235
- * If it is, the component's `datasourceLinkedElementSymbol` property is set to the element, and the component
236
- * attaches an observer to the datasource's changes.
237
- *
238
- * The observer is a function that calls the `handleDataSourceChanges` method in the context of the component.
239
- * Additionally, the component attaches an observer to itself, which also calls the `handleDataSourceChanges`
240
- * method in the component's context.
241
- */
242
- [assembleMethodSymbol]() {
243
- super[assembleMethodSymbol]();
244
-
245
- initEventHandler.call(this);
246
-
247
- const selector = this.getOption("datasource.selector");
248
-
249
- if (isString(selector)) {
250
- const element = findElementWithSelectorUpwards(this, selector);
251
- if (element === null) {
252
- throw new Error("the selector must match exactly one element");
253
- }
254
-
255
- if (!(element instanceof Datasource)) {
256
- throw new TypeError("the element must be a datasource");
257
- }
258
-
259
- this[datasourceLinkedElementSymbol] = element;
260
- element.datasource.attachObserver(
261
- new Observer(handleDataSourceChanges.bind(this)),
262
- );
263
- }
264
-
265
- this.attachObserver(
266
- new Observer(() => {
267
- handleDataSourceChanges.call(this);
268
- }),
269
- );
270
-
271
- if (this.getOption("features.refreshOnMutation")&&this.getOption("refreshOnMutation.selector")) {
272
- initMutationObserver.call(this);
273
- }
274
-
275
- }
276
-
277
- /**
278
- * @return [CSSStyleSheet]
279
- */
280
- static getCSSStyleSheet() {
281
- return [FormStyleSheet, DatasetStyleSheet];
282
- }
82
+ /**
83
+ * This method is called by the `instanceof` operator.
84
+ * @returns {symbol}
85
+ */
86
+ static get [instanceSymbol]() {
87
+ return Symbol.for("@schukai/monster/components/dataset@@instance");
88
+ }
89
+
90
+ /**
91
+ * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
92
+ *
93
+ * @return {string[]}
94
+ * @since 1.15.0
95
+ */
96
+ static get observedAttributes() {
97
+ const attributes = super.observedAttributes;
98
+ attributes.push(ATTRIBUTE_DATATABLE_INDEX);
99
+ return attributes;
100
+ }
101
+
102
+ /**
103
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
104
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
105
+ *
106
+ * The individual configuration values can be found in the table.
107
+ *
108
+ * @property {Object} templates Template definitions
109
+ * @property {string} templates.main Main template
110
+ * @property {object} datasource The datasource
111
+ * @property {string} datasource.selector The selector of the datasource
112
+ * @property {object} mapping The mapping
113
+ * @property {string} mapping.data The data
114
+ * @property {number} mapping.index The index
115
+ * @property {Array} data The data
116
+ */
117
+ get defaults() {
118
+ const obj = Object.assign({}, super.defaults, {
119
+ templates: {
120
+ main: getTemplate(),
121
+ },
122
+
123
+ datasource: {
124
+ selector: null,
125
+ },
126
+
127
+ mapping: {
128
+ data: "dataset",
129
+ index: 0,
130
+ },
131
+
132
+ features: {
133
+ /**
134
+ * @since 3.70.0
135
+ * @type {boolean}
136
+ */
137
+ refreshOnMutation: true,
138
+ },
139
+
140
+ /**
141
+ * @since 3.70.0
142
+ * @type {boolean}
143
+ */
144
+ refreshOnMutation: {
145
+ selector: "input, select, textarea",
146
+ },
147
+
148
+ data: {},
149
+ });
150
+
151
+ updateOptionsFromArguments.call(this, obj);
152
+ return obj;
153
+ }
154
+
155
+ /**
156
+ *
157
+ * @return {string}
158
+ */
159
+ static getTag() {
160
+ return "monster-dataset";
161
+ }
162
+
163
+ /**
164
+ * This method is called when the component is created.
165
+ * @since 3.70.0
166
+ * @returns {DataSet}
167
+ */
168
+ refresh() {
169
+ // makes sure that handleDataSourceChanges is called
170
+ this.setOption("data", {});
171
+ return this;
172
+ }
173
+
174
+ /**
175
+ *
176
+ * @returns {Promise<unknown>}
177
+ */
178
+ write() {
179
+ return new Promise((resolve, reject) => {
180
+ if (!this[datasourceLinkedElementSymbol]) {
181
+ reject(new Error("No datasource"));
182
+ return;
183
+ }
184
+
185
+ const internalUpdateCloneData = this.getInternalUpdateCloneData();
186
+ if (!internalUpdateCloneData) {
187
+ reject(new Error("No update data"));
188
+ return;
189
+ }
190
+
191
+ const internalData = internalUpdateCloneData?.["data"];
192
+ if (
193
+ internalData === undefined ||
194
+ internalData === null ||
195
+ internalData === ""
196
+ ) {
197
+ reject(new Error("No data"));
198
+ return;
199
+ }
200
+
201
+ setTimeout(() => {
202
+ const path = this.getOption("mapping.data");
203
+ const index = this.getOption("mapping.index");
204
+
205
+ let pathWithIndex;
206
+
207
+ if (isString(path) && path !== "") {
208
+ pathWithIndex = path + "." + index;
209
+ } else {
210
+ pathWithIndex = String(index);
211
+ }
212
+
213
+ const data = this[datasourceLinkedElementSymbol].data;
214
+ const unref = JSON.stringify(data);
215
+ const ref = JSON.parse(unref);
216
+
217
+ new Pathfinder(ref).setVia(pathWithIndex, internalData);
218
+
219
+ this[datasourceLinkedElementSymbol].data = ref;
220
+
221
+ resolve();
222
+ }, 0);
223
+ });
224
+ }
225
+
226
+ /**
227
+ * This method is responsible for assembling the component.
228
+ *
229
+ * It calls the parent's assemble method first, then initializes control references and event handlers.
230
+ * If the `datasource.selector` option is provided and is a string, it searches for the corresponding
231
+ * element in the DOM using that selector.
232
+ *
233
+ * If the selector matches exactly one element, it checks if the element is an instance of the `Datasource` class.
234
+ *
235
+ * If it is, the component's `datasourceLinkedElementSymbol` property is set to the element, and the component
236
+ * attaches an observer to the datasource's changes.
237
+ *
238
+ * The observer is a function that calls the `handleDataSourceChanges` method in the context of the component.
239
+ * Additionally, the component attaches an observer to itself, which also calls the `handleDataSourceChanges`
240
+ * method in the component's context.
241
+ */
242
+ [assembleMethodSymbol]() {
243
+ super[assembleMethodSymbol]();
244
+
245
+ initEventHandler.call(this);
246
+
247
+ const selector = this.getOption("datasource.selector");
248
+
249
+ if (isString(selector)) {
250
+ const element = findElementWithSelectorUpwards(this, selector);
251
+ if (element === null) {
252
+ throw new Error("the selector must match exactly one element");
253
+ }
254
+
255
+ if (!(element instanceof Datasource)) {
256
+ throw new TypeError("the element must be a datasource");
257
+ }
258
+
259
+ this[datasourceLinkedElementSymbol] = element;
260
+ element.datasource.attachObserver(
261
+ new Observer(handleDataSourceChanges.bind(this)),
262
+ );
263
+ }
264
+
265
+ this.attachObserver(
266
+ new Observer(() => {
267
+ handleDataSourceChanges.call(this);
268
+ }),
269
+ );
270
+
271
+ if (
272
+ this.getOption("features.refreshOnMutation") &&
273
+ this.getOption("refreshOnMutation.selector")
274
+ ) {
275
+ initMutationObserver.call(this);
276
+ }
277
+ }
278
+
279
+ /**
280
+ * @return [CSSStyleSheet]
281
+ */
282
+ static getCSSStyleSheet() {
283
+ return [FormStyleSheet, DatasetStyleSheet];
284
+ }
283
285
  }
284
286
 
285
287
  /**
286
288
  * @private
287
289
  */
288
290
  function initEventHandler() {
289
- this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => {
290
- const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
291
- if (index) {
292
- this.setOption("mapping.index", parseInt(index, 10));
293
- }
294
- };
291
+ this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => {
292
+ const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
293
+ if (index) {
294
+ this.setOption("mapping.index", parseInt(index, 10));
295
+ }
296
+ };
295
297
  }
296
298
 
297
299
  /**
@@ -299,67 +301,65 @@ function initEventHandler() {
299
301
  * @param {Object} options
300
302
  */
301
303
  function updateOptionsFromArguments(options) {
302
- const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
304
+ const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
303
305
 
304
- if (index !== null && index !== undefined) {
305
- options.mapping.index = parseInt(index, 10);
306
- }
306
+ if (index !== null && index !== undefined) {
307
+ options.mapping.index = parseInt(index, 10);
308
+ }
307
309
 
308
- const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
310
+ const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
309
311
 
310
- if (selector) {
311
- options.datasource.selector = selector;
312
- }
312
+ if (selector) {
313
+ options.datasource.selector = selector;
314
+ }
313
315
  }
314
316
 
315
317
  /**
316
318
  * @private
317
319
  */
318
320
  function initMutationObserver() {
319
-
320
- const config = {attributes: false, childList: true, subtree: true};
321
-
322
- const callback = (mutationList, observer) => {
323
-
324
- if (mutationList.length === 0) {
325
- return;
326
- }
327
-
328
- let doneFlag = false;
329
- for (const mutation of mutationList) {
330
-
331
- if (mutation.type === "childList") {
332
- for (const node of mutation.addedNodes) {
333
- if(node instanceof HTMLElement && node.matches(this.getOption("refreshOnMutation.selector"))) {
334
- doneFlag = true;
335
- break;
336
- }
337
- }
338
-
339
- if (doneFlag) {
340
- break;
341
- }
342
- }
343
- }
344
-
345
- if (doneFlag) {
346
- this.refresh();
347
- }
348
- };
349
-
350
- const observer = new MutationObserver(callback);
351
- observer.observe(this, config);
352
-
321
+ const config = { attributes: false, childList: true, subtree: true };
322
+
323
+ const callback = (mutationList, observer) => {
324
+ if (mutationList.length === 0) {
325
+ return;
326
+ }
327
+
328
+ let doneFlag = false;
329
+ for (const mutation of mutationList) {
330
+ if (mutation.type === "childList") {
331
+ for (const node of mutation.addedNodes) {
332
+ if (
333
+ node instanceof HTMLElement &&
334
+ node.matches(this.getOption("refreshOnMutation.selector"))
335
+ ) {
336
+ doneFlag = true;
337
+ break;
338
+ }
339
+ }
340
+
341
+ if (doneFlag) {
342
+ break;
343
+ }
344
+ }
345
+ }
346
+
347
+ if (doneFlag) {
348
+ this.refresh();
349
+ }
350
+ };
351
+
352
+ const observer = new MutationObserver(callback);
353
+ observer.observe(this, config);
353
354
  }
354
355
 
355
-
356
356
  /**
357
357
  * @private
358
358
  * @return {string}
359
359
  */
360
360
  function getTemplate() {
361
- // language=HTML
362
- return `
361
+ // language=HTML
362
+ return `
363
363
  <div data-monster-role="control" part="control">
364
364
  <slot></slot>
365
365
  </div>
@@ -180,7 +180,7 @@ function updateDataSource() {
180
180
  data = [];
181
181
  }
182
182
 
183
- this.datasource.set(data);
183
+ this.data = data;
184
184
  }
185
185
 
186
186
  /**