Browse Source

docs: remove references to remote from docs (#27715)

Co-authored-by: Jeremy Rose <[email protected]>
trop[bot] 4 years ago
parent
commit
51bb0ad36d

+ 5 - 5
docs/api/app.md

@@ -502,7 +502,7 @@ Returns:
 Emitted when `desktopCapturer.getSources()` is called in the renderer process of `webContents`.
 Calling `event.preventDefault()` will make it return empty sources.
 
-### Event: 'remote-require'
+### Event: 'remote-require' _Deprecated_
 
 Returns:
 
@@ -514,7 +514,7 @@ Emitted when `remote.require()` is called in the renderer process of `webContent
 Calling `event.preventDefault()` will prevent the module from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-### Event: 'remote-get-global'
+### Event: 'remote-get-global' _Deprecated_
 
 Returns:
 
@@ -526,7 +526,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process of `webConte
 Calling `event.preventDefault()` will prevent the global from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-### Event: 'remote-get-builtin'
+### Event: 'remote-get-builtin' _Deprecated_
 
 Returns:
 
@@ -538,7 +538,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process of `webCont
 Calling `event.preventDefault()` will prevent the module from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-### Event: 'remote-get-current-window'
+### Event: 'remote-get-current-window' _Deprecated_
 
 Returns:
 
@@ -549,7 +549,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process of `w
 Calling `event.preventDefault()` will prevent the object from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-### Event: 'remote-get-current-web-contents'
+### Event: 'remote-get-current-web-contents' _Deprecated_
 
 Returns:
 

+ 0 - 3
docs/api/browser-window.md

@@ -8,9 +8,6 @@ Process: [Main](../glossary.md#main-process)
 // In the main process.
 const { BrowserWindow } = require('electron')
 
-// Or use `remote` from the renderer process.
-// const { BrowserWindow } = require('electron').remote
-
 const win = new BrowserWindow({ width: 800, height: 600 })
 
 // Load a remote URL

+ 0 - 8
docs/api/dialog.md

@@ -11,14 +11,6 @@ const { dialog } = require('electron')
 console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
 ```
 
-The Dialog is opened from Electron's main thread. If you want to use the dialog
-object from a renderer process, remember to access it using the remote:
-
-```javascript
-const { dialog } = require('electron').remote
-console.log(dialog)
-```
-
 ## Methods
 
 The `dialog` module has the following methods:

+ 9 - 3
docs/api/frameless-window.md

@@ -112,13 +112,19 @@ optional parameter can be used to forward mouse move messages to the web page,
 allowing events such as `mouseleave` to be emitted:
 
 ```javascript
-const win = require('electron').remote.getCurrentWindow()
+const { ipcRenderer } = require('electron')
 const el = document.getElementById('clickThroughElement')
 el.addEventListener('mouseenter', () => {
-  win.setIgnoreMouseEvents(true, { forward: true })
+  ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
 })
 el.addEventListener('mouseleave', () => {
-  win.setIgnoreMouseEvents(false)
+  ipcRenderer.send('set-ignore-mouse-events', false)
+})
+
+// Main process
+const { ipcMain } = require('electron')
+ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
+  BrowserWindow.fromWebContents(event.sender).setIgnoreMouseEvents(...args)
 })
 ```
 

+ 8 - 22
docs/api/sandbox-option.md

@@ -88,26 +88,17 @@ and preload.js:
 
 ```js
 // This file is loaded whenever a javascript context is created. It runs in a
-// private scope that can access a subset of Electron renderer APIs. We must be
-// careful to not leak any objects into the global scope!
-const { ipcRenderer, remote } = require('electron')
-const fs = remote.require('fs')
-
-// read a configuration file using the `fs` module
-const buf = fs.readFileSync('allowed-popup-urls.json')
-const allowedUrls = JSON.parse(buf.toString('utf8'))
+// private scope that can access a subset of Electron renderer APIs. Without
+// contextIsolation enabled, it's possible to accidentally leak privileged
+// globals like ipcRenderer to web content.
+const { ipcRenderer } = require('electron')
 
 const defaultWindowOpen = window.open
 
-function customWindowOpen (url, ...args) {
-  if (allowedUrls.indexOf(url) === -1) {
-    ipcRenderer.sendSync('blocked-popup-notification', location.origin, url)
-    return null
-  }
-  return defaultWindowOpen(url, ...args)
+window.open = function customWindowOpen (url, ...args) {
+  ipcRenderer.send('report-window-open', location.origin, url, args)
+  return defaultWindowOpen(url + '?from_electron=1', ...args)
 }
-
-window.open = customWindowOpen
 ```
 
 Important things to notice in the preload script:
@@ -115,8 +106,6 @@ Important things to notice in the preload script:
 - Even though the sandboxed renderer doesn't have Node.js running, it still has
   access to a limited node-like environment: `Buffer`, `process`, `setImmediate`,
   `clearImmediate` and `require` are available.
-- The preload script can indirectly access all APIs from the main process through the
-  `remote` and `ipcRenderer` modules.
 - The preload script must be contained in a single script, but it is possible to have
   complex preload code composed with multiple modules by using a tool like
   webpack or browserify. An example of using browserify is below.
@@ -144,15 +133,12 @@ following modules:
   - `desktopCapturer`
   - `ipcRenderer`
   - `nativeImage`
-  - `remote`
   - `webFrame`
 - `events`
 - `timers`
 - `url`
 
-More may be added as needed to expose more Electron APIs in the sandbox, but any
-module in the main process can already be used through
-`electron.remote.require`.
+More may be added as needed to expose more Electron APIs in the sandbox.
 
 ## Rendering untrusted content
 

+ 4 - 4
docs/api/synopsis.md

@@ -9,7 +9,7 @@ the [native modules](../tutorial/using-native-node-modules.md)).
 Electron also provides some extra built-in modules for developing native
 desktop applications. Some modules are only available in the main process, some
 are only available in the renderer process (web page), and some can be used in
-both processes.
+either process type.
 
 The basic rule is: if a module is [GUI][gui] or low-level system related, then
 it should be only available in the main process. You need to be familiar with
@@ -29,15 +29,15 @@ app.whenReady().then(() => {
 ```
 
 The renderer process is no different than a normal web page, except for the
-extra ability to use node modules:
+extra ability to use node modules if `nodeIntegration` is enabled:
 
 ```html
 <!DOCTYPE html>
 <html>
 <body>
 <script>
-  const { app } = require('electron').remote
-  console.log(app.getVersion())
+  const fs = require('fs')
+  console.log(fs.readFileSync(__filename, 'utf8'))
 </script>
 </body>
 </html>

+ 20 - 10
docs/api/web-contents.md

@@ -785,7 +785,7 @@ Returns:
 Emitted when `desktopCapturer.getSources()` is called in the renderer process.
 Calling `event.preventDefault()` will make it return empty sources.
 
-#### Event: 'remote-require'
+#### Event: 'remote-require' _Deprecated_
 
 Returns:
 
@@ -796,7 +796,7 @@ Emitted when `remote.require()` is called in the renderer process.
 Calling `event.preventDefault()` will prevent the module from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-#### Event: 'remote-get-global'
+#### Event: 'remote-get-global' _Deprecated_
 
 Returns:
 
@@ -807,7 +807,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process.
 Calling `event.preventDefault()` will prevent the global from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-#### Event: 'remote-get-builtin'
+#### Event: 'remote-get-builtin' _Deprecated_
 
 Returns:
 
@@ -818,7 +818,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process.
 Calling `event.preventDefault()` will prevent the module from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-#### Event: 'remote-get-current-window'
+#### Event: 'remote-get-current-window' _Deprecated_
 
 Returns:
 
@@ -828,7 +828,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process.
 Calling `event.preventDefault()` will prevent the object from being returned.
 Custom value can be returned by setting `event.returnValue`.
 
-#### Event: 'remote-get-current-web-contents'
+#### Event: 'remote-get-current-web-contents' _Deprecated_
 
 Returns:
 
@@ -1482,7 +1482,7 @@ An example of showing devtools in a `<webview>` tag:
   <webview id="browser" src="https://github.com"></webview>
   <webview id="devtools" src="about:blank"></webview>
   <script>
-    const { webContents } = require('electron').remote
+    const { ipcRenderer } = require('electron')
     const emittedOnce = (element, eventName) => new Promise(resolve => {
       element.addEventListener(eventName, event => resolve(event), { once: true })
     })
@@ -1491,16 +1491,26 @@ An example of showing devtools in a `<webview>` tag:
     const browserReady = emittedOnce(browserView, 'dom-ready')
     const devtoolsReady = emittedOnce(devtoolsView, 'dom-ready')
     Promise.all([browserReady, devtoolsReady]).then(() => {
-      const browser = webContents.fromId(browserView.getWebContentsId())
-      const devtools = webContents.fromId(devtoolsView.getWebContentsId())
-      browser.setDevToolsWebContents(devtools)
-      browser.openDevTools()
+      const targetId = browserView.getWebContentsId()
+      const devtoolsId = devtoolsView.getWebContentsId()
+      ipcRenderer.send('open-devtools', targetId, devtoolsId)
     })
   </script>
 </body>
 </html>
 ```
 
+```js
+// Main process
+const { ipcMain, webContents } = require('electron')
+ipcMain.on('open-devtools', (event, targetContentsId, devtoolsContentsId) => {
+  const target = webContents.fromId(targetContentsId)
+  const devtools = webContents.fromId(devtoolsContentsId)
+  target.setDevToolsWebContents(devtools)
+  target.openDevTools()
+})
+```
+
 An example of showing devtools in a `BrowserWindow`:
 
 ```js

+ 1 - 1
docs/api/webview-tag.md

@@ -137,7 +137,7 @@ This option is disabled by default in the guest page.
 ```
 
 A `Boolean`. When this attribute is `false` the guest page in `webview` will not have access
-to the [`remote`](remote.md) module. The remote module is available by default.
+to the [`remote`](remote.md) module. The remote module is unavailable by default.
 
 ### `plugins`
 

+ 1 - 2
docs/development/debug-instructions-windows.md

@@ -69,8 +69,7 @@ way of figuring out which is which.
 ### Which Process Should I Attach to?
 
 Code executed within the main process (that is, code found in or eventually run
-by your main JavaScript file) as well as code called using the remote
-(`require('electron').remote`) will run inside the main process, while other
+by your main JavaScript file) will run inside the main process, while other
 code will execute inside its respective renderer process.
 
 You can be attached to multiple programs when you are debugging, but only one

+ 5 - 1
docs/fiddles/media/screenshot/take-screenshot/main.js

@@ -1,7 +1,11 @@
-const { BrowserWindow, app } = require('electron')
+const { BrowserWindow, app, screen, ipcMain } = require('electron')
 
 let mainWindow = null
 
+ipcMain.handle('get-screen-size', () => {
+  return screen.getPrimaryDisplay().workAreaSize
+})
+
 function createWindow () {
   const windowOptions = {
     width: 600,

+ 5 - 6
docs/fiddles/media/screenshot/take-screenshot/renderer.js

@@ -1,5 +1,4 @@
-const { desktopCapturer } = require('electron')
-const { screen, shell } = require('electron').remote
+const { desktopCapturer, shell, ipcRenderer } = require('electron')
 
 const fs = require('fs')
 const os = require('os')
@@ -8,9 +7,9 @@ const path = require('path')
 const screenshot = document.getElementById('screen-shot')
 const screenshotMsg = document.getElementById('screenshot-path')
 
-screenshot.addEventListener('click', (event) => {
+screenshot.addEventListener('click', async (event) => {
   screenshotMsg.textContent = 'Gathering screens...'
-  const thumbSize = determineScreenShotSize()
+  const thumbSize = await determineScreenShotSize()
   const options = { types: ['screen'], thumbnailSize: thumbSize }
 
   desktopCapturer.getSources(options, (error, sources) => {
@@ -33,8 +32,8 @@ screenshot.addEventListener('click', (event) => {
   })
 })
 
-function determineScreenShotSize () {
-  const screenSize = screen.getPrimaryDisplay().workAreaSize
+async function determineScreenShotSize () {
+  const screenSize = await ipcRenderer.invoke('get-screen-size')
   const maxDimension = Math.max(screenSize.width, screenSize.height)
   return {
     width: maxDimension * window.devicePixelRatio,

+ 7 - 10
docs/fiddles/windows/manage-windows/create-frameless-window/main.js

@@ -1,23 +1,20 @@
-const { app, BrowserWindow } = require('electron')
+const { app, BrowserWindow, ipcMain } = require('electron')
 
-let mainWindow = null
+ipcMain.on('create-frameless-window', (event, {url}) => {
+  const win = new BrowserWindow({ frame: false })
+  win.loadURL(url)
+})
 
 function createWindow () {
-  const windowOptions = {
+  const mainWindow = new BrowserWindow({
     width: 600,
     height: 400,
     title: 'Create a frameless window',
     webPreferences: {
       nodeIntegration: true
     }
-  }
-
-  mainWindow = new BrowserWindow(windowOptions)
-  mainWindow.loadFile('index.html')
-
-  mainWindow.on('closed', () => {
-    mainWindow = null
   })
+  mainWindow.loadFile('index.html')
 }
 
 app.whenReady().then(() => {

+ 4 - 8
docs/fiddles/windows/manage-windows/create-frameless-window/renderer.js

@@ -1,12 +1,8 @@
-const { BrowserWindow } = require('electron').remote
+const { ipcRenderer } = require('electron')
 
 const newWindowBtn = document.getElementById('frameless-window')
 
-newWindowBtn.addEventListener('click', (event) => {
-  let win = new BrowserWindow({ frame: false })
-
-  win.on('close', () => { win = null })
-
-  win.loadURL('data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>')
-  win.show()
+newWindowBtn.addEventListener('click', () => {
+  const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
+  ipcRenderer.send('create-frameless-window', { url })
 })

+ 5 - 15
docs/fiddles/windows/manage-windows/frameless-window/main.js

@@ -1,13 +1,14 @@
 // Modules to control application life and create native browser window
 const { app, BrowserWindow } = require('electron')
 
-// Keep a global reference of the window object, if you don't, the window will
-// be closed automatically when the JavaScript object is garbage collected.
-let mainWindow
+ipcMain.on('create-frameless-window', (event, {url}) => {
+  const win = new BrowserWindow({ frame: false })
+  win.loadURL(url)
+})
 
 function createWindow () {
   // Create the browser window.
-  mainWindow = new BrowserWindow({
+  const mainWindow = new BrowserWindow({
     width: 800,
     height: 600,
     webPreferences: {
@@ -17,17 +18,6 @@ function createWindow () {
 
   // and load the index.html of the app.
   mainWindow.loadFile('index.html')
-
-  // Open the DevTools.
-  // mainWindow.webContents.openDevTools()
-
-  // Emitted when the window is closed.
-  mainWindow.on('closed', function () {
-    // Dereference the window object, usually you would store windows
-    // in an array if your app supports multi windows, this is the time
-    // when you should delete the corresponding element.
-    mainWindow = null
-  })
 }
 
 // This method will be called when Electron has finished

+ 5 - 22
docs/fiddles/windows/manage-windows/frameless-window/renderer.js

@@ -1,25 +1,8 @@
-const { BrowserWindow } = require('electron').remote
-const shell = require('electron').shell
+const { ipcRenderer } = require('electron')
 
-const framelessWindowBtn = document.getElementById('frameless-window')
+const newWindowBtn = document.getElementById('frameless-window')
 
-const links = document.querySelectorAll('a[href]')
-
-framelessWindowBtn.addEventListener('click', (event) => {
-  const modalPath = 'https://electronjs.org'
-  let win = new BrowserWindow({ frame: false })
-
-  win.on('close', () => { win = null })
-  win.loadURL(modalPath)
-  win.show()
-})
-
-Array.prototype.forEach.call(links, (link) => {
-  const url = link.getAttribute('href')
-  if (url.indexOf('http') === 0) {
-    link.addEventListener('click', (e) => {
-      e.preventDefault()
-      shell.openExternal(url)
-    })
-  }
+newWindowBtn.addEventListener('click', () => {
+  const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
+  ipcRenderer.send('create-frameless-window', { url })
 })

+ 15 - 15
docs/fiddles/windows/manage-windows/manage-window-state/main.js

@@ -1,9 +1,20 @@
 // Modules to control application life and create native browser window
-const { app, BrowserWindow } = require('electron')
+const { app, BrowserWindow, ipcMain } = require('electron')
 
-// Keep a global reference of the window object, if you don't, the window will
-// be closed automatically when the JavaScript object is garbage collected.
-let mainWindow
+ipcMain.on('create-demo-window', (event) => {
+  const win = new BrowserWindow({ width: 400, height: 275 })
+
+  function updateReply() {
+    event.sender.send('bounds-changed', {
+      size: win.getSize(),
+      position: win.getPosition()
+    })
+  }
+
+  win.on('resize', updateReply)
+  win.on('move', updateReply)
+  win.loadURL('https://electronjs.org')
+})
 
 function createWindow () {
   // Create the browser window.
@@ -17,17 +28,6 @@ function createWindow () {
 
   // and load the index.html of the app.
   mainWindow.loadFile('index.html')
-
-  // Open the DevTools.
-  // mainWindow.webContents.openDevTools()
-
-  // Emitted when the window is closed.
-  mainWindow.on('closed', function () {
-    // Dereference the window object, usually you would store windows
-    // in an array if your app supports multi windows, this is the time
-    // when you should delete the corresponding element.
-    mainWindow = null
-  })
 }
 
 // This method will be called when Electron has finished

+ 7 - 17
docs/fiddles/windows/manage-windows/manage-window-state/renderer.js

@@ -1,27 +1,17 @@
-const { BrowserWindow } = require('electron').remote
-const shell = require('electron').shell
+const { shell, ipcRenderer } = require('electron')
 
 const manageWindowBtn = document.getElementById('manage-window')
 
 const links = document.querySelectorAll('a[href]')
 
-let win
+ipcRenderer.on('bounds-changed', (event, bounds) => {
+  const manageWindowReply = document.getElementById('manage-window-reply')
+  const message = `Size: ${bounds.size} Position: ${bounds.position}`
+  manageWindowReply.textContent = message
+})
 
 manageWindowBtn.addEventListener('click', (event) => {
-  const modalPath = 'https://electronjs.org'
-  win = new BrowserWindow({ width: 400, height: 275 })
-
-  win.on('resize', updateReply)
-  win.on('move', updateReply)
-  win.on('close', () => { win = null })
-  win.loadURL(modalPath)
-  win.show()
-
-  function updateReply () {
-    const manageWindowReply = document.getElementById('manage-window-reply')
-    const message = `Size: ${win.getSize()} Position: ${win.getPosition()}`
-    manageWindowReply.innerText = message
-  }
+  ipcRenderer.send('create-demo-window')
 })
 
 Array.prototype.forEach.call(links, (link) => {

+ 1 - 1
docs/fiddles/windows/manage-windows/new-window/index.html

@@ -7,7 +7,7 @@
   <h2>Create a new window</h2>
   <h3>Supports: Win, macOS, Linux <span>|</span> Process: Main</h3>
   <button id="new-window">View Demo</button>
-  <p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app. This main process module can be used from the renderer process with the <code>remote</code> module, as is shown in this demo.</p>
+  <p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app.</p>
   <p>There are a lot of options when creating a new window. A few are in this demo, but visit the <a id="browser-window-link" href="">documentation<span>(opens in new window)</span></a>
 <div>
             <h2>ProTip</h2>

+ 6 - 16
docs/fiddles/windows/manage-windows/new-window/main.js

@@ -1,13 +1,14 @@
 // Modules to control application life and create native browser window
-const { app, BrowserWindow } = require('electron')
+const { app, BrowserWindow, ipcMain } = require('electron')
 
-// Keep a global reference of the window object, if you don't, the window will
-// be closed automatically when the JavaScript object is garbage collected.
-let mainWindow
+ipcMain.on('new-window', (event, { url, width, height }) => {
+  const win = new BrowserWindow({ width, height })
+  win.loadURL(url)
+})
 
 function createWindow () {
   // Create the browser window.
-  mainWindow = new BrowserWindow({
+  const mainWindow = new BrowserWindow({
     width: 800,
     height: 600,
     webPreferences: {
@@ -17,17 +18,6 @@ function createWindow () {
 
   // and load the index.html of the app.
   mainWindow.loadFile('index.html')
-
-  // Open the DevTools.
-  // mainWindow.webContents.openDevTools()
-
-  // Emitted when the window is closed.
-  mainWindow.on('closed', function () {
-    // Dereference the window object, usually you would store windows
-    // in an array if your app supports multi windows, this is the time
-    // when you should delete the corresponding element.
-    mainWindow = null
-  })
 }
 
 // This method will be called when Electron has finished

+ 3 - 8
docs/fiddles/windows/manage-windows/new-window/renderer.js

@@ -1,16 +1,11 @@
-const { BrowserWindow } = require('electron').remote
-const { shell } = require('electron').remote
+const { shell, ipcRenderer } = require('electron')
 
 const newWindowBtn = document.getElementById('new-window')
 const link = document.getElementById('browser-window-link')
 
 newWindowBtn.addEventListener('click', (event) => {
-
-  let win = new BrowserWindow({ width: 400, height: 320 })
-
-  win.on('close', () => { win = null })
-  win.loadURL('https://electronjs.org')
-  win.show()
+  const url = 'https://electronjs.org'
+  ipcRenderer.send('new-window', { url, width: 400, height: 320 });
 })
 
 link.addEventListener('click', (e) => {

+ 22 - 14
docs/fiddles/windows/manage-windows/window-events/main.js

@@ -1,13 +1,9 @@
 // Modules to control application life and create native browser window
-const { app, BrowserWindow } = require('electron')
-
-// Keep a global reference of the window object, if you don't, the window will
-// be closed automatically when the JavaScript object is garbage collected.
-let mainWindow
+const { app, BrowserWindow, ipcMain } = require('electron')
 
 function createWindow () {
   // Create the browser window.
-  mainWindow = new BrowserWindow({
+  const mainWindow = new BrowserWindow({
     width: 800,
     height: 600,
     webPreferences: {
@@ -18,15 +14,27 @@ function createWindow () {
   // and load the index.html of the app.
   mainWindow.loadFile('index.html')
 
-  // Open the DevTools.
-  // mainWindow.webContents.openDevTools()
+  let demoWindow
+  ipcMain.on('show-demo-window', () => {
+    if (demoWindow) {
+      demoWindow.focus()
+      return
+    }
+    demoWindow = new BrowserWindow({ width: 600, height: 400 })
+    demoWindow.loadURL('https://electronjs.org')
+    demoWindow.on('close', () => {
+      mainWindow.webContents.send('window-close')
+    })
+    demoWindow.on('focus', () => {
+      mainWindow.webContents.send('window-focus')
+    })
+    demoWindow.on('blur', () => {
+      mainWindow.webContents.send('window-blur')
+    })
+  })
 
-  // Emitted when the window is closed.
-  mainWindow.on('closed', function () {
-    // Dereference the window object, usually you would store windows
-    // in an array if your app supports multi windows, this is the time
-    // when you should delete the corresponding element.
-    mainWindow = null
+  ipcMain.on('focus-demo-window', () => {
+    if (demoWindow) demoWindow.focus()
   })
 }
 

+ 22 - 31
docs/fiddles/windows/manage-windows/window-events/renderer.js

@@ -1,42 +1,33 @@
-const { BrowserWindow } = require('electron').remote
-const shell = require('electron').shell
+const { shell, ipcRenderer } = require('electron')
 
 const listenToWindowBtn = document.getElementById('listen-to-window')
 const focusModalBtn = document.getElementById('focus-on-modal-window')
 
-const links = document.querySelectorAll('a[href]')
-
-let win
+const hideFocusBtn = () => {
+  focusModalBtn.classList.add('disappear')
+  focusModalBtn.classList.remove('smooth-appear')
+  focusModalBtn.removeEventListener('click', focusWindow)
+}
+
+const showFocusBtn = (btn) => {
+  focusModalBtn.classList.add('smooth-appear')
+  focusModalBtn.classList.remove('disappear')
+  focusModalBtn.addEventListener('click', focusWindow)
+}
+const focusWindow = () => {
+  ipcRenderer.send('focus-demo-window')
+}
+
+ipcRenderer.on('window-focus', hideFocusBtn)
+ipcRenderer.on('window-close', hideFocusBtn)
+ipcRenderer.on('window-blur', showFocusBtn)
 
 listenToWindowBtn.addEventListener('click', () => {
-  const modalPath = 'https://electronjs.org'
-  win = new BrowserWindow({ width: 600, height: 400 })
-
-  const hideFocusBtn = () => {
-    focusModalBtn.classList.add('disappear')
-    focusModalBtn.classList.remove('smooth-appear')
-    focusModalBtn.removeEventListener('click', clickHandler)
-  }
-
-  const showFocusBtn = (btn) => {
-    if (!win) return
-    focusModalBtn.classList.add('smooth-appear')
-    focusModalBtn.classList.remove('disappear')
-    focusModalBtn.addEventListener('click', clickHandler)
-  }
-
-  win.on('focus', hideFocusBtn)
-  win.on('blur', showFocusBtn)
-  win.on('close', () => {
-    hideFocusBtn()
-    win = null
-  })
-  win.loadURL(modalPath)
-  win.show()
-
-  const clickHandler = () => { win.focus() }
+  ipcRenderer.send('show-demo-window')
 })
 
+const links = document.querySelectorAll('a[href]')
+
 Array.prototype.forEach.call(links, (link) => {
   const url = link.getAttribute('href')
   if (url.indexOf('http') === 0) {

+ 2 - 1
docs/tutorial/in-app-purchases.md

@@ -26,7 +26,8 @@ To test In-App Purchase in development with Electron you'll have to change the `
 Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1`). Note that you have to listen to the `transactions-updated` event as soon as possible in your app.
 
 ```javascript
-const { inAppPurchase } = require('electron').remote
+// Main process
+const { inAppPurchase } = require('electron')
 const PRODUCT_IDS = ['id1', 'id2']
 
 // Listen for transactions as soon as possible.

+ 1 - 5
lib/browser/api/browser-window.ts

@@ -92,11 +92,7 @@ BrowserWindow.getFocusedWindow = () => {
 };
 
 BrowserWindow.fromWebContents = (webContents: WebContents) => {
-  for (const window of BrowserWindow.getAllWindows()) {
-    if (window.webContents && window.webContents.equal(webContents)) return window;
-  }
-
-  return null;
+  return webContents.getOwnerBrowserWindow();
 };
 
 BrowserWindow.fromBrowserView = (browserView: BrowserView) => {