aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-02-27 18:15:43 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-03-06 18:56:48 +0100
commitc80aad5b4ab70462f39b5073c936adf9f54c5fd3 (patch)
tree23d37d3d7564f9dcac442adeafe4ef9c7e9bedd6 /packages
parentfeat: Location bar actions (diff)
downloadsophie-c80aad5b4ab70462f39b5073c936adf9f54c5fd3.tar.gz
sophie-c80aad5b4ab70462f39b5073c936adf9f54c5fd3.tar.zst
sophie-c80aad5b4ab70462f39b5073c936adf9f54c5fd3.zip
fix(service-preload): Browser view canvas background
Due to `BrowserView.setBackgroundColor` not working under linux, we have to inject styles to make sure our `BrowserView` is opaque. We try to cover more edge cases to avoid the interference of the injected style and the web site's own styles according to the CSS specification: https://www.w3.org/TR/css-backgrounds-3/#body-background In particular, we avoid overwriting the styles for the `html` element if `body` already has an opaque background so that the background of `body` can extend to the whole canvas. This might still interfere with the web site if it updates the background color on the fly (dark mode), but a reload should solve most of such issues. Hopefully, after https://github.com/electron/electron/issues/32898 is resolved, we can get rid of the hack entirely. Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages')
-rw-r--r--packages/main/src/stores/MainStore.ts2
-rw-r--r--packages/service-preload/package.json4
-rw-r--r--packages/service-preload/src/index.ts53
3 files changed, 57 insertions, 2 deletions
diff --git a/packages/main/src/stores/MainStore.ts b/packages/main/src/stores/MainStore.ts
index bf351d7..21d7a63 100644
--- a/packages/main/src/stores/MainStore.ts
+++ b/packages/main/src/stores/MainStore.ts
@@ -87,7 +87,7 @@ const MainStore = types
87 self.settings.setShowLocationBar(action.showLocationBar); 87 self.settings.setShowLocationBar(action.showLocationBar);
88 break; 88 break;
89 case 'reload-all-services': 89 case 'reload-all-services':
90 // TODO 90 self.services.forEach((service) => service.reload());
91 break; 91 break;
92 case 'dispatch-service-action': { 92 case 'dispatch-service-action': {
93 const { serviceId, serviceAction } = action; 93 const { serviceId, serviceAction } = action;
diff --git a/packages/service-preload/package.json b/packages/service-preload/package.json
index 1cfa74c..2090cf9 100644
--- a/packages/service-preload/package.json
+++ b/packages/service-preload/package.json
@@ -9,6 +9,10 @@
9 }, 9 },
10 "dependencies": { 10 "dependencies": {
11 "@sophie/service-shared": "workspace:*", 11 "@sophie/service-shared": "workspace:*",
12 "color-string": "^1.9.0",
12 "electron": "17.1.0" 13 "electron": "17.1.0"
14 },
15 "devDependencies": {
16 "@types/color-string": "^1"
13 } 17 }
14} 18}
diff --git a/packages/service-preload/src/index.ts b/packages/service-preload/src/index.ts
index fb19107..a49a3a4 100644
--- a/packages/service-preload/src/index.ts
+++ b/packages/service-preload/src/index.ts
@@ -19,12 +19,63 @@
19 */ 19 */
20 20
21import { ServiceToMainIpcMessage, WebSource } from '@sophie/service-shared'; 21import { ServiceToMainIpcMessage, WebSource } from '@sophie/service-shared';
22import colorString from 'color-string';
22import { ipcRenderer, webFrame } from 'electron'; 23import { ipcRenderer, webFrame } from 'electron';
23 24
25const DEFAULT_BG_COLOR = '#fff';
26
27/**
28 * Styles a HTML element such that its background is opaque.
29 *
30 * If there is an existing background color, it will be made maximally opaque.
31 *
32 * If there is a background image, transparent areas will be colored `DEFAULT_BG_COLOR`.
33 *
34 * If the element was completely transparent, the function returns `false` instead.
35 * This allows leaving a `html` element transparent to let the background of the `body`
36 * element render in its palce.
37 *
38 * @param element The HTML element to style.
39 * @returns `true` if the background was made opaque.
40 * @see https://www.w3.org/TR/css-backgrounds-3/#body-background
41 */
42function tryMakeOpaque(element: HTMLElement): boolean {
43 const style = getComputedStyle(element);
44 const bgColor = colorString.get.rgb(style.backgroundColor);
45 if (bgColor[3] > 0) {
46 if (bgColor[3] < 1) {
47 bgColor[3] = 1;
48 // eslint-disable-next-line no-param-reassign -- Deliberately add element style.
49 element.style.backgroundColor = colorString.to.rgb(bgColor);
50 }
51 return true;
52 }
53 if (style.backgroundImage !== 'none') {
54 // eslint-disable-next-line no-param-reassign -- Deliberately add element style.
55 element.style.backgroundColor = DEFAULT_BG_COLOR;
56 return true;
57 }
58 return false;
59}
60
24if (webFrame.parent === null) { 61if (webFrame.parent === null) {
25 // Inject CSS to simulate `browserView.setBackgroundColor`. 62 // Inject CSS to simulate `browserView.setBackgroundColor`.
26 // This is injected before the page loads, so the styles from the website will overwrite it. 63 // This is injected before the page loads, so the styles from the website will overwrite it.
27 webFrame.insertCSS('body { background-color: #fff; }'); 64 document.addEventListener('DOMContentLoaded', () => {
65 if (
66 document.documentElement.style.contain === '' &&
67 document.body.style.contain === ''
68 ) {
69 if (
70 !tryMakeOpaque(document.documentElement) &&
71 !tryMakeOpaque(document.body)
72 ) {
73 document.body.style.backgroundColor = DEFAULT_BG_COLOR;
74 }
75 } else if (!tryMakeOpaque(document.documentElement)) {
76 document.documentElement.style.backgroundColor = DEFAULT_BG_COLOR;
77 }
78 });
28} 79}
29 80
30/** 81/**