Skip to content

feat: add dynamic imports for .json assets #2740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
1b3b3d4
create dynamic imports for i18n
pskelin Jan 22, 2021
0307939
remove asset registry mapping function
pskelin Jan 26, 2021
a2a2565
additional loaders can override specific locales that they handle
pskelin Jan 26, 2021
e892fdd
add .properties support, change registerLoader signature
pskelin Jan 28, 2021
571dfbf
remove icons package assets imports
pskelin Jan 28, 2021
c6a4c5b
improve warning readability
pskelin Jan 28, 2021
0190a21
fix locale ids for static assets
pskelin Jan 28, 2021
56c5850
lefovers
pskelin Jan 28, 2021
5f3e59f
add dynamic imports for icons
pskelin Jan 29, 2021
f191f93
add dynamic assets for fiori package
pskelin Jan 29, 2021
696691e
dynamic imports for theming
pskelin Jan 29, 2021
74682fd
switch locale data with static imports to loader API
pskelin Feb 1, 2021
08a5948
add dynamic imports for cldr
pskelin Feb 1, 2021
2e6d284
unify registerLoader APIs
pskelin Feb 2, 2021
941b572
new api for .properties example
pskelin Feb 4, 2021
14a195d
unify registerLoader APIs
pskelin Feb 4, 2021
2148207
switch module naming to dynamic default, static suffix
pskelin Feb 8, 2021
b3a36e7
remove theme load log from bundle
pskelin Feb 8, 2021
218192e
meaningful error when dynamic imports use URL plugin
pskelin Feb 8, 2021
b523052
meaningful dynamic import error messages
pskelin Feb 8, 2021
1cc4806
add default cldr loader with CDN fetch
pskelin Feb 9, 2021
fe2edc9
remove feature PropertiesFormatSupport
pskelin Feb 9, 2021
770b8a9
depracate registerIconBundle
pskelin Feb 9, 2021
8080846
Merge branch 'master' into wip-dynamic-assets
pskelin Feb 9, 2021
ff72058
return lint and fix errors
pskelin Feb 9, 2021
5da646b
remove EffectiveAssetPath
pskelin Feb 9, 2021
dbf7baf
fix cldr and i18n imports
pskelin Feb 9, 2021
afc17cc
fix url plugin generating empty bundle
pskelin Feb 9, 2021
3f7427c
make icons package i18n aware
pskelin Feb 9, 2021
36c2edd
fiori dynamic imports
pskelin Feb 9, 2021
bc35042
register english CLDR as default only
pskelin Feb 10, 2021
c957467
switch inline theme registration to async and deprecate sync
pskelin Feb 10, 2021
f5ce462
remove internal deprecated usage
pskelin Feb 10, 2021
3cc3cbf
remove async in function without await
pskelin Feb 10, 2021
7f3eb8f
use public imports for bundle
pskelin Feb 10, 2021
23d864b
remove deprecated method documentation pointing to removed modules
pskelin Feb 10, 2021
e80898e
add openui5 cldr reuse, simplify code
pskelin Feb 10, 2021
55f3eca
extract parseProperties util to public module
pskelin Feb 10, 2021
1c6bdfd
add missing return for i18n imports
pskelin Feb 11, 2021
e4acae3
remove named exports from JSON
pskelin Feb 11, 2021
fe0bba2
rework icon registry for lazy fetch
pskelin Feb 11, 2021
203ea17
Merge branch 'master' into wip-dynamic-assets
pskelin Feb 12, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions packages/base/bundle.esm.js
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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";
Expand All @@ -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,
Expand All @@ -48,7 +47,7 @@ window["sap-ui-webcomponents-bundle"] = {
getFirstDayOfWeek,
},
getIconNames,
registerI18nBundle,
registerI18nLoader,
fetchI18nBundle,
getI18nBundle,
renderFinished,
Expand Down
17 changes: 8 additions & 9 deletions packages/base/src/AssetRegistry.js
Original file line number Diff line number Diff line change
@@ -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";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registerIconLoader -> registerIconsLoader to be consistent with the rest (Data, Properties) which are plural


export {
registerCldr,
registerCldrMappingFunction,
registerThemeProperties,
registerI18nBundle,
registerAssetPathMappingFunction,
registerI18nLoader,
registerLocaleDataLoader,
registerThemePropertiesLoader,
registerIconLoader,
};
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
73 changes: 0 additions & 73 deletions packages/base/src/SVGIconRegistry.js

This file was deleted.

108 changes: 94 additions & 14 deletions packages/base/src/asset-registries/Icons.js
Original file line number Diff line number Diff line change
@@ -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];

Expand All @@ -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,
};
Loading