Skip to content

Commit

Permalink
Fix sidebarInThisTab and form rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
twschiller committed Jan 4, 2024
1 parent 7b68090 commit 6ff08d0
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 16 deletions.
12 changes: 11 additions & 1 deletion src/bricks/transformers/ephemeralForm/formTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { getThisFrame } from "webext-messenger";
import { type BrickConfig } from "@/bricks/types";
import { type FormDefinition } from "@/bricks/transformers/ephemeralForm/formTypes";
import { isExpression } from "@/utils/expressionUtils";
import { isMV3 } from "@/mv3/api";

// The modes for createFrameSrc are different than the location argument for FormTransformer. The mode for the frame
// just determines the layout container of the form
Expand All @@ -44,7 +45,16 @@ export async function createFrameSource(
nonce: string,
mode: Mode,
): Promise<URL> {
const target = await getThisFrame();
let target;

if (mode === "panel" && isMV3()) {
// In MV3, the sidebar is not "in" the page. But the data source is the top-level content script for the tab
const tabId = new URLSearchParams(location.search).get("tabId");
target = { tabId: Number(tabId), frameId: 0 };
} else {
// `getThisFrame` doesn't work the Chrome Side Panel it's not a normal frame
target = await getThisFrame();
}

const frameSource = new URL(browser.runtime.getURL("ephemeralForm.html"));
frameSource.searchParams.set("nonce", nonce);
Expand Down
6 changes: 5 additions & 1 deletion src/contentScript/sidebarDomControllerLiteMv3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ if (!isMV3()) {
);
}

// TODO: drop constant. Is referenced by notify.tsx to calculate offset
// TODO: drop/refactor constant. Is referenced by notify.tsx to calculate offset
export const SIDEBAR_WIDTH_CSS_PROPERTY = "--pb-sidebar-width";

/**
* The Chrome Side Panel API doesn't have a method yet for checking if the sidebar is open, so track it ourselves.
* @see init
*/
let sidePanelOpen = false;

/**
Expand Down
63 changes: 51 additions & 12 deletions src/sidebar/messenger/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,60 @@
*/

/* Do not use `registerMethod` in this file */
import { getMethod, getNotifier } from "webext-messenger";
import {
getMethod,
getNotifier,
getThisFrame,
type PageTarget,
} from "webext-messenger";
import { isMV3 } from "@/mv3/api";
import type { Target } from "@/types/messengerTypes";

const target = { tabId: "this", page: "/sidebar.html" } as const;
function bindToMethodTarget<T extends keyof MessengerMethods>(type: T) {
return async (
...args: Parameters<MessengerMethods[T]>
): Promise<ReturnType<MessengerMethods[T]>> => {
const { tabId } = await getThisFrame();

const target: Target | PageTarget = isMV3()
? { page: `/sidebar.html?tabId=${tabId}` }
: { tabId: "this", page: "/sidebar.html" };

console.debug("bindToMethodTarget", { type, target, args });

const method = getMethod(type, target);
// @ts-expect-error -- :shrug: figure out types later
return method(...args);
};
}

function bindToNotifierTarget<T extends keyof MessengerMethods>(type: T) {
return async (...args: Parameters<MessengerMethods[T]>): Promise<void> => {
const { tabId } = await getThisFrame();

const target: Target | PageTarget = isMV3()
? { page: `/sidebar.html?tabId=${tabId}` }
: { tabId: "this", page: "/sidebar.html" };

console.debug("bindToNotifierTarget", { type, target, args });

const method = getNotifier(type);
// @ts-expect-error -- :shrug: figure out types later
method(target, ...args);
};
}

const sidebarInThisTab = {
renderPanels: getMethod("SIDEBAR_RENDER_PANELS", target),
activatePanel: getMethod("SIDEBAR_ACTIVATE_PANEL", target),
showForm: getMethod("SIDEBAR_SHOW_FORM", target),
hideForm: getMethod("SIDEBAR_HIDE_FORM", target),
pingSidebar: getMethod("SIDEBAR_PING", target),
showTemporaryPanel: getMethod("SIDEBAR_SHOW_TEMPORARY_PANEL", target),
updateTemporaryPanel: getNotifier("SIDEBAR_UPDATE_TEMPORARY_PANEL", target),
hideTemporaryPanel: getMethod("SIDEBAR_HIDE_TEMPORARY_PANEL", target),
showModActivationPanel: getMethod("SIDEBAR_SHOW_ACTIVATE_RECIPE", target),
hideModActivationPanel: getMethod("SIDEBAR_HIDE_ACTIVATE_RECIPE", target),
renderPanels: bindToMethodTarget("SIDEBAR_RENDER_PANELS"),
activatePanel: bindToMethodTarget("SIDEBAR_ACTIVATE_PANEL"),
showForm: bindToMethodTarget("SIDEBAR_SHOW_FORM"),
hideForm: bindToMethodTarget("SIDEBAR_HIDE_FORM"),
pingSidebar: bindToMethodTarget("SIDEBAR_PING"),
showTemporaryPanel: bindToMethodTarget("SIDEBAR_SHOW_TEMPORARY_PANEL"),
updateTemporaryPanel: bindToNotifierTarget("SIDEBAR_UPDATE_TEMPORARY_PANEL"),
hideTemporaryPanel: bindToMethodTarget("SIDEBAR_HIDE_TEMPORARY_PANEL"),
showModActivationPanel: bindToMethodTarget("SIDEBAR_SHOW_ACTIVATE_RECIPE"),
hideModActivationPanel: bindToMethodTarget("SIDEBAR_HIDE_ACTIVATE_RECIPE"),
};

export default sidebarInThisTab;
9 changes: 7 additions & 2 deletions src/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ if (isMV3()) {
// Background and content scripts communicate on different ports
// https://developer.chrome.com/docs/extensions/develop/concepts/messaging
let backgroundPort = chrome.runtime.connect({ name: SIDEPANEL_PORT_NAME });
const tabPort = chrome.tabs.connect(tabId, { name: SIDEPANEL_PORT_NAME });
let tabPort = chrome.tabs.connect(tabId, { name: SIDEPANEL_PORT_NAME });

const sendStatusMessage = (port: chrome.runtime.Port) => {
port.postMessage({
Expand All @@ -83,12 +83,17 @@ if (isMV3()) {
backgroundPort = chrome.runtime.connect({ name: SIDEPANEL_PORT_NAME });
});

tabPort.onDisconnect.addListener(() => {
// Reconnect if the tab does a full navigation (i.e., the content script is reloaded)
tabPort = chrome.tabs.connect(tabId, { name: SIDEPANEL_PORT_NAME });
});

document.addEventListener("visibilitychange", () => {
sendStatusMessage(backgroundPort);
sendStatusMessage(tabPort);
});

// Keep the background worker open. Is keep alive necessary given the reconnection logic above?
// XXX: Keep the background worker alive. Is keep alive necessary given the reconnection logic above?
setInterval(
() => {
sendStatusMessage(backgroundPort);
Expand Down

0 comments on commit 6ff08d0

Please sign in to comment.