fix: ensure nativeImage serialization main->renderer (#23759)
This commit is contained in:
parent
e5da2caa34
commit
e8ea007104
3 changed files with 41 additions and 8 deletions
|
@ -4,12 +4,13 @@ import * as electron from 'electron';
|
|||
import { EventEmitter } from 'events';
|
||||
import objectsRegistry from './objects-registry';
|
||||
import { ipcMainInternal } from '../ipc-main-internal';
|
||||
import { isPromise, isSerializableObject, deserialize } from '@electron/internal/common/type-utils';
|
||||
import { isPromise, isSerializableObject, deserialize, serialize } from '@electron/internal/common/type-utils';
|
||||
import { Size } from 'electron/main';
|
||||
|
||||
const v8Util = process.electronBinding('v8_util');
|
||||
const eventBinding = process.electronBinding('event');
|
||||
const features = process.electronBinding('features');
|
||||
const { NativeImage } = process.electronBinding('native_image');
|
||||
|
||||
if (!features.isRemoteModuleEnabled()) {
|
||||
throw new Error('remote module is disabled');
|
||||
|
@ -114,6 +115,9 @@ type MetaType = {
|
|||
} | {
|
||||
type: 'promise',
|
||||
then: MetaType
|
||||
} | {
|
||||
type: 'nativeimage'
|
||||
value: electron.NativeImage
|
||||
}
|
||||
|
||||
// Convert a real value into meta data.
|
||||
|
@ -124,6 +128,8 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
|
|||
// Recognize certain types of objects.
|
||||
if (value instanceof Buffer) {
|
||||
type = 'buffer';
|
||||
} else if (value instanceof NativeImage) {
|
||||
type = 'nativeimage';
|
||||
} else if (Array.isArray(value)) {
|
||||
type = 'array';
|
||||
} else if (value instanceof Error) {
|
||||
|
@ -147,6 +153,8 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
|
|||
type,
|
||||
members: value.map((el: any) => valueToMeta(sender, contextId, el, optimizeSimpleObject))
|
||||
};
|
||||
} else if (type === 'nativeimage') {
|
||||
return { type, value: serialize(value) };
|
||||
} else if (type === 'object' || type === 'function') {
|
||||
return {
|
||||
type,
|
||||
|
|
|
@ -5,7 +5,7 @@ const { hasSwitch } = process.electronBinding('command_line');
|
|||
const { NativeImage } = process.electronBinding('native_image');
|
||||
|
||||
const { CallbacksRegistry } = require('@electron/internal/renderer/remote/callbacks-registry');
|
||||
const { isPromise, isSerializableObject, serialize } = require('@electron/internal/common/type-utils');
|
||||
const { isPromise, isSerializableObject, serialize, deserialize } = require('@electron/internal/common/type-utils');
|
||||
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal');
|
||||
|
||||
const callbacksRegistry = new CallbacksRegistry();
|
||||
|
@ -219,6 +219,7 @@ function metaToValue (meta) {
|
|||
const types = {
|
||||
value: () => meta.value,
|
||||
array: () => meta.members.map((member) => metaToValue(member)),
|
||||
nativeimage: () => deserialize(meta.value),
|
||||
buffer: () => Buffer.from(meta.value.buffer, meta.value.byteOffset, meta.value.byteLength),
|
||||
promise: () => Promise.resolve({ then: metaToValue(meta.then) }),
|
||||
error: () => metaToError(meta),
|
||||
|
|
|
@ -366,11 +366,11 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
|||
const w = makeWindow();
|
||||
const remotely = makeRemotely(w);
|
||||
|
||||
it('can serialize an empty nativeImage', async () => {
|
||||
const getEmptyImage = (img: NativeImage) => img.isEmpty();
|
||||
it('can serialize an empty nativeImage from renderer to main', async () => {
|
||||
const getImageEmpty = (img: NativeImage) => img.isEmpty();
|
||||
|
||||
w().webContents.once('remote-get-global', (event) => {
|
||||
event.returnValue = getEmptyImage;
|
||||
event.returnValue = getImageEmpty;
|
||||
});
|
||||
|
||||
await expect(remotely(() => {
|
||||
|
@ -379,11 +379,23 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
|||
})).to.eventually.be.true();
|
||||
});
|
||||
|
||||
it('can serialize a non-empty nativeImage', async () => {
|
||||
const getNonEmptyImage = (img: NativeImage) => img.getSize();
|
||||
it('can serialize an empty nativeImage from main to renderer', async () => {
|
||||
w().webContents.once('remote-get-global', (event) => {
|
||||
const emptyImage = require('electron').nativeImage.createEmpty();
|
||||
event.returnValue = emptyImage;
|
||||
});
|
||||
|
||||
await expect(remotely(() => {
|
||||
const image = require('electron').remote.getGlobal('someFunction');
|
||||
return image.isEmpty();
|
||||
})).to.eventually.be.true();
|
||||
});
|
||||
|
||||
it('can serialize a non-empty nativeImage from renderer to main', async () => {
|
||||
const getImageSize = (img: NativeImage) => img.getSize();
|
||||
|
||||
w().webContents.once('remote-get-global', (event) => {
|
||||
event.returnValue = getNonEmptyImage;
|
||||
event.returnValue = getImageSize;
|
||||
});
|
||||
|
||||
await expect(remotely(() => {
|
||||
|
@ -393,6 +405,18 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
|
|||
})).to.eventually.deep.equal({ width: 2, height: 2 });
|
||||
});
|
||||
|
||||
it('can serialize a non-empty nativeImage from main to renderer', async () => {
|
||||
w().webContents.once('remote-get-global', (event) => {
|
||||
const nonEmptyImage = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAFklEQVQYlWP8//8/AwMDEwMDAwMDAwAkBgMBBMzldwAAAABJRU5ErkJggg==');
|
||||
event.returnValue = nonEmptyImage;
|
||||
});
|
||||
|
||||
await expect(remotely(() => {
|
||||
const image = require('electron').remote.getGlobal('someFunction');
|
||||
return image.getSize();
|
||||
})).to.eventually.deep.equal({ width: 2, height: 2 });
|
||||
});
|
||||
|
||||
it('can properly create a menu with an nativeImage icon in the renderer', async () => {
|
||||
await expect(remotely(() => {
|
||||
const { remote, nativeImage } = require('electron');
|
||||
|
|
Loading…
Reference in a new issue