@schukai/monster 3.71.2 → 3.72.0

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 (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
  /**