@schukai/monster 3.80.0 → 3.80.2
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.
- package/CHANGELOG.md +19 -0
- package/package.json +1 -1
- package/source/components/content/copy.mjs +1 -1
- package/source/components/layout/collapse.mjs +4 -4
- package/source/components/style/space.pcss +1 -1
- package/source/components/tree-menu/dragable-tree-menu.mjs +664 -664
- package/source/components/tree-menu/tree-menu.mjs +1 -24
- package/source/data/datasource/server/restapi/data-fetch-error.mjs +0 -1
- package/source/dom/customcontrol.mjs +0 -25
- package/source/dom/customelement.mjs +1 -9
- package/source/i18n/formatter.mjs +0 -2
- package/source/i18n/locale.mjs +0 -2
- package/source/i18n/provider.mjs +0 -2
- package/source/i18n/translations.mjs +0 -1
- package/source/logging/handler/console.mjs +0 -1
- package/source/logging/handler.mjs +0 -1
- package/source/logging/logger.mjs +2 -11
- package/source/monster.mjs +0 -1
- package/source/net/webconnect/message.mjs +0 -1
- package/source/types/base.mjs +1 -3
- package/source/types/basewithoptions.mjs +1 -2
- package/source/types/nodelist.mjs +0 -1
- package/source/types/noderecursiveiterator.mjs +1 -5
- package/source/types/observablequeue.mjs +0 -4
- package/source/types/observer.mjs +0 -3
- package/source/types/observerlist.mjs +0 -2
- package/source/types/proxyobserver.mjs +0 -2
- package/source/types/queue.mjs +0 -3
- package/source/types/randomid.mjs +0 -1
- package/source/types/regex.mjs +0 -1
- package/source/types/stack.mjs +1 -2
- package/source/types/tokenlist.mjs +0 -2
- package/source/types/typeof.mjs +0 -2
- package/source/types/uniquequeue.mjs +0 -1
- package/source/types/uuid.mjs +1 -2
- package/source/types/version.mjs +2 -5
- package/source/util/processing/callback.mjs +56 -0
- package/source/util/processing.mjs +2 -40
- package/test/web/test.html +1 -1
|
@@ -11,683 +11,683 @@
|
|
|
11
11
|
*
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
|
13
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
} from "../../dom/constants.mjs";
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
+
//
|
|
607
49
|
// /**
|
|
608
50
|
// * @private
|
|
609
|
-
// * @
|
|
610
|
-
//
|
|
611
|
-
//
|
|
612
|
-
//
|
|
613
|
-
//
|
|
614
|
-
// * @
|
|
615
|
-
// * @
|
|
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
|
|
616
131
|
// * @fires Monster.Components.TreeMenu.event:monster-fetched
|
|
617
132
|
// */
|
|
618
|
-
//
|
|
619
|
-
//
|
|
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
|
+
// },
|
|
620
186
|
//
|
|
621
|
-
//
|
|
622
|
-
//
|
|
623
|
-
//
|
|
187
|
+
// data: [],
|
|
188
|
+
// },
|
|
189
|
+
// initOptionsFromArguments.call(this),
|
|
190
|
+
// );
|
|
191
|
+
// }
|
|
624
192
|
//
|
|
625
|
-
//
|
|
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);
|
|
626
251
|
//
|
|
627
|
-
//
|
|
628
|
-
// threshold: [0.5]
|
|
629
|
-
// }
|
|
252
|
+
// const selector = this.getOption("datasource.selector");
|
|
630
253
|
//
|
|
631
|
-
//
|
|
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
|
+
// }
|
|
632
259
|
//
|
|
633
|
-
//
|
|
634
|
-
//
|
|
635
|
-
//
|
|
636
|
-
// observer.disconnect();
|
|
637
|
-
// }
|
|
260
|
+
// if (!(element instanceof Datasource)) {
|
|
261
|
+
// throw new TypeError("the element must be a datasource");
|
|
262
|
+
// }
|
|
638
263
|
//
|
|
639
|
-
//
|
|
640
|
-
//
|
|
641
|
-
//
|
|
642
|
-
//
|
|
643
|
-
//
|
|
264
|
+
// this[datasourceLinkedElementSymbol] = element;
|
|
265
|
+
// element.datasource.attachObserver(
|
|
266
|
+
// new Observer(handleDataSourceChanges.bind(this)),
|
|
267
|
+
// );
|
|
268
|
+
// }
|
|
644
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
|
+
// }
|
|
645
279
|
//
|
|
646
|
-
//
|
|
647
|
-
//
|
|
648
|
-
//
|
|
280
|
+
// //let container = findClosestByAttribute(element, ATTRIBUTE_ROLE, 'option');
|
|
281
|
+
// const index = container
|
|
282
|
+
// .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
|
|
283
|
+
// .split("-")
|
|
284
|
+
// .pop();
|
|
649
285
|
//
|
|
650
|
-
//
|
|
651
|
-
// observer.observe(self);
|
|
286
|
+
// const currentState = this.getOption("data." + index + ".state");
|
|
652
287
|
//
|
|
288
|
+
// const newState = currentState === "close" ? "open" : "close";
|
|
289
|
+
// this.setOption("data." + index + ".state", newState);
|
|
653
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;
|
|
654
349
|
// }
|
|
655
|
-
|
|
656
|
-
/**
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
function
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
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);
|