Skip to content
Permalink
Browse files

refactor: take advantage of structured clone algorithm in the remote …

…module (#20427)
  • Loading branch information...
miniak authored and jkleinsc committed Oct 10, 2019
1 parent c2e77e4 commit b92163d2260dcee8dfef531a9fb837b6d372e060
@@ -138,9 +138,7 @@ auto_filenames = {
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/remote/type-utils.ts",
"lib/common/web-view-methods.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
@@ -175,7 +173,6 @@ auto_filenames = {

isolated_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/isolated_renderer/init.js",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
@@ -189,7 +186,6 @@ auto_filenames = {

content_script_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/content_script/init.js",
"lib/renderer/chrome-api.ts",
"lib/renderer/extensions/event.ts",
@@ -272,11 +268,9 @@ auto_filenames = {
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"lib/common/parse-features-string.js",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/remote/type-utils.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
@@ -297,10 +291,8 @@ auto_filenames = {
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/remote/type-utils.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.ts",
"lib/renderer/api/crash-reporter.js",
@@ -347,10 +339,8 @@ auto_filenames = {
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/remote/type-utils.ts",
"lib/common/reset-search-paths.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
@@ -10,7 +10,6 @@ const { app, ipcMain, session, deprecate } = electron
const NavigationController = require('@electron/internal/browser/navigation-controller')
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
const errorUtils = require('@electron/internal/common/error-utils')

// session is not used here, the purpose is to make sure session is initalized
// before the webContents module.
@@ -1,5 +1,4 @@
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'
import * as errorUtils from '@electron/internal/common/error-utils'

type IPCHandler = (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any

@@ -8,7 +7,7 @@ export const handleSync = function <T extends IPCHandler> (channel: string, hand
try {
event.returnValue = [null, await handler(event, ...args)]
} catch (error) {
event.returnValue = [errorUtils.serialize(error)]
event.returnValue = [error]
}
})
}
@@ -30,7 +29,7 @@ export function invokeInWebContents<T> (sender: Electron.WebContentsInternal, se
ipcMainInternal.removeListener(channel, handler)

if (error) {
reject(errorUtils.deserialize(error))
reject(error)
} else {
resolve(result)
}
@@ -2,12 +2,10 @@

import * as electron from 'electron'
import { EventEmitter } from 'events'
import { isBuffer, bufferToMeta, BufferMeta, metaToBuffer } from '@electron/internal/common/remote/buffer-utils'
import objectsRegistry from './objects-registry'
import { ipcMainInternal } from '../ipc-main-internal'
import * as guestViewManager from '@electron/internal/browser/guest-view-manager'
import * as errorUtils from '@electron/internal/common/error-utils'
import { isPromise } from '@electron/internal/common/remote/is-promise'
import { isPromise, isSerializableObject } from '@electron/internal/common/remote/type-utils'

const v8Util = process.electronBinding('v8_util')
const eventBinding = process.electronBinding('event')
@@ -105,16 +103,14 @@ type MetaType = {
value: any,
} | {
type: 'buffer',
value: BufferMeta,
value: Uint8Array,
} | {
type: 'array',
members: MetaType[]
} | {
type: 'error',
value: Error,
members: ObjectMember[]
} | {
type: 'date',
value: number
} | {
type: 'promise',
then: MetaType
@@ -126,16 +122,14 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
let type: MetaType['type'] = typeof value
if (type === 'object') {
// Recognize certain types of objects.
if (value === null) {
type = 'value'
} else if (isBuffer(value)) {
if (value instanceof Buffer) {
type = 'buffer'
} else if (Array.isArray(value)) {
type = 'array'
} else if (value instanceof Error) {
type = 'error'
} else if (value instanceof Date) {
type = 'date'
} else if (isSerializableObject(value)) {
type = 'value'
} else if (isPromise(value)) {
type = 'promise'
} else if (hasProp.call(value, 'callee') && value.length != null) {
@@ -165,7 +159,7 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
proto: getObjectPrototype(value)
}
} else if (type === 'buffer') {
return { type, value: bufferToMeta(value) }
return { type, value }
} else if (type === 'promise') {
// Add default handler to prevent unhandled rejections in main process
// Instead they should appear in the renderer process
@@ -178,16 +172,14 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
})
}
} else if (type === 'error') {
const members = plainObjectToMeta(value)

// Error.name is not part of own properties.
members.push({
name: 'name',
value: value.name
})
return { type, members }
} else if (type === 'date') {
return { type, value: value.getTime() }
return {
type,
value,
members: Object.keys(value).map(name => ({
name,
value: valueToMeta(sender, contextId, value[name])
}))
}
} else {
return {
type: 'value',
@@ -196,24 +188,6 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
}
}

// Convert object to meta by value.
const plainObjectToMeta = function (obj: any): ObjectMember[] {
return Object.getOwnPropertyNames(obj).map(function (name) {
return {
name: name,
value: obj[name]
}
})
}

// Convert Error into meta data.
const exceptionToMeta = function (error: Error) {
return {
type: 'exception',
value: errorUtils.serialize(error)
}
}

const throwRPCError = function (message: string) {
const error = new Error(message) as Error & {code: string, errno: number}
error.code = 'EBADRPC'
@@ -253,10 +227,7 @@ type MetaTypeFromRenderer = {
value: MetaTypeFromRenderer[]
} | {
type: 'buffer',
value: BufferMeta
} | {
type: 'date',
value: number
value: Uint8Array
} | {
type: 'promise',
then: MetaTypeFromRenderer
@@ -285,9 +256,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
case 'array':
return unwrapArgs(sender, frameId, contextId, meta.value)
case 'buffer':
return metaToBuffer(meta.value)
case 'date':
return new Date(meta.value)
return Buffer.from(meta.value.buffer, meta.value.byteOffset, meta.value.byteLength)
case 'promise':
return Promise.resolve({
then: metaToValue(meta.then)
@@ -365,7 +334,10 @@ const handleRemoteCommand = function (channel: string, handler: (event: Electron
try {
returnValue = handler(event, contextId, ...args)
} catch (error) {
returnValue = exceptionToMeta(error)
returnValue = {
type: 'exception',
value: valueToMeta(event.sender, contextId, error)
}
}

if (returnValue !== undefined) {
@@ -11,7 +11,6 @@ const { crashReporterInit } = require('@electron/internal/browser/crash-reporter
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
const guestViewManager = require('@electron/internal/browser/guest-view-manager')
const errorUtils = require('@electron/internal/common/error-utils')
const clipboardUtils = require('@electron/internal/common/clipboard-utils')

const emitCustomEvent = function (contents, eventName, ...args) {
@@ -91,8 +90,8 @@ const getPreloadScript = async function (preloadPath) {
let preloadError = null
try {
preloadSrc = (await fs.promises.readFile(preloadPath)).toString()
} catch (err) {
preloadError = errorUtils.serialize(err)
} catch (error) {
preloadError = error
}
return { preloadPath, preloadSrc, preloadError }
}
@@ -130,5 +129,5 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event)
})

ipcMainInternal.on('ELECTRON_BROWSER_PRELOAD_ERROR', function (event, preloadPath, error) {
event.sender.emit('preload-error', event, preloadPath, errorUtils.deserialize(error))
event.sender.emit('preload-error', event, preloadPath, error)
})

This file was deleted.

This file was deleted.

@@ -10,3 +10,16 @@ export function isPromise (val: any) {
val.constructor.resolve instanceof Function
)
}

const serializableTypes = [
Boolean,
Number,
String,
Date,
RegExp,
ArrayBuffer
]

export function isSerializableObject (value: any) {
return value === null || ArrayBuffer.isView(value) || serializableTypes.some(type => value instanceof type)
}

0 comments on commit b92163d

Please sign in to comment.
You can’t perform that action at this time.