@cedx/base 0.29.0 → 0.31.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/ReadMe.md +1 -1
- package/lib/String.d.ts +4 -1
- package/lib/String.d.ts.map +1 -1
- package/lib/String.js +3 -2
- package/lib/TimeSpan.d.ts +6 -6
- package/lib/TimeSpan.js +6 -6
- package/lib/UI/Components/BackButton.d.ts +1 -1
- package/lib/UI/Components/BackButton.d.ts.map +1 -1
- package/lib/UI/Components/BackButton.js +3 -3
- package/lib/UI/Components/DialogBox.js +5 -5
- package/lib/UI/Components/FullScreenToggler.d.ts +1 -1
- package/lib/UI/Components/FullScreenToggler.d.ts.map +1 -1
- package/lib/UI/Components/FullScreenToggler.js +10 -7
- package/lib/UI/Components/KeyboardAccelerator.d.ts.map +1 -1
- package/lib/UI/Components/KeyboardAccelerator.js +6 -2
- package/lib/UI/Components/LoadingIndicator.d.ts +4 -0
- package/lib/UI/Components/LoadingIndicator.d.ts.map +1 -1
- package/lib/UI/Components/LoadingIndicator.js +6 -0
- package/lib/UI/Components/MenuActivator.d.ts.map +1 -1
- package/lib/UI/Components/MenuActivator.js +7 -4
- package/lib/UI/Components/OfflineIndicator.d.ts +4 -0
- package/lib/UI/Components/OfflineIndicator.d.ts.map +1 -1
- package/lib/UI/Components/OfflineIndicator.js +12 -3
- package/lib/UI/Components/TabActivator.d.ts.map +1 -1
- package/lib/UI/Components/ThemeDropdown.d.ts +12 -1
- package/lib/UI/Components/ThemeDropdown.d.ts.map +1 -1
- package/lib/UI/Components/ThemeDropdown.js +46 -10
- package/lib/UI/Components/Toast.d.ts.map +1 -1
- package/lib/UI/Components/Toast.js +7 -5
- package/lib/UI/Components/Toaster.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/Client/String.ts +3 -2
- package/src/Client/TimeSpan.ts +6 -6
- package/src/Client/UI/Components/BackButton.ts +3 -3
- package/src/Client/UI/Components/DialogBox.ts +5 -5
- package/src/Client/UI/Components/FullScreenToggler.ts +11 -7
- package/src/Client/UI/Components/KeyboardAccelerator.ts +7 -2
- package/src/Client/UI/Components/LoadingIndicator.ts +7 -0
- package/src/Client/UI/Components/MenuActivator.ts +8 -4
- package/src/Client/UI/Components/OfflineIndicator.ts +14 -2
- package/src/Client/UI/Components/TabActivator.ts +1 -0
- package/src/Client/UI/Components/ThemeDropdown.ts +48 -11
- package/src/Client/UI/Components/Toast.ts +8 -6
- package/src/Client/UI/Components/Toaster.ts +1 -2
package/ReadMe.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Cédric Belin's Base
|
|
2
|
-
   
|
|
3
3
|
|
|
4
4
|
Base library by [Cédric Belin](https://cedric-belin.fr), full stack developer,
|
|
5
5
|
implemented in [C#](https://learn.microsoft.com/en-us/dotnet/csharp) and [TypeScript](https://www.typescriptlang.org).
|
package/lib/String.d.ts
CHANGED
|
@@ -8,9 +8,12 @@ export declare function capitalize(value: string, locale?: Intl.Locale | string)
|
|
|
8
8
|
/**
|
|
9
9
|
* Replaces all new lines in the specified value by HTML line breaks.
|
|
10
10
|
* @param value The string to format.
|
|
11
|
+
* @param options Value indicating whether to use XHTML compatible line breaks.
|
|
11
12
|
* @returns The formatted string.
|
|
12
13
|
*/
|
|
13
|
-
export declare function newLineToBr(value: string
|
|
14
|
+
export declare function newLineToBr(value: string, options?: {
|
|
15
|
+
xhtml?: boolean;
|
|
16
|
+
}): string;
|
|
14
17
|
/**
|
|
15
18
|
* Reverses the specified string.
|
|
16
19
|
* @param value The string to reverse.
|
package/lib/String.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"String.d.ts","sourceRoot":"","sources":["../src/Client/String.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,IAAI,CAAC,MAAM,GAAC,MAA2B,GAAG,MAAM,CAEjG;AAED
|
|
1
|
+
{"version":3,"file":"String.d.ts","sourceRoot":"","sources":["../src/Client/String.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,IAAI,CAAC,MAAM,GAAC,MAA2B,GAAG,MAAM,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAM,GAAG,MAAM,CAElF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,SAAI,GAAG,MAAM,EAAE,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAQ,GAAG,MAAM,CAEhF"}
|
package/lib/String.js
CHANGED
|
@@ -10,10 +10,11 @@ export function capitalize(value, locale = navigator.language) {
|
|
|
10
10
|
/**
|
|
11
11
|
* Replaces all new lines in the specified value by HTML line breaks.
|
|
12
12
|
* @param value The string to format.
|
|
13
|
+
* @param options Value indicating whether to use XHTML compatible line breaks.
|
|
13
14
|
* @returns The formatted string.
|
|
14
15
|
*/
|
|
15
|
-
export function newLineToBr(value) {
|
|
16
|
-
return value.split(/\r?\n/g).join("<br>");
|
|
16
|
+
export function newLineToBr(value, options = {}) {
|
|
17
|
+
return value.split(/\r?\n/g).join(options.xhtml ? "<br />" : "<br>");
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* Reverses the specified string.
|
package/lib/TimeSpan.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const TimeSpan: Readonly<{
|
|
|
9
9
|
/**
|
|
10
10
|
* The number of minutes in 1 day.
|
|
11
11
|
*/
|
|
12
|
-
MinutesPerDay:
|
|
12
|
+
MinutesPerDay: number;
|
|
13
13
|
/**
|
|
14
14
|
* The number of minutes in 1 hour.
|
|
15
15
|
*/
|
|
@@ -17,11 +17,11 @@ export declare const TimeSpan: Readonly<{
|
|
|
17
17
|
/**
|
|
18
18
|
* The number of seconds in 1 day.
|
|
19
19
|
*/
|
|
20
|
-
SecondsPerDay:
|
|
20
|
+
SecondsPerDay: number;
|
|
21
21
|
/**
|
|
22
22
|
* The number of seconds in 1 hour.
|
|
23
23
|
*/
|
|
24
|
-
SecondsPerHour:
|
|
24
|
+
SecondsPerHour: number;
|
|
25
25
|
/**
|
|
26
26
|
* The number of seconds in 1 minute.
|
|
27
27
|
*/
|
|
@@ -29,15 +29,15 @@ export declare const TimeSpan: Readonly<{
|
|
|
29
29
|
/**
|
|
30
30
|
* The number of milliseconds in 1 day.
|
|
31
31
|
*/
|
|
32
|
-
MillisecondsPerDay:
|
|
32
|
+
MillisecondsPerDay: number;
|
|
33
33
|
/**
|
|
34
34
|
* The number of milliseconds in 1 hour.
|
|
35
35
|
*/
|
|
36
|
-
MillisecondsPerHour:
|
|
36
|
+
MillisecondsPerHour: number;
|
|
37
37
|
/**
|
|
38
38
|
* The number of milliseconds in 1 minute.
|
|
39
39
|
*/
|
|
40
|
-
MillisecondsPerMinute:
|
|
40
|
+
MillisecondsPerMinute: number;
|
|
41
41
|
/**
|
|
42
42
|
* The number of milliseconds in 1 second.
|
|
43
43
|
*/
|
package/lib/TimeSpan.js
CHANGED
|
@@ -9,7 +9,7 @@ export const TimeSpan = Object.freeze({
|
|
|
9
9
|
/**
|
|
10
10
|
* The number of minutes in 1 day.
|
|
11
11
|
*/
|
|
12
|
-
MinutesPerDay:
|
|
12
|
+
MinutesPerDay: 24 * 60,
|
|
13
13
|
/**
|
|
14
14
|
* The number of minutes in 1 hour.
|
|
15
15
|
*/
|
|
@@ -17,11 +17,11 @@ export const TimeSpan = Object.freeze({
|
|
|
17
17
|
/**
|
|
18
18
|
* The number of seconds in 1 day.
|
|
19
19
|
*/
|
|
20
|
-
SecondsPerDay:
|
|
20
|
+
SecondsPerDay: 24 * 60 * 60,
|
|
21
21
|
/**
|
|
22
22
|
* The number of seconds in 1 hour.
|
|
23
23
|
*/
|
|
24
|
-
SecondsPerHour:
|
|
24
|
+
SecondsPerHour: 60 * 60,
|
|
25
25
|
/**
|
|
26
26
|
* The number of seconds in 1 minute.
|
|
27
27
|
*/
|
|
@@ -29,15 +29,15 @@ export const TimeSpan = Object.freeze({
|
|
|
29
29
|
/**
|
|
30
30
|
* The number of milliseconds in 1 day.
|
|
31
31
|
*/
|
|
32
|
-
MillisecondsPerDay:
|
|
32
|
+
MillisecondsPerDay: 24 * 60 * 60 * 1_000,
|
|
33
33
|
/**
|
|
34
34
|
* The number of milliseconds in 1 hour.
|
|
35
35
|
*/
|
|
36
|
-
MillisecondsPerHour:
|
|
36
|
+
MillisecondsPerHour: 60 * 60 * 1_000,
|
|
37
37
|
/**
|
|
38
38
|
* The number of milliseconds in 1 minute.
|
|
39
39
|
*/
|
|
40
|
-
MillisecondsPerMinute:
|
|
40
|
+
MillisecondsPerMinute: 60 * 1_000,
|
|
41
41
|
/**
|
|
42
42
|
* The number of milliseconds in 1 second.
|
|
43
43
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackButton.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/BackButton.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAW,SAAQ,WAAW;IAE1C;;OAEG;;IAaH;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"BackButton.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/BackButton.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAW,SAAQ,WAAW;IAE1C;;OAEG;;IAaH;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAGtC;CACF;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,aAAa,EAAE,UAAU,CAAC;KAC1B;CACD"}
|
|
@@ -7,7 +7,7 @@ export class BackButton extends HTMLElement {
|
|
|
7
7
|
*/
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
|
-
this.addEventListener("click", this.goBack
|
|
10
|
+
this.addEventListener("click", this.goBack, { capture: true });
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Registers the component.
|
|
@@ -29,8 +29,8 @@ export class BackButton extends HTMLElement {
|
|
|
29
29
|
* Moves back in the session history.
|
|
30
30
|
* @param event The dispatched event.
|
|
31
31
|
*/
|
|
32
|
-
goBack
|
|
32
|
+
goBack = event => {
|
|
33
33
|
event?.stopPropagation();
|
|
34
34
|
history.go(-this.steps);
|
|
35
|
-
}
|
|
35
|
+
};
|
|
36
36
|
}
|
|
@@ -29,9 +29,9 @@ export class DialogBox extends HTMLElement {
|
|
|
29
29
|
constructor() {
|
|
30
30
|
super();
|
|
31
31
|
this.firstElementChild.addEventListener("hide.bs.modal", () => this.#resolve(this.#result));
|
|
32
|
-
this.querySelector(".btn-close").addEventListener("click", this.#close
|
|
32
|
+
this.querySelector(".btn-close").addEventListener("click", this.#close);
|
|
33
33
|
for (const button of this.querySelectorAll(".modal-footer button"))
|
|
34
|
-
button.addEventListener("click", this.#close
|
|
34
|
+
button.addEventListener("click", this.#close);
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Registers the component.
|
|
@@ -211,7 +211,7 @@ export class DialogBox extends HTMLElement {
|
|
|
211
211
|
if (message) {
|
|
212
212
|
const footer = message.footer ?? document.createDocumentFragment();
|
|
213
213
|
for (const button of footer.querySelectorAll("button"))
|
|
214
|
-
button.addEventListener("click", this.#close
|
|
214
|
+
button.addEventListener("click", this.#close);
|
|
215
215
|
this.body = message.body;
|
|
216
216
|
this.caption = message.caption;
|
|
217
217
|
this.footer = footer;
|
|
@@ -226,10 +226,10 @@ export class DialogBox extends HTMLElement {
|
|
|
226
226
|
* Closes this dialog box.
|
|
227
227
|
* @param event The dispatched event.
|
|
228
228
|
*/
|
|
229
|
-
#close
|
|
229
|
+
#close = event => {
|
|
230
230
|
event.preventDefault();
|
|
231
231
|
this.close(event.currentTarget.value);
|
|
232
|
-
}
|
|
232
|
+
};
|
|
233
233
|
/**
|
|
234
234
|
* Updates the title displayed in the header.
|
|
235
235
|
* @param value The new value.
|
|
@@ -30,7 +30,7 @@ export declare class FullScreenToggler extends HTMLElement {
|
|
|
30
30
|
* @param event The dispatched event.
|
|
31
31
|
* @returns Completes when the full-screen mode has been toggled.
|
|
32
32
|
*/
|
|
33
|
-
toggleFullScreen(event?: Event)
|
|
33
|
+
readonly toggleFullScreen: (event?: Event) => Promise<void>;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Declaration merging.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullScreenToggler.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/FullScreenToggler.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;;
|
|
1
|
+
{"version":3,"file":"FullScreenToggler.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/FullScreenToggler.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;;IAiBjD;;OAEG;;IAaH;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAGnB;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAMzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAI5B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAIzD;CAoCF;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,oBAAoB,EAAE,iBAAiB,CAAC;KACxC;CACD"}
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* A component for toggling an element to full-screen.
|
|
3
3
|
*/
|
|
4
4
|
export class FullScreenToggler extends HTMLElement {
|
|
5
|
+
/**
|
|
6
|
+
* The abort controller used to remove the event listeners.
|
|
7
|
+
*/
|
|
8
|
+
#abortController = new AbortController;
|
|
5
9
|
/**
|
|
6
10
|
* The target element.
|
|
7
11
|
*/
|
|
@@ -15,7 +19,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
15
19
|
*/
|
|
16
20
|
constructor() {
|
|
17
21
|
super();
|
|
18
|
-
this.addEventListener("click", this.toggleFullScreen
|
|
22
|
+
this.addEventListener("click", this.toggleFullScreen, { capture: true }); // eslint-disable-line @typescript-eslint/no-misused-promises
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
25
|
* Registers the component.
|
|
@@ -46,29 +50,28 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
46
50
|
* Method invoked when this component is connected.
|
|
47
51
|
*/
|
|
48
52
|
connectedCallback() {
|
|
49
|
-
document.addEventListener("visibilitychange", this.#onVisibilityChanged);
|
|
53
|
+
document.addEventListener("visibilitychange", this.#onVisibilityChanged, { signal: this.#abortController.signal });
|
|
50
54
|
this.#element = document.querySelector(this.target) ?? document.body;
|
|
51
|
-
this.#element.addEventListener("fullscreenchange", this.#onFullScreenChanged);
|
|
55
|
+
this.#element.addEventListener("fullscreenchange", this.#onFullScreenChanged, { signal: this.#abortController.signal });
|
|
52
56
|
}
|
|
53
57
|
/**
|
|
54
58
|
* Method invoked when this component is disconnected.
|
|
55
59
|
*/
|
|
56
60
|
disconnectedCallback() {
|
|
57
|
-
|
|
58
|
-
this.#element.removeEventListener("fullscreenchange", this.#onFullScreenChanged);
|
|
61
|
+
this.#abortController.abort();
|
|
59
62
|
}
|
|
60
63
|
/**
|
|
61
64
|
* Toggles the full-screen mode of the associated element.
|
|
62
65
|
* @param event The dispatched event.
|
|
63
66
|
* @returns Completes when the full-screen mode has been toggled.
|
|
64
67
|
*/
|
|
65
|
-
async
|
|
68
|
+
toggleFullScreen = async (event) => {
|
|
66
69
|
event?.stopPropagation();
|
|
67
70
|
if (document.fullscreenElement)
|
|
68
71
|
await document.exitFullscreen();
|
|
69
72
|
else
|
|
70
73
|
await this.#element.requestFullscreen();
|
|
71
|
-
}
|
|
74
|
+
};
|
|
72
75
|
/**
|
|
73
76
|
* Acquires a new wake lock.
|
|
74
77
|
* @returns Completes when the wake lock has been acquired.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KeyboardAccelerator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/KeyboardAccelerator.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;;
|
|
1
|
+
{"version":3,"file":"KeyboardAccelerator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/KeyboardAccelerator.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;;IAmBnD;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IACD,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,EAEpB;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAItB;IACD,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,EAK1B;IAED;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;CAuB5B;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,sBAAsB,EAAE,mBAAmB,CAAC;KAC5C;CACD"}
|
|
@@ -3,6 +3,10 @@ import { KeyboardModifiers } from "../KeyboardModifiers.js";
|
|
|
3
3
|
* Represents a shortcut key associated with an element.
|
|
4
4
|
*/
|
|
5
5
|
export class KeyboardAccelerator extends HTMLElement {
|
|
6
|
+
/**
|
|
7
|
+
* The abort controller used to remove the event listeners.
|
|
8
|
+
*/
|
|
9
|
+
#abortController = new AbortController;
|
|
6
10
|
/**
|
|
7
11
|
* The mapping between the modifier names and their values.
|
|
8
12
|
*/
|
|
@@ -40,13 +44,13 @@ export class KeyboardAccelerator extends HTMLElement {
|
|
|
40
44
|
* Method invoked when this component is connected.
|
|
41
45
|
*/
|
|
42
46
|
connectedCallback() {
|
|
43
|
-
addEventListener("keyup", this.#activateChildContent, { capture: true });
|
|
47
|
+
addEventListener("keyup", this.#activateChildContent, { capture: true, signal: this.#abortController.signal });
|
|
44
48
|
}
|
|
45
49
|
/**
|
|
46
50
|
* Method invoked when this component is disconnected.
|
|
47
51
|
*/
|
|
48
52
|
disconnectedCallback() {
|
|
49
|
-
|
|
53
|
+
this.#abortController.abort();
|
|
50
54
|
}
|
|
51
55
|
/**
|
|
52
56
|
* Activates the child content when the specified keyboard event designates the same key and modifiers as this keyboard accelerator.
|
|
@@ -12,6 +12,10 @@ export declare class LoadingIndicator extends HTMLElement {
|
|
|
12
12
|
*/
|
|
13
13
|
get fade(): boolean;
|
|
14
14
|
set fade(value: boolean);
|
|
15
|
+
/**
|
|
16
|
+
* Value indicating whether this component is shown.
|
|
17
|
+
*/
|
|
18
|
+
get isShown(): boolean;
|
|
15
19
|
/**
|
|
16
20
|
* Value indicating whether to initially show this component.
|
|
17
21
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/LoadingIndicator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;;IAEhD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAY;IAc9C;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAO/F;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;;OAGG;IACH,IAAI,CAAC,OAAO,GAAE;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,IAAI;IAS3C;;OAEG;IACH,IAAI,IAAI,IAAI;CAaZ;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,gBAAgB,CAAC;KACtC;CACD"}
|
|
1
|
+
{"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/LoadingIndicator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;;IAEhD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAY;IAc9C;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAO/F;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;;OAGG;IACH,IAAI,CAAC,OAAO,GAAE;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,IAAI;IAS3C;;OAEG;IACH,IAAI,IAAI,IAAI;CAaZ;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,gBAAgB,CAAC;KACtC;CACD"}
|
|
@@ -25,6 +25,12 @@ export class LoadingIndicator extends HTMLElement {
|
|
|
25
25
|
set fade(value) {
|
|
26
26
|
this.toggleAttribute("fade", value);
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Value indicating whether this component is shown.
|
|
30
|
+
*/
|
|
31
|
+
get isShown() {
|
|
32
|
+
return this.classList.contains("show");
|
|
33
|
+
}
|
|
28
34
|
/**
|
|
29
35
|
* Value indicating whether to initially show this component.
|
|
30
36
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuActivator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/MenuActivator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;;
|
|
1
|
+
{"version":3,"file":"MenuActivator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/MenuActivator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;;IAc7C;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAMzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;CAe5B;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,gBAAgB,EAAE,aAAa,CAAC;KAChC;CACD"}
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* A component that activates the items of a menu, based on the current document URL.
|
|
3
3
|
*/
|
|
4
4
|
export class MenuActivator extends HTMLElement {
|
|
5
|
+
/**
|
|
6
|
+
* The abort controller used to remove the event listeners.
|
|
7
|
+
*/
|
|
8
|
+
#abortController = new AbortController;
|
|
5
9
|
/**
|
|
6
10
|
* Registers the component.
|
|
7
11
|
*/
|
|
@@ -13,15 +17,14 @@ export class MenuActivator extends HTMLElement {
|
|
|
13
17
|
*/
|
|
14
18
|
connectedCallback() {
|
|
15
19
|
this.#update();
|
|
16
|
-
addEventListener("popstate", this.#update);
|
|
17
|
-
document.body.addEventListener("htmx:afterRequest", this.#update);
|
|
20
|
+
addEventListener("popstate", this.#update, { signal: this.#abortController.signal });
|
|
21
|
+
document.body.addEventListener("htmx:afterRequest", this.#update, { signal: this.#abortController.signal });
|
|
18
22
|
}
|
|
19
23
|
/**
|
|
20
24
|
* Method invoked when this component is disconnected.
|
|
21
25
|
*/
|
|
22
26
|
disconnectedCallback() {
|
|
23
|
-
|
|
24
|
-
document.body.removeEventListener("htmx:afterRequest", this.#update);
|
|
27
|
+
this.#abortController.abort();
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
27
30
|
* Updates this component.
|
|
@@ -12,6 +12,10 @@ export declare class OfflineIndicator extends HTMLElement {
|
|
|
12
12
|
*/
|
|
13
13
|
get fade(): boolean;
|
|
14
14
|
set fade(value: boolean);
|
|
15
|
+
/**
|
|
16
|
+
* Value indicating whether this component is shown.
|
|
17
|
+
*/
|
|
18
|
+
get isShown(): boolean;
|
|
15
19
|
/**
|
|
16
20
|
* Value indicating whether to initially show this component.
|
|
17
21
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OfflineIndicator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/OfflineIndicator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;;IAEhD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAY;
|
|
1
|
+
{"version":3,"file":"OfflineIndicator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/OfflineIndicator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;;IAEhD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAY;IAc9C;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAO/F;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAMzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAI5B;;OAEG;IACH,IAAI,IAAI,IAAI;IAKZ;;OAEG;IACH,IAAI,IAAI,IAAI;CAoBZ;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,gBAAgB,CAAC;KACtC;CACD"}
|
|
@@ -6,6 +6,10 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
6
6
|
* The list of observed attributes.
|
|
7
7
|
*/
|
|
8
8
|
static observedAttributes = ["fade"];
|
|
9
|
+
/**
|
|
10
|
+
* The abort controller used to remove the event listeners.
|
|
11
|
+
*/
|
|
12
|
+
#abortController = new AbortController;
|
|
9
13
|
/**
|
|
10
14
|
* Registers the component.
|
|
11
15
|
*/
|
|
@@ -21,6 +25,12 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
21
25
|
set fade(value) {
|
|
22
26
|
this.toggleAttribute("fade", value);
|
|
23
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Value indicating whether this component is shown.
|
|
30
|
+
*/
|
|
31
|
+
get isShown() {
|
|
32
|
+
return this.classList.contains("show");
|
|
33
|
+
}
|
|
24
34
|
/**
|
|
25
35
|
* Value indicating whether to initially show this component.
|
|
26
36
|
*/
|
|
@@ -50,7 +60,7 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
50
60
|
*/
|
|
51
61
|
connectedCallback() {
|
|
52
62
|
for (const event of ["online", "offline"])
|
|
53
|
-
addEventListener(event, this.#updateVisibility);
|
|
63
|
+
addEventListener(event, this.#updateVisibility, { signal: this.#abortController.signal });
|
|
54
64
|
if (this.open)
|
|
55
65
|
this.show();
|
|
56
66
|
else
|
|
@@ -60,8 +70,7 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
60
70
|
* Method invoked when this component is disconnected.
|
|
61
71
|
*/
|
|
62
72
|
disconnectedCallback() {
|
|
63
|
-
|
|
64
|
-
removeEventListener(event, this.#updateVisibility);
|
|
73
|
+
this.#abortController.abort();
|
|
65
74
|
}
|
|
66
75
|
/**
|
|
67
76
|
* Hides this offline indicator.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabActivator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/TabActivator.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE9C;;GAEG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAE5C;;OAEG;;
|
|
1
|
+
{"version":3,"file":"TabActivator.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/TabActivator.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE9C;;GAEG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAE5C;;OAEG;;IAgBH;;OAEG;IACH,IAAI,cAAc,IAAI,MAAM,CAG3B;IACD,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,EAE/B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,UAAU,CAAC,OAAO,CAEhC;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,WAAW,CAG7B;IACD,IAAI,WAAW,CAAC,KAAK,EAAE,WAAW,EAEjC;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAGvB;IACD,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,UAAU,CAAC,WAAW,CAAC,CAElC;IAED;;OAEG;IACH,iBAAiB,IAAI,IAAI;CAGzB;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,eAAe,EAAE,YAAY,CAAC;KAC9B;CACD"}
|
|
@@ -23,6 +23,16 @@ export declare class ThemeDropdown extends HTMLElement {
|
|
|
23
23
|
*/
|
|
24
24
|
get appTheme(): AppTheme;
|
|
25
25
|
set appTheme(value: AppTheme);
|
|
26
|
+
/**
|
|
27
|
+
* Value indicating whether to store the application theme in a cookie.
|
|
28
|
+
*/
|
|
29
|
+
get cookie(): boolean;
|
|
30
|
+
set cookie(value: boolean);
|
|
31
|
+
/**
|
|
32
|
+
* The URI for which the associated cookie is valid.
|
|
33
|
+
*/
|
|
34
|
+
get cookieDomain(): string;
|
|
35
|
+
set cookieDomain(value: string);
|
|
26
36
|
/**
|
|
27
37
|
* The label of the dropdown menu.
|
|
28
38
|
*/
|
|
@@ -46,8 +56,9 @@ export declare class ThemeDropdown extends HTMLElement {
|
|
|
46
56
|
close(): void;
|
|
47
57
|
/**
|
|
48
58
|
* Method invoked when this component is connected.
|
|
59
|
+
* @returns Completes when this component has been connected.
|
|
49
60
|
*/
|
|
50
|
-
connectedCallback(): void
|
|
61
|
+
connectedCallback(): Promise<void>;
|
|
51
62
|
/**
|
|
52
63
|
* Method invoked when this component is disconnected.
|
|
53
64
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeDropdown.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/ThemeDropdown.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAC,QAAQ,EAAU,MAAM,gBAAgB,CAAC;AAEjD;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;;IAE7C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAsC;
|
|
1
|
+
{"version":3,"file":"ThemeDropdown.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/ThemeDropdown.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAC,QAAQ,EAAU,MAAM,gBAAgB,CAAC;AAEjD;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;;IAE7C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAsC;IAiBxE;;OAEG;;IAaH;;OAEG;IACH,IAAI,SAAS,IAAI,SAAS,CAGzB;IACD,IAAI,SAAS,CAAC,KAAK,EAAE,SAAS,EAE7B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,QAAQ,CAGvB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAE3B;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,OAAO,CAEpB;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAGvB;IACD,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAS/F;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYxC;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAK5B;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,IAAI,IAAI,IAAI;CAwDZ;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,gBAAgB,EAAE,aAAa,CAAC;KAChC;CACD"}
|
|
@@ -9,6 +9,10 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
9
9
|
* The list of observed attributes.
|
|
10
10
|
*/
|
|
11
11
|
static observedAttributes = ["alignment", "apptheme", "label"];
|
|
12
|
+
/**
|
|
13
|
+
* The abort controller used to remove the event listeners.
|
|
14
|
+
*/
|
|
15
|
+
#abortController = new AbortController;
|
|
12
16
|
/**
|
|
13
17
|
* The dropdown menu.
|
|
14
18
|
*/
|
|
@@ -23,7 +27,7 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
23
27
|
constructor() {
|
|
24
28
|
super();
|
|
25
29
|
for (const button of this.querySelectorAll(".dropdown-menu button"))
|
|
26
|
-
button.addEventListener("click", this.#setAppTheme
|
|
30
|
+
button.addEventListener("click", this.#setAppTheme);
|
|
27
31
|
}
|
|
28
32
|
/**
|
|
29
33
|
* Registers the component.
|
|
@@ -51,6 +55,24 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
51
55
|
set appTheme(value) {
|
|
52
56
|
this.setAttribute("apptheme", value);
|
|
53
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Value indicating whether to store the application theme in a cookie.
|
|
60
|
+
*/
|
|
61
|
+
get cookie() {
|
|
62
|
+
return this.hasAttribute("cookie");
|
|
63
|
+
}
|
|
64
|
+
set cookie(value) {
|
|
65
|
+
this.toggleAttribute("cookie", value);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The URI for which the associated cookie is valid.
|
|
69
|
+
*/
|
|
70
|
+
get cookieDomain() {
|
|
71
|
+
return (this.getAttribute("cookiedomain") ?? "").trim();
|
|
72
|
+
}
|
|
73
|
+
set cookieDomain(value) {
|
|
74
|
+
this.setAttribute("cookiedomain", value);
|
|
75
|
+
}
|
|
54
76
|
/**
|
|
55
77
|
* The label of the dropdown menu.
|
|
56
78
|
*/
|
|
@@ -100,20 +122,26 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
100
122
|
}
|
|
101
123
|
/**
|
|
102
124
|
* Method invoked when this component is connected.
|
|
125
|
+
* @returns Completes when this component has been connected.
|
|
103
126
|
*/
|
|
104
|
-
connectedCallback() {
|
|
105
|
-
const appTheme = localStorage.getItem(this.storageKey);
|
|
106
|
-
if (appTheme)
|
|
107
|
-
this.appTheme = appTheme;
|
|
127
|
+
async connectedCallback() {
|
|
108
128
|
this.#dropdown = new Dropdown(this.querySelector(".dropdown-toggle"));
|
|
109
|
-
this.#mediaQuery.addEventListener("change", this.#applyToDocument);
|
|
129
|
+
this.#mediaQuery.addEventListener("change", this.#applyToDocument, { signal: this.#abortController.signal });
|
|
130
|
+
const cookie = this.cookie ? await cookieStore.get(this.storageKey) : null;
|
|
131
|
+
if (cookie)
|
|
132
|
+
this.appTheme = cookie.value;
|
|
133
|
+
else {
|
|
134
|
+
const storage = localStorage.getItem(this.storageKey);
|
|
135
|
+
if (storage)
|
|
136
|
+
this.appTheme = storage;
|
|
137
|
+
}
|
|
110
138
|
}
|
|
111
139
|
/**
|
|
112
140
|
* Method invoked when this component is disconnected.
|
|
113
141
|
*/
|
|
114
142
|
disconnectedCallback() {
|
|
143
|
+
this.#abortController.abort();
|
|
115
144
|
this.#dropdown.dispose();
|
|
116
|
-
this.#mediaQuery.removeEventListener("change", this.#applyToDocument);
|
|
117
145
|
}
|
|
118
146
|
/**
|
|
119
147
|
* Opens the dropdown menu.
|
|
@@ -125,7 +153,15 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
125
153
|
* Saves the current application theme into the local storage.
|
|
126
154
|
*/
|
|
127
155
|
save() {
|
|
128
|
-
|
|
156
|
+
const { appTheme, cookieDomain } = this;
|
|
157
|
+
localStorage.setItem(this.storageKey, appTheme);
|
|
158
|
+
if (this.cookie)
|
|
159
|
+
void cookieStore.set({
|
|
160
|
+
domain: cookieDomain ? cookieDomain : null,
|
|
161
|
+
expires: Date.now() + (365 * 24 * 60 * 60 * 1_000),
|
|
162
|
+
name: this.storageKey,
|
|
163
|
+
value: appTheme
|
|
164
|
+
});
|
|
129
165
|
}
|
|
130
166
|
/**
|
|
131
167
|
* Applies the application theme to the document.
|
|
@@ -139,11 +175,11 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
139
175
|
* Changes the current application theme.
|
|
140
176
|
* @param event The dispatched event.
|
|
141
177
|
*/
|
|
142
|
-
#setAppTheme
|
|
178
|
+
#setAppTheme = event => {
|
|
143
179
|
event.preventDefault();
|
|
144
180
|
this.appTheme = event.currentTarget.value;
|
|
145
181
|
this.save();
|
|
146
|
-
}
|
|
182
|
+
};
|
|
147
183
|
/**
|
|
148
184
|
* Updates the alignment of the dropdown menu.
|
|
149
185
|
* @param value The new value.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toast.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAiB,MAAM,eAAe,CAAC;AAEtD;;GAEG;AACH,qBAAa,KAAM,SAAQ,WAAW;;IAErC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAA0E;
|
|
1
|
+
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toast.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAiB,MAAM,eAAe,CAAC;AAEtD;;GAEG;AACH,qBAAa,KAAM,SAAQ,WAAW;;IAErC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAA0E;IAuC5G;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;OAEG;IACH,IAAI,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAE/B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAExB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAGrB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAGzB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,GAAC,IAAI,CAGtB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAC,IAAI,EAG1B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAa/F;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,iBAAiB,IAAI,IAAI;IASzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAM5B;;OAEG;IACH,IAAI,IAAI,IAAI;CAoGZ;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,cAAc,EAAE,KAAK,CAAC;KACtB;CACD"}
|
|
@@ -12,6 +12,10 @@ export class Toast extends HTMLElement {
|
|
|
12
12
|
* The time units.
|
|
13
13
|
*/
|
|
14
14
|
static #timeUnits = ["second", "minute", "hour"];
|
|
15
|
+
/**
|
|
16
|
+
* The abort controller used to remove the event listeners.
|
|
17
|
+
*/
|
|
18
|
+
#abortController = new AbortController;
|
|
15
19
|
/**
|
|
16
20
|
* The formatter used to format the relative time.
|
|
17
21
|
*/
|
|
@@ -169,8 +173,8 @@ export class Toast extends HTMLElement {
|
|
|
169
173
|
*/
|
|
170
174
|
connectedCallback() {
|
|
171
175
|
const root = this.firstElementChild;
|
|
172
|
-
root.addEventListener("hide.bs.toast", this.#stopTimer);
|
|
173
|
-
root.addEventListener("show.bs.toast", this.#startTimer);
|
|
176
|
+
root.addEventListener("hide.bs.toast", this.#stopTimer, { signal: this.#abortController.signal });
|
|
177
|
+
root.addEventListener("show.bs.toast", this.#startTimer, { signal: this.#abortController.signal });
|
|
174
178
|
this.#toast = new BootstrapToast(root);
|
|
175
179
|
if (this.open)
|
|
176
180
|
this.show();
|
|
@@ -179,10 +183,8 @@ export class Toast extends HTMLElement {
|
|
|
179
183
|
* Method invoked when this component is disconnected.
|
|
180
184
|
*/
|
|
181
185
|
disconnectedCallback() {
|
|
182
|
-
const root = this.firstElementChild;
|
|
183
|
-
root.removeEventListener("hide.bs.toast", () => this.#stopTimer);
|
|
184
|
-
root.removeEventListener("show.bs.toast", () => this.#startTimer);
|
|
185
186
|
this.#stopTimer();
|
|
187
|
+
this.#abortController.abort();
|
|
186
188
|
this.#toast.dispose();
|
|
187
189
|
}
|
|
188
190
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAC,QAAQ,EAAQ,MAAM,gBAAgB,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,MAAM;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,gBAAgB,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,OAAQ,SAAQ,WAAW;;IAEvC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAgB;IAOlD;;OAEG;;
|
|
1
|
+
{"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAC,QAAQ,EAAQ,MAAM,gBAAgB,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,MAAM;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,gBAAgB,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,OAAQ,SAAQ,WAAW;;IAEvC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAgB;IAOlD;;OAEG;;IAaH;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAGrB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAGzB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,GAAC,IAAI,CAGtB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAC,IAAI,EAG1B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,QAAQ,CAGvB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAE3B;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAO/F;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAI1E;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CA4BzB;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,OAAO,CAAC;KAC7B;CACD"}
|
package/package.json
CHANGED
|
@@ -7,23 +7,23 @@
|
|
|
7
7
|
"name": "@cedx/base",
|
|
8
8
|
"repository": "cedx/base",
|
|
9
9
|
"type": "module",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.31.0",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@playwright/browser-chromium": "^1.55.0",
|
|
13
13
|
"@types/bootstrap": "^5.2.10",
|
|
14
14
|
"@types/chai": "^5.2.2",
|
|
15
15
|
"@types/mocha": "^10.0.10",
|
|
16
|
-
"@types/node": "^24.
|
|
16
|
+
"@types/node": "^24.5.2",
|
|
17
17
|
"@types/serve-handler": "^6.1.4",
|
|
18
18
|
"chai": "^6.0.1",
|
|
19
|
-
"esbuild": "^0.25.
|
|
20
|
-
"globals": "^16.
|
|
19
|
+
"esbuild": "^0.25.10",
|
|
20
|
+
"globals": "^16.4.0",
|
|
21
21
|
"mocha": "^11.7.2",
|
|
22
22
|
"playwright": "^1.55.0",
|
|
23
23
|
"serve-handler": "^6.1.6",
|
|
24
|
-
"typedoc": "^0.28.
|
|
24
|
+
"typedoc": "^0.28.13",
|
|
25
25
|
"typescript": "^5.9.2",
|
|
26
|
-
"typescript-eslint": "^8.
|
|
26
|
+
"typescript-eslint": "^8.44.0"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=24.0.0"
|
package/src/Client/String.ts
CHANGED
|
@@ -11,10 +11,11 @@ export function capitalize(value: string, locale: Intl.Locale|string = navigator
|
|
|
11
11
|
/**
|
|
12
12
|
* Replaces all new lines in the specified value by HTML line breaks.
|
|
13
13
|
* @param value The string to format.
|
|
14
|
+
* @param options Value indicating whether to use XHTML compatible line breaks.
|
|
14
15
|
* @returns The formatted string.
|
|
15
16
|
*/
|
|
16
|
-
export function newLineToBr(value: string): string {
|
|
17
|
-
return value.split(/\r?\n/g).join("<br>");
|
|
17
|
+
export function newLineToBr(value: string, options: {xhtml?: boolean} = {}): string {
|
|
18
|
+
return value.split(/\r?\n/g).join(options.xhtml ? "<br />" : "<br>");
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
/**
|
package/src/Client/TimeSpan.ts
CHANGED
|
@@ -11,7 +11,7 @@ export const TimeSpan = Object.freeze({
|
|
|
11
11
|
/**
|
|
12
12
|
* The number of minutes in 1 day.
|
|
13
13
|
*/
|
|
14
|
-
MinutesPerDay:
|
|
14
|
+
MinutesPerDay: 24 * 60,
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* The number of minutes in 1 hour.
|
|
@@ -21,12 +21,12 @@ export const TimeSpan = Object.freeze({
|
|
|
21
21
|
/**
|
|
22
22
|
* The number of seconds in 1 day.
|
|
23
23
|
*/
|
|
24
|
-
SecondsPerDay:
|
|
24
|
+
SecondsPerDay: 24 * 60 * 60,
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* The number of seconds in 1 hour.
|
|
28
28
|
*/
|
|
29
|
-
SecondsPerHour:
|
|
29
|
+
SecondsPerHour: 60 * 60,
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* The number of seconds in 1 minute.
|
|
@@ -36,17 +36,17 @@ export const TimeSpan = Object.freeze({
|
|
|
36
36
|
/**
|
|
37
37
|
* The number of milliseconds in 1 day.
|
|
38
38
|
*/
|
|
39
|
-
MillisecondsPerDay:
|
|
39
|
+
MillisecondsPerDay: 24 * 60 * 60 * 1_000,
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* The number of milliseconds in 1 hour.
|
|
43
43
|
*/
|
|
44
|
-
MillisecondsPerHour:
|
|
44
|
+
MillisecondsPerHour: 60 * 60 * 1_000,
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* The number of milliseconds in 1 minute.
|
|
48
48
|
*/
|
|
49
|
-
MillisecondsPerMinute:
|
|
49
|
+
MillisecondsPerMinute: 60 * 1_000,
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* The number of milliseconds in 1 second.
|
|
@@ -8,7 +8,7 @@ export class BackButton extends HTMLElement {
|
|
|
8
8
|
*/
|
|
9
9
|
constructor() {
|
|
10
10
|
super();
|
|
11
|
-
this.addEventListener("click", this.goBack
|
|
11
|
+
this.addEventListener("click", this.goBack, {capture: true});
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -33,10 +33,10 @@ export class BackButton extends HTMLElement {
|
|
|
33
33
|
* Moves back in the session history.
|
|
34
34
|
* @param event The dispatched event.
|
|
35
35
|
*/
|
|
36
|
-
goBack(event?: Event)
|
|
36
|
+
readonly goBack: (event?: Event) => void = event => {
|
|
37
37
|
event?.stopPropagation();
|
|
38
38
|
history.go(-this.steps);
|
|
39
|
-
}
|
|
39
|
+
};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -82,8 +82,8 @@ export class DialogBox extends HTMLElement {
|
|
|
82
82
|
constructor() {
|
|
83
83
|
super();
|
|
84
84
|
this.firstElementChild!.addEventListener("hide.bs.modal", () => this.#resolve(this.#result));
|
|
85
|
-
this.querySelector(".btn-close")!.addEventListener("click", this.#close
|
|
86
|
-
for (const button of this.querySelectorAll(".modal-footer button")) button.addEventListener("click", this.#close
|
|
85
|
+
this.querySelector(".btn-close")!.addEventListener("click", this.#close);
|
|
86
|
+
for (const button of this.querySelectorAll(".modal-footer button")) button.addEventListener("click", this.#close);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
@@ -267,7 +267,7 @@ export class DialogBox extends HTMLElement {
|
|
|
267
267
|
show(message: IDialogMessage|null = null): Promise<string> {
|
|
268
268
|
if (message) {
|
|
269
269
|
const footer = message.footer ?? document.createDocumentFragment();
|
|
270
|
-
for (const button of footer.querySelectorAll("button")) button.addEventListener("click", this.#close
|
|
270
|
+
for (const button of footer.querySelectorAll("button")) button.addEventListener("click", this.#close);
|
|
271
271
|
this.body = message.body;
|
|
272
272
|
this.caption = message.caption;
|
|
273
273
|
this.footer = footer;
|
|
@@ -284,10 +284,10 @@ export class DialogBox extends HTMLElement {
|
|
|
284
284
|
* Closes this dialog box.
|
|
285
285
|
* @param event The dispatched event.
|
|
286
286
|
*/
|
|
287
|
-
#close(event: Event)
|
|
287
|
+
readonly #close: (event: Event) => void = event => {
|
|
288
288
|
event.preventDefault();
|
|
289
289
|
this.close((event.currentTarget as HTMLButtonElement).value);
|
|
290
|
-
}
|
|
290
|
+
};
|
|
291
291
|
|
|
292
292
|
/**
|
|
293
293
|
* Updates the title displayed in the header.
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export class FullScreenToggler extends HTMLElement {
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The abort controller used to remove the event listeners.
|
|
8
|
+
*/
|
|
9
|
+
readonly #abortController = new AbortController;
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* The target element.
|
|
8
13
|
*/
|
|
@@ -18,7 +23,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
18
23
|
*/
|
|
19
24
|
constructor() {
|
|
20
25
|
super();
|
|
21
|
-
this.addEventListener("click", this.toggleFullScreen
|
|
26
|
+
this.addEventListener("click", this.toggleFullScreen, {capture: true}); // eslint-disable-line @typescript-eslint/no-misused-promises
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
/**
|
|
@@ -53,17 +58,16 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
53
58
|
* Method invoked when this component is connected.
|
|
54
59
|
*/
|
|
55
60
|
connectedCallback(): void {
|
|
56
|
-
document.addEventListener("visibilitychange", this.#onVisibilityChanged);
|
|
61
|
+
document.addEventListener("visibilitychange", this.#onVisibilityChanged, {signal: this.#abortController.signal});
|
|
57
62
|
this.#element = document.querySelector(this.target) ?? document.body;
|
|
58
|
-
this.#element.addEventListener("fullscreenchange", this.#onFullScreenChanged);
|
|
63
|
+
this.#element.addEventListener("fullscreenchange", this.#onFullScreenChanged, {signal: this.#abortController.signal});
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
/**
|
|
62
67
|
* Method invoked when this component is disconnected.
|
|
63
68
|
*/
|
|
64
69
|
disconnectedCallback(): void {
|
|
65
|
-
|
|
66
|
-
this.#element.removeEventListener("fullscreenchange", this.#onFullScreenChanged);
|
|
70
|
+
this.#abortController.abort();
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
/**
|
|
@@ -71,11 +75,11 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
71
75
|
* @param event The dispatched event.
|
|
72
76
|
* @returns Completes when the full-screen mode has been toggled.
|
|
73
77
|
*/
|
|
74
|
-
|
|
78
|
+
readonly toggleFullScreen: (event?: Event) => Promise<void> = async event => {
|
|
75
79
|
event?.stopPropagation();
|
|
76
80
|
if (document.fullscreenElement) await document.exitFullscreen();
|
|
77
81
|
else await this.#element.requestFullscreen();
|
|
78
|
-
}
|
|
82
|
+
};
|
|
79
83
|
|
|
80
84
|
/**
|
|
81
85
|
* Acquires a new wake lock.
|
|
@@ -5,6 +5,11 @@ import {KeyboardModifiers} from "../KeyboardModifiers.js";
|
|
|
5
5
|
*/
|
|
6
6
|
export class KeyboardAccelerator extends HTMLElement {
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* The abort controller used to remove the event listeners.
|
|
10
|
+
*/
|
|
11
|
+
readonly #abortController = new AbortController;
|
|
12
|
+
|
|
8
13
|
/**
|
|
9
14
|
* The mapping between the modifier names and their values.
|
|
10
15
|
*/
|
|
@@ -46,14 +51,14 @@ export class KeyboardAccelerator extends HTMLElement {
|
|
|
46
51
|
* Method invoked when this component is connected.
|
|
47
52
|
*/
|
|
48
53
|
connectedCallback(): void {
|
|
49
|
-
addEventListener("keyup", this.#activateChildContent, {capture: true});
|
|
54
|
+
addEventListener("keyup", this.#activateChildContent, {capture: true, signal: this.#abortController.signal});
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
/**
|
|
53
58
|
* Method invoked when this component is disconnected.
|
|
54
59
|
*/
|
|
55
60
|
disconnectedCallback(): void {
|
|
56
|
-
|
|
61
|
+
this.#abortController.abort();
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
/**
|
|
@@ -30,6 +30,13 @@ export class LoadingIndicator extends HTMLElement {
|
|
|
30
30
|
this.toggleAttribute("fade", value);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Value indicating whether this component is shown.
|
|
35
|
+
*/
|
|
36
|
+
get isShown(): boolean {
|
|
37
|
+
return this.classList.contains("show");
|
|
38
|
+
}
|
|
39
|
+
|
|
33
40
|
/**
|
|
34
41
|
* Value indicating whether to initially show this component.
|
|
35
42
|
*/
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export class MenuActivator extends HTMLElement {
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The abort controller used to remove the event listeners.
|
|
8
|
+
*/
|
|
9
|
+
readonly #abortController = new AbortController;
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* Registers the component.
|
|
8
13
|
*/
|
|
@@ -15,16 +20,15 @@ export class MenuActivator extends HTMLElement {
|
|
|
15
20
|
*/
|
|
16
21
|
connectedCallback(): void {
|
|
17
22
|
this.#update();
|
|
18
|
-
addEventListener("popstate", this.#update);
|
|
19
|
-
document.body.addEventListener("htmx:afterRequest", this.#update);
|
|
23
|
+
addEventListener("popstate", this.#update, {signal: this.#abortController.signal});
|
|
24
|
+
document.body.addEventListener("htmx:afterRequest", this.#update, {signal: this.#abortController.signal});
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
/**
|
|
23
28
|
* Method invoked when this component is disconnected.
|
|
24
29
|
*/
|
|
25
30
|
disconnectedCallback(): void {
|
|
26
|
-
|
|
27
|
-
document.body.removeEventListener("htmx:afterRequest", this.#update);
|
|
31
|
+
this.#abortController.abort();
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
/**
|
|
@@ -8,6 +8,11 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
8
8
|
*/
|
|
9
9
|
static readonly observedAttributes = ["fade"];
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* The abort controller used to remove the event listeners.
|
|
13
|
+
*/
|
|
14
|
+
readonly #abortController = new AbortController;
|
|
15
|
+
|
|
11
16
|
/**
|
|
12
17
|
* Registers the component.
|
|
13
18
|
*/
|
|
@@ -25,6 +30,13 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
25
30
|
this.toggleAttribute("fade", value);
|
|
26
31
|
}
|
|
27
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Value indicating whether this component is shown.
|
|
35
|
+
*/
|
|
36
|
+
get isShown(): boolean {
|
|
37
|
+
return this.classList.contains("show");
|
|
38
|
+
}
|
|
39
|
+
|
|
28
40
|
/**
|
|
29
41
|
* Value indicating whether to initially show this component.
|
|
30
42
|
*/
|
|
@@ -52,7 +64,7 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
52
64
|
* Method invoked when this component is connected.
|
|
53
65
|
*/
|
|
54
66
|
connectedCallback(): void {
|
|
55
|
-
for (const event of ["online", "offline"]) addEventListener(event, this.#updateVisibility);
|
|
67
|
+
for (const event of ["online", "offline"]) addEventListener(event, this.#updateVisibility, {signal: this.#abortController.signal});
|
|
56
68
|
if (this.open) this.show();
|
|
57
69
|
else this.#updateVisibility();
|
|
58
70
|
}
|
|
@@ -61,7 +73,7 @@ export class OfflineIndicator extends HTMLElement {
|
|
|
61
73
|
* Method invoked when this component is disconnected.
|
|
62
74
|
*/
|
|
63
75
|
disconnectedCallback(): void {
|
|
64
|
-
|
|
76
|
+
this.#abortController.abort();
|
|
65
77
|
}
|
|
66
78
|
|
|
67
79
|
/**
|
|
@@ -12,6 +12,11 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
12
12
|
*/
|
|
13
13
|
static readonly observedAttributes = ["alignment", "apptheme", "label"];
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* The abort controller used to remove the event listeners.
|
|
17
|
+
*/
|
|
18
|
+
readonly #abortController = new AbortController;
|
|
19
|
+
|
|
15
20
|
/**
|
|
16
21
|
* The dropdown menu.
|
|
17
22
|
*/
|
|
@@ -27,8 +32,7 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
27
32
|
*/
|
|
28
33
|
constructor() {
|
|
29
34
|
super();
|
|
30
|
-
for (const button of this.querySelectorAll(".dropdown-menu button"))
|
|
31
|
-
button.addEventListener("click", this.#setAppTheme.bind(this));
|
|
35
|
+
for (const button of this.querySelectorAll(".dropdown-menu button")) button.addEventListener("click", this.#setAppTheme);
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
/**
|
|
@@ -60,6 +64,26 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
60
64
|
this.setAttribute("apptheme", value);
|
|
61
65
|
}
|
|
62
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Value indicating whether to store the application theme in a cookie.
|
|
69
|
+
*/
|
|
70
|
+
get cookie(): boolean {
|
|
71
|
+
return this.hasAttribute("cookie");
|
|
72
|
+
}
|
|
73
|
+
set cookie(value: boolean) {
|
|
74
|
+
this.toggleAttribute("cookie", value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The URI for which the associated cookie is valid.
|
|
79
|
+
*/
|
|
80
|
+
get cookieDomain(): string {
|
|
81
|
+
return (this.getAttribute("cookiedomain") ?? "").trim();
|
|
82
|
+
}
|
|
83
|
+
set cookieDomain(value: string) {
|
|
84
|
+
this.setAttribute("cookiedomain", value);
|
|
85
|
+
}
|
|
86
|
+
|
|
63
87
|
/**
|
|
64
88
|
* The label of the dropdown menu.
|
|
65
89
|
*/
|
|
@@ -106,21 +130,26 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
106
130
|
|
|
107
131
|
/**
|
|
108
132
|
* Method invoked when this component is connected.
|
|
133
|
+
* @returns Completes when this component has been connected.
|
|
109
134
|
*/
|
|
110
|
-
connectedCallback(): void {
|
|
111
|
-
const appTheme = localStorage.getItem(this.storageKey) as AppTheme|null;
|
|
112
|
-
if (appTheme) this.appTheme = appTheme;
|
|
113
|
-
|
|
135
|
+
async connectedCallback(): Promise<void> {
|
|
114
136
|
this.#dropdown = new Dropdown(this.querySelector(".dropdown-toggle")!);
|
|
115
|
-
this.#mediaQuery.addEventListener("change", this.#applyToDocument);
|
|
137
|
+
this.#mediaQuery.addEventListener("change", this.#applyToDocument, {signal: this.#abortController.signal});
|
|
138
|
+
|
|
139
|
+
const cookie = this.cookie ? await cookieStore.get(this.storageKey) : null;
|
|
140
|
+
if (cookie) this.appTheme = cookie.value as AppTheme;
|
|
141
|
+
else {
|
|
142
|
+
const storage = localStorage.getItem(this.storageKey);
|
|
143
|
+
if (storage) this.appTheme = storage as AppTheme;
|
|
144
|
+
}
|
|
116
145
|
}
|
|
117
146
|
|
|
118
147
|
/**
|
|
119
148
|
* Method invoked when this component is disconnected.
|
|
120
149
|
*/
|
|
121
150
|
disconnectedCallback(): void {
|
|
151
|
+
this.#abortController.abort();
|
|
122
152
|
this.#dropdown.dispose();
|
|
123
|
-
this.#mediaQuery.removeEventListener("change", this.#applyToDocument);
|
|
124
153
|
}
|
|
125
154
|
|
|
126
155
|
/**
|
|
@@ -134,7 +163,15 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
134
163
|
* Saves the current application theme into the local storage.
|
|
135
164
|
*/
|
|
136
165
|
save(): void {
|
|
137
|
-
|
|
166
|
+
const {appTheme, cookieDomain} = this;
|
|
167
|
+
localStorage.setItem(this.storageKey, appTheme);
|
|
168
|
+
|
|
169
|
+
if (this.cookie) void cookieStore.set({
|
|
170
|
+
domain: cookieDomain ? cookieDomain : null,
|
|
171
|
+
expires: Date.now() + (365 * 24 * 60 * 60 * 1_000),
|
|
172
|
+
name: this.storageKey,
|
|
173
|
+
value: appTheme
|
|
174
|
+
});
|
|
138
175
|
}
|
|
139
176
|
|
|
140
177
|
/**
|
|
@@ -150,11 +187,11 @@ export class ThemeDropdown extends HTMLElement {
|
|
|
150
187
|
* Changes the current application theme.
|
|
151
188
|
* @param event The dispatched event.
|
|
152
189
|
*/
|
|
153
|
-
#setAppTheme(event: Event)
|
|
190
|
+
readonly #setAppTheme: (event: Event) => void = event => {
|
|
154
191
|
event.preventDefault();
|
|
155
192
|
this.appTheme = (event.currentTarget as HTMLButtonElement).value as AppTheme;
|
|
156
193
|
this.save();
|
|
157
|
-
}
|
|
194
|
+
};
|
|
158
195
|
|
|
159
196
|
/**
|
|
160
197
|
* Updates the alignment of the dropdown menu.
|
|
@@ -16,6 +16,11 @@ export class Toast extends HTMLElement {
|
|
|
16
16
|
*/
|
|
17
17
|
static readonly #timeUnits: Intl.RelativeTimeFormatUnit[] = ["second", "minute", "hour"];
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* The abort controller used to remove the event listeners.
|
|
21
|
+
*/
|
|
22
|
+
readonly #abortController = new AbortController;
|
|
23
|
+
|
|
19
24
|
/**
|
|
20
25
|
* The formatter used to format the relative time.
|
|
21
26
|
*/
|
|
@@ -173,8 +178,8 @@ export class Toast extends HTMLElement {
|
|
|
173
178
|
*/
|
|
174
179
|
connectedCallback(): void {
|
|
175
180
|
const root = this.firstElementChild!;
|
|
176
|
-
root.addEventListener("hide.bs.toast", this.#stopTimer);
|
|
177
|
-
root.addEventListener("show.bs.toast", this.#startTimer);
|
|
181
|
+
root.addEventListener("hide.bs.toast", this.#stopTimer, {signal: this.#abortController.signal});
|
|
182
|
+
root.addEventListener("show.bs.toast", this.#startTimer, {signal: this.#abortController.signal});
|
|
178
183
|
|
|
179
184
|
this.#toast = new BootstrapToast(root);
|
|
180
185
|
if (this.open) this.show();
|
|
@@ -184,11 +189,8 @@ export class Toast extends HTMLElement {
|
|
|
184
189
|
* Method invoked when this component is disconnected.
|
|
185
190
|
*/
|
|
186
191
|
disconnectedCallback(): void {
|
|
187
|
-
const root = this.firstElementChild!;
|
|
188
|
-
root.removeEventListener("hide.bs.toast", () => this.#stopTimer);
|
|
189
|
-
root.removeEventListener("show.bs.toast", () => this.#startTimer);
|
|
190
|
-
|
|
191
192
|
this.#stopTimer();
|
|
193
|
+
this.#abortController.abort();
|
|
192
194
|
this.#toast.dispose();
|
|
193
195
|
}
|
|
194
196
|
|
|
@@ -67,8 +67,7 @@ export class Toaster extends HTMLElement {
|
|
|
67
67
|
*/
|
|
68
68
|
constructor() {
|
|
69
69
|
super();
|
|
70
|
-
for (const toast of this.querySelectorAll("toaster-item"))
|
|
71
|
-
toast.addEventListener("hidden.bs.toast", () => toast.remove());
|
|
70
|
+
for (const toast of this.querySelectorAll("toaster-item")) toast.addEventListener("hidden.bs.toast", () => toast.remove());
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
/**
|