From 29abca107ba6500fb8bd9f566fcfb93ebdb4cd16 Mon Sep 17 00:00:00 2001 From: bingenito Date: Wed, 12 Sep 2018 11:20:07 -0400 Subject: [PATCH] Add facade for consistent access to underlying native JavaScript window --- src/Default/default.ts | 4 ++++ src/Electron/electron.ts | 5 +++++ src/OpenFin/openfin.ts | 4 ++++ src/window.ts | 7 +++++++ tests/unit/Default/default.spec.ts | 7 +++++++ tests/unit/Electron/electron.spec.ts | 6 ++++++ tests/unit/OpenFin/openfin.spec.ts | 11 ++++++++++- tests/unit/window.spec.ts | 6 ++++++ 8 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/Default/default.ts b/src/Default/default.ts index d6d726db..5339becf 100644 --- a/src/Default/default.ts +++ b/src/Default/default.ts @@ -107,6 +107,10 @@ export class DefaultContainerWindow extends ContainerWindow { protected detachListener(eventName: string, listener: (...args: any[]) => void): void { this.innerWindow.removeEventListener(windowEventMap[eventName] || eventName, listener); } + + public get nativeWindow(): Window { + return this.innerWindow; + } } /** diff --git a/src/Electron/electron.ts b/src/Electron/electron.ts index 2a181c16..90d9dd58 100644 --- a/src/Electron/electron.ts +++ b/src/Electron/electron.ts @@ -193,6 +193,11 @@ export class ElectronContainerWindow extends ContainerWindow { protected detachListener(eventName: string, listener: (...args: any[]) => void): void { this.innerWindow.removeListener(windowEventMap[eventName] || eventName, listener); } + + public get nativeWindow(): Window { + // For Electron we can only return in and for current renderer + return this.window || window; + } } /** diff --git a/src/OpenFin/openfin.ts b/src/OpenFin/openfin.ts index d7b8f39d..87d9cb3a 100644 --- a/src/OpenFin/openfin.ts +++ b/src/OpenFin/openfin.ts @@ -193,6 +193,10 @@ export class OpenFinContainerWindow extends ContainerWindow { protected detachListener(eventName: string, listener: (...args: any[]) => void): any { this.innerWindow.removeEventListener(windowEventMap[eventName] || eventName, listener); } + + public get nativeWindow(): Window { + return this.innerWindow.getNativeWindow(); + } } /** diff --git a/src/window.ts b/src/window.ts index a2f99e85..af2c0d62 100644 --- a/src/window.ts +++ b/src/window.ts @@ -141,6 +141,13 @@ export abstract class ContainerWindow extends EventEmitter { public abstract getOptions(): Promise; + /** Gets the underlying native JavaScript window object. As some containers + * do not support native access, check for undefined. + */ + public get nativeWindow(): Window { + return undefined; + } + /** * Override to provide custom container logic for adding an event handler. */ diff --git a/tests/unit/Default/default.spec.ts b/tests/unit/Default/default.spec.ts index 15e662fb..9d4cfa73 100644 --- a/tests/unit/Default/default.spec.ts +++ b/tests/unit/Default/default.spec.ts @@ -190,6 +190,13 @@ describe("DefaultContainerWindow", () => { }); }); }); + + it("nativeWindow returns wrapped window", () => { + const innerWindow = {}; + const nativeWindow = new DefaultContainerWindow(innerWindow).nativeWindow; + expect(nativeWindow).toBeDefined(); + expect(nativeWindow).toEqual(innerWindow); + }); }); describe("DefaultContainer", () => { diff --git a/tests/unit/Electron/electron.spec.ts b/tests/unit/Electron/electron.spec.ts index 8e95ad2f..2ecf9dac 100644 --- a/tests/unit/Electron/electron.spec.ts +++ b/tests/unit/Electron/electron.spec.ts @@ -268,6 +268,12 @@ describe("ElectronContainerWindow", () => { win.removeListener("move", () => {}); expect(win.innerWindow.removeListener).toHaveBeenCalledWith("move", jasmine.any(Function)); }); + + it("nativeWindow returns window", () => { + var window = {}; + const win = new ElectronContainerWindow(innerWin, container, window); + expect(win.nativeWindow).toEqual(window); + }); }); describe("window grouping", () => { diff --git a/tests/unit/OpenFin/openfin.spec.ts b/tests/unit/OpenFin/openfin.spec.ts index 5cbc2019..03523a54 100644 --- a/tests/unit/OpenFin/openfin.spec.ts +++ b/tests/unit/OpenFin/openfin.spec.ts @@ -57,6 +57,7 @@ class MockInterApplicationBus { class MockWindow { static singleton: MockWindow = new MockWindow("Singleton"); + public nativeWindow: Window = jasmine.createSpyObj("window", ["location"]); constructor(name?: string) { this.name = name; @@ -68,7 +69,7 @@ class MockWindow { getParentWindow(): any { return MockWindow.singleton; } - getNativeWindow(): any { return jasmine.createSpyObj("window", ["location"]); } + getNativeWindow(): any { return this.nativeWindow; } focus(callback: () => void, error: (reason) => void): any { callback(); @@ -175,6 +176,14 @@ describe("OpenFinContainerWindow", () => { expect(win.name).toEqual("NAME"); }); + it ("nativeWindow invokes underlying getNativeWindow", () => { + spyOn(innerWin, "getNativeWindow").and.callThrough(); + const nativeWin = win.nativeWindow; + expect(innerWin.getNativeWindow).toHaveBeenCalled(); + expect(nativeWin).toBeDefined(); + expect(nativeWin).toEqual(innerWin.nativeWindow); + }); + it("focus", (done) => { spyOn(innerWin, "focus").and.callThrough(); win.focus().then(() => { diff --git a/tests/unit/window.spec.ts b/tests/unit/window.spec.ts index f98085b0..aea6a0f5 100644 --- a/tests/unit/window.spec.ts +++ b/tests/unit/window.spec.ts @@ -12,6 +12,12 @@ class MockWindow extends ContainerWindow { public restore(): Promise { return Promise.resolve(); } } +describe ("ContainerWindow", () => { + it("nativeWindow returns undefined", () => { + expect(new MockWindow(undefined).nativeWindow).toBeUndefined(); + }); +}); + describe ("static events", () => { let container: TestContainer;