Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions packages/base/src/Boot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getFeature } from "./FeaturesRegistry.js";
import type OpenUI5Support from "./features/OpenUI5Support.js";
import type F6Navigation from "./features/F6Navigation.js";
import { PromiseResolve } from "./types.js";
import { attachThemeRegistered } from "./theming/ThemeRegistered.js";

let booted = false;
let bootPromise: Promise<void>;
Expand Down Expand Up @@ -40,6 +41,8 @@ const boot = async (): Promise<void> => {
return;
}

attachThemeRegistered(onThemeRegistered);

registerCurrentRuntime();

const openUI5Support = getFeature<typeof OpenUI5Support>("OpenUI5Support");
Expand Down Expand Up @@ -70,6 +73,19 @@ const boot = async (): Promise<void> => {
return bootPromise;
};

/**
* Callback, executed after theme properties registration
* to apply the newly registered theme.
* @private
* @param { string } theme
*/
const onThemeRegistered = (theme: string) => {
const currentTheme = getTheme();
if (booted && theme === currentTheme) {
applyTheme(currentTheme);
}
};

export {
boot,
attachBoot,
Expand Down
2 changes: 2 additions & 0 deletions packages/base/src/asset-registries/Themes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DEFAULT_THEME } from "../generated/AssetParameters.js";
import { StyleData, StyleDataCSP } from "../types.js";
import { fireThemeRegistered } from "../theming/ThemeRegistered.js";

type ThemeData = {_: StyleDataCSP } | StyleDataCSP | string;
type ThemeLoader = (themeName: string) => Promise<ThemeData>;
Expand All @@ -13,6 +14,7 @@ const registerThemePropertiesLoader = (packageName: string, themeName: string, l
loaders.set(`${packageName}/${themeName}`, loader);
registeredPackages.add(packageName);
registeredThemes.add(themeName);
fireThemeRegistered(themeName);
};

const getThemeProperties = async (packageName: string, themeName: string) => {
Expand Down
19 changes: 19 additions & 0 deletions packages/base/src/theming/ThemeRegistered.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import EventProvider from "../EventProvider.js";

type ThemeRegisteredCallback = (theme: string) => void;

const eventProvider = new EventProvider<string, void>();
const THEME_REGISTERED = "themeRegistered";

const attachThemeRegistered = (listener: ThemeRegisteredCallback) => {
eventProvider.attachEvent(THEME_REGISTERED, listener);
};

const fireThemeRegistered = (theme: string) => {
return eventProvider.fireEvent(THEME_REGISTERED, theme);
};

export {
attachThemeRegistered,
fireThemeRegistered,
};
26 changes: 7 additions & 19 deletions packages/base/test/assets/bundle.light.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,25 @@
import { attachBoot } from "../../dist/Boot.js";
import { boot } from "../../dist/Boot.js";
import { registerThemePropertiesLoader } from "../../dist/AssetRegistry.js";

// Call attachBoot early
// attachBoot (no longer triggers "boot")
attachBoot(() => {
console.log("Listener1: after framework booted!")
})

attachBoot(() => {
console.log("Listener2: after framework booted!")
})

attachBoot(() => {
console.log("Listener3: after framework booted!")
})
import { registerThemePropertiesLoader } from "../../dist/AssetRegistry.js";
// boot the framework
boot();

const testAssets = {
registerThemePropsAndBoot: () => {
// registerThemePropertiesLoader after boot (and after attachBoot ), will call applyTheme
registerThemeProps: async () => {
registerThemePropertiesLoader("@ui5/webcomponents-theming", "sap_fiori_3", () => {
return {
content: `:root{ --var1: red; }`,
content: `:root{ --customCol: #fff; --customBg: #000; }`,
packageName: "",
fileName: "",
};
});
// call "boot" multiple times as if multiple web components start upgrading
console.log("Booting...");
boot();
boot();
boot();
boot();
boot();
boot();
},
}
window["sap-ui-webcomponents-bundle"] = testAssets;
3 changes: 2 additions & 1 deletion packages/base/test/assets/styles/Boot.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.content {
color: var(--var1);
color: var(--customCol);
background-color: var(--customBg);
}
2 changes: 1 addition & 1 deletion packages/base/test/pages/Boot.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
</head>
<body>

<div class="content">When styles are applied, this text shoul be red.</div>
<div class="content">Register theme properties to style this text - window['sap-ui-webcomponents-bundle'].registerThemeProps()</div>
</body>
</html>
6 changes: 3 additions & 3 deletions packages/base/test/specs/Boot.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ describe("Framework boot", async () => {
await browser.url("test/pages/Boot.html");
});

it("Tests theme loading, when attachBoot is called before theme is registered", async () => {
it("Tests theme loading, when registered after 'attachBoot' and 'boot'", async () => {
await browser.executeAsync(done => {
window['sap-ui-webcomponents-bundle'].registerThemePropsAndBoot();
window['sap-ui-webcomponents-bundle'].registerThemeProps();
done();
});

const styleElement = await browser.executeAsync(done => {
return done(document.querySelector("head>style[data-ui5-theme-properties]"));
});

assert.ok(styleElement, "style[data-ui5-theme-properties] tag is successfully created");
assert.ok(styleElement, "style[data-ui5-theme-properties] tag is successfully created and theme applied.");
});
});