@schukai/monster 3.53.0 → 3.55.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.
- package/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/source/components/datatable/datasource/rest.mjs +358 -309
- package/source/components/datatable/datatable/header.mjs +8 -0
- package/source/components/datatable/datatable.mjs +606 -557
- package/source/components/datatable/embedded-pagination.mjs +50 -62
- package/source/components/datatable/filter/util.mjs +122 -0
- package/source/components/datatable/filter.mjs +893 -708
- package/source/components/datatable/pagination.mjs +335 -310
- package/source/components/datatable/status.mjs +248 -0
- package/source/components/datatable/style/datatable.pcss +1 -0
- package/source/components/datatable/style/embedded-pagination.pcss +59 -2
- package/source/components/datatable/style/filter.pcss +4 -0
- package/source/components/datatable/style/pagination.pcss +28 -4
- package/source/components/datatable/style/status.pcss +42 -0
- package/source/components/datatable/stylesheet/column-bar.mjs +1 -1
- package/source/components/datatable/stylesheet/datatable.mjs +1 -1
- package/source/components/datatable/stylesheet/filter-button.mjs +1 -1
- package/source/components/datatable/stylesheet/filter.mjs +1 -1
- package/source/components/datatable/stylesheet/pagination.mjs +1 -1
- package/source/components/datatable/stylesheet/status.mjs +27 -0
- package/source/components/form/action-button.mjs +1 -1
- package/source/components/form/api-button.mjs +1 -1
- package/source/components/form/button-bar.mjs +1 -1
- package/source/components/form/button.mjs +1 -1
- package/source/components/form/confirm-button.mjs +1 -1
- package/source/components/form/context-error.mjs +275 -0
- package/source/components/form/context-help.mjs +5 -5
- package/source/components/form/form.mjs +2 -2
- package/source/components/form/message-state-button.mjs +2 -2
- package/source/components/form/popper-button.mjs +7 -4
- package/source/components/form/popper.mjs +317 -309
- package/source/components/form/reload.mjs +1 -1
- package/source/components/form/select.mjs +9 -3
- package/source/components/form/shadow-reload.mjs +1 -1
- package/source/components/form/state-button.mjs +2 -1
- package/source/components/form/style/context-error.pcss +32 -0
- package/source/components/form/style/context-help.pcss +22 -5
- package/source/components/form/stylesheet/context-error.mjs +27 -0
- package/source/components/form/stylesheet/context-help.mjs +1 -1
- package/source/components/form/stylesheet/select.mjs +1 -1
- package/source/components/form/stylesheet/tabs.mjs +1 -1
- package/source/components/form/tabs.mjs +757 -707
- package/source/components/form/template.mjs +1 -1
- package/source/components/form/tree-select.mjs +1 -1
- package/source/components/host/collapse.mjs +22 -5
- package/source/components/host/config-manager.mjs +39 -2
- package/source/components/host/host.mjs +14 -0
- package/source/components/host/stylesheet/call-button.mjs +1 -1
- package/source/components/host/stylesheet/overlay.mjs +1 -1
- package/source/components/host/stylesheet/toggle-button.mjs +1 -1
- package/source/components/host/util.mjs +6 -1
- package/source/components/notify/stylesheet/message.mjs +1 -1
- package/source/components/stylesheet/icons.mjs +1 -1
- package/source/data/transformer.mjs +39 -42
- package/source/dom/customelement.mjs +1 -1
- package/source/dom/updater.mjs +700 -688
- package/source/dom/util.mjs +42 -0
- package/source/i18n/providers/embed.mjs +3 -3
- package/source/monster.mjs +6 -0
- package/source/text/formatter.mjs +2 -2
- package/source/types/observer.mjs +1 -1
- package/source/types/version.mjs +1 -1
- package/source/util/sleep.mjs +18 -0
- package/test/cases/components/form/button.mjs +2 -1
- package/test/cases/components/form/select.mjs +1 -1
- package/test/cases/components/form/tree-select.mjs +1 -1
- package/test/cases/data/transformer.mjs +2 -2
- package/test/cases/dom/updater.mjs +67 -46
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +18 -13
|
@@ -4,51 +4,52 @@
|
|
|
4
4
|
* This file is licensed under the AGPLv3 License.
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import {instanceSymbol} from "../../constants.mjs";
|
|
8
|
+
import {createPopper} from "@popperjs/core";
|
|
9
|
+
import {extend} from "../../data/extend.mjs";
|
|
10
|
+
import {Pathfinder} from "../../data/pathfinder.mjs";
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
addAttributeToken,
|
|
13
|
+
addToObjectLink,
|
|
14
|
+
hasObjectLink,
|
|
15
15
|
} from "../../dom/attributes.mjs";
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
ATTRIBUTE_ERRORMESSAGE,
|
|
18
|
+
ATTRIBUTE_PREFIX,
|
|
19
|
+
ATTRIBUTE_ROLE,
|
|
20
20
|
} from "../../dom/constants.mjs";
|
|
21
21
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
assembleMethodSymbol,
|
|
23
|
+
CustomElement,
|
|
24
|
+
getSlottedElements,
|
|
25
|
+
registerCustomElement,
|
|
26
26
|
} from "../../dom/customelement.mjs";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
27
|
+
import {findTargetElementFromEvent, fireCustomEvent} from "../../dom/events.mjs";
|
|
28
|
+
import {getDocument} from "../../dom/util.mjs";
|
|
29
|
+
import {random} from "../../math/random.mjs";
|
|
30
|
+
import {getGlobal} from "../../types/global.mjs";
|
|
31
|
+
import {ID} from "../../types/id.mjs";
|
|
32
|
+
import {isArray, isString} from "../../types/is.mjs";
|
|
33
|
+
import {TokenList} from "../../types/tokenlist.mjs";
|
|
34
|
+
import {clone} from "../../util/clone.mjs";
|
|
35
|
+
import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
|
|
36
|
+
import {Processing} from "../../util/processing.mjs";
|
|
37
37
|
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
ATTRIBUTE_BUTTON_LABEL,
|
|
39
|
+
ATTRIBUTE_FORM_RELOAD,
|
|
40
|
+
ATTRIBUTE_FORM_URL,
|
|
41
|
+
STYLE_DISPLAY_MODE_BLOCK,
|
|
42
42
|
} from "./constants.mjs";
|
|
43
43
|
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
44
|
+
import {TabsStyleSheet} from "./stylesheet/tabs.mjs";
|
|
45
|
+
import {loadAndAssignContent} from "./util/fetch.mjs";
|
|
46
|
+
import {ThemeStyleSheet} from "../stylesheet/theme.mjs";
|
|
46
47
|
import {
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
popperInstanceSymbol,
|
|
49
|
+
setEventListenersModifiers,
|
|
49
50
|
} from "./util/popper.mjs";
|
|
50
51
|
|
|
51
|
-
export {
|
|
52
|
+
export {Tabs};
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
55
|
* @private
|
|
@@ -168,283 +169,289 @@ const resizeObserverSymbol = Symbol("resizeObserver");
|
|
|
168
169
|
* @fires Monster.Components.Form.event:monster-fetched
|
|
169
170
|
*/
|
|
170
171
|
class Tabs extends CustomElement {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
172
|
+
/**
|
|
173
|
+
* This method is called by the `instanceof` operator.
|
|
174
|
+
* @returns {symbol}
|
|
175
|
+
* @since 2.1.0
|
|
176
|
+
*/
|
|
177
|
+
static get [instanceSymbol]() {
|
|
178
|
+
return Symbol.for("@schukai/monster/components/form/tabs");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* To set the options via the html tag the attribute `data-monster-options` must be used.
|
|
183
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
184
|
+
*
|
|
185
|
+
* The individual configuration values can be found in the table.
|
|
186
|
+
*
|
|
187
|
+
* @property {Object} templates Template definitions
|
|
188
|
+
* @property {string} templates.main Main template
|
|
189
|
+
* @property {Object} labels
|
|
190
|
+
* @property {string} labels.new-tab-label="New Tab"
|
|
191
|
+
* @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
|
|
192
|
+
* @property {String} fetch.redirect=error
|
|
193
|
+
* @property {String} fetch.method=GET
|
|
194
|
+
* @property {String} fetch.mode=same-origin
|
|
195
|
+
* @property {String} fetch.credentials=same-origin
|
|
196
|
+
* @property {Object} fetch.headers={"accept":"text/html"}}
|
|
197
|
+
* @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
|
|
198
|
+
* @property {string} popper.placement=bottom PopperJS placement
|
|
199
|
+
* @property {Object[]} modifiers={name:offset} PopperJS placement
|
|
200
|
+
*/
|
|
201
|
+
get defaults() {
|
|
202
|
+
return Object.assign({}, super.defaults, {
|
|
203
|
+
templates: {
|
|
204
|
+
main: getTemplate(),
|
|
205
|
+
},
|
|
206
|
+
labels: {
|
|
207
|
+
"new-tab-label": "New Tab",
|
|
208
|
+
},
|
|
209
|
+
buttons: {
|
|
210
|
+
standard: [],
|
|
211
|
+
popper: [],
|
|
212
|
+
},
|
|
213
|
+
fetch: {
|
|
214
|
+
redirect: "error",
|
|
215
|
+
method: "GET",
|
|
216
|
+
mode: "same-origin",
|
|
217
|
+
credentials: "same-origin",
|
|
218
|
+
headers: {
|
|
219
|
+
accept: "text/html",
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
classes: {
|
|
224
|
+
button: "monster-theme-primary-1",
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
popper: {
|
|
228
|
+
placement: "bottom",
|
|
229
|
+
modifiers: [
|
|
230
|
+
{
|
|
231
|
+
name: "offset",
|
|
232
|
+
options: {
|
|
233
|
+
offset: [0, 2],
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
{
|
|
238
|
+
name: "eventListeners",
|
|
239
|
+
enabled: false,
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* This method is called internal and should not be called directly.
|
|
248
|
+
*/
|
|
249
|
+
[assembleMethodSymbol]() {
|
|
250
|
+
super[assembleMethodSymbol]();
|
|
251
|
+
|
|
252
|
+
initControlReferences.call(this);
|
|
253
|
+
|
|
254
|
+
this[dimensionsSymbol] = new Pathfinder({data: {}});
|
|
255
|
+
|
|
256
|
+
initEventHandler.call(this);
|
|
257
|
+
|
|
258
|
+
// setup structure
|
|
259
|
+
initTabButtons.call(this).then(() => {
|
|
260
|
+
initPopperSwitch.call(this);
|
|
261
|
+
initPopper.call(this);
|
|
262
|
+
attachResizeObserver.call(this);
|
|
263
|
+
attachTabChangeObserver.call(this);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* This method is called internal and should not be called directly.
|
|
269
|
+
*
|
|
270
|
+
* @return {CSSStyleSheet[]}
|
|
271
|
+
*/
|
|
272
|
+
static getCSSStyleSheet() {
|
|
273
|
+
return [TabsStyleSheet, ThemeStyleSheet];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* This method is called internal and should not be called directly.
|
|
278
|
+
*
|
|
279
|
+
* @return {string}
|
|
280
|
+
*/
|
|
281
|
+
static getTag() {
|
|
282
|
+
return "monster-tabs";
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* This method is called by the dom and should not be called directly.
|
|
287
|
+
*
|
|
288
|
+
* @return {void}
|
|
289
|
+
*/
|
|
290
|
+
connectedCallback() {
|
|
291
|
+
super.connectedCallback();
|
|
292
|
+
|
|
293
|
+
const document = getDocument();
|
|
294
|
+
|
|
295
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
296
|
+
// close on outside ui-events
|
|
297
|
+
document.addEventListener(type, this[closeEventHandler]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* This method is called by the dom and should not be called directly.
|
|
303
|
+
*
|
|
304
|
+
* @return {void}
|
|
305
|
+
*/
|
|
306
|
+
disconnectedCallback() {
|
|
307
|
+
super.disconnectedCallback();
|
|
308
|
+
|
|
309
|
+
const document = getDocument();
|
|
310
|
+
|
|
311
|
+
// close on outside ui-events
|
|
312
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
313
|
+
document.removeEventListener(type, this[closeEventHandler]);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
310
316
|
}
|
|
311
317
|
|
|
312
318
|
/**
|
|
313
319
|
* @private
|
|
314
320
|
*/
|
|
315
321
|
function initPopperSwitch() {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
322
|
+
const nodes = getSlottedElements.call(this, `[${ATTRIBUTE_ROLE}="switch"]`); // null ↦ only unnamed slots
|
|
323
|
+
let switchButton;
|
|
324
|
+
if (nodes.size === 0) {
|
|
325
|
+
switchButton = document.createElement("button");
|
|
326
|
+
switchButton.setAttribute(ATTRIBUTE_ROLE, "switch");
|
|
327
|
+
switchButton.setAttribute("part", "switch");
|
|
328
|
+
switchButton.classList.add("hidden");
|
|
329
|
+
switchButton.innerHTML =
|
|
330
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/></svg>';
|
|
331
|
+
this[navElementSymbol].prepend(switchButton);
|
|
332
|
+
} else {
|
|
333
|
+
switchButton = nodes.next();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* @param {Event} event
|
|
338
|
+
*/
|
|
339
|
+
this[popperSwitchEventHandler] = (event) => {
|
|
340
|
+
const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "switch");
|
|
341
|
+
|
|
342
|
+
if (element instanceof HTMLButtonElement) {
|
|
343
|
+
togglePopper.call(this);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
for (const type of ["click", "touch"]) {
|
|
348
|
+
switchButton.addEventListener(type, this[popperSwitchEventHandler]);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
this[switchElementSymbol] = switchButton;
|
|
346
352
|
}
|
|
347
353
|
|
|
348
354
|
/**
|
|
349
355
|
* @private
|
|
350
356
|
*/
|
|
351
357
|
function hidePopper() {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
358
|
+
if (!this[popperInstanceSymbol]) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
355
361
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
362
|
+
this[popperElementSymbol].style.display = "none";
|
|
363
|
+
// performance https://popper.js.org/docs/v2/tutorial/#performance
|
|
364
|
+
setEventListenersModifiers.call(this, false);
|
|
359
365
|
}
|
|
360
366
|
|
|
361
367
|
/**
|
|
362
368
|
* @private
|
|
363
369
|
*/
|
|
364
370
|
function showPopper() {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
371
|
+
if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
this[popperElementSymbol].style.visibility = "hidden";
|
|
376
|
+
this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
|
|
377
|
+
// performance https://popper.js.org/docs/v2/tutorial/#performance
|
|
378
|
+
setEventListenersModifiers.call(this, true);
|
|
379
|
+
|
|
380
|
+
this[popperInstanceSymbol].update();
|
|
381
|
+
|
|
382
|
+
new Processing(() => {
|
|
383
|
+
this[popperElementSymbol].style.removeProperty("visibility");
|
|
384
|
+
})
|
|
385
|
+
.run(undefined)
|
|
386
|
+
.then(() => {
|
|
387
|
+
})
|
|
388
|
+
.catch((e) => {
|
|
389
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
|
|
390
|
+
});
|
|
384
391
|
}
|
|
385
392
|
|
|
386
393
|
/**
|
|
387
394
|
* @private
|
|
388
395
|
*/
|
|
389
396
|
function togglePopper() {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
|
|
398
|
+
hidePopper.call(this);
|
|
399
|
+
} else {
|
|
400
|
+
showPopper.call(this);
|
|
401
|
+
}
|
|
395
402
|
}
|
|
396
403
|
|
|
397
404
|
/**
|
|
398
405
|
* @private
|
|
399
406
|
*/
|
|
400
407
|
function attachResizeObserver() {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
408
|
+
// against flickering
|
|
409
|
+
this[resizeObserverSymbol] = new ResizeObserver((entries) => {
|
|
410
|
+
if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
|
|
411
|
+
try {
|
|
412
|
+
this[timerCallbackSymbol].touch();
|
|
413
|
+
return;
|
|
414
|
+
} catch (e) {
|
|
415
|
+
delete this[timerCallbackSymbol];
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
|
|
420
|
+
this[dimensionsSymbol].setVia("data.calculated", false);
|
|
421
|
+
checkAndRearrangeButtons.call(this);
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
this[resizeObserverSymbol].observe(this[navElementSymbol]);
|
|
419
426
|
}
|
|
420
427
|
|
|
421
428
|
/**
|
|
422
429
|
* @private
|
|
423
430
|
*/
|
|
424
431
|
function attachTabChangeObserver() {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
432
|
+
// against flickering
|
|
433
|
+
new MutationObserver((mutations) => {
|
|
434
|
+
let runUpdate = false;
|
|
435
|
+
|
|
436
|
+
for (const mutation of mutations) {
|
|
437
|
+
if (mutation.type === "childList") {
|
|
438
|
+
if (
|
|
439
|
+
mutation.addedNodes.length > 0 ||
|
|
440
|
+
mutation.removedNodes.length > 0
|
|
441
|
+
) {
|
|
442
|
+
runUpdate = true;
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (runUpdate === true) {
|
|
449
|
+
this[dimensionsSymbol].setVia("data.calculated", false);
|
|
450
|
+
initTabButtons.call(this);
|
|
451
|
+
}
|
|
452
|
+
}).observe(this, {
|
|
453
|
+
childList: true,
|
|
454
|
+
});
|
|
448
455
|
}
|
|
449
456
|
|
|
450
457
|
/**
|
|
@@ -454,42 +461,42 @@ function attachTabChangeObserver() {
|
|
|
454
461
|
* @see {@link Plugins}
|
|
455
462
|
*/
|
|
456
463
|
function initPopper() {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
464
|
+
const self = this;
|
|
465
|
+
|
|
466
|
+
const options = extend({}, self.getOption("popper"));
|
|
467
|
+
|
|
468
|
+
self[popperInstanceSymbol] = createPopper(
|
|
469
|
+
self[switchElementSymbol],
|
|
470
|
+
self[popperElementSymbol],
|
|
471
|
+
options,
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
const observer1 = new MutationObserver(function (mutations) {
|
|
475
|
+
let runUpdate = false;
|
|
476
|
+
|
|
477
|
+
for (const mutation of mutations) {
|
|
478
|
+
if (mutation.type === "childList") {
|
|
479
|
+
if (
|
|
480
|
+
mutation.addedNodes.length > 0 ||
|
|
481
|
+
mutation.removedNodes.length > 0
|
|
482
|
+
) {
|
|
483
|
+
runUpdate = true;
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (runUpdate === true) {
|
|
490
|
+
self[popperInstanceSymbol].update();
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
observer1.observe(self[popperNavElementSymbol], {
|
|
495
|
+
childList: true,
|
|
496
|
+
subtree: true,
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
return self;
|
|
493
500
|
}
|
|
494
501
|
|
|
495
502
|
/**
|
|
@@ -497,132 +504,173 @@ function initPopper() {
|
|
|
497
504
|
* @param {HTMLElement} element
|
|
498
505
|
*/
|
|
499
506
|
function show(element) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
507
|
+
const self = this;
|
|
508
|
+
if (!this.shadowRoot) {
|
|
509
|
+
throw new Error("no shadow-root is defined");
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const reference = element.getAttribute(`${ATTRIBUTE_PREFIX}tab-reference`);
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
const nodes = getSlottedElements.call(this);
|
|
518
|
+
for (const node of nodes) {
|
|
519
|
+
const id = node.getAttribute("id");
|
|
520
|
+
|
|
521
|
+
if (id === reference) {
|
|
522
|
+
node.classList.add("active");
|
|
523
|
+
|
|
524
|
+
// get all data- from button and filter out data-monster-attributes and data-monster-insert
|
|
525
|
+
const data = {};
|
|
526
|
+
const mask = ["data-monster-attributes",
|
|
527
|
+
"data-monster-insert-reference",
|
|
528
|
+
"data-monster-state",
|
|
529
|
+
"data-monster-button-label",
|
|
530
|
+
"data-monster-objectlink",
|
|
531
|
+
"data-monster-role"];
|
|
532
|
+
|
|
533
|
+
for (const [, attr] of Object.entries(node.attributes)) {
|
|
534
|
+
if (attr.name.startsWith("data-") && mask.indexOf(attr.name) === -1) {
|
|
535
|
+
data[attr.name] = attr.value;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (node.hasAttribute(ATTRIBUTE_FORM_URL)) {
|
|
540
|
+
const url = node.getAttribute(ATTRIBUTE_FORM_URL);
|
|
541
|
+
|
|
542
|
+
if (
|
|
543
|
+
!node.hasAttribute(ATTRIBUTE_FORM_RELOAD) ||
|
|
544
|
+
node.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase() === "onshow"
|
|
545
|
+
) {
|
|
546
|
+
node.removeAttribute(ATTRIBUTE_FORM_URL);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const options = this.getOption("fetch", {});
|
|
550
|
+
const filter = undefined;
|
|
551
|
+
loadAndAssignContent(node, url, options, filter)
|
|
552
|
+
.then(() => {
|
|
553
|
+
fireCustomEvent(self, "monster-tab-changed", {
|
|
554
|
+
reference,
|
|
555
|
+
});
|
|
556
|
+
})
|
|
557
|
+
.catch((e) => {
|
|
558
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
|
|
559
|
+
});
|
|
560
|
+
} else {
|
|
561
|
+
fireCustomEvent(self, "monster-tab-changed", {
|
|
562
|
+
reference,
|
|
563
|
+
data
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
} else {
|
|
567
|
+
node.classList.remove("active");
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const standardButtons = this.getOption("buttons.standard");
|
|
572
|
+
for (const index in standardButtons) {
|
|
573
|
+
const button = standardButtons[index];
|
|
574
|
+
const state = button["reference"] === reference ? "active" : "inactive";
|
|
575
|
+
this.setOption(`buttons.standard.${index}.state`, state);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const popperButton = this.getOption("buttons.popper");
|
|
579
|
+
for (const index in popperButton) {
|
|
580
|
+
const button = popperButton[index];
|
|
581
|
+
const state = button["reference"] === reference ? "active" : "inactive";
|
|
582
|
+
this.setOption(`buttons.popper.${index}.state`, state);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
hidePopper.call(this);
|
|
551
586
|
}
|
|
552
587
|
|
|
553
588
|
/**
|
|
554
589
|
* @private
|
|
555
590
|
*/
|
|
556
591
|
function initEventHandler() {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
592
|
+
|
|
593
|
+
const self=this;
|
|
594
|
+
|
|
595
|
+
if (!this.shadowRoot) {
|
|
596
|
+
throw new Error("no shadow-root is defined");
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* @param {Event} event
|
|
601
|
+
*/
|
|
602
|
+
this[changeTabEventHandler] = (event) => {
|
|
603
|
+
const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "button");
|
|
604
|
+
|
|
605
|
+
if (element instanceof HTMLButtonElement && element.disabled !== true) {
|
|
606
|
+
show.call(this, element);
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* event:monster-tab-remove
|
|
612
|
+
* @event Monster.Components.Form.event:monster-tab-remove
|
|
613
|
+
*/
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* @param {Event} event
|
|
617
|
+
* @fires Monster.Components.Form.event:monster-tab-remove
|
|
618
|
+
*/
|
|
619
|
+
this[removeTabEventHandler] = (event) => {
|
|
620
|
+
|
|
621
|
+
const element = findTargetElementFromEvent(
|
|
622
|
+
event,
|
|
623
|
+
ATTRIBUTE_ROLE,
|
|
624
|
+
"remove-tab",
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
if (element instanceof HTMLElement) {
|
|
628
|
+
const button = findTargetElementFromEvent(
|
|
629
|
+
event,
|
|
630
|
+
ATTRIBUTE_ROLE,
|
|
631
|
+
"button",
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
if (button instanceof HTMLButtonElement && button.disabled !== true) {
|
|
635
|
+
const reference = button.getAttribute(
|
|
636
|
+
`${ATTRIBUTE_PREFIX}tab-reference`,
|
|
637
|
+
);
|
|
638
|
+
if (reference) {
|
|
639
|
+
const container = this.querySelector(`[id=${reference}]`);
|
|
640
|
+
if (container instanceof HTMLElement) {
|
|
641
|
+
container.remove();
|
|
642
|
+
initTabButtons.call(this);
|
|
643
|
+
fireCustomEvent(self, "monster-tab-remove", {
|
|
644
|
+
reference,
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
this[navElementSymbol].addEventListener("touch", this[changeTabEventHandler]);
|
|
653
|
+
this[navElementSymbol].addEventListener("click", this[changeTabEventHandler]);
|
|
654
|
+
|
|
655
|
+
this[navElementSymbol].addEventListener("touch", this[removeTabEventHandler]);
|
|
656
|
+
this[navElementSymbol].addEventListener("click", this[removeTabEventHandler]);
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* @param {Event} event
|
|
660
|
+
*/
|
|
661
|
+
this[closeEventHandler] = (event) => {
|
|
662
|
+
const path = event.composedPath();
|
|
663
|
+
|
|
664
|
+
for (const [, element] of Object.entries(path)) {
|
|
665
|
+
if (element === this) {
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
hidePopper.call(this);
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
return this;
|
|
626
674
|
}
|
|
627
675
|
|
|
628
676
|
/**
|
|
@@ -630,37 +678,37 @@ function initEventHandler() {
|
|
|
630
678
|
* @param observedNode
|
|
631
679
|
*/
|
|
632
680
|
function attachTabMutationObserver(observedNode) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
681
|
+
const self = this;
|
|
682
|
+
|
|
683
|
+
if (hasObjectLink(observedNode, mutationObserverSymbol)) {
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* this construct monitors a node whether it is disabled or modified
|
|
689
|
+
* @type {MutationObserver}
|
|
690
|
+
*/
|
|
691
|
+
const observer = new MutationObserver(function (mutations) {
|
|
692
|
+
if (isArray(mutations)) {
|
|
693
|
+
const mutation = mutations.pop();
|
|
694
|
+
if (mutation instanceof MutationRecord) {
|
|
695
|
+
initTabButtons.call(self);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
observer.observe(observedNode, {
|
|
701
|
+
childList: false,
|
|
702
|
+
attributes: true,
|
|
703
|
+
subtree: false,
|
|
704
|
+
attributeFilter: [
|
|
705
|
+
"disabled",
|
|
706
|
+
ATTRIBUTE_BUTTON_LABEL,
|
|
707
|
+
`${ATTRIBUTE_PREFIX}button-icon`,
|
|
708
|
+
],
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
addToObjectLink(observedNode, mutationObserverSymbol, observer);
|
|
664
712
|
}
|
|
665
713
|
|
|
666
714
|
/**
|
|
@@ -669,22 +717,22 @@ function attachTabMutationObserver(observedNode) {
|
|
|
669
717
|
* @throws {Error} no shadow-root is defined
|
|
670
718
|
*/
|
|
671
719
|
function initControlReferences() {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
720
|
+
if (!this.shadowRoot) {
|
|
721
|
+
throw new Error("no shadow-root is defined");
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
this[controlElementSymbol] = this.shadowRoot.querySelector(
|
|
725
|
+
`[${ATTRIBUTE_ROLE}=control]`,
|
|
726
|
+
);
|
|
727
|
+
this[navElementSymbol] = this.shadowRoot.querySelector(
|
|
728
|
+
`nav[${ATTRIBUTE_ROLE}=nav]`,
|
|
729
|
+
);
|
|
730
|
+
this[popperElementSymbol] = this.shadowRoot.querySelector(
|
|
731
|
+
`[${ATTRIBUTE_ROLE}=popper]`,
|
|
732
|
+
);
|
|
733
|
+
this[popperNavElementSymbol] = this.shadowRoot.querySelector(
|
|
734
|
+
`[${ATTRIBUTE_ROLE}=popper-nav]`,
|
|
735
|
+
);
|
|
688
736
|
}
|
|
689
737
|
|
|
690
738
|
/**
|
|
@@ -694,101 +742,102 @@ function initControlReferences() {
|
|
|
694
742
|
*
|
|
695
743
|
*/
|
|
696
744
|
function initTabButtons() {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
745
|
+
if (!this.shadowRoot) {
|
|
746
|
+
throw new Error("no shadow-root is defined");
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
let activeReference;
|
|
750
|
+
|
|
751
|
+
const dimensionsCalculated = this[dimensionsSymbol].getVia(
|
|
752
|
+
"data.calculated",
|
|
753
|
+
false,
|
|
754
|
+
);
|
|
755
|
+
|
|
756
|
+
const buttons = [];
|
|
757
|
+
const nodes = getSlottedElements.call(this, undefined, null); // null ↦ only unnamed slots
|
|
758
|
+
|
|
759
|
+
for (const node of nodes) {
|
|
760
|
+
if (!(node instanceof HTMLElement)) continue;
|
|
761
|
+
let label = getButtonLabel.call(this, node);
|
|
762
|
+
|
|
763
|
+
let reference;
|
|
764
|
+
if (node.hasAttribute("id")) {
|
|
765
|
+
reference = node.getAttribute("id");
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
let disabled;
|
|
769
|
+
if (node.hasAttribute("disabled") || node.disabled === true) {
|
|
770
|
+
disabled = true;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if (!reference) {
|
|
774
|
+
reference = new ID("tab").toString();
|
|
775
|
+
node.setAttribute("id", reference);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
if (node.hasAttribute(`${ATTRIBUTE_PREFIX}button-icon`)) {
|
|
779
|
+
label = `<span part="label">${label}</span><img part="icon" src="${node.getAttribute(
|
|
780
|
+
`${ATTRIBUTE_PREFIX}button-icon`,
|
|
781
|
+
)}">`;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
let remove = false;
|
|
785
|
+
if (node.hasAttribute(`${ATTRIBUTE_PREFIX}removable`)) {
|
|
786
|
+
remove = true;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
if (node.matches(".active") === true && disabled !== true) {
|
|
790
|
+
node.classList.remove("active");
|
|
791
|
+
activeReference = reference;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const state = "";
|
|
795
|
+
const classes = dimensionsCalculated ? "" : "invisible";
|
|
796
|
+
|
|
797
|
+
buttons.push({
|
|
798
|
+
reference,
|
|
799
|
+
label,
|
|
800
|
+
state,
|
|
801
|
+
class: classes,
|
|
802
|
+
disabled,
|
|
803
|
+
remove,
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
attachTabMutationObserver.call(this, node);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
this.setOption("buttons.standard", clone(buttons));
|
|
810
|
+
this.setOption("buttons.popper", []);
|
|
811
|
+
this.setOption("marker", random());
|
|
812
|
+
|
|
813
|
+
return adjustButtonVisibility.call(this).then(() => {
|
|
814
|
+
if (activeReference) {
|
|
815
|
+
return new Processing(() => {
|
|
816
|
+
const button = this.shadowRoot.querySelector(
|
|
817
|
+
`[${ATTRIBUTE_PREFIX}tab-reference="${activeReference}"]`,
|
|
818
|
+
);
|
|
819
|
+
if (button instanceof HTMLButtonElement && button.disabled !== true) {
|
|
820
|
+
show.call(this, button);
|
|
821
|
+
}
|
|
822
|
+
})
|
|
823
|
+
.run(undefined)
|
|
824
|
+
.then(() => {
|
|
825
|
+
})
|
|
826
|
+
.catch((e) => {
|
|
827
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
return Promise.resolve();
|
|
832
|
+
});
|
|
784
833
|
}
|
|
785
834
|
|
|
786
835
|
function checkAndRearrangeButtons() {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
836
|
+
if (this[dimensionsSymbol].getVia("data.calculated", false) !== true) {
|
|
837
|
+
calculateNavigationButtonsDimensions.call(this);
|
|
838
|
+
}
|
|
790
839
|
|
|
791
|
-
|
|
840
|
+
rearrangeButtons.call(this);
|
|
792
841
|
}
|
|
793
842
|
|
|
794
843
|
/**
|
|
@@ -796,29 +845,29 @@ function checkAndRearrangeButtons() {
|
|
|
796
845
|
* @return {Promise<unknown>}
|
|
797
846
|
*/
|
|
798
847
|
function adjustButtonVisibility() {
|
|
799
|
-
|
|
848
|
+
const self = this;
|
|
800
849
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
850
|
+
return new Promise((resolve) => {
|
|
851
|
+
const observer = new MutationObserver(function (mutations) {
|
|
852
|
+
const defCount = self.getOption("buttons.standard").length;
|
|
853
|
+
const domCount = self[navElementSymbol].querySelectorAll(
|
|
854
|
+
'button[data-monster-role="button"]',
|
|
855
|
+
).length;
|
|
807
856
|
|
|
808
|
-
|
|
809
|
-
|
|
857
|
+
// in drawing
|
|
858
|
+
if (defCount !== domCount) return;
|
|
810
859
|
|
|
811
|
-
|
|
860
|
+
observer.disconnect();
|
|
812
861
|
|
|
813
|
-
|
|
862
|
+
checkAndRearrangeButtons.call(self);
|
|
814
863
|
|
|
815
|
-
|
|
816
|
-
|
|
864
|
+
resolve();
|
|
865
|
+
});
|
|
817
866
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
867
|
+
observer.observe(self[navElementSymbol], {
|
|
868
|
+
attributes: true,
|
|
869
|
+
});
|
|
870
|
+
});
|
|
822
871
|
}
|
|
823
872
|
|
|
824
873
|
/**
|
|
@@ -827,17 +876,17 @@ function adjustButtonVisibility() {
|
|
|
827
876
|
* @return {number}
|
|
828
877
|
*/
|
|
829
878
|
function getDimValue(value) {
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
879
|
+
if ([undefined, null].indexOf(value) !== -1) {
|
|
880
|
+
return 0;
|
|
881
|
+
}
|
|
833
882
|
|
|
834
|
-
|
|
883
|
+
const valueAsInt = parseInt(value, 10);
|
|
835
884
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
885
|
+
if (isNaN(valueAsInt)) {
|
|
886
|
+
return 0;
|
|
887
|
+
}
|
|
839
888
|
|
|
840
|
-
|
|
889
|
+
return valueAsInt;
|
|
841
890
|
}
|
|
842
891
|
|
|
843
892
|
/**
|
|
@@ -846,18 +895,18 @@ function getDimValue(value) {
|
|
|
846
895
|
* @return {number}
|
|
847
896
|
*/
|
|
848
897
|
function calcBoxWidth(node) {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
898
|
+
const dim = getGlobal("window").getComputedStyle(node);
|
|
899
|
+
const bounding = node.getBoundingClientRect();
|
|
900
|
+
|
|
901
|
+
return (
|
|
902
|
+
getDimValue(dim["border-left-width"]) +
|
|
903
|
+
getDimValue(dim["padding-left"]) +
|
|
904
|
+
getDimValue(dim["margin-left"]) +
|
|
905
|
+
getDimValue(bounding["width"]) +
|
|
906
|
+
getDimValue(dim["border-right-width"]) +
|
|
907
|
+
getDimValue(dim["margin-right"]) +
|
|
908
|
+
getDimValue(dim["padding-left"])
|
|
909
|
+
);
|
|
861
910
|
}
|
|
862
911
|
|
|
863
912
|
/**
|
|
@@ -865,35 +914,35 @@ function calcBoxWidth(node) {
|
|
|
865
914
|
* @return {Object}
|
|
866
915
|
*/
|
|
867
916
|
function rearrangeButtons() {
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
917
|
+
const standardButtons = [];
|
|
918
|
+
const popperButtons = [];
|
|
919
|
+
|
|
920
|
+
let sum = 0;
|
|
921
|
+
const space = this[dimensionsSymbol].getVia("data.space");
|
|
922
|
+
|
|
923
|
+
const buttons = this.getOption("buttons.standard");
|
|
924
|
+
for (const [, button] of buttons.entries()) {
|
|
925
|
+
const ref = button?.reference;
|
|
926
|
+
|
|
927
|
+
sum += this[dimensionsSymbol].getVia(`data.button.${ref}`);
|
|
928
|
+
|
|
929
|
+
if (sum > space) {
|
|
930
|
+
popperButtons.push(clone(button));
|
|
931
|
+
} else {
|
|
932
|
+
standardButtons.push(clone(button));
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
this.setOption("buttons.standard", standardButtons);
|
|
937
|
+
this.setOption("buttons.popper", popperButtons);
|
|
938
|
+
|
|
939
|
+
if (this[switchElementSymbol]) {
|
|
940
|
+
if (popperButtons.length > 0) {
|
|
941
|
+
this[switchElementSymbol].classList.remove("hidden");
|
|
942
|
+
} else {
|
|
943
|
+
this[switchElementSymbol].classList.add("hidden");
|
|
944
|
+
}
|
|
945
|
+
}
|
|
897
946
|
}
|
|
898
947
|
|
|
899
948
|
/**
|
|
@@ -901,50 +950,50 @@ function rearrangeButtons() {
|
|
|
901
950
|
* @return {Object}
|
|
902
951
|
*/
|
|
903
952
|
function calculateNavigationButtonsDimensions() {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
953
|
+
const width = this[navElementSymbol].getBoundingClientRect().width;
|
|
954
|
+
|
|
955
|
+
let startEndWidth = 0;
|
|
956
|
+
|
|
957
|
+
getSlottedElements.call(this, undefined, "start").forEach((node) => {
|
|
958
|
+
startEndWidth += calcBoxWidth.call(this, node);
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
getSlottedElements.call(this, undefined, "end").forEach((node) => {
|
|
962
|
+
startEndWidth += calcBoxWidth.call(this, node);
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
this[dimensionsSymbol].setVia("data.space", width - startEndWidth - 2);
|
|
966
|
+
this[dimensionsSymbol].setVia("data.visible", !(width === 0));
|
|
967
|
+
|
|
968
|
+
const buttons = this.getOption("buttons.standard").concat(
|
|
969
|
+
this.getOption("buttons.popper"),
|
|
970
|
+
);
|
|
971
|
+
|
|
972
|
+
for (const [i, button] of buttons.entries()) {
|
|
973
|
+
const ref = button?.reference;
|
|
974
|
+
const element = this[navElementSymbol].querySelector(
|
|
975
|
+
`:scope > [${ATTRIBUTE_PREFIX}tab-reference="${ref}"]`,
|
|
976
|
+
);
|
|
977
|
+
if (!(element instanceof HTMLButtonElement)) continue;
|
|
978
|
+
|
|
979
|
+
this[dimensionsSymbol].setVia(
|
|
980
|
+
`data.button.${ref}`,
|
|
981
|
+
calcBoxWidth.call(this, element),
|
|
982
|
+
);
|
|
983
|
+
button["class"] = new TokenList(button["class"])
|
|
984
|
+
.remove("invisible")
|
|
985
|
+
.toString();
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
const slots = this[controlElementSymbol].querySelectorAll(
|
|
989
|
+
`nav[${ATTRIBUTE_PREFIX}role=nav] > slot.invisible, slot[${ATTRIBUTE_PREFIX}role=slot].invisible`,
|
|
990
|
+
);
|
|
991
|
+
for (const [, slot] of slots.entries()) {
|
|
992
|
+
slot.classList.remove("invisible");
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
this[dimensionsSymbol].setVia("data.calculated", true);
|
|
996
|
+
this.setOption("buttons.standard", clone(buttons));
|
|
948
997
|
}
|
|
949
998
|
|
|
950
999
|
/**
|
|
@@ -953,34 +1002,34 @@ function calculateNavigationButtonsDimensions() {
|
|
|
953
1002
|
* @return {string}
|
|
954
1003
|
*/
|
|
955
1004
|
function getButtonLabel(node) {
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1005
|
+
let label;
|
|
1006
|
+
let setLabel = false;
|
|
1007
|
+
if (node.hasAttribute(ATTRIBUTE_BUTTON_LABEL)) {
|
|
1008
|
+
label = node.getAttribute(ATTRIBUTE_BUTTON_LABEL);
|
|
1009
|
+
} else {
|
|
1010
|
+
label = node.innerText;
|
|
1011
|
+
setLabel = true;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
if (!isString(label)) {
|
|
1015
|
+
label = "";
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
label = label.trim();
|
|
1019
|
+
|
|
1020
|
+
if (label === "") {
|
|
1021
|
+
label = this.getOption("labels.new-tab-label", "New Tab");
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
if (label.length > 100) {
|
|
1025
|
+
label = `${label.substring(0, 99)}…`;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
if (setLabel === true) {
|
|
1029
|
+
node.setAttribute(ATTRIBUTE_BUTTON_LABEL, label);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
return label;
|
|
984
1033
|
}
|
|
985
1034
|
|
|
986
1035
|
/**
|
|
@@ -988,12 +1037,13 @@ function getButtonLabel(node) {
|
|
|
988
1037
|
* @return {string}
|
|
989
1038
|
*/
|
|
990
1039
|
function getTemplate() {
|
|
991
|
-
|
|
992
|
-
|
|
1040
|
+
// language=HTML
|
|
1041
|
+
return `
|
|
993
1042
|
<template id="buttons">
|
|
994
1043
|
<button part="button"
|
|
995
1044
|
data-monster-role="button"
|
|
996
1045
|
data-monster-attributes="
|
|
1046
|
+
class path:classes.button,
|
|
997
1047
|
data-monster-state path:buttons.state,
|
|
998
1048
|
disabled path:buttons.disabled | if:true,
|
|
999
1049
|
data-monster-tab-reference path:buttons.reference"><span
|