Merge branch 'master' into certificate-addition-windows
This commit is contained in:
commit
50af70a0e8
23 changed files with 279 additions and 80 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/browser/native_window.h"
|
#include "atom/browser/native_window.h"
|
||||||
#include "atom/browser/window_list.h"
|
#include "atom/browser/window_list.h"
|
||||||
|
#include "atom/common/api/event_emitter_caller.h"
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
|
@ -47,7 +48,9 @@ void AutoUpdater::OnError(const std::string& message) {
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||||
EmitCustomEvent(
|
mate::EmitEvent(
|
||||||
|
isolate(),
|
||||||
|
GetWrapper(),
|
||||||
"error",
|
"error",
|
||||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
||||||
// Message is also emitted to keep compatibility with old code.
|
// Message is also emitted to keep compatibility with old code.
|
||||||
|
|
|
@ -191,6 +191,10 @@ void Window::OnWindowClosed() {
|
||||||
FROM_HERE, GetDestroyClosure());
|
FROM_HERE, GetDestroyClosure());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::OnWindowEndSession() {
|
||||||
|
Emit("session-end");
|
||||||
|
}
|
||||||
|
|
||||||
void Window::OnWindowBlur() {
|
void Window::OnWindowBlur() {
|
||||||
Emit("blur");
|
Emit("blur");
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||||
void WillCloseWindow(bool* prevent_default) override;
|
void WillCloseWindow(bool* prevent_default) override;
|
||||||
void WillDestroyNativeObject() override;
|
void WillDestroyNativeObject() override;
|
||||||
void OnWindowClosed() override;
|
void OnWindowClosed() override;
|
||||||
|
void OnWindowEndSession() override;
|
||||||
void OnWindowBlur() override;
|
void OnWindowBlur() override;
|
||||||
void OnWindowFocus() override;
|
void OnWindowFocus() override;
|
||||||
void OnWindowShow() override;
|
void OnWindowShow() override;
|
||||||
|
|
|
@ -474,6 +474,11 @@ void NativeWindow::NotifyWindowClosed() {
|
||||||
observer.OnWindowClosed();
|
observer.OnWindowClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindow::NotifyWindowEndSession() {
|
||||||
|
for (NativeWindowObserver& observer : observers_)
|
||||||
|
observer.OnWindowEndSession();
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindow::NotifyWindowBlur() {
|
void NativeWindow::NotifyWindowBlur() {
|
||||||
for (NativeWindowObserver& observer : observers_)
|
for (NativeWindowObserver& observer : observers_)
|
||||||
observer.OnWindowBlur();
|
observer.OnWindowBlur();
|
||||||
|
|
|
@ -218,6 +218,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
// Public API used by platform-dependent delegates and observers to send UI
|
// Public API used by platform-dependent delegates and observers to send UI
|
||||||
// related notifications.
|
// related notifications.
|
||||||
void NotifyWindowClosed();
|
void NotifyWindowClosed();
|
||||||
|
void NotifyWindowEndSession();
|
||||||
void NotifyWindowBlur();
|
void NotifyWindowBlur();
|
||||||
void NotifyWindowFocus();
|
void NotifyWindowFocus();
|
||||||
void NotifyWindowShow();
|
void NotifyWindowShow();
|
||||||
|
|
|
@ -40,6 +40,9 @@ class NativeWindowObserver {
|
||||||
// Called when the window is closed.
|
// Called when the window is closed.
|
||||||
virtual void OnWindowClosed() {}
|
virtual void OnWindowClosed() {}
|
||||||
|
|
||||||
|
// Called when Windows sends WM_ENDSESSION message
|
||||||
|
virtual void OnWindowEndSession() {}
|
||||||
|
|
||||||
// Called when window loses focus.
|
// Called when window loses focus.
|
||||||
virtual void OnWindowBlur() {}
|
virtual void OnWindowBlur() {}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,11 @@ bool NativeWindowViews::PreHandleMSG(
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
case WM_ENDSESSION: {
|
||||||
|
if (w_param) {
|
||||||
|
NotifyWindowEndSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
45
default_app/renderer.js
Normal file
45
default_app/renderer.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
const {remote, shell} = require('electron')
|
||||||
|
const {execFile} = require('child_process')
|
||||||
|
|
||||||
|
const {execPath} = remote.process
|
||||||
|
|
||||||
|
document.onclick = function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
if (e.target.tagName === 'A') {
|
||||||
|
shell.openExternal(e.target.href)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
document.ondragover = document.ondrop = function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const holder = document.getElementById('holder')
|
||||||
|
holder.ondragover = function () {
|
||||||
|
this.className = 'hover'
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.ondragleave = holder.ondragend = function () {
|
||||||
|
this.className = ''
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.ondrop = function (e) {
|
||||||
|
this.className = ''
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
const file = e.dataTransfer.files[0]
|
||||||
|
execFile(execPath, [file.path], {
|
||||||
|
detached: true, stdio: 'ignore'
|
||||||
|
}).unref()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = process.versions.electron
|
||||||
|
document.querySelector('.header-version').innerText = version
|
||||||
|
document.querySelector('.command-example').innerText = `${execPath} path-to-your-app`
|
||||||
|
document.querySelector('.quick-start-link').href = `https://github.com/electron/electron/blob/v${version}/docs/tutorial/quick-start.md`
|
||||||
|
document.querySelector('.docs-link').href = `https://github.com/electron/electron/tree/v${version}/docs#readme`
|
|
@ -376,6 +376,11 @@ window.onbeforeunload = (e) => {
|
||||||
Emitted when the window is closed. After you have received this event you should
|
Emitted when the window is closed. After you have received this event you should
|
||||||
remove the reference to the window and avoid using it any more.
|
remove the reference to the window and avoid using it any more.
|
||||||
|
|
||||||
|
#### Event: 'session-end' _Windows_
|
||||||
|
|
||||||
|
Emitted when window session is going to end due to force shutdown or machine restart
|
||||||
|
or session log off.
|
||||||
|
|
||||||
#### Event: 'unresponsive'
|
#### Event: 'unresponsive'
|
||||||
|
|
||||||
Emitted when the web page becomes unresponsive.
|
Emitted when the web page becomes unresponsive.
|
||||||
|
|
|
@ -100,6 +100,8 @@ Returns `Boolean` - Whether the download is paused.
|
||||||
|
|
||||||
Resumes the download that has been paused.
|
Resumes the download that has been paused.
|
||||||
|
|
||||||
|
**Note:** To enable resumable downloads the server you are downloading from must support range requests and provide both `Last-Modified` and `ETag` header values. Otherwise `resume()` will dismiss previously received bytes and restart the download from the beginning.
|
||||||
|
|
||||||
#### `downloadItem.canResume()`
|
#### `downloadItem.canResume()`
|
||||||
|
|
||||||
Resumes `Boolean` - Whether the download can resume.
|
Resumes `Boolean` - Whether the download can resume.
|
||||||
|
|
|
@ -70,7 +70,7 @@ The `role` property can have following values:
|
||||||
* `editMenu` - Whole default "Edit" menu (Undo, Copy, etc.)
|
* `editMenu` - Whole default "Edit" menu (Undo, Copy, etc.)
|
||||||
* `windowMenu` - Whole default "Window" menu (Minimize, Close, etc.)
|
* `windowMenu` - Whole default "Window" menu (Minimize, Close, etc.)
|
||||||
|
|
||||||
The following additional roles are avaiable on macOS:
|
The following additional roles are available on macOS:
|
||||||
|
|
||||||
* `about` - Map to the `orderFrontStandardAboutPanel` action
|
* `about` - Map to the `orderFrontStandardAboutPanel` action
|
||||||
* `hide` - Map to the `hide` action
|
* `hide` - Map to the `hide` action
|
||||||
|
@ -120,4 +120,4 @@ A String representing the menu items visible label
|
||||||
|
|
||||||
#### `menuItem.click`
|
#### `menuItem.click`
|
||||||
|
|
||||||
A Function that is fired when the MenuItem recieves a click event
|
A Function that is fired when the MenuItem receives a click event
|
||||||
|
|
|
@ -30,6 +30,10 @@ has to be a field of `BrowserWindow`'s options.
|
||||||
|
|
||||||
* Node integration will always be disabled in the opened `window` if it is
|
* Node integration will always be disabled in the opened `window` if it is
|
||||||
disabled on the parent window.
|
disabled on the parent window.
|
||||||
|
* Context isolation will always be enabled in the opened `window` if it is
|
||||||
|
enabled on the parent window.
|
||||||
|
* JavaScript will always be disabled in the opened `window` if it is disabled on
|
||||||
|
the parent window.
|
||||||
* Non-standard features (that are not handled by Chromium or Electron) given in
|
* Non-standard features (that are not handled by Chromium or Electron) given in
|
||||||
`features` will be passed to any registered `webContent`'s `new-window` event
|
`features` will be passed to any registered `webContent`'s `new-window` event
|
||||||
handler in the `additionalFeatures` argument.
|
handler in the `additionalFeatures` argument.
|
||||||
|
|
|
@ -148,7 +148,7 @@ npm uninstall electron
|
||||||
npm uninstall -g electron
|
npm uninstall -g electron
|
||||||
```
|
```
|
||||||
|
|
||||||
However if your are using the built-in module but still getting this error, it
|
However if you are using the built-in module but still getting this error, it
|
||||||
is very likely you are using the module in the wrong process. For example
|
is very likely you are using the module in the wrong process. For example
|
||||||
`electron.app` can only be used in the main process, while `electron.webFrame`
|
`electron.app` can only be used in the main process, while `electron.webFrame`
|
||||||
is only available in renderer processes.
|
is only available in renderer processes.
|
||||||
|
|
|
@ -36,8 +36,8 @@ are fine differences.
|
||||||
* On Windows 8.1 and Windows 8, a shortcut to your app, with a [Application User
|
* On Windows 8.1 and Windows 8, a shortcut to your app, with a [Application User
|
||||||
Model ID][app-user-model-id], must be installed to the Start screen. Note,
|
Model ID][app-user-model-id], must be installed to the Start screen. Note,
|
||||||
however, that it does not need to be pinned to the Start screen.
|
however, that it does not need to be pinned to the Start screen.
|
||||||
* On Windows 7, notifications are not supported. You can however send
|
* On Windows 7, notifications work via a custom implemetation which visually
|
||||||
"balloon notifications" using the [Tray API][tray-balloon].
|
resembles the native one on newer systems.
|
||||||
|
|
||||||
Furthermore, the maximum length for the notification body is 250 characters,
|
Furthermore, the maximum length for the notification body is 250 characters,
|
||||||
with the Windows team recommending that notifications should be kept to 200
|
with the Windows team recommending that notifications should be kept to 200
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
'default_app/index.html',
|
'default_app/index.html',
|
||||||
'default_app/main.js',
|
'default_app/main.js',
|
||||||
'default_app/package.json',
|
'default_app/package.json',
|
||||||
|
'default_app/renderer.js',
|
||||||
],
|
],
|
||||||
'lib_sources': [
|
'lib_sources': [
|
||||||
'atom/app/atom_content_client.cc',
|
'atom/app/atom_content_client.cc',
|
||||||
|
|
|
@ -5,7 +5,7 @@ const {isSameOrigin} = process.atomBinding('v8_util')
|
||||||
const parseFeaturesString = require('../common/parse-features-string')
|
const parseFeaturesString = require('../common/parse-features-string')
|
||||||
|
|
||||||
const hasProp = {}.hasOwnProperty
|
const hasProp = {}.hasOwnProperty
|
||||||
const frameToGuest = {}
|
const frameToGuest = new Map()
|
||||||
|
|
||||||
// Copy attribute of |parent| to |child| if it is not defined in |child|.
|
// Copy attribute of |parent| to |child| if it is not defined in |child|.
|
||||||
const mergeOptions = function (child, parent, visited) {
|
const mergeOptions = function (child, parent, visited) {
|
||||||
|
@ -48,11 +48,16 @@ const mergeBrowserWindowOptions = function (embedder, options) {
|
||||||
options.webPreferences.nodeIntegration = false
|
options.webPreferences.nodeIntegration = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable context isolation on child window if enable on parent window
|
// Enable context isolation on child window if enabled on parent window
|
||||||
if (embedder.getWebPreferences().contextIsolation === true) {
|
if (embedder.getWebPreferences().contextIsolation === true) {
|
||||||
options.webPreferences.contextIsolation = true
|
options.webPreferences.contextIsolation = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable JavaScript on child window if disabled on parent window
|
||||||
|
if (embedder.getWebPreferences().javascript === false) {
|
||||||
|
options.webPreferences.javascript = false
|
||||||
|
}
|
||||||
|
|
||||||
// Sets correct openerId here to give correct options to 'new-window' event handler
|
// Sets correct openerId here to give correct options to 'new-window' event handler
|
||||||
options.webPreferences.openerId = embedder.id
|
options.webPreferences.openerId = embedder.id
|
||||||
|
|
||||||
|
@ -87,10 +92,10 @@ const setupGuest = function (embedder, frameName, guest, options) {
|
||||||
guest.once('closed', closedByUser)
|
guest.once('closed', closedByUser)
|
||||||
}
|
}
|
||||||
if (frameName) {
|
if (frameName) {
|
||||||
frameToGuest[frameName] = guest
|
frameToGuest.set(frameName, guest)
|
||||||
guest.frameName = frameName
|
guest.frameName = frameName
|
||||||
guest.once('closed', function () {
|
guest.once('closed', function () {
|
||||||
delete frameToGuest[frameName]
|
frameToGuest.delete(frameName)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return guestId
|
return guestId
|
||||||
|
@ -98,7 +103,7 @@ const setupGuest = function (embedder, frameName, guest, options) {
|
||||||
|
|
||||||
// Create a new guest created by |embedder| with |options|.
|
// Create a new guest created by |embedder| with |options|.
|
||||||
const createGuest = function (embedder, url, frameName, options, postData) {
|
const createGuest = function (embedder, url, frameName, options, postData) {
|
||||||
let guest = frameToGuest[frameName]
|
let guest = frameToGuest.get(frameName)
|
||||||
if (frameName && (guest != null)) {
|
if (frameName && (guest != null)) {
|
||||||
guest.loadURL(url)
|
guest.loadURL(url)
|
||||||
return guest.webContents.id
|
return guest.webContents.id
|
||||||
|
@ -186,7 +191,7 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName,
|
||||||
const options = {}
|
const options = {}
|
||||||
|
|
||||||
const ints = ['x', 'y', 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight', 'zoomFactor']
|
const ints = ['x', 'y', 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight', 'zoomFactor']
|
||||||
const webPreferences = ['zoomFactor', 'nodeIntegration', 'preload']
|
const webPreferences = ['zoomFactor', 'nodeIntegration', 'preload', 'javascript', 'contextIsolation']
|
||||||
const disposition = 'new-window'
|
const disposition = 'new-window'
|
||||||
|
|
||||||
// Used to store additional features
|
// Used to store additional features
|
||||||
|
@ -197,6 +202,10 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName,
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
additionalFeatures.push(key)
|
additionalFeatures.push(key)
|
||||||
} else {
|
} else {
|
||||||
|
// Don't allow webPreferences to be set since it must be an object
|
||||||
|
// that cannot be directly overridden
|
||||||
|
if (key === 'webPreferences') return
|
||||||
|
|
||||||
if (webPreferences.includes(key)) {
|
if (webPreferences.includes(key)) {
|
||||||
if (options.webPreferences == null) {
|
if (options.webPreferences == null) {
|
||||||
options.webPreferences = {}
|
options.webPreferences = {}
|
||||||
|
|
|
@ -78,7 +78,7 @@ for (let arg of process.argv) {
|
||||||
if (window.location.protocol === 'chrome-devtools:') {
|
if (window.location.protocol === 'chrome-devtools:') {
|
||||||
// Override some inspector APIs.
|
// Override some inspector APIs.
|
||||||
require('./inspector')
|
require('./inspector')
|
||||||
nodeIntegration = 'true'
|
nodeIntegration = 'false'
|
||||||
} else if (window.location.protocol === 'chrome-extension:') {
|
} else if (window.location.protocol === 'chrome-extension:') {
|
||||||
// Add implementations of chrome API.
|
// Add implementations of chrome API.
|
||||||
require('./chrome-api').injectTo(window.location.hostname, isBackgroundPage, window)
|
require('./chrome-api').injectTo(window.location.hostname, isBackgroundPage, window)
|
||||||
|
|
|
@ -32,6 +32,13 @@ const resolveURL = function (url) {
|
||||||
return a.href
|
return a.href
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use this method to ensure values expected as strings in the main process
|
||||||
|
// are convertible to strings in the renderer process. This ensures exceptions
|
||||||
|
// converting values to strings are thrown in this process.
|
||||||
|
const toString = (value) => {
|
||||||
|
return value != null ? `${value}` : value
|
||||||
|
}
|
||||||
|
|
||||||
const windowProxies = {}
|
const windowProxies = {}
|
||||||
|
|
||||||
const getOrCreateProxy = (ipcRenderer, guestId) => {
|
const getOrCreateProxy = (ipcRenderer, guestId) => {
|
||||||
|
@ -82,7 +89,7 @@ function BrowserWindowProxy (ipcRenderer, guestId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.postMessage = (message, targetOrigin) => {
|
this.postMessage = (message, targetOrigin) => {
|
||||||
ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', guestId, message, targetOrigin, window.location.origin)
|
ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', guestId, message, toString(targetOrigin), window.location.origin)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.eval = (...args) => {
|
this.eval = (...args) => {
|
||||||
|
@ -112,7 +119,7 @@ module.exports = (ipcRenderer, guestInstanceId, openerId, hiddenPage) => {
|
||||||
if (url != null && url !== '') {
|
if (url != null && url !== '') {
|
||||||
url = resolveURL(url)
|
url = resolveURL(url)
|
||||||
}
|
}
|
||||||
const guestId = ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, features)
|
const guestId = ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, toString(frameName), toString(features))
|
||||||
if (guestId != null) {
|
if (guestId != null) {
|
||||||
return getOrCreateProxy(ipcRenderer, guestId)
|
return getOrCreateProxy(ipcRenderer, guestId)
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,11 +128,11 @@ module.exports = (ipcRenderer, guestInstanceId, openerId, hiddenPage) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.alert = function (message, title) {
|
window.alert = function (message, title) {
|
||||||
ipcRenderer.sendSync('ELECTRON_BROWSER_WINDOW_ALERT', message, title)
|
ipcRenderer.sendSync('ELECTRON_BROWSER_WINDOW_ALERT', toString(message), toString(title))
|
||||||
}
|
}
|
||||||
|
|
||||||
window.confirm = function (message, title) {
|
window.confirm = function (message, title) {
|
||||||
return ipcRenderer.sendSync('ELECTRON_BROWSER_WINDOW_CONFIRM', message, title)
|
return ipcRenderer.sendSync('ELECTRON_BROWSER_WINDOW_CONFIRM', toString(message), toString(title))
|
||||||
}
|
}
|
||||||
|
|
||||||
// But we do not support prompt().
|
// But we do not support prompt().
|
||||||
|
@ -157,7 +164,7 @@ module.exports = (ipcRenderer, guestInstanceId, openerId, hiddenPage) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.history.go = function (offset) {
|
window.history.go = function (offset) {
|
||||||
sendHistoryOperation(ipcRenderer, 'goToOffset', offset)
|
sendHistoryOperation(ipcRenderer, 'goToOffset', +offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProperty(window.history, 'length', {
|
defineProperty(window.history, 'length', {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const autoUpdater = require('electron').remote.autoUpdater
|
const {autoUpdater} = require('electron').remote
|
||||||
const ipcRenderer = require('electron').ipcRenderer
|
const {ipcRenderer} = require('electron')
|
||||||
|
|
||||||
// Skip autoUpdater tests in MAS build.
|
// Skip autoUpdater tests in MAS build.
|
||||||
if (!process.mas) {
|
if (!process.mas) {
|
||||||
|
@ -64,5 +64,25 @@ if (!process.mas) {
|
||||||
autoUpdater.quitAndInstall()
|
autoUpdater.quitAndInstall()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('error event', function () {
|
||||||
|
it('serializes correctly over the remote module', function (done) {
|
||||||
|
if (process.platform === 'linux') {
|
||||||
|
return done()
|
||||||
|
}
|
||||||
|
|
||||||
|
autoUpdater.once('error', function (error) {
|
||||||
|
assert.equal(error instanceof Error, true)
|
||||||
|
assert.deepEqual(Object.getOwnPropertyNames(error), ['stack', 'message', 'name'])
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
autoUpdater.setFeedURL('')
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
autoUpdater.checkForUpdates()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,45 @@ describe('chromium feature', function () {
|
||||||
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
|
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('disables node integration when it is disabled on the parent window for chrome devtools URLs', function (done) {
|
||||||
|
var b
|
||||||
|
app.once('web-contents-created', (event, contents) => {
|
||||||
|
contents.once('did-finish-load', () => {
|
||||||
|
contents.executeJavaScript('typeof process').then((typeofProcessGlobal) => {
|
||||||
|
assert.equal(typeofProcessGlobal, 'undefined')
|
||||||
|
b.close()
|
||||||
|
done()
|
||||||
|
}).catch(done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
b = window.open('chrome-devtools://devtools/bundled/inspector.html', '', 'nodeIntegration=no,show=no')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('disables JavaScript when it is disabled on the parent window', function (done) {
|
||||||
|
var b
|
||||||
|
app.once('web-contents-created', (event, contents) => {
|
||||||
|
contents.once('did-finish-load', () => {
|
||||||
|
app.once('browser-window-created', (event, window) => {
|
||||||
|
const preferences = window.webContents.getWebPreferences()
|
||||||
|
assert.equal(preferences.javascript, false)
|
||||||
|
window.destroy()
|
||||||
|
b.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
// Click link on page
|
||||||
|
contents.sendInputEvent({type: 'mouseDown', clickCount: 1, x: 1, y: 1})
|
||||||
|
contents.sendInputEvent({type: 'mouseUp', clickCount: 1, x: 1, y: 1})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var windowUrl = require('url').format({
|
||||||
|
pathname: `${fixtures}/pages/window-no-javascript.html`,
|
||||||
|
protocol: 'file',
|
||||||
|
slashes: true
|
||||||
|
})
|
||||||
|
b = window.open(windowUrl, '', 'javascript=no,show=no')
|
||||||
|
})
|
||||||
|
|
||||||
it('does not override child options', function (done) {
|
it('does not override child options', function (done) {
|
||||||
var b, size
|
var b, size
|
||||||
size = {
|
size = {
|
||||||
|
@ -322,6 +361,44 @@ describe('chromium feature', function () {
|
||||||
})
|
})
|
||||||
b = window.open()
|
b = window.open()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('throws an exception when the arguments cannot be converted to strings', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
window.open('', {toString: null})
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
|
||||||
|
assert.throws(function () {
|
||||||
|
window.open('', '', {toString: 3})
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets the window title to the specified frameName', function (done) {
|
||||||
|
let b
|
||||||
|
app.once('browser-window-created', (event, createdWindow) => {
|
||||||
|
assert.equal(createdWindow.getTitle(), 'hello')
|
||||||
|
b.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
b = window.open('', 'hello')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not throw an exception when the frameName is a built-in object property', function (done) {
|
||||||
|
let b
|
||||||
|
app.once('browser-window-created', (event, createdWindow) => {
|
||||||
|
assert.equal(createdWindow.getTitle(), '__proto__')
|
||||||
|
b.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
b = window.open('', '__proto__')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not throw an exception when the features include webPreferences', function () {
|
||||||
|
let b
|
||||||
|
assert.doesNotThrow(function () {
|
||||||
|
b = window.open('', '', 'webPreferences=')
|
||||||
|
})
|
||||||
|
b.close()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('window.opener', function () {
|
describe('window.opener', function () {
|
||||||
|
@ -499,6 +576,14 @@ describe('chromium feature', function () {
|
||||||
})
|
})
|
||||||
b = window.open('file://' + fixtures + '/pages/window-open-postMessage.html', '', 'show=no')
|
b = window.open('file://' + fixtures + '/pages/window-open-postMessage.html', '', 'show=no')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('throws an exception when the targetOrigin cannot be converted to a string', function () {
|
||||||
|
var b = window.open('')
|
||||||
|
assert.throws(function () {
|
||||||
|
b.postMessage('test', {toString: null})
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
b.close()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('window.opener.postMessage', function () {
|
describe('window.opener.postMessage', function () {
|
||||||
|
@ -880,4 +965,36 @@ describe('chromium feature', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('window.alert(message, title)', function () {
|
||||||
|
it('throws an exception when the arguments cannot be converted to strings', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
window.alert({toString: null})
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
|
||||||
|
assert.throws(function () {
|
||||||
|
window.alert('message', {toString: 3})
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('window.confirm(message, title)', function () {
|
||||||
|
it('throws an exception when the arguments cannot be converted to strings', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
window.confirm({toString: null}, 'title')
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
|
||||||
|
assert.throws(function () {
|
||||||
|
window.confirm('message', {toString: 3})
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('window.history.go(offset)', function () {
|
||||||
|
it('throws an exception when the argumnet cannot be converted to a string', function () {
|
||||||
|
assert.throws(function () {
|
||||||
|
window.history.go({toString: null})
|
||||||
|
}, /Cannot convert object to primitive value/)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
12
spec/fixtures/pages/window-no-javascript.html
vendored
Normal file
12
spec/fixtures/pages/window-no-javascript.html
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<a href="about:blank>" target="_blank">CLICK</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -2,20 +2,15 @@
|
||||||
process.throwDeprecation = true
|
process.throwDeprecation = true
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const app = electron.app
|
const {app, BrowserWindow, crashReporter, dialog, ipcMain, protocol, webContents} = electron
|
||||||
const crashReporter = electron.crashReporter
|
|
||||||
const ipcMain = electron.ipcMain
|
const {Coverage} = require('electabul')
|
||||||
const dialog = electron.dialog
|
|
||||||
const BrowserWindow = electron.BrowserWindow
|
|
||||||
const protocol = electron.protocol
|
|
||||||
const webContents = electron.webContents
|
|
||||||
const v8 = require('v8')
|
|
||||||
|
|
||||||
const Coverage = require('electabul').Coverage
|
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const url = require('url')
|
const url = require('url')
|
||||||
const util = require('util')
|
const util = require('util')
|
||||||
|
const v8 = require('v8')
|
||||||
|
|
||||||
var argv = require('yargs')
|
var argv = require('yargs')
|
||||||
.boolean('ci')
|
.boolean('ci')
|
||||||
|
@ -103,6 +98,12 @@ app.on('window-all-closed', function () {
|
||||||
app.quit()
|
app.quit()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.on('web-contents-created', (event, contents) => {
|
||||||
|
contents.on('crashed', (event, killed) => {
|
||||||
|
console.log(`webContents ${contents.id} crashed: ${contents.getURL()} (killed=${killed})`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
app.on('ready', function () {
|
app.on('ready', function () {
|
||||||
// Test if using protocol module would crash.
|
// Test if using protocol module would crash.
|
||||||
electron.protocol.registerStringProtocol('test-if-crashes', function () {})
|
electron.protocol.registerStringProtocol('test-if-crashes', function () {})
|
||||||
|
|
Loading…
Reference in a new issue