As the semester is drawing to a close and we the open source crew are feeling comfortable with the JavaScript language, Dave took us to the next level. From the content scripts we had been working on, we got our first exposure to chrome scripts: JavaScript that doesn’t just run in the browser: it runs the browser. With elevated privileges (like hard drive access) and a larger object model (like controlling the tabs) things were getting interesting. And how else would we work with this than by rewriting a very small part of Firefox to give it some added spark?
So that’s exactly what we had to do. Something simple, just changing the behaviour of new tabs from by default being appending to the end of the tab collection to appearing just to the right of the currently active tab. It could be done in just a few lines of code, he said. He was right but it took sifting through millions.
Enter MXR: Mozilla Cross-Reference. It’s a powerful web tool that allows you to search through and jump all over the source code through cross-referenced links. Every function call and definition, regular expression and plain text searching, everything was made easier with this tool. The hard part was finding a good starting ground. Kenneth in class suggested a search for “New Tab”. This didn’t get us exactly what we wanted, but it was the best we could hope for considering our ignorance and we ended up following a quick chain.
- We started with the UI descriptive text “New Tab” label, stored in tabCmd.label
- From there a search for tabCmd.label brought us to a menu description, which mapped the label to a command (cmd_newNavigatorTab)
- From there, it was easy to find the mapping of the command to the function (BrowserOpenTab();)
- Now we’re getting into code. A search for the function quickly found the definition…
- …Which held the setting of the currently selected tab
- … And also a call to the addTab function, inside of which held appending to a master tab list
- A little further down from there was the real location, setting the tab position
All of this was done by the class, but conveniently we ran out of time before we could get right to the bottom of how to do this mini-assignment. Though ending on the cusp of discovery, some self research into the rest of tabbrowser.xml quickly found me a solution. 2 lines of code later, I had something that seemed to be working. After generating a diff file using Mercurial…
hg diff -p -U 8 > changes.diff
I had a portable way to model and ship my changes. I had been working off an older code base (current from when I had last built Firefox) so line numbers are slightly skewed with respect to the current code. It seemed to work on my computer, but I had to test it on other’s. So I got experimenting some more and found out I’d stopped just shy when building Firefox last time: I had never packaged it!
make -C objdir/browser/installer // ZIPs/Tarballs to objdir/dist make -C objdir/browser/installer installer // Builds MSI to objdir/dist/install/sea
After a few quick commands from the source root (and replacing “objdir” with my object dir), I was ready. Gave the ZIP file to a friend on USB and she tried running it. Error. Hmm. Turns out there were a few missing DLLs. My compiler (Visual Studio 10) had a few dependent dlls in C:\Windows\system32 that hadn’t been archived. Remedying that though, and everything was a-ok.
What did I take away from this? I felt this was a great way to not only learn about chrome scripts, but drilling down from the UI “New Tab” label to the code that made it happen gave me an appreciation not just for the size of the Mozilla code base, but the architecture as well. I learned more about various tools at public disposal to make the 500 foot dive into the Mozilla project seem more like 5. And most of all, I learned the excitement of shaping Firefox.

Leave a Reply