зеркало из https://github.com/electron/electron.git
feat: add remote.require() / remote.getGlobal() filtering (#15014)
This commit is contained in:
Родитель
dffe4fdd4f
Коммит
db37ab1039
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright (c) 2018 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "atom/browser/api/event_emitter.h"
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
v8::Local<v8::Object> CreateWithSender(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Object> sender) {
|
||||||
|
return mate::internal::CreateJSEvent(isolate, sender, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
|
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||||
|
dict.SetMethod("createWithSender", &CreateWithSender);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
|
@ -36,6 +36,7 @@
|
||||||
V(atom_browser_debugger) \
|
V(atom_browser_debugger) \
|
||||||
V(atom_browser_dialog) \
|
V(atom_browser_dialog) \
|
||||||
V(atom_browser_download_item) \
|
V(atom_browser_download_item) \
|
||||||
|
V(atom_browser_event) \
|
||||||
V(atom_browser_global_shortcut) \
|
V(atom_browser_global_shortcut) \
|
||||||
V(atom_browser_in_app_purchase) \
|
V(atom_browser_in_app_purchase) \
|
||||||
V(atom_browser_menu) \
|
V(atom_browser_menu) \
|
||||||
|
|
|
@ -399,6 +399,30 @@ non-minimized.
|
||||||
This event is guaranteed to be emitted after the `ready` event of `app`
|
This event is guaranteed to be emitted after the `ready` event of `app`
|
||||||
gets emitted.
|
gets emitted.
|
||||||
|
|
||||||
|
### Event: 'remote-require'
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
* `event` Event
|
||||||
|
* `webContents` [WebContents](web-contents.md)
|
||||||
|
* `moduleName` String
|
||||||
|
|
||||||
|
Emitted when `remote.require()` is called in the renderer process of `webContents`.
|
||||||
|
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||||
|
Custom value can be returned by setting `event.returnValue`.
|
||||||
|
|
||||||
|
### Event: 'remote-get-global'
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
* `event` Event
|
||||||
|
* `webContents` [WebContents](web-contents.md)
|
||||||
|
* `globalName` String
|
||||||
|
|
||||||
|
Emitted when `remote.getGlobal()` is called in the renderer process of `webContents`.
|
||||||
|
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||||
|
Custom value can be returned by setting `event.returnValue`.
|
||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
The `app` object has the following methods:
|
The `app` object has the following methods:
|
||||||
|
|
|
@ -663,6 +663,28 @@ Returns:
|
||||||
Emitted when the associated window logs a console message. Will not be emitted
|
Emitted when the associated window logs a console message. Will not be emitted
|
||||||
for windows with *offscreen rendering* enabled.
|
for windows with *offscreen rendering* enabled.
|
||||||
|
|
||||||
|
#### Event: 'remote-require'
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
* `event` Event
|
||||||
|
* `moduleName` String
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
* `event` Event
|
||||||
|
* `globalName` String
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
### Instance Methods
|
### Instance Methods
|
||||||
|
|
||||||
#### `contents.loadURL(url[, options])`
|
#### `contents.loadURL(url[, options])`
|
||||||
|
|
|
@ -133,6 +133,7 @@ filenames = {
|
||||||
"atom/browser/api/atom_api_dialog.cc",
|
"atom/browser/api/atom_api_dialog.cc",
|
||||||
"atom/browser/api/atom_api_download_item.cc",
|
"atom/browser/api/atom_api_download_item.cc",
|
||||||
"atom/browser/api/atom_api_download_item.h",
|
"atom/browser/api/atom_api_download_item.h",
|
||||||
|
"atom/browser/api/atom_api_event.cc",
|
||||||
"atom/browser/api/atom_api_global_shortcut.cc",
|
"atom/browser/api/atom_api_global_shortcut.cc",
|
||||||
"atom/browser/api/atom_api_global_shortcut.h",
|
"atom/browser/api/atom_api_global_shortcut.h",
|
||||||
"atom/browser/api/atom_api_in_app_purchase.cc",
|
"atom/browser/api/atom_api_in_app_purchase.cc",
|
||||||
|
|
|
@ -338,6 +338,14 @@ WebContents.prototype._init = function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.on('remote-require', (event, ...args) => {
|
||||||
|
app.emit('remote-require', event, this, ...args)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.on('remote-get-global', (event, ...args) => {
|
||||||
|
app.emit('remote-get-global', event, this, ...args)
|
||||||
|
})
|
||||||
|
|
||||||
deprecate.event(this, 'did-get-response-details', '-did-get-response-details')
|
deprecate.event(this, 'did-get-response-details', '-did-get-response-details')
|
||||||
deprecate.event(this, 'did-get-redirect-request', '-did-get-redirect-request')
|
deprecate.event(this, 'did-get-redirect-request', '-did-get-redirect-request')
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ const fs = require('fs')
|
||||||
const os = require('os')
|
const os = require('os')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const v8Util = process.atomBinding('v8_util')
|
const v8Util = process.atomBinding('v8_util')
|
||||||
|
const eventBinding = process.atomBinding('event')
|
||||||
|
|
||||||
const { isPromise } = electron
|
const { isPromise } = electron
|
||||||
|
|
||||||
|
@ -280,16 +281,38 @@ const handleRemoteCommand = function (channel, handler) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, module) {
|
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, moduleName) {
|
||||||
return valueToMeta(event.sender, contextId, process.mainModule.require(module))
|
const customEvent = eventBinding.createWithSender(event.sender)
|
||||||
|
event.sender.emit('remote-require', customEvent, moduleName)
|
||||||
|
|
||||||
|
if (customEvent.defaultPrevented) {
|
||||||
|
if (typeof customEvent.returnValue === 'undefined') {
|
||||||
|
throw new Error(`Invalid module: ${moduleName}`)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
customEvent.returnValue = process.mainModule.require(moduleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
|
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
|
||||||
return valueToMeta(event.sender, contextId, electron[module])
|
return valueToMeta(event.sender, contextId, electron[module])
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, name) {
|
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, globalName) {
|
||||||
return valueToMeta(event.sender, contextId, global[name])
|
const customEvent = eventBinding.createWithSender(event.sender)
|
||||||
|
event.sender.emit('remote-get-global', customEvent, globalName)
|
||||||
|
|
||||||
|
if (customEvent.defaultPrevented) {
|
||||||
|
if (typeof customEvent.returnValue === 'undefined') {
|
||||||
|
throw new Error(`Invalid global: ${globalName}`)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
customEvent.returnValue = global[globalName]
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
|
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
|
||||||
|
|
|
@ -358,6 +358,28 @@ describe('app module', () => {
|
||||||
})
|
})
|
||||||
w = new BrowserWindow({ show: false })
|
w = new BrowserWindow({ show: false })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should emit remote-require event when remote.require() is invoked', (done) => {
|
||||||
|
app.once('remote-require', (event, webContents, moduleName) => {
|
||||||
|
expect(webContents).to.equal(w.webContents)
|
||||||
|
expect(moduleName).to.equal('test')
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
w = new BrowserWindow({ show: false })
|
||||||
|
w.loadURL('about:blank')
|
||||||
|
w.webContents.executeJavaScript(`require('electron').remote.require('test')`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should emit remote-get-global event when remote.getGlobal() is invoked', (done) => {
|
||||||
|
app.once('remote-get-global', (event, webContents, globalName) => {
|
||||||
|
expect(webContents).to.equal(w.webContents)
|
||||||
|
expect(globalName).to.equal('test')
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
w = new BrowserWindow({ show: false })
|
||||||
|
w.loadURL('about:blank')
|
||||||
|
w.webContents.executeJavaScript(`require('electron').remote.getGlobal('test')`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('app.setBadgeCount', () => {
|
describe('app.setBadgeCount', () => {
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
|
const chai = require('chai')
|
||||||
|
const dirtyChai = require('dirty-chai')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const { closeWindow } = require('./window-helpers')
|
const { closeWindow } = require('./window-helpers')
|
||||||
const { resolveGetters } = require('./assert-helpers')
|
const { resolveGetters } = require('./assert-helpers')
|
||||||
|
|
||||||
const { remote } = require('electron')
|
const { remote, ipcRenderer } = require('electron')
|
||||||
|
const { expect } = chai
|
||||||
|
|
||||||
|
chai.use(dirtyChai)
|
||||||
|
|
||||||
const comparePaths = (path1, path2) => {
|
const comparePaths = (path1, path2) => {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
|
@ -22,7 +27,29 @@ describe('remote module', () => {
|
||||||
|
|
||||||
afterEach(() => closeWindow(w).then(() => { w = null }))
|
afterEach(() => closeWindow(w).then(() => { w = null }))
|
||||||
|
|
||||||
|
describe('remote.getGlobal', () => {
|
||||||
|
it('can return custom values', () => {
|
||||||
|
ipcRenderer.send('handle-next-remote-get-global', { test: 'Hello World!' })
|
||||||
|
expect(remote.getGlobal('test')).to.be.equal('Hello World!')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws when no returnValue set', () => {
|
||||||
|
ipcRenderer.send('handle-next-remote-get-global')
|
||||||
|
expect(() => remote.getGlobal('process')).to.throw('Invalid global: process')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('remote.require', () => {
|
describe('remote.require', () => {
|
||||||
|
it('can return custom values', () => {
|
||||||
|
ipcRenderer.send('handle-next-remote-require', { test: 'Hello World!' })
|
||||||
|
expect(remote.require('test')).to.be.equal('Hello World!')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws when no returnValue set', () => {
|
||||||
|
ipcRenderer.send('handle-next-remote-require')
|
||||||
|
expect(() => remote.require('electron')).to.throw('Invalid module: electron')
|
||||||
|
})
|
||||||
|
|
||||||
it('should returns same object for the same module', () => {
|
it('should returns same object for the same module', () => {
|
||||||
const dialog1 = remote.require('electron')
|
const dialog1 = remote.require('electron')
|
||||||
const dialog2 = remote.require('electron')
|
const dialog2 = remote.require('electron')
|
||||||
|
|
|
@ -242,6 +242,24 @@ app.on('ready', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.on('handle-next-remote-require', function (event, modulesMap = {}) {
|
||||||
|
event.sender.once('remote-require', (event, moduleName) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if (modulesMap.hasOwnProperty(moduleName)) {
|
||||||
|
event.returnValue = modulesMap[moduleName]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('handle-next-remote-get-global', function (event, globalsMap = {}) {
|
||||||
|
event.sender.once('remote-get-global', (event, globalName) => {
|
||||||
|
event.preventDefault()
|
||||||
|
if (globalsMap.hasOwnProperty(globalName)) {
|
||||||
|
event.returnValue = globalsMap[globalName]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
ipcMain.on('set-client-certificate-option', function (event, skip) {
|
ipcMain.on('set-client-certificate-option', function (event, skip) {
|
||||||
app.once('select-client-certificate', function (event, webContents, url, list, callback) {
|
app.once('select-client-certificate', function (event, webContents, url, list, callback) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
Загрузка…
Ссылка в новой задаче