diff --git a/packages/base/bundle.esm.js b/packages/base/bundle.esm.js
index b81e05d2174c..d9f76317bb19 100644
--- a/packages/base/bundle.esm.js
+++ b/packages/base/bundle.esm.js
@@ -1,4 +1,4 @@
-import { registerThemeProperties } from "./dist/AssetRegistry.js";
+import { registerThemePropertiesLoader } from "./dist/AssetRegistry.js";
// ESM bundle targets browsers with native support
import "./dist/features/OpenUI5Support.js";
@@ -20,11 +20,10 @@ import { isIE } from "./dist/Device.js";
window.isIE = isIE; // attached to the window object for testing purposes
// used for tests - to register a custom theme
-window.registerThemeProperties = registerThemeProperties;
+window.registerThemePropertiesLoader = registerThemePropertiesLoader;
// i18n
-import "./dist/features/PropertiesFormatSupport.js";
-import { registerI18nBundle, fetchI18nBundle, getI18nBundle } from "./dist/i18nBundle.js";
+import { registerI18nLoader, fetchI18nBundle, getI18nBundle } from "./dist/i18nBundle.js";
// Note: keep in sync with rollup.config value for IIFE
import { getAnimationMode } from "./dist/config/AnimationMode.js";
@@ -34,7 +33,7 @@ import { getTheme, setTheme } from "./dist/config/Theme.js";
import { getNoConflict, setNoConflict } from "./dist/config/NoConflict.js";
import { getRTL } from "./dist/config/RTL.js";
import { getFirstDayOfWeek } from "./dist/config/FormatSettings.js";
-import { getRegisteredNames as getIconNames } from "./dist/SVGIconRegistry.js"
+import { _getRegisteredNames as getIconNames } from "./dist/asset-registries/Icons.js"
window["sap-ui-webcomponents-bundle"] = {
configuration : {
getAnimationMode,
@@ -48,7 +47,7 @@ window["sap-ui-webcomponents-bundle"] = {
getFirstDayOfWeek,
},
getIconNames,
- registerI18nBundle,
+ registerI18nLoader,
fetchI18nBundle,
getI18nBundle,
renderFinished,
diff --git a/packages/base/src/AssetRegistry.js b/packages/base/src/AssetRegistry.js
index 307c966967d7..ba71fae7edc5 100644
--- a/packages/base/src/AssetRegistry.js
+++ b/packages/base/src/AssetRegistry.js
@@ -1,12 +1,11 @@
-import { registerI18nBundle } from "./asset-registries/i18n.js";
-import { registerCldr, _registerMappingFunction as registerCldrMappingFunction } from "./asset-registries/LocaleData.js";
-import { registerThemeProperties } from "./asset-registries/Themes.js";
-import { registerAssetPathMappingFunction } from "./util/EffectiveAssetPath.js";
+import { registerI18nLoader } from "./asset-registries/i18n.js";
+import { registerLocaleDataLoader } from "./asset-registries/LocaleData.js";
+import { registerThemePropertiesLoader } from "./asset-registries/Themes.js";
+import { registerIconLoader } from "./asset-registries/Icons.js";
export {
- registerCldr,
- registerCldrMappingFunction,
- registerThemeProperties,
- registerI18nBundle,
- registerAssetPathMappingFunction,
+ registerI18nLoader,
+ registerLocaleDataLoader,
+ registerThemePropertiesLoader,
+ registerIconLoader,
};
diff --git a/packages/base/src/util/parseProperties.js b/packages/base/src/PropertiesFileFormat.js
similarity index 91%
rename from packages/base/src/util/parseProperties.js
rename to packages/base/src/PropertiesFileFormat.js
index 9de28143d6ea..3e24c3a48f55 100644
--- a/packages/base/src/util/parseProperties.js
+++ b/packages/base/src/PropertiesFileFormat.js
@@ -15,6 +15,12 @@ const mEscapes = {
"\\t": "\t",
};
+/**
+ * Parses a .properties format
+ * @param {string} sText the contents a of a .properties file
+ * @returns a object with key/value pairs parsed from the .properties file format
+ * @public
+ */
const parseProperties = sText => {
const properties = {},
aLines = sText.split(rLines);
diff --git a/packages/base/src/SVGIconRegistry.js b/packages/base/src/SVGIconRegistry.js
deleted file mode 100644
index 3f2d4e24f9e9..000000000000
--- a/packages/base/src/SVGIconRegistry.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import getSharedResource from "./getSharedResource.js";
-
-const registry = getSharedResource("SVGIcons.registry", new Map());
-const iconCollectionPromises = getSharedResource("SVGIcons.promises", new Map());
-
-const ICON_NOT_FOUND = "ICON_NOT_FOUND";
-const DEFAULT_COLLECTION = "SAP-icons";
-
-const parseName = name => {
- // silently support ui5-compatible URIs
- if (name.startsWith("sap-icon://")) {
- name = name.replace("sap-icon://", "");
- }
-
- let collection;
- [name, collection] = name.split("/").reverse();
- collection = collection || DEFAULT_COLLECTION;
- // hardcoded alias in case icon explorer is used, resolve `SAP-icons-TNT` to `tnt`
- // aliases can be made a feature in the future if more collections need it or more aliases are needed.
- if (collection === "SAP-icons-TNT") {
- collection = "tnt";
- }
- const registryKey = `${collection}/${name}`;
- return { name, collection, registryKey };
-};
-
-
-const registerIcon = (name, { pathData, ltr, accData, collection } = {}) => { // eslint-disable-line
- if (!collection) {
- collection = DEFAULT_COLLECTION;
- }
-
- const key = `${collection}/${name}`;
- registry.set(key, { pathData, ltr, accData });
-};
-
-const getIconDataSync = nameProp => {
- const { registryKey } = parseName(nameProp);
- return registry.get(registryKey);
-};
-
-const getIconData = async nameProp => {
- const { collection, registryKey } = parseName(nameProp);
-
- if (!iconCollectionPromises.has(collection)) {
- iconCollectionPromises.set(collection, Promise.resolve(ICON_NOT_FOUND));
- }
-
- const iconData = await iconCollectionPromises.get(collection);
-
- if (iconData === ICON_NOT_FOUND) {
- return iconData;
- }
-
- return registry.get(registryKey);
-};
-
-const getRegisteredNames = async () => {
- await Promise.all(Array.from(iconCollectionPromises.values()));
- return Array.from(registry.keys());
-};
-
-const registerCollectionPromise = (collection, promise) => {
- iconCollectionPromises.set(collection, promise);
-};
-
-export {
- getIconData,
- getIconDataSync,
- registerIcon,
- getRegisteredNames,
- registerCollectionPromise,
-};
diff --git a/packages/base/src/asset-registries/Icons.js b/packages/base/src/asset-registries/Icons.js
index 741aa60d4e28..ea3b5461ec1d 100644
--- a/packages/base/src/asset-registries/Icons.js
+++ b/packages/base/src/asset-registries/Icons.js
@@ -1,22 +1,33 @@
-import { registerIcon, registerCollectionPromise } from "../SVGIconRegistry.js";
-import { fetchJsonOnce } from "../util/FetchHelper.js";
-import { getEffectiveAssetPath } from "../util/EffectiveAssetPath.js";
+import getSharedResource from "../getSharedResource.js";
+const loaders = new Map();
+const registry = getSharedResource("SVGIcons.registry", new Map());
+const iconCollectionPromises = getSharedResource("SVGIcons.promises", new Map());
+
+const ICON_NOT_FOUND = "ICON_NOT_FOUND";
+const DEFAULT_COLLECTION = "SAP-icons";
+
+/**
+ * @deprecated
+ */
const registerIconBundle = async (collectionName, bundleData) => {
- let resolveFn;
- const collectionFetched = new Promise(resolve => {
- resolveFn = resolve;
- });
- registerCollectionPromise(collectionName, collectionFetched);
+ throw new Error("This method has been removed. Use `registerIconLoader` instead.");
+};
- if (typeof bundleData !== "object") { // not inlined from build -> fetch it
- bundleData = await fetchJsonOnce(getEffectiveAssetPath(bundleData));
+const registerIconLoader = async (collectionName, loader) => {
+ loaders.set(collectionName, loader);
+};
+
+const _loadIconCollectionOnce = async collectionName => {
+ if (!iconCollectionPromises.has(collectionName)) {
+ const loadIcons = loaders.get(collectionName);
+ iconCollectionPromises.set(collectionName, loadIcons(collectionName));
}
- fillRegistry(bundleData);
- resolveFn();
+
+ return iconCollectionPromises.get(collectionName);
};
-const fillRegistry = bundleData => {
+const _fillRegistry = bundleData => {
Object.keys(bundleData.data).forEach(iconName => {
const iconData = bundleData.data[iconName];
@@ -29,4 +40,73 @@ const fillRegistry = bundleData => {
});
};
-export { registerIconBundle }; // eslint-disable-line
+// set
+const registerIcon = (name, { pathData, ltr, accData, collection } = {}) => { // eslint-disable-line
+ if (!collection) {
+ collection = DEFAULT_COLLECTION;
+ }
+
+ const key = `${collection}/${name}`;
+ registry.set(key, { pathData, ltr, accData });
+};
+
+const _parseName = name => {
+ // silently support ui5-compatible URIs
+ if (name.startsWith("sap-icon://")) {
+ name = name.replace("sap-icon://", "");
+ }
+
+ let collection;
+ [name, collection] = name.split("/").reverse();
+ collection = collection || DEFAULT_COLLECTION;
+ // hardcoded alias in case icon explorer is used, resolve `SAP-icons-TNT` to `tnt`
+ // aliases can be made a feature in the future if more collections need it or more aliases are needed.
+ if (collection === "SAP-icons-TNT") {
+ collection = "tnt";
+ }
+ const registryKey = `${collection}/${name}`;
+ return { name, collection, registryKey };
+};
+
+const getIconDataSync = nameProp => {
+ const { registryKey } = _parseName(nameProp);
+ return registry.get(registryKey);
+};
+
+const getIconData = async nameProp => {
+ const { collection, registryKey } = _parseName(nameProp);
+
+ let iconData = ICON_NOT_FOUND;
+ try {
+ iconData = await _loadIconCollectionOnce(collection);
+ } catch (e) {
+ console.error(e.message); /* eslint-disable-line */
+ }
+
+ if (iconData === ICON_NOT_FOUND) {
+ return iconData;
+ }
+
+ if (!registry.has(registryKey)) {
+ // not filled by another await. many getters will await on the same loader, but fill only once
+ _fillRegistry(iconData);
+ }
+ return registry.get(registryKey);
+};
+
+// test page usage only
+const _getRegisteredNames = async () => {
+ // fetch one icon of each collection to trigger the bundle load
+ await getIconData("edit");
+ await getIconData("tnt/arrow");
+ return Array.from(registry.keys());
+};
+
+export {
+ registerIconBundle,
+ registerIconLoader,
+ getIconData,
+ getIconDataSync,
+ registerIcon,
+ _getRegisteredNames,
+};
diff --git a/packages/base/src/asset-registries/LocaleData.js b/packages/base/src/asset-registries/LocaleData.js
index 78821d5a9467..22c048b1a288 100644
--- a/packages/base/src/asset-registries/LocaleData.js
+++ b/packages/base/src/asset-registries/LocaleData.js
@@ -1,17 +1,12 @@
-import { fetchJsonOnce } from "../util/FetchHelper.js";
import { attachLanguageChange } from "../locale/languageChange.js";
import getLocale from "../locale/getLocale.js";
-import { getFeature } from "../FeaturesRegistry.js";
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from "../generated/AssetParameters.js";
-import { getEffectiveAssetPath } from "../util/EffectiveAssetPath.js";
-
-const resources = new Map();
-const cldrData = {};
-const cldrUrls = {};
+import { getFeature } from "../FeaturesRegistry.js";
-// externally configurable mapping function for resolving (localeId -> URL)
-// default implementation - ui5 CDN
-let cldrMappingFn = locale => `https://ui5.sap.com/1.60.2/resources/sap/ui/core/cldr/${locale}.json`;
+const localeDataMap = new Map();
+const loaders = new Map();
+const cldrPromises = new Map();
+const reportedErrors = new Set();
const M_ISO639_OLD_TO_NEW = {
"iw": "he",
@@ -50,73 +45,67 @@ const calcLocale = (language, region, script) => {
return localeId;
};
+// internal set data
+const setLocaleData = (localeId, content) => {
+ localeDataMap.set(localeId, content);
+};
-const resolveMissingMappings = () => {
- if (!cldrMappingFn) {
- return;
+// external getSync
+const getLocaleData = localeId => {
+ const content = localeDataMap.get(localeId);
+ if (!content) {
+ throw new Error(`CLDR data for locale ${localeId} is not loaded!`);
}
- const missingLocales = SUPPORTED_LOCALES.filter(locale => !cldrData[locale] && !cldrUrls[locale]);
- missingLocales.forEach(locale => {
- cldrUrls[locale] = cldrMappingFn(locale);
- });
+ return content;
};
-const registerModuleContent = (moduleName, content) => {
- resources.set(moduleName, content);
-};
-
-const getModuleContent = moduleName => {
- const moduleContent = resources.get(moduleName);
- if (moduleContent) {
- return moduleContent;
- }
+// load bundle over the network once
+const _loadCldrOnce = localeId => {
+ const loadCldr = loaders.get(localeId);
- const missingModule = moduleName.match(/sap\/ui\/core\/cldr\/(\w+)\.json/);
- if (missingModule) {
- throw new Error(`CLDR data for locale ${missingModule[1]} is not loaded!`);
+ if (!cldrPromises.get(localeId)) {
+ cldrPromises.set(localeId, loadCldr(localeId));
}
- throw new Error(`Unknown module ${moduleName}`);
+ return cldrPromises.get(localeId);
};
+// external getAsync
const fetchCldr = async (language, region, script) => {
- resolveMissingMappings();
const localeId = calcLocale(language, region, script);
- let cldrObj = cldrData[localeId];
- const url = cldrUrls[localeId];
-
+ // reuse OpenUI5 CLDR if present
const OpenUI5Support = getFeature("OpenUI5Support");
- if (!cldrObj && OpenUI5Support) {
- cldrObj = OpenUI5Support.getLocaleDataObject();
+ if (OpenUI5Support) {
+ const cldrContent = OpenUI5Support.getLocaleDataObject();
+ if (cldrContent) {
+ // only if openui5 actually returned valid content
+ setLocaleData(localeId, cldrContent);
+ return;
+ }
}
- if (cldrObj) {
- // inlined from build or fetched independently
- registerModuleContent(`sap/ui/core/cldr/${localeId}.json`, cldrObj);
- } else if (url) {
- // fetch it
- const cldrContent = await fetchJsonOnce(getEffectiveAssetPath(url));
- registerModuleContent(`sap/ui/core/cldr/${localeId}.json`, cldrContent);
+ // fetch it
+ try {
+ const cldrContent = await _loadCldrOnce(localeId);
+ setLocaleData(localeId, cldrContent);
+ } catch (e) {
+ if (!reportedErrors.has(e.message)) {
+ reportedErrors.add(e.message);
+ console.error(e.message); /* eslint-disable-line */
+ }
}
};
-const registerCldr = (locale, url) => {
- cldrUrls[locale] = url;
-};
-
-const setCldrData = (locale, data) => {
- cldrData[locale] = data;
+const registerLocaleDataLoader = (localeId, loader) => {
+ loaders.set(localeId, loader);
};
-const getCldrData = locale => {
- return cldrData[locale];
-};
-
-const _registerMappingFunction = mappingFn => {
- cldrMappingFn = mappingFn;
-};
+// register default loader for "en" from ui5 CDN (dev workflow without assets)
+registerLocaleDataLoader("en", async runtimeLocaleId => {
+ return (await fetch(`https://ui5.sap.com/1.60.2/resources/sap/ui/core/cldr/en.json`)).json();
+});
// When the language changes dynamically (the user calls setLanguage),
// re-fetch the required CDRD data.
@@ -126,10 +115,7 @@ attachLanguageChange(() => {
});
export {
+ registerLocaleDataLoader,
fetchCldr,
- registerCldr,
- setCldrData,
- getCldrData,
- getModuleContent,
- _registerMappingFunction,
+ getLocaleData,
};
diff --git a/packages/base/src/asset-registries/Themes.js b/packages/base/src/asset-registries/Themes.js
index 81754ab3049f..39f833f7201a 100644
--- a/packages/base/src/asset-registries/Themes.js
+++ b/packages/base/src/asset-registries/Themes.js
@@ -1,10 +1,7 @@
-import { fetchJsonOnce, fetchTextOnce } from "../util/FetchHelper.js";
import { DEFAULT_THEME } from "../generated/AssetParameters.js";
-import getFileExtension from "../util/getFileExtension.js";
-import { getEffectiveAssetPath } from "../util/EffectiveAssetPath.js";
-const themeURLs = new Map();
const themeStyles = new Map();
+const loaders = new Map();
const registeredPackages = new Set();
const registeredThemes = new Set();
@@ -16,29 +13,19 @@ const registeredThemes = new Set();
* Example usage:
* 1) Pass the CSS Vars as a string directly.
* registerThemeProperties("my-package", "my_theme", ":root{--var1: red;}");
- * 2) Pass the CSS Vars as an object directly
- * registerThemeProperties("my-package", "my_theme", {"_": ":root{--var1: red;}"});
- * 3) Pass a URL to a CSS file, containing the CSS Vars. Will be fetched on demand, not upon registration.
- * registerThemeProperties("my-package", "my_theme", "http://url/to/my/theme.css");
- * 4) Pass a URL to a JSON file, containing the CSS Vars in its "_" property. Will be fetched on demand, not upon registration.
- * registerThemeProperties("my-package", "my_theme", "http://url/to/my/theme.json");
*
* @public
* @param packageName - the NPM package for which CSS Vars are registered
* @param themeName - the theme which the CSS Vars implement
- * @param style - can be one of four options: a string, an object with a "_" property, URL to a CSS file, or URL to a JSON file with a "_" property
+ * @param style - the style content directly
+ * @deprecated
*/
-const registerThemeProperties = (packageName, themeName, style) => {
- if (style._) {
- // JSON object like ({"_": ":root"})
- themeStyles.set(`${packageName}_${themeName}`, style._);
- } else if (style.includes(":root") || style === "") {
- // pure string, including empty string
- themeStyles.set(`${packageName}_${themeName}`, style);
- } else {
- // url for fetching
- themeURLs.set(`${packageName}_${themeName}`, style);
- }
+const registerThemeProperties = (_packageName, _themeName, _style) => {
+ throw new Error("`registerThemeProperties` has been depracated. Use `registerThemePropertiesLoader` instead.");
+};
+
+const registerThemePropertiesLoader = (packageName, themeName, loader) => {
+ loaders.set(`${packageName}/${themeName}`, loader);
registeredPackages.add(packageName);
registeredThemes.add(themeName);
};
@@ -55,23 +42,25 @@ const getThemeProperties = async (packageName, themeName) => {
return themeStyles.get(`${packageName}_${DEFAULT_THEME}`);
}
- const data = await fetchThemeProperties(packageName, themeName);
+ const loader = loaders.get(`${packageName}/${themeName}`);
+ if (!loader) {
+ // no themes for package
+ console.error(`Theme [${themeName}] not registered for package [${pacakgeName}]`); /* eslint-disable-line */
+ return;
+ }
+ let data;
+ try {
+ data = await loader(themeName);
+ } catch (e) {
+ console.error(packageName, e.message); /* eslint-disable-line */
+ return;
+ }
const themeProps = data._ || data;
themeStyles.set(`${packageName}_${themeName}`, themeProps);
return themeProps;
};
-const fetchThemeProperties = async (packageName, themeName) => {
- const url = themeURLs.get(`${packageName}_${themeName}`);
-
- if (!url) {
- throw new Error(`You have to import the ${packageName}/dist/Assets.js module to switch to additional themes`);
- }
-
- return getFileExtension(url) === ".css" ? fetchTextOnce(url) : fetchJsonOnce(getEffectiveAssetPath(url));
-};
-
const getRegisteredPackages = () => {
return registeredPackages;
};
@@ -81,6 +70,7 @@ const isThemeRegistered = theme => {
};
export {
+ registerThemePropertiesLoader,
registerThemeProperties,
getThemeProperties,
getRegisteredPackages,
diff --git a/packages/base/src/asset-registries/i18n.js b/packages/base/src/asset-registries/i18n.js
index aa2d7c6d05df..3a49ca908227 100644
--- a/packages/base/src/asset-registries/i18n.js
+++ b/packages/base/src/asset-registries/i18n.js
@@ -1,23 +1,31 @@
-import { getFeature } from "../FeaturesRegistry.js";
import getLocale from "../locale/getLocale.js";
import { attachLanguageChange } from "../locale/languageChange.js";
-import { fetchTextOnce } from "../util/FetchHelper.js";
import normalizeLocale from "../locale/normalizeLocale.js";
import nextFallbackLocale from "../locale/nextFallbackLocale.js";
import { DEFAULT_LANGUAGE } from "../generated/AssetParameters.js";
-import { getEffectiveAssetPath } from "../util/EffectiveAssetPath.js";
import { getUseDefaultLanguage } from "../config/Language.js";
+// contains package names for which the warning has been shown
+const warningShown = new Set();
+const reportedErrors = new Set();
+
const bundleData = new Map();
-const bundleURLs = new Map();
+const bundlePromises = new Map();
+const loaders = new Map();
/**
- * Sets a map with texts and ID the are related to.
- * @param {string} packageName package ID that the i18n bundle will be related to
- * @param {Object} data an object with string locales as keys and text translataions as values
- * @public
+ *
+ * @param {string} packageName for which package this loader can fetch data
+ * @param {function} loader async function that will be passed a localeId and should return a JSON object
+ * @param {Array} localeIds Array of locale IDs that this loader can handle
*/
-const setI18nBundleData = (packageName, data) => {
+const registerI18nLoader = (packageName, localeId, loader) => {
+ // register loader by key
+ const bundleKey = `${packageName}/${localeId}`;
+ loaders.set(bundleKey, loader);
+};
+
+const _setI18nBundleData = (packageName, data) => {
bundleData.set(packageName, data);
};
@@ -26,18 +34,36 @@ const getI18nBundleData = packageName => {
};
/**
- * Registers a map of locale/url information, to be used by the fetchI18nBundle
method.
- * Note: In order to be able to register ".properties" files, you must import the following module:
- * import "@ui5/webcomponents-base/dist/features/PropertiesFormatSupport.js";
- *
- * @param {string} packageName package ID that the i18n bundle will be related to
- * @param {Object} bundle an object with string locales as keys and the URLs (in .json or .properties format - see the note above) where the corresponding locale can be fetched from, f.e {"en": "path/en.json", ...}
- *
* @public
+ * @deprecated
*/
-const registerI18nBundle = (packageName, bundle) => {
- const oldBundle = bundleURLs.get(packageName) || {};
- bundleURLs.set(packageName, Object.assign({}, oldBundle, bundle));
+const registerI18nBundle = (_packageName, _bundle) => {
+ throw new Error("This method has been removed. Use `registerI18nLoader` instead.");
+};
+
+const _hasLoader = (packageName, localeId) => {
+ const bundleKey = `${packageName}/${localeId}`;
+ return loaders.has(bundleKey);
+};
+
+// load bundle over the network once
+const _loadMessageBundleOnce = (packageName, localeId) => {
+ const bundleKey = `${packageName}/${localeId}`;
+ const loadMessageBundle = loaders.get(bundleKey);
+
+ if (!bundlePromises.get(bundleKey)) {
+ bundlePromises.set(bundleKey, loadMessageBundle(localeId));
+ }
+
+ return bundlePromises.get(bundleKey);
+};
+
+const _showAssetsWarningOnce = packageName => {
+ if (!warningShown.has(packageName)) {
+ console.warn(`[${packageName}]: Message bundle assets are not configured. Falling back to English texts.`, /* eslint-disable-line */
+ ` Add \`import "${packageName}/dist/Assets.js"\` in your bundle and make sure your build tool supports dynamic imports and JSON imports. See section "Assets" in the documentation for more information.`); /* eslint-disable-line */
+ warningShown.add(packageName);
+ }
};
/**
@@ -50,50 +76,34 @@ const registerI18nBundle = (packageName, bundle) => {
* @public
*/
const fetchI18nBundle = async packageName => {
- const bundlesForPackage = bundleURLs.get(packageName);
-
- if (!bundlesForPackage) {
- console.warn(`Message bundle assets are not configured. Falling back to English texts.`, /* eslint-disable-line */
- ` You need to import ${packageName}/dist/Assets.js with a build tool that supports JSON imports.`); /* eslint-disable-line */
- return;
- }
-
const language = getLocale().getLanguage();
const region = getLocale().getRegion();
- const useDefaultLanguage = getUseDefaultLanguage();
let localeId = normalizeLocale(language + (region ? `-${region}` : ``));
- while (localeId !== DEFAULT_LANGUAGE && !bundlesForPackage[localeId]) {
+ while (localeId !== DEFAULT_LANGUAGE && !_hasLoader(packageName, localeId)) {
localeId = nextFallbackLocale(localeId);
}
- if (useDefaultLanguage && localeId === DEFAULT_LANGUAGE) {
- setI18nBundleData(packageName, null); // reset for the default language (if data was set for a previous language)
+ if (!_hasLoader(packageName, localeId)) {
+ _showAssetsWarningOnce(packageName);
return;
}
- const bundleURL = bundlesForPackage[localeId];
-
- if (typeof bundleURL === "object") { // inlined from build
- setI18nBundleData(packageName, bundleURL);
+ const useDefaultLanguage = getUseDefaultLanguage();
+ if (useDefaultLanguage && localeId === DEFAULT_LANGUAGE) {
+ _setI18nBundleData(packageName, null); // reset for the default language (if data was set for a previous language)
return;
}
- const content = await fetchTextOnce(getEffectiveAssetPath(bundleURL));
- let parser;
- if (content.startsWith("{")) {
- parser = JSON.parse;
- } else {
- const PropertiesFormatSupport = getFeature("PropertiesFormatSupport");
- if (!PropertiesFormatSupport) {
- throw new Error(`In order to support .properties files, please: import "@ui5/webcomponents-base/dist/features/PropertiesFormatSupport.js";`);
+ try {
+ const data = await _loadMessageBundleOnce(packageName, localeId);
+ _setI18nBundleData(packageName, data);
+ } catch (e) {
+ if (!reportedErrors.has(e.message)) {
+ reportedErrors.add(e.message);
+ console.error(e.message); /* eslint-disable-line */
}
- parser = PropertiesFormatSupport.parser;
}
-
- const data = parser(content);
-
- setI18nBundleData(packageName, data);
};
// When the language changes dynamically (the user calls setLanguage), re-fetch all previously fetched bundles
@@ -103,8 +113,8 @@ attachLanguageChange(() => {
});
export {
+ registerI18nLoader,
fetchI18nBundle,
registerI18nBundle,
- setI18nBundleData,
getI18nBundleData,
};
diff --git a/packages/base/src/features/PropertiesFormatSupport.js b/packages/base/src/features/PropertiesFormatSupport.js
deleted file mode 100644
index 080e59bbb9ce..000000000000
--- a/packages/base/src/features/PropertiesFormatSupport.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { registerFeature } from "../FeaturesRegistry.js";
-import parseProperties from "../util/parseProperties.js";
-
-const PropertiesFormatSupport = {
- parser: parseProperties,
-};
-
-registerFeature("PropertiesFormatSupport", PropertiesFormatSupport);
diff --git a/packages/base/src/i18nBundle.js b/packages/base/src/i18nBundle.js
index a05308b328f0..0dc6df93ad3e 100644
--- a/packages/base/src/i18nBundle.js
+++ b/packages/base/src/i18nBundle.js
@@ -1,4 +1,4 @@
-import { registerI18nBundle, fetchI18nBundle, getI18nBundleData } from "./asset-registries/i18n.js";
+import { registerI18nLoader, fetchI18nBundle, getI18nBundleData } from "./asset-registries/i18n.js";
import formatMessage from "./util/formatMessage.js";
const I18nBundleInstances = new Map();
@@ -46,7 +46,7 @@ const getI18nBundle = packageName => {
};
export {
- registerI18nBundle,
+ registerI18nLoader,
fetchI18nBundle,
getI18nBundle,
};
diff --git a/packages/base/src/util/EffectiveAssetPath.js b/packages/base/src/util/EffectiveAssetPath.js
deleted file mode 100644
index fa8bdfd39c31..000000000000
--- a/packages/base/src/util/EffectiveAssetPath.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { getAssetsPath } from "../config/AssetsPath.js";
-
-let assetPathMappingFn = assetName => assetName;
-
-const getEffectiveAssetPath = assetName => {
- if (typeof assetName !== "string") {
- return assetName;
- }
-
- assetName = assetPathMappingFn(assetName);
-
- const assetsPathPrefix = getAssetsPath();
- if (assetsPathPrefix) {
- return `${assetsPathPrefix}${assetName}`;
- }
-
- return assetName;
-};
-
-const registerAssetPathMappingFunction = mappingFn => {
- assetPathMappingFn = mappingFn;
-};
-
-export {
- getEffectiveAssetPath,
- registerAssetPathMappingFunction,
-};
diff --git a/packages/base/test/assets/Themes.js b/packages/base/test/assets/Themes.js
index 4f9b213e8fe5..b3d48a25da49 100644
--- a/packages/base/test/assets/Themes.js
+++ b/packages/base/test/assets/Themes.js
@@ -1,4 +1,4 @@
-import { registerThemeProperties } from "../../asset-registries/Themes.js";
+import { registerThemePropertiesLoader } from "../../asset-registries/Themes.js";
const fiori3 = `:root{ --var1: red; }`;
const fiori3Dark = `:root{ --var1: green; }`;
@@ -8,10 +8,10 @@ const belizeHcw = `:root{ --var1: orange; }`;
const fiori3Hcb = `:root{ --var1: yellow; }`;
const fiori3Hcw = `:root{ --var1: yellow; }`;
-registerThemeProperties("@ui5/webcomponents-base-test", "sap_fiori_3", fiori3);
-registerThemeProperties("@ui5/webcomponents-base-test", "sap_fiori_3_dark", fiori3Dark);
-registerThemeProperties("@ui5/webcomponents-base-test", "sap_belize", belize);
-registerThemeProperties("@ui5/webcomponents-base-test", "sap_belize_hcb", belizeHcb);
-registerThemeProperties("@ui5/webcomponents-base-test", "sap_belize_hcw", belizeHcw);
-registerThemeProperties("@ui5/webcomponents-base-test", "sap_fiori_3_hcb", fiori3Hcb);
-registerThemeProperties("@ui5/webcomponents-base-test", "sap_fiori_3_hcw", fiori3Hcw);
+registerThemePropertiesLoader("@ui5/webcomponents-base-test", "sap_fiori_3", () => fiori3);
+registerThemePropertiesLoader("@ui5/webcomponents-base-test", "sap_fiori_3_dark", () => fiori3Dark);
+registerThemePropertiesLoader("@ui5/webcomponents-base-test", "sap_belize", () => belize);
+registerThemePropertiesLoader("@ui5/webcomponents-base-test", "sap_belize_hcb", () => belizeHcb);
+registerThemePropertiesLoader("@ui5/webcomponents-base-test", "sap_belize_hcw", () => belizeHcw);
+registerThemePropertiesLoader("@ui5/webcomponents-base-test", "sap_fiori_3_hcb", () => fiori3Hcb);
+registerThemePropertiesLoader("@ui5/webcomponents-base-test", "sap_fiori_3_hcw", () => fiori3Hcw);
diff --git a/packages/base/test/pages/i18n.html b/packages/base/test/pages/i18n.html
index 683291466499..237760490a64 100644
--- a/packages/base/test/pages/i18n.html
+++ b/packages/base/test/pages/i18n.html
@@ -15,12 +15,7 @@