@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
@@ -0,0 +1,693 @@
1
+ /**
2
+ * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
3
+ * Node module: @schukai/monster
4
+ *
5
+ * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
6
+ * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
7
+ *
8
+ * For those who do not wish to adhere to the AGPLv3, a commercial license is available.
9
+ * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
10
+ * For more information about purchasing a commercial license, please contact schukai GmbH.
11
+ *
12
+ * SPDX-License-Identifier: AGPL-3.0
13
+ */
14
+
15
+ import { buildTree } from "../../data/buildtree.mjs";
16
+ import { Datasource } from "../../data/datasource.mjs";
17
+ import { addAttributeToken } from "../../dom/attributes.mjs";
18
+ import {
19
+ ATTRIBUTE_DISABLED,
20
+ ATTRIBUTE_ERRORMESSAGE,
21
+ ATTRIBUTE_ROLE,
22
+ ATTRIBUTE_UPDATER_INSERT_REFERENCE,
23
+ } from "../../dom/constants.mjs";
24
+ import {
25
+ assembleMethodSymbol,
26
+ CustomElement,
27
+ initMethodSymbol,
28
+ registerCustomElement,
29
+ } from "../../dom/customelement.mjs";
30
+ import { findTargetElementFromEvent } from "../../dom/events.mjs";
31
+ import { findElementWithSelectorUpwards } from "../../dom/util.mjs";
32
+ import { Formatter } from "../../text/formatter.mjs";
33
+ import { isObject, isString } from "../../types/is.mjs";
34
+ import { Node } from "../../types/node.mjs";
35
+ import { NodeRecursiveIterator } from "../../types/noderecursiveiterator.mjs";
36
+ import { Observer } from "../../types/observer.mjs";
37
+ import { ProxyObserver } from "../../types/proxyobserver.mjs";
38
+ import { validateInstance } from "../../types/validate.mjs";
39
+ import {
40
+ datasourceLinkedElementSymbol,
41
+ handleDataSourceChanges,
42
+ } from "../datatable/util.mjs";
43
+ import { ATTRIBUTE_INTEND } from "./../constants.mjs";
44
+ import { CommonStyleSheet } from "../stylesheet/common.mjs";
45
+ import { TreeMenuStyleSheet } from "./stylesheet/tree-menu.mjs";
46
+
47
+ export { TreeMenu };
48
+
49
+ /**
50
+ * @private
51
+ * @type {symbol}
52
+ */
53
+ const internalNodesSymbol = Symbol("internalNodes");
54
+
55
+ /**
56
+ * @private
57
+ * @type {symbol}
58
+ */
59
+ const controlElementSymbol = Symbol("controlElement");
60
+
61
+ /**
62
+ * @private
63
+ * @type {symbol}
64
+ */
65
+ const openEntryEventHandlerSymbol = Symbol("openEntryEventHandler");
66
+
67
+ /**
68
+ * @private
69
+ * @type {symbol}
70
+ */
71
+ const dragstartEventHandlerSymbol = Symbol("dragstartEventHandler");
72
+ /**
73
+ * @private
74
+ * @type {symbol}
75
+ */
76
+ const dragenterEventHandlerSymbol = Symbol("dragenterEventHandler");
77
+
78
+ /**
79
+ * @private
80
+ * @type {symbol}
81
+ */
82
+ const dragleaveEventHandlerSymbol = Symbol("dragleaveEventHandler");
83
+
84
+ /**
85
+ * @private
86
+ * @type {symbol}
87
+ */
88
+ const dragEventHandlerSymbol = Symbol("dragEventHandler");
89
+
90
+ /**
91
+ * @private
92
+ * @type {symbol}
93
+ */
94
+ const dragoverEventHandlerSymbol = Symbol("dragoverEventHandler");
95
+
96
+ /**
97
+ * @private
98
+ * @type {symbol}
99
+ */
100
+ const dropEventHandlerSymbol = Symbol("dropEventHandlerSymbol");
101
+
102
+ /**
103
+ * TreeMenu
104
+ *
105
+ * <img src="./images/tree-menu.png">
106
+ *
107
+ * You can create this control either by specifying the HTML tag `<monster-tree-menu />` directly in the HTML
108
+ *
109
+ * ```html
110
+ * <monster-tree-menu></monster-tree-menu>
111
+ * ```
112
+ *
113
+ * or using Javascript via the `document.createElement('monster-tree-menu');` method.
114
+ *
115
+ * ```javascript
116
+ * import {TreeMenu} from 'https://cdn.jsdelivr.net/npm/@schukai/component-treemenu@0.1.0/dist/modules/treemenu.js';
117
+ * document.createElement('monster-treemenu');
118
+ * ```
119
+ *
120
+ * @startuml tree-menu.png
121
+ * skinparam monochrome true
122
+ * skinparam shadowing false
123
+ * HTMLElement <|-- CustomElement
124
+ * CustomElement <|-- CustomControl
125
+ * CustomControl <|-- TreeMenu
126
+ * @enduml
127
+ * @since 1.0.0
128
+ * @copyright schukai GmbH
129
+ * @memberOf Monster.Components.TreeMenu
130
+ * @summary A TreeMenu control
131
+ * @fires Monster.Components.TreeMenu.event:monster-fetched
132
+ */
133
+ class TreeMenu extends CustomElement {
134
+ /**
135
+ * This method is called internal and should not be called directly.
136
+ *
137
+ * The defaults can be set either directly in the object or via an attribute in the HTML tag.
138
+ * The value of the attribute `data-monster-options` in the HTML tag must be a JSON string.
139
+ *
140
+ * ```
141
+ * <monster-treemenu data-monster-options="{}"></monster-treemenu>
142
+ * ```
143
+ *
144
+ * Since 1.18.0 the JSON can be specified as a DataURI.
145
+ *
146
+ * ```
147
+ * new Monster.Types.DataUrl(btoa(JSON.stringify({
148
+ * shadowMode: 'open',
149
+ * })),'application/json',true).toString()
150
+ * ```
151
+ * @property {Object} toggleEventType=click,touch List of event types to be observed for opening the dropdown
152
+ * @property {Object} templates Template definitions
153
+ * @property {string} templates.main Main template
154
+ * @property {Datasource} datasource data source
155
+ * @property {Object} mapping
156
+ * @property {String} mapping.selector=* Path to select the appropriate entries
157
+ * @property {String} mapping.labelTemplate="" template with the label placeholders in the form ${name}, where name is the key
158
+ * @property {String} mapping.keyTemplate="" template with the key placeholders in the form ${name}, where name is the key
159
+ * @property {String} mapping.rootReferences=['0', undefined, null]
160
+ * @property {String} mapping.idTemplate=id
161
+ * @property {String} mapping.parentTemplate=parent
162
+ * @property {String} mapping.selection
163
+ */
164
+ get defaults() {
165
+ return Object.assign(
166
+ {},
167
+ super.defaults,
168
+ {
169
+ toggleEventType: ["click", "touch"],
170
+ mapping: {
171
+ rootReferences: ["0", undefined, null],
172
+ idTemplate: "id",
173
+ parentTemplate: "parent",
174
+ selector: "*",
175
+ labelTemplate: "",
176
+ valueTemplate: "",
177
+ filter: undefined,
178
+ },
179
+ templates: {
180
+ main: getTemplate(),
181
+ },
182
+
183
+ datasource: {
184
+ selector: null,
185
+ },
186
+
187
+ data: [],
188
+ },
189
+ initOptionsFromArguments.call(this),
190
+ );
191
+ }
192
+
193
+ /**
194
+ * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
195
+ *
196
+ * @return {string[]}
197
+ * @since 1.15.0
198
+ */
199
+ static get observedAttributes() {
200
+ const list = super.observedAttributes;
201
+ //list.push(ATTRIBUTE_FORM_URL);
202
+ return list;
203
+ }
204
+
205
+ /**
206
+ *
207
+ */
208
+ [initMethodSymbol]() {
209
+ super[initMethodSymbol]();
210
+ }
211
+
212
+ /**
213
+ *
214
+ * @return {Monster.Components.TreeMenu.Form}
215
+ */
216
+ [assembleMethodSymbol]() {
217
+ super[assembleMethodSymbol]();
218
+
219
+ initControlReferences.call(this);
220
+ initEventHandler.call(this);
221
+ // importEntriesFromDatasource.call(this);
222
+ initObserver.call(this);
223
+
224
+ return this;
225
+ }
226
+
227
+ /**
228
+ * This method is called internal and should not be called directly.
229
+ *
230
+ * @return {CSSStyleSheet[]}
231
+ */
232
+ static getCSSStyleSheet() {
233
+ return [CommonStyleSheet, TreeMenuStyleSheet];
234
+ }
235
+
236
+ /**
237
+ * This method is called internal and should not be called directly.
238
+ *
239
+ * @return {string}
240
+ */
241
+ static getTag() {
242
+ return "monster-tree-menu";
243
+ }
244
+ }
245
+
246
+ /**
247
+ * @private
248
+ */
249
+ function initEventHandler() {
250
+ switchToConfig.call(this);
251
+
252
+ const selector = this.getOption("datasource.selector");
253
+
254
+ if (isString(selector)) {
255
+ const element = findElementWithSelectorUpwards(this, selector);
256
+ if (element === null) {
257
+ throw new Error("the selector must match exactly one element");
258
+ }
259
+
260
+ if (!(element instanceof Datasource)) {
261
+ throw new TypeError("the element must be a datasource");
262
+ }
263
+
264
+ this[datasourceLinkedElementSymbol] = element;
265
+ element.datasource.attachObserver(
266
+ new Observer(handleDataSourceChanges.bind(this)),
267
+ );
268
+ }
269
+
270
+ this[openEntryEventHandlerSymbol] = (event) => {
271
+ const container = findTargetElementFromEvent(
272
+ event,
273
+ ATTRIBUTE_ROLE,
274
+ "entry",
275
+ );
276
+ if (!(container instanceof HTMLElement)) {
277
+ return;
278
+ }
279
+
280
+ //let container = findClosestByAttribute(element, ATTRIBUTE_ROLE, 'option');
281
+ const index = container
282
+ .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
283
+ .split("-")
284
+ .pop();
285
+
286
+ const currentState = this.getOption("data." + index + ".state");
287
+
288
+ const newState = currentState === "close" ? "open" : "close";
289
+ this.setOption("data." + index + ".state", newState);
290
+
291
+ const newVisibility = newState === "open" ? "visible" : "hidden";
292
+
293
+ if (container.hasAttribute(ATTRIBUTE_INTEND)) {
294
+ const intend = container.getAttribute(ATTRIBUTE_INTEND);
295
+
296
+ let ref = container.nextElementSibling;
297
+ const childIntend = parseInt(intend) + 1;
298
+
299
+ const cmp = (a, b) => {
300
+ if (newState === "open") {
301
+ return a === b;
302
+ }
303
+
304
+ return a >= b;
305
+ };
306
+
307
+ while (
308
+ ref &&
309
+ ref.hasAttribute(ATTRIBUTE_INTEND) &&
310
+ cmp(parseInt(ref.getAttribute(ATTRIBUTE_INTEND)), childIntend)
311
+ ) {
312
+ const refIndex = ref
313
+ .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
314
+ .split("-")
315
+ .pop();
316
+ this.setOption("data." + refIndex + ".visibility", newVisibility);
317
+
318
+ if (newState === "close") {
319
+ this.setOption("data." + refIndex + ".state", "close");
320
+ }
321
+
322
+ ref = ref.nextElementSibling;
323
+ }
324
+ }
325
+ };
326
+
327
+ const types = this.getOption("toggleEventType", ["click"]);
328
+ for (const [, type] of Object.entries(types)) {
329
+ this.shadowRoot.addEventListener(type, this[openEntryEventHandlerSymbol]);
330
+ }
331
+
332
+ // for (const [, type] of Object.entries(types)) {
333
+ //
334
+ // self[controlElementSymbol].addEventListener(type, function (event) {
335
+ //
336
+ // const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, 'entry');
337
+ // if (!(element instanceof HTMLElement)) {
338
+ // return;
339
+ // }
340
+ //
341
+ // toggle.call(self);
342
+ //
343
+ //
344
+ // })
345
+ //
346
+ // }
347
+
348
+ return this;
349
+ }
350
+
351
+ /**
352
+ * @private
353
+ * @this Form
354
+ */
355
+ function initObserver() {}
356
+
357
+ /**
358
+ * Import Menu Entries from dataset
359
+ *
360
+ * @since 1.0.0
361
+ * @param {array|object|Map|Set} data
362
+ * @return {TreeMenu}
363
+ * @throws {Error} map is not iterable
364
+ * @private
365
+ */
366
+ function importEntries(data) {
367
+ this[internalNodesSymbol] = new Map();
368
+
369
+ const mappingOptions = this.getOption("mapping", {});
370
+
371
+ const filter = mappingOptions?.["filter"];
372
+ const rootReferences = mappingOptions?.["rootReferences"];
373
+
374
+ const id = this.getOption("mapping.idTemplate", "id");
375
+ const parentID = this.getOption("mapping.parentTemplate", "parent");
376
+
377
+ const selector = mappingOptions?.["selector"];
378
+
379
+ const nodes = buildTree(data, selector, id, parentID, {
380
+ filter,
381
+ rootReferences,
382
+ });
383
+
384
+ const options = [];
385
+ for (const node of nodes) {
386
+ const iterator = new NodeRecursiveIterator(node);
387
+ for (const n of iterator) {
388
+ const formattedValues = formatKeyLabel.call(this, n);
389
+
390
+ const label = formattedValues.label;
391
+ const value = formattedValues.value;
392
+ const intend = n.level;
393
+
394
+ const visibility = intend > 0 ? "hidden" : "visible";
395
+ const state = "close";
396
+
397
+ this[internalNodesSymbol].set(value, n);
398
+
399
+ options.push({
400
+ value,
401
+ label,
402
+ intend,
403
+ state,
404
+ visibility,
405
+ ["has-children"]: n.hasChildNodes(),
406
+ });
407
+ }
408
+ }
409
+
410
+ this.setOption("entries", options);
411
+ return this;
412
+ }
413
+
414
+ /**
415
+ * @private
416
+ */
417
+ function importEntriesFromDatasource() {
418
+ const self = this;
419
+ self.setAttribute(ATTRIBUTE_DISABLED, ATTRIBUTE_DISABLED);
420
+
421
+ const datasource = self.getOption("datasource");
422
+ if (!(datasource instanceof Datasource)) {
423
+ addAttributeToken(
424
+ self,
425
+ ATTRIBUTE_ERRORMESSAGE,
426
+ "datasource is not defined",
427
+ );
428
+ return;
429
+ }
430
+
431
+ datasource.attachObserver(
432
+ new Observer(function () {
433
+ if (isObject(this) && this instanceof ProxyObserver) {
434
+ importEntries.call(self, datasource.get());
435
+ }
436
+ }),
437
+ );
438
+
439
+ datasource
440
+ .read()
441
+ .then(() => {
442
+ new Processing(() => {
443
+ self.removeAttribute(ATTRIBUTE_DISABLED);
444
+ }).run();
445
+ })
446
+ .catch((e) => {
447
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
448
+ });
449
+
450
+ return self;
451
+ }
452
+
453
+ /**
454
+ *
455
+ * @param {Node} node
456
+ * @return {array<label, value>}
457
+ * @memberOf Monster.Components.TreeMenu
458
+ * @private
459
+ */
460
+ function formatKeyLabel(node) {
461
+ validateInstance(node, Node);
462
+
463
+ const label = new Formatter(node.value).format(
464
+ this.getOption("mapping.labelTemplate", ""),
465
+ );
466
+ const value = new Formatter(node.value).format(
467
+ this.getOption("mapping.valueTemplate", ""),
468
+ );
469
+
470
+ return {
471
+ value,
472
+ label,
473
+ };
474
+ }
475
+
476
+ /**
477
+ * @private
478
+ * @return {Monster.Components.TreeMenu.Form}
479
+ */
480
+ function initControlReferences() {
481
+ if (!this.shadowRoot) {
482
+ throw new Error("no shadow-root is defined");
483
+ }
484
+
485
+ this[controlElementSymbol] = this.shadowRoot.querySelector(
486
+ "[data-monster-role=control]",
487
+ );
488
+
489
+ return this;
490
+ }
491
+
492
+ /**
493
+ *
494
+ * ```
495
+ * <monster-tree-menu data-monster-url="https://example.com/"></monster-tree-menu>
496
+ * ```
497
+
498
+ * @private
499
+ * @return {object}
500
+ */
501
+ function initOptionsFromArguments() {
502
+ const options = {};
503
+
504
+ // let url = self.getAttribute(ATTRIBUTE_FORM_URL);
505
+ //
506
+ // if (isString(url)) {
507
+ // options['url'] = new URL(url, document.location).toString()
508
+ // }
509
+
510
+ return options;
511
+ }
512
+
513
+ function switchToConfig() {
514
+ if (!this.shadowRoot) {
515
+ throw new Error("no shadow-root is defined");
516
+ }
517
+
518
+ this[dragoverEventHandlerSymbol] = (event) => {
519
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
520
+ event.preventDefault();
521
+ if (!(element instanceof HTMLElement)) {
522
+ return;
523
+ }
524
+
525
+ const dropzone = document.createElement("div");
526
+ dropzone.classList.add("dropzone");
527
+
528
+ element.prepend(dropzone);
529
+
530
+ console.log("over", element.outerHTML, event);
531
+
532
+ event.dataTransfer.dropEffect = "move";
533
+ };
534
+
535
+ this[dragenterEventHandlerSymbol] = (event) => {
536
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
537
+ console.log("enter", element.outerHTML, event);
538
+
539
+ event.dataTransfer.dropEffect = "move";
540
+ event.preventDefault();
541
+ };
542
+
543
+ this[dragleaveEventHandlerSymbol] = (event) => {
544
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
545
+
546
+ event.preventDefault();
547
+ if (!(element instanceof HTMLElement)) {
548
+ return;
549
+ }
550
+
551
+ console.log("leave", element.outerHTML, event);
552
+
553
+ event.dataTransfer.dropEffect = "move";
554
+ event.preventDefault();
555
+ };
556
+
557
+ this[dragEventHandlerSymbol] = (event) => {
558
+ event.preventDefault();
559
+ };
560
+
561
+ this[dropEventHandlerSymbol] = (event) => {
562
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
563
+ console.log("drop", element.outerHTML, event);
564
+ event.preventDefault();
565
+ };
566
+
567
+ this[dragstartEventHandlerSymbol] = (event) => {
568
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
569
+ if (!(element instanceof HTMLElement)) {
570
+ return;
571
+ }
572
+
573
+ //let container = findClosestByAttribute(element, ATTRIBUTE_ROLE, 'option');
574
+ const index = element
575
+ .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
576
+ .split("-")
577
+ .pop();
578
+
579
+ const currentState = this.getOption("entries." + index + ".state");
580
+ event.dataTransfer.setData("text/plain", "22");
581
+ event.dataTransfer.setData("text/html", "22");
582
+ event.dataTransfer.effectAllowed = "move";
583
+ };
584
+
585
+ this[controlElementSymbol].addEventListener(
586
+ "dragstart",
587
+ this[dragstartEventHandlerSymbol],
588
+ );
589
+ this[controlElementSymbol].addEventListener(
590
+ "dragenter",
591
+ this[dragenterEventHandlerSymbol],
592
+ );
593
+ this[controlElementSymbol].addEventListener(
594
+ "dragleave",
595
+ this[dragleaveEventHandlerSymbol],
596
+ );
597
+ this[controlElementSymbol].addEventListener(
598
+ "dragover",
599
+ this[dragoverEventHandlerSymbol],
600
+ );
601
+ this[controlElementSymbol].addEventListener(
602
+ "drop",
603
+ this[dropEventHandlerSymbol],
604
+ );
605
+ }
606
+
607
+ // /**
608
+ // * @private
609
+ // * @throws {Error} missing default slot
610
+ // * @throws {Error} no shadow-root is defined
611
+ // * @throws {Error} missing url
612
+ // * @throws {Error} we won't be able to read the data
613
+ // * @throws {Error} request failed
614
+ // * @throws {Error} not found
615
+ // * @throws {Error} undefined status or type
616
+ // * @fires Monster.Components.TreeMenu.event:monster-fetched
617
+ // */
618
+ // function initIntersectionObserver() {
619
+ // const self = this;
620
+ //
621
+ // if (self[intersectionObserverWasInitialized] === true) {
622
+ // return
623
+ // }
624
+ //
625
+ // self[intersectionObserverWasInitialized] = true;
626
+ //
627
+ // let options = {
628
+ // threshold: [0.5]
629
+ // }
630
+ //
631
+ // const callback = (entries, observer) => {
632
+ //
633
+ // for (const [, entry] of entries.entries()) {
634
+ // if (entry.isIntersecting === true) {
635
+ // if (!self.hasAttribute(ATTRIBUTE_FORM_RELOAD) || self.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase() === 'onshow') {
636
+ // observer.disconnect();
637
+ // }
638
+ //
639
+ // try {
640
+ // loadContent.call(self);
641
+ // } catch (e) {
642
+ // self.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
643
+ // }
644
+ //
645
+ //
646
+ // }
647
+ // }
648
+ // }
649
+ //
650
+ // const observer = new IntersectionObserver(callback, options);
651
+ // observer.observe(self);
652
+ //
653
+ //
654
+ // }
655
+
656
+ /**
657
+ * @private
658
+ * @return {string}
659
+ */
660
+ function getTemplate() {
661
+ // language=HTML
662
+ return `
663
+ <template id="entries">
664
+ <div data-monster-role="entry"
665
+ draggable="true"
666
+ data-monster-attributes="
667
+ data-monster-intend path:entries.intend,
668
+ data-monster-state path:entries.state,
669
+ data-monster-visibility path:entries.visibility,
670
+ data-monster-filtered path:entries.filtered,
671
+ data-monster-has-children path:entries.has-children">
672
+
673
+ <button data-monster-role="button"
674
+ data-monster-attributes="
675
+ type path:type,
676
+ role path:role,
677
+ value path:entries.value,
678
+ name path:name,
679
+ part path:type | prefix:option- | suffix: form" tabindex="-1">
680
+ <span data-monster-role="folder-handler"></span>
681
+ <span data-monster-replace="path:entries | index:label" part="entry-label"></span>
682
+ </button>
683
+ </template>
684
+
685
+ <div data-monster-role="control" part="control">
686
+ <div part="entries" data-monster-role="entries"
687
+ data-monster-insert="entries path:entries"
688
+ tabindex="-1"></div>
689
+ </div>
690
+ `;
691
+ }
692
+
693
+ registerCustomElement(TreeMenu);