Skip to content

Commit

Permalink
refactor: Split 'Event' docs/types into more specific Event types
Browse files Browse the repository at this point in the history
* Event = Base event type (with preventDefault)
* IpcMainEvent = Event that ipcMain emits (with sender, reply, etc.)
* IpcRendererEvent = Event that ipcRenderer emits (with sender,
senderId, etc.)
* KeyboardEvent = Event that we emit with keyboard flags (ctrlKey,
altKey, etc.)

This will dramatically improve peoples TS experience with IPC events
  • Loading branch information
MarshallOfSound committed Feb 19, 2019
1 parent ef2e7d9 commit 71de845
Show file tree
Hide file tree
Showing 22 changed files with 514 additions and 284 deletions.
3 changes: 3 additions & 0 deletions build/tsc.gni
Expand Up @@ -22,6 +22,9 @@ template("typescript_build") {
invoker.tsconfig,
"//electron/tsconfig.json",
"//electron/package-lock.json",
"//electron/typings/internal-ambient.d.ts",
"//electron/typings/internal-electron.d.ts",
"//electron/typings/internal-helpers.d.ts",
]

type_roots = "node_modules/@types,typings"
Expand Down
30 changes: 6 additions & 24 deletions docs/api/ipc-main.md
Expand Up @@ -58,6 +58,8 @@ The `ipcMain` module has the following method to listen for events:

* `channel` String
* `listener` Function
* `event` IpcMainEvent
* `...args` any[]

Listens to `channel`, when a new message arrives `listener` would be called with
`listener(event, args...)`.
Expand All @@ -66,6 +68,8 @@ Listens to `channel`, when a new message arrives `listener` would be called with

* `channel` String
* `listener` Function
* `event` IpcMainEvent
* `...args` any[]

Adds a one time `listener` function for the event. This `listener` is invoked
only the next time a message is sent to `channel`, after which it is removed.
Expand All @@ -86,27 +90,5 @@ Removes listeners of the specified `channel`.

## Event object

The `event` object passed to the `callback` has the following methods:

### `event.frameId`

An `Integer` representing the ID of the renderer frame that sent this message.

### `event.returnValue`

Set this to the value to be returned in a synchronous message.

### `event.sender`

Returns the `webContents` that sent the message, you can call
`event.sender.send` to reply to the asynchronous message, see
[webContents.send][web-contents-send] for more information.

[web-contents-send]: web-contents.md#contentssendchannel-arg1-arg2-

### `event.reply`

A function that will send an IPC message to the renderer frane that sent
the original message that you are currently handling. You should use this
method to "reply" to the sent message in order to guaruntee the reply will go
to the correct process and frame.
The documentation for the `event` object passed to the `callback` can be found
in the [`ipc-main-event`](structures/ipc-main-event.md) structure docs.
17 changes: 6 additions & 11 deletions docs/api/ipc-renderer.md
Expand Up @@ -20,6 +20,8 @@ The `ipcRenderer` module has the following method to listen for events and send

* `channel` String
* `listener` Function
* `event` IpcRendererEvent
* `...args` any[]

Listens to `channel`, when a new message arrives `listener` would be called with
`listener(event, args...)`.
Expand All @@ -28,6 +30,8 @@ Listens to `channel`, when a new message arrives `listener` would be called with

* `channel` String
* `listener` Function
* `event` IpcRendererEvent
* `...args` any[]

Adds a one time `listener` function for the event. This `listener` is invoked
only the next time a message is sent to `channel`, after which it is removed.
Expand Down Expand Up @@ -92,14 +96,5 @@ the host page instead of the main process.

## Event object

The `event` object passed to the `callback` has the following methods:

### `event.senderId`

Returns the `webContents.id` that sent the message, you can call
`event.sender.sendTo(event.senderId, ...)` to reply to the message, see
[ipcRenderer.sendTo][ipc-renderer-sendto] for more information.
This only applies to messages sent from a different renderer.
Messages sent directly from the main process set `event.senderId` to `0`.

[ipc-renderer-sendto]: #ipcrenderersendtowindowid-channel--arg1-arg2-
The documentation for the `event` object passed to the `callback` can be found
in the [`ipc-renderer-event`](structures/ipc-renderer-event.md) structure docs.
2 changes: 1 addition & 1 deletion docs/api/menu-item.md
Expand Up @@ -13,7 +13,7 @@ See [`Menu`](menu.md) for examples.
`click(menuItem, browserWindow, event)` when the menu item is clicked.
* `menuItem` MenuItem
* `browserWindow` [BrowserWindow](browser-window.md)
* `event` Event
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteandmatchstyle`, `delete`, `selectall`, `reload`, `forcereload`, `toggledevtools`, `resetzoom`, `zoomin`, `zoomout`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideothers`, `unhide`, `quit`, `startspeaking`, `stopspeaking`, `close`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](#roles).
* `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
Expand Down
6 changes: 0 additions & 6 deletions docs/api/structures/event.md
@@ -1,9 +1,3 @@
# Event Object extends `GlobalEvent`

* `preventDefault` VoidFunction
* `sender` WebContents
* `returnValue` any
* `ctrlKey` Boolean (optional) - whether the Control key was used in an accelerator to trigger the Event
* `metaKey` Boolean (optional) - whether a meta key was used in an accelerator to trigger the Event
* `shiftKey` Boolean (optional) - whether a Shift key was used in an accelerator to trigger the Event
* `altKey` Boolean (optional) - whether an Alt key was used in an accelerator to trigger the Event
8 changes: 8 additions & 0 deletions docs/api/structures/ipc-main-event.md
@@ -0,0 +1,8 @@
# IpcMainEvent Object extends `Event`

* `frameId` Integer - The ID of the renderer frame that sent this message
* `returnValue` any - Set this to the value to be returned in a syncronous message
* `sender` WebContents - Returns the `webContents` that sent the message
* `reply` Function - A function that will send an IPC message to the renderer frane that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guaruntee the reply will go to the correct process and frame.
* `...args` any[]
IpcRenderer
6 changes: 6 additions & 0 deletions docs/api/structures/ipc-renderer-event.md
@@ -0,0 +1,6 @@
# IpcRendererEvent Object extends `Event`

* `sender` IpcRenderer - The `IpcRenderer` instance that emitted the event originally
* `senderId` Integer - The `webContents.id` that sent the message, you can call `event.sender.sendTo(event.senderId, ...)` to reply to the message, see [ipcRenderer.sendTo][ipc-renderer-sendto] for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set `event.senderId` to `0`.

[ipc-renderer-sendto]: #ipcrenderersendtowindowid-channel--arg1-arg2-
6 changes: 6 additions & 0 deletions docs/api/structures/keyboard-event.md
@@ -0,0 +1,6 @@
# KeyboardEvent Object extends `Event`

* `ctrlKey` Boolean (optional) - whether the Control key was used in an accelerator to trigger the Event
* `metaKey` Boolean (optional) - whether a meta key was used in an accelerator to trigger the Event
* `shiftKey` Boolean (optional) - whether a Shift key was used in an accelerator to trigger the Event
* `altKey` Boolean (optional) - whether an Alt key was used in an accelerator to trigger the Event
36 changes: 6 additions & 30 deletions docs/api/tray.md
Expand Up @@ -70,34 +70,22 @@ The `Tray` module emits the following events:

#### Event: 'click'

* `event` Event
* `altKey` Boolean
* `shiftKey` Boolean
* `ctrlKey` Boolean
* `metaKey` Boolean
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `bounds` [Rectangle](structures/rectangle.md) - The bounds of tray icon.
* `position` [Point](structures/point.md) - The position of the event.

Emitted when the tray icon is clicked.

#### Event: 'right-click' _macOS_ _Windows_

* `event` Event
* `altKey` Boolean
* `shiftKey` Boolean
* `ctrlKey` Boolean
* `metaKey` Boolean
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `bounds` [Rectangle](structures/rectangle.md) - The bounds of tray icon.

Emitted when the tray icon is right clicked.

#### Event: 'double-click' _macOS_ _Windows_

* `event` Event
* `altKey` Boolean
* `shiftKey` Boolean
* `ctrlKey` Boolean
* `metaKey` Boolean
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `bounds` [Rectangle](structures/rectangle.md) - The bounds of tray icon.

Emitted when the tray icon is double clicked.
Expand Down Expand Up @@ -147,33 +135,21 @@ Emitted when a drag operation ends on the tray or ends at another location.

#### Event: 'mouse-enter' _macOS_

* `event` Event
* `altKey` Boolean
* `shiftKey` Boolean
* `ctrlKey` Boolean
* `metaKey` Boolean
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `position` [Point](structures/point.md) - The position of the event.

Emitted when the mouse enters the tray icon.

#### Event: 'mouse-leave' _macOS_

* `event` Event
* `altKey` Boolean
* `shiftKey` Boolean
* `ctrlKey` Boolean
* `metaKey` Boolean
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `position` [Point](structures/point.md) - The position of the event.

Emitted when the mouse exits the tray icon.

#### Event: 'mouse-move' _macOS_

* `event` Event
* `altKey` Boolean
* `shiftKey` Boolean
* `ctrlKey` Boolean
* `metaKey` Boolean
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `position` [Point](structures/point.md) - The position of the event.

Emitted when the mouse moves in the tray icon.
Expand Down
3 changes: 3 additions & 0 deletions filenames.auto.gni
Expand Up @@ -75,8 +75,11 @@ auto_filenames = {
"docs/api/structures/file-filter.md",
"docs/api/structures/gpu-feature-status.md",
"docs/api/structures/io-counters.md",
"docs/api/structures/ipc-main-event.md",
"docs/api/structures/ipc-renderer-event.md",
"docs/api/structures/jump-list-category.md",
"docs/api/structures/jump-list-item.md",
"docs/api/structures/keyboard-event.md",
"docs/api/structures/memory-info.md",
"docs/api/structures/memory-usage-details.md",
"docs/api/structures/mime-typed-buffer.md",
Expand Down
2 changes: 1 addition & 1 deletion lib/browser/ipc-main-internal-utils.ts
Expand Up @@ -3,7 +3,7 @@ import * as errorUtils from '@electron/internal/common/error-utils'

type IPCHandler = (...args: any[]) => any

const callHandler = async function (handler: IPCHandler, event: Electron.Event, args: any[], reply: (args: any[]) => void) {
const callHandler = async function (handler: IPCHandler, event: ElectronInternal.IpcMainInternalEvent, args: any[], reply: (args: any[]) => void) {
try {
const result = await handler(event, ...args)
reply([null, result])
Expand Down
2 changes: 1 addition & 1 deletion lib/browser/ipc-main-internal.ts
Expand Up @@ -5,4 +5,4 @@ const emitter = new EventEmitter()
// Do not throw exception when channel name is "error".
emitter.on('error', () => {})

export const ipcMainInternal = emitter
export const ipcMainInternal = emitter as ElectronInternal.IpcMainInternal
2 changes: 1 addition & 1 deletion lib/renderer/content-scripts-injector.ts
Expand Up @@ -84,7 +84,7 @@ const injectContentScript = function (extensionId: string, script: Electron.Cont

// Handle the request of chrome.tabs.executeJavaScript.
ipcRendererInternal.on('CHROME_TABS_EXECUTESCRIPT', function (
event: Electron.Event,
event,
senderWebContentsId: number,
requestId: number,
extensionId: string,
Expand Down
2 changes: 1 addition & 1 deletion lib/renderer/ipc-renderer-internal-utils.ts
Expand Up @@ -7,7 +7,7 @@ export function invoke<T> (command: string, ...args: any[]) {
return new Promise<T>((resolve, reject) => {
const requestId = ++nextId
ipcRendererInternal.once(`${command}_RESPONSE_${requestId}`, (
_event: Electron.Event, error: Electron.SerializedError, result: any
_event, error: Electron.SerializedError, result: any
) => {
if (error) {
reject(errorUtils.deserialize(error))
Expand Down
4 changes: 2 additions & 2 deletions lib/renderer/web-frame-init.ts
Expand Up @@ -11,7 +11,7 @@ type WebFrameMethod = {
export const webFrameInit = () => {
// Call webFrame method
ipcRendererInternal.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (
_event: Electron.Event, method: keyof WebFrameMethod, args: any[]
_event, method: keyof WebFrameMethod, args: any[]
) => {
// The TypeScript compiler cannot handle the sheer number of
// call signatures here and simply gives up. Incorrect invocations
Expand All @@ -20,7 +20,7 @@ export const webFrameInit = () => {
})

ipcRendererInternal.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (
event: Electron.Event, requestId: number, method: keyof WebFrameMethod, args: any[]
event, requestId: number, method: keyof WebFrameMethod, args: any[]
) => {
new Promise(resolve =>
// The TypeScript compiler cannot handle the sheer number of
Expand Down
4 changes: 2 additions & 2 deletions lib/renderer/window-setup.ts
Expand Up @@ -206,7 +206,7 @@ export const windowSetup = (
}

ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
_event: Electron.Event, sourceId: number, message: any, sourceOrigin: string
_event, sourceId: number, message: any, sourceOrigin: string
) {
// Manually dispatch event instead of using postMessage because we also need to
// set event.source.
Expand Down Expand Up @@ -253,7 +253,7 @@ export const windowSetup = (
let cachedVisibilityState = isHiddenPage ? 'hidden' : 'visible'

// Subscribe to visibilityState changes.
ipcRendererInternal.on('ELECTRON_GUEST_INSTANCE_VISIBILITY_CHANGE', function (_event: Electron.Event, visibilityState: VisibilityState) {
ipcRendererInternal.on('ELECTRON_GUEST_INSTANCE_VISIBILITY_CHANGE', function (_event, visibilityState: VisibilityState) {
if (cachedVisibilityState !== visibilityState) {
cachedVisibilityState = visibilityState
document.dispatchEvent(new Event('visibilitychange'))
Expand Down

0 comments on commit 71de845

Please sign in to comment.