aboutsummaryrefslogtreecommitdiffstats
path: root/packages/service-preload/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/service-preload/src/index.ts')
-rw-r--r--packages/service-preload/src/index.ts41
1 files changed, 16 insertions, 25 deletions
diff --git a/packages/service-preload/src/index.ts b/packages/service-preload/src/index.ts
index fb19107..eee8551 100644
--- a/packages/service-preload/src/index.ts
+++ b/packages/service-preload/src/index.ts
@@ -18,45 +18,36 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { ServiceToMainIpcMessage, WebSource } from '@sophie/service-shared'; 21import { webFrame } from 'electron';
22import { ipcRenderer, webFrame } from 'electron'; 22// eslint-disable-next-line import/no-unresolved -- Synthetic import provided by an eslint plugin.
23 23import injectSource from 'sophie-src:@sophie/service-inject';
24if (webFrame.parent === null) {
25 // Inject CSS to simulate `browserView.setBackgroundColor`.
26 // This is injected before the page loads, so the styles from the website will overwrite it.
27 webFrame.insertCSS('body { background-color: #fff; }');
28}
29 24
30/** 25/**
31 * Fetches and executes the service inject script in the isolated world. 26 * Executes the service inject script in the isolated world.
32 * 27 *
33 * The service inject script relies on exposed APIs, so this function can only 28 * The service inject script relies on exposed APIs, so this function can only
34 * be called after APIs have been exposed via `contextBridge` to the main world. 29 * be called after APIs have been exposed via `contextBridge` to the main world.
35 * 30 *
36 * We have to call `executeJavaScriptInIsolatedWorld` from the service preload script, 31 * We embed the source code of the inject script into the preload script
37 * beause there is no way currently (electron 16) to execute a script on a 32 * with an esbuild plugin, so there is no need to fetch it separately.
38 * `WebFrameMain` in the main process by specifying a `WebSource`. 33 *
39 * Calling `executeJavaScriptInInsolatedWorld` on a `WebContents` in the main process
40 * will always inject the script into the _top-level_ frame, but here we
41 * are injecting into the _current_ frame instead.
42 * As a tradeoff, the promise returned by `executeJavaScriptInIsolatedWorld` 34 * As a tradeoff, the promise returned by `executeJavaScriptInIsolatedWorld`
43 * will resolve to `unknown` (instead of rejecting) even if the injected script fails, 35 * will resolve to `unknown` (instead of rejecting) even if the injected script fails,
44 * because chromium doesn't dispatch main world errors to isolated worlds. 36 * because chromium doesn't dispatch main world errors to isolated worlds.
45 * 37 *
46 * @return A promise that only rejects if we fail to fetch the inject script. 38 * @return A promise that always resolves to `undefined`.
47 * @see https://www.electronjs.org/docs/latest/api/web-frame#webframeexecutejavascriptinisolatedworldworldid-scripts-usergesture-callback
48 * @see https://www.electronjs.org/docs/latest/api/web-frame-main#frameexecutejavascriptcode-usergesture
49 * @see https://www.electronjs.org/docs/latest/api/web-contents#contentsexecutejavascriptinisolatedworldworldid-scripts-usergesture
50 */ 39 */
51async function fetchAndExecuteInjectScript(): Promise<void> { 40async function fetchAndExecuteInjectScript(): Promise<void> {
52 const apiExposedResponse: unknown = await ipcRenderer.invoke(
53 ServiceToMainIpcMessage.ApiExposedInMainWorld,
54 );
55 const injectSource = WebSource.parse(apiExposedResponse);
56 // Isolated world 0 is the main world. 41 // Isolated world 0 is the main world.
57 await webFrame.executeJavaScriptInIsolatedWorld(0, [injectSource]); 42 await webFrame.executeJavaScriptInIsolatedWorld(0, [
43 {
44 code: injectSource,
45 },
46 ]);
58} 47}
59 48
60fetchAndExecuteInjectScript().catch((error) => { 49fetchAndExecuteInjectScript().catch((error) => {
61 console.error('Failed to fetch inject source:', error); 50 // This will never happen because of
51 // https://www.electronjs.org/docs/latest/api/web-frame#webframeexecutejavascriptinisolatedworldworldid-scripts-usergesture-callback
52 console.error('Failed to execute service inject:', error);
62}); 53});