@schukai/monster 4.34.1 → 4.35.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.
@@ -17,24 +17,24 @@ import { createPopper } from "@popperjs/core";
17
17
  import { extend } from "../../data/extend.mjs";
18
18
  import { Pathfinder } from "../../data/pathfinder.mjs";
19
19
  import {
20
- addAttributeToken,
21
- addToObjectLink,
22
- hasObjectLink,
20
+ addAttributeToken,
21
+ addToObjectLink,
22
+ hasObjectLink,
23
23
  } from "../../dom/attributes.mjs";
24
24
  import {
25
- ATTRIBUTE_ERRORMESSAGE,
26
- ATTRIBUTE_PREFIX,
27
- ATTRIBUTE_ROLE,
25
+ ATTRIBUTE_ERRORMESSAGE,
26
+ ATTRIBUTE_PREFIX,
27
+ ATTRIBUTE_ROLE,
28
28
  } from "../../dom/constants.mjs";
29
29
  import {
30
- assembleMethodSymbol,
31
- CustomElement,
32
- getSlottedElements,
33
- registerCustomElement,
30
+ assembleMethodSymbol,
31
+ CustomElement,
32
+ getSlottedElements,
33
+ registerCustomElement,
34
34
  } from "../../dom/customelement.mjs";
35
35
  import {
36
- findTargetElementFromEvent,
37
- fireCustomEvent,
36
+ findTargetElementFromEvent,
37
+ fireCustomEvent,
38
38
  } from "../../dom/events.mjs";
39
39
  import { getDocument, getWindow } from "../../dom/util.mjs";
40
40
  import { random } from "../../math/random.mjs";
@@ -46,18 +46,18 @@ import { clone } from "../../util/clone.mjs";
46
46
  import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
47
47
  import { Processing } from "../../util/processing.mjs";
48
48
  import {
49
- ATTRIBUTE_BUTTON_LABEL,
50
- ATTRIBUTE_FORM_RELOAD,
51
- ATTRIBUTE_FORM_URL,
52
- STYLE_DISPLAY_MODE_BLOCK,
49
+ ATTRIBUTE_BUTTON_LABEL,
50
+ ATTRIBUTE_FORM_RELOAD,
51
+ ATTRIBUTE_FORM_URL,
52
+ STYLE_DISPLAY_MODE_BLOCK,
53
53
  } from "../form/constants.mjs";
54
54
 
55
55
  import { TabsStyleSheet } from "./stylesheet/tabs.mjs";
56
56
  import { loadAndAssignContent } from "../form/util/fetch.mjs";
57
57
  import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
58
58
  import {
59
- popperInstanceSymbol,
60
- setEventListenersModifiers,
59
+ popperInstanceSymbol,
60
+ setEventListenersModifiers,
61
61
  } from "../form/util/popper.mjs";
62
62
  import { getLocaleOfDocument } from "../../dom/locale.mjs";
63
63
 
@@ -161,315 +161,319 @@ const resizeObserverSymbol = Symbol("resizeObserver");
161
161
  * @summary This CustomControl creates a tab element with a variety of options.
162
162
  */
163
163
  class Tabs extends CustomElement {
164
- /**
165
- * This method is called by the `instanceof` operator.
166
- * @return {symbol}
167
- */
168
- static get [instanceSymbol]() {
169
- return Symbol.for("@schukai/monster/components/layout/tabs");
170
- }
171
-
172
- /**
173
- * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
174
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
175
- *
176
- * The individual configuration values can be found in the table.
177
- *
178
- * @property {Object} templates Template definitions
179
- * @property {string} templates.main Main template
180
- * @property {Object} labels
181
- * @property {string} labels.new-tab-label="New Tab"
182
- * @property {Object} features
183
- * @property {number} features.openDelay=500 Open delay in milliseconds
184
- * @property {string} features.removeBehavior="auto" Remove behavior, auto (default), next, previous and none
185
- * @property {boolean} features.openFirst=true Open the first tab
186
- * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
187
- * @property {String} fetch.redirect=error
188
- * @property {String} fetch.method=GET
189
- * @property {String} fetch.mode=same-origin
190
- * @property {String} fetch.credentials=same-origin
191
- * @property {Object} fetch.headers={"accept":"text/html"}}
192
- * @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
193
- * @property {string} popper.placement=bottom PopperJS placement
194
- * @property {Object[]} modifiers={name:offset} PopperJS placement
195
- */
196
- get defaults() {
197
- return Object.assign({}, super.defaults, {
198
- templates: {
199
- main: getTemplate(),
200
- },
201
- labels: getTranslations(),
202
- buttons: {
203
- standard: [],
204
- popper: [],
205
- },
206
- fetch: {
207
- redirect: "error",
208
- method: "GET",
209
- mode: "same-origin",
210
- credentials: "same-origin",
211
- headers: {
212
- accept: "text/html",
213
- },
214
- },
215
-
216
- features: {
217
- openDelay: null,
218
- removeBehavior: "auto",
219
- openFirst: true,
220
- },
221
-
222
- classes: {
223
- button: "monster-theme-primary-1",
224
- popper: "monster-theme-primary-1",
225
- navigation: "monster-theme-primary-1",
226
- },
227
-
228
- popper: {
229
- placement: "bottom",
230
- modifiers: [
231
- {
232
- name: "offset",
233
- options: {
234
- offset: [0, 2],
235
- },
236
- },
237
-
238
- {
239
- name: "eventListeners",
240
- enabled: false,
241
- },
242
- ],
243
- },
244
- });
245
- }
246
-
247
- /**
248
- * This method is called internal and should not be called directly.
249
- */
250
- [assembleMethodSymbol]() {
251
- super[assembleMethodSymbol]();
252
-
253
- initControlReferences.call(this);
254
-
255
- this[dimensionsSymbol] = new Pathfinder({ data: {} });
256
-
257
- initEventHandler.call(this);
258
-
259
- // setup structure
260
- initTabButtons.call(this).then(() => {
261
- initPopperSwitch.call(this);
262
- initPopper.call(this);
263
- attachResizeObserver.call(this);
264
- attachTabChangeObserver.call(this);
265
- });
266
- }
267
-
268
- /**
269
- * This method is called internal and should not be called directly.
270
- *
271
- * @return {CSSStyleSheet[]}
272
- */
273
- static getCSSStyleSheet() {
274
- return [TabsStyleSheet];
275
- }
276
-
277
- /**
278
- * This method is called internal and should not be called directly.
279
- *
280
- * @return {string}
281
- */
282
- static getTag() {
283
- return "monster-tabs";
284
- }
285
-
286
- /**
287
- * This method is called internal and should not be called directly.
288
- * @param tabId
289
- * @returns {Tabs}
290
- */
291
- removeTab(tabId) {
292
- const tabs = this.getTabs();
293
- for (const tab of tabs) {
294
- if ((tab.getAttribute("id") === tabId || tab.getAttribute("data-monster-name") === tabId) && tab.hasAttribute("data-monster-removable")) {
295
- tab.remove();
296
- initTabButtons.call(this);
297
- return this;
298
- }
299
- }
300
- return this;
301
- }
302
-
303
- /**
304
- * This method is called internal and should not be called directly.
305
- * @returns {[]}
306
- */
307
- getTabs() {
308
- const nodes = getSlottedElements.call(this);
309
- const tabs = [];
310
- for (const node of nodes) {
311
- if (node instanceof HTMLElement) {
312
- tabs.push(node);
313
- }
314
- }
315
- return tabs;
316
- }
317
-
318
- /**
319
- * This method is called internal and should not be called directly.
320
- * @param content
321
- * @param active
322
- * @param label
323
- * @param tabId
324
- * @param removable
325
- * @returns {Tabs}
326
- */
327
- addTab(content, {
328
- active = false,
329
- label = null,
330
- tabId = null,
331
- removable = true
332
- } = {} ) {
333
- const tab = document.createElement("div");
334
- if (!isString(label) || label.trim() === "") {
335
- label = this.getOption("labels.new-tab-label");
336
- }
337
- tab.setAttribute("data-monster-button-label" ,label);
338
-
339
- if (!isString(tabId) || tabId.trim() === "") {
340
- let thisID = this.getAttribute("id");
341
- if (!thisID) {
342
- thisID = new ID("tab").toString();
343
- }
344
-
345
- tabId = new ID(thisID).toString();
346
- }
347
-
348
- // check if id is already used
349
- const existingTabs = this.getTabs();
350
- for (const existingTab of existingTabs) {
351
- if (existingTab.getAttribute("id") === tabId || existingTab.getAttribute("data-monster-name") === tabId) {
352
- throw new Error(`Tab with id "${tabId}" already exists.`);
353
- }
354
- }
355
-
356
-
357
- tab.setAttribute("id", tabId);
358
-
359
- if (active === true) {
360
- tab.classList.add("active");
361
- }
362
-
363
- tab.setAttribute(ATTRIBUTE_ROLE, "tab");
364
-
365
- if(removable === true) {
366
- tab.setAttribute("data-monster-removable", "true");
367
- }
368
-
369
- if(content instanceof HTMLElement) {
370
- tab.appendChild(content);
371
- } else if (isString(content)) {
372
- tab.innerHTML = content;
373
- }
374
-
375
- this.appendChild(tab);
376
- return this
377
- }
378
-
379
- /**
380
- * A function that activates a tab based on the provided name.
381
- *
382
- * The tabs have to be named with the `data-monster-name` attribute.
383
- *
384
- * @param {type} idOrName - the name or id of the tab to activate
385
- * @return {Tabs} - The current instance
386
- */
387
- activeTab(idOrName) {
388
- let found = false;
389
-
390
- getSlottedElements.call(this).forEach((node) => {
391
- if (found === true) {
392
- return;
393
- }
394
-
395
- if (node.getAttribute("data-monster-name") === idOrName) {
396
- const tabControl = this.shadowRoot.querySelector(
397
- `[data-monster-tab-reference="${node.getAttribute("id")}"]`,
398
- );
399
-
400
- if (tabControl) {
401
- tabControl.click();
402
- found = true;
403
- }
404
- }
405
-
406
- if (node.getAttribute("id") === idOrName) {
407
- const tabControl = this.shadowRoot.querySelector(
408
- `[data-monster-tab-reference="${node.getAttribute("id")}"]`,
409
- );
410
-
411
- if (tabControl) {
412
- tabControl.click();
413
- found = true;
414
- }
415
- }
416
- });
417
-
418
- return this;
419
- }
420
-
421
- /**
422
- * A function that returns the name or id of the currently active tab.
423
- *
424
- * The tabs have to be named with the `data-monster-name` attribute.
425
- *
426
- * @return {string|null}
427
- */
428
- getActiveTab() {
429
- const nodes = getSlottedElements.call(this);
430
- for (const node of nodes) {
431
- if (node.matches(".active") === true) {
432
- if (node.hasAttribute("data-monster-name")) {
433
- return node.getAttribute("data-monster-name");
434
- }
435
-
436
- return node.getAttribute("id");
437
- }
438
- }
439
- return null;
440
- }
441
-
442
- /**
443
- * This method is called by the dom and should not be called directly.
444
- *
445
- * @return {void}
446
- */
447
- connectedCallback() {
448
- super.connectedCallback();
449
-
450
- const document = getDocument();
451
-
452
- for (const [, type] of Object.entries(["click", "touch"])) {
453
- // close on outside ui-events
454
- document.addEventListener(type, this[closeEventHandler]);
455
- }
456
- }
457
-
458
- /**
459
- * This method is called by the dom and should not be called directly.
460
- *
461
- * @return {void}
462
- */
463
- disconnectedCallback() {
464
- super.disconnectedCallback();
465
-
466
- const document = getDocument();
467
-
468
- // close on outside ui-events
469
- for (const [, type] of Object.entries(["click", "touch"])) {
470
- document.removeEventListener(type, this[closeEventHandler]);
471
- }
472
- }
164
+ /**
165
+ * This method is called by the `instanceof` operator.
166
+ * @return {symbol}
167
+ */
168
+ static get [instanceSymbol]() {
169
+ return Symbol.for("@schukai/monster/components/layout/tabs");
170
+ }
171
+
172
+ /**
173
+ * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
174
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
175
+ *
176
+ * The individual configuration values can be found in the table.
177
+ *
178
+ * @property {Object} templates Template definitions
179
+ * @property {string} templates.main Main template
180
+ * @property {Object} labels
181
+ * @property {string} labels.new-tab-label="New Tab"
182
+ * @property {Object} features
183
+ * @property {number} features.openDelay=500 Open delay in milliseconds
184
+ * @property {string} features.removeBehavior="auto" Remove behavior, auto (default), next, previous and none
185
+ * @property {boolean} features.openFirst=true Open the first tab
186
+ * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
187
+ * @property {String} fetch.redirect=error
188
+ * @property {String} fetch.method=GET
189
+ * @property {String} fetch.mode=same-origin
190
+ * @property {String} fetch.credentials=same-origin
191
+ * @property {Object} fetch.headers={"accept":"text/html"}}
192
+ * @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
193
+ * @property {string} popper.placement=bottom PopperJS placement
194
+ * @property {Object[]} modifiers={name:offset} PopperJS placement
195
+ */
196
+ get defaults() {
197
+ return Object.assign({}, super.defaults, {
198
+ templates: {
199
+ main: getTemplate(),
200
+ },
201
+ labels: getTranslations(),
202
+ buttons: {
203
+ standard: [],
204
+ popper: [],
205
+ },
206
+ fetch: {
207
+ redirect: "error",
208
+ method: "GET",
209
+ mode: "same-origin",
210
+ credentials: "same-origin",
211
+ headers: {
212
+ accept: "text/html",
213
+ },
214
+ },
215
+
216
+ features: {
217
+ openDelay: null,
218
+ removeBehavior: "auto",
219
+ openFirst: true,
220
+ },
221
+
222
+ classes: {
223
+ button: "monster-theme-primary-1",
224
+ popper: "monster-theme-primary-1",
225
+ navigation: "monster-theme-primary-1",
226
+ },
227
+
228
+ popper: {
229
+ placement: "bottom",
230
+ modifiers: [
231
+ {
232
+ name: "offset",
233
+ options: {
234
+ offset: [0, 2],
235
+ },
236
+ },
237
+
238
+ {
239
+ name: "eventListeners",
240
+ enabled: false,
241
+ },
242
+ ],
243
+ },
244
+ });
245
+ }
246
+
247
+ /**
248
+ * This method is called internal and should not be called directly.
249
+ */
250
+ [assembleMethodSymbol]() {
251
+ super[assembleMethodSymbol]();
252
+
253
+ initControlReferences.call(this);
254
+
255
+ this[dimensionsSymbol] = new Pathfinder({ data: {} });
256
+
257
+ initEventHandler.call(this);
258
+
259
+ // setup structure
260
+ initTabButtons.call(this).then(() => {
261
+ initPopperSwitch.call(this);
262
+ initPopper.call(this);
263
+ attachResizeObserver.call(this);
264
+ attachTabChangeObserver.call(this);
265
+ });
266
+ }
267
+
268
+ /**
269
+ * This method is called internal and should not be called directly.
270
+ *
271
+ * @return {CSSStyleSheet[]}
272
+ */
273
+ static getCSSStyleSheet() {
274
+ return [TabsStyleSheet];
275
+ }
276
+
277
+ /**
278
+ * This method is called internal and should not be called directly.
279
+ *
280
+ * @return {string}
281
+ */
282
+ static getTag() {
283
+ return "monster-tabs";
284
+ }
285
+
286
+ /**
287
+ * This method is called internal and should not be called directly.
288
+ * @param tabId
289
+ * @returns {Tabs}
290
+ */
291
+ removeTab(tabId) {
292
+ const tabs = this.getTabs();
293
+ for (const tab of tabs) {
294
+ if (
295
+ (tab.getAttribute("id") === tabId ||
296
+ tab.getAttribute("data-monster-name") === tabId) &&
297
+ tab.hasAttribute("data-monster-removable")
298
+ ) {
299
+ tab.remove();
300
+ initTabButtons.call(this);
301
+ return this;
302
+ }
303
+ }
304
+ return this;
305
+ }
306
+
307
+ /**
308
+ * This method is called internal and should not be called directly.
309
+ * @returns {[]}
310
+ */
311
+ getTabs() {
312
+ const nodes = getSlottedElements.call(this);
313
+ const tabs = [];
314
+ for (const node of nodes) {
315
+ if (node instanceof HTMLElement) {
316
+ tabs.push(node);
317
+ }
318
+ }
319
+ return tabs;
320
+ }
321
+
322
+ /**
323
+ * This method is called internal and should not be called directly.
324
+ * @param content
325
+ * @param active
326
+ * @param label
327
+ * @param tabId
328
+ * @param removable
329
+ * @returns {Tabs}
330
+ */
331
+ addTab(
332
+ content,
333
+ { active = false, label = null, tabId = null, removable = true } = {},
334
+ ) {
335
+ const tab = document.createElement("div");
336
+ if (!isString(label) || label.trim() === "") {
337
+ label = this.getOption("labels.new-tab-label");
338
+ }
339
+ tab.setAttribute("data-monster-button-label", label);
340
+
341
+ if (!isString(tabId) || tabId.trim() === "") {
342
+ let thisID = this.getAttribute("id");
343
+ if (!thisID) {
344
+ thisID = new ID("tab").toString();
345
+ }
346
+
347
+ tabId = new ID(thisID).toString();
348
+ }
349
+
350
+ // check if id is already used
351
+ const existingTabs = this.getTabs();
352
+ for (const existingTab of existingTabs) {
353
+ if (
354
+ existingTab.getAttribute("id") === tabId ||
355
+ existingTab.getAttribute("data-monster-name") === tabId
356
+ ) {
357
+ throw new Error(`Tab with id "${tabId}" already exists.`);
358
+ }
359
+ }
360
+
361
+ tab.setAttribute("id", tabId);
362
+
363
+ if (active === true) {
364
+ tab.classList.add("active");
365
+ }
366
+
367
+ tab.setAttribute(ATTRIBUTE_ROLE, "tab");
368
+
369
+ if (removable === true) {
370
+ tab.setAttribute("data-monster-removable", "true");
371
+ }
372
+
373
+ if (content instanceof HTMLElement) {
374
+ tab.appendChild(content);
375
+ } else if (isString(content)) {
376
+ tab.innerHTML = content;
377
+ }
378
+
379
+ this.appendChild(tab);
380
+ return this;
381
+ }
382
+
383
+ /**
384
+ * A function that activates a tab based on the provided name.
385
+ *
386
+ * The tabs have to be named with the `data-monster-name` attribute.
387
+ *
388
+ * @param {type} idOrName - the name or id of the tab to activate
389
+ * @return {Tabs} - The current instance
390
+ */
391
+ activeTab(idOrName) {
392
+ let found = false;
393
+
394
+ getSlottedElements.call(this).forEach((node) => {
395
+ if (found === true) {
396
+ return;
397
+ }
398
+
399
+ if (node.getAttribute("data-monster-name") === idOrName) {
400
+ const tabControl = this.shadowRoot.querySelector(
401
+ `[data-monster-tab-reference="${node.getAttribute("id")}"]`,
402
+ );
403
+
404
+ if (tabControl) {
405
+ tabControl.click();
406
+ found = true;
407
+ }
408
+ }
409
+
410
+ if (node.getAttribute("id") === idOrName) {
411
+ const tabControl = this.shadowRoot.querySelector(
412
+ `[data-monster-tab-reference="${node.getAttribute("id")}"]`,
413
+ );
414
+
415
+ if (tabControl) {
416
+ tabControl.click();
417
+ found = true;
418
+ }
419
+ }
420
+ });
421
+
422
+ return this;
423
+ }
424
+
425
+ /**
426
+ * A function that returns the name or id of the currently active tab.
427
+ *
428
+ * The tabs have to be named with the `data-monster-name` attribute.
429
+ *
430
+ * @return {string|null}
431
+ */
432
+ getActiveTab() {
433
+ const nodes = getSlottedElements.call(this);
434
+ for (const node of nodes) {
435
+ if (node.matches(".active") === true) {
436
+ if (node.hasAttribute("data-monster-name")) {
437
+ return node.getAttribute("data-monster-name");
438
+ }
439
+
440
+ return node.getAttribute("id");
441
+ }
442
+ }
443
+ return null;
444
+ }
445
+
446
+ /**
447
+ * This method is called by the dom and should not be called directly.
448
+ *
449
+ * @return {void}
450
+ */
451
+ connectedCallback() {
452
+ super.connectedCallback();
453
+
454
+ const document = getDocument();
455
+
456
+ for (const [, type] of Object.entries(["click", "touch"])) {
457
+ // close on outside ui-events
458
+ document.addEventListener(type, this[closeEventHandler]);
459
+ }
460
+ }
461
+
462
+ /**
463
+ * This method is called by the dom and should not be called directly.
464
+ *
465
+ * @return {void}
466
+ */
467
+ disconnectedCallback() {
468
+ super.disconnectedCallback();
469
+
470
+ const document = getDocument();
471
+
472
+ // close on outside ui-events
473
+ for (const [, type] of Object.entries(["click", "touch"])) {
474
+ document.removeEventListener(type, this[closeEventHandler]);
475
+ }
476
+ }
473
477
  }
474
478
 
475
479
  /**
@@ -477,188 +481,188 @@ class Tabs extends CustomElement {
477
481
  * @returns {object}
478
482
  */
479
483
  function getTranslations() {
480
- const locale = getLocaleOfDocument();
481
- switch (locale.language) {
482
- case "de":
483
- return {
484
- "new-tab-label": "Neuer Tab",
485
- };
486
- case "fr":
487
- return {
488
- "new-tab-label": "Nouvel Onglet",
489
- };
490
- case "sp":
491
- return {
492
- "new-tab-label": "Nueva Pestaña",
493
- };
494
- case "it":
495
- return {
496
- "new-tab-label": "Nuova Scheda",
497
- };
498
- case "pl":
499
- return {
500
- "new-tab-label": "Nowa Karta",
501
- };
502
- case "no":
503
- return {
504
- "new-tab-label": "Ny Fane",
505
- };
506
- case "dk":
507
- return {
508
- "new-tab-label": "Ny Fane",
509
- };
510
- case "sw":
511
- return {
512
- "new-tab-label": "Ny Flik",
513
- };
514
- default:
515
- case "en":
516
- return {
517
- "new-tab-label": "New Tab",
518
- };
519
- }
484
+ const locale = getLocaleOfDocument();
485
+ switch (locale.language) {
486
+ case "de":
487
+ return {
488
+ "new-tab-label": "Neuer Tab",
489
+ };
490
+ case "fr":
491
+ return {
492
+ "new-tab-label": "Nouvel Onglet",
493
+ };
494
+ case "sp":
495
+ return {
496
+ "new-tab-label": "Nueva Pestaña",
497
+ };
498
+ case "it":
499
+ return {
500
+ "new-tab-label": "Nuova Scheda",
501
+ };
502
+ case "pl":
503
+ return {
504
+ "new-tab-label": "Nowa Karta",
505
+ };
506
+ case "no":
507
+ return {
508
+ "new-tab-label": "Ny Fane",
509
+ };
510
+ case "dk":
511
+ return {
512
+ "new-tab-label": "Ny Fane",
513
+ };
514
+ case "sw":
515
+ return {
516
+ "new-tab-label": "Ny Flik",
517
+ };
518
+ default:
519
+ case "en":
520
+ return {
521
+ "new-tab-label": "New Tab",
522
+ };
523
+ }
520
524
  }
521
525
 
522
526
  /**
523
527
  * @private
524
528
  */
525
529
  function initPopperSwitch() {
526
- const nodes = getSlottedElements.call(this, `[${ATTRIBUTE_ROLE}="switch"]`); // null ↦ only unnamed slots
527
- let switchButton;
528
- if (nodes.size === 0) {
529
- switchButton = document.createElement("button");
530
- switchButton.setAttribute(ATTRIBUTE_ROLE, "switch");
531
- switchButton.setAttribute("part", "switch");
532
- switchButton.classList.add("hidden");
533
- const classList = this.getOption("classes.button");
534
- if (classList) {
535
- switchButton.classList.add(classList);
536
- }
537
- switchButton.innerHTML =
538
- '<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>';
539
- this[navElementSymbol].prepend(switchButton);
540
- } else {
541
- switchButton = nodes.next();
542
- }
543
-
544
- /**
545
- * @param {Event} event
546
- */
547
- this[popperSwitchEventHandler] = (event) => {
548
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "switch");
549
-
550
- if (element instanceof HTMLButtonElement) {
551
- togglePopper.call(this);
552
- }
553
- };
554
-
555
- for (const type of ["click", "touch"]) {
556
- switchButton.addEventListener(type, this[popperSwitchEventHandler]);
557
- }
558
-
559
- this[switchElementSymbol] = switchButton;
530
+ const nodes = getSlottedElements.call(this, `[${ATTRIBUTE_ROLE}="switch"]`); // null ↦ only unnamed slots
531
+ let switchButton;
532
+ if (nodes.size === 0) {
533
+ switchButton = document.createElement("button");
534
+ switchButton.setAttribute(ATTRIBUTE_ROLE, "switch");
535
+ switchButton.setAttribute("part", "switch");
536
+ switchButton.classList.add("hidden");
537
+ const classList = this.getOption("classes.button");
538
+ if (classList) {
539
+ switchButton.classList.add(classList);
540
+ }
541
+ switchButton.innerHTML =
542
+ '<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>';
543
+ this[navElementSymbol].prepend(switchButton);
544
+ } else {
545
+ switchButton = nodes.next();
546
+ }
547
+
548
+ /**
549
+ * @param {Event} event
550
+ */
551
+ this[popperSwitchEventHandler] = (event) => {
552
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "switch");
553
+
554
+ if (element instanceof HTMLButtonElement) {
555
+ togglePopper.call(this);
556
+ }
557
+ };
558
+
559
+ for (const type of ["click", "touch"]) {
560
+ switchButton.addEventListener(type, this[popperSwitchEventHandler]);
561
+ }
562
+
563
+ this[switchElementSymbol] = switchButton;
560
564
  }
561
565
 
562
566
  /**
563
567
  * @private
564
568
  */
565
569
  function hidePopper() {
566
- if (!this[popperInstanceSymbol]) {
567
- return;
568
- }
570
+ if (!this[popperInstanceSymbol]) {
571
+ return;
572
+ }
569
573
 
570
- this[popperElementSymbol].style.display = "none";
571
- // performance https://popper.js.org/docs/v2/tutorial/#performance
572
- setEventListenersModifiers.call(this, false);
574
+ this[popperElementSymbol].style.display = "none";
575
+ // performance https://popper.js.org/docs/v2/tutorial/#performance
576
+ setEventListenersModifiers.call(this, false);
573
577
  }
574
578
 
575
579
  /**
576
580
  * @private
577
581
  */
578
582
  function showPopper() {
579
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
580
- return;
581
- }
582
-
583
- this[popperElementSymbol].style.visibility = "hidden";
584
- this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
585
- // performance https://popper.js.org/docs/v2/tutorial/#performance
586
- setEventListenersModifiers.call(this, true);
587
-
588
- this[popperInstanceSymbol].update();
589
-
590
- new Processing(() => {
591
- this[popperElementSymbol].style.removeProperty("visibility");
592
- })
593
- .run(undefined)
594
- .then(() => {})
595
- .catch((e) => {
596
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
597
- });
583
+ if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
584
+ return;
585
+ }
586
+
587
+ this[popperElementSymbol].style.visibility = "hidden";
588
+ this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
589
+ // performance https://popper.js.org/docs/v2/tutorial/#performance
590
+ setEventListenersModifiers.call(this, true);
591
+
592
+ this[popperInstanceSymbol].update();
593
+
594
+ new Processing(() => {
595
+ this[popperElementSymbol].style.removeProperty("visibility");
596
+ })
597
+ .run(undefined)
598
+ .then(() => {})
599
+ .catch((e) => {
600
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
601
+ });
598
602
  }
599
603
 
600
604
  /**
601
605
  * @private
602
606
  */
603
607
  function togglePopper() {
604
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
605
- hidePopper.call(this);
606
- } else {
607
- showPopper.call(this);
608
- }
608
+ if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
609
+ hidePopper.call(this);
610
+ } else {
611
+ showPopper.call(this);
612
+ }
609
613
  }
610
614
 
611
615
  /**
612
616
  * @private
613
617
  */
614
618
  function attachResizeObserver() {
615
- // against flickering
616
- this[resizeObserverSymbol] = new ResizeObserver((entries) => {
617
- if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
618
- try {
619
- this[timerCallbackSymbol].touch();
620
- return;
621
- } catch (e) {
622
- delete this[timerCallbackSymbol];
623
- }
624
- }
625
-
626
- this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
627
- this[dimensionsSymbol].setVia("data.calculated", false);
628
- checkAndRearrangeButtons.call(this);
629
- });
630
- });
631
-
632
- this[resizeObserverSymbol].observe(this[navElementSymbol]);
619
+ // against flickering
620
+ this[resizeObserverSymbol] = new ResizeObserver((entries) => {
621
+ if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
622
+ try {
623
+ this[timerCallbackSymbol].touch();
624
+ return;
625
+ } catch (e) {
626
+ delete this[timerCallbackSymbol];
627
+ }
628
+ }
629
+
630
+ this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
631
+ this[dimensionsSymbol].setVia("data.calculated", false);
632
+ checkAndRearrangeButtons.call(this);
633
+ });
634
+ });
635
+
636
+ this[resizeObserverSymbol].observe(this[navElementSymbol]);
633
637
  }
634
638
 
635
639
  /**
636
640
  * @private
637
641
  */
638
642
  function attachTabChangeObserver() {
639
- // against flickering
640
- new MutationObserver((mutations) => {
641
- let runUpdate = false;
642
-
643
- for (const mutation of mutations) {
644
- if (mutation.type === "childList") {
645
- if (
646
- mutation.addedNodes.length > 0 ||
647
- mutation.removedNodes.length > 0
648
- ) {
649
- runUpdate = true;
650
- break;
651
- }
652
- }
653
- }
654
-
655
- if (runUpdate === true) {
656
- this[dimensionsSymbol].setVia("data.calculated", false);
657
- initTabButtons.call(this);
658
- }
659
- }).observe(this, {
660
- childList: true,
661
- });
643
+ // against flickering
644
+ new MutationObserver((mutations) => {
645
+ let runUpdate = false;
646
+
647
+ for (const mutation of mutations) {
648
+ if (mutation.type === "childList") {
649
+ if (
650
+ mutation.addedNodes.length > 0 ||
651
+ mutation.removedNodes.length > 0
652
+ ) {
653
+ runUpdate = true;
654
+ break;
655
+ }
656
+ }
657
+ }
658
+
659
+ if (runUpdate === true) {
660
+ this[dimensionsSymbol].setVia("data.calculated", false);
661
+ initTabButtons.call(this);
662
+ }
663
+ }).observe(this, {
664
+ childList: true,
665
+ });
662
666
  }
663
667
 
664
668
  /**
@@ -667,41 +671,41 @@ function attachTabChangeObserver() {
667
671
  * @external "external:createPopper"
668
672
  */
669
673
  function initPopper() {
670
- const self = this;
671
-
672
- const options = extend({}, self.getOption("popper"));
673
-
674
- self[popperInstanceSymbol] = createPopper(
675
- self[switchElementSymbol],
676
- self[popperElementSymbol],
677
- options,
678
- );
679
-
680
- const observer1 = new MutationObserver(function (mutations) {
681
- let runUpdate = false;
682
- for (const mutation of mutations) {
683
- if (mutation.type === "childList") {
684
- if (
685
- mutation.addedNodes.length > 0 ||
686
- mutation.removedNodes.length > 0
687
- ) {
688
- runUpdate = true;
689
- break;
690
- }
691
- }
692
- }
693
-
694
- if (runUpdate === true) {
695
- self[popperInstanceSymbol].update();
696
- }
697
- });
698
-
699
- observer1.observe(self[popperNavElementSymbol], {
700
- childList: true,
701
- subtree: true,
702
- });
703
-
704
- return self;
674
+ const self = this;
675
+
676
+ const options = extend({}, self.getOption("popper"));
677
+
678
+ self[popperInstanceSymbol] = createPopper(
679
+ self[switchElementSymbol],
680
+ self[popperElementSymbol],
681
+ options,
682
+ );
683
+
684
+ const observer1 = new MutationObserver(function (mutations) {
685
+ let runUpdate = false;
686
+ for (const mutation of mutations) {
687
+ if (mutation.type === "childList") {
688
+ if (
689
+ mutation.addedNodes.length > 0 ||
690
+ mutation.removedNodes.length > 0
691
+ ) {
692
+ runUpdate = true;
693
+ break;
694
+ }
695
+ }
696
+ }
697
+
698
+ if (runUpdate === true) {
699
+ self[popperInstanceSymbol].update();
700
+ }
701
+ });
702
+
703
+ observer1.observe(self[popperNavElementSymbol], {
704
+ childList: true,
705
+ subtree: true,
706
+ });
707
+
708
+ return self;
705
709
  }
706
710
 
707
711
  /**
@@ -709,226 +713,230 @@ function initPopper() {
709
713
  * @param {HTMLElement} element
710
714
  */
711
715
  function show(element) {
712
- if (!this.shadowRoot) {
713
- throw new Error("no shadow-root is defined");
714
- }
715
-
716
- const reference = element.getAttribute(`${ATTRIBUTE_PREFIX}tab-reference`);
717
-
718
- const nodes = getSlottedElements.call(this);
719
- for (const node of nodes) {
720
- const id = node.getAttribute("id");
721
-
722
- if (id === reference) {
723
- node.classList.add("active");
724
-
725
- const openDelay = Number.parseInt(
726
- this.getOption("features.openDelay"),
727
- 10,
728
- );
729
-
730
- if (!Number.isNaN(openDelay) && openDelay > 0) {
731
- node.style.visibility = "hidden";
732
-
733
- setTimeout(() => {
734
- node.style.visibility = "visible";
735
- }, openDelay);
736
- }
737
-
738
- // get all data- from button and filter out data-monster-attributes and data-monster-insert
739
- const data = {};
740
- const mask = [
741
- "data-monster-attributes",
742
- "data-monster-insert-reference",
743
- "data-monster-state",
744
- "data-monster-button-label",
745
- "data-monster-objectlink",
746
- "data-monster-role",
747
- ];
748
-
749
- for (const [, attr] of Object.entries(node.attributes)) {
750
- if (attr.name.startsWith("data-") && mask.indexOf(attr.name) === -1) {
751
- data[attr.name] = attr.value;
752
- }
753
- }
754
-
755
- if (node.hasAttribute(ATTRIBUTE_FORM_URL)) {
756
- const url = node.getAttribute(ATTRIBUTE_FORM_URL);
757
-
758
- if (
759
- !node.hasAttribute(ATTRIBUTE_FORM_RELOAD) ||
760
- node.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase() === "onshow"
761
- ) {
762
- node.removeAttribute(ATTRIBUTE_FORM_URL);
763
- }
764
-
765
- const options = this.getOption("fetch", {});
766
- const filter = undefined;
767
- loadAndAssignContent(node, url, options, filter)
768
- .then(() => {
769
- fireCustomEvent(this, "monster-tab-changed", {
770
- reference,
771
- });
772
- })
773
- .catch((e) => {
774
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
775
- });
776
- } else {
777
- fireCustomEvent(this, "monster-tab-changed", {
778
- reference,
779
- data,
780
- });
781
- }
782
- } else {
783
- node.classList.remove("active");
784
- }
785
- }
786
-
787
- const standardButtons = this.getOption("buttons.standard");
788
- for (const index in standardButtons) {
789
- const button = standardButtons[index];
790
- const state = button["reference"] === reference ? "active" : "inactive";
791
- this.setOption(`buttons.standard.${index}.state`, state);
792
- }
793
-
794
- const popperButton = this.getOption("buttons.popper");
795
- for (const index in popperButton) {
796
- const button = popperButton[index];
797
- const state = button["reference"] === reference ? "active" : "inactive";
798
- this.setOption(`buttons.popper.${index}.state`, state);
799
- }
800
-
801
- hidePopper.call(this);
716
+ if (!this.shadowRoot) {
717
+ throw new Error("no shadow-root is defined");
718
+ }
719
+
720
+ const reference = element.getAttribute(`${ATTRIBUTE_PREFIX}tab-reference`);
721
+
722
+ const nodes = getSlottedElements.call(this);
723
+ for (const node of nodes) {
724
+ const id = node.getAttribute("id");
725
+
726
+ if (id === reference) {
727
+ node.classList.add("active");
728
+
729
+ fireCustomEvent(this, "monster-tab-change", {
730
+ reference,
731
+ });
732
+
733
+ const openDelay = Number.parseInt(
734
+ this.getOption("features.openDelay"),
735
+ 10,
736
+ );
737
+
738
+ if (!Number.isNaN(openDelay) && openDelay > 0) {
739
+ node.style.visibility = "hidden";
740
+
741
+ setTimeout(() => {
742
+ node.style.visibility = "visible";
743
+ }, openDelay);
744
+ }
745
+
746
+ // get all data- from button and filter out data-monster-attributes and data-monster-insert
747
+ const data = {};
748
+ const mask = [
749
+ "data-monster-attributes",
750
+ "data-monster-insert-reference",
751
+ "data-monster-state",
752
+ "data-monster-button-label",
753
+ "data-monster-objectlink",
754
+ "data-monster-role",
755
+ ];
756
+
757
+ for (const [, attr] of Object.entries(node.attributes)) {
758
+ if (attr.name.startsWith("data-") && mask.indexOf(attr.name) === -1) {
759
+ data[attr.name] = attr.value;
760
+ }
761
+ }
762
+
763
+ if (node.hasAttribute(ATTRIBUTE_FORM_URL)) {
764
+ const url = node.getAttribute(ATTRIBUTE_FORM_URL);
765
+
766
+ if (
767
+ !node.hasAttribute(ATTRIBUTE_FORM_RELOAD) ||
768
+ node.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase() === "onshow"
769
+ ) {
770
+ node.removeAttribute(ATTRIBUTE_FORM_URL);
771
+ }
772
+
773
+ const options = this.getOption("fetch", {});
774
+ const filter = undefined;
775
+ loadAndAssignContent(node, url, options, filter)
776
+ .then(() => {
777
+ fireCustomEvent(this, "monster-tab-changed", {
778
+ reference,
779
+ });
780
+ })
781
+ .catch((e) => {
782
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
783
+ });
784
+ } else {
785
+ fireCustomEvent(this, "monster-tab-changed", {
786
+ reference,
787
+ data,
788
+ });
789
+ }
790
+ } else {
791
+ node.classList.remove("active");
792
+ }
793
+ }
794
+
795
+ const standardButtons = this.getOption("buttons.standard");
796
+ for (const index in standardButtons) {
797
+ const button = standardButtons[index];
798
+ const state = button["reference"] === reference ? "active" : "inactive";
799
+ this.setOption(`buttons.standard.${index}.state`, state);
800
+ }
801
+
802
+ const popperButton = this.getOption("buttons.popper");
803
+ for (const index in popperButton) {
804
+ const button = popperButton[index];
805
+ const state = button["reference"] === reference ? "active" : "inactive";
806
+ this.setOption(`buttons.popper.${index}.state`, state);
807
+ }
808
+
809
+ hidePopper.call(this);
802
810
  }
803
811
 
804
812
  /**
805
813
  * @private
806
814
  */
807
815
  function initEventHandler() {
808
- const self = this;
809
-
810
- if (!this.shadowRoot) {
811
- throw new Error("no shadow-root is defined");
812
- }
813
-
814
- /**
815
- * @param {Event} event
816
- * @fires monster-tab-remove
817
- */
818
- this[removeTabEventHandler] = (event) => {
819
- const element = findTargetElementFromEvent(
820
- event,
821
- ATTRIBUTE_ROLE,
822
- "remove-tab",
823
- );
824
-
825
- if (element instanceof HTMLElement) {
826
- const button = findTargetElementFromEvent(
827
- event,
828
- ATTRIBUTE_ROLE,
829
- "button",
830
- );
831
-
832
- if (button instanceof HTMLButtonElement && button.disabled !== true) {
833
- const reference = button.getAttribute(
834
- `${ATTRIBUTE_PREFIX}tab-reference`,
835
- );
836
-
837
- let doChange = false;
838
- let nextName = null;
839
- let previousName = null;
840
-
841
- const btn = this.getOption("buttons");
842
- for (let i = 0; i < btn.standard.length; i++) {
843
- if (btn.standard[i].reference === reference) {
844
- if (btn.standard[i].state === "active") {
845
- doChange = i;
846
- if (i < btn.standard.length - 1) {
847
- nextName = btn.standard[i + 1]?.reference;
848
- }
849
- if (i > 0) {
850
- previousName = btn.standard[i - 1]?.reference;
851
- }
852
- }
853
- break;
854
- }
855
- }
856
-
857
- if (reference) {
858
- const container = this.querySelector(`[id=${reference}]`);
859
- if (container instanceof HTMLElement) {
860
- if (doChange) {
861
- switch (this.getOption("features.removeBehavior")) {
862
- case "auto":
863
- if (nextName !== null) {
864
- self.activeTab(nextName);
865
- } else {
866
- if (previousName !== null) {
867
- self.activeTab(previousName);
868
- }
869
- }
870
- break;
871
- case "next":
872
- if (nextName !== null) {
873
- self.activeTab(nextName);
874
- }
875
- break;
876
- case "previous":
877
- if (previousName !== null) {
878
- self.activeTab(previousName);
879
- }
880
- break;
881
-
882
- default: // and "none"
883
- break;
884
- }
885
- }
886
-
887
- container.remove();
888
- initTabButtons.call(this);
889
- fireCustomEvent(this, "monster-tab-remove", {
890
- reference,
891
- });
892
- }
893
- }
894
- }
895
- }
896
- };
897
-
898
- /**
899
- * @param {Event} event
900
- */
901
- this[changeTabEventHandler] = (event) => {
902
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "button");
903
-
904
- if (element instanceof HTMLButtonElement && element.disabled !== true) {
905
- show.call(this, element);
906
- }
907
- };
908
-
909
- /**
910
- * @param {Event} event
911
- */
912
- this[closeEventHandler] = (event) => {
913
- const path = event.composedPath();
914
-
915
- for (const [, element] of Object.entries(path)) {
916
- if (element === this) {
917
- return;
918
- }
919
- }
920
-
921
- hidePopper.call(this);
922
- };
923
-
924
- // the order is important, because the remove must be before the change
925
- this[navElementSymbol].addEventListener("touch", this[removeTabEventHandler]);
926
- this[navElementSymbol].addEventListener("click", this[removeTabEventHandler]);
927
-
928
- this[navElementSymbol].addEventListener("touch", this[changeTabEventHandler]);
929
- this[navElementSymbol].addEventListener("click", this[changeTabEventHandler]);
930
-
931
- return this;
816
+ const self = this;
817
+
818
+ if (!this.shadowRoot) {
819
+ throw new Error("no shadow-root is defined");
820
+ }
821
+
822
+ /**
823
+ * @param {Event} event
824
+ * @fires monster-tab-remove
825
+ */
826
+ this[removeTabEventHandler] = (event) => {
827
+ const element = findTargetElementFromEvent(
828
+ event,
829
+ ATTRIBUTE_ROLE,
830
+ "remove-tab",
831
+ );
832
+
833
+ if (element instanceof HTMLElement) {
834
+ const button = findTargetElementFromEvent(
835
+ event,
836
+ ATTRIBUTE_ROLE,
837
+ "button",
838
+ );
839
+
840
+ if (button instanceof HTMLButtonElement && button.disabled !== true) {
841
+ const reference = button.getAttribute(
842
+ `${ATTRIBUTE_PREFIX}tab-reference`,
843
+ );
844
+
845
+ let doChange = false;
846
+ let nextName = null;
847
+ let previousName = null;
848
+
849
+ const btn = this.getOption("buttons");
850
+ for (let i = 0; i < btn.standard.length; i++) {
851
+ if (btn.standard[i].reference === reference) {
852
+ if (btn.standard[i].state === "active") {
853
+ doChange = i;
854
+ if (i < btn.standard.length - 1) {
855
+ nextName = btn.standard[i + 1]?.reference;
856
+ }
857
+ if (i > 0) {
858
+ previousName = btn.standard[i - 1]?.reference;
859
+ }
860
+ }
861
+ break;
862
+ }
863
+ }
864
+
865
+ if (reference) {
866
+ const container = this.querySelector(`[id=${reference}]`);
867
+ if (container instanceof HTMLElement) {
868
+ if (doChange) {
869
+ switch (this.getOption("features.removeBehavior")) {
870
+ case "auto":
871
+ if (nextName !== null) {
872
+ self.activeTab(nextName);
873
+ } else {
874
+ if (previousName !== null) {
875
+ self.activeTab(previousName);
876
+ }
877
+ }
878
+ break;
879
+ case "next":
880
+ if (nextName !== null) {
881
+ self.activeTab(nextName);
882
+ }
883
+ break;
884
+ case "previous":
885
+ if (previousName !== null) {
886
+ self.activeTab(previousName);
887
+ }
888
+ break;
889
+
890
+ default: // and "none"
891
+ break;
892
+ }
893
+ }
894
+
895
+ container.remove();
896
+ initTabButtons.call(this);
897
+ fireCustomEvent(this, "monster-tab-remove", {
898
+ reference,
899
+ });
900
+ }
901
+ }
902
+ }
903
+ }
904
+ };
905
+
906
+ /**
907
+ * @param {Event} event
908
+ */
909
+ this[changeTabEventHandler] = (event) => {
910
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "button");
911
+
912
+ if (element instanceof HTMLButtonElement && element.disabled !== true) {
913
+ show.call(this, element);
914
+ }
915
+ };
916
+
917
+ /**
918
+ * @param {Event} event
919
+ */
920
+ this[closeEventHandler] = (event) => {
921
+ const path = event.composedPath();
922
+
923
+ for (const [, element] of Object.entries(path)) {
924
+ if (element === this) {
925
+ return;
926
+ }
927
+ }
928
+
929
+ hidePopper.call(this);
930
+ };
931
+
932
+ // the order is important, because the remove must be before the change
933
+ this[navElementSymbol].addEventListener("touch", this[removeTabEventHandler]);
934
+ this[navElementSymbol].addEventListener("click", this[removeTabEventHandler]);
935
+
936
+ this[navElementSymbol].addEventListener("touch", this[changeTabEventHandler]);
937
+ this[navElementSymbol].addEventListener("click", this[changeTabEventHandler]);
938
+
939
+ return this;
932
940
  }
933
941
 
934
942
  /**
@@ -936,37 +944,37 @@ function initEventHandler() {
936
944
  * @param observedNode
937
945
  */
938
946
  function attachTabMutationObserver(observedNode) {
939
- const self = this;
940
-
941
- if (hasObjectLink(observedNode, mutationObserverSymbol)) {
942
- return;
943
- }
944
-
945
- /**
946
- * this construct monitors a node whether it is disabled or modified
947
- * @type {MutationObserver}
948
- */
949
- const observer = new MutationObserver(function (mutations) {
950
- if (isArray(mutations)) {
951
- const mutation = mutations.pop();
952
- if (mutation instanceof MutationRecord) {
953
- initTabButtons.call(self);
954
- }
955
- }
956
- });
957
-
958
- observer.observe(observedNode, {
959
- childList: false,
960
- attributes: true,
961
- subtree: false,
962
- attributeFilter: [
963
- "disabled",
964
- ATTRIBUTE_BUTTON_LABEL,
965
- `${ATTRIBUTE_PREFIX}button-icon`,
966
- ],
967
- });
968
-
969
- addToObjectLink(observedNode, mutationObserverSymbol, observer);
947
+ const self = this;
948
+
949
+ if (hasObjectLink(observedNode, mutationObserverSymbol)) {
950
+ return;
951
+ }
952
+
953
+ /**
954
+ * this construct monitors a node whether it is disabled or modified
955
+ * @type {MutationObserver}
956
+ */
957
+ const observer = new MutationObserver(function (mutations) {
958
+ if (isArray(mutations)) {
959
+ const mutation = mutations.pop();
960
+ if (mutation instanceof MutationRecord) {
961
+ initTabButtons.call(self);
962
+ }
963
+ }
964
+ });
965
+
966
+ observer.observe(observedNode, {
967
+ childList: false,
968
+ attributes: true,
969
+ subtree: false,
970
+ attributeFilter: [
971
+ "disabled",
972
+ ATTRIBUTE_BUTTON_LABEL,
973
+ `${ATTRIBUTE_PREFIX}button-icon`,
974
+ ],
975
+ });
976
+
977
+ addToObjectLink(observedNode, mutationObserverSymbol, observer);
970
978
  }
971
979
 
972
980
  /**
@@ -975,22 +983,22 @@ function attachTabMutationObserver(observedNode) {
975
983
  * @throws {Error} no shadow-root is defined
976
984
  */
977
985
  function initControlReferences() {
978
- if (!this.shadowRoot) {
979
- throw new Error("no shadow-root is defined");
980
- }
981
-
982
- this[controlElementSymbol] = this.shadowRoot.querySelector(
983
- `[${ATTRIBUTE_ROLE}=control]`,
984
- );
985
- this[navElementSymbol] = this.shadowRoot.querySelector(
986
- `nav[${ATTRIBUTE_ROLE}=nav]`,
987
- );
988
- this[popperElementSymbol] = this.shadowRoot.querySelector(
989
- `[${ATTRIBUTE_ROLE}=popper]`,
990
- );
991
- this[popperNavElementSymbol] = this.shadowRoot.querySelector(
992
- `[${ATTRIBUTE_ROLE}=popper-nav]`,
993
- );
986
+ if (!this.shadowRoot) {
987
+ throw new Error("no shadow-root is defined");
988
+ }
989
+
990
+ this[controlElementSymbol] = this.shadowRoot.querySelector(
991
+ `[${ATTRIBUTE_ROLE}=control]`,
992
+ );
993
+ this[navElementSymbol] = this.shadowRoot.querySelector(
994
+ `nav[${ATTRIBUTE_ROLE}=nav]`,
995
+ );
996
+ this[popperElementSymbol] = this.shadowRoot.querySelector(
997
+ `[${ATTRIBUTE_ROLE}=popper]`,
998
+ );
999
+ this[popperNavElementSymbol] = this.shadowRoot.querySelector(
1000
+ `[${ATTRIBUTE_ROLE}=popper-nav]`,
1001
+ );
994
1002
  }
995
1003
 
996
1004
  /**
@@ -1000,110 +1008,110 @@ function initControlReferences() {
1000
1008
  *
1001
1009
  */
1002
1010
  function initTabButtons() {
1003
- if (!this.shadowRoot) {
1004
- throw new Error("no shadow-root is defined");
1005
- }
1006
-
1007
- let activeReference;
1008
-
1009
- const dimensionsCalculated = this[dimensionsSymbol].getVia(
1010
- "data.calculated",
1011
- false,
1012
- );
1013
-
1014
- const buttons = [];
1015
- const nodes = getSlottedElements.call(this, undefined, null); // null ↦ only unnamed slots
1016
-
1017
- for (const node of nodes) {
1018
- if (!(node instanceof HTMLElement)) continue;
1019
- let label = getButtonLabel.call(this, node);
1020
-
1021
- let reference;
1022
- if (node.hasAttribute("id")) {
1023
- reference = node.getAttribute("id");
1024
- }
1025
-
1026
- let disabled;
1027
- if (node.hasAttribute("disabled") || node.disabled === true) {
1028
- disabled = true;
1029
- }
1030
-
1031
- if (!reference) {
1032
- reference = new ID("tab").toString();
1033
- node.setAttribute("id", reference);
1034
- }
1035
-
1036
- if (node.hasAttribute(`${ATTRIBUTE_PREFIX}button-icon`)) {
1037
- label = `<span part="label">${label}</span><img part="icon" alt="this is an icon" src="${node.getAttribute(
1038
- `${ATTRIBUTE_PREFIX}button-icon`,
1039
- )}">`;
1040
- }
1041
-
1042
- let remove = false;
1043
- if (node.hasAttribute(`${ATTRIBUTE_PREFIX}removable`)) {
1044
- remove = true;
1045
- }
1046
-
1047
- if (node.matches(".active") === true && disabled !== true) {
1048
- node.classList.remove("active");
1049
- activeReference = reference;
1050
- }
1051
-
1052
- const state = "";
1053
- const classes = dimensionsCalculated ? "" : "invisible";
1054
-
1055
- buttons.push({
1056
- reference,
1057
- label,
1058
- state,
1059
- class: classes,
1060
- disabled,
1061
- remove,
1062
- });
1063
-
1064
- attachTabMutationObserver.call(this, node);
1065
- }
1066
-
1067
- this.setOption("buttons.standard", clone(buttons));
1068
- this.setOption("buttons.popper", []);
1069
- this.setOption("marker", random());
1070
-
1071
- return adjustButtonVisibility.call(this).then(() => {
1072
- if (!activeReference && this.getOption("features.openFirst") === true) {
1073
- const firstButton = this.getOption("buttons.standard").find(
1074
- (button) => button.disabled !== true,
1075
- );
1076
- if (firstButton) {
1077
- activeReference = firstButton.reference;
1078
- }
1079
- }
1080
-
1081
- if (activeReference) {
1082
- return new Processing(() => {
1083
- const button = this.shadowRoot.querySelector(
1084
- `[${ATTRIBUTE_PREFIX}tab-reference="${activeReference}"]`,
1085
- );
1086
- if (button instanceof HTMLButtonElement && button.disabled !== true) {
1087
- show.call(this, button);
1088
- }
1089
- })
1090
- .run(undefined)
1091
- .then(() => {})
1092
- .catch((e) => {
1093
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1094
- });
1095
- }
1096
-
1097
- return Promise.resolve();
1098
- });
1011
+ if (!this.shadowRoot) {
1012
+ throw new Error("no shadow-root is defined");
1013
+ }
1014
+
1015
+ let activeReference;
1016
+
1017
+ const dimensionsCalculated = this[dimensionsSymbol].getVia(
1018
+ "data.calculated",
1019
+ false,
1020
+ );
1021
+
1022
+ const buttons = [];
1023
+ const nodes = getSlottedElements.call(this, undefined, null); // null ↦ only unnamed slots
1024
+
1025
+ for (const node of nodes) {
1026
+ if (!(node instanceof HTMLElement)) continue;
1027
+ let label = getButtonLabel.call(this, node);
1028
+
1029
+ let reference;
1030
+ if (node.hasAttribute("id")) {
1031
+ reference = node.getAttribute("id");
1032
+ }
1033
+
1034
+ let disabled;
1035
+ if (node.hasAttribute("disabled") || node.disabled === true) {
1036
+ disabled = true;
1037
+ }
1038
+
1039
+ if (!reference) {
1040
+ reference = new ID("tab").toString();
1041
+ node.setAttribute("id", reference);
1042
+ }
1043
+
1044
+ if (node.hasAttribute(`${ATTRIBUTE_PREFIX}button-icon`)) {
1045
+ label = `<span part="label">${label}</span><img part="icon" alt="this is an icon" src="${node.getAttribute(
1046
+ `${ATTRIBUTE_PREFIX}button-icon`,
1047
+ )}">`;
1048
+ }
1049
+
1050
+ let remove = false;
1051
+ if (node.hasAttribute(`${ATTRIBUTE_PREFIX}removable`)) {
1052
+ remove = true;
1053
+ }
1054
+
1055
+ if (node.matches(".active") === true && disabled !== true) {
1056
+ node.classList.remove("active");
1057
+ activeReference = reference;
1058
+ }
1059
+
1060
+ const state = "";
1061
+ const classes = dimensionsCalculated ? "" : "invisible";
1062
+
1063
+ buttons.push({
1064
+ reference,
1065
+ label,
1066
+ state,
1067
+ class: classes,
1068
+ disabled,
1069
+ remove,
1070
+ });
1071
+
1072
+ attachTabMutationObserver.call(this, node);
1073
+ }
1074
+
1075
+ this.setOption("buttons.standard", clone(buttons));
1076
+ this.setOption("buttons.popper", []);
1077
+ this.setOption("marker", random());
1078
+
1079
+ return adjustButtonVisibility.call(this).then(() => {
1080
+ if (!activeReference && this.getOption("features.openFirst") === true) {
1081
+ const firstButton = this.getOption("buttons.standard").find(
1082
+ (button) => button.disabled !== true,
1083
+ );
1084
+ if (firstButton) {
1085
+ activeReference = firstButton.reference;
1086
+ }
1087
+ }
1088
+
1089
+ if (activeReference) {
1090
+ return new Processing(() => {
1091
+ const button = this.shadowRoot.querySelector(
1092
+ `[${ATTRIBUTE_PREFIX}tab-reference="${activeReference}"]`,
1093
+ );
1094
+ if (button instanceof HTMLButtonElement && button.disabled !== true) {
1095
+ show.call(this, button);
1096
+ }
1097
+ })
1098
+ .run(undefined)
1099
+ .then(() => {})
1100
+ .catch((e) => {
1101
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1102
+ });
1103
+ }
1104
+
1105
+ return Promise.resolve();
1106
+ });
1099
1107
  }
1100
1108
 
1101
1109
  function checkAndRearrangeButtons() {
1102
- if (this[dimensionsSymbol].getVia("data.calculated", false) !== true) {
1103
- calculateNavigationButtonsDimensions.call(this);
1104
- }
1110
+ if (this[dimensionsSymbol].getVia("data.calculated", false) !== true) {
1111
+ calculateNavigationButtonsDimensions.call(this);
1112
+ }
1105
1113
 
1106
- rearrangeButtons.call(this);
1114
+ rearrangeButtons.call(this);
1107
1115
  }
1108
1116
 
1109
1117
  /**
@@ -1111,29 +1119,29 @@ function checkAndRearrangeButtons() {
1111
1119
  * @return {Promise<unknown>}
1112
1120
  */
1113
1121
  function adjustButtonVisibility() {
1114
- const self = this;
1122
+ const self = this;
1115
1123
 
1116
- return new Promise((resolve) => {
1117
- const observer = new MutationObserver(function (mutations) {
1118
- const defCount = self.getOption("buttons.standard").length;
1119
- const domCount = self[navElementSymbol].querySelectorAll(
1120
- 'button[data-monster-role="button"]',
1121
- ).length;
1124
+ return new Promise((resolve) => {
1125
+ const observer = new MutationObserver(function (mutations) {
1126
+ const defCount = self.getOption("buttons.standard").length;
1127
+ const domCount = self[navElementSymbol].querySelectorAll(
1128
+ 'button[data-monster-role="button"]',
1129
+ ).length;
1122
1130
 
1123
- // in drawing
1124
- if (defCount !== domCount) return;
1131
+ // in drawing
1132
+ if (defCount !== domCount) return;
1125
1133
 
1126
- observer.disconnect();
1134
+ observer.disconnect();
1127
1135
 
1128
- checkAndRearrangeButtons.call(self);
1136
+ checkAndRearrangeButtons.call(self);
1129
1137
 
1130
- resolve();
1131
- });
1138
+ resolve();
1139
+ });
1132
1140
 
1133
- observer.observe(self[navElementSymbol], {
1134
- attributes: true,
1135
- });
1136
- });
1141
+ observer.observe(self[navElementSymbol], {
1142
+ attributes: true,
1143
+ });
1144
+ });
1137
1145
  }
1138
1146
 
1139
1147
  /**
@@ -1142,17 +1150,17 @@ function adjustButtonVisibility() {
1142
1150
  * @return {number}
1143
1151
  */
1144
1152
  function getDimValue(value) {
1145
- if ([undefined, null].indexOf(value) !== -1) {
1146
- return 0;
1147
- }
1153
+ if ([undefined, null].indexOf(value) !== -1) {
1154
+ return 0;
1155
+ }
1148
1156
 
1149
- const valueAsInt = parseInt(value, 10);
1157
+ const valueAsInt = parseInt(value, 10);
1150
1158
 
1151
- if (isNaN(valueAsInt)) {
1152
- return 0;
1153
- }
1159
+ if (isNaN(valueAsInt)) {
1160
+ return 0;
1161
+ }
1154
1162
 
1155
- return valueAsInt;
1163
+ return valueAsInt;
1156
1164
  }
1157
1165
 
1158
1166
  /**
@@ -1161,18 +1169,18 @@ function getDimValue(value) {
1161
1169
  * @return {number}
1162
1170
  */
1163
1171
  function calcBoxWidth(node) {
1164
- const dim = getGlobal("window").getComputedStyle(node);
1165
- const bounding = node.getBoundingClientRect();
1166
-
1167
- return (
1168
- getDimValue(dim["border-left-width"]) +
1169
- getDimValue(dim["padding-left"]) +
1170
- getDimValue(dim["margin-left"]) +
1171
- getDimValue(bounding["width"]) +
1172
- getDimValue(dim["border-right-width"]) +
1173
- getDimValue(dim["margin-right"]) +
1174
- getDimValue(dim["padding-left"])
1175
- );
1172
+ const dim = getGlobal("window").getComputedStyle(node);
1173
+ const bounding = node.getBoundingClientRect();
1174
+
1175
+ return (
1176
+ getDimValue(dim["border-left-width"]) +
1177
+ getDimValue(dim["padding-left"]) +
1178
+ getDimValue(dim["margin-left"]) +
1179
+ getDimValue(bounding["width"]) +
1180
+ getDimValue(dim["border-right-width"]) +
1181
+ getDimValue(dim["margin-right"]) +
1182
+ getDimValue(dim["padding-left"])
1183
+ );
1176
1184
  }
1177
1185
 
1178
1186
  /**
@@ -1180,40 +1188,40 @@ function calcBoxWidth(node) {
1180
1188
  * @return {Object}
1181
1189
  */
1182
1190
  function rearrangeButtons() {
1183
- getWindow().requestAnimationFrame(() => {
1184
- const standardButtons = [];
1185
- const popperButtons = [];
1186
- let sum = 0;
1187
- const space = this[dimensionsSymbol].getVia("data.space");
1188
-
1189
- if (space <= 0) {
1190
- return;
1191
- }
1192
-
1193
- const buttons = this.getOption("buttons.standard");
1194
- for (const [, button] of buttons.entries()) {
1195
- const ref = button?.reference;
1196
-
1197
- sum += this[dimensionsSymbol].getVia(`data.button.${ref}`);
1198
-
1199
- if (sum > space) {
1200
- popperButtons.push(clone(button));
1201
- } else {
1202
- standardButtons.push(clone(button));
1203
- }
1204
- }
1205
-
1206
- this.setOption("buttons.standard", standardButtons);
1207
- this.setOption("buttons.popper", popperButtons);
1208
-
1209
- if (this[switchElementSymbol]) {
1210
- if (popperButtons.length > 0) {
1211
- this[switchElementSymbol].classList.remove("hidden");
1212
- } else {
1213
- this[switchElementSymbol].classList.add("hidden");
1214
- }
1215
- }
1216
- });
1191
+ getWindow().requestAnimationFrame(() => {
1192
+ const standardButtons = [];
1193
+ const popperButtons = [];
1194
+ let sum = 0;
1195
+ const space = this[dimensionsSymbol].getVia("data.space");
1196
+
1197
+ if (space <= 0) {
1198
+ return;
1199
+ }
1200
+
1201
+ const buttons = this.getOption("buttons.standard");
1202
+ for (const [, button] of buttons.entries()) {
1203
+ const ref = button?.reference;
1204
+
1205
+ sum += this[dimensionsSymbol].getVia(`data.button.${ref}`);
1206
+
1207
+ if (sum > space) {
1208
+ popperButtons.push(clone(button));
1209
+ } else {
1210
+ standardButtons.push(clone(button));
1211
+ }
1212
+ }
1213
+
1214
+ this.setOption("buttons.standard", standardButtons);
1215
+ this.setOption("buttons.popper", popperButtons);
1216
+
1217
+ if (this[switchElementSymbol]) {
1218
+ if (popperButtons.length > 0) {
1219
+ this[switchElementSymbol].classList.remove("hidden");
1220
+ } else {
1221
+ this[switchElementSymbol].classList.add("hidden");
1222
+ }
1223
+ }
1224
+ });
1217
1225
  }
1218
1226
 
1219
1227
  /**
@@ -1221,53 +1229,53 @@ function rearrangeButtons() {
1221
1229
  * @return {Object}
1222
1230
  */
1223
1231
  function calculateNavigationButtonsDimensions() {
1224
- const width = this[navElementSymbol].getBoundingClientRect().width;
1225
-
1226
- let startEndWidth = 0;
1227
-
1228
- getSlottedElements.call(this, undefined, "start").forEach((node) => {
1229
- startEndWidth += calcBoxWidth.call(this, node);
1230
- });
1231
-
1232
- getSlottedElements.call(this, undefined, "end").forEach((node) => {
1233
- startEndWidth += calcBoxWidth.call(this, node);
1234
- });
1235
-
1236
- this[dimensionsSymbol].setVia("data.space", width - startEndWidth - 2);
1237
- this[dimensionsSymbol].setVia("data.visible", !(width === 0));
1238
-
1239
- const buttons = this.getOption("buttons.standard").concat(
1240
- this.getOption("buttons.popper"),
1241
- );
1242
-
1243
- for (const [i, button] of buttons.entries()) {
1244
- const ref = button?.reference;
1245
- const element = this[navElementSymbol].querySelector(
1246
- `:scope > [${ATTRIBUTE_PREFIX}tab-reference="${ref}"]`,
1247
- );
1248
- if (!(element instanceof HTMLButtonElement)) continue;
1249
-
1250
- this[dimensionsSymbol].setVia(
1251
- `data.button.${ref}`,
1252
- calcBoxWidth.call(this, element),
1253
- );
1254
- button["class"] = new TokenList(button["class"])
1255
- .remove("invisible")
1256
- .toString();
1257
- }
1258
-
1259
- const slots = this[controlElementSymbol].querySelectorAll(
1260
- `nav[${ATTRIBUTE_PREFIX}role=nav] > slot.invisible, slot[${ATTRIBUTE_PREFIX}role=slot].invisible`,
1261
- );
1262
- for (const [, slot] of slots.entries()) {
1263
- slot.classList.remove("invisible");
1264
- }
1265
-
1266
- this.setOption("buttons.standard", clone(buttons));
1267
-
1268
- getWindow().requestAnimationFrame(() => {
1269
- this[dimensionsSymbol].setVia("data.calculated", true);
1270
- });
1232
+ const width = this[navElementSymbol].getBoundingClientRect().width;
1233
+
1234
+ let startEndWidth = 0;
1235
+
1236
+ getSlottedElements.call(this, undefined, "start").forEach((node) => {
1237
+ startEndWidth += calcBoxWidth.call(this, node);
1238
+ });
1239
+
1240
+ getSlottedElements.call(this, undefined, "end").forEach((node) => {
1241
+ startEndWidth += calcBoxWidth.call(this, node);
1242
+ });
1243
+
1244
+ this[dimensionsSymbol].setVia("data.space", width - startEndWidth - 2);
1245
+ this[dimensionsSymbol].setVia("data.visible", !(width === 0));
1246
+
1247
+ const buttons = this.getOption("buttons.standard").concat(
1248
+ this.getOption("buttons.popper"),
1249
+ );
1250
+
1251
+ for (const [i, button] of buttons.entries()) {
1252
+ const ref = button?.reference;
1253
+ const element = this[navElementSymbol].querySelector(
1254
+ `:scope > [${ATTRIBUTE_PREFIX}tab-reference="${ref}"]`,
1255
+ );
1256
+ if (!(element instanceof HTMLButtonElement)) continue;
1257
+
1258
+ this[dimensionsSymbol].setVia(
1259
+ `data.button.${ref}`,
1260
+ calcBoxWidth.call(this, element),
1261
+ );
1262
+ button["class"] = new TokenList(button["class"])
1263
+ .remove("invisible")
1264
+ .toString();
1265
+ }
1266
+
1267
+ const slots = this[controlElementSymbol].querySelectorAll(
1268
+ `nav[${ATTRIBUTE_PREFIX}role=nav] > slot.invisible, slot[${ATTRIBUTE_PREFIX}role=slot].invisible`,
1269
+ );
1270
+ for (const [, slot] of slots.entries()) {
1271
+ slot.classList.remove("invisible");
1272
+ }
1273
+
1274
+ this.setOption("buttons.standard", clone(buttons));
1275
+
1276
+ getWindow().requestAnimationFrame(() => {
1277
+ this[dimensionsSymbol].setVia("data.calculated", true);
1278
+ });
1271
1279
  }
1272
1280
 
1273
1281
  /**
@@ -1276,34 +1284,34 @@ function calculateNavigationButtonsDimensions() {
1276
1284
  * @return {string}
1277
1285
  */
1278
1286
  function getButtonLabel(node) {
1279
- let label;
1280
- let setLabel = false;
1281
- if (node.hasAttribute(ATTRIBUTE_BUTTON_LABEL)) {
1282
- label = node.getAttribute(ATTRIBUTE_BUTTON_LABEL);
1283
- } else {
1284
- label = node.innerText;
1285
- setLabel = true;
1286
- }
1287
-
1288
- if (!isString(label)) {
1289
- label = "";
1290
- }
1291
-
1292
- label = label.trim();
1293
-
1294
- if (label === "") {
1295
- label = this.getOption("labels.new-tab-label", "New Tab");
1296
- }
1297
-
1298
- if (label.length > 100) {
1299
- label = `${label.substring(0, 99)}…`;
1300
- }
1301
-
1302
- if (setLabel === true) {
1303
- node.setAttribute(ATTRIBUTE_BUTTON_LABEL, label);
1304
- }
1305
-
1306
- return label;
1287
+ let label;
1288
+ let setLabel = false;
1289
+ if (node.hasAttribute(ATTRIBUTE_BUTTON_LABEL)) {
1290
+ label = node.getAttribute(ATTRIBUTE_BUTTON_LABEL);
1291
+ } else {
1292
+ label = node.innerText;
1293
+ setLabel = true;
1294
+ }
1295
+
1296
+ if (!isString(label)) {
1297
+ label = "";
1298
+ }
1299
+
1300
+ label = label.trim();
1301
+
1302
+ if (label === "") {
1303
+ label = this.getOption("labels.new-tab-label", "New Tab");
1304
+ }
1305
+
1306
+ if (label.length > 100) {
1307
+ label = `${label.substring(0, 99)}…`;
1308
+ }
1309
+
1310
+ if (setLabel === true) {
1311
+ node.setAttribute(ATTRIBUTE_BUTTON_LABEL, label);
1312
+ }
1313
+
1314
+ return label;
1307
1315
  }
1308
1316
 
1309
1317
  /**
@@ -1311,8 +1319,8 @@ function getButtonLabel(node) {
1311
1319
  * @return {string}
1312
1320
  */
1313
1321
  function getTemplate() {
1314
- // language=HTML
1315
- return `
1322
+ // language=HTML
1323
+ return `
1316
1324
  <template id="buttons">
1317
1325
  <button part="button"
1318
1326
  tabindex="0"