w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
576 stars 50 forks source link

Private tabs/windows handling in mobile form factors #632

Open carlosjeurissen opened 3 weeks ago

carlosjeurissen commented 3 weeks ago

Introduction

During the 2024 San Diego in-person meeting the question on how to handle private tabs/windows has briefly been discussed and promised to create a WECG issue to proceed this discussion.

The concept of window is often absent in mobile web browsers nowadays. The ability to open private tabs is often implemented by having a separate tab stack. Users can then toggle between their private tabs and normal tabs.

The questions for this group is how the extension APIs should handle this form factor. This is especially questioned for the browser.windows API.

In this issue I want to describe two approaches. The first approach is currently implemented by Safari on iOS. The second approach has not been discussed in detail however to make sure we make the right decision I want to include it as both approaches have their benefits and downsides.

Approach 1: using a window pair

This approach would mean every app frame would have two windows which are a pair. One window will contain all the normal tabs, while the other window will contain the private tabs.

To assist developers, a new pairedWith key in the windows.Window object can be introduced containing an array which includes the window ids of the other window(s) which the window is paired with.

Benefit:

Downsides:

Approach 2: using one window with mixed private and non-private tabs

This approach would allow "mixed" as value for the incognito property in windows.Window objects. As alternative a non-breaking new property can be introduced named private which can be true|false|"mixed" and has the added benefit of being more browser-neutral (see https://github.com/w3c/webextensions/issues/113). In the case of "mixed" windows, the incognito would then simply state true to prevent any privacy issues and backwards compatibility issues.

Benefits:

Downsides:

Use cases

Reopen in private This extension reopens the current tab in a private tab if it is currently a normal tab. And reopens it as a normal tab if it is a private tab. This requires the browser.windows API.

Others During the in-person meeting it was implicitly mentioned extension developers request the browser.windows API on mobile. Related issue on Firefox bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=1372178

Conclusion

Both approaches have benefits and downsides and need further discussion. There are a few open ends. For example, should we consider a device switching back and forth to a mobile form factor? (Think about a tablet for example).

carlosjeurissen commented 3 weeks ago

This was discussed during the 2024-06-06 meeting. @Rob--W Requested for use cases which I have added to the main issue. I suggest everyone with browser.windows to share their use cases of the browser.windows API on mobile.

Rob--W commented 3 weeks ago

In the meeting I mentioned the use case of opening a private tab. On Firefox's side there is a bug report for that at https://bugzilla.mozilla.org/show_bug.cgi?id=1372178

At the abstract level, I view a "window" in the extension API as a collection of tabs. In Firefox for Android the current extension implementation treats every tab as a single tab in a window, but this is something I'd like to change.

The two most common collection of tabs on Firefox for Android are the private and non-private tabs. In your proposal (1) you mentioned window pairs. That could be implemented either as a property of the window (e.g. an array referencing others) or a new type (collection of ). I currently have no opinions on which to use, but note that the introduction of a new type would enable more metadata to be added to the collection of paired windows if desired.

To answer the design questions in the original issue:

  • Windows could contain no tabs at all. Meaning running tabs.query({currentWindow: true, active: true}) could result in an empty list.

That API call could already return an empty list. E.g. on macOS, it is possible to close all browser windows and the application still be running. Even on non-macOS, you can have the global Browser Console open and there not being an active window.

An alternative to an always-existing paired window is to introduce an option to the windows.create API to allow creation of a paired window. It will throw if the paired window already exists, in which case the extension could use windows.getAll() with a new option to limit to windows related to a "paired window".

  • Incompatible with windows.remove() as it is unclear what should happen with paired windows

Up to the implementation, but in the API design this could be exposed as windows.onRemoved. Optionally, the event could include extra details to let the extension know that it was closed as part of closing a window pair. The tabs.onRemoved event has prior art on this.

  • browser.windows.create API would create two windows when calling. What window id to return in that case?

The created window. If another window is created the windows.onCreated event could fire.

  • It is not clear if both windows of the pair should have an active tab. Safari currently does not state any active tab in the paired window.

From the API design perspective, one of the tabs in the window could be marked as active, i.e. the one to be highlighted if the window were to be activated. I know that the UI could not be focusing any particular tab. In that case it could be acceptable to either highlight the last active tab or none.