Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: WebContents.opener is undefined for windows opened via links with target=_blank #36025

Closed
3 tasks done
mgalla10 opened this issue Oct 13, 2022 · 4 comments
Closed
3 tasks done
Labels
21-x-y bug 🪲 component/webcontents has-repro-gist Issue can be reproduced with code at https://gist.github.com/ invalid status/confirmed A maintainer reproduced the bug or agreed with the feature

Comments

@mgalla10
Copy link

Preflight Checklist

Electron Version

21.1.1

What operating system are you using?

Windows

Operating System Version

Windows 10 version 21H2

What arch are you using?

x64

Last Known Working Electron version

No response

Expected Behavior

If a new window is opened via a programmatic call to window.open(), that window's webContents.opener provides a reference to the frame that opened that window. I would expect the same behavior for new windows opened via links with target="_blank".

Actual Behavior

For new windows opened via links with target="_blank", the window's webContents.opener is undefined. The opener is provided as expected if the target is a specified frame name (which doesn't already exist).

Testcase Gist URL

https://gist.github.com/8dc8da58f36238db0ef950a0a1d639d9

Additional Information

No response

@codebytere
Copy link
Member

cc @samuelmaddock given this refs #35140

@codebytere codebytere added component/webcontents 21-x-y status/confirmed A maintainer reproduced the bug or agreed with the feature has-repro-gist Issue can be reproduced with code at https://gist.github.com/ labels Oct 17, 2022
@samuelmaddock
Copy link
Member

This is expected behavior when using [target=_blank]. It can be avoided by adding a rel="opener" attribute.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target

Note: Setting target="_blank" on elements implicitly provides the same rel behavior as setting rel="noopener" which does not set window.opener.

I only learned about this when writing the tests for this API:

it('can get opener with a[target=_blank][rel=opener]', async () => {
const w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
await w.loadURL('about:blank');
const childPromise = emittedOnce(w.webContents, 'did-create-window');
w.webContents.executeJavaScript(`(function() {
const a = document.createElement('a');
a.target = '_blank';
a.rel = 'opener';
a.href = 'about:blank';
a.click();
}())`, true);
const [childWindow] = await childPromise;
expect(childWindow.webContents.opener).to.equal(w.webContents.mainFrame);
});
it('has no opener with a[target=_blank][rel=noopener]', async () => {
const w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
await w.loadURL('about:blank');
const childPromise = emittedOnce(w.webContents, 'did-create-window');
w.webContents.executeJavaScript(`(function() {
const a = document.createElement('a');
a.target = '_blank';
a.rel = 'noopener';
a.href = 'about:blank';
a.click();
}())`, true);
const [childWindow] = await childPromise;
expect(childWindow.webContents.opener).to.be.null();
});

@pushkin-
Copy link

@samuelmaddock huh, so even Electron isn't able to access/know the window that opened the child window? I'm not totally following how they're connected. If I window.open a window but disable window.opener, won't webContents.opener still give me the correct result? So how is that different from a link that opens a window with window.opener disabled.

@samuelmaddock
Copy link
Member

@samuelmaddock huh, so even Electron isn't able to access/know the window that opened the child window? I'm not totally following how they're connected. If I window.open a window but disable window.opener, won't webContents.opener still give me the correct result? So how is that different from a link that opens a window with window.opener disabled.

WebContents.opener is the main process equivalent of window.opener (MDN).

If window.open(url, name, 'noopener') is set, WebContents.opener will be null as seen in the tests:

it('can get opener with window.open()', async () => {
const w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
await w.loadURL('about:blank');
const childPromise = emittedOnce(w.webContents, 'did-create-window');
w.webContents.executeJavaScript('window.open("about:blank")', true);
const [childWindow] = await childPromise;
expect(childWindow.webContents.opener).to.equal(w.webContents.mainFrame);
});
it('has no opener when using "noopener"', async () => {
const w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
await w.loadURL('about:blank');
const childPromise = emittedOnce(w.webContents, 'did-create-window');
w.webContents.executeJavaScript('window.open("about:blank", undefined, "noopener")', true);
const [childWindow] = await childPromise;
expect(childWindow.webContents.opener).to.be.null();
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
21-x-y bug 🪲 component/webcontents has-repro-gist Issue can be reproduced with code at https://gist.github.com/ invalid status/confirmed A maintainer reproduced the bug or agreed with the feature
Projects
None yet
Development

No branches or pull requests

4 participants