<?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>existdissolve.com &#187; Web Design</title>
	<atom:link href="http://existdissolve.com/category/web-design/feed/" rel="self" type="application/rss+xml" />
	<link>http://existdissolve.com</link>
	<description>the singularity of being and nothingness</description>
	<lastBuildDate>Wed, 16 May 2012 12:54:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>CSS3 Infographic</title>
		<link>http://existdissolve.com/2012/01/css3-infographic/</link>
		<comments>http://existdissolve.com/2012/01/css3-infographic/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 20:26:28 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Flex-box]]></category>
		<category><![CDATA[Infographic]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2356</guid>
		<description><![CDATA[There&#8217;s something with me, the weekend, and CSS3&#8230;hmm&#8230; On Saturday, Google Politics &#38; Elections posted an interesting infographic about search trends over the last week related to the four remaining GOP Presidential candidates. Here&#8217;s the infographic: Overall, pretty nice. It makes good use of color, highlights the important details, and avoids loading the graphic with&#8230;]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s something with me, the weekend, and CSS3&#8230;hmm&#8230;</p>
<p>On Saturday, <a href="https://plus.google.com/u/0/114401727024677849167/posts">Google Politics &amp; Elections</a> posted an interesting infographic about search trends over the last week related to the four remaining GOP Presidential candidates.</p>
<p>Here&#8217;s the infographic:</p>
<div class="wp-caption alignnone" style="width: 624px"><img class=" " title="Top 4 Candidate Search Gains (1/14 - 1/21)" src="https://lh6.googleusercontent.com/-i9HmVaMuS3Q/TxsJSXk-8tI/AAAAAAAACHg/d9t9nX6FPXs/s1024/gingrich%2Bsurge%2B2.jpg" alt="" width="614" height="346" /><p class="wp-caption-text">From Google Politics &amp; Elections</p></div>
<p>Overall, pretty nice. It makes good use of color, highlights the important details, and avoids loading the graphic with needless frills, pointless content, etc.</p>
<p>The one problem, though, is that it&#8217;s simply an image. While it&#8217;s nice to look at, it&#8217;s kind of boring.</p>
<h2>Some CSS3 Up In Here</h2>
<p>So as I was internally complaining about how boring the image qua image is, it occurred to me that some simple CSS3 flourishes could really make this nice.</p>
<p><strong><a href="http://existdissolve.com/demos/css3/infographic/">Check Out the Example</a> </strong>(note: you&#8217;ll need a more recent version of Webkit or Firefox for this to work&#8230;)</p>
<p>In this experiment, I&#8217;m using a few things I&#8217;ve not messed with much in the past: <strong>keyframes</strong> and the <strong>flex-box model</strong>.</p>
<h3>Flex-Box Model</h3>
<p>If you&#8217;re a web designer, you&#8217;ve no doubt spent endless hours trying to coax HTML and CSS to do simple things like expand &#8220;columns&#8221; a particular percentage in width and height. This is a horrible nightmare to endure, and it usually ends in a lot of hacks and more cursing, just to get content to line up correctly.</p>
<p>Enter the flex-box model. WIth the flex-box model, you can create dynamic, &#8220;flexible&#8221; areas of content that not only &#8220;flex&#8221; to fill space based on your precise specification, but can also have intrinsic relationships to other elements.</p>
<p>In my example, I used the flex-box model to handle laying out the &#8220;name&#8221; and &#8220;percentage&#8221; content in each candidate&#8217;s &#8220;bar.&#8221; Here&#8217;s the HTML:</p>
<pre>&lt;div class="bar"&gt;
    &lt;img src... /&gt;
    &lt;div class="name"&gt;Newt Gingrich&lt;/div&gt;
    &lt;div class="total"&gt;+688%&lt;/div&gt;
&lt;/div&gt;</pre>
<p>Very simple. In fact, the flex-box doesn&#8217;t really require much in the way of mark-up&#8230;you can easily use the basic structures that you would normally implement.</p>
<p>Since there&#8217;s nothing special about the markup, the real magic happens in CSS:</p>
<pre>// flex box styles for "bar" container
.bar {
    display: -webkit-box;
    display: -moz-box;
}
// flex box styles for "name" content
.name {
    -webkit-box-flex: 1;
    -moz-box-flex:1;
}</pre>
<p><strong>That&#8217;s it?</strong> Yep, that&#8217;s it. When we add &#8220;display:box;&#8221; to the parent element, we are telling it that it should behave according to the flex-box model. By default, this will lay out all of its children along the horizontal axis. Notice we didn&#8217;t have to float anything. That is awesome.</p>
<p>And for the &#8220;name&#8221; content, we&#8217;ve added the &#8220;box-flex&#8221; attribute and given it a value of &#8220;1&#8243;. This tells the individual item that not only should it be laid out horizontally with its siblings, but that moreover it should take up additional space. Since we&#8217;ve applied &#8220;box-flex&#8221; to only 1 element, this will take up any remaining space in the parent&#8211;if other siblings had &#8220;box-flex&#8221; as well, the value of &#8220;1&#8243; would change in relation to the box-flex of the other siblings.</p>
<p>In essence, what this does it to give us a really nice horizontal layout of 3 items (the image, the &#8220;name&#8221; and the &#8220;percentage&#8221;) without needing floats, positioning, or any other nonsense. Since &#8220;name&#8221; is the only content with &#8220;box-flex&#8221; assigned, it will greedily gobble up the remaining space left over in the parent, resulting in a nice right-alignment of the variable-width &#8220;percentage&#8221; content. Did I mention no floats? Hooray.</p>
<h3>Keyframe Animations</h3>
<p>Besides the super-sweet flex-box utilization, this example also uses the super-fancy keyframe animation specification. What are keyframes? Think about when you used to create animations in Flash, and you created keyframes at specified points along a timeline where you wanted specific events to occur. Keyframes in CSS3 animations are very similar.</p>
<p>In this example, I wanted to animate the background of the main content area (the gradients behind each candidate). WIth the keyframe specification, this is stupid simple. Here&#8217;s some CSS:</p>
<pre>@-webkit-keyframes expanding {
    0%   { width:0;}
    100% { width:100%;}
}
.bar {
    -webkit-animation-iteration-count: 1;
    -webkit-animation-name: expanding;
    -webkit-animation-duration: .25s;
    -webkit-animation-timing-function:ease-in-out;
    -webkit-animation-fill-mode: forwards;
}</pre>
<p>This is a bit more involved than the flex-box model, so let&#8217;s take a look piece by piece.</p>
<p>The first chunk of code is where we define the keyframe to be used in the animation. You use the <strong>@-webkit-keyframes</strong> directive, and then provide a name (&#8220;expanding&#8221;, in this example). Then, within the object, you simply define the style rules that should be applied at each &#8220;frame&#8221; of the animation. In this example, we have a very simple definition. At the start of the animation (0%), the width of the element will be 0; at the end (100%) the width will be 100%. The cool part is that the browser takes care of the animation in between each keyframe, and this is why we get the horizontal bar &#8220;expansion&#8221; animation in this example.</p>
<p>The next chunk of code is how we 1.) apply the keyframe specification to the particular element (&#8220;animation-name&#8221;) and 2.) additionally configure how the animation will behave, such as the duration, why kind of timing function should be applied, how many times the animation should run, etc.</p>
<p>Pretty cool stuff.</p>
<h2>Some Caveats</h2>
<p>Unfortunately, support in browsers for some of the cooler stuff in this demo is currently pretty limited. To the best of my knowledge, both the flex-box and keyframe specification are only implemented in Webkit and Firefox.</p>
<p>Moreover, I didn&#8217;t bother with a graceful degradation to other browsers. So if you open this example in IE, Opera, etc., you&#8217;re out of luck. If you feel like implementing a graceful degradation, feel free to <a href="https://github.com/existdissolve/InfoGraphic">grab the source from GitHub</a>.</p>
<h2>Wrapping Up</h2>
<p>While a lot of these features are still not yet ready for primetime, I think this example shows ways in which these new aspects of CSS3 can help to improve the experience of the internet. Does this application of CSS3 radically improve the infographic? Probably not. However, it does show the promise of how simple interactivity can be added without much pain at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2012/01/css3-infographic/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sencha Touch Theming: 1.1.0</title>
		<link>http://existdissolve.com/2011/04/sencha-touch-theming-1-1-0/</link>
		<comments>http://existdissolve.com/2011/04/sencha-touch-theming-1-1-0/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 05:05:01 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[CSS3]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Sencha Touch]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2087</guid>
		<description><![CDATA[In my last article, I showed how to get setup and started with creating custom stylesheets. After a significant release (1.1.0) and several reader requests, I&#8217;m updating the walkthrough with screenshots and instructions for v1.1.0. This version will be strictly business: for discussion about the more interesting points of what&#8217;s going on, refer back to&#8230;]]></description>
			<content:encoded><![CDATA[<p>In my last article, I showed how to <a href="http://existdissolve.com/2011/03/sencha-touch-theming-getting-started/">get setup and started with creating custom stylesheets</a>. After a significant release (1.1.0) and several reader requests, I&#8217;m updating the walkthrough with screenshots and instructions for v1.1.0. This version will be strictly business: for discussion about the more interesting points of what&#8217;s going on, refer back to the original post <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Step 1: Install Ruby</h2>
<p>To get SASS setup, you’ll first need to install Ruby and Ruby Gems (SASS is bundled with something called “Compass”, and Compass is a “Gem” that can be added into Ruby). You can go the painful route and install Ruby and then add Gems into it. However, if you’re stupid about these things, you can do what I did and just grab the Ruby 1.92 installer–it comes pre-built with Gems already configured.</p>
<h3>Get the <a href="http://rubyforge.org/frs/download.php/74298/rubyinstaller-1.9.2-p180.exe">Ruby 1.92 Installer</a></h3>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/04/rubysplash.jpg"><img class="size-full wp-image-2088" style="display: block;" title="rubysplash" src="http://existdissolve.com/wp-content/uploads/2011/04/rubysplash.jpg" alt="" width="350" height="267" /></a></p>
<h3>When prompted, choose “”Add Ruby executables to you PATH”</h3>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/04/ruby-exec.jpg"><img class="size-full wp-image-2090" title="ruby-exec" src="http://existdissolve.com/wp-content/uploads/2011/04/ruby-exec.jpg" alt="" width="350" height="267" /></a></p>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/04/ruby-exec.jpg"></a>I installed to the default directory on Windows (C:\Ruby192\)</p>
<h2>Step 2: Setup Compass</h2>
<p>Now that Ruby is installed, the next step is to get Compass (e.g., SASS) setup. This step actually took me the longest, simply because I’m stupid about command-line stuff. So here’s a play-by-play of what to do (this is for Windows…I assume Mac is similar), just in case you suffer from a similar level of stupidity:</p>
<ul>
<li>Open a new Command Shell (Start -&gt; Run -&gt; type “cmd”)</li>
<li>Navigate to your Ruby installation directory (cd/ruby192)</li>
<li>Type “<span style="color: #ff0000;"><strong>gem install compass &#8211;pre</strong></span>” – if it works, you should see a bunch of text appear about things being installed, configured, and what not.</li>
<li>BTW, we&#8217;re using &#8220;&#8211;pre&#8221; to get a beta version (0.11) of Compass. This is necessary, as the latest non-beta will break when compiling.</li>
</ul>
<p><a href="http://existdissolve.com/wp-content/uploads/2011/04/compass-install.jpg"><img class="size-medium wp-image-2091" title="compass-install" src="http://existdissolve.com/wp-content/uploads/2011/04/compass-install-300x124.jpg" alt="" width="300" height="124" /></a></p>
<h3>Step 3: Done!</h3>
<p>You&#8217;re done. The next step is to actually <a href="http://existdissolve.com/2011/03/sencha-touch-theming-building-our-custom-stylesheet-with-sass/">start customizing some sassy stylesheets</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/04/sencha-touch-theming-1-1-0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Chrome Web Apps Upgrade</title>
		<link>http://existdissolve.com/2011/02/chrome-web-apps-upgrade/</link>
		<comments>http://existdissolve.com/2011/02/chrome-web-apps-upgrade/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 04:11:32 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Web Store]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=2014</guid>
		<description><![CDATA[Just a quick note&#8211;if you didn&#8217;t see, Google Chrome has revamped the display for your personal app dashboard. You can now re-order apps by drag-n-drop, rather than installing and uninstalling in the right order. Check it out]]></description>
			<content:encoded><![CDATA[<p>Just a quick note&#8211;if you didn&#8217;t see, <a href="http://google.com/chrome">Google Chrome</a> has revamped the display for your personal app dashboard. You can now re-order apps by drag-n-drop, rather than installing and uninstalling in the right order.</p>
<p>Check it out <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/02/chrome-web-apps-upgrade/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New HTML5 Logo</title>
		<link>http://existdissolve.com/2011/01/new-html5-logo/</link>
		<comments>http://existdissolve.com/2011/01/new-html5-logo/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 03:54:49 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=1986</guid>
		<description><![CDATA[If you didn&#8217;t see, W3C unveiled a shiny (new) logo to represent the far off dream of HTML5. Check it out &#8211; http://www.w3.org/html/logo/]]></description>
			<content:encoded><![CDATA[<p>If you didn&#8217;t see, W3C unveiled a shiny (new) logo to represent the far off dream of HTML5. Check it out &#8211; <a href="http://www.w3.org/html/logo/">http://www.w3.org/html/logo/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2011/01/new-html5-logo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beginnings</title>
		<link>http://existdissolve.com/2010/11/beginnings/</link>
		<comments>http://existdissolve.com/2010/11/beginnings/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 04:07:04 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Awesomeness]]></category>
		<category><![CDATA[The Viceroy]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=1941</guid>
		<description><![CDATA[Over the weekend, my family and I moved to Maineville, OH.  We were able to find a really nice house with a lot more space than our old cramped apartment.  While unpacking, I decided to finally tackle a task I had been putting off for years: pulling data off my old PC so that I&#8230;]]></description>
			<content:encoded><![CDATA[<p>Over the weekend, my family and I moved to Maineville, OH.  We were able to find a really nice house with a lot more space than our old cramped apartment.  While unpacking, I decided to finally tackle a task I had been putting off for years: pulling data off my old PC so that I can stop dragging it around everywhere I go&#8230;</p>
<p>While browsing these old files, I found the source code for the very first web site that I ever made.</p>
<p>As a disclaimer, this site is very rough.  I had no idea about HTML&#8211;so it&#8217;s basically an export from Photoshop to the web.  But as rough as it is, it was where I got my start, and so this site will always have a special place in my heart.  Plus, it was something that I made for good friends, so that&#8217;s an added bonus <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Anyway, <a href="http://singularityconcepts.com/theviceroy/">check it out</a> when you have a chance, and marvel at the awesomeness!</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2010/11/beginnings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#8217;m Probably Getting Ready to Dump Firefox</title>
		<link>http://existdissolve.com/2010/08/im-probably-getting-ready-to-dump-firefox/</link>
		<comments>http://existdissolve.com/2010/08/im-probably-getting-ready-to-dump-firefox/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 03:59:54 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://existdissolve.com/?p=1680</guid>
		<description><![CDATA[Anyone who knows me knows that I have long been a big supporter of Firefox.  Back in the day, Firefox was the breath of fresh air in the otherwise olfactory-oppressing wasteland of an IE-dominated interwebs.  Firefox was fast, innovative, and, best of all, let you add stuff on to it. Add cool stuff.  Like Pay-Pal plugins.  Like&#8230;]]></description>
			<content:encoded><![CDATA[<p>Anyone who knows me knows that I have long been a big supporter of Firefox.  Back in the day, Firefox was the breath of fresh air in the otherwise olfactory-oppressing wasteland of an IE-dominated interwebs.  Firefox was fast, innovative, and, best of all, let you add stuff on to it.</p>
<p>Add cool stuff.  Like Pay-Pal plugins.  Like RSS readers.  <a href="http://getfirebug.com/">Like Firebug</a>.</p>
<p>It was the bees&#8217; knees, and looked like it was going to gobble up all the stragglers that IE left in its &#8220;who cares about the experience&#8221; attitude toward the internet.</p>
<p>But then Chrome came along.  It was sleek.  It was fast.  And best of all, it brought some fresher-than-Firefox ideas to browsing.</p>
<p>Better, fresher ideas.  Like tabs-on-top.  Like better architecture for faster&#8230;everything.  Like not-having-to-upgrade-every-2.5-seconds.</p>
<p>So I&#8217;ve been using Chrome alot lately.  Sure, it&#8217;s different.  But what I&#8217;ve found is that it&#8217;s better.  Sure, it doesn&#8217;t have Firebug (which is probably the only reason whatsoever that I continue to use Firefox).  But every version gets better.  And faster.  And awesomer.</p>
<p>And Firefox?  Perhaps its my groaning, Vista-laden PC, but Firefox hates everything.  It&#8217;s slow, it freezes, it crashes&#8230;and very few of the plugins that I depend on for Firefox to be awesome can keep up with the releases.</p>
<p>And the things I&#8217;ve been seeing for v4 are less than impressive.  The other day I <a href="http://www.youtube.com/watch?v=HmgtW2Iw-kE">watched a video</a> on their &#8220;new&#8221; feature for 4&#8211;tabs on top.</p>
<p><strong>Tabs on top. </strong></p>
<p>Hmmm&#8230;where have I seen that before?  Oh yeah, every other browser to update its version in the last 6 months.</p>
<p>Now in all fairness, tabs on top makes sense, and the logic in the video&#8211;IMO&#8211;is pretty well founded.  But it just feels like a lot of far too little and way too late.</p>
<p>Obviously, I&#8217;m going to keep using Firefox in some capacity.  There&#8217;s the perennial issue of cross-browser compatibility that I always have to wrangle for my work, and Firebug still destroys Chrome&#8217;s girly development tools. However, I see our paths steadily diverging, and see little opportunities for them to entwine again.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2010/08/im-probably-getting-ready-to-dump-firefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Web SQL: Versions</title>
		<link>http://existdissolve.com/2010/07/html5-web-sql-versions/</link>
		<comments>http://existdissolve.com/2010/07/html5-web-sql-versions/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 21:45:17 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://existdissolve.wordpress.com/?p=1603</guid>
		<description><![CDATA[As mentioned in my last post about Web SQL databases, each Web SQL database consists of a unique name and version.  Each database, however, can only have a single version at any given time, so there&#8217;s no possibility of older and newer versions running concurrently.  To quote the spec, this is provided to &#8220;&#8230;allow authors&#8230;]]></description>
			<content:encoded><![CDATA[<p>As mentioned in my <a href="http://existdissolve.wordpress.com/2010/07/18/html5-web-sql/">last post about Web SQL databases</a>, each Web SQL database  consists of a unique name and version.  Each database, however, can only  have a single version at any given time, so there&#8217;s no possibility of  older and newer versions running concurrently.  To quote the spec, this  is provided to &#8220;&#8230;allow authors to manage schema changes incrementally  and   non-destructively, and without running the risk of old code (e.g.  in   another browser window) trying to write to a database with  incorrect   assumptions.&#8221;   In other words, instead of trying to manage  the hassle of temporarily offloading data, rebuilding the data structure  from scratch, and then reloading data when code changes, versioning  allows for the detection of the client&#8217;s current db version, with the  option of programmatically upgrading them to a different (read &#8220;new&#8217;) version of  the database schema.  Of course, you could conceivably also use this to  detect old versions and point to different code entirely, but that would  be a lot of code to manage&#8230;</p>
<p>My idea on this is to use the versioning as a way to push incremental  database schema changes in a systematic way.  For example, you could  easily define a complex series of schema updates that take the user&#8217;s  database version (whatever it might be) directly to the most current  version.  However, this seems like an undue amount of work to me.   Rather, I think that maintaining a procedural update history of each  version makes more sense.</p>
<p>Here&#8217;s the idea.  Let&#8217;s say that we&#8217;re building a blog.  Perhaps  version 1 of our database is very simple: just a &#8220;posts&#8221; table that  captures <strong>title, content, publishdate, and author</strong>.</p>
<pre><strong>VERSION 1</strong>
posts
      postid
      title
      content
      publishdate
      author</pre>
<p>But let&#8217;s say in  version 2, we add two more tables (comments and categories, for  example).</p>
<pre><strong>VERSION 1          ---&gt;    VERSION 2</strong>
posts                      posts
      postid                    postid
      title                     title
      content                   content
      publishdate               publishdate
      author                    author
                           <em>comments
                                commentid
                                content
                                author
                                publishdate
                                postid
                           categories
                                categoryid
                                category</em></pre>
<p>Now our approach is increasing in complexity, for not only do  we need to give new users the full version 2 schema, but we also need  to upgrade version 1 users to the new schema without destroying their  existing data.</p>
<p>But let&#8217;s push this out into the future a bit.  Perhaps by version 3,  we&#8217;ve added a few more tables.  Now we have to give new users the  version 3 schema and upgrade BOTH version 2 and potential version 1  users to the new schema, taking into the account the discrepencies  between version 1 and 2, and between both 1 and 3 and 2 and 3.</p>
<pre><strong>VERSION 1          ---&gt;    VERSION 3</strong>
posts                      posts
      postid                    postid
      title                     title
      content                   content
      publishdate               publishdate
      author                    author
                           <em>comments
                                commentid
                                content
                                author
                                publishdate
                                postid
                           categories
                                categoryid
                                category
                           tags
                                tagid
                                tag
                           bloginfo
                                title
                                owner
                                tagline</em><strong>

VERSION 2          ---&gt;    VERSION 3</strong>
posts                      posts
      postid                    postid
      title                     title
      content                   content
      publishdate               publishdate
      author                    author
comments                   comments
      commentid                 commentid
      content                   content
      author                    author
      publishdate               publishdate
      postid                    postid
categories                 categories
      categoryid                categoryid
      category                  category
                           <em>tags
                                tagid
                                tag
                           bloginfo
                                title
                                owner
                                tagline</em></pre>
<p>Oh, and  we just realized we need to add an additional column to our original  &#8220;posts&#8221; table, so version 3.1 increases the complexity yet again.</p>
<p>How do we manage this?  Do we write a full complement of schema  updates to get each version (1, 2, and 3) to the current version (3.1)?   If we do, this will be a lot of code.  Do we simply write a bunch of  clunky &#8220;if exists&#8221; procedures in our sql to account for gaps in our  schemas at any stage in the versioning?  It&#8217;s a better solution, but is  still lacking, IMO, because it doesn&#8217;t really show how the changes are  occurring across versions.  If something goes wrong at some point, it&#8217;s  not immediately obvious where the discrepancy originated.</p>
<p>So my solution is to manage the version updates through incremental  upgrades to the newest version by way of any versions in between.   Therefore, if our current version is 3.1, a user with the 1.0 version  will be upgraded to 3.1 by first upgrading to 2, then to 3, then to  3.1.  While this requires a bit more effort than the &#8220;if exists&#8221;  SQL-based solution, it provides an immediate version history, providing  great introspection into how each version is related to the previous,  and to the next.  Let&#8217;s look at how this plays out:</p>
<p>First, I create an array representing the complete version history of  the database:</p>
<pre>this.apphistory    =    ['1.00','2.00','3.00','3.10'];
this.appversion    =    '3.10';</pre>
<p>Then, upon each opening of the database, I invoke a custom method  &#8220;setSchema&#8221; which checks the current version of the database against the  current &#8220;official&#8221; version of the database, and handles the incremental  updates if needed:</p>
<pre>setSchema = function() {
     // set array for holding our sql statements; sql lite can only process one statement at a time
     var sql    = new Array();
     // get history object-- returns current version and whether version is equal to the "official" or current version
     var history = this.getHistory();
     // if client db version is not equal to current appversion, start iterative update
     var ver = history.iscurrent ? this.appversion : history.current;
     if(!history.iscurrent) {
          switch(ver) {
               case '1.00':
                    sql[0]    =    "create table  comments(commentid,content,author,publishdate,postid);";
                    break;
               case '2.00':
                    sql[0]    =    "create table categories(categoryid,category)";
                    sql[1]    =    "create table tags(tagid,tag)";
                    break;
               case '3.00':
                    sql[0]     =   "alter table posts add created";
                    sql[1]    =    "alter table posts add updated";
                    break;
               // default will be a snapshot of the current version of the schema;
               default:
                    sql[0]    =    "create table posts(postid integer primary key  autoincrement,title,publishdate,author,content,created,updated);";
                    sql[1]    =    "create table  comments(commentid,content,author,publishdate,postid);";
                    sql[2]    =    "create table categories(categoryid,category)";
                    sql[3]    =    "create table tags(tagid,tag)";
                    sql[4]    =    "create table bloginfo(name,owner,tagline)";
          }
          this.database.transaction(function (t) {
          for(var i=0;i&lt;sql.length;i++) {
               t.executeSql(sql[i]);
          }
      });
      this.setVersion();
   }
}</pre>
<p>What&#8217;s basically happening here is that the &#8220;default&#8221; case will  always have what the &#8220;official&#8221; version of the database should be.  In  this case, this is the &#8220;3.10&#8243; version of the database.  So if any new  users come to the site, they will get the full-on copy of this database  written to their client.  If, however, they have a previous version of  the database, they don&#8217;t need a full upgrade to the 3.1.  Rather, they  only need incremental changes to get them to the current database  version.  Therefore, if the client has a &#8220;2.00&#8243; database version, they  will execute SQL statements to get them to the &#8220;3.00&#8243; version, and on  the next pass of this method, they will get the final incremental change  to &#8220;3.10.&#8221;</p>
<p>And in the future, when additional tables or columns are  added/modified, the &#8220;default&#8221; case can be updated to include the  changes, and a case for &#8220;3.10&#8243; can be added to manage the incremental  change to the newest version.</p>
<p>As I mentioned before, this is perhaps not the prettiest way to  manage this.  The thing I like, however, is how explicitly it defines  the relationships between the versions.  With a quick glance, we can see  what changes are occurring from version to version.  And, because this  is an iterative process, we don&#8217;t have to worry about updating the  &#8220;version 2.00&#8243; case to get the client database directly to the newest  version (imagine doing that for 50 versions&#8230;yikes!). Rather, because the  upgrade from 2.00 to 3.00 will ALWAYS be the same, we only have to  worry about keeping the newest and most recent versions synched, as this process  will take any previous version iteratively through to the official  current version.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2010/07/html5-web-sql-versions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Web SQL</title>
		<link>http://existdissolve.com/2010/07/html5-web-sql/</link>
		<comments>http://existdissolve.com/2010/07/html5-web-sql/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 19:20:20 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web SQL database]]></category>

		<guid isPermaLink="false">http://existdissolve.wordpress.com/?p=1597</guid>
		<description><![CDATA[A while back, I wrote up a quick post about some of the new client storage options that will be available in HTML5, particularly localStorage and sessionStorage.  While they are both pretty nice alternatives to the clunkiness of managing client cookies, they are definitely limited.  The biggest limitation is the data structure that each supports&#8230;]]></description>
			<content:encoded><![CDATA[<p>A while back, I wrote up a quick post about some of the new client <a href="http://existdissolve.wordpress.com/2010/07/08/html5-storage-goodbye-cookies/">storage options that will be available in HTML5</a>, particularly<strong> localStorage</strong> and <strong>sessionStorage</strong>.  While they are both pretty nice alternatives to the clunkiness of managing client cookies, they are definitely limited.  The biggest limitation is the data structure that each supports (they&#8217;re exactly the same, after all, except for lifetime of the data).  As I pointed out, while their storage capacity is much greater than that of the old cookie, all data is still managed as key/value pairs.  Of course, you can always use JSON encoding to store complex data structures as strings in these options&#8230;however, if you need to get at deeper levels of data relationships, these will quickly get VERY clunky and unusable.</p>
<p>Enter <strong>Web SQL</strong> databases.  As the name implies, Web SQL databases are, well, client-based SQL databases (SQL Lite, to be exact) that can be levered through JavaScript.  Each &#8220;origin&#8221; can have a number of databases, each of which has a unique name and version (more about this later).  If you use something like the Developer Tools in Chrome, you can see these databases in action&#8211;including the databases themselves, child tables, and any data that has been added to the tables.</p>
<h2>Working with Web SQL</h2>
<p>The doorway to creating and using Web SQL databases is the <strong>openDatabase()</strong> method.  It doesn&#8217;t matter if you&#8217;re creating a new database, or creating a connection to an existing one: this is the first thing you&#8217;ll do, and here&#8217;s what it looks like:</p>
<pre>this.database = openDatabase('Blog',"",'A Blog to Rule the World',2000000);</pre>
<p>The openDatabase() method takes 4 required arguments:</p>
<ol>
<li><strong>Name:</strong> Any valid string, including the empty string, is acceptable.  Database names must be unique, however, and should be evaluated in a case-sensitive manner</li>
<li><strong>Version: </strong> The version of the database to open</li>
<li><strong>Display Name:</strong> A friendly name that the browser can use (in prompts, etc.)</li>
<li><strong>Estimated Size:</strong> Each database has a default  maximum size, and users will be prompted to allow this to increase if the data exceeds the default quota.  Specifying a particular value here can avoid this annoyance by telling the browser up front what the total size might eventually be, short-circuiting the otherwise annoying prompts at each incremental increase (e.g., at 5, 10, 15, 20MB&#8230;)</li>
</ol>
<p>Additionally, there is an optional 5th argument&#8211; <strong>callback method</strong>.  This callback method will be invoked if the database is created (not opened), and per the spec should be used to invoke the changeVersion() method to set the appropriate version of the database.  If no callback method is specified, the database will be created with whatever version is specified in the openDatabase() method invocation.</p>
<p>Now that we&#8217;ve got an open connection to our database, let&#8217;s do some stuff to it!</p>
<h2>SQL Transactions</h2>
<p>The core of working with your now-open connection is the Web SQL <strong>transaction()</strong> method.  [There's also the "readTransaction()" method, which allows for read-only access].  This method takes 1-3 arguments, including the following:</p>
<ol>
<li><strong>SQLTransactionCallback:</strong> This is required, and is the executeSql method that will actually execute the sql command (more on this later)</li>
<li><strong>SQLTransactionCallback:</strong> Optional callback method to handle transaction errors.  This method passes both the transaction, and an error object which contains, among other things, a message describing the error</li>
<li><strong>SQLVoidCallback:</strong> Optional callback method executed upon a successful transaction</li>
</ol>
<p>A really cool part about the transaction() method is that it provides the ability for rollback.  This is why, in short, the actual execution of the SQL is wrapped in a transaction.  It&#8217;s kind of a pain if you don&#8217;t care about rollbacks, but if you don&#8217;t care about rollbacks, maybe you don&#8217;t care about data integrity <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Here&#8217;s what a transaction might look like:</p>
<pre>database.transaction(
     function(t){
        //execute sql here...
     }
);</pre>
<h2>Executing SQL</h2>
<p>Now that we&#8217;ve created a transaction() method wrapper, we can actually get down to running some SQL.  This is accomplished by the aptly named <strong>executeSQL()</strong> method.  This method takes up to 4 arguments:</p>
<ol>
<li><strong>SQLStatement:</strong> A valid string representation of the SQL to be executed (this, obviously, is required)</li>
<li><strong>Argument Array:</strong> An array of arguments to be matched in SQL statement (more about this later)</li>
<li><strong>SQLStatementCallback: </strong>An optional callback method to be invoked on successful execution of the SQL statement&#8211;this method passes the transaction and result set from the query&#8230;so it&#8217;s pretty important to specify if you want to return data from the database&#8230;</li>
<li><strong>SQLStatementErrorCallback: </strong> An optional callback method to be invoked when the executeSql() method fails&#8211;this method passes the transaction and error object</li>
</ol>
<p>So let&#8217;s say we want to create a new table called &#8220;posts&#8221; with a few columns.  Our full transaction/executeSql() statement might look like this:</p>
<pre>database.transaction(
     function(t) {
          t.executeSql("create table posts(postid integer primary key autoincrement,title,publishdate,author,content);";
     }
)</pre>
<p>One thing to note, especially relating to schema creation, is that in SQL Lite, only one SQL statement can be executed per request.  So for example, if you&#8217;re trying to create multiple tables at one time (like when you&#8217;re building the schema for your database), you&#8217;ll have to pass the SQL statement for each table creation to an individual executeSql() method.  To streamline this, I simply create an array of SQL statements, and then iterate over them in a loop.  I&#8217;m sure there are other fine ways to accomplish this as well, but this works for me.</p>
<h2>Preventing SQL Injection</h2>
<p>If you&#8217;re a web developer, you should always be aware of the possibility of SQL injection, and do all that you can to prevent it.  Because of the way that Web Sql is structured, it&#8217;s probably a pretty big temptation to build SQL statements on the fly.  DON&#8217;T DO IT. This just opens the door to SQL injection, and because this is all happening in JavaScript, it would not be hard to identify where SQL is being dynamically generated and exploit it.</p>
<p>To help prevent SQL injection, the 2nd argument of the executeSQL() method, the Arguments array, allows you to specify &#8220;placeholders&#8221; in your SQL that can be substituted at execution time with scrubbed and validated data.  It works like this:</p>
<pre>var sql = "insert into posts (title,content,publishdate,author) values (?,?,?,?,?)";
var val = new Array(t,c,p,a);
var executeSql(sql,val);</pre>
<p>As you can see, in the actual SQL statement, I used &#8220;?&#8221; to specify my argument&#8217;s placeholders.  Then, I created a new array containing my scrubbed values coming from the client.  Then, I simply passed both to my executeSql method, and it works brilliantly.  Simple.  Of course, since I&#8217;m passing an array and not a key/value pair object, the order of the arguments compared to the placeholders is EXTREMELY important.  Just keep that in mind <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Finally&#8230;Getting Some Data</h2>
<p>So far, we&#8217;ve seen how to establish a database connection, create transactions, and then execute SQL against the database.  Now let&#8217;s talk about what to do with the data once we get it.</p>
<p>If you&#8217;ll remember, the executeSql() method provides an optional (although recommended) callback method that returns a results object from the executed SQL.  This object contains the following:</p>
<ul>
<li>insertedId:  This is the id of the row that a SQL execution inserted, if any.  If multiple rows were inserted, it returns the id of the last inserted row.  Very handy.</li>
<li>rowsAffected:  This is the number of rows affected by the SQL execution.</li>
<li>rows:  An object containing any rows returned from the SQL execution</li>
</ul>
<p>Once you&#8217;ve got the &#8220;rows&#8221; object to work with, you can retrieve an individual row&#8217;s data like so:</p>
<pre>var row     = results.rows.item(num);
var title   = row.title;
var author  = row.author;
var content = row.content;</pre>
<p>As you can see, each &#8220;column&#8221; in the row can simply be accessed by its name in the object.  Pretty simple, huh?</p>
<h2>So What&#8217;s the Point?</h2>
<p>As we&#8217;ve seen, working with Web SQL databases is pretty straightforward.  If you&#8217;re familiar with anonymous functions, and have a good grasp of general SQL, this is easy stuff.   Plus, because it is SQL based, the concepts involved with managing the data and database structure are no big deal, and you can concentrate more on developing the connections, error-handling, etc.</p>
<p>But on a more conceptual level, what&#8217;s the point of this?  After all, this is still a client-based solution.  If the user goes nuclear on their client history settings, any databases will be wiped out.  If this data, in that sense, is still so &#8220;temporary,&#8221; why bother with it?</p>
<p>Obviously, Web SQL databases are not intended to be replacements for server-based solutions.  On some level, data does need to be managed in a controlled, secure, and &#8220;permanent&#8221; way.  Web SQL is not going to change that.  What it will change, however, is how application development happens.</p>
<p>For example, consider the present situation.  If you&#8217;re developing an application that needs to regularly (let&#8217;s say once a minute) save data states for your users, the way to do this is through either clunky cookies (blah) or regular server-side hits to save records to a managed database.  While this works, it&#8217;s expensive.  Depending on the size of the data and amount of traffic, this could result in thousands and thousands of remote requests hitting every couple seconds.  If you have the hardware to handle this, it&#8217;s not a big deal.  But if you don&#8217;t, it can take it&#8217;s toll.</p>
<p>So what if you could reduce this by a quarter? Or half?  Or a 75%?  Imagine this:  instead of hitting the server every minute to save a data state, you could instead change the schedule to once every 5 minutes.  During those 5 minutes you could still have the same routine running, only in this scenario it would be saving the data state to the client Web SQL database.  Then, after 5 minutes, a protocol could transfer the saved datastates from client to server.  This will be entirely seemless to the user, and will save load on the server by making the requests less frequent.</p>
<p>Or imagine making your applications available offline.  When connected, the client machine could maintain a synchronized set of data with the remote server.  Then, when the client goes offline, they could continue working with the application, utilizing the data from their machine&#8217;s synched data from the server.  Then, when they are available to get online again, the client data repository could be resynched with the remote server, pushing any new or modified data.  While the experience between offline and online states would be different in some ways, the very ability to be able to work online and offline in a more or less seamless manner is a radical paradigm shift for web-based applications, and opens up the doors of some very exciting possibilities.</p>
<h2>The Demo</h2>
<p>Ok, enough of this post.  If you&#8217;re interested in learning more, be sure to check out the <a href="http://dev.w3.org/html5/webdatabase/#concept-database-expected-version">W3C spec</a> of this.</p>
<p>Also, be sure to <a href="http://singularityconcepts.com/code_samples/websql/database.cfm">check out my demo</a> (use Chrome&#8230;).  It&#8217;s a simple blog manager that allows you to create, edit and delete posts.  <a href="http://singularityconcepts.com/code_samples/websql/database.cfm">Check it out!!</a></p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 575px; width: 1px; height: 1px; overflow: hidden;">if(!history.iscurrent) {<br />
switch(ver) {<br />
case &#8217;1.00&#8242;:<br />
sql[0]    =    &#8221;create table comments(commentid,content,author,publishdate,postid);&#8221;;<br />
break;<br />
case &#8217;2.00&#8242;:<br />
sql[0]    =     &#8221;create table categories(categoryid,category)&#8221;;<br />
sql[1]    =    &#8221;create table tags(tagid,tag)&#8221;;<br />
break;<br />
case &#8217;3.00&#8242;:<br />
sql[0]     =     &#8221;alter table posts add created&#8221;;<br />
sql[1]    =    &#8221;alter table posts add updated&#8221;;<br />
break;<br />
// default will be a snapshot of the current version of the schema;<br />
default:<br />
sql[0]    =     &#8221;create table posts(postid integer primary key autoincrement,title,publishdate,author,content,created,updated);&#8221;;<br />
sql[1]    =     &#8221;create table comments(commentid,content,author,publishdate,postid);&#8221;;<br />
sql[2]    =     &#8221;create table categories(categoryid,category)&#8221;;<br />
sql[3]    =    &#8221;create table tags(tagid,tag)&#8221;;<br />
sql[4]    =    &#8221;create table bloginfo(name,owner,tagline)&#8221;;<br />
}<br />
this.database.transaction(function (t) {<br />
for(var i=0;i&lt;sql.length;i++) {<br />
t.executeSql(sql[i]);<br />
}<br />
});<br />
this.setVersion();<br />
}</div>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2010/07/html5-web-sql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HTML5 Server-Sent Events</title>
		<link>http://existdissolve.com/2010/07/html5-server-sent-events/</link>
		<comments>http://existdissolve.com/2010/07/html5-server-sent-events/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 12:38:29 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Push Data]]></category>
		<category><![CDATA[Server-Sent Events]]></category>

		<guid isPermaLink="false">http://existdissolve.wordpress.com/?p=1588</guid>
		<description><![CDATA[A common requirement in the era of Web 2.0 (and beyond) technologies is the ability to have &#8220;smart&#8221; client interfaces that are aware of changes that occur on the server (data, sessions, etc.). Most approaches include some manner of AJAX that regularly polls the server for changes. While this is easy enough to accomplish, it&#8230;]]></description>
			<content:encoded><![CDATA[<p>A common requirement in the era of Web 2.0 (and beyond) technologies is the ability to have &#8220;smart&#8221; client interfaces that are aware of changes that occur on the server (data, sessions, etc.).  Most approaches include some manner of AJAX that regularly polls the server for changes.  While this is easy enough to accomplish, it can be a taxing and somewhat annoying process.  After all, wouldn&#8217;t it be much better if the server could communicate to the client when it has something share, rather than the client mindlessly asking over-and-over-again for the same thing?</p>
<p>In HTML5, this becomes a reality.  Enter Server-Sent Events.  In a nutshell, server-sent events &#8220;<a href="http://dev.w3.org/html5/eventsource/">enable servers to push data to Web pages over HTTP or using   dedicated server-push protocols.</a>&#8221;  This means, basically, that the client doesn&#8217;t have to keep asking for information: the server will notify the client when new information is available.</p>
<p>In it&#8217;s present state, server-sent events are only available for Opera and Chrome (6) dev releases.  Additionally, they are currently implemented in two different ways.  For Opera, the technology utilizes a DOM element  (), while Chrome is entirely JS based.  For this overview, I&#8217;ll be concentrating on the Chrome implementation.</p>
<p>For the example I worked up, <a href="http://singularityconcepts.com/code_samples/serversent/serversent.cfm">I&#8217;ve created a simple chat interface</a>. The basic idea is that two people share usernames, entering them into their respective client interfaces.  When each chat message is sent, the record is saved to a database on the server, and an independent page continues to query the db for new data pertaining to the chat session.  If new data exists, it pushes it to the clients&#8217; interfaces.</p>
<h2>The Code</h2>
<p>So first things first.  Let&#8217;s create our <strong>EventSource</strong>, the base object that we&#8217;ll utilize to make the magic happen:</p>
<pre>serverevent = new EventSource("serversent_helper.cfm");
serverevent.addEventListener('message', onMessageHandler);</pre>
<p>This is easy enough to see what&#8217;s happening.  Basically, I define a new <strong>EventSource</strong>, and pass to it the server-side page that will manage the pushing of data.  Finally, I add a listener to the &#8220;onmessage&#8221; event of the EventSource, which then in turn calls a user-defined function to do whatever with the data from the server (an event object is passed in the callback method).</p>
<p>That&#8217;s it.  Seriously, pretty simple.  From here, the rest is basically getting the data from the server to be in the proper format to work with the EventSource.  And this is where it gets a little murky.  <a href="http://dev.w3.org/html5/eventsource/">Per the spec</a>, the data pushed from the server has to be in a very specific format.  To be honest, I spent more time than I&#8217;d care to admit on this.  But it was a good lesson.</p>
<p>There&#8217;s a lot in the spec about this, so I&#8217;ll only cover the most important details.  This is from <strong>serversent_helper.cfm</strong>, the source specified in the EventSource invocation:</p>
<pre>
           writeoutput("data:"&amp;serializejson(message)&amp;chr(10));
           writeoutput("id:"&amp;qmessages.messageid&amp;chr(10));</pre>
<p>What I&#8217;m not showing you is the queries I used to create and retrieve data from the chat sessions.  Assuming that a chat to be pushed exists, this is the code that generates the data pushed to the client.</p>
<p>First, notice the content declaration of &#8220;<strong>text/event-stream</strong>&#8220;.  This is incredibly important.  If your content is not in this format, the push from the server will not work.</p>
<p>Next, notice the output sections.  Per the spec, data pushed should be in the following format:  &#8220;data:  [string]&#8220;.  It is the combination of &#8220;data:&#8221; and an accompanying string that makes the push work.  Without it, nothing will happen.  Following the &#8220;data:&#8221; declaration, I&#8217;ve also set &#8220;id:&#8221;.  This is important because you can optionally tag each push with an id which will then be subsequently passed as a header in future interactions between the client and server.  Specifically, the header &#8220;Last-Event-ID&#8221; will be used, so if a connection is lost, the last-used id can be processed when the connection is restored, picking up where it left off.</p>
<p>Finally, notice the newline characters at the end of each line (&#8220;chr(10)&#8221; in ColdFusion, &#8220;\n&#8221; in other languages).  This is EXTREMELY important because the &#8220;field names&#8221; of the response are processed on the basis of the newline characters.  In this example, if I did not put the newline character after the &#8220;data&#8221; block, my response would look like <strong>{&#8230;jsonstring&#8230;}id:numeric</strong>, rather than just <strong>{&#8230;jsonstring&#8230;}</strong>.  Additionally, the Last-Event-ID would not get set.</p>
<p>And yes, you can use JSON, so not problems at all pushing complex data objects <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Additional Methods and Considerations</h2>
<p>I didn&#8217;t use these in my demo, but thought I&#8217;d point them out anyway.  Besides the &#8220;onmessage&#8221; event, you can also add listeners to the following exposed events from EventSource:</p>
<ol>
<li><strong>onopen</strong> &#8211; fires when connection between server and client is created</li>
<li><strong>onerror</strong> &#8211; fires when there&#8217;s an error in the connection</li>
</ol>
<p>And in addition to the url and Last-Event-ID, the <strong>readyState</strong> attribute is available from EventSource.  As its name implies, readyState represents the current state of the connection, and can take the following values:</p>
<ol>
<li><strong>CONNECTING</strong> = 0</li>
<li><strong>OPEN</strong> = 1</li>
<li><strong>CLOSED</strong> = 2</li>
</ol>
<h2>Wrapping Up</h2>
<p>As mentioned earlier, because of the relative newness of EventSource, its implementation is severely limited.  However, I think it is a pretty cool idea and I can think of lots of potential uses for this, specifically in relation to connection-less data pushing.  I&#8217;m excited to see how this develops as the spec is more well-defined and more browsers begin to implement it.</p>
<p><a href="http://singularityconcepts.com/code_samples/serversent/serversent.cfm">A note about the demo</a>.  It definitely works, but there are a few things to keep in mind:</p>
<ol>
<li>It will ONLY work with the <a href="http://www.chromium.org/getting-involved/dev-channel">latest dev version of Chrome (v. 6)</a>.  If you try it in any other browser, it will be quite disappointing <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Because it&#8217;s just a quick demo, you&#8217;ll have to arrange a chat with someone with the same dev version of Chrome, and you&#8217;ll have to coordinate the usernames that you&#8217;ll use to try it out, given that the chat sessions are based on user-entered names</li>
<li>Sure, I could have made a static example&#8230;but I thought the chat would show off the tech a bit more&#8230;so sue me!!!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2010/07/html5-server-sent-events/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HTML5(ish) Notifications</title>
		<link>http://existdissolve.com/2010/07/html5ish-notifications/</link>
		<comments>http://existdissolve.com/2010/07/html5ish-notifications/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 17:16:34 +0000</pubDate>
		<dc:creator>existdissolve</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Notifications]]></category>
		<category><![CDATA[Webkit Notifications]]></category>

		<guid isPermaLink="false">http://existdissolve.wordpress.com/?p=1580</guid>
		<description><![CDATA[Something that&#8217;s coming down the pike pretty soon in tandem with HTML5 is the related, but independent W3C draft of a &#8220;Notifications&#8221; interface.  Basically, this new interface provides a way for the browser to send notification messages on your desktop or device.  So as example, while Facebook Chat will currently use AJAX to update the&#8230;]]></description>
			<content:encoded><![CDATA[<p>Something that&#8217;s coming down the pike pretty soon in tandem with HTML5 is the related, but independent <a href="http://dev.w3.org/2006/webapi/WebNotifications/publish/">W3C draft of a &#8220;Notifications&#8221; interface</a>.  Basically, this new interface provides a way for the browser to send notification messages on your desktop or device.  So as example, while Facebook Chat will currently use AJAX to update the content on the browser page (causing the annoying tab &#8220;flicker&#8221; when a new message arrives), using the Notifications interface will allow a browser-independent message to be displayed directly on your desktop.</p>
<p>As with the other items we&#8217;ve been exploring in our look at HTML5-related technologies, Notifications are really easy to work with.  A word of warning, however.  Right now, this is only implemented in <a href="http://www.google.com/chrome/">Chrome</a>, and the W3C spec is itself based upon a <a href="http://www.chromium.org/developers/design-documents/desktop-notifications/api-specification">webkit-specific API</a>.  So in order to make these work right now, you have to use the Chromium API, not the W3C spec.  The fundamental principles are precisely the same (since the latter is based on the former), but has some minor differences.</p>
<p>So now for the <a href="http://singularityconcepts.com/code_samples/notification/notification.cfm">obligatory example</a>&#8211;let&#8217;s get my (or someone else&#8217;s&#8230;) most recent <a href="http://twitter.com/existdissolve">Twitter post</a> and display a notification.</p>
<p>First, let&#8217;s create a reference to the Notifications object:</p>
<pre>var notification = window.webkitNotifications;</pre>
<p>(Notice the &#8220;webkit&#8221; syntax)</p>
<p>Now that we have a reference to our Notifications interface, let&#8217;s handle the entering and submitting of a Twitter username:</p>
<pre>function SetNotification() {
     var username = Ext.get('twitterusername').getValue();
     if(username=='') {
          Ext.Msg.alert('Attention!','Please enter a Twitter username');
          return false;
     }
     if(notification.checkPermission()==0) {
          GetTwitterData();
     }
     else {
          notification.requestPermission(PermissionDelegate);
     }
}</pre>
<p>A few things to point out here.  First, as part of the spec, the user has to grant permissions to the service to create Notifications.  Before we actually handle the requesting of permissions, we can check if permissions already exist by invoking the <strong>checkPermission()</strong> method.  This will return three possible values:</p>
<ol>
<li>PERMISSION_ALLOWED = 0;</li>
<li>PERMISSION_NOT_ALLOWED = 1;</li>
<li>PERMISSION_DENIED = 2;</li>
</ol>
<p>To me, the numbering is a bit counter-intuitive (0 == allowed?), but it&#8217;s easy enough to work with.</p>
<p>So if we&#8217;ve already obtained permissions, we simply call our main function for retrieving Twitter data.  If permissions do not exist, however, we invoke the <strong>requestPermission()</strong> method.  This will create a browser prompt, and the user can either Allow or Deny permissions for Notifications.  requestPermission() takes one argument: a callback function.  This can be invoked to handle post-permission granting/denying.  In this example, the callback is PermissionDelegate():</p>
<pre>function PermissionDelegate() {    �
     // if permissions have been granted (checkpermission()==0), proceed; otherwise, show error message and cancel operation�
     if(notification.checkPermission()==0) {
          GetTwitterData();
     }
     else {
          Ext.Msg.alert('Notice','To receive notifications from this application, please grant permissions when prompted.&lt;br /&gt;&lt;br /&gt;Please try again.');
     }
}</pre>
<p>Simple enough.  If the user grants permissions (checkPermission()==0), we continue with the processing.  If not, we display an error message and suggest that the users tries the operation again.</p>
<p>So on with the example.  I won&#8217;t bore you with the process of getting the Twitter post.  If you want, you can check the source code, but it boils down to the <a href="http://remysharp.com/2007/10/08/what-is-jsonp/comment-page-1/">nifty JSONP hack</a>&#8230;</p>
<p>Now that we&#8217;ve been granted permission to create Notifications, and finally have the Twitter data, let&#8217;s create a notification!</p>
<pre>function TweetSuccess(req) {
     if(req.length) {
          var type = Ext.getCmp('radiogroup').getValue().value;
          var img     = req[0].user.profile_image_url;
          var name    = req[0].user.screen_name;
          var tweet    = req[0].text;
          if(type==1) {
               var tweet    = tweet.parseURL().parseUsername().parseHashtag();
               notification.createHTMLNotification("notification_helper.cfm?title="+name+"&amp;img="+img+"&amp;content="+tweet).show();
          }
          else {
               notification.createNotification(img,name,tweet).show();
          }
      }
      else {
           Ext.Msg.alert('Uh-oh','Sorry, that\'s not a valid Twitter username. Please try again!');
           return false;
      }
}</pre>
<p>Most of this function is just getting the values from the returned data, so we&#8217;ll skip to the important stuff: <strong>createNotification()</strong> and <strong>createHTMLNotification()</strong>.</p>
<p>Why two methods?  Well, each provides a little bit different way of displaying notifications, of course! <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>createNotification() </strong>creates a standard, vanilla notification that inherits whatever styles the browser has defined for its notifications.  This method takes three arguments:</p>
<ol>
<li>iconUrl &#8211; This is the path (absolute) of the icon that you would like displayed in the notification</li>
<li>title &#8211; Um, the title of the notification <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>body -  The main content to be displayed in the notification.</li>
</ol>
<p>While this works pretty nicely, I wasn&#8217;t thrilled with the look of the notification.  And although I didn&#8217;t pursue it very far, I couldn&#8217;t get links or any other styling to show up in the notification.</p>
<p><strong>createHTMLNotifications()</strong> picks up where createNotification() falls short in the customization department.  Whereas you pass icons, titles, and body content to createNotification(), you simply pass a url to a page that defines your notification content for createHTMLNotifications().  While this creates a bit more work for arranging icons, titles, and body content, it does allow you to be a bit more creative in how the notifications look.  Plus, since it&#8217;s an HTML notification, you can use some nifty CSS3, and who doesn&#8217;t love that!</p>
<h2>Wrapping Up</h2>
<p>There&#8217;s a bunch more to Notifications that I didn&#8217;t cover (like closing them programmatically, etc.), but hopefully this is a nice introduction to the concepts behind what will hopefully be embraced by all browsers in the very near future.  I see a lot of promise to these, and can&#8217;t wait until all the environments are more unified to start utilizing them to their full potential.</p>
<p>As always, be sure to <a href="http://singularityconcepts.com/code_samples/notification/notification.cfm">check out the demo</a> (remember, Chrome only <img src='http://existdissolve.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) and let me know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://existdissolve.com/2010/07/html5ish-notifications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

