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