@schukai/monster 3.101.3 → 3.102.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 +12 -0
- package/package.json +1 -1
- package/source/components/form/select.mjs +2197 -2157
- package/source/dom/customelement.mjs +1 -1
- package/source/dom/updater.mjs +792 -768
@@ -12,59 +12,59 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {
|
16
|
-
import {
|
17
|
-
import {
|
18
|
-
import {
|
19
|
-
import {
|
15
|
+
import {instanceSymbol} from "../../constants.mjs";
|
16
|
+
import {internalSymbol} from "../../constants.mjs";
|
17
|
+
import {buildMap} from "../../data/buildmap.mjs";
|
18
|
+
import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
|
19
|
+
import {positionPopper} from "./util/floating-ui.mjs";
|
20
20
|
import {
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
addAttributeToken,
|
22
|
+
findClosestByAttribute,
|
23
|
+
removeAttributeToken,
|
24
24
|
} from "../../dom/attributes.mjs";
|
25
|
-
import {
|
26
|
-
import {
|
25
|
+
import {ATTRIBUTE_PREFIX, ATTRIBUTE_ROLE} from "../../dom/constants.mjs";
|
26
|
+
import {CustomControl} from "../../dom/customcontrol.mjs";
|
27
27
|
import {
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
assembleMethodSymbol,
|
29
|
+
getSlottedElements,
|
30
|
+
registerCustomElement,
|
31
31
|
} from "../../dom/customelement.mjs";
|
32
32
|
import {
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
findTargetElementFromEvent,
|
34
|
+
fireCustomEvent,
|
35
|
+
fireEvent,
|
36
36
|
} from "../../dom/events.mjs";
|
37
|
-
import {
|
38
|
-
import {
|
39
|
-
import {
|
40
|
-
import {
|
37
|
+
import {getDocument} from "../../dom/util.mjs";
|
38
|
+
import {Formatter} from "../../text/formatter.mjs";
|
39
|
+
import {getGlobal} from "../../types/global.mjs";
|
40
|
+
import {ID} from "../../types/id.mjs";
|
41
41
|
import {
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
42
|
+
isArray,
|
43
|
+
isFunction,
|
44
|
+
isInteger,
|
45
|
+
isIterable,
|
46
|
+
isObject,
|
47
|
+
isPrimitive,
|
48
|
+
isString,
|
49
49
|
} from "../../types/is.mjs";
|
50
|
-
import {
|
51
|
-
import {
|
52
|
-
import {
|
53
|
-
import {
|
54
|
-
import {
|
55
|
-
import {
|
50
|
+
import {Observer} from "../../types/observer.mjs";
|
51
|
+
import {ProxyObserver} from "../../types/proxyobserver.mjs";
|
52
|
+
import {validateArray, validateString} from "../../types/validate.mjs";
|
53
|
+
import {Processing} from "../../util/processing.mjs";
|
54
|
+
import {STYLE_DISPLAY_MODE_BLOCK} from "./constants.mjs";
|
55
|
+
import {SelectStyleSheet} from "./stylesheet/select.mjs";
|
56
56
|
import {
|
57
|
-
|
58
|
-
|
57
|
+
getDocumentTranslations,
|
58
|
+
Translations,
|
59
59
|
} from "../../i18n/translations.mjs";
|
60
|
-
import {
|
61
|
-
import {
|
60
|
+
import {getLocaleOfDocument} from "../../dom/locale.mjs";
|
61
|
+
import {addErrorAttribute, removeErrorAttribute} from "../../dom/error.mjs";
|
62
62
|
|
63
63
|
export {
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
Select,
|
65
|
+
popperElementSymbol,
|
66
|
+
getSummaryTemplate,
|
67
|
+
getSelectionTemplate,
|
68
68
|
};
|
69
69
|
|
70
70
|
/**
|
@@ -185,7 +185,7 @@ const popperFilterElementSymbol = Symbol("popperFilterElement");
|
|
185
185
|
* @type {Symbol}
|
186
186
|
*/
|
187
187
|
const popperFilterContainerElementSymbol = Symbol(
|
188
|
-
|
188
|
+
"popperFilterContainerElement",
|
189
189
|
);
|
190
190
|
|
191
191
|
/**
|
@@ -264,9 +264,8 @@ const FILTER_POSITION_INLINE = "inline";
|
|
264
264
|
/**
|
265
265
|
* A select control that can be used to select o
|
266
266
|
*
|
267
|
-
* ne or more options from a list.
|
268
|
-
*
|
269
267
|
* @issue @issue https://localhost.alvine.dev:8444/development/issues/closed/280.html
|
268
|
+
* @issue @issue https://localhost.alvine.dev:8444/development/issues/closed/287.html
|
270
269
|
*
|
271
270
|
* @fragments /fragments/components/form/select/
|
272
271
|
*
|
@@ -284,482 +283,497 @@ const FILTER_POSITION_INLINE = "inline";
|
|
284
283
|
* @fires monster-changed
|
285
284
|
*/
|
286
285
|
class Select extends CustomControl {
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
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
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
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
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
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
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
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
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
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
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
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
|
-
|
286
|
+
/**
|
287
|
+
*
|
288
|
+
*/
|
289
|
+
constructor() {
|
290
|
+
super();
|
291
|
+
initOptionObserver.call(this);
|
292
|
+
}
|
293
|
+
|
294
|
+
/**
|
295
|
+
* This method is called by the `instanceof` operator.
|
296
|
+
* @return {Symbol}
|
297
|
+
*/
|
298
|
+
static get [instanceSymbol]() {
|
299
|
+
return Symbol.for("@schukai/monster/components/form/select@@instance");
|
300
|
+
}
|
301
|
+
|
302
|
+
/**
|
303
|
+
* The current selection of the Select
|
304
|
+
*
|
305
|
+
* ```
|
306
|
+
* e = document.querySelector('monster-select');
|
307
|
+
* console.log(e.value)
|
308
|
+
* // ↦ 1
|
309
|
+
* // ↦ ['1','2']
|
310
|
+
* ```
|
311
|
+
*
|
312
|
+
* @return {string}
|
313
|
+
*/
|
314
|
+
get value() {
|
315
|
+
return convertSelectionToValue.call(this, this.getOption("selection"));
|
316
|
+
}
|
317
|
+
|
318
|
+
/**
|
319
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
|
320
|
+
* @return {boolean}
|
321
|
+
*/
|
322
|
+
static get formAssociated() {
|
323
|
+
return true;
|
324
|
+
}
|
325
|
+
|
326
|
+
/**
|
327
|
+
* Set selection
|
328
|
+
*
|
329
|
+
* ```
|
330
|
+
* e = document.querySelector('monster-select');
|
331
|
+
* e.value=1
|
332
|
+
* ```
|
333
|
+
*
|
334
|
+
* @property {string|array} value
|
335
|
+
* @throws {Error} unsupported type
|
336
|
+
* @fires monster-selected this event is fired when the selection is set
|
337
|
+
*/
|
338
|
+
set value(value) {
|
339
|
+
|
340
|
+
let ignoreValues = this.getOption("ignoreValues", []);
|
341
|
+
if(!isArray(ignoreValues)){
|
342
|
+
ignoreValues = [];
|
343
|
+
}
|
344
|
+
|
345
|
+
for (const v of ignoreValues) {
|
346
|
+
if (value === v) {
|
347
|
+
return;
|
348
|
+
}
|
349
|
+
}
|
350
|
+
|
351
|
+
const result = convertValueToSelection.call(this, value);
|
352
|
+
setSelection
|
353
|
+
.call(this, result.selection)
|
354
|
+
.then(() => {
|
355
|
+
})
|
356
|
+
.catch((e) => {
|
357
|
+
addErrorAttribute(this, e);
|
358
|
+
});
|
359
|
+
}
|
360
|
+
|
361
|
+
/**
|
362
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
363
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
364
|
+
*
|
365
|
+
* The individual configuration values can be found in the table.
|
366
|
+
*
|
367
|
+
* @property {Object} toggleEventType List of event types to be observed for opening the dropdown
|
368
|
+
* @property {boolean} delegatesFocus lorem [see mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus)
|
369
|
+
* @property {Object[]} options Selection of key identifier pairs available for selection and displayed in the dropdown.
|
370
|
+
* @property {string} options[].label
|
371
|
+
* @property {string} options[].value
|
372
|
+
* @property {string} options[].visibility hidden or visible
|
373
|
+
* @property {Array} selection Selected options
|
374
|
+
* @property {Integer} showMaxOptions Maximum number of visible options before a scroll bar should be displayed.
|
375
|
+
* @property {string} type Multiple (checkbox) or single selection (radio)
|
376
|
+
* @property {string} name Name of the form field
|
377
|
+
* @property {string} url Load options from server per url
|
378
|
+
* @property {object} lookup Load options from server per url
|
379
|
+
* @property {string} lookup.url Load options from server per url
|
380
|
+
* @property {boolean} lookup.grouping Load all selected options from server per url at once (true) or one by one (false)
|
381
|
+
* @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
|
382
|
+
* @property {String} fetch.redirect
|
383
|
+
* @property {String} fetch.method
|
384
|
+
* @property {String} fetch.mode
|
385
|
+
* @property {String} fetch.credentials
|
386
|
+
* @property {Object} fetch.headers
|
387
|
+
* @property {Object} labels
|
388
|
+
* @property {string} labels.cannot-be-loaded cannot be loaded
|
389
|
+
* @property {string} labels.no-options-available no options available
|
390
|
+
* @property {string} labels.select-an-option select an option
|
391
|
+
* @property {string} labels.no-option no option in the list, maybe you have to change the filter
|
392
|
+
* @property {Object} features List with features
|
393
|
+
* @property {Boolean} features.clearAll Display of a delete button to delete the entire selection
|
394
|
+
* @property {Boolean} features.clear Display of a delete key for deleting the specific selection
|
395
|
+
* @property {Boolean} features.lazyLoad Load options when first opening the dropdown. (Hint; lazylLoad is not supported with remote filter)
|
396
|
+
* @property {Boolean} features.closeOnSelect Close the dropdown when an option is selected (since 3.54.0)
|
397
|
+
* @property {Boolean} features.emptyValueIfNoOptions If no options are available, the selection is set to an empty array
|
398
|
+
* @property {Boolean} features.storeFetchedData Store fetched data in the object
|
399
|
+
* @property {Boolean} features.useStrictValueComparison Use strict value comparison for the selection
|
400
|
+
* @property {string} filter.defaultValue Default filter value, if the filter is empty, if the default value is null, then no request is made
|
401
|
+
* @property {Boolean} filter.mode Filter mode, values: options, remote, disabled (Hint; lazylLoad is not supported with remote filter, if you use remote filter, the lazyLoad is disabled)
|
402
|
+
* @property {Object} templates Template definitions
|
403
|
+
* @property {string} templates.main Main template
|
404
|
+
* @property {string} templateMapping Mapping of the template placeholders
|
405
|
+
* @property {string} templateMapping.selected Selected Template
|
406
|
+
* @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
|
407
|
+
* @property {string} popper.placement PopperJS placement
|
408
|
+
* @property {Object[]} modifiers PopperJS placement
|
409
|
+
* @property {Object} mapping
|
410
|
+
* @property {String} mapping.selector Path to select the appropriate entries
|
411
|
+
* @property {String} mapping.labelTemplate template with the label placeholders in the form ${name}, where name is the key (**)
|
412
|
+
* @property {String} mapping.valueTemplate template with the value placeholders in the form ${name}, where name is the key
|
413
|
+
* @property {function|undefined} mapping.filter Filtering of values via a function
|
414
|
+
* @property {Array} ignoreValues Ignore values in the selection and value
|
415
|
+
* @property {Object} formatter
|
416
|
+
* @property {function|undefined} formatter.selection format selection label
|
417
|
+
*/
|
418
|
+
get defaults() {
|
419
|
+
return Object.assign(
|
420
|
+
{},
|
421
|
+
super.defaults,
|
422
|
+
{
|
423
|
+
toggleEventType: ["click", "touch"],
|
424
|
+
delegatesFocus: false,
|
425
|
+
options: [],
|
426
|
+
selection: [],
|
427
|
+
showMaxOptions: 10,
|
428
|
+
type: "radio",
|
429
|
+
name: new ID("s").toString(),
|
430
|
+
features: {
|
431
|
+
clearAll: true,
|
432
|
+
clear: true,
|
433
|
+
lazyLoad: false,
|
434
|
+
closeOnSelect: false,
|
435
|
+
emptyValueIfNoOptions: false,
|
436
|
+
storeFetchedData: false,
|
437
|
+
useStrictValueComparison: false
|
438
|
+
},
|
439
|
+
url: null,
|
440
|
+
lookup: {
|
441
|
+
url: null,
|
442
|
+
grouping: false,
|
443
|
+
},
|
444
|
+
labels: getTranslations(),
|
445
|
+
messages: {
|
446
|
+
control: null,
|
447
|
+
selected: null,
|
448
|
+
emptyOptions: null,
|
449
|
+
},
|
450
|
+
fetch: {
|
451
|
+
redirect: "error",
|
452
|
+
method: "GET",
|
453
|
+
mode: "same-origin",
|
454
|
+
credentials: "same-origin",
|
455
|
+
headers: {
|
456
|
+
accept: "application/json",
|
457
|
+
},
|
458
|
+
},
|
459
|
+
filter: {
|
460
|
+
defaultValue: null,
|
461
|
+
mode: FILTER_MODE_DISABLED,
|
462
|
+
position: FILTER_POSITION_INLINE,
|
463
|
+
marker: {
|
464
|
+
open: "{",
|
465
|
+
close: "}",
|
466
|
+
},
|
467
|
+
},
|
468
|
+
classes: {
|
469
|
+
badge: "monster-badge-primary",
|
470
|
+
statusOrRemoveBadge: "empty",
|
471
|
+
},
|
472
|
+
mapping: {
|
473
|
+
selector: "*",
|
474
|
+
labelTemplate: "",
|
475
|
+
valueTemplate: "",
|
476
|
+
filter: null
|
477
|
+
},
|
478
|
+
ignoreValues: [undefined, null, ""],
|
479
|
+
formatter: {
|
480
|
+
selection: buildSelectionLabel,
|
481
|
+
},
|
482
|
+
templates: {
|
483
|
+
main: getTemplate(),
|
484
|
+
},
|
485
|
+
templateMapping: {
|
486
|
+
/** with the attribute `data-monster-selected-template` the template for the selected options can be defined. */
|
487
|
+
selected: getSelectionTemplate(),
|
488
|
+
},
|
489
|
+
|
490
|
+
popper: {
|
491
|
+
placement: "bottom",
|
492
|
+
middleware: ["flip", "offset:1"],
|
493
|
+
},
|
494
|
+
},
|
495
|
+
initOptionsFromArguments.call(this),
|
496
|
+
);
|
497
|
+
}
|
498
|
+
|
499
|
+
/**
|
500
|
+
* @return {Select}
|
501
|
+
*/
|
502
|
+
[assembleMethodSymbol]() {
|
503
|
+
const self = this;
|
504
|
+
super[assembleMethodSymbol]();
|
505
|
+
|
506
|
+
initControlReferences.call(self);
|
507
|
+
initEventHandler.call(self);
|
508
|
+
|
509
|
+
let lazyLoadFlag = self.getOption("features.lazyLoad", false);
|
510
|
+
let remoteFilterFlag = getFilterMode.call(this) === FILTER_MODE_REMOTE;
|
511
|
+
|
512
|
+
if (getFilterMode.call(this) === FILTER_MODE_REMOTE) {
|
513
|
+
self.getOption("features.lazyLoad", false);
|
514
|
+
if (lazyLoadFlag === true) {
|
515
|
+
addErrorAttribute(this, "lazyLoad is not supported with remote filter");
|
516
|
+
lazyLoadFlag = false;
|
517
|
+
}
|
518
|
+
}
|
519
|
+
|
520
|
+
if (self.hasAttribute("value")) {
|
521
|
+
new Processing(10, () => {
|
522
|
+
this.value = this.getAttribute("value");
|
523
|
+
})
|
524
|
+
.run()
|
525
|
+
.catch((e) => {
|
526
|
+
addErrorAttribute(this, e);
|
527
|
+
});
|
528
|
+
}
|
529
|
+
|
530
|
+
if (self.getOption("url") !== null) {
|
531
|
+
if (lazyLoadFlag || remoteFilterFlag) {
|
532
|
+
lookupSelection.call(self);
|
533
|
+
} else {
|
534
|
+
self.fetch().catch((e) => {
|
535
|
+
addErrorAttribute(self, e);
|
536
|
+
});
|
537
|
+
}
|
538
|
+
}
|
539
|
+
|
540
|
+
requestAnimationFrame(() => {
|
541
|
+
let lastValue = self.value;
|
542
|
+
self[internalSymbol].attachObserver(
|
543
|
+
new Observer(function () {
|
544
|
+
if (isObject(this) && this instanceof ProxyObserver) {
|
545
|
+
const n = this.getSubject()?.options?.value;
|
546
|
+
|
547
|
+
if (lastValue !== n && n !== undefined) {
|
548
|
+
lastValue = n;
|
549
|
+
setSelection
|
550
|
+
.call(self, n)
|
551
|
+
.then(() => {
|
552
|
+
})
|
553
|
+
.catch((e) => {
|
554
|
+
addErrorAttribute(self, e);
|
555
|
+
});
|
556
|
+
}
|
557
|
+
}
|
558
|
+
}),
|
559
|
+
);
|
560
|
+
|
561
|
+
areOptionsAvailableAndInit.call(self);
|
562
|
+
});
|
563
|
+
|
564
|
+
return this;
|
565
|
+
}
|
566
|
+
|
567
|
+
/**
|
568
|
+
*
|
569
|
+
* @return {*}
|
570
|
+
* @throws {Error} storeFetchedData is not enabled
|
571
|
+
* @since 3.66.0
|
572
|
+
*/
|
573
|
+
getLastFetchedData() {
|
574
|
+
if (this.getOption("features.storeFetchedData") === false) {
|
575
|
+
throw new Error("storeFetchedData is not enabled");
|
576
|
+
}
|
577
|
+
|
578
|
+
return this?.[lastFetchedDataSymbol];
|
579
|
+
}
|
580
|
+
|
581
|
+
/**
|
582
|
+
* The Button.click() method simulates a click on the internal button element.
|
583
|
+
*
|
584
|
+
* @since 3.27.0
|
585
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
|
586
|
+
*/
|
587
|
+
click() {
|
588
|
+
if (this.getOption("disabled") === true) {
|
589
|
+
return;
|
590
|
+
}
|
591
|
+
|
592
|
+
toggle.call(this);
|
593
|
+
}
|
594
|
+
|
595
|
+
/**
|
596
|
+
* The Button.focus() method sets focus on the internal button element.
|
597
|
+
*
|
598
|
+
* @since 3.27.0
|
599
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
|
600
|
+
*/
|
601
|
+
focus(options) {
|
602
|
+
if (this.getOption("disabled") === true) {
|
603
|
+
return;
|
604
|
+
}
|
605
|
+
|
606
|
+
new Processing(() => {
|
607
|
+
gatherState.call(this);
|
608
|
+
focusFilter.call(this, options);
|
609
|
+
})
|
610
|
+
.run()
|
611
|
+
.catch((e) => {
|
612
|
+
addErrorAttribute(this, e);
|
613
|
+
});
|
614
|
+
}
|
615
|
+
|
616
|
+
/**
|
617
|
+
* The Button.blur() method removes focus from the internal button element.
|
618
|
+
* @link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur
|
619
|
+
*/
|
620
|
+
blur() {
|
621
|
+
new Processing(() => {
|
622
|
+
gatherState.call(this);
|
623
|
+
blurFilter.call(this);
|
624
|
+
})
|
625
|
+
.run()
|
626
|
+
.catch((e) => {
|
627
|
+
addErrorAttribute(this, e);
|
628
|
+
});
|
629
|
+
}
|
630
|
+
|
631
|
+
/**
|
632
|
+
* If no url is specified, the options are taken from the Component itself.
|
633
|
+
*
|
634
|
+
* @param {string|URL} url URL to fetch the options
|
635
|
+
* @return {Promise}
|
636
|
+
*/
|
637
|
+
fetch(url) {
|
638
|
+
return fetchIt.call(this, url);
|
639
|
+
}
|
640
|
+
|
641
|
+
/**
|
642
|
+
* @return {void}
|
643
|
+
*/
|
644
|
+
connectedCallback() {
|
645
|
+
super.connectedCallback();
|
646
|
+
const document = getDocument();
|
647
|
+
|
648
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
649
|
+
// close on outside ui-events
|
650
|
+
document.addEventListener(type, this[closeEventHandler]);
|
651
|
+
}
|
652
|
+
|
653
|
+
parseSlotsToOptions.call(this);
|
654
|
+
attachResizeObserver.call(this);
|
655
|
+
updatePopper.call(this);
|
656
|
+
|
657
|
+
new Processing(() => {
|
658
|
+
gatherState.call(this);
|
659
|
+
focusFilter.call(this);
|
660
|
+
})
|
661
|
+
.run()
|
662
|
+
.catch((e) => {
|
663
|
+
addErrorAttribute(this, e);
|
664
|
+
});
|
665
|
+
}
|
666
|
+
|
667
|
+
/**
|
668
|
+
* @return {void}
|
669
|
+
*/
|
670
|
+
disconnectedCallback() {
|
671
|
+
super.disconnectedCallback();
|
672
|
+
const document = getDocument();
|
673
|
+
|
674
|
+
// close on outside ui-events
|
675
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
676
|
+
document.removeEventListener(type, this[closeEventHandler]);
|
677
|
+
}
|
678
|
+
|
679
|
+
disconnectResizeObserver.call(this);
|
680
|
+
}
|
681
|
+
|
682
|
+
/**
|
683
|
+
* Import Select Options from dataset
|
684
|
+
* Not to be confused with the control defaults/options
|
685
|
+
*
|
686
|
+
* @param {array|object|Map|Set} data
|
687
|
+
* @return {Select}
|
688
|
+
* @throws {Error} map is not iterable
|
689
|
+
* @throws {Error} missing label configuration
|
690
|
+
* @fires monster-options-set this event is fired when the options are set
|
691
|
+
*/
|
692
|
+
importOptions(data) {
|
693
|
+
const mappingOptions = this.getOption("mapping", {});
|
694
|
+
const selector = mappingOptions?.["selector"];
|
695
|
+
const labelTemplate = mappingOptions?.["labelTemplate"];
|
696
|
+
const valueTemplate = mappingOptions?.["valueTemplate"];
|
697
|
+
const filter = mappingOptions?.["filter"];
|
698
|
+
|
699
|
+
let flag = false;
|
700
|
+
if (labelTemplate === "") {
|
701
|
+
addErrorAttribute(this, "empty label template");
|
702
|
+
flag = true;
|
703
|
+
}
|
704
|
+
|
705
|
+
if (valueTemplate === "") {
|
706
|
+
addErrorAttribute(this, "empty value template");
|
707
|
+
flag = true;
|
708
|
+
}
|
709
|
+
|
710
|
+
if (flag === true) {
|
711
|
+
throw new Error("missing label configuration");
|
712
|
+
}
|
713
|
+
|
714
|
+
const map = buildMap(data, selector, labelTemplate, valueTemplate, filter);
|
715
|
+
|
716
|
+
const options = [];
|
717
|
+
|
718
|
+
if (!isIterable(map)) {
|
719
|
+
throw new Error("map is not iterable");
|
720
|
+
}
|
721
|
+
|
722
|
+
const visibility = "visible";
|
723
|
+
|
724
|
+
map.forEach((label, value) => {
|
725
|
+
options.push({
|
726
|
+
value,
|
727
|
+
label,
|
728
|
+
visibility,
|
729
|
+
data: map.get(value),
|
730
|
+
});
|
731
|
+
});
|
732
|
+
|
733
|
+
runAsOptionLengthChanged.call(this, map.size);
|
734
|
+
this.setOption("options", options);
|
735
|
+
|
736
|
+
fireCustomEvent(this, "monster-options-set", {
|
737
|
+
options,
|
738
|
+
});
|
739
|
+
|
740
|
+
setTimeout(() => {
|
741
|
+
setSelection
|
742
|
+
.call(this, this.getOption("selection"))
|
743
|
+
.then(() => {
|
744
|
+
})
|
745
|
+
.catch((e) => {
|
746
|
+
addErrorAttribute(this, e);
|
747
|
+
});
|
748
|
+
}, 10);
|
749
|
+
|
750
|
+
return this;
|
751
|
+
}
|
752
|
+
|
753
|
+
/**
|
754
|
+
* @private
|
755
|
+
* @return {Select}
|
756
|
+
*/
|
757
|
+
calcAndSetOptionsDimension() {
|
758
|
+
calcAndSetOptionsDimension.call(this);
|
759
|
+
return this;
|
760
|
+
}
|
761
|
+
|
762
|
+
/**
|
763
|
+
*
|
764
|
+
* @return {string}
|
765
|
+
*/
|
766
|
+
static getTag() {
|
767
|
+
return "monster-select";
|
768
|
+
}
|
769
|
+
|
770
|
+
/**
|
771
|
+
*
|
772
|
+
* @return {CSSStyleSheet[]}
|
773
|
+
*/
|
774
|
+
static getCSSStyleSheet() {
|
775
|
+
return [SelectStyleSheet];
|
776
|
+
}
|
763
777
|
}
|
764
778
|
|
765
779
|
/**
|
@@ -767,285 +781,285 @@ class Select extends CustomControl {
|
|
767
781
|
* @returns {object}
|
768
782
|
*/
|
769
783
|
function getTranslations() {
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
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
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
784
|
+
const locale = getLocaleOfDocument();
|
785
|
+
switch (locale.language) {
|
786
|
+
case "de":
|
787
|
+
return {
|
788
|
+
"cannot-be-loaded": "Kann nicht geladen werden",
|
789
|
+
"no-options-available": "Keine Optionen verfügbar.",
|
790
|
+
"click-to-load-options": "Klicken, um Optionen zu laden.",
|
791
|
+
"select-an-option": "Wähle eine Option",
|
792
|
+
"summary-text": {
|
793
|
+
zero: "Keine Einträge ausgewählt",
|
794
|
+
one: '<span class="monster-badge-primary-pill">1</span> Eintrag ausgewählt',
|
795
|
+
other:
|
796
|
+
'<span class="monster-badge-primary-pill">${count}</span> Einträge ausgewählt',
|
797
|
+
},
|
798
|
+
"no-options": "Leider gibt es keine Optionen in der Liste.",
|
799
|
+
"no-options-found":
|
800
|
+
"Keine Optionen in der Liste verfügbar. Bitte ändern Sie den Filter.",
|
801
|
+
};
|
802
|
+
case "fr":
|
803
|
+
return {
|
804
|
+
"cannot-be-loaded": "Impossible de charger",
|
805
|
+
"no-options-available": "Aucune option disponible.",
|
806
|
+
"click-to-load-options": "Cliquez pour charger les options.",
|
807
|
+
"select-an-option": "Sélectionnez une option",
|
808
|
+
"summary-text": {
|
809
|
+
zero: "Aucune entrée sélectionnée",
|
810
|
+
one: '<span class="monster-badge-primary-pill">1</span> entrée sélectionnée',
|
811
|
+
other:
|
812
|
+
'<span class="monster-badge-primary-pill">${count}</span> entrées sélectionnées',
|
813
|
+
},
|
814
|
+
"no-options":
|
815
|
+
"Malheureusement, il n'y a pas d'options disponibles dans la liste.",
|
816
|
+
"no-options-found":
|
817
|
+
"Aucune option disponible dans la liste. Veuillez modifier le filtre.",
|
818
|
+
};
|
819
|
+
|
820
|
+
case "sp":
|
821
|
+
return {
|
822
|
+
"cannot-be-loaded": "No se puede cargar",
|
823
|
+
"no-options-available": "No hay opciones disponibles.",
|
824
|
+
"click-to-load-options": "Haga clic para cargar opciones.",
|
825
|
+
"select-an-option": "Seleccione una opción",
|
826
|
+
"summary-text": {
|
827
|
+
zero: "No se seleccionaron entradas",
|
828
|
+
one: '<span class="monster-badge-primary-pill">1</span> entrada seleccionada',
|
829
|
+
other:
|
830
|
+
'<span class="monster-badge-primary-pill">${count}</span> entradas seleccionadas',
|
831
|
+
},
|
832
|
+
"no-options":
|
833
|
+
"Desafortunadamente, no hay opciones disponibles en la lista.",
|
834
|
+
"no-options-found":
|
835
|
+
"No hay opciones disponibles en la lista. Considere modificar el filtro.",
|
836
|
+
};
|
837
|
+
case "it":
|
838
|
+
return {
|
839
|
+
"cannot-be-loaded": "Non può essere caricato",
|
840
|
+
"no-options-available": "Nessuna opzione disponibile.",
|
841
|
+
"click-to-load-options": "Clicca per caricare le opzioni.",
|
842
|
+
"select-an-option": "Seleziona un'opzione",
|
843
|
+
"summary-text": {
|
844
|
+
zero: "Nessuna voce selezionata",
|
845
|
+
one: '<span class="monster-badge-primary-pill">1</span> voce selezionata',
|
846
|
+
other:
|
847
|
+
'<span class="monster-badge-primary-pill">${count}</span> voci selezionate',
|
848
|
+
},
|
849
|
+
"no-options": "Purtroppo, non ci sono opzioni disponibili nella lista.",
|
850
|
+
"no-options-found":
|
851
|
+
"Nessuna opzione disponibile nella lista. Si prega di modificare il filtro.",
|
852
|
+
};
|
853
|
+
case "pl":
|
854
|
+
return {
|
855
|
+
"cannot-be-loaded": "Nie można załadować",
|
856
|
+
"no-options-available": "Brak dostępnych opcji.",
|
857
|
+
"click-to-load-options": "Kliknij, aby załadować opcje.",
|
858
|
+
"select-an-option": "Wybierz opcję",
|
859
|
+
"summary-text": {
|
860
|
+
zero: "Nie wybrano żadnych wpisów",
|
861
|
+
one: '<span class="monster-badge-primary-pill">1</span> wpis został wybrany',
|
862
|
+
other:
|
863
|
+
'<span class="monster-badge-primary-pill">${count}</span> wpisy zostały wybrane',
|
864
|
+
},
|
865
|
+
"no-options": "Niestety, nie ma dostępnych opcji na liście.",
|
866
|
+
"no-options-found":
|
867
|
+
"Brak dostępnych opcji na liście. Rozważ zmianę filtra.",
|
868
|
+
};
|
869
|
+
case "no":
|
870
|
+
return {
|
871
|
+
"cannot-be-loaded": "Kan ikke lastes",
|
872
|
+
"no-options-available": "Ingen alternativer tilgjengelig.",
|
873
|
+
"click-to-load-options": "Klikk for å laste alternativer.",
|
874
|
+
"select-an-option": "Velg et alternativ",
|
875
|
+
"summary-text": {
|
876
|
+
zero: "Ingen oppføringer ble valgt",
|
877
|
+
one: '<span class="monster-badge-primary-pill">1</span> oppføring valgt',
|
878
|
+
other:
|
879
|
+
'<span class="monster-badge-primary-pill">${count}</span> oppføringer valgt',
|
880
|
+
},
|
881
|
+
"no-options":
|
882
|
+
"Dessverre er det ingen alternativer tilgjengelig i listen.",
|
883
|
+
"no-options-found":
|
884
|
+
"Ingen alternativer tilgjengelig på listen. Vurder å endre filteret.",
|
885
|
+
};
|
886
|
+
|
887
|
+
case "dk":
|
888
|
+
return {
|
889
|
+
"cannot-be-loaded": "Kan ikke indlæses",
|
890
|
+
"no-options-available": "Ingen muligheder tilgængelige.",
|
891
|
+
"click-to-load-options": "Klik for at indlæse muligheder.",
|
892
|
+
"select-an-option": "Vælg en mulighed",
|
893
|
+
"summary-text": {
|
894
|
+
zero: "Ingen indlæg blev valgt",
|
895
|
+
one: '<span class="monster-badge-primary-pill">1</span> indlæg blev valgt',
|
896
|
+
other:
|
897
|
+
'<span class="monster-badge-primary-pill">${count}</span> indlæg blev valgt',
|
898
|
+
},
|
899
|
+
"no-options":
|
900
|
+
"Desværre er der ingen muligheder tilgængelige på listen.",
|
901
|
+
"no-options-found":
|
902
|
+
"Ingen muligheder tilgængelige på listen. Overvej at ændre filteret.",
|
903
|
+
};
|
904
|
+
case "sw":
|
905
|
+
return {
|
906
|
+
"cannot-be-loaded": "Kan inte laddas",
|
907
|
+
"no-options-available": "Inga alternativ tillgängliga.",
|
908
|
+
"click-to-load-options": "Klicka för att ladda alternativ.",
|
909
|
+
"select-an-option": "Välj ett alternativ",
|
910
|
+
"summary-text": {
|
911
|
+
zero: "Inga poster valdes",
|
912
|
+
one: '<span class="monster-badge-primary-pill">1</span> post valdes',
|
913
|
+
other:
|
914
|
+
'<span class="monster-badge-primary-pill">${count}</span> poster valdes',
|
915
|
+
},
|
916
|
+
"no-options": "Tyvärr finns det inga alternativ tillgängliga i listan.",
|
917
|
+
"no-options-found":
|
918
|
+
"Inga alternativ finns tillgängliga i listan. Överväg att modifiera filtret.",
|
919
|
+
};
|
920
|
+
|
921
|
+
default:
|
922
|
+
case "en":
|
923
|
+
return {
|
924
|
+
"cannot-be-loaded": "Cannot be loaded",
|
925
|
+
"no-options-available": "No options available.",
|
926
|
+
"click-to-load-options": "Click to load options.",
|
927
|
+
"select-an-option": "Select an option",
|
928
|
+
"summary-text": {
|
929
|
+
zero: "No entries were selected",
|
930
|
+
one: '<span class="monster-badge-primary-pill">1</span> entry was selected',
|
931
|
+
other:
|
932
|
+
'<span class="monster-badge-primary-pill">${count}</span> entries were selected',
|
933
|
+
},
|
934
|
+
"no-options":
|
935
|
+
"Unfortunately, there are no options available in the list.",
|
936
|
+
"no-options-found":
|
937
|
+
"No options are available in the list. Please consider modifying the filter.",
|
938
|
+
};
|
939
|
+
}
|
926
940
|
}
|
927
941
|
|
928
942
|
/**
|
929
943
|
* @private
|
930
944
|
*/
|
931
945
|
function lookupSelection() {
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
946
|
+
const self = this;
|
947
|
+
|
948
|
+
setTimeout(() => {
|
949
|
+
const selection = self.getOption("selection");
|
950
|
+
if (selection.length === 0) {
|
951
|
+
return;
|
952
|
+
}
|
953
|
+
|
954
|
+
if (self[isLoadingSymbol] === true) {
|
955
|
+
return;
|
956
|
+
}
|
957
|
+
|
958
|
+
if (self[lazyLoadDoneSymbol] === true) {
|
959
|
+
return;
|
960
|
+
}
|
961
|
+
|
962
|
+
let url = self.getOption("url");
|
963
|
+
let lookupUrl = self.getOption("lookup.url");
|
964
|
+
if (lookupUrl !== null) {
|
965
|
+
url = lookupUrl;
|
966
|
+
}
|
967
|
+
|
968
|
+
if (this.getOption("lookup.grouping") === true) {
|
969
|
+
filterFromRemoteByValue
|
970
|
+
.call(
|
971
|
+
self,
|
972
|
+
url,
|
973
|
+
selection.map((s) => s?.["value"]),
|
974
|
+
)
|
975
|
+
.catch((e) => {
|
976
|
+
addErrorAttribute(self, e);
|
977
|
+
});
|
978
|
+
return;
|
979
|
+
}
|
980
|
+
|
981
|
+
for (const s of selection) {
|
982
|
+
if (s?.["value"]) {
|
983
|
+
filterFromRemoteByValue.call(self, url, s?.["value"]).catch((e) => {
|
984
|
+
addErrorAttribute(self, e);
|
985
|
+
});
|
986
|
+
}
|
987
|
+
}
|
988
|
+
}, 100);
|
975
989
|
}
|
976
990
|
|
977
991
|
function fetchIt(url, controlOptions) {
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
992
|
+
if (url instanceof URL) {
|
993
|
+
url = url.toString();
|
994
|
+
}
|
995
|
+
|
996
|
+
if (url !== undefined && url !== null) {
|
997
|
+
url = validateString(url);
|
998
|
+
} else {
|
999
|
+
url = this.getOption("url");
|
1000
|
+
if (url === null) {
|
1001
|
+
return Promise.reject(new Error("No url defined"));
|
1002
|
+
}
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
return new Promise((resolve, reject) => {
|
1006
|
+
setStatusOrRemoveBadges.call(this, "loading");
|
1007
|
+
|
1008
|
+
new Processing(10, () => {
|
1009
|
+
fetchData
|
1010
|
+
.call(this, url)
|
1011
|
+
.then((map) => {
|
1012
|
+
if (
|
1013
|
+
isObject(map) ||
|
1014
|
+
isArray(map) ||
|
1015
|
+
map instanceof Set ||
|
1016
|
+
map instanceof Map
|
1017
|
+
) {
|
1018
|
+
try {
|
1019
|
+
this.importOptions(map);
|
1020
|
+
} catch (e) {
|
1021
|
+
setStatusOrRemoveBadges.call(this, "error");
|
1022
|
+
reject(e);
|
1023
|
+
return;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
this[lastFetchedDataSymbol] = map;
|
1027
|
+
|
1028
|
+
let result;
|
1029
|
+
const selection = this.getOption("selection");
|
1030
|
+
let newValue = [];
|
1031
|
+
if (selection) {
|
1032
|
+
newValue = selection;
|
1033
|
+
} else if (this.hasAttribute("value")) {
|
1034
|
+
newValue = this.getAttribute("value");
|
1035
|
+
}
|
1036
|
+
|
1037
|
+
result = setSelection.call(this, newValue);
|
1038
|
+
requestAnimationFrame(() => {
|
1039
|
+
checkOptionState.call(this);
|
1040
|
+
setStatusOrRemoveBadges.call(this, "closed");
|
1041
|
+
updatePopper.call(this);
|
1042
|
+
resolve(result);
|
1043
|
+
});
|
1044
|
+
|
1045
|
+
return;
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
setStatusOrRemoveBadges.call(this, "error");
|
1049
|
+
reject(new Error("invalid response"));
|
1050
|
+
})
|
1051
|
+
.catch((e) => {
|
1052
|
+
setStatusOrRemoveBadges.call(this, "error");
|
1053
|
+
reject(e);
|
1054
|
+
});
|
1055
|
+
})
|
1056
|
+
.run()
|
1057
|
+
.catch((e) => {
|
1058
|
+
setStatusOrRemoveBadges.call(this, "error");
|
1059
|
+
addErrorAttribute(this, e);
|
1060
|
+
reject(e);
|
1061
|
+
});
|
1062
|
+
});
|
1049
1063
|
}
|
1050
1064
|
|
1051
1065
|
/**
|
@@ -1060,68 +1074,68 @@ function fetchIt(url, controlOptions) {
|
|
1060
1074
|
* @return {object}
|
1061
1075
|
*/
|
1062
1076
|
function initOptionsFromArguments() {
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1077
|
+
const options = {};
|
1078
|
+
|
1079
|
+
const template = this.getAttribute("data-monster-selected-template");
|
1080
|
+
if (isString(template)) {
|
1081
|
+
if (!options["templateMapping"]) options["templateMapping"] = {};
|
1082
|
+
|
1083
|
+
switch (template) {
|
1084
|
+
case "summary":
|
1085
|
+
case "default":
|
1086
|
+
options["templateMapping"]["selected"] = getSummaryTemplate();
|
1087
|
+
break;
|
1088
|
+
case "selected":
|
1089
|
+
options["templateMapping"]["selected"] = getSelectionTemplate();
|
1090
|
+
break;
|
1091
|
+
default:
|
1092
|
+
addErrorAttribute(this, "invalid template, use summary or selected");
|
1093
|
+
}
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
return options;
|
1083
1097
|
}
|
1084
1098
|
|
1085
1099
|
/**
|
1086
1100
|
* @private
|
1087
1101
|
*/
|
1088
1102
|
function attachResizeObserver() {
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1103
|
+
// against flickering
|
1104
|
+
this[resizeObserverSymbol] = new ResizeObserver((entries) => {
|
1105
|
+
if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
|
1106
|
+
try {
|
1107
|
+
this[timerCallbackSymbol].touch();
|
1108
|
+
return;
|
1109
|
+
} catch (e) {
|
1110
|
+
delete this[timerCallbackSymbol];
|
1111
|
+
}
|
1112
|
+
}
|
1113
|
+
|
1114
|
+
this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
|
1115
|
+
updatePopper.call(this);
|
1116
|
+
delete this[timerCallbackSymbol];
|
1117
|
+
});
|
1118
|
+
});
|
1119
|
+
|
1120
|
+
requestAnimationFrame(() => {
|
1121
|
+
let parent = this.parentNode;
|
1122
|
+
while (!(parent instanceof HTMLElement) && parent !== null) {
|
1123
|
+
parent = parent.parentNode;
|
1124
|
+
}
|
1125
|
+
|
1126
|
+
if (parent instanceof HTMLElement) {
|
1127
|
+
this[resizeObserverSymbol].observe(parent);
|
1128
|
+
}
|
1129
|
+
});
|
1116
1130
|
}
|
1117
1131
|
|
1118
1132
|
/**
|
1119
1133
|
* @private
|
1120
1134
|
*/
|
1121
1135
|
function disconnectResizeObserver() {
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1136
|
+
if (this[resizeObserverSymbol] instanceof ResizeObserver) {
|
1137
|
+
this[resizeObserverSymbol].disconnect();
|
1138
|
+
}
|
1125
1139
|
}
|
1126
1140
|
|
1127
1141
|
/**
|
@@ -1129,7 +1143,7 @@ function disconnectResizeObserver() {
|
|
1129
1143
|
* @returns {string}
|
1130
1144
|
*/
|
1131
1145
|
function getSelectionTemplate() {
|
1132
|
-
|
1146
|
+
return `<div data-monster-role="selection" part="selection"
|
1133
1147
|
data-monster-insert="selection path:selection" role="search"
|
1134
1148
|
><input type="text" role="searchbox"
|
1135
1149
|
part="inline-filter" name="inline-filter"
|
@@ -1145,7 +1159,7 @@ function getSelectionTemplate() {
|
|
1145
1159
|
* @returns {string}
|
1146
1160
|
*/
|
1147
1161
|
function getSummaryTemplate() {
|
1148
|
-
|
1162
|
+
return `<div data-monster-role="selection" role="search" part="summary">
|
1149
1163
|
<input type="text" role="searchbox"
|
1150
1164
|
part="inline-filter" name="inline-filter"
|
1151
1165
|
data-monster-role="filter"
|
@@ -1161,35 +1175,35 @@ function getSummaryTemplate() {
|
|
1161
1175
|
* @private
|
1162
1176
|
*/
|
1163
1177
|
function parseSlotsToOptions() {
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1178
|
+
let options = this.getOption("options");
|
1179
|
+
if (!isIterable(options)) {
|
1180
|
+
options = [];
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
let counter = 1;
|
1184
|
+
getSlottedElements.call(this, "div").forEach((node) => {
|
1185
|
+
let value = (counter++).toString();
|
1186
|
+
let visibility = "visible";
|
1187
|
+
|
1188
|
+
if (node.hasAttribute("data-monster-value")) {
|
1189
|
+
value = node.getAttribute("data-monster-value");
|
1190
|
+
}
|
1191
|
+
|
1192
|
+
let label = node.outerHTML;
|
1193
|
+
|
1194
|
+
if (node.style.display === "none") {
|
1195
|
+
visibility = "hidden";
|
1196
|
+
}
|
1197
|
+
|
1198
|
+
options.push({
|
1199
|
+
value,
|
1200
|
+
label,
|
1201
|
+
visibility,
|
1202
|
+
});
|
1203
|
+
});
|
1204
|
+
|
1205
|
+
runAsOptionLengthChanged.call(this, options.length);
|
1206
|
+
this.setOption("options", options);
|
1193
1207
|
}
|
1194
1208
|
|
1195
1209
|
/**
|
@@ -1199,39 +1213,39 @@ function parseSlotsToOptions() {
|
|
1199
1213
|
* @param {int} targetLength
|
1200
1214
|
*/
|
1201
1215
|
function runAsOptionLengthChanged(targetLength) {
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1216
|
+
const self = this;
|
1217
|
+
|
1218
|
+
if (!self[optionsElementSymbol]) {
|
1219
|
+
return;
|
1220
|
+
}
|
1221
|
+
|
1222
|
+
const callback = function (mutationsList, observer) {
|
1223
|
+
const run = false;
|
1224
|
+
for (const mutation of mutationsList) {
|
1225
|
+
if (mutation.type === "childList") {
|
1226
|
+
const run = true;
|
1227
|
+
break;
|
1228
|
+
}
|
1229
|
+
}
|
1230
|
+
|
1231
|
+
if (run === true) {
|
1232
|
+
const nodes = self[optionsElementSymbol].querySelectorAll(
|
1233
|
+
`div[${ATTRIBUTE_ROLE}=option]`,
|
1234
|
+
);
|
1235
|
+
|
1236
|
+
if (nodes.length === targetLength) {
|
1237
|
+
checkOptionState.call(self);
|
1238
|
+
observer.disconnect();
|
1239
|
+
}
|
1240
|
+
}
|
1241
|
+
};
|
1242
|
+
|
1243
|
+
const observer = new MutationObserver(callback);
|
1244
|
+
observer.observe(self[optionsElementSymbol], {
|
1245
|
+
attributes: false,
|
1246
|
+
childList: true,
|
1247
|
+
subtree: true,
|
1248
|
+
});
|
1235
1249
|
}
|
1236
1250
|
|
1237
1251
|
/**
|
@@ -1240,38 +1254,38 @@ function runAsOptionLengthChanged(targetLength) {
|
|
1240
1254
|
* @return {*}
|
1241
1255
|
*/
|
1242
1256
|
function buildSelectionLabel(value) {
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1257
|
+
const options = this.getOption("options");
|
1258
|
+
|
1259
|
+
for (let i = 0; i < options.length; i++) {
|
1260
|
+
let o = options?.[i];
|
1261
|
+
let l, v, v2;
|
1262
|
+
|
1263
|
+
if (this.getOption("features.useStrictValueComparison") === true) {
|
1264
|
+
v = value;
|
1265
|
+
} else {
|
1266
|
+
v = `${value}`;
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
if (isPrimitive(o) && o === value) {
|
1270
|
+
return o;
|
1271
|
+
} else if (!isObject(o)) {
|
1272
|
+
continue;
|
1273
|
+
}
|
1274
|
+
|
1275
|
+
if (this.getOption("features.useStrictValueComparison") === true) {
|
1276
|
+
l = o?.["label"];
|
1277
|
+
v2 = o?.["value"];
|
1278
|
+
} else {
|
1279
|
+
l = `${o?.["label"]}`;
|
1280
|
+
v2 = `${o?.["value"]}`;
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
if (v2 === v) {
|
1284
|
+
return l;
|
1285
|
+
}
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
return undefined;
|
1275
1289
|
}
|
1276
1290
|
|
1277
1291
|
/**
|
@@ -1281,17 +1295,17 @@ function buildSelectionLabel(value) {
|
|
1281
1295
|
* @throws {Error} no value found
|
1282
1296
|
*/
|
1283
1297
|
function getSelectionLabel(value) {
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1298
|
+
const callback = this.getOption("formatter.selection");
|
1299
|
+
if (isFunction(callback)) {
|
1300
|
+
const label = callback.call(this, value);
|
1301
|
+
if (isString(label)) return label;
|
1302
|
+
}
|
1289
1303
|
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1304
|
+
if (isString(value) || isInteger(value)) {
|
1305
|
+
return `${value}`;
|
1306
|
+
}
|
1293
1307
|
|
1294
|
-
|
1308
|
+
return this.getOption("labels.cannot-be-loaded", value);
|
1295
1309
|
}
|
1296
1310
|
|
1297
1311
|
/**
|
@@ -1299,25 +1313,25 @@ function getSelectionLabel(value) {
|
|
1299
1313
|
* @param {Event} event
|
1300
1314
|
*/
|
1301
1315
|
function handleToggleKeyboardEvents(event) {
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1316
|
+
switch (event?.["code"]) {
|
1317
|
+
case "Escape":
|
1318
|
+
toggle.call(this);
|
1319
|
+
event.preventDefault();
|
1320
|
+
break;
|
1321
|
+
case "Space":
|
1322
|
+
toggle.call(this);
|
1323
|
+
event.preventDefault();
|
1324
|
+
break;
|
1325
|
+
case "ArrowDown":
|
1326
|
+
show.call(this);
|
1327
|
+
activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
|
1328
|
+
event.preventDefault();
|
1329
|
+
break;
|
1330
|
+
case "ArrowUp":
|
1331
|
+
hide.call(this);
|
1332
|
+
event.preventDefault();
|
1333
|
+
break;
|
1334
|
+
}
|
1321
1335
|
}
|
1322
1336
|
|
1323
1337
|
/**
|
@@ -1327,32 +1341,32 @@ function handleToggleKeyboardEvents(event) {
|
|
1327
1341
|
* @this CustomElement
|
1328
1342
|
*/
|
1329
1343
|
function initOptionObserver() {
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1344
|
+
const self = this;
|
1345
|
+
|
1346
|
+
self.attachObserver(
|
1347
|
+
new Observer(function () {
|
1348
|
+
new Processing(() => {
|
1349
|
+
try {
|
1350
|
+
self.updateI18n();
|
1351
|
+
} catch (e) {
|
1352
|
+
addErrorAttribute(self, e);
|
1353
|
+
requestAnimationFrame(() => {
|
1354
|
+
setStatusOrRemoveBadges.call(self, "error");
|
1355
|
+
});
|
1356
|
+
}
|
1357
|
+
try {
|
1358
|
+
areOptionsAvailableAndInit.call(self);
|
1359
|
+
} catch (e) {
|
1360
|
+
addErrorAttribute(self, e);
|
1361
|
+
requestAnimationFrame(() => {
|
1362
|
+
setStatusOrRemoveBadges.call(self, "error");
|
1363
|
+
});
|
1364
|
+
}
|
1365
|
+
|
1366
|
+
setSummaryAndControlText.call(self);
|
1367
|
+
}).run();
|
1368
|
+
}),
|
1369
|
+
);
|
1356
1370
|
}
|
1357
1371
|
|
1358
1372
|
/**
|
@@ -1360,16 +1374,17 @@ function initOptionObserver() {
|
|
1360
1374
|
* @returns {Translations}
|
1361
1375
|
*/
|
1362
1376
|
function getDefaultTranslation() {
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1377
|
+
const translation = new Translations("en").assignTranslations(
|
1378
|
+
this.getOption("labels", {}),
|
1379
|
+
);
|
1366
1380
|
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1381
|
+
try {
|
1382
|
+
const doc = getDocumentTranslations();
|
1383
|
+
translation.locale = doc.locale;
|
1384
|
+
} catch (e) {
|
1385
|
+
}
|
1371
1386
|
|
1372
|
-
|
1387
|
+
return translation;
|
1373
1388
|
}
|
1374
1389
|
|
1375
1390
|
/**
|
@@ -1377,36 +1392,36 @@ function getDefaultTranslation() {
|
|
1377
1392
|
* @return {string|*}
|
1378
1393
|
*/
|
1379
1394
|
function setSummaryAndControlText() {
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1395
|
+
const translations = getDefaultTranslation.call(this);
|
1396
|
+
const selections = this.getOption("selection");
|
1397
|
+
|
1398
|
+
const text = translations.getPluralRuleText(
|
1399
|
+
"summary-text",
|
1400
|
+
selections.length,
|
1401
|
+
"",
|
1402
|
+
);
|
1403
|
+
|
1404
|
+
const selectedText = new Formatter({
|
1405
|
+
count: String(selections.length),
|
1406
|
+
}).format(text);
|
1407
|
+
|
1408
|
+
this.setOption("messages.selected", selectedText);
|
1409
|
+
|
1410
|
+
const current = this.getOption("messages.control");
|
1411
|
+
const msg = this.getOption("labels.select-an-option");
|
1412
|
+
|
1413
|
+
if (
|
1414
|
+
current === "" ||
|
1415
|
+
current === undefined ||
|
1416
|
+
current === msg ||
|
1417
|
+
current === null
|
1418
|
+
) {
|
1419
|
+
if (selections.length === 0) {
|
1420
|
+
this.setOption("messages.control", msg);
|
1421
|
+
} else {
|
1422
|
+
this.setOption("messages.control", "");
|
1423
|
+
}
|
1424
|
+
}
|
1410
1425
|
}
|
1411
1426
|
|
1412
1427
|
/**
|
@@ -1414,9 +1429,9 @@ function setSummaryAndControlText() {
|
|
1414
1429
|
* @return {NodeList}
|
1415
1430
|
*/
|
1416
1431
|
function getOptionElements() {
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1432
|
+
return this[optionsElementSymbol].querySelectorAll(
|
1433
|
+
`[${ATTRIBUTE_ROLE}=option]`,
|
1434
|
+
);
|
1420
1435
|
}
|
1421
1436
|
|
1422
1437
|
/**
|
@@ -1440,75 +1455,75 @@ function getOptionElements() {
|
|
1440
1455
|
* @private
|
1441
1456
|
*/
|
1442
1457
|
function calcAndSetOptionsDimension() {
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1458
|
+
const options = getOptionElements.call(this);
|
1459
|
+
const container = this[optionsElementSymbol];
|
1460
|
+
if (!(container instanceof HTMLElement && options instanceof NodeList)) {
|
1461
|
+
return;
|
1462
|
+
}
|
1463
|
+
|
1464
|
+
let visible = 0;
|
1465
|
+
let optionHeight = 0;
|
1466
|
+
const max = this.getOption("showMaxOptions", 10);
|
1467
|
+
|
1468
|
+
let scrollFlag = false;
|
1469
|
+
for (const [, option] of Object.entries(options)) {
|
1470
|
+
const computedStyle = getGlobal().getComputedStyle(option);
|
1471
|
+
if (computedStyle.display === "none") continue;
|
1472
|
+
|
1473
|
+
let h = option.getBoundingClientRect().height;
|
1474
|
+
h += parseInt(computedStyle.getPropertyValue("margin-top"), 10);
|
1475
|
+
h += parseInt(computedStyle.getPropertyValue("margin-bottom"), 10);
|
1476
|
+
optionHeight += h;
|
1477
|
+
|
1478
|
+
visible++;
|
1479
|
+
|
1480
|
+
if (visible > max) {
|
1481
|
+
break;
|
1482
|
+
}
|
1483
|
+
}
|
1484
|
+
|
1485
|
+
if (visible > max) {
|
1486
|
+
visible = max;
|
1487
|
+
scrollFlag = true;
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
if (visible === 0) {
|
1491
|
+
if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
|
1492
|
+
this.setOption(
|
1493
|
+
"messages.emptyOptions",
|
1494
|
+
this.getOption("labels.no-options-available"),
|
1495
|
+
);
|
1496
|
+
} else {
|
1497
|
+
this.setOption(
|
1498
|
+
"messages.emptyOptions",
|
1499
|
+
this.getOption("labels.no-options-found"),
|
1500
|
+
);
|
1501
|
+
}
|
1502
|
+
this[noOptionsAvailableElementSymbol].classList.remove("d-none");
|
1503
|
+
} else {
|
1504
|
+
this[noOptionsAvailableElementSymbol].classList.add("d-none");
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
const styles = getGlobal().getComputedStyle(this[optionsElementSymbol]);
|
1508
|
+
let padding = parseInt(styles.getPropertyValue("padding-top"), 10);
|
1509
|
+
padding += parseInt(styles.getPropertyValue("padding-bottom"), 10);
|
1510
|
+
|
1511
|
+
let margin = parseInt(styles.getPropertyValue("margin-top"), 10);
|
1512
|
+
margin += parseInt(styles.getPropertyValue("margin-bottom"), 10);
|
1513
|
+
|
1514
|
+
const containerHeight = optionHeight + padding + margin;
|
1515
|
+
container.style.height = `${containerHeight}px`;
|
1516
|
+
|
1517
|
+
if (scrollFlag === true) {
|
1518
|
+
container.style.overflowY = "scroll";
|
1519
|
+
} else {
|
1520
|
+
container.style.overflowY = "auto";
|
1521
|
+
}
|
1522
|
+
|
1523
|
+
const domRect = this[controlElementSymbol].getBoundingClientRect();
|
1524
|
+
|
1525
|
+
this[popperElementSymbol].style.width = `${domRect.width}px`;
|
1526
|
+
container.style.overflowX = "auto";
|
1512
1527
|
}
|
1513
1528
|
|
1514
1529
|
/**
|
@@ -1517,126 +1532,126 @@ function calcAndSetOptionsDimension() {
|
|
1517
1532
|
* @throws {Error} no shadow-root is defined
|
1518
1533
|
*/
|
1519
1534
|
function activateCurrentOption(direction) {
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1535
|
+
if (!this.shadowRoot) {
|
1536
|
+
throw new Error("no shadow-root is defined");
|
1537
|
+
}
|
1538
|
+
|
1539
|
+
let focused = this.shadowRoot.querySelector(`[${ATTRIBUTE_PREFIX}focused]`);
|
1540
|
+
|
1541
|
+
if (
|
1542
|
+
!(focused instanceof HTMLElement) ||
|
1543
|
+
focused.matches("[data-monster-visibility=hidden]")
|
1544
|
+
) {
|
1545
|
+
for (const [, e] of Object.entries(
|
1546
|
+
this.shadowRoot.querySelectorAll(`[${ATTRIBUTE_ROLE}=option]`),
|
1547
|
+
)) {
|
1548
|
+
if (e.matches("[data-monster-visibility=visible]")) {
|
1549
|
+
focused = e;
|
1550
|
+
break;
|
1551
|
+
}
|
1552
|
+
}
|
1553
|
+
} else {
|
1554
|
+
if (direction === FOCUS_DIRECTION_DOWN) {
|
1555
|
+
while (focused.nextSibling) {
|
1556
|
+
focused = focused.nextSibling;
|
1557
|
+
|
1558
|
+
if (
|
1559
|
+
focused instanceof HTMLElement &&
|
1560
|
+
focused.hasAttribute(ATTRIBUTE_ROLE) &&
|
1561
|
+
focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
|
1562
|
+
focused.matches("[data-monster-visibility=visible]") &&
|
1563
|
+
focused.matches(":not([data-monster-filtered=true])")
|
1564
|
+
) {
|
1565
|
+
break;
|
1566
|
+
}
|
1567
|
+
}
|
1568
|
+
} else {
|
1569
|
+
let found = false;
|
1570
|
+
while (focused.previousSibling) {
|
1571
|
+
focused = focused.previousSibling;
|
1572
|
+
if (
|
1573
|
+
focused instanceof HTMLElement &&
|
1574
|
+
focused.hasAttribute(ATTRIBUTE_ROLE) &&
|
1575
|
+
focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
|
1576
|
+
focused.matches("[data-monster-visibility=visible]") &&
|
1577
|
+
focused.matches(":not([data-monster-filtered=true])")
|
1578
|
+
) {
|
1579
|
+
found = true;
|
1580
|
+
break;
|
1581
|
+
}
|
1582
|
+
}
|
1583
|
+
if (found === false) {
|
1584
|
+
focusFilter.call(this);
|
1585
|
+
}
|
1586
|
+
}
|
1587
|
+
}
|
1588
|
+
|
1589
|
+
new Processing(() => {
|
1590
|
+
if (focused instanceof HTMLElement) {
|
1591
|
+
this.shadowRoot
|
1592
|
+
.querySelectorAll(`[${ATTRIBUTE_PREFIX}focused]`)
|
1593
|
+
.forEach((e) => {
|
1594
|
+
e.removeAttribute(`${ATTRIBUTE_PREFIX}focused`);
|
1595
|
+
});
|
1596
|
+
|
1597
|
+
focused.focus();
|
1598
|
+
focused.setAttribute(`${ATTRIBUTE_PREFIX}focused`, true);
|
1599
|
+
}
|
1600
|
+
})
|
1601
|
+
.run()
|
1602
|
+
.catch((e) => {
|
1603
|
+
addErrorAttribute(this, e);
|
1604
|
+
});
|
1590
1605
|
}
|
1591
1606
|
|
1592
1607
|
/**
|
1593
1608
|
* @private
|
1594
1609
|
*/
|
1595
1610
|
function filterOptions() {
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1611
|
+
new Processing(() => {
|
1612
|
+
let filterValue;
|
1613
|
+
|
1614
|
+
switch (this.getOption("filter.position")) {
|
1615
|
+
case FILTER_POSITION_INLINE:
|
1616
|
+
if (this[inlineFilterElementSymbol] instanceof HTMLElement) {
|
1617
|
+
filterValue = this[inlineFilterElementSymbol].value.toLowerCase();
|
1618
|
+
} else {
|
1619
|
+
return;
|
1620
|
+
}
|
1621
|
+
|
1622
|
+
break;
|
1623
|
+
case FILTER_POSITION_POPPER:
|
1624
|
+
default:
|
1625
|
+
if (this[popperFilterElementSymbol] instanceof HTMLInputElement) {
|
1626
|
+
filterValue = this[popperFilterElementSymbol].value.toLowerCase();
|
1627
|
+
} else {
|
1628
|
+
return;
|
1629
|
+
}
|
1630
|
+
}
|
1631
|
+
|
1632
|
+
const options = this.getOption("options");
|
1633
|
+
for (const [i, option] of Object.entries(options)) {
|
1634
|
+
if (option.label.toLowerCase().indexOf(filterValue) === -1) {
|
1635
|
+
this.setOption(`options.${i}.filtered`, "true");
|
1636
|
+
} else {
|
1637
|
+
this.setOption(`options.${i}.filtered`, undefined);
|
1638
|
+
}
|
1639
|
+
}
|
1640
|
+
})
|
1641
|
+
.run()
|
1642
|
+
.then(() => {
|
1643
|
+
new Processing(100, () => {
|
1644
|
+
calcAndSetOptionsDimension.call(this);
|
1645
|
+
focusFilter.call(this);
|
1646
|
+
})
|
1647
|
+
.run()
|
1648
|
+
.catch((e) => {
|
1649
|
+
addErrorAttribute(this, e);
|
1650
|
+
});
|
1651
|
+
})
|
1652
|
+
.catch((e) => {
|
1653
|
+
addErrorAttribute(this, e);
|
1654
|
+
});
|
1640
1655
|
}
|
1641
1656
|
|
1642
1657
|
/**
|
@@ -1644,37 +1659,37 @@ function filterOptions() {
|
|
1644
1659
|
* @param {Event} event
|
1645
1660
|
*/
|
1646
1661
|
function handleFilterKeyboardEvents(event) {
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1662
|
+
const shiftKey = event?.["shiftKey"];
|
1663
|
+
|
1664
|
+
switch (event?.["code"]) {
|
1665
|
+
case "Tab":
|
1666
|
+
activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
|
1667
|
+
event.preventDefault();
|
1668
|
+
break;
|
1669
|
+
case "Escape":
|
1670
|
+
toggle.call(this);
|
1671
|
+
event.preventDefault();
|
1672
|
+
break;
|
1673
|
+
case "Tab" && shiftKey === true:
|
1674
|
+
case "ArrowUp":
|
1675
|
+
activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
|
1676
|
+
event.preventDefault();
|
1677
|
+
break;
|
1678
|
+
case "Tab" && !shiftKey:
|
1679
|
+
case "ArrowDown":
|
1680
|
+
activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
|
1681
|
+
event.preventDefault();
|
1682
|
+
break;
|
1683
|
+
default:
|
1684
|
+
if (
|
1685
|
+
this.getOption("features.lazyLoad") === true &&
|
1686
|
+
this[lazyLoadDoneSymbol] !== true
|
1687
|
+
) {
|
1688
|
+
this.click();
|
1689
|
+
}
|
1690
|
+
|
1691
|
+
handleFilterKeyEvents.call(this);
|
1692
|
+
}
|
1678
1693
|
}
|
1679
1694
|
|
1680
1695
|
/**
|
@@ -1688,86 +1703,86 @@ function handleFilterKeyboardEvents(event) {
|
|
1688
1703
|
* @return {void} This method does not return anything.
|
1689
1704
|
*/
|
1690
1705
|
function handleFilterKeyEvents() {
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1706
|
+
if (this[keyFilterEventSymbol] instanceof DeadMansSwitch) {
|
1707
|
+
try {
|
1708
|
+
this[keyFilterEventSymbol].touch();
|
1709
|
+
return;
|
1710
|
+
} catch (e) {
|
1711
|
+
delete this[keyFilterEventSymbol];
|
1712
|
+
}
|
1713
|
+
}
|
1714
|
+
|
1715
|
+
this[keyFilterEventSymbol] = new DeadMansSwitch(200, () => {
|
1716
|
+
if (getFilterMode.call(this) !== FILTER_MODE_REMOTE) {
|
1717
|
+
filterOptions.call(this);
|
1718
|
+
} else {
|
1719
|
+
filterFromRemote.call(this).catch((e) => {
|
1720
|
+
addErrorAttribute(this, e);
|
1721
|
+
});
|
1722
|
+
}
|
1723
|
+
|
1724
|
+
delete this[keyFilterEventSymbol];
|
1725
|
+
});
|
1711
1726
|
}
|
1712
1727
|
|
1713
1728
|
/**
|
1714
1729
|
* @private
|
1715
1730
|
*/
|
1716
1731
|
function filterFromRemote() {
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1732
|
+
if (
|
1733
|
+
!(this[inlineFilterElementSymbol] instanceof HTMLElement) &&
|
1734
|
+
!(this[popperFilterElementSymbol] instanceof HTMLElement)
|
1735
|
+
) {
|
1736
|
+
return;
|
1737
|
+
}
|
1738
|
+
|
1739
|
+
show.call(this);
|
1740
|
+
|
1741
|
+
const url = this.getOption("url");
|
1742
|
+
if (!url) {
|
1743
|
+
addErrorAttribute(this, "Missing URL for Remote Filter.");
|
1744
|
+
return;
|
1745
|
+
}
|
1746
|
+
|
1747
|
+
let filterValue;
|
1748
|
+
|
1749
|
+
switch (this.getOption("filter.position")) {
|
1750
|
+
case FILTER_POSITION_INLINE:
|
1751
|
+
if (this[inlineFilterElementSymbol] instanceof HTMLElement) {
|
1752
|
+
filterValue = this[inlineFilterElementSymbol].value.toLowerCase();
|
1753
|
+
}
|
1754
|
+
|
1755
|
+
break;
|
1756
|
+
case FILTER_POSITION_POPPER:
|
1757
|
+
default:
|
1758
|
+
if (this[popperFilterElementSymbol] instanceof HTMLInputElement) {
|
1759
|
+
filterValue = this[popperFilterElementSymbol].value.toLowerCase();
|
1760
|
+
}
|
1761
|
+
}
|
1762
|
+
|
1763
|
+
return filterFromRemoteByValue.call(this, url, filterValue);
|
1749
1764
|
}
|
1750
1765
|
|
1751
1766
|
function formatURL(url, value) {
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1767
|
+
if (value === undefined || value === null || value === "") {
|
1768
|
+
value = this.getOption("filter.defaultValue");
|
1769
|
+
if (value === undefined || value === null || value === "") {
|
1770
|
+
value = disabledRequestMarker.toString();
|
1771
|
+
}
|
1772
|
+
}
|
1773
|
+
|
1774
|
+
const formatter = new Formatter({filter: encodeURI(value)});
|
1775
|
+
const openMarker = this.getOption("filter.marker.open");
|
1776
|
+
let closeMarker = this.getOption("filter.marker.close");
|
1777
|
+
if (!closeMarker) {
|
1778
|
+
closeMarker = openMarker;
|
1779
|
+
}
|
1780
|
+
|
1781
|
+
if (openMarker && closeMarker) {
|
1782
|
+
formatter.setMarker(openMarker, closeMarker);
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
return formatter.format(url);
|
1771
1786
|
}
|
1772
1787
|
|
1773
1788
|
/**
|
@@ -1777,28 +1792,28 @@ function formatURL(url, value) {
|
|
1777
1792
|
* @returns {Promise<unknown>}
|
1778
1793
|
*/
|
1779
1794
|
function filterFromRemoteByValue(optionUrl, value) {
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1795
|
+
return new Processing(() => {
|
1796
|
+
let url = formatURL.call(this, optionUrl, value);
|
1797
|
+
if (url.indexOf(disabledRequestMarker.toString()) !== -1) {
|
1798
|
+
return;
|
1799
|
+
}
|
1800
|
+
|
1801
|
+
fetchIt
|
1802
|
+
.call(this, url, {
|
1803
|
+
disableHiding: true,
|
1804
|
+
})
|
1805
|
+
.then(() => {
|
1806
|
+
checkOptionState.call(this);
|
1807
|
+
show.call(this);
|
1808
|
+
})
|
1809
|
+
.catch((e) => {
|
1810
|
+
throw e;
|
1811
|
+
});
|
1812
|
+
})
|
1813
|
+
.run()
|
1814
|
+
.catch((e) => {
|
1815
|
+
throw e;
|
1816
|
+
});
|
1802
1817
|
}
|
1803
1818
|
|
1804
1819
|
/**
|
@@ -1806,50 +1821,50 @@ function filterFromRemoteByValue(optionUrl, value) {
|
|
1806
1821
|
* @private
|
1807
1822
|
*/
|
1808
1823
|
function handleOptionKeyboardEvents(event) {
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1824
|
+
const shiftKey = event?.["shiftKey"];
|
1825
|
+
|
1826
|
+
switch (event?.["code"]) {
|
1827
|
+
case "Escape":
|
1828
|
+
toggle.call(this);
|
1829
|
+
event.preventDefault();
|
1830
|
+
break;
|
1831
|
+
case "Enter":
|
1832
|
+
case "Space":
|
1833
|
+
const path = event.composedPath();
|
1834
|
+
const element = path?.[0];
|
1835
|
+
if (element instanceof HTMLElement) {
|
1836
|
+
const input = element.getElementsByTagName("input");
|
1837
|
+
if (!input) {
|
1838
|
+
return;
|
1839
|
+
}
|
1840
|
+
fireEvent(input, "click");
|
1841
|
+
}
|
1842
|
+
event.preventDefault();
|
1843
|
+
break;
|
1844
|
+
|
1845
|
+
case "Tab" && shiftKey === true:
|
1846
|
+
case "ArrowUp":
|
1847
|
+
activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
|
1848
|
+
event.preventDefault();
|
1849
|
+
break;
|
1850
|
+
|
1851
|
+
case "Tab" && !shiftKey:
|
1852
|
+
case "ArrowLeft":
|
1853
|
+
case "ArrowRight":
|
1854
|
+
// handled by tree select
|
1855
|
+
break;
|
1856
|
+
case "ArrowDown":
|
1857
|
+
activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
|
1858
|
+
event.preventDefault();
|
1859
|
+
break;
|
1860
|
+
default:
|
1861
|
+
const p = event.composedPath();
|
1862
|
+
if (p?.[0] instanceof HTMLInputElement) {
|
1863
|
+
return;
|
1864
|
+
}
|
1865
|
+
focusFilter.call(this);
|
1866
|
+
break;
|
1867
|
+
}
|
1853
1868
|
}
|
1854
1869
|
|
1855
1870
|
/**
|
@@ -1857,33 +1872,33 @@ function handleOptionKeyboardEvents(event) {
|
|
1857
1872
|
* @return {string}
|
1858
1873
|
*/
|
1859
1874
|
function getFilterMode() {
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1875
|
+
switch (this.getOption("filter.mode")) {
|
1876
|
+
case FILTER_MODE_OPTIONS:
|
1877
|
+
return FILTER_MODE_OPTIONS;
|
1878
|
+
case FILTER_MODE_REMOTE:
|
1879
|
+
return FILTER_MODE_REMOTE;
|
1880
|
+
default:
|
1881
|
+
return FILTER_MODE_DISABLED;
|
1882
|
+
}
|
1868
1883
|
}
|
1869
1884
|
|
1870
1885
|
/**
|
1871
1886
|
* @private
|
1872
1887
|
*/
|
1873
1888
|
function blurFilter() {
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1889
|
+
if (!(this[inlineFilterElementSymbol] instanceof HTMLElement)) {
|
1890
|
+
return;
|
1891
|
+
}
|
1877
1892
|
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1893
|
+
if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
|
1894
|
+
return;
|
1895
|
+
}
|
1881
1896
|
|
1882
|
-
|
1883
|
-
|
1897
|
+
this[popperFilterContainerElementSymbol].classList.remove("active");
|
1898
|
+
this[popperFilterContainerElementSymbol].blur();
|
1884
1899
|
|
1885
|
-
|
1886
|
-
|
1900
|
+
this[inlineFilterElementSymbol].classList.remove("active");
|
1901
|
+
this[inlineFilterElementSymbol].blur();
|
1887
1902
|
}
|
1888
1903
|
|
1889
1904
|
/**
|
@@ -1891,25 +1906,25 @@ function blurFilter() {
|
|
1891
1906
|
* @param focusOptions
|
1892
1907
|
*/
|
1893
1908
|
function focusPopperFilter(focusOptions) {
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1909
|
+
this[popperFilterContainerElementSymbol].classList.remove("d-none");
|
1910
|
+
this[popperFilterElementSymbol].classList.add("active");
|
1911
|
+
this[inlineFilterElementSymbol].classList.remove("active");
|
1912
|
+
this[inlineFilterElementSymbol].classList.add("d-none");
|
1913
|
+
|
1914
|
+
if (!(this[popperFilterElementSymbol] instanceof HTMLElement)) {
|
1915
|
+
addErrorAttribute(this, "Missing Popper Filter Element.");
|
1916
|
+
return;
|
1917
|
+
}
|
1918
|
+
|
1919
|
+
// visibility is set to visible, because focus() does not work on invisible elements
|
1920
|
+
// and the class definition is assigned later in the processing
|
1921
|
+
setTimeout(() => {
|
1922
|
+
if (focusOptions === undefined || focusOptions === null) {
|
1923
|
+
this[popperFilterElementSymbol].focus();
|
1924
|
+
} else {
|
1925
|
+
this[popperFilterElementSymbol].focus(focusOptions);
|
1926
|
+
}
|
1927
|
+
}, 100);
|
1913
1928
|
}
|
1914
1929
|
|
1915
1930
|
/**
|
@@ -1917,44 +1932,44 @@ function focusPopperFilter(focusOptions) {
|
|
1917
1932
|
* @param focusOptions
|
1918
1933
|
*/
|
1919
1934
|
function focusInlineFilter(focusOptions) {
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1935
|
+
const options = this.getOption("options");
|
1936
|
+
if (
|
1937
|
+
(!isArray(options) || options.length === 0) &&
|
1938
|
+
getFilterMode.call(this) !== FILTER_MODE_REMOTE
|
1939
|
+
) {
|
1940
|
+
return;
|
1941
|
+
}
|
1942
|
+
|
1943
|
+
this[popperFilterContainerElementSymbol].classList.add("d-none");
|
1944
|
+
this[inlineFilterElementSymbol].classList.add("active");
|
1945
|
+
this[inlineFilterElementSymbol].classList.remove("d-none");
|
1946
|
+
|
1947
|
+
// visibility is set to visible, because focus() does not work on invisible elements
|
1948
|
+
// and the class definition is assigned later in the processing
|
1949
|
+
setTimeout(() => {
|
1950
|
+
if (focusOptions === undefined || focusOptions === null) {
|
1951
|
+
this[inlineFilterElementSymbol].focus();
|
1952
|
+
} else {
|
1953
|
+
this[inlineFilterElementSymbol].focus(focusOptions);
|
1954
|
+
}
|
1955
|
+
}, 100);
|
1941
1956
|
}
|
1942
1957
|
|
1943
1958
|
/**
|
1944
1959
|
* @private
|
1945
1960
|
*/
|
1946
1961
|
function focusFilter(focusOptions) {
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1962
|
+
if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
|
1963
|
+
this[popperFilterContainerElementSymbol].classList.add("d-none");
|
1964
|
+
this[inlineFilterElementSymbol].classList.add("d-none");
|
1965
|
+
return;
|
1966
|
+
}
|
1952
1967
|
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1968
|
+
if (this.getOption("filter.position") === FILTER_POSITION_INLINE) {
|
1969
|
+
return focusInlineFilter.call(this, focusOptions);
|
1970
|
+
}
|
1956
1971
|
|
1957
|
-
|
1972
|
+
return focusPopperFilter.call(this, focusOptions);
|
1958
1973
|
}
|
1959
1974
|
|
1960
1975
|
/**
|
@@ -1964,39 +1979,40 @@ function focusFilter(focusOptions) {
|
|
1964
1979
|
* @throws {Error} unsupported type
|
1965
1980
|
*/
|
1966
1981
|
function gatherState() {
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
1982
|
+
const type = this.getOption("type");
|
1983
|
+
if (["radio", "checkbox"].indexOf(type) === -1) {
|
1984
|
+
throw new Error("unsupported type");
|
1985
|
+
}
|
1986
|
+
|
1987
|
+
if (!this.shadowRoot) {
|
1988
|
+
throw new Error("no shadow-root is defined");
|
1989
|
+
}
|
1990
|
+
|
1991
|
+
const selection = [];
|
1992
|
+
const elements = this.shadowRoot.querySelectorAll(
|
1993
|
+
`input[type=${type}]:checked`,
|
1994
|
+
);
|
1995
|
+
|
1996
|
+
for (const e of elements) {
|
1997
|
+
selection.push({
|
1998
|
+
label: getSelectionLabel.call(this, e.value),
|
1999
|
+
value: e.value,
|
2000
|
+
});
|
2001
|
+
}
|
2002
|
+
|
2003
|
+
setSelection
|
2004
|
+
.call(this, selection)
|
2005
|
+
.then(() => {
|
2006
|
+
})
|
2007
|
+
.catch((e) => {
|
2008
|
+
addErrorAttribute(this, e);
|
2009
|
+
});
|
2010
|
+
|
2011
|
+
if (this.getOption("features.closeOnSelect") === true) {
|
2012
|
+
toggle.call(this);
|
2013
|
+
}
|
2014
|
+
|
2015
|
+
return this;
|
2000
2016
|
}
|
2001
2017
|
|
2002
2018
|
/**
|
@@ -2005,120 +2021,121 @@ function gatherState() {
|
|
2005
2021
|
* @throws {Error} unsupported type
|
2006
2022
|
*/
|
2007
2023
|
function clearSelection() {
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
|
2022
|
-
|
2024
|
+
const type = this.getOption("type");
|
2025
|
+
if (["radio", "checkbox"].indexOf(type) === -1) {
|
2026
|
+
throw new Error("unsupported type");
|
2027
|
+
}
|
2028
|
+
|
2029
|
+
if (!this.shadowRoot) {
|
2030
|
+
throw new Error("no shadow-root is defined");
|
2031
|
+
}
|
2032
|
+
|
2033
|
+
setSelection
|
2034
|
+
.call(this, [])
|
2035
|
+
.then(() => {
|
2036
|
+
})
|
2037
|
+
.catch((e) => {
|
2038
|
+
addErrorAttribute(this, e);
|
2039
|
+
});
|
2023
2040
|
}
|
2024
2041
|
|
2025
2042
|
/**
|
2026
2043
|
* @private
|
2027
2044
|
*/
|
2028
2045
|
function areOptionsAvailableAndInit() {
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2046
|
+
// prevent multiple calls
|
2047
|
+
if (this[areOptionsAvailableAndInitSymbol] === undefined) {
|
2048
|
+
this[areOptionsAvailableAndInitSymbol] = 0;
|
2049
|
+
}
|
2050
|
+
|
2051
|
+
if (this[areOptionsAvailableAndInitSymbol] > 0) {
|
2052
|
+
this[areOptionsAvailableAndInitSymbol]--;
|
2053
|
+
return true;
|
2054
|
+
}
|
2055
|
+
|
2056
|
+
this[areOptionsAvailableAndInitSymbol]++;
|
2057
|
+
|
2058
|
+
const options = this.getOption("options");
|
2059
|
+
|
2060
|
+
if (
|
2061
|
+
options === undefined ||
|
2062
|
+
options === null ||
|
2063
|
+
(isArray(options) && options.length === 0)
|
2064
|
+
) {
|
2065
|
+
setStatusOrRemoveBadges.call(this, "empty");
|
2066
|
+
|
2067
|
+
// hide.call(this);
|
2068
|
+
|
2069
|
+
let msg = this.getOption("labels.no-options-available");
|
2070
|
+
|
2071
|
+
if (
|
2072
|
+
this.getOption("url") !== null &&
|
2073
|
+
this.getOption("features.lazyLoad") === true &&
|
2074
|
+
this[lazyLoadDoneSymbol] !== true
|
2075
|
+
) {
|
2076
|
+
msg = this.getOption("labels.click-to-load-options");
|
2077
|
+
}
|
2078
|
+
|
2079
|
+
this.setOption("messages.control", msg);
|
2080
|
+
this.setOption("messages.summary", "");
|
2081
|
+
|
2082
|
+
if (this.getOption("features.emptyValueIfNoOptions") === true) {
|
2083
|
+
this.value = "";
|
2084
|
+
}
|
2085
|
+
addErrorAttribute(this, "No options available.");
|
2086
|
+
return false;
|
2087
|
+
}
|
2088
|
+
|
2089
|
+
const selections = this.getOption("selection");
|
2090
|
+
if (
|
2091
|
+
selections === undefined ||
|
2092
|
+
selections === null ||
|
2093
|
+
selections.length === 0
|
2094
|
+
) {
|
2095
|
+
this.setOption(
|
2096
|
+
"messages.control",
|
2097
|
+
this.getOption("labels.select-an-option"),
|
2098
|
+
);
|
2099
|
+
} else {
|
2100
|
+
this.setOption("messages.control", "");
|
2101
|
+
}
|
2102
|
+
|
2103
|
+
this.setOption("messages.summary", setSummaryAndControlText.call(this));
|
2104
|
+
|
2105
|
+
let updated = false;
|
2106
|
+
let valueCounter = 1;
|
2107
|
+
for (const option of options) {
|
2108
|
+
if (option?.visibility === undefined) {
|
2109
|
+
option.visibility = "visible";
|
2110
|
+
updated = true;
|
2111
|
+
}
|
2112
|
+
|
2113
|
+
if (option?.value === undefined && option?.label === undefined) {
|
2114
|
+
option.value = `${valueCounter++}`;
|
2115
|
+
option.label = option.value;
|
2116
|
+
updated = true;
|
2117
|
+
continue;
|
2118
|
+
}
|
2119
|
+
|
2120
|
+
if (option?.value === undefined) {
|
2121
|
+
option.value = option.label;
|
2122
|
+
updated = true;
|
2123
|
+
}
|
2124
|
+
|
2125
|
+
if (option?.label === undefined) {
|
2126
|
+
option.label = option.value;
|
2127
|
+
updated = true;
|
2128
|
+
}
|
2129
|
+
}
|
2130
|
+
|
2131
|
+
if (updated) {
|
2132
|
+
this.setOption("options", options);
|
2133
|
+
}
|
2134
|
+
|
2135
|
+
setStatusOrRemoveBadges.call(this);
|
2136
|
+
|
2137
|
+
removeErrorAttribute(this, "No options available.");
|
2138
|
+
return true;
|
2122
2139
|
}
|
2123
2140
|
|
2124
2141
|
/**
|
@@ -2126,30 +2143,30 @@ function areOptionsAvailableAndInit() {
|
|
2126
2143
|
* @throws {Error} no shadow-root is defined
|
2127
2144
|
*/
|
2128
2145
|
function checkOptionState() {
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
2147
|
-
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
2146
|
+
if (!this.shadowRoot) {
|
2147
|
+
throw new Error("no shadow-root is defined");
|
2148
|
+
}
|
2149
|
+
|
2150
|
+
const elements = this.shadowRoot.querySelectorAll(
|
2151
|
+
`[${ATTRIBUTE_ROLE}=option] input`,
|
2152
|
+
);
|
2153
|
+
|
2154
|
+
let selection = this.getOption("selection");
|
2155
|
+
if (!isArray(selection)) {
|
2156
|
+
selection = [];
|
2157
|
+
}
|
2158
|
+
|
2159
|
+
const checkedValues = selection.map((a) => {
|
2160
|
+
return a.value;
|
2161
|
+
});
|
2162
|
+
|
2163
|
+
for (const e of elements) {
|
2164
|
+
if (checkedValues.indexOf(e.value) !== -1) {
|
2165
|
+
if (e.checked !== true) e.checked = true;
|
2166
|
+
} else {
|
2167
|
+
if (e.checked !== false) e.checked = false;
|
2168
|
+
}
|
2169
|
+
}
|
2153
2170
|
}
|
2154
2171
|
|
2155
2172
|
/**
|
@@ -2158,41 +2175,41 @@ function checkOptionState() {
|
|
2158
2175
|
* @return {Object}
|
2159
2176
|
*/
|
2160
2177
|
function convertValueToSelection(value) {
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2178
|
+
const selection = [];
|
2179
|
+
|
2180
|
+
if (isString(value)) {
|
2181
|
+
value = value
|
2182
|
+
.split(",")
|
2183
|
+
.map((a) => {
|
2184
|
+
return a.trim();
|
2185
|
+
})
|
2186
|
+
.filter((a) => {
|
2187
|
+
return a !== "";
|
2188
|
+
});
|
2189
|
+
}
|
2190
|
+
|
2191
|
+
if (isString(value) || isInteger(value)) {
|
2192
|
+
selection.push({
|
2193
|
+
label: getSelectionLabel.call(this, value),
|
2194
|
+
value: value,
|
2195
|
+
});
|
2196
|
+
} else if (isArray(value)) {
|
2180
2197
|
for (const v of value) {
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
2198
|
+
selection.push({
|
2199
|
+
label: getSelectionLabel.call(this, v),
|
2200
|
+
value: v,
|
2201
|
+
});
|
2202
|
+
}
|
2203
|
+
|
2204
|
+
value = value.join(",");
|
2205
|
+
} else {
|
2206
|
+
throw new Error("unsupported type");
|
2207
|
+
}
|
2208
|
+
|
2209
|
+
return {
|
2210
|
+
selection: selection,
|
2211
|
+
value: value,
|
2212
|
+
};
|
2196
2213
|
}
|
2197
2214
|
|
2198
2215
|
/**
|
@@ -2201,104 +2218,127 @@ function convertValueToSelection(value) {
|
|
2201
2218
|
* @return {string}
|
2202
2219
|
*/
|
2203
2220
|
function convertSelectionToValue(selection) {
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2221
|
+
const value = [];
|
2222
|
+
|
2223
|
+
if (isArray(selection)) {
|
2224
|
+
for (const obj of selection) {
|
2225
|
+
const v = obj?.["value"];
|
2226
|
+
if (v !== undefined) value.push(`${v}`);
|
2227
|
+
}
|
2228
|
+
}
|
2229
|
+
|
2230
|
+
if (value.length === 0) {
|
2231
|
+
return "";
|
2232
|
+
} else if (value.length === 1) {
|
2233
|
+
const v = value.pop();
|
2234
|
+
if (v === undefined) return "";
|
2235
|
+
if (v === null) return "";
|
2236
|
+
return `${v}`;
|
2237
|
+
}
|
2238
|
+
|
2239
|
+
return value.join(",");
|
2223
2240
|
}
|
2224
2241
|
|
2225
2242
|
/**
|
2226
2243
|
* @private
|
2227
|
-
* @param {array} selection
|
2244
|
+
* @param {array|string} selection
|
2228
2245
|
* @return {Promise}
|
2229
2246
|
* @throws {Error} no shadow-root is defined
|
2230
2247
|
*/
|
2231
2248
|
function setSelection(selection) {
|
2232
|
-
|
2233
|
-
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2272
|
-
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2283
|
-
|
2284
|
-
|
2285
|
-
|
2286
|
-
|
2287
|
-
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2249
|
+
|
2250
|
+
if (isString(selection) || isInteger(selection)) {
|
2251
|
+
const result = convertValueToSelection.call(this, selection);
|
2252
|
+
selection = result?.selection;
|
2253
|
+
} else if (selection === undefined || selection === null) {
|
2254
|
+
selection = [];
|
2255
|
+
}
|
2256
|
+
|
2257
|
+
validateArray(selection);
|
2258
|
+
let ignoreValues = this.getOption("ignoreValues", []);
|
2259
|
+
if(!isArray(ignoreValues)) {
|
2260
|
+
ignoreValues = [];
|
2261
|
+
}
|
2262
|
+
|
2263
|
+
let resultSelection = [];
|
2264
|
+
for (let i = 0; i < selection.length; i++) {
|
2265
|
+
|
2266
|
+
let ignore = false;
|
2267
|
+
|
2268
|
+
for (const v of ignoreValues) {
|
2269
|
+
if (selection[i].value === v) {
|
2270
|
+
ignore = true
|
2271
|
+
break;
|
2272
|
+
}
|
2273
|
+
}
|
2274
|
+
if (ignore) {
|
2275
|
+
continue;
|
2276
|
+
}
|
2277
|
+
|
2278
|
+
let l = getSelectionLabel.call(this, selection[i].value);
|
2279
|
+
if (l === selection[i].value) {
|
2280
|
+
l = selection[i].label;
|
2281
|
+
}
|
2282
|
+
|
2283
|
+
|
2284
|
+
resultSelection.push({
|
2285
|
+
label: l,
|
2286
|
+
value: selection[i].value,
|
2287
|
+
})
|
2288
|
+
|
2289
|
+
}
|
2290
|
+
|
2291
|
+
selection = resultSelection;
|
2292
|
+
|
2293
|
+
this.setOption("selection", selection);
|
2294
|
+
checkOptionState.call(this);
|
2295
|
+
setSummaryAndControlText.call(this);
|
2296
|
+
|
2297
|
+
try {
|
2298
|
+
this?.setFormValue(this.value);
|
2299
|
+
} catch (e) {
|
2300
|
+
addErrorAttribute(this, e);
|
2301
|
+
}
|
2302
|
+
|
2303
|
+
fireCustomEvent(this, "monster-selected", {
|
2304
|
+
selection,
|
2305
|
+
});
|
2306
|
+
|
2307
|
+
fireEvent(this, "change");
|
2308
|
+
|
2309
|
+
return new Processing(() => {
|
2310
|
+
const CLASSNAME = "selected";
|
2311
|
+
|
2312
|
+
if (!this.shadowRoot) {
|
2313
|
+
throw new Error("no shadow-root is defined");
|
2314
|
+
}
|
2315
|
+
|
2316
|
+
const notSelected = this.shadowRoot.querySelectorAll(":not(:checked)");
|
2317
|
+
|
2318
|
+
if (notSelected) {
|
2319
|
+
notSelected.forEach((node) => {
|
2320
|
+
const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
|
2321
|
+
if (parent) {
|
2322
|
+
parent.classList.remove(CLASSNAME);
|
2323
|
+
}
|
2324
|
+
});
|
2325
|
+
}
|
2326
|
+
|
2327
|
+
const selected = this.shadowRoot.querySelectorAll(":checked");
|
2328
|
+
|
2329
|
+
if (selected) {
|
2330
|
+
selected.forEach((node) => {
|
2331
|
+
const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
|
2332
|
+
if (parent) {
|
2333
|
+
parent.classList.add(CLASSNAME);
|
2334
|
+
}
|
2335
|
+
});
|
2336
|
+
}
|
2337
|
+
})
|
2338
|
+
.run()
|
2339
|
+
.catch((e) => {
|
2340
|
+
addErrorAttribute(this, e);
|
2341
|
+
});
|
2302
2342
|
}
|
2303
2343
|
|
2304
2344
|
/**
|
@@ -2309,139 +2349,139 @@ function setSelection(selection) {
|
|
2309
2349
|
* @throws {TypeError} unsupported response
|
2310
2350
|
*/
|
2311
2351
|
function fetchData(url) {
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
|
2322
|
-
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2329
|
-
|
2330
|
-
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
2352
|
+
const self = this;
|
2353
|
+
if (!url) url = this.getOption("url");
|
2354
|
+
if (!url) return Promise.resolve();
|
2355
|
+
|
2356
|
+
const fetchOptions = this.getOption("fetch", {});
|
2357
|
+
|
2358
|
+
let delayWatch = false;
|
2359
|
+
|
2360
|
+
// if fetch short time, do not show loading badge, because of flickering
|
2361
|
+
requestAnimationFrame(() => {
|
2362
|
+
if (delayWatch === true) return;
|
2363
|
+
setStatusOrRemoveBadges.call(this, "loading");
|
2364
|
+
delayWatch = true;
|
2365
|
+
});
|
2366
|
+
|
2367
|
+
url = formatURL.call(this, url);
|
2368
|
+
|
2369
|
+
self[isLoadingSymbol] = true;
|
2370
|
+
const global = getGlobal();
|
2371
|
+
return global
|
2372
|
+
.fetch(url, fetchOptions)
|
2373
|
+
.then((response) => {
|
2374
|
+
self[isLoadingSymbol] = false;
|
2375
|
+
delayWatch = true;
|
2376
|
+
const contentType = response.headers.get("content-type");
|
2377
|
+
if (contentType && contentType.indexOf("application/json") !== -1) {
|
2378
|
+
return response.text();
|
2379
|
+
}
|
2380
|
+
|
2381
|
+
throw new TypeError(`unsupported response ${contentType}`);
|
2382
|
+
})
|
2383
|
+
.then((text) => {
|
2384
|
+
try {
|
2385
|
+
return Promise.resolve(JSON.parse(String(text)));
|
2386
|
+
} catch (e) {
|
2387
|
+
throw new TypeError("the result cannot be parsed, check the URL");
|
2388
|
+
}
|
2389
|
+
})
|
2390
|
+
.catch((e) => {
|
2391
|
+
self[isLoadingSymbol] = false;
|
2392
|
+
delayWatch = true;
|
2393
|
+
throw e;
|
2394
|
+
});
|
2355
2395
|
}
|
2356
2396
|
|
2357
2397
|
/**
|
2358
2398
|
* @private
|
2359
2399
|
*/
|
2360
2400
|
function hide() {
|
2361
|
-
|
2362
|
-
|
2363
|
-
|
2401
|
+
this[popperElementSymbol].style.display = "none";
|
2402
|
+
setStatusOrRemoveBadges.call(this, "closed");
|
2403
|
+
removeAttributeToken(this[controlElementSymbol], "class", "open");
|
2364
2404
|
}
|
2365
2405
|
|
2366
2406
|
/**
|
2367
2407
|
* @private
|
2368
2408
|
*/
|
2369
2409
|
function show() {
|
2370
|
-
|
2371
|
-
|
2372
|
-
|
2373
|
-
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2387
|
-
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
2409
|
-
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2414
|
-
|
2415
|
-
|
2416
|
-
|
2417
|
-
|
2418
|
-
|
2419
|
-
|
2420
|
-
|
2421
|
-
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
2425
|
-
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2431
|
-
|
2432
|
-
|
2433
|
-
|
2410
|
+
if (this.getOption("disabled", undefined) === true) {
|
2411
|
+
return;
|
2412
|
+
}
|
2413
|
+
|
2414
|
+
if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
|
2415
|
+
return;
|
2416
|
+
}
|
2417
|
+
|
2418
|
+
focusFilter.call(this);
|
2419
|
+
|
2420
|
+
const lazyLoadFlag =
|
2421
|
+
this.getOption("features.lazyLoad") && this[lazyLoadDoneSymbol] !== true;
|
2422
|
+
|
2423
|
+
if (lazyLoadFlag === true) {
|
2424
|
+
this[lazyLoadDoneSymbol] = true;
|
2425
|
+
setStatusOrRemoveBadges.call(this, "loading");
|
2426
|
+
|
2427
|
+
new Processing(200, () => {
|
2428
|
+
this.fetch()
|
2429
|
+
.then(() => {
|
2430
|
+
checkOptionState.call(this);
|
2431
|
+
requestAnimationFrame(() => {
|
2432
|
+
show.call(this);
|
2433
|
+
});
|
2434
|
+
})
|
2435
|
+
.catch((e) => {
|
2436
|
+
addErrorAttribute(this, e);
|
2437
|
+
setStatusOrRemoveBadges.call(this, "error");
|
2438
|
+
});
|
2439
|
+
})
|
2440
|
+
.run()
|
2441
|
+
.catch((e) => {
|
2442
|
+
addErrorAttribute(this, e);
|
2443
|
+
setStatusOrRemoveBadges.call(this, "error");
|
2444
|
+
});
|
2445
|
+
|
2446
|
+
return;
|
2447
|
+
}
|
2448
|
+
|
2449
|
+
const hasPopperFilterFlag =
|
2450
|
+
this.getOption("filter.position") === FILTER_POSITION_POPPER &&
|
2451
|
+
getFilterMode.call(this) !== FILTER_MODE_DISABLED;
|
2452
|
+
|
2453
|
+
const options = getOptionElements.call(this);
|
2454
|
+
if (options.length === 0 && hasPopperFilterFlag === false) {
|
2455
|
+
return;
|
2456
|
+
}
|
2457
|
+
|
2458
|
+
this[popperElementSymbol].style.visibility = "hidden";
|
2459
|
+
this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
|
2460
|
+
setStatusOrRemoveBadges.call(this, "open");
|
2461
|
+
|
2462
|
+
addAttributeToken(this[controlElementSymbol], "class", "open");
|
2463
|
+
|
2464
|
+
new Processing(() => {
|
2465
|
+
calcAndSetOptionsDimension.call(this);
|
2466
|
+
focusFilter.call(this);
|
2467
|
+
this[popperElementSymbol].style.removeProperty("visibility");
|
2468
|
+
updatePopper.call(this);
|
2469
|
+
})
|
2470
|
+
.run()
|
2471
|
+
.catch((e) => {
|
2472
|
+
addErrorAttribute(this, e);
|
2473
|
+
});
|
2434
2474
|
}
|
2435
2475
|
|
2436
2476
|
/**
|
2437
2477
|
* @private
|
2438
2478
|
*/
|
2439
2479
|
function toggle() {
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2443
|
-
|
2444
|
-
|
2480
|
+
if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
|
2481
|
+
hide.call(this);
|
2482
|
+
} else {
|
2483
|
+
show.call(this);
|
2484
|
+
}
|
2445
2485
|
}
|
2446
2486
|
|
2447
2487
|
/**
|
@@ -2450,188 +2490,188 @@ function toggle() {
|
|
2450
2490
|
* @fires monster-selection-cleared
|
2451
2491
|
*/
|
2452
2492
|
function initEventHandler() {
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
2460
|
-
|
2461
|
-
|
2462
|
-
|
2463
|
-
|
2464
|
-
|
2465
|
-
|
2466
|
-
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2486
|
-
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
2490
|
-
|
2491
|
-
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
2509
|
-
|
2510
|
-
|
2511
|
-
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
|
2520
|
-
|
2521
|
-
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
2525
|
-
|
2526
|
-
|
2527
|
-
|
2528
|
-
|
2529
|
-
|
2530
|
-
|
2531
|
-
|
2532
|
-
|
2533
|
-
|
2534
|
-
|
2535
|
-
|
2536
|
-
|
2537
|
-
|
2538
|
-
|
2539
|
-
|
2540
|
-
|
2541
|
-
|
2542
|
-
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2546
|
-
|
2547
|
-
|
2548
|
-
|
2549
|
-
|
2550
|
-
|
2551
|
-
|
2552
|
-
|
2553
|
-
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
|
2569
|
-
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2578
|
-
|
2579
|
-
|
2580
|
-
|
2581
|
-
|
2582
|
-
|
2583
|
-
|
2584
|
-
|
2585
|
-
|
2586
|
-
|
2587
|
-
|
2588
|
-
|
2589
|
-
|
2590
|
-
|
2591
|
-
|
2592
|
-
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
|
2597
|
-
|
2598
|
-
|
2599
|
-
|
2600
|
-
|
2601
|
-
|
2602
|
-
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2611
|
-
|
2612
|
-
|
2613
|
-
|
2614
|
-
|
2615
|
-
|
2616
|
-
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
2622
|
-
|
2623
|
-
|
2624
|
-
|
2625
|
-
|
2626
|
-
|
2627
|
-
|
2628
|
-
|
2629
|
-
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2633
|
-
|
2634
|
-
|
2493
|
+
const self = this;
|
2494
|
+
|
2495
|
+
/**
|
2496
|
+
* @param {Event} event
|
2497
|
+
*/
|
2498
|
+
self[clearOptionEventHandler] = (event) => {
|
2499
|
+
const element = findTargetElementFromEvent(
|
2500
|
+
event,
|
2501
|
+
ATTRIBUTE_ROLE,
|
2502
|
+
"remove-badge",
|
2503
|
+
);
|
2504
|
+
|
2505
|
+
if (element instanceof HTMLElement) {
|
2506
|
+
const badge = findClosestByAttribute(element, ATTRIBUTE_ROLE, "badge");
|
2507
|
+
if (badge instanceof HTMLElement) {
|
2508
|
+
const value = badge.getAttribute(`${ATTRIBUTE_PREFIX}value`);
|
2509
|
+
|
2510
|
+
let selection = self.getOption("selection");
|
2511
|
+
selection = selection.filter((b) => {
|
2512
|
+
return value !== b.value;
|
2513
|
+
});
|
2514
|
+
|
2515
|
+
setSelection
|
2516
|
+
.call(self, selection)
|
2517
|
+
.then(() => {
|
2518
|
+
fireCustomEvent(self, "monster-selection-removed", {
|
2519
|
+
value,
|
2520
|
+
});
|
2521
|
+
})
|
2522
|
+
.catch((e) => {
|
2523
|
+
addErrorAttribute(self, e);
|
2524
|
+
});
|
2525
|
+
}
|
2526
|
+
}
|
2527
|
+
};
|
2528
|
+
|
2529
|
+
/**
|
2530
|
+
* @param {Event} event
|
2531
|
+
*/
|
2532
|
+
self[closeEventHandler] = (event) => {
|
2533
|
+
const path = event.composedPath();
|
2534
|
+
|
2535
|
+
for (const [, element] of Object.entries(path)) {
|
2536
|
+
if (element === self) {
|
2537
|
+
return;
|
2538
|
+
}
|
2539
|
+
}
|
2540
|
+
hide.call(self);
|
2541
|
+
};
|
2542
|
+
|
2543
|
+
/**
|
2544
|
+
* @param {Event} event
|
2545
|
+
*/
|
2546
|
+
self[inputEventHandler] = (event) => {
|
2547
|
+
const path = event.composedPath();
|
2548
|
+
const element = path?.[0];
|
2549
|
+
|
2550
|
+
if (element instanceof HTMLElement) {
|
2551
|
+
if (
|
2552
|
+
element.hasAttribute(ATTRIBUTE_ROLE) &&
|
2553
|
+
element.getAttribute(ATTRIBUTE_ROLE) === "option-control"
|
2554
|
+
) {
|
2555
|
+
fireCustomEvent(self, "monster-change", {
|
2556
|
+
type: event.type,
|
2557
|
+
value: element.value,
|
2558
|
+
checked: element.checked,
|
2559
|
+
});
|
2560
|
+
} else if (
|
2561
|
+
element.hasAttribute(ATTRIBUTE_ROLE) &&
|
2562
|
+
element.getAttribute(ATTRIBUTE_ROLE) === "filter"
|
2563
|
+
) {
|
2564
|
+
}
|
2565
|
+
}
|
2566
|
+
};
|
2567
|
+
|
2568
|
+
/**
|
2569
|
+
* @param {Event} event
|
2570
|
+
*/
|
2571
|
+
self[changeEventHandler] = (event) => {
|
2572
|
+
gatherState.call(self);
|
2573
|
+
fireCustomEvent(self, "monster-changed", event?.detail);
|
2574
|
+
};
|
2575
|
+
|
2576
|
+
self[keyEventHandler] = (event) => {
|
2577
|
+
const path = event.composedPath();
|
2578
|
+
const element = path.shift();
|
2579
|
+
|
2580
|
+
let role;
|
2581
|
+
|
2582
|
+
if (element instanceof HTMLElement) {
|
2583
|
+
if (element.hasAttribute(ATTRIBUTE_ROLE)) {
|
2584
|
+
role = element.getAttribute(ATTRIBUTE_ROLE);
|
2585
|
+
} else if (element === this) {
|
2586
|
+
show.call(this);
|
2587
|
+
// focusFilter.call(self);
|
2588
|
+
} else {
|
2589
|
+
const e = element.closest(`[${ATTRIBUTE_ROLE}]`);
|
2590
|
+
if (e instanceof HTMLElement && e.hasAttribute(ATTRIBUTE_ROLE)) {
|
2591
|
+
role = e.getAttribute(ATTRIBUTE_ROLE);
|
2592
|
+
}
|
2593
|
+
}
|
2594
|
+
} else {
|
2595
|
+
return;
|
2596
|
+
}
|
2597
|
+
|
2598
|
+
switch (role) {
|
2599
|
+
case "filter":
|
2600
|
+
handleFilterKeyboardEvents.call(self, event);
|
2601
|
+
break;
|
2602
|
+
case "option-label":
|
2603
|
+
case "option-control":
|
2604
|
+
case "option":
|
2605
|
+
handleOptionKeyboardEvents.call(self, event);
|
2606
|
+
break;
|
2607
|
+
case "control":
|
2608
|
+
case "toggle":
|
2609
|
+
handleToggleKeyboardEvents.call(self, event);
|
2610
|
+
break;
|
2611
|
+
}
|
2612
|
+
};
|
2613
|
+
|
2614
|
+
const types = self.getOption("toggleEventType", ["click"]);
|
2615
|
+
|
2616
|
+
for (const [, type] of Object.entries(types)) {
|
2617
|
+
self[controlElementSymbol]
|
2618
|
+
.querySelector(`[${ATTRIBUTE_ROLE}="container"]`)
|
2619
|
+
.addEventListener(type, function (event) {
|
2620
|
+
const element = findTargetElementFromEvent(
|
2621
|
+
event,
|
2622
|
+
ATTRIBUTE_ROLE,
|
2623
|
+
"remove-badge",
|
2624
|
+
);
|
2625
|
+
if (element instanceof HTMLElement) {
|
2626
|
+
return;
|
2627
|
+
}
|
2628
|
+
|
2629
|
+
toggle.call(self);
|
2630
|
+
});
|
2631
|
+
|
2632
|
+
self[controlElementSymbol]
|
2633
|
+
.querySelector(`[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`)
|
2634
|
+
.addEventListener(type, function (event) {
|
2635
|
+
if (self.getOption("disabled", undefined) === true) {
|
2636
|
+
return;
|
2637
|
+
}
|
2638
|
+
|
2639
|
+
const path = event.composedPath();
|
2640
|
+
const element = path?.[0];
|
2641
|
+
if (element instanceof HTMLElement) {
|
2642
|
+
const control = element.closest(
|
2643
|
+
`[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`,
|
2644
|
+
);
|
2645
|
+
if (control instanceof HTMLElement) {
|
2646
|
+
if (control.classList.contains("clear")) {
|
2647
|
+
clearSelection.call(self);
|
2648
|
+
|
2649
|
+
fireCustomEvent(self, "monster-selection-cleared", {});
|
2650
|
+
} else {
|
2651
|
+
const element = findTargetElementFromEvent(
|
2652
|
+
event,
|
2653
|
+
ATTRIBUTE_ROLE,
|
2654
|
+
"remove-badge",
|
2655
|
+
);
|
2656
|
+
if (element instanceof HTMLElement) {
|
2657
|
+
return;
|
2658
|
+
}
|
2659
|
+
|
2660
|
+
toggle.call(self);
|
2661
|
+
}
|
2662
|
+
}
|
2663
|
+
}
|
2664
|
+
});
|
2665
|
+
|
2666
|
+
// badge, selection
|
2667
|
+
self.addEventListener(type, self[clearOptionEventHandler]);
|
2668
|
+
}
|
2669
|
+
|
2670
|
+
self.addEventListener("monster-change", self[changeEventHandler]);
|
2671
|
+
self.addEventListener("input", self[inputEventHandler]);
|
2672
|
+
self.addEventListener("keydown", self[keyEventHandler]);
|
2673
|
+
|
2674
|
+
return self;
|
2635
2675
|
}
|
2636
2676
|
|
2637
2677
|
/**
|
@@ -2639,70 +2679,70 @@ function initEventHandler() {
|
|
2639
2679
|
* @return {Select}
|
2640
2680
|
*/
|
2641
2681
|
function setStatusOrRemoveBadges(suggestion) {
|
2642
|
-
|
2643
|
-
|
2644
|
-
|
2645
|
-
|
2646
|
-
|
2647
|
-
|
2648
|
-
|
2649
|
-
|
2650
|
-
|
2651
|
-
|
2652
|
-
|
2653
|
-
|
2654
|
-
|
2655
|
-
|
2656
|
-
|
2657
|
-
|
2658
|
-
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
|
2668
|
-
|
2669
|
-
|
2670
|
-
|
2671
|
-
|
2672
|
-
|
2673
|
-
|
2674
|
-
|
2675
|
-
|
2676
|
-
|
2677
|
-
|
2678
|
-
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2683
|
-
|
2684
|
-
|
2685
|
-
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2682
|
+
requestAnimationFrame(() => {
|
2683
|
+
const selection = this.getOption("selection");
|
2684
|
+
|
2685
|
+
const clearAllFlag =
|
2686
|
+
isArray(selection) &&
|
2687
|
+
selection.length > 0 &&
|
2688
|
+
this.getOption("features.clearAll") === true;
|
2689
|
+
|
2690
|
+
const current = this.getOption("classes.statusOrRemoveBadge");
|
2691
|
+
|
2692
|
+
if (suggestion === "error") {
|
2693
|
+
if (current !== "error") {
|
2694
|
+
this.setOption("classes.statusOrRemoveBadge", "error");
|
2695
|
+
}
|
2696
|
+
return;
|
2697
|
+
}
|
2698
|
+
|
2699
|
+
if (this[isLoadingSymbol] === true) {
|
2700
|
+
if (current !== "loading") {
|
2701
|
+
this.setOption("classes.statusOrRemoveBadge", "loading");
|
2702
|
+
}
|
2703
|
+
return;
|
2704
|
+
}
|
2705
|
+
|
2706
|
+
if (suggestion === "loading") {
|
2707
|
+
if (current !== "loading") {
|
2708
|
+
this.setOption("classes.statusOrRemoveBadge", "loading");
|
2709
|
+
}
|
2710
|
+
return;
|
2711
|
+
}
|
2712
|
+
|
2713
|
+
if (clearAllFlag) {
|
2714
|
+
if (current !== "clear") {
|
2715
|
+
this.setOption("classes.statusOrRemoveBadge", "clear");
|
2716
|
+
}
|
2717
|
+
return;
|
2718
|
+
}
|
2719
|
+
|
2720
|
+
if (this[controlElementSymbol].classList.contains("open")) {
|
2721
|
+
if (current !== "open") {
|
2722
|
+
this.setOption("classes.statusOrRemoveBadge", "open");
|
2723
|
+
}
|
2724
|
+
return;
|
2725
|
+
}
|
2726
|
+
|
2727
|
+
const options = this.getOption("options");
|
2728
|
+
if (
|
2729
|
+
options === undefined ||
|
2730
|
+
options === null ||
|
2731
|
+
(isArray(options) && options.length === 0)
|
2732
|
+
) {
|
2733
|
+
if (current !== "empty") {
|
2734
|
+
this.setOption("classes.statusOrRemoveBadge", "empty");
|
2735
|
+
}
|
2736
|
+
return;
|
2737
|
+
}
|
2738
|
+
|
2739
|
+
if (suggestion) {
|
2740
|
+
if (current !== suggestion) {
|
2741
|
+
this.setOption("classes.statusOrRemoveBadge", suggestion);
|
2742
|
+
}
|
2743
|
+
return;
|
2744
|
+
}
|
2745
|
+
});
|
2706
2746
|
}
|
2707
2747
|
|
2708
2748
|
/**
|
@@ -2711,68 +2751,68 @@ function setStatusOrRemoveBadges(suggestion) {
|
|
2711
2751
|
* @throws {Error} no shadow-root is defined
|
2712
2752
|
*/
|
2713
2753
|
function initControlReferences() {
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2746
|
-
|
2754
|
+
if (!this.shadowRoot) {
|
2755
|
+
throw new Error("no shadow-root is defined");
|
2756
|
+
}
|
2757
|
+
|
2758
|
+
this[controlElementSymbol] = this.shadowRoot.querySelector(
|
2759
|
+
`[${ATTRIBUTE_ROLE}=control]`,
|
2760
|
+
);
|
2761
|
+
this[selectionElementSymbol] = this.shadowRoot.querySelector(
|
2762
|
+
`[${ATTRIBUTE_ROLE}=selection]`,
|
2763
|
+
);
|
2764
|
+
this[containerElementSymbol] = this.shadowRoot.querySelector(
|
2765
|
+
`[${ATTRIBUTE_ROLE}=container]`,
|
2766
|
+
);
|
2767
|
+
this[popperElementSymbol] = this.shadowRoot.querySelector(
|
2768
|
+
`[${ATTRIBUTE_ROLE}=popper]`,
|
2769
|
+
);
|
2770
|
+
this[inlineFilterElementSymbol] = this.shadowRoot.querySelector(
|
2771
|
+
`[${ATTRIBUTE_ROLE}=filter][name="inline-filter"]`,
|
2772
|
+
);
|
2773
|
+
this[popperFilterElementSymbol] = this.shadowRoot.querySelector(
|
2774
|
+
`[${ATTRIBUTE_ROLE}=filter][name="popper-filter"]`,
|
2775
|
+
);
|
2776
|
+
this[popperFilterContainerElementSymbol] =
|
2777
|
+
this[popperFilterElementSymbol].parentElement;
|
2778
|
+
this[optionsElementSymbol] = this.shadowRoot.querySelector(
|
2779
|
+
`[${ATTRIBUTE_ROLE}=options]`,
|
2780
|
+
);
|
2781
|
+
this[noOptionsAvailableElementSymbol] = this.shadowRoot.querySelector(
|
2782
|
+
`[${ATTRIBUTE_ROLE}="no-options"]`,
|
2783
|
+
);
|
2784
|
+
this[statusOrRemoveBadgesElementSymbol] = this.shadowRoot.querySelector(
|
2785
|
+
`[${ATTRIBUTE_ROLE}=status-or-remove-badges]`,
|
2786
|
+
);
|
2747
2787
|
}
|
2748
2788
|
|
2749
2789
|
/**
|
2750
2790
|
* @private
|
2751
2791
|
*/
|
2752
2792
|
function updatePopper() {
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2793
|
+
if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
|
2794
|
+
return;
|
2795
|
+
}
|
2796
|
+
|
2797
|
+
if (this.getOption("disabled", false) === true) {
|
2798
|
+
return;
|
2799
|
+
}
|
2800
|
+
|
2801
|
+
new Processing(() => {
|
2802
|
+
calcAndSetOptionsDimension.call(this);
|
2803
|
+
positionPopper.call(
|
2804
|
+
this,
|
2805
|
+
this[controlElementSymbol],
|
2806
|
+
this[popperElementSymbol],
|
2807
|
+
this.getOption("popper", {}),
|
2808
|
+
);
|
2809
|
+
})
|
2810
|
+
.run()
|
2811
|
+
.catch((e) => {
|
2812
|
+
addErrorAttribute(this, e);
|
2813
|
+
});
|
2814
|
+
|
2815
|
+
return this;
|
2776
2816
|
}
|
2777
2817
|
|
2778
2818
|
/**
|
@@ -2780,8 +2820,8 @@ function updatePopper() {
|
|
2780
2820
|
* @return {string}
|
2781
2821
|
*/
|
2782
2822
|
function getTemplate() {
|
2783
|
-
|
2784
|
-
|
2823
|
+
// language=HTML
|
2824
|
+
return `
|
2785
2825
|
<template id="options">
|
2786
2826
|
<div data-monster-role="option" tabindex="-1"
|
2787
2827
|
data-monster-attributes="
|