@ui5/webcomponents-localization 1.22.0-rc.0 → 1.22.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/generated/assets/cldr/ar.json +102 -62
- package/dist/generated/assets/cldr/ar_EG.json +102 -62
- package/dist/generated/assets/cldr/ar_SA.json +102 -62
- package/dist/generated/assets/cldr/bg.json +364 -325
- package/dist/generated/assets/cldr/ca.json +491 -453
- package/dist/generated/assets/cldr/cs.json +431 -324
- package/dist/generated/assets/cldr/cy.json +608 -340
- package/dist/generated/assets/cldr/da.json +290 -227
- package/dist/generated/assets/cldr/de.json +348 -241
- package/dist/generated/assets/cldr/de_AT.json +348 -241
- package/dist/generated/assets/cldr/de_CH.json +347 -240
- package/dist/generated/assets/cldr/el.json +128 -100
- package/dist/generated/assets/cldr/el_CY.json +128 -100
- package/dist/generated/assets/cldr/en.json +538 -512
- package/dist/generated/assets/cldr/en_AU.json +583 -520
- package/dist/generated/assets/cldr/en_GB.json +485 -441
- package/dist/generated/assets/cldr/en_HK.json +519 -474
- package/dist/generated/assets/cldr/en_IE.json +485 -440
- package/dist/generated/assets/cldr/en_IN.json +465 -420
- package/dist/generated/assets/cldr/en_NZ.json +505 -460
- package/dist/generated/assets/cldr/en_PG.json +505 -460
- package/dist/generated/assets/cldr/en_SG.json +505 -460
- package/dist/generated/assets/cldr/en_ZA.json +485 -440
- package/dist/generated/assets/cldr/es.json +709 -456
- package/dist/generated/assets/cldr/es_AR.json +687 -434
- package/dist/generated/assets/cldr/es_BO.json +721 -468
- package/dist/generated/assets/cldr/es_CL.json +567 -422
- package/dist/generated/assets/cldr/es_CO.json +485 -339
- package/dist/generated/assets/cldr/es_MX.json +734 -481
- package/dist/generated/assets/cldr/es_PE.json +409 -372
- package/dist/generated/assets/cldr/es_UY.json +433 -396
- package/dist/generated/assets/cldr/es_VE.json +453 -416
- package/dist/generated/assets/cldr/et.json +340 -307
- package/dist/generated/assets/cldr/fa.json +96 -34
- package/dist/generated/assets/cldr/fi.json +359 -308
- package/dist/generated/assets/cldr/fr.json +347 -321
- package/dist/generated/assets/cldr/fr_BE.json +347 -321
- package/dist/generated/assets/cldr/fr_CA.json +458 -432
- package/dist/generated/assets/cldr/fr_CH.json +290 -264
- package/dist/generated/assets/cldr/fr_LU.json +347 -321
- package/dist/generated/assets/cldr/he.json +241 -130
- package/dist/generated/assets/cldr/hi.json +103 -53
- package/dist/generated/assets/cldr/hr.json +467 -410
- package/dist/generated/assets/cldr/hu.json +246 -195
- package/dist/generated/assets/cldr/id.json +478 -406
- package/dist/generated/assets/cldr/it.json +418 -362
- package/dist/generated/assets/cldr/it_CH.json +418 -362
- package/dist/generated/assets/cldr/ja.json +58 -18
- package/dist/generated/assets/cldr/kk.json +562 -398
- package/dist/generated/assets/cldr/ko.json +36 -15
- package/dist/generated/assets/cldr/lt.json +320 -231
- package/dist/generated/assets/cldr/lv.json +184 -120
- package/dist/generated/assets/cldr/ms.json +460 -388
- package/dist/generated/assets/cldr/nb.json +160 -92
- package/dist/generated/assets/cldr/nl.json +621 -373
- package/dist/generated/assets/cldr/nl_BE.json +621 -373
- package/dist/generated/assets/cldr/pl.json +590 -279
- package/dist/generated/assets/cldr/pt.json +696 -334
- package/dist/generated/assets/cldr/pt_PT.json +730 -454
- package/dist/generated/assets/cldr/ro.json +409 -339
- package/dist/generated/assets/cldr/ru.json +317 -279
- package/dist/generated/assets/cldr/ru_UA.json +312 -274
- package/dist/generated/assets/cldr/sk.json +454 -413
- package/dist/generated/assets/cldr/sl.json +118 -80
- package/dist/generated/assets/cldr/sr.json +294 -142
- package/dist/generated/assets/cldr/sr_Latn.json +972 -824
- package/dist/generated/assets/cldr/sv.json +382 -338
- package/dist/generated/assets/cldr/th.json +56 -36
- package/dist/generated/assets/cldr/tr.json +371 -320
- package/dist/generated/assets/cldr/uk.json +340 -290
- package/dist/generated/assets/cldr/vi.json +352 -328
- package/dist/generated/assets/cldr/zh_CN.json +34 -10
- package/dist/generated/assets/cldr/zh_HK.json +33 -9
- package/dist/generated/assets/cldr/zh_SG.json +33 -9
- package/dist/generated/assets/cldr/zh_TW.json +32 -8
- package/dist/sap/base/Event.js +59 -0
- package/dist/sap/base/Eventing.js +146 -0
- package/dist/sap/base/Log.js +2 -239
- package/dist/sap/base/assert.js +28 -1
- package/dist/sap/base/config/MemoryConfigurationProvider.js +20 -0
- package/dist/sap/base/config.js +17 -0
- package/dist/sap/base/i18n/Formatting.js +1130 -0
- package/dist/sap/base/i18n/LanguageTag.js +168 -30
- package/dist/sap/base/i18n/date/CalendarType.js +36 -1
- package/dist/sap/base/i18n/date/CalendarWeekNumbering.js +76 -1
- package/dist/sap/base/i18n/date/TimezoneUtils.js +242 -12
- package/dist/sap/base/strings/camelize.js +30 -0
- package/dist/sap/base/strings/formatMessage.js +88 -15
- package/dist/sap/base/util/ObjectPath.js +95 -3
- package/dist/sap/base/util/Version.js +157 -0
- package/dist/sap/base/util/_merge.js +83 -26
- package/dist/sap/base/util/array/uniqueSort.js +37 -15
- package/dist/sap/base/util/deepClone.js +102 -0
- package/dist/sap/base/util/deepEqual.js +75 -51
- package/dist/sap/base/util/extend.js +58 -7
- package/dist/sap/base/util/isEmptyObject.js +34 -0
- package/dist/sap/base/util/isPlainObject.js +35 -1
- package/dist/sap/base/util/now.js +24 -3
- package/dist/sap/base/util/resolveReference.js +157 -0
- package/dist/sap/base/util/uid.js +27 -0
- package/dist/sap/ui/base/DataType.js +657 -0
- package/dist/sap/ui/base/Interface.js +47 -1
- package/dist/sap/ui/base/Metadata.js +433 -180
- package/dist/sap/ui/base/Object.js +284 -48
- package/dist/sap/ui/core/CalendarType.js +23 -1
- package/dist/sap/ui/core/Locale.js +189 -57
- package/dist/sap/ui/core/LocaleData.js +2670 -1380
- package/dist/sap/ui/core/Supportability.js +5 -0
- package/dist/sap/ui/core/Theming.js +539 -0
- package/dist/sap/ui/core/date/Buddhist.js +162 -87
- package/dist/sap/ui/core/date/CalendarUtils.js +61 -21
- package/dist/sap/ui/core/date/CalendarWeekNumbering.js +29 -1
- package/dist/sap/ui/core/date/Gregorian.js +25 -10
- package/dist/sap/ui/core/date/Islamic.js +298 -185
- package/dist/sap/ui/core/date/Japanese.js +210 -115
- package/dist/sap/ui/core/date/Persian.js +324 -195
- package/dist/sap/ui/core/date/UI5Date.js +923 -237
- package/dist/sap/ui/core/date/UniversalDate.js +1238 -245
- package/dist/sap/ui/core/date/_Calendars.js +10 -1
- package/dist/sap/ui/core/format/DateFormat.js +3163 -2145
- package/dist/sap/ui/core/format/TimezoneUtil.js +23 -1
- package/package-scripts.cjs +4 -10
- package/package.json +9 -5
- package/tsconfig.json +2 -1
- package/used-modules.txt +20 -1
- package/dist/sap/ui/Device.js +0 -5
@@ -0,0 +1,539 @@
|
|
1
|
+
/*!
|
2
|
+
* copyright
|
3
|
+
*/
|
4
|
+
import assert from "../../base/assert.js";
|
5
|
+
import BaseConfig from "../../base/config.js";
|
6
|
+
import BaseEvent from "../../base/Event.js";
|
7
|
+
import Eventing from "../../base/Eventing.js";
|
8
|
+
import Log from "../../base/Log.js";
|
9
|
+
import Localization from "../../base/i18n/Localization.js";
|
10
|
+
import deepEqual from "../../base/util/deepEqual.js";
|
11
|
+
import ThemeHelper from "./theming/ThemeHelper.js";
|
12
|
+
const oWritableConfig = BaseConfig.getWritableInstance();
|
13
|
+
const oEventing = new Eventing();
|
14
|
+
let mChanges;
|
15
|
+
let oThemeManager;
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Provides theming related API
|
19
|
+
*
|
20
|
+
* @alias module:sap/ui/core/Theming
|
21
|
+
* @namespace
|
22
|
+
* @public
|
23
|
+
* @since 1.118
|
24
|
+
*/
|
25
|
+
const Theming = {
|
26
|
+
/**
|
27
|
+
* Returns the theme name
|
28
|
+
* @return {string} the theme name
|
29
|
+
* @public
|
30
|
+
* @since 1.118
|
31
|
+
*/
|
32
|
+
getTheme: () => {
|
33
|
+
// analyze theme parameter
|
34
|
+
let sTheme = oWritableConfig.get({
|
35
|
+
name: "sapTheme",
|
36
|
+
type: oWritableConfig.Type.String,
|
37
|
+
defaultValue: oWritableConfig.get({
|
38
|
+
name: "sapUiTheme",
|
39
|
+
type: oWritableConfig.Type.String,
|
40
|
+
external: true
|
41
|
+
}),
|
42
|
+
external: true
|
43
|
+
});
|
44
|
+
|
45
|
+
// Empty string is a valid value wrt. the <String> type.
|
46
|
+
// An empty string is equivalent to "no theme given" here.
|
47
|
+
// We apply the default, but also automatically detect the dark mode.
|
48
|
+
if (sTheme === "") {
|
49
|
+
const mDefaultThemeInfo = ThemeHelper.getDefaultThemeInfo();
|
50
|
+
sTheme = `${mDefaultThemeInfo.DEFAULT_THEME}${mDefaultThemeInfo.DARK_MODE ? "_dark" : ""}`;
|
51
|
+
}
|
52
|
+
|
53
|
+
// It's only possible to provide a themeroot via theme parameter using
|
54
|
+
// the initial config provider such as Global-, Bootstrap-, Meta- and
|
55
|
+
// URLConfigurationProvider. The themeroot is also only validated against
|
56
|
+
// allowedThemeOrigin in this case.
|
57
|
+
const iIndex = sTheme.indexOf("@");
|
58
|
+
if (iIndex >= 0) {
|
59
|
+
const sThemeRoot = validateThemeRoot(sTheme.slice(iIndex + 1));
|
60
|
+
sTheme = iIndex > 0 ? sTheme.slice(0, iIndex) : sTheme;
|
61
|
+
if (sThemeRoot !== Theming.getThemeRoot(sTheme)) {
|
62
|
+
Theming.setThemeRoot(sTheme, sThemeRoot);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
// validate theme and fallback to the fixed default, in case the configured theme is not valid
|
67
|
+
sTheme = ThemeHelper.validateAndFallbackTheme(sTheme, Theming.getThemeRoot(sTheme));
|
68
|
+
return sTheme;
|
69
|
+
},
|
70
|
+
/**
|
71
|
+
* Allows setting the theme name
|
72
|
+
* @param {string} sTheme the theme name
|
73
|
+
* @public
|
74
|
+
* @since 1.118
|
75
|
+
*/
|
76
|
+
setTheme: sTheme => {
|
77
|
+
if (sTheme) {
|
78
|
+
if (sTheme.indexOf("@") !== -1) {
|
79
|
+
throw new TypeError("Providing a theme root as part of the theme parameter is not allowed.");
|
80
|
+
}
|
81
|
+
const bFireChange = !mChanges;
|
82
|
+
mChanges ??= {};
|
83
|
+
const sOldTheme = Theming.getTheme();
|
84
|
+
oWritableConfig.set("sapTheme", sTheme);
|
85
|
+
const sNewTheme = Theming.getTheme();
|
86
|
+
const bThemeChanged = sOldTheme !== sNewTheme;
|
87
|
+
if (bThemeChanged) {
|
88
|
+
mChanges.theme = {
|
89
|
+
"new": sNewTheme,
|
90
|
+
"old": sOldTheme
|
91
|
+
};
|
92
|
+
} else {
|
93
|
+
mChanges = undefined;
|
94
|
+
}
|
95
|
+
if (bFireChange) {
|
96
|
+
fireChange(mChanges);
|
97
|
+
}
|
98
|
+
if (!oThemeManager && bThemeChanged) {
|
99
|
+
fireApplied({
|
100
|
+
theme: sNewTheme
|
101
|
+
});
|
102
|
+
}
|
103
|
+
}
|
104
|
+
},
|
105
|
+
/**
|
106
|
+
*
|
107
|
+
* @param {string} sTheme The Theme
|
108
|
+
* @param {string} [sLib] An optional library name
|
109
|
+
* @returns {string} The themeRoot if configured
|
110
|
+
* @private
|
111
|
+
* @ui5-restricted sap.ui.core.theming.ThemeManager
|
112
|
+
* @since 1.118
|
113
|
+
*/
|
114
|
+
getThemeRoot: (sTheme, sLib) => {
|
115
|
+
const oThemeRoots = oWritableConfig.get({
|
116
|
+
name: "sapUiThemeRoots",
|
117
|
+
type: oWritableConfig.Type.MergedObject
|
118
|
+
});
|
119
|
+
let sThemeRoot;
|
120
|
+
sTheme ??= Theming.getTheme();
|
121
|
+
if (oThemeRoots[sTheme] && typeof oThemeRoots[sTheme] === "string") {
|
122
|
+
sThemeRoot = oThemeRoots[sTheme];
|
123
|
+
} else if (oThemeRoots[sTheme] && typeof oThemeRoots[sTheme] === "object") {
|
124
|
+
sThemeRoot = oThemeRoots[sTheme][sLib] || oThemeRoots[sTheme][""];
|
125
|
+
}
|
126
|
+
return sThemeRoot;
|
127
|
+
},
|
128
|
+
/**
|
129
|
+
* Defines the root directory from below which UI5 should load the theme with the given name.
|
130
|
+
* Optionally allows restricting the setting to parts of a theme covering specific control libraries.
|
131
|
+
*
|
132
|
+
* Example:
|
133
|
+
* <pre>
|
134
|
+
* Theming.setThemeRoot("my_theme", "https://mythemeserver.com/allThemes");
|
135
|
+
* Theming.setTheme("my_theme");
|
136
|
+
* </pre>
|
137
|
+
*
|
138
|
+
* will cause the following file to be loaded (assuming that the bootstrap is configured to load
|
139
|
+
* libraries <code>sap.m</code> and <code>sap.ui.layout</code>):
|
140
|
+
* <pre>
|
141
|
+
* https://mythemeserver.com/allThemes/sap/ui/core/themes/my_theme/library.css
|
142
|
+
* https://mythemeserver.com/allThemes/sap/ui/layout/themes/my_theme/library.css
|
143
|
+
* https://mythemeserver.com/allThemes/sap/m/themes/my_theme/library.css
|
144
|
+
* </pre>
|
145
|
+
*
|
146
|
+
* If parts of the theme are at different locations (e.g. because you provide a standard theme
|
147
|
+
* like "sap_belize" for a custom control library and this self-made part of the standard theme is at a
|
148
|
+
* different location than the UI5 resources), you can also specify for which control libraries the setting
|
149
|
+
* should be used, by giving an array with the names of the respective control libraries as second parameter:
|
150
|
+
* <pre>
|
151
|
+
* Theming.setThemeRoot("sap_belize", ["my.own.library"], "https://mythemeserver.com/allThemes");
|
152
|
+
* </pre>
|
153
|
+
*
|
154
|
+
* This will cause the Belize theme to be loaded from the UI5 location for all standard libraries.
|
155
|
+
* Resources for styling the <code>my.own.library</code> controls will be loaded from the configured
|
156
|
+
* location:
|
157
|
+
* <pre>
|
158
|
+
* https://openui5.hana.ondemand.com/resources/sap/ui/core/themes/sap_belize/library.css
|
159
|
+
* https://openui5.hana.ondemand.com/resources/sap/ui/layout/themes/sap_belize/library.css
|
160
|
+
* https://openui5.hana.ondemand.com/resources/sap/m/themes/sap_belize/library.css
|
161
|
+
* https://mythemeserver.com/allThemes/my/own/library/themes/sap_belize/library.css
|
162
|
+
* </pre>
|
163
|
+
*
|
164
|
+
* If the custom theme should be loaded initially (via bootstrap attribute), the <code>themeRoots</code>
|
165
|
+
* property of the <code>window["sap-ui-config"]</code> object must be used instead of calling
|
166
|
+
* <code>Theming.setThemeRoot(...)</code> in order to configure the theme location early enough.
|
167
|
+
*
|
168
|
+
* @param {string} sThemeName Name of the theme for which to configure the location
|
169
|
+
* @param {string} sThemeBaseUrl Base URL below which the CSS file(s) will be loaded from
|
170
|
+
* @param {string[]} [aLibraryNames] Optional library names to which the configuration should be restricted
|
171
|
+
* @param {boolean} [bForceUpdate=false] Force updating URLs of currently loaded theme
|
172
|
+
* @private
|
173
|
+
* @ui5-restricted sap.ui.core.Core
|
174
|
+
* @since 1.118
|
175
|
+
*/
|
176
|
+
setThemeRoot: (sThemeName, sThemeBaseUrl, aLibraryNames, bForceUpdate) => {
|
177
|
+
assert(typeof sThemeName === "string", "sThemeName must be a string");
|
178
|
+
assert(typeof sThemeBaseUrl === "string", "sThemeBaseUrl must be a string");
|
179
|
+
const bFireChange = !mChanges;
|
180
|
+
mChanges ??= {};
|
181
|
+
const oThemeRootConfigParam = {
|
182
|
+
name: "sapUiThemeRoots",
|
183
|
+
type: oWritableConfig.Type.MergedObject
|
184
|
+
};
|
185
|
+
|
186
|
+
// Use get twice, for a deep copy of themeRoots object
|
187
|
+
// we add a new default "empty object" with each call, so we don't accidentally share it
|
188
|
+
const mOldThemeRoots = oWritableConfig.get(Object.assign(oThemeRootConfigParam, {
|
189
|
+
defaultValue: {}
|
190
|
+
}));
|
191
|
+
const mNewThemeRoots = oWritableConfig.get(Object.assign(oThemeRootConfigParam, {
|
192
|
+
defaultValue: {}
|
193
|
+
}));
|
194
|
+
|
195
|
+
// normalize parameters
|
196
|
+
if (typeof aLibraryNames === "boolean") {
|
197
|
+
bForceUpdate = aLibraryNames;
|
198
|
+
aLibraryNames = undefined;
|
199
|
+
}
|
200
|
+
mNewThemeRoots[sThemeName] ??= {};
|
201
|
+
|
202
|
+
// Normalize theme-roots to an object in case it was initially given as a string.
|
203
|
+
// We only check newThemeRoots, since both old and new are identical at this point.
|
204
|
+
if (typeof mNewThemeRoots[sThemeName] === "string") {
|
205
|
+
mNewThemeRoots[sThemeName] = {
|
206
|
+
"": mNewThemeRoots[sThemeName]
|
207
|
+
};
|
208
|
+
mOldThemeRoots[sThemeName] = {
|
209
|
+
"": mOldThemeRoots[sThemeName]
|
210
|
+
};
|
211
|
+
}
|
212
|
+
if (aLibraryNames) {
|
213
|
+
// registration of URL for several libraries
|
214
|
+
for (let i = 0; i < aLibraryNames.length; i++) {
|
215
|
+
const lib = aLibraryNames[i];
|
216
|
+
mNewThemeRoots[sThemeName][lib] = sThemeBaseUrl;
|
217
|
+
}
|
218
|
+
} else {
|
219
|
+
// registration of theme default base URL
|
220
|
+
mNewThemeRoots[sThemeName][""] = sThemeBaseUrl;
|
221
|
+
}
|
222
|
+
if (!deepEqual(mOldThemeRoots, mNewThemeRoots)) {
|
223
|
+
oWritableConfig.set("sapUiThemeRoots", mNewThemeRoots);
|
224
|
+
if (aLibraryNames) {
|
225
|
+
mChanges.themeRoots = {
|
226
|
+
"new": Object.assign({}, mNewThemeRoots[sThemeName]),
|
227
|
+
"old": Object.assign({}, mOldThemeRoots[sThemeName])
|
228
|
+
};
|
229
|
+
} else {
|
230
|
+
mChanges.themeRoots = {
|
231
|
+
"new": sThemeBaseUrl,
|
232
|
+
"old": mOldThemeRoots[sThemeName]?.[""]
|
233
|
+
};
|
234
|
+
}
|
235
|
+
mChanges.themeRoots.forceUpdate = bForceUpdate && sThemeName === Theming.getTheme();
|
236
|
+
} else {
|
237
|
+
mChanges = undefined;
|
238
|
+
}
|
239
|
+
if (bFireChange) {
|
240
|
+
fireChange();
|
241
|
+
}
|
242
|
+
},
|
243
|
+
/**
|
244
|
+
* Fired after a theme has been applied.
|
245
|
+
*
|
246
|
+
* More precisely, this event is fired when any of the following conditions is met:
|
247
|
+
* <ul>
|
248
|
+
* <li>the initially configured theme has been applied after core init</li>
|
249
|
+
* <li>the theme has been changed and is now applied (see {@link #applyTheme})</li>
|
250
|
+
* <li>a library has been loaded dynamically after core init (e.g. with
|
251
|
+
* <code>sap.ui.core.Lib.load(...)</code> and the current theme
|
252
|
+
* has been applied for it</li>
|
253
|
+
* </ul>
|
254
|
+
*
|
255
|
+
* For the event parameters please refer to {@link module:sap/ui/core/Theming$AppliedEvent}.
|
256
|
+
*
|
257
|
+
* @name module:sap/ui/core/Theming.applied
|
258
|
+
* @event
|
259
|
+
* @param {module:sap/ui/core/Theming$AppliedEvent} oEvent
|
260
|
+
* @public
|
261
|
+
* @since 1.118.0
|
262
|
+
*/
|
263
|
+
|
264
|
+
/**
|
265
|
+
* The theme applied Event.
|
266
|
+
*
|
267
|
+
* @typedef {object} module:sap/ui/core/Theming$AppliedEvent
|
268
|
+
* @property {string} theme The newly set language.
|
269
|
+
* @public
|
270
|
+
* @since 1.118.0
|
271
|
+
*/
|
272
|
+
|
273
|
+
/**
|
274
|
+
* Attaches event handler <code>fnFunction</code> to the {@link #event:applied applied} event
|
275
|
+
*
|
276
|
+
* The given handler is called when the the applied event is fired. If the theme is already applied
|
277
|
+
* the handler will be called immediately.
|
278
|
+
*
|
279
|
+
* @param {function(module:sap/ui/core/Theming$AppliedEvent)} fnFunction The function to be called, when the event occurs
|
280
|
+
* @private
|
281
|
+
* @ui5-restricted sap.ui.core.Core
|
282
|
+
* @since 1.118.0
|
283
|
+
*/
|
284
|
+
attachAppliedOnce: fnFunction => {
|
285
|
+
const sId = "applied";
|
286
|
+
if (oThemeManager) {
|
287
|
+
if (oThemeManager.themeLoaded) {
|
288
|
+
fnFunction.call(null, new BaseEvent(sId, {
|
289
|
+
theme: Theming.getTheme()
|
290
|
+
}));
|
291
|
+
} else {
|
292
|
+
oEventing.attachEventOnce(sId, fnFunction);
|
293
|
+
}
|
294
|
+
} else {
|
295
|
+
fnFunction.call(null, new BaseEvent(sId, {
|
296
|
+
theme: Theming.getTheme()
|
297
|
+
}));
|
298
|
+
}
|
299
|
+
},
|
300
|
+
/**
|
301
|
+
* Attaches event handler <code>fnFunction</code> to the {@link #event:applied applied} event.
|
302
|
+
*
|
303
|
+
* The given handler is called when the the applied event is fired. If the theme is already applied
|
304
|
+
* the handler will be called immediately. The handler stays attached to the applied event for future
|
305
|
+
* theme changes.
|
306
|
+
*
|
307
|
+
* @param {function(module:sap/ui/core/Theming$AppliedEvent)} fnFunction The function to be called, when the event occurs
|
308
|
+
* @public
|
309
|
+
* @since 1.118.0
|
310
|
+
*/
|
311
|
+
attachApplied: fnFunction => {
|
312
|
+
const sId = "applied";
|
313
|
+
oEventing.attachEvent(sId, fnFunction);
|
314
|
+
if (oThemeManager) {
|
315
|
+
if (oThemeManager.themeLoaded) {
|
316
|
+
fnFunction.call(null, new BaseEvent(sId, {
|
317
|
+
theme: Theming.getTheme()
|
318
|
+
}));
|
319
|
+
}
|
320
|
+
} else {
|
321
|
+
fnFunction.call(null, new BaseEvent(sId, {
|
322
|
+
theme: Theming.getTheme()
|
323
|
+
}));
|
324
|
+
}
|
325
|
+
},
|
326
|
+
/**
|
327
|
+
* Detaches event handler <code>fnFunction</code> from the {@link #event:applied applied} event
|
328
|
+
*
|
329
|
+
* The passed function must match the one used for event registration.
|
330
|
+
*
|
331
|
+
* @param {function(module:sap/ui/core/Theming$AppliedEvent)} fnFunction The function to be called, when the event occurs
|
332
|
+
* @public
|
333
|
+
* @since 1.118.0
|
334
|
+
*/
|
335
|
+
detachApplied: fnFunction => {
|
336
|
+
oEventing.detachEvent("applied", fnFunction);
|
337
|
+
},
|
338
|
+
/**
|
339
|
+
* The <code>change</code> event is fired, when the configuration options are changed.
|
340
|
+
*
|
341
|
+
* @name module:sap/ui/core/Theming.change
|
342
|
+
* @event
|
343
|
+
* @param {module:sap/ui/core/Theming$ChangeEvent} oEvent
|
344
|
+
* @private
|
345
|
+
* @ui5-restricted sap.ui.core.theming.ThemeManager
|
346
|
+
* @since 1.118.0
|
347
|
+
*/
|
348
|
+
|
349
|
+
/**
|
350
|
+
* The theme applied Event.
|
351
|
+
*
|
352
|
+
* @typedef {object} module:sap/ui/core/Theming$ChangeEvent
|
353
|
+
* @property {Object<string,string>} [theme] Theme object containing the old and the new theme
|
354
|
+
* @property {string} [theme.new] The new theme.
|
355
|
+
* @property {string} [theme.old] The old theme.
|
356
|
+
* @property {Object<string,Object<string,string>|boolean>} [themeRoots] ThemeRoots object containing the old and the new ThemeRoots
|
357
|
+
* @property {object} [themeRoots.new] The new ThemeRoots.
|
358
|
+
* @property {object} [themeRoots.old] The old ThemeRoots.
|
359
|
+
* @property {boolean} [themeRoots.forceUpdate] Whether an update of currently loaded theme URLS should be forced
|
360
|
+
* @private
|
361
|
+
* @ui5-restricted sap.ui.core.theming.ThemeManager
|
362
|
+
* @since 1.118.0
|
363
|
+
*/
|
364
|
+
|
365
|
+
/**
|
366
|
+
* Attaches the <code>fnFunction</code> event handler to the {@link #event:change change} event
|
367
|
+
* of <code>sap.ui.core.Theming</code>.
|
368
|
+
*
|
369
|
+
* @param {function(module:sap/ui/core/Theming$ChangeEvent)} fnFunction The function to be called when the event occurs
|
370
|
+
* @private
|
371
|
+
* @ui5-restricted sap.ui.core.theming.ThemeManager
|
372
|
+
* @since 1.118.0
|
373
|
+
*/
|
374
|
+
attachChange: fnFunction => {
|
375
|
+
oEventing.attachEvent("change", fnFunction);
|
376
|
+
},
|
377
|
+
/**
|
378
|
+
* Detaches event handler <code>fnFunction</code> from the {@link #event:change change} event of
|
379
|
+
* this <code>sap.ui.core.Theming</code>.
|
380
|
+
*
|
381
|
+
* @param {function(module:sap/ui/core/Theming$ChangeEvent)} fnFunction Function to be called when the event occurs
|
382
|
+
* @private
|
383
|
+
* @ui5-restricted sap.ui.core.theming.ThemeManager
|
384
|
+
* @since 1.118.0
|
385
|
+
*/
|
386
|
+
detachChange: fnFunction => {
|
387
|
+
oEventing.detachEvent("change", fnFunction);
|
388
|
+
},
|
389
|
+
/**
|
390
|
+
* Fired when a scope class has been added or removed on a control/element
|
391
|
+
* by using the custom style class API <code>addStyleClass</code>,
|
392
|
+
* <code>removeStyleClass</code> or <code>toggleStyleClass</code>.
|
393
|
+
*
|
394
|
+
* Scope classes are defined by the library theme parameters coming from the
|
395
|
+
* current theme.
|
396
|
+
*
|
397
|
+
* <b>Note:</b> The event will only be fired after the
|
398
|
+
* <code>sap.ui.core.theming.Parameters</code> module has been loaded.
|
399
|
+
* By default this is not the case.
|
400
|
+
*
|
401
|
+
* @name module:sap/ui/core/Theming.themeScopingChanged
|
402
|
+
* @event
|
403
|
+
* @param {module:sap/ui/core/Theming$ThemeScopingChangedEvent} oEvent
|
404
|
+
* @private
|
405
|
+
* @ui5-restricted SAPUI5 Distribution Layer Libraries
|
406
|
+
* @since 1.118.0
|
407
|
+
*/
|
408
|
+
|
409
|
+
/**
|
410
|
+
* The theme scoping change Event.
|
411
|
+
*
|
412
|
+
* @typedef {object} module:sap/ui/core/Theming$ThemeScopingChangedEvent
|
413
|
+
* @property {array} scopes An array containing all changed scopes.
|
414
|
+
* @property {boolean} added Whether the scope was added or removed.
|
415
|
+
* @property {sap.ui.core.Element} element The UI5 element the scope has changed for.
|
416
|
+
* @private
|
417
|
+
* @ui5-restricted sap.ui.core.theming.ThemeManager
|
418
|
+
* @since 1.118.0
|
419
|
+
*/
|
420
|
+
|
421
|
+
/**
|
422
|
+
* Attaches the <code>fnFunction</code> event handler to the {@link #event:themeScopingChanged change} event
|
423
|
+
* of <code>sap.ui.core.Theming</code>.
|
424
|
+
*
|
425
|
+
* @param {function(module:sap/ui/core/Theming$ThemeScopingChangedEvent)} fnFunction The function to be called when the event occurs
|
426
|
+
* @private
|
427
|
+
* @ui5-restricted SAPUI5 Distribution Layer Libraries
|
428
|
+
* @since 1.118.0
|
429
|
+
*/
|
430
|
+
attachThemeScopingChanged: fnFunction => {
|
431
|
+
oEventing.attachEvent("themeScopingChanged", fnFunction);
|
432
|
+
},
|
433
|
+
/**
|
434
|
+
* Detaches event handler <code>fnFunction</code> from the {@link #event:themeScopingChanged change} event of
|
435
|
+
* this <code>sap.ui.core.Theming</code>.
|
436
|
+
*
|
437
|
+
* @param {function(module:sap/ui/core/Theming$ThemeScopingChangedEvent)} fnFunction Function to be called when the event occurs
|
438
|
+
* @private
|
439
|
+
* @ui5-restricted SAPUI5 Distribution Layer Libraries
|
440
|
+
* @since 1.118.0
|
441
|
+
*/
|
442
|
+
detachThemeScopingChanged: fnFunction => {
|
443
|
+
oEventing.detachEvent("themeScopingChanged", fnFunction);
|
444
|
+
},
|
445
|
+
/**
|
446
|
+
* Fire themeScopingChanged event.
|
447
|
+
*
|
448
|
+
* @param {Object<string,array|boolean|sap.ui.core.Element>} mParameters Function to be called when the event occurs
|
449
|
+
* @private
|
450
|
+
* @ui5-restricted SAPUI5 Distribution Layer Libraries
|
451
|
+
* @since 1.118.0
|
452
|
+
*/
|
453
|
+
fireThemeScopingChanged: mParameters => {
|
454
|
+
oEventing.fireEvent("themeScopingChanged", mParameters);
|
455
|
+
},
|
456
|
+
/**
|
457
|
+
* Notify content density changes
|
458
|
+
*
|
459
|
+
* @public
|
460
|
+
* @since 1.118.0
|
461
|
+
*/
|
462
|
+
notifyContentDensityChanged: () => {
|
463
|
+
fireApplied({
|
464
|
+
theme: Theming.getTheme()
|
465
|
+
});
|
466
|
+
},
|
467
|
+
/** Register a ThemeManager instance
|
468
|
+
* @param {sap.ui.core.theming.ThemeManager} oManager The ThemeManager to register.
|
469
|
+
* @private
|
470
|
+
* @ui5-restricted sap.ui.core.theming.ThemeManager
|
471
|
+
* @since 1.118.0
|
472
|
+
*/
|
473
|
+
registerThemeManager: oManager => {
|
474
|
+
oThemeManager = oManager;
|
475
|
+
oThemeManager._attachThemeApplied(function (oEvent) {
|
476
|
+
fireApplied(BaseEvent.getParameters(oEvent));
|
477
|
+
});
|
478
|
+
// handle RTL changes
|
479
|
+
Localization.attachChange(function (oEvent) {
|
480
|
+
var bRTL = oEvent.rtl;
|
481
|
+
if (bRTL !== undefined) {
|
482
|
+
oThemeManager._updateThemeUrls(Theming.getTheme());
|
483
|
+
}
|
484
|
+
});
|
485
|
+
}
|
486
|
+
};
|
487
|
+
function fireChange() {
|
488
|
+
if (mChanges) {
|
489
|
+
oEventing.fireEvent("change", mChanges);
|
490
|
+
mChanges = undefined;
|
491
|
+
}
|
492
|
+
}
|
493
|
+
function fireApplied(oTheme) {
|
494
|
+
oEventing.fireEvent("applied", oTheme);
|
495
|
+
}
|
496
|
+
function validateThemeOrigin(sOrigin, bNoProtocol) {
|
497
|
+
const sAllowedOrigins = oWritableConfig.get({
|
498
|
+
name: "sapAllowedThemeOrigins",
|
499
|
+
type: oWritableConfig.Type.String
|
500
|
+
});
|
501
|
+
return !!sAllowedOrigins?.split(",").some(sAllowedOrigin => {
|
502
|
+
try {
|
503
|
+
sAllowedOrigin = bNoProtocol && !sAllowedOrigin.startsWith("//") ? "//" + sAllowedOrigin : sAllowedOrigin;
|
504
|
+
return sAllowedOrigin === "*" || sOrigin === new URL(sAllowedOrigin.trim(), globalThis.location.href).origin;
|
505
|
+
} catch (error) {
|
506
|
+
Log.error("[FUTURE FATAL] sapAllowedThemeOrigin provides invalid theme origin: " + sAllowedOrigin);
|
507
|
+
return false;
|
508
|
+
}
|
509
|
+
});
|
510
|
+
}
|
511
|
+
function validateThemeRoot(sThemeRoot) {
|
512
|
+
const bNoProtocol = sThemeRoot.startsWith("//");
|
513
|
+
let oThemeRoot, sPath;
|
514
|
+
try {
|
515
|
+
// Remove search query as they are not supported for themeRoots/resourceRoots
|
516
|
+
oThemeRoot = new URL(sThemeRoot, globalThis.location.href);
|
517
|
+
oThemeRoot.search = "";
|
518
|
+
|
519
|
+
// If the URL is absolute, validate the origin
|
520
|
+
if (oThemeRoot.origin && validateThemeOrigin(oThemeRoot.origin, bNoProtocol)) {
|
521
|
+
sPath = oThemeRoot.toString();
|
522
|
+
} else {
|
523
|
+
// For relative URLs or not allowed origins
|
524
|
+
// ensure same origin and resolve relative paths based on origin
|
525
|
+
oThemeRoot = new URL(oThemeRoot.pathname, globalThis.location.href);
|
526
|
+
sPath = oThemeRoot.toString();
|
527
|
+
}
|
528
|
+
|
529
|
+
// legacy compatibility: support for "protocol-less" urls (previously handled by URI.js)
|
530
|
+
if (bNoProtocol) {
|
531
|
+
sPath = sPath.replace(oThemeRoot.protocol, "");
|
532
|
+
}
|
533
|
+
sPath += (sPath.endsWith('/') ? '' : '/') + "UI5/";
|
534
|
+
} catch (e) {
|
535
|
+
// malformed URL are also not accepted
|
536
|
+
}
|
537
|
+
return sPath;
|
538
|
+
}
|
539
|
+
export default Theming;
|