{"id":1930,"date":"2011-01-17T23:15:02","date_gmt":"2011-01-18T04:15:02","guid":{"rendered":"http:\/\/mikeconley.ca\/blog\/?p=1930"},"modified":"2023-12-20T16:25:15","modified_gmt":"2023-12-20T21:25:15","slug":"day-1-at-mozilla-messaging-getting-my-hands-dirty","status":"publish","type":"post","link":"https:\/\/mikeconley.ca\/blog\/2011\/01\/17\/day-1-at-mozilla-messaging-getting-my-hands-dirty\/","title":{"rendered":"Day 1 at Mozilla Messaging:  Getting my hands dirty&#8230;"},"content":{"rendered":"<p>So today was my first day working for Mozilla Messaging.<\/p>\n<p>And it was <strong>awesome<\/strong>.<\/p>\n<p>Now, I know that <a href=\"http:\/\/mikeconley.ca\/blog\/2011\/01\/11\/starting-work-on-mozilla-thunderbird\/\">I had originally told you that I&#8217;d be working on Thunderbird + Unity integration<\/a>.\u00a0 That&#8217;s still on my TODO list, but today, I put some contributions in with the Firefox team for <a href=\"http:\/\/en.wikipedia.org\/wiki\/Firefox_4\">the upcoming Firefox 4 release<\/a>.\u00a0 There are still a few bugs that need to be squashed before Firefox 4 is ready for the prime-time, and we&#8217;re all psyched to see it happen, so I lent a hand.<\/p>\n<p><a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=624808 \">This was the bug I decided to tackle today.<\/a> Basically, in the new add-ons manager, add-ons are listed alphabetically, regardless of their state (and by state, I mean enabled, disabled, incompatible, blocked, etc).\u00a0 This leads to kind of a strip-ey look for large numbers of add-ons.<\/p>\n<p>What we&#8217;d like instead is to have the add-ons grouped by state, and then sorted alphabetically within that state.\u00a0 Here&#8217;s a mock-up by bug-reporter (and Firefox UX team member) Jennifer Boriss:<\/p>\n<p><a href=\"http:\/\/mikeconley.ca\/blog\/wp-content\/uploads\/2011\/01\/addons_inlist_accordingtostatus.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Add-ons in list, grouped by status\" src=\"http:\/\/mikeconley.ca\/blog\/wp-content\/uploads\/2011\/01\/addons_inlist_accordingtostatus-237x300.png\" alt=\"Add-ons in list, grouped by status\" width=\"308\" height=\"389\" \/><\/a><\/p>\n<p>I got to work around 8:45AM this morning.\u00a0 Around 10:13AM, I had finished most of my introductions, had my tour, had my accounts set up, found my desk, and started work.<\/p>\n<p>The first thing I did was locate where exactly the code was for listing the add-ons.\u00a0 <a href=\"http:\/\/weblog.latte.ca\/blake\/ \">Blake<\/a> pointed out <a href=\"http:\/\/mxr.mozilla.org\/\">a particularly useful resource called MXR (Mozilla Cross Reference)<\/a>, which lets me search through the source code very quickly.\u00a0 I had originally been using <a href=\"http:\/\/en.wikipedia.org\/wiki\/Grep\">grep<\/a>, but this was way better.<\/p>\n<p>My approach to finding the code:\u00a0 I find a string in the interface that seems unique to the area I&#8217;m working in (in this case, it was &#8220;Search all add-ons&#8221;, which is found in the search text input of the add-ons manager).\u00a0 I did a search for that string, and it returned the file \ufeff\ufeffmozilla-central\/toolkit\/locales\/en-US\/chrome\/mozapps\/extensions\/extensions.dtd.<\/p>\n<p>But this only takes us half-way.\u00a0 Since Firefox is translated, the strings are stored separately from where they&#8217;re used.\u00a0 In extensions.dtd, the string I searched for is given the key &#8220;search.placeholder&#8221;.<\/p>\n<p>Searching for &#8220;search.placeholder&#8221; with MXR gives me paydirt:\u00a0 mozilla-central\/toolkit\/mozapps\/extensions\/content\/ holds the files extensions.css, extensions.js, extensions.xul and extensions.xml.<\/p>\n<p>So I tool around in extensions.js a bit, reading <a href=\"https:\/\/developer.mozilla.org\/En\/Developer_Guide\">the developer documentation<\/a>, and getting to know the code.\u00a0 The code contains quite a few classes, including something called gViewController.\u00a0 Digging deeper into it, it looks like gViewController controls (brings up, shuts down) the various &#8220;views&#8221; available in the add-ons manager.\u00a0 Cool &#8211; so now I just need to find the view that lists the user&#8217;s add-ons.<\/p>\n<p>Ah hah!\u00a0 Found it:\u00a0 gListView.\u00a0 gListView grabs all of the installed (or to-be-installed) add-ons, and populates the interface.\u00a0 So this is where the sorting needs to happen.\u00a0 I tested to make sure I was in the right place in the code <a href=\"https:\/\/developer.mozilla.org\/en\/Debugging_JavaScript\">by using dump calls to a terminal<\/a>.\u00a0 Bonus:\u00a0 edits in this portion of the code do not require a full browser restart &#8211; instead, I just close and reopen the add-ons manager to see my changes.\u00a0 Nice!<\/p>\n<p>Initially, my idea was to have 4 &#8220;buckets&#8221;, one for each of the 4 states (&#8220;enabled&#8221;, &#8220;incompatible&#8221;, &#8220;disabled&#8221;, &#8220;blocked&#8221;).\u00a0 I&#8217;d divide up the add-ons into those 4 buckets, and then sort each bucket, and then join the 4 buckets for the final result.<\/p>\n<p>Blake came up with a better solution: the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Schwartzian_transform\">Schwartzian Transform<\/a> (straight out of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Space_Balls\">Space Balls<\/a>, I know).\u00a0 The idea is that, instead of having separate buckets like before, we just go through the entire collection of add-ons, and &#8220;label&#8221; them based on what bucket they belong to.\u00a0 Then we sort the entire collection, giving the bucket-label a high-order sorting priority.\u00a0 It sounds complicated, but it actually wasn&#8217;t that difficult to code.\u00a0 It&#8217;s a tiny piece of code, its readable, and quite elegant.\u00a0 So kudos to Blake for that solution.<\/p>\n<p>Anyhow, I wrote my patch.\u00a0 I just figured out how to run the interface tests for Firefox (they use something called <a href=\"https:\/\/developer.mozilla.org\/en\/Mochitest\">Mochitest<\/a>).\u00a0 I set those tests off on one of the fast machines in the office, packed up my gear, and headed home.<\/p>\n<p>It was a solid days work.\u00a0 Tomorrow, I hope to write some new tests for the Schwartzian transform, and submit my patch to Bugzilla.\u00a0 Woop!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So today was my first day working for Mozilla Messaging. And it was awesome. Now, I know that I had originally told you that I&#8217;d be working on Thunderbird + Unity integration.\u00a0 That&#8217;s still on my TODO list, but today, I put some contributions in with the Firefox team for the upcoming Firefox 4 release.\u00a0 [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[874,861],"tags":[878,881,125,875,35,877,876,880,879,867],"class_list":["post-1930","post","type-post","status-publish","format-standard","hentry","category-firefox-mozilla-2","category-mozilla-2","tag-add-ons","tag-blake-winton","tag-firefox","tag-first-day","tag-mozilla","tag-mozilla-messaging","tag-newbie","tag-schwartzian-transform","tag-sorting","tag-thunderbird-2"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/prmTy-v8","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/1930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/comments?post=1930"}],"version-history":[{"count":11,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/1930\/revisions"}],"predecessor-version":[{"id":3147,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/1930\/revisions\/3147"}],"wp:attachment":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/media?parent=1930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/categories?post=1930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/tags?post=1930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}