fix: window.open popups are always resizable (#47540)

fix: window.open popups are always resizable

Closes https://github.com/electron/electron/issues/43591.

Per current WHATWG spec, the `window.open` API should always
create a resizable popup window. This change updates the
`parseFeaturesString` function to ensure that windows opened
with `window.open` are always resizable, regardless of the
`resizable` feature string.
This commit is contained in:
Shelley Vohr 2025-07-02 15:02:59 +02:00 committed by GitHub
commit 655037fbdf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 0 deletions

View file

@ -21,6 +21,23 @@ macOS 11 (Big Sur) is no longer supported by [Chromium](https://chromium-review.
Older versions of Electron will continue to run on Big Sur, but macOS 12 (Monterey) Older versions of Electron will continue to run on Big Sur, but macOS 12 (Monterey)
or later will be required to run Electron v38.0.0 and higher. or later will be required to run Electron v38.0.0 and higher.
### Behavior Changed: window.open popups are always resizable
Per current [WHATWG spec](https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-open-dev), the `window.open` API will now always create a resizable popup window.
To restore previous behavior:
```js
webContents.setWindowOpenHandler((details) => {
return {
action: 'allow',
overrideBrowserWindowOptions: {
resizable: details.features.includes('resizable=yes')
}
}
})
```
## Planned Breaking API Changes (37.0) ## Planned Breaking API Changes (37.0)
### Utility Process unhandled rejection behavior change ### Utility Process unhandled rejection behavior change

View file

@ -91,6 +91,12 @@ export function parseFeatures (features: string) {
delete parsed[key]; delete parsed[key];
} }
// Per spec - https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-open-dev
// windows are always resizable.
if (parsed.resizable !== undefined) {
delete parsed.resizable;
}
if (parsed.left !== undefined) parsed.x = parsed.left; if (parsed.left !== undefined) parsed.x = parsed.left;
if (parsed.top !== undefined) parsed.y = parsed.top; if (parsed.top !== undefined) parsed.y = parsed.top;

View file

@ -1273,6 +1273,16 @@ describe('chromium features', () => {
}); });
} }
it('is always resizable', async () => {
const w = new BrowserWindow({ show: false });
w.loadFile(path.resolve(__dirname, 'fixtures', 'blank.html'));
w.webContents.executeJavaScript(`
{ b = window.open('about:blank', '', 'resizable=no,show=no'); null }
`);
const [, popup] = await once(app, 'browser-window-created') as [any, BrowserWindow];
expect(popup.isResizable()).to.be.true();
});
// FIXME(zcbenz): This test is making the spec runner hang on exit on Windows. // FIXME(zcbenz): This test is making the spec runner hang on exit on Windows.
ifit(process.platform !== 'win32')('disables node integration when it is disabled on the parent window', async () => { ifit(process.platform !== 'win32')('disables node integration when it is disabled on the parent window', async () => {
const windowUrl = url.pathToFileURL(path.join(fixturesPath, 'pages', 'window-opener-no-node-integration.html')); const windowUrl = url.pathToFileURL(path.join(fixturesPath, 'pages', 'window-opener-no-node-integration.html'));