electron/lib/browser/rpc-server.ts

126 lines
4.2 KiB
TypeScript
Raw Normal View History

import { app } from 'electron/main';
import type { WebContents } from 'electron/main';
import { clipboard, nativeImage } from 'electron/common';
import * as fs from 'fs';
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
import * as typeUtils from '@electron/internal/common/type-utils';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
const eventBinding = process._linkedBinding('electron_browser_event');
const emitCustomEvent = function (contents: WebContents, eventName: string, ...args: any[]) {
2020-03-20 20:28:31 +00:00
const event = eventBinding.createWithSender(contents);
app.emit(eventName, event, contents, ...args);
2020-03-20 20:28:31 +00:00
contents.emit(eventName, event, ...args);
2020-03-20 20:28:31 +00:00
return event;
};
const logStack = function (contents: WebContents, code: string, stack: string) {
if (stack) {
2020-03-20 20:28:31 +00:00
console.warn(`WebContents (${contents.id}): ${code}`, stack);
}
2020-03-20 20:28:31 +00:00
};
// Implements window.close()
ipcMainInternal.on(IPC_MESSAGES.BROWSER_WINDOW_CLOSE, function (event) {
2020-03-20 20:28:31 +00:00
const window = event.sender.getOwnerBrowserWindow();
2017-08-17 17:56:37 +00:00
if (window) {
2020-03-20 20:28:31 +00:00
window.close();
}
2020-03-20 20:28:31 +00:00
event.returnValue = null;
});
ipcMainInternal.handle(IPC_MESSAGES.BROWSER_GET_LAST_WEB_PREFERENCES, function (event) {
2020-03-20 20:28:31 +00:00
return event.sender.getLastWebPreferences();
});
// Methods not listed in this set are called directly in the renderer process.
const allowedClipboardMethods = (() => {
switch (process.platform) {
case 'darwin':
2020-03-20 20:28:31 +00:00
return new Set(['readFindText', 'writeFindText']);
case 'linux':
2020-03-20 20:28:31 +00:00
return new Set(Object.keys(clipboard));
default:
2020-03-20 20:28:31 +00:00
return new Set();
}
2020-03-20 20:28:31 +00:00
})();
ipcMainUtils.handleSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, function (event, method: string, ...args: any[]) {
if (!allowedClipboardMethods.has(method)) {
2020-03-20 20:28:31 +00:00
throw new Error(`Invalid method: ${method}`);
}
return typeUtils.serialize((clipboard as any)[method](...typeUtils.deserialize(args)));
2020-03-20 20:28:31 +00:00
});
if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) {
2020-03-20 20:28:31 +00:00
const desktopCapturer = require('@electron/internal/browser/desktop-capturer');
ipcMainInternal.handle(IPC_MESSAGES.DESKTOP_CAPTURER_GET_SOURCES, async function (event, options: Electron.SourcesOptions, stack: string) {
2020-03-20 20:28:31 +00:00
logStack(event.sender, 'desktopCapturer.getSources()', stack);
const customEvent = emitCustomEvent(event.sender, 'desktop-capturer-get-sources');
if (customEvent.defaultPrevented) {
2020-03-20 20:28:31 +00:00
console.error('Blocked desktopCapturer.getSources()');
return [];
}
return typeUtils.serialize(await desktopCapturer.getSourcesImpl(event, options));
2020-03-20 20:28:31 +00:00
});
}
const getPreloadScript = async function (preloadPath: string) {
2020-03-20 20:28:31 +00:00
let preloadSrc = null;
let preloadError = null;
try {
preloadSrc = await fs.promises.readFile(preloadPath, 'utf8');
} catch (error) {
2020-03-20 20:28:31 +00:00
preloadError = error;
}
2020-03-20 20:28:31 +00:00
return { preloadPath, preloadSrc, preloadError };
};
ipcMainUtils.handleSync(IPC_MESSAGES.BROWSER_SANDBOX_LOAD, async function (event) {
2020-03-20 20:28:31 +00:00
const preloadPaths = event.sender._getPreloadPaths();
return {
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
process: {
arch: process.arch,
platform: process.platform,
refactor: use v8 serialization for ipc (#20214) * refactor: use v8 serialization for ipc * cloning process.env doesn't work * serialize host objects by enumerating key/values * new serialization can handle NaN, Infinity, and undefined correctly * can't allocate v8 objects during GC * backport microtasks fix * fix compile * fix node_stream_loader reentrancy * update subframe spec to expect undefined instead of null * write undefined instead of crashing when serializing host objects * fix webview spec * fix download spec * buffers are transformed into uint8arrays * can't serialize promises * fix chrome.i18n.getMessage * fix devtools tests * fix zoom test * fix debug build * fix lint * update ipcRenderer tests * fix printToPDF test * update patch * remove accidentally re-added remote-side spec * wip * don't attempt to serialize host objects * jump through different hoops to set options.webContents sometimes * whoops * fix lint * clean up error-handling logic * fix memory leak * fix lint * convert host objects using old base::Value serialization * fix lint more * fall back to base::Value-based serialization * remove commented-out code * add docs to breaking-changes.md * Update breaking-changes.md * update ipcRenderer and WebContents docs * lint * use named values for format tag * save a memcpy for ~30% speedup * get rid of calls to ShallowClone * extra debugging for paranoia * d'oh, use the correct named tags * apparently msstl doesn't like this DCHECK * funny story about that DCHECK * disable remote-related functions when enable_remote_module = false * nits * use EnableIf to disable remote methods in mojom * fix include * review comments
2019-10-09 17:59:08 +00:00
env: { ...process.env },
version: process.version,
versions: process.versions,
execPath: process.helperExecPath
}
2020-03-20 20:28:31 +00:00
};
});
ipcMainInternal.on(IPC_MESSAGES.NAVIGATION_CONTROLLER_GO_BACK, function (event) {
event.sender.goBack();
});
ipcMainInternal.on(IPC_MESSAGES.NAVIGATION_CONTROLLER_GO_FORWARD, function (event) {
event.sender.goForward();
});
ipcMainInternal.on(IPC_MESSAGES.NAVIGATION_CONTROLLER_GO_TO_OFFSET, function (event, offset) {
event.sender.goToOffset(offset);
});
ipcMainInternal.on(IPC_MESSAGES.NAVIGATION_CONTROLLER_LENGTH, function (event) {
event.returnValue = event.sender.length();
});
ipcMainInternal.on(IPC_MESSAGES.BROWSER_PRELOAD_ERROR, function (event, preloadPath: string, error: Error) {
2020-03-20 20:28:31 +00:00
event.sender.emit('preload-error', event, preloadPath, error);
});
ipcMainInternal.handle(IPC_MESSAGES.NATIVE_IMAGE_CREATE_THUMBNAIL_FROM_PATH, async (_, path: string, size: Electron.Size) => {
return typeUtils.serialize(await nativeImage.createThumbnailFromPath(path, size));
});