fix: will-attach-webview handler modifying params.instanceId does not break <webview> (#32386)
This commit is contained in:
parent
cbe68bdbb8
commit
99ee1fc0eb
5 changed files with 34 additions and 16 deletions
|
@ -73,6 +73,17 @@ function makeWebPreferences (embedder: Electron.WebContents, params: Record<stri
|
||||||
return webPreferences;
|
return webPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeLoadURLOptions (params: Record<string, any>) {
|
||||||
|
const opts: Electron.LoadURLOptions = {};
|
||||||
|
if (params.httpreferrer) {
|
||||||
|
opts.httpReferrer = params.httpreferrer;
|
||||||
|
}
|
||||||
|
if (params.useragent) {
|
||||||
|
opts.userAgent = params.useragent;
|
||||||
|
}
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new guest instance.
|
// Create a new guest instance.
|
||||||
const createGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, params: Record<string, any>) {
|
const createGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, params: Record<string, any>) {
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
|
@ -96,7 +107,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||||
|
|
||||||
// Init guest web view after attached.
|
// Init guest web view after attached.
|
||||||
guest.once('did-attach' as any, function (this: Electron.WebContents, event: Electron.Event) {
|
guest.once('did-attach' as any, function (this: Electron.WebContents, event: Electron.Event) {
|
||||||
params = this.attachParams!;
|
const params = this.attachParams!;
|
||||||
delete this.attachParams;
|
delete this.attachParams;
|
||||||
|
|
||||||
const previouslyAttached = this.viewInstanceId != null;
|
const previouslyAttached = this.viewInstanceId != null;
|
||||||
|
@ -108,14 +119,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.src) {
|
if (params.src) {
|
||||||
const opts: Electron.LoadURLOptions = {};
|
this.loadURL(params.src, params.opts);
|
||||||
if (params.httpreferrer) {
|
|
||||||
opts.httpReferrer = params.httpreferrer;
|
|
||||||
}
|
|
||||||
if (params.useragent) {
|
|
||||||
opts.userAgent = params.useragent;
|
|
||||||
}
|
|
||||||
this.loadURL(params.src, opts);
|
|
||||||
}
|
}
|
||||||
embedder.emit('did-attach-webview', event, guest);
|
embedder.emit('did-attach-webview', event, guest);
|
||||||
});
|
});
|
||||||
|
@ -204,13 +208,15 @@ const attachGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { instanceId } = params;
|
||||||
|
|
||||||
// If this guest is already attached to an element then remove it
|
// If this guest is already attached to an element then remove it
|
||||||
if (guestInstance.elementInstanceId) {
|
if (guestInstance.elementInstanceId) {
|
||||||
const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`;
|
const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`;
|
||||||
embedderElementsMap.delete(oldKey);
|
embedderElementsMap.delete(oldKey);
|
||||||
|
|
||||||
// Remove guest from embedder if moving across web views
|
// Remove guest from embedder if moving across web views
|
||||||
if (guest.viewInstanceId !== params.instanceId) {
|
if (guest.viewInstanceId !== instanceId) {
|
||||||
webViewManager.removeGuest(guestInstance.embedder, guestInstanceId);
|
webViewManager.removeGuest(guestInstance.embedder, guestInstanceId);
|
||||||
guestInstance.embedder._sendInternal(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${guest.viewInstanceId}`);
|
guestInstance.embedder._sendInternal(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${guest.viewInstanceId}`);
|
||||||
}
|
}
|
||||||
|
@ -221,12 +227,12 @@ const attachGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||||
const event = eventBinding.createWithSender(embedder);
|
const event = eventBinding.createWithSender(embedder);
|
||||||
embedder.emit('will-attach-webview', event, webPreferences, params);
|
embedder.emit('will-attach-webview', event, webPreferences, params);
|
||||||
if (event.defaultPrevented) {
|
if (event.defaultPrevented) {
|
||||||
if (guest.viewInstanceId == null) guest.viewInstanceId = params.instanceId;
|
if (guest.viewInstanceId == null) guest.viewInstanceId = instanceId;
|
||||||
guest.destroy();
|
guest.destroy();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
guest.attachParams = params;
|
guest.attachParams = { instanceId, src: params.src, opts: makeLoadURLOptions(params) };
|
||||||
embedderElementsMap.set(key, guestInstanceId);
|
embedderElementsMap.set(key, guestInstanceId);
|
||||||
|
|
||||||
guest.setEmbedder(embedder);
|
guest.setEmbedder(embedder);
|
||||||
|
|
|
@ -25,7 +25,6 @@ export class WebViewImpl {
|
||||||
public hasFocus = false
|
public hasFocus = false
|
||||||
public internalInstanceId?: number;
|
public internalInstanceId?: number;
|
||||||
public resizeObserver?: ResizeObserver;
|
public resizeObserver?: ResizeObserver;
|
||||||
public userAgentOverride?: string;
|
|
||||||
public viewInstanceId: number
|
public viewInstanceId: number
|
||||||
|
|
||||||
// on* Event handlers.
|
// on* Event handlers.
|
||||||
|
@ -180,8 +179,7 @@ export class WebViewImpl {
|
||||||
|
|
||||||
buildParams () {
|
buildParams () {
|
||||||
const params: Record<string, any> = {
|
const params: Record<string, any> = {
|
||||||
instanceId: this.viewInstanceId,
|
instanceId: this.viewInstanceId
|
||||||
userAgentOverride: this.userAgentOverride
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [attributeName, attribute] of this.attributes) {
|
for (const [attributeName, attribute] of this.attributes) {
|
||||||
|
|
|
@ -138,6 +138,12 @@ ipcMain.on('prevent-next-will-attach-webview', (event) => {
|
||||||
event.sender.once('will-attach-webview', event => event.preventDefault());
|
event.sender.once('will-attach-webview', event => event.preventDefault());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.on('break-next-will-attach-webview', (event, id) => {
|
||||||
|
event.sender.once('will-attach-webview', (event, webPreferences, params) => {
|
||||||
|
params.instanceId = null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.on('disable-node-on-next-will-attach-webview', (event, id) => {
|
ipcMain.on('disable-node-on-next-will-attach-webview', (event, id) => {
|
||||||
event.sender.once('will-attach-webview', (event, webPreferences, params) => {
|
event.sender.once('will-attach-webview', (event, webPreferences, params) => {
|
||||||
params.src = `file://${path.join(__dirname, '..', 'fixtures', 'pages', 'c.html')}`;
|
params.src = `file://${path.join(__dirname, '..', 'fixtures', 'pages', 'c.html')}`;
|
||||||
|
|
|
@ -1163,6 +1163,14 @@ describe('<webview> tag', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handler modifying params.instanceId does not break <webview>', async () => {
|
||||||
|
ipcRenderer.send('break-next-will-attach-webview');
|
||||||
|
|
||||||
|
await startLoadingWebViewAndWaitForMessage(webview, {
|
||||||
|
src: `file://${fixtures}/pages/a.html`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('supports preventing a webview from being created', async () => {
|
it('supports preventing a webview from being created', async () => {
|
||||||
ipcRenderer.send('prevent-next-will-attach-webview');
|
ipcRenderer.send('prevent-next-will-attach-webview');
|
||||||
|
|
||||||
|
|
2
typings/internal-electron.d.ts
vendored
2
typings/internal-electron.d.ts
vendored
|
@ -81,7 +81,7 @@ declare namespace Electron {
|
||||||
attachToIframe(embedderWebContents: Electron.WebContents, embedderFrameId: number): void;
|
attachToIframe(embedderWebContents: Electron.WebContents, embedderFrameId: number): void;
|
||||||
detachFromOuterFrame(): void;
|
detachFromOuterFrame(): void;
|
||||||
setEmbedder(embedder: Electron.WebContents): void;
|
setEmbedder(embedder: Electron.WebContents): void;
|
||||||
attachParams?: Record<string, any>;
|
attachParams?: { instanceId: number; src: string, opts: LoadURLOptions };
|
||||||
viewInstanceId: number;
|
viewInstanceId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue