<?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>ColonelPanic &#187; Richard</title>
	<atom:link href="http://colonelpanic.net/author/richard/feed/" rel="self" type="application/rss+xml" />
	<link>http://colonelpanic.net</link>
	<description>Dumping our corps so you don&#039;t have to</description>
	<lastBuildDate>Mon, 30 Jan 2012 17:50:10 +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 best JavaScript stack I have ever used</title>
		<link>http://colonelpanic.net/2011/12/the-best-javascript-stack-i-have-ever-used/</link>
		<comments>http://colonelpanic.net/2011/12/the-best-javascript-stack-i-have-ever-used/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 07:06:54 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=622</guid>
		<description><![CDATA[JavaScript as a real language Like many, the suggestion that JavaScript could be used in a fully architected system initially left me doubting the sanity of the person with whom I spoke. Over the years I have done several different types of Web Development; I am best known for my work with browser plugins in [...]]]></description>
			<content:encoded><![CDATA[<h1>JavaScript as a real language</h1>
<p>Like many, the suggestion that JavaScript could be used in a fully architected system initially left me doubting the sanity of the person with whom I spoke. Over the years I have done several different types of Web Development; I am best known for my work with browser plugins in general and the <a href="http://firebreath.org">FireBreath framework</a> in particular. What most do not know is that I actually started out doing a lot of PHP and JavaScript development and that it was actually my work with JavaScript that eventually led me to learning about NPAPI and ActiveX plugin technologies.</p>
<p>Throughout all this I experimented with many different types of javascript code; I wrote AJAX applications long before I&#8217;d heard the term coined using a system called <a href="http://www.ashleyit.com/rs/jsrs/test.htm">JSRS</a> &#8212; which is surprisingly still around, or at least the page I got it from. I worked for Move Networks on their JavaScript SDK and I wrote several AJAX heavy websites, such as <a href="http://hamstudy.org">HamStudy.org</a>. Many reading this will scoff when I admit that while I considered myself fairly well versed in JavaScript I still wrote it as if it were a simple scripting language. Others may wonder what is wrong with that? JavaScript more than perhaps any other language I have used gives you <a href="http://www.amazon.com/Enough-Rope-Shoot-Yourself-Foot/dp/0070296898">just enough rope to shoot yourself in the foot with</a>. I have learned over the last few months just how little I knew &#8212; and didn&#8217;t know that I didn&#8217;t know.</p>
<p>My upward climb started off simply enough &#8212; I wanted to learn about some of the new technologies that I had heard about; <a href="http://documentcloud.github.com/backbone/">Backbone</a>, MVC frameworks, client-side template libraries&#8230; I had written my own &#8220;frameworks&#8221; on which to base my websites, all of which were side projects, but I found myself spending much more time than I liked updating and maintaining those frameworks. I thought perhaps I could use someone else&#8217;s system and save myself some trouble.</p>
<p>I purchased a book called <a href="http://shop.oreilly.com/product/0636920018421.do">JavaScript Web Applications</a> which claimed to teach how to write an actual application with JavaScript. The table of contents looked interesting, and besides teaching about the principles used it also had instructions on several different MVC frameworks that I wanted to know about, including Backbone.</p>
<p>This book was the beginning &#8212; as a result of this purchase I soon came to grips with just how comparitively incomptetent my old code had been, and started to actually understand that JavaScript can indeed be a real language. Over the course of a few posts I would like to share with you the stack that has grown out of this system: What the components are, how they help, and why they are integral to the overall solution. I will start out in this post with the basics and my next post will detail the specific tweaks that we have made to them that have made our system so successful.</p>
<h1>Dependency Management</h1>
<p>Having been so long-winded with my earlier explanation, I will now spare you the details of all of the things I tried, researched, or experimented with during my search. One thing quickly became clear to me, though: Perhaps the #1 reason that my previous code had ended up so ugly was the need to avoid creating lots of JavaScript files. These can be difficult to deploy cleanly as it is not a good idea to have too many script includes in your production site and combining them can be an annoying process. The end result of this problem is that I had about 10 JavaScript files &#8212; and felt guilty about it &#8212; and all of my functionality was stuffed in those files. I had page-specific files, site-specific files, and general reuse library files, and all of them tried to register themselves cleanly in the global scope without clobbering each other. In short, it was a mess.</p>
<p>Enter <a href="http://requirejs.org/">require.js</a>. Require.js is a system in which all javascript files are wrapped in a function. This is actually a really common pattern, but with require.js that function is passed into the &#8220;define&#8221; function call along with a list of dependencies. Require will first resolve these dependencies and then when they are all resolved it will call the function you provided, passing in the exports of each dependency as arguments in the order that the dependencies are listed in the define call.</p>
<p>The question left unanswered, then, is what are the exports of the other dependencies? Simply put, each &#8220;module&#8221; exports some value by simply returning that value from the function passed into the define call (See file1.js and file2.js).</p>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;backbone&quot;</span><span class="p">,</span> <span class="s2">&quot;./reqfile2&quot;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">,</span> <span class="nx">File2</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// In this file we do whatever it is we do; we know file2 was loaded first and we can use what it exports</span></div>
<div class='line' id='LC3'><br/></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">File2</span><span class="p">.</span><span class="nx">text</span> <span class="o">+</span> <span class="s2">&quot; from two different files&quot;</span><span class="p">;</span></div>
<div class='line' id='LC5'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/40e1484de2bc94b65add80219d87e9dc0104d8f8/reqfile1.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_reqfile1.js" style="float:right;margin-right:10px;color:#666">reqfile1.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([],</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">File2</span> <span class="o">=</span> <span class="p">{};</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">File2</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="s2">&quot;This is some text&quot;</span><span class="p">;</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">File2</span><span class="p">;</span></div>
<div class='line' id='LC5'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/c9f3ad81c0dba359d2e61093cfd368b22058dafc/reqfile2.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_reqfile2.js" style="float:right;margin-right:10px;color:#666">reqfile2.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<p>The natural result of so much flexibility is a lot of small files; this is really good for code organization because it makes it easy to seperate things into logical pieces and even to include whole modules consisting of multiple files (because one can depend on multiple others and combine them in its return value). The downside is that with lots of small files your page load time starts to get a bit out of control. Fortunately, require.js has an answer for this problem as well!</p>
<p>Require.js has an optimize phase that will examine the dependencies of your main file and combine all of them into a single file so that they are all loaded at once. The require.js system still makes sure that the functions are called in the correct order, but makes it very easy for your production site to be seamlessly updated to use a combined and minified single javascript file instead of the potentially dozens of small other files.</p>
<p>To me, this was a nearly life-changing WIN.</p>
<h1>JavaScript Templates</h1>
<p>If dependency management became the #1 most useful change in my architecture, a close #2 would have the be JavaScript Templates. The more I did things on the client the more client-side HTML I created in JavaScript; I experimented with several methods but still ended up with really hard to read html mixed in with my JavaScript as strings. When the time came to update one of those sites it was painful; not all of the code was in the same place, it wasn&#8217;t easy to read, it wasn&#8217;t easy therefore to change.</p>
<p>I considered different types of templates but had previously rejected the idea. The problem with templates, you see, is that you still have to include the template code somehow. The most &#8220;traditional&#8221; method would be to pretend you&#8217;re on a backend and just store them one template per file. Of course, then if you have any real number of these files you find yourself making a multitude of AJAX requests to download all of these templates; it&#8217;s clean from a file structure perspective and fairly easy to use, but to me the added complexity of all those requests is not acceptible. Other options include storing the template in javascript strings (same problem as I had before without templates) and storing them in a special script tag on the html page, which had the (to me) serious disadvantage of being nearly impossible to reasonably use on multiple pages. It was a problem.</p>
<p>Enter require.js and the text plugin. The text plugin of require.js is an idea both simple and brilliant; it allows you to specify files that should be loaded and the text of those files will be passed into your page function as the value of that dependency. With the text plugin you can save your templates each in their own file and have require load the text when the page loads. Of course, this doesn&#8217;t solve the problem we mentioned earlier! You still have potentially lots of AJAX requests being made to load those files. Problem? Not at all! Remember the optimize step in require.js; just like the normal dependencies are loaded and combined into one file the text plugin provides a mechanism to serialize those templates into javascript as strings and combine them into that same file. You get the best of both worlds! When you&#8217;re developing you have the flexibility of having each template in an easy-to-read file, but when you deploy those templates are packaged with your javascript.</p>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;backbone&quot;</span><span class="p">,</span> <span class="s2">&quot;underscore&quot;</span><span class="p">,</span> <span class="s2">&quot;text!./mytemplate.jst&quot;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">tplCode</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span><span class="nx">tplCode</span><span class="p">);</span></div>
<div class='line' id='LC4'><br/></div>
<div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">function</span> <span class="nx">doSomething</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Here is the rendered template: &quot;</span><span class="p">,</span> <span class="nx">tplCode</span><span class="p">({</span><span class="nx">key</span><span class="o">:</span> <span class="nx">val</span><span class="p">}));</span></div>
<div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">doSomething</span><span class="p">;</span></div>
<div class='line' id='LC9'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/e30e9374666998bd5cb309ce8ce1547199e0ffea/reqtpl.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_reqtpl.js" style="float:right;margin-right:10px;color:#666">reqtpl.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<p>Top all of this off with the fact that for several of the most popular template libraries there are already require.js plugins, such as <a href="https://github.com/ZeeAgency/requirejs-tpl">requirejs-tpl</a>. These plugins work like the text plugin, but they compile the template string into an actual template function before passing it back to resolve the dependency. Then, when you optimize, they actually compile your template code into javascript functions and minify them along with the rest of your JS code!</p>
<p>To me, this was a nearly life-changing WIN.</p>
<h1>Deferred Objects</h1>
<p>This may seem like it doesn&#8217;t fit with the other items on this page, but if templates and dependency management have revolutionized the organization of my code then deferred objects have revolutionized the way that I write JavaScript code. One of my coworkers at <a href="http://www.gradecam.com">GradeCam</a>, Robin, has already begun a <a href="http://colonelpanic.net/2011/11/jquery-deferred-objects/">small introductory series on how deferred objects work</a>, so I&#8217;m not going to go into those details, but I do want to explain the conceptual shift in how pieces of the system interact that this led me to. It is both subtle and extremely powerful.</p>
<p>Most JavaScript operations anymore are asynchronous; in other words, they return immediately even though the operation in question hasn&#8217;t been completed. This can make it difficult to handle result cases; the traditional method is to pass a callback into the function to be called when the operation completes. You then perform some other operation once that function is called back and so forth.</p>
<p>The challenge with that is that it is a significant deviation from the patterns that we are all accustomed to. Granted, it&#8217;s important to understand what is <em>actually </em>happening, but often you may want to call a function in a place where you don&#8217;t actually want to handle the results; a good example is when you are requesting data from a model in your controller code, but you will actually be rendering it withing your view and your controller doesn&#8217;t really care what the results are. The view, of course, should not need to know or care where the data came from. In fact, it shouldn&#8217;t really need to know if the data is immediately available or will be available later on &#8212; it should display it <em>when it is available</em> and not worry about the other details.</p>
<p>Code speaks louder than prose, so here is an example of the difference between these two approaches; in both async1.js and async2.js three async operations take place. In async1.js they are handled in a traditional way, and in async2.js they are handled using jQuery.Deferred.</p>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="kd">function</span> <span class="nx">asyncOper1</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="s2">&quot;One second has passed since &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">1000</span><span class="p">);</span></div>
<div class='line' id='LC5'><span class="p">}</span></div>
<div class='line' id='LC6'><br/></div>
<div class='line' id='LC7'><span class="kd">function</span> <span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="s2">&quot;Two seconds were added, then &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">2000</span><span class="p">);</span></div>
<div class='line' id='LC11'><span class="p">}</span></div>
<div class='line' id='LC12'><br/></div>
<div class='line' id='LC13'><span class="kd">function</span> <span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="s2">&quot;A long time (3 seconds) went by before &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">3000</span><span class="p">);</span></div>
<div class='line' id='LC17'><span class="p">}</span></div>
<div class='line' id='LC18'><br/></div>
<div class='line' id='LC19'><span class="kd">function</span> <span class="nx">alertResult</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alert</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC21'><span class="p">}</span></div>
<div class='line' id='LC22'><br/></div>
<div class='line' id='LC23'><span class="c1">// Call them all; alert the final result</span></div>
<div class='line' id='LC24'><span class="nx">asyncOper1</span><span class="p">(</span><span class="s2">&quot;we started&quot;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">strVal1</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">strVal1</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">strVal2</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">strVal2</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">strVal3</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alertResult</span><span class="p">(</span><span class="nx">strVal3</span><span class="p">);</span></div>
<div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC30'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/be1fceb3098909ae1d02d0a03a1e6f36169fbbe1/async1.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_async1.js" style="float:right;margin-right:10px;color:#666">async1.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="kd">function</span> <span class="nx">asyncOper1</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">()</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s2">&quot;One second has passed since &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">1000</span><span class="p">);</span></div>
<div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC9'><span class="p">}</span></div>
<div class='line' id='LC10'><br/></div>
<div class='line' id='LC11'><span class="kd">function</span> <span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">()</span></div>
<div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s2">&quot;Two seconds were added, then &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">2000</span><span class="p">);</span></div>
<div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span></div>
<div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC19'><span class="p">}</span></div>
<div class='line' id='LC20'><br/></div>
<div class='line' id='LC21'><span class="kd">function</span> <span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">()</span></div>
<div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s2">&quot;A long time (3 seconds) went by before &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">3000</span><span class="p">);</span></div>
<div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span></div>
<div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC29'><span class="p">}</span></div>
<div class='line' id='LC30'><br/></div>
<div class='line' id='LC31'><span class="kd">function</span> <span class="nx">alertResult</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">done</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alert</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC35'><span class="p">}</span></div>
<div class='line' id='LC36'><br/></div>
<div class='line' id='LC37'><span class="kd">var</span> <span class="nx">res1</span><span class="p">,</span> <span class="nx">res2</span><span class="p">,</span> <span class="nx">res3</span><span class="p">;</span></div>
<div class='line' id='LC38'><br/></div>
<div class='line' id='LC39'><span class="nx">res1</span> <span class="o">=</span> <span class="nx">asyncOper1</span><span class="p">(</span><span class="s2">&quot;we started&quot;</span><span class="p">);</span></div>
<div class='line' id='LC40'><span class="nx">res2</span> <span class="o">=</span> <span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">res1</span><span class="p">);</span></div>
<div class='line' id='LC41'><span class="nx">res3</span> <span class="o">=</span> <span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">res2</span><span class="p">);</span></div>
<div class='line' id='LC42'><br/></div>
<div class='line' id='LC43'><span class="nx">alertResult</span><span class="p">(</span><span class="nx">res3</span><span class="p">);</span></div>
<div class='line' id='LC44'><br/></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/75a294c8603e678d91db660c5e0c2e6060aa1636/async2.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_async2.js" style="float:right;margin-right:10px;color:#666">async2.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<p>As you can see, the Deferred object method is slightly more complex at first; however, the complexity is where it belongs. Each method need know nothing about the others &#8212; they all assume that the input value *might* be Deferred. They return a Deferred object, and so they use the Deferred.pipe method, which makes it easy to chain deferred objects. Because each of the methods returns a Deferred object and is aware that it may receive a Deferred object, you can call one after the other as though they were happening synchronously &#8212; because indeed they will end up doing so, in all practical purposes. However, you shouldn&#8217;t think of this as hiding the fact that it is asynchronous, but rather as returning asynchronous return values.</p>
<p>Because we used $.when, you can pass a regular parameter in to any of those methods as well and chain them as much as you want. It will handle them all perfectly.</p>
<p>To me, this was a completely life-changing WIN.</p>
<h1>This is just the beginning</h1>
<p>I have a lot more to talk about here; this is just the foundation. If you know nothing more about our stack, you should understand these things. Next time, though, I&#8217;ll talk about how we tie this together using Backbone.js Routers, Views, and Models, how those tie into our templates, and how Deferred objects allowed us to add data cacheing to our data models completely transparently &#8212; without changing a line of code outside of the model classes.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/12/the-best-javascript-stack-i-have-ever-used/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>jQuery Deferred Objects &#8211; Part 2</title>
		<link>http://colonelpanic.net/2011/12/jquery-deferred-objects-part-2/</link>
		<comments>http://colonelpanic.net/2011/12/jquery-deferred-objects-part-2/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 16:47:58 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=603</guid>
		<description><![CDATA[Deferred Objects &#8211; Part II As you recall from the first part jQuery Deferred Objects &#8211; Part I, deferred objects give you a way to organize asynchronous blocks of code in to a self-managed callback queue, while allowing you to attach 1..* callbacks. Also, you&#8217;ll recall that the basics of using jQuery deferred objects include [...]]]></description>
			<content:encoded><![CDATA[<h1> Deferred Objects &#8211; Part II</h1>
<p>As you recall from the first part <a href="http://colonelpanic.net/2011/11/jquery-deferred-objects/" target="_blank">jQuery Deferred Objects &#8211; Part I</a>, deferred objects give you a way to organize asynchronous blocks of code in to <a href="http://www.erichynds.com/jquery/using-deferreds-in-jquery/" target="_blank">a self-managed callback queue</a>, while allowing you to attach 1..* callbacks. Also, you&#8217;ll recall that the basics of using jQuery deferred objects include essentially the following &#8220;simplified&#8221; steps:<br />
1. Created a deferred object<br />
2. Attached .done and .fail callbacks<br />
3. Called resolve or reject, thereby triggering the appropriate respective callbacks</p>
<h2> Promises</h2>
<p>This was fine as a first step in understanding what&#8217;s going on, but in all likelyhood you&#8217;ll use a slightly different approach. What&#8217;s wrong with returning a deferred object itself? It gives the caller access to resolve or reject directly, and that means other callers could be affected as a result. What we really want to do is return a &#8220;promise&#8221;. From the <a href="http://api.jquery.com/Types/#Promise">jQuery Promise Documentation</a> we learn:<br />
&#8220;This object provides a subset of the methods of the Deferred object (then, done, fail, always, pipe. isResolved, and isRejected) to prevent users from changing the state of the Deferred.&#8221;</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/push_to_twitter&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/push_to_facebook&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/push_to_linkedin&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/generate_report&quot;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">then</span><span style="color: #009900;">&#40;</span> it_succeeded<span style="color: #339933;">,</span> it_failed<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> it_succeeded<span style="color: #009900;">&#40;</span>report_data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Now do something with the report data e.g. show</span>
    <span style="color: #006600; font-style: italic;">// an awesome summary with pretty bars and graphs!</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">function</span> it_failed<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Treat user's depression, OCD and other ailments</span>
    <span style="color: #006600; font-style: italic;">// Prescribe prozac, etc., etc...</span>
<span style="color: #009900;">&#125;</span></pre>
</div>
</div>
<h2>Possible Uses</h2>
<p>Possible use cases are endless but here are some examples:<br />
1. You need to make multiple asynchronous Ajax requests &#8211; with Deferred objects you can handle the results together without concern for which order they finish in.<br />
2. You want to be able to make the call in one region of code, then pass the result as an argument to a different part, but the call may be asynchronous.<br />
3. Easily return data from a modal dialog<br />
4. Caching &#8211; an API properly supporting Deferred objects can implement caching <em>without any changes to the consumer of the API</em>.</p>
<h2>An Example: Caching</h2>
<p>For caching, jQuery&#8217;s when .. then provides us the tools we need to return both fresh and cached data from one interface. Take the following code:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> cacheA <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectA<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/fooEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> cacheB <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectB<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/barEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>fetch_some_objectA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> fetch_some_objectB<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>dataA<span style="color: #339933;">,</span> dataB<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Do whatever you want with said data</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fail</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errA<span style="color: #339933;">,</span> errB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Deal with error handling</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<h3> The basics of caching with Deferred objects</h3>
<p>There are a couple of cases to consider here; the first case is that you are requesting object(&#8216;foo&#8217;) for the first time. In this case, cacheA["foo"] will not exist and so an ajax call is created. $.ajax returns a deferred object, which is saved in the cache. The reason this is important is that thereafter, future requests will get that same deferred object, thus preventing two requests from being made to the same endpoint. Once the ajax call completes the done handler we set updates the cache with the actual object. Any calls that ran fetch<em>some</em>objectA(&#8216;foo&#8217;) while the request was &#8220;in progress&#8221; will be notified with the data once the deferred is resolved. Calls made after the request has resolved will get the actual data straight away. So, how do you tell if you have a deferred or the real data? The answer is simple: you don&#8217;t need to.</p>
<p>This is where <a href="http://api.jquery.com/jQuery.when/">jQuery.when</a> neatly ties everything together. jQuery.when ($.when) accepts any number of arguments and returns a jquery.Deferred object. That object will be resolved once all of the arguments are resolved; however, if those objects are not jQuery.Deferred objects then they will be considered resolved immediately. From the documentation, jQuery.when takes either a Deferred or object: &#8220;If a single argument is passed to jQuery.when and it is not a Deferred, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.&#8221;</p>
<p>After passing through a jQuery.when, a Deferred object that resolves to a string &#8220;A&#8221; and the string &#8220;A&#8221; become functionally equivalent &#8212; no matter which you passed in, you&#8217;ll still get the same thing:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;fdsafdsa&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>This will immediately alert &#8220;fdsafdsa&#8221;. Now essentially the same using the deferred resolve idiom:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> dfd <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> $.<span style="color: #660066;">Deferred</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>dfd<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dfd.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;fdsafdsa&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>This will also alert the same thing; it doesn&#8217;t matter if it&#8217;s a real object or a deferred, once you make it into the when it&#8217;ll be a real object. This makes caching really slick because you don&#8217;t need to care if you have the object yet or not, you just let jQuery.when figure that out and tell it what should happen once it does.</p>
<h3>One small problem&#8230;</h3>
<p>If you actually copy in this code and play with it long enough, you&#8217;ll notice something that doesn&#8217;t quite work how you expect. When the jQuery.ajax call returns you&#8217;ll actually get a slightly different object in the jQuery.when callback; this actually makes sense if you look at it closer. From the jQuery codebase, when the ajax call completes it is either resolved or rejected with the following lines:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Success/Error</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> isSuccess <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    deferred.<span style="color: #660066;">resolveWith</span><span style="color: #009900;">&#40;</span> callbackContext<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span> success<span style="color: #339933;">,</span> statusText<span style="color: #339933;">,</span> jqXHR <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    deferred.<span style="color: #660066;">rejectWith</span><span style="color: #009900;">&#40;</span> callbackContext<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span> jqXHR<span style="color: #339933;">,</span> statusText<span style="color: #339933;">,</span> error <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre>
</div>
</div>
<p>Notice that there are actually three arguments in either case; this may surprise you, since most examples you&#8217;ll see of the callbacks accept just one, like the above code. Most don&#8217;t need the other two, but jQuery.when isn&#8217;t going to discard those extra values and yet it still needs to keep one argument per input in the callback function. Therefore, in the $.when block above you&#8217;ll actually have both dataA and dataB resolve to an array with three values (success, statusText, jqXHR); however, we normally would only cache one of those values (success) so when reading from the cache we don&#8217;t get that array. The solution is to make our functions a little bit more complicated by using the jquery pipe method to restructure the result a little bit:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> cacheA <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectA<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/fooEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> cacheB <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectB<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/barEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>fetch_some_objectA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> fetch_some_objectB<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>dataA<span style="color: #339933;">,</span> dataB<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Do whatever you want with said data</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fail</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errA<span style="color: #339933;">,</span> errB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Deal with error handling</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>You may notice the assignment of the result to the cache happens twice. The reason is that you first want to assign the deferred object to the cache when you start the request &#8212; otherwise if you call the function again before the ajax request finishes it&#8217;ll start a new request rather than reusing the old one. </p>
<p>With this new object (the result of the .pipe) the resolved value will be as we expect it. This relatively simple pattern can get a little more complex if you&#8217;re doing a lot with pipe, but for the consumer the interface is really simple.</p>
<p>Admittedly, there is some complexity to using this pattern but the &#8220;win&#8221; is that your interface now has a &#8220;Single Point of Contact&#8221; (<a href="http://en.wikipedia.org/wiki/Point_of_contact">SPOC</a>)<br />
Let&#8217;s look at a convenient analogy&#8230;</p>
<h2>An Example: Placing a Special Order</h2>
<p>Let&#8217;s imagine that, as an active supporter of your local community businesses, you make it a point to go to your favorite little &#8220;mom and pop&#8221; bookstore to place orders for books. The lady at the counter asks for your phone number or email, and says she&#8217;ll contact you as soon as your books come in. Now obviously, there&#8217;s the small chance that, after the fact, the wholesaler, manufacturer, etc., will have ran out of the ordered book(s). Should this happen, you&#8217;d probably feel it was acceptable for the bookstore to contact you and give you the option to wait or cancel your order. However, you would not want to here directly from the wholesaler or manufacturer directly. This would probably confuse you and you may even complain to the bookstore that they should manage their purchases better should this happen! The expectation you have as a customer in this example is that you only have to deal with a single point of contact. In code, we can have a similar convenience using deferred objects:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Contrived ajax and random failure stubs so we can</span>
<span style="color: #006600; font-style: italic;">// pretend to have &quot;mostly successful&quot; requests</span>
<span style="color: #003366; font-weight: bold;">function</span> randomTrueFalse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> r <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>r<span style="color: #339933;">%</span>9 <span style="color: #339933;">!==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> ajaxStub<span style="color: #009900;">&#40;</span>endpoint<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> dfdResult <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> $.<span style="color: #660066;">Deferred</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> bool <span style="color: #339933;">=</span> randomTrueFalse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>bool<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            dfdResult.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'success: '</span><span style="color: #339933;">+</span>endpoint<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            dfdResult.<span style="color: #660066;">reject</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fail: '</span><span style="color: #339933;">+</span>endpoint<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> dfdResult.<span style="color: #660066;">promise</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> manufacturer <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        orderBook<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>ajaxStub<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/book/'</span><span style="color: #339933;">+</span>bookName<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Manufacturer-DONE: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">return</span> respObj<span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Manufacturer-FAIL: &quot;</span><span style="color: #339933;">,</span> errObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">return</span> errObj<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> wholesaler <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> m <span style="color: #339933;">=</span> manufacturer<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
        orderBook<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>m.<span style="color: #660066;">orderBook</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Wholesaler-DONE: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">return</span> respObj<span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Wholesaler-FAIL: &quot;</span><span style="color: #339933;">,</span> errObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">return</span> errObj<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> retailer <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> w <span style="color: #339933;">=</span> wholesaler<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
        orderBook<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>w.<span style="color: #660066;">orderBook</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Retailer-DONE: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                dfdResult.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Retailer-FAIL: &quot;</span><span style="color: #339933;">,</span> errObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">return</span> errObj<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Notice that, although we have multiple potential points of failure above (e.g.</span>
<span style="color: #006600; font-style: italic;">// Manufacturer, Wholesaler, Retailer, the customer only needs to deal with the</span>
<span style="color: #006600; font-style: italic;">// retailer directly.)</span>
<span style="color: #003366; font-weight: bold;">function</span> makePurchase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Place an order for two books</span>
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">3</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>retailer.<span style="color: #660066;">orderBook</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Great Book - Part &quot;</span> <span style="color: #339933;">+</span> i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Purchaser-DONE... respObj: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fail</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Purchaser-FAIL... err: &quot;</span><span style="color: #339933;">,</span> err<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
makePurchase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/*
Random output for placing order of two books might look like:
Manufacturer-FAIL: fail: /book/Great Book - Part 1
Wholesaler-FAIL: fail: /book/Great Book - Part 1
Retailer-FAIL: fail: /book/Great Book - Part 1
Purchaser-FAIL... err: fail: /book/Great Book - Part 1
Manufacturer-DONE: success: /book/Great Book - Part 2
Wholesaler-DONE: success: /book/Great Book - Part 2
Retailer-DONE: success: /book/Great Book - Part 2
Purchaser-DONE... respObj: success: /book/Great Book - Part 2
*/</span></pre>
</div>
</div>
<p>Start at the bottom at the makePurchase() call and you should see that we&#8217;ve essentially modeled our story of a customer (purchaser) placing an order for two books. Should the purchase succeed or fail, the purchaser will only ever have to deal with the retailer directly (as expected), because the fact that deferred promises can sort of &#8220;bubble back up&#8221; the call chain. This keeps the interface quite clean, and the caller&#8217;s required knowledge of inner working to a minimum.</p>
<h2> Conclusion</h2>
<p>I&#8217;ve purposely kept the examples contrived so you can focus on the principles of deferred objects. If you&#8217;d like to see a variety of other example implementations, <a href="http://jaubourg.net/">Julian Aubourg</a> and <a href="http://addyosmani.com/">Addy Osmani</a> have written a <a href="http://msdn.microsoft.com/en-us/scriptjunkie/gg723713">wonderful article</a> you should definitey have a look at. jQuery deferred objects take a bit to get used to, but provide some very compelling advantages for web applications that require heavy ajax or graphics.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/12/jquery-deferred-objects-part-2/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>backbone.js attaching multiple Routers to the same route</title>
		<link>http://colonelpanic.net/2011/09/backbone-js-attaching-multiple-routers-to-the-same-route/</link>
		<comments>http://colonelpanic.net/2011/09/backbone-js-attaching-multiple-routers-to-the-same-route/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 00:00:46 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=562</guid>
		<description><![CDATA[Recently I had need to attach multiple backbone.js Router objects to the same route; the purpose was to create a page which could have multiple sections that were unaware of each other, since the path gave them all the information they needed. This allowed a much looser form of coupling and gave us a bit [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had need to attach multiple backbone.js Router objects to the same route; the purpose was to create a page which could have multiple sections that were unaware of each other, since the path gave them all the information they needed. This allowed a much looser form of coupling and gave us a bit more of a MVP feel rather than a traditional MVC.</p>
<p>However, after a lot of discussion we ended up scrapping this plan for a slightly different one.  I had already written a patch to make backbone.js routers support multiple route handlers, though, and I didn&#8217;t think it made sense to just throw it out, so I&#8217;ll provide it here.  Keep in mind that this may not work with future versions of backbone.js!</p>
<p>So, without further ado, here it is:</p>
<div id="gist-1223417" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;require&quot;</span><span class="p">,</span> <span class="s2">&quot;./underscore&quot;</span><span class="p">,</span> <span class="s2">&quot;./backbone&quot;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">require</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Backbone.js doesn&#39;t quite do what we want it to, but it almost does;</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// we can modify it so that it does do what we want pretty easily, thanks</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// to the eminent hackability of javascript.</span></div>
<div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//</span></div>
<div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// We may need to update this when backbone.js updates! :-/</span></div>
<div class='line' id='LC7'><br/></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">patched_methods</span> <span class="o">=</span> <span class="p">{</span></div>
<div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Save and rename the old route function, modified to work with the new</span></div>
<div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">override_route</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">.</span><span class="nx">unshift</span><span class="p">({</span><span class="nx">route</span> <span class="o">:</span> <span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span> <span class="o">:</span> <span class="p">[</span><span class="nx">callback</span><span class="p">]});</span></div>
<div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span></div>
<div class='line' id='LC13'><br/></div>
<div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Add a route to be tested when the fragment changes.</span></div>
<div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// RB 9/15/2011: We don&#39;t want routes added later to</span></div>
<div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               override previous routes; we want</span></div>
<div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               routes added later to get called as well.</span></div>
<div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//</span></div>
<div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               With this change, callback becomes an array</span></div>
<div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               of callbacks instead of just one.</span></div>
<div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">route</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">appended</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">handler</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">route</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span> <span class="o">==</span> <span class="nx">route</span><span class="p">.</span><span class="nx">toString</span><span class="p">())</span> <span class="p">{</span></div>
<div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span></div>
<div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">true</span><span class="p">;</span></div>
<div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">appended</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">.</span><span class="nx">unshift</span><span class="p">({</span><span class="nx">route</span> <span class="o">:</span> <span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span> <span class="o">:</span> <span class="p">[</span><span class="nx">callback</span><span class="p">]});</span></div>
<div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span></div>
<div class='line' id='LC32'><br/></div>
<div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Add a feature to remove a route, since we no longer override them</span></div>
<div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">unroute</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">found_and_removed</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">handler</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">route</span> <span class="o">==</span> <span class="nx">route</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC37'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">idx</span> <span class="o">=</span> <span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span></div>
<div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">idx</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">idx</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span></div>
<div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">true</span><span class="p">;</span></div>
<div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></div>
<div class='line' id='LC42'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">false</span><span class="p">;</span></div>
<div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC44'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC45'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC46'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span></div>
<div class='line' id='LC47'><br/></div>
<div class='line' id='LC48'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Attempt to load the current URL fragment. If a route succeeds with a</span></div>
<div class='line' id='LC49'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// match, returns `true`. If no defined routes matches the fragment,</span></div>
<div class='line' id='LC50'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// returns `false`.</span></div>
<div class='line' id='LC51'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// RB 9/15/2011: overriding this function</span></div>
<div class='line' id='LC52'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">loadUrl</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fragmentOverride</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC53'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">fragment</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">fragment</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getFragment</span><span class="p">(</span><span class="nx">fragmentOverride</span><span class="p">);</span></div>
<div class='line' id='LC54'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">matched</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">handler</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC55'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">route</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">fragment</span><span class="p">))</span> <span class="p">{</span></div>
<div class='line' id='LC56'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC57'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="nx">fragment</span><span class="p">);</span></div>
<div class='line' id='LC58'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC59'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">true</span><span class="p">;</span></div>
<div class='line' id='LC60'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC61'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC62'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">matched</span><span class="p">;</span></div>
<div class='line' id='LC63'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC64'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">};</span></div>
<div class='line' id='LC65'><br/></div>
<div class='line' id='LC66'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">History</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="nx">patched_methods</span><span class="p">);</span></div>
<div class='line' id='LC67'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">Backbone</span><span class="p">;</span></div>
<div class='line' id='LC68'><span class="p">});</span></div>
<div class='line' id='LC69'><br/></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1223417/97e8eb2209011f0f342de56664a7b44df3f7d59b/backbone-multihash.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1223417#file_backbone_multihash.js" style="float:right;margin-right:10px;color:#666">backbone-multihash.js</a><br />
            <a href="https://gist.github.com/1223417">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/09/backbone-js-attaching-multiple-routers-to-the-same-route/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Installing VMWare ESXi 4.1.0 on an i7 3.4Ghz and Asus P8Q67-M</title>
		<link>http://colonelpanic.net/2011/07/installing-vmware-esxi-4-1-0-on-i7-and-p8q67-m/</link>
		<comments>http://colonelpanic.net/2011/07/installing-vmware-esxi-4-1-0-on-i7-and-p8q67-m/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 05:28:58 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=530</guid>
		<description><![CDATA[I&#8217;m not going to go into the many reasons why you might want to do this; basically I find myself in need of more computers at my home office than I can conveniently store the boxes for, and I am not doing anything graphics related, so I started looking at how to set up my [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not going to go into the many reasons why you might want to do this; basically I find myself in need of more computers at my home office than I can conveniently store the boxes for, and I am not doing anything graphics related, so I started looking at how to set up my own VPS system; unfortunately, the tools I found were for the most part lacking.</p>
<p>I tried VMWare server for awhile, but found that every time I updated my system everything broke and I had to recompile drivers.</p>
<p>I tried VirtualBox in headless mode, which worked much better; still, it was hard to keep things running well since something always seemed to go wrong if the server got restarted for any reason.</p>
<p>Finally, I decided to invest in a machine to dedicate to the task. I did some research and decided on VMWare ESXi as the host platform &#8212; the free version is plenty for what I need.</p>
<h2>Finding &#8220;Supported&#8221; Hardware</h2>
<p>The list of supported hardware that I found was filled with things outside of my price range; okay, I admit it, I&#8217;m a bit cheap. I&#8217;ll save you the sob story of the time it took me to piece together a system that I thought might work and just give you the list of what I settled on. This is not a &#8220;supported&#8221; setup, but it does work (with a little tinkering with the setup file):</p>
<ul>
<li>$179.99 &#8211; <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820231442">G.SKILL 16GB of ram</a> &#8211; I wanted a little more performance, so I got the faster set.</li>
<li>2 x $139.99 &#8211; <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16822148506">Seagate Barracuda XT 2TB 7200 RPM SATA 6.0GB/s hard drive</a> &#8211; My goal was to mirror these; that hasn&#8217;t turned out to be directly possible, but I have ideas for workarounds.</li>
<li>$29.99 (+$9.99 shipping) <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16811147112">Rosewill R101-P-BK Mid Tower case</a> &#8211; Just about anything would work, but this case seems adequate so far</li>
<li>$59.99 <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16817182200">Rosewill Green Series 630W Power supply</a> &#8211; Again, I wasn&#8217;t really picky, but this one looked decent and specifically says it works for i7 cpus</li>
<li>$299.99 <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16819115071">Intel Core i7-2600 3.4Ghz quad core CPU</a> &#8211; Note that this is the 2600, not the 2600k. There are virtualization features missing on the 2600k.</li>
<li>$139.99 <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16813131766">Asus P8Q67-M LGA 1155 Intel Q67 Motherboard</a> &#8211; This one is where it really got scary and dicy. The new CPUs (like the 2600, not the 2600k) support something called VT-D. Now, I don&#8217;t have this fully working yet, but the Q67 boards are supposed to support it as well; mine says it does, and I have enabled it, but I haven&#8217;t seen it work in VMWare yet, so I&#8217;m not 100% sure if this is working or not.  However, since most of the hardware needing support is on this board, which motherboard you get matters a lot.</li>
</ul>
<p>Total cost of the system after shipping: $1,007.25</p>
<h2>Installing VMWare ESXi</h2>
<p>The first thing I tried, of course, was to install from the ISO I downloaded from VMWare.  Unfortunately, that gave me an ugly python error message; I forget exactly what it said. A little constructive googling turned up that it meant that ESXi couldn&#8217;t find a valid network card.  DRAT! I knew I was right to be worried about the motherboard choice; it has an Intel chipset, but the NIC is not supported by VMWare ESXi. I was quite put out and even started looking to see if any local computer stores had a NIC that was supported so I could get things going today. However, I found something better!</p>
<h2>Customizing the install disk</h2>
<p>As it turns out, there is a <a href="http://vm-help.com/">website (vm-help.com)</a> for people who are running ESXi on hardware other than the &#8220;official supported&#8221; hardware. It took me awhile to find what I needed, but it turns out someone else has already had the issue I did (probably on a different motherboard) and created a driver customization archive (oem.tgz) with the drivers I need!</p>
<p>Here are the steps:</p>
<ol>
<li>Download the latest VMWare ESXi install iso; the one I got was called &#8220;VMware-VMvisor-Installer-4.1.0.update1-348481.x86_64.iso&#8221;</li>
<li>Found and downloaded <a href="http://www.vm-help.com/forum/viewtopic.php?f=12&amp;t=2194&amp;p=11181#p11181">the oem.tgz file (2 rar files that I extracted) that supports the Intel 82579 Gigabit ethernet card</a></li>
<li>Followed <a href="http://www.vm-help.com/forum/viewtopic.php?f=16&amp;t=4">these instructions</a> to use the <a href="http://code.google.com/p/mkesxiaio/">mkesxiaio shell script</a> (on a linux machine) to customize my ISO</li>
<li>Burned the new ISO and installed</li>
</ol>
<p>That was it! It works now! I did of course have to turn on all the virtualization features in the motherboard BIOS settings; I also set the SATA controller to AHCI mode. Really, though, everything seems to work perfectly and I&#8217;m now in the process of adding virtual machines.</p>
<p>Life is good =]</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/07/installing-vmware-esxi-4-1-0-on-i7-and-p8q67-m/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Building a firefox plugin &#8211; part four</title>
		<link>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/</link>
		<comments>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 03:41:01 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=520</guid>
		<description><![CDATA[The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I [...]]]></description>
			<content:encoded><![CDATA[<p>The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I ended up reviewing for an employer where the original author had not previously met me. I never inteded those to be the end of the series, but it has been quite some time since I last posted an update.  The main reason for this is that for all but a few uses &#8212; android in particular &#8212; I no longer recommend anyone write a NPAPI plugin from scratch. The reason for this is that the popular <a href="http://www.firebreath.org">FireBreath</a> framework makes all of this so easy and fixes so many edge cases in different browser versions that it isn&#8217;t worth doing it by hand anymore.</p>
<p>Yes, I wrote <a href="http://www.firebreath.org">FireBreath</a>. A lot of others have contributed.</p>
<h2>A different approach to learning NPAPI</h2>
<p>Now that I have a good example already up and running, it seems pointless to keep trying to describe things with words and code snippets when I can simply walk you through what I have done &#8212; what is in use and works well. To that end, and in hopes that it will foster more capable NPAPI developers to help with FireBreath development (we still don&#8217;t support printing, for example), I have created a series of 5 minute screencasts providing a brief overview of FireBreath&#8217;s NPAPI framework.</p>
<p>I don&#8217;t expect that this is as comprehensive as it should be; I&#8217;m hoping that comments will help me see what future segments I should create.  I have posted these screencasts on youtube and will link to them from here. You can also find a more complete series that includes this one <a href="http://www.firebreath.org/display/documentation/FireBreath+development+video+tutorials">on the FireBreath website</a>.</p>
<p><iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/ehHfsxj2xSk" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/VbHW4HvitIg" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/RtPyEpiTFxY" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/c17kvVxoNGU" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/SQtduyKCAZ8" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/4NxLMDUHufE" frameborder="0"><br />
</iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Jenkins on Mac OS X; git w/ ssh public key</title>
		<link>http://colonelpanic.net/2011/06/jenkins-on-mac-os-x-git-w-ssh-public-key/</link>
		<comments>http://colonelpanic.net/2011/06/jenkins-on-mac-os-x-git-w-ssh-public-key/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 20:22:08 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=514</guid>
		<description><![CDATA[Jenkins on Mac OS X I just finished setting up a build server on Mac OS X using Jenkins (formerly Hudson). The company I&#8217;m working for (GradeCam) uses git and gitolite for our source control and so I expected no trouble using Jenkins to build our tools using the git plugin. However, I quickly ran [...]]]></description>
			<content:encoded><![CDATA[<h1>Jenkins on Mac OS X</h1>
<p>I just finished setting up a build server on Mac OS X using Jenkins (formerly Hudson). The company I&#8217;m working for (<a href="http://www.gradecam.com" target="_blank">GradeCam</a>) uses git and gitolite for our source control and so I expected no trouble using Jenkins to build our tools using the git plugin.</p>
<p>However, I quickly ran into a snag: the source control server is on a public address and so our source code is not available except via ssh, and gitolite ssh access uses private key authentication.  Well, I&#8217;m an experience unix sysadmin, so that didn&#8217;t sound like a big issue &#8212; after all, setting up public key authentication is childs play, right?</p>
<h2>Default install</h2>
<p>The default installation of Jenkins on Mac OS X (at the time of this writing) installs a Launch Agent plist to /Library/LaunchAgents/org.jenkins-ci.plist. This plist file causes Jenkins to load as user &#8220;daemon&#8221;, which sounds fine &#8212; except that the home directory for the &#8220;daemon&#8221; user is /var/root, same as for user root.  This means that the .ssh dir in there will never have the right permissions for a private key to be used.</p>
<h2>Creating a new hidden user</h2>
<p>My solution was to create a new &#8220;hidden&#8221; user for Jenkins to run under. Following instructions I found on a <a href="http://hints.macworld.com/article.php?story=20080127172157404" target="_blank">blog post</a>, I created a user &#8220;jenkins&#8221; with a home directory &#8220;/Users/Shared/Jenkins/Home&#8221;:</p>
<pre>sudo dscl . create /Users/jenkins
sudo dscl . create /Users/jenkins PrimaryGroupID 1
sudo dscl . create /Users/jenkins UniqueID 300   
sudo dscl . create /Users/jenkins UserShell /bin/bash
sudo dscl . passwd /Users/jenkins $PASSWORD
sudo dscl . create /Users/jenkins home /Users/Shared/Jenkins/Home/</pre>
<p>I then stopped Jenkins: &#8220;sudo launchctl unload -w /Library/LaunchAgents/org.jenkins-ci.plist&#8221; and <a href="https://gist.github.com/1028036">edited the plist file</a> to set the username to jenkins instead of daemon.  &#8220;chown -R jenkins: /Users/Shared/Jenkins/Home&#8221; sets the permissions how they need to be, and then &#8220;sudo launchctl load -w /Library/LaunchAgents/org.jenkins-ci.plist&#8221; should get you up and running!</p>
<p>To get git over ssh running, &#8220;sudo su &#8211; jenkins&#8221; to get a console as the jenkins user and set up the ssh keys and such. Make sure you can ssh to where you want to go (or even do a test git clone) because you need to save the keys so it doesn&#8217;t ask for them when jenkins tries to do the clone.</p>
<p>That should do you! Hope it helps someone.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/06/jenkins-on-mac-os-x-git-w-ssh-public-key/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Git and gitolite nirvana</title>
		<link>http://colonelpanic.net/2011/01/git-and-gitolite-nirvana/</link>
		<comments>http://colonelpanic.net/2011/01/git-and-gitolite-nirvana/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 20:05:11 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=480</guid>
		<description><![CDATA[Having recently begun switching all of my projects to use git for source control, I have been using gitosis on my server and have been pretty happy with it. However, the one thing that kinda annoyed me was that every time I wanted to create a new repository, I had to go add it to [...]]]></description>
			<content:encoded><![CDATA[<p>Having recently begun switching all of my projects to use git for source control, I have been using gitosis on my server and have been pretty happy with it. However, the one thing that kinda annoyed me was that every time I wanted to create a new repository, I had to go add it to the config file.  I found myself making up excuses to just use a raw ssh to my server at home.  This, of course, was also a bit of a pain since I had to go set up a raw repository each time I wanted to do it&#8230;</p>
<h2>Enter gitolite</h2>
<p>Gitolite has a really cool feature that I make heavy use of called &#8220;wildcard repositories&#8221;. The way I use it, this lets me set up a group of users (@wildcardusers) that can create whatever arbitrary repositories they want in a subdirectory of the same name as their username.</p>
<p>In the gitolite.conf file:</p>
<div class="wp_syntax">
<div class="code">
<pre class="conf" style="font-family:monospace;">@wildcard_users = richard jarom ben
&nbsp;
repo    CREATOR/.*
    C     = @wildcard_users
    CRW+D = CREATOR
    RW    = WRITERS
    R     = READERS</pre>
</div>
</div>
<p>Voila! I can now push to any repo looking like git@my_server.net:richard/my_repo.git</p>
<h2>Setting the default remote HEAD</h2>
<p>Ben and I happily used this for the better part of a day before we ran into our first disappointing snag. Ben is a huge fan (and I as well to a lesser extent) of <a title="Git-flow" href="https://github.com/nvie/gitflow">git-flow</a>, but with the layout we normally use with git-flow the default repository should be named &#8220;develop&#8221; instead of &#8220;master&#8221;.  Well, no problem, right?  A quick git checkout -b develop and we have a develop branch, then git branch -D master and the master branch is gone.  git push origin :master removes it from the gitolite server, and we&#8217;re ready to roll!</p>
<p>Oops! When we clone the repository, it clones okay but gives us an error at the end that it can&#8217;t find the HEAD ref. This is aparently a normal git configuration thing that has to be done on the server, but users who can create wildcard repositories shouldn&#8217;t need shell access on the box!</p>
<p>Fortunately, gitolite supports Admin Defined Commands (ADCs). They are suprisingly easy to use if you know a bit of shell script programming (or python, as I&#8217;ll explain later). As of a commit last night, there is now a <a href="https://github.com/sitaramc/gitolite/blob/pu/contrib/adc/set-head">set-head</a> ADC in the contrib directory in the main repo.</p>
<pre>ssh git@my_server.net set-head richard/my_repo.git refs/heads/develop
</pre>
<p>Simple as that, the HEAD is changed!  Note that ADCs have to be <a href="https://github.com/sitaramc/gitolite/blob/pu/doc/admin-defined-commands.mkd">enabled and configured</a> before you can use them.</p>
<h2>Giving other users access to your repo</h2>
<p>As you probably gathered earlier, this server is used by a small group of people who often work on projects together. Sometimes we need to give someone else access to our repository.  We might also want to just give access to anyone through the git:// protocol (which gitolite supports when configured correctly using the daemon user).</p>
<p>You can do this using the setperms and getperms built-in ADC.  However, these are a little inflexible for my tastes, and I had a few minutes, so I wrote a quick <a href="https://github.com/sitaramc/gitolite/blob/pu/contrib/adc/pygitolite.py">python helper class</a> for writing ADCs and threw together the <a href="https://github.com/sitaramc/gitolite/blob/pu/contrib/adc/perms">perms</a> ADC, which is also in the main repo now.</p>
<p>You can run the command and see the help for yourself, but here is a quick example of what you can do:</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;">richard<span style="color: #000000; font-weight: bold;">@</span>machine:~ $ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>my_server.net perms
Usage: perms <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #7a0874; font-weight: bold;">command</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>repository<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>args<span style="color: #000000; font-weight: bold;">&gt;</span>
             list <span style="color: #000000; font-weight: bold;">&lt;</span>repository<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>TYPE<span style="color: #7a0874; font-weight: bold;">&#93;</span>
             <span style="color: #c20cb9; font-weight: bold;">clear</span> <span style="color: #000000; font-weight: bold;">&lt;</span>repository<span style="color: #000000; font-weight: bold;">&gt;</span>
             add <span style="color: #000000; font-weight: bold;">&lt;</span>repository<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>TYPE<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>user and group list<span style="color: #7a0874; font-weight: bold;">&#93;</span>
             <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #000000; font-weight: bold;">&lt;</span>repository<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>TYPE<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>user and group list<span style="color: #7a0874; font-weight: bold;">&#93;</span>
             remove <span style="color: #000000; font-weight: bold;">&lt;</span>repository<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>TYPE<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>user and group list<span style="color: #7a0874; font-weight: bold;">&#93;</span>
&nbsp;
richard<span style="color: #000000; font-weight: bold;">@</span>machine:~ $ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>my_server.net perms list richard<span style="color: #000000; font-weight: bold;">/</span>test.git
WRITERS:
    fred
READERS:
    ben
    jarom
richard<span style="color: #000000; font-weight: bold;">@</span>machine:~ $ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>my_server.net perms add richard<span style="color: #000000; font-weight: bold;">/</span>test.git WRITERS billy
WRITERS:
    fred
    billy
richard<span style="color: #000000; font-weight: bold;">@</span>machine:~ $ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>my_server.net perms add richard<span style="color: #000000; font-weight: bold;">/</span>test.git READERS joe
READERS:
    ben
    jarom
    joe
richard<span style="color: #000000; font-weight: bold;">@</span>machine:~ $ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>my_server.net perms remove richard<span style="color: #000000; font-weight: bold;">/</span>test.git READERS jarom
READERS:
    ben
    joe
richard<span style="color: #000000; font-weight: bold;">@</span>machine:~ $ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>my_server.net perms <span style="color: #000000; font-weight: bold;">set</span> richard<span style="color: #000000; font-weight: bold;">/</span>test.git READERS ben jarom
READERS:
    ben
    jarom
richard<span style="color: #000000; font-weight: bold;">@</span>machine:~ $ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>my_server.net perms list richard<span style="color: #000000; font-weight: bold;">/</span>test.git
WRITERS:
    fred
    billy
READERS:
    ben
    jarom</pre>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/01/git-and-gitolite-nirvana/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CMake Tip: Find the path to Visual Studio</title>
		<link>http://colonelpanic.net/2010/12/cmake-tip-find-the-path-to-visual-studio/</link>
		<comments>http://colonelpanic.net/2010/12/cmake-tip-find-the-path-to-visual-studio/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 17:25:51 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=471</guid>
		<description><![CDATA[Finding ATL headers I needed to find the ATL headers that should be used with the currently selected generator in my CMake project (FireBreath). The reason for this is that if the user is running Visual Studio Express edition, the ATL headers won&#8217;t be there so we need to look for the Windows DDK (Driver [...]]]></description>
			<content:encoded><![CDATA[<h2>Finding ATL headers</h2>
<p>I needed to find the ATL headers that should be used with the currently selected generator in my CMake project (<a href="http://www.firebreath.org" target="_blank">FireBreath</a>). The reason for this is that if the user is running Visual Studio Express edition, the ATL headers won&#8217;t be there so we need to look for the Windows DDK (Driver Development Kit) and use the headers from that.  If that isn&#8217;t there, we should throw an error.</p>
<p>Turns out that finding the path to the VC directory isn&#8217;t really that hard, but you have to know how =]  I found the registry paths (as well as how to use them in CMake) in the CMake source code.  Here is the snippet in hopes it will help someone:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cmake" style="font-family:monospace;"><span style="color: #1f3f81; font-style: bold;">if</span> <span style="color: #197d8b;">(</span>MSVC10<span style="color: #197d8b;">)</span>
    <span style="color: #1f3f81; font-style: bold;">GET_FILENAME_COMPONENT</span><span style="color: #197d8b;">(</span>VS_DIR <span style="color: #197d8b;"><span style="color: #0000cd;">[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VS;ProductDir]</span></span> REALPATH <span style="color: #077807; font-sytle: italic;">CACHE</span><span style="color: #197d8b;">)</span>
<span style="color: #1f3f81; font-style: bold;">elseif</span> <span style="color: #197d8b;">(</span>MSVC90<span style="color: #197d8b;">)</span>
    <span style="color: #1f3f81; font-style: bold;">GET_FILENAME_COMPONENT</span><span style="color: #197d8b;">(</span>VS_DIR <span style="color: #197d8b;"><span style="color: #0000cd;">[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VS;ProductDir]</span></span> REALPATH <span style="color: #077807; font-sytle: italic;">CACHE</span><span style="color: #197d8b;">)</span>
<span style="color: #1f3f81; font-style: bold;">elseif</span> <span style="color: #197d8b;">(</span>MSVC80<span style="color: #197d8b;">)</span>
    <span style="color: #1f3f81; font-style: bold;">GET_FILENAME_COMPONENT</span><span style="color: #197d8b;">(</span>VS_DIR <span style="color: #197d8b;"><span style="color: #0000cd;">[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VS;ProductDir]</span></span> REALPATH <span style="color: #077807; font-sytle: italic;">CACHE</span><span style="color: #197d8b;">)</span>
<span style="color: #1f3f81; font-style: bold;">endif</span><span style="color: #197d8b;">()</span></pre>
</div>
</div>
<p>This should work on Visual Studio 2005, 2008, and 2010.  Other versions could be added if you care. FireBreath only supports 2005 on, so I didn&#8217;t bother. (Might actually work on older versions, but I haven&#8217;t tried). The path to the Visual Studio directory should end up in VS_DIR.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/12/cmake-tip-find-the-path-to-visual-studio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FireBreath Tips: Asynchronous Javascript Calls</title>
		<link>http://colonelpanic.net/2010/12/firebreath-tips-asynchronous-javascript-calls/</link>
		<comments>http://colonelpanic.net/2010/12/firebreath-tips-asynchronous-javascript-calls/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 00:12:58 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[blocking calls]]></category>
		<category><![CDATA[firebreath]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsapi]]></category>
		<category><![CDATA[jsobject]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=463</guid>
		<description><![CDATA[Never block a Javascript call! One cardinal rule of browser plugins is that you should never block the thread when processing a method or property call from Javascript.  In FireBreath, that means that any method or property on your JSAPI must never block, but should return in a timely manner. The reason for this is [...]]]></description>
			<content:encoded><![CDATA[<h2>Never block a Javascript call!</h2>
<p>One cardinal rule of browser plugins is that you should never block the thread when processing a method or property call from Javascript.  In FireBreath, that means that any method or property on your JSAPI must <em><strong>never</strong></em> block, but should return in a timely manner.</p>
<p>The reason for this is that Javascript is effectively not a multi-threaded language. The way that Javascript handles setTimeout and setInterval varies, but from the perspective of your plugin, all JSAPI calls come in on the same thread &#8212; the UI thread. If you block on a JSAPI call the whole web browser will lock up until you finish.</p>
<p>In the programming circles that I hang out in, this is considered a Bad Thing.</p>
<p>However, there are often cases when you may need to perform some operation that is inherently blocking &#8212; such as searching the filesystem, processing a large file, or making a network request. There are doubtless several ways you could deal with this, but perhaps the easiest is to run the blocking operation on a new thread, and then call back into Javascript when you&#8217;re done.</p>
<p>If you think about it, this is why AJAX calls are all asynchronous.</p>
<h2>FB::JSObjectPtr to the rescue!</h2>
<p>One of the types supported by FireBreath is <a href="http://www.firebreath.org/display/documentation/class+FB+JSObject"  target="_blank">FB::JSObject</a>.  This represents any type of Javascript object that is passed in &#8212; so basically anything other than a primitive datatype. This includes arrays, raw objects (key : value stores), and functions as well as other things like DOM objects.</p>
<p>FB:JSObject has a method <a href="http://www.firebreath.org/display/documentation/class%20FB%20JSObject%20InvokeAsync" target="_blank">InvokeAsync</a> that works the same way as Invoke would on a normal <a href="http://www.firebreath.org/display/documentation/class%20FB%20JSAPI">JSAPI</a> object except that the call is asynchronous, so it doesn&#8217;t have a return value and thus doesn&#8217;t wait for the call to complete before returning. If we want, we can even pass back a reference to the current API object in the callback. To call a function (instead of a method on an object), we pass an empty string in for the method name when we call <a href="http://www.firebreath.org/display/documentation/class%20FB%20JSAPI%20Invoke%20%282%29" target="_blank">Invoke</a> or InvokeAsync.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Say we have a FB::JSObjectPtr callback</span>
callback<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>InvokeAsync<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;&quot;</span>, FB<span style="color: #008080;">::</span><span style="color: #007788;">variant_list_of</span><span style="color: #008000;">&#40;</span>shared_from_this<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Creating a thread</h2>
<p>FireBreath relies on the boost thread library; this means that it is quite simple to create a new thread, particularly to run something minor.  Keep in mind that my purpose isn&#8217;t to talk about proper techniques for multithreaded programming, so you&#8217;ll have to worry about things like making sure that your threads have all ended before shutting down and so forth on your own.</p>
<p>With boost thread, basically you just create a function that will be run on the other thread and use boost::bind to provide that method object<del datetime="2011-01-19T20:25:08+00:00"> (with a shared_from_this to the object instance to keep it from going away while the thread is running) to the thread constructor</del>. <strong>Edit 1/19/2010:</strong> Someone rightly pointed out that using shared_from_this may not be (in fact usually is not) optimal. If you want to stop the thread when the JSAPI object goes away, you should pass &#8220;this&#8221; instead of shared_from_this.  The code below has been updated to reflect that.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    boost<span style="color: #008080;">::</span><span style="color: #007788;">thread</span> t<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">bind</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming_thread</span>,
         <span style="color: #0000dd;">this</span>, num, callback<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Putting it together</h2>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming</span><span style="color: #008000;">&#40;</span> <span style="color: #0000ff;">int</span> num, FB<span style="color: #008080;">::</span><span style="color: #007788;">JSObjectPtr</span> <span style="color: #000040;">&amp;</span>callback <span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">thread</span> t<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">bind</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming_thread</span>,
         <span style="color: #0000dd;">this</span>, num, callback<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span> <span style="color: #666666;">// the thread is started</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming_thread</span><span style="color: #008000;">&#40;</span> <span style="color: #0000ff;">int</span> num, FB<span style="color: #008080;">::</span><span style="color: #007788;">JSObjectPtr</span> <span style="color: #000040;">&amp;</span>callback <span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Do something that takes a long time here</span>
    <span style="color: #0000ff;">int</span> result <span style="color: #000080;">=</span> num <span style="color: #000040;">*</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span>
    callback<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>InvokeAsync<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;&quot;</span>, FB<span style="color: #008080;">::</span><span style="color: #007788;">variant_list_of</span><span style="color: #008000;">&#40;</span>shared_from_this<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>result<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>As you can see, when doSomethingTimeConsuming is called it accepts a callback. It creates a new thread and gives it the callback function.</p>
<h2>Synchronous calls</h2>
<p>It should also be noted that calls to Invoke on a FB::JSObject will also be threadsafe &#8212; they can be called from any thread. Keep in mind that a mutex and signal are being used behind to scenes to block until after the call is made to Javascript on the main thread, so there will be a performance hit for this.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/12/firebreath-tips-asynchronous-javascript-calls/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>FireBreath Tips: Drawing on Windows</title>
		<link>http://colonelpanic.net/2010/11/firebreath-tips-drawing-on-windows/</link>
		<comments>http://colonelpanic.net/2010/11/firebreath-tips-drawing-on-windows/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 18:17:55 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[drawing]]></category>
		<category><![CDATA[firebreath]]></category>
		<category><![CDATA[gdi]]></category>
		<category><![CDATA[hwnd]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=461</guid>
		<description><![CDATA[FireBreath Window Abstraction It is an interesting thing to me that so many people seem to have a hard time understanding how the FireBreath windowing abstraction works, since to me it seems fairly clear. Of course, I wrote it, so that&#8217;s probably the reason =] There are a few things you should understand before you [...]]]></description>
			<content:encoded><![CDATA[<h1>FireBreath Window Abstraction</h1>
<p>It is an interesting thing to me that so many people seem to have a hard time understanding how the FireBreath windowing abstraction works, since to me it seems fairly clear. Of course, I wrote it, so that&#8217;s probably the reason =] There are a few things you should understand before you start trying to do your drawing on Windows:</p>
<h2>PluginWindow</h2>
<p>Every platform has a <a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindow" target="_blank">PluginWindow</a>.  In fact, some platforms (<a href="http://www.firebreath.org/display/documentation/Mac+Plugins" target="_blank">most notably Mac</a>) have several different types of PluginWindow depending on which drawing model and event model you use.  The PluginWindow is the source of all system events for the plugin.</p>
<p>In the default plugin skeleton generated by fbgen there are several Events mapped:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">BEGIN_PLUGIN_EVENT_MAP<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    EVENTTYPE_CASE<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">AttachedEvent</span>, onWindowAttached, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span><span style="color: #008000;">&#41;</span>
    EVENTTYPE_CASE<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">DetachedEvent</span>, onWindowDetached, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span><span style="color: #008000;">&#41;</span>
END_PLUGIN_EVENT_MAP<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></pre>
</div>
</div>
<p>Then the matching handlers are:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> onWindowAttached<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">AttachedEvent</span> <span style="color: #000040;">*</span>evt, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span> <span style="color: #000040;">*</span>wnd<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> onWindowDetached<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">DetachedEvent</span> <span style="color: #000040;">*</span>evt, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span> <span style="color: #000040;">*</span>wnd<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p><a href="http://www.firebreath.org/display/documentation/class+FB+AttachedEvent" target="_blank">FB::AttachedEvent</a> will be fired each time a window is attached to the plugin.  <a href="http://www.firebreath.org/display/documentation/class+FB+DetachedEvent" target="_blank">FB::DetachedEvent</a> will be fired each time a window is detached from the plugin.  <em><strong>NOTE:</strong></em> <em>Though in practice each of these usually get fired only once per plugin instance, there is no guarantee in the browser contract that it won&#8217;t take away the window it gave you and give you a different one.</em></p>
<h2>PluginWindowWin</h2>
<p>The main plugin object is, by default, a platform agnostic object.  There are several ways that you can do your windows specific drawing:</p>
<ol>
<li>Make your plugin object windows specific<br />
<blockquote><p>This is certainly the easiest way, though the least friendly to cross-platform development; you could just change the type of the event source specified in EVENTTYPE_CASE to FB::PluginWindowWin (as well as the type in the handlers) and you will have your object cast in the way you need it.</p></blockquote>
<blockquote><p>Note that FB::PluginWindowWin is in
<pre>#include "Win/PluginWindowWin.h"</pre>
</blockquote>
</li>
<li>Create a platform specific subclass of your plugin object<br />
<blockquote><p>This is actually fairly easy. Simply create an object (Such as MyPluginWin) in the Win/ directory that extends your main (MyPlugin) object and move Factory.cpp into your Win/ directory.  If you support other platforms, you&#8217;ll need to create a subclass and factory for each platform you want to support.  Then modify each Factory.cpp so that createPlugin returns the platform-specific plugin object.  Then you can make platform-specific event code to get your PluginWindowWin object.</p></blockquote>
</li>
<li>Use #ifdef FB_WIN to have platform specific code in your plugin object<br />
<blockquote><p>Don&#8217;t do this.  It&#8217;s messy and ugly.  Still, you can if you want. To get a PluginWindowWin* from your PluginWindow* object, you can do:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindowWin</span> <span style="color: #000040;">*</span>pwnd <span style="color: #000080;">=</span> wnd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>get_as<span style="color: #000080;">&lt;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindowWin</span><span style="color: #000040;">*</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
</blockquote>
</li>
<li>Create a platform specific object and pass the window and other information to it to draw<br />
<blockquote><p>Use the same method mentioned previously to convert the PluginWindow to a PluginWindowWin. This is the method that the BasicMediaPlayer example (found in examples/) uses.</p></blockquote>
</li>
</ol>
<p>Once you have your <a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin" target="_blank">PluginWindowWin</a> object, you can get the information you need to do the actual drawing with a few functions:</p>
<ol>
<li><a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin+getHWND" target="_blank">getHWND</a>() &#8211; returns the HWND assigned to the browser plugin</li>
<li><a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin+getBrowserHWND" target="_blank">getBrowserHWND</a>() &#8211; returns the HWND of the top-level browser window</li>
<li><a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin+InvalidateWindow" target="_blank">InvalidateWindow</a>() &#8211; instructs the browser to invalidate the window and give you a <a href="http://www.firebreath.org/display/documentation/class+FB+RefreshEvent" target="_blank">RefreshEvent</a> (fired when a WM_PAINT is received)</li>
</ol>
<h2>When to draw</h2>
<p>Once you have the HWND, the next thing you need to know is when you can draw.  There are a few guidelines:</p>
<ul>
<li>Whenever a RefreshEvent is received, you <strong>must</strong> redraw. If you are using a secondary thread to draw, make sure you have some way of passing the message to that thread or you will get flickering.</li>
<li>You can create your own rendering / drawing loop and draw whenever you want. In order to do this, you must create thread to handle the drawing; remember that in the instance of a DetachedEvent you should be able to tell this to stop drawing! If you choose to use something like OpenGL or D3D, you should (sometimes <strong>must</strong>) do all initialization and drawing on the same secondary thread.</li>
<li>Remember that these are windowed plugins, which means that the plugin will &#8220;float&#8221; above everything else on the page.</li>
</ul>
<h2>Handling custom windows messages (your own WINPROC)</h2>
<p>If you need to handle the windows messages directly rather than using the FireBreath abstractions, there are two ways to do this.</p>
<ol>
<li>Extend PluginWindowWin and override the virtual function CustomWinProc<br />
<blockquote><p>This is the most direct way; CustomWinProc will get called for all unhandled messages.  If you don&#8217;t do anything but return false in <a href="http://www.firebreath.org/display/documentation/class+FB+PluginEventSink+HandleEvent" target="_blank">HandleEvent</a>, all messages will be unhandled. To override which object is created for the PluginWindow, implement the <a href="http://www.firebreath.org/display/documentation/file%20FactoryBase.cpp#l00056" target="_blank">createPluginWindowWin</a> method on your Factory to return your custom window class (which <strong>must</strong> extend PluginWindowWin)</p></blockquote>
</li>
<li>Handle <a href="http://www.firebreath.org/display/documentation/class+FB+WindowsEvent">WindowsEvent</a><br />
<blockquote><p>This is the way that we recommend. This can be done by simply adding an EVENTTYPE_CASE line. All of the arguments given in an event loop are available as members of the WindowsEvent object. This makes it possible to pass the object through to the correct place without having a platform-specialized class, if desired.</p></blockquote>
</li>
</ol>
<h1>FireBreath is flexible</h1>
<p>One of the main design goals of FireBreath is to allow a user to extend it however they want to make it work how they are most accustomed; that is why there are so many options. Some restrictions are imposed externally by the nature of browser plugins. In all things, we recommend doing the simplest thing and only override existing classes if you need to &#8212; those are the solutions most likely to break with future versions.</p>
<p>As always, if you have questions or need help, feel free to <a href="http://www.firebreath.org/display/documentation/IRC+Access" target="_blank">drop into the IRC room</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/11/firebreath-tips-drawing-on-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

