Building WebExtensions in Typescript

I spent yesterday evening doing something I haven’t done in a while: tinkering. You may have seen the news that there’s a big change coming in Firefox. The short version is that later this year, the old extension model is going to be retired permanently, and extensions using it will no longer work. As someone with an extension on addons.mozilla.org, I’ve received more than a few emails warning me that they’re about to go dark. This isn’t the first time Mozilla has tried to entice folks to move on from XUL Overlays: Jetpack was a similar effort to allow extensions to play better within a sandbox. This time I think it’s going to stick: the performance benefits seems undeniable, and as a developer the prospect of writing a single extension to support multiple browsers is pretty appealing.

Over a year ago I took a stab at porting OpenAttribute to Browser (Web)Extensions. I read the Firefox code and basically understood it, but only because it was the third iteration of something I’d built. The Chrome code — which should be close to a proper WebExtension — was almost inscrutable to me. So naturally I wanted to start with tests. But a year ago I couldn’t quite make the connection for some reason. WebExtensions split your code between the page (content scripts) and the background process. Long running things belong in the background, and the two communicate via message passing. After reading about the coming XUL-pocalypse, I decided to take another run at it.

Last night, though, I focused on something far smaller: just understanding how to put together a WebExtension using the technologies I’m familiar with — react, redux — and the ones I’m interested in — TypeScript. The result is an extension that doesn’t do much, but it is written in TypeScript, and it does work in both Firefox and Chrome from a single code base.

The attribution extensions I’ve written have always had a data flow problem. There’s the question of what triggers parsing, where the extracted data is stored, and how you update the display. Not to mention how do you do that without slowing down overall browser performance. I’ve had good luck with React in other projects: it feels like it forces me to think of things more functionally, making it easier to write tests: does this component do the right thing with the right data? does this other thing send the right signals with the right input? Cool. But how to do that across the process boundary between background and content scripts?

webext-redux is a package that makes it easy to manage a Redux store in both processes and keep it in sync. The only real wrinkle is that the actions you fire on the content side have to be mapped to actions on the background process, which is where the mutations all take place.

So why TypeScript? I’ve been enjoying ES6 and the changes it brings to JavaScript. But I’ve still missed the types you get in Go with MyPy. TypeScript is interesting: it’s duck typed, but the ducks seem to quack louder than they do in Python.

I was particularly intrigued by ambient modules, which is how TypeScript provides type information for third party JavaScript libraries you may want to integrate. Luckily type definitions already exit for the web extension API, and it’s easy to write a (useless) one to quell the compiler warnings.

I think the biggest shift I’ve been trying to make is understanding imports. import * as actions from './actions' feels weird to write, and to be honest I’m not sure how it differs from import actions from './actions' when there’s not a default export.

I like TypeScript enough to try another experiment in the future. The compiler already pointed out a couple of errors that would have been hard to track down.

Up next: figuring out how to test web extensions and build a single code base that runs under Chrome, Firefox, Edge, and Opera.

Web Progress Notifications in Fennec

Working on OpenAttribute for Firefox Mobile (Fennec) yesterday, one of the first challenges I faced was how to get notification that a page had finished loading. In the desktop version, I attach a listener for all tabs using gBrowser.addTabsProgressListener. Unfortunately with browsers running in their own processes, this approach doesn’t work on Fennec. I spent quite a bit of time trying different approaches, all with the intent of creating a progress listener and attaching it myself. The Electrolysis wiki page says that one of the nice side effects of the message passing model is that this problem is easy to solve, but it sure didn’t feel easy.

I don’t remember why I eventually started looking at the mobile-browser source tree, but as I looked through browser.js, there it was:

messageManager.addMessageListener("Content:StateChange", this);

It turns out it is really easy: you can listen for Content:StateChange or Content:LocationChange, and get access to the same details you’d normally have in the WebProgressListener implementation.

date:2011-04-04 20:41:18
wordpress_id:1889
layout:post
slug:web-progress-notifications-in-fennec
comments:
category:mozCC
tags:fennec, firefox, mobile, mozcc, OpenAttribute

Unexpected Attribution

I’m working on adding support for Firefox Mobile to OpenAttribute this weekend. I’d hoped to get that done in time for the official launch, but, well, things have been a little busy. Firefox Mobile (Fennec) uses Electrolysis, a multi-process architecture that’s a little different from what I’m used to. Looking at the documentation and APIs, it actually looks a little closer to Chrome’s extension architecture. I was looking at tutorial videos yesterday, and downloaded Mark Finkle’s boilerplate addon to get a better look at the overlays.

As I explored the boilerplate, I opened the build script. Imagine my surprise when I read this comment at the top of the script:

#!/bin/bash
# build.sh -- builds JAR and XPI files for mozilla extensions
#   by Nickolay Ponomarev <asqueella@gmail.com>
#   (original version based on Nathan Yergler's build script)
# Most recent version is at &lt;http://kb.mozillazine.org/Bash_build_script&gt;``

I have to assume this is based on the build script I developed for MozCC in 2004. I doubt anything from the original still survives (or at least I hope not), but appreciate the credit.

date:2011-04-03 10:53:00
wordpress_id:1881
layout:post
slug:unexpected-attribution
comments:
category:mozCC
tags:fennec, firefox, mozcc, OpenAttribute

Minor update for OpenAttribute

I’ve just pushed a minor update to OpenAttribute to github. It’s minor in terms of user-facing functionality, but improves support for one important use case, licensing of “objects” in a page.

*Summary:* OpenAttribute 0.8.1 (XPI) fixes Issues 1, 2, 3, and 5. All users should install this update.

CC REL is Creative Commons’ recommended way to describe licenses and licensed works. It builds on RDFa, a W3 recommendation, and allows publishers to specify the license and other related information about a work. One of the advantages of building on RDFa was that we could scope the assertions in the page, making it unambiguous (for software) what was being licensed: the page, a particular image or video, or even a specific portion of text. While the initial release of OpenAttribute properly detected the license, it was unable to display the results.

Creative Commons licenses are self-describing using CC REL: a tool (like OpenAttribute) can dereference the license and discover information like the human readable name, version, and permissions/requirements/prohibitions. While Igor’s code from GSoC used the CC API to retrieve this information, it was clear to me that using the license itself is preferable: using self-describing resources on the web allows everyone to play, without registration or integration.

OpenAttribute 0.8 had a somewhat naive implementation of license dereferencing and parsing, which caused problems when there were multiple licensed objects in a page. In the 0.8 release, only information about the last object was displayed in the dialog. OpenAttribute 0.8.1 includes a new licenseloader component, which implements some simple serialization for these requests. If multiple requests are made, they’re queued and dereferenced/processed in order.


You’ll note that OpenAttribute isn’t available from AMO yet. That’s partially because I’d like to have some more testing before making it available there. If you try it out and find bugs or have feature requests, you can file those on the github project.

date:2010-12-31 13:02:03
wordpress_id:1840
layout:post
slug:minor-update-for-openattribute
comments:
category:mozCC
tags:add-on, cc, drumbeat, firefox, mozcc, OpenAttribute

Licenses & Attribution in Firefox: OpenAttribute

Seven years ago I started working on MozCC, an add-on for Firefox that exposed Creative Commons license information embedded in web pages. Little did I know that add-on would be the start of a career with CC, eventually leading me to San Francisco, and subsequently around the globe to talk about CC’s technology. MozCC was dropped from active maintenance somewhere around Firefox 3, but of the tools I built during my first couple years at CC, it’s the one I still get the most questions about.

This summer, Igor Lukanin worked on a Google Summer of Code project for CC to develop a replacement for MozCC, an add-on for Firefox that would expose license and attribution information. While the project wasn’t totally successful, it did produce an add-on that detected CC licenses in pages, and exposed details about them.

Last month I had the opportunity to attend Learning, Freedom, and the Web, the first Mozilla Drumbeat Festival, in Barcelona, Spain. One of the issues identified by attendees was that, while there are plenty of works being licensed under CC licenses, knowing how to properly attribute re-use is still a challenge. How many times have we seen presentations made up of beautiful photos, with a simple “CC licensed, Flickr” under each (if that)? The proposed solution was an attribution generator: a tool that would generate reasonable attribution for CC licensed works, based on information available.

I’ve spent the past month or so hacking on Igor’s code in my spare time, using it as the basis of an attribution generator for Firefox. The result is OpenAttribute (working name, selected by the Drumbeat group), which is available for testing on Firefox 3.6 and above (I’ve been testing with 3.6 and 4.0b8 on Linux). As Dame Shirley Bassey sang, this is “all just a little bit of history repeating.”

|image0|

OpenAttribute is an add-on that displays a small “CC” icon in the URL bar when license information is present. Clicking that icon displays the page’s license information and, importantly, copy and paste HTML you can use to attribute the work. You can click the “More Information” button to display the details on licensed objects in the page.

|image1|

There’s still work to be done, but at this point I think it’s ready for broader testing. You can download the add-on and find the code on github. Feedback, questions, suggestions should all probably go to the attrib-generator Google Group.

date:2010-12-29 16:00:52
wordpress_id:1828
layout:post
slug:licenses-attribution-in-firefox-openattribute
comments:
category:mozCC
tags:add-on, cc, drumbeat, firefox, mozcc, OpenAttribute