diff options
Diffstat (limited to 'packages/service-preload/src/index.ts')
-rw-r--r-- | packages/service-preload/src/index.ts | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/packages/service-preload/src/index.ts b/packages/service-preload/src/index.ts index a49a3a4..99d02ec 100644 --- a/packages/service-preload/src/index.ts +++ b/packages/service-preload/src/index.ts | |||
@@ -18,9 +18,10 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { ServiceToMainIpcMessage, WebSource } from '@sophie/service-shared'; | ||
22 | import colorString from 'color-string'; | 21 | import colorString from 'color-string'; |
23 | import { ipcRenderer, webFrame } from 'electron'; | 22 | import { webFrame } from 'electron'; |
23 | // eslint-disable-next-line import/no-unresolved -- Synthetic import provided by an eslint plugin. | ||
24 | import injectSource from 'sophie-src:@sophie/service-inject'; | ||
24 | 25 | ||
25 | const DEFAULT_BG_COLOR = '#fff'; | 26 | const DEFAULT_BG_COLOR = '#fff'; |
26 | 27 | ||
@@ -79,35 +80,31 @@ if (webFrame.parent === null) { | |||
79 | } | 80 | } |
80 | 81 | ||
81 | /** | 82 | /** |
82 | * Fetches and executes the service inject script in the isolated world. | 83 | * Executes the service inject script in the isolated world. |
83 | * | 84 | * |
84 | * The service inject script relies on exposed APIs, so this function can only | 85 | * The service inject script relies on exposed APIs, so this function can only |
85 | * be called after APIs have been exposed via `contextBridge` to the main world. | 86 | * be called after APIs have been exposed via `contextBridge` to the main world. |
86 | * | 87 | * |
87 | * We have to call `executeJavaScriptInIsolatedWorld` from the service preload script, | 88 | * We embed the source code of the inject script into the preload script |
88 | * beause there is no way currently (electron 16) to execute a script on a | 89 | * with an esbuild plugin, so there is no need to fetch it separately. |
89 | * `WebFrameMain` in the main process by specifying a `WebSource`. | 90 | * |
90 | * Calling `executeJavaScriptInInsolatedWorld` on a `WebContents` in the main process | ||
91 | * will always inject the script into the _top-level_ frame, but here we | ||
92 | * are injecting into the _current_ frame instead. | ||
93 | * As a tradeoff, the promise returned by `executeJavaScriptInIsolatedWorld` | 91 | * As a tradeoff, the promise returned by `executeJavaScriptInIsolatedWorld` |
94 | * will resolve to `unknown` (instead of rejecting) even if the injected script fails, | 92 | * will resolve to `unknown` (instead of rejecting) even if the injected script fails, |
95 | * because chromium doesn't dispatch main world errors to isolated worlds. | 93 | * because chromium doesn't dispatch main world errors to isolated worlds. |
96 | * | 94 | * |
97 | * @return A promise that only rejects if we fail to fetch the inject script. | 95 | * @return A promise that always resolves to `undefined`. |
98 | * @see https://www.electronjs.org/docs/latest/api/web-frame#webframeexecutejavascriptinisolatedworldworldid-scripts-usergesture-callback | ||
99 | * @see https://www.electronjs.org/docs/latest/api/web-frame-main#frameexecutejavascriptcode-usergesture | ||
100 | * @see https://www.electronjs.org/docs/latest/api/web-contents#contentsexecutejavascriptinisolatedworldworldid-scripts-usergesture | ||
101 | */ | 96 | */ |
102 | async function fetchAndExecuteInjectScript(): Promise<void> { | 97 | async function fetchAndExecuteInjectScript(): Promise<void> { |
103 | const apiExposedResponse: unknown = await ipcRenderer.invoke( | ||
104 | ServiceToMainIpcMessage.ApiExposedInMainWorld, | ||
105 | ); | ||
106 | const injectSource = WebSource.parse(apiExposedResponse); | ||
107 | // Isolated world 0 is the main world. | 98 | // Isolated world 0 is the main world. |
108 | await webFrame.executeJavaScriptInIsolatedWorld(0, [injectSource]); | 99 | await webFrame.executeJavaScriptInIsolatedWorld(0, [ |
100 | { | ||
101 | code: injectSource, | ||
102 | }, | ||
103 | ]); | ||
109 | } | 104 | } |
110 | 105 | ||
111 | fetchAndExecuteInjectScript().catch((error) => { | 106 | fetchAndExecuteInjectScript().catch((error) => { |
112 | console.error('Failed to fetch inject source:', error); | 107 | // This will never happen because of |
108 | // https://www.electronjs.org/docs/latest/api/web-frame#webframeexecutejavascriptinisolatedworldworldid-scripts-usergesture-callback | ||
109 | console.error('Failed to execute service inject:', error); | ||
113 | }); | 110 | }); |