<?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/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>Software As She's Developed &#187; JQuery</title>
	<atom:link href="http://softwareas.com/tag/jquery/feed" rel="self" type="application/rss+xml" />
	<link>http://softwareas.com</link>
	<description>Mahemoff's Podcast/Blog - Web, Programming, Usability from the Author of 'Ajax Design Patterns' (AjaxPatterns.org)</description>
	<lastBuildDate>Mon, 26 Jul 2010 16:52:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- podcast_generator="podPress/8.8" - maintenance_release="8.8.4" -->
		<copyright>Copyright &amp;#xA9; Software As She's Developed 2010 </copyright>
		<managingEditor>michael@mahemoff.com (Software As She's Developed)</managingEditor>
		<webMaster>michael@mahemoff.com (Software As She's Developed)</webMaster>
		<category>posts</category>
		<ttl>1440</ttl>
		<itunes:keywords></itunes:keywords>
		<itunes:subtitle></itunes:subtitle>
		<itunes:summary>Mahemoff's Podcast/Blog - Web, Programming, Usability from the Author of 'Ajax Design Patterns' (AjaxPatterns.org)</itunes:summary>
		<itunes:author>Software As She's Developed</itunes:author>
		<itunes:category text="Society &amp; Culture"/>
		<itunes:owner>
			<itunes:name>Software As She's Developed</itunes:name>
			<itunes:email>michael@mahemoff.com</itunes:email>
		</itunes:owner>
		<itunes:block>No</itunes:block>
		<itunes:explicit>no</itunes:explicit>
		<itunes:image href="http://softwareas.com/wp-content/plugins/podpress/images/powered_by_podpress_large.jpg" />
		<image>
			<url>http://softwareas.com/wp-content/plugins/podpress/images/powered_by_podpress.jpg</url>
			<title>Software As She's Developed</title>
			<link>http://softwareas.com</link>
			<width>144</width>
			<height>144</height>
		</image>
		<item>
		<title>Automagic Event Registration</title>
		<link>http://softwareas.com/automagic-event-registration</link>
		<comments>http://softwareas.com/automagic-event-registration#comments</comments>
		<pubDate>Mon, 22 Mar 2010 10:43:33 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax Patterns]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=829</guid>
		<description><![CDATA[Further to last night's post on custom events, I've set things up now to use "magic event registration". It's a little like the auto-wiring facility of a dependency injection container. It's quite simple really - the app's initialisation sequence does this:


Register all components that might listen to something.
Register all events they might listen to.
For each [...]]]></description>
			<content:encoded><![CDATA[<p>Further to <a href="http://mini.softwareas.com/playing-with-jquery-custom-events-good-tip-fr">last night's post on custom events</a>, I've set things up now to use "magic event registration". It's a little like the <a href="http://static.springsource.org/spring/docs/2.5.6/reference/beans.html#beans-factory-autowire">auto-wiring facility of a dependency injection container</a>. It's quite simple really - the app's initialisation sequence does this:</p>

<ul>
<li>Register all components that might listen to something.</li>
<li>Register all events they might listen to.</li>
<li>For each listener method among the components, automatically bind the event to it.</li>
</ul>

<p>In code:</p>

<div class="igBar"><span id="ljavascript-5"><a href="#" onclick="javascript:showPlainTxt('javascript-5'); return false;">PLAIN TEXT</a></span></div>

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-5">
<div class="javascript"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> components = <span style="color: #66cc66;">&#91;</span>siteFrame, singleTrial, trialController, statsZone, tableView, analysis, rawView, graphView<span style="color: #66cc66;">&#93;</span>;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #003366; font-weight: bold;">var</span> eventTypes = <span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">"trialCreate"</span>, <span style="color: #3366CC;">"trialUpdate"</span>, <span style="color: #3366CC;">"trialSuspend"</span>, <span style="color: #3366CC;">"trialRun"</span>, <span style="color: #3366CC;">"trialComplete"</span><span style="color: #66cc66;">&#93;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; $.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span>components, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>i,component<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; $.<span style="color: #006600;">each</span><span style="color: #66cc66;">&#40;</span>eventTypes, <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>i,eventType<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> handler = component<span style="color: #66cc66;">&#91;</span>eventType<span style="color: #66cc66;">&#93;</span>;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>handler<span style="color: #66cc66;">&#41;</span> $<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">bind</span><span style="color: #66cc66;">&#40;</span>eventType, handler<span style="color: #66cc66;">&#41;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span> </div></li></ol></div>
</div></div>

<p><br /></p>

<p>A component looks like:</p>

<div class="igBar"><span id="ljavascript-6"><a href="#" onclick="javascript:showPlainTxt('javascript-6'); return false;">PLAIN TEXT</a></span></div>

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-6">
<div class="javascript"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">statsZone = <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; trialCreate: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e, trial<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; ...</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span>,</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; trialUpdate: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e, trial<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; ...</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div></li></ol></div>
</div></div>

<p><br /></p>

<p>And elsewhere in the code, the events it listens to get triggered through the normal jQuery custom events mechanism:</p>

<div class="igBar"><span id="ljavascript-7"><a href="#" onclick="javascript:showPlainTxt('javascript-7'); return false;">PLAIN TEXT</a></span></div>

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-7">
<div class="javascript"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">trigger</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"trialUpdate"</span>, trial<span style="color: #66cc66;">&#41;</span>; </div></li></ol></div>
</div></div>

<p><br /></p>

<p>Part of this is based on what I said last night, which is (a) I'm keeping things simple - hence everything happens at startup and all the instances are singleton classes; (b) consequently, events are global, rather than being attached to any particular component.</p>

<p>Stepping back, what were the alternatives to this design:</p>

<ul>
<li><p>Components register themselves as listeners - this would be the purist OO answer, i.e. keeping objects autonomous. A perfectly cromulent solution, but a little more redundancy than it needs to be. If objects really do have consistently named listener methods, it's just as easy to handle registration automagically.</p></li>
<li><p>The initialisation routine manually wires up components to events. It has a certain Python-like "explicit" feel to it, but again is quite pointless if we can instead do it automagically.</p></li>
</ul>

<p>So where does the automagic model fall down? If we are doing things dynamically, it would get more complicated and would, for example, require objects to register upon their creation. So I think that's still okay. Another problem could be if a single method was listening to more than one event type, since this technique assumes it's one-to-one from event type to methods. But that's okay too - I actually had this problem and it was simply solved by getting both handlers to delegate to a third, common, handler:</p>

<div class="igBar"><span id="ljavascript-8"><a href="#" onclick="javascript:showPlainTxt('javascript-8'); return false;">PLAIN TEXT</a></span></div>

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-8">
<div class="javascript"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> trialController = <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; trialCompleteOrCreate: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; ...</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">trialController.<span style="color: #006600;">trialCreate</span> = trialController.<span style="color: #006600;">trialComplete</span> = trialController.<span style="color: #006600;">trialCompleteOrCreate</span>; </div></li></ol></div>
</div></div>

<p><br /></p>

<p>I realised while working on TiddlySpace there's a lot to be said for dependency injection style patterns in Javascript, and it's not happening yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/automagic-event-registration/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Whoa! jQuery&#8217;s Adding User Comments to their Docs</title>
		<link>http://softwareas.com/whoa-jquerys-adding-user-comments-to-their-docs</link>
		<comments>http://softwareas.com/whoa-jquerys-adding-user-comments-to-their-docs#comments</comments>
		<pubDate>Fri, 13 Nov 2009 23:12:56 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://softwareas.com/whoa-jquerys-adding-user-comments-to-their-docs</guid>
		<description><![CDATA[I just heard on the new jQuery podcast that jQuery docs will be getting comments.  jQuery just got a whole - even more - useful. This is direct from the horse's mouth, an interview with jQuery head honcho John Resig.

I've felt for a long time jQuery has been ahead of the pack with its [...]]]></description>
			<content:encoded><![CDATA[<p>I just heard on <a href="http://blog.jquery.com/2009/11/13/announcing-the-official-jquery-podcast/">the new jQuery podcast</a> that jQuery docs will be getting comments.  jQuery just got a whole - even more - useful. This is direct from the horse's mouth, an interview with jQuery head honcho John Resig.</p>

<p>I've felt for <a href="http://ajaxian.com/archives/docs-for-dojo-prototype-others">a long time</a> jQuery has been ahead of the pack with its documentation, and since then both jQuery and its docs have gone from strength to strength.</p>

<p>One thing I was still missing though is user comments.</p>

<blockquote>PHP leads the way here, with the official API docs allowing user comments at the bottom (<a href="http://www.php.net/manual/en/language.variables.scope.php">example</a>).  No-one can anticipate all the issues that will arise, so why not open up docs to the developer community? Allowing user comments is also an easy way to help keep the docs up to date (if something of a compromise.)  It could also be done as a wiki, if the wiki is managed well. (<a href="http://wiki.rubyonrails.org/">The Rails wiki</a> is a good example of a well-maintained wiki that receives frequent contributions from people in the know.)</blockquote>

<p>I was missing it until I heard that announcement. Again, jQuery's leading the way.</p>

<p>I realise there are spam complications, but user comments are a no-brainer for making documentation useful. I continue to derive huge benefit from user comments. (To wit: The user comments about random number seeding were of vital importance in the making of <a href="http://ie6isolderthanyourgrandpa.com">the site I realised earlier today</a>. I use them pretty much every time I have a PHP problem.)</p>

<p>I've even thought of making such a project myself, so much did I miss doc based comments.</p>

<p>The docs are being migrated from MediaWiki to WordPress. FWIW I think the OWF could benefit from a similar architecture if <a href="http://wiki.openwebfoundation.org/Main_Page">the wiki is going to engage with the community</a>. As I've learned from <a href="http://ajaxpatterns.org">AjaxPatterns</a> and maintaining <a href="http://tiddlywiki.mahemoff.com/CommentsPlugin.html">the tiddlywiki comments plugin</a>, most people would rather append comments than updating a wiki. Updating a wiki is intimidating for some, and in any event, requires much more thought in order to make it coherent. Comments tend to be easier to moderate too because of their atomic nature.</p>

<p>Anyway, great news for jQuery and the community!</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/whoa-jquerys-adding-user-comments-to-their-docs/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>State of jQuery 2009</title>
		<link>http://softwareas.com/state-of-jquery-2009</link>
		<comments>http://softwareas.com/state-of-jquery-2009#comments</comments>
		<pubDate>Fri, 18 Sep 2009 08:08:21 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://softwareas.com/state-of-jquery-2009</guid>
		<description><![CDATA[Fred noticed Jon Resig's State of jQuery slides are up:

State of jQuery &#39;09View more documents from jeresig.

Highlights for me:

Now:


Now using sizzle, the quick, generic (not just JQuery), selector engine. Slide 8 show
s almost 2* performance improvement on IE6 from JQuery 1.2.6 -> 1.3.2.
Performance improvements are apparently dramatic (browser averages):


width() / height() ~4* speedup (good - [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/FND">Fred</a> noticed Jon Resig's State of jQuery slides are up:</p>

<div style="width:425px;text-align:left" id="__ss_2006198"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/jeresig/state-of-jquery-09" title="State of jQuery &#39;09">State of jQuery &#39;09</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=state-of-jquery-09-090916091836-phpapp02&#038;stripped_title=state-of-jquery-09" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=state-of-jquery-09-090916091836-phpapp02&#038;stripped_title=state-of-jquery-09" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">documents</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/jeresig">jeresig</a>.</div></div>

<p>Highlights for me:</p>

<p>Now:</p>

<ul>
<li>Now using sizzle, the quick, generic (not just JQuery), selector engine. Slide 8 show
s almost 2* performance improvement on IE6 from JQuery 1.2.6 -> 1.3.2.</li>
<li>Performance improvements are apparently dramatic (browser averages):

<ul>
<li>width() / height() ~4* speedup (good - I need these for http://caption.im8ge.com)</li>
<li>hide() / show() ~3* speedup (good - I use them everywhere!)</li>
<li>element insert: : ~6* speedup (likewise)</li>
</ul></li>
<li><p><a href="http://testswarm.com">Test Swarm</a> is go! Awesome, Awesome initiative. I hope we take advantage of it for TiddlyWiki testing, once it extends to other frameworks. (Or make something similar.)</p></li>
<li><p>Ridiculous growth and market share (p15-17), and new big sites using JQuery (p13): Whitehouse, Wikipedia, Amazon, Microsoft. Not too shabby eh. Stuff like this makes it much easier for advocates to sell in their organisations.</p></li>
<li>Setting up private CDN on Media Temple, who's donating all the resources.</li>
</ul>

<p>Future:</p>

<ul>
<li><strong>More performance improvements in 1.3.3</strong> - p23 shows 3.5x improment over 1.3.2! (perhaps for a subset, but it's still a big and useful set).</li>
<li>JQuery builds <strong>optimised for mobile</strong>.</li>
<li>Moving <strong>parts of JQuery UI widget -> core</strong>.</li>
<li>Four conferences in 2009 - online, <strong>London</strong>, SF, Boston.</li>
<li>Better community sites, inlcuding online forum. Plugin site rewrite. </li>
<li><strong>All plugins on CDN.</strong>.</li>
<li>Core -> Github.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/state-of-jquery-2009/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JQuery IFrame Plugin</title>
		<link>http://softwareas.com/jquery-iframe-plugin</link>
		<comments>http://softwareas.com/jquery-iframe-plugin#comments</comments>
		<pubDate>Tue, 15 Sep 2009 23:10:52 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Scrumptious]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://softwareas.com/jquery-iframe-plugin</guid>
		<description><![CDATA[This article by Nick Zakas, covering some technical issues in iframe loading, triggered me to  surface a JQuery IFrame plugin I made a little while ago, which supports loading IFrames. (I did tweet it at the time, though I've since changed the location.)

JQuery IFrame plugin



The plugin basically tells you, the programmer of the parent [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/">This article by Nick Zakas</a>, covering some technical issues in iframe loading, triggered me to  surface a JQuery IFrame plugin I made a little while ago, which supports loading IFrames. (I did <a href="http://twitter.com/mahemoff/statuses/3177377341">tweet it</a> at the time, though I've since changed the location.)</p>

<p><a href="http://project.mahemoff.com/jquery-iframe/">JQuery IFrame plugin</a></p>

<p><a href="http://project.mahemoff.com/jquery-iframe/"><img style="width:400px;" src="http://img.skitch.com/20090915-k34qa5qjcxfht4axtrfdkcdni6.jpg"/></a></p>

<p>The plugin basically tells you, the programmer of the parent document, when your child iframe has loaded. It also has some other bells and whistles, like timing the load duration.</p>

<p>It's inspired by the use cases of WebWait (http://webwait.com) and the Scrumptious trails player (http://scrumptious.tv). Both are applications whose whole mission in life is to open up an external page in an iframe, and do something when it has loaded.</p>

<p>There's already an <a href="http://ideamill.synaptrixgroup.com/?p=6">IFrame JQuery plugin</a>, but it's to do with controlling what's inside the iframe, i.e. the situation which is only possible when the iframes are from the same domain. What I'm dealing with here is the parent knowing when the iframe is loaded, regardless of when it comes from and agnostic to what it does.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/jquery-iframe-plugin/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Modal Dialog JQuery Plugin</title>
		<link>http://softwareas.com/modal-dialog-jquery-plugin</link>
		<comments>http://softwareas.com/modal-dialog-jquery-plugin#comments</comments>
		<pubDate>Thu, 27 Aug 2009 16:03:46 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Lightbox]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Project]]></category>

		<guid isPermaLink="false">http://softwareas.com/modal-dialog-jquery-plugin</guid>
		<description><![CDATA[

This has been a while coming, but I made a little "yet another modal dialog lightbox JQuery plugin" thing this week.

Demo and Download for Modal Dialog - JQuery Plugin

It was driven by TiddlyDocs, but I've been wanting one anyway for a while. Mostly because lightbox libraries generally do some hocus-pocus on page load, like applying [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/mahemoff/status/1640629729"><img style="width:400px;" src="http://img.skitch.com/20090827-fd8efw4bp1bp8b85y84t93d9tf.jpg" /></a></p>

<p>This has been a while coming, but I made a little "yet another modal dialog lightbox JQuery plugin" thing this week.</p>

<p><a href="http://project.mahemoff.com/modal/">Demo and Download for Modal Dialog - JQuery Plugin</a></p>

<p>It was driven by <a href="http://tiddlydocs.com">TiddlyDocs</a>, but I've been wanting one anyway for a while. Mostly because lightbox libraries generally do some hocus-pocus on page load, like applying to everything marked rel="lightbox", but don't let you dynamically produce the lightbox yourself. That's fine for pages that are just a static image gallery, but not useful to someone building a dynamic web app.</p>

<p>I've subsequently used <a href="nyromodal.nyrodev.com/">nyromodal</a>, <a href="http://twitter.com/mahemoff/statuses/1647793685">on good advice</a>, but wanted something smalller and with a simple API for my main use case, which is just showing some text.</p>

<p>The plugin also simplifies work by not requiring you to install a separate CSS file. Doing that, and linking to it, as well as installing any images, is something that always slows me down when I want to start using a graphical client. In keeping with the "happy path" You-Aint-Gonna-Need-It (YAGNI) mantra, I'd rather keep a library to a single Javascript file - be evil and do styling in the library by default, but still support users who want to put custom CSS in a stylesheet.</p>

<p><img style="width:400px;" src="http://img.skitch.com/20090827-qqk7a963e6f3j758fntauu7nh2.jpg" /></p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/modal-dialog-jquery-plugin/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Towards A Single Page Application Framework</title>
		<link>http://softwareas.com/towards-a-single-page-application-framework</link>
		<comments>http://softwareas.com/towards-a-single-page-application-framework#comments</comments>
		<pubDate>Tue, 18 Aug 2009 02:02:57 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[SPA]]></category>
		<category><![CDATA[TiddlyWiki]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=590</guid>
		<description><![CDATA[Tonight, I was thinking of making a Twitter app to manage my various accounts (I have ~dormant accounts related to projects like @webwait and @listoftweets). The app would be holding username and password details for each of these accounts, so it made sense to build it as a Single Page Application (SPA). This way, a [...]]]></description>
			<content:encoded><![CDATA[<p>Tonight, I was thinking of making a Twitter app to manage my various accounts (I have ~dormant accounts related to projects like @webwait and @listoftweets). The app would be holding username and password details for each of these accounts, so it made sense to build it as a <a href="http://en.wikipedia.org/wiki/Single_page_application">Single Page Application</a> (SPA). This way, a more paranoid user could always keep the app in their local file system, while a less paranoid user could always stick the file on a protected server somewhere, having configured all the username-password details.</p>

<p>TiddlyWiki is a framework for developing SPAs. One might say it's <em>the</em> framework for developing SPAs, since there are no prominent alternatives. So my obvious choice was a TiddlyWiki. However, not too long ago, the TiddlyWiki core guys extracted out the secret sauce for SPAs: the ingenius bit of code that saves files without requiring any browser extensions. (I've tried to explain this to people and it always leaves even the most brilliant minds a little dumbstruck, but yes TiddlyWiki demonstrates there are pragmatic hacks that can be used to read a file into the browser and then write it out again.) I was keen to explore this saving mechanism, so experimentation ensued.</p>

<p>The file management techniques ship conveniently in a JQuery plugin, <strong>jQuery.twFile</strong>. There is a <a href="http://jquery.tiddlywiki.org/twFile.html">basic demo which lets you edit the entire text and save it</a>. The demo confused me at first - because it was editing the entire body of the file, I wasn't sure how to translate that info into what I, as an application developer needed. The demo is useful for framework developers understanding the plugin, but less so for application developers. So I extracted it into a demo that is still minimalistic, but closer to the kind of thing you'd do in an application.</p>

<p><a href="http://project.mahemoff.com/spa-demo.html">The SPA demo is here.</a></p>

<p><a href="http://project.mahemoff.com/spa-demo.html"><img style="width: 400px; border: 1px solid #999;"  src="http://img.skitch.com/20090818-xy1n926xgpfdbaua3x4typ4qfb.jpg" /></a></p>

<p>Once I did that, I realised what's required is a SPA framework. In practice, most developers using twFile will be keeping all the HTML, CSS, and Javascript in a single file, so it's possible to build a higher-level abstraction on twFile, so that developers can focus only on the content. I built the demo in a way that distinguished what was boilerplate framework code and what was application-specific HTML, CSS, and Javascript.</p>

<p>It was all still in one file, and that's fine for many developers - you can give the developer the file, tell them "edit these bits", and they can come up with something functional. I decided to extract things further though, and <a href="http://mini.softwareas.com/jinja-python-templating-lib-has-a-very-nice-w">found the Jinja templating framework to be useful here</a>. Jinja has a concept of template inheritance, so you can easily build up an "include" system.  The net effect is I was able to encapsulate SPA logic in a single file, which was passed through a Jinja processor to produce the executable HTML document.</p>

<p>The basic SPA logic is shown below:</p>

<div class="igBar"><span id="lhtml-11"><a href="#" onclick="javascript:showPlainTxt('html-11'); return false;">PLAIN TEXT</a></span></div>

<div class="syntax_hilite"><span class="langName">HTML:</span><br /><div id="html-11">
<div class="html"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% extends &quot;spa-template.html&quot; %}</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% block title %}JQuery SPA demo{% endblock %}</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% block css %}</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; etc etc</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; body { background: black; padding: 0; margin: 0; font-family: Gill Sans, sans-serif; }</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; h1 { background: white; color: black; padding: 10px 10px 0; margin: 0; height: 52px; }</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% endblock %}</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% block html %}</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/h1.html"><span style="color: #000000; font-weight: bold;">&lt;h1&gt;</span></a></span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/img.html"><span style="color: #000000; font-weight: bold;">&lt;img</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"logo"</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">"data:image/jpeg,%FFetc etc"</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/span.html"><span style="color: #000000; font-weight: bold;">&lt;span</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"title"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>JQuery-SPA Demo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/span&gt;</span></span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h1&gt;</span></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"main"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/ol.html"><span style="color: #000000; font-weight: bold;">&lt;ol&gt;</span></a></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/li.html"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></a></span>Save this file to your local file system and open your local copy in the browser (using a file:/// URI). The browser might ask for special permission for this document, and you will need to grant it.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/li.html"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></a></span>Type your message: <span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"message"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"change me"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/input&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/li.html"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></a></span>Save this page: <span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"saveButton"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"Save"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"button"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/li.html"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></a></span>Hit shift-reload to perform a clean reload the page and observe that your message has been saved.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ol&gt;</span></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/h3.html"><span style="color: #000000; font-weight: bold;">&lt;h3&gt;</span></a></span>What is this?<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h3&gt;</span></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/p.html"><span style="color: #000000; font-weight: bold;">&lt;p&gt;</span></a></span>This is a demo of an experimental Single Page Application I am building atop <span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"http://jquery.tiddlywiki.org/twFile.html"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>jQuery.twFile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span>, the file saving plugin extracted from TiddlyWiki. Forked from <span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"http://jquery.tiddlywiki.org/twFileDemo.html"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>this twFile Demo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span>. Only tested on Firefox for now.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p&gt;</span></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% endblock %}</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% block javascript %}</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; $.spa.save = function(text) {</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; return text.replace(/<span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"message"</span>.*?<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>\/input&gt;</span>/,</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '<span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"message"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"'+$("</span>#message<span style="color: #ff0000;">").val()+'"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/input&gt;</span></span>');</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; }</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">{% endblock %} </div></li></ol></div>
</div></div>

<p><br /></p>

<p>So it contains separate HTML/CSS/Javascript blocks. Probably not a good engineering practice (though it doesn't impact on the end-user experience, which is always a single file), but it's convenient for now. The key SPA logic is here:</p>

<div class="igBar"><span id="lhtml-12"><a href="#" onclick="javascript:showPlainTxt('html-12'); return false;">PLAIN TEXT</a></span></div>

<div class="syntax_hilite"><span class="langName">HTML:</span><br /><div id="html-12">
<div class="html"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/li.html"><span style="color: #000000; font-weight: bold;">&lt;li&gt;</span></a></span>Type your message: <span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"message"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"change me"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/input&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li&gt;</span></span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; ....</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; $.spa.save = function(text) {</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; return text.replace(/<span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"message"</span>.*?<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>\/input&gt;</span>/,</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '<span style="color: #009900;"><a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">&lt;input</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">"message"</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">"'+$("</span>#message<span style="color: #ff0000;">").val()+'"</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/input&gt;</span></span>');</div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; } </div></li></ol></div>
</div></div>

<p><br /></p>

<p>As an app developer, all you have to do is override $.spa.save (which in retrospect should be renamed as it doesn't actually perform the save). This function receives the text of the file as it was stored on disk when the page loaded. It must then return the text that should be saved to disk. Thus, it must store application state in HTML, probably by performing some kind of substitution.</p>

<p>Having put this together, I'm keen to proceed with the envisioned Twitter app. It's not yet clear if there's any mileage here over a regular TiddlyWiki, but as someone who is more familiar with starting apps from a blank HTML page (or a simple <a href="http://projectdeploy.com">Project Deploy*</a> template), it might end up being a more familiar way to kick an app off. Watch this space.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/towards-a-single-page-application-framework/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ColourLovers API &#8211; JSON Demos</title>
		<link>http://softwareas.com/colourlovers-api-json-demos</link>
		<comments>http://softwareas.com/colourlovers-api-json-demos#comments</comments>
		<pubDate>Sun, 02 Aug 2009 23:26:22 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[ColourLovers]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Project]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=563</guid>
		<description><![CDATA[About a year ago, I was excited to discover ColourLovers had an API. There is some great data about colours and palettes on that site, and some great possibilities for mashups - some as general-purpose art projects, and some as tools for designers.

However, I noticed there was no JSON-P interface, so there was no way [...]]]></description>
			<content:encoded><![CDATA[<p>About a year ago, I was excited to discover <a href="http://colourlovers.com">ColourLovers</a> had an API. There is some great data about colours and palettes on that site, and some great possibilities for mashups - some as general-purpose art projects, and some as tools for designers.</p>

<p>However, I noticed there was no <a href="http://ajaxian.com/archives/jsonp-json-with-padding">JSON-P</a> interface, so there was no way to write a pure browser-based mashup. I got in touch with them, and heard back from <a href="http://twitter.com/pureform">Chris Williams</a>, who to my pleasant surprise was willing to introduce JSON-P. And so we had some email discussion about the various options for the API interface (e.g. do you call it "jsonp" versus "callback"; do you use "real JSONP" versus just a callback function; do you hardcode the name of the callback function versus let the caller specify it as a parameter), and ultimately Chris went ahead and implemented it a short time later and published the API on January 26, 2009. Fantastic!</p>

<p>I offered to make some demos illustrating code usage, and did around that time, but never got around to publishing them until now. I've released the demos <a href="http://colourlovers.rainbowgelati.com">here</a>. There's a couple of JQuery demos, and one raw Javascript demo. I had fun making them and have plans to do a lot more with this API.</p>

<p><a href="http://colourlovers.rainbowgelati.com"><img src="http://img.skitch.com/20090802-p8jnmrj6u58421ebbbxrm9eige.jpg" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/colourlovers-api-json-demos/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>TiddlyWeb-JQuery Comments Plugin</title>
		<link>http://softwareas.com/tiddlyweb-jquery-comments-plugin</link>
		<comments>http://softwareas.com/tiddlyweb-jquery-comments-plugin#comments</comments>
		<pubDate>Tue, 21 Jul 2009 15:39:59 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Osmosoft]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[tiddlyweb]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=558</guid>
		<description><![CDATA[

TiddlyWeb-JQuery Comments Plugin - Screencast @ Vimeo

I've extracted from Scrumptious a nested comments plugin you can integrate into any POJA (plain ol' Javascript app). You can find it here in the repo: TiddlyWeb-JQuery Comments Plugin.

As the README explains, usage is a one-liner once you've set it up. Just do $(selector).comments("topic"). The topic is an identifier [...]]]></description>
			<content:encoded><![CDATA[<p><object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=5694409&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=5694409&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object></p>

<p><a href="http://vimeo.com/5694409">TiddlyWeb-JQuery Comments Plugin - Screencast @ Vimeo</a></p>

<p>I've extracted from <a href="http://scrumptious.tv">Scrumptious</a> a nested comments plugin you can integrate into any POJA (plain ol' Javascript app). You can find it here in the repo: <a href="http://trac.tiddlywiki.org/browser/Trunk/contributors/MichaelMahemoff/lib/comments">TiddlyWeb-JQuery Comments Plugin</a>.</p>

<p>As the <a href="http://trac.tiddlywiki.org/browser/Trunk/contributors/MichaelMahemoff/lib/comments/README">README</a> explains, usage is a one-liner once you've set it up. Just do $(selector).comments("topic"). The topic is an identifier for the set of comments; so that when the UI loads, it pulls down all comments with that ID in its "topic" field. Internally, topic acts as the root of the comments tree...but you don't really need to know that.</p>

<p>This plugin is a JQuery equivalent of <a href="http://tiddlywiki.mahemoff.com/CommentsPlugin.html">the TiddlyWiki comments plugin</a>, minus some of the more exotic options, and the ability to delete. Eventually, I hope to introduce those things, but only as the need arises - so if you're using this, please let me know how I can improve it.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/tiddlyweb-jquery-comments-plugin/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Google jQuery CDN</title>
		<link>http://softwareas.com/google-jquery-cdn</link>
		<comments>http://softwareas.com/google-jquery-cdn#comments</comments>
		<pubDate>Thu, 22 Jan 2009 14:12:01 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=507</guid>
		<description><![CDATA[SUMMARY: Get the latest jQuery here:

http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js

For example, cut-and-paste one of the following:


curl -O http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
wget http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js




With the release of JQuery 1.3, I thought I'd mention the Google JQuery CDN, one of several libraries you can yoink from Google's Ajax Libraries API. Instead of hosting your own JQuery, you just point your web app to Google's JQuery:

&#60;script [...]]]></description>
			<content:encoded><![CDATA[<p>SUMMARY: Get the latest jQuery here:</p>

<p><a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js</a></p>

<p>For example, cut-and-paste one of the following:</p>

<ul>
<li>curl -O http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js</li>
<li>wget http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js</li>
</ul>

<hr />

<p>With the release of JQuery 1.3, I thought I'd mention the Google JQuery CDN, one of several libraries you can yoink from Google's <a href="http://code.google.com/apis/ajaxlibs/">Ajax Libraries API</a>. Instead of hosting your own JQuery, you just point your web app to Google's JQuery:</p>

<p>&lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
(Modified version from 1.3. I'll try and keep this post linking to the latest version.)</p>

<p>Google's documentation would lead you to believe you need to import Google's library, and then call <tt>google.load()</tt>, but it's unnecessary; just pull in the script directly using the link above. The link is officially documented, so it's going to stay put for a very, very, long time.</p>

<p>There are also other libraries available on Google's CDN and <a href="http://dev.aol.com/dojo">elsewhere</a>.</p>

<p>The main point of the CDN is caching. If a user hits 100 JQuery sites, the library will only be downloaded once, and the remaining 99 sites will pull it from the local cache. From an operation cost, you also get to offload the cost of server Javascript to Google. As an added bonus, I also find it easier as a developer to kick off a new project by just linking to the CDN - no need to download and copy the latest version of JQuery.</p>

<p>Great. So when not to use a CDN?</p>

<p>Obviously, whenever you're working offline. This sometimes occurs as a developer working locally, and with <a href="http://code.google.com/p/trimpath/wiki/SinglePageApplications">Single Page Applications</a> like <a href="http://tiddlywiki.com">TiddlyWiki</a>. (The next "major minor" release of TiddlyWiki, v2.5 is JQuery-powered.)</p>

<p>Another case would be when you can deliver faster than the CDN, and care about that. This might be the case when all users are close to the server. Even then, though, you won't get the local cache benefit from users who already have the JQuery.</p>

<p>Finally, privacy and security concerns. Using the CDN, you are trusting the CDN to faithfully serve JQuery and relying on no third-parties injecting funniness in between the CDN and your user's browser. If anything went wrong here, your user could be subject to a world of XSS and CSRF attacks. Or, in a more mundane scenario, the CDN might simply go down, thus breaking your web app. Furthermore, you're giving the CDN data about your users this way. Although Google doesn't use cookies, others might; and even if they don't, the IP number is going to be sent back to them. The referrer - being your website - will also be sent to them, so they can, if they want, track your website's usage.</p>

<p>For many websites, though, it's great that we can use a reliable CDN like Google's to fetch JQuery fast.</p>

<p>Update (11-Feb-2009): In a show of recursive linking, I should fess up as to <a href="http://twitter.com/mahemoff/status/1199810558">why I originally sat down to wrote this</a> ...
<a href="http://twitter.com/mahemoff/status/1199810558"><img style="width:400px;" src="http://img.skitch.com/20090211-bhd9kuhk1tdanbmf24bbhihh1x.jpg" alt="twitter message" />.</a></p>

<p>Update (erm, mid-2009 sometime): Montana left a comment pointing out you can also drop off the minor numbers to get the latest version. So, for the latest JQuery (since 2.0 doesn't exist), use http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js. Or, for the latest in the old 1.2 series: http://ajax.googleapis.com/ajax/libs/jquery/1.2/jquery.min.js.</p>

<p>Update (19-March-2010): Scratch that. @premasagar pointed out to me that the link to just the latest version  (until 2.0, i.e. http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js) as opposed to a specific version (http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js) is undesirable; <a href="http://nichol.as/how-google-is-wasting-your-bandwidth">Google will expire the "latest" content after one hour</a>, as opposed to one year for a specific version. This is for good reason of course, as the latest version is subject to change. For this reason, I've reverted the link at top to be a specific version, which I'll endeavour to update upon each new release.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/google-jquery-cdn/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
