From e1775b55203a0534db41f4d478c8c0cf44442381 Mon Sep 17 00:00:00 2001 From: Todd Schiller Date: Thu, 11 Apr 2024 11:53:20 -0400 Subject: [PATCH] #8219: don't let frames control sidebar --- src/contentScript/contentScriptCore.ts | 8 ++++++-- src/contentScript/sidebarController.tsx | 10 ++++++++++ src/{ => store}/sidebar/sidebarSlice.test.ts | 0 src/utils/iframeUtils.ts | 5 ++++- 4 files changed, 20 insertions(+), 3 deletions(-) rename src/{ => store}/sidebar/sidebarSlice.test.ts (100%) diff --git a/src/contentScript/contentScriptCore.ts b/src/contentScript/contentScriptCore.ts index 58a0c85baa..0fb91c2f88 100644 --- a/src/contentScript/contentScriptCore.ts +++ b/src/contentScript/contentScriptCore.ts @@ -55,6 +55,7 @@ import { markDocumentAsFocusableByUser } from "@/utils/focusTracker"; import contentScriptPlatform from "@/contentScript/contentScriptPlatform"; import axios from "axios"; import { initDeferredLoginController } from "@/contentScript/integrations/deferredLoginController"; +import { isLoadedInIframe } from "@/utils/iframeUtils"; setPlatform(contentScriptPlatform); @@ -101,8 +102,11 @@ export async function init(): Promise { initSidebarFocusEvents(); void initSidebarActivation(); - // Update `sidePanel` - void renderPanelsIfVisible(); + if (!isLoadedInIframe()) { + // FIXME: do we want to do this? It will cause the panels to be reset on non-SPA navigation/reload + // Update `sidePanel` + void renderPanelsIfVisible(); + } // Let the partner page know initPartnerIntegrations(); diff --git a/src/contentScript/sidebarController.tsx b/src/contentScript/sidebarController.tsx index fd654c611f..6df2d9be32 100644 --- a/src/contentScript/sidebarController.tsx +++ b/src/contentScript/sidebarController.tsx @@ -210,6 +210,11 @@ export async function updateSidebar( export async function renderPanelsIfVisible(): Promise { expectContext("contentScript"); + if (isLoadedInIframe()) { + console.warn("renderPanelsIfVisible should not be called from a frame"); + return; + } + if (await isSidePanelOpen()) { void sidebarInThisTab.renderPanels(getTimedSequence(), panels); } else { @@ -298,6 +303,11 @@ export function removeExtensions(extensionIds: UUID[]): void { console.debug("sidebarController:removeExtensions", { extensionIds }); + // Avoid unnecessary messaging. Also, prevent issues if this method is called as cleanup from a frame + if (extensionIds.length === 0) { + return; + } + // `panels` is const, so replace the contents const current = panels.splice(0); panels.push(...current.filter((x) => !extensionIds.includes(x.extensionId))); diff --git a/src/sidebar/sidebarSlice.test.ts b/src/store/sidebar/sidebarSlice.test.ts similarity index 100% rename from src/sidebar/sidebarSlice.test.ts rename to src/store/sidebar/sidebarSlice.test.ts diff --git a/src/utils/iframeUtils.ts b/src/utils/iframeUtils.ts index 609a059286..f0c6300e24 100644 --- a/src/utils/iframeUtils.ts +++ b/src/utils/iframeUtils.ts @@ -19,9 +19,12 @@ * Returns true if this function is called within an IFrame */ -export const isLoadedInIframe = () => { +export const isLoadedInIframe = (): boolean => { // Using a try/catch block because in some cases trying to // access window.top from an iframe can result in a SecurityError + + // If updating this method to use the messenger/frameId, remember that frameId === 0 only for the active top-level + // frame: see https://developer.chrome.com/blog/extension-instantnav try { return window.self !== window.top; } catch {