fix: call loadUrl when opening new windows from links (#34159)

* fix: call loadUrl when opening new windows from links

* spec: add regression test
This commit is contained in:
Shelley Vohr 2022-05-11 20:34:33 +02:00 коммит произвёл GitHub
Родитель 6f8a36f404
Коммит dd6ce91f57
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 135 добавлений и 0 удалений

Просмотреть файл

@ -78,6 +78,19 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
...browserWindowOptions ...browserWindowOptions
}); });
if (!guest) {
// When we open a new window from a link (via OpenURLFromTab),
// the browser process is responsible for initiating navigation
// in the new window.
window.loadURL(url, {
httpReferrer: referrer,
...(postData && {
postData,
extraHeaders: formatPostDataHeaders(postData as Electron.UploadRawData[])
})
});
}
handleWindowLifecycleEvents({ embedder, frameName, guest: window, outlivesOpener }); handleWindowLifecycleEvents({ embedder, frameName, guest: window, outlivesOpener });
embedder.emit('did-create-window', window, { url, frameName, options: browserWindowOptions, disposition, referrer, postData }); embedder.emit('did-create-window', window, { url, frameName, options: browserWindowOptions, disposition, referrer, postData });
@ -243,6 +256,15 @@ export function makeWebPreferences ({ embedder, secureOverrideWebPreferences = {
}; };
} }
function formatPostDataHeaders (postData: PostData) {
if (!postData) return;
const { contentType, boundary } = parseContentTypeFormat(postData);
if (boundary != null) { return `content-type: ${contentType}; boundary=${boundary}`; }
return `content-type: ${contentType}`;
}
const MULTIPART_CONTENT_TYPE = 'multipart/form-data'; const MULTIPART_CONTENT_TYPE = 'multipart/form-data';
const URL_ENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded'; const URL_ENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded';

Просмотреть файл

@ -1937,6 +1937,26 @@ describe('BrowserWindow module', () => {
}); });
}); });
describe('Opening a BrowserWindow from a link', () => {
let appProcess: childProcess.ChildProcessWithoutNullStreams | undefined;
afterEach(() => {
if (appProcess && !appProcess.killed) {
appProcess.kill();
appProcess = undefined;
}
});
it('can properly open and load a new window from a link', async () => {
const appPath = path.join(__dirname, 'fixtures', 'apps', 'open-new-window-from-link');
appProcess = childProcess.spawn(process.execPath, [appPath]);
const [code] = await emittedOnce(appProcess, 'exit');
expect(code).to.equal(0);
});
});
describe('BrowserWindow.fromWebContents(webContents)', () => { describe('BrowserWindow.fromWebContents(webContents)', () => {
afterEach(closeAllWindows); afterEach(closeAllWindows);

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
<title>Hello World!</title>
</head>
<body>
<a href="./new-window-page.html">Open New Window</a>
</body>
</html>

Просмотреть файл

@ -0,0 +1,64 @@
const { app, BrowserWindow } = require('electron');
const path = require('path');
async function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
x: 100,
y: 100,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: false,
nodeIntegration: true
}
});
await mainWindow.loadFile('index.html');
const rect = await mainWindow.webContents.executeJavaScript('JSON.parse(JSON.stringify(document.querySelector("a").getBoundingClientRect()))');
const x = rect.x + rect.width / 2;
const y = rect.y + rect.height / 2;
function click (x, y, options) {
x = Math.floor(x);
y = Math.floor(y);
mainWindow.webContents.sendInputEvent({
type: 'mouseDown',
button: 'left',
x,
y,
clickCount: 1,
...options
});
mainWindow.webContents.sendInputEvent({
type: 'mouseUp',
button: 'left',
x,
y,
clickCount: 1,
...options
});
}
click(x, y, { modifiers: ['shift'] });
}
app.whenReady().then(() => {
app.on('web-contents-created', (e, wc) => {
wc.on('render-process-gone', (e, details) => {
console.error(details);
process.exit(1);
});
wc.on('did-finish-load', () => {
const title = wc.getTitle();
if (title === 'Window From Link') {
process.exit(0);
}
});
});
createWindow();
});

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
<title>Window From Link</title>
</head>
<body>
I'm a window opened from a link!
</body>
</html>

Просмотреть файл

@ -0,0 +1,4 @@
{
"name": "electron-test-open-new-window-from-link",
"main": "main.js"
}

Просмотреть файл

@ -0,0 +1,3 @@
window.addEventListener('click', e => {
console.log('click', e);
});