From 00ea3320b5d42beda9cc6fb6cf3d4e34e53ec004 Mon Sep 17 00:00:00 2001 From: Todd Schiller Date: Thu, 11 Apr 2024 16:06:19 -0400 Subject: [PATCH] #8227: error if showing temporary panel from frame --- .../DisplayTemporaryInfo.test.ts | 33 +++++++++++++++++++ src/contentScript/ephemeralPanel.ts | 8 +++++ 2 files changed, 41 insertions(+) diff --git a/src/bricks/transformers/temporaryInfo/DisplayTemporaryInfo.test.ts b/src/bricks/transformers/temporaryInfo/DisplayTemporaryInfo.test.ts index 482266c1fa..8239c90393 100644 --- a/src/bricks/transformers/temporaryInfo/DisplayTemporaryInfo.test.ts +++ b/src/bricks/transformers/temporaryInfo/DisplayTemporaryInfo.test.ts @@ -55,16 +55,21 @@ import { contextAsPlainObject } from "@/runtime/extendModVariableContext"; import { unary } from "lodash"; import { toExpression } from "@/utils/expressionUtils"; import { showModal } from "@/contentScript/modalDom"; +import { isLoadedInIframe } from "@/utils/iframeUtils"; jest.mock("@/contentScript/modalDom"); jest.mock("@/contentScript/sidebarController"); jest.mock("@/platform/panels/panelController"); +jest.mock("@/utils/iframeUtils"); + const displayTemporaryInfoBlock = new DisplayTemporaryInfo(); const renderer = new DocumentRenderer(); describe("DisplayTemporaryInfo", () => { beforeEach(() => { + jest.mocked(isLoadedInIframe).mockReturnValue(false); + blockRegistry.clear(); blockRegistry.register([ echoBrick, @@ -197,6 +202,34 @@ describe("DisplayTemporaryInfo", () => { }); }); + test("it errors from frame", async () => { + jest.mocked(isLoadedInIframe).mockReturnValue(true); + + const config = getExampleBrickConfig(renderer.id); + const pipeline = { + id: displayTemporaryInfoBlock.id, + config: { + title: "Test Temp Panel", + body: toExpression("pipeline", [{ id: renderer.id, config }]), + location: "panel", + isRootAware: true, + }, + }; + + const extensionId = uuidv4(); + + const options = { + ...testOptions("v3"), + logger: new ConsoleLogger({ + extensionId, + }), + }; + + await expect( + reducePipeline(pipeline, simpleInput({}), options), + ).rejects.toThrow("Cannot show sidebar in a frame"); + }); + test("requires target for popover", async () => { const config = getExampleBrickConfig(renderer.id); const pipeline = { diff --git a/src/contentScript/ephemeralPanel.ts b/src/contentScript/ephemeralPanel.ts index 572d044c23..e3825e9af1 100644 --- a/src/contentScript/ephemeralPanel.ts +++ b/src/contentScript/ephemeralPanel.ts @@ -43,6 +43,7 @@ import type { Location } from "@/types/starterBrickTypes"; import { getThisFrame } from "webext-messenger"; import { expectContext } from "@/utils/expectContext"; import { showModal } from "@/contentScript/modalDom"; +import { isLoadedInIframe } from "@/utils/iframeUtils"; export async function createFrameSource( nonce: string, @@ -82,6 +83,13 @@ export async function ephemeralPanel({ }: TemporaryPanelDefinition): Promise { expectContext("contentScript"); + if (location === "panel" && isLoadedInIframe()) { + // Validate before registerEmptyTemporaryPanel to avoid an uncaught promise rejection + throw new BusinessError( + "Cannot show sidebar in a frame. To use the sidebar, set the target to Top-level Frame", + ); + } + const nonce = uuidv4(); let onReady: (() => void) | undefined;