Skip to content

Commit

Permalink
feat: make ipc-message and ipc-message-sync events public
Browse files Browse the repository at this point in the history
  • Loading branch information
miniak committed Jan 21, 2019
1 parent 0b0679e commit f19fda8
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 29 deletions.
2 changes: 1 addition & 1 deletion atom/renderer/atom_render_frame_observer.cc
Expand Up @@ -216,7 +216,7 @@ void AtomRenderFrameObserver::OnTakeHeapSnapshot(
args.AppendBoolean(success);

render_frame_->Send(new AtomFrameHostMsg_Message(
render_frame_->GetRoutingID(), "ipc-message", args));
render_frame_->GetRoutingID(), "ipc-internal-message", args));
}

void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
Expand Down
20 changes: 20 additions & 0 deletions docs/api/web-contents.md
Expand Up @@ -673,6 +673,26 @@ Returns:

Emitted when the preload script `preloadPath` throws an unhandled exception `error`.

#### Event: 'ipc-message'

Returns:

* `event` Event
* `channel` String
* `...args` any[]

Emitted when the renderer process sends an asynchronous message via `ipcRenderer.send()`.

#### Event: 'ipc-message-sync'

Returns:

* `event` Event
* `channel` String
* `...args` any[]

Emitted when the renderer process sends a synchronous message via `ipcRenderer.sendSync()`.

#### Event: 'desktop-capturer-get-sources'

Returns:
Expand Down
10 changes: 6 additions & 4 deletions lib/browser/api/web-contents.js
Expand Up @@ -237,15 +237,15 @@ WebContents.prototype.getZoomFactor = function (callback) {
WebContents.prototype.takeHeapSnapshot = function (filePath) {
return new Promise((resolve, reject) => {
const channel = `ELECTRON_TAKE_HEAP_SNAPSHOT_RESULT_${getNextId()}`
ipcMain.once(channel, (event, success) => {
ipcMainInternal.once(channel, (event, success) => {
if (success) {
resolve()
} else {
reject(new Error('takeHeapSnapshot failed'))
}
})
if (!this._takeHeapSnapshot(filePath, channel)) {
ipcMain.emit(channel, false)
ipcMainInternal.emit(channel, false)
}
})
}
Expand Down Expand Up @@ -342,17 +342,19 @@ WebContents.prototype._init = function () {
this.capturePage = deprecate.promisify(this.capturePage, 2)

// Dispatch IPC messages to the ipc module.
this.on('ipc-message', function (event, [channel, ...args]) {
this.on('-ipc-message', function (event, [channel, ...args]) {
this.emit('ipc-message', event, channel, ...args)
ipcMain.emit(channel, event, ...args)
})

this.on('ipc-message-sync', function (event, [channel, ...args]) {
this.on('-ipc-message-sync', function (event, [channel, ...args]) {
Object.defineProperty(event, 'returnValue', {
set: function (value) {
return event.sendReply([value])
},
get: function () {}
})
this.emit('ipc-message-sync', event, channel, ...args)
ipcMain.emit(channel, event, ...args)
})

Expand Down
4 changes: 2 additions & 2 deletions lib/renderer/api/ipc-renderer.js
Expand Up @@ -8,11 +8,11 @@ const ipcRenderer = v8Util.getHiddenValue(global, 'ipc')
const internal = false

ipcRenderer.send = function (...args) {
return binding.send('ipc-message', args)
return binding.send('-ipc-message', args)
}

ipcRenderer.sendSync = function (...args) {
return binding.sendSync('ipc-message-sync', args)[0]
return binding.sendSync('-ipc-message-sync', args)[0]
}

ipcRenderer.sendToHost = function (...args) {
Expand Down
28 changes: 28 additions & 0 deletions spec/api-web-contents-spec.js
Expand Up @@ -995,6 +995,34 @@ describe('webContents module', () => {
})
})

describe('ipc-message event', () => {
it('emits when the renderer process sends an asynchronous message', async () => {
const webContents = remote.getCurrentWebContents()
const promise = emittedOnce(webContents, 'ipc-message')

ipcRenderer.send('message', 'Hello World!')

const [, channel, args] = await promise
expect(channel).to.equal('message')
expect(args[0]).to.equal('Hello World!')
})
})

describe('ipc-message-sync event', () => {
it('emits when the renderer process sends a synchronous message', async () => {
const webContents = remote.getCurrentWebContents()
const promise = emittedOnce(webContents, 'ipc-message-sync')

ipcRenderer.send('handle-next-ipc-message-sync', 'foobar')
const result = ipcRenderer.sendSync('message', 'Hello World!')

const [, channel, args] = await promise
expect(channel).to.equal('message')
expect(args[0]).to.equal('Hello World!')
expect(result).to.equal('foobar')
})
})

describe('referrer', () => {
it('propagates referrer information to new target=_blank windows', (done) => {
const server = http.createServer((req, res) => {
Expand Down
42 changes: 21 additions & 21 deletions spec/chromium-spec.js
Expand Up @@ -175,8 +175,8 @@ describe('chromium feature', () => {
session: ses
}
})
w.webContents.on('ipc-message', (event, args) => {
if (args[0] === 'deviceIds') deviceIds.push(args[1])
w.webContents.on('ipc-message', (event, channel, [deviceId]) => {
if (channel === 'deviceIds') deviceIds.push(deviceId)
if (deviceIds.length === 2) {
assert.notDeepStrictEqual(deviceIds[0], deviceIds[1])
closeWindow(w).then(() => {
Expand Down Expand Up @@ -216,13 +216,13 @@ describe('chromium feature', () => {
partition: 'sw-file-scheme-spec'
}
})
w.webContents.on('ipc-message', (event, args) => {
if (args[0] === 'reload') {
w.webContents.on('ipc-message', (event, channel, args) => {
if (channel === 'reload') {
w.webContents.reload()
} else if (args[0] === 'error') {
done(args[1])
} else if (args[0] === 'response') {
assert.strictEqual(args[1], 'Hello from serviceWorker!')
} else if (channel === 'error') {
done(args[0])
} else if (channel === 'response') {
assert.strictEqual(args[0], 'Hello from serviceWorker!')
session.fromPartition('sw-file-scheme-spec').clearStorageData({
storages: ['serviceworkers']
}, () => done())
Expand Down Expand Up @@ -255,13 +255,13 @@ describe('chromium feature', () => {
session: customSession
}
})
w.webContents.on('ipc-message', (event, args) => {
if (args[0] === 'reload') {
w.webContents.on('ipc-message', (event, channel, args) => {
if (channel === 'reload') {
w.webContents.reload()
} else if (args[0] === 'error') {
done(`unexpected error : ${args[1]}`)
} else if (args[0] === 'response') {
assert.strictEqual(args[1], 'Hello from serviceWorker!')
} else if (channel === 'error') {
done(`unexpected error : ${args[0]}`)
} else if (channel === 'response') {
assert.strictEqual(args[0], 'Hello from serviceWorker!')
customSession.clearStorageData({
storages: ['serviceworkers']
}, () => {
Expand Down Expand Up @@ -298,8 +298,8 @@ describe('chromium feature', () => {
partition: 'geolocation-spec'
}
})
w.webContents.on('ipc-message', (event, args) => {
if (args[0] === 'success') {
w.webContents.on('ipc-message', (event, channel, args) => {
if (channel === 'success') {
done()
} else {
done('unexpected response from geolocation api')
Expand Down Expand Up @@ -584,18 +584,18 @@ describe('chromium feature', () => {

describe('window.opener', () => {
const url = `file://${fixtures}/pages/window-opener.html`
it('is null for main window', (done) => {
it('is null for main window', async () => {
w = new BrowserWindow({
show: false,
webPreferences: {
nodeIntegration: true
}
})
w.webContents.once('ipc-message', (event, args) => {
assert.deepStrictEqual(args, ['opener', null])
done()
})
const promise = emittedOnce(w.webContents, 'ipc-message')
w.loadFile(path.join(fixtures, 'pages', 'window-opener.html'))
const [, channel, args] = await promise
expect(channel).to.equal('opener')
expect(args[0]).to.equal(null)
})

it('is not null for window opened by window.open', (done) => {
Expand Down
6 changes: 6 additions & 0 deletions spec/static/main.js
Expand Up @@ -235,6 +235,12 @@ app.on('ready', function () {
})
})

ipcMain.on('handle-next-ipc-message-sync', function (event, returnValue) {
event.sender.once('ipc-message-sync', (event, channel, args) => {
event.returnValue = returnValue
})
})

for (const eventName of [
'remote-require',
'remote-get-global',
Expand Down
2 changes: 1 addition & 1 deletion spec/webview-spec.js
Expand Up @@ -624,7 +624,7 @@ describe('<webview> tag', function () {
})

describe('ipc-message event', () => {
it('emits when guest sends a ipc message to browser', async () => {
it('emits when guest sends an ipc message to browser', async () => {
loadWebView(webview, {
nodeintegration: 'on',
src: `file://${fixtures}/pages/ipc-message.html`
Expand Down

0 comments on commit f19fda8

Please sign in to comment.