How to write Chrome (and also Firefox I guess) addons

Hi! I’m Twitter User Afal. I’m just like any other millenial on the Internet. I prefer to do the selfies on snapchats rather than buying houses, and I too long wish for the fall of capitalism to be swift and without mercy.

Just like any person my age I like video games. I also like feminism, and any combination of the two is [100 Emoji]. But sometimes, whenever I watch a youtube video, I get suggestions for various videos like “I’m a chemical engineer and here’s why halo for the playstation is not sexist for 45 minutes”, and “I’m not racist but I think white people should be allowed to say the N word and not letting them do so is censoring free speech”. This isn’t [100 emoji].

Anyway, I don’t suggest watching those videos. Instead I suggest Hbomberguy’s “Measured Response” videos. Which are hilarious. You should watch them. They’re good.

Unfortunately, by watching his videos you end up getting awful suggestions yourself. Fortunately, Hbomb has a solution for that as well.

The Hbomb Youtube Censorship Addon is a chrome extension (which is also for Firefox) that I made. I got hired by Hbomb (and paid in exposure) to make a chrome addon that hides videos. Yes I know there’s an addon that does this already. Yes I know there’s a report function on youtube that you can use to hide certain channels indefinitely. This addon has a jingle though.

There’s a few things I’ve been asked since releasing this like “Why do you hate free speech?” and“How would YOU like it if we ignored your lord and saviour Anita Sarkeesian?”. Today I’m going to answer two of the other questions I get which is “Can you add X to this?” and “Can you share the source code?”.

I can do better than that. I can SHOW you how to make addons for chrome. Now YOU can be

Step 1: Learn JavaScript

It is the law that any blog post talking about JavaScript should contain a picture of this book. Preferably side to side with the “JavaScript” O’Reilly book that is quite a lot bigger than this one. This is one of the many jokes about JavaScript that people like to do along with “leftpad” and “haha! package managers right?”

At one point in developing for the web you’re going to have to learn JavaScript. A long time ago you could just stick JQuery everywhere and it would do everything, now you have to actually learn it.

There’s not much help I can give you here. I suggest either getting a book or using https://www.codecademy.com/ or something.

Step 2: Learn The DOM

Most learning resources on JavaScript skip on this, which is fine because introducing it will scare new programmers away. The DOM is a scary monster and I hate it and it’s easily the worst thing about JavaScript. Again I don’t have any good advice here. Try https://dom-tutorials.appspot.com/ maybe?

Or you can skip this bit and use a bit of code later in this post.

Step 3: Make a UserScript

UserScripts or Greasemonkey scripts are going to be the base of our addons. These are scripts that are run once a webpage has loaded. Either get Tampermonkey (for Chrome) or Greasemonkey (for Firefox).

I’m going to assume you’re using Tampermonkey, but Greasemonkey users shouldn’t be wildly different. Click on the icon and click “Add new script”. You should get something like the following:

I’ve added that alert there to test. Once you save this script, whenever you load a webpage you’ll get an annoying alert box. Obviously not a helpful script but there you go, you’ve made your first plugin… sortof.

For the next half of this half-assed tutorial, I’m going to come up with an example plugin idea. I see the word “cuck” being used a lot lately. It’s gotten to the point where the word has no meaning and is literally interchangeable with any other nonsense word.

So… let’s just make this a little more fun by changing “cuck” to “smurf” shall we?

Now to replace the text on a webpage, the best way to do so is to check the structure and branches of a webpage until you get to “text nodes” and do the changes there and then. Something like this:

Then you can go handle the text. Here we should change the word “cuck” to “smurf” while still maintaining whether it’s written in upper or lower case:

Get the script to handle the page with “walk(document.body)” and you’re done.

Except, the script will only load once on page load. In order to make it change on sites where the whole page doesn’t load when you click a link (like twitter or youtube) you’ll need to use a mutation observer that checks for changes in the webpage and runs the script again when it does so. Something like the following should do:

You’ll notice I add a timeout to the trigger. Many changes can happen a second and if the mutation observer were to trigger and change every time it could lock and freeze the page up and freeze your browser. Actually, this might be completely unnecessary but I’ve added it just in case.

Step 4: Create a package

Now that you’ve got your script working you can go ahead and disable your userscript. Go ahead and do it. We’re going to start creating the package now.

The following is going to be about Chrome because creating addons for Chrome is actually a lot easier and less of a pain in the ass.

Basically you go to “More Tools > Extensions” in chrome and click the “Developer Mode” tickbox. Now you’re a developer. Congrats.

Developer mode allows you to load a folder as a chrome extension. The important thing is that this folder needs a few things:

  • The script
  • An icon (a png which is 127x127, 64x64, and/or 32x32)
  • A manifest

What’s a manifest I hear you ask? well it’s one of these:

Just save your userscript you made in the previous step as “script.js” and you’re good to go. Load up this unpacked extension and you get the following:

Ah *chef kissy fingers*

You can go check that this works, go ahead.

I’d go to Step 5 now but I have to check on Firefox users

Step 4.5: Package for Firefox

Firefox packages are a pain in the ass and I wish there was a “Developer Mode” that allowed me to load unpacked extensions. Add that in Mozilla, please.

Anyway, you’re going to have to actually make a .xpi package. On the one hand this isn’t a bad thing because this is what you’re going to need for the next step “adding it to the store”. The problem though that if this doesn’t work then you’ll have to uninstall the addon, repackage it, and restart Firefox.

Oh, and you have to go to the config so that Firefox can let you add external addons. I can’t remember how I did this.

Anyway to create the .xpi you need to add to the manifest.json an application id. This is typically in the format “something@website.tld”

Oh, by the way, if you’re going to make an extension for both Chrome and Firefox, the “applications” part of the manifest needs to be removed for the Chrome package. You should probably have separate manifests or something.

All you need to do now is zip up the manifest.json, the script.js, and the icon. you then have to rename your .zip file to an .xpi. That’s it. you’ve packaged your Firefox addon

Step 6: Sending it to the store

Ok before this next step I’m going to need an easier way to build the packages, so I’ll just create a script for it. I’m using windows so I have to use a batch script. Also I’ve found the easiest way to create zip files on the command line was to use 7zip so whatever.

Ok, now all we need to do is upload the plugin to the store. The only caveats I’ve found with either are as follows:

  • With Chrome you have to pay a “one time” fee of $5 to submit as many plugins as you want.
  • Firefox has a manual code review process that can reject your plugin at any time.

These are all I can think of.

Step 7: Don’t do any of the above because I’ve done it anyway

Bam

https://chrome.google.com/webstore/detail/ofphpecnggajokednpbnbghnlloaccco

Already on the Chrome and Firefox store! Also a GitHub repository for completeness sake.


Now I know what you’re all thinking “Twitter User Afal, this doesn’t answer any of the questions that was asked before”, and you’re absolutely right! I didn’t answer ANYTHING.

Fine, I’ll create a github repo for the hbomb censorship addon.

Don’t ask me to do anything ever again.