Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sidePanel API: lifecycle events #517

Open
fregante opened this issue Jan 7, 2024 · 10 comments
Open

sidePanel API: lifecycle events #517

fregante opened this issue Jan 7, 2024 · 10 comments
Labels
enhancement Enhancement or change to an existing feature needs-triage: chrome Chrome needs to assess this issue for the first time needs-triage: firefox Firefox needs to assess this issue for the first time supportive: safari Supportive from Safari

Comments

@fregante
Copy link

fregante commented Jan 7, 2024

Our extension uses sidebar to display extra content about the current website, the content script communicates to the sidebar, acting as a controller.

It would be useful to have more control over it, specifically, to only do operations when the sidebar is open or know when it's opened/closed.

Proposal: lifecycle events

Some example useful events could be:

  • sidePanel.onLoad (the document/context is loaded)
    • somewhat possible via manual .sendMessage to all the relevant contexts
  • sidePanel.onUnload (the document/context is unloaded/closed)
    • impossible via chrome.runtime.connect's onDisconnect event if there are multiple sidebars open, because the connection is preserved across instances: https://stackoverflow.com/a/36465331
    • impossible via onbeforeunload because .sendMessage doesn't complete

Some other more specific events could be:

  • sidePanel.onShow (like visibilitychange, the current extension's sidePanel is shown)
  • sidePanel.onHide (the user selects another extension's sidepanel)

These two are less important, I suppose a local visibilitychange + runtime.sendMessage could work as well.

@yankovichv
Copy link

+1 🙏.

Here are my similar requests - https://groups.google.com/a/chromium.org/g/chromium-extensions/c/cJmdMLmpbjg

@yankovichv
Copy link

Why can't you use the existing DOM visibilitychange event in the side panel to inform the connected content script?

Any tricks of trying to track the visibility of our extension in the side panel via document.hidden or via clients.matchAll() didn't work. When the user switches between OS applications or minimizes the browser, we get a message that the document is invisible, which makes sense. So we need a native sidepanel API method to report show/hide and window Id accurately.

@yankovichv
Copy link

Yep, this, this is not so critical.

Although I would like to have such a common event for all contexts that may occur in chrome.runtime.getContext - https://developer.chrome.com/docs/extensions/reference/api/runtime#method-getContexts

For now, it’s easier to use a poll every 5 seconds.

@fregante
Copy link
Author

fregante commented Jan 8, 2024

Polling is not an alternative. By that suggestion, you don't need almost any events, you can just poll it.

Events are useful specifically because they let you avoid polling. That's the whole point of events: you want to respond to changes immediately without continuously waking up the background worker.

@isnolan
Copy link

isnolan commented Oct 30, 2024

The life cycle events of SidePanel are so important that I searched a lot of information to find it here. I look forward to its early release.

@xeenon xeenon added supportive: safari Supportive from Safari needs-triage: chrome Chrome needs to assess this issue for the first time needs-triage: firefox Firefox needs to assess this issue for the first time labels Jan 30, 2025
@Rob--W
Copy link
Member

Rob--W commented Jan 30, 2025

FYI #752 was discussed today and marked as a duplicate of this issue because this is a more general version of the request for a sidePanel.onClosed event.

The meeting notes are pending review at #753 and once merged will be available at https://github.com/w3c/webextensions/blob/main/_minutes/2025-01-30-wecg.md

Next step is for @twschiller and @mukul-p to come up with a concrete proposal to cover the relevant lifecycle events.

@twschiller
Copy link

twschiller commented Feb 2, 2025

Here's some initial thinking for the events. I have some questions on side panel lifecycle when the browser/another extension opens its side panel. I'll follow up with my team and @mukul-p to map out additional considerations

Open Questions

  • Conceptually, what happens when a user/an extension opens another side panel? Chrome used to have a panel picker dropdown. At first glance, in the current Chrome behavior, when opening another panel (e.g., Reading Mode) the extension's side panel seems be closed vs. deactivated/hidden
  • Does windowId need to be exposed? Probably yes, because we'd likely only want a single event to fire for a global/window side panel
  • Do we need PanelCloseInfo, e.g., to distinguish the user closing the panel via "x" vs. the extension programmatically closing its own panel? It doesn't seem strictly necessary because the extension could track if there any outstanding programmatic close requests at the time of the close event

Permissions

  • Like the other sidePanel APIs, would require the sidePanel permission in the manifest
  • During last meeting, I had raised potentially requiring tabs in order to make the path/URL a visible property.
    • The consideration would be if it opens a side-channel to determine which page the user is visiting in the tab
    • At first glance, it doesn't seem there is one because the current sidePanel API doesn't provide any automatic affordances for site-specific panel paths/match patterns. A proposal such as sidePanel API: site-specific panels #618 would introduce panels as a side-channel of page URL information. (But then again, there's nothing to prevent the panel's JS for recording that it was loaded, so the background seeing it via an event doesn't seem to provide any additional information)

Excluded Events

Typescript Definitions

declare namespace browser.sidePanel {
  interface PanelOpenInfo {
    position: "right" | "left";
    path: string;
  }

  interface PanelChangeInfo {
    /** The panel's new active state, e.g., if a native (e.g., Reading Mode) was opened. Or is the panel closed when a new side panel is opened? **/
    active?: boolean;
    /** The panel's new position. Occurs if the user updates their Appearances settings **/
    position?: "right" | "left";
    /** The panel's new path. Is this necessary given that only the extension can update the path? **/
    path?: string; 
  }

  interface Event<T extends (...args: any[]) => any> {
    addListener(callback: T, ...params: unknown[]): void;
    removeListener(callback: T): void;
    hasListener(callback: T): boolean;
  }

  // Match terminology of the `browser.sidePanel.open` method
  export const onOpened: Event<[tabId: number, panelInfo: PanelOpenInfo]>;
  // Closed might be a misleading name if this event is used instead of PanelChangeInfo.active for when the panel is replaced
  export const onClosed: Event<[tabId: number]>;
  // TODO: depending on side panel lifecycle, determine if onReplaced is more appropriate than PanelChangeInfo.active or onClosed to represent another panel being opened
  export const onReplaced: Event<[tabId: number]>;
  // Would only be fired if the panel is open. E.g., will not fire if the panel position is configured when no panels are open
  export const onUpdated: Event<[tabId: number, changeInfo: PanelChangeInfo]>;
}

@fregante
Copy link
Author

fregante commented Feb 3, 2025

I think that:

  • if the sidePanel document is unloaded on replace, it should just fire the onClosed event, because as far as the extension is concerned the sidePanel document has been closed
  • if the sidePanel is hidden, onUpdated with active:false sounds reasonable

Does windowId need to be exposed?

IIRC there's always one sidePanel per window, and Chrome might also have one sidePanel per tab, so both should likely be exposed.

@twschiller
Copy link

twschiller commented Feb 6, 2025

@mukul-p @oliverdunk is there documentation on the conceptual/specification for how browsers handle another extension or the browser replacing an extension's side panel? Does it close or just become inactive?

@oliverdunk
Copy link
Member

@mukul-p @oliverdunk is there documentation on the conceptual/specification for how browsers handle another extension or the browser replacing an extensions panel? Does it close or just become inactive?

I'm not aware of anything right now I'm afraid. It does seem like something we should try to document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement or change to an existing feature needs-triage: chrome Chrome needs to assess this issue for the first time needs-triage: firefox Firefox needs to assess this issue for the first time supportive: safari Supportive from Safari
Projects
None yet
Development

No branches or pull requests

7 participants