Browse Source

chore: remove deprecated 'new-window' event (#34526)

Milan Burda 2 years ago
parent
commit
8646bf8d30

+ 0 - 3
docs/api/structures/new-window-web-contents-event.md

@@ -1,3 +0,0 @@
-# NewWindowWebContentsEvent Object extends `Event`
-
-* `newGuest` BrowserWindow (optional)

+ 0 - 58
docs/api/web-contents.md

@@ -156,64 +156,6 @@ Returns:
 
 Emitted when page receives favicon urls.
 
-#### Event: 'new-window' _Deprecated_
-
-Returns:
-
-* `event` NewWindowWebContentsEvent
-* `url` string
-* `frameName` string
-* `disposition` string - Can be `default`, `foreground-tab`, `background-tab`,
-  `new-window`, `save-to-disk` and `other`.
-* `options` BrowserWindowConstructorOptions - The options which will be used for creating the new
-  [`BrowserWindow`](browser-window.md).
-* `additionalFeatures` string[] - The non-standard features (features not handled
-  by Chromium or Electron) given to `window.open()`. Deprecated, and will now
-  always be the empty array `[]`.
-* `referrer` [Referrer](structures/referrer.md) - The referrer that will be
-  passed to the new window. May or may not result in the `Referer` header being
-  sent, depending on the referrer policy.
-* `postBody` [PostBody](structures/post-body.md) (optional) - The post data that
-  will be sent to the new window, along with the appropriate headers that will
-  be set. If no post data is to be sent, the value will be `null`. Only defined
-  when the window is being created by a form that set `target=_blank`.
-
-Deprecated in favor of [`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
-
-Emitted when the page requests to open a new window for a `url`. It could be
-requested by `window.open` or an external link like `<a target='_blank'>`.
-
-By default a new `BrowserWindow` will be created for the `url`.
-
-Calling `event.preventDefault()` will prevent Electron from automatically creating a
-new [`BrowserWindow`](browser-window.md). If you call `event.preventDefault()` and manually create a new
-[`BrowserWindow`](browser-window.md) then you must set `event.newGuest` to reference the new [`BrowserWindow`](browser-window.md)
-instance, failing to do so may result in unexpected behavior. For example:
-
-```javascript
-myBrowserWindow.webContents.on('new-window', (event, url, frameName, disposition, options, additionalFeatures, referrer, postBody) => {
-  event.preventDefault()
-  const win = new BrowserWindow({
-    webContents: options.webContents, // use existing webContents if provided
-    show: false
-  })
-  win.once('ready-to-show', () => win.show())
-  if (!options.webContents) {
-    const loadOptions = {
-      httpReferrer: referrer
-    }
-    if (postBody != null) {
-      const { data, contentType, boundary } = postBody
-      loadOptions.postData = postBody.data
-      loadOptions.extraHeaders = `content-type: ${contentType}; boundary=${boundary}`
-    }
-
-    win.loadURL(url, loadOptions) // existing webContents will be navigated automatically
-  }
-  event.newGuest = win
-})
-```
-
 #### Event: 'did-create-window'
 
 Returns:

+ 0 - 27
docs/api/webview-tag.md

@@ -805,33 +805,6 @@ const requestId = webview.findInPage('test')
 console.log(requestId)
 ```
 
-### Event: 'new-window'
-
-Returns:
-
-* `url` string
-* `frameName` string
-* `disposition` string - Can be `default`, `foreground-tab`, `background-tab`,
-  `new-window`, `save-to-disk` and `other`.
-* `options` BrowserWindowConstructorOptions - The options which should be used for creating the new
-  [`BrowserWindow`](browser-window.md).
-
-Fired when the guest page attempts to open a new browser window.
-
-The following example code opens the new url in system's default browser.
-
-```javascript
-const { shell } = require('electron')
-const webview = document.querySelector('webview')
-
-webview.addEventListener('new-window', async (e) => {
-  const protocol = (new URL(e.url)).protocol
-  if (protocol === 'http:' || protocol === 'https:') {
-    await shell.openExternal(e.url)
-  }
-})
-```
-
 ### Event: 'will-navigate'
 
 Returns:

+ 18 - 0
docs/breaking-changes.md

@@ -12,6 +12,24 @@ This document uses the following convention to categorize breaking changes:
 * **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
 * **Removed:** An API or feature was removed, and is no longer supported by Electron.
 
+## Planned Breaking API Changes (22.0)
+
+### Removed: WebContents `new-window` event
+
+The `new-window` event of WebContents has been removed. It is replaced by [`webContents.setWindowOpenHandler()`](api/web-contents.md#contentssetwindowopenhandlerhandler).
+
+```js
+// Removed in Electron 21
+webContents.on('new-window', (event) => {
+  event.preventDefault()
+})
+
+// Replace with
+webContents.setWindowOpenHandler((details) => {
+  return { action: 'deny' }
+})
+```
+
 ## Planned Breaking API Changes (20.0)
 
 ### Behavior Changed: V8 Memory Cage enabled

+ 0 - 1
filenames.auto.gni

@@ -98,7 +98,6 @@ auto_filenames = {
     "docs/api/structures/mime-typed-buffer.md",
     "docs/api/structures/mouse-input-event.md",
     "docs/api/structures/mouse-wheel-input-event.md",
-    "docs/api/structures/new-window-web-contents-event.md",
     "docs/api/structures/notification-action.md",
     "docs/api/structures/notification-response.md",
     "docs/api/structures/payment-discount.md",

+ 4 - 8
lib/browser/api/web-contents.ts

@@ -670,7 +670,6 @@ WebContents.prototype._init = function () {
       const options = result.browserWindowConstructorOptions;
       if (!event.defaultPrevented) {
         openGuestWindow({
-          event,
           embedder: event.sender,
           disposition,
           referrer,
@@ -717,18 +716,16 @@ WebContents.prototype._init = function () {
           transparent: windowOpenOverriddenOptions.transparent,
           ...windowOpenOverriddenOptions.webPreferences
         } : undefined;
-        // TODO(zcbenz): The features string is parsed twice: here where it is
-        // passed to C++, and in |makeBrowserWindowOptions| later where it is
-        // not actually used since the WebContents is created here.
-        // We should be able to remove the latter once the |new-window| event
-        // is removed.
         const { webPreferences: parsedWebPreferences } = parseFeatures(rawFeatures);
-        // Parameters should keep same with |makeBrowserWindowOptions|.
         const webPreferences = makeWebPreferences({
           embedder: event.sender,
           insecureParsedWebPreferences: parsedWebPreferences,
           secureOverrideWebPreferences
         });
+        windowOpenOverriddenOptions = {
+          ...windowOpenOverriddenOptions,
+          webPreferences
+        };
         this._setNextChildWebPreferences(webPreferences);
       }
     });
@@ -750,7 +747,6 @@ WebContents.prototype._init = function () {
       }
 
       openGuestWindow({
-        event,
         embedder: event.sender,
         guest: webContents,
         overrideBrowserWindowOptions: overriddenOptions,

+ 0 - 16
lib/browser/guest-view-manager.ts

@@ -22,13 +22,6 @@ const supportedWebViewEvents = Object.keys(webViewEvents);
 const guestInstances = new Map<number, GuestInstance>();
 const embedderElementsMap = new Map<string, number>();
 
-function sanitizeOptionsForGuest (options: Record<string, any>) {
-  const ret = { ...options };
-  // WebContents values can't be sent over IPC.
-  delete ret.webContents;
-  return ret;
-}
-
 function makeWebPreferences (embedder: Electron.WebContents, params: Record<string, any>) {
   // parse the 'webpreferences' attribute string, if set
   // this uses the same parsing rules as window.open uses for its features
@@ -156,15 +149,6 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
     });
   }
 
-  guest.on('new-window', function (event, url, frameName, disposition, options) {
-    sendToEmbedder(IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT, 'new-window', {
-      url,
-      frameName,
-      disposition,
-      options: sanitizeOptionsForGuest(options)
-    });
-  });
-
   // Dispatch guest's IPC messages to embedder.
   guest.on('ipc-message-host' as any, function (event: Electron.IpcMainEvent, channel: string, args: any[]) {
     sendToEmbedder(IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT, 'ipc-message', {

+ 10 - 111
lib/browser/guest-window-manager.ts

@@ -5,7 +5,7 @@
  * out-of-process (cross-origin) are created here. "Embedder" roughly means
  * "parent."
  */
-import { BrowserWindow, deprecate } from 'electron/main';
+import { BrowserWindow } from 'electron/main';
 import type { BrowserWindowConstructorOptions, Referrer, WebContents, LoadURLOptions } from 'electron/main';
 import { parseFeatures } from '@electron/internal/browser/parse-features-string';
 
@@ -24,13 +24,8 @@ const getGuestWindowByFrameName = (name: string) => frameNamesToWindow.get(name)
 /**
  * `openGuestWindow` is called to create and setup event handling for the new
  * window.
- *
- * Until its removal in 12.0.0, the `new-window` event is fired, allowing the
- * user to preventDefault() on the passed event (which ends up calling
- * DestroyWebContents).
  */
-export function openGuestWindow ({ event, embedder, guest, referrer, disposition, postData, overrideBrowserWindowOptions, windowOpenArgs, outlivesOpener }: {
-  event: { sender: WebContents, defaultPrevented: boolean },
+export function openGuestWindow ({ embedder, guest, referrer, disposition, postData, overrideBrowserWindowOptions, windowOpenArgs, outlivesOpener }: {
   embedder: WebContents,
   guest?: WebContents,
   referrer: Referrer,
@@ -41,23 +36,14 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
   outlivesOpener: boolean,
 }): BrowserWindow | undefined {
   const { url, frameName, features } = windowOpenArgs;
-  const browserWindowOptions = makeBrowserWindowOptions({
-    embedder,
-    features,
-    overrideOptions: overrideBrowserWindowOptions
-  });
-
-  const didCancelEvent = emitDeprecatedNewWindowEvent({
-    event,
-    embedder,
-    guest,
-    browserWindowOptions,
-    windowOpenArgs,
-    disposition,
-    postData,
-    referrer
-  });
-  if (didCancelEvent) return;
+  const { options: parsedOptions } = parseFeatures(features);
+  const browserWindowOptions = {
+    show: true,
+    width: 800,
+    height: 600,
+    ...parsedOptions,
+    ...overrideBrowserWindowOptions
+  };
 
   // To spec, subsequent window.open calls with the same frame name (`target` in
   // spec parlance) will reuse the previous window.
@@ -134,68 +120,6 @@ const handleWindowLifecycleEvents = function ({ embedder, guest, frameName, outl
   }
 };
 
-/**
- * Deprecated in favor of `webContents.setWindowOpenHandler` and
- * `did-create-window` in 11.0.0. Will be removed in 12.0.0.
- */
-function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs, browserWindowOptions, disposition, referrer, postData }: {
-  event: { sender: WebContents, defaultPrevented: boolean, newGuest?: BrowserWindow },
-  embedder: WebContents,
-  guest?: WebContents,
-  windowOpenArgs: WindowOpenArgs,
-  browserWindowOptions: BrowserWindowConstructorOptions,
-  disposition: string,
-  referrer: Referrer,
-  postData?: PostData,
-}): boolean {
-  const { url, frameName } = windowOpenArgs;
-  const isWebViewWithPopupsDisabled = embedder.getType() === 'webview' && embedder.getLastWebPreferences()!.disablePopups;
-  const postBody = postData ? {
-    data: postData,
-    ...parseContentTypeFormat(postData)
-  } : null;
-
-  if (embedder.listenerCount('new-window') > 0) {
-    deprecate.log('The new-window event is deprecated and will be removed. Please use contents.setWindowOpenHandler() instead.');
-  }
-
-  embedder.emit(
-    'new-window',
-    event,
-    url,
-    frameName,
-    disposition,
-    {
-      ...browserWindowOptions,
-      webContents: guest
-    },
-    [], // additionalFeatures
-    referrer,
-    postBody
-  );
-
-  const { newGuest } = event;
-  if (isWebViewWithPopupsDisabled) return true;
-  if (event.defaultPrevented) {
-    if (newGuest) {
-      if (guest === newGuest.webContents) {
-        // The webContents is not changed, so set defaultPrevented to false to
-        // stop the callers of this event from destroying the webContents.
-        event.defaultPrevented = false;
-      }
-
-      handleWindowLifecycleEvents({
-        embedder: event.sender,
-        guest: newGuest,
-        frameName,
-        outlivesOpener: false
-      });
-    }
-    return true;
-  }
-  return false;
-}
-
 // Security options that child windows will always inherit from parent windows
 const securityWebPreferences: { [key: string]: boolean } = {
   contextIsolation: true,
@@ -207,31 +131,6 @@ const securityWebPreferences: { [key: string]: boolean } = {
   enableWebSQL: false
 };
 
-function makeBrowserWindowOptions ({ embedder, features, overrideOptions }: {
-  embedder: WebContents,
-  features: string,
-  overrideOptions?: BrowserWindowConstructorOptions,
-}) {
-  const { options: parsedOptions, webPreferences: parsedWebPreferences } = parseFeatures(features);
-
-  return {
-    show: true,
-    width: 800,
-    height: 600,
-    ...parsedOptions,
-    ...overrideOptions,
-    // Note that for normal code path an existing WebContents created by
-    // Chromium will be used, with web preferences parsed in the
-    // |-will-add-new-contents| event.
-    // The |webPreferences| here is only used by the |new-window| event.
-    webPreferences: makeWebPreferences({
-      embedder,
-      insecureParsedWebPreferences: parsedWebPreferences,
-      secureOverrideWebPreferences: overrideOptions && overrideOptions.webPreferences
-    })
-  } as Electron.BrowserViewConstructorOptions;
-}
-
 export function makeWebPreferences ({ embedder, secureOverrideWebPreferences = {}, insecureParsedWebPreferences: parsedWebPreferences = {} }: {
   embedder: WebContents,
   insecureParsedWebPreferences?: ReturnType<typeof parseFeatures>['webPreferences'],

+ 3 - 115
spec-main/api-browser-window-spec.ts

@@ -5,7 +5,7 @@ import * as fs from 'fs';
 import * as qs from 'querystring';
 import * as http from 'http';
 import { AddressInfo } from 'net';
-import { app, BrowserWindow, BrowserView, dialog, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents, BrowserWindowConstructorOptions } from 'electron/main';
+import { app, BrowserWindow, BrowserView, dialog, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents } from 'electron/main';
 
 import { emittedOnce, emittedUntil, emittedNTimes } from './events-helpers';
 import { ifit, ifdescribe, defer, delay } from './spec-helpers';
@@ -3080,7 +3080,7 @@ describe('BrowserWindow module', () => {
         expect(argv).to.include('--enable-sandbox');
       });
 
-      it('should open windows with the options configured via new-window event listeners', async () => {
+      it('should open windows with the options configured via setWindowOpenHandler handlers', async () => {
         const w = new BrowserWindow({
           show: false,
           webPreferences: {
@@ -3171,30 +3171,6 @@ describe('BrowserWindow module', () => {
         });
       });
 
-      it('supports calling preventDefault on new-window events', (done) => {
-        const w = new BrowserWindow({
-          show: false,
-          webPreferences: {
-            sandbox: true
-          }
-        });
-        const initialWebContents = webContents.getAllWebContents().map((i) => i.id);
-        w.webContents.once('new-window', (e) => {
-          e.preventDefault();
-          // We need to give it some time so the windows get properly disposed (at least on OSX).
-          setTimeout(() => {
-            const currentWebContents = webContents.getAllWebContents().map((i) => i.id);
-            try {
-              expect(currentWebContents).to.deep.equal(initialWebContents);
-              done();
-            } catch (error) {
-              done(e);
-            }
-          }, 100);
-        });
-        w.loadFile(path.join(fixtures, 'pages', 'window-open.html'));
-      });
-
       it('validates process APIs access in sandboxed renderer', async () => {
         const w = new BrowserWindow({
           show: false,
@@ -3350,7 +3326,7 @@ describe('BrowserWindow module', () => {
         w.loadFile(path.join(fixtures, 'api', 'new-window-webview.html'));
         await webviewLoaded;
       });
-      it('should open windows with the options configured via new-window event listeners', async () => {
+      it('should open windows with the options configured via setWindowOpenHandler handlers', async () => {
         const preloadPath = path.join(mainFixtures, 'api', 'new-window-preload.js');
         w.webContents.setWindowOpenHandler(() => ({
           action: 'allow',
@@ -3720,94 +3696,6 @@ describe('BrowserWindow module', () => {
     });
   });
 
-  describe('new-window event', () => {
-    afterEach(closeAllWindows);
-
-    it('emits when window.open is called', (done) => {
-      const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
-      w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
-        e.preventDefault();
-        try {
-          expect(url).to.equal('http://host/');
-          expect(frameName).to.equal('host');
-          expect((options as any)['this-is-not-a-standard-feature']).to.equal(true);
-          done();
-        } catch (e) {
-          done(e);
-        }
-      });
-      w.loadFile(path.join(fixtures, 'pages', 'window-open.html'));
-    });
-
-    it('emits when window.open is called with no webPreferences', (done) => {
-      const w = new BrowserWindow({ show: false });
-      w.webContents.once('new-window', function (e, url, frameName, disposition, options) {
-        e.preventDefault();
-        try {
-          expect(url).to.equal('http://host/');
-          expect(frameName).to.equal('host');
-          expect((options as any)['this-is-not-a-standard-feature']).to.equal(true);
-          done();
-        } catch (e) {
-          done(e);
-        }
-      });
-      w.loadFile(path.join(fixtures, 'pages', 'window-open.html'));
-    });
-
-    it('emits when link with target is called', (done) => {
-      const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
-      w.webContents.once('new-window', (e, url, frameName) => {
-        e.preventDefault();
-        try {
-          expect(url).to.equal('http://host/');
-          expect(frameName).to.equal('target');
-          done();
-        } catch (e) {
-          done(e);
-        }
-      });
-      w.loadFile(path.join(fixtures, 'pages', 'target-name.html'));
-    });
-
-    it('includes all properties', async () => {
-      const w = new BrowserWindow({ show: false });
-
-      const p = new Promise<{
-        url: string,
-        frameName: string,
-        disposition: string,
-        options: BrowserWindowConstructorOptions,
-        additionalFeatures: string[],
-        referrer: Electron.Referrer,
-        postBody: Electron.PostBody
-      }>((resolve) => {
-        w.webContents.once('new-window', (e, url, frameName, disposition, options, additionalFeatures, referrer, postBody) => {
-          e.preventDefault();
-          resolve({ url, frameName, disposition, options, additionalFeatures, referrer, postBody });
-        });
-      });
-      w.loadURL(`data:text/html,${encodeURIComponent(`
-        <form target="_blank" method="POST" id="form" action="http://example.com/test">
-          <input type="text" name="post-test-key" value="post-test-value"></input>
-        </form>
-        <script>form.submit()</script>
-      `)}`);
-      const { url, frameName, disposition, options, additionalFeatures, referrer, postBody } = await p;
-      expect(url).to.equal('http://example.com/test');
-      expect(frameName).to.equal('');
-      expect(disposition).to.equal('foreground-tab');
-      expect(options).to.be.an('object').not.null();
-      expect(referrer.policy).to.equal('strict-origin-when-cross-origin');
-      expect(referrer.url).to.equal('');
-      expect(additionalFeatures).to.deep.equal([]);
-      expect(postBody.data).to.have.length(1);
-      expect(postBody.data[0].type).to.equal('rawData');
-      expect((postBody.data[0] as any).bytes).to.deep.equal(Buffer.from('post-test-key=post-test-value'));
-      expect(postBody.contentType).to.equal('application/x-www-form-urlencoded');
-    });
-  });
-
   ifdescribe(process.platform !== 'linux')('max/minimize events', () => {
     afterEach(closeAllWindows);
     it('emits an event when window is maximized', async () => {

+ 0 - 22
spec-main/api-web-contents-spec.ts

@@ -2102,26 +2102,4 @@ describe('webContents module', () => {
       expect(params.y).to.be.a('number');
     });
   });
-
-  it('emits a cancelable event before creating a child webcontents', async () => {
-    const w = new BrowserWindow({
-      show: false,
-      webPreferences: {
-        sandbox: true
-      }
-    });
-    w.webContents.on('-will-add-new-contents' as any, (event: any, url: any) => {
-      expect(url).to.equal('about:blank');
-      event.preventDefault();
-    });
-    let wasCalled = false;
-    w.webContents.on('new-window' as any, () => {
-      wasCalled = true;
-    });
-    await w.loadURL('about:blank');
-    await w.webContents.executeJavaScript('window.open(\'about:blank\')');
-    await new Promise((resolve) => { process.nextTick(resolve); });
-    expect(wasCalled).to.equal(false);
-    await closeAllWindows();
-  });
 });

+ 0 - 161
spec-main/fixtures/snapshots/native-window-open.snapshot.txt

@@ -1,161 +0,0 @@
-[
-  [
-    "top=5,left=10,resizable=no",
-    {
-      "sender": "[WebContents]"
-    },
-    "about:blank",
-    "frame-name",
-    "new-window",
-    {
-      "show": true,
-      "width": 800,
-      "height": 600,
-      "top": 5,
-      "left": 10,
-      "resizable": false,
-      "x": 10,
-      "y": 5,
-      "webPreferences": {
-        "contextIsolation": true,
-        "nodeIntegration": false,
-        "sandbox": true,
-        "webviewTag": false,
-        "nodeIntegrationInSubFrames": false
-      },
-      "webContents": "[WebContents]"
-    },
-    [],
-    {
-      "url": "",
-      "policy": "strict-origin-when-cross-origin"
-    },
-    null
-  ],
-  [
-    "zoomFactor=2,resizable=0,x=0,y=10",
-    {
-      "sender": "[WebContents]"
-    },
-    "about:blank",
-    "frame-name",
-    "new-window",
-    {
-      "show": true,
-      "width": 800,
-      "height": 600,
-      "resizable": false,
-      "x": 0,
-      "y": 10,
-      "webPreferences": {
-        "zoomFactor": "2",
-        "contextIsolation": true,
-        "nodeIntegration": false,
-        "sandbox": true,
-        "webviewTag": false,
-        "nodeIntegrationInSubFrames": false
-      },
-      "webContents": "[WebContents]"
-    },
-    [],
-    {
-      "url": "",
-      "policy": "strict-origin-when-cross-origin"
-    },
-    null
-  ],
-  [
-    "backgroundColor=gray,webPreferences=0,x=100,y=100",
-    {
-      "sender": "[WebContents]"
-    },
-    "about:blank",
-    "frame-name",
-    "new-window",
-    {
-      "show": true,
-      "width": 800,
-      "height": 600,
-      "backgroundColor": "gray",
-      "webPreferences": {
-        "contextIsolation": true,
-        "nodeIntegration": false,
-        "sandbox": true,
-        "webviewTag": false,
-        "nodeIntegrationInSubFrames": false
-      },
-      "x": 100,
-      "y": 100,
-      "webContents": "[WebContents]"
-    },
-    [],
-    {
-      "url": "",
-      "policy": "strict-origin-when-cross-origin"
-    },
-    null
-  ],
-  [
-    "x=50,y=20,title=sup",
-    {
-      "sender": "[WebContents]"
-    },
-    "about:blank",
-    "frame-name",
-    "new-window",
-    {
-      "show": true,
-      "width": 800,
-      "height": 600,
-      "x": 50,
-      "y": 20,
-      "title": "sup",
-      "webPreferences": {
-        "contextIsolation": true,
-        "nodeIntegration": false,
-        "sandbox": true,
-        "webviewTag": false,
-        "nodeIntegrationInSubFrames": false
-      },
-      "webContents": "[WebContents]"
-    },
-    [],
-    {
-      "url": "",
-      "policy": "strict-origin-when-cross-origin"
-    },
-    null
-  ],
-  [
-    "show=false,top=1,left=1",
-    {
-      "sender": "[WebContents]"
-    },
-    "about:blank",
-    "frame-name",
-    "new-window",
-    {
-      "show": false,
-      "width": 800,
-      "height": 600,
-      "top": 1,
-      "left": 1,
-      "x": 1,
-      "y": 1,
-      "webPreferences": {
-        "contextIsolation": true,
-        "nodeIntegration": false,
-        "sandbox": true,
-        "webviewTag": false,
-        "nodeIntegrationInSubFrames": false
-      },
-      "webContents": "[WebContents]"
-    },
-    [],
-    {
-      "url": "",
-      "policy": "strict-origin-when-cross-origin"
-    },
-    null
-  ]
-]

+ 1 - 107
spec-main/guest-window-manager-spec.ts

@@ -1,75 +1,8 @@
 import { BrowserWindow } from 'electron';
-import { writeFileSync, readFileSync } from 'fs';
-import { resolve } from 'path';
 import { expect, assert } from 'chai';
 import { closeAllWindows } from './window-helpers';
 const { emittedOnce } = require('./events-helpers');
 
-function genSnapshot (browserWindow: BrowserWindow, features: string) {
-  return new Promise((resolve) => {
-    browserWindow.webContents.on('new-window', (...args: any[]) => {
-      resolve([features, ...args]);
-    });
-    browserWindow.webContents.executeJavaScript(`window.open('about:blank', 'frame-name', '${features}') && true`);
-  });
-}
-
-describe('new-window event', () => {
-  const snapshotFileName = 'native-window-open.snapshot.txt';
-  const browserWindowOptions = {
-    show: false,
-    width: 200,
-    title: 'cool',
-    backgroundColor: 'blue',
-    focusable: false,
-    webPreferences: {
-      sandbox: true
-    }
-  };
-
-  const snapshotFile = resolve(__dirname, 'fixtures', 'snapshots', snapshotFileName);
-  let browserWindow: BrowserWindow;
-  let existingSnapshots: any[];
-
-  before(() => {
-    existingSnapshots = parseSnapshots(readFileSync(snapshotFile, { encoding: 'utf8' }));
-  });
-
-  beforeEach((done) => {
-    browserWindow = new BrowserWindow(browserWindowOptions);
-    browserWindow.loadURL('about:blank');
-    browserWindow.on('ready-to-show', () => { done(); });
-  });
-
-  afterEach(closeAllWindows);
-
-  const newSnapshots: any[] = [];
-  [
-    'top=5,left=10,resizable=no',
-    'zoomFactor=2,resizable=0,x=0,y=10',
-    'backgroundColor=gray,webPreferences=0,x=100,y=100',
-    'x=50,y=20,title=sup',
-    'show=false,top=1,left=1'
-  ].forEach((features, index) => {
-    /**
-     * ATTN: If this test is failing, you likely just need to change
-     * `shouldOverwriteSnapshot` to true and then evaluate the snapshot diff
-     * to see if the change is harmless.
-     */
-    it(`matches snapshot for ${features}`, async () => {
-      const newSnapshot = await genSnapshot(browserWindow, features);
-      newSnapshots.push(newSnapshot);
-      // TODO: The output when these fail could be friendlier.
-      expect(stringifySnapshots(newSnapshot)).to.equal(stringifySnapshots(existingSnapshots[index]));
-    });
-  });
-
-  after(() => {
-    const shouldOverwriteSnapshot = false;
-    if (shouldOverwriteSnapshot) writeFileSync(snapshotFile, stringifySnapshots(newSnapshots, true));
-  });
-});
-
 describe('webContents.setWindowOpenHandler', () => {
   let browserWindow: BrowserWindow;
   beforeEach(async () => {
@@ -95,10 +28,6 @@ describe('webContents.setWindowOpenHandler', () => {
       }
     });
 
-    browserWindow.webContents.on('new-window', () => {
-      assert.fail('new-window should not be called with an overridden window.open');
-    });
-
     browserWindow.webContents.on('did-create-window', () => {
       assert.fail('did-create-window should not be called with an overridden window.open');
     });
@@ -118,10 +47,6 @@ describe('webContents.setWindowOpenHandler', () => {
       });
     });
 
-    browserWindow.webContents.on('new-window', () => {
-      assert.fail('new-window should not be called with an overridden window.open');
-    });
-
     browserWindow.webContents.on('did-create-window', () => {
       assert.fail('did-create-window should not be called with an overridden window.open');
     });
@@ -138,9 +63,6 @@ describe('webContents.setWindowOpenHandler', () => {
         return { action: 'deny' };
       });
     });
-    browserWindow.webContents.on('new-window', () => {
-      assert.fail('new-window should not be called with an overridden window.open');
-    });
 
     browserWindow.webContents.on('did-create-window', () => {
       assert.fail('did-create-window should not be called with an overridden window.open');
@@ -158,9 +80,6 @@ describe('webContents.setWindowOpenHandler', () => {
         return { action: 'deny' };
       });
     });
-    browserWindow.webContents.on('new-window', () => {
-      assert.fail('new-window should not be called with an overridden window.open');
-    });
 
     browserWindow.webContents.on('did-create-window', () => {
       assert.fail('did-create-window should not be called with an overridden window.open');
@@ -180,9 +99,6 @@ describe('webContents.setWindowOpenHandler', () => {
         return { action: 'deny' };
       });
     });
-    browserWindow.webContents.on('new-window', () => {
-      assert.fail('new-window should not be called with an overridden window.open');
-    });
 
     browserWindow.webContents.on('did-create-window', () => {
       assert.fail('did-create-window should not be called with an overridden window.open');
@@ -257,10 +173,7 @@ describe('webContents.setWindowOpenHandler', () => {
       browserWindow.webContents.executeJavaScript("window.open('about:blank', '', 'show=no') && true");
     });
 
-    await Promise.all([
-      emittedOnce(browserWindow.webContents, 'did-create-window'),
-      emittedOnce(browserWindow.webContents, 'new-window')
-    ]);
+    await emittedOnce(browserWindow.webContents, 'did-create-window');
   });
 
   it('can change webPreferences of child windows', (done) => {
@@ -282,22 +195,3 @@ describe('webContents.setWindowOpenHandler', () => {
     expect(await browserWindow.webContents.executeJavaScript('42')).to.equal(42);
   });
 });
-
-function stringifySnapshots (snapshots: any, pretty = false) {
-  return JSON.stringify(snapshots, (key, value) => {
-    if (['sender', 'webContents'].includes(key)) {
-      return '[WebContents]';
-    }
-    if (key === 'processId' && typeof value === 'number') {
-      return 'placeholder-process-id';
-    }
-    if (key === 'returnValue') {
-      return 'placeholder-guest-contents-id';
-    }
-    return value;
-  }, pretty ? 2 : undefined);
-}
-
-function parseSnapshots (snapshotsJson: string) {
-  return JSON.parse(snapshotsJson);
-}

+ 0 - 47
spec-main/webview-spec.ts

@@ -668,31 +668,6 @@ describe('<webview> tag', function () {
       expect(content).to.equal(expectedContent);
     });
 
-    it('emits a new-window event', async () => {
-      // Don't wait for loading to finish.
-      const attributes = {
-        allowpopups: 'on',
-        nodeintegration: 'on',
-        webpreferences: 'contextIsolation=no',
-        src: `file://${fixtures}/pages/window-open.html`
-      };
-      const { url, frameName } = await w.webContents.executeJavaScript(`
-        new Promise((resolve, reject) => {
-          const webview = document.createElement('webview')
-          for (const [k, v] of Object.entries(${JSON.stringify(attributes)})) {
-            webview.setAttribute(k, v)
-          }
-          document.body.appendChild(webview)
-          webview.addEventListener('new-window', (e) => {
-            resolve({url: e.url, frameName: e.frameName})
-          })
-        })
-      `);
-
-      expect(url).to.equal('http://host/');
-      expect(frameName).to.equal('host');
-    });
-
     it('emits a browser-window-created event', async () => {
       // Don't wait for loading to finish.
       loadWebView(w.webContents, {
@@ -1435,28 +1410,6 @@ describe('<webview> tag', function () {
     });
     after(closeAllWindows);
 
-    describe('new-window event', () => {
-      it('emits when window.open is called', async () => {
-        const { url, frameName } = await loadWebViewAndWaitForEvent(w, {
-          src: `file://${fixtures}/pages/window-open.html`,
-          allowpopups: 'true'
-        }, 'new-window');
-
-        expect(url).to.equal('http://host/');
-        expect(frameName).to.equal('host');
-      });
-
-      it('emits when link with target is called', async () => {
-        const { url, frameName } = await loadWebViewAndWaitForEvent(w, {
-          src: `file://${fixtures}/pages/target-name.html`,
-          allowpopups: 'true'
-        }, 'new-window');
-
-        expect(url).to.equal('http://host/');
-        expect(frameName).to.equal('target');
-      });
-    });
-
     describe('ipc-message event', () => {
       it('emits when guest sends an ipc message to browser', async () => {
         const { frameId, channel, args } = await loadWebViewAndWaitForEvent(w, {

+ 0 - 5
spec/ts-smoke/electron/renderer.ts

@@ -174,11 +174,6 @@ webview.addEventListener('found-in-page', function (e) {
 
 const requestId = webview.findInPage('test')
 
-webview.addEventListener('new-window', async e => {
-  const { shell } = require('electron')
-  await shell.openExternal(e.url)
-})
-
 webview.addEventListener('close', function () {
   webview.src = 'about:blank'
 })