Skip to content

Commit

Permalink
refactor: make configuration initial only (#638)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Theming.js no longer has getTheme and setTheme methods. Use Configuration.js instead.
  • Loading branch information
vladitasev committed Jul 11, 2019
1 parent 9985634 commit 86ad25b
Show file tree
Hide file tree
Showing 103 changed files with 400 additions and 2,523 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ import "@ui5/webcomponents/dist/Label.js"; // loads ui5-label
## Configure
UI5 Web Components have built-in internationalization and globalization support. Language, compact/cozy switch, date/time settings and theme can be changed with parameters.

To provide configuration settings, create a ```script``` tag having ```data-id="sap-ui-config"``` and ```type="application/json"```:
To provide configuration settings, create a ```script``` tag having ```data-ui5-config``` and ```type="application/json"```:

```html
<script data-id="sap-ui-config" type="application/json">
<script data-ui5-config type="application/json">
{
"theme": "sap_belize",
"language": "EN"
Expand All @@ -101,7 +101,7 @@ To provide configuration settings, create a ```script``` tag having ```data-id="
UI5 Web Components support right-to-left text direction (RTL). To enable RTL globally, provide the option ```rtl: true``` in the configuration ```script``` tag:

```html
<script data-id="sap-ui-config" type="application/json">
<script data-ui5-config type="application/json">
{
"language": "en",
"rtl": true
Expand All @@ -113,7 +113,7 @@ UI5 Web Components support right-to-left text direction (RTL). To enable RTL glo
UI5 Web Components supports ```Compact``` and ```Cozy``` mode. It is set to ```Cozy``` by default. To enable ```Compact``` globally, provide the option ```compactSize: true``` in the configuration ```script``` tag:

```html
<script data-id="sap-ui-config" type="application/json">
<script data-ui5-config type="application/json">
{
"compactSize": true
}
Expand All @@ -124,7 +124,7 @@ UI5 Web Components supports ```Compact``` and ```Cozy``` mode. It is set to ```C
UI5 Web Components support different calendar types (Gregorian, Islamic, Japanese, Buddhist and Persian). To change them, provide the option ```calendarType: "Islamic"``` in the configuration ```script``` tag:

```html
<script data-id="sap-ui-config" type="application/json">
<script data-ui5-config type="application/json">
{
"calendarType": "Islamic"
}
Expand Down
35 changes: 32 additions & 3 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,51 @@ There are several configuration settings that affect all UI5 Web Components glob
------------ | ----------------------------------------------- | ------------- | -------------------------------------------------------------
theme | sap_fiori_3, sap_belize, sap_belize_hcb | sap_fiori_3 | Visual theme
language | en, de, es, etc... | en | Language to be used for translatable texts
rtl | true, false | false | When true, sets global text direction to right-to-left
rtl* | true, false | false | When true, sets global text direction to right-to-left
compactSize | true, false | false | When set, enforces compact density (smaller margins/paddings)
calendarType | Gregorian, Islamic, Buddhist, Japanese, Persian | Gregorian | Default calendar type for date-related web components
noConflict** | true, false | Object | false | When set to true, all events will be fired with a "ui5-" prefix only

`*` When the `rtl` setting is set to `true`, UI5 Web Components will adjust their styling accordingly.
However, you should also set the HTML attribute `dir` to `rtl` on the `body` or `html` or any other relevant region of your application
so that the rest of your application is also affected.

`**` By default UI5 Web Components fire all custom events twice - once with the documented name (f.e. `change`), and once more with a `ui5-` prefix (f.e. `ui5-change`).
For example, when the `ui5-switch` is toggled, it fires a `change` event, but also a `ui5-change` event.

The `noConflict` configuration setting allows certain control over this behavior:
- When `false` (default value) all custom events are fired with and without the `ui5-` prefix.
- When `true` all custom events are fired with the `ui5-` prefix **only**.
This is handy for example if the name of some event happens to collide with the name of an event provided by a third-party library.
- When an object is supplied, just the specified events will be fired with the `ui5-` prefix **only**.
All other events will be fired normally - once with the prefix, and once without.
The format of this object is as follows:
```json
{
"events": ["selectionChange", "headerClick"]
}
```
*Please note that other keys may be added to this object in the future for the purpose of name conflict resolution.*

In the above example, only the `selectionChange` and `headerClick` events will not be fired without a prefix.
You can still use them by listening to `ui5-selectionChange` and `ui5-headerClick`, but the names `selectionChange` and `headerClick` will be
free for use by other UI components and libraries without name collision.

## Configuration script

In order to provide configuration settings, include the following ```<script>``` element in your HTML page:

```html
<script data-id="sap-ui-config" type="application/json">
<script data-ui5-config type="application/json">
{
"rtl": true,
"compactSize": true,
"language": "ja",
"calendarType": "Japanese",
"theme": "sap_belize_hcb"
"theme": "sap_belize_hcb",
"noConflict": {
"events": ["selectionChange", "headerClick"]
}
}
</script>
```
Expand Down
4 changes: 2 additions & 2 deletions docs/PublicModuleImports.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ import "@ui5/webcomponents/dist/ThemePropertiesProvider.js";

and
```js
import { setTheme } from "@ui5/webcomponents-base/dist/Theming.js";
import { setTheme } from "@ui5/webcomponents-base/dist/Configuration.js";
```
(for changing the theme at runtime)

Expand Down Expand Up @@ -145,7 +145,7 @@ By importing the second module, you get the:
method that allows you to change the theme during runtime, if necessary.
Example:
```js
import { setTheme } from "@ui5/webcomponents-base/dist/Theming.js";
import { setTheme } from "@ui5/webcomponents-base/dist/Configuration.js";
setTheme("sap_belize_hcb");
```

Expand Down
2 changes: 1 addition & 1 deletion packages/base/src/CSS.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getTheme } from "./Configuration.js";
import { getEffectiveStyle } from "./Theming.js";
import { getTheme } from "./config/Theme.js";
import { injectWebComponentStyle } from "./theming/StyleInjection.js";

const styleMap = new Map();
Expand Down
152 changes: 12 additions & 140 deletions packages/base/src/Configuration.js
Original file line number Diff line number Diff line change
@@ -1,149 +1,21 @@
import CalendarType from "@ui5/webcomponents-core/dist/sap/ui/core/CalendarType.js";
import getDesigntimePropertyAsArray from "./util/getDesigntimePropertyAsArray.js";
import { getTheme, setTheme } from "./config/Theme.js";
import { getNoConflict, setNoConflict } from "./config/NoConflict.js";
import { getCompactSize } from "./config/CompactSize.js";
import { getRTL } from "./config/RTL.js";
import { getLanguage, getSupportedLanguages } from "./config/Language.js";
import { getCalendarType } from "./config/CalendarType.js";

let initialized = false;

const CONFIGURATION = {
theme: "sap_fiori_3",
rtl: null,
language: null,
compactSize: false,
supportedLanguages: null,
calendarType: null,
derivedRTL: null,
"xx-wc-no-conflict": false, // no URL
};

/* General settings */
const getTheme = () => {
initConfiguration();
return CONFIGURATION.theme;
};

const getRTL = () => {
initConfiguration();
return CONFIGURATION.rtl;
};

const getLanguage = () => {
initConfiguration();
return CONFIGURATION.language;
};

const getCompactSize = () => {
initConfiguration();
return CONFIGURATION.compactSize;
};

const getSupportedLanguages = () => {
return getDesigntimePropertyAsArray("$core-i18n-locales:,ar,bg,ca,cs,da,de,el,en,es,et,fi,fr,hi,hr,hu,it,iw,ja,ko,lt,lv,nl,no,pl,pt,ro,ru,sh,sk,sl,sv,th,tr,uk,vi,zh_CN,zh_TW$");
};

const getWCNoConflict = () => {
initConfiguration();
return CONFIGURATION["xx-wc-no-conflict"];
};

const _setWCNoConflict = value => {
CONFIGURATION["xx-wc-no-conflict"] = value;
};

/* Calendar stuff */
const getCalendarType = () => {
initConfiguration();
if (CONFIGURATION.calendarType) {
const type = Object.keys(CalendarType).filter(calType => calType === CONFIGURATION.calendarType)[0];

if (type) {
return type;
}
}

return CalendarType.Gregorian;
};

const getOriginInfo = () => {};

const getLocale = () => {
initConfiguration();
return CONFIGURATION.language;
};

const _setTheme = themeName => {
CONFIGURATION.theme = themeName;
};

const booleanMapping = new Map();
booleanMapping.set("true", true);
booleanMapping.set("false", false);

let runtimeConfig = {};

const parseConfigurationScript = () => {
const configScript = document.querySelector("[data-id='sap-ui-config']");
let configJSON;

if (configScript) {
try {
configJSON = JSON.parse(configScript.innerHTML);
} catch (е) {
console.warn("Incorrect data-sap-ui-config format. Please use JSON"); /* eslint-disable-line */
}

if (configJSON) {
runtimeConfig = Object.assign({}, configJSON);
}
}
};

const parseURLParameters = () => {
const params = new URLSearchParams(window.location.search);

params.forEach((value, key) => {
if (!key.startsWith("sap-ui")) {
return;
}

const lowerCaseValue = value.toLowerCase();

const param = key.split("sap-ui-")[1];

if (booleanMapping.has(value)) {
value = booleanMapping.get(lowerCaseValue);
}

runtimeConfig[param] = value;
});
};

const applyConfigurations = () => {
Object.keys(runtimeConfig).forEach(key => {
CONFIGURATION[key] = runtimeConfig[key];
});
};

const initConfiguration = () => {
if (initialized) {
return;
}

parseConfigurationScript();
parseURLParameters();
applyConfigurations();

initialized = true;
};
const getOriginInfo = () => {}; // needed for the shim

export {
getTheme,
setTheme,
getNoConflict,
setNoConflict,
getCompactSize,
getRTL,
getLanguage,
getCompactSize,
getWCNoConflict,
getCalendarType,
getLocale,
_setTheme,
_setWCNoConflict,
getSupportedLanguages,
getCalendarType,
getOriginInfo,
};
112 changes: 112 additions & 0 deletions packages/base/src/InitialConfiguration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
let initialized = false;

const initialConfig = {
theme: "sap_fiori_3",
rtl: null,
language: null,
compactSize: false,
calendarType: null,
noConflict: false, // no URL
};

/* General settings */
const getTheme = () => {
initConfiguration();
return initialConfig.theme;
};

const getRTL = () => {
initConfiguration();
return initialConfig.rtl;
};

const getLanguage = () => {
initConfiguration();
return initialConfig.language;
};

const getCompactSize = () => {
initConfiguration();
return initialConfig.compactSize;
};

const getNoConflict = () => {
initConfiguration();
return initialConfig.noConflict;
};

const getCalendarType = () => {
initConfiguration();
return initialConfig.calendarType;
};

const booleanMapping = new Map();
booleanMapping.set("true", true);
booleanMapping.set("false", false);

let runtimeConfig = {};

const parseConfigurationScript = () => {
const configScript = document.querySelector("[data-ui5-config]") || document.querySelector("[data-id='sap-ui-config']"); // for backward compatibility

let configJSON;

if (configScript) {
try {
configJSON = JSON.parse(configScript.innerHTML);
} catch (err) {
console.warn("Incorrect data-sap-ui-config format. Please use JSON"); /* eslint-disable-line */
}

if (configJSON) {
runtimeConfig = Object.assign({}, configJSON);
}
}
};

const parseURLParameters = () => {
const params = new URLSearchParams(window.location.search);

params.forEach((value, key) => {
if (!key.startsWith("sap-ui")) {
return;
}

const lowerCaseValue = value.toLowerCase();

const param = key.split("sap-ui-")[1];

if (booleanMapping.has(value)) {
value = booleanMapping.get(lowerCaseValue);
}

runtimeConfig[param] = value;
});
};

const applyConfigurations = () => {
Object.keys(runtimeConfig).forEach(key => {
initialConfig[key] = runtimeConfig[key];
});
};

const initConfiguration = () => {
if (initialized) {
return;
}

parseConfigurationScript();
parseURLParameters();
applyConfigurations();

initialized = true;
};

export {
getTheme,
getRTL,
getLanguage,
getCompactSize,
getNoConflict,
getCalendarType,
};
Loading

0 comments on commit 86ad25b

Please sign in to comment.