@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
@@ -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);