<?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>incaseofstairs &#187; Web Development</title>
	<atom:link href="http://www.incaseofstairs.com/tag/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.incaseofstairs.com</link>
	<description>Code and other randomness</description>
	<lastBuildDate>Tue, 17 Jan 2012 17:01:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Quick: Firediff and Firefocus updated for 5.0 support</title>
		<link>http://www.incaseofstairs.com/2011/07/firediff-and-firefocus-updated-for-5-0-support/</link>
		<comments>http://www.incaseofstairs.com/2011/07/firediff-and-firefocus-updated-for-5-0-support/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 02:05:15 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[Firediff]]></category>
		<category><![CDATA[Firefocus]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=425</guid>
		<description><![CDATA[Both Firediff and Firefocus have been updated to increase the target application support up to Firefox 5.0. Both of these are available from the update stream on this site. New installations are recommended to use the Firediff and Firefocus projects on AMO as these will be more responsive to the march of Firefox releases.]]></description>
			<content:encoded><![CDATA[<p>
Both Firediff and Firefocus have been updated to increase the target application support up to Firefox 5.0.
</p>
<p>
Both of these are available from the update stream on this site. New installations are recommended to use the <a href="https://addons.mozilla.org/en-US/firefox/addon/firediff/">Firediff</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/firefocus/">Firefocus</a> projects on AMO as these will be more responsive to the march of Firefox releases.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2011/07/firediff-and-firefocus-updated-for-5-0-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firediff 1.1.2</title>
		<link>http://www.incaseofstairs.com/2011/03/firediff-1-1-2/</link>
		<comments>http://www.incaseofstairs.com/2011/03/firediff-1-1-2/#comments</comments>
		<pubDate>Tue, 22 Mar 2011 04:21:57 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[Firediff]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=403</guid>
		<description><![CDATA[Just in time for the impending Firefox 4.0 release, Firediff has been updated to version 1.1.2. This release contains compatibility changes for Firefox 4.0 and Firebug 1.7 as well as the ability to sort CSS properties alphabetically. As always, the latest version is available here and is currently under review at AMO.]]></description>
			<content:encoded><![CDATA[<p>
Just in time for the impending Firefox 4.0 release, Firediff has been updated to version 1.1.2. This release contains compatibility changes for Firefox 4.0 and Firebug 1.7 as well as the ability to sort CSS properties alphabetically.
</p>
<p>
As always, the latest version is available <a href="http://incaseofstairs.com/download/firediff/?C=M">here</a> and is currently under review at <a href="https://addons.mozilla.org/en-US/firefox/addon/firediff/">AMO</a>.
</p>]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2011/03/firediff-1-1-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Firebug Extension Updates: Firebug 1.6</title>
		<link>http://www.incaseofstairs.com/2010/12/firebug-extension-updates-firebug-1-6/</link>
		<comments>http://www.incaseofstairs.com/2010/12/firebug-extension-updates-firebug-1-6/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 08:23:48 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[Firediff]]></category>
		<category><![CDATA[Firefocus]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=388</guid>
		<description><![CDATA[As many of you are already aware, the recent release of Firebug 1.6 introduced some API changes that caused breakages within Firediff. To fix these some minor code changes within Firediff were necessary, thus the 1.1 release that has just been published. Along with the updates for the new APIs, this version also includes: Copy [...]]]></description>
			<content:encoded><![CDATA[<p>
As many of you are already aware, the recent release of <a href="http://blog.getfirebug.com/2010/11/29/firebug-1-6-0/">Firebug 1.6</a> introduced some API changes that caused breakages within <a href="http://www.incaseofstairs.com/firediff/">Firediff</a>. To fix these some minor code changes within Firediff were necessary, thus the 1.1 release that has just been published.
</p>
<p>
Along with the updates for the new APIs, this version also includes:
<ul>
	<li>Copy support</li>
	<li>Bug fixes for Firebug detached mode</li>
	<li>Change monitor context menu fixes</li>
	<li>Slight adjustment to the colors used within the text diffs</li>
</ul>
</p>
<p>
There are a few support changes in this release. Rather than trying to support multiple versions of both Firebug and Gecko, official testing is limited to a single version of Firebug, 1.6, and as a consequence for Firebug 1.6 to a single version of Firefox, 3.6. This is simply due to the increased QA time that is required to test all of the permutations of Firebug version, Gecko version, and OS type. When updating for the changed APIs in Firebug 1.6 attempts were made to maintain compatibility with Firebug 1.5, but this configuration is no longer officially tested.
</p>
<p>
Since I was going to through the release process for Firediff I decided to release the 1.2 version of <a href="http://www.incaseofstairs.com/firefocus/">Firefocus</a> as well. This version implements the uk-UA locale but is otherwise the same as 1.1.
</p>
<p>
Firediff 1.1 is available <a href="http://www.incaseofstairs.com/download/firediff/firediff1.1.xpi">here</a> on incaseofstairs and is currently under review on <a href="https://addons.mozilla.org/en-US/firefox/addon/13179/">AMO</a>. 
Firefocus 1.2 is available <a href="http://www.incaseofstairs.com/download/firefocus/firefocus1.2.xpi">here</a> on incaseofstairs and is currently under review on <a href="https://addons.mozilla.org/en-US/firefox/addon/49662/">AMO</a>.
</p>
<p>
Thanks to everyone who notified me of the breakage when 1.6 was released. It&#8217;s great to hear feedback from users and to hear that the project is in active use! As always please do not hesitate to let me know how the project is working for you, good or bad.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/12/firebug-extension-updates-firebug-1-6/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Cross Platform Text-Indexer</title>
		<link>http://www.incaseofstairs.com/2010/11/text-indexer/</link>
		<comments>http://www.incaseofstairs.com/2010/11/text-indexer/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 18:05:29 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[webOS]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=359</guid>
		<description><![CDATA[While working on a recent Facebook release we ran into a performance bottleneck within the Mojo.Format.runTextIndexer API. Performance on device was on the order of a couple of seconds to process the content for feed items 30-50. This combined with the other tasks in the formatting and rendering cycle led to poor performance in the [...]]]></description>
			<content:encoded><![CDATA[<p>
While working on a recent Facebook release we ran into a performance bottleneck within the <code>Mojo.Format.runTextIndexer</code> API. Performance on device was on the order of a couple of seconds to process the content for feed items 30-50. This combined with the other tasks in the formatting and rendering cycle led to poor performance in the news stream.
</p>
<p>
For those who are not familiar with the <code>Mojo.Format.runTextIndexer</code> API, this API scans human generated text for URLs, phone numbers and email addresses, replacing the plain text representation with HTML links to the particular object. Additionally this API will replace emoticons with image representations on supporting platforms.
</p>
<p>
With the news stream scene being the primary scene in the application it was vital that we make this as performant as possible so I spent some time profiling this and determined that the bulk of the time in this operation was spent in the generic C indexer logic. Since at it&#8217;s core this is just a text scanning heuristic that, for the most part, does not rely on any C-level constructs, I decided to investigate a Javascript implementation to see if this would be more performant.
</p>
<p>
The result was a Javascript implementation that was many magnitudes faster than the core implementation (multiple seconds vs. ~10ms for a variety of Facebook news feeds), allowing for much faster execution as well as the creation of the library being released today.
</p>
<p>
While this library is designed primarily for webOS applications, it has also been designed to work in cross-platform environments for all functionality other than the emoticon replacement which requires platform specific logic to determine the proper image to replace.
</p>

<h3>Implementation</h3>
<p>
There are two key components to this implementation, the cross platform link indexer and the platform specific emoticon processor.
</p>
<p>
The link indexer is a two-stage regular expression, using the quite daunting <a href="https://github.com/kpdecker/text-indexer/blob/d8c4f396d90300ef63846a132462508f23d72265/text-indexer.js#L22">INDEXER_REGEX</a> regex to extract possible linker tokens with Javascript being used to determine the meaning of each token (or throwing it out just text content).
</p>
<p>
The emoticon processor is implemented by scanning for known, or possibly known, emoticons using the <a href="https://github.com/kpdecker/text-indexer/blob/d8c4f396d90300ef63846a132462508f23d72265/text-indexer.js#L6">EMOTICON_REGEX</a> regex and then passing these tokens to the platform&#8217;s text indexer implementation. Doing this allows for our own custom implementation while retaining the look and feel of emoticons used by the rest of the platform. For non-Mojo platforms this logic is disabled and emoticons will be left unmodified, with minimal change.
</p>

<h3>Warnings</h3>
<h4>HTML Content</h4>
<p>
Like the API this aims to replace, this API does not handle HTML context when replacing content. As a consequence this algorithm can break HTML content. In order to prevent this, the input and outputs for the <code>TextIndxer.run</code> API should be considered text or minimal HTML that will not match any of the replacements.
</p>
<p>
It is still possible to use this with content containing HTML by processing in a manner similar to the following although the input still needs to be filtered for XSS and other security concerns.
<pre class="brush: jscript; title: ; notranslate">
        var srcText = $(this).val(),
            womb = $(&quot;&lt;div&gt;&quot; + srcText + &quot;&lt;/div&gt;&quot;);

        womb.contents()
            .filter(function() {
                return this.nodeType === Node.TEXT_NODE;
            })
            .each(function() {
                var text = $(this),
                    indexedText = TextIndexer.run(text.text()),
                    womb = $(&quot;&lt;div&gt;&quot; + indexedText + &quot;&lt;/div&gt;&quot;);
                womb.contents().each(function() {
                    text.before(this);
                });

                text.remove();
            });

        $(&quot;#previewContent&quot;).html(womb.html());
</pre>
</p>

<h4>Framework Override</h4>
<p>
By default this library overrides the <code>Mojo.Format.runTextIndexer</code> API (when used within the Mojo framework). Care should be taken with each OS upgrade to ensure that this override does not break any expected behavior. If uncomfortable with this override then it can be removed by removing these lines from the library and using the <code>TextIndexer.run</code> API directly.

<pre class="brush: jscript; title: ; notranslate">
    // Mojo Framework override. Unused on non-Mojo platforms and may be removed if undesired in Mojo apps
    if (window.Mojo &amp;&amp; Mojo.Format) {
        // Override the Mojo API if it exists in this context.
        Mojo.Format.runTextIndexer = TextIndexer.run;
    }
</pre>
</p>

<h4>Code</h4>
<p>
The code is available on Github within the <a href="https://github.com/kpdecker/text-indexer">text-indexer</a> repository. A cross-platform live demo is also available <a href="http://demo.incaseofstairs.com/indexer/index.html">here</a>.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/11/text-indexer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jsPerf</title>
		<link>http://www.incaseofstairs.com/2010/08/jsperf/</link>
		<comments>http://www.incaseofstairs.com/2010/08/jsperf/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 22:06:35 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=343</guid>
		<description><![CDATA[Recently heard about the relatively new jsPerf service that Mathias Bynens has created and after spending some time playing around with this on my own machine I can honestly say that I love this service. Rather than a few gushing tweets on the subject, I felt like this deserves a blog entry covering it&#8217;s coolness. [...]]]></description>
			<content:encoded><![CDATA[<p>
Recently heard about the relatively new <a href="http://jsperf.com/">jsPerf</a> service that <a href="http://mathiasbynens.be/">Mathias Bynens</a> has created and after spending some time playing around with this on my own machine I can honestly say that I love this service. Rather than a few gushing tweets on the subject, I felt like this deserves a blog entry covering it&#8217;s coolness.
</p>
<p>
The thing that I found the most striking about the site (and most likely the reason that I am writing this now) is that it broke many of my previous assumptions about performance of specific statements and relative performance of different platforms. Is innerHTML faster than DOM manipulation when generating a DOM tree? Not for a <a href="http://jsperf.com/innerclone">specific (relatively simple) construct</a> under Chrome (OS X v5). Is array.join(&#8221;) the fastest way to concat a string. On my test platforms (OS X Firefox, Safari, Opera, Chrome release versions), <a href="http://jsperf.com/string-concatenation/2">nope</a>.
</p>
<p>
Being a public playground, the community benefits from the collective knowledge. Scanning through the <a href="http://jsperf.com/browse">test list</a> I saw many of the problems that I have run into before as well as some I had never considered such as the <a href="http://jsperf.com/rounding-numbers-down/3">multiple methods</a> of performing a Math.floor operation. While some of these honestly scare me and remind me of Kernel code, it&#8217;s good to know they exist.
</p>
<p>
jsPerf has full support for mobile browsers as well, meaning that you can test performance test the various algorithm options on device and have a realistic view of how it will behave on the device. In running some of the tests on a webOS device there were some quite distinct differences between comparable environments on a desktop class machine. 
</p>
<p>
As with any performance testing I would recommend running these tests multiple times on your target device(s) before selecting a particular path to use as there are many things that could cause a single test to provide inaccurate results for a given execution, particularly on the more resource constrained environments.
</p>
<p>
Great job Mathias and can&#8217;t wait to see what features are added to this as well as the content that the community creates!
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/08/jsperf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Implementation: Facebook for webOS Add Tag UI</title>
		<link>http://www.incaseofstairs.com/2010/06/implementation-facebook-for-webos-add-tag-ui/</link>
		<comments>http://www.incaseofstairs.com/2010/06/implementation-facebook-for-webos-add-tag-ui/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 22:29:40 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[webOS]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[Palm]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=296</guid>
		<description><![CDATA[Yesterday we released Facebook for webOS 1.2.5 Beta which brings many improvements to our photo functionality including tagging support. Now that the release is out the door, I&#8217;d like to take some time to discuss the cooler aspects of the implementation particularly the Add Tag UI. Design The core layout of the Add Tag UI [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_299" class="wp-caption alignright" style="width: 250px"><a href="http://static.incaseofstairs.com/uploads/2010/06/add-tag.png"><img src="http://static.incaseofstairs.com/uploads/2010/06/add-tag.png" alt="Add Tag Interface" title="Add Tag Interface" width="240" height="360" class="size-full wp-image-299" /></a><p class="wp-caption-text">Facebook Add Tag Interface</p></div>
<p>
Yesterday we released <a href="http://developer.palm.com/blog/2010/06/facebook-1-2-5-beta-photo-tagging-and-more/">Facebook for webOS 1.2.5 Beta</a> which brings many improvements to our photo functionality including tagging support. Now that the release is out the door, I&#8217;d like to take some time to discuss the cooler aspects of the implementation particularly the Add Tag UI.
</p>

<h3>Design</h3>
<p>
The core layout of the Add Tag UI is an overlay container containing a fixed position header and a scrolling list below that. The entire screen is covered by these two elements, with the header section maintain its height and the content section expanding to cover the remainder.
</p>
<p>
This fixed header layout is fairly common throughout the app, the most common example being the navbar used in the majority of the application&#8217;s scenes, and is fairly easy to solve if the header is a fixed height and the content scrolls under the header. All that needs to be done is to position the header control using <code>position: fixed</code> and apply a <code>margin-top</code> to the list such that the first element in the list appears at the bottom of the fixed element.
</p>
<p>
I&#8217;ve never really like this solution as it requires that the header height be fixed and the list section be &#8220;aware&#8221; of the header rather than being only concerned about it&#8217;s own layout. With this in mind (and also wanting to play around with some of the cool things that WebKit offers but I have not been able to use on projects due to the IE factor), I decided to try out the flexible box layout type in webOS.
</p>

<h3>Flexible Box Layout</h3>
<p>
To provide some background, one of the key goals of the <a href="http://www.w3.org/TR/css3-flexbox/">flexible box layout module</a> is the ability to specify the size and growth of an element relative to both it&#8217;s siblings and it&#8217;s parent. While this was previously possible by using percentage layouts, each of the elements had to be aware of the size that their siblings expected and all elements needed to use the same relative system. 
</p>
<p>
This is not the case with this layout scheme. Rather than defining a percentage of the container size, elements are defined with an affinity for the excess space in the container. This means that the layout first attempts to fit everything as it would normally layout, then adjusts each element based on the difference in size between the children and the parent. In practice this can generate much more stable, but still fluid layouts when creating applications in HTML+CSS.
</p>
<p>
The <code>box-flex</code> (<a href="https://developer.mozilla.org/en/CSS/-moz-box-flex">-moz-box-flex</a>, <a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266--webkit-box-flex">-webkit-box-flex</a>) is used to define the resize affinity.
</p>
<p>
Values here can range from zero to any positive decimal value. When the value is zero, the element will not change size based on extra or lack of space in its parent. When this value is larger than zero the element is considered flexible. This means that when the layout engine determines that the parent box is either overflowed or underflowed these elements will expand or shrink such that all of the children fill the container. The differences in magnitudes of this value determines how the flexible elements are resized.
</p>
<p>
As an example a vertically oriented flexible box with 3 children whose flex values are 0, 1, and 2 and has 60px of open space will add 20px to the second element, 40px to the third element and leave the height of the first unchanged. On the other end of the spectrum if there is an overflow of 60px, the elements will be shrunk by the same dimensions above.
</p>
<p>
The flexible box model is <a href="http://caniuse.com/#feat=flexbox">supported</a> by Safari 3+, Chrome 3+, Firefox 3+, and of course webOS. As covering the entirety of the specification was out of the scope of this post I would recommend reading some of the other <a href="http://hacks.mozilla.org/2010/04/the-css-3-flexible-box-model/">excellent</a> <a href="http://www.the-haystack.com/2010/01/23/css3-flexbox-part-1/">sources</a> on this topic as well as the <a href="http://www.w3.org/TR/css3-flexbox/">specification</a> itself.
</p>

<h3>Implementation</h3>
<p>
For the Add Tag UI, we take advantage of the flexible overflow case outlined above. This allows the upper section to layout at it&#8217;s natural size using <code>-webkit-box-flex: 0</code> and the user list section to expand to fill the remainder of the page using <code>-webkit-box-flex: 1</code>. By defining the list section to be a <code>Scroller</code> with an embedded <code>List</code>, we can maintain fixed behavior for the upper section and still allow for an arbitrary number of users.
</p>

<p>Implemented this looks something like the following:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;tag-selector&quot;&gt;
  &lt;div class=&quot;tag-selector-panel&quot;&gt;
    &lt;div x-mojo-element=&quot;TextField&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;form-wrapper&quot;&gt;
      &lt;div x-mojo-element=&quot;Button&quot;&gt;&lt;/div&gt;
      &lt;div x-mojo-element=&quot;Button&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;tag-scroller&quot; x-mojo-element=&quot;Scroller&quot;&gt;
    &lt;div x-mojo-element=&quot;List&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>

<p>With the CSS doing most of the heavy lifting:</p>
<pre class="brush: css; title: ; notranslate">
.tag-selector {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;

  z-index: 1000;

  display: -webkit-box;
  -webkit-box-orient: vertical;
}

.tag-scroller {
  position: static !important;
  -webkit-box-flex: 1; 
}
</pre>

<p>
A live demo for Firefox and Safari/Chrome available is available <a href="http://demo.incaseofstairs.com/flex-box/index.html">here</a>. Note that the demo is running a modified version to handle desktop and cross-browser differences. These are mostly experimental prefix concerns i.e. <code>display: -webkit-box</code> becomes
</p>
<pre class="brush: css; title: ; notranslate">
    display: -webkit-box;
    display: -moz-box;
    display: box;
</pre>
<p>
Although there are a few hacks in place to force common layout under both WebKit and Gecko (See <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=570036">Bug 570036</a>). Such is life developing with CSS3 :)
</p>

<h3>Future Posts</h3>
<p>
As a final note, I&#8217;d like to start a series of these posts. Are there any sections of the Facebook app that you would like me to provide an overview of their implementation? Feel free to comment on this post or drop me a line at <a href="mailto:kpdecker@gmail.com">kpdecker@gmail.com</a>.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/06/implementation-facebook-for-webos-add-tag-ui/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>border-image-generator: Local File Access</title>
		<link>http://www.incaseofstairs.com/2010/05/border-image-generator-local-file-access/</link>
		<comments>http://www.incaseofstairs.com/2010/05/border-image-generator-local-file-access/#comments</comments>
		<pubDate>Mon, 31 May 2010 20:23:51 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[border-image-generator]]></category>
		<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=277</guid>
		<description><![CDATA[This article covers the techniques used to implement the local file access feature that is included, along with tiling support, alternate styling, and parameter optimization, in the most recent push to border-image-generator. One of the biggest short comings that I felt like border-image-generator was that all files had to be posted on a HTTP server [...]]]></description>
			<content:encoded><![CDATA[<p>
This article covers the techniques used to implement the local file access feature that is included, along with tiling support, alternate styling, and parameter optimization, in the most recent push to <a href="http://border-image.com">border-image-generator</a>.
</p>
<p>
One of the biggest short comings that I felt like border-image-generator was that all files had to be posted on a HTTP server due to restrictions on the access to the <code>file://</code> protocol. In my personal workflow this was somewhat of a pain, so I set out to find a way around this issue.
</p>
<p>
During the design of this feature, I quickly decided that all data must remain on the client as I did not want to upgrade my hosting service to include more bandwidth, felt like responsiveness could be a concern, and do not want to tangle with the potentially messy privacy issues that could arrise from storing user generated images on my server.
</p>
<p>
While this sounded like a daunting task, it turns out that this was possible, in sufficiently advanced browsers, using a variety of HTML5 techniques, including <a href="http://en.wikipedia.org/wiki/Data_URI_scheme">Data URIs</a>, the <a href="http://www.w3.org/TR/FileAPI/">File API</a> and the <a href="http://www.w3.org/TR/webstorage/">Web Storage API</a>.
</p>

<h3>Display</h3>
<p>
The problem of displaying the image was the easiest to solve as all of the targeted browsers support data URIs as part of the <code>border-image</code> property. This allowed the application to generate URLs like the following
</p>
<pre class="brush: css; title: ; notranslate">
    border-width: 46px;
    border-image: url(&quot;data:image/png;base64,iVBORw0KGgoAAA....&quot;) 46 stretch;
</pre>

<p>
And operate as expected. Data URIs have been covered fairly extensively elsewhere, so I will leave this to the reader to investigate.
</p>

<h3>Reading</h3>
<p>
With the actual display issue solvled, there was still the non-trivial issue of actually loading the content. My initial investigations involved Flash, which provides <a href="http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/net/FileReference.html#load()">FileReference.load</a> API which allowing for this functionality, but under the version I was testing on this API is only usable if invoked in response to user input. Being a HTML guy and lacking functional knowledge of the Flash development process I quickly ruled this technique out.
</p>
<p>
Continuing my research I came across an <a href="https://developer.mozilla.org/en/Using_files_from_web_applications">article</a> on MDC that covered this exact use case, using the draft File API specification. This worked like a charm, even exposing the ability to read the image contents directly into a data URI.
</p>

The API is very clean for use cases such as this:

<pre class="brush: jscript; title: ; notranslate">
function loadFile(file) {
    var reader = new FileReader();
    reader.onload = function(event) {
         updateImageURI(file.name, reader.result);
     };
     reader.readAsDataURL(file);
}
</pre>
<p>
Where the <code>file</code> variable above is a <code>File</code> object retrieved from a <pre class="brush: xml; light: true; title: ; notranslate">&lt;input type=&quot;file&quot;&gt;</pre> or the <code>dataTransfer</code> object passed to the <code>drop</code> html event.
</p>

<pre class="brush: jscript; title: ; notranslate">
        $(&quot;body&quot;).bind(&quot;dragenter dragover&quot;, function(event) {
            // We have to cancel these events or we will not recieve the drop event
            event.preventDefault();
            event.stopPropagation();
        });
        $(&quot;body&quot;).bind(&quot;drop&quot;, function(event) {
            event.preventDefault();
            event.stopPropagation();
            var dataTransfer = event.originalEvent.dataTransfer,
                file = dataTransfer.files[0];

            loadFile(file);
        });
        $(&quot;#localImage&quot;).bind(&quot;change&quot;, function(event) {
            var file = this.files[0];

            loadFile(file);
        });
</pre>

<p>
This unfortunately is not without it&#8217;s issues. The File API is very much bleeding edge at this point and support is somewhat limited. As of this writing Firefox is the only browser which features this in production (Version 3.6). Support <a href="http://trac.webkit.org/changeset/59162">landed</a> in the WebKit trunk literally earlier this month and can be used in their nightlies, but so far has not made it into any production releases.
</p>
<p>
The site is currently designed to progressively enhance as it detects support for the File API, so no need to worry about being left out of the site as a whole if you are not on one of these browsers yet.
</p>

<h3>History</h3>
<p>
After loading the content using the File API, the original implementation utilized the same #hash storage method for the data URIs, but this proved to be problematic as these strings can become quite large and interacting with these URLs was unwieldily. Needing another data store and being forced to maintain a cache of all local images due to the security model employed by the File API, we were left the options of storing all data in Javascript space or using the new Web Storage APIs implemented as part of HTML5.
</p>
<p>
Examining both options it seemed the the best course was to utilize the <code>sessionStorage</code> object when available and fail over to the javascript data model when not.
</p>
<pre class="brush: jscript; title: ; notranslate">
    // Check for browser support of session storage and that it is accessible
    // This may be inaccessible under certain contexts such as file://
    function supportsSessionStorage() {
        try {
            return !!window.sessionStorage;
        } catch (err) {
            return false;
        }
    }
    var localDataBinding = (function() {
        if (supportsSessionStorage()) {
            // If they support FileReader they really should support storage... but who knows (With the exception of file://)
            return {
                storeImage: function(name, data) {
                    var entryId = (parseInt(sessionStorage[&quot;imageList-count&quot;])||0)+1;
                    sessionStorage[&quot;imageList-count&quot;] = entryId;
                    sessionStorage[&quot;imageList-src-&quot; + entryId] = data;
                    sessionStorage[&quot;imageList-display-&quot; + entryId] = name;
                    return entryId;
                },
                getImage: function(entryId) {
                    return { src: sessionStorage[&quot;imageList-src-&quot; + entryId], displayName: sessionStorage[&quot;imageList-display-&quot; + entryId] };
                }
            };
        } else {
            // Fail over to plain js structures, meaing that refresh, etc will cause failures.
            var cache = [];
            return {
                storeImage: function(name, data) {
                    cache.push({ src: data, displayName: name });
                    return cache.length-1;
                },
                getImage: function(entryId) {
                    return cache[entryId];
                }
            };
        }
    })();
</pre>

<p>
Working with this API it seems as though it is still somewhat rough. The vendor documentation all state that supported datatypes are only string values (<a href="https://developer.mozilla.org/en/dom/storage">Mozilla</a>, <a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/Storage_idl/Classes/Storage/index.html">WebKit</a>), but the spec implies that this will change be final release and allow for storage of a much broader set of datatypes.
</p>
<p>
A consequence of this design is that boomark and URL sharing for local files is not a possibility. For users who need to share or store  application states the image in question will need to be stored on a HTTP server and accessed by this route.
</p>
<p>
These changes as well as some incremental changes have been pushed live on <a href="http://border-image.com">border-image.com</a> and are available in the github <a href="http://github.com/kpdecker/border-image-generator">repository</a>.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/05/border-image-generator-local-file-access/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Javascript Operation Queue</title>
		<link>http://www.incaseofstairs.com/2010/05/javascript-operation-queue/</link>
		<comments>http://www.incaseofstairs.com/2010/05/javascript-operation-queue/#comments</comments>
		<pubDate>Fri, 28 May 2010 08:43:00 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[Dev]]></category>
		<category><![CDATA[Palm]]></category>
		<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[webOS]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[palmdev]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=258</guid>
		<description><![CDATA[When developing for a platform that relies on asynchronous APIs, such as webOS, the application logic frequently will need to block on a given operation prior to executing other dependent components. This may include anything from loading user data after authentication to saving data after initialization of a given data structure among others. One method [...]]]></description>
			<content:encoded><![CDATA[<p>
When developing for a platform that relies on asynchronous APIs, such as webOS, the application logic frequently will need to block on a given operation prior to executing other dependent components. This may include anything from loading user data after authentication to saving data after initialization of a given data structure among others.
</p>
<p>
One method of handling this problem is to make the blocker component explicitly aware of the dependent components and the unique interface to each component, which works for simple cases or situations where the dependent to blocking relationship is one-to-one, but this quickly becomes complicated as a number of dependent components grows. In the extreme cases the blocker may have to be aware of significant portions of the system, leading to maintenance concerns.
</p>
<p>
Alternatively the blocker call can allow dependent components to register their interest in the completion of the operation and upon completion the blocker can simply notify the components on this list in a generic fashion. This allows that components to remain loosely coupled and has the added benefit of allowing for run-time conditional relationships without requiring that the blocker be aware of the state of the dependent.
</p>
<p>
Implementing such a notification system is fairly straightforward in Javascript: Simply collect waiting callbacks in an array or other structure then executing each upon completion of the blocking call.
</p>

<h3>Library</h3>
<p>
While simple to implement, my experience on<a href="http://www.facebook.com/apps/application.php?id=4620273157">Facebook for webOS</a> has shown that a library to implement this behavior is worth the initial effort as manually writing nearly identical for loops over callbacks for the umpteenth time becomes tedious and error-prone.
</p>
<p>
To this end, we developed and open sourced the <code>OperationQueue</code> class which provides a common implementation that doesn&#8217;t require far too many for loops :)
</p>

<h3>Usage</h3>
<p>To use the <code>OperationQueue</code> class you simply need to enqueue your dependent operations using the <code>queue</code> API.</p>

<p><code>queue</code> can accept a single function which will be called upon successful completion.</p>
<pre class="brush: jscript; title: ; notranslate">
    opQueue.queue(function(result) {
        // Do something with the data that we were waiting for!
        console.log(&quot;Blocking Operation Completed!&quot;);
    });
</pre>

It also accepts an object with any combination of <code>onSuccess</code> and <code>onFailure</code> fields who will be called for each respective event.
<pre class="brush: jscript; title: ; notranslate">
    opQueue.queue({
        onSuccess: function(result) {
            // Do something with the data that we were waiting for!
            console.log(&quot;Blocking Operation Completed!&quot;);
        },
        onFailure: function(result) {
            console.log(&quot;Blocking Operation Failed&quot;);
        }
    });
</pre>

<p>
These calls may occur at anytime. If the blocking operation has already completed then calls to <code>queue</code> will result in immediate execution of the queued operation. In this case the result object will not be included.
</p>
<p>
For the blocking call itself the <code>getSuccessHandler</code> and <code>getFailureHandler</code> generators will return callback functions that may be used to directly on completion or may be passed as callback handlers to the async API. These methods also accept a function parameter which will be called prior to their completion.
</p>

Used directly:
<pre class="brush: jscript; light: true; title: ; notranslate">(opQueue.getSuccessHandler())();</pre>

As a callback:
<pre class="brush: jscript; title: ; notranslate">
ServiceRequestWrapper.request('palm://com.palm.preferences/systemProperties', {
        method:&quot;Get&quot;,
        parameters:{&quot;key&quot;: &quot;com.palm.properties.nduid&quot; },
        onSuccess: opQueue.getSuccessHandler(function(response) {
                Mojo.Log.info(&quot;Device ID: %j&quot;, response);
            }),
        onFailure: opQueue.getFailureHandler()
    });
</pre>

<p>
For more complicated use cases, the <code>reset</code> function allows for enabling and disabling queuing at any time. For example, if you need to initially allow all operations to proceed and then block only while a given operation is in progress, the <code>getSuccessHandler</code> API may be called immediately after instantiation of the queue and then <code>reset</code> called prior to execution of the blocking operation.
</p>

<h3>Source:</h3>
<p>
<a href="http://github.com/palm/webos-samples/tree/master/tipsAndTricks/operation-queue/">Operation queue</a> is available in the <a href="http://github.com/palm/webos-samples/">webos-samples</a> repository on github, within the <a href="http://github.com/palm/webos-samples/tree/master/tipsAndTricks/">tipsAndTricks</a> subproject.
</p>
<p>
One final note: While this was written for a webOS application, it does not depend on any webOS-specific constructs and may be used in any Javascript environment. To see it in action, check out the <a href="http://demo.incaseofstairs.com/operation-queue/">demo</a> in any browser!
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/05/javascript-operation-queue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>border-image-generator</title>
		<link>http://www.incaseofstairs.com/2010/04/border-image-generator/</link>
		<comments>http://www.incaseofstairs.com/2010/04/border-image-generator/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 23:52:39 +0000</pubDate>
		<dc:creator>kpdecker</dc:creator>
				<category><![CDATA[border-image-generator]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=174</guid>
		<description><![CDATA[Update: border-image-generator is not hosted on border-image.com. The previous URLs are configured to redirect to this url. The CSS3 border-image property allows for some very cool and efficient design but after implementing them in both Mozilla for the Firebug search panel and WebKit for the Palm Facebook notifications badge, I&#8217;ve learned that they can be [...]]]></description>
			<content:encoded><![CDATA[<p>
Update: border-image-generator is not hosted on <a href="http://border-image.com">border-image.com</a>. The previous URLs are configured to redirect to this url.
</p>
<p>
<img class="alignright size-full  wp-image-180" title="border-image-generator Example" src="http://static.incaseofstairs.com/uploads/2010/04/Screen-shot-2010-04-04-at-6.10.36-PM.png" alt="Example of the border-image-generator visual editor. " width="137" height="137" />The CSS3 <code><a href="http://www.w3.org/TR/css3-background/#border-images">border-image</a></code> property allows for some very cool and efficient design but after implementing them in both Mozilla for the Firebug search panel and WebKit for the Palm Facebook notifications badge, I&#8217;ve learned that they can be quite frustrating to properly tweak by hand.
 </p>

<h3>Background</h3>
<p>
For those who have not been exposed to this property, it allows a single image to be used to style the borders and background of a particular element. In the example above, each section will map to a different border, corner, or the content background, allowing for a single element and image to provide styling the previously required significantly more of each.
</p>
<p>
Using these properties the following element can be rendered using simple semantic HTML and CSS.
</p>

<img class="alignnone size-full wp-image-188" title="Rendered Element" src="http://static.incaseofstairs.com/uploads/2010/04/Screen-shot-2010-04-04-at-6.29.07-PM.png" alt="Element rendered using border-image" width="173" height="88" />

<pre class="brush: xml; title: ; notranslate">
&lt;div class=&quot;stylishContent&quot;&gt;Some stylish content&lt;/div&gt;
</pre>

<pre class="brush: css; title: ; notranslate">
.stylishContent {
    display: inline-block;
    border-width: 27px 27px 27px 27px;
    -moz-border-image: url(http://www.w3.org/TR/css3-background/border.png) 27 27 27 27; -webkit-border-image: url(http://www.w3.org/TR/css3-background/border.png) 27 27 27 27;
    border-image: url(http://www.w3.org/TR/css3-background/border.png) 27 27 27 27;
}
</pre>

<p>
For more detail, John Resig has published an <a href="http://ejohn.org/blog/border-image-in-firefox/">excellent writeup</a> on the Mozilla <a href="https://developer.mozilla.org/En/CSS/-moz-border-image">implementation</a>.
</p>

<h3>App</h3>
<p>
As noted above there is a bit of tweaking involved in getting these settings right. To ease some of this pain I&#8217;ve created the border-image-generator project, which allows for WYSIWYG editing of these properties. Rather than manually adjusting each parameter, border-image-generator allows the various parameters involved to be changed visually with instant preview of what these changes will look like in the current browser.
</p>
<p>
Seen in action demonstrating Resig&#8217;s examples <a href="http://www.incaseofstairs.com/border-image-generator/#%7B%22src%22%3A%22http%3A%2F%2Fwww.w3.org%2FTR%2Fcss3-background%2Fborder.png%22%2C%22linkBorder%22%3Atrue%2C%22borderWidth%22%3A%5B8%2C0%2C0%2C0%5D%2C%22imageOffset%22%3A%5B27%2C27%2C27%2C27%5D%2C%22scaleFactor%22%3A3.689655172413793%7D">here</a> and <a href="http://www.incaseofstairs.com/border-image-generator/#%7B%22src%22%3A%22http%3A%2F%2Fejohn.org%2Ffiles%2Fborder-image%2Fiui%2Fiui%2FwhiteButton.png%22%2C%22linkBorder%22%3Atrue%2C%22borderWidth%22%3A%5B0%2C0%2C0%2C0%5D%2C%22imageOffset%22%3A%5B12%2C12%2C12%2C12%5D%2C%22scaleFactor%22%3A4.655172413793103%7D">here</a>.
</p>

<h4>Features</h4>
<ul>
	<li>WYSIWYG editing of border-image properties</li>
	<li>Cross-browser border-image CSS generation</li>
	<li>URL-based State (History + Preview in multiple browsers)</li>
</ul>
<p>It can be accessed through any of the following URLs:</p>
<ul>
	<li><a href="http://border-image.com/">border-image</a></li>
	<li><a href="http://github.com/kpdecker/border-image-generator">github/kpdecker/border-image-generator</a></li>
</ul>
<p>
Any issues or suggestions for improvements can be sent to myself or logged in the github <a href="http://github.com/kpdecker/border-image-generator/issues">issue tracker</a>.
</p>

<h3>Warning</h3>
<p>
As a preliminary warning this is currently a vendor experimental feature but it is currently set to be included in the CSS3 specification. There are some significant differences between the vendor implementations and the W3C candidate, so some caution should be used. Border-image-generator attempts to handle these cases as defined by the spec, but many things could change between the current implementations and the release of CSS3 implementations in the wild.
</p>

<h3>Related Links:</h3>
<ul>
	<li><a href="https://developer.mozilla.org/En/CSS/-moz-border-image">MDC -moz-border-image Property</a></li>
	<li><a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266--webkit-border-image">ADC -webkit-border-image Documentation</a></li>
	<li><a href="http://www.w3.org/TR/css3-background/#border-images">W3C Standard Documentation</a></li>
	<li><a href="http://ejohn.org/blog/border-image-in-firefox/">John Resig&#8217;s article</a></li>
        <li><a href="http://www.suburban-glory.com/blog?page=111">Suburban Glory&#8217;s article</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/04/border-image-generator/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Firediff 1.0 Released</title>
		<link>http://www.incaseofstairs.com/2010/03/firediff-10-released/</link>
		<comments>http://www.incaseofstairs.com/2010/03/firediff-10-released/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 20:37:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Firediff]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.incaseofstairs.com/?p=136</guid>
		<description><![CDATA[After more than a year of development I am absolutely ecstatic to announce the 1.0 release of Firediff. There were quite a few hiccups due to personal commitments in this development cycle, but I feel like this release is quite solid and brings quite a few must have features. As noted in the previous alpha and [...]]]></description>
			<content:encoded><![CDATA[<p>
After more than a year of development I am absolutely ecstatic to announce the 1.0 release of Firediff. There were quite a few hiccups due to personal commitments in this development cycle, but I feel like this release is quite solid and brings quite a few must have features.
</p>
<p>
As noted in the previous alpha and beta announcements, this release adds many key features to the 0.2.1 release:
<ul>
	<li>Revert Changes</li>
	<li>Save Snapshot</li>
	<li>Save Diff</li>
	<li>Document Formatters</li>
	<li>Search</li>
	<li>Activation Data Handling Improvements</li>
	<li>Style attribute change handling</li>
</ul>
</p>
<p>
At this point I have achieved the majority of my initial goals for Firediff and feel as though it fits most of the realistic needs that I originally envisioned when I set out on this project. From this point onward the community is even more vital in defining the future direction of Firediff as I am looking for additional features that can be implemented.
</p>
<p>
The following features and fixes are currently under consideration for future releases but we are looking for more to implement.
<ul>
	<li>Filtering of the changes view</li>
	<li>Stack trace</li>
	<li>Free Edit Diffing</li>
	<li>Entire tree diffs on insertion or removal</li>
	<li>Improved handling of inline stylesheets</li>
	<li>Iframe Support</li>
	<li>Parity changes with Firebug enhancements</li>
</ul></p>
<p>
Any input from the community in terms of feature request or code contributions that will help improve the quality of the project. If you have a cool feature that you would like to see implemented in Firediff, please feel free to file bugs or enhancement requests with the fbug project or contact me directly.
</p>
<p>
Version 1.0 is available on <a href="http://www.incaseofstairs.com/download/firediff/firediff1.0.xpi">here</a> and has been seeded to <a href="https://addons.mozilla.org/en-US/firefox/addon/13179">AMO</a> (Under review as of this writing).
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.incaseofstairs.com/2010/03/firediff-10-released/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

