<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>ls.n</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/" />
    <link rel="self" type="application/atom+xml" href="http://lucassmith.name/atom.xml" />
    <id>tag:lucassmith.name,2008-08-18://1</id>
    <updated>2011-10-04T03:15:15Z</updated>
    <subtitle>code stuff</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.2-en</generator>

<entry>
    <title>Satyen&apos;s Chai</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2010/12/satyens-chai.html" />
    <id>tag:lucassmith.name,2010://1.130</id>

    <published>2010-12-29T06:00:26Z</published>
    <updated>2011-10-04T03:15:15Z</updated>

    <summary> This chai recipe is courtesy of my coworker, Satyen Desai. He was kind enough to bring a pot of this into the office. Chai has forever been changed for me. Ingredients (for one cup) 1/2 cup water 2 flat...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Life" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="chai" label="chai" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="recipe" label="recipe" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<img src="/images/blog/chai/chai.jpg" height="188" width="250" title="A cup of chai" class="inset">

<p>This chai recipe is courtesy of my coworker, Satyen Desai.  He was kind enough to bring a pot of this into the office.  Chai has forever been changed for me.</p>

<h3>Ingredients (for one cup)</h3>

<ul>
    <li><strong>1/2 cup</strong> water</li>
    <li><strong>2 flat tsps</strong> <a href="http://www.dhavalgroups.com/Waghbakari/Productwaghbakri.aspx">Wagh Bakari</a> (or another loose-leaf black tea)</li>
    <li><strong>3</strong> fresh mint leaves</li>
    <li><strong>2 pinches</strong> ground <a href="http://en.wikipedia.org/wiki/File:Sa_cardamom.jpg">green cardamon</a> seeds</li>
    <li><strong>1 pinch</strong> of my <a href="#masala">Grandmom's chai masala</a> </li>
    <li><strong>1 pinch</strong> of fresh ginger and/or lemongrass (optional)</li>
    <li><strong>1/2 cup</strong> milk</li>
</ul>

<h3>Instructions</h3>

<ol>
    <li>In a sauce pan, add water, tea, mint, cardamon, masala, and (optional) ginger/lemongrass and bring to a rolling boil</li>
    <li>Add milk, lower heat, and bring to a rolling boil again</li>
    <li>Take the pot off the heat before it overflows, let it settle back down, and put it back on.  It'll continue to rise even when off the heat, so take if off before it reaches the top. Repeat a couple of times (more if you want it stronger)</li>
</ol>

<p>Enjoy!</p>

<h4 id="masala">Grandmom's chai masala</h4>
<p>Satyen admits you can probably get something close in Indian stores, but there's nothing like recipes from grandmom.  A (I assume roughly equal) mix of the following, ground separately:</p>

<ul>
    <li>black pepper</li>
    <li>green cardamom seeds</li>
    <li>cinnamon</li>
    <li>dried ginger</li>
    <li>clove</li>
</ul>

<p>Chai image via <a href="http://en.wikipedia.org/wiki/Chai">Wikipedia</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>I want my touch screen</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2010/10/i-want-my-touch-screen.html" />
    <id>tag:lucassmith.name,2010://1.129</id>

    <published>2010-10-21T14:33:16Z</published>
    <updated>2010-12-12T07:45:56Z</updated>

    <summary>At yesterday&apos;s Apple event &quot;Back to the Mac&quot;, the point was stated and reiterated that they opted not to make the laptop screen a (multi) touch interface. The reason? ergonomics. After a while, your arm gets tired. Then after a...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Life" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="apple" label="apple" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ergonomics" label="ergonomics" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="touchscreen" label="touch screen" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>At yesterday's Apple event "Back to the Mac", the point was stated and reiterated that they opted not to make the laptop screen a (multi) touch interface.  The reason? ergonomics.  <q>After a while, your arm gets tired.  Then after a while, your arm wants to fall off,</q> Steve Jobs said.</p>

<p>I wonder if he was spouting party line or he actually believed that ergonomics was a valid reason to detach the interface from the thing being interfaced.  I know I don't.</p>

<p>If the iPhone, iPod, and iPad proved anything with the touch interface, it's that a direct touch interface is incredibly natural.  My three year old knows how to operate my iPod Touch, but I didn't teach him.  In contrast, I spent some time introducing him to the idea that when you move this thing (the mouse), this other thing up here on the screen moves (the cursor).  And <em>then</em>, when you click on this button, it does something.  He didn't get it.  A disembodied, foreign, two-step process will never beat a direct correlation to a natural process.</p>

<p>The other day, a coworker noted that after working with an iPad for a week, he started touching the monitor attached to his laptop.  He's been using computers for a long time.  Years of experience with mice and trackpad (even multi-touch gesture supporting trackpads) undone in a week.  Why?  Because people use their hands to manipulate what they see <em>by touching it</em>.</p>

<p>Do I buy the fatigue argument?  You bet.</p>

<p>Unlike the iPad, laptop screens are inherently vertical.  Making them horizontal, or more horizontal, would result in a lot of time spent looking (further) down, which results in bad posture and fatigue.  And of course, touching a deeply inclined screen would just tip the laptop over.  The reason it's ok for the iPad to rely on a touch screen is that it is not aimed at extended operation with extensive interaction.  Reading a book or watching a movie takes time, but not much interaction.  Productivity on an iPad basically requires a horizontal physical keyboard or a lot of intelligence in the software being interacted with, such that complex tasks can be done with little interaction.  Having to physically support the thing while using it, or craning down over it to use both hands, is less than ideal, especially for extended interaction. (Full disclosure: I don't own an iPad, and have used one very little, but I have both an iPhone and iPod Touch)</p>

<p>I'm curious what people that have the iPad stand and keyboard think about the usability of the device while fully docked.  Did they abandon the touch screen for a mouse or trackpad?  If so, did they <em>completely</em> abandon it?</p>

<p>It seems to me the debate isn't over yet.  Natural interfaces are a huge win for usability, but we apparently still need to learn how to bridge the gap to make them a huge win for <em>productivity</em>.  I hope Apple and others are not content to leave the discussion at "it can't be done; bad ergonomics".</p>]]>
        
    </content>
</entry>

<entry>
    <title>Liam quotes of the day</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2009/12/liam-quotes-of-the-day.html" />
    <id>tag:lucassmith.name,2009://1.128</id>

    <published>2009-12-24T04:04:54Z</published>
    <updated>2009-12-24T04:26:27Z</updated>

    <summary>I want to break it into five pieces. &#8212; in reference to many many things. I have hummus in my nose. &#8212; while being rocked to sleep. And my personal favorite needs a little context. The metal drum in our...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Life" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="liam" label="Liam" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="quote" label="quote" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p><q>I want to break it into five pieces.</q> &#8212; in reference to many many things.</p>

<p><q>I have hummus in my nose.</q> &#8212; while being rocked to sleep.</p>

<p>And my personal favorite needs a little context.  The metal drum in our drier cracked a few weeks ago, and the other day the crack expanded to a point where it was dangerous for our clothes.  Fortunately we'd bought the extended warranty, so the repair was free.</p>

<p>The new drum came in a very large bubble wrap bag.  We played with the bag for a while; I swung him around in there, slung him over a shoulder, and bounced him up and down in it.</p>

<p>Then it got late and he melted.  We weren't terribly successful convincing him that eating is a great cure for being hungry, so there was a lot of screaming.  At one point he cried, <em>in the same breath</em>, <q>I want soup. I don't want soup!</q> (but that's not the quote).  There was a lot of this.</p>

<p>We negotiated that if he gets in his diaper and pajamas that I'll carry him to his room in the bubble wrap bag.  This was a turbulent activity, but eventually, he gets in his PJs.  He's completely out of his senses and flinging arms and legs everywhere, then he hops in and I pick up the bag and carry him to his bedroom.  While in transit, the crazies suddenly disappear and a calm sweet child's voice utters <q>It's nice in here.</q></p>

<p>Then the crazies came back.</p>]]>
        
    </content>
</entry>

<entry>
    <title>CommonJS require(..) API is a poor fit for client side JS</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2009/11/commonjs-require-api-is-a-poor-fit-for-client-side-js.html" />
    <id>tag:lucassmith.name,2009://1.127</id>

    <published>2009-11-25T06:54:16Z</published>
    <updated>2010-12-12T07:44:57Z</updated>

    <summary>This post is in response to David Flanagan&apos;s client side JS implementation of CommonJS&apos;s module pattern/API. There are several performance considerations with script/module/dependency loading. script tags in markup block the page progression synchronous XHR blocks the js thread and therefore...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="commonjs" label="commonjs" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>This post is in response to <a href="http://www.davidflanagan.com/2009/11/commonjs-module.html">David Flanagan's client side JS implementation</a> of <a href="http://commonjs.org/specs/modules/1.0.html">CommonJS's module pattern/API</a>.</p>

<p>There are several performance considerations with script/module/dependency loading.</p>

<ol>
    <li>script tags in markup block the page progression</li>
    <li>synchronous XHR blocks the js thread and therefore the UI responsiveness</li>
    <li>script tags added to the DOM via js do not block page progression, but their execution order must be managed</li>
    <li>there are severe performance penalties for numerous http requests (http meta/overhead, time, and browser's concurrent resource request limits)</li>
    <li>&quot;discovered&quot; dependency resolution == chained http requests (sync or async), so deep deps trees could take a long time to resolve. A reqs B reqs C could result in load A, then load B, then load C, then execute C, then B, then A, then execute requiring code (see #2 and #4).</li>
</ol>

<p>The CommonJS API has great qualities for environments that don't suffer from the sorts of IO costs and conditions that make sync behavior a Bad Idea(tm) in client side scripting.  The implementation as one-expression-per-requirement is especially bad because it is functionally equivalent to multiple blocking script nodes locking up the page progress or rendered UI, which is somewhere between bad and horrible.  To avoid this, require might be a registration function of an async loader to bundle multiple require(..) calls from the same thread, but that breaks the require-then-use contract.</p>

<p>The YUI 3 module and <code>use(..)</code> arch is basically an async implementation of key parts of this API.  This is especially obvious in the <code>YUI.add(moduleName, function (Y) { /* add stuff to Y */ }, ver, meta);</code> form of registering modules where you could easily substitute <code>export</code> for <code>Y</code>.</p>

<p>The big differences are that <code>Y.use(..)</code> accepts multiple modules/requirements to avoid the one-expression-per-requirement, it does pre-fetch dependency resolution based on a managed dependency metadata tree, and the modules are loaded asynchronously using as few requests as possible (the Yahoo! CDN combo service makes 1 request the common case), executing a callback when complete.</p>

<p>The less than optimal part of this is the dependency resolution tactic, especially for modules from third parties.  Delaying dependency calculation for a module until that module is loaded would kill performance, so all dependency metadata for library modules is stored in a meta module for pre-fetch resolution.  We already know this won't scale in a non-impactful way, and of course this doesn't address third party modules.  For third party modules, we require dependency metadata in the configuration for requiring code, which is less than ideal.  For optimal performance and client side footprint, dependency resolution basically has to happen on the server side or be integrated into a pre-deployment build step.</p>

<p>All that said, my main point is that as exciting as the recent server-side JS movement has been, the synchronous <code>require(..)</code> pattern is a poor fit on the client side for the high performance demands of today's sites and RIAs.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Test if a font is installed via JavaScript</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2009/05/test-if-a-font-is-installed-via-javascript.html" />
    <id>tag:lucassmith.name,2009://1.125</id>

    <published>2009-05-26T15:45:52Z</published>
    <updated>2009-05-27T04:06:42Z</updated>

    <summary>There are a few threads available on the web with regard to how to test if a font is installed on a client machine, but I&apos;m not satisfied with any of those that I found. The reason being that they...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="font" label="font" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="test" label="test" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>There are a few threads available on the web with regard to how to test if a font is installed on a client machine, but I'm not satisfied with any of those that I found.  The reason being that they each seem to use a single common font as a baseline measurement and compare the dimensions of some reasonably complex string rendered in the common font against the same string rendered in the test font.</p>

<p>This irks me for a number of reasons:</p>
<ol>
    <li>It assumes the common font is installed</li>
    <li>It only confirms the dimensions of the tested font don't coincide with the common font</li>
    <li>All of those I saw rerendered the same element over and over, triggering an unnecessary number of reflows</li>
</ol>

<p>If you want to check if a font is installed, start with a provable test.  The system default <code>monospace</code> font <em>should</em> render a string in different dimensions than the system default <code>sans-serif</code> font.  But you can test this.</p>

<pre class="code"><code>(function () {
var div = document.createElement('div'),
    different = false;

div.innerHTML = '&lt;span style="...;font-family: sans-serif"&gt;some string&lt;/span&gt;' +
                '&lt;span style="...;font-family: monospace"&gt;some string&lt;/span&gt;';

document.body.insertBefore(div, document.body.firstChild);

different = div.childNodes[0].offsetWidth != div.childNodes[1].offsetWidth;

document.body.removeChild(div);

alert(different);
})();</code></pre>

<p>Using this tested assertion as a baseline, let the browser tell you if the test font is installed by using the default behavior of font stacks.  Create two elements with the same content (&quot;ii&quot; has been sufficient in my tests), each styled with a <code>font-family</code> of the test font followed respectively by the two control fonts that you know to render to different dimensions.</p>

<pre class="code"><code>&lt;b style="font: normal 10px/1 'FONT_X', sans-serif !important"&gt;ii&lt;/b&gt;
&lt;b style="font: normal 10px/1 'FONT_X', monospace !important"&gt;ii&lt;/b&gt;</code></pre>

<p>The two elements will render to the same dimensions if and only if the the font is installed.</p>

<p>Here's my approach:</p>

<pre class="code"><code>function testFont(name) {
    name = name.replace(/['"&lt;&gt;]/g,'');

    var body  = document.body,
        test  = document.createElement('div'),
        installed = false,
        template =
            '&lt;b style="display:inline !important; width:auto !important; font:normal 10px/1 \'X\',sans-serif !important"&gt;ii&lt;/b&gt;'+
            '&lt;b style="display:inline !important; width:auto !important; font:normal 10px/1 \'X\',monospace !important"&gt;ii&lt;/b&gt;',
        ab;

    if (name) {
        test.innerHTML = template.replace(/X/g, name);

        test.style.cssText = 'position: absolute; visibility: hidden; display: block !important';

        body.insertBefore(test, body.firstChild);

        ab = test.getElementsByTagName('b');

        installed = ab[0].offsetWidth === ab[1].offsetWidth;

        body.removeChild(test);
    }

    return installed;
}</code></pre>

<p>The code above assumes the string &quot;ii&quot; renders to different width in <code>monospace</code> than <code>sans-serif</code>, but the important part is that this can be tested if you don't feel comfortable with that assumption.  Additionally, containing two elements in an absolutely positioned div should limit the scope of the two requisite reflows if the browser is smart about it.</p>

<p>If you want to test more fonts, create more template entries in the innerHTML all at once before attaching the <code>div</code> to the DOM, then just loop through the entry pairs.  This will preserve the two reflow impact.</p>

<p>Here's a <a href="http://lucassmith.name/pub/font_installed.html">test page</a>.</p>
<p>And here's <a href="http://gist.github.com/118155">the code in a GitHub gist</a>.  It's likely this is more up to date than the snippet above.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Factory/Constructor that accepts N args</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2009/05/factoryconstructor-that-accepts-n-args.html" />
    <id>tag:lucassmith.name,2009://1.124</id>

    <published>2009-05-21T02:38:58Z</published>
    <updated>2009-05-21T04:00:52Z</updated>

    <summary>I&apos;m a big fan of the Factory/Constructor pattern in JavaScript. function Foo() { if (!(this instanceof Foo)) { return new Foo(); } // the rest of your initialization code } Foo.prototype = { ... }; var f1 = new Foo(),...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="factory" label="factory" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="poc" label="poc" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>I'm a big fan of the Factory/Constructor pattern in JavaScript.</p>

<pre class="code"><code>function Foo() {
    if (!(this instanceof Foo)) {
        return new Foo();
    }

    // the rest of your initialization code
}

Foo.prototype = { ... };

var f1 = new Foo(), // f1 instanceof Foo === true
    f2 = Foo(); // f2 instanceof Foo === true</code></pre>

<p>But this runs into a problem when you want your constructor to accept any number of arguments.</p>

<pre class="code"><code>Function Person(mother, father) {
    this.mother = mother;
    this.father = father;
    this.children = [].slice.call(arguments,2);
}</code></pre>

<h3>Apply invocation vs Constructor invocation</h3>
<p>Unfortunately, you would need to invoke the constructor via <code>Person.apply(arguments)</code> to pass all the arguments in individually, but that doesn't create an instance of Person since it wasn't called via <code>new</code>.  You can get around this by referring to a local variable in your constructor that is either <code>this</code> or a new empty instance, then applying the changes to whatever is in the variable and returning it.</p>

<pre class="code"><code>Function Person(mother, father) {
    var self = (this instanceof Person) ? this : new Person();

    self.mother = mother;
    self.father = father;
    self.children = [].slice.call(arguments,2);

    return self; // important
}</code></pre>

<p>When a constructor returns an object, the return statement is honored over the default behavior (sans return statement) of returning a class instance.</p>

<p>But this doesn't pan out if it is inappropriate for the class to be called without arguments or if there's some complex logic that needs the seed info in order to make sense.</p>

<h3>Quite a list of requirements</h3>
<p>Now, at this point any reasonable person would probably rethink the architecture that necessitated such a construct (seriously, is it <em>really</em> a requirement to also support function invocation?), but a) I'm not a reasonable person, and b) hey, fun with code!  So here goes.</p>

<p>Circling back to the point that returning an object from a constructor will trump the default behavior, we can just defer the construction behavior to another constructor function.</p>

<pre class="code"><code>function Person(mother, father) {
    return new _Person(arguments);
}

function _Person(_) {
    this.mother = _.shift();
    this.father = _.shift();
    this.children = _;
}</code></pre>

<p>Now it doesn't matter how you execute the <code>Person</code> function.  It will return an instance of _Person, which is set up with the initialization code in <em>its</em> constructor.</p>

<h3>But I didn't ask for a <code>_Person</code></h3>
<p>Now there are two things left to attend to: 1) the returned object isn't an instance of <code>Person</code>, and 2) we now have <em>two</em> constructor functions exposed to our consumers.</p>

<pre class="code"><code>var Person = (function () {
    function C(mother, father) {
        return new _Person(arguments);
    }
    function _Person(_) {
        this.mother = _.shift();
        this.father = _.shift();
        this.children = _;
    }

    C.prototype = _Person.prototype = { ... };

    return C;
})();</code></pre>

<p>Assigning <code>_Person</code>'s prototype to <code>C</code> (aka <code>Person</code>) makes instances pass the <code>instanceof</code> test and allows for modifying the class prototype with the expected outcome.  And defining the helper constructor in a closure hides it from the implementation layer.</p>

<p>Overkill?  Almost certainly.  But JavaScript is a fun language, and who knows?  Maybe this pattern is just the right thing for <em>some</em> use case out there.  Ok, maybe not :)</p>]]>
        
    </content>
</entry>

<entry>
    <title>Emelia Isa Lorraine Smith</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2009/02/emelia-isa-lorraine-smith.html" />
    <id>tag:lucassmith.name,2009://1.123</id>

    <published>2009-02-19T03:15:59Z</published>
    <updated>2009-02-21T21:58:34Z</updated>

    <summary> I became a papa again on Sunday. At 1pm, Feb 15th 2009, my second child was born. My daughter, Emelia Isa Lorraine. The two births were very different. Where Liam was 7lbs 14oz, Emelia was 8lbs 10oz. Liam&apos;s birth...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Life" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="baby" label="baby" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="birth" label="birth" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="emelia" label="Emelia" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="family" label="family" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="liam" label="Liam" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="merriemelodies" label="merrie melodies" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<img src="/images/blog/emelia/held.jpg" alt="Emelia Isa Lorraine, held by papa" width="600">

<p>I became a papa again on Sunday.</p>

<p>At 1pm, Feb 15th 2009, my second child was born.  My daughter, <strong>Emelia Isa Lorraine</strong>.</p>

<p>The two births were very different.  Where Liam was 7lbs 14oz, Emelia was 8lbs 10oz.  Liam's birth was long, shrouded in anxiety; the fear of the unknown, trauma marked by the eventual hospital transfer and c-section.  It was Heidi's first time being admitted to a hospital, and the event left more scars than just the one on her belly.</p>

<p>Emelia came after only 6 hours of peaceful, natural labor, arriving in the birthing tub with me supporting Heidi (physically and psychologically) and the midwife receiving her.</p>

<p>The experience was incredibly healing for both of us.  We were different people this time around, tempered by our experience with Liam's birth and punctuated by our time as parents.</p>

<p>And of course, we got a little angel out of the deal :)</p>

<img src="/images/blog/emelia/bundle.jpg" alt="Emelia Isa Lorraine, held by papa" width="600">
<img src="/images/blog/emelia/sleeping.jpg" alt="Emelia Isa Lorraine, sleeping" width="600">
<img src="/images/blog/emelia/sleeping2.jpg" alt="Emelia Isa Lorraine, sleeping" width="600">

<p>For some reason, this picture reminds me of the Merrie Melodies short <a href="http://www.youtube.com/watch?v=28hk97-vZdQ">&quot;I Love to Singa&quot;</a>.  I don't think it looks like her at all&#8212;it's amazing how poorly cameras capture certain moments.  All the same, I did love that short :)</p>
<img src="/images/blog/emelia/i_like_to_singa.jpg" alt="Emelia Isa Lorraine, looking like a cartoon owl" width="600">

<p>And here's what Liam was doing on the day of his sister's birth:</p>
<img src="/images/blog/emelia/liam_ham.jpg" alt="Liam smiling for the camera" width="600">

<p>Being a ham, of course.  He went down for a nap 20mins before Emelia was born.  Needless to say, things had changed a bit by the time he woke up.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Seven things</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2009/01/seven-things.html" />
    <id>tag:lucassmith.name,2009://1.122</id>

    <published>2009-01-10T07:20:23Z</published>
    <updated>2010-11-22T20:17:18Z</updated>

    <summary>Dear Ryan. You suck. I&apos;ve been tagged, so on with the show. Seven things you (probably) don&apos;t know about me I&apos;ve taught a little bit of Lindy Hop and/or East Coast swing to thousands of people. For about a year...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Life" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="aboutme" label="about me" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="dance" label="dance" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="meme" label="meme" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="slackline" label="slackline" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="spam" label="spam" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="swing" label="swing" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>Dear <a href="http://wonko.com">Ryan</a>.  You suck.</p>

<p><a href="http://wonko.com/post/seven-things">I've been tagged</a>, so on with the show.</p>

<h3>Seven things you (probably) don't know about me</h3>
<ol>
    <li><strong>I've taught a little bit of Lindy Hop and/or East Coast swing to thousands of people</strong>.  For about a year or more I was the lead to <a href="http://thejointisjumpin.com">Denise Steele</a>, teaching before the Sunday swing shows at the <a href="http://www.mcmenamins.com/index.php?loc=2&id=104">Crystal Ballroom</a> in Portland.   This was during the post-Gap-commercial swing revival, so it was pretty common to get around 300 to 500 people each weekend.  Really it was mostly Denise, but eh, it takes two to&#8212;wait, oh nevermind.  Add on a few group classes, some choreography, and some corporate gigs, too.  Those were good days.  I still have my big purple zoot pants.</li>
    <li><strong>I won the &quot;Tricks&quot; category in a slackline comp</strong> for doing, among other things, a 270&deg; hop (still haven't made a 360&deg;), a running 360&deg; jump mount onto the line, and a distance mount from about 7 or 8 feet away.  At least that's how far away it was in my happy memory.  It may have been less in real life.  Maybe more :)</li>
    <li><strong>I bought my first intimate girlfriend thigh high stockings as a Christmas gift</strong> and she opened them in front of her parents.  Because I told her it was safe to do so.  Yeah.  I wasn't too bright.</li>
    <li><strong>In college, I considered if it were possible to bat for the other team</strong> when I heard some guy may have been interested in me.  Seriously, he was <em>hot</em>, and smart, and musically talented.  Turns out it really wasn't.  And he wasn't (interested), which made it&#8230;easier?  I guess?</li>
    <li><strong>I have a little bit of extra cartilage in my neck</strong> that, when properly manipulated, makes it look like I have a toothpick jabbing out of my esophagus.  I've never tried to freak anybody out at a restaurant, though.</li>
    <li><strong>My mother almost named me Peni</strong> (pronounced like penny).  That's right, Peni Smith.  This is Peni's therapy bill.  There aren't a lot of Penis in my class.  Thankfully, grandma almost smacked her.  So Mandy Jo it is!  I'm glad I'm a boy.</li>
    <li><strong>I'm scared of teenagers</strong> and positively <em>terrified</em> of what kind of father I'll be when my kids get to that age.</li>
</ol>

<h3>Them's the rules</h3>
<p>Though I have no intention of meme spamming seven more bloggers (largely because I don't actually have friends), I may as well comply to the rules to some degree.</p>

<ul>
    <li>Link your original tagger(s), and list these rules on your blog.</li>
    <li>Share seven facts about yourself in the post -- some random, some weird.</li>
    <li>Tag seven people at the end of your post by leaving their names and the links to their blogs.</li>
    <li>Let them know they've been tagged by leaving a comment on their blogs and/or Twitter.</li>
</ul>

<h3>You're it?</h3>
<p>All I got for bloggers are</p>
<ul>
    <li><a href="http://jshirley.vox.com/">J Shirley</a></li>
    <li><a href="http://blog.davglass.com/">Dav Glass</a></li>
    <li><a href="http://foohack.com">Isaac Schlueter</a></li>
    <li><a href="http://www.nczonline.net/">Nicholas Zakas</a></li>
</ul>

<p>Sorry fellas.  You've been tagged.  Feel free to tell me to go to hell.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Another js function to insert commas in numbers</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2008/12/another-js-function-to-insert-commas-in-numbers.html" />
    <id>tag:lucassmith.name,2008://1.121</id>

    <published>2008-12-15T05:52:33Z</published>
    <updated>2009-03-19T00:36:52Z</updated>

    <summary><![CDATA[This evening's academic exercise was to write your basic 1234 =&gt; 1,234 function as terse as possible, and without a loop. At first I thought I could do it with just a clever regex, and maybe I could have, but...]]></summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="format" label="format" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="function" label="function" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="number" label="number" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>This evening's academic exercise was to write your basic 1234 =&gt; 1,234 function as terse as possible, and without a loop.  At first I thought I could do it with just a clever regex, and maybe I could have, but I abandoned that approach.</p>

<p>This is what I ended up with:</p>

<pre class="code"><code>function formatNumber(n) {
    if (!isFinite(n)) {
        return n;
    }

    var s = ""+n, abs = Math.abs(n), _, i;

    if (abs >= 1000) {
        _  = (""+abs).split(/\./);
        i  = _[0].length % 3 || 3;

        _[0] = s.slice(0,i + (n < 0)) +
               _[0].slice(i).replace(/(\d{3})/g,',$1');

        s = _.join('.');
    }

    return s;
}</code></pre>

<p>I could have omitted the storage of <code>Math.abs(n)</code> and the short circuit for numbers not needing comma injection, but eh.  No need to sacrifice runtime performance for a few characters.</p>

<p>The basic principle is to use string <code>replace</code> to insert commas on only the chunk of the number that needs them.  <code>intAsString.length % 3 || 3;</code> will return the index of the first character that needs a comma before it (for positive values, hence the <code>abs</code>), so everything beyond that point needs to be divided into three digit chunks, each preceded by a comma.</p>

<h3>Update - 1/16/2009</h3>
<p>I happened across <a href="http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_number_format/">a similar function</a>, based on PHP's <code>number_format</code> function.  It prompted me to adapt in the extra params to support precision and specified characters for decimal and thousands divider.</p>

<p><a href="http://gist.github.com/47871">I put the result in a gist</a>.  I put together <a href="http://lucassmith.name/pub/format_number.html">this page</a> to confirm they were behaving comparably.</p>

<h3>Update - 3/18/2009</h3>
<p>Updated to account for input 1000.  &gt; should have been &gt;=  Oops! Thanks to Simon for helping me notice that :)</p>
<p>I also put the <a href="http://gist.github.com/81507">barebones function in a gist</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>Add business days to a Date</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2008/11/add-business-days-to-a-date.html" />
    <id>tag:lucassmith.name,2008://1.120</id>

    <published>2008-11-19T04:11:37Z</published>
    <updated>2011-10-05T05:53:13Z</updated>

    <summary>This morning in ##javascript, a visitor asked how to add n business days to a Date instance. Call me a sucker, but I love little tasks like this. Maybe I just get antsy when I smell a potential modulo. I...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="addbusinessdays" label="addBusinessDays" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="date" label="date" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>This morning in ##javascript, a visitor asked how to add <code>n</code> business days to a <code>Date</code> instance.  Call me a sucker, but I love little tasks like this.  Maybe I just get antsy when I smell a potential modulo.</p>

<p>I thought I would be able to find such a function pretty quickly online, but I wanted to write it first, then validate my approach against what I found.  Here's what I came up with:</p>

<pre class="code"><code>function addBusinessDays(d,n) {
    d = new Date(d.getTime());

    var day = d.getDay();

    d.setDate(
        d.getDate() + n +
        (day === 6 ? 2 : +!day) +
        (Math.floor((n - 1 + (day % 6 || 1)) / 5) * 2));

    return d;
}</code></pre>

<p>Not terribly readable, but it works.  You could omit the first line if you have no desire to preserve the input Date object.  And it is hard coded to assume &quot;business days&quot; are between Monday and Friday.  If you wanted to offset the resulting date for holidays, you could maintain an object literal keyed by a serialization of holiday dates, and in the function check against the object, rerunning the algo with <code>n + 1</code> if a match was found.</p>

<h3>Compare and contrast</h3>

<p>It turned out after finishing the code, I had little luck finding a comparable function in the wild.  Perhaps my search criteria were awful or there's not actually a market for such a function, but my findings were sparse.  The closest thing I found was <a href="http://lawrence.ecorp.net/inet/samples/js-date-fx.shtml#addbizdays">this gargantuan monster</a>.  I was surprised that such a function didn't show up in the <a href="http://www.datejs.com/">DateJS lib</a>.  Regardless, both collections of functions modify the <code>Date.prototype</code> which I don't do.</p>

<p>So either I need to hone my search skills, or my efforts may have actually been worthwhile.</p>

<p>Here's the function minified&#8230;you know, in case you wanted to save 25b over the wire or something:</p>

<pre class="code"><code>function addBusinessDays(B,C){B=new Date(B.getTime());var A=B.getDay();B.setDate(B.getDate()+C+(A===6?2:+!A)+(Math.floor((C-1+(A%6||1))/5)*2));return B;}</code></pre>

<p>And a <a href="/pub/addBusinessDays.html">demo page</a> showing a variety of dates and a delta range of -10 to +10.</p>

<h3>Update 10/14/2009</h3>
<p>I've moved this to a <a href="http://github.com/lsmith/addBusinessDays">GitHub project</a> and included a couple new versions.  One to modify the Date in place and two others that adjust for holidays (some assembly required).</p>]]>
        
    </content>
</entry>

<entry>
    <title>Is my image loaded?</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2008/11/is-my-image-loaded.html" />
    <id>tag:lucassmith.name,2008://1.119</id>

    <published>2008-11-06T06:33:05Z</published>
    <updated>2008-11-19T18:57:59Z</updated>

    <summary>While developing on YUI&apos;s Slider widget for the upcoming 3.0 version, I came across a challenge regarding the slider&apos;s thumb image. In some cases, I need to reference offset dimensions for Slider to use to correctly place the thumb on...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="image" label="image" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="onerror" label="onerror" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="onload" label="onload" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>While developing on YUI's Slider widget for the upcoming 3.0 version, I came across a challenge regarding the slider's thumb image.  In some cases, I need to reference offset dimensions for Slider to use to correctly place the thumb on the background rail.</p>

<p>There were three scenarios that  I needed to address.</p>

<ol>
    <li>The image is in the DOM and loaded before the js executes</li>
    <li>The image may be in the DOM but not yet loaded</li>
    <li>The image <code>src</code> is incorrect either in the DOM or provided via configuration</li>
</ol>

<p>All A-grade browsers support the DOM events <code>onload</code> and <code>onerror</code> if the image hasn't already been loaded.  That's the easy part.  The hard part is dealing with the browser differences for successful and unsuccessful image urls that may or may not have been requested in the past.</p>

<p>What I found is listed here:</p>

<ul>
    <li>All browsers fire <code>onload</code> or <code>onerror</code> for images that haven't received a server/cache response</li>
    <li>FF and Opera cache the 404 response from bad images, and treat future requests for that url as a cache pull</li>
    <li>FF and Opera browsers do not fire (at least) <code>onerror</code> for cached 404 pulls</li>
    <li>cached 404s in FF/Opera show <code>img.complete == true</code></li>
    <li>FF and SF3 support <code>img.naturalHeight</code> and <code>img.naturalWidth</code>, which report 0 if the image did not load (also cached 404 + img.complete)</li>
    <li>Opera reports <code>img.width</code> and <code>img.height</code> of 0 for failed urls</li>
    <li>All other browsers report <code>img.width</code> <code>img.height</code> as the dims of the alt text</li>
    <li>IE reports <code>img.complete == false</code> for failed urls</li>
</ul>

<p>Some of these are suppositions, and likely there's a lot more to it than what I've found.  But at any rate, it &#8230;&quot;inspired&quot; me to write this little function to attach some callbacks to an <code>&lt;img&gt;</code> element (or generate one on the fly) that simulate an <code>onload</code> and <code>onerror</code> mechanism, that will execute when the image is loaded or determined to be in error.  If the image is a cache pull, the callbacks execute immediately.</p>

<pre class="code"><code>// First a couple helper functions
function $(id) {
    return !id || id.nodeType === 1 ? id : document.getElementById(id);
}
function isType(o,t) {    return (typeof o).indexOf(t.charAt(0).toLowerCase()) === 0;}

// Here's the meat and potatoes
function image(src,cfg) {    var img, prop, target;
    cfg = cfg || (isType(src,'o') ? src : {});

    img = $(src);
    if (img) {
        src = cfg.src || img.src;
    } else {
        img = document.createElement('img');
        src = src || cfg.src;
    }

    if (!src) {
        return null;
    }

    prop = isType(img.naturalWidth,'u') ? 'width' : 'naturalWidth';
    img.alt = cfg.alt || img.alt;

    // Add the image and insert if requested (must be on DOM to load or
    // pull from cache)
    img.src = src;

    target = $(cfg.target);
    if (target) {
        target.insertBefore(img, $(cfg.insertBefore) || null);
    }

    // Loaded?
    if (img.complete) {
        if (img[prop]) {
            if (isType(cfg.success,'f')) {
                cfg.success.call(img);
            }
        } else {
            if (isType(cfg.failure,'f')) {
                cfg.failure.call(img);
            }
        }
    } else {
        if (isType(cfg.success,'f')) {
            img.onload = cfg.success;
        }
        if (isType(cfg.failure,'f')) {
            img.onerror = cfg.failure;
        }
    }

    return img;
}</code></pre>

<p>Some example usage might be</p>
<pre class="code"><code>image('imgId',{
    success : function () { alert(this.width); },
    failure : function () { alert('Damn your eyes!'); },
});

image('http://somedomain.com/image/typooed_url.jpg', {
    success : function () {...},
    failure : function () {...},
    target : 'myContainerId',
    insertBefore : 'someChildOfmyContainerId'
});</code></pre>

<p>And a <a href="http://lucassmith.name/pub/imgload.html">demo here</a>.</p>

<p>If I missed something, please let me know.  Otherwise, I hope you find this useful.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Playing favorites</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2008/11/playing-favorites.html" />
    <id>tag:lucassmith.name,2008://1.118</id>

    <published>2008-11-02T23:56:03Z</published>
    <updated>2008-11-03T00:12:30Z</updated>

    <summary>I am Liam&apos;s favorite person in the world right now. Actually, for the last few months. He explodes with glee when I come home from work each night, running full steam to latch onto my legs and insisting I pick...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Life" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="family" label="family" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="heidi" label="Heidi" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="liam" label="Liam" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>I am Liam's favorite person in the world right now.  Actually, for the last few months.  He explodes with glee when I come home from work each night, running full steam to latch onto my legs and insisting I pick him up and join him in whatever his imagination is concocting at the moment.  We play all the time, I read to him, bathe him, and he helps me do some chores (often enough, cleaning up after him).</p>

<p>Normally I'd say this is great, but now he does not listen to his mama, refuses food from her&#8212;insisting I feed him&#8212;and in general wants nothing to do with her when I'm around.  When she asks him to come and give her a hug or kiss, he runs to me and refuses.</p>

<p>It breaks her heart.  And mine.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Script to add CSS only when JavaScript is available</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2008/10/script-to-add-css-only-when-javascript-is-available.html" />
    <id>tag:lucassmith.name,2008://1.117</id>

    <published>2008-10-29T14:07:32Z</published>
    <updated>2010-11-04T14:53:23Z</updated>

    <summary>If your site uses JavaScript to hide and show content, styled using display: none and (commonly) display: block, you may have an accessibility problem on your hands. The hidden content can&apos;t be viewed by users that have JavaScript turned off...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="accessibility" label="accessibility" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="css" label="css" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="hiddencontent" label="hidden content" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>If your site uses JavaScript to hide and show content, styled using <code>display: none</code> and (commonly) <code>display: block</code>, you may have an accessibility problem on your hands.  The hidden content can't be viewed by users that have JavaScript turned off unless you've provided adequate navigable hooks to get to it via default html behavior (e.g. <code>&lt;a href="..."&gt;</code>).</p>

<p>One way of addressing this is to add a class to the elements you want to hide once the DOM is in a modifiable state, but this can cause the hidden content to appear for some unknown amount of time, then disappear.  Less than elegant.</p>

<p>Another approach might be to have a class that hides elements only when relative to a trigger class that is applied to a containing element, such as <code>&lt;body&gt;</code>, ala</p>

<pre class="code"><code>&lt;head&gt;
    &lt;style type="text/css"&gt;
        .js_on .hide { display: none !important; }
        ... and so on
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;script type="text/javascript"&gt;
        document.body.className = "js_on";
    &lt;/script&gt;
    ...
    &lt;div class="hide"&gt;This is only hidden when JavaScript is on.&lt;/div&gt;</code></pre>

<p>That would prevent the content flicker, but if the body class is modified by another script on the page, your content could suddenly appear.</p>

<p>There are numerous other ways to address the problem, such as using JavaScript in the <code>&lt;head&gt;</code> to add a <code>&lt;link&gt;</code> element pointing to a stylesheet with your hide rules.  Etc etc.  Many ways to skin this cat.</p>

<p>Last night as I was falling asleep, I concocted this little script that I named <code>script2style.js</code> to address the problem a different way:</p>

<pre class="code"><code>(function () {

var d = document,
    scripts = d.getElementsByTagName('script'),
    me      = scripts[scripts.length - 1],
    content = me.innerHTML,
    style   = d.createElement('style');

style.type = 'text/css';

if (style.styleSheet) {
    style.styleSheet.cssText = content;
} else {
    style.appendChild(d.createTextNode(content));
}

me.parentNode.replaceChild(style,me);

})();</code></pre>

<p>Drop that in the <code>&lt;head&gt;</code> like so:</p>

<pre class="code"><code>&lt;head&gt;
    ...
    &lt;script src="script2style.js"&gt;
        .hide { display: none !important; }
        #other .selectors { ... }
        ...
    &lt;/script&gt;
&lt;/head&gt;</code></pre>

<p>The script replaces itself with a <code>&lt;style&gt;</code> element with the same content, and since scripts are blocking, the CSS will be in place as the browser loads the remainder of the page.</p>

<p>To be honest, I suspect it's been done before, but it was a fun little exercise.</p>

<p>Here's a <a href="/pub/script2style-basic.html">demo</a>.</p>

<h3>Update</h3>
<p>This morning, I added support for pulling <code>@import</code> rules out into separate <code>&lt;link&gt;</code> elements, just for kicks.</p>

<p>Here's a <a href="/pub/script2style.html">demo for that</a>.</p>

<p>The code for both simple version and @import version are <a href="https://github.com/lsmith/script2style">on github</a>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Object collection API</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2008/10/object-collection-api.html" />
    <id>tag:lucassmith.name,2008://1.116</id>

    <published>2008-10-16T17:30:09Z</published>
    <updated>2008-11-19T15:55:52Z</updated>

    <summary>This has probably been done before, but I decided to spend a few minutes this morning creating a proof of concept for it. The objective is to create a function that accepts multiple objects and returns an API that mimics...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="chaining" label="chaining" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="poc" label="poc" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<p>This has probably been done before, but I decided to spend a few minutes this morning creating a proof of concept for it.  The objective is to create a function that accepts multiple objects and returns an API that mimics the objects' APIs, but applies the named method to all of the objects in the group in turn.</p>

<p>So, if you have an object <code>x</code> and an object <code>y</code>, and both have a function <code>foo()</code>, you can call <code>group(x,y).foo()</code>.</p>

<p>Here's my 5 minute POC:</p>

<pre class="code"><code>
var _A = Array.prototype,
    _sl = function (_) { return _A.slice.call(_); },
    _jn = function (_,x) { return _A.join.call(_,x); };

function group() {
    var _ = _sl(arguments),i,len,
        results = [],
        methods = {},m,
        out = {
            results : function () { return results; },
            exec : function (fn) {
                var a = _sl(arguments)
                a.shift();
                results = [];
                for (i=0,len=_.length; i&lt;len; ++i) {
                    results.push(fn.call(null,_[i],a));
                }
                return this;
            }
        };

    for (m in _[0]) {
        if (typeof _[0][m] === 'function') {
            methods[m] = true;
        }
    }
    for (i=1,len=_.length; i&lt;len; ++i) {
        for (m in methods) {
            if (typeof _[i][m] !== 'function') {
                delete methods[m];
            }
        }
    }
    for (m in methods) {
        out[m] = (function (meth) {
                return function () {
                    results = [];
                    for (i=0,len=_.length; i&lt;len; ++i) {
                        results.push(_[i][meth].apply(_[i],arguments));
                    }
                    return this;
                };
            })(m);
    }

    return out;
};</code></pre>

<p>For kicks, I made it chainable, too, so each API method will return <code>this</code>.  Results of the method calls are accessible via the <code>results()</code> API method.</p>

<p>You can <a href="/pub/group_poc.html">see it in action here</a>.</p>

<p>I decided to only expose functions and only those that were common amongst all objects passed in.  It would have been easy enough to create API methods for all discovered methods and ignore objects that didn't have the requested method or just execute an empty stub.  But hey, POC, right?  And of course, it doesn't handle asynchronous operations via <code>setTimeout</code> or XHR.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Use str.slice(..)</title>
    <link rel="alternate" type="text/html" href="http://lucassmith.name/2008/10/use-strslice.html" />
    <id>tag:lucassmith.name,2008://1.115</id>

    <published>2008-10-10T17:05:26Z</published>
    <updated>2008-10-10T17:36:01Z</updated>

    <summary> .demo table { border-collapse: collapse; font-family: Arial,sans-serif; } .demo tbody { border: 1px solid #ccc; } .demo th { border-bottom: 5px solid #ccc; padding: .5ex 1em; text-align: left; } .demo td { border: 1px dotted #ddd; padding: .5ex 1em;...</summary>
    <author>
        <name>Luke Smith</name>
        <uri>http://lucassmith.name</uri>
    </author>
    
        <category term="Code" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="iebug" label="IE bug" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="slice" label="slice" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="substring" label="substring" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://lucassmith.name/">
        <![CDATA[<style type="text/css">
        .demo table {
            border-collapse: collapse;
            font-family: Arial,sans-serif;
        }
        .demo tbody {
            border: 1px solid #ccc;
        }
        .demo th {
            border-bottom: 5px solid #ccc;
            padding: .5ex 1em;
            text-align: left;
        }
        .demo td {
            border: 1px dotted #ddd;
            padding: .5ex 1em;
        }
        .demo .no td {
            background: #a33;
            color: #fff;
        }
    </style>

<p>There are three ways to get a substring from a string in JavaScript:</p>
<ol>
    <li><code>str.substr(<em>startIndex</em>,<em>length</em>)</code></li>
    <li><code>str.substring(<em>startIndex</em>,<em>endIndexPlusOne</em>)</code></li>
    <li><code>str.slice(<em>startIndex</em>,<em>endIndexPlusOne</em>)</code></li>
</ol>

<h3><code>substr</code> and <code>substring</code></h3>
<p>All browsers treat <code>str.substring(-2)</code> as <code>str.substring(0)</code>.</p>

<p><code>substring(4,2)</code> inputs are automatically reversed when the second param is less than the first, resulting in <code>substring(2,4)</code>.  So <code>substring(12,-2)</code> is treated as <code>substring(0,12)</code>.</p>

<p>IE treats <code>str.substr(-2)</code> as <code>str.substr(0)</code>.  All others support neg index in <code>substr</code>.</p>

<h3>All browsers support <code>str.slice(-2)</code>.</h3>
<p><code>slice</code> is the only method that properly handles negative indexes across all browsers. Here's a demo, run in your current browser.</p>
 
<div class="demo">
    <p>Starting string: <code>var str = &quot;abcdefghijklmnopqrstuvwxyz&quot;</code></p>
    <table>
    <thead>
        <tr><th>code</th><th>result</th><th>desired</th><th>correct?</th></tr>
    </thead>
    <tbody id="out">
    </tbody>
    </table>
</div>

<p>Note if you are viewing this in IE, <code>str.substr(-12,5)</code> results in &quot;abcde&quot;, whereas in other browsers &quot;opqrs&quot;.</p>

<p>So in conclusion, there are too many ways to skin the substring cat.  <code>substr</code> has cross-browser compatibility issues and <code>substring</code> doesn't support negative indexes.  <code>slice</code> is always safe, so just use <code>slice</code>.</p>

<script type="text/javascript">
var d = document,
    str = "abcdefghijklmnopqrstuvwxyz",
    out = d.getElementById('out'),
    tr = function (code,output,desired) {
        var r = d.createElement('tr'),
            t1 = r.appendChild(d.createElement('td')),
            t2 = r.appendChild(d.createElement('td')),
            t3 = r.appendChild(d.createElement('td')),
            t4 = r.appendChild(d.createElement('td'));

        t1.innerHTML = '<code>'+code+'</code>';
        t2.innerHTML = output;
        t3.innerHTML = desired;
        if (output === desired) {
            t4.innerHTML = 'YES';
        } else {
            r.className = 'no';
            t4.innerHTML = 'NO';
        }

        out.appendChild(r);
    };

//substr(..)                                     DESIRED RESULT
tr('str.substr(12)',       str.substr(12),       'mnopqrstuvwxyz');
tr('str.substr(-12,5)',    str.substr(-12,5),    'opqrs');
tr('str.substr(-2)',       str.substr(-2),       'yz');

//substring(..)                                  DESIRED RESULT
tr('str.substring(12)',    str.substring(12),    'mnopqrstuvwxyz');
tr('str.substring(12,-2)', str.substring(12,-2), 'mnopqrstuvwx');
tr('str.substring(-2)',    str.substring(-2),    'yz');

//slice(..)                                      DESIRED RESULT
tr('str.slice(12)',        str.slice(12),        'mnopqrstuvwxyz');
tr('str.slice(12,-2)',     str.slice(12,-2),     'mnopqrstuvwx');
tr('str.slice(-2)',        str.slice(-2),        'yz');
</script>]]>
        
    </content>
</entry>

</feed>

