<?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; IFrame</title>
	<atom:link href="http://softwareas.com/tag/iframe/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>Unintended Consequences and the Inevitable &#8220;Why Would Anyone Want To Do This?&#8221;</title>
		<link>http://softwareas.com/unintended-consequences-and-the-inevitable-why-would-anyone-want-to-do-this</link>
		<comments>http://softwareas.com/unintended-consequences-and-the-inevitable-why-would-anyone-want-to-do-this#comments</comments>
		<pubDate>Tue, 16 Feb 2010 20:53:03 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Unintended Consequences]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=786</guid>
		<description><![CDATA[I&#8217;m listening to this excellent BBC podcast on Unintended Consequences of Mathematics.


In his book The Mathematician&#8217;s Apology (1941), the Cambridge mathematician GH Hardy expressed his reverence for pure maths, and celebrated its uselessness in the real world. Yet one of the branches of pure mathematics in which Hardy excelled was number theory, and it was [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m listening to <a href="http://www.bbc.co.uk/programmes/b00qj2nq">this excellent BBC podcast on Unintended Consequences of Mathematics</a>.</p>

<blockquote>
In his book The Mathematician&#8217;s Apology (1941), the Cambridge mathematician GH Hardy expressed his reverence for pure maths, and celebrated its uselessness in the real world. Yet one of the branches of pure mathematics in which Hardy excelled was number theory, and it was this field which played a major role in the work of his younger colleague, Alan Turing, as he worked first to crack Nazi codes at Bletchley Park and then on one of the first computers.

Melvyn Bragg and guests explore the many surprising and completely unintended uses to which mathematical discoveries have been put.

These include:

The cubic equations which led, after 400 years, to the development of alternating current &#8211; and the electric chair.

The centuries-old work on games of chance which eventually contributed to the birth of population statistics.

The discovery of non-Euclidean geometry, which crucially provided an &#8216;off-the-shelf&#8217; solution which helped Albert Einstein forge his theory of relativity.

The 17th-century theorem which became the basis for credit card encryption.
</blockquote>

<p>The relevance to the topic of this blog should be clear.</p>

<p>Show me someone doing something <a href="http://ajaxian.com/archives/dojogfx-presentations-in-dojogfx">cool</a> or <a href="http://ajaxian.com/archives/javascript-jpeg-encoding">experimental</a> and I&#8217;ll show you someone who sniffs, &#8220;Why would anyone want to do this?&#8221;. The answer may be because it was fun, because they wanted to see if it was possible, or because they wanted to learn something. But whatever their primary reason, one thing&#8217;s for sure: there will be unintended consequences. The examples above show it&#8217;s happened in mathematics, and we&#8217;ve seen the same thing happen time and again in web development.</p>

<p>The rich interactivity we see today wouldn&#8217;t have been possible if people hadn&#8217;t been willing to fool around with the not-so-always-obvious features of web browsers. Take <a href="http://softwareas.com/cross-domain-communication-with-iframes">cross-domain iframe messaging</a>, for example. Not something people knew much about until a few years ago, when <a href="http://tagneto.blogspot.com/2006/06/cross-domain-frame-communication-with.html">James Burke</a> documented his experiments. A few years later, it&#8217;s a fundamental technology in OpenSocial (which means iGoogle, the Yahoo! homepage, among many other sites), <a href="http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel">Facebook&#8217;s official Javascript client</a>,  and <a href="http://stackoverflow.com/questions/tagged/cross-domain+iframe">evidently</a> has much interest from elsewhere.</p>

<p>So next time you see some wit ask &#8220;Why would anyone ever need this?&#8221;, just stay schtoom, sit back, and wait six months.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/unintended-consequences-and-the-inevitable-why-would-anyone-want-to-do-this/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Not Your Grandpa&#8217;s Framesets: Premasagar Rose shows us IFrame 2.0!</title>
		<link>http://softwareas.com/not-your-grandpas-framesets-premasagar-rose-shows-us-iframe-2-0</link>
		<comments>http://softwareas.com/not-your-grandpas-framesets-premasagar-rose-shows-us-iframe-2-0#comments</comments>
		<pubDate>Tue, 09 Feb 2010 00:09:12 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Widgets]]></category>

		<guid isPermaLink="false">http://softwareas.com/not-your-grandpas-framesets-premasagar-rose-shows-us-iframe-2-0</guid>
		<description><![CDATA[usual live blogging caveats &#8211; spelling errors, messy, etc etc

@premasagar is visiting the Osmoplex today (thanks @jayfresh for arranging it) and is taking us through his work on iframes, widgets, and sandboxing. I&#8217;ve realised we could perhaps be collaborating as my jquery-iframe plugin is so close to his. Different emphases, but much overlap.

GitHub is where [...]]]></description>
			<content:encoded><![CDATA[<p>usual live blogging caveats &#8211; spelling errors, messy, etc etc</p>

<p>@premasagar is visiting the Osmoplex today (thanks @jayfresh for arranging it) and is taking us through his work on iframes, widgets, and sandboxing. I&#8217;ve realised we could perhaps be collaborating as my jquery-iframe plugin is so close to his. Different emphases, but much overlap.</p>

<p><a href="http://github.com/premasagar">GitHub</a> is where you can see what he&#8217;s been working on. Basically, this guy is a guru on all things iFrame. In particular, all the quirks around squirting dynamic content into iFrames, as opposed to pointing them elesewhere using &#8220;src&#8221;.</p>

<p>QUOTE OF THE DAY</p>

<p>&#8220;sqwidget is my tiddly&#8221;</p>

<p>BACKGROUND &#8211; THE EMBEDDING PROBLEM</p>

<p>In patternesque speak, the basic problem is:</p>

<p>Problem: You want to embed 3rd party content into another site.</p>

<p>Forces:</p>

<ul>
<li>You want the 3rd party content to have its own style</li>
<li>BUT it will inherit style from the parent page</li>
</ul>

<p>SOLUTION 1</p>

<p>IFrame</p>

<p>Works great (in fact, I&#8217;m using it in my TiddlyWiki playground app, to be documented at some point, and is similarly used in Jon Lister&#8217;s <a href="http://iwab.tiddlyspot.com/">TiddlyTemplating</a>.</p>

<p>The problem is you sometimes want the widget to jump out of the iframe, e.g. a ligthboxed video. So &#8230;</p>

<p>SOLUTION 2</p>

<p><a href="http://code.google.com/p/cleanslatecss/">CleanSlateCSS</a></p>

<p>Basically a CSS reset, but whereas CSS resets will only handle browser defaults, cleanSlate blats everything! This is exactly the kind of thing I was looking for when <a href="http://groups.google.com/group/tiddlywikidev/browse_thread/thread/53f7c8120a3c3887">I was trying to cancel out tiddlywiki styling</a>. In that case, I was flipping the entire page back and forth, so I could just cheat by removing stylesheets and re-add them. (Prem pointed out there&#8217;s a &#8220;disabled&#8221; attribute on style tags &#8211; <a href="http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.htm">true</a>, so I should really use this instead, assuming it&#8217;s portable, which he thinks it is.)</p>

<p>Problems:
- Difficult to maintain CleanSlate library, because new CSS stuff and browser quirks keep coming up
- IE6 and IE7 don&#8217;t support &#8220;inherit&#8221;, so need CSS expression.
- When using Javascript to interact with CSS style properties, e.g. slideDown(), these will override CleanSlate. The solution is to set the &#8220;style&#8221; attribute with !important, but it becomes an arms race!
- Doesn&#8217;t solve iFrame security model</p>

<p>SOLUTION 3</p>

<p>Inject (aka squirt, inject; <a href="http://softwareas.com/injecting-html-into-an-iframe">summary</a>) content into a fresh iframe.</p>

<p>The content comes from the widget site. The sqwidget library injects it. This resolves the tension with wanting independent CSS on the same page. If the sqwidget library is running on the host page, it could even (potentially) lock down capabilities, i.e. do Caja-style sanitisation.</p>

<p>Sqwidget also does templating, using Resig&#8217;s micro-templating. (That thing&#8217;s getting to be very popular; I&#8217;m using it myself in Scrumptious via the UnderScoreJS library after @fnd gave us a talk about them.)</p>

<p>Also, prem is playing around with the idea of a div, with custom (data-*) attribute pointing to the third-party URL. You could put inside it &#8220;now loading&#8221; and then the script tag will pick those things up and load them.</p>

<hr />

<p>Various points:</p>

<ul>
<li><p>for content-squirting into the iframe, you should be setting doctype, otherwise IE will load in.</p></li>
<li><p>worth investigating use of <object> tag</object></p></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/not-your-grandpas-framesets-premasagar-rose-shows-us-iframe-2-0/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inline SVG</title>
		<link>http://softwareas.com/inline-svg</link>
		<comments>http://softwareas.com/inline-svg#comments</comments>
		<pubDate>Mon, 26 Jan 2009 19:12:43 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Data Island]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[TiddlyWiki]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=509</guid>
		<description><![CDATA[Okay, I'm currently ripsnort delighted to have found a solution to this problem of rendering SVG element dynamically. As in:


  My web apps receive some &#60;svg&#62;...&#60;svg&#62; from an Ajax call
  ???
  Super, there's a drawing on the page!!!    


What is the secret sauce in step 2?

After a merry frolic [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, I'm currently ripsnort delighted to have found a solution to this problem of rendering SVG element dynamically. As in:</p>

<ol>
  <li>My web apps receive some <tt>&lt;svg&gt;...&lt;svg&gt;</tt> from an Ajax call</li>
  <li>???</li>
  <li>Super, there's a drawing on the page!!!</li>    
</ol>

<p>What is the secret sauce in step 2?</p>

<p>After a merry frolic through the majority of the internets and a dozen prototypes, I finally found <a href="http://blog.pothoven.net/2006/05/inline-dynamic-svg-from-xml-with-ajax.html">the answer</a>. In essence, you just create an "object" element with type and data settings:</p>

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

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-2">
<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> svgObject = document.<span style="color: #006600;">createElement</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'object'</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;">svgObject.<span style="color: #006600;">setAttribute</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'type'</span>, <span style="color: #3366CC;">'image/svg+xml'</span><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;">svgObject.<span style="color: #006600;">setAttribute</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'data'</span>, <span style="color: #3366CC;">'data:image/svg+xml,'</span>+ svgCode<span style="color: #66cc66;">&#41;</span>; <span style="color: #009900; font-style: italic;">// the &quot;&lt;svg&gt;...&lt;/svg&gt;&quot; returned from Ajax call</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;">&#40;</span><span style="color: #3366CC;">"#reportSVGDiv"</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">append</span><span style="color: #66cc66;">&#40;</span>svgObject<span style="color: #66cc66;">&#41;</span>; </div></li></ol></div>
</div></div>

<p><br /></p>

<p>It works in Firefox, and the article explains how to get it working in IE too, which I don't need just yet.</p>

<p>A few other things I learned and tried:</p>

<ul>
<li>I initially, naievely, tried just adding the SVG via innerHTML. As <a href="http://jermolene.com">Jeremy</a> explained to me, this doesn't work because the browser uses a different compiler for HTML compared to pure XHTML.  (And TiddlyWiki, like most things on the web, is HTML.) Even with an &lt;object&gt; tag around it, it won't just switch over.</li>
<li>The easiest way to do this is to use a .svg suffix (or probably set mime type to svg, but this is tiddlywiki and I'm working from file:// URLs, where it's not possible to set mime type). But then you can't embed it on the page - you'd have to point to it from an embed tag or object tag.</li>
<li>You can inline the SVG if you write "pure" xhtml, and for this, you have to give the file a .xhtml suffix. <a href="http://benjamin.smedbergs.us/blog/wp-content/uploads/2008/12/svg-inline.xhtml">As in this example</a>.</li>
<li>I tried the <a href="http://softwareas.com/injecting-html-into-an-iframe">Inject HTML into an iframe technique</a>. I was hoping that with the right XML declaration and HTML type, I could convince the iframe it was hosting XHTML. But no, I could not. I'm still interested to know if there's any way I could convince a dynamically generated iframe, with dynamic content, about the type of content it contains.</li>
</ul>

<p>This is all part of some recent prototyping on an exciting TiddlyWiki project involving rich text editing, among other things. In a later blog post, I'll explain how we've used this SVG stuff to mash up an online chart drawing tool with TiddlyWiki. I'm currently packaging it into a plugin.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/inline-svg/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Injecting HTML into an IFrame</title>
		<link>http://softwareas.com/injecting-html-into-an-iframe</link>
		<comments>http://softwareas.com/injecting-html-into-an-iframe#comments</comments>
		<pubDate>Tue, 05 Aug 2008 17:41:02 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Ajax Patterns]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[TiddlyWiki]]></category>

		<guid isPermaLink="false">http://softwareas.com/?p=466</guid>
		<description><![CDATA[Walking through Tiddlywiki source (write-up to follow), I noticed some interesting code in TiddlyWiki.js, importTiddlyWiki function.

The code takes a string and injects into an IFrame. I had talked to Jon a little while ago about a similar problem and was wondering about it ever since. The technique here looks like this:

It wraps the text with [...]]]></description>
			<content:encoded><![CDATA[<p>Walking through Tiddlywiki source (write-up to follow), I noticed some interesting code in TiddlyWiki.js, <tt>importTiddlyWiki</tt> function.</p>

<p>The code takes a string and injects into an IFrame. I had talked to <a href="http://jaybyjayfresh.com/">Jon</a> a little while ago about a similar problem and was wondering about it ever since. The technique here looks like this:</p>

<p>It wraps the text with tags to make it an HTML document:</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: #003366; font-weight: bold;">var</span> content = <span style="color: #3366CC;">"&lt;html&gt;&lt;body&gt;"</span> + text + <span style="color: #3366CC;">"&lt;/body&gt;&lt;/html&gt;"</span>; </div></li></ol></div>
</div></div>

<p><br /></p>

<p>It then introduces a new iframe to the page.</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> iframe = document.<span style="color: #006600;">createElement</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"iframe"</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; &nbsp; document.<span style="color: #006600;">body</span>.<span style="color: #006600;">appendChild</span><span style="color: #66cc66;">&#40;</span>iframe<span style="color: #66cc66;">&#41;</span>; </div></li></ol></div>
</div></div>

<p><br /></p>

<p>Now comes the tricky part. You would think you could just create a new iframe element and set its innerHTML, but with iframes you must use an internal doc ument property.</p>

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

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-9">
<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> doc = iframe.<span style="color: #006600;">document</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: #000066; font-weight: bold;">if</span><span style="color: #66cc66;">&#40;</span>iframe.<span style="color: #006600;">contentDocument</span><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; &nbsp; &nbsp; doc = iframe.<span style="color: #006600;">contentDocument</span>; <span style="color: #009900; font-style: italic;">// For NS6</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: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #66cc66;">&#40;</span>iframe.<span style="color: #006600;">contentWindow</span><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; &nbsp; &nbsp; doc = iframe.<span style="color: #006600;">contentWindow</span>.<span style="color: #006600;">document</span>; <span style="color: #009900; font-style: italic;">// For IE5.5 and IE6</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; font-style: italic;">// Put the content in the iframe</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; doc.<span style="color: #000066;">open</span><span style="color: #66cc66;">&#40;</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; &nbsp; doc.<span style="color: #006600;">writeln</span><span style="color: #66cc66;">&#40;</span>content<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; doc.<span style="color: #000066;">close</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; </div></li></ol></div>
</div></div>

<p><br /></p>

<p>Now the content is in our new iframe. We can then manipulate the content using standard Javascript...but ensuring a call like getElementById is executed against the iframe document, not the global document. (i.e. don't use the usual document.getElementById()).</p>

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

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-10">
<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: #009900; font-style: italic;">// Load the content into a TiddlyWiki() object</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: #003366; font-weight: bold;">var</span> storeArea = doc.<span style="color: #006600;">getElementById</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"storeArea"</span><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;"><span style="color: #66cc66;">&#125;</span>; </div></li></ol></div>
</div></div>

<p><br /></p>

<p>With this technique, you can take an arbitrary HTML string and delegate its parsing to the browser's built-in DOM engine.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/injecting-html-into-an-iframe/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Cross-Domain Communication with IFrames</title>
		<link>http://softwareas.com/cross-domain-communication-with-iframes</link>
		<comments>http://softwareas.com/cross-domain-communication-with-iframes#comments</comments>
		<pubDate>Mon, 31 Mar 2008 08:48:29 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[AjaxPatterns]]></category>
		<category><![CDATA[Cross-Domain]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Shindig]]></category>
		<category><![CDATA[Widgets]]></category>

		<guid isPermaLink="false">http://softwareas.com/cross-domain-communication-with-iframes</guid>
		<description><![CDATA[This article explains iframe-to-iframe communication, when the iframes come from different domains. That you can do this effectively is only now becoming apparent to the community, and is now used in production by Google, Facebook, and others, and has powerful implications for the future of Ajax, mashups, and widgets/gadgets. I've been investigating the technique and [...]]]></description>
			<content:encoded><![CDATA[<p>This article explains iframe-to-iframe communication, when the iframes come from different domains. That you can do this effectively is only now becoming apparent to the community, and is now used in production by Google, Facebook, and others, and has powerful implications for the future of Ajax, mashups, and widgets/gadgets. I've been investigating the technique and working some demos, introduced in the article.</p>

<h2>Background: Cross-Domain Communication</h2>

<p>Ironic that in this world of mashups and Ajax, it's not very easy to do both of them together. Ajax applications run in the browser and such applications were never intended to talk to anything but the server from whence they came. So it's not easy to mash content from multiple sources, when everything must be squeezed through the originating web server. A few hacks have arisen over the years to deal with this, such as <a href="http://ajaxpatterns.org/On-Demand_Javascript">On-Demand Javascript</a>, and the most recent one is a hack involving iframes, which I'll explain in this article. As we'll see later, the iframe technique is arguably more secure than On-Demand Javascript, and it's also better places for communication <em>within</em> the browser, i.e. from one iframe to another.</p>

<p>Related to this article is a <a href="http://www.ajaxify.com/run/crossframe/">demo application</a> and a <a href="http://www.ajaxify.com/run/crossframe/duo">couple</a> of <a href="http://www.ajaxify.com/run/crossframe/framecomms/">variants</a>.</p>

<p>The first mention I've seen of this hack originated on <a href="http://tagneto.blogspot.com/2006/06/cross-domain-frame-communication-with.html">James Burke's Tagneto blog</a> in June, 2006, though I'm fairly certain it's been used in some quarters long before that. It's now used in production by Google in <a href="http://code.google.com/apis/maps/documentation/mapplets/">Mapplets</a>. It's also used in Shindig for widget-container communication. The technique also happens to be the best way to make safe cross-domain calls from the browser directly to a third-party server, which is why it is employed by <a href="http://wiki.developers.facebook.com/index.php/JavaScript_Client_Library">Facebook's new Javascript Client Library.</a></p>

<h2>The Demo</h2>

<p>First, let's see what we can do with this hack.</p>

<p><a href="http://www.ajaxify.com/run/crossframe/">Demo</a></p>

<p>In this demo, we have a control on the top-level document affecting something in the iframe and vice-versa. This shows you can run communication in both directions with this technique. Typical of the technique, the communication is between two browser-side components from different domains (as opposed to browser-to-server communication, although there is actually server communication involved in making this happen).</p>

<h2>The Laws of Physics: What you can do with IFrames</h2>

<p>To understand the hack, we need to understand the "laws of physics" as they apply to iframes and domain policies within the browser. Once you appreciate the constraints in place, the pattern itself becomes trivial. <a href="http://www.ajaxify.com/run/crossframe/framecomms/">This demo</a> was created to explore and illustrate these constraints, and contains some simple code examples.</p>

<p><strong>Definition I: A "window" refers either to an iframe or the top-level window (i.e. the "main" page).</strong> In our model, then, we have a tree-like hierarchy of windows.</p>

<p><strong>Law I: Any window in the hierarchy can get a handle to any other window in the hierarchy.</strong> It doesn't matter where they live within the hierarchy or which domain they come from - with the right commands, a window can always refer to any other window. Parent windows are accessed as "parent", "parent.parent", etc., or "top" for the top-level. Child windows are accessed as "window.frames[0]" or "window.frames[name]". Note in this case that the name is <em>not</em> the iframe's <tt>id</tt>, but rather the iframe's <tt>name</tt>. (This reflects the legacy nature of all this stuff, relating back to ugly late-90s frames and framesets.) Thus, to get a sibling handle, you might use "parent.frames[1]".</p>

<p><strong>Law II: Windows can only access each others' internal state if they belong to the same domain.</strong> This rather puts a kibosh on the whole cross-domain cross-iframe thing. All this would be so easy if iframe scripts could talk to each other directly, but that would cause all manner of security shenanigans. <a href="http://blog.monstuff.com/archives/000304.html">HTML 5 does define explicit communication between iframes</a>, but until wide adoption, we have to think harder ...</p>

<p><strong>Law III: Any window in the hierarchy can set (but not read) any other window's location/URL, even though (from Law II) browser security policies prevent different-domain iframes from accessing each other's internal state.</strong> <i>Note: Exact details for this law needs further investigation</i> Again, it doesn't matter which domain it comes from or its position in the hierarchy. It can always get a handle on another window and can always set the window's URL, e.g. "parent.frames[1].location.href". This establishes window URLs as the one type of information on the page which is shared across all windows, regardless of the domain they come from. <em>It seems sensible that a parent can change its child windows' URLs, BUT not vice-versa; how strange that a child window is allowed to alter its parent's (or uncle's, sibling's, etc.) URLs! The only justification I know of is the old technique of escaping the frame trap, where a website, upon loading, ensures it's not inside a frame by simply setting the top-level URL - if it's different to itself - to its own URL. This would then cause the page to reload to its own URL. However, that's a special case and hardly seems worth justifying this much leeway. So I don't really know why you can do this, but lucky for us, you can!</em></p>

<p><strong>Law IV: When you change the URL's fragment identifier (the bit on the end starting with a #, e.g. http://example.com/blah#fragmentID), the page doesn't reload.</strong> This will already be familiar to you if you're familiar with another Ajax hack, <a href="http://Unique_URLs">Unique URLs</a> to allow for bookmarkability and page history. Normally, changing a document's "href" property causes it to reload, but if you only change the fragment identifier, it doesn't. You can use this knowledge to change the URL symbolically - in a manner which allows a script to inspect it and make use of it - without causing any noticeable change to the page content.</p>

<h2>Exploiting the Laws of Physics for Cross-Domain Fun and Profit - The Cross-Domain Hack (URL Polling version)</h2>

<p>The laws above are all we need to get cross-domain communication happening. The technique is simply this, assuming Window A wants to control Window B:</p>

<ul>
<li>Window A changes Window B's fragment identifier.</li>
<li>Window B is polling the fragment identifier and notices the change, and updates itself according to the fragment identifier.</li>
</ul>

<p>Ta-da!!! That's the whole thing, in its glorious entirety. Of course, you had to know the laws of physics in order to understand why all this works. It simply relies on the fact that both Window A and Window B have one common piece of state - the URL - and the fact that we can change the URL unintrusively by manipulating only the fragment identifier. For example, in the demo, the iframe's URL changes to <tt>http://ajaxpatterns.org/crossframe/#orange</tt> and once the iframe script notices it, it updates the colour.</p>

<p>A few observations:</p>

<ul>
<li>This works in either direction. Parent to child, child to parent. As the demo illustrates.</li>
<li>It requires co-operation from both parties; it's not some magic way to bypass browser security mechanisms. Once Window A changes Window B's fragment identifier, it's up to Window B to act on the change; and it's up to Window B to be polling the fragment identifier in the first place.</li>
<li>Polling the fragment identifier happens to be exactly the same technique used in the <a href="http://Unique_URLs">Unique URLs</a> pattern.</li>
</ul>

<p>There are a couple of downsides: (a) Polling slows down the whole application; (b) Polling always involves some lag time (and there's always a trade-off a and b - the faster the response, the more cycles you application uses up); (c) The URL visibly changes (assuming you want to manipulate the top-level window). We'll now consider a second technique that addresses these (albeit in a way that introduces a different downside).</p>

<h2>The Cross-Domain Hack (Marathon version)</h2>

<p>Here's a variant which no longer involves polling or changing any URLs. I learned of it <a href="http://www.julienlecomte.net/blog/2007/11/31/">from Juliene Le Comte's blog</a>, and he's even packaged it as a library.</p>

<p>Looking back at Law II: "Windows can only access each others' internal state if they belong to the same domain". At the time, I made this sound like a bad thing, but as David Brent likes to say, "So, you know, every cloud ...". The law is bad if you state it as "cross-domain iframes can't play with each others' toys" (paraphrasing the <a href="http://c2.com/cgi/wiki?LawOfDemeter">informal version of Demeter's law</a>). But it's good if you spin it as "well, at least <em>same-domain</em> iframes <em>can</em> play with each others' toys". That's what we're going to exploit here.</p>

<p>As for the demo, the functionality is the same, but since this one involves spawning iframes, I've left them intact, and made them visible, for your viewing delight. Normally, of course, they'd be invisible, and the application would look exactly the same as the previous demo.</p>

<p><a href="http://www.ajaxify.com/run/crossframe/duo"><img src="http://img101.imageshack.us/img101/8923/crossframemarathonpj9.png" /></a></p>

<p>Here's how this technique works:</p>

<ul>
<li>Every time Window A wants to call Window B, it spawns a child iframe, "Window B2" in the same domain as Window B. The URL includes the command being issued (as a CGI parameter, fragment identifier, or any other URL pattern which will be recognised by the destination script).</li>
<li>When window B2 starts up, its Javascript inspects the URL, gets a handle on Window B, and updates Window B according to the URL (e.g. a CGI parameter).</li>
<li>Window B2 destroys itself in a puff of self-gratified logic.</li>
</ul>

<p>So in this case, we create a new, short-lived, iframe for every message being passed. Because the iframe comes from the same domain as the window we're trying to update, it's allowed to change the window's internal state. It's only useful to us on startup, because after that we can no longer communicate with it (apart from by the previous fragment identifier trick, but we could do that directly on the original window).</p>

<p>Window B2 is sometimes called a proxy because it accepts commands from Window A and passes them to Window B. I like to think of it as Pheidippides of <a href="http://en.wikipedia.org/wiki/Marathon"> fame; it passes on a message and then undergoes a noble expiration. Its whole mission in life is to deliver that one message.</a></p>

<p>This technique comes with its own downside too. Quite obviously, the downside is that you must create a new iframe for every call, which requires a trip to the server. However, with caching in place, that could be avoided, since everything that must happen will happen inside the browser. So it would simply be the processing expense of creating and deleting an iframe element. Note that the previous variant never changed the DOM structure or invoked the server.</p>

<p>Also, note that in either versions of the hack, there is the awkward matter of having to express the request in string form, since in either pattern, you are required to embed the request on the window URL.  There is <a href="http://www.alexpooley.com/2007/08/07/how-to-cross-domain-javascript/">an inspired extension of this hack</a> that also has some untapped promise in this area. It involves setting up a subdomain and updating its DNS to point to a third-party website. When combined with the old <a href="http://fettig.net/weblog/2005/11/30/xmlhttprequest-subdomain-update">document.domain hack</a>, you end up with a situation where your iframe can communicate with a cross-domain iframe, without relying on iframe. (The technique described in the article is about browser-to-server communication, but I believe this iframe-to-iframe is possible too.)</p>

<h2>A Third Hack Emerges: Window Size Monitoring</h2>

<p><a href="http://shouldersofgiants.co.uk/Blog/post/2009/08/17/Another-Cross-Domain-iFrame-Communication-Technique.aspx">A  newer third hack by Piers Lawson</a>  is based around the porous nature of window sizes and the use of window.resize(). Fragment IDs are used like in the first technique here, but instead of polling, window resize events are used to cause a more direct trigger.</p>

<h2>Applications</h2>

<h3>Cross-Domain IFrame-to-IFrame Calls ... and Widgets/Gadgets</h3>

<p>In the world of mashups, iframes are a straightforward way to syndicate content from one place to another. The problem, though, is limited interaction between iframes; in pure form, you end up with a few mini web browsers on a single page. It gets better when the iframes can communicate with each other. For example, you can imagine having iGoogle open, with a contacts widget and a map widget. Clicking on a contact, the map widget notices and focuses on the contact's location. This is possible via <a href="http://code.google.com/apis/gadgets/docs/pubsub.html">Gadget-To-Gadget communication</a>, a form of publish-subscribe which works on the iframe hack described here. And speaking of maps, check out <a href="http://code.google.com/apis/maps/documentation/mapplets/basics.html">Google Mapplets</a>, which are a special form of gadget that work on Google Maps, and also rely on this technique.</p>

<p>In terms of gadgets, another application is communication between a gadget and its container, and this is something I've been looking at wrt Shindig. For example, there is a dynamic-height feature gadgets can declare. This gives the gadget developer an API to say "I've updated, now please change my height". Well, an iframe can't change its own height; it must tell its parent to do that. And since the gadget lives in an iframe, on a different domain as the container (e.g. iGoogle), this requires a cross-domain, cross-iframe, message. And so, it uses this technique ("rpc" - remote procedural call - in shindig terminology) to pass a message to the container.</p>

<h3>Cross-Domain Browser-to-Server Calls</h3>

<p>The best known technique for calls from the browser to an third-party server is <a href="On-Demand Javascript">On-Demand Javascript</a>, aka Javascript APIs aka JSON/JSONP. This was obscure in 2005, with Delicious being the best example. Now, it's big time in Web 2.0 API land, and Yahoo! has exposed almost all of its APIs this way, and Google also provides data such as RSS content via JSON.</p>

<p>It works by spawning a new script element programmatically, an element pointing to an external Javascript URL. Since there's no restriction on third-party Javascript running, the browser will faithfully fetch and execute the script, and so the script will typically be written to "return" by updating variable and/or calling an event handler.</p>

<p>There are two major security issues with On-Demand Javascript. Firstly, you have to trust the API provider (e.g. Yahoo!) a lot because you are letting them run a script on your own web page. And there's no way to sanitise it, due to the script tag mechanism involved. If they are malicious or downright stoopid, your users may end up running an evil script which could ask for their password, send their data somewhere, or destroy their data altogether. That's because whatever your web app can do, so can the third party's script, even if you're only trying to get a simple value back. The mechanism forces you to hand over the keys to the Ferrari when all you want is a new bumper sticker. Secondly, what's to stop other websites also making use of the external Javascript? If your own site can embed the script to call a third-party JS API, so too can a malicious fourth-party. This is fine for public, read-only, data, but what if you're relying on the user's cookies to make privileged calls to the third-party? Then the fourth-party's web app will be just as capable of issuing calls from the browser to the third-party, and they might well be more evil calls than you're making, e.g. "transferFunds()" instead of "getBankBalance()". The moral is: Javascript APIs  can only be used for serving public data.</p>

<p>Whoa!!! Public data only? That's a tragic restriction on our cross-domain API! For mashups to be truly useful, it must be personal. We'll increasingly have OAuth-style APIs where users will tell Site X that Site Y is allowed to read its data. But how can that work in the browser? How can Site Y expose its data so that it's usable from the browser, but only when Site X is running? It can't work with On-Demand Javascript. Site Y could try reading the referrer headers to see where the call is coming from, but anyone could write a command-line client with fake headers.</p>

<p>In fact, the answer is to use the iframe hack described in this article. As I mentioned earlier, this is how Facebook gets the job done, with what is essentially the same "power of attorney" delegation model as OAuth (BTW thanks to my colleague <a href="http://osmosoft.com">Jeremy Ruston</a> for the "power of attorney" OAuth analogy - albeit it was stated in a slightly different context from OAuth).</p>

<p>I haven't looked too much into the mechanism involved with the Facebook API, but it looks like it's essentially using a variant of the Marathon technique. From memory, there's an ever-present invisible facebook.com iframe. Each time your web app make a Facebook call, the Facebook JS library spawns a new "proxy" iframe, which passes the message on to its same-domain ever-present frame, which makes a bog-standard XHR call to Facebook. So now we're making an XHR call to another domain, which we can get away with because it's coming from a separate iframe. Once the XHR call returns, I think the message is returned to your application (this happens via another same-domain iframe you must host on your server, though I think that's unnecessary) and the proxy iframe disappears.</p>

<p>Note that all Facebook ever exposes is a standard web service that relies on the user being logged into Facebook - there's no Javascript involved. The user must be logged in and must have given permission for the application to access its Facebook details. Effectively, the user is allowing a particular website URL to make Facebook calls, since the application developer must register the URL. If you look back at the iframe algorithms I described earlier, you'll see that it's straightforward for Facebook to ensure that only this application (and any other application the user trusts) can access the data. The Facebook.com iframe (whose behaviour is controlled by IFrame and can't be tampered) simply has to inspect the URL of the parent window and pass it to the server as part of the XHR call. The server can then check that the logged-in user has authorised this application, using the URL to identify it.</p>

<p>As for the first concern of cross-domain Javascript - having to trust the third-party API provider - I believe the iframe technique overcomes this concern too. Facebook.com never gets to run arbitrary Javascript on your server. Of course, you have to trust the Facebook library and the Facebook-provided iframe you're required to host on your domain, but those could be audited prior to installation. All those things are set up to do is call callback methods inside your top-level application; you could inspect the library and ensure that's all that will ever happen.</p>

<p>Thus, cross-domain iframe-based communication solves both problems which have plagued On-Demand Javascript. It <em>is</em> slightly more complicated, however.</p>

<h3>Conclusions</h3>

<p>Yes, this is a somewhat complicated technique. Actually understanding the problem it solves is really the hard part! Once you understand that, and once you understand those laws of physics, the trick is actually quite straightforward (either version of it).</p>

<p>The technique will be critical for gadget containers such as Shindig. As OAuth takes off, we'll also see the technique used a lot more in mainstream applications and APIs.</p>

<p>With HTML 5, cross-frame messaging will render the hack unnecessary for iframe-to-iframe communication. Indeed, the aforementioned Cross-Domain library uses that technique already for Opera, in a fortuitous twist of fate since Opera doesn't actually support everything this hack requires. However, the notion of using iframes for cross-domain calls will still be  present, no matter how the windows talk to each other.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/cross-domain-communication-with-iframes/feed</wfw:commentRss>
		<slash:comments>75</slash:comments>
		</item>
		<item>
		<title>Time Your Website with WebWait.com</title>
		<link>http://softwareas.com/time-your-website-with-webwaitcom</link>
		<comments>http://softwareas.com/time-your-website-with-webwaitcom#comments</comments>
		<pubDate>Mon, 12 Feb 2007 05:39:47 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[Benchmark]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[WebWait]]></category>

		<guid isPermaLink="false">http://www.softwareas.com/time-your-website-with-webwaitcom</guid>
		<description><![CDATA[

Update (2 days later): The siteâ€™s been popular - 10k+ views yesterday. Hit Delicious Popular and somehow got caught up in the German blogosphere, the greatest source of hits. Technorati it. Thereâ€™s a good discussion in Ajaxian of the strengths and weaknesses of this technique. As with AjaxPatterns, which also reached Delicious Popular, it failed [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://webwait.com"><img style="text-align: center;" src="http://webwait.com/images/webwait.jpg"/></a><br /></p>

<p><em><b>Update (2 days later):</b> The siteâ€™s been popular - 10k+ views yesterday. Hit Delicious Popular and somehow got caught up in the German blogosphere, the greatest source of hits. Technorati it. Thereâ€™s a good discussion in Ajaxian of the strengths and weaknesses of this technique. As with AjaxPatterns, which also reached Delicious Popular, it failed to attract Digg users somehow. (Digg was supposedly inspired by Delicious Popular. Incidentally, Digg doesn't let you submit URLs with fragment identifiers such as http://webwait.com#digg.com, which rules out any Ajax site attempting to allow bookmarks.) Go figure. Or better, <a href="http://digg.com/tech_news/How_long_does_the_Digg_homepage_take_to_fully_load">go Digg</a> <img src='http://softwareas.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</em></p>

<p>Here's another new website - <a href="http://webwait.com">WebWait</a>. I wanted a portable, consistent, way to
benchmark Ajax web apps, that would show how long the wait is (though it's useful for any app, especially if there were a lot of images, for instance). Using a 
command-line tool like curl is an improper simulation and doesn't cut it as a 
proper simulation. WebWait has the following benefits:</p>

<ul>
  <li>Runs in a browser. You get actual load times in the same client web users 
  are running, not simulated times.</li>
  <li>Runs in multiple browsers. There are plugins that do this, but as well as  
  the installation overhead, they are usually specific to one browser. With 
  WebWait, you can just cut-and-paste the same URL into different browsers. (No 
  Safari yet as it doesn't listen to iframe onload ???.)</li>
  <li>Respects your cookies and authentication - If you can access a URL in a web
  page, you can benchmark it with WebWait. Trying to set up cookies for use 
  with a command-line tool like Curl is hard work. Doing it with a plugin is 
  usually impossible. Doing it with a third-party website is dangerously 
  insecure.</li>
</ul>

<p><img width="380" height="200" style="text-align: center;" src="http://img368.imageshack.us/img368/862/webwaitlq6.png"/></p>

<p>Quick feature list as it stands right now:</p>

<ul>
  <li>Basic functionality: Type a URL, see how long it takes to load.</li>
  <li>Option: Set the delay between calls. WebWait will call the website
  multiple times and provide an average load time.</li>
  <li>Option: Set the number of calls before ceasing activity.</li>
  <li>Ability to pause.</li>
  <li>Partially transparent lightbox eye candy.</li>
  <li><a href="http://ajaxpatterns.org/Unique_URLs">Unique URLs</a> - it's
  Ajax, but that shouldn't stop you from bookmarking and sending URLs with
  details of the website being tested. Incidentally, implementing this rare but
  highly useful feature took three lines of Javascript.</li>
</ul>

<p>Have fun. Any comments/suggestions, please let me know!</p>

<p>See the <a href="http://webwait.com/faq.html">FAQ</a> for more info.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/time-your-website-with-webwaitcom/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Portable Comet? It&#8217;s the IFrame, Stupid!</title>
		<link>http://softwareas.com/portable-comet-its-the-iframe-stupid</link>
		<comments>http://softwareas.com/portable-comet-its-the-iframe-stupid#comments</comments>
		<pubDate>Tue, 06 Jun 2006 07:05:44 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[AjaxPatterns]]></category>
		<category><![CDATA[Comet]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Streaming]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.softwareas.com/portable-comet-its-the-iframe-stupid</guid>
		<description><![CDATA[Comet Takes to IE Like a Fish Takes to Acid

Comet - or HTTP Streaming, if you will - is a little sensitive when it comes to portability, and I'll give you four guesses which major browser is causing the grief?  Yeah, IE makes it difficult for two reasons: (a) IE's XMLHttpRequest component doesn't tell [...]]]></description>
			<content:encoded><![CDATA[<h2>Comet Takes to IE Like a Fish Takes to Acid</h2>

<p><a href="http://softwareas.com/comet-podcast">Comet</a> - or <a href="http://ajaxpatterns.org/HTTP_Streaming">HTTP Streaming</a>, if you will - is a little sensitive when it comes to portability, and I'll give you four guesses which major browser is causing the grief?  Yeah, IE makes it difficult for two reasons: (a) IE's XMLHttpRequest component doesn't tell you anything about the response until the connection has closed - even if you try polling it instead of relying on onReadyStateChange, you'll still get an empty string (<a href="http://ajaxify.com/run/streaming/xmlHttpRequest/">Try it</a>); (B) Okay, switch to plan B and inspect IFrame content - we can't rely on onload, which is only called once at the end, so we <em>must</em> poll. But no, polling won't help either, as the IFrame content remains empty until (you guessed it) the connection is closed. (<a href="http://ajaxify.com/run/streaming/xmlHttpRequest/iframe/">Try it</a>).</p>

<h2>We're Going Back, Way Back: Inline Script Tags</h2>

<p>Don't give up on the IFrame so fast ... we're closer than we think. Actually, the solution harkens back to one of the original Push techniques: outputting script tags with inline code (what the HTTP Streaming pattern calls "page streaming"). If you do that in your main document, the code will be executed immediately, and the same is true if you do that inside an IFrame.</p>

<p>I'm talking about a service that outputs stuff like this:</p>

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

<div class="syntax_hilite"><span class="langName">HTML:</span><br /><div id="html-14">
<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/script.html"><span style="color: #000000; font-weight: bold;">&lt;script</span></a> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"text/javascript"</span><span style="color: #000000; font-weight: bold;">&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; doSomething();</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: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span> </div></li></ol></div>
</div></div>

<p><br /></p>

<h2>So Make the Server Spit Out Inline Script Tags</h2>

<p>The portable solution is this: <b>Have the server continuously output script tags that call a known function in the parent frame</b>. When you set the child IFrame's source to point to this service, it will start evaluating the inline scripts as they pop out of the server. This happens to be one technique people have used for remoting for many years (I think Brent Ashley recently told me he was doing it in ?1999). The twist with Comet is that you &#42;keep&#42; doing it, and don't actually close the connection for a while. (Again, I'm sure some people were doing that for a long time too!).</p>

<p>Is it elegant? No. It means the remote service is suddenly coupled to the client-side of the web app - it has to know something about what's in the parent frame, whereas you'd often like it to be generic and just deliver a response in <a href="http://ajaxpatterns.org/XML_Message">XML</a>, <a href="http://ajaxpatterns.org/JSON_Message">JSON</a> or <a href="http://ajaxpatterns.org/Plain-Text_Message">whatever</a>. Like most things Ajax, we're using a hack because it nonetheless push all the right buttons for our users.</p>

<p><a href="http://ajaxify.com/run/streaming/xmlHttpRequest/iframe/scriptTags/">Try It. Portable Comet for the Masses</a></p>

<p><a href="http://ajaxify.com/run/streaming/xmlHttpRequest/iframe/scriptTags/"><img src="http://img62.imageshack.us/img62/2792/streamingtags2wz.png"/></a></p>

<h2>Here's Some Code I Prepared Earlier</h2>

<p>In the example above, the remote service outputs script tags in a loop - it's a simple countdown service:</p>

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

<div class="syntax_hilite"><span class="langName">PHP:</span><br /><div id="php-15">
<div class="php"><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:#000000; font-weight:bold;">&lt;?</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:#616100;">for</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$i</span>=<span style="color:#0000FF;">$_GET</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">"start"</span><span style="color:#006600; font-weight:bold;">&#93;</span>; <span style="color:#0000FF;">$i</span>&gt;=<span style="color:#CC66CC;color:#800000;">0</span>; <span style="color:#0000FF;">$i</span>--<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#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;"><span style="color:#000000; font-weight:bold;">?&gt;</span></div></li>
<li style="font-weight: bold;color:#26536A;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &lt;script type=<span style="color:#FF0000;">"text/javascript"</span>&gt;</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; window.parent.onNewValue<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#000000; font-weight:bold;">&lt;?</span>= <span style="color:#0000FF;">$i</span> <span style="color:#000000; font-weight:bold;">?&gt;</span><span style="color:#006600; font-weight:bold;">&#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:#000000; font-weight:bold;">&lt;/script&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;"><span style="color:#000000; font-weight:bold;">&lt;?</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:#006600; font-weight:bold;">&#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:#000000; font-weight:bold;">?&gt;</span> </div></li></ol></div>
</div></div>

<p><br /></p>

<p>And in the browser's initial Javascript, there's a run-of-the-mill onNewValue() function, it looks something like this.</p>

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

<div class="syntax_hilite"><span class="langName">JAVASCRIPT:</span><br /><div id="javascript-16">
<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;">function</span> onNewValue<span style="color: #66cc66;">&#40;</span>i<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; statusDiv.<span style="color: #006600;">innerHTML</span> = i; <span style="color: #009900; font-style: italic;">// Paint the new value onto the page</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></ol></div>
</div></div>

<p><br /></p>

<p>See what I mean about coupling? The server-side service had to know that there's a Javascript function defined in the parent called onNewValue(). At least we've minimised the coupling by using an Observer/Event style indirection approach - evidenced by the simple call to "onNewValue()". It would be worse if it was the script that actually performed application logic directly, repainting the DOM with the new value.</p>

<h2>IFrame is the new XMLHttpRequest</h2>

<p>Whoever put the X in Ajax ought to put an I in Comit. IE's XHR component doesn't provide the response until the connection has closed, and I don't think version 7 changes that. Assuming (graciously) it happens in IE8, you'll need to use IFrame for the next five years if you're doing any Comet work. And of course, you won't need to do that, because libraries will do it for you.</p>

<p>BTW You could argue that IE is doing the right thing by preventing access to the content until the connection is closed. Maybe they are, maybe they aren't. From a pragmatic perspective, though, portable Comet requires Ajax. Alternatively, use IFrame with IE and XmlHttpRequest with the others, though I'm not sure if there's much mileage to be gained from this hybrid strategy.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/portable-comet-its-the-iframe-stupid/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>SAG Ajax Patterns Review 1 &#8211; XHR Call, IFrame Call, HTTP Streaming</title>
		<link>http://softwareas.com/sag-ajax-patterns-review-1</link>
		<comments>http://softwareas.com/sag-ajax-patterns-review-1#comments</comments>
		<pubDate>Sat, 04 Mar 2006 02:51:40 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[AjaxPatterns]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Review]]></category>
		<category><![CDATA[SAG]]></category>
		<category><![CDATA[Streaming]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.softwareas.com/sag-ajax-patterns-review-1</guid>
		<description><![CDATA[

A little while back, I mentioned that some people in the patterns community have been noticing the Ajax Patterns. In particular, there have been a series of discussions about the patterns by the Software Architecture Group in the University of Illinois Computer Science Dept (home of Netscape forerunner Mosaic btw). The SAG is led by [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://wiki.cs.uiuc.edu/SAG"><img style="text-align: right; margin: 8px; float: right;" src="http://img234.imageshack.us/img234/966/illinois3ag.png"/></a></p>

<p>A little while back, I mentioned that some people in the patterns community <a href="http://www.softwareas.com/ajax-patterns-in-the-pattern-community-radar">have been noticing</a> the Ajax Patterns. In particular, <strong>there have been a series of discussions about the patterns by the <a href="http://wiki.cs.uiuc.edu/SAG">Software Architecture Group</a> in the <a href="http://www.cs.uiuc.edu/">University of Illinois Computer Science Dept</a></strong> (home of Netscape forerunner Mosaic btw). The SAG is led by <a href="http://st-www.cs.uiuc.edu/users/johnson/">Ralph Johnson</a> (Gang Of Four "Design Patterns" author) and <a href="http://wiki.cs.uiuc.edu/SAG/SAG+members">the group</a> also includes <a href="http://www.laputan.org/">Brian Foote</a>, who <a href="http://www.laputan.org/catfish/archives/000139.html">blogged about Ajax as a pattern earlier on</a> and has kindly been keeping me updated on <a href="http://brain.cs.uiuc.edu/SAG/">the MP3s emerging from these discussions</a>.</p>

<p>The feedback has been very helpful and I've been able to incorporate it in time for the physical publication - thanks again to everyone in the group.</p>

<p>While listening to the audio, I've been taking notes and writing some comments. With the permission of Ralph and Brian, <strong>I'm going to be posting these, each discussion as a separate post. It's an opportunity to see how a group of very intelligent people without much Ajax experience respond to Ajax and the Ajax patterns.</strong> You'll notice two conventions here:  "TODO" is a note to myself that some action needs to be taken. "MM" signals my ideas, views, and comments back to the group.</p>

<p><b><a href="http://brain.cs.uiuc.edu/SAG/2006-01-30-Ajax.mp3">Jan-30-2006 First Ajax Patterns Discussion</a></b></p>

<p>30/1/2006 Ajax Workshop</p>

<h1><pre></pre></h1>

<p>9:45 XMLHttpRequest Call</p>

<p>What it's about.
  - Probably missing in old browsers if you can't use Ajax on
    them.
  - Remote call to server without refreshing a whole page.
  - I assumed in JS you can open a socket, you could have done
    this yourself.
    - Depends on what the browser provides. But not
      cross-browser.  [TODO Mention HTTP restriction and what JS
      can do, cf Richer Plugin]
    - Ironically, because JS isn't general-purpose (due to
      security), it's wound up being a better citizen. Also
      because it was kind of low-brow, everyone kind of ignored
      it.
  - The big idea is this is a way to call the server.</p>

<p>Interesting characteristic of XHR:
  - Asynchronous
  - Built-in security (originating server)</p>

<p>Did you find this pattern easy to understand?
  - One thing that troubles me (not particular to this pattern),
    pretty soon the code becomes spaghetti-like. Nd good patterns
    on how to manage code.  [MM Agree, we need a JS patterns
    book! That's not the aim here, the book will make that
    explicit].
    - Part of the problem here is JS itself.
  - Haven't seen the word "simple" "elegant" or "pretty" to
    describe JS architect. This is a Rube Goldberg solution,
    duct-tape ... at it's best.  [MM Sort of true, but there's a
    lot that can be done to improve it]
    - There are libraries that help. (AjaxCaller, Prototype).</p>

<p>Writing here, even though it doesn't address these problems,
could understand/follow it?
  - I don't like the Problems section. "How can the browser
    communicate with the server?" But this pattern is more
    specific than server communication.  The next 1-2 patterns
    have the same problem.
      - But the problem might be the same, but different
        Solution. What I dislike is the forces are also the same.
        How does it mitigate the forces? Maybe there should be
        some different forces.
      - Only difference between IFrame and XHR is only restricted
        to same host, so maybe okay other than that.  [MM
        Actually, even this difference doesn't exist, since you
        can't read a remote IFrame's content] [TODO Possibly
        update forces to be different, back-reflect the solution]</p>

<p>22:30 Doesn't say anything about being asynchronous at the start
  - Ajax should be highly responsive. Distributed system, so you
    want to minimise communications. ie Must be asynchronous
    [TODO Revise forces. HOWEVER, note that XHR doesn't have to
    be async.]
  - "Conventional means ... slow." He's trying to rule out
    Solutions, before we get to the solution.  [MM This sort of
    goes against the previous suggestion that IFrame and XHR need
    different Forces. Maybe suggests different people have
    different views on this issue of the forces.] Doesn't so much
    talk about the forces as take potshots at existing solutions.
    [MM This is a fair point, more prevalent in the initial
    patterns as they're arising as a reaction to conventional web
    dev, but it's true you don't have to formulate them that
    way.]</p>

<p>26:30 It's a long pattern, is that okay?
  - Yes, longer than all the others, problem if all patterns were
    this long, but given it's so core to Ajax, it's fine.
  - Length is fine, but a lot of code there.
    - I would like more examples of the old way of doing things.
      [Covered in the Anagrams tutorial, perhaps reference it]
    - The general idea is if you have a big object and only small
      things change at a time, then you keep going back to the
      server and grabbing small bits of it. I think of Google
      Maps.
  - Pattern could be shorter if PHP wasn't written.
    - So you'd like <em>less</em> example code, others want more.
    - It's a Chimera/Frankenstein ie PHP (or whatever serverside)
      on the one side, and even JS is a kind of Frankenstein
      language. So it's important to have the PHP, reminds me
      that's the game I'm playing. I didn't mind it, seeing all
      the pieces together reminds you we're receiving small
      chunks etc.
    - The pattern is really introducing XHR, not how to use it.
      - Disagree with people who are trying to call everything a
        pattern.
      - Well, these particular patterns are what he calls
        foundational. He says they're not really patterns,
        they're just how the technology works.
      - I know what you're saying about that, and it bugs me too,
        but I've been trying to come up with a rationalisation
        for admitting that this kind of design exposition is a
        contribution to our software architecture literature ...
        and if designs recur, if a lot of people come up with the
        same solution to a problem ... my mind cries out to keep
        distinct from Visitor and ... Composite, but I don't have
        the vocab to keep them distinct, and I want to maintain
        this notion that the patterns community is talking about
        good ideas that keep coming up over and over that we
        haven't come up with ourselves ... true, it's a different
        kind of discussion from the GoF, without having
        disclaimer kind of nags at me [MM Agree wholeheartedly,
        why I've sounded a bit apologetic describing these as
        patterns, but they just fit into the overall language
        well.  See earlier blog post.] [TODO Needs better
        "disclaimer" in the book]
    - So then what are the patterns around XHR?
      - Event handling, Asynchronous call
      - Lots of people dealing with SOA, problems s.a. async
        smell the same but with different names [MM Later
        patterns, e.g. Distr'd events]
      - Error detection
      - Invesion-of-control/DepInj/Observers. People patternising
        closures.  There's an aspect of dealing with callbacks.
        Callbacks are part of the discussion here, and that's an
        idea that comes up here.
      - Feedback from the call. Or using poll. Fire-and-forget.
        Typical remote invocation styles: What does XHR do?
      - In JS: Callbacks used here (XHR), also used for user
        interops. We want to follow flow-of-control, but if
        everything is event handlers, hard to follow. (ie JS hard
        to follow because of this style.) A lot of the time,
        "callbacks" are basically continuations. It's a general
        pattern discussion we could have.</p>

<p>41:30 Real-World Examples and Code.
  - These systems are not thoroughly responsive as claimed.
    Google Suggest surprisingly fast. Others like Backpackit and
    Kiko not.  [MM See perf optimisation, also comments in HTML
    Message, etc. Alex Kirk mentioned Kiko a while ago as a
    problem due to too much browser-side rendering.]
  - Need to avoid too many requests
  - Curious didn't mention the most famous examples (Google
    Suggest etc) Maybe can't see the code. But it's JS, have to
    be able to. But maybe unclear.  [MM Yes, obfuscated. Also,
    tried to avoid the cliche references too much, they're
    mentioned elsewhere]
  - Discussion about mint stats package, security issues in
    uploading data.
    - Next, ways of telling your web browser what to report back.
    - If trying to keep people from attacking you. It's
      interesting to me.
    - Applets got crucified for some of the security problems
      that JS has.  People moved on from panicking about them,
      but got away with it because browser wars finished etc.</p>

<p>===============================================================
49:00 IFrame Call
  - Poor Man's version of the previous one.
  - More like a hack
  - What can you do with one that you can't do with the other?
    XHR and not with IFr?
    - I only know the other way round...IFrame is more compat
      with older browsers.
    - Long discussion about relative benefits etc.
    - Comment about Google using IFrame. Not sure if it's true as
      you can zoom in.[TODO More specific about how it's being
      used. (I think book version already does that)]
    - IFrame Call doesn't talk about hidden frames.  [MM XHR
      Pattern alternatives has a detailed comparison)] [TODO XHR
      comparison should briefly explain <em>how</em> the two are diff,
      not just compare the benefits]
    - IFrame has no timeout function. (But could fake this using
      polling)
    - Calls IFrame a hack ... Pot calling the kettle black, since
      Ajax itself is sort of a hack. Is it bad just because it's
      old?  [MM Again, comes down to the comparison. XHR is a
      more intention-based, intuitive, API, although it's true
      that you won't care about that because you should use a
      wrapper lib anyway. Better argument is the extra
      functionality such as call tracking.]
    - Would like better explanation on what's so bad about
      IFrames.  [TODO Include x-reference in IFrame Solution.
      Also mention the portable wrappers in the Solution, ie you
      shouldn't actually care/know which you're using is the more
      pertinent issue here.]
    - I'm feeling historical. The room we used to sit in is the
      room where the original Mosaic web browser developers sat.
      Continuously astonished in the web industry, using things
      that in ways they weren't invented for. Go down this list,
      frames, tables ...  Ungodly mess, but really impressed,
      poster child for pragmatism and "worse is better".  IFrame
      is a typical example.
  - I didn't get any feel on whether I would use one or the
    other.
  - Intrigued by the history of JS. Knowing that IFrame predated
    XHR because features that made it easier to do the second
    came along in 2003. Whether it needs to be here, not sure.
    [TODO Sidebar?]</p>

<p>===============================================================
49:00 HTTP Streaming</p>

<pre><code>Is it competition for the other two?  
  - Different problem (push/streaming)
  - "How can the browser communicate with the server?" Same
    problem as the other two.
    - I don't know, it turns the table. Little pattern device
      of using the same problem with different solutions may
      be okay here. Here, the forces would be different.
      Could make the case for having the same problem.  [TODO
      Change the problem statement, just enough to make it a
      little different from previous two.]

What would make you choose this over the others?
  - Changes coming from lots of other sources, not just the
    client.
  - e.g. Chat system.
  - I don't want to do this. Don't want to grow the system
    ...
    - But scaleability is oversold. You'll never be like
      EBay, don't need to scale up like that.  [TODO Good
      point, mention in the pattern.]
    - Our wiki - 4-5 hits per second - can handle that, but
      not scaleable.  Wikipedia is not a wiki in that sense,
      pages don't change because I believe something like 90%
      of all edits are done by 200 people, these are official
      wikipedia authors. Specific process.
    - Doesn't fit into proxies. Caching etc doesn't ddeal
      with longer responses.

Long refactoring illustration here. Do the others have one?
  - Streaming wiki demo.
  - Seemed nice to refactor in this way.
  - The group is looking at the live version on the web -
    "There's about a half dozen laptops in it for the
    author's information". It worked.  [MM Phew]
</code></pre>

<p>===============================================================
1:20
    - I didn't get the feel of which one to use.
      - Was hidden in the Alternatives section [MM TODO Emphasise
        this in the partintro, maybe in the solutions]</p>

<p>======
Next time: Different patterns
    - Problem with web version [MM Incidentally, the wiki
      publishing hasn't worked out ideally, didn't get the full
      benefit as I didn't open up the wiki (and still haven't due
      to spam). Ideally would have better PS format. (Blogged
      about printing from the web a yr ago as it happens.)]
    - Being on the web doesn't seem to affect (ie drop) sales.
      [MM We'll soon find out...:-)]
</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/sag-ajax-patterns-review-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://brain.cs.uiuc.edu/SAG/2006-01-30-Ajax.mp3" length="81625216" type="audio/mpeg" />
		</item>
		<item>
		<title>Basics of Ajax 2 of 3: Web Remoting (XMLHttpRequest etc) (Podcast)</title>
		<link>http://softwareas.com/ajax-basics-podcast-2</link>
		<comments>http://softwareas.com/ajax-basics-podcast-2#comments</comments>
		<pubDate>Wed, 02 Nov 2005 12:48:26 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[Podcast]]></category>
		<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[AjaxPatterns]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Remote Scripting]]></category>
		<category><![CDATA[Remoting]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Streaming]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.softwareas.com/ajax-basics-podcast-2</guid>
		<description><![CDATA[Ajax Basics 2 of 3

This is the second of three podcasts on the basic Ajax patterns.


Podcast 1: Display Patterns and the DOM.
Podcast 2: Web Remoting - XMLHttpRequest, IFrame Call, HTTP Streaming.
Podcast 3: Dynamic Behaviour - Events and Timing.


Podcast 2: Web Remoting (XMLHttpRequest, IFrame, HTTP Streaming)



This 75 minute podcast covers web remoting concepts and the following [...]]]></description>
			<content:encoded><![CDATA[<h2>Ajax Basics 2 of 3</h2>

<p><strong>This is the second of three podcasts on the basic <a href="http://ajaxpatterns.org">Ajax patterns</a>.</strong></p>

<ul>
<li><a href="http://www.softwareas.com/ajax-basics-podcast-1">Podcast 1</a>: Display Patterns and the DOM.</li>
<li><strong>Podcast 2: Web Remoting - XMLHttpRequest, IFrame Call, HTTP Streaming.</strong></li>
<li>Podcast 3: Dynamic Behaviour - Events and Timing.</li>
</ul>

<h2>Podcast 2: Web Remoting (XMLHttpRequest, IFrame, HTTP Streaming)</h2>

<p><a href="http://www.softwareas.com/podcast/SASD_AjaxRemotingBasics2Of3.mp3"
title="Click to download the Podcast and play it on your computer."
style="text-decoration: none;"><img src="/images/aquapodcastfileicon.gif"
border="0" alt="Click to download the Podcast. You can also subscribe to the
feed if you want future podcasts automatically downloaded - check out the
podcast FAQ at http://podca.st." border="0"/></a></p>

<p>This 75 minute podcast covers web remoting concepts and the following specific patterns:</p>

<ul>
<li><a href="http://ajaxpatterns.org/XMLHttpRequest_Call">XMLHttpRequest Call</a> Use XMLHttpRequest objects for browser-server communication. (05:00)</li>
<li><a href="http://ajaxpatterns.org/IFrame_Call">IFrame Call</a> Use IFrames for browser-server communication. (31:45)</li>
<li><a href="http://ajaxpatterns.org/HTTP_Streaming">HTTP Streaming</a> Stream server data in the response of a long-lived HTTP connection. (47:00)</li>
</ul>

<p><span style="display:none"></span></p>

<hr />

<p>Please ignore this bit, I'm claiming 
<a href="http://odeo.com/claim/feed/bdd768d9acefcad9">My Odeo Channel</a> (odeo/bdd768d9acefcad9)</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/ajax-basics-podcast-2/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
<enclosure url="http://softwareas.com/podcast/SASD_AjaxRemotingBasics2Of3.mp3" length="36291904" type="audio/mpeg" />
<enclosure url="http://www.softwareas.com/podcast/SASD_AjaxRemotingBasics2Of3.mp3" length="36291904" type="audio/mpeg" />
		</item>
		<item>
		<title>New Patterns: XMLHttpRequest Call and IFrame Call</title>
		<link>http://softwareas.com/new-patterns-xmlhttprequest-call-and-iframe-call</link>
		<comments>http://softwareas.com/new-patterns-xmlhttprequest-call-and-iframe-call#comments</comments>
		<pubDate>Mon, 10 Oct 2005 01:29:08 +0000</pubDate>
		<dc:creator>mahemoff</dc:creator>
				<category><![CDATA[HumansAndTech]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[SoftwareDev]]></category>
		<category><![CDATA[AjaxPatterns]]></category>
		<category><![CDATA[IFrame]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Remoting]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.softwareas.com/new-patterns-xmlhttprequest-call-and-iframe-call</guid>
		<description><![CDATA[Full drafts are now online for the two big Web Remoting patterns: XMLHttpRequest Call and IFrame Call. There are also a couple of new demos to illustrate GETting and POSTing with both call types: XMLHttpRequest Example, IFrame Example.

A few extracts follow, but first, let me ask you: Do you know of any public IFrame remoting [...]]]></description>
			<content:encoded><![CDATA[<p>Full drafts are now online for the two big Web Remoting patterns: <a href="http://ajaxpatterns.org/XMLHttpRequest_Call">XMLHttpRequest Call</a> and <a href="IFrame_Call">IFrame Call</a>. There are also a couple of new demos to illustrate GETting and POSTing with both call types: <a href="http://ajaxify.com/run/xmlHtttpRequestCall/">XMLHttpRequest Example</a>, <a href="http://ajaxify.com/run/iframe">IFrame Example</a>.</p>

<p>A few extracts follow, but first, let me ask you: <strong>Do you know of any public IFrame remoting examples?</strong> Google Maps is the only public example I know. All the other examples here are tutorials and framework demos.</p>

<p>The XMLHttpRequest alternatives was the most fun thing here (headings shown below). I went through the various techniques I've seen, read about, and tried out, to list as many ways as possible to programmatically call the server. As you might expect for these "Foundational Technology" patterns, there's a lot more code in the Solutions than in later patterns, where the focus shifts more towards the -ilities, particularly usability and maintainability.</p>

<p><strong>As usual, feedback much appreciated.</strong> (Mainly on the content, rather than woeful spelling and outright grammatical disasters at this stage.)</p>

<h3>XMLHttpRequest Call</h3>

<p><strong>Solution:</strong>
<strong>Use XMLHttpRequest objects for browser-server communication.</strong> XMLHttpRequest is a Javascript class capable of calling the server and capturing its response. Just like a browser or a command-line web client, an XMLHttpRequest issues standard HTTP requests and grabs responses. Note: The code shown throughout this demo is closely based on an online companion demo (http://ajaxify.com/run/xmlHttpRequestCall/).</p>

<p><example omitted.></example></p>

<p>The above example hopefully illustrates that the fundamental technology is pretty simple. However, be aware that it's a very basic usage, not yet fit for production. Fundamental questions remain:</p>

<pre><code>* How can XMLHttpRequests be created?
* How does an asynchronous call work?
* How do our code detect errors?
* What if the service requires a "POST" or "PUT" request rather than a "GET"?
* Which URLs can be accessed?
* How can you deal with XML responses?
* What's the API? 
</code></pre>

<p>The following sections address these questions and show how the code above needs to be modified. 
...</p>

<p><strong>Decisions</strong>
<pre>
6.1 What kind of content will web services provide?
6.2 How will caching be controlled?
6.3 How will you deal with errors?
</pre></p>

<p><strong>Alternatives:</strong>
<pre>
9.1 IFrame Call
9.2 Persistent Connection
9.3 Richer Plugin
9.4 On-Demand Javascript
9.5 Import XML Document
9.6 Image-Cookie Call
9.7 Stylesheet Call
</pre></p>

<h3>IFrame Call</h3>

<p><strong>Solution:</strong>
<strong>Use IFrames for browser-server communication.</strong> IFrames are page-like elements that can be embedded in other pages. They have their own source URL, distinct from their parent page, and it can change dynamically. IFrame Calls work by making the IFrame point to a URL we're interested in, then reading the IFrame's contents once the new content has loaded.
</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareas.com/new-patterns-xmlhttprequest-call-and-iframe-call/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
