diff --git a/packages/api/src/webviewWindow.ts b/packages/api/src/webviewWindow.ts index f73d5cab58a8..d95ed9419d53 100644 --- a/packages/api/src/webviewWindow.ts +++ b/packages/api/src/webviewWindow.ts @@ -22,21 +22,17 @@ import type { Color, DragDropEvent } from './webview' */ function getCurrentWebviewWindow(): WebviewWindow { const webview = getCurrentWebview() - // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor return new WebviewWindow(webview.label, { skip: true }) } /** - * Gets a list of instances of `Webview` for all available webview windows. - * - * @since 2.0.0 + * Gets a list of instances of `Webview` for all available webviews. */ async function getAllWebviewWindows(): Promise { return invoke('plugin:window|get_all_windows').then((windows) => windows.map( (w) => new WebviewWindow(w, { - // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor skip: true }) ) @@ -52,7 +48,6 @@ class WebviewWindow { /** Local event listeners. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any listeners: Record>> - /** * Creates a new {@link Window} hosting a {@link Webview}. * @example @@ -75,14 +70,12 @@ class WebviewWindow { constructor( label: WebviewLabel, options: Omit - & WindowOptions = {} + & WindowOptions & { skip?: boolean } = {} ) { this.label = label - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment this.listeners = Object.create(null) - // @ts-expect-error `skip` is not a public API so it is not defined in WebviewOptions - if (!options?.skip) { + if (!(options && 'skip' in options && options.skip)) { invoke('plugin:webview|create_webview_window', { options: { ...options, @@ -109,11 +102,11 @@ class WebviewWindow { * @param label The webview label. * @returns The Webview instance to communicate with the webview or null if the webview doesn't exist. */ + static async getByLabel(label: string): Promise { const webview = (await getAllWebviewWindows()).find((w) => w.label === label) ?? null if (webview) { - // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor return new WebviewWindow(webview.label, { skip: true }) } return null @@ -126,13 +119,9 @@ class WebviewWindow { return getCurrentWebviewWindow() } - /** - * Gets a list of instances of `Webview` for all available webviews. - */ static async getAll(): Promise { return getAllWebviewWindows() } - /** * Listen to an emitted event on this webivew window. * @@ -152,15 +141,16 @@ class WebviewWindow { * @returns A promise resolving to a function to unlisten to the event. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. */ + async listen( event: EventName, handler: EventCallback ): Promise { if (this._handleTauriEvent(event, handler)) { return () => { - // eslint-disable-next-line security/detect-object-injection const listeners = this.listeners[event] - listeners.splice(listeners.indexOf(handler), 1) + const idx = listeners.indexOf(handler) + if (idx >= 0) listeners.splice(idx, 1) } } return listen(event, handler, { @@ -187,22 +177,22 @@ class WebviewWindow { * @returns A promise resolving to a function to unlisten to the event. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. */ + async once( event: EventName, handler: EventCallback ): Promise { if (this._handleTauriEvent(event, handler)) { return () => { - // eslint-disable-next-line security/detect-object-injection const listeners = this.listeners[event] - listeners.splice(listeners.indexOf(handler), 1) + const idx = listeners.indexOf(handler) + if (idx >= 0) listeners.splice(idx, 1) } } return once(event, handler, { target: { kind: 'WebviewWindow', label: this.label } }) } - /** * Set the window and webview background color. * @@ -220,12 +210,16 @@ class WebviewWindow { * @since 2.1.0 */ async setBackgroundColor(color: Color): Promise { - return invoke('plugin:window|set_background_color', { color }).then(() => { - return invoke('plugin:webview|set_webview_background_color', { color }) - }) + try { + await invoke('plugin:window|set_background_color', { color }) + await invoke('plugin:webview|set_webview_background_color', { color }) + } catch (err) { + throw new Error('Failed to set background color', { cause: err }) + } } } + // Order matters, we use window APIs by default applyMixins(WebviewWindow, [Window, Webview]) @@ -243,12 +237,12 @@ function applyMixins( typeof baseClass.prototype === 'object' && baseClass.prototype && name in baseClass.prototype - ) + ) { return + } Object.defineProperty( baseClass.prototype, name, - // eslint-disable-next-line Object.getOwnPropertyDescriptor(extendedClass.prototype, name) ?? Object.create(null) ) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 73de4d17fe33..6137ec825e97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,6 +88,9 @@ importers: globals: specifier: ^16.2.0 version: 16.2.0 + prettier: + specifier: ^3.5.3 + version: 3.5.3 rollup: specifier: 4.52.3 version: 4.52.3