A few weeks ago, I realized I was spending a lot of time every day at work opening all of the websites I need to use. There’s the payroll webapp, work and personal Gmail, JIRA, Testrail, Jenkins, and the list goes on. Every afternoon when I would get to work, I would open a new Firefox incognito window, manually open each tab, then type out all of those URLs. And I wasn’t the only one — I had noticed my colleagues were doing the same thing as I. Being one who enjoys puzzles and solving them, I saw this as an opportunity to solve an issue with programming.
Before I go any further, I will say that I knew it was possible to have specified URLs open as soon as you start your browser. What I didn’t know was how simple it was. I had thought you needed to write a script to do it automatically (something I figured the average browser user didn’t know or want to do), but in reality, it’s as easy as piping your desired sites in the “Homepage” field or adding said sites to a bookmarks folder, right-clicking on the folder, and selecting “Open all in tabs”. But this realization was to come later.
In order to tackle this problem, I decided to make a browser add-on/extension. I had worked on one before starting this project so I was able to grasp the capabilities and limitations extensions had when manipulating the browser. From there, I knew I wanted to be able to press a button (preferably located in a convenient spot) and after doing so, it should open all of the websites I had listed in some sort of settings page.
Mozilla has provided excellent documentation for creating WebExtensions (the latest type of add-ons that will only be excepted after Firefox 57 is released — check out the Getting Started guide). Based on my wants and needs from above, I figured I would want a toolbar action button (as opposed to a page action which is only functional for certain sites). This would allow me to press the button at any time regardless of the current tab or website open since the toolbar button will always be present. The way WebExtensions work, the event listener for the toolbar button would need to be in something called a background script which is constantly running regardless of whether or not the WebExtension is active. In my case, this is ideal because that means I can press the toolbar button at any time and won’t have to worry about whether or not the event listener will be triggered since it is always listening. At the time of this writing, I’ve already gone through a few minor changes and bug fixes for RapidTabOpener, so the logic with opening the desired websites has changed a bit. For the sake of time, I will only explain how it currently works.
RapidTabOpener_With the push of the button, RapidTabOpener opens all the sites you want immediately, no typing necessary!_addons.mozilla.org
The first time the toolbar button is clicked, RapidTabOpener will automatically open it’s Options page in order for users to select the window type they want opened and to add the sites they would like “opened rapidly.” Once preferences are added and saved, those preferences are then stored as JSON objects in the browser’s local storage. Here’s what those objects look like:
/*** object for window-type, where 'windowType' is a String,* "normal" or "incognito"*/var windowSettings = {type: windowType};
/*** the URLs, saved as Strings in an array*/var urls = ["gmail.com","news.ycombinator.com","reddit.com"];
When it comes to developing add-ons, developers have two different options as to where they would like to store data: local or session storage. The two are quite similar, the only difference being any data stored in local storage has no expiration date and persists even after the browser application is closed, whereas session storage data will be cleared after the session ends. Knowing this, I used local storage since I wanted users to only have to add their initial preferences once.
Once their preferences are saved, users are immediately able to press the toolbar button and “magically” the websites they entered will be opened in the window type they selected. This is possible because once the preferences have been saved, the window type and websites will be saved as objects in local storage. Then when the toolbar button is pressed, the event listener from the background script is triggered, which looks for and fetches those preferences objects. The window type is determined, then based on whether or not the desired window type is already opened, the program may or may not open a new window before cycling through and opening the sites added by the user.
A simple flowchart depicting how RapidTabOpener works (generated with ShakyDraw).
Having a minimal but working extension, I was quick to get it on addons.mozilla.org (AMO), the app store of Firefox extensions and themes. I really just wanted to be able to use the add-on at work so the initial version I submitted to AMO was classified as “Experimental” since I didn’t feel comfortable releasing it to the public. This made it so only people with the AMO listing URL could download RapidTabOpener. That initial version (dubbed 1.0) only had the ability to add and save URLs, and it would open a new private window and close any normal windows currently open. You can maybe see why I didn’t want the public to have this. Once I got the window-type selection functionality set up and the newer version added to AMO, I changed the listing to be public and was ready for users to try it for themselves.
After the second version was approved on AMO, I went to my usual place for self-plugging projects, Reddit. The first subreddit I created a post in was /r/firefox. The people over there were a tough crowd to please to say the least. I wasn’t really sure what to expect, but the overall feeling towards RapidTabOpener was, well, you decide by the comments:
“This can be done natively by setting multiple sites separated by the pipe character…”
“What’s the difference between this and bookmark folders?”
“Not to pile on, but a quicker/easier way, rather than right clicking a folder is to either hold CTRL while clicking it or middle click (if you have a mouse).”
“Why not just use session restore?”
I answered everyone’s questions, trying to defend my idea and all the work put into it. Although they admired my efforts, they just weren’t the right crowd for a tool like this (since they already knew about the built-in features to open a group of designated URLs). I’d be lying if I said I wasn’t a little upset after that initial post. This project was the first one I had ever made that I felt as if people would actually use and find helpful. I knew I hadn’t reached a target audience since a day after that Reddit post, the add-on’s statistics revealed I only had 11 downloads the previous day, 3 of which coming from an external source (Reddit), whereas the rest were from the “Recently Added” section of AMO.
Although I had solved the problem I faced originally, I thought RapidTabOpener would be something far more accepted by others. Frustrated with myself for not being able to think of better project ideas, I took the next couple days off from coding to think about everything. It was after stepping back and giving myself room to think that I realized my accomplishments from tackling the initial problem and being able to solve it. One, I was able to learn the basics of JavaScript on my own which I think is pretty neat. I realized adding, editing, removing, and saving the URLs was like creating a TODO app, a common first project that JavaScript beginners take on. On top of that, I learned how to read documentation while using the browser API in order to have all the various pieces of my add-on communicate with each other. Lastly, I realized I hadn’t just copied a built-in browser feature, I was able to tweak and even improve upon it. Natively, you can’t select what window-type you want your URLs opened in, they just open in whatever window is currently open. I was able to take it one step further and give that functionality to the users. Even more so, you can only add and remove URLs natively — editing the links is not an option. As we know, that’s not an issue in RapidTabOpener. And as of the latest version (v1.4.5
), RapidTabOpener has context menu options so you can easily add the current website you’re on or open the Options Page by right-clicking.
Upon having these realizations, I decided to try making a few more posts on different subreddits, this time /r/learnjavascript and /r/coolgithubprojects. The posts were identical and I made sure to include my newfound conclusions about this project, and this time it really struck a chord with people, with RapidTabOpener garnering just shy of 60 downloads that day and even a few stars on GitHub.
I was ecstatic! People were actually using something I had created myself and it made me feel more confident in my ability to program but also solve problems. I think the difference between the first post and the other two was that I not only shared the actual product I had made, but I also included the process in which I had gone about making it. It’s cool seeing a final product, but what’s even more intriguing is being able to see what went into developing that product and the mindset of the creator.
Starting with a simple problem I wanted to fix, I went from solving the issue, to improving upon the solution, to sharing my solution and hoping others would find it useful but it not really being accepted, to getting upset only to realize what I had actually learned and accomplished, to sharing my solution along with my realizations, to finally targeting the right audience and finding a solution for not just myself but others as well.
By almost-unknowingly copying a builtin browser feature, I was able to learn much more than I would have anticipated. From the technical aspects I picked up, like learning the basics of JavaScript and learning to read documentation, to the important marketing facet/lesson I just coined, “share you process, not just the project”, I’m happy to say RapidTabOpener has been one of my, if not the, most significant projects I have created. Now if only I would add Medium to my list of websites to RapidTabOpener so I can remember to write more often…
If after reading this article you’d like to try RapidTabOpener yourself, feel free to download it from AMO below. For you Chrome users, you’ll have to wait just little longer. The process of porting RapidTabOpener to Chrome is currently underway. If you’ve enjoyed this post, check out the rest of Cedric’s writing at his blog, coffee. code. cedric, also found below.
RapidTabOpener_With the push of the button, RapidTabOpener opens all the sites you want immediately, no typing necessary!_addons.mozilla.org
coffee. code. cedric._musings and thoughts from the mind of a wannabe software developer._blog.cedricamaya.me