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 @@