Skip to content

Conversation

@hharshas
Copy link
Contributor

This proposal introduces a sidePanel.close() method (among work items for Summer of Code).
While not fully fleshed out, it outlines the core idea. Initial feedback is welcome. I would also like your thoughts on the need for a user gesture for this. #521 #chromium

Copy link
Member

@dotproto dotproto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All changes requested in this review are either internal styling consistency or GFM rendering fixes.

@dotproto
Copy link
Member

dotproto commented May 29, 2025

I would also like your thoughts on the need for a user gesture for this.

Developers can currently close the document in the sidebar or sidepanel ("sidebar" for simplicity) by calling window.close() inside the sidebar document in Firefox and Chrome. This flow does not require user activation. Introducing a user activation requirement in a new sidebar.close() method would create an unexpected point of friction compared to the current solution.

There are times when it might make sense to diverge or to change existing behavior to also require a user activation, but I don't think this is such a case. As I see it, there's minimal risk to allowing an extension to close it's own sidebar, especially since both supporting browsers currently require user activation to open a sidebar. The main risk I see is that an extension might try to close a side panel right before a user clicks in order to cause the user to click something they didn't intend to in the main document, but I'm not sure how practical that kind of attack would be.

At the moment I'm comfortable with not requiring user activation, but I'll defer to @Rob--W for a more official position.

Copy link
Member

@oliverdunk oliverdunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left one comment, but otherwise this seems like a good proposal.

@kiaraarose kiaraarose self-requested a review June 5, 2025 17:51
@hharshas
Copy link
Contributor Author

hharshas commented Jun 5, 2025

@carlosjeurissen While preparing the proposal, I was not in favor of throwing an error when the side panel is already closed for the given context. To keep things simple, an error should only be thrown if the context is invalid. Otherwise, it should simply do nothing and resolve, indicating that the panel is already closed for that context. If the side panel is opened globally for a window and we try to close it for just one tab, it will close for all tabs in that window.

@carlosjeurissen carlosjeurissen self-requested a review June 6, 2025 07:10
Copy link
Member

@oliverdunk oliverdunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure to align on the behavior when both windowId and tabId are specified. Otherwise, LGTM.

@carlosjeurissen
Copy link
Contributor

  1. as mentioned in Proposal: API to Query Side Panel Layout #838 (comment), it would make a ton of sense to align on a unified sidebar API as proposed in Proposal: agree on a unified sidebar API for mv3 #128

  2. We should clarify the difference between hiding vs closing the sidebar and the implications.

  3. As was discussed briefly in the last call, the behaviour if both windowId and tabId and if a global side panel is visible on the given tabId. Why should it close the sidePanel for all tabs instead of simply throwing an exception? The intention of the developer is to close it for a specific tab. Closing the global sidePanel can be an unrequested side-effect. If an exception is thrown, a developer can always call close without a tabId to get this kind of behaviour. Yet it seems this should be optional, not enforced.

@hharshas
Copy link
Contributor Author

hharshas commented Jul 3, 2025

  1. We should clarify the difference between hiding vs closing the sidebar and the implications.

Currently, the focus is on using "close" when the intention is to remove the side panel from the tab registry entirely. The concept of "hide"—making the side panel inactive but not removing it—could be considered for future enhancements.

  1. As was discussed briefly in the last call, the behaviour if both windowId and tabId and if a global side panel is visible on the given tabId. Why should it close the sidePanel for all tabs instead of simply throwing an exception? The intention of the developer is to close it for a specific tab. Closing the global sidePanel can be an unrequested side-effect. If an exception is thrown, a developer can always call close without a tabId to get this kind of behaviour. Yet it seems this should be optional, not enforced.

What I thought was -

  1. If a developer wants to close the side panel for a specific tab, they should provide the tabId. This action should only affect the tab-specific side panel on that particular tab.
  2. If a developer wants to remove all side panels from a specific tab—regardless of whether they are global or tab-specific—they should provide both windowId and tabId.
    @oliverdunk WDYT?

@oliverdunk
Copy link
Member

2. If a developer wants to remove all side panels from a specific tab—regardless of whether they are global or tab-specific—they should provide both windowId and tabId.

If tabId is specified, I don't think we should change behavior (other than basic validation that they match) depending on whether windowId is present. That would conflict with other APIs like sidePanel.open() where windowId is currently ignored if tabId is set.

If there is a global panel open, and you call close() with a tabId, to me it feels like the best option is to match the behavior of the user clicking the close icon in the UI. With that in mind, we would close the global panel everywhere. I feel less strongly on this though and think we could do whatever there is most alignment on.

@kiaraarose Do you have a preference from the Safari side?

aarongable pushed a commit to chromium/chromium that referenced this pull request Aug 8, 2025
The sidePanel.close() method allows extensions to programmatically
close the side panel for a specified tabId or windowId.

Reference: w3c/webextensions#837
Bug: 403765214
Change-Id: I16b1c05869a1f4707bf107d4eff1d085235b906b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6638129
Reviewed-by: Devlin Cronin <[email protected]>
Commit-Queue: Oliver Dunk <[email protected]>
Reviewed-by: Oliver Dunk <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1499029}
@kiaraarose
Copy link
Collaborator

kiaraarose commented Aug 14, 2025

@kiaraarose Do you have a preference from the Safari side?

I agree with @carlosjeurissen that the behavior of closing a global sidePanel for all tabs if both windowId and tabId is a bit odd. If the intent is to close a global side panel, then not specifying the tabId would make sense. I can follow up with a dev who hacked on this for Safari (as a project, not shipped) to see they align.

Update: For Safari, we agree that having the sidePanel close for all tabs in this scenario wouldn't be ideal. I think an error for this case is sufficient.

@oliverdunk
Copy link
Member

Update: For Safari, we agree that having the sidePanel close for all tabs in this scenario wouldn't be ideal. I think an error for this case is sufficient.

Thanks for following up. To confirm:

  • If only tabId is specified, we can still close tab specific side panels. We don't need to require windowId.
  • If tabId is specified, but the open side panel for that tab is a global side panel, throw an error.

Is that correct?

Also, an additional question: If you try to open a side panel for a tabId, but you only have a global side panel, should we also throw an error? I expect so but would want to check with Chrome folk as this would be a breaking change we would need to make.

@oliverdunk
Copy link
Member

Hi @kiaraarose / @carlosjeurissen - we have been looking at updating sidePanel.open to remove the fallback to a global panel if tabId is specified but there is no tab-specific panel. However, in testing this breaks many of the popular extensions I tried including Grammarly, Phantom, Sider and QuillBot. With that in mind, it seems like this would be both a non-trivial breaking change and go against the expectations developers seem to naturally have.

Let's plan on discussing next steps at TPAC? Based on this I am once again leaning towards supporting a fallback to the global panel for both the open() and close() methods.

@Rob--W Rob--W requested review from Rob--W and removed request for zombie November 14, 2025 05:49
@Rob--W
Copy link
Member

Rob--W commented Nov 14, 2025

I'm taking over the review from @zombie on behalf of Mozilla, since I have been actively involved in discussions on the design of sidepanel/sidebar APIs at TPAC 2025. Those meeting notes will be published soon.

Copy link
Contributor

@carlosjeurissen carlosjeurissen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggested changes apply what has been discussed during TPAC2025. There is one open end:
Should we specify a global side panel will be reopened when closing a contextual one when switching tabs and returning to the tab with contextual side panel? As this is current Chrome behaviour.

- If `windowId` or `tabId` is invalid, rejects with an error.
- If both `windowId` and `tabId` are provided, the method will verify
that the tab belongs to the specified window. If not, it rejects with an error.
- If both `windowId` and `tabId` are provided:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- If both `windowId` and `tabId` are provided:
- If `tabId` is provided:

Calling only with a tabId should be possible

Comment on lines +89 to +90
- If the panel is already closed or does not exist in the given
context, the method does nothing.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- If the panel is already closed or does not exist in the given
context, the method does nothing.

Move this to the two different scenarios, in which the method is called with a tabId or without a tabId

Comment on lines +96 to +98
1. If a contextual side panel is visible on the specified `tabId`, it will be closed.
2. If a global side panel is visible on the given `tabId`,
it will be closed for all tabs in that window, not just the specified tab.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. If a contextual side panel is visible on the specified `tabId`, it will be closed.
2. If a global side panel is visible on the given `tabId`,
it will be closed for all tabs in that window, not just the specified tab.
1. If no contextual side panel is configured for the specified `tabId`, reject with an error.
2. If the contextual side panel is currently not open, the method does nothing.
3. If the contextual side panel is currently open, it will close the contextual side panel.

1. If a contextual side panel is visible on the specified `tabId`, it will be closed.
2. If a global side panel is visible on the given `tabId`,
it will be closed for all tabs in that window, not just the specified tab.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- If `tabId` is not provided:
1. If no global side panel is currently open in the window, this method does nothing.
2. If a global side panel is currently open in the window, close just the global side panel.

brave-builds pushed a commit to brave/chromium that referenced this pull request Jan 8, 2026
The sidePanel.close() call with tabId no longer falls back to the
global panel. It now exclusively closes tab-specific panels and
returns an error if one is not enabled for that tab.

Reference: w3c/webextensions#837
Bug: 403765214
Change-Id: I6d4fe1b1f2382a7d81bc2216418c9e4e513f66ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7317143
Reviewed-by: Oliver Dunk <[email protected]>
Commit-Queue: Oliver Dunk <[email protected]>
Reviewed-by: Solomon Kinard <[email protected]>
Commit-Queue: Harsh Singh <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1566376}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants