Skip to content

Commit

Permalink
feat(framework): add configuration to prevent font loading (#9483)
Browse files Browse the repository at this point in the history
Previously, default fonts could be prevented from loading using a `<style>` tag with the `data-ui5-font-face` attribute. However, recent changes have standardized style additions using adopted stylesheets, which are widely supported by major browsers. This eliminates the need to check for the existence of style elements for validation purposes. Additionally, frameworks like Nuxt.js have raised concerns about empty attributes in these style elements, making the previous solution less optimal.

To address this, we have introduced the `defaultFontLoading` configuration option. This provides a more straightforward approach for users who wish to prevent the default font faces from loading and manage this process themselves.

Example usage:

```html
<script data-ui5-config type="application/json">
{
    "defaultFontLoading": false
}
</script>
```

Setting `"defaultFontLoading": false` will prevent the default font faces from being automatically loaded, allowing users to handle font loading according to their specific requirements.

Fixes: #8991
  • Loading branch information
nnaydenow authored Jul 23, 2024
1 parent 8b937a0 commit d188638
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 44 deletions.
25 changes: 24 additions & 1 deletion docs/2-advanced/01-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ There are several configuration settings that affect all UI5 Web Components glob
| [noConflict](#noConflict) | `true`, `false` | `false` | When set to true, all events will be fired with a `ui5-` prefix only | Components that fire events (most do) |
| [formatSettings](#formatSettings) | See the [Format settings](#formatSettings) section below | `{}` | Allows to override locale-specific configuration | Date/time components (`ui5-date-picker`, etc.) |
| [fetchDefaultLanguage](#fetchDefaultLanguage) | `true`, `false` | `false` | Whether to fetch assets even for the default language | Framework |
| [defaultFontLoading](#defaultFontLoading) | `true`, `false` | `true` | Whether to fetch default font faces | Framework |
| [timezone](#timezone) | `Asia/Tokyo`, `Pacific/Apia`, `Asia/Kolkata`, `Europe/Sofia` and etc. | Your local time zone. | Allows to override your local time zone. | Date/time components (`ui5-date-picker`, etc.) |
| [themeRoot](#themeRoot) | String to a URL - see the [themeRoot](#themeRoot) section below | N/A | Allows to set a URL to a Theme-designer-created custom theme. | All components |

Expand Down Expand Up @@ -217,6 +218,21 @@ Example:
}
</script>
```
### defaultFontLoading
<a name="defaultFontLoading"></a>

This configuration option controls whether default font faces are fetched over the network.

Typically, you would not need to modify this setting. However, if for technical reasons you prefer the default font faces to not be fetched over the network, you can set `defaultFontLoading` to `false`.

Example:
```html
<script data-ui5-config type="application/json">
{
"defaultFontLoading": false
}
</script>
```
### timezone
<a name="timezone"></a>

Expand Down Expand Up @@ -273,7 +289,8 @@ Example:
"events": ["selection-change", "header-click"]
},
"fetchDefaultLanguage": true,
"timezone": "Europe/Sofia"
"timezone": "Europe/Sofia",
defaultFontLoading
}
</script>
```
Expand Down Expand Up @@ -325,6 +342,12 @@ import { getFirstDayOfWeek } from "@ui5/webcomponents-base/dist/config/FormatSet

```js
import { getFetchDefaultLanguage, setFetchDefaultLanguage } from "@ui5/webcomponents-base/dist/config/Language.js";
```

- `defaultFontLoading`

```js
import { getDefaultFontLoading, setDefaultFontLoading } from "@ui5/webcomponents-base/dist/config/Fonts.js";
```
- `timezone` - can only be set initially in the configuration script.

Expand Down
66 changes: 25 additions & 41 deletions docs/2-advanced/14-fonts.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,38 @@
# Custom Fonts

## The data-ui5-font-face style tag
During boot, the UI5 Web Components framework loads the necessary fonts to achieve the desired design of its components.

Upon `boot`, the UI5 Web Components framework creates a `<style data-ui5-font-face>` tag in the `<head>` in order to load the necessary fonts.

For example:

```html
<style type="text/css" data-ui5-font-face="">
@font-face {
font-family: "72";
font-style: normal;
font-weight: 400;
src: local("72"),
url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular.woff2?ui5-webcomponents) format("woff2");
}
................
</style>
```
**Important:** Notice the `data-ui5-font-face` attribute. It is unique and recognized by UI5 Web Components.
**Important:** These fonts are fetched via network requests.

## Customizing Fonts

You might need to customize fonts for several reasons:
- To provide different paths for the fonts (e.g. no public internet connection on the server).
- To provide additional declarations inside `@font-face`.
- To download additional fonts, such as e.g. `72-Light`.
- Not to download any of the default fonts.
There are several reasons why you might need to customize fonts:
- To specify different paths for fonts (e.g., due to restrictions on public internet access).
- To include additional declarations within `@font-face`.
- To download additional fonts, such as `72-Light`.
- To prevent the default fonts from being fetched.

To achieve this, you can prevent the fetching of default fonts by configuring `setDefaultFontLoading (@ui5/webcomponents-base/dist/config/Fonts.js)` to `false`:

To do that, just create a `<style type="text/css" data-ui5-font-face="">` tag in the `head` of your HTML page and
provide arbitrary content for it.
```ts
import { getDefaultFontLoading, setDefaultFontLoading } from "@ui5/webcomponents-base/dist/config/Fonts.js";

Then, when the UI5 Web Components framework boots, it will detect the existence of this tag by the `data-ui5-font-face`
attribute, and will not create it. The one you provided will be used instead.
setDefaultFontLoading(false);
```

## Example
Then, specify the custom font you intend to use. When the UI5 Web Components framework initializes, it will refrain from fetching default fonts and instead use the ones you have provided.

In order to use the `72-Light` font in your app and have an additional setting (`font-display`), you could add the following markup in the `<head>` of your HTML page:
To use the `72-Light` font in your application and specify the `font-display` setting, you should define the font in your application's styles.

```html
<style type="text/css" data-ui5-font-face="">
@font-face {
font-family: "72";
font-style: normal;
font-weight: 200;
font-display: swap;
src: local("72-Light"),
url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light.woff2?ui5-webcomponents) format("woff2");
}
</style>
<style type="text/css">
@font-face {
font-family: "72";
font-style: normal;
font-weight: 200;
font-display: swap;
src: local("72-Light"),
url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light.woff2?ui5-webcomponents) format("woff2");
}
</style>
```
2 changes: 2 additions & 0 deletions packages/base/bundle.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { getAnimationMode } from "./dist/config/AnimationMode.js";
import { getLanguage, setLanguage } from "./dist/config/Language.js";
import { getCalendarType } from "./dist/config/CalendarType.js";
import { getTheme, setTheme } from "./dist/config/Theme.js";
import { getDefaultFontLoading } from "./dist/config/Fonts.js";
import { getThemeRoot, setThemeRoot } from "./dist/config/ThemeRoot.js";
import { getNoConflict, setNoConflict } from "./dist/config/NoConflict.js";
import { getFirstDayOfWeek, getLegacyDateCalendarCustomizing } from "./dist/config/FormatSettings.js";
Expand All @@ -53,6 +54,7 @@ window["sap-ui-webcomponents-bundle"] = {
getCalendarType,
getFirstDayOfWeek,
getLegacyDateCalendarCustomizing,
getDefaultFontLoading,
},
getCurrentRuntimeIndex,
getIconNames,
Expand Down
9 changes: 8 additions & 1 deletion packages/base/src/FontFace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { getFeature } from "./FeaturesRegistry.js";
import fontFaceCSS from "./generated/css/FontFace.css.js";
import overrideFontFaceCSS from "./generated/css/OverrideFontFace.css.js";
import type OpenUI5Support from "./features/OpenUI5Support.js";
import { getDefaultFontLoading } from "./config/Fonts.js";

const insertFontFace = () => {
const openUI5Support = getFeature<typeof OpenUI5Support>("OpenUI5Support");

// Only set the main font if there is no OpenUI5 support, or there is, but OpenUI5 is not loaded
if (!openUI5Support || !openUI5Support.isOpenUI5Detected()) {
if ((!openUI5Support || !openUI5Support.isOpenUI5Detected())) {
insertMainFontFace();
}

Expand All @@ -17,6 +18,12 @@ const insertFontFace = () => {
};

const insertMainFontFace = () => {
const hasFontStyles = document.querySelector("head>style[data-ui5-font-face]");

if (!getDefaultFontLoading() || hasFontStyles) {
return;
}

if (!hasStyle("data-ui5-font-face")) {
createStyle(fontFaceCSS, "data-ui5-font-face");
}
Expand Down
8 changes: 8 additions & 0 deletions packages/base/src/InitialConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type InitialConfig = {
noConflict: boolean,
formatSettings: FormatSettings,
fetchDefaultLanguage: boolean,
defaultFontLoading: boolean,
};

let initialConfig: InitialConfig = {
Expand All @@ -35,6 +36,7 @@ let initialConfig: InitialConfig = {
noConflict: false, // no URL
formatSettings: {},
fetchDefaultLanguage: false,
defaultFontLoading: true,
};

/* General settings */
Expand Down Expand Up @@ -73,6 +75,11 @@ const getNoConflict = () => {
return initialConfig.noConflict;
};

const getDefaultFontLoading = () => {
initConfiguration();
return initialConfig.defaultFontLoading;
};

/**
* Get the configured calendar type
* @returns { String } the name of the configured calendar type
Expand Down Expand Up @@ -217,4 +224,5 @@ export {
getSecondaryCalendarType,
getTimezone,
getFormatSettings,
getDefaultFontLoading,
};
33 changes: 33 additions & 0 deletions packages/base/src/config/Fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { getDefaultFontLoading as getConfiguredDefaultFontLoading } from "../InitialConfiguration.js";

let defaultFontLoading: boolean;

/**
* Returns if the "defaultFontLoading" configuration is set.
* @public
* @returns { boolean }
*/
const getDefaultFontLoading = (): boolean => {
if (defaultFontLoading === undefined) {
defaultFontLoading = getConfiguredDefaultFontLoading();
}

return defaultFontLoading;
};

/**
* Defines the "defaultFontLoading" setting.
*
* - When set to "true" (default), all used font faces are fetched over the network.
* - When set to "false", default font faces are not fetched automatically and must be managed separately.
* @public
* @param { boolean } defaultFontLoadingData
*/
const setDefaultFontLoading = (defaultFontLoadingData: boolean) => {
defaultFontLoading = defaultFontLoadingData;
};

export {
getDefaultFontLoading,
setDefaultFontLoading,
};
3 changes: 2 additions & 1 deletion packages/base/test/pages/ConfigurationScript.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"theme": "sap_horizon_hcb",
"noConflict": {
"events": ["selection-change", "header-click"]
}
},
"defaultFontLoading": false
}
</script>

Expand Down
8 changes: 8 additions & 0 deletions packages/base/test/specs/ConfigurationScript.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,12 @@ describe("Configuration script has effect", () => {
});
assert.strictEqual(res, 'basic', "animationMode is basic");
});

it("Tests that defaultFontLoading is applied", async () => {
const res = await browser.executeAsync(done => {
const config = window['sap-ui-webcomponents-bundle'].configuration;
done(config.getDefaultFontLoading());
});
assert.strictEqual(res, false, "defaultFontLoading is false");
});
});

0 comments on commit d188638

Please sign in to comment.