@umbraco-cms/backoffice 14.0.0--preview005-bbf54b9a → 14.0.0--preview005-c6c57135
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-cms/libs/element-api/element.mixin.d.ts +3 -3
- package/dist-cms/libs/element-api/element.mixin.js +2 -2
- package/dist-cms/libs/extension-api/registry/extension.registry.d.ts +19 -0
- package/dist-cms/libs/extension-api/registry/extension.registry.js +42 -1
- package/dist-cms/libs/localization-api/index.d.ts +2 -2
- package/dist-cms/libs/localization-api/index.js +2 -2
- package/dist-cms/libs/localization-api/{localize.controller.d.ts → localization.controller.d.ts} +6 -4
- package/dist-cms/libs/localization-api/{localize.controller.js → localization.controller.js} +34 -24
- package/dist-cms/libs/localization-api/localization.manager.d.ts +29 -0
- package/dist-cms/libs/localization-api/localization.manager.js +94 -0
- package/dist-cms/packages/core/localization/registry/localization.registry.d.ts +3 -3
- package/dist-cms/packages/core/localization/registry/localization.registry.js +59 -60
- package/dist-cms/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.js +1 -1
- package/dist-cms/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.js +1 -1
- package/dist-cms/packages/documents/documents/workspace/document-workspace-split-view.element.js +1 -2
- package/dist-cms/packages/user/current-user/current-user.context.js +2 -7
- package/dist-cms/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist-cms/libs/localization-api/manager.d.ts +0 -18
- package/dist-cms/libs/localization-api/manager.js +0 -40
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UmbLocalizationController } from '../localization-api/index.js';
|
|
2
2
|
import type { Observable } from '../../external/rxjs/index.js';
|
|
3
3
|
import type { HTMLElementConstructor } from '../extension-api/index.js';
|
|
4
4
|
import { type UmbControllerHostElement } from '../controller-api/index.js';
|
|
@@ -21,8 +21,8 @@ export declare class UmbElement extends UmbControllerHostElement {
|
|
|
21
21
|
consumeContext<BaseType = unknown, ResultType extends BaseType = BaseType>(alias: string | UmbContextToken<BaseType, ResultType>, callback: UmbContextCallback<ResultType>): UmbContextConsumerController<BaseType, ResultType>;
|
|
22
22
|
/**
|
|
23
23
|
* Use the UmbLocalizeController to localize your element.
|
|
24
|
-
* @see
|
|
24
|
+
* @see UmbLocalizationController
|
|
25
25
|
*/
|
|
26
|
-
localize:
|
|
26
|
+
localize: UmbLocalizationController;
|
|
27
27
|
}
|
|
28
28
|
export declare const UmbElementMixin: <T extends HTMLElementConstructor>(superClass: T) => HTMLElementConstructor<UmbElement> & T;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UmbLocalizationController } from '../localization-api/index.js';
|
|
2
2
|
import { UmbControllerHostElementMixin } from '../controller-api/index.js';
|
|
3
3
|
import { UmbContextConsumerController, UmbContextProviderController } from '../context-api/index.js';
|
|
4
4
|
import { UmbObserverController } from '../observable-api/index.js';
|
|
@@ -6,7 +6,7 @@ export const UmbElementMixin = (superClass) => {
|
|
|
6
6
|
class UmbElementMixinClass extends UmbControllerHostElementMixin(superClass) {
|
|
7
7
|
constructor() {
|
|
8
8
|
super(...arguments);
|
|
9
|
-
this.localize = new
|
|
9
|
+
this.localize = new UmbLocalizationController(this);
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* @description Observe a RxJS source of choice.
|
|
@@ -21,6 +21,25 @@ export declare class UmbExtensionRegistry<IncomingManifestTypes extends Manifest
|
|
|
21
21
|
getByAlias<T extends ManifestBase = ManifestBase>(alias: string): Observable<T | undefined>;
|
|
22
22
|
getByTypeAndAlias<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key, alias: string): Observable<T | undefined>;
|
|
23
23
|
getByTypeAndAliases<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key, aliases: Array<string>): Observable<T[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get an observable of an extension by type and a given filter method.
|
|
26
|
+
* This will return the all extensions that matches the type and which filter method returns true.
|
|
27
|
+
* The filter method will be called for each extension manifest of the given type, and the first argument to it is the extension manifest.
|
|
28
|
+
* @param type {string} - The type of the extension to get
|
|
29
|
+
* @param filter {(ext: T): void} - The filter method to use to filter the extensions
|
|
30
|
+
* @returns {Observable<T | undefined>} - An observable of the extensions that matches the type and filter method
|
|
31
|
+
*/
|
|
32
|
+
byTypeAndFilter<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key, filter: (ext: T) => boolean): Observable<T | undefined>;
|
|
33
|
+
/**
|
|
34
|
+
* Get an observable that provides extensions matching the given type.
|
|
35
|
+
* @param type {string} - The type of the extensions to get.
|
|
36
|
+
* @returns {Observable<T | undefined>} - An observable of the extensions that matches the type.
|
|
37
|
+
*/
|
|
24
38
|
extensionsOfType<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key): Observable<T[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Get an observable that provides extensions matching given types.
|
|
41
|
+
* @param type {Array<string>} - The types of the extensions to get.
|
|
42
|
+
* @returns {Observable<T | undefined>} - An observable of the extensions that matches the types.
|
|
43
|
+
*/
|
|
25
44
|
extensionsOfTypes<ExtensionTypes extends ManifestBase = ManifestBase>(types: string[]): Observable<Array<ExtensionTypes>>;
|
|
26
45
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UmbBasicState } from '../../observable-api/index.js';
|
|
2
|
-
import { map, distinctUntilChanged, combineLatest, of, switchMap
|
|
2
|
+
import { map, distinctUntilChanged, combineLatest, of, switchMap } from '../../../external/rxjs/index.js';
|
|
3
3
|
function extensionArrayMemoization(previousValue, currentValue) {
|
|
4
4
|
// If length is different, data is different:
|
|
5
5
|
if (previousValue.length !== currentValue.length) {
|
|
@@ -137,6 +137,7 @@ export class UmbExtensionRegistry {
|
|
|
137
137
|
_extensionsOfTypes(types) {
|
|
138
138
|
return this.extensions.pipe(map((exts) => exts.filter((ext) => types.indexOf(ext.type) !== -1)), distinctUntilChanged(extensionArrayMemoization));
|
|
139
139
|
}
|
|
140
|
+
// TODO: get rid of the name get
|
|
140
141
|
getByAlias(alias) {
|
|
141
142
|
return this.extensions.pipe(map((exts) => exts.find((ext) => ext.alias === alias)), distinctUntilChanged(extensionSingleMemoization), switchMap((ext) => {
|
|
142
143
|
if (ext?.kind) {
|
|
@@ -160,6 +161,7 @@ export class UmbExtensionRegistry {
|
|
|
160
161
|
return of(ext);
|
|
161
162
|
}), distinctUntilChanged(extensionAndKindMatchSingleMemoization));
|
|
162
163
|
}
|
|
164
|
+
// TODO: get rid of the name get
|
|
163
165
|
getByTypeAndAlias(type, alias) {
|
|
164
166
|
return combineLatest([
|
|
165
167
|
this.extensions.pipe(map((exts) => exts.find((ext) => ext.type === type && ext.alias === alias)), distinctUntilChanged(extensionSingleMemoization)),
|
|
@@ -180,6 +182,7 @@ export class UmbExtensionRegistry {
|
|
|
180
182
|
return ext;
|
|
181
183
|
}), distinctUntilChanged(extensionAndKindMatchSingleMemoization));
|
|
182
184
|
}
|
|
185
|
+
// TODO: get rid of the name get
|
|
183
186
|
getByTypeAndAliases(type, aliases) {
|
|
184
187
|
return combineLatest([
|
|
185
188
|
this.extensions.pipe(map((exts) => exts.filter((ext) => ext.type === type && aliases.indexOf(ext.alias) !== -1)), distinctUntilChanged(extensionArrayMemoization)),
|
|
@@ -199,6 +202,39 @@ export class UmbExtensionRegistry {
|
|
|
199
202
|
})
|
|
200
203
|
.sort(sortExtensions)), distinctUntilChanged(extensionAndKindMatchArrayMemoization));
|
|
201
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Get an observable of an extension by type and a given filter method.
|
|
207
|
+
* This will return the all extensions that matches the type and which filter method returns true.
|
|
208
|
+
* The filter method will be called for each extension manifest of the given type, and the first argument to it is the extension manifest.
|
|
209
|
+
* @param type {string} - The type of the extension to get
|
|
210
|
+
* @param filter {(ext: T): void} - The filter method to use to filter the extensions
|
|
211
|
+
* @returns {Observable<T | undefined>} - An observable of the extensions that matches the type and filter method
|
|
212
|
+
*/
|
|
213
|
+
byTypeAndFilter(type, filter) {
|
|
214
|
+
return combineLatest([
|
|
215
|
+
this.extensions.pipe(map((exts) => exts.find((ext) => ext.type === type && filter(ext))), distinctUntilChanged(extensionSingleMemoization)),
|
|
216
|
+
this._kindsOfType(type),
|
|
217
|
+
]).pipe(map(([ext, kinds]) => {
|
|
218
|
+
// TODO: share one merge function between the different methods of this class:
|
|
219
|
+
// Specific Extension Meta merge (does not merge conditions)
|
|
220
|
+
if (ext) {
|
|
221
|
+
const baseManifest = kinds.find((kind) => kind.matchKind === ext.kind)?.manifest;
|
|
222
|
+
if (baseManifest) {
|
|
223
|
+
const merged = { __isMatchedWithKind: true, ...baseManifest, ...ext };
|
|
224
|
+
if (baseManifest.meta) {
|
|
225
|
+
merged.meta = { ...baseManifest.meta, ...ext.meta };
|
|
226
|
+
}
|
|
227
|
+
return merged;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return ext;
|
|
231
|
+
}), distinctUntilChanged(extensionAndKindMatchSingleMemoization));
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Get an observable that provides extensions matching the given type.
|
|
235
|
+
* @param type {string} - The type of the extensions to get.
|
|
236
|
+
* @returns {Observable<T | undefined>} - An observable of the extensions that matches the type.
|
|
237
|
+
*/
|
|
202
238
|
extensionsOfType(type) {
|
|
203
239
|
return combineLatest([this._extensionsOfType(type), this._kindsOfType(type)]).pipe(map(([exts, kinds]) => exts
|
|
204
240
|
.map((ext) => {
|
|
@@ -215,6 +251,11 @@ export class UmbExtensionRegistry {
|
|
|
215
251
|
})
|
|
216
252
|
.sort(sortExtensions)), distinctUntilChanged(extensionAndKindMatchArrayMemoization));
|
|
217
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Get an observable that provides extensions matching given types.
|
|
256
|
+
* @param type {Array<string>} - The types of the extensions to get.
|
|
257
|
+
* @returns {Observable<T | undefined>} - An observable of the extensions that matches the types.
|
|
258
|
+
*/
|
|
218
259
|
extensionsOfTypes(types) {
|
|
219
260
|
return combineLatest([this._extensionsOfTypes(types), this._kindsOfTypes(types)]).pipe(map(([exts, kinds]) => exts
|
|
220
261
|
.map((ext) => {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './localization.controller.js';
|
|
2
2
|
export * from './types/localization.js';
|
|
3
|
-
export * from './manager.js';
|
|
3
|
+
export * from './localization.manager.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './localization.controller.js';
|
|
2
2
|
export * from './types/localization.js';
|
|
3
|
-
export * from './manager.js';
|
|
3
|
+
export * from './localization.manager.js';
|
package/dist-cms/libs/localization-api/{localize.controller.d.ts → localization.controller.d.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UmbLocalizationSet, FunctionParams, UmbLocalizationSetBase, UmbLocalizationSetKey } from './localization.manager.js';
|
|
2
2
|
import type { UmbController, UmbControllerHost } from '../controller-api/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* The UmbLocalizeController enables localization for your element.
|
|
@@ -18,13 +18,15 @@ import type { UmbController, UmbControllerHost } from '../controller-api/index.j
|
|
|
18
18
|
* }
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
|
-
export declare class
|
|
21
|
+
export declare class UmbLocalizationController<LocalizationSetType extends UmbLocalizationSetBase = UmbLocalizationSet> implements UmbController {
|
|
22
22
|
#private;
|
|
23
|
-
controllerAlias: symbol;
|
|
23
|
+
readonly controllerAlias: symbol;
|
|
24
24
|
constructor(host: UmbControllerHost);
|
|
25
25
|
hostConnected(): void;
|
|
26
26
|
hostDisconnected(): void;
|
|
27
27
|
destroy(): void;
|
|
28
|
+
documentUpdate(): void;
|
|
29
|
+
keysChanged(changedKeys: Set<UmbLocalizationSetKey>): void;
|
|
28
30
|
/**
|
|
29
31
|
* Gets the host element's directionality as determined by the `dir` attribute. The return value is transformed to
|
|
30
32
|
* lowercase.
|
|
@@ -37,7 +39,7 @@ export declare class UmbLocalizeController<LocalizationType extends Localization
|
|
|
37
39
|
lang(): string;
|
|
38
40
|
private getLocalizationData;
|
|
39
41
|
/** Outputs a translated term. */
|
|
40
|
-
term<K extends keyof
|
|
42
|
+
term<K extends keyof LocalizationSetType>(key: K, ...args: FunctionParams<LocalizationSetType[K]>): string;
|
|
41
43
|
/** Outputs a localized date in the specified format. */
|
|
42
44
|
date(dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions): string;
|
|
43
45
|
/** Outputs a localized number in the specified format. */
|
package/dist-cms/libs/localization-api/{localize.controller.js → localization.controller.js}
RENAMED
|
@@ -9,9 +9,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var
|
|
13
|
-
import {
|
|
14
|
-
const
|
|
12
|
+
var _UmbLocalizationController_host, _UmbLocalizationController_hostEl, _UmbLocalizationController_usedKeys;
|
|
13
|
+
import { umbLocalizationManager } from './localization.manager.js';
|
|
14
|
+
const LocalizationControllerAlias = Symbol();
|
|
15
15
|
/**
|
|
16
16
|
* The UmbLocalizeController enables localization for your element.
|
|
17
17
|
*
|
|
@@ -30,52 +30,62 @@ const LocalizeControllerAlias = Symbol();
|
|
|
30
30
|
* }
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
export class
|
|
33
|
+
export class UmbLocalizationController {
|
|
34
34
|
constructor(host) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.controllerAlias =
|
|
38
|
-
|
|
39
|
-
__classPrivateFieldSet(this,
|
|
40
|
-
|
|
35
|
+
_UmbLocalizationController_host.set(this, void 0);
|
|
36
|
+
_UmbLocalizationController_hostEl.set(this, void 0);
|
|
37
|
+
this.controllerAlias = LocalizationControllerAlias;
|
|
38
|
+
_UmbLocalizationController_usedKeys.set(this, new Array());
|
|
39
|
+
__classPrivateFieldSet(this, _UmbLocalizationController_host, host, "f");
|
|
40
|
+
__classPrivateFieldSet(this, _UmbLocalizationController_hostEl, host.getHostElement(), "f");
|
|
41
|
+
__classPrivateFieldGet(this, _UmbLocalizationController_host, "f").addController(this);
|
|
41
42
|
}
|
|
42
43
|
hostConnected() {
|
|
43
|
-
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
connectedElements.add(__classPrivateFieldGet(this, _UmbLocalizeController_hostEl, "f"));
|
|
44
|
+
umbLocalizationManager.appendConsumer(this);
|
|
47
45
|
}
|
|
48
46
|
hostDisconnected() {
|
|
49
|
-
|
|
47
|
+
umbLocalizationManager.removeConsumer(this);
|
|
50
48
|
}
|
|
51
49
|
destroy() {
|
|
52
|
-
__classPrivateFieldGet(this,
|
|
53
|
-
__classPrivateFieldSet(this,
|
|
50
|
+
__classPrivateFieldGet(this, _UmbLocalizationController_host, "f").removeController(this);
|
|
51
|
+
__classPrivateFieldSet(this, _UmbLocalizationController_hostEl, undefined, "f");
|
|
52
|
+
}
|
|
53
|
+
documentUpdate() {
|
|
54
|
+
__classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.requestUpdate?.();
|
|
55
|
+
}
|
|
56
|
+
keysChanged(changedKeys) {
|
|
57
|
+
const hasOneOfTheseKeys = __classPrivateFieldGet(this, _UmbLocalizationController_usedKeys, "f").find((key) => changedKeys.has(key));
|
|
58
|
+
if (hasOneOfTheseKeys) {
|
|
59
|
+
__classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.requestUpdate?.();
|
|
60
|
+
}
|
|
54
61
|
}
|
|
55
62
|
/**
|
|
56
63
|
* Gets the host element's directionality as determined by the `dir` attribute. The return value is transformed to
|
|
57
64
|
* lowercase.
|
|
58
65
|
*/
|
|
59
66
|
dir() {
|
|
60
|
-
return `${__classPrivateFieldGet(this,
|
|
67
|
+
return `${__classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.dir || umbLocalizationManager.documentDirection}`.toLowerCase();
|
|
61
68
|
}
|
|
62
69
|
/**
|
|
63
70
|
* Gets the host element's language as determined by the `lang` attribute. The return value is transformed to
|
|
64
71
|
* lowercase.
|
|
65
72
|
*/
|
|
66
73
|
lang() {
|
|
67
|
-
return `${__classPrivateFieldGet(this,
|
|
74
|
+
return `${__classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.lang || umbLocalizationManager.documentLanguage}`.toLowerCase();
|
|
68
75
|
}
|
|
69
76
|
getLocalizationData(lang) {
|
|
70
77
|
const locale = new Intl.Locale(lang);
|
|
71
78
|
const language = locale?.language.toLowerCase();
|
|
72
79
|
const region = locale?.region?.toLowerCase() ?? '';
|
|
73
|
-
const primary = localizations.get(`${language}-${region}`);
|
|
74
|
-
const secondary = localizations.get(language);
|
|
80
|
+
const primary = umbLocalizationManager.localizations.get(`${language}-${region}`);
|
|
81
|
+
const secondary = umbLocalizationManager.localizations.get(language);
|
|
75
82
|
return { locale, language, region, primary, secondary };
|
|
76
83
|
}
|
|
77
84
|
/** Outputs a translated term. */
|
|
78
85
|
term(key, ...args) {
|
|
86
|
+
if (!__classPrivateFieldGet(this, _UmbLocalizationController_usedKeys, "f").includes(key)) {
|
|
87
|
+
__classPrivateFieldGet(this, _UmbLocalizationController_usedKeys, "f").push(key);
|
|
88
|
+
}
|
|
79
89
|
const { primary, secondary } = this.getLocalizationData(this.lang());
|
|
80
90
|
let term;
|
|
81
91
|
// Look for a matching term using regionCode, code, then the fallback
|
|
@@ -85,8 +95,8 @@ export class UmbLocalizeController {
|
|
|
85
95
|
else if (secondary && secondary[key]) {
|
|
86
96
|
term = secondary[key];
|
|
87
97
|
}
|
|
88
|
-
else if (fallback && fallback[key]) {
|
|
89
|
-
term = fallback[key];
|
|
98
|
+
else if (umbLocalizationManager.fallback && umbLocalizationManager.fallback[key]) {
|
|
99
|
+
term = umbLocalizationManager.fallback[key];
|
|
90
100
|
}
|
|
91
101
|
else {
|
|
92
102
|
return String(key);
|
|
@@ -120,4 +130,4 @@ export class UmbLocalizeController {
|
|
|
120
130
|
return new Intl.RelativeTimeFormat(this.lang(), options).format(value, unit);
|
|
121
131
|
}
|
|
122
132
|
}
|
|
123
|
-
|
|
133
|
+
_UmbLocalizationController_host = new WeakMap(), _UmbLocalizationController_hostEl = new WeakMap(), _UmbLocalizationController_usedKeys = new WeakMap();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { UmbLocalizationController } from './localization.controller.js';
|
|
2
|
+
import type { UmbLocalizationEntry } from './types/localization.js';
|
|
3
|
+
export type FunctionParams<T> = T extends (...args: infer U) => string ? U : [];
|
|
4
|
+
export interface UmbLocalizationSetBase {
|
|
5
|
+
$code: string;
|
|
6
|
+
$dir: 'ltr' | 'rtl';
|
|
7
|
+
}
|
|
8
|
+
export type UmbLocalizationSetKey = string | number | symbol;
|
|
9
|
+
export interface UmbLocalizationSet extends UmbLocalizationSetBase {
|
|
10
|
+
[key: UmbLocalizationSetKey]: UmbLocalizationEntry;
|
|
11
|
+
}
|
|
12
|
+
export declare const UMB_DEFAULT_LOCALIZATION_CULTURE = "en-us";
|
|
13
|
+
export declare class UmbLocalizationManager {
|
|
14
|
+
#private;
|
|
15
|
+
connectedControllers: Set<UmbLocalizationController<UmbLocalizationSetBase>>;
|
|
16
|
+
localizations: Map<string, UmbLocalizationSetBase>;
|
|
17
|
+
documentDirection: string;
|
|
18
|
+
documentLanguage: string;
|
|
19
|
+
get fallback(): UmbLocalizationSet | undefined;
|
|
20
|
+
constructor();
|
|
21
|
+
appendConsumer(consumer: UmbLocalizationController<UmbLocalizationSetBase>): void;
|
|
22
|
+
removeConsumer(consumer: UmbLocalizationController<UmbLocalizationSetBase>): void;
|
|
23
|
+
/** Registers one or more translations */
|
|
24
|
+
registerLocalization(t: UmbLocalizationSetBase): void;
|
|
25
|
+
registerManyLocalizations(translations: Array<UmbLocalizationSetBase>): void;
|
|
26
|
+
/** Updates all localized elements that are currently connected */
|
|
27
|
+
updateAll: () => void;
|
|
28
|
+
}
|
|
29
|
+
export declare const umbLocalizationManager: UmbLocalizationManager;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _UmbLocalizationManager_instances, _UmbLocalizationManager_documentElementObserver, _UmbLocalizationManager_changedKeys, _UmbLocalizationManager_requestUpdateChangedKeysId, _UmbLocalizationManager_registerLocalizationBind, _UmbLocalizationManager_updateChangedKeys, _UmbLocalizationManager_requestChangedKeysUpdate;
|
|
13
|
+
export const UMB_DEFAULT_LOCALIZATION_CULTURE = 'en-us';
|
|
14
|
+
export class UmbLocalizationManager {
|
|
15
|
+
get fallback() {
|
|
16
|
+
return this.localizations.get(UMB_DEFAULT_LOCALIZATION_CULTURE);
|
|
17
|
+
}
|
|
18
|
+
constructor() {
|
|
19
|
+
_UmbLocalizationManager_instances.add(this);
|
|
20
|
+
this.connectedControllers = new Set();
|
|
21
|
+
_UmbLocalizationManager_documentElementObserver.set(this, void 0);
|
|
22
|
+
_UmbLocalizationManager_changedKeys.set(this, new Set());
|
|
23
|
+
_UmbLocalizationManager_requestUpdateChangedKeysId.set(this, undefined);
|
|
24
|
+
this.localizations = new Map();
|
|
25
|
+
this.documentDirection = document.documentElement.dir || 'ltr';
|
|
26
|
+
this.documentLanguage = document.documentElement.lang || navigator.language;
|
|
27
|
+
_UmbLocalizationManager_registerLocalizationBind.set(this, this.registerLocalization.bind(this));
|
|
28
|
+
/** Updates all localized elements that are currently connected */
|
|
29
|
+
this.updateAll = () => {
|
|
30
|
+
const newDir = document.documentElement.dir || 'ltr';
|
|
31
|
+
const newLang = document.documentElement.lang || navigator.language;
|
|
32
|
+
if (this.documentDirection === newDir && this.documentLanguage === newLang)
|
|
33
|
+
return;
|
|
34
|
+
// The document direction or language did changed, so lets move on:
|
|
35
|
+
this.documentDirection = newDir;
|
|
36
|
+
this.documentLanguage = newLang;
|
|
37
|
+
// Check if there was any changed.
|
|
38
|
+
this.connectedControllers.forEach((ctrl) => {
|
|
39
|
+
ctrl.documentUpdate();
|
|
40
|
+
});
|
|
41
|
+
if (__classPrivateFieldGet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, "f")) {
|
|
42
|
+
cancelAnimationFrame(__classPrivateFieldGet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, "f"));
|
|
43
|
+
__classPrivateFieldSet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, undefined, "f");
|
|
44
|
+
}
|
|
45
|
+
__classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f").clear();
|
|
46
|
+
};
|
|
47
|
+
_UmbLocalizationManager_updateChangedKeys.set(this, () => {
|
|
48
|
+
__classPrivateFieldSet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, undefined, "f");
|
|
49
|
+
this.connectedControllers.forEach((ctrl) => {
|
|
50
|
+
ctrl.keysChanged(__classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f"));
|
|
51
|
+
});
|
|
52
|
+
__classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f").clear();
|
|
53
|
+
});
|
|
54
|
+
__classPrivateFieldSet(this, _UmbLocalizationManager_documentElementObserver, new MutationObserver(this.updateAll), "f");
|
|
55
|
+
__classPrivateFieldGet(this, _UmbLocalizationManager_documentElementObserver, "f").observe(document.documentElement, {
|
|
56
|
+
attributes: true,
|
|
57
|
+
attributeFilter: ['dir', 'lang'],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
appendConsumer(consumer) {
|
|
61
|
+
if (this.connectedControllers.has(consumer))
|
|
62
|
+
return;
|
|
63
|
+
this.connectedControllers.add(consumer);
|
|
64
|
+
}
|
|
65
|
+
removeConsumer(consumer) {
|
|
66
|
+
this.connectedControllers.delete(consumer);
|
|
67
|
+
}
|
|
68
|
+
/** Registers one or more translations */
|
|
69
|
+
registerLocalization(t) {
|
|
70
|
+
const code = t.$code.toLowerCase();
|
|
71
|
+
if (this.localizations.has(code)) {
|
|
72
|
+
// Merge translations that share the same language code
|
|
73
|
+
this.localizations.set(code, { ...this.localizations.get(code), ...t });
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
this.localizations.set(code, t);
|
|
77
|
+
}
|
|
78
|
+
// Declare what keys have been changed:
|
|
79
|
+
const keys = Object.keys(t);
|
|
80
|
+
for (const key of keys) {
|
|
81
|
+
__classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f").add(key);
|
|
82
|
+
}
|
|
83
|
+
__classPrivateFieldGet(this, _UmbLocalizationManager_instances, "m", _UmbLocalizationManager_requestChangedKeysUpdate).call(this);
|
|
84
|
+
}
|
|
85
|
+
registerManyLocalizations(translations) {
|
|
86
|
+
translations.map(__classPrivateFieldGet(this, _UmbLocalizationManager_registerLocalizationBind, "f"));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
_UmbLocalizationManager_documentElementObserver = new WeakMap(), _UmbLocalizationManager_changedKeys = new WeakMap(), _UmbLocalizationManager_requestUpdateChangedKeysId = new WeakMap(), _UmbLocalizationManager_registerLocalizationBind = new WeakMap(), _UmbLocalizationManager_updateChangedKeys = new WeakMap(), _UmbLocalizationManager_instances = new WeakSet(), _UmbLocalizationManager_requestChangedKeysUpdate = function _UmbLocalizationManager_requestChangedKeysUpdate() {
|
|
90
|
+
if (__classPrivateFieldGet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, "f"))
|
|
91
|
+
return;
|
|
92
|
+
__classPrivateFieldSet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, requestAnimationFrame(__classPrivateFieldGet(this, _UmbLocalizationManager_updateChangedKeys, "f")), "f");
|
|
93
|
+
};
|
|
94
|
+
export const umbLocalizationManager = new UmbLocalizationManager();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UmbLocalizationSetBase } from '../../../../libs/localization-api/index.js';
|
|
2
2
|
import type { UmbBackofficeExtensionRegistry } from '../../extension-registry/index.js';
|
|
3
3
|
export declare class UmbLocalizationRegistry {
|
|
4
4
|
#private;
|
|
5
|
+
readonly currentLanguage: import("rxjs/internal/Observable").Observable<string>;
|
|
5
6
|
/**
|
|
6
7
|
* Get the current registered translations.
|
|
7
8
|
*/
|
|
8
|
-
get localizations(): Map<string,
|
|
9
|
-
get isDefaultLoaded(): import("rxjs/internal/Observable").Observable<boolean>;
|
|
9
|
+
get localizations(): Map<string, UmbLocalizationSetBase>;
|
|
10
10
|
constructor(extensionRegistry: UmbBackofficeExtensionRegistry);
|
|
11
11
|
/**
|
|
12
12
|
* Load a language from the extension registry.
|
|
@@ -3,72 +3,75 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var
|
|
7
|
-
import {
|
|
8
|
-
import { hasDefaultExport, loadManifestPlainJs } from '../../../../libs/extension-api/index.js';
|
|
6
|
+
var _UmbLocalizationRegistry_currentLanguage, _UmbLocalizationRegistry_loadedExtAliases, _UmbLocalizationRegistry_loadExtension;
|
|
7
|
+
import { umbLocalizationManager } from '../../../../libs/localization-api/index.js';
|
|
9
8
|
import { umbExtensionsRegistry } from '../../extension-registry/index.js';
|
|
10
|
-
import {
|
|
9
|
+
import { UmbStringState } from '../../../../libs/observable-api/index.js';
|
|
10
|
+
import { combineLatest } from '../../../../external/rxjs/index.js';
|
|
11
|
+
import { hasDefaultExport, loadManifestPlainJs } from '../../../../libs/extension-api/index.js';
|
|
12
|
+
function addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary) {
|
|
13
|
+
for (const [key, value] of Object.entries(dictionary)) {
|
|
14
|
+
innerDictionary[`${dictionaryName}_${key}`] = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
11
17
|
export class UmbLocalizationRegistry {
|
|
12
18
|
/**
|
|
13
19
|
* Get the current registered translations.
|
|
14
20
|
*/
|
|
15
21
|
get localizations() {
|
|
16
|
-
return localizations;
|
|
17
|
-
}
|
|
18
|
-
get isDefaultLoaded() {
|
|
19
|
-
return __classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").asObservable();
|
|
22
|
+
return umbLocalizationManager.localizations;
|
|
20
23
|
}
|
|
21
24
|
constructor(extensionRegistry) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
.map(async (extension) => {
|
|
33
|
-
const innerDictionary = {};
|
|
34
|
-
// If extension contains a dictionary, add it to the inner dictionary.
|
|
35
|
-
if (extension.meta.localizations) {
|
|
36
|
-
for (const [dictionaryName, dictionary] of Object.entries(extension.meta.localizations)) {
|
|
37
|
-
__classPrivateFieldGet(this, _UmbLocalizationRegistry_instances, "m", _UmbLocalizationRegistry_addOrUpdateDictionary).call(this, innerDictionary, dictionaryName, dictionary);
|
|
38
|
-
}
|
|
25
|
+
_UmbLocalizationRegistry_currentLanguage.set(this, new UmbStringState(document.documentElement.lang ?? 'en-us'));
|
|
26
|
+
this.currentLanguage = __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").asObservable();
|
|
27
|
+
_UmbLocalizationRegistry_loadedExtAliases.set(this, []);
|
|
28
|
+
_UmbLocalizationRegistry_loadExtension.set(this, async (extension) => {
|
|
29
|
+
__classPrivateFieldGet(this, _UmbLocalizationRegistry_loadedExtAliases, "f").push(extension.alias);
|
|
30
|
+
const innerDictionary = {};
|
|
31
|
+
// If extension contains a dictionary, add it to the inner dictionary.
|
|
32
|
+
if (extension.meta.localizations) {
|
|
33
|
+
for (const [dictionaryName, dictionary] of Object.entries(extension.meta.localizations)) {
|
|
34
|
+
addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary);
|
|
39
35
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
}
|
|
37
|
+
// If extension contains a js file, load it and add the default dictionary to the inner dictionary.
|
|
38
|
+
if (extension.js) {
|
|
39
|
+
const loadedExtension = await loadManifestPlainJs(extension.js);
|
|
40
|
+
if (loadedExtension && hasDefaultExport(loadedExtension)) {
|
|
41
|
+
for (const [dictionaryName, dictionary] of Object.entries(loadedExtension.default)) {
|
|
42
|
+
addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary);
|
|
47
43
|
}
|
|
48
44
|
}
|
|
49
|
-
// Notify subscribers that the inner dictionary has changed.
|
|
50
|
-
return {
|
|
51
|
-
$code: extension.meta.culture.toLowerCase(),
|
|
52
|
-
$dir: extension.meta.direction ?? 'ltr',
|
|
53
|
-
...innerDictionary,
|
|
54
|
-
};
|
|
55
|
-
}));
|
|
56
|
-
if (translations.length) {
|
|
57
|
-
registerLocalization(...translations);
|
|
58
|
-
// Set the document language
|
|
59
|
-
const newLang = locale.baseName.toLowerCase();
|
|
60
|
-
if (document.documentElement.lang.toLowerCase() !== newLang) {
|
|
61
|
-
document.documentElement.lang = newLang;
|
|
62
|
-
}
|
|
63
|
-
// Set the document direction to the direction of the primary language
|
|
64
|
-
const newDir = translations[0].$dir ?? 'ltr';
|
|
65
|
-
if (document.documentElement.dir !== newDir) {
|
|
66
|
-
document.documentElement.dir = newDir;
|
|
67
|
-
}
|
|
68
45
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
46
|
+
// Notify subscribers that the inner dictionary has changed.
|
|
47
|
+
return {
|
|
48
|
+
$code: extension.meta.culture.toLowerCase(),
|
|
49
|
+
$dir: extension.meta.direction ?? 'ltr',
|
|
50
|
+
...innerDictionary,
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
combineLatest([this.currentLanguage, extensionRegistry.extensionsOfType('localization')]).subscribe(async ([currentLanguage, extensions]) => {
|
|
54
|
+
const locale = new Intl.Locale(currentLanguage);
|
|
55
|
+
const filteredExt = extensions.filter((ext) => ext.meta.culture.toLowerCase() === locale.baseName.toLowerCase() ||
|
|
56
|
+
ext.meta.culture.toLowerCase() === locale.language.toLowerCase());
|
|
57
|
+
// Only get the extensions that are not already loading/loaded:
|
|
58
|
+
const diff = filteredExt.filter((ext) => !__classPrivateFieldGet(this, _UmbLocalizationRegistry_loadedExtAliases, "f").includes(ext.alias));
|
|
59
|
+
if (diff.length !== 0) {
|
|
60
|
+
// got new localizations to load:
|
|
61
|
+
const translations = await Promise.all(diff.map(__classPrivateFieldGet(this, _UmbLocalizationRegistry_loadExtension, "f")));
|
|
62
|
+
if (translations.length) {
|
|
63
|
+
umbLocalizationManager.registerManyLocalizations(translations);
|
|
64
|
+
// Set the document language
|
|
65
|
+
const newLang = locale.baseName.toLowerCase();
|
|
66
|
+
if (document.documentElement.lang.toLowerCase() !== newLang) {
|
|
67
|
+
document.documentElement.lang = newLang;
|
|
68
|
+
}
|
|
69
|
+
// Set the document direction to the direction of the primary language
|
|
70
|
+
const newDir = translations[0].$dir ?? 'ltr';
|
|
71
|
+
if (document.documentElement.dir !== newDir) {
|
|
72
|
+
document.documentElement.dir = newDir;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
72
75
|
}
|
|
73
76
|
});
|
|
74
77
|
}
|
|
@@ -77,12 +80,8 @@ export class UmbLocalizationRegistry {
|
|
|
77
80
|
* @param locale The locale to load.
|
|
78
81
|
*/
|
|
79
82
|
loadLanguage(locale) {
|
|
80
|
-
__classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").
|
|
83
|
+
__classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").setValue(locale.toLowerCase());
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
|
-
_UmbLocalizationRegistry_currentLanguage = new WeakMap(),
|
|
84
|
-
for (const [key, value] of Object.entries(dictionary)) {
|
|
85
|
-
innerDictionary[`${dictionaryName}_${key}`] = value;
|
|
86
|
-
}
|
|
87
|
-
};
|
|
86
|
+
_UmbLocalizationRegistry_currentLanguage = new WeakMap(), _UmbLocalizationRegistry_loadedExtAliases = new WeakMap(), _UmbLocalizationRegistry_loadExtension = new WeakMap();
|
|
88
87
|
export const umbLocalizationRegistry = new UmbLocalizationRegistry(umbExtensionsRegistry);
|
package/dist-cms/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.js
CHANGED
|
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { html, nothing, customElement, property } from '../../../../external/lit/index.js';
|
|
8
8
|
import { UmbLitElement } from '../../../../shared/lit-element/index.js';
|
|
9
|
-
import { umbExtensionsRegistry
|
|
9
|
+
import { umbExtensionsRegistry } from '../../extension-registry/index.js';
|
|
10
10
|
// TODO: Move to separate file:
|
|
11
11
|
const manifest = {
|
|
12
12
|
type: 'kind',
|