diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-02-27 18:15:43 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-03-06 18:56:48 +0100 |
commit | c80aad5b4ab70462f39b5073c936adf9f54c5fd3 (patch) | |
tree | 23d37d3d7564f9dcac442adeafe4ef9c7e9bedd6 | |
parent | feat: Location bar actions (diff) | |
download | sophie-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>
-rw-r--r-- | packages/main/src/stores/MainStore.ts | 2 | ||||
-rw-r--r-- | packages/service-preload/package.json | 4 | ||||
-rw-r--r-- | packages/service-preload/src/index.ts | 53 | ||||
-rw-r--r-- | yarn.lock | 37 |
4 files changed, 93 insertions, 3 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 | ||
21 | import { ServiceToMainIpcMessage, WebSource } from '@sophie/service-shared'; | 21 | import { ServiceToMainIpcMessage, WebSource } from '@sophie/service-shared'; |
22 | import colorString from 'color-string'; | ||
22 | import { ipcRenderer, webFrame } from 'electron'; | 23 | import { ipcRenderer, webFrame } from 'electron'; |
23 | 24 | ||
25 | const 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 | */ | ||
42 | function 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 | |||
24 | if (webFrame.parent === null) { | 61 | if (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 | /** |
@@ -1365,6 +1365,8 @@ __metadata: | |||
1365 | resolution: "@sophie/service-preload@workspace:packages/service-preload" | 1365 | resolution: "@sophie/service-preload@workspace:packages/service-preload" |
1366 | dependencies: | 1366 | dependencies: |
1367 | "@sophie/service-shared": "workspace:*" | 1367 | "@sophie/service-shared": "workspace:*" |
1368 | "@types/color-string": ^1 | ||
1369 | color-string: ^1.9.0 | ||
1368 | electron: 17.1.0 | 1370 | electron: 17.1.0 |
1369 | languageName: unknown | 1371 | languageName: unknown |
1370 | linkType: soft | 1372 | linkType: soft |
@@ -1462,6 +1464,13 @@ __metadata: | |||
1462 | languageName: node | 1464 | languageName: node |
1463 | linkType: hard | 1465 | linkType: hard |
1464 | 1466 | ||
1467 | "@types/color-string@npm:^1": | ||
1468 | version: 1.5.2 | ||
1469 | resolution: "@types/color-string@npm:1.5.2" | ||
1470 | checksum: b604373cd151b66c44b3fb1df5e7a93136307755f571016ff249b378b20c0ce190ed373af294cc6cdbbe489fdcd71eb2026a6150a0312eee9ca7b2de4eea4e17 | ||
1471 | languageName: node | ||
1472 | linkType: hard | ||
1473 | |||
1465 | "@types/debug@npm:^4.1.6": | 1474 | "@types/debug@npm:^4.1.6": |
1466 | version: 4.1.7 | 1475 | version: 4.1.7 |
1467 | resolution: "@types/debug@npm:4.1.7" | 1476 | resolution: "@types/debug@npm:4.1.7" |
@@ -2869,13 +2878,23 @@ __metadata: | |||
2869 | languageName: node | 2878 | languageName: node |
2870 | linkType: hard | 2879 | linkType: hard |
2871 | 2880 | ||
2872 | "color-name@npm:~1.1.4": | 2881 | "color-name@npm:^1.0.0, color-name@npm:~1.1.4": |
2873 | version: 1.1.4 | 2882 | version: 1.1.4 |
2874 | resolution: "color-name@npm:1.1.4" | 2883 | resolution: "color-name@npm:1.1.4" |
2875 | checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 | 2884 | checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 |
2876 | languageName: node | 2885 | languageName: node |
2877 | linkType: hard | 2886 | linkType: hard |
2878 | 2887 | ||
2888 | "color-string@npm:^1.9.0": | ||
2889 | version: 1.9.0 | ||
2890 | resolution: "color-string@npm:1.9.0" | ||
2891 | dependencies: | ||
2892 | color-name: ^1.0.0 | ||
2893 | simple-swizzle: ^0.2.2 | ||
2894 | checksum: 93c6678b847f8cfa47d19677fd19e1d4b19d7a33f100644400357c298266080b5bca64e5f874fa8ac8cc0aa0606ad44f7a838b4e6fd05e6affea190a68555bb4 | ||
2895 | languageName: node | ||
2896 | linkType: hard | ||
2897 | |||
2879 | "color-support@npm:^1.1.2": | 2898 | "color-support@npm:^1.1.2": |
2880 | version: 1.1.3 | 2899 | version: 1.1.3 |
2881 | resolution: "color-support@npm:1.1.3" | 2900 | resolution: "color-support@npm:1.1.3" |
@@ -5227,6 +5246,13 @@ __metadata: | |||
5227 | languageName: node | 5246 | languageName: node |
5228 | linkType: hard | 5247 | linkType: hard |
5229 | 5248 | ||
5249 | "is-arrayish@npm:^0.3.1": | ||
5250 | version: 0.3.2 | ||
5251 | resolution: "is-arrayish@npm:0.3.2" | ||
5252 | checksum: 977e64f54d91c8f169b59afcd80ff19227e9f5c791fa28fa2e5bce355cbaf6c2c356711b734656e80c9dd4a854dd7efcf7894402f1031dfc5de5d620775b4d5f | ||
5253 | languageName: node | ||
5254 | linkType: hard | ||
5255 | |||
5230 | "is-bigint@npm:^1.0.1": | 5256 | "is-bigint@npm:^1.0.1": |
5231 | version: 1.0.4 | 5257 | version: 1.0.4 |
5232 | resolution: "is-bigint@npm:1.0.4" | 5258 | resolution: "is-bigint@npm:1.0.4" |
@@ -8149,6 +8175,15 @@ __metadata: | |||
8149 | languageName: node | 8175 | languageName: node |
8150 | linkType: hard | 8176 | linkType: hard |
8151 | 8177 | ||
8178 | "simple-swizzle@npm:^0.2.2": | ||
8179 | version: 0.2.2 | ||
8180 | resolution: "simple-swizzle@npm:0.2.2" | ||
8181 | dependencies: | ||
8182 | is-arrayish: ^0.3.1 | ||
8183 | checksum: a7f3f2ab5c76c4472d5c578df892e857323e452d9f392e1b5cf74b74db66e6294a1e1b8b390b519fa1b96b5b613f2a37db6cffef52c3f1f8f3c5ea64eb2d54c0 | ||
8184 | languageName: node | ||
8185 | linkType: hard | ||
8186 | |||
8152 | "sisteransi@npm:^1.0.5": | 8187 | "sisteransi@npm:^1.0.5": |
8153 | version: 1.0.5 | 8188 | version: 1.0.5 |
8154 | resolution: "sisteransi@npm:1.0.5" | 8189 | resolution: "sisteransi@npm:1.0.5" |