<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>visophyte: shiny? shiny. &#187; Mozilla</title>
	<atom:link href="http://www.visophyte.org/blog/category/mozilla/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.visophyte.org/blog</link>
	<description>Andrew Sutherland writes things but (almost) always includes pictures to look at.</description>
	<lastBuildDate>Thu, 29 Sep 2011 02:22:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>The joy of integrated logging and log viewing with fancy logs</title>
		<link>http://www.visophyte.org/blog/2011/09/28/the-joy-of-integrated-logging-and-log-viewing-with-fancy-logs/</link>
		<comments>http://www.visophyte.org/blog/2011/09/28/the-joy-of-integrated-logging-and-log-viewing-with-fancy-logs/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 02:16:31 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Program Execution]]></category>
		<category><![CDATA[arbpl]]></category>
		<category><![CDATA[deuxdrop]]></category>
		<category><![CDATA[loggest]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=809</guid>
		<description><![CDATA[The deuxdrop messaging experiment&#8216;s current incarnation exists as an (under development) Jetpack that runs in Firefox.  I am still trying to shake out functionality to be driven by the UI rather than headless unit tests.  While firebug has been a great help, another boon has been the logging framework and log viewing framework developed for [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-810" title="about-loggest-collapsed-view" src="http://www.visophyte.org/blog/wp-content/uploads/2011/09/about-loggest-collapsed-view.png" alt="" width="142" height="101" /></p>
<p>The <a href="https://github.com/mozilla/deuxdrop">deuxdrop messaging experiment</a>&#8216;s current incarnation exists as an (under development) Jetpack that runs in Firefox.  I am still trying to shake out functionality to be driven by the UI rather than headless unit tests.  While <a href="http://www.visophyte.org/blog/2011/07/12/new-adventures-in-rich-execution-logs-for-debugging-and-program-understanding/">firebug</a> has been a great help, another boon has been the logging framework and log viewing framework developed for the unit tests.  (Previous posts <a href="http://www.visophyte.org/blog/2011/07/12/new-adventures-in-rich-execution-logs-for-debugging-and-program-understanding/">here</a> and <a href="http://www.visophyte.org/blog/2011/07/20/overview-ownershipcommunication-graphs-for-rich-execution-logs/">here</a>).  Since the log is made up of structured JSON data, all the log processing logic is written in JS, and the log viewing UI is HTML/CSS/JS, it is trivial to embed the log viewer into the Jetpack itself.</p>
<p>If you type <strong>about:loggest</strong> in the URL bar (or better yet, create a bookmark on the bookmark bar and click that), the log viewer is displayed.  Deuxdrop&#8217;s client daemon logic (which runs in a hidden frame), uses a log reaper that runs at 1-second intervals.  If anything happens log-wise during that second, it is packaged and added to a circular-buffer style list of the last 60 seconds where anything happened.  When the log viewer starts up, it asks for and receives the data.  The result looks like the above small screenshot.  If no errors were logged during the time interval, it is automatically collapsed.</p>
<p>Let us experience the joy of integrated logging by looking at a real problem I recently encountered.  In the development UI (accessible via about:dddev), I brought up a list of my contacts after starting a conversation.  It looks like this right now:</p>
<p><img class="alignnone size-full wp-image-811" title="peeps-tab-user-erroneously-included" src="http://www.visophyte.org/blog/wp-content/uploads/2011/09/peeps-tab-user-erroneously-included.png" alt="" width="505" height="91" /></p>
<p>The problem is that I, the user, am &#8220;Andrew Sutherland&#8221; and should not be in my own contact list.  Also, the display should not be claiming there are an undefined number of unread messages from me, but that is likely fallout from the system intentionally not maintaining such information about me, the user.</p>
<p>I want to quickly figure out why this is happening, so I bring up about:loggest and open the most recent time entry to see what happened when this query was issued and filled:</p>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/09/loggest-query-peeps-by-any.png"><img class="alignnone size-thumbnail wp-image-814" title="loggest-query-peeps-by-any" src="http://www.visophyte.org/blog/wp-content/uploads/2011/09/loggest-query-peeps-by-any-600x139.png" alt="" width="600" height="139" /></a></p>
<p>I can see that the query ended up issuing database requests for both Walternate (purple) and myself (green), strongly suggesting that the database index being queried on names me.</p>
<p>I wonder if the conversation processing logic was the code that did this&#8230; let&#8217;s check by going to the time slice where the conversation was processed, expanding it, and only screenshotting some of it:</p>
<p><img class="alignnone size-full wp-image-813" title="loggest-new-conv-join-process-bad-index-write" src="http://www.visophyte.org/blog/wp-content/uploads/2011/09/loggest-new-conv-join-process-bad-index-write.png" alt="" width="594" height="461" /></p>
<p>Yes, the conversation logic did this.  It&#8217;s generating index values in the <em>peepData</em> table for the <em>idxPeepAny</em> and <em>idxPeepRecip</em> indices.  But I thought my unit tests covered this?  Nope.  It turns that although we test that a peep query returns the right thing both cold from the database and inductively via notifications as contact relationships are established, we don&#8217;t issue a new query after creating a conversation.  Furthermore, we only issued queries against the alphabetical index, not against <em>idxPeepAny</em>.  So we rectify that by augmenting the unit test:</p>
<pre>  // - make sure that the conversation addition did not screw up our peeps list
  T.group('check peeps list after conversation join');
  lqFinalAllPeeps = moda_a.do_queryPeeps("allPeepsFinal:any", {by: 'any'});</pre>
<p>And the test indeed now fails:</p>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/09/test-run-details-query-any-failure.png"><img class="alignnone size-thumbnail wp-image-815" title="test-run-details-query-any-failure" src="http://www.visophyte.org/blog/wp-content/uploads/2011/09/test-run-details-query-any-failure-600x155.png" alt="" width="600" height="155" /></a></p>
<p>The relevant bit is in the lower right, which I blow up here with the &#8220;unexpected event&#8221; <em>obj</em> popup displayed above it, and the &#8220;failed expectation&#8221; <em>obj</em> popup below it.  The postAnno stuff is to indicate what is new in the query result.  Because it&#8217;s a freshly issued query and this is the first set of results, everything is new.  It&#8217;s probably worth noting that these errors would usually show up as a single &#8220;mismatched&#8221; error instead of an unexpected/failed pair in our tests, but the specific logger was operating in unordered set mode because we don&#8217;t care about the exact order that different query notifications occur in, we just care that they do occur.</p>
<p><img class="alignnone size-full wp-image-816" title="test-run-details-query-any-failure-focused-with-popups" src="http://www.visophyte.org/blog/wp-content/uploads/2011/09/test-run-details-query-any-failure-focused-with-popups.png" alt="" width="534" height="355" /></p>
<p>(The structure is intended to later be enhanced to provide a nicer visualization where we only show the contents of the &#8220;state&#8221; attribute and use preAnno to indicate annotations on a representation of the most recent state for the object (from a previous log entry) and postAnno to indicate annotations on the now-current representation &#8220;state&#8221;.  For postAnno, values of 1 represent an addition, and values of 0 represent a change or event firing on the object.)</p>
<p>A potentially even more exciting bit of integrated logging is that <strong>about:loggest-server</strong> opens a tab that retrieves its contents from the server.  When run with the <em>&#8211;loggest-web-debug</em> flag, the server loads a module that cranks up the logging and does the same 1-second interval log reaping magic and exposes it for HTTP retrieval.  While this specific configuration with the high level of detailed logging is only appropriate for a developer-machine test server, it is incredibly valuable to be able to just pop open another tab and see what the server just got up to.</p>
<p>In any event, I leave it as an exercise to the reader to assume that I will take care of the bug now that it&#8217;s extremely clear what the problem is.  Well, extremely clear if I had taken a bigger screenshot of the conversation creation log.  Above the region captured is a header that indicates the actions are being triggered by the &#8216;convJoin&#8217; task and the entry (which is visible) indicates the update_conv_data function likely kicked off the database activity.</p>
<p>PS: All the gibberish looking characters in the screenshots are crypto keys or other binary data that lack aliases mapping them to known objects.  Examples of successfully mapped aliases are the colored blocks.  In the case of the conversation creation gibberish, we are seeing the conversation id.  Those aliases are generated as a separate pass by the log reaper by walking the set of existing queries and using helper functions to map the items currently exposed by the queries to human names because it&#8217;s quick and easy and is O(what&#8217;s being looked at) not O(size of the database).  In the case of the conversation, there was no query against the conversation and I also have not written the helper function yet, which is why it did not get aliased.  Unit tests don&#8217;t have the problem because we create aliases for everything.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2011/09/28/the-joy-of-integrated-logging-and-log-viewing-with-fancy-logs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>overview ownership/communication graphs for rich execution logs</title>
		<link>http://www.visophyte.org/blog/2011/07/20/overview-ownershipcommunication-graphs-for-rich-execution-logs/</link>
		<comments>http://www.visophyte.org/blog/2011/07/20/overview-ownershipcommunication-graphs-for-rich-execution-logs/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 23:48:26 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Program Execution]]></category>
		<category><![CDATA[Visualizing]]></category>
		<category><![CDATA[arbpl]]></category>
		<category><![CDATA[loggest]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=797</guid>
		<description><![CDATA[My last blog post covered the fancy pants logging being used for the deuxdrop project.  To summarize: we have loggers they are organized by ownership hierarchy they provide sufficient metadata that we can reconstruct the loggers that were talking to each other This can result in a lot of loggers.  If you look at the [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-798" src="http://www.visophyte.org/blog/wp-content/uploads/2011/07/relationship-overview-spgm.png" alt="relationship-overview-spgm" width="518" height="444" /></p>
<p>My <a href="http://www.visophyte.org/blog/2011/07/12/new-adventures-in-rich-execution-logs-for-debugging-and-program-understanding/">last blog post</a> covered the fancy pants logging being used for the deuxdrop project.  To summarize:</p>
<ul>
<li>we have loggers</li>
<li>they are organized by ownership hierarchy</li>
<li>they provide sufficient metadata that we can reconstruct the loggers that were talking to each other</li>
</ul>
<div>This can result in a lot of loggers.  If you look at the <a href="https://clicky.visophyte.org/examples/arbpl-loggest/20110712/">log output from the last blog post</a> (caution: BIG JSON file in standalone ArbPL instance) you might notice a list of loggers that looks something like the below, except not quite as sideways or shrunk:</div>
<p><img class="alignnone size-full wp-image-799" title="" src="http://www.visophyte.org/blog/wp-content/uploads/2011/07/prev-rev-logger-hier.png" alt="last generation's logger hierarchy rotated sideways" width="600" height="196" /></p>
<p>Obviously, that much raw data is not super helpful.  So now we process the hierarchy, constructing graph nodes or aggregate graph nodes for things that are interesting in their own or in aggregate.  We use <a href="http://mbostock.github.com/d3/">d3</a> of the vaunted <a href="http://mbostock.github.com/protovis/">protovis</a> lineage to visualize the network and <a href="http://www.graphviz.org/">graphviz</a> to lay it out.</p>
<p>d3 has a super-polished, fun-to-use interactive force-directed graph implementation, but graphviz&#8217;s circo layout produces better results.  Given that <a href="https://github.com/asutherland/arbitrarypushlog">ArbPL</a> already has a processing step for intake, it wasn&#8217;t too much extra work to include a step where we use the same JS code as on the client to generate a dot file, pass it to circo to lay it out, then extract the layout information and store it with the log data.  Many props to <a href="http://algorithmique.net/">Gregoire Lejeune</a> for his <a href="https://github.com/glejeune/node-graphviz">node-graphviz</a> bindings that made it so easy to do.</p>
<p><img class="alignnone size-full wp-image-800" title="" src="http://www.visophyte.org/blog/wp-content/uploads/2011/07/overview-z-joined-notif-highlighted.png" alt="overview-z-joined-notif-highlighted" width="517" height="445" /></p>
<p>Although the overview graph on its own is neat, it becomes useful by showing us the involved loggers/actors in a test step by highlighting them.  It does this by listening for <a href="https://github.com/asutherland/wmsy">wmsy</a>&#8216;s focus change events to know what the focused test step is.  (Since mouse interaction also causes toggling, it&#8217;s easiest to appreciate the process by using the up/down arrow keys to change focus without expanding the steps.  And if you want to toggle the expanded state without involving the mouse, you can hit the enter key.)</p>
<p><img class="alignnone size-full wp-image-801" title="" src="http://www.visophyte.org/blog/wp-content/uploads/2011/07/z-joined-step-callout-causes-highlighting.png" alt="z-joined-step-callout-causes-highlighting" width="624" height="107" /></p>
<p>For reference, the steps look like the above, and the highlighted one has the ever-so-fashionable glowing fancy focus ring.</p>
<p>If you would like to see this for yourself, you can check out the archived (and therefore less likely to break) standalone version of the example log file: <a href="https://clicky.visophyte.org/examples/arbpl-loggest/20110720/">https://clicky.visophyte.org/examples/arbpl-loggest/20110720/</a>.  The previously super-huge JSON file is now about an order-of-magnitude smaller because I started eliding large strings that are of no human interest.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2011/07/20/overview-ownershipcommunication-graphs-for-rich-execution-logs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>arbitrarypushlog now more realtimey; likes wide screens, humans</title>
		<link>http://www.visophyte.org/blog/2011/03/22/arbitrarypushlog-now-more-realtimey-likes-wide-screens-humans/</link>
		<comments>http://www.visophyte.org/blog/2011/03/22/arbitrarypushlog-now-more-realtimey-likes-wide-screens-humans/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 01:50:01 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[arbpl]]></category>
		<category><![CDATA[tbpl]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=745</guid>
		<description><![CDATA[Arbitrary Pushlog (ArbPL) recap: It shows revision control pushes and the tinderbox build results for specific build trees like tinderboxpushlog (TBPL). It is backed by a server which has a database so your browser is not going to launch a DOS attack on the mozilla infrastructure.  On the other hand, if that server falls over&#8230; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/03/tracemonkey-widescreen-arbpl.png"><img class="alignnone size-thumbnail wp-image-746" title="tracemonkey-widescreen-arbpl" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/tracemonkey-widescreen-arbpl-600x218.png" alt="" width="600" height="218" /></a></p>
<p>Arbitrary Pushlog (ArbPL) <a href="http://www.visophyte.org/blog/tag/arbpl/">recap</a>:</p>
<ul>
<li>It shows revision control pushes and the tinderbox build results for specific build trees like <a href="http://tbpl.mozilla.org/">tinderboxpushlog</a> (TBPL).</li>
<li>It is backed by a server which has a database so your browser is not going to launch a DOS attack on the mozilla infrastructure.  On the other hand, if that server falls over&#8230;</li>
<li>It figures out what failed by parsing the failed test logs.  It passes the time savings of this onto you in the form of listing the failures.  It also secretly knows things about failures that it does not tell you.</li>
<li>For Thunderbird mozmill test runs that experience failures it scrapes the fancy logging goodness out of the logs and exposes them in a pretty UI.  See the <a href="http://www.visophyte.org/blog/2011/03/02/teaser-rich-contextual-information-for-thunderbird-mozmill-failures/">teaser post</a> for screenshots.  You can also check to <a href="http://arbpl.visophyte.org/?tree=Thunderbird">see if we&#8217;ve fixed all the Thunderbird mozmill oranges</a> or not and maybe see a fresh new log!</li>
<li>It&#8217;s not capable of serving as a (full) replacement for TBPL at this time.  It does not show tree status (although that is easily fixed and should be fixed sometime soon), and it currently cannot star builds.</li>
</ul>
<p>What&#8217;s new:</p>
<ul>
<li>Widescreen display friendly.  It previously assumed you were me and ran your screen in portrait mode because that is the way you can see the most code; now it spills to two columns if your window is at least 1400px wide.  (See top screenshot.)</li>
<li>TraceMonkey&#8217;s mobile build matrix is split out from its desktop build matrix because the column sets did not meaningfully overlap.  No attempt has been made to deal with the other unique aspects of the TraceMonkey tree, although at least all known TraceMonkey builds should be categorized.  (If the builds that were triggered off another repo were split out into their own tinderbox tree so they could use the same mechanism Thunderbird and other comm-central complex repos use, no special work would be required.  It sounds like the tupled repo is going away soon, so it likely should become a moot issue.)</li>
</ul>
<p><img class="alignnone size-full wp-image-747" title="tracemonke-hier-summarized-failures" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/tracemonke-hier-summarized-failures.png" alt="" width="640" height="413" /></p>
<ul>
<li>It now does fancy hierarchical grouping of the failures.  The builder names&#8217; backgrounds are in gray because the failures have been starred.  The builder names would be in orange if the failing builds had not been starred.</li>
</ul>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/03/elided-changesets.png"><img class="alignnone size-thumbnail wp-image-748" title="elided-changesets" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/elided-changesets-600x194.png" alt="" width="600" height="194" /></a></p>
<ul>
<li>When people merge things or otherwise push more than 8 changesets, we don&#8217;t show you everything they pushed, just the top 3 and provide a link to the full log elsewhere.</li>
</ul>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/03/build-summary-popup.png"><img class="alignnone size-full wp-image-749" title="build-summary-popup" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/build-summary-popup.png" alt="" width="574" height="358" /></a></p>
<ul>
<li>I made an effort to help explain what is going on with builds in non-secret code.  You click on a build, you get this lovely box.  Unfortunately I apparently also forgot to expose the secret code in the popup like I was planning.</li>
</ul>
<p>And last, but not least&#8230;!</p>
<ul>
<li>ArbPL now uses <a href="http://socket.io/">socket.io</a> magic to provide realtime-ish updates.  Your browser creates a websocket/weird flash object bridge/XHR long-poll/etc. in order to be able to get the build information that&#8217;s hot off the press.  The &#8220;ish&#8221; part of realtime-ish comes from the bit where the presses are a cron job that runs every 3 minutes.  I think I have appropriate abort/retry logic in place now to contend with the half-written JSON and hanging HTTP requests, but I&#8217;m still sticking with the safety of a cron job with a built-in death clock until the logs agree with me.</li>
</ul>
<p>Important caveats:</p>
<ul>
<li>If the server restarts, the client is smart enough to reconnect, but not smart enough to re-establish its subscriptions with the server.  Refreshing the page or clicking the ArbPL logo in the upper left to go back to the list of trees and then picking a tree will resolve this issue.  The server only restarts when I push to production, as it were, so there is some other problem if you find yourself constantly needing to refresh.</li>
<li>Builders in the failure list look like they want to do something when you click on them, but this is a lie for all non-Thunderbird mozmill builders at the current time; those are the secrets ArbPL is keeping from you.</li>
</ul>
<p>You can use ArbPL for yourself at <a href="http://arbpl.visophyte.org/?">arbpl.visophyte.org</a>.  You can make your own using the <a href="https://github.com/asutherland/arbitrarypushlog">source on github</a>.</p>
<p>As noted by <a href="http://cloquewerk.livejournal.com/21937.html">mcote in his post on autolog</a>, the automation team is working on something in this domain, <a href="https://wiki.mozilla.org/Auto-tools/Projects/Autolog">autolog</a>, and I&#8217;m hoping to work with them to collaborate / pass-the-torch / or port Thunderbird&#8217;s mozmill logging to their solution so Thunderbird can have its fancy logging cake but not have to bake it too.</p>
<p>If you would like to discuss ArbPL/autolog/etc., I think the mozilla.tools group is supposed to be the right place for that.  One caveat is that I can&#8217;t seem to find the mailing list proper to sign up, just the newsgroup and google group&#8230;?  (Neither <a href="https://lists.mozilla.org/listinfo">https://lists.mozilla.org/listinfo</a> or <a href="https://mail.mozilla.org/listinfo/">https://mail.mozilla.org/listinfo/</a> seem to know about it.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2011/03/22/arbitrarypushlog-now-more-realtimey-likes-wide-screens-humans/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>build matrices for arbitrarypushlog</title>
		<link>http://www.visophyte.org/blog/2011/03/08/build-matrices-for-arbitrarypushlog/</link>
		<comments>http://www.visophyte.org/blog/2011/03/08/build-matrices-for-arbitrarypushlog/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 04:42:54 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Stuff]]></category>
		<category><![CDATA[arbpl]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=732</guid>
		<description><![CDATA[As I mentioned in my teaser on rich thunderbird mozmill logs, in order to get the build logs and provide failure clustering you already have to do most of the stuff tinderboxpushlog does.  One of the key things is summarizing the builds in a way that is useful, where the definition of &#8220;useful&#8221; probably varies [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_734" class="wp-caption alignnone" style="width: 610px"><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/03/tracemonkey-with-unstarred.png"><img class="size-thumbnail wp-image-734" title="tracemonkey-with-unstarred" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/tracemonkey-with-unstarred-600x382.png" alt="" width="600" height="382" /></a><p class="wp-caption-text">A TraceMonkey Push</p></div>
<p>As I mentioned in my <a href="http://www.visophyte.org/blog/2011/03/02/teaser-rich-contextual-information-for-thunderbird-mozmill-failures/">teaser on rich thunderbird mozmill logs</a>, in order to get the build logs and provide failure clustering you already have to do most of the stuff <a href="http://tbpl.mozilla.org/">tinderboxpushlog</a> does.  One of the key things is summarizing the builds in a way that is useful, where the definition of &#8220;useful&#8221; probably varies a lot between users.</p>
<p>While Thunderbird has an extremely boring set of build types (build, xpcshell, mozmill), my first take on summarizing them was no good.  While fixing it, I decided to feature creep (out of my hobby time allocation) and see if I could create a presentation that could handle the prolific Firefox and TraceMonkey trees.</p>
<div id="attachment_735" class="wp-caption alignnone" style="width: 610px"><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/03/firefox-all-starred.png"><img class="size-thumbnail wp-image-735" title="firefox-all-starred" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/firefox-all-starred-600x444.png" alt="" width="600" height="444" /></a><p class="wp-caption-text">A Firefox Push</p></div>
<p>While I am not going to claim it&#8217;s perfect, I like it.  It&#8217;s probably also important to caveat that not all Tracemonkey builds are categorized.  The mobile talos runs identify themselves by a completely different set of names from the desktop ones, and there&#8217;s not really room for columns for that.  Additionally, some builds cite a revision for &#8220;mobile-browser&#8221;, but we ignore that extra meta-data.  Although the design was intended to handle Thunderbird&#8217;s repository where each build is a tuple of &#8220;comm-central&#8221; and &#8220;mozilla-central&#8221; revision used, we really need to have that tuple for every build in the tinderbox tree, and TraceMonkey is not providing it.  (We could kick builds without the info to the &#8220;outer&#8221; push as an enhancement.)</p>
<div id="attachment_736" class="wp-caption alignnone" style="width: 610px"><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/03/thunderbird-unstarred.png"><img class="size-thumbnail wp-image-736" title="thunderbird-unstarred" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/thunderbird-unstarred-600x430.png" alt="" width="600" height="430" /></a><p class="wp-caption-text">A Thunderbird (well, comm-central) push.</p></div>
<p>As a gesture of friendship to non-Thunderbird trees, we now also process mochitest and reftest logs, although I&#8217;m failing to surface some of the details retrieved in the UI.</p>
<p>Anywho, you can see arbpl in action for yourself at <a href="http://arbpl.visophyte.org/?">arbpl.visophyte.org</a>.  It cron scrapes every 5 minutes.  The error recovery logic is not production-grade yet; the scraper can fall victim to partially written tinderbox JSON files on the tinderbox server, which means that some trees might not see updates for longer than that.  And various other things may go wrong too.  The client does not auto-refresh or use Socket.IO or anything.  If you want to run your own, <a href="https://github.com/asutherland/arbitrarypushlog">hit github</a>.  If you want to read the source, you should probably hit github too, because the production serving mode is reasonably optimized and crams all the JS into a single (gzipped) file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2011/03/08/build-matrices-for-arbitrarypushlog/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>teaser: Rich contextual information for Thunderbird mozmill failures</title>
		<link>http://www.visophyte.org/blog/2011/03/02/teaser-rich-contextual-information-for-thunderbird-mozmill-failures/</link>
		<comments>http://www.visophyte.org/blog/2011/03/02/teaser-rich-contextual-information-for-thunderbird-mozmill-failures/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 15:59:56 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Thunderbird]]></category>
		<category><![CDATA[arbpl]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[logsploder]]></category>
		<category><![CDATA[mozmill]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=722</guid>
		<description><![CDATA[Sometimes Thunderbird mozmill unit tests fail.  When they do, it&#8217;s frequently a mystery.  My logsploder work helped reduce the mystery for my local mozmill test runs, but did nothing for tinderbox runs or developers without tool fever.  Thanks to recent renewed activity on the Thunderbird front-end, this has become more of a problem and so [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-724 alignnone" title="unhappy-popups-screenshot-from-bad-wm" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/unhappy-popups-screenshot-from-bad-wm.png" alt="" width="503" height="444" /></p>
<p>Sometimes <a href="https://developer.mozilla.org/en/Thunderbird/Thunderbird_MozMill_Testing">Thunderbird mozmill</a> unit tests fail.  When they do, it&#8217;s frequently a mystery.  My <a href="http://www.visophyte.org/blog/2011/01/14/logsploder-circa-a-year-ago/">logsploder</a> work helped reduce the mystery for my local mozmill test runs, but did nothing for tinderbox runs or developers without tool fever.  Thanks to recent renewed activity on the Thunderbird front-end, this has become more of a problem and so it was time for another round of amortized tool building towards a platonic ideal.</p>
<p>The exciting pipeline that leads to screenshots like you see in this post:</p>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2011/03/unhappy-popups-from-bad-wm.png"><img class="alignnone size-thumbnail wp-image-725" title="unhappy-popups-from-bad-wm" src="http://www.visophyte.org/blog/wp-content/uploads/2011/03/unhappy-popups-from-bad-wm-600x258.png" alt="" width="600" height="258" /></a></p>
<ul>
<li>Thunderbird Mozmill tests run with the testing framework set to log semi-rich object representations to in-memory per-test buckets.</li>
<li>In the event of a test failure, the in-Thunderbird test framework:
<ul>
<li>Gathers information about the state of the system now that we know there is a failure and emit it.  This takes the form of canvas-based screenshots (using chrome privileges) of all open windows in the application, plus the currently focused element in the window.</li>
<li>Emits (up to) the last 10 seconds of log events from the previous test.</li>
<li>Emits all of the log events from the current test.</li>
</ul>
</li>
<li>The python test driver receives the emitted data and dumps it to stdout in a series of JSON blobs that are surrounded by magical annotations.</li>
<li>A node.js daemon doing the database-based tinderboxpushlog thing (like my <a href="http://www.visophyte.org/blog/2010/03/03/tinderbox-results-in-bugzilla-jetpack-times-2-couchdb-review-board/">previous Jetpack/CouchDB work</a> that <a href="http://www.visophyte.org/blog/2010/08/08/clicky-visophyte-org-hosted-couchdb-services-offline/">found CouchDB to not be a great thing to directly expose to users and died</a>, but now with node and hbase) processes the tinderbox logs for the delicious JSON blobs.
<ul>
<li>It also processes xpcshell runs and creates an MD5 hash that attempts to characterize the specific fingerprint of the run.  Namely, xpcshell emits lines prefixed with &#8220;TEST-&#8221; that have a regular form to describe when the pending test count changes or when specific comparison operations or failures occur.  It is assumed that tests will not comparison check values that are effectively random values, that the comparisons will tend to be deterministic (even if there are random orderings in the test) or notable when not deterministic, and thus that the trace derived from this filtering and hashing will be sufficiently consistent that similar failures should result in identical hashes.</li>
<li>Nothing is done with mochitests because: Thunderbird does not have them, they don&#8217;t appear to emit any context about their failures, and as far as I can tell, frequently the source of a mochitest failure is the fault of an earlier test that claimed it had completed but still had some kind of ripples happening that broke a later test.</li>
</ul>
<li>A wmsy-based UI does the UI thing.</li>
<ul></ul>
</li>
</ul>
<p>The particular failure shown here is an interesting one where the exception is telling us that a popup we expected to open never opened.  But when we look at the events from the log, we can see that what happened is the popup opened and then immediately closed itself.  Given that this happened (locally) on linux, this made me suspect that the window manager didn&#8217;t let the popup acquire focus and perform a capture.  It turns out that I forgot to install the xfwm4 window manager on my new machine which my xvnc session&#8217;s xstartup script was trying to run in order to get a window manager that plays nicely with mozmill and our focus needs.  (Many window managers have configurable focus protection that converts a window trying to grab focus into an attention-requested notification.)</p>
<p>This is a teaser because it will probably be a few more days before the required patch lands on comm-central, I use <a href="http://requirejs.org/">RequireJS</a>&#8216; fancy new <a href="http://requirejs.org/docs/optimization.html">optimizer</a> to make the client load process more efficient, and I am happy that the server daemons can keep going for long stretches of time without messing up.  The server and client code is available <a href="https://github.com/asutherland/arbitrarypushlog">on github</a>, and the <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/comm-central-patches/file/97ef5f6b655e/mozmill-dump-useful-data-on-failure">comm-central patch from hg</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2011/03/02/teaser-rich-contextual-information-for-thunderbird-mozmill-failures/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>teaser: code completion in skywriter/ajax.org code editor using jstut and narcissus</title>
		<link>http://www.visophyte.org/blog/2011/01/10/teaser-code-completion-in-skywriterajax-org-code-editor-using-jstut-and-narcissus/</link>
		<comments>http://www.visophyte.org/blog/2011/01/10/teaser-code-completion-in-skywriterajax-org-code-editor-using-jstut-and-narcissus/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 22:36:11 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[ace]]></category>
		<category><![CDATA[bespin]]></category>
		<category><![CDATA[jstut]]></category>
		<category><![CDATA[narcissus]]></category>
		<category><![CDATA[narscribblus]]></category>
		<category><![CDATA[skywriter]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=665</guid>
		<description><![CDATA[I&#8217;ve hooked up jstut&#8217;s (formerly narscribblus&#8216;) narcissus-based parser and jsctags-based abstract interpreter up to the ajax.org code editor (ace, to be the basis for skywriter, the renamed and somewhat rewritten bespin).  Ace&#8217;s built-in syntax highlighters are based on the somewhat traditional regex-based state machine pattern and have no deep understanding of JS.  The tokenizers have [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-666" title="ace-jstut-autocomplete-dot-ref" src="http://www.visophyte.org/blog/wp-content/uploads/2011/01/ace-jstut-autocomplete-dot-ref.png" alt="" width="717" height="329" /></p>
<p>I&#8217;ve hooked up <a href="http://www.visophyte.org/blog/tag/jstut/">jstut&#8217;s</a> (formerly <a href="http://www.visophyte.org/blog/2010/09/07/documentation-for-complex-things-you-dont-basically-already-understand/">narscribblus</a>&#8216;) <a href="https://github.com/mozilla/narcissus/">narcissus</a>-based parser and <a href="http://pcwalton.blogspot.com/2010/05/introducing-jsctags.html">jsctags</a>-based abstract interpreter up to the <a href="http://www.ajax.org/">ajax.org</a> code editor (<a href="https://github.com/mozilla/ace/">ace</a>, to be the basis for skywriter, the renamed and somewhat rewritten bespin).  Ace&#8217;s built-in syntax highlighters are based on the somewhat traditional regex-based state machine pattern and have no deep understanding of JS.  The tokenizers have a very limited stateful-ness; they are line-centric and the only state is the state of the parser at the conclusion of tokenizing the previous line.  The advantage is that they will tend to be somewhat resilient in the face of syntax errors.</p>
<p>In contrast, narcissus is a recursive descent parser that explodes when it encounters a parse error (and takes all the state on the stack at the point of failure with it).  Accordingly, my jstut/narscribblus parser is exposed to ace through a hybrid tokenizer that uses the proper narcissus parser as its primary source of tokens and falls back to the regex state machine tokenizer for lines that the parser cannot provide tokens for.  I have thus far made some attempt at handling invalidation regions in a respectable fashion but it appears ace is pretty cavalier in terms of invalidating from the edit point to infinity, so it doesn&#8217;t really help all that much.</p>
<p>Whenever a successful parse occurs, the abstract interpreter is kicked off which goes and attempts to evaluate the document.  This includes special support for CommonJS require() and CommonJS AMD define() operations.  The <em>require(&#8220;wmsy/wmsy&#8221;)</em> in the screenshot above actually retrieves the wmsy/wmsy module (using the <a href="http://requirejs.org/">RequireJS</a> configuration), parses it using narcissus, parses the documentation blocks using jstut, performs abstract interpretation and follow-on munging, and then returns the contents of that namespace (asynchronously using promises) to the abstract interpreter for the body of the text editor.  The hybrid tokenizer does keep around a copy of the last good parse to deal with code completion in the very likely case where the intermediate stages of writing new code result in parse failures.  Analysis of the delta from the last good parse is used in conjunction with the last good parse to (attempt to) provide useful code completion</p>
<p>The net result is that we have semantic information about many of the tokens on the screen and could do fancy syntax highlighting like Eclipse can do.  For example, global variables could be highlighted specially, types defines from third party libraries could get their own color, etc.  For the purposes of code completion, we are able to determine the context surrounding the cursor and the appropriate data types to use as the basis for completion.  For example, in the first screenshot, we are able to determine that we are completing a child of &#8220;wy&#8221; which we know to be an instance of type WmsyDomain from the wmsy namespace.  We know the children of the prototype of WmsyDomain and are able to subsequently filter on the letter &#8220;d&#8221; which we know has been (effectively) typed based on the position of the cursor.  (Note: completion items are currently not sorted bur rather shown in definition order.)</p>
<p><img class="alignnone size-full wp-image-667" title="ace-jstut-autocomplete-arg-obj" src="http://www.visophyte.org/blog/wp-content/uploads/2011/01/ace-jstut-autocomplete-arg-obj.png" alt="" width="671" height="459" /></p>
<p>In the second example, we are able to determine that the cursor is in an object initializer, that the object initializer is the first argument of a call to defineWidget on &#8220;wy&#8221; (which we know about as previously described).  We accordingly know the type constraint on the object initializer and thus know the legal/documented key names that can be used.</p>
<p>This is not working enough to point people at a live demo, but it is exciting enough to post teaser screenshots.  Of course, the code is always available for the intrepid: <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/narscribblus/">jstut/narscribblus</a>, <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/wmsy/">wmsy</a>.  In a nutshell, you can hit &#8220;Alt-/&#8221; and the auto-completion code will try and do its thing.  It will display its results in a wmsy popup that is not unified with ace in terms of how focus is handled (wmsy&#8217;s bad).  Nothing you do will actually insert text, but if you click outside of the popup or hit escape it will at least go away.  The egregious deficiencies are likely to go away soon, but I am very aware and everyone else should be aware that getting this to a production-quality state you can use on multi-thousand line files with complex control flow would likely be quite difficult (although if people document their types/signatures, maybe not so bad).  And I&#8217;m not planning to pursue that (for the time being); the goal is still interactive, editable, tutorial-style examples.  And for these, the complexity is way down low.</p>
<p>My thanks to the ajax.org and skywriter teams; even at this early state of external and source documentation it was pretty easy to figure out how various parts worked so as to integrate my hybrid tokenizer and hook keyboard commands up.  (Caveat: I am doing some hacky things&#8230; <img src='http://www.visophyte.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )  I am looking forward to the continued evolution and improvement of an already great text editor component!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2011/01/10/teaser-code-completion-in-skywriterajax-org-code-editor-using-jstut-and-narcissus/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thunderbuddy: Weave-synchronized Thunderbird contacts on Android</title>
		<link>http://www.visophyte.org/blog/2010/11/01/thunderbuddy-weave-synchronized-thunderbird-contacts-on-android/</link>
		<comments>http://www.visophyte.org/blog/2010/11/01/thunderbuddy-weave-synchronized-thunderbird-contacts-on-android/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 04:42:45 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Thunderbird]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[weave]]></category>
		<category><![CDATA[wmsy]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=619</guid>
		<description><![CDATA[I got my first modern Android phone at the end of last week and I figured it would be a good idea to get over the activation energy hump so it&#8217;s easy to do incremental mozilla hacking on it.  Thanks to a lot of work by other people, this turned out to be pretty easy.  [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-620" title="thunderbuddy-on-hardware-half-size" src="http://www.visophyte.org/blog/wp-content/uploads/2010/11/thunderbuddy-on-hardware-half-size.png" alt="" width="240" height="400" /></p>
<p>I got my first modern Android phone at the end of last week and I figured it would be a good idea to get over the activation energy hump so it&#8217;s easy to do incremental mozilla hacking on it.  Thanks to a lot of work by other people, this turned out to be pretty easy.  It would have been even easier if the Android emulator ran at anything remotely close to real time or if my Samsung Galaxy S Vibrant (Bell Canada model) running 2.1 did not have a habit of locking up all the time.  (And this is before my code touched it, mind you.  I&#8217;m half-hoping my device is a lemon.  If anyone knows how to tell a lemon from lockups-as-usual, please let me know.)</p>
<p>The screenshot shows my Android device running the app.  It&#8217;s a super trivial wmsy UI showing contacts from my address book pulled down from a weave server that were put there by Thunderbird.</p>
<p>Anywho, props to:</p>
<ul>
<li><a href="http://www.phonegap.com/">Phonegap</a>, the HTML/JS way to write mobile apps!  Major awesome.</li>
<li><a href="http://bitbucket.org/philikon/weaveclient-chromium/">weaveclient-chromium</a>, a slightly bitrotted pure JS weave client by <a href="http://philikon.de/">Philipp von Weitershausen / philikon</a> (now of the mozilla weave/sync team) which built on the <a href="https://wiki.mozilla.org/Services/Sync/Experimental_Clients/Web">weaveweb</a> project by Anant Narayanan and pure JS crypto work by the people mentioned in the <a href="http://bitbucket.org/philikon/weaveclient-chromium/src/tip/README">README</a>.</li>
<li><a href="http://bitbucket.org/mixedpuppy/weaver">weaver</a> and <a href="http://bitbucket.org/mixedpuppy/weave-ext">weave-ext</a> by <a href="http://shane.caraveo.com/">Shane Caraveo</a>, which make weave happily run in Thunderbird and have it propagate the contents of the address book.</li>
<li>The Mozilla Weave/Firefox Sync team who made it easy and practical for software like Thunderbird to partake in the encrypted synchronization revolution.</li>
<li><a href="http://requirejs.org/">RequireJS</a>, CommonJS loader to the stars.</li>
</ul>
<p>The relevant repos for those interested, are:</p>
<ul>
<li><a href="http://hg.mozilla.org/users/bugmail_asutherland.org/weaveclient-js/">weaveclient-js</a>: This is a fork of weaveclient-chromium that ditches the chromium bits, makes things CommonJS/Asynchronous Module Definition happy, and slightly factors out the encryption so that thunderbuddy can provide &#8216;native&#8217; accelerated encryption support on android.</li>
<li><a href="http://hg.mozilla.org/users/bugmail_asutherland.org/thunderbuddy/">thunderbuddy</a>: The phonegap android app repo proper.  The only really notable thing at this point is the custom Java class that implements and exposes faster &#8216;native&#8217; encryption methods.  (Thunderbuddy can also just be used as a webpage on any reasonably capable browser with good JS performance.)</li>
</ul>
<p>It&#8217;s worth noting that the goal is not actually to perform contact synchronization with Android.  There are already a ton of ways to synchronize your Thunderbird contacts with gmail and from there your phone.  The goal is to let other interesting data and meta-data propagate.  I just picked contacts for this example because Shane already had the data propagating.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2010/11/01/thunderbuddy-weave-synchronized-thunderbird-contacts-on-android/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Documentation for complex things (you don’t basically already understand)</title>
		<link>http://www.visophyte.org/blog/2010/09/07/documentation-for-complex-things-you-dont-basically-already-understand/</link>
		<comments>http://www.visophyte.org/blog/2010/09/07/documentation-for-complex-things-you-dont-basically-already-understand/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 00:36:22 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Thunderbird]]></category>
		<category><![CDATA[doccelerator]]></category>
		<category><![CDATA[docs]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[jstut]]></category>
		<category><![CDATA[narscribblus]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=562</guid>
		<description><![CDATA[The Problem One of my focuses at MoMo is to improve the plight of Thunderbird extension developers.  An important aspect of this is improving the platform they are exposed to.  Any platform usually entails a fair amount of complexity.  The trick is that you only pay for the things that are new-to-you, learning-wise. The &#8216;web&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p style="padding-left: 30px;"><a href="http://clicky.visophyte.org/examples/cjs/narscribblus/web/docloader.html?doc=wmsy/refdocs/viewslice-interposing.skwbl"><img class="alignnone size-full wp-image-566" title="editable-and-output" src="http://www.visophyte.org/blog/wp-content/uploads/2010/09/editable-and-output.png" alt="" width="538" height="337" /></a></p>
<h3>The Problem</h3>
<p>One of my focuses at <a href="http://www.mozillamessaging.com/en-US/">MoMo</a> is to improve the plight of <a href="http://www.mozillamessaging.com/en-US/thunderbird/">Thunderbird</a> extension developers.  An important aspect of this is improving the platform they are exposed to.  Any platform usually entails a fair amount of complexity.  The trick is that you only pay for the things that are new-to-you, learning-wise.</p>
<p>The &#8216;web&#8217; as a platform is not particularly simple; it&#8217;s got a lot of pieces, some of which are fantastically complex (ex: layout engines).  But those bits are frequently orthogonal, can be learned incrementally, have reams of available documentation, extensive tools that can aid in understanding, and, most importantly, are already reasonably well known to a comparatively large population.  The further you get from the web-become-platform, the more new things you need to learn and the more hand-holding you need if you&#8217;re not going to just read the source or trial-and-error your way through.  (Not that those are bad ways to roll; but not a lot of people make it all the way through those gauntlets.)</p>
<p>I am working to make Thunderbird more extensible in more than a replace-some-function/widget-and-hope-no-other-extensions-had-similar-ideas sort of way.  I am also working to make Thunderbird and its extensions more scalable and performant without requiring a lot of engineering work on the part of every extension.  This entails new mini-platforms and non-trivial new things to learn.</p>
<p>There is, of course, no point in building a spaceship if no one is going to fly it into space and fight space pirates.  Which is to say, the training program for astronauts with all its sword-fighting lessons is just as important as the spaceship, and just buying them each a copy of &#8220;sword-fighting for dummies who live in the future&#8221; won&#8217;t cut it.</p>
<p>Translating this into modern-day pre-space-pirate terminology, it would be dumb to make a super fancy extension API if no one uses it.  And given that the platform is far enough from pure-web and universally familiar subject domains, a lot of hand-holding is in order.  Since there is no pre-existing development community familiar with the framework, they can&#8217;t practically be human hands either.</p>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2010/09/definewidget-popup.png"><img class="alignnone size-thumbnail wp-image-567" title="definewidget-popup" src="http://www.visophyte.org/blog/wp-content/uploads/2010/09/definewidget-popup-600x310.png" alt="" width="600" height="310" /></a></p>
<h3>The Requirements</h3>
<p>I assert the following things are therefore important for the documentation to be able to do:</p>
<ul>
<li>Start with an explained, working example.</li>
<li>Let the student modify the example with as little work on their part as possible so that they can improve their mental model of how things actually work.</li>
<li>Link to other relevant documentation that explains what is going on, especially reference/API docs, without the user having to open a browser window and manually go search/cross-reference things for themselves.</li>
<li>Let the student convert the modified example into something they can then use as the basis for an extension.</li>
</ul>
<p><a href="http://clicky.visophyte.org/examples/cjs/narscribblus/web/docloader.html?doc=wmsy/refdocs/viewslice-interposing.skwbl"><img class="alignnone size-full wp-image-568" title="trace-output" src="http://www.visophyte.org/blog/wp-content/uploads/2010/09/trace-output.png" alt="" width="539" height="194" /></a></p>
<h3>The In-Process Solution: Narscribblus</h3>
<p>So, I honestly was quite willing to settle for an existing solution that was anywhere close to what I needed.  Specifically, the ability to automatically deep-link source code to the most appropriate documentation for the bits on hand.  It has become quite common to have JS APIs that take an object where you can have a non-trivial number of keys with very specific semantics, and my new developer friendly(-ish) APIs are no exception.</p>
<p>Unfortunately, most existing JavaScript documentation tools are based on the doxygen/JavaDoc model of markup that:</p>
<ul>
<li>Was built for static languages where your types need to be defined.  You can then document each component of the type by hanging doc-blocks off them.  In contrast, in JS if you have a complex Object/dictionary argument that you want to hang stuff of of, your best bet may be to just create a dummy object/type for documentation purposes.  JSDoc and friends do support a somewhat enriched syntax  like &#8220;@param arg.attr&#8221;, but run into the fact that the syntax&#8230;</li>
<li>Is basically ad-hoc with limited extensibility.  I&#8217;m not talking about the ability to add additional doctags or declare specific regions of markup that should be passed through a plugin, which is pretty common.  In this case, I mean that it is very easy to hit a wall in the markup language that you can&#8217;t resolve without making an end-run around the existing markup language entirely.  As per the previous bullet point, if you want to nest rich type definitions, you can quickly run out of road.</li>
</ul>
<p>The net result is that it&#8217;s hard to even describe the data types you are working with, let alone have tools that are able to infer links into their nested structure.</p>
<p><a href="http://clicky.visophyte.org/examples/cjs/narscribblus/web/docloader.html?doc=wmsy/typedocs/WmsyObjDef.skwbl&amp;forcelang=narscribblus/raw"><img class="alignnone size-full wp-image-569" title="skwbl-highlighted-widgetdef" src="http://www.visophyte.org/blog/wp-content/uploads/2010/09/skwbl-highlighted-widgetdef.png" alt="" width="625" height="336" /></a></p>
<p>So what is my solution?</p>
<ul>
<li>Steal as much as possible from <a href="http://docs.racket-lang.org/index.html">Racket</a> (formerly PLT Scheme)&#8217;s documentation tool, <a href="http://docs.racket-lang.org/scribble/index.html">Scribble</a>.  To get a quick understanding of the brilliance of Racket and Scribble, check out the <a href="http://docs.racket-lang.org/quick/index.html">quick introduction to racket</a>.  For those of you who don&#8217;t click through, you are missing out on examples that automatically hyperlink to the documentation for invoked methods, plus pictures capturing the results of the output in the document.
<ul>
<li>We steal the <a href="http://docs.racket-lang.org/scribble/reader.html">syntax</a> insofar as it is possible without implementing a scheme interpreter.  The syntax amounts to @command[s-expression stuff where whitespace does not matter]{text stuff which can have more @command stuff in it and whitespace generally does matter}.  The brilliance is that everything is executed and there are no heuristics you need to guess at and that fall down.</li>
<li>Our limitation is that while Racket is a prefix language and can use reader macros and have the entire documents be <em>processed in the same fashion as source code and totally understood by the text editor</em>, such purity is somewhat beyond us.  But we do what we can.</li>
</ul>
</li>
<li>Use narcissus, <a href="http://brendaneich.com/">Brendan Eich</a>/mozilla&#8217;s JS meta-circular interpreter thing, to handle parsing JavaScript.  Although we don&#8217;t have reader macros, we play at having them.  If you&#8217;ve ever tried to parse JavaScript, you know it&#8217;s a nightmare that requires the lexer to be aware of the parsing state thanks to the regexp syntax.  So in order for us to be able to parse JavaScript inline without depending on weird escaping syntaxes, when parsing our documents we use narcissus to make sure that we parse JavaScript as JavaScript; we just break out when we hit our closing squiggly brace.  No getting tricked by regular expressions, comments, etc.</li>
<li>Use the abstract interpreter logic from <a href="http://pcwalton.blogspot.com/">Patrick Walton</a>&#8216;s <a href="http://pcwalton.blogspot.com/2010/05/introducing-jsctags.html">jsctags</a> (and actually stole its CommonJS-ified narcissus as the basis for our hacked up one too) as the basis for abstract interpretation to facilitate being able to linkify all our JavaScript code.  The full narcissus stack is basically:
<ul>
<li>The narcissus lexer has been modified to optionally generate a log of all tokens it generates for the lowest level of syntax highlighting.</li>
<li>The narcissus parser has been modified to, when generating a token log, link syntax tokens to their AST parse nodes.</li>
<li>The abstract interpreter logic has been modified to annotate parse nodes with semantic links so that we can traverse the tokens to be able to say &#8220;hey, this is attribute &#8216;foo&#8217; in an object that is argument index 1 of an invocation of function &#8216;bar&#8217;&#8221; where we were able to resolve bar to a documented node somewhere.  (We also can infer some object/class organization as a result of the limited abstract interpretation.)</li>
<li>We do not use any of the fancy static analysis stuff that is going on as of late with the DoctorJS stuff.  Automated stuff is sweet and would be nice to hook in, but the goal here is friendly documentation.</li>
<li>The abstract interpreter has been given an implementation of CommonJS require that causes it to load other source documents and recursively process them (including annotating documentation blocks onto them.)</li>
</ul>
</li>
<li>We use bespin as the text editor to let you interactively edit code and then see the changes.  Unfortunately, I did not hook bespin up to the syntaxy magic we get when we are not using bespin.  I punted because of CommonJS loader snafus.  I did, however, make the &#8216;apply changes&#8217; button use narcissus to syntax check things (with surprisingly useful error messages in some cases).</li>
</ul>
<p>Extra brief nutshell facts:</p>
<ul>
<li>It&#8217;s all CommonJS code.  The web enabled version which I link to above and below runs using a slightly modified version of <a href="http://github.com/Gozala">Gozala</a>&#8216;s <a href="http://github.com/Gozala/teleport">teleport</a> loader.  It can also run privileged under Jetpack, but there are a few unimplemented sharp edges relating to Jetpack loader semantics.  (Teleport has been modified mainly to play more like jetpack, especially in cases where its aggressive regexes go looking for jetpack libs that aren&#8217;t needed on the web.)  For mindshare reasons, I will probably migrate off of teleport for web loading and may consider adding some degree of node.js support.  The interactive functionality currently reaches directly into the DOM, so some minor changes would be required for the server model, but that was all anticipated.  (And the non-interactive &#8220;manual&#8221; language already outputs plain HTML documents.)</li>
<li>The web version uses a loader to generate the page which gets displayed in an iframe inside the page.  The jetpack version generates a page and then does horrible things using <a href="http://www.toolness.com/wp/">Atul</a>&#8216;s custom-protocol mechanism to get the page displayed but defying normal browser navigation; it should either move to an encapsulated loader or implement a proper custom protocol.</li>
</ul>
<p>Anywho, there is still a lot of work that can and will be done (more &#8216;can&#8217; than &#8216;will&#8217;), but I think I&#8217;ve got all the big rocks taken care of and things aren&#8217;t just blue sky dreams, so I figure I&#8217;d give a brief intro for those who are interested.</p>
<p>Feel free to check out the live <a href="http://clicky.visophyte.org/examples/cjs/narscribblus/web/docloader.html?doc=wmsy/refdocs/viewslice-interposing.skwbl">example interactive tutorialish thing</a> linked to in some of the images, and its <a href="http://clicky.visophyte.org/examples/cjs/narscribblus/web/docloader.html?doc=wmsy%2Frefdocs%2Fviewslice-interposing.skwbl&amp;forcelang=narscribblus%2Fraw">syntax highlighted source</a>.  Keep in mind that lots of inefficient XHRs currently happen, so it could take a few seconds for things to happen.  The type hierarchy emission and styling still likely has a number of issues including potential failures to popup on clicks.  (Oh, and you need to click on the source of the popup to toggle it&#8230;)</p>
<p>Here&#8217;s a <a href="http://clicky.visophyte.org/examples/cjs/narscribblus/web/docloader.html?doc=wmsy/refdocs/emitreceive.skwbl">bonus example</a> to look at too, keeping in mind that the first few blocks using the elided js magic have not yet been wrapped in something that provides them with the semantic context to do magic linking.  And the <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/narscribblus/">narscribblus repo</a> is here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2010/09/07/documentation-for-complex-things-you-dont-basically-already-understand/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>understanding where layout goes wrong with gecko reflow debug logs (Part 1)</title>
		<link>http://www.visophyte.org/blog/2010/07/03/understanding-where-layout-goes-wrong-with-gecko-reflow-debug-logs-part-1/</link>
		<comments>http://www.visophyte.org/blog/2010/07/03/understanding-where-layout-goes-wrong-with-gecko-reflow-debug-logs-part-1/#comments</comments>
		<pubDate>Sun, 04 Jul 2010 05:51:24 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[jetpack]]></category>
		<category><![CDATA[layout]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=531</guid>
		<description><![CDATA[HTML and CSS provide awesome layout potential, but harnessing that potential to do your bidding can sometimes be problematic.  I suspect all people who have written HTML documents have been in a situation where they have randomly permuted the document structure and CSS of something that should work in the hopes of evolving it into [...]]]></description>
			<content:encoded><![CDATA[<p>HTML and CSS provide awesome layout potential, but harnessing that potential to do your bidding can sometimes be problematic.  I suspect all people who have written HTML documents have been in a situation where they have randomly permuted the document structure and CSS of something that should work in the hopes of evolving it into something that actually does work.  Matching wits with a black box that is invulnerable to even pirate-grade profanity is generally not a pleasant experience.</p>
<p>It turns out gecko has a way to let you see inside that black box.  Well, actually, multiple ways.  There&#8217;s a <a href="https://developer.mozilla.org/Layout_Debugger">layout debugger</a> (that seems broken on trunk?) that can display visual overlays for box sizes/events/reflow counts, dump info about paints/invalidations/events as they happen as well as dumping the current content tree and frames.  Even better, <a href="http://www.mozilla.org/newlayout/doc/frame_reflow_debug.html">gecko&#8217;s frame reflow debugging mechanism</a> will dump most of the inputs and outputs of each stage of reflow calculations as they happen.  With some comparatively minor patches[1] we can augment this information so that we can isolate reflow decisions to their origin presentation shell/associated URL and so that we know the tag name, element id, and class information on HTML nodes subjected to reflow calculations.  A reasonably sane person would want to do this if they were planning to be doing a lot of potentially complicated HTML layout work and would a) benefit from better understanding how layout actually works, b) not want to propagate layout cargo culting or its ilk from the code being replaced, c) not want to waste days of their lives later the next time this happens, d) help locate and fix layout bugs if bugs they be so that all might benefit.</p>
<p>Of course, with logs that effectively amount to execution traces, examining them by hand is frequently intractable unless you really know what you&#8217;re looking for or are dealing with a toy example.  My non-reduced problem case resulted in 58,107 lines, for one.  So writing a tool is a good idea, and writing it in JS using <a href="https://jetpack.mozillalabs.com/">Jetpack</a> doubly so.</p>
<p>In any event, the problem is I am trying to use the flexible box model to create an area of the screen that takes up as much space as possible.  In this space I want to be able to house a virtual scrolling widget so I use &#8220;overflow: hidden&#8221;.  Regrettably, when my logic goes to populate the div, the box ends up resizing itself and now the whole page wants to scroll.  Very sad.  (Things work out okay with an explicitly sized box which is why my unit tests for the virtual scrolling widget pass&#8230;)</p>
<p>Let&#8217;s formulate a query on the div of interest (which I will conceal) and then see what the first little bit of output is:</p>
<pre>*** Box 24 tag:div id: classes:default-bugzilla-ui-bug-page-runBox
*** scroll 25 tag:div id: classes:default-bugzilla-ui-bug-page-runs
scroll 25 variant 1  (parent 24) first line 406
  why: GetPrefSize
  inputs: boxAvail: 0,UC
          boxLast: 0,0
          reflowAvailable: 0,UC
          reflowComputed: 0,UC
          reflowExtra: dirty v-resize
  output: prefWidth: 0
          minWidth: 0
          reflowDims: 0,0
          prefSize: 0,0
          minSize: 0,0
          maxSize: UC,UC
  parent concluded: minSize: 0,0
                    maxSize: UC,UC
                    prefSize: 2,0
scroll 25 variant 2  (parent 24) first line 406
  why: Layout
  inputs: boxAvail: 771,1684
          boxLast: 0,0
          reflowAvailable: 771,UC
          reflowComputed: 771,1684
          reflowExtra: dirty dirty-children h-resize v-resize
  output: prefSize: 0,0
          minSize: 0,0
          maxSize: UC,UC
          reflowDims: 771,1684
          layout: 2,0,771,1684
  parent concluded: minSize: 0,0
                    maxSize: UC,UC
                    prefSize: 0,0
                    layout: 0,0,773,1684
</pre>
<p>This is the general pattern we will see to the reflows.  The parent will ask it what size it wants to be and it will usually  respond with &#8220;ridiculously wide but not so tall&#8221;.  (Not in this first base case, but the next one responds with a prefsize of &#8220;1960,449&#8243;, and that&#8217;s pixels.) The parent will then perform layout and say &#8220;no, you need to be taller than you want to be&#8221;, at least until I start cramming stuff in there.</p>
<p>So we skim down the output to find out where things first went off the rails&#8230;</p>
<pre>scroll 25 variant 16  (parent 24) first line 20548
  why: GetPrefSize
  inputs: boxAvail: 1960,UC
          boxLast: 771,1686
          reflowAvailable: 1960,UC
          reflowComputed: 1960,UC
          reflowExtra: dirty-children h-resize v-resize
  output: prefWidth: 1960
          minWidth: 352
          reflowDims: 1960,1755
          prefSize: 1960,1755
          minSize: 352,1755
          maxSize: UC,UC
  parent concluded: minSize: 0,0
                    maxSize: UC,UC
                    prefSize: 1962,1755
scroll 25 variant 17  (parent 24) first line 20548
  why: Layout
  inputs: boxAvail: 771,1755
          boxLast: 1960,1755
          reflowAvailable: 771,UC
          reflowComputed: 771,1755
          reflowExtra: dirty-children h-resize
  output: prefSize: 0,0
          minSize: 352,1755
          maxSize: UC,UC
          reflowDims: 771,1755
          layout: 2,0,771,1755
  parent concluded: minSize: 0,0
                    maxSize: UC,UC
                    prefSize: 0,0
                    layout: 0,0,773,1755
</pre>
<p>Okay, that looks pretty likely to be the area of concern.  The parent asked it for its ideal size, so it told it, but then the parent apparently decided to enlarge itself too.  That is not what we wanted.  We would have been cool if just the scroll #25 enlarged itself (or its block child #26 that corresponds to the same content node but which I have elided because it always says the same thing as its parent #25) since some frame needs to end up holding the overflow coordinate space.</p>
<p>Thus concludes part 1 of our exciting saga.  In part 2, we hopefully figure out what the problem is and how to fix it.  Lest anyone suggest the root problem is that I am completely off base and am not remotely reasonably sane for choosing this as a strategy to solve the problem&#8230; it works in chrome.  Which is not to say that my html/css is correct and firefox&#8217;s layout is wrong; it&#8217;s quite possible for layout engines to err or deal with unspecified behaviour cases in my favor, after all.  But it does make me want to understand what the layout engine is thinking and be able to do so with a minimum of effort in the future, since I doubt this is the last time I will not immediately understand the problem or that layout engines will differ in their behaviour.</p>
<p>For those who want to play along at home: the raw <a href="http://www.visophyte.org/blog/wp-content/uploads/2010/07/framedebug.gz">gzip&#8217;d /tmp/framedebug</a> file (gunzip to /tmp/framedebug) that is the entirety of the trunk firefox log with debug output, <a href="http://www.visophyte.org/blog/wp-content/uploads/2010/07/serial-12-0.gz">the spliced output just for the one window</a> derived from an invocation of &#8220;cfx run splice&#8221; (it will show up under the URL in /tmp/framedumps), and the output of <a href="http://www.visophyte.org/blog/wp-content/uploads/2010/07/summarize-unique-22242526.txt">the output of &#8220;cfx run summarize serial-12-0 summarize unique 22,24,25,26</a>.  Those unique identifiers are deterministic but arbitrary values for the given file.  We discovered them by using the query on the CSS class using &#8220;cfx run summarize serial-12-0 summarize class wlib-wlib-virt-wlib-virt-container-root&#8221;.  The <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/geckgrok/">hg repo for the processing tool is here</a>, the mozilla-central patches are: <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/mozilla-central-patches/file/4c411d365720/presarena-tell-allocs">first</a> and <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/mozilla-central-patches/file/4c411d365720/box-reflow-debug">second</a>.  A <a href="http://twitter.com/asutherland/status/17592978792">minor jetpack patch</a> is also required for the command line stuff to work.</p>
<p>1: I was initially trying to avoid patching anything.  This didn&#8217;t work out, but it did cause the initial log file splicing logic to leverage the arena allocation scheme of presentation shells to allow us to to map frames back to their URLs.  Sadly, it turned out the arena allocation blocks requested from the upstream allocators are really small (4k or 1k) and all from the same source and so I had to instrument the allocation as well as adding debug output of the window/docshell/presshell linkages.  The output adds an unacceptable additional level of noise to the default DEBUG case; the right thing to do is likely to cause the reflow log debugging to emit the document URL before each logging outburst if it is different from the last outburst.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2010/07/03/understanding-where-layout-goes-wrong-with-gecko-reflow-debug-logs-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Thunderbird Quick Filter Bar extensions, they&#8217;re a thing!</title>
		<link>http://www.visophyte.org/blog/2010/05/02/thunderbird-quick-filter-bar-extensions-theyre-a-thing/</link>
		<comments>http://www.visophyte.org/blog/2010/05/02/thunderbird-quick-filter-bar-extensions-theyre-a-thing/#comments</comments>
		<pubDate>Sun, 02 May 2010 18:09:11 +0000</pubDate>
		<dc:creator>Andrew Sutherland</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Thunderbird]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[jetpack]]></category>
		<category><![CDATA[quick filter bar]]></category>

		<guid isPermaLink="false">http://www.visophyte.org/blog/?p=519</guid>
		<description><![CDATA[The previously discussed Quick Filter Bar interface landed in time for Thunderbird (Lanikai) 3.1 beta 2 (whose release is real-soon-now).  Although the Quick Filter Bar already contains dangerously high levels of awesome, we made sure to make it extensible so you can cram even more awesome in. As an example, I have created an extension [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-516" title="pivot-popup" src="http://www.visophyte.org/blog/wp-content/uploads/2010/05/pivot-popup.png" alt="" width="392" height="198" /></p>
<p>The <a href="http://www.visophyte.org/blog/2010/02/14/thunderbird-message-filter-bar-prototype-extension-check-it/">previously</a> <a href="http://clarkbw.net/blog/2010/04/02/quick-filtering-in-thunderbird/">discussed</a> Quick Filter Bar interface landed in time for Thunderbird (Lanikai) 3.1 beta 2 (whose release is real-soon-now).  Although the Quick Filter Bar already contains dangerously high levels of awesome, we made sure to make it extensible so you can cram even more awesome in.</p>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2010/05/pivot-results-from.png"><img class="alignnone size-thumbnail wp-image-517" title="pivot-results-from" src="http://www.visophyte.org/blog/wp-content/uploads/2010/05/pivot-results-from-600x193.png" alt="" width="600" height="193" /></a></p>
<p>As an example, I have created an extension that enables you to &#8216;pivot&#8217; based on the currently selected message(s).</p>
<p>In its most straightforward manner of operation, you can click on an e-mail address in the message reader header and pivot by that e-mail address.  Out of the box, this will show you all the messages in the current folder sent by that user.  You can also (or only) show messages where that user is on the to/cc lines by toggling the buttons on the expando bar appropriately.</p>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2010/05/pivot-email-to.png"><img class="alignnone size-thumbnail wp-image-518" title="pivot-email-to" src="http://www.visophyte.org/blog/wp-content/uploads/2010/05/pivot-email-to-600x137.png" alt="" width="600" height="137" /></a></p>
<p>You can also constrain the display to only show messages within some time interval of the message(s) in question.</p>
<p><a href="http://www.visophyte.org/blog/wp-content/uploads/2010/05/pivot-email-from-week.png"><img class="alignnone size-thumbnail wp-image-522" title="pivot-email-from-week" src="http://www.visophyte.org/blog/wp-content/uploads/2010/05/pivot-email-from-week-600x123.png" alt="" width="600" height="123" /></a></p>
<p>The more confusing way to access the pivot functionality is to simply toggle the facet on the quick filter bar.  When you toggle the filter on, we walk all of the selected messages and build up a list of the observed e-mail addresses for all of the senders and all of the recipients.  One trick is that we filter out any e-mail addresses associated with your own account in order to avoid the filter becoming too inclusive.  We save those e-mail addresses into our state.  We also walk all the messages and find the time range that the messages cover and save that.  These are used as the basis for the specific constraints you can enable from the expando bar.  Because the values are saved, the filter does not change when you change your selected messages.  You need to toggle the pivot filter off and on again (or use the &#8216;pivot&#8217; option on the email address popup) to change the data we are pivoting on.</p>
<p>The extension can be <a href="https://addons.mozilla.org/en-US/thunderbird/addon/159026">found on AMO</a> and in <a href="http://hg.mozilla.org/users/bugmail_asutherland.org/qfb-pivot/">source form</a>.  In a forward-looking move that is probably complicating things for now, I used the Jetpack SDK and its XUL extension support to implement the extension.  In practice, all the example uses Jetpack for is its CommonJS module system and the standard mozilla-style JS modules would have been sufficient.  All the UI stuff is done purely in XUL overlays bound to the backing code using addEventListener.</p>
<p>The broad strokes for implementing a Quick Filter Bar extension are:</p>
<ol>
<li>Overlay your toolbarbutton into the quick filter bar, preferably the <a href="http://mxr.mozilla.org/comm-central/source/mail/base/content/quickFilterBar.xul#113">#quick-filter-bar-collapsible-buttons box</a>.  If you have an expando bar you want to contribute, you probably want to put that into the <a href="http://mxr.mozilla.org/comm-central/source/mail/base/content/quickFilterBar.xul#160">#quick-filter-bar-expando</a>.  As things currently stand, multiple expando bars being uncollapsed at the same time will probably turn out poorly, so you may need to be pragmatic and put your bar outside that box or do something clever.</li>
<li>Import <a href="http://mxr.mozilla.org/comm-central/source/mail/base/modules/quickFilterManager.js">resource:///modules/quickFilterManager.js</a>, implement your filter, and register it with <a href="http://mxr.mozilla.org/comm-central/source/mail/base/modules/quickFilterManager.js">QuickFilterManager.defineFilter()</a> (whose documentation explains the interface you need to conform to).</li>
</ol>
<p>We will likely not be doing up full documentation for this extension point beyond the in-code documentation and in-tree/extension examples.  This is an advanced extension point by virtue of it touching nsIMsgDBHdrs, nsIMsgDBViews, nsIMsgSearchSessions, and friends, all of which have sharp edges.  The way forward with soft, human-friendly documented abstractions is gloda and that&#8217;s where (my) effort will be concentrated.  The awesome in this extension point is making it practical for people who already have the scars to utilize the full power of the message view/traditional search subsystem without losing a limb and do so in a previously impossibly short period of time.</p>
<p>PS: I made the icon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.visophyte.org/blog/2010/05/02/thunderbird-quick-filter-bar-extensions-theyre-a-thing/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

