From 5948dd0dfb61c49f1eb1644ebc358b96311c33ce Mon Sep 17 00:00:00 2001 From: Aleksei Kuzmin Date: Tue, 1 Dec 2020 06:07:59 +0300 Subject: [PATCH 1/2] fix: add a "set" trap to the "screen" module proxy --- lib/browser/api/screen.ts | 44 +++++++++++++++++++----------------- spec-main/api-screen-spec.ts | 12 ++++++++++ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/lib/browser/api/screen.ts b/lib/browser/api/screen.ts index d3e9aaee3d7b7..5899e8b547205 100644 --- a/lib/browser/api/screen.ts +++ b/lib/browser/api/screen.ts @@ -2,37 +2,39 @@ const { createScreen } = process._linkedBinding('electron_common_screen'); let _screen: Electron.Screen; +const createScreenIfNeeded = () => { + if (_screen === undefined) { + _screen = createScreen(); + } +}; + // We can't call createScreen until after app.on('ready'), but this module // exposes an instance created by createScreen. In order to avoid // side-effecting and calling createScreen upon import of this module, instead // we export a proxy which lazily calls createScreen on first access. export default new Proxy({}, { - get: (target, prop: keyof Electron.Screen) => { - if (_screen === undefined) { - _screen = createScreen(); + get: (target, property: keyof Electron.Screen) => { + createScreenIfNeeded(); + const value = _screen[property]; + if (typeof value === 'function') { + return value.bind(_screen); } - const v = _screen[prop]; - if (typeof v === 'function') { - return v.bind(_screen); - } - return v; + return value; + }, + set: (target, property: string, value: unknown) => { + createScreenIfNeeded(); + return Reflect.set(_screen, property, value); }, ownKeys: () => { - if (_screen === undefined) { - _screen = createScreen(); - } + createScreenIfNeeded(); return Reflect.ownKeys(_screen); }, - has: (target, prop: string) => { - if (_screen === undefined) { - _screen = createScreen(); - } - return prop in _screen; + has: (target, property: string) => { + createScreenIfNeeded(); + return property in _screen; }, - getOwnPropertyDescriptor: (target, prop: string) => { - if (_screen === undefined) { - _screen = createScreen(); - } - return Reflect.getOwnPropertyDescriptor(_screen, prop); + getOwnPropertyDescriptor: (target, property: string) => { + createScreenIfNeeded(); + return Reflect.getOwnPropertyDescriptor(_screen, property); } }); diff --git a/spec-main/api-screen-spec.ts b/spec-main/api-screen-spec.ts index 7eb4019403627..a638c513370b9 100644 --- a/spec-main/api-screen-spec.ts +++ b/spec-main/api-screen-spec.ts @@ -1,7 +1,19 @@ import { expect } from 'chai'; import { screen } from 'electron/main'; +import * as sinon from 'sinon'; describe('screen module', () => { + describe('methods reassignment', () => { + after(() => { + sinon.restore(); + }); + + it('works for a selected method', () => { + sinon.stub((screen as any), 'getPrimaryDisplay').returns(null); + expect(screen.getPrimaryDisplay()).to.be.null(); + }); + }); + describe('screen.getCursorScreenPoint()', () => { it('returns a point object', () => { const point = screen.getCursorScreenPoint(); From c692fd7850b59458903576b8db01908afab8b74d Mon Sep 17 00:00:00 2001 From: Aleksei Kuzmin Date: Sat, 5 Dec 2020 01:08:19 +0300 Subject: [PATCH 2/2] fixup! fix: add a "set" trap to the "screen" module proxy --- spec-main/api-screen-spec.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec-main/api-screen-spec.ts b/spec-main/api-screen-spec.ts index a638c513370b9..102e68155d28b 100644 --- a/spec-main/api-screen-spec.ts +++ b/spec-main/api-screen-spec.ts @@ -1,16 +1,16 @@ import { expect } from 'chai'; import { screen } from 'electron/main'; -import * as sinon from 'sinon'; describe('screen module', () => { describe('methods reassignment', () => { - after(() => { - sinon.restore(); - }); - it('works for a selected method', () => { - sinon.stub((screen as any), 'getPrimaryDisplay').returns(null); - expect(screen.getPrimaryDisplay()).to.be.null(); + const originalFunction = screen.getPrimaryDisplay; + try { + (screen as any).getPrimaryDisplay = () => null; + expect(screen.getPrimaryDisplay()).to.be.null(); + } finally { + screen.getPrimaryDisplay = originalFunction; + } }); });