Blog-o! Notes from latte.ca

Mon, 07 Jul 2014

People love heatmaps.

They’re a great way to show how much various UI elements are used in relation to each other, and are much easier to read at a glance than a table of click- counts would be. They can also reveal hidden patterns of usage based on the locations of elements, let us know if we’re focusing our efforts on the correct elements, and tell us how effective our communication about new features is. Because they’re so useful, one of the things I am doing in my new role is setting up the framework to provide our UX team with automatically updating heatmaps for both Desktop and Android Firefox.

Unfortunately, we can’t just wave our wands and have a heatmap magically appear. Creating them takes work, and one of the most tedious processes is figuring out where each element starts and stops. Even worse, we need to repeat the process for each platform we’re planning on displaying. This is one of the primary reasons we haven’t run a heatmap study since 2012.

In order to not spend all my time generating the heatmaps, I had to reduce the effort involved in producing these visualizations.

Being a programmer, my first inclination was to write a program to calculate them, and that sort of worked for the first version of the heatmap, but there were some difficulties. To collect locations for all the elements, we had to display all the elements.

Firefox in the process of being customized

Customize mode (as shown above) was an obvious choice since it shows everything you could click on almost by definition, but it led people to think that we weren’t showing which elements were being clicked the most, but instead which elements people customized the most. So that was out.

Next we tried putting everything in the toolbar, or the menu, but those were a little too cluttered even without leaving room for labels, and too wide (or too tall, in the case of the menu).

A shockingly busy toolbar

Similarly, I couldn’t fit everything into the menu panel either. The only solution was to resort to some Photoshop-trickery to fit all the buttons in, but that ended up breaking the script I was using to locate the various elements in the UI.

A surprisingly tall menu panel

Since I couldn’t automatically figure out where everything was, I figured we might as well use a nicely-laid out, partially generated image, and calculate the positions (mostly-)manually.

The current version of the heatmap (Note: This is not the real data.)

I had foreseen the need for different positions for the widgets when the project started, and so I put the widget locations in their own file from the start. This meant that I could update them without changing the code, which made it a little nicer to see what’s changed between versions, but still required me to reload the whole page every time I changed a position or size, which would just have taken way too long. I needed something that could give me much more immediate feedback.

Fortunately, I had recently finished watching a series of videos from Ian Johnson (@enjalot on twitter) where he used a tool he made called Tributary to do some rapid prototyping of data visualization code. It seemed like a good fit for the quick moving around of elements I was trying to do, and so I copied a bunch of the code and data in, and got to work moving things around.

I did encounter a few problems: Tributary wasn’t functional in Firefox Nightly (but I could use Chrome as a workaround) and occasionally sometimes trying to move the cursor would change the value slider instead. Even with these glitches it only took me an hour or two to get from set-up to having all the numbers for the final result! And the best part is that since it's all open source, you can take a look at the final result, or fork it yourself!

[Posted at 11:53 by Blake Winton] link
Sat, 12 Oct 2013

I’ve recently been playing a lot of Fez, a 2-D (kinda) platforming/puzzle video game. Many of the puzzles use a series of symbols in squares as a code language. I really liked the way the language looked, and so I decided to write a small single page app in Angular to transliterate English into the Fezish alphabet. The first implementation was written as a filter, and it seemed to work okay, but emitting a bunch of HTML and then forcing the user of the filter to use a sanitizer to get it to render as HTML was kinda strange. That very same day, in an odd twist of fate, I got some email from Packt Publishing asking if I would be interested in featuring their new Angular JS book on my blog. Long story short, I agreed to post a review of it here in exchange for a free copy of the eBook. So on to the review…

The first thing that struck me about Angular JS Directives was the writing. I’ve read a lot of extremely dry technical books which were hard to get through, and I’m happy to say that this is not one of them. I found the writing both engaging and amusing. There are a few times where the author even pokes fun at himself for repeating the same points, which was wonderful to see. The examples were clear to read, and ably demonstrated the points that the accompanying text was making. The overall flow of the book mostly made sense, with simpler concepts leading to more complicated concepts. My only suggestion is that the chapter on Testing could have been introduced sooner, and then used in the rest of the examples to prove things were working the way that the author claimed.

I don’t like to only say positive things about something I’m reviewing, both because I believe that there’s always something that could be done better, and because I don’t want to look like a corporate shill. At least not for $17. ;) So, on to the bad things I’ve run into. It took me a lot longer to read than I would have hoped. This was partially because of a bunch of work stuff taking up all my spare time, but also because after every few pages I wanted to go back and re-write large parts of the projects I’ve done. :) My other concern is that $17 for 87 pages of content might not not be worth it to you. I found the content very useful, and I’ve certainly gotten $17 worth of knowledge out of it, but at my previous job, where I didn’t use any JavaScript much less Angular, it wouldn’t have been money well spent.

Having said all that, after the fourth chapter, I re-wrote the Fezish Filter as a Directive, and the code became far cleaner. And now that I’m done reading the ninth chapter, I think I might spend the rest of this weekend adding some unit and end-to-end tests. So in the end, would I recommend this book? Yes. Yes I would.

(Monday October 14th edit: I’ve also just been informed that Packt is running a Columbus Day sale, and if you use the discount code "COL50" in the next four days, you’ll get 50% off this, and any other eBook or video, so if you’re thinking of buying it, today would be a great day to do so!)

[Posted at 17:07 by Blake Winton] link
Fri, 28 Jun 2013

In my previous blog post, I mentioned a tool I’m writing to make it easy for designers to link mockups to live bugs. But I didn’t mention that I had a reasonably-working version of the tool written in Backbone which I’ve decided to port to Angular. The reasons why are largely beside the point of this blog post, but I’ll try to sum them up by saying that I reached a point where Backbone seemed to be confusing me more than helping me, and Angular got a lot of good press at FluentConf this year.

So this morning’s task in the re-write was to re-hook up the Persona integration. I had read recently that when you had a lot of dom-manipulation functions, you should probably put that code in a directive, and since I hadn’t written an Angular directive yet, I figured this would be a great time to learn how. Writing the html was pretty easy, of course, and most of the code from the existing implementation (which was largely based on the code from the express-persona readme) could be ported over fairly quickly. The only tricky part I ran into was figuring out that I needed to include restrict: 'E' in the Directive Definition Object. After I was done, I noticed that there really wasn’t that much in the code that had anything to do with the tool I’m writing, and thus I pulled it out into a separate repo so that other people can use it.

And with that, I announce Angular-Tools, a repo containing one or more tools which you might find useful if you build Angular apps. As always, pull requests and bug reports welcome!

[Posted at 15:16 by Blake Winton] link
Fri, 14 Jun 2013

One of the things I’m working on as part of my job1 at Mozilla is a tool to make it easy for designers to create mockups that are linked to live bugs, similar to the ones at Are We Pretty Yet. Now, I’ve got the background showing up, and the bugs overlayed on top of it, but as it stands, I’m requiring the designers to draw the lines connecting the bugs to the various areas in the mockup right on the mockup itself! This is obviously a fairly terrible idea, since it makes it much harder than it should to move stuff around after the fact, and requires a ton of up-front planning when creating the initial image. But what are my other options?

I thought for a while about layering a canvas element over the mockup; it would let me draw whatever shapes I wanted to, but passing the click events through to the mockup seemed like it would be fairly annoying, and I don’t think the connecting lines should appear in front of the boxes showing the bug details, which adds another wrinkle. Then, over lunch, I started to wonder what it would look like if a 1px by 1px black square got stretched and rotated with CSS… So I took some time after lunch, and played around a little, and it seems like it just might work! Give it a try, let me know if you have any ideas to make it better, and feel free to take the idea anywhere you think it might be useful!

Update: In the comments, Andrew points out that I could use a 1px by 1px span instead, which would make it much easier to change the colour of the line, so I’ve linked to his jsfiddle instead. :)


  1. Sometimes I still can’t believe how lucky I am to get to do this stuff all day, and get paid for it!  

[Posted at 14:57 by Blake Winton] link
Sun, 25 Mar 2012

I think what I want is pretty simple, or at least, reasonably common. I’m just looking for a couple of programs.

An SMTP server which will accept mail for the accounts at latte.ca, and deliver it to a Maildir of my choosing, and let me send mail through it if, and only if, I’ve logged in with the password to that account. (Being able to define a few aliases would also be nice.)

And an IMAP server which will expose the previously-mentioned Maildir, after I’ve logged in with the password to that account.

And yet, every time I try to set that up, something completely falls over for no particularly understandable reason, and I end up wasting an afternoon (or more) of my life. I had hoped this time would be different, since I decided not to install and configure everything myself, but instead bought a copy of OS X Lion Server which was supposed to do all the hard work for me. I’m not going to enumerate all the problems I ran into, but I will say that I still haven’t managed to get there. I’m just done for tonight.

Anyways, if anyone reading this has a working setup that meets the requirements (and the added requirement of needing to use Dovecot and Postfix, since those are what’s installed), I would love to get a copy of their config files. And in the meantime, I might seriously look into getting a refund for Lion Server, given how badly it’s failed me. :P

[Posted at 21:52 by Blake Winton] link
Tue, 06 Mar 2012

A few people recently asked me about building Thunderbird on the latest version of Mac OS X. Since I have it working, and to give myself a place to point to the next time they ask, I figured it would be a good idea to blog about it.

So, here’s my .mozconfig.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Debug .mozconfig
mk_add_options MOZ_MAKE_FLAGS=-j4
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/../objdir-`basename \`pwd\``-`hg branch`
# mk_add_options AUTOCONF=autoconf213
ac_add_options --enable-application=mail
ac_add_options --enable-extensions=default,inspector
ac_add_options --enable-inspector-apis

# Compilation options
ac_add_options --disable-optimize
ac_add_options --enable-debug
ac_add_options --enable-tests
ac_add_options --disable-jemalloc
#ac_add_options --enable-trace-malloc
ac_add_options --enable-chrome-format=symlink

ac_add_options --with-macos-sdk=/Developer/SDKs/MacOSX10.7.sdk
ac_add_options --enable-macos-target=10.7

# For NSS symbols
export MOZ_DEBUG_SYMBOLS=1
#ac_add_options --enable-debug-symbols="-gdwarf-2"

#Use ccache
#ac_add_options --with-ccache=/usr/local/bin/ccache

# We don't have GCC anymore, since XCode 4.2, so use clang instead.
CC=clang
CXX=clang++

There are probably a bunch of things I don’t really need in there, so if anyone wants to take it, and cut it down to the minimal set, I would definitely appreciate it. But in the meantime, this works for me, and will probably work for you, too.

[Posted at 10:34 by Blake Winton] link
Thu, 08 Dec 2011

Much of the new work I’m doing these days is being stored in git repositories. Now, I’m not the biggest fan of git, particularly its UI, but the advantages of GitHub and GitX are hard to ignore. Despite that, I still really missed being able to type hg out to see which patches I would be pushing, so, after a short chat with (and demo from) Ben, I came up with the following:

Somewhere in your path, add a file named git-outgoing which contains the following contents:

# !/bin/sh
# Uh, there shouldn’t be a space between the # and ! in the previous
# line, but the highlighter I’m using seems to require it…
git push --dry-run $1 2>&1 | awk '/^ / {print $1}' | xargs git log

(Make sure it’s executable by whomever needs to use it!)

Then, in your git config, add the following section:

[alias]
    out = outgoing

And finally, you should be able to type git out, and see something like:

commit 7d4c9b89a4663a07bed030669bae2d3c73ec78dc
Author: Blake Winton <bwinton@latte.ca>
Date:   Thu Dec 8 12:22:41 2011 -0500

    Blear 2

commit a4e8c6627bc26d7371fb2614a1c47aaf694957bd
Author: Blake Winton <bwinton@latte.ca>
Date:   Thu Dec 8 12:18:04 2011 -0500

    Bleah.

So, hopefully some of the rest of you will find this helpful, too, and if you know of a better way to do this, please let me know in the comments!

[Posted at 13:04 by Blake Winton] link
Tue, 27 Sep 2011

On a previous post in a different blog, some commenters were asking us if we were considering doing things that we have planned to do for a while now, and that led me to realize that I haven’t been communicating the future of Thunderbird’s UI nearly well enough. I mainly blame it on my trying to do too many other things, and thus failing to cover all the bases. So, having said all that, here is the list of things, in no particular order, that I would like to see worked on in the next few versions of Thunderbird. But first, I’ld like to say a little bit about why I want them.

I recently heard about someone who said “Thunderbird looks like iTunes”, and while that’s rather complimentary given the amount of time Apple puts into making things look good, it doesn’t really lead me to believe that people can pick our product out of a screenshot. And so one of the overall goals is to make Thunderbird iconic. You can always tell when a screenshot is of Apple mail, based on the layout and the lack of colour, and Firefox is similarly immediately recognizable because of the big circular back button and smaller rectangular forward button. Similarly, I’m hoping to have Thunderbird look different to other apps, while still fitting in on the platform, and maintaining a little consistency with Firefox. Of course, that’s not the only goal, nor even the main goal. My main idea for Thunderbird is to let you focus on the content that’s important to you, and not be distracted by things you don’t care about. Hopefully most of the changes I talk about here will help that, and as a side benefit also help to give us a more unique style.

  • A simple thing that will make the product nicer to use is just to line things up. We’re all over the place, and it should be fairly simple to make this better. There are a couple of bugs that are related to this, and I suspect we could file a few more for various other parts.

  • We want to put the tabs on top, because they let us put the compose and address book into tabs, while still having the appropriate toolbars. (As well, having everything be a tab makes the application more consistent, as described in the next point.)

  • This leads into removing the standalone Compose and Address Book windows. You’ll still be able to open a window for those functions, but it will just be a regular window with a Compose or Address Book tab. (No bugs for this yet. Removals are sensitive things, and we want to get the replacement UI working well before we remove the existing UI.)

  • We really want the Thunderbird button, so that we can hide the menus, and have less Glass on Windows, and make the most common actions easier to find and use.

  • But, to add that button, we first need to see what the most common menu items people use are, therefore we need Test Pilot.

  • We would like to add a HomeTab, to give people a personalized place to land when they start Thunderbird, or open a new window.

  • We would like to merge the Gloda bar and Quick Filter bar, cause duh.

  • Having two different settings locations is too confusing for me, let alone people who don’t care about the details of the product. We want to merge those into a single searchable place for all the settings, a la Mac System Prefs.

  • This next change is more a small, personal thing, rather than part of a grand plan. It was originally suggested by Mike Beltzner, and while I’ve had some time to work on it, I haven’t had enough to push it through to completion. Basically, I’ld like to be able to order my email by date, while grouping it by subject. (This is different than threading, because I don’t care about which replies are to which messages. I just want a single group for the subject, with the messages ordered by date within that group, and the groups ordered by the date of the most recent message.) There’s no bug for this yet, but as mentioned, I started to write an extension, before hitting some annoying bugs that made it hard.

  • Compactify the header. It’s really too big. Well, that’s a bit of a lie. What I really mean here is that we should move the buttons and their toolbar out of the header, to float just above it. This would allow people to easily turn them off (by removing the entire toolbar), and for those of us who like to keep them, it would make them more visually distinct. As an added bonus, in vertical mode, we could merge that toolbar with the other toolbars, to get something like the pictures of what Thunderbird could look like posted by Asa Dotzler.

  • And finally, I think we should remove the Migration Assistant. It was very useful in the 2.0⇒3.0 transition, but it’s been less and less useful as time goes on, and as people have moved more and more onto Thunderbird 3, and 4, and 5… (No bug for this one either, again, because removals are sensitive things.)

See all the bugs in one big list.

Many thank-yous to Alex Faaborg, and areweprettyyet for the code to link the bugs, and the basis of the styling to make them stand out.

[Posted at 11:02 by Blake Winton] link
Thu, 08 Sep 2011

Add-ons are an important part of many Mozilla products, and many people have noticed that they’ve taken a hit as we’ve switched to the Rapid Release process. To help users have a little more control over how well their Firefox works, I would like to propose the following slight modification to the automatic Update process:

It all starts when Firefox (and Thunderbird) notice an update is available.

We immediately check the user’s add-ons to see if they are compatible, or if there are compatible versions we haven’t downloaded yet.

If all the add-ons are compatible (or will be made so at the next download), we show the NoAddons dialog:

NoAddons dialog

It‘s the same as the current Firefox or Thunderbird update dialog, and as you would expect, the “Ask Later” and “Update Firefox” buttons do the same things that they do now.

On the other hand, if there are in-compatible add-ons, we show the Addons dialog:

Addons dialog

As you can see, we let the user know which add-ons are incompatible, and give the user an extra button at the bottom to do something different.

The new “Update when my add-ons work” button (wording to be clarified later) will check the add-ons periodically, and automatically update Firefox when all the add-ons are compatible. If the add-ons aren’t compatible after a week (period of time to be configurable), the user will be shown this dialog again, with the (hopefully smaller) list of incompatible add-ons.

Showing the user which add-ons are incompatible will let them decide whether the add-ons are important enough to not upgrade, or whether they can live with the (hopefully short) period of reduced functionality.

As always, comments welcome, but keep them polite or they’ll be deleted.

[Posted at 14:49 by Blake Winton] link
Wed, 15 Jun 2011

A friend of mine recently said:

EVERY behavior aspect of EVERY application should be user-settable if the user is prepared to drill down far enough. No exceptions. Even if the user will be shooting his own foot by messing with it.

I, obviously, disagree with him, and wanted to explain why in a few more characters than Twitter would allow.

While giving the user complete control over every aspect of an application seems like a good idea, there are two slightly-hidden downsides to it.

First, every choice you give the user doubles the amount of testing you have to do. (Okay, it doesn’t exactly double it, but it certainly adds a testing, maintenance, and support burden.) Is it a responsible use of your time to implement these options if less than 1% of your users will ever change them (and risk shooting their own feet), or would it be better for everyone to implement a feature that more people would use?

Second, Emacs notwithstanding, you’ll never get to a great text editor by customizing a mail reader. The whole Unix (and iOS, oddly) philosophy is to write each app to do one thing, and do it well. Not to do a whole bunch of optional things. And if you’re doing only one thing, presenting an option to the user to do it or not doesn’t make a lot of sense.

And finally, because I can’t count, if you offer people too much choice, it imposes a cognitive burden on them which can lead to their making no choices at all, or at least not making them any happier than when they had fewer choices.

To bring this back to the product I’m working on, we are going out of our way to make Thunderbird more usable and part of that is simplifying it by offering fewer, more meaningful choices.

[Posted at 10:13 by Blake Winton] link
Wed, 01 Jun 2011

One of the big questions I had when I started writing patches was who I should ask to review them. Now that I’ve been in the community for a while, I’ve got a much better sense of who I should be talking to for the type of things I’m likely to write, but there are still times when I want to make a change in a part of the code that I haven’t touched before, and I’m not sure who to ask. In those cases, I usually fall back to a fairly simple (if non-obvious) set of steps to try and figure out who to pick.

  1. Get the list of files I’ve changed.
  2. Get the hg log for those files.
  3. Check through the log for “r=”, and “sr=”.

Of course, that’s a fairly easy set of steps to automate, and so I present my first cut at the automated reviewer chooser!

Of course, there are a lot of things I’ld like to do with this, such as:

  • Improving the documentation.
  • Checking to see how well this script would have done on previous commits.
  • Taking into account the length of the queues for the reviewers.
  • Adding some sort of recent-ness calculations.

But I think that this tool is useful enough in its current state that releasing it and getting feedback on what to actually work on would be a win.

To use it, be in a mercurial source repo, and type getReviewer.py to get a list of suggested reviewers for the current differences, or getReviewer.py temp.diff or getReviewer.py https://bugzilla.mozilla.org/attachment.cgi\?id\=536017 to specify a different set of changes.

[Posted at 20:13 by Blake Winton] link
Thu, 31 Mar 2011
New GetAnAccount UI.

Since we released the GetAnAccount addon, we’ve had a lot of feedback. Many of the people who commented were looking for the option of getting an ad-supported account instead of paying for email access. We were always planning on integrating ad-supported services, as soon as we could, but of course, doing this required a redesign.

One important note before we get to the good stuff: I’ve used GMail soley as an example of a well-known ad-supported email provider here. We may or may not be partnering with them, and you should not take these screenshots as proof of our intentions one way or another.

As you can see from this first mockup, the initial view makes it much more obvious that you don’t need to create a new account just to use Thunderbird.

Initial View

If you click in the bottom half, it expands up to make it more obvious that that’s what you want to do, and to allow us to display more information (although we don’t have any extra information to display there yet.

Existing Address

On the other hand, if you click on the top, we do have more information that you probably want to see before continuing on.

New Address

And this is something like what we hope to show you when the results have been returned. (Note: the Terms of Service, Existing Account, and Do It Later buttons are still there, but have been scrolled off the bottom of the dialog in this mockup.)

Search Results

And finally, once you pick one of the providers, we expand that list to show you all of the results for that provider.

Provider Chosen

Feedback, as always, is welcome, either here or in the forum.

[Posted at 21:41 by Blake Winton] link
Fri, 25 Mar 2011

A co-worker of mine recently mentioned that he had a problem where he all-too-often accidentally quit his applications by hitting ⌘-q (command-q). Since he has been having problems with Thunderbird that I can’t fix, I thought I might do a little digging and see if I could come up with some way of helping him. And so here’s what I found:

In the System Preferences application, there’s a “Keyboard” section.

The Keyboard Preference Pane

One of the things you can choose in that section is “Keyboard Shortcuts”.

The Keyboard Shortcuts

Pick a relatively innocuous function, like turning Zoom on and off.

(Note: DO NOT choose Front Row for this!)

The Access Shortcuts

And assign that function to ⌘-q.

The New Shortcut

Now, whenever you hit ⌘-q, it will do whatever you selected, instead of quitting the application. Ta-da!

[Posted at 17:48 by Blake Winton] link
Fri, 25 Feb 2011

Over the past week, I’ve been working on fixing some of the reported bugs in the OpenSearch add-on for Thunderbird, and now I think I’ve fixed enough of them to release a new version.

You can find the full details on the Mozilla Labs blog, or you could just jump straight to the OpenSearch add-on page to install it. And please leave your feedback about the add-on on our Google group!

[Posted at 11:25 by Blake Winton] link
Fri, 24 Dec 2010

I was reading Making Software by Andy Oram and Greg Wilson, and got to the chapter about An Automated Fault Prediction System. It’s a pretty neat chapter, and it got me wondering which files in the Thunderbird code base had the most bugs. Now, I don’t have all the info I need, but I figured an easy first pass would be to go through the commit logs, and for each commit that started with “bug ”, add one to the files changed in that commit. Hmm, that sounded unintuitive. Let me just paste (and link) the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from mercurial import ui, hg
import operator
import re

ext = re.compile("(\.c(pp)?|\.js|\.xml)$")

repo = hg.repository(ui.ui(), ".")
changes = [repo[i] for i in repo
                   if repo[i].description().lower().startswith("bug ")]

master = {}

for change in changes:
  files = [f for f in change.files() if ext.search(f)]
  for f in files:
    master[f] = master.get(f, 0) + 1

files = master.items()
files.sort()
counts = master.items()
counts.sort(key=operator.itemgetter(1))
counts.reverse()
print "\n".join([c[0] + ":" + str(c[1]) for c in counts[:10]])

And so, without further ado, here are the files that have been changed the most in bug fixes, and the number of times they've been changed:

  • mail/base/content/mailWindowOverlay.js:109
  • suite/browser/browser-prefs.js:73
  • suite/browser/navigator.js:70
  • mail/base/content/msgMail3PaneWindow.js:69
  • mail/app/profile/all-thunderbird.js:67
  • suite/common/src/nsSessionStore.js:66
  • mail/components/compose/content/MsgComposeCommands.js:60
  • mailnews/imap/src/nsImapMailFolder.cpp:56
  • suite/browser/tabbrowser.xml:53
  • mail/base/content/msgHdrViewOverlay.js:52

As a side note, for the mozilla repo it looks like this:

  • js/src/jstracer.cpp:780
  • browser/base/content/browser.js:654
  • layout/base/nsCSSFrameConstructor.cpp:410
  • layout/base/nsPresShell.cpp:400
  • js/src/jsobj.cpp:399
  • browser/base/content/tabbrowser.xml:397
  • widget/src/windows/nsWindow.cpp:390
  • toolkit/components/places/src/nsNavHistory.cpp:374
  • js/src/jsinterp.cpp:345
  • js/src/jsapi.cpp:343
[Posted at 14:59 by Blake Winton] link
Sat, 04 Dec 2010

I’ve created a couple of checklists, and would like to hear any feedback on them. They are a Review Checklist, and a Commit Checklist.

They came about after I had been working mostly on experimental add-ons for a while, and then attempted to push a couple of reviewed fixes. Since I was out of practice, I managed to get something minor wrong on both of the pushes. (The first one failed to attribute the patch to the proper author; The second one failed to mention the bug number in the commit message.) Since I’m a bit of a perfectionist, this really annoyed me, and so I vowed to write up the steps that I go through when I need to commit and push a patch, so that I could refer to them later, since if checklists can save lives, then I figure they can probably also help me do my job better. But before I go to that, I needed to review a patch, so I wrote up some of the things I look for when I review a patch too.

[Posted at 19:49 by Blake Winton] link
Tue, 30 Nov 2010

I was recently modifying an add-on for the upcoming Thunderbird 3.3, and part of what I wanted to do was to run some javascript in a chrome context that added some DOM nodes to a document in a content context. But when I ran the following code:

1
2
3
4
5
6
7
8
9
let browser = document.getElementById('tabmail').getBrowserForSelectedTab();
let doc = browser.contentDocument;
dump("\n\n\n\nXXXXXXXXXX\n");
dump("DOM Content loaded for " + doc.location + "\n");
var topBar = document.createElement("div");
topBar.innerHTML = "We got it!!!!!";
dump("iB = "+doc.body.insertBefore+"\n");
dump("fC = "+doc.body.firstChild+"\n");
doc.body.insertBefore(topBar, doc.body.firstChild);

I got the following error:

WARNING: NS_ENSURE_SUCCESS(rv, rv) failed with result 0x80530009: file /Volumes/Devel/thunderbird/src-central/mozilla/content/base/src/nsNodeUtils.h, line 304
WARNING: NS_ENSURE_SUCCESS(rv, rv) failed with result 0x80530009: file /Volumes/Devel/thunderbird/src-central/mozilla/content/base/src/nsGenericElement.cpp, line 4077
-- Exception object --
[snip…]
+ message (string) 'Operation is not supported'
+ result (number) 2152923145
+ name (string) 'NS_ERROR_DOM_NOT_SUPPORTED_ERR'

Poking around a little, it seemed like I had reasonable things for the insertBefore method, the firstChild attribute, and the topBar variable, and so since it was late, and I couldn't see what I had done wrong, I went to bed.

That turned out to be a the best thing for me to do, because this morning Jonathan Protzenko came to the rescue, saying (in response to a similar problem with a Firefox 4.0 beta 7 extension):

If you're modifying some content DOM from chrome code, you need to make sure the child you're appending was created using the unprivileged document, not the global document.

// This is chrome code, this is wrong because the span is now chrome
// and you're trying to insert it into content
myContentNode.appendChild(document.createElement("span"))

// This is right, appending a content node to another content node
myContentNode.appendChild(myContentNode.ownerDocument.createElement("span"))

I've hit this issue at least three times when upgrading stuff for Gecko 2.0. Might be what you're looking for .

And sure enough, when I changed var topBar = document.createElement("div"); to var topBar = doc.createElement("div"); , it all started working beautifully.

Thank you, Jonathan!

[Posted at 10:58 by Blake Winton] link
Wed, 25 Aug 2010
More secure!

As someone who works on an email client, I’m interested in making my communications more secure. So, with the assistance of Ludovic and Gozer, I got a client certificate that would allow me to sign and encrypt my messages. (Check out the envelope and lock in the image below.)

An outgoing message, with an envelope and a
lock

Most of the time, I’ll probably just sign my messages – after all, that’s what I’ve set it up to do by default – but it’s nice to know that if there’s something I need to encrypt, that option is now available to me.

[Posted at 17:34 by Blake Winton] link
Mon, 19 Jul 2010

A co-worker of mine was having problems remembering where the makefile puts the binary for Thunderbird when you build it yourself. Now, I type in the path far too often, so I know where it is (on my computer, anyways), but since I type it in far too often, I grabbed someone's zsh function that launched Firefox, and modified it to launch Thunderbird from either the build directory or the source directory, but only on Mac OS X.

Anyways, here it is, I hope some of you find it useful.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
thunderbird() {
  local -a currdir;
  currdir=$PWD:t;
  for nm in LanikaiDebug ShredderDebug Lanikai Shredder; do
    if [ -d "./mozilla/dist/$nm.app" ]; then
      ./mozilla/dist/$nm.app/Contents/MacOS/thunderbird-bin $*
      break;
    elif [ -d "../objdir-$currdir/mozilla/dist/$nm.app" ]; then
      ../objdir-$currdir/mozilla/dist/$nm.app/Contents/MacOS/thunderbird-bin $*
      break;
    fi
  done
}
[Posted at 10:20 by Blake Winton] link
Fri, 16 Apr 2010

I’ve been reviewing a patch from Andreas and Standard8 which adds lightweight theme support (aka personas) to Thunderbird. It’s so cool that I couldn’t resist taking a screenshot, and posting it for you all to see!

Pretty new persona

It looks like there’s a good chance the code will make it in to Thunderbird 3.1 beta 2, so with any luck, soon your Thunderbird will be a pretty as mine.

[Posted at 09:55 by Blake Winton] link