Can a click event be used to open the sidebar

I have an extension that contains a content script that generates a grid of icons where each icon (image) corresponds to a search engine that can be clicked. Ideally, I’d like the sidebar to open when one of the icons is clicked. Reading the documentation, this doesn’t seem possible. Am I wrong?

Sadly, it’s not yet possible:

It’s possible only on extension pages, or when clicking context menu item.
Even if you load iframe with extension page inside, the required API is not available.

Thanks for confirming, Juraj. It would be so much easier for web extension developers if sidebars had a tab id. There still are quite a few things missing.

Yeah, it’s been a while since I’ve worked with the sidebar so I can’t remember how it worked, but yes, it’s not easy to target it.
I think I was just broadcasting all messages using runtime.sendMessage API.

See also this discussion for more tips:
https://groups.google.com/a/chromium.org/g/chromium-extensions/c/K0ZWVcjEVzA/m/FXsT4UVjAAAJ
Chromium has a bug for it:
https://issues.chromium.org/issues/40912790

1 Like

Thanks for the link, Juraj. The latest info about sidebars for Chromium based browsers that I found is here: https://groups.google.com/a/chromium.org/g/chromium-extensions/c/5PQyHPYQuXY/m/ZbsHqqTlAgAJ

The least I can say is that progress is being made at a snail’s pace! Would have been nice to see Firefox take the lead here, but I don’t think it’s gonna happen! For some things though, it’s a pleasant surprise to see Firefox take the lead: a few years ago when I migrated my web extension to Chromium, I was really surprised that there was no support for favicons in context menus. I found that using Google’s tools can be quite constraining and frustrating. Was always hoping that a more open and privacy conscientious Firefox would offer more flexibility, but it’s not always the case: for instance, we can’t programmatically set the sidebar to open on the left or right side dependent on a user setting in the Options page. Small things, but details make all the difference.

There may be reasons for limiting what developers can do, but then I wish those responsible would be more transparent and open to discussion.

On a side note, I’ve always dreamed of migrating the current version of my extension to the Chrome web store so that I could monetize all the hard work that went into creating the extension all these years, but now, with manifest v3 and the use of service workers, I’d probably have to rewrite most of the code. Therefore, I think once MV2 is gone so will it be the end of my extension.

Take care and thank you for your dedication in helping us.

I don’t think there is enough developers in Firefox team in general, not to mention dedicated to extension API.
So yeah, things are moving super slow these days/years.

It feels like Firefox is now only adding features that Chrome has.
You see, not many people actually uses extensions, so things like new CSS/JS API have priority, because those are the things that can make pages broken in Firefox.

Note that migration to Manifest V3 should be pretty easy in most cases (I’ve migrated all of my 13 extensions).
Apart from the manifest.json file changes, there is not much that’s different. The biggest issues I had were the various race conditions caused by waking up background script and executing things that were not fully initialized.
But other than that, the code is pretty much the same for Firefox and Chrome/Edge.

1 Like

If you have enough spare time, I’d be willing to pay you a reasonable amount to migrate my extension from MV2 to MV3. I think that it also requires getting rid of global variables and I have quite a few of those. If you personally don’t have the time but know a dev who’d be happy to help…

But, otherwise, I think you’re quite right: I believe Mozilla has maybe had to shrink its dev teams and focus on priorities like privacy. Maybe they should create an addon store and ask devs for a percentage of sales so that Mozilla gets an additional stream of revenue. Mozilla also produces excellent documentation on MDN. Maybe they could monetize it partially by requesting a small slice of the pie from AI providers that use the documentation to train their systems.

Anyway, I hope that Firefox will keep some interest on the sidebar, because I think that it’s really handy to have some AI agent in the sidebar to whom you can ask questions about the active tab/web page one is viewing. It was actually adopted by Edge and I think that was a smart move.

2 Likes

Sadly, I have absolutely no free time :smiley:, I go to work also Saturday.
My todo lists are crazy long and I have a feeling they are only getting longer.

Also, refactoring someone else’s code can be very challenging. It’s best if you do it yourself. I can help only here with questions :slight_smile:.

Note that global variables, although in general not recommended, are not forbidden in MV3, you just have to make sure they are being set “in time” when the background script is woken up.

So if you have async module A and some module B needs to use properties from A, you first need to await some “A.promise” before running some B.execute(). I’m not sure if I’m describing it right :smiley:.

1 Like

No worries!

I have difficulties understanding service workers.

I wish there was an AI tool or something like an eslint for VS Code that could assist in migrating code from MV2 to MV3. It would list the problems it finds in the code that still isn’t MV3 compliant.

Have a nice end of day.

P.S. Can I ask you what your job title is? Do you work full time for Mozilla?

I think ChatGPT should be able to help with refactoring if you ask specific question.
Also Copilot plugin is great help for the IDE, if you are not using it yet, you should try it.
It will write so much for you, it’s crazy! Plus it has chat integrated so you ask questions about refactoring.

Regarding the actual work with the “service workers”, there is almost NONE! No registration or other complicated things.
Let me give you simple example:
Firefox manifest file (MV2):

  "background": {
    "scripts": ["background.worker.js"], "persistent": true
  },

Chrome manifest file (MV3):

  "background": {
    "service_worker": "background.loader.js"
  },

And in the “background.loader.js” you put this:

try {
  self.importScripts('./browser-polyfill.min.js', './background.worker.js');
} catch (e) {
  console.error(e);
}

THE END!
Now your “background.worker.js” javascript file is executed as normal persistent in Firefox and also as service worker in Chrome.
The “browser-polyfill.min.js” is optional polyfill for the “browser” namespace in Chrome.

Regarding my job title, I’m not sure, I’m entrepreneur :slight_smile:, so CEO and CTO? :smiley:
And sadly I don’t work at Mozilla, sometimes I wish I would, but then how would I manage all of my addons…
Look, this is me few years back:

2 Likes

Kinda funny, I thought you were Indian but you don’t look Indian at all!!! :joy:

Actually, I’m contacting you because I released an update to my extension that has caused a lot of stir and trouble to my users, as you can see here: https://github.com/odebroqueville/contextSearch/issues/189

I’m really quite sad about this because I went through a lot of effort to refactor parts of the background script to make it cleaner. It’s a bit strange: I only released the code because I wasn’t encountering any issues on my Mac. Sadly, I don’t have a Windows machine to test things out, so I was wondering if you could find some time to see if there are any error messages in the Console. If you have a Windows machine that is!

I really need to find a more proficient developer of web extensions who could help me out.

LOL! Indian… that can be considered as insult here :smiley:.
So when you were offering me a job, that was with “Indian pricing” in mind? :smiley:
I would charge you 40€/h for my services! :slight_smile:

Anyway, if you need to test some specific use case in Windows, I can do that (for free!), but so far I’ve haven’t seen any errors in the background console (I’ve just installed it).

But it’s very unlikely a background script issue would be platform specific (I haven’t read the long github thread :slight_smile:) .

And I’ve briefly checked your code… oh man, you weren’t kidding about those global variables!
It’s crazy!

I would strongly recommend you to split your code into modules!
Instead of having one background script with 2,000 lines of code you should have, for example, 20 files with 100 lines - each file implementing specific feature, using own “locally global” variables, and exporting (if needed) some function/variable.

These days, you can use export and import natively in the browser without any bundler.
And it will even allow you to share functions between different contexts (except for content script, those doesn’t support modules).

And modern IDE should handle imports automatically (so that you don’t have to write them manually).

More info:

Thanks for looking at the code on Windows. Several users reported using Facebook or Whatsapp. Not sure if that’s a path to follow. Most users were either on Windows or Linux. Only one other user was on Mac.

Most frequent problems encountered were:

  • context search menu not appearing (but it would appear again after a change to the search engines)
  • multiple tabs of same search results opening

If you could give me one small example showing me how you would place part of the background script into a module, that would help a lot. Two things I struggle with in JS are modules and Promises! I think there have been quite a few changes re modules, some using require others import, etc.

You don’t like Ruppees?

1 Like

So, modules. Let’s start super simple!
First, edit your manifest file by marking your background script as module:

    "background": {
        "type": "module",
        "scripts": [
            "/scripts/background.js"
        ]
    },

Then test if your addon still works :slight_smile:.
It shouldn’t break anything, unless you are already doing something bad since it enforces strict mode.

Next, try to move something simple out of your background script.

For example, remove line:

const chatGPTUrl = 'https://chatgpt.com/';

Then create new file called “hosts.js” (for example) and paste there this:

export const chatGPTUrl = 'https://chatgpt.com/';

Now in your background script, on the very first line of the file, import the chatGPTUrl from the newly created hosts.js file by adding the following line:

import { chatGPTUrl } from './hosts.js';

Now just test it to see if it still works.

I’m using WebStorm, so refactoring like this can be fully handled by the IDE. All I have to do is click the variable/function/class/etc, press F6 to “extract” it and then just name the file (or create new) where I want to move it and it will do all the things for me - adds export and import.

If you want to encapsulate file that doesn’t export anything (for example some “onCommand” handler), then import the file only:

import './browser_commands.js';

Importing a file will simply execute it.

I hope all this will work as expected, I’m using TypeScript with webpack so some of these things are assumptions :slight_smile:.

1 Like

Thank you for these explanations. I’ll see what I can do. It would definitely make the code look cleaner. Gee! I have a lot of work doing this and migrating to MV3!

In the mean time, I found 2 bugs in my code. One of them was really silly: I was using lastTab.index where lastTab was an integer! The other bug was in the rebuildContextMenu function: I wasn’t removing a listener properly for browser.menus.onClicked.addListener. I’m not sure though if this could have been the cause for users getting a message saying that the extension was slowing down Firefox.

I’ve updated the code on GitHub. If you’d care to test the changes, I’d be most grateful.

Btw, I’ve heard that Parcel is easier to use than Webpack, but I don’t think that I need a bundler as I’m using vanilla js. However, I’ll eventually be using the webextension-polyfill for cross browser compatibility. If I’m using a polyfill, do I still need to change all the ‘browser.’ to ‘chrome.’?

P.S. In which country are you based?

Let’s start with the simple stuff.
I’m from Slovakia - a small country in the middle of Europe :slight_smile:.

The issue you mentioned with the integer type - this is why people love TypeScript, it eliminates all these issues once and for all. I can’t imagine programming anything big in plain JavaScript.

Regarding Parcel - when I started working on extensions, I’ve used vanilla JS, just like you. Then I’ve build my own build system (because Webpack was too complex), then it got too slow to recompile so I’ve used Rollup. That was pretty great, but later on, it couldn’t do things I needed.
So I’ve ended up learning to use Webpack, and I believe it’s the best option. It has great community support and all libraries works with it.

Then again, maybe you don’t need it just yet.

The webextension polyfill is great, you will be able to keep using browser namespace and everything will work in Chrome.

Now your Github code, I’ve started it locally, but selecting any text on the page produces a bunch of errors and context menu is empty.

These are unlikely platform specific, you should see the same issues.
I’ve used web-ext run to run it and opened Wikipedia page and selected some text and look at all these errors:

20:21:44.120 TypeError: can't access property "disableAltClick", options is undefined
selection.js:511:9
20:21:44.235 TypeError: can't access property "siteSearchUrl", options is undefined
selection.js:707:23

BTW: your root folder shouldn’t be your source code folder, you should have a “src” folder with the addon source code, and use other root folders for tests/docs/AMO info/build system/etc…

Strange! I’ve never seen these errors! It’s your first run, so it looks like the default settings for options aren’t saved to storage.sync. I can’t reproduce these errors though. If I remove the extension and restart Firefox, will it clear storage sync?

I really don’t understand why you’re seeing those errors! When I Inspect the Console, I can clearly see that the options are being saved to storage sync followed by the search engines being saved to local storage:

I think storage.sync stays even after uninstalling.
In any case, use web-ext, it creates new profile so the extension behaves as if it was just installed.

Are you creating default options in the background script when they are missing?

Storage is empty:

22:45:22.944 await browser.storage.sync.get()
22:45:22.954 Object {  }

22:45:28.803 await browser.storage.local.get()
22:45:28.816 Object {  }

Is there some build script I should execute? I just downloaded the github code and run web-ext run

Yes, in the function initialiseOptionsAndSearchEngines (Lines 687, 688).

I’ve debugged it and your fetchConfig function returns rejected promise. So the rest is not executed.