@schukai/monster 4.120.1 → 4.121.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
CHANGED
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.
|
|
1
|
+
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.121.0"}
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
assembleMethodSymbol,
|
|
19
19
|
registerCustomElement,
|
|
20
20
|
} from "../../dom/customelement.mjs";
|
|
21
|
-
import { getDocument } from "../../dom/util.mjs";
|
|
21
|
+
import { findElementWithSelectorUpwards, getDocument } from "../../dom/util.mjs";
|
|
22
22
|
import { isFunction } from "../../types/is.mjs";
|
|
23
23
|
import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
|
|
24
24
|
import { Popper } from "../layout/popper.mjs";
|
|
@@ -77,6 +77,20 @@ const popperElementSymbol = Symbol("popperElement");
|
|
|
77
77
|
*/
|
|
78
78
|
const arrowElementSymbol = Symbol("arrowElement");
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* local symbol
|
|
82
|
+
* @private
|
|
83
|
+
* @type {symbol}
|
|
84
|
+
*/
|
|
85
|
+
const hostElementSymbol = Symbol("hostElement");
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* local symbol
|
|
89
|
+
* @private
|
|
90
|
+
* @type {symbol}
|
|
91
|
+
*/
|
|
92
|
+
const usesHostDismissSymbol = Symbol("usesHostDismiss");
|
|
93
|
+
|
|
80
94
|
/**
|
|
81
95
|
* A beautiful popper button that can make your life easier and also looks good.
|
|
82
96
|
*
|
|
@@ -149,6 +163,10 @@ class PopperButton extends Popper {
|
|
|
149
163
|
role: null,
|
|
150
164
|
label: null,
|
|
151
165
|
},
|
|
166
|
+
|
|
167
|
+
features: {
|
|
168
|
+
closeOnOutsideClick: true,
|
|
169
|
+
},
|
|
152
170
|
});
|
|
153
171
|
}
|
|
154
172
|
|
|
@@ -187,11 +205,24 @@ class PopperButton extends Popper {
|
|
|
187
205
|
connectedCallback() {
|
|
188
206
|
super.connectedCallback();
|
|
189
207
|
|
|
208
|
+
this[hostElementSymbol] = findElementWithSelectorUpwards(
|
|
209
|
+
this,
|
|
210
|
+
"monster-host",
|
|
211
|
+
);
|
|
212
|
+
this[usesHostDismissSymbol] =
|
|
213
|
+
this[hostElementSymbol] &&
|
|
214
|
+
typeof this[hostElementSymbol].registerDismissable === "function";
|
|
215
|
+
|
|
190
216
|
const document = getDocument();
|
|
191
217
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
218
|
+
if (
|
|
219
|
+
this.getOption("features.closeOnOutsideClick", true) === true &&
|
|
220
|
+
!this[usesHostDismissSymbol]
|
|
221
|
+
) {
|
|
222
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
223
|
+
// close on outside ui-events
|
|
224
|
+
document.addEventListener(type, this[closeEventHandler]);
|
|
225
|
+
}
|
|
195
226
|
}
|
|
196
227
|
|
|
197
228
|
updatePopper.call(this);
|
|
@@ -204,9 +235,14 @@ class PopperButton extends Popper {
|
|
|
204
235
|
disconnectedCallback() {
|
|
205
236
|
super.disconnectedCallback();
|
|
206
237
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
238
|
+
if (
|
|
239
|
+
this.getOption("features.closeOnOutsideClick", true) === true &&
|
|
240
|
+
!this[usesHostDismissSymbol]
|
|
241
|
+
) {
|
|
242
|
+
// close on outside ui-events
|
|
243
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
244
|
+
document.removeEventListener(type, this[closeEventHandler]);
|
|
245
|
+
}
|
|
210
246
|
}
|
|
211
247
|
|
|
212
248
|
disconnectResizeObserver.call(this);
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
fireEvent,
|
|
39
39
|
} from "../../dom/events.mjs";
|
|
40
40
|
import { getLocaleOfDocument } from "../../dom/locale.mjs";
|
|
41
|
-
import { getDocument } from "../../dom/util.mjs";
|
|
41
|
+
import { findElementWithSelectorUpwards, getDocument } from "../../dom/util.mjs";
|
|
42
42
|
import {
|
|
43
43
|
getDocumentTranslations,
|
|
44
44
|
Translations,
|
|
@@ -105,6 +105,9 @@ const isLoadingSymbol = Symbol("isLoading");
|
|
|
105
105
|
* @type {Symbol}
|
|
106
106
|
*/
|
|
107
107
|
const closeEventHandler = Symbol("closeEventHandler");
|
|
108
|
+
const hostElementSymbol = Symbol("hostElement");
|
|
109
|
+
const dismissRecordSymbol = Symbol("dismissRecord");
|
|
110
|
+
const usesHostDismissSymbol = Symbol("usesHostDismiss");
|
|
108
111
|
|
|
109
112
|
/**
|
|
110
113
|
* local symbol
|
|
@@ -841,11 +844,20 @@ class Select extends CustomControl {
|
|
|
841
844
|
*/
|
|
842
845
|
connectedCallback() {
|
|
843
846
|
super.connectedCallback();
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
847
|
+
this[hostElementSymbol] = findElementWithSelectorUpwards(
|
|
848
|
+
this,
|
|
849
|
+
"monster-host",
|
|
850
|
+
);
|
|
851
|
+
this[usesHostDismissSymbol] =
|
|
852
|
+
this[hostElementSymbol] &&
|
|
853
|
+
typeof this[hostElementSymbol].registerDismissable === "function";
|
|
854
|
+
|
|
855
|
+
if (!this[usesHostDismissSymbol]) {
|
|
856
|
+
const document = getDocument();
|
|
857
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
858
|
+
// close on outside ui-events
|
|
859
|
+
document.addEventListener(type, this[closeEventHandler]);
|
|
860
|
+
}
|
|
849
861
|
}
|
|
850
862
|
|
|
851
863
|
parseSlotsToOptions.call(this);
|
|
@@ -873,13 +885,16 @@ class Select extends CustomControl {
|
|
|
873
885
|
*/
|
|
874
886
|
disconnectedCallback() {
|
|
875
887
|
super.disconnectedCallback();
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
888
|
+
if (!this[usesHostDismissSymbol]) {
|
|
889
|
+
const document = getDocument();
|
|
890
|
+
// close on outside ui-events
|
|
891
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
892
|
+
document.removeEventListener(type, this[closeEventHandler]);
|
|
893
|
+
}
|
|
881
894
|
}
|
|
882
895
|
|
|
896
|
+
unregisterFromHost.call(this);
|
|
897
|
+
|
|
883
898
|
disconnectResizeObserver.call(this);
|
|
884
899
|
}
|
|
885
900
|
|
|
@@ -3703,6 +3718,7 @@ function hide() {
|
|
|
3703
3718
|
this[popperElementSymbol].style.display = "none";
|
|
3704
3719
|
setStatusOrRemoveBadges.call(this, "closed");
|
|
3705
3720
|
removeAttributeToken(this[controlElementSymbol], "class", "open");
|
|
3721
|
+
unregisterFromHost.call(this);
|
|
3706
3722
|
}
|
|
3707
3723
|
|
|
3708
3724
|
/**
|
|
@@ -3772,6 +3788,7 @@ function show() {
|
|
|
3772
3788
|
setStatusOrRemoveBadges.call(this, "open");
|
|
3773
3789
|
|
|
3774
3790
|
addAttributeToken(this[controlElementSymbol], "class", "open");
|
|
3791
|
+
registerWithHost.call(this);
|
|
3775
3792
|
|
|
3776
3793
|
new Processing(() => {
|
|
3777
3794
|
if (!self?.[remoteFilterFirstOpendSymbol]) {
|
|
@@ -3798,6 +3815,56 @@ function show() {
|
|
|
3798
3815
|
});
|
|
3799
3816
|
}
|
|
3800
3817
|
|
|
3818
|
+
/**
|
|
3819
|
+
* @private
|
|
3820
|
+
*/
|
|
3821
|
+
function registerWithHost() {
|
|
3822
|
+
if (!this[usesHostDismissSymbol]) {
|
|
3823
|
+
return;
|
|
3824
|
+
}
|
|
3825
|
+
|
|
3826
|
+
if (!(this[hostElementSymbol] instanceof HTMLElement)) {
|
|
3827
|
+
return;
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
const record = this[hostElementSymbol].registerDismissable?.({
|
|
3831
|
+
element: this,
|
|
3832
|
+
owner: this,
|
|
3833
|
+
close: () => {
|
|
3834
|
+
hide.call(this);
|
|
3835
|
+
},
|
|
3836
|
+
priority: 20,
|
|
3837
|
+
options: {
|
|
3838
|
+
dismissOnOutside: true,
|
|
3839
|
+
},
|
|
3840
|
+
});
|
|
3841
|
+
|
|
3842
|
+
if (record) {
|
|
3843
|
+
this[dismissRecordSymbol] = record;
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
|
|
3847
|
+
/**
|
|
3848
|
+
* @private
|
|
3849
|
+
*/
|
|
3850
|
+
function unregisterFromHost() {
|
|
3851
|
+
if (!this[usesHostDismissSymbol]) {
|
|
3852
|
+
return;
|
|
3853
|
+
}
|
|
3854
|
+
|
|
3855
|
+
if (!(this[hostElementSymbol] instanceof HTMLElement)) {
|
|
3856
|
+
return;
|
|
3857
|
+
}
|
|
3858
|
+
|
|
3859
|
+
if (this[dismissRecordSymbol]) {
|
|
3860
|
+
this[hostElementSymbol].unregisterDismissable?.(this[dismissRecordSymbol]);
|
|
3861
|
+
this[dismissRecordSymbol] = null;
|
|
3862
|
+
return;
|
|
3863
|
+
}
|
|
3864
|
+
|
|
3865
|
+
this[hostElementSymbol].unregisterDismissable?.(this);
|
|
3866
|
+
}
|
|
3867
|
+
|
|
3801
3868
|
function initDefaultOptionsFromUrl() {
|
|
3802
3869
|
const url = this.getOption("filter.defaultOptionsUrl");
|
|
3803
3870
|
if (!url) {
|
|
@@ -68,6 +68,48 @@ const focusManagerSymbol = Symbol("focusManager");
|
|
|
68
68
|
*/
|
|
69
69
|
const resourceManagerSymbol = Symbol("resourceManager");
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* @private
|
|
73
|
+
* @type {symbol}
|
|
74
|
+
*/
|
|
75
|
+
const dismissablesSymbol = Symbol("dismissables");
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @private
|
|
79
|
+
* @type {symbol}
|
|
80
|
+
*/
|
|
81
|
+
const dismissQueueSymbol = Symbol("dismissQueue");
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @private
|
|
85
|
+
* @type {symbol}
|
|
86
|
+
*/
|
|
87
|
+
const dismissVersionSymbol = Symbol("dismissVersion");
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @private
|
|
91
|
+
* @type {symbol}
|
|
92
|
+
*/
|
|
93
|
+
const dismissSequenceSymbol = Symbol("dismissSequence");
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @private
|
|
97
|
+
* @type {symbol}
|
|
98
|
+
*/
|
|
99
|
+
const dismissScheduledSymbol = Symbol("dismissScheduled");
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @private
|
|
103
|
+
* @type {symbol}
|
|
104
|
+
*/
|
|
105
|
+
const dismissHandlerSymbol = Symbol("dismissHandler");
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @private
|
|
109
|
+
* @type {symbol}
|
|
110
|
+
*/
|
|
111
|
+
const dismissListenersAttachedSymbol = Symbol("dismissListenersAttached");
|
|
112
|
+
|
|
71
113
|
/**
|
|
72
114
|
* The Host component is used to encapsulate the content of a web app.
|
|
73
115
|
*
|
|
@@ -171,6 +213,8 @@ class Host extends CustomElement {
|
|
|
171
213
|
document.body.classList.remove(classNames);
|
|
172
214
|
}
|
|
173
215
|
|
|
216
|
+
attachDismissListeners.call(this);
|
|
217
|
+
|
|
174
218
|
fireCustomEvent(this, "monster-host-connected");
|
|
175
219
|
}
|
|
176
220
|
|
|
@@ -204,6 +248,8 @@ class Host extends CustomElement {
|
|
|
204
248
|
);
|
|
205
249
|
|
|
206
250
|
fireCustomEvent(this, "monster-host-disconnected");
|
|
251
|
+
|
|
252
|
+
detachDismissListeners.call(this);
|
|
207
253
|
}
|
|
208
254
|
|
|
209
255
|
/**
|
|
@@ -358,6 +404,24 @@ class Host extends CustomElement {
|
|
|
358
404
|
this[notifyElementSymbol].push(message);
|
|
359
405
|
return this;
|
|
360
406
|
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Register a dismissable overlay (popper/select/dialog) for outside click handling.
|
|
410
|
+
* @param {Object} entry
|
|
411
|
+
* @return {Object|null}
|
|
412
|
+
*/
|
|
413
|
+
registerDismissable(entry) {
|
|
414
|
+
return registerDismissable.call(this, entry);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Unregister a dismissable overlay.
|
|
419
|
+
* @param {Object|HTMLElement} entry
|
|
420
|
+
* @return {boolean}
|
|
421
|
+
*/
|
|
422
|
+
unregisterDismissable(entry) {
|
|
423
|
+
return unregisterDismissable.call(this, entry);
|
|
424
|
+
}
|
|
361
425
|
}
|
|
362
426
|
|
|
363
427
|
/**
|
|
@@ -392,9 +456,316 @@ function initTranslations() {
|
|
|
392
456
|
* @private
|
|
393
457
|
*/
|
|
394
458
|
function initEventHandler() {
|
|
459
|
+
initDismissManager.call(this);
|
|
395
460
|
return this;
|
|
396
461
|
}
|
|
397
462
|
|
|
463
|
+
/**
|
|
464
|
+
* @private
|
|
465
|
+
*/
|
|
466
|
+
function initDismissManager() {
|
|
467
|
+
this[dismissablesSymbol] = new Map();
|
|
468
|
+
this[dismissQueueSymbol] = [];
|
|
469
|
+
this[dismissVersionSymbol] = 0;
|
|
470
|
+
this[dismissSequenceSymbol] = 0;
|
|
471
|
+
this[dismissScheduledSymbol] = false;
|
|
472
|
+
this[dismissListenersAttachedSymbol] = false;
|
|
473
|
+
|
|
474
|
+
this[dismissHandlerSymbol] = (event) => {
|
|
475
|
+
if (!this.isConnected) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
queueDismissEvent.call(this, event);
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* @private
|
|
484
|
+
*/
|
|
485
|
+
function attachDismissListeners() {
|
|
486
|
+
if (this[dismissListenersAttachedSymbol] === true) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const supportsPointer = typeof globalThis.PointerEvent === "function";
|
|
491
|
+
const eventTypes = supportsPointer
|
|
492
|
+
? ["pointerdown"]
|
|
493
|
+
: ["mousedown", "touchstart"];
|
|
494
|
+
|
|
495
|
+
for (const type of eventTypes) {
|
|
496
|
+
this.addEventListener(type, this[dismissHandlerSymbol], {
|
|
497
|
+
capture: true,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
this[dismissListenersAttachedSymbol] = true;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* @private
|
|
506
|
+
*/
|
|
507
|
+
function detachDismissListeners() {
|
|
508
|
+
if (this[dismissListenersAttachedSymbol] !== true) {
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const supportsPointer = typeof globalThis.PointerEvent === "function";
|
|
513
|
+
const eventTypes = supportsPointer
|
|
514
|
+
? ["pointerdown"]
|
|
515
|
+
: ["mousedown", "touchstart"];
|
|
516
|
+
|
|
517
|
+
for (const type of eventTypes) {
|
|
518
|
+
this.removeEventListener(type, this[dismissHandlerSymbol], {
|
|
519
|
+
capture: true,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
this[dismissListenersAttachedSymbol] = false;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @private
|
|
528
|
+
* @param {Event} event
|
|
529
|
+
*/
|
|
530
|
+
function queueDismissEvent(event) {
|
|
531
|
+
if (!event) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
536
|
+
this[dismissQueueSymbol].push({
|
|
537
|
+
path,
|
|
538
|
+
target: event.target || null,
|
|
539
|
+
version: this[dismissVersionSymbol],
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
if (this[dismissScheduledSymbol] === true) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
this[dismissScheduledSymbol] = true;
|
|
547
|
+
const schedule =
|
|
548
|
+
typeof queueMicrotask === "function"
|
|
549
|
+
? queueMicrotask
|
|
550
|
+
: (cb) => Promise.resolve().then(cb);
|
|
551
|
+
|
|
552
|
+
schedule(() => {
|
|
553
|
+
this[dismissScheduledSymbol] = false;
|
|
554
|
+
processDismissQueue.call(this);
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* @private
|
|
560
|
+
*/
|
|
561
|
+
function processDismissQueue() {
|
|
562
|
+
const queue = this[dismissQueueSymbol];
|
|
563
|
+
this[dismissQueueSymbol] = [];
|
|
564
|
+
|
|
565
|
+
if (!queue.length) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
for (const entry of queue) {
|
|
570
|
+
if (entry.version !== this[dismissVersionSymbol]) {
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const top = getTopDismissable.call(this);
|
|
575
|
+
if (!top) {
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (isEventInsideDismissable(entry, top)) {
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
if (top.options?.dismissOnOutside === false) {
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if (typeof top.close === "function") {
|
|
588
|
+
top.close();
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* @private
|
|
597
|
+
* @param {Object} entry
|
|
598
|
+
* @return {Object|null}
|
|
599
|
+
*/
|
|
600
|
+
function registerDismissable(entry) {
|
|
601
|
+
if (this[dismissablesSymbol] instanceof Map === false) {
|
|
602
|
+
initDismissManager.call(this);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const normalized = normalizeDismissEntry(entry);
|
|
606
|
+
if (!normalized) {
|
|
607
|
+
return null;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const existing = this[dismissablesSymbol].get(normalized.element);
|
|
611
|
+
const record = existing || { element: normalized.element };
|
|
612
|
+
|
|
613
|
+
record.owner = normalized.owner || record.owner || null;
|
|
614
|
+
record.close = normalized.close || record.close || null;
|
|
615
|
+
record.priority = Number.isFinite(normalized.priority)
|
|
616
|
+
? normalized.priority
|
|
617
|
+
: Number.isFinite(record.priority)
|
|
618
|
+
? record.priority
|
|
619
|
+
: 0;
|
|
620
|
+
record.options = Object.assign({}, record.options || {}, normalized.options || {});
|
|
621
|
+
record.sequence = ++this[dismissSequenceSymbol];
|
|
622
|
+
|
|
623
|
+
this[dismissablesSymbol].set(record.element, record);
|
|
624
|
+
this[dismissVersionSymbol] += 1;
|
|
625
|
+
|
|
626
|
+
return record;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* @private
|
|
631
|
+
* @param {Object|HTMLElement} entry
|
|
632
|
+
* @return {boolean}
|
|
633
|
+
*/
|
|
634
|
+
function unregisterDismissable(entry) {
|
|
635
|
+
if (this[dismissablesSymbol] instanceof Map === false) {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const record = resolveDismissRecord.call(this, entry);
|
|
640
|
+
if (!record) {
|
|
641
|
+
return false;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
this[dismissablesSymbol].delete(record.element);
|
|
645
|
+
this[dismissVersionSymbol] += 1;
|
|
646
|
+
return true;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* @private
|
|
651
|
+
* @param {Object} entry
|
|
652
|
+
* @return {Object|null}
|
|
653
|
+
*/
|
|
654
|
+
function normalizeDismissEntry(entry) {
|
|
655
|
+
if (!entry) {
|
|
656
|
+
return null;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
const element = entry.element || entry.owner || entry;
|
|
660
|
+
if (!(element instanceof HTMLElement)) {
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
return {
|
|
665
|
+
element,
|
|
666
|
+
owner: entry.owner instanceof HTMLElement ? entry.owner : null,
|
|
667
|
+
close: typeof entry.close === "function" ? entry.close : null,
|
|
668
|
+
priority: entry.priority,
|
|
669
|
+
options: entry.options || {},
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* @private
|
|
675
|
+
* @param {Object|HTMLElement} entry
|
|
676
|
+
* @return {Object|null}
|
|
677
|
+
*/
|
|
678
|
+
function resolveDismissRecord(entry) {
|
|
679
|
+
if (!entry) {
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
if (entry.element && this[dismissablesSymbol].has(entry.element)) {
|
|
684
|
+
return this[dismissablesSymbol].get(entry.element);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (entry instanceof HTMLElement && this[dismissablesSymbol].has(entry)) {
|
|
688
|
+
return this[dismissablesSymbol].get(entry);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
for (const record of this[dismissablesSymbol].values()) {
|
|
692
|
+
if (record === entry) {
|
|
693
|
+
return record;
|
|
694
|
+
}
|
|
695
|
+
if (record.owner && record.owner === entry) {
|
|
696
|
+
return record;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* @private
|
|
705
|
+
* @return {Object|null}
|
|
706
|
+
*/
|
|
707
|
+
function getTopDismissable() {
|
|
708
|
+
if (this[dismissablesSymbol] instanceof Map === false) {
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
let top = null;
|
|
713
|
+
for (const record of this[dismissablesSymbol].values()) {
|
|
714
|
+
if (!record) {
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
if (!top) {
|
|
718
|
+
top = record;
|
|
719
|
+
continue;
|
|
720
|
+
}
|
|
721
|
+
if ((record.priority || 0) > (top.priority || 0)) {
|
|
722
|
+
top = record;
|
|
723
|
+
continue;
|
|
724
|
+
}
|
|
725
|
+
if (
|
|
726
|
+
(record.priority || 0) === (top.priority || 0) &&
|
|
727
|
+
(record.sequence || 0) > (top.sequence || 0)
|
|
728
|
+
) {
|
|
729
|
+
top = record;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
return top;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* @private
|
|
738
|
+
* @param {Object} eventEntry
|
|
739
|
+
* @param {Object} record
|
|
740
|
+
* @return {boolean}
|
|
741
|
+
*/
|
|
742
|
+
function isEventInsideDismissable(eventEntry, record) {
|
|
743
|
+
if (!record) {
|
|
744
|
+
return false;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
const path = eventEntry.path || [];
|
|
748
|
+
const target = eventEntry.target || null;
|
|
749
|
+
|
|
750
|
+
if (path.includes(record.element)) {
|
|
751
|
+
return true;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
if (record.owner && path.includes(record.owner)) {
|
|
755
|
+
return true;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
if (target && record.element?.contains?.(target)) {
|
|
759
|
+
return true;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
if (target && record.owner?.contains?.(target)) {
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
return false;
|
|
767
|
+
}
|
|
768
|
+
|
|
398
769
|
/**
|
|
399
770
|
* @private
|
|
400
771
|
* @return {string}
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
registerCustomElement,
|
|
26
26
|
} from "../../dom/customelement.mjs";
|
|
27
27
|
import { fireCustomEvent } from "../../dom/events.mjs";
|
|
28
|
-
import { getDocument } from "../../dom/util.mjs";
|
|
28
|
+
import { findElementWithSelectorUpwards, getDocument } from "../../dom/util.mjs";
|
|
29
29
|
import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
|
|
30
30
|
import { STYLE_DISPLAY_MODE_BLOCK } from "../form/constants.mjs";
|
|
31
31
|
import { positionPopper } from "../form/util/floating-ui.mjs";
|
|
@@ -83,6 +83,24 @@ const popperElementSymbol = Symbol("popperElement");
|
|
|
83
83
|
*/
|
|
84
84
|
const arrowElementSymbol = Symbol("arrowElement");
|
|
85
85
|
|
|
86
|
+
/**
|
|
87
|
+
* @private
|
|
88
|
+
* @type {symbol}
|
|
89
|
+
*/
|
|
90
|
+
const hostElementSymbol = Symbol("hostElement");
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @private
|
|
94
|
+
* @type {symbol}
|
|
95
|
+
*/
|
|
96
|
+
const dismissRecordSymbol = Symbol("dismissRecord");
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @private
|
|
100
|
+
* @type {symbol}
|
|
101
|
+
*/
|
|
102
|
+
const usesHostDismissSymbol = Symbol("usesHostDismiss");
|
|
103
|
+
|
|
86
104
|
/**
|
|
87
105
|
* Popper component for displaying floating UI elements
|
|
88
106
|
*
|
|
@@ -177,10 +195,19 @@ class Popper extends CustomElement {
|
|
|
177
195
|
connectedCallback() {
|
|
178
196
|
super.connectedCallback();
|
|
179
197
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
198
|
+
this[hostElementSymbol] = findElementWithSelectorUpwards(
|
|
199
|
+
this,
|
|
200
|
+
"monster-host",
|
|
201
|
+
);
|
|
202
|
+
this[usesHostDismissSymbol] =
|
|
203
|
+
this[hostElementSymbol] &&
|
|
204
|
+
typeof this[hostElementSymbol].registerDismissable === "function";
|
|
205
|
+
|
|
206
|
+
if (!this[usesHostDismissSymbol]) {
|
|
207
|
+
const document = getDocument();
|
|
208
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
209
|
+
document.addEventListener(type, this[closeEventHandler]);
|
|
210
|
+
}
|
|
184
211
|
}
|
|
185
212
|
|
|
186
213
|
updatePopper.call(this);
|
|
@@ -194,10 +221,15 @@ class Popper extends CustomElement {
|
|
|
194
221
|
disconnectedCallback() {
|
|
195
222
|
super.disconnectedCallback();
|
|
196
223
|
|
|
197
|
-
|
|
198
|
-
document
|
|
224
|
+
if (!this[usesHostDismissSymbol]) {
|
|
225
|
+
const document = getDocument();
|
|
226
|
+
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
227
|
+
document.removeEventListener(type, this[closeEventHandler]);
|
|
228
|
+
}
|
|
199
229
|
}
|
|
200
230
|
|
|
231
|
+
unregisterFromHost.call(this);
|
|
232
|
+
|
|
201
233
|
disconnectResizeObserver.call(this);
|
|
202
234
|
}
|
|
203
235
|
|
|
@@ -399,6 +431,7 @@ function hide() {
|
|
|
399
431
|
|
|
400
432
|
self[popperElementSymbol].style.display = "none";
|
|
401
433
|
removeAttributeToken(self[controlElementSymbol], "class", "open");
|
|
434
|
+
unregisterFromHost.call(self);
|
|
402
435
|
|
|
403
436
|
setTimeout(() => {
|
|
404
437
|
fireCustomEvent(self, "monster-popper-hidden", {
|
|
@@ -430,6 +463,7 @@ function show() {
|
|
|
430
463
|
self[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
|
|
431
464
|
|
|
432
465
|
addAttributeToken(self[controlElementSymbol], "class", "open");
|
|
466
|
+
registerWithHost.call(self);
|
|
433
467
|
updatePopper.call(self);
|
|
434
468
|
|
|
435
469
|
setTimeout(() => {
|
|
@@ -460,6 +494,56 @@ function updatePopper() {
|
|
|
460
494
|
);
|
|
461
495
|
}
|
|
462
496
|
|
|
497
|
+
/**
|
|
498
|
+
* @private
|
|
499
|
+
*/
|
|
500
|
+
function registerWithHost() {
|
|
501
|
+
if (!this[usesHostDismissSymbol]) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (!(this[hostElementSymbol] instanceof HTMLElement)) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const record = this[hostElementSymbol].registerDismissable?.({
|
|
510
|
+
element: this,
|
|
511
|
+
owner: this,
|
|
512
|
+
close: () => {
|
|
513
|
+
this.hideDialog();
|
|
514
|
+
},
|
|
515
|
+
priority: 10,
|
|
516
|
+
options: {
|
|
517
|
+
dismissOnOutside: true,
|
|
518
|
+
},
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
if (record) {
|
|
522
|
+
this[dismissRecordSymbol] = record;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @private
|
|
528
|
+
*/
|
|
529
|
+
function unregisterFromHost() {
|
|
530
|
+
if (!this[usesHostDismissSymbol]) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (!(this[hostElementSymbol] instanceof HTMLElement)) {
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (this[dismissRecordSymbol]) {
|
|
539
|
+
this[hostElementSymbol].unregisterDismissable?.(this[dismissRecordSymbol]);
|
|
540
|
+
this[dismissRecordSymbol] = null;
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
this[hostElementSymbol].unregisterDismissable?.(this);
|
|
545
|
+
}
|
|
546
|
+
|
|
463
547
|
/**
|
|
464
548
|
* Initializes references to DOM elements
|
|
465
549
|
* @private
|