@olenbetong/appframe-core 2.4.4 → 2.5.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/dist/esm/af.common.js +44 -33
- package/dist/esm/af.common.legacy.js +46 -35
- package/dist/esm/af.common.legacy.min.js +1 -1
- package/dist/esm/af.common.legacy.min.js.map +4 -4
- package/dist/esm/af.common.min.js +1 -1
- package/dist/esm/af.common.min.js.map +4 -4
- package/dist/iife/af.common.js +44 -33
- package/dist/iife/af.common.legacy.js +46 -35
- package/dist/iife/af.common.legacy.min.js +1 -1
- package/dist/iife/af.common.legacy.min.js.map +4 -4
- package/dist/iife/af.common.min.js +1 -1
- package/dist/iife/af.common.min.js.map +4 -4
- package/es/UserSession.js +15 -1
- package/es/expose.d.ts +7 -1
- package/es/expose.js +2 -2
- package/es/index.d.ts +1 -1
- package/es/index.js +2 -2
- package/es/requireNamespace.js +1 -2
- package/package.json +2 -2
- package/src/SessionHandler.ts +56 -56
- package/src/UserSession.ts +38 -24
- package/src/downloadBlob.ts +18 -18
- package/src/downloadRequest.ts +67 -67
- package/src/errorHandler.ts +23 -23
- package/src/expose.ts +54 -43
- package/src/getLocalizedString.ts +40 -40
- package/src/getUserImage.ts +44 -44
- package/src/has.ts +2 -5
- package/src/index.ts +26 -27
- package/src/invariant.ts +5 -5
- package/src/localStorage.ts +39 -42
- package/src/localize.ts +10 -10
- package/src/parseFunc.ts +4 -4
- package/src/requireNamespace.ts +13 -17
- package/src/settings.ts +19 -23
package/src/SessionHandler.ts
CHANGED
|
@@ -3,60 +3,60 @@ import mitt, { Emitter, Handler } from "mitt";
|
|
|
3
3
|
type SessionHandlerEvent = "onExpired" | "onAuthenticated";
|
|
4
4
|
|
|
5
5
|
export default class SessionHandler {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
6
|
+
private eventHandler: Emitter<{ onAuthenticated: void; onExpired: void }> = mitt();
|
|
7
|
+
|
|
8
|
+
authenticated() {
|
|
9
|
+
this.eventHandler.emit("onAuthenticated");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async expired(callback?: () => void, type?: "RequireTwoFactor"): Promise<void> {
|
|
13
|
+
try {
|
|
14
|
+
let authPromise = new Promise<void>((resolve) => {
|
|
15
|
+
let eventHandler = () => {
|
|
16
|
+
this.eventHandler.off("onAuthenticated", eventHandler);
|
|
17
|
+
callback?.();
|
|
18
|
+
resolve();
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
this.eventHandler.on("onAuthenticated", eventHandler);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
let dialog: HTMLDialogElement | null = document.querySelector("dialog.session-expired-dialog");
|
|
25
|
+
if (!dialog) {
|
|
26
|
+
dialog = document.createElement("dialog");
|
|
27
|
+
dialog.className = "session-expired-dialog";
|
|
28
|
+
dialog.style.display = "flex";
|
|
29
|
+
dialog.style.padding = "0";
|
|
30
|
+
dialog.style.left = "50%";
|
|
31
|
+
dialog.style.transform = "translateX(-50%)";
|
|
32
|
+
|
|
33
|
+
let link = "/login?ReturnUrl=%2fapi/sessionexpired/remove";
|
|
34
|
+
if (type !== "RequireTwoFactor") {
|
|
35
|
+
await fetch("/logout", { method: "POST" });
|
|
36
|
+
} else {
|
|
37
|
+
link = "/login?RequireTwoFactor=1&ReturnUrl=%2fapi/sessionexpired/remove";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
dialog.innerHTML = `<iframe sandbox="allow-same-origin allow-scripts allow-modals allow-top-navigation-by-user-activation allow-forms" src="${link}" style="border:0;width:min(500px,100vw);height:min(700px, 100vh);"></iframe>`;
|
|
41
|
+
document.body.append(dialog);
|
|
42
|
+
dialog.showModal();
|
|
43
|
+
await authPromise;
|
|
44
|
+
dialog.remove();
|
|
45
|
+
} else {
|
|
46
|
+
await authPromise;
|
|
47
|
+
}
|
|
48
|
+
} catch (_) {
|
|
49
|
+
window.location.href = `/login?ReturnUrl=${encodeURIComponent(window.location.pathname)}${encodeURIComponent(
|
|
50
|
+
window.location.search
|
|
51
|
+
)}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
attachEvent(eventName: SessionHandlerEvent, handler: Handler) {
|
|
56
|
+
return this.eventHandler.on(eventName, handler);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
detachEvent(eventName: SessionHandlerEvent, handler: Handler) {
|
|
60
|
+
return this.eventHandler.off(eventName, handler);
|
|
61
|
+
}
|
|
62
62
|
}
|
package/src/UserSession.ts
CHANGED
|
@@ -1,29 +1,43 @@
|
|
|
1
1
|
import SessionHandler from "./SessionHandler.js";
|
|
2
2
|
|
|
3
3
|
export class UserSession extends SessionHandler {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
amDesignator: string = "a.m.";
|
|
5
|
+
dayNames: string[] = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
|
|
6
|
+
dayNamesShort: string[] = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
7
|
+
decimalSeparator: string = ".";
|
|
8
|
+
domain: string = "OB";
|
|
9
|
+
email: string | null | undefined;
|
|
10
|
+
formats: undefined | Record<string, string>;
|
|
11
|
+
groupSeparator: string | null = null;
|
|
12
|
+
integratedSecurity: boolean = false;
|
|
13
|
+
isDeveloper: boolean = false;
|
|
14
|
+
login: string = "";
|
|
15
|
+
loginType: string | undefined;
|
|
16
|
+
monthNames: string[] = [
|
|
17
|
+
"january",
|
|
18
|
+
"february",
|
|
19
|
+
"march",
|
|
20
|
+
"april",
|
|
21
|
+
"may",
|
|
22
|
+
"june",
|
|
23
|
+
"july",
|
|
24
|
+
"august",
|
|
25
|
+
"september",
|
|
26
|
+
"october",
|
|
27
|
+
"november",
|
|
28
|
+
"december",
|
|
29
|
+
"",
|
|
30
|
+
];
|
|
31
|
+
monthNamesShort: string[] = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "augt", "sep", "oct", "nov", "dec", ""];
|
|
32
|
+
name: string | undefined;
|
|
33
|
+
pmDesignator: string = "p.m.";
|
|
34
|
+
shortDateFormat: string = "dd.MM.yyyy";
|
|
35
|
+
culture: string = "en-GB";
|
|
36
|
+
uiculture: string = "en-GB";
|
|
23
37
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
constructor(userData: any) {
|
|
39
|
+
super();
|
|
40
|
+
this.formats = {};
|
|
41
|
+
Object.assign(this, userData);
|
|
42
|
+
}
|
|
29
43
|
}
|
package/src/downloadBlob.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
export function downloadBlob(blob: Blob | MediaSource, fileName: string) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
return new Promise<void>(function (resolve, reject) {
|
|
3
|
+
try {
|
|
4
|
+
const url = URL.createObjectURL(blob);
|
|
5
|
+
const parent = document.body;
|
|
6
|
+
const anchor = document.createElement("a");
|
|
7
|
+
anchor.setAttribute("download", fileName);
|
|
8
|
+
anchor.href = url;
|
|
9
|
+
parent.append(anchor);
|
|
10
|
+
anchor.click();
|
|
11
|
+
parent.removeChild(anchor);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
setTimeout(function () {
|
|
14
|
+
URL.revokeObjectURL(url);
|
|
15
|
+
resolve();
|
|
16
|
+
}, 250);
|
|
17
|
+
} catch (ex) {
|
|
18
|
+
reject(ex);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
21
|
}
|
package/src/downloadRequest.ts
CHANGED
|
@@ -2,77 +2,77 @@ import { downloadBlob } from "./downloadBlob.js";
|
|
|
2
2
|
import { invariant } from "./invariant.js";
|
|
3
3
|
|
|
4
4
|
export type DownloadItem = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
status: "cancelled" | "error" | "requested" | "downloading" | "downloaded" | "completed";
|
|
6
|
+
bytesReceived?: number;
|
|
7
|
+
error?: string;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export type DownloadParameters = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
fileName: string;
|
|
13
|
+
onProgress?: (progress: DownloadItem) => void;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export async function downloadRequest(request: Request, { fileName, signal, onProgress }: DownloadParameters) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
17
|
+
function reportProgress(progress: DownloadItem) {
|
|
18
|
+
if (typeof onProgress === "function") {
|
|
19
|
+
onProgress({ ...progress });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let bytesReceived = 0;
|
|
24
|
+
|
|
25
|
+
reportProgress({ status: "requested" });
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
let response = await fetch(request);
|
|
29
|
+
|
|
30
|
+
if (!response.ok || !response.body) {
|
|
31
|
+
if (response.headers.get("content-type")?.includes("application/json")) {
|
|
32
|
+
let data = await response.json();
|
|
33
|
+
invariant(!data.error, data.error);
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`${response.status} ${response.statusText}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const reader = response.body.getReader();
|
|
40
|
+
const stream = new ReadableStream({
|
|
41
|
+
start: function (controller) {
|
|
42
|
+
function pump(): Promise<void> {
|
|
43
|
+
return reader.read().then(function (read) {
|
|
44
|
+
if (read.done) {
|
|
45
|
+
controller.close();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
bytesReceived += read.value.length;
|
|
50
|
+
reportProgress({ bytesReceived, status: "downloading" });
|
|
51
|
+
controller.enqueue(read.value);
|
|
52
|
+
|
|
53
|
+
return pump();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return pump();
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
response = new Response(stream);
|
|
62
|
+
} catch (error) {}
|
|
63
|
+
|
|
64
|
+
const blob = await response.blob();
|
|
65
|
+
|
|
66
|
+
reportProgress({ bytesReceived, status: "downloaded" });
|
|
67
|
+
|
|
68
|
+
await downloadBlob(blob, fileName);
|
|
69
|
+
|
|
70
|
+
reportProgress({ bytesReceived, status: "completed" });
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (signal?.aborted) {
|
|
73
|
+
reportProgress({ status: "cancelled" });
|
|
74
|
+
} else {
|
|
75
|
+
reportProgress({ error: (err as Error).message, status: "error" });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
78
|
}
|
package/src/errorHandler.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
if (process.env.NODE_ENV === "production") {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
globalThis.window?.addEventListener("error", (event) => {
|
|
3
|
+
try {
|
|
4
|
+
// Try to avoid error-logging-loop
|
|
5
|
+
const data = {
|
|
6
|
+
error: event.error?.message ?? event.message ?? null,
|
|
7
|
+
file: event.filename,
|
|
8
|
+
line: event.lineno ?? 0,
|
|
9
|
+
column: event.colno ?? 0,
|
|
10
|
+
stack: event.error?.stack ?? null,
|
|
11
|
+
};
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
13
|
+
fetch("/data/Logger/LogError", {
|
|
14
|
+
body: JSON.stringify(data),
|
|
15
|
+
headers: {
|
|
16
|
+
Accept: "application/json",
|
|
17
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
18
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
19
|
+
},
|
|
20
|
+
method: "POST",
|
|
21
|
+
});
|
|
22
|
+
} catch (ex) {
|
|
23
|
+
// ignore
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
26
|
}
|
package/src/expose.ts
CHANGED
|
@@ -3,52 +3,63 @@ import { invariant } from "./invariant.js";
|
|
|
3
3
|
import { parseFunc } from "./parseFunc.js";
|
|
4
4
|
import { requireNamespace } from "./requireNamespace.js";
|
|
5
5
|
|
|
6
|
+
export type ExposeOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* Whether we should overwrite any existing values without warning.
|
|
9
|
+
*/
|
|
10
|
+
overwrite?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
6
13
|
/**
|
|
7
14
|
* Expose a value to a potentially deeply nested global variable
|
|
8
15
|
* @param name {string | object} Either a dot-separated path to the global variable, or an object to expose the value on
|
|
9
16
|
* @param value {object | Function | Function[]} The value(s) to expose
|
|
10
17
|
*/
|
|
11
|
-
export function expose(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
18
|
+
export function expose(
|
|
19
|
+
name: object | string,
|
|
20
|
+
value: object | Function | Function[],
|
|
21
|
+
options: ExposeOptions = {}
|
|
22
|
+
): void {
|
|
23
|
+
invariant(arguments.length === 2, "Incorrect number of arguments passed to the expose function!");
|
|
24
|
+
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
for (let func of value) {
|
|
27
|
+
const { name: funcName } = parseFunc(func);
|
|
28
|
+
|
|
29
|
+
invariant(
|
|
30
|
+
funcName,
|
|
31
|
+
"Unable to detect name of function! Name it, or only supply one function and include name in first parameter."
|
|
32
|
+
);
|
|
33
|
+
expose(name, func); // Expose func on namespace found in pName
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
let keyName: string | undefined;
|
|
37
|
+
let namespace;
|
|
38
|
+
|
|
39
|
+
if (typeof value === "function") {
|
|
40
|
+
keyName = parseFunc(value).name;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof name === "string") {
|
|
44
|
+
let pathParts = name.split(".");
|
|
45
|
+
|
|
46
|
+
if (!keyName) {
|
|
47
|
+
keyName = pathParts[pathParts.length - 1];
|
|
48
|
+
pathParts = pathParts.slice(0, pathParts.length - 1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
namespace = requireNamespace(window, pathParts);
|
|
52
|
+
} else if (keyName && (typeof name === "object" || typeof name === "function")) {
|
|
53
|
+
namespace = name;
|
|
54
|
+
} else {
|
|
55
|
+
invariant(false, "Invalid typeof parameter 'name', or unable to parse pValue!");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (has(namespace, keyName) && options?.overwrite !== true) {
|
|
59
|
+
// If class is already defined, warn or show an alert
|
|
60
|
+
console.warn([name, keyName].join(".") + " is already defined!");
|
|
61
|
+
} else {
|
|
62
|
+
namespace[keyName] = value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
54
65
|
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { has } from "./has.js";
|
|
2
2
|
|
|
3
3
|
async function fetchLocalizedString(text: string) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
try {
|
|
5
|
+
let response = await fetch(`/api/user/localize/new/${af.article.id}`, {
|
|
6
|
+
body: JSON.stringify({ text }),
|
|
7
|
+
headers: {
|
|
8
|
+
Accept: "application/json; */*",
|
|
9
|
+
"Content-Type": "application/json",
|
|
10
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
11
|
+
},
|
|
12
|
+
method: "POST",
|
|
13
|
+
});
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
if (response.ok) {
|
|
16
|
+
return (await response.json()) as string;
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
return text;
|
|
21
21
|
}
|
|
22
22
|
export function getLocalizedStringAsync(string: undefined | null): undefined | null;
|
|
23
23
|
export function getLocalizedStringAsync(string: string): Promise<string>;
|
|
24
24
|
export function getLocalizedStringAsync(string: string | undefined | null) {
|
|
25
|
-
|
|
25
|
+
if (!string) return string;
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
return getLocalizedString(string, true);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export function getLocalizedString(string: undefined | null): undefined | null;
|
|
@@ -33,33 +33,33 @@ export function getLocalizedString(string: string, wait: false): string;
|
|
|
33
33
|
export function getLocalizedString(string: string, wait: true): Promise<string>;
|
|
34
34
|
export function getLocalizedString(string: undefined | null, wait: true): undefined | null;
|
|
35
35
|
export function getLocalizedString(
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
string: string | undefined | null,
|
|
37
|
+
wait?: boolean
|
|
38
38
|
): string | undefined | null | Promise<string> {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
if (typeof string === "string" && string.trim().length === 0) {
|
|
40
|
+
return string;
|
|
41
|
+
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
if (string === undefined || string === "" || string === null) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
if (af?.article?.i18n !== undefined) {
|
|
48
|
+
if (!has(af.article.i18n, string)) {
|
|
49
|
+
af.article.i18n[string] = string;
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
let promise = fetchLocalizedString(string).then((text) => {
|
|
52
|
+
af.article.i18n[string] = text;
|
|
53
|
+
return text;
|
|
54
|
+
});
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
if (wait) {
|
|
57
|
+
return promise;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
return af.article.i18n[string];
|
|
62
|
+
} else {
|
|
63
|
+
return string;
|
|
64
|
+
}
|
|
65
65
|
}
|