Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firefox WebExtension toolbar buttons to toggle sidebars

Since the Firefox Australis interface, there are no more toolbar buttons to toggle the Bookmarks and History sidebars with one click. There is the "show sidebars" toolbar button, but it displays an animated popup and requires 2 clicks.

So I'm trying to create a WebExtension to implement these buttons back.

  • a given WebExtension can add only one toolbar button, so I would have to create two separate extensions. This starts well... but ok, I'll deal with it.
  • sidebar_action doesn't add a toolbar button, so it rules out this method.
  • this leaves me with browser_action.

I tried many things, without success, for example:

  • Calling SidebarUI.toggle("viewBookmarksSidebar"); in a background.js script, but there is not defined SidebarUI object.
  • There is the chrome://browser/content/bookmarks/bookmarksPanel.xul URL, but I lack the sidebar to load it into.
  • I tried to combine sidebar_action and browser_action but that is not possible.
like image 894
Gras Double Avatar asked Jun 24 '17 22:06

Gras Double


1 Answers

Opening your own sidebar with a browserAction button

You can have a browserAction toolbar button which opens your own sidebar. You can do this by defining both a sidebar_action and a browser_action in your manifest.json.

When this question was asked, it wasn't possible to combine both a sidebar_action and a browser_action in a manifest.json. I'm not sure when that actually changed, but as of this point (tested on FF71), you can have both.

The following is example code which will do this:

manifest.json:

{
    "manifest_version": 2,
    "name": "Button opens sidebar",
    "description": "Open the sidebar with a toolbar button.",
    "version": "1.0",

    "browser_action": {
        "default_icon": "icon.png",
        "default_title": "Open Sidebar"
    },
    "background": {
        "scripts":[
            "background.js"
        ]
    },
    "sidebar_action": {
        "default_icon": "icon.png",
        "default_title": "Example Sidebar",
        "default_panel": "sidebar.html",
        "open_at_install": false
    }
}

background.js:

//The manifest.json entry must be a file in your extension, but you can change it to
//  an external site in your background.js:
browser.sidebarAction.setPanel({panel: 'https://example.org/'});
//Open the sidebar when the browserAction button is clicked.
browser.browserAction.onClicked.addListener(() => {
  browser.sidebarAction.open();
});

sidebar.html

<html>
  <body>
    <div>Example text</div>
  </body>
</html>

Toggling the sidebar open/closed

I tried implementing a naive implementation of the button actually toggling the sidebar:

background.js

browser.browserAction.onClicked.addListener(() => {
    browser.sidebarAction.isOpen({}).then((isOpen) =>  {
        if (isOpen) {
            browser.sidebarAction.close();
        } else {
            browser.sidebarAction.open();
        }
    });
});

Unfortunately, this fails with the error:

Error: sidebarAction.open may only be called from a user input handler

Use a second browserAction onClicked

You can take advantage of the fact that a sidebar that's showing HTML from within your extension is running in the background context, by just adding an additional browserAction.onClicked listener in the sidebar which closes the sidebar.

background.js

browser.browserAction.onClicked.addListener(() => {
    browser.sidebarAction.open();
});

sidebar.js

browser.browserAction.onClicked.addListener(() => {
    browser.sidebarAction.close();
});

sidebar.html

<html>
  <head>
    <script src="sidebar.js"></script>
  </head>
  <body>
    <div>Example text</div>
  </body>
</html>

Event listeners are executed in the order they are added, so the one added by the sidebar.js, which closes the sidebar, is run after the one in background.js, which opens the sidebar. Thus, when the sidebar is open, it gets closed upon the browserAction button being clicked.

Can't open the actual Bookmark or History sidebar

What you specifically desire, opening the actual Bookmarks or History sidebar, is not possible with WebExtensions. What you could do is implement similar sidebars yourself.

I did try changing the sidebar URL to a chrome:// URL:

browser.sidebarAction.setPanel({panel: 'chrome://browser/content/aboutDialog.xul'});

Unfortunately, that results in an error:

Error: Access denied for URL chrome://browser/content/aboutDialog.xul

If you desire some way to programmatically open the actual Bookmark or history sidebars, then you will need to file a bug requesting the functionality. Alternately, you can also create a WebExtension Experiment which adds the functionality to the WebExtensions API when the WebExtension Experiment is installed. WebExtension Experiments do not automatically get integrated into Firefox, but there is the possibility that it can be.

like image 139
Makyen Avatar answered Sep 20 '22 02:09

Makyen