Files
reverse-engineering-anything/src/domain/javascript/electronWindowConstructorSurfaces.ts
T
0b1a945d69 fix(electron): model view constructors as window-like surfaces (#9571)
* fix(electron): model view constructors as window-like surfaces

Electron's static pass recognized a window only through the literal
`BrowserWindow` constructor, so `BaseWindow`, `BrowserView` and
`WebContentsView` produced no node and their literal `webPreferences` were
invisible. IPC registrations reached through such a view's own
`webContents.ipc` were dropped too, because the receiver resolver had the
same single-constructor gate -- VS Code alone registers seven channels this
way, and a shipped sample of four applications put 29 percent of window
construction sites on an unmodeled constructor.

Read webPreferences through one constructor set shared by the construction
inspector and the IPC receiver resolver. The finding only carries the new
`window_constructor` field when the site is not `BrowserWindow`, so existing
projections and their evidence stay byte-identical. A non-BrowserWindow
owner is not admitted for `loadFile`/`loadURL` on itself: only BrowserWindow
exposes those directly.

* fix(electron): keep the view constructor label lookup nullable

Observation labels are nullable in the application graph schema, so the
byLabel lookup failed tsc with TS18047 and took the Static checks job
down with it.

---------

Co-authored-by: 2SinceJuly <202121119+2SinceJuly@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-11-09 19:53:11 +08:00

42 lines
1.9 KiB
TypeScript

import type { ElectronWindowConstructor } from "./electronStaticAnalysisTypes.js";
/**
* Electron modules that build a window-like `webContents` surface and the
* surfaces each one exposes. One table so the construction inspector and the
* scoped-IPC receiver resolver cannot disagree about which constructors carry
* a preference, preload or `webContents` surface.
*/
export interface ElectronWindowConstructorSurface {
/** The constructor accepts `webPreferences` in its options object. */
readonly preferences: boolean;
/** The instance owns `webContents`, and so `webContents.ipc`, directly. */
readonly webContents: boolean;
/** The instance exposes `loadFile`/`loadURL` on itself, not via contents. */
readonly selfLoad: boolean;
}
export const ELECTRON_WINDOW_CONSTRUCTOR_SURFACES: Readonly<
Record<ElectronWindowConstructor, ElectronWindowConstructorSurface>
> = {
// A BrowserWindow is created with its own contents and preferences.
BrowserWindow: { preferences: true, webContents: true, selfLoad: true },
// BaseWindow owns native frame geometry; its contents live in separately
// attached WebContentsViews, so it accepts no webPreferences and exposes no
// webContents of its own.
BaseWindow: { preferences: false, webContents: false, selfLoad: false },
// A BrowserView is constructed with webPreferences and owns its webContents.
BrowserView: { preferences: true, webContents: true, selfLoad: false },
// A WebContentsView accepts preferences or an explicitly adopted webContents.
WebContentsView: { preferences: true, webContents: true, selfLoad: false },
};
const CONSTRUCTOR_NAMES: ReadonlySet<string> = new Set(
Object.keys(ELECTRON_WINDOW_CONSTRUCTOR_SURFACES),
);
/** Narrow an Electron export path segment to a modeled window constructor. */
export const electronWindowConstructor = (
name: string,
): ElectronWindowConstructor | undefined =>
CONSTRUCTOR_NAMES.has(name) ? (name as ElectronWindowConstructor) : undefined;