From 23714831bd568ded98957b9173d367511cfca59c Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Fri, 16 Oct 2020 16:01:41 -0500 Subject: [PATCH] Fix getDataExplorerWindow (#285) --- src/Utils/WindowUtils.test.ts | 58 +++++++++++++++-------------------- src/Utils/WindowUtils.ts | 27 +++++++--------- 2 files changed, 35 insertions(+), 50 deletions(-) diff --git a/src/Utils/WindowUtils.test.ts b/src/Utils/WindowUtils.test.ts index ea78a82b0..567219e22 100644 --- a/src/Utils/WindowUtils.test.ts +++ b/src/Utils/WindowUtils.test.ts @@ -1,49 +1,39 @@ import { getDataExplorerWindow } from "./WindowUtils"; -const createWindow = (dataExplorerPlatform: unknown, parent: Window): Window => { - // TODO: Need to `any` here since we're creating a mock window object - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const mockWindow: any = {}; - if (dataExplorerPlatform !== undefined) { - mockWindow.dataExplorerPlatform = dataExplorerPlatform; - } - if (parent) { - mockWindow.parent = parent; - } - return mockWindow; -}; +interface MockWindow { + parent?: MockWindow; + top?: MockWindow; +} describe("WindowUtils", () => { describe("getDataExplorerWindow", () => { - it("should return current window if current window has dataExplorerPlatform property", () => { - const currentWindow = createWindow(0, undefined); + it("should return undefined if current window is at the top", () => { + const mockWindow: MockWindow = {}; + mockWindow.parent = mockWindow; - expect(getDataExplorerWindow(currentWindow)).toEqual(currentWindow); + expect(getDataExplorerWindow(mockWindow as Window)).toEqual(undefined); }); - it("should return current window's parent if current window's parent has dataExplorerPlatform property", () => { - const parentWindow = createWindow(0, undefined); - const currentWindow = createWindow(undefined, parentWindow); + it("should return current window if parent is top", () => { + const dataExplorerWindow: MockWindow = {}; + const portalWindow: MockWindow = {}; + dataExplorerWindow.parent = portalWindow; + dataExplorerWindow.top = portalWindow; - expect(getDataExplorerWindow(currentWindow)).toEqual(parentWindow); + expect(getDataExplorerWindow(dataExplorerWindow as Window)).toEqual(dataExplorerWindow); }); - it("should return undefined if none of the windows in the hierarchy have dataExplorerPlatform property and window's parent is reference to itself", () => { - const parentWindow = createWindow(undefined, undefined); + it("should return closest window to top if in nested windows", () => { + const terminalWindow: MockWindow = {}; + const dataExplorerWindow: MockWindow = {}; + const portalWindow: MockWindow = {}; + dataExplorerWindow.top = portalWindow; + dataExplorerWindow.parent = portalWindow; + terminalWindow.top = portalWindow; + terminalWindow.parent = dataExplorerWindow; - // TODO: Need to `any` here since parent is a readonly property - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (parentWindow as any).parent = parentWindow; // If a window does not have a parent, its parent property is a reference to itself. - const currentWindow = createWindow(undefined, parentWindow); - - expect(getDataExplorerWindow(currentWindow)).toBeUndefined(); - }); - - it("should return undefined if none of the windows in the hierarchy have dataExplorerPlatform property and window's parent is not defined", () => { - const parentWindow = createWindow(undefined, undefined); - const currentWindow = createWindow(undefined, parentWindow); - - expect(getDataExplorerWindow(currentWindow)).toBeUndefined(); + expect(getDataExplorerWindow(terminalWindow as Window)).toEqual(dataExplorerWindow); + expect(getDataExplorerWindow(dataExplorerWindow as Window)).toEqual(dataExplorerWindow); }); }); }); diff --git a/src/Utils/WindowUtils.ts b/src/Utils/WindowUtils.ts index 909cc9a3f..e24fd8290 100644 --- a/src/Utils/WindowUtils.ts +++ b/src/Utils/WindowUtils.ts @@ -1,23 +1,18 @@ export const getDataExplorerWindow = (currentWindow: Window): Window | undefined => { - // Start with the current window and traverse up the parent hierarchy to find a window - // with `dataExplorerPlatform` property - let dataExplorerWindow: Window | undefined = currentWindow; - + // Data explorer is always loaded in an iframe, so traverse the parents until we hit the top and return the first child window. try { - // TODO: Need to `any` here since the window imports Explorer which can't be in strict mode yet - // eslint-disable-next-line @typescript-eslint/no-explicit-any - while (dataExplorerWindow && (dataExplorerWindow as any).dataExplorerPlatform === undefined) { - // If a window does not have a parent, its parent property is a reference to itself. - if (dataExplorerWindow.parent === dataExplorerWindow) { - dataExplorerWindow = undefined; - } else { - dataExplorerWindow = dataExplorerWindow.parent; + while (currentWindow) { + if (currentWindow.parent === currentWindow) { + return undefined; } + if (currentWindow.parent === currentWindow.top) { + return currentWindow; + } + currentWindow = currentWindow.parent; } } catch (error) { - // This can happen if we come across parent from a different origin - dataExplorerWindow = undefined; + // Hitting a cross domain error means we are in the portal and the current window is data explorer + return currentWindow; } - - return dataExplorerWindow; + return undefined; };