<?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>Eli Thompson&#039;s Blog</title>
	<atom:link href="http://eli.eliandlyndi.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://eli.eliandlyndi.com</link>
	<description>Code and thoughts from life as an interwebz developer</description>
	<lastBuildDate>Fri, 19 Oct 2012 00:20:29 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Static resource caching and cache-busting with ASP.NET MVC and AppHarbor</title>
		<link>http://eli.eliandlyndi.com/2012/02/15/static-resource-caching-cache-busting-asp-net-mvc-appharbor/</link>
		<comments>http://eli.eliandlyndi.com/2012/02/15/static-resource-caching-cache-busting-asp-net-mvc-appharbor/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 04:43:49 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[appharbor]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[busting]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/?p=208</guid>
		<description><![CDATA[Serving static content (javascript, css, images) with headers specifying long cache expirations is easy. However, cache-busting those is hard. In this post, I&#8217;ll show how to deliver static content with cache-busting URLs. I&#8217;m going to show code which I wrote &#8230; <a href="http://eli.eliandlyndi.com/2012/02/15/static-resource-caching-cache-busting-asp-net-mvc-appharbor/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Serving static content (javascript, css, images) with headers specifying long cache expirations is easy. However, cache-busting those is hard. In this post, I&#8217;ll show how to deliver static content with cache-busting URLs.</p>
<p>I&#8217;m going to show code which I wrote specifically to use with <a href="http://appharbor.com">AppHarbor</a>, but you may find that you can use the same techniques in different environments.</p>
<h2>Cache-busting Technique: Versioned Path</h2>
<p>The most reliable method of cache busting is to put some version identifier in the path to the static content such as:</p>
<pre class="brush: plain; title: ; notranslate">http://localhost/statics/12345678/css/style.css</pre>
<p>Where 12345678 is the version identifier. This method even works with CDNs which might otherwise ignore lesser important path tokens like querystring parameters or an identifier after a hash mark.</p>
<p>In the code below, I&#8217;ll show a solution which includes the version identifier in the path to the static content Version identifier changes whenever a build is released to AppHarbor.</p>
<h2>How It Works</h2>
<p>A browser makes a request to your server for your homepage. The server delivers the homepage and references to static resources using the versioned path.</p>
<p>The browser requests those static resources from your server. The server finds the resources requested, adds headers,</p>
<pre class="brush: plain; title: ; notranslate">Cache-Control: public
Expires:Fri, 15 Feb 2013 02:45:01 GMT // a year from now</pre>
<p>and serves them.</p>
<p>The browser keeps the resources in its cache for a long time and future requests for them are served from cache.</p>
<p>You ship new code to AppHarbor. AppHarbor builds and deploys your application. <a href="http://support.appharbor.com/kb/getting-started/managing-environments">It also adds a configuration setting into your web.config</a> with a key of <strong>appharbor.commit_id </strong>and the value is set to the last changeset ID. Your server uses that changeset ID as the  version identifier in static resource paths.</p>
<p>The browser makes a request for your homepage again. The server delivers the homepage, but this time references the static resources using the new version identifier.</p>
<p>The browser now must request those static resources again because the version identifier has changed. The server serves up the updated files back to the browser where they&#8217;re cached again.</p>
<p><strong>Caveat</strong>: browsers will have to request all static resources again every time a build is deployed. I&#8217;m very happy to accept this. Alternatively, you could do crazy things like get a hash of the file and serve that as part of the file&#8217;s path. See <a href="http://codebetter.com/karlseguin/2010/01/11/asp-net-performance-part-3-cache-busting/">Karl Seguin&#8217;s article about cache busting</a> if you&#8217;re interested in that sort of thing.</p>
<h2>How To Do This In Code</h2>
<p>First, you&#8217;ll need to be able to provide static resource urls. I like to write them like this:</p>
<script src="https://gist.github.com/1840989.js?file=SampleStaticContentUsage.cshtml"></script><noscript><pre><code class="language- ">@using Core.Html
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;link rel=&quot;Stylesheet&quot; href=&quot;@Url.StaticContent(&quot;~/css/style.css&quot;)&quot; /&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;@Url.StaticContent(&quot;~/Scripts/script.js&quot;)&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    
&lt;/body&gt;
&lt;/html&gt;
</code></pre></noscript>
<p>Which means I&#8217;ll need an extension method on the UrlHelper:</p>
<script src="https://gist.github.com/1840989.js?file=HtmlHelperExtensions.cs"></script><noscript><pre><code class="language-c# c#">using System;
using System.Configuration;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;

namespace Core.Html
{
    public static class HtmlHelperExtensions
    {
        public static string StaticContent(this UrlHelper helper, string contentPath)
        {
            var staticResourceVersion = (ConfigurationManager.AppSettings.Get(&quot;appharbor.commit_id&quot;) ?? &quot;_default&quot;).Substring(0, 8);
            var staticServer = ConfigurationManager.AppSettings.Get(ConfigKeys.StaticServer);
            var prefix = &quot;&quot;;
            if (!string.IsNullOrEmpty(staticServer))
                prefix = &quot;//&quot; + staticServer;
            
            return prefix + &quot;/s/&quot; + staticResourceVersion + helper.Content(contentPath);
        }
    }
}</code></pre></noscript>
<p>In the StaticContent method, I&#8217;m populating the staticResourceVersion variable from a configuration value which is in my web.config. If one is not set, like when you&#8217;re running your site locally, &#8220;_default&#8221; is provided.</p>
<p>Another thing to note is that if the staticServer variable is populated, then it&#8217;ll be prepended to the returned url. This supports <a href="http://developer.yahoo.com/performance/rules.html#cookie_free">serving static content from a cookie-less domain</a>.</p>
<p>Now that static content can be referenced, we need to have a route and a controller to handle requests for static content.</p>
<script src="https://gist.github.com/1840989.js?file=Global.asax.cs"></script><noscript><pre><code class="language-c# c#">namespace Website
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute(&quot;{resource}.axd/{*pathInfo}&quot;);

            routes.MapRoute(
                &quot;Statics&quot;,
                &quot;s/{staticResourceVersion}/{*path}&quot;,
                new { controller = &quot;Statics&quot;, action = &quot;Index&quot; }
            );

            routes.MapRoute(
                &quot;Default&quot;, // Route name
                &quot;{controller}/{action}/{id}&quot;, // URL with parameters
                new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional } // Parameter defaults
            );
        }
    }
}</code></pre></noscript>
<p>The first and third routes are the default ones that come with MVC. The middle route understands how to handle requests which start with s/ followed by the version identifier and then whatever the path to the resource is. It directs those requests to the StaticsController&#8217;s Index action.</p>
<script src="https://gist.github.com/1840989.js?file=StaticsController.cs"></script><noscript><pre><code class="language-c# c#">using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Website.Controllers
{
    public class StaticsController : Controller
    {
        private readonly HttpResponseBase _response;
        private readonly HttpRequestBase _request;

        public StaticsController(HttpResponseBase response, HttpRequestBase request)
        {
            _response = response;
            _request = request;
        }

        public ActionResult Index(string staticResourceVersion, string path)
        {
            if (!IsAllowed(path))
                return new HttpStatusCodeResult(404);

            if (!_request.IsLocal)
            {
                _response.Cache.SetCacheability(HttpCacheability.Public);
                _response.Cache.SetExpires(DateTime.Now.AddYears(1));
            }

            return File(Server.MapPath(&quot;~/&quot; + path), GetContentType(path));
        }

        private bool IsAllowed(string path)
        {
            if (string.IsNullOrEmpty(path))
                return false;

            var lowerPath = path.ToLower();

            if (!lowerPath.StartsWith(&quot;img/&quot;) &amp;&amp; !lowerPath.StartsWith(&quot;scripts/&quot;) &amp;&amp; !lowerPath.StartsWith(&quot;css/&quot;))
                return false;

            if (!lowerPath.EndsWith(&quot;.png&quot;) &amp;&amp; !lowerPath.EndsWith(&quot;.css&quot;) &amp;&amp; !lowerPath.EndsWith(&quot;.js&quot;))
                return false;

            if (lowerPath.Contains(&quot;..&quot;))
                return false;

            return true;
        }

        private static string GetContentType(string path)
        {
            var extension = Path.GetExtension(path);
            switch (extension)
            {
                case &quot;.js&quot;:
                    return &quot;text/javascript&quot;;
                case &quot;.css&quot;:
                    return &quot;text/css&quot;;
                case &quot;.png&quot;:
                    return &quot;image/png&quot;;
            }
            return null;
        }

    }
}</code></pre></noscript>
<p>The StaticController&#8217;s Index action first needs to check if the requested path is allowed. We certainly wouldn&#8217;t want to serve just any content back through here. (I&#8217;m showing a really simple IsAllowed implementation, please feel free to be smarter about yours.)</p>
<p>For my own sanity, when I&#8217;m deving on my localbox, I don&#8217;t ever want content cached. So the caching headers are only set when the request is not local.</p>
<p>And finally, the file is served up with the correct content type. (Again, simple implementation, feel free to be smarter.)</p>
<p>The staticResourceVersion variable is ignored; I haven&#8217;t thought of anything to do with it yet.</p>
<p>And the hard work is done! Update your static resource urls to use the Url.StaticContent helper, deploy out to AppHarbor, and bask in the the glory of long-cache-expiration-headered static content.</p>
<h2>The End</h2>
<p>Special thanks to my fellow devs at <a href="http://cheezburger.com/">Cheezburger</a> for teaching me this technique.</p>
<p>Thanks to <a href="http://twitter.com/friism">Michael Friis</a> for telling me that AppHarbor inserts the commit_id into a deployed web.config.</p>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2012/02/15/static-resource-caching-cache-busting-asp-net-mvc-appharbor/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>jQuery UI Sortable + Bootstrap&#8217;s Buttons = Perfect Performance Storm</title>
		<link>http://eli.eliandlyndi.com/2011/12/18/jui-sortable-bootstrap-perf-problem/</link>
		<comments>http://eli.eliandlyndi.com/2011/12/18/jui-sortable-bootstrap-perf-problem/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 00:46:11 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[bootstrap]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery ui]]></category>
		<category><![CDATA[perf]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/?p=177</guid>
		<description><![CDATA[I ran into this crazy performance problem on: jQuery 1.7.1 jQuery UI 1.8.16 Twitter&#8217;s Bootstrap 1.4.0 Windows 7 / Chrome 16.0.912.63 See how the button starts dragging from the top left corner and drags really slowly? I stripped down the CSS &#8230; <a href="http://eli.eliandlyndi.com/2011/12/18/jui-sortable-bootstrap-perf-problem/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I ran into this crazy performance problem on:</p>
<ul>
<li>jQuery 1.7.1</li>
<li>jQuery UI 1.8.16</li>
<li>Twitter&#8217;s Bootstrap 1.4.0</li>
<li>Windows 7 / Chrome 16.0.912.63</li>
</ul>
<iframe style="width: 100%; height: 200px" src="http://jsfiddle.net/FV5ak/1/embedded/result"></iframe>
<p>See how the button starts dragging from the top left corner and drags really slowly? I stripped down the CSS element by element using Chrome&#8217;s dev tools and was able to isolate the problem to the <strong>-webkit-transition</strong> and <strong>box-shadow</strong> styles on the .btn class. Setting those to <strong>none</strong> fixed the problem.</p>
<iframe style="width: 100%; height: 200px" src="http://jsfiddle.net/FV5ak/2/embedded/result,css"></iframe>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/12/18/jui-sortable-bootstrap-perf-problem/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Using jQuery to provide an inline confirmation on buttons</title>
		<link>http://eli.eliandlyndi.com/2011/10/10/using-jquery-to-provide-an-inline-confirmation-on-buttons/</link>
		<comments>http://eli.eliandlyndi.com/2011/10/10/using-jquery-to-provide-an-inline-confirmation-on-buttons/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 20:22:31 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[code sample]]></category>
		<category><![CDATA[confirm button]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/?p=125</guid>
		<description><![CDATA[I was working on a side project and wanted the user to confirm when they wanted to delete something. The normal window.confirm method was just too primitive so I decided to write something I liked a little more. Click the &#8230; <a href="http://eli.eliandlyndi.com/2011/10/10/using-jquery-to-provide-an-inline-confirmation-on-buttons/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I was working on a side project and wanted the user to confirm when they wanted to delete something. The normal window.confirm method was just too primitive so I decided to write something I liked a little more.</p>
<p>Click the delete button below to see it in action. Click the JavaScript tab below to see how it works.</p>
<iframe style="width: 100%; height: 500px" src="http://jsfiddle.net/elithompson/nz6z2/9/embedded/result,js"></iframe>
<p>This was built for use with the amazing <a href="http://twitter.github.com/bootstrap/">Bootstrap</a> CSS framework. Only the classes that are added/removed are dependent on Bootstrap, so adjust to your needs.</p>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/10/10/using-jquery-to-provide-an-inline-confirmation-on-buttons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting the version number of your own Chrome Extension</title>
		<link>http://eli.eliandlyndi.com/2011/08/12/getting-the-version-number-of-your-own-chrome-extension/</link>
		<comments>http://eli.eliandlyndi.com/2011/08/12/getting-the-version-number-of-your-own-chrome-extension/#comments</comments>
		<pubDate>Fri, 12 Aug 2011 19:42:37 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[getting]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[version]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/2011/08/12/getting-the-version-number-of-your-own-chrome-extension/</guid>
		<description><![CDATA[http://siphon9.net/loune/2010/07/getting-the-version-number-of&#8230; This is so kludgy. I hope they make it better sometime, though :-/ See this Amp at http://amplify.com/u/a1arws &#160;]]></description>
				<content:encoded><![CDATA[<div>
<div class="Amp_Content_Outer_Bookmark">
<div class="Amp_Bookmark_Link"><a title="http://siphon9.net/loune/2010/07/getting-the-version-number-of-your-own-chrome-extension/" href="http://siphon9.net/loune/2010/07/getting-the-version-number-of-your-own-chrome-extension/" rel="clipsource" target="_blank">http://siphon9.net/loune/2010/07/getting-the-version-number-of&#8230;</a></div>
</div>
</div>
<div class="Amp_Commentary_Wrap">
<div class="Amp_Post_Text">
<p>This is so kludgy. I hope they make it better sometime, though :-/</p>
</div>
</div>
<div class="Amp_Link">See this Amp at <a href="http://amplify.com/u/a1arws">http://amplify.com/u/a1arws</a></div>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/08/12/getting-the-version-number-of-your-own-chrome-extension/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit testing CoffeeScript with QUnit</title>
		<link>http://eli.eliandlyndi.com/2011/07/28/unit-testing-coffeescript-with-qunit/</link>
		<comments>http://eli.eliandlyndi.com/2011/07/28/unit-testing-coffeescript-with-qunit/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 05:54:04 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/?p=91</guid>
		<description><![CDATA[I got bitten by the CoffeeScript bug and decided that I liked it enough to try to add CoffeeScript support to Cheezburger.com. Paul Betts&#8217; very cool SassAndCoffee library has a method which compiles CoffeeScript to JavaScript which I could easily integrate &#8230; <a href="http://eli.eliandlyndi.com/2011/07/28/unit-testing-coffeescript-with-qunit/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I got bitten by the <a title="CoffeeScript" href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> bug and decided that I liked it enough to try to add CoffeeScript support to <a title="Cheezburger.com - All your funny in one place" href="http://cheezburger.com/">Cheezburger.com</a>. <a title="Paul Betts' Twitter" href="https://twitter.com/#!/xpaulbettsx">Paul Betts&#8217;</a> very cool <a title="SassAndCoffee" href="https://github.com/xpaulbettsx/SassAndCoffee">SassAndCoffee</a> library has a method which compiles CoffeeScript to JavaScript which I could easily integrate into our script serving system.</p>
<p>I&#8217;ve also been bitten by the <a title="QUnit - JavaScript test suite" href="http://docs.jquery.com/Qunit">QUnit</a> bug so before I enable CoffeeScript on Cheezburger.com, I want to make sure that I can unit test whatever CoffeeScript we write. A quick <a title="Search for qunit and coffeescript" href="http://www.google.com/search?q=qunit+coffeescript">Google search</a> yielded next to nothing about testing CoffeeScript but I was feeling inventive and came up with the following way to use QUnit with CoffeeScript.</p>
<h2>Important Gotcha</h2>
<p>Since we&#8217;re going to load .coffee scripts via jQuery.get(), they must be served by a web server. They will not load off the local file system if you simply open index.htm locally. If anyone finds a way around this, feel free to comment on the gist.</p>
<p>I enabled IIS Express to serve .coffee files by adding the following element to applicationhost.config in the configuration/system.webserver/staticContent element:</p>
<p>&lt;mimeMap fileExtension=&#8221;.coffee&#8221; mimeType=&#8221;text/plain&#8221; /&gt;</p>
<h2>/Gotcha</h2>
<p>Here is a contrived Dog class and a test for it:</p>
<script src="https://gist.github.com/1113154.js?file=dog.coffee"></script><noscript><pre><code class="language-coffeescript coffeescript">class Dog
    speak: -&gt; &quot;woof&quot;
    legs: 4</code></pre></noscript>
<script src="https://gist.github.com/1113154.js?file=dog.test.coffee"></script><noscript><pre><code class="language-coffeescript coffeescript">module &quot;Dog&quot;

test &quot;dog says woof&quot;, 1, () -&gt;
    dog = new Dog()
    actual = dog.speak()
    equal actual, &quot;woof&quot;
	
test &quot;dogs have four legs&quot;, 1, () -&gt;
    dog = new Dog()
    actual = dog.legs
    equal actual, 4</code></pre></noscript>
<p>And here&#8217;s the index.htm which runs the tests:</p>
<script src="https://gist.github.com/1113154.js?file=index.htm"></script><noscript><pre><code class="language-html html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;UTF-8&quot; /&gt;
	&lt;title&gt;QUnit Test Suite&lt;/title&gt;
	&lt;link rel=&quot;stylesheet&quot; href=&quot;qunit/qunit.css&quot; type=&quot;text/css&quot; media=&quot;screen&quot;&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;qunit/qunit.js&quot;&gt;&lt;/script&gt;
	
        &lt;script type=&quot;text/javascript&quot; src=&quot;http://jashkenas.github.com/coffee-script/extras/coffee-script.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/coffeescript&quot;&gt;
$ -&gt;
    scriptsToTest = [&quot;dog.coffee&quot;]
    tests = [&quot;dog.test.coffee&quot;]
    loadCoffee =  (files) -&gt; 
        $head = $ &quot;head&quot;
        load = (file) -&gt;
             $.get file, (content) -&gt;
                compiled = CoffeeScript.compile content, {bare: on}
                $(&quot;&lt;script /&gt;&quot;).attr(&quot;type&quot;, &quot;text/javascript&quot;).html(compiled).appendTo $head
        load file for file in files
    loadCoffee scriptsToTest
    loadCoffee tests
	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h1 id=&quot;qunit-header&quot;&gt;QUnit Test Suite&lt;/h1&gt;
	&lt;h2 id=&quot;qunit-banner&quot;&gt;&lt;/h2&gt;
	&lt;div id=&quot;qunit-testrunner-toolbar&quot;&gt;&lt;/div&gt;
	&lt;h2 id=&quot;qunit-userAgent&quot;&gt;&lt;/h2&gt;
	&lt;ol id=&quot;qunit-tests&quot;&gt;&lt;/ol&gt;
	&lt;div id=&quot;qunit-fixture&quot;&gt;test markup&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></noscript>
<p>I started out with the normal set of QUnit files (index.htm, the css, and js), then included the <a title="Executing CoffeeScript from within a script element" href="http://jashkenas.github.com/coffee-script/#scripts">coffee-script.js</a> which enables us to execute CoffeeScript written in a &lt;script type=&#8221;text/coffeescript&#8221;&gt;&lt;/script&gt; tag. My usage of this tag in the code was completely unnecessary, but I thought this example would be more interesting if it was ALL CoffeeScript.</p>
<p>The <em>scriptsToTest</em> variable is a list of paths to .coffee files which will get loaded on the page. The <em>tests</em> variable is similar, but holds the tests. I split these up simply for readability.</p>
<p>The <em>loadCoffee</em> function spins through the contents of each of the files handed to it, executes the CoffeeScript compiler on them, and injects a script tag containing the compiled code into the page.</p>
<p>It&#8217;s important to include the &#8220;bare: on&#8221; option when calling the CoffeeScript.compile function. If bare is off (false), then the compiled code will be wrapped in a function so that declared variables get declared globally. My tests expect the Dog class to be declared globally, so I set bare to on.</p>
<p>Here&#8217;s a zip file full of all the files to make this example run (except for IIS Express):</p>
<p><a href="http://eli.eliandlyndi.com/wp-content/uploads/2011/07/QUnitAndCoffeeScript.zip">QUnitAndCoffeeScript</a></p>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/07/28/unit-testing-coffeescript-with-qunit/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Turntable.fm: Mute until next track starts</title>
		<link>http://eli.eliandlyndi.com/2011/06/28/turntable-fm-mute-until-next-track-starts/</link>
		<comments>http://eli.eliandlyndi.com/2011/06/28/turntable-fm-mute-until-next-track-starts/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 02:31:29 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/?p=82</guid>
		<description><![CDATA[Drag the link below up to your bookmark bar. When clicked, this bookmarklet will mute the current song in Turntable.fm and then unmute when the next song starts playing. Updated 7/5/2011 - Turntable.fm changed the name of their player control, &#8230; <a href="http://eli.eliandlyndi.com/2011/06/28/turntable-fm-mute-until-next-track-starts/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Drag the link below up to your bookmark bar. When clicked, this bookmarklet will mute the current song in Turntable.fm and then unmute when the next song starts playing.</p>
<p><strong>Updated 7/5/2011 </strong>- Turntable.fm changed the name of their player control, so instead of calling it directly, we&#8217;re just invoking the event handlers for the actual mute button. Should be more stable!</p>
<p><a href="javascript:(function(){ function toggleMute() { $(&quot;.mute_btn:first&quot;).click(); } toggleMute(); console.log(&quot;muted!&quot;); var $messagesDiv = $(&quot;.messages&quot;); function onMessageReceived(event) { if (event.target.tagName !== &quot;DIV&quot;) { return; } var $message = $(&quot;div:last span:eq(1)&quot;, this); setTimeout(function() { var message = $message.text(); if (message.indexOf(&quot; started playing&quot;) !== 0) { return; } console.log(&quot;volume up!&quot;); $messagesDiv.unbind(&quot;DOMNodeInserted&quot;, onMessageReceived); toggleMute(); }, 25); } $messagesDiv.unbind(&quot;DOMNodeInserted&quot;, onMessageReceived).bind(&quot;DOMNodeInserted&quot;, onMessageReceived); })();">Mute Until Next Track Starts</a></p>
<p>I requested this feature via the Turntable.fm feedback button but I got tired waiting and decided to dive in and figure how to do it myself. The JavaScript simply activates the click event on the mute button, then binds a handler which waits for a chat message of &#8221; started playing&#8221; to appear. When it does, the volume it turned all the way up again and the handler is unbound.</p>
<p>Here&#8217;s the code powering the bookmarklet:<br />
<script src="https://gist.github.com/1052827.js?file=turntable-track-muter.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/06/28/turntable-fm-mute-until-next-track-starts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Events on JavaScript Objects</title>
		<link>http://eli.eliandlyndi.com/2011/05/23/events-on-javascript-objects/</link>
		<comments>http://eli.eliandlyndi.com/2011/05/23/events-on-javascript-objects/#comments</comments>
		<pubDate>Tue, 24 May 2011 00:15:50 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/?p=75</guid>
		<description><![CDATA[I did a search for javascript events and came up with lots of articles about onclick and onload and all the lovely things we use to make our pages interactive. But in this case, I wanted a C#-style event, like &#8230; <a href="http://eli.eliandlyndi.com/2011/05/23/events-on-javascript-objects/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I did a <a href="http://www.google.com/search?q=javascript+events">search for javascript events</a> and came up with lots of articles about onclick and onload and all the lovely things we use to make our pages interactive. But in this case, I wanted a C#-style event, like an event on an object. With a little more digging, I found this <a href="http://blog.mdk-photo.com/post/CSharp-like-Event-Patterns-for-Javascript.aspx">article about C#-style events</a> which pointed me towards the approach of just keeping a list of the functions that should be triggered by that event. However, I didn&#8217;t like the way it was written so I decided to re-implement the same idea in a JavaScript writing style more like this article about <a href="http://plasmasturm.org/log/311/">JavaScript instant iterators</a>. Here&#8217;s the result:</p>
<p><script src="https://gist.github.com/990042.js?file=createEvent.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/05/23/events-on-javascript-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Chrome extensions from a service account</title>
		<link>http://eli.eliandlyndi.com/2011/05/01/more-chrome-extension-building-fun/</link>
		<comments>http://eli.eliandlyndi.com/2011/05/01/more-chrome-extension-building-fun/#comments</comments>
		<pubDate>Mon, 02 May 2011 03:41:19 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[folder]]></category>
		<category><![CDATA[organisation group]]></category>
		<category><![CDATA[regards adi]]></category>

		<guid isPermaLink="false">http://elithompson.amplify.com/2011/05/01/more-chrome-extension-building-fun/</guid>
		<description><![CDATA[So I got our build system to call the chrome.exe to build my Chrome extension, but it didn&#8217;t work. It said: Could not find exported function RelaunchChromeBrowserWithNewCommandLineIfNeeded The build system runs in a web application, so I&#8217;d have to guess &#8230; <a href="http://eli.eliandlyndi.com/2011/05/01/more-chrome-extension-building-fun/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div class="Clog_Commentary_Wrap">
<div class="Clog_Post_Text">
<p>So I got our build system to call the chrome.exe to build my Chrome extension, but it didn&#8217;t work. It said:</p>
<p>Could not find exported function RelaunchChromeBrowserWithNewCommandLineIfNeeded</p>
<p>The build system runs in a web application, so I&#8217;d have to guess that chrome was mad because it wasn&#8217;t running as a real user account.</p>
<p>I found this post that suggested moving the chrome.exe into the application/{version} folder. Once it was there, my build worked.</p>
</div>
</div>
<div>
<div class="Clog_Content_Outer"><!-- BEGIN_CLOG_CONTENT ID: D56E53BC-3528-47E3-BF23-69E34207DFF6 CLOGS.CLIPMARKS.COM --></p>
<div class="Clog_Top_Wrap">
<div class="Clog_Source_First"><span>Clipped from <a title="http://code.google.com/p/chromium/issues/detail?id=47211" rel="clipsource" href="http://code.google.com/p/chromium/issues/detail?id=47211" target="_blank">code.google.com</a></span></div>
</div>
<div class="Clog_Middle_Wrap">
<blockquote class="Clog_Content_Item" cite="http://code.google.com/p/chromium/issues/detail?id=47211">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div class="TxtCntnt">I also faced this problem.<br />
Exact deatails are as follows, In my Organisation Group policy does not allows for downloading and installing any s/w on computers from internet.Since i like chrome very much, I copied the chrome installation file(Chrome folder) from c:doc&amp;settingsusernamelocalsettingapplication datagooglechrome and tried to run chrome and recieved this error( exported function not available)<br />
To solve this problem I copied the chrome.exe from ~application folder into ~chromeapplication8.0.552.215 folder and tried to run chrome , it started working and i recieved no error<br />
qustion is why chrome.exe in ~application folder was not able to read dlls into 8.0552.215 folder though it is hard wired to do so( I think so atleast).<br />
It is a bug which devs should atleast try to correct it.&nbsp;</p>
<p>I would also suggest to users who are facing this problem to copy chrome.exe from~application folder to ~applicationversion Id folder and running chrome.</p>
<p>Lets see what happens</p>
<p>Regards<br />
Adi</p>
</div>
<p><span class="Clog_Source_Button"><a title="http://code.google.com/p/chromium/issues/detail?id=47211" rel="clipsource" href="http://code.google.com/p/chromium/issues/detail?id=47211" target="_blank">Read more at code.google.com</a></span></td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="Clog_Bottom_Wrap"></div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/05/01/more-chrome-extension-building-fun/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Still relevant</title>
		<link>http://eli.eliandlyndi.com/2011/03/10/still-relevant/</link>
		<comments>http://eli.eliandlyndi.com/2011/03/10/still-relevant/#comments</comments>
		<pubDate>Thu, 10 Mar 2011 21:59:42 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dilbert]]></category>
		<category><![CDATA[new ruling class]]></category>
		<category><![CDATA[official dilbert website]]></category>
		<category><![CDATA[pointy haired boss]]></category>
		<category><![CDATA[strips]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/2011/03/10/still-relevant/</guid>
		<description><![CDATA[]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.dilbert.com/strips/comic/2009-12-07"><img class="alignnone" title="Still Relevant" src="http://www.dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/70000/5000/900/75988/75988.strip.gif" alt="" width="640" height="199" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/03/10/still-relevant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Basics of Statistics in SQL Server 2005 &#8211; Developer.com</title>
		<link>http://eli.eliandlyndi.com/2011/01/04/basics-of-statistics-in-sql-server-2005-developer-com/</link>
		<comments>http://eli.eliandlyndi.com/2011/01/04/basics-of-statistics-in-sql-server-2005-developer-com/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 17:24:03 +0000</pubDate>
		<dc:creator>Eli Thompson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[having]]></category>
		<category><![CDATA[mono linux]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[queries]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://eli.eliandlyndi.com/2011/01/04/basics-of-statistics-in-sql-server-2005-developer-com/</guid>
		<description><![CDATA[URL:  http://www.developer.com/db/article.php/3622881/Basics-&#8230; I had a table that was too large to get a count of. I tried Select Count(*) from {Table} but the query didn&#8217;t want to come back very quickly. Another way to get the size is to get &#8230; <a href="http://eli.eliandlyndi.com/2011/01/04/basics-of-statistics-in-sql-server-2005-developer-com/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div>
<div class="Amp_Content_Outer_Bookmark">
<div class="Amp_Bookmark_Link">URL:  <a title="http://www.developer.com/db/article.php/3622881/Basics-of-Statistics-in-SQL-Server-2005.htm" href="http://www.developer.com/db/article.php/3622881/Basics-of-Statistics-in-SQL-Server-2005.htm" rel="clipsource" target="_blank">http://www.developer.com/db/article.php/3622881/Basics-&#8230;</a></div>
</div>
</div>
<div class="Amp_Commentary_Wrap">
<div class="Amp_Post_Text">
<p>I had a table that was too large to get a count of. I tried Select Count(*) from {Table} but the query didn&#8217;t want to come back very quickly.</p>
<p>Another way to get the size is to get statistical information on the primary key. You can do sp_helpstats &#8216;{Schema}.{Table}&#8217;, &#8216;ALL&#8217; to get a list of objects with statistical information. Find the primary key, then do DBCC SHOW_STATISTICS(&#8216;{Schema}.{Table}&#8217;, {value of statistics_name column from previous query}</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://eli.eliandlyndi.com/2011/01/04/basics-of-statistics-in-sql-server-2005-developer-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
