Skip to content

Commit aa463d9

Browse files
authored
refactor(framework): remove the CSP module (#8496)
Previously, we used <style> and <link> tags to style web components due to the lack of browser support for adoptedStyleSheets. However, as latest version of all relevant browsers now support "adoptedStyleSheets", we are removing all additional functionality that was implemented to compensate for the missing support and rely entirely on "adoptedStyleSheets". As a result, there is no need of additional handling to full-fill Content Security Policy (CSP) requirements, because adoptedStyleSheets are CSP compliant. BREAKING CHANGE: Removed the `CSP.js` module and the creation of `<style>` and `<link>` tags, as all browsers now support adoptedStyleSheets. The following APIs are not available any more and should not be used: ```ts import { setUseLinks } from "@ui5/webcomponents-base/dist/CSP.js" import { setPackageCSSRoot } from "@ui5/webcomponents-base/dist/CSP.js" import { setPreloadLinks } from "@ui5/webcomponents-base/dist/CSP.js" ``` Related to [#8461](#8461)
1 parent 7656a93 commit aa463d9

20 files changed

+33
-396
lines changed

docs/2-advanced/08-CSP.md

-101
This file was deleted.

packages/base/README.md

-8
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ Contains the base files for all Web Components, most notably `@ui5/webcomponents
2020
Components | `import applyDirection from "@ui5/webcomponents-base/dist/locale/applyDirection.js"`| Applies direction ("ltr"/"rtl") - re-renders all RTL-aware components |
2121
Components | `import { setCustomElementsScopingSuffix } from "@ui5/webcomponents-base/dist/CustomElementsScope.js"`| Adds suffix to the tag names of all components |
2222
Components | `@ui5/webcomponents-base/dist/util/InvisibleMessage.js` | Provides a way to expose dynamic content changes that can be announced by screen readers |
23-
CSP compliance| `import { setPackageCSSRoot } from "@ui5/webcomponents-base/dist/CSP.js"`| Sets directory path where the CSS resources for given package will be served from |
24-
CSP compliance| `import { setUseLinks } from "@ui5/webcomponents-base/dist/CSP.js"` | Enables or disables the usage of `<link>` tags instead of `<style>` tags |
25-
CSP compliance| `import { setPreloadLinks } from "@ui5/webcomponents-base/dist/CSP.js"` | Enables or disables the preloading of `<link>` tags |
2623

2724
### `applyDirection.js`
2825
- `applyDirection`
@@ -42,11 +39,6 @@ Contains the base files for all Web Components, most notably `@ui5/webcomponents
4239

4340
- `ignoreCustomElements`
4441

45-
### `CSP.js`
46-
- `setPackageCSSRoot`
47-
- `setUseLinks`
48-
- `setPreloadLinks`
49-
5042
### `i18nBundle.js`
5143

5244
- `registerI18nLoader`

packages/base/index.js

-12
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,6 @@ import { registerIconLoader } from "./dist/asset-registries/Icons.js";
5656
// Boot.ts
5757
import { attachBoot } from "./dist/Boot.js";
5858

59-
// CSP.ts
60-
import {
61-
setPackageCSSRoot,
62-
setUseLinks,
63-
setPreloadLinks,
64-
} from "./dist/CSP.js";
65-
6659
// CustomElementsScope.ts
6760
import {
6861
setCustomElementsScopingSuffix,
@@ -172,11 +165,6 @@ export {
172165
// Boot.ts
173166
attachBoot,
174167

175-
// CSP.ts
176-
setPackageCSSRoot,
177-
setUseLinks,
178-
setPreloadLinks,
179-
180168
// CustomElementsScope.ts
181169
setCustomElementsScopingSuffix,
182170
getCustomElementsScopingSuffix,

packages/base/src/CSP.ts

-69
This file was deleted.

packages/base/src/ManagedStyles.ts

+21-95
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import createStyleInHead from "./util/createStyleInHead.js";
2-
import createLinkInHead from "./util/createLinkInHead.js";
3-
import { shouldUseLinks, getUrl } from "./CSP.js";
41
import { StyleData, StyleDataCSP } from "./types.js";
5-
import { isSafari } from "./Device.js";
62
import { getCurrentRuntimeIndex, compareRuntimes } from "./Runtimes.js";
73

84
const isSSR = typeof document === "undefined";
@@ -22,87 +18,34 @@ const createStyle = (data: StyleData, name: string, value = "", theme?: string)
2218
const content = typeof data === "string" ? data : data.content;
2319
const currentRuntimeIndex = getCurrentRuntimeIndex();
2420

25-
if (shouldUseLinks()) {
26-
const attributes = {} as Record<string, any>;
27-
attributes[name] = value;
28-
if (theme) {
29-
attributes["data-ui5-runtime-index"] = currentRuntimeIndex;
30-
attributes["data-ui5-theme"] = theme;
31-
}
32-
const href = getUrl((data as StyleDataCSP).packageName, (data as StyleDataCSP).fileName);
33-
createLinkInHead(href, attributes);
34-
} else if (document.adoptedStyleSheets && !isSafari()) {
35-
const stylesheet = new CSSStyleSheet();
36-
stylesheet.replaceSync(content);
37-
(stylesheet as Record<string, any>)._ui5StyleId = getStyleId(name, value); // set an id so that we can find the style later
38-
if (theme) {
39-
(stylesheet as Record<string, any>)._ui5RuntimeIndex = currentRuntimeIndex;
40-
(stylesheet as Record<string, any>)._ui5Theme = theme;
41-
}
42-
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
43-
} else {
44-
const attributes = {} as Record<string, any>;
45-
attributes[name] = value;
46-
if (theme) {
47-
attributes["data-ui5-runtime-index"] = currentRuntimeIndex;
48-
attributes["data-ui5-theme"] = theme;
49-
}
50-
createStyleInHead(content, attributes);
21+
const stylesheet = new CSSStyleSheet();
22+
stylesheet.replaceSync(content);
23+
(stylesheet as Record<string, any>)._ui5StyleId = getStyleId(name, value); // set an id so that we can find the style later
24+
if (theme) {
25+
(stylesheet as Record<string, any>)._ui5RuntimeIndex = currentRuntimeIndex;
26+
(stylesheet as Record<string, any>)._ui5Theme = theme;
5127
}
28+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
5229
};
5330

5431
const updateStyle = (data: StyleData, name: string, value = "", theme?: string) => {
5532
const content = typeof data === "string" ? data : data.content;
5633
const currentRuntimeIndex = getCurrentRuntimeIndex();
5734

58-
if (shouldUseLinks()) {
59-
const link = document.querySelector(`head>link[${name}="${value}"]`) as HTMLLinkElement;
60-
const href = getUrl((data as StyleDataCSP).packageName, (data as StyleDataCSP).fileName);
61-
62-
if (!theme) {
63-
link.href = href;
64-
} else {
65-
const linkRuntimeIndex = link.getAttribute("data-ui5-runtime-index") || undefined;
66-
const linkTheme = link.getAttribute("data-ui5-theme");
67-
if (linkTheme !== theme || shouldUpdate(linkRuntimeIndex)) {
68-
link.href = href;
69-
link.setAttribute("data-ui5-runtime-index", String(currentRuntimeIndex));
70-
link.setAttribute("data-ui5-theme", theme);
71-
}
72-
}
73-
} else if (document.adoptedStyleSheets && !isSafari()) {
74-
const stylesheet = document.adoptedStyleSheets.find(sh => (sh as Record<string, any>)._ui5StyleId === getStyleId(name, value));
75-
if (!stylesheet) {
76-
return;
77-
}
35+
const stylesheet = document.adoptedStyleSheets.find(sh => (sh as Record<string, any>)._ui5StyleId === getStyleId(name, value));
36+
if (!stylesheet) {
37+
return;
38+
}
7839

79-
if (!theme) {
80-
stylesheet.replaceSync(content || "");
81-
} else {
82-
const stylesheetRuntimeIndex: string | undefined = (stylesheet as Record<string, any>)._ui5RuntimeIndex;
83-
const stylesheetTheme: string | undefined = (stylesheet as Record<string, any>)._ui5Theme;
84-
if (stylesheetTheme !== theme || shouldUpdate(stylesheetRuntimeIndex)) {
85-
stylesheet.replaceSync(content || "");
86-
(stylesheet as Record<string, any>)._ui5RuntimeIndex = String(currentRuntimeIndex);
87-
(stylesheet as Record<string, any>)._ui5Theme = theme;
88-
}
89-
}
40+
if (!theme) {
41+
stylesheet.replaceSync(content || "");
9042
} else {
91-
const style = document.querySelector(`head>style[${name}="${value}"]`);
92-
if (!style) {
93-
return;
94-
}
95-
96-
if (!theme) {
97-
style.textContent = content || "";
98-
} else {
99-
const styleRuntimeIndex = style.getAttribute("data-ui5-runtime-index") || undefined;
100-
const styleTheme = style.getAttribute("data-ui5-theme");
101-
if (styleTheme !== theme || shouldUpdate(styleRuntimeIndex)) {
102-
style.textContent = content || "";
103-
style.setAttribute("data-ui5-runtime-index", String(currentRuntimeIndex));
104-
style.setAttribute("data-ui5-theme", theme);
105-
}
43+
const stylesheetRuntimeIndex: string | undefined = (stylesheet as Record<string, any>)._ui5RuntimeIndex;
44+
const stylesheetTheme: string | undefined = (stylesheet as Record<string, any>)._ui5Theme;
45+
if (stylesheetTheme !== theme || shouldUpdate(stylesheetRuntimeIndex)) {
46+
stylesheet.replaceSync(content || "");
47+
(stylesheet as Record<string, any>)._ui5RuntimeIndex = String(currentRuntimeIndex);
48+
(stylesheet as Record<string, any>)._ui5Theme = theme;
10649
}
10750
}
10851
};
@@ -111,29 +54,12 @@ const hasStyle = (name: string, value = ""): boolean => {
11154
if (isSSR) {
11255
return true;
11356
}
114-
if (shouldUseLinks()) {
115-
return !!document.querySelector(`head>link[${name}="${value}"]`);
116-
}
11757

118-
const styleElement = document.querySelector(`head>style[${name}="${value}"]`);
119-
120-
if (document.adoptedStyleSheets && !isSafari()) {
121-
return !!styleElement || !!document.adoptedStyleSheets.find(sh => (sh as Record<string, any>)._ui5StyleId === getStyleId(name, value));
122-
}
123-
124-
return !!styleElement;
58+
return !!document.adoptedStyleSheets.find(sh => (sh as Record<string, any>)._ui5StyleId === getStyleId(name, value));
12559
};
12660

12761
const removeStyle = (name: string, value = "") => {
128-
if (shouldUseLinks()) {
129-
const linkElement = document.querySelector(`head>link[${name}="${value}"]`);
130-
linkElement?.parentElement?.removeChild(linkElement);
131-
} else if (document.adoptedStyleSheets && !isSafari()) {
132-
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(sh => (sh as Record<string, any>)._ui5StyleId !== getStyleId(name, value));
133-
} else {
134-
const styleElement = document.querySelector(`head > style[${name}="${value}"]`);
135-
styleElement?.parentElement?.removeChild(styleElement);
136-
}
62+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(sh => (sh as Record<string, any>)._ui5StyleId !== getStyleId(name, value));
13763
};
13864

13965
const createOrUpdateStyle = (data: StyleData, name: string, value = "", theme?: string) => {

packages/base/src/UI5Element.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import isValidPropertyName from "./util/isValidPropertyName.js";
2525
import { getSlotName, getSlottedNodesList } from "./util/SlotsHelper.js";
2626
import arraysAreEqual from "./util/arraysAreEqual.js";
2727
import { markAsRtlAware } from "./locale/RTLAwareRegistry.js";
28-
import preloadLinks from "./theming/preloadLinks.js";
2928
import executeTemplate from "./renderer/executeTemplate.js";
3029
import type { TemplateFunction, TemplateFunctionResult } from "./renderer/executeTemplate.js";
3130
import type { PromiseResolve, ComponentStylesData, ClassMap } from "./types.js";
@@ -35,7 +34,7 @@ let autoId = 0;
3534
const elementTimeouts = new Map<string, Promise<void>>();
3635
const uniqueDependenciesCache = new Map<typeof UI5Element, Array<typeof UI5Element>>();
3736

38-
type Renderer = (templateResult: TemplateFunctionResult, container: HTMLElement | DocumentFragment, styleStrOrHrefsArr: string | Array<string> | undefined, forStaticArea: boolean, options: RendererOptions) => void;
37+
type Renderer = (templateResult: TemplateFunctionResult, container: HTMLElement | DocumentFragment, forStaticArea: boolean, options: RendererOptions) => void;
3938

4039
type RendererOptions = {
4140
/**
@@ -1139,7 +1138,6 @@ abstract class UI5Element extends HTMLElement {
11391138
this._generateAccessors();
11401139
registerTag(tag);
11411140
customElements.define(tag, this as unknown as CustomElementConstructor);
1142-
preloadLinks(this);
11431141
}
11441142
return this;
11451143
}

0 commit comments

Comments
 (0)