Work-around extension popout-tab refusing to close on Firefox Android

How do you close an web extension popout-window (the small window that appears when you click on an extension’s toolbar button?) On the desktop, all you need is a simple window.close(). Because of the limited available screen space Firefox on Android have popout-tabs instead of popout-windows. Users can dismiss these tabs by pressing the back button, closing them manually, or switching to another tab. However, they’re deceptively difficult to close pragmatically.

Update (): This articles applies to Firefox for Android starting with version 57 up to and including 69. It’s not relevant to versions newer than this.

It’s common for web extension popout-windows to close themselves after the user has completed an action in them. While many web extensions work on Firefox for Android, users often have to manually close the popout-tabs on their own.

You can’t reliably close web extension popout-tabs with the browser.tabs.remove() function or replace it with a blank tab using browser.tabs.update(). You also can’t close them with window.close() because the browser doesn’t allow closing of tabs that weren’t opened by JavaScript (there’s a specific exception to allow this on desktop). So, what can you do?

To close your extension’s tab, you can exploit an implementation detail of how the popout-tabs work. You’ll always have a previously active tab (the opener-tab), and it and the popout-tab are considered to be active at the same time. By reactivating the active tab with browser.tabs.update(), you can get the browser to switch back to the opener-tab and dismiss the popout-tab in the process.

The following example closePopOut() function will close popout-windows on desktop as well as the popout-tab on Android. The function will use the window.close() function on desktop but also as a fallback on Android if the work-around stops working in a future version of Firefox.

// SPDX-License-Identifier: CC0-1.0

function closePopOut()
{
  return Promise.all(
    [
      browser.runtime.getBrowserInfo(),
      browser.runtime.getPlatformInfo()
    ]
  ).then(
    data =>
    {
      if (data[0].name == 'Firefox' &&
          data[1].os == 'android')
      {
        return browser.tabs.update(
          {active: true}
        );
      }
    }
  ).finally(
    window.close
  );
}

The above method have to be called from the scope of the popout-tab, just like it does on desktop. Calling it from the background script or a content script will have as little effect on the popout-tab as it does on the popout-window.

The method returns a Promise of closing the tab. The method can sometimes be slower than normal if the opener-tab is a private tab (and I’ve got no idea why).This work-around will fail on Android (not on desktop) if you close the opener-tab before calling this method. You can, however, activate another specific tab by tab ID instead of re-activating the previously active tab. Like with private tabs, this can sometime be slow to execute on Android.

Note that the above implementation only reactivates the active tab on Android. You could just always call the work-around code on other platforms too. However, you may see an unattractive white flash in the address field on Windows and accessibility tools might freak out a bit if you first move window focus and then close the popout-window. (The typical order is window-closing followed by resetting focus; going out of order could, e.g. trigger redundant and confusing messages for screen readers.)

The future might not be looking too bright for Firefox for Android, and especially web extensions in Firefox for Android. Mozilla put Firefox for Android on the back burner while it work on new and more exciting browser-like products such as Focus and Fenix. Neither of these two initiatives currently support web extensions, however. Firefox has carved out a mere 0,38 % of the web browser market share on Android (so still a huge number of people), according to StatCounter.

I hope Mozilla won’t abandon extensions on Android going forward. As someone who likes web extensions, I can’t say I’m too happy about this development. Firefox for Android has a limited and buggy web extension support, but its way better than having no extensions at all.