<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oliver Steele &#187; OpenLaszlo</title>
	<atom:link href="http://osteele.com/archives/category/openlaszlo/feed" rel="self" type="application/rss+xml" />
	<link>http://osteele.com</link>
	<description>Languages of the real and artificial.</description>
	<lastBuildDate>Wed, 28 Oct 2009 22:31:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>FlashBridge: proxying Flash  OpenLaszlo</title>
		<link>http://osteele.com/archives/2008/04/flashbridge</link>
		<comments>http://osteele.com/archives/2008/04/flashbridge#comments</comments>
		<pubDate>Sun, 13 Apr 2008 11:27:07 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[OpenLaszlo]]></category>

		<guid isPermaLink="false">http://osteele.com/2008/04/13/flashbridge-proxying-flash-openlaszlo</guid>
		<description><![CDATA[I've updated my "OpenLaszlo utility grab-bag":http://github.com/osteele/lzosutils to make browser <-> applet communication even easier.  How easy?


h3. Proxies

Put this in your browser JavaScript:

[code language="javascript"]
var gObject = {
  f: function() { console.info('gObject.f', arguments) },
  g: function() { console.info('gObject.g', arguments) }
};
[/code]

And this in an OpenLaszlo applet:

[code language="javascript"]
var gObject = FlashBridge.createRemoteProxy('gObject', ['f', 'g']);
gObject.f(1, 2);
gObject.g(3);
[/code]

When you run the applet code, it prints this to the browser console:]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve updated my <a href="http://github.com/osteele/lzosutils">OpenLaszlo utility grab-bag</a> to make browser &lt;-&gt; applet communication even easier.  How easy?</p>


<h3>Proxies</h3>

<p>Put this in your browser JavaScript:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> gObject <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  f<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gObject.f'</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  g<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gObject.g'</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>




<p>And this in an OpenLaszlo applet:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> gObject <span style="color: #339933;">=</span> FlashBridge.<span style="color: #660066;">createRemoteProxy</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gObject'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'f'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'g'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
gObject.<span style="color: #660066;">f</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
gObject.<span style="color: #660066;">g</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>




<p>When you run the applet code, it prints this to the browser console:</p>



<pre>
gObject.f [1,2]
gObject.g [3]
</pre>



<p>That&#8217;s right, Flash is invoking the function calls, but they&#8217;re executing in the browser.</p>

<p>Now switch these around &#8212; put the first block in the applet, and the second block in the browser JavaScript &#8212; and it still runs the same way, except that it&#8217;s the <strong>browser</strong> that invokes the functions, and they run in the <strong>applet</strong> (and print to the OpenLaszlo debug console, if the applet was compiled with debugging on).</p>

<p>(By the way, the full sources for the examples are <a href="http://github.com/osteele/lzosutils/tree/master/test/flashbridge">here</a>.)</p>


<h3>Return Values</h3>

<p>Callbacks, or continuations for return values, make it easy for the applet to operate on the return value from a call into the browser, even though these calls are asynchronous.</p>

<p>Put this in the browser:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> gService <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  add<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    logCall<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gBrowserObject.add'</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> a<span style="color: #339933;">+</span>b<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  error<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    logCall<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gBrowserObject.error'</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">throw</span> msg<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>




<p>And this in the applet:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">gBrowserObject.<span style="color: #660066;">add</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">onreturn</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'1 + 2 -&gt; '</span> <span style="color: #339933;">+</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
gBrowserObject.<span style="color: #660066;">error</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'error msg'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">onexception</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'error !&gt; '</span> <span style="color: #339933;">+</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>




<p>The argument to <code>onreturn</code> is called (asynchronously) with the return value.  The argument to <code>onexception</code> is called with the message from the exception, if an exception occurred.</p>

<p>Callbacks, unlike proxies, only work one direction &#8212; for calls from the applet to the browser.  That&#8217;s not for a technical reason &#8212; I&#8217;ve just only needed it one direction so far.</p>


<h3>Call Storage</h3>

<p>Browser code can call into the applet even if the applet hasn&#8217;t initialized yet, and vice versa.</p>

<p>To implement this, each side of the bridge stores calls (and return value handlers) in a <a href="http://en.wikipedia.org/wiki/Mailbox_%28computing%29">mailbox</a> until it hears back that the other side has loaded.  Once this happens, the mailboxes are flushed and the remote call methods switch to direct invocation.</p>

<p>This works around a couple of race conditions.  First, the applet won&#8217;t generally have run its initialization code by the time the browser receives its load event, so a naive implementation of the bridge wouldn&#8217;t allow the browser to make calls into the applet until the browser had heard back that the applet had loaded &#8212; which is hard to detect.  (It isn&#8217;t enough to wait for the object&#8217;s onload event, because this can trigger before the first frame of the movie plays, so the applet may still not have initialized enough to receive messages.)  Conversely, depending on your page organization and initialization raindance, the applet might load before page side has registered &#8212; so the applet couldn&#8217;t call into the page until an unknown time.</p>


<h3>Security Implications</h3>

<p>FlashBridge, by default, allows the browser to call anything sitting in the applet, and vice versa.  This increases the attack surface of your application, because it allows an embedded Flash applet to invoke any part of it.  This means that an <span class="caps">XSS </span>can tunnel through your applet to gain access to any site with a <code>crossdomain.xml</code> file that allows your applet to connect to it &#8212; something that <span class="caps">XSS </span>on a pure JavaScript page can&#8217;t do.</p>

<p>It you prefer not to audit your application against this, you can call <code>FlashBridge.secure</code> to prevent it from accepting arbitrary calls, and then <code>FlashBridge.register</code> to register callins.</p>

<p>There&#8217;s no lockdown facility in the other direction &#8212; to lock down the browser JavaScript against calls from the Flash application.  That&#8217;s because it&#8217;s trivial for a Flash application to invoke arbitrary JavaScript in the browser context &#8212; in fact, that&#8217;s how the applet -&gt; browser communication is implemented, and if that were secured at the FlashBridge layer, the vulnerability would still be accessible one layer down.</p>


<h3>Gitting It</h3>

<p>All this is in the <a href="http://github.com/osteele/lzosutils">LzOsUtils project on GitHub</a>, with examples <a href="http://github.com/osteele/lzosutils/tree/master/test/flashbridge">here</a>.  Download it via the Download button, clone it via <code>git clone git://github.com/osteele/lzosutils.git</code>, or add it as a submodule to an existing git repo via <code>git add submodule git://github.com/osteele/lzosutils.git</code>.</p>

<p>FlashBridge is written for OpenLaszlo, but would probably run in straight Flash too. And it uses my own funky alternative to <code>ExternalInterface</code> for calling from Flash to the browser (since the built-in <span class="caps">API </span>is <a href="http://codinginparadise.org/weblog/2005/12/serious-bug-in-flash-8.html">seriously broken</a>), but it could be ported to run on top of Dojo or something pretty easily.</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2008/04/flashbridge/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What I didnâ€™t get to</title>
		<link>http://osteele.com/archives/2007/12/what-i-didnt-get-to</link>
		<comments>http://osteele.com/archives/2007/12/what-i-didnt-get-to#comments</comments>
		<pubDate>Tue, 01 Jan 2008 04:25:23 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://osteele.com/2008/01/01/what-i-didnt-get-to</guid>
		<description><![CDATA[Here are some of the weekend projects that I didn't finish this year.  These aren't good enough to put on my project list or my "sources page":http://osteele.com/sources/.  Some of these aren't even working, and some of them I might not finish at all (most of my weekends are spoken for).  And some of them I can't bear to look at (I'm not proud of the code, and don't want to be judged by it...), but I'm making myself put them out there anyway.  I feel bad for the neglected little things, trapped on my hard drive, and I'd like to let them see the sun, even if just briefly before they flicker out and die.]]></description>
			<content:encoded><![CDATA[<p>Here are some of the weekend projects that I didn&#8217;t finish this year.  These aren&#8217;t good enough to put on my project list or my <a href="http://osteele.com/sources/">sources page</a>.  Some of these aren&#8217;t even working, and some of them I might not finish at all (most of my weekends are spoken for).  And some of them I can&#8217;t bear to look at (I&#8217;m not proud of the code, and don&#8217;t want to be judged by it&#8230;), but I&#8217;m making myself put them out there anyway.  I feel bad for the neglected little things, trapped on my hard drive, and I&#8217;d like to let them see the sun, even if just briefly before they flicker out and die.</p>

<p>Libraries:<br />
* <a href="http://osteele.com/sources/openlaszlo/lzosutils">LzOSUtils</a> &#8212; jQuery-compatible <code>ajax</code> function, Flash-&gt;JS bridge with callbacks, declarative Flash 8 filter effects, console that reports to Firebug, dashed lines, Prototype-compatible string and collection methods, etc.  Completely undocumented and fairly disorganized.<br />
* <a href="http://osteele.com/sources/openlaszlo/lztestkit">LzTestKit</a> &#8212; mocks and asynchronous and automated testing for OpenLaszlo; still pretty raw.<br />
* <a href="http://osteele.com/sources/javascript/hopkit">HopKit</a> &#8212; a &#8220;higher order programming kit&#8221;, for constructed chained <span class="caps">API</span>s such as in LzTestKit&#8217;s mocks and expectations; still somewhat buggy and undocumented.<br />
* <a href="http://osteele.com/sources/javascript/concurrent">MVars</a> &#8212; a port of Haskell <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-MVar.html">MVar</a>&#8217;s to JavaScript.  I realized that what I actually needed for real-world applications was an implementation of the <a href="http://en.wikipedia.org/wiki/Join_calculus">join calculus</a> (a la <a href="http://jocaml.inria.fr/">JoCaml</a>).  I haven&#8217;t written the join calculus version.<br />
* <a href="http://osteele.com/sources/javascript/protodoc">Protodoc</a> &#8212; I wrote this to extract the docs from the source files and to implement the live examples in <a href="http://osteele.com/sources/javascript/functional">Functional</a> and <a href="http://osteele.com/sources/javascript/sequentially">Sequentially</a>; it includes a version of the wonderful <a href="http://docs.python.org/lib/module-doctest.html">doctest</a>, for JavaScript.  I got part way through refactoring it into something that isn&#8217;t quite put together again.  I haven&#8217;t decided whether to finish it or whether there&#8217;s an existing project that&#8217;s close enough.<br />
* [No link yet] Updates to <a href="http://osteele.com/sources/openlaszlo/json/">OpenLaszlo <span class="caps">JSON</span></a> and <a href="http://ropenlaszlo.rubyforge.org/">ropenlaszlo</a>, from using them over the past year.  (No, those links go to the old versions &#8212; I haven&#8217;t uploaded the updates <img src='http://osteele.com/wp/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> <br />
* Implementations in <a href="http://osteele.com/sources/ruby/cfdg.rb">Ruby</a> and <a href="http://osteele.com/sources/javascript/cfdg">JavaScript</a>  of the awesome <a href="http://www.chriscoyne.com/cfdg/"><span class="caps">CFDG</span></a>.  I wrote these a couple of years ago, and really want to update and clean them up to point where I can donate them to <a href="http://hacketyhack.net/">Hackety Hack</a>, or someone else who might use them.</p>

<p>Applets:<br />
* <a href="http://osteele.com/applets/tiles.html">Tiles</a> &#8212; <span class="caps">HTML </span>port of my mid-nineties <a href="http://osteele.com/applets/java-tiles.html">Java version</a> (which was a port of my mid-eighties C version), uses the Canvas tag; probably doesn&#8217;t work in <span class="caps">MSIE</span><br />
* <a href="http://osteele.com/applets/ifs.html"><span class="caps">IFS</span></a> &#8212; a few minutes of pair programming with my son to show him some stuff about matrices; probably doesn&#8217;t work in <span class="caps">MSIE</span><br />
* <a href="http://osteele.com/applets/onthisday/">On this day</a> &#8212; iPhone applet; the feed is down right now<br />
* Force-directed layout for my home page &#8212; this was my experiment using <span class="caps">HTML </span>instead of Flash; I got discouraged when I saw how bad the frame rate for full-page animation is was even in Firefox, let alone <span class="caps">MSIE </span>(Safari rocks now, though!)</p>

<p>Plus a couple dozen essays that are half or three-quarters written (programming, software development, math education), a couple of <span class="caps">AJAX </span>presentations, and two workbooks for teaching abstract math at the elementary level.  It takes me longer to write an essay than a program, though!</p>

<p>More weekends, please.</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2007/12/what-i-didnt-get-to/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Canvas with Text</title>
		<link>http://osteele.com/archives/2006/02/textcanvas</link>
		<comments>http://osteele.com/archives/2006/02/textcanvas#comments</comments>
		<pubDate>Tue, 28 Feb 2006 04:13:35 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://osteele.com/2006/02/28/canvas-with-text</guid>
		<description><![CDATA[The two times that I've used the WHATWG canvas element recently, I've wanted a canvas with string rendering.  The most recent time that I've used the OpenLaszlo drawview class (which has substantially the same API), I've wanted string rendering too.

The graph in "reAnimator":/tools/reanimator is a drawview, but with text labels for the edges.  And the graph and parse tree in the Graph and Parse tabs of "reMatch":/tools/rematch both use WHATWG canvas for lines, but text for labels.  (These tabs are only visible in Firefox, for now.)

"TextCanvas.js":/sources/javascript/textcanvas.js implements the canvas context extended with labels, for DHTML.  And "textdrawview.lzx" implements drawview extended with labels.  They share the same API, so that I can write graphics libraries (such as graph drawing) that work with both DHTML and OpenLaszlo.  That API is described "here":/sources/javascript/textcanvas-api.]]></description>
			<content:encoded><![CDATA[<p>The two times that I&#8217;ve used the <span class="caps">WHATWG </span>canvas element recently, I&#8217;ve wanted a canvas with string rendering.  The most recent time that I&#8217;ve used the OpenLaszlo drawview class (which has substantially the same <span class="caps">API</span>), I&#8217;ve wanted string rendering too.</p>

<p>The graph in <a href="/tools/reanimator">reAnimator</a> is a drawview, but with text labels for the edges.  And the graph and parse tree in the Graph and Parse tabs of <a href="/tools/rematch">reMatch</a> both use <span class="caps">WHATWG </span>canvas for lines, but text for labels.  (These tabs are only visible in Firefox, for now.)</p>

<p><a href="/sources/javascript/textcanvas.js">TextCanvas.js</a> implements the canvas context extended with labels, for <span class="caps">DHTML. </span> And &#8220;textdrawview.lzx&#8221; implements drawview extended with labels.  They share the same <span class="caps">API, </span>so that I can write graphics libraries (such as graph drawing) that work with both <span class="caps">DHTML </span>and OpenLaszlo.  That <span class="caps">API </span>is described <a href="/sources/javascript/textcanvas-api">here</a>.</p>

<p>The first example below is an OpenLaszlo application that uses textdrawview; view source <a href="/sources/openlaszlo/textdrawview-example.lzx">here</a>.</p>

<p><object width="340" height="140" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"><param name="movie" value="/sources/openlaszlo/textdrawview-example.swf"><param name="quality" value="high"><param name="controller" value=""><embed src="/sources/openlaszlo/textdrawview-example.swf" width="340" height="140" quality="high" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></object></p>

<p>If you&#8217;re using Firefox, you can also view the <span class="caps">DHTML </span>example.  This uses TextCanvas; open it in a separate page <a href="/sources/javascript/textcanvas-example.html" target="_blank">here</a>.</p>

<p><iframe src="/sources/javascript/textcanvas-example.html?inline=true" width="340" height="140" style="border: 0" scrolling="no"></iframe></p>

<p>Files:<br />
* <a href="/sources/javascript/textcanvas.js">textcanvas.js</a> &#8212; <span class="caps">DHTML </span>implementation<br />
* <a href="/sources/javascript/textcanvas-example.html">textcanvas-example.html</a> &#8212; <span class="caps">DHTML </span>example (shown running above)<br />
* <a href="/sources/openlaszlo/textdrawview.lzx">textdrawview.lzx</a> &#8212; OpenLaszlo implementation<br />
* <a href="/sources/openlaszlo/textdrawview-example.lzx">textdrawview-example.lzx</a> &#8212; OpenLaszlo example (shown running above)<br />
* <a href="/sources/javascript/textcanvas-api">textcanvas-api</a> &#8212; <span class="caps">API </span>documentation</p>

<p>Some example code:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// &lt;div id=&quot;canvasContainer&quot;&gt;&lt;/div&gt;</span>
<span style="color: #003366; font-weight: bold;">var</span> container <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'canvasContainer'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> textCanvasController <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> TextCanvasController<span style="color: #009900;">&#40;</span>container<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> ctx <span style="color: #339933;">=</span> textCanvasController.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2d'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctx.<span style="color: #660066;">moveTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctx.<span style="color: #660066;">lineTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctx.<span style="color: #660066;">stringStyle</span>.<span style="color: #660066;">color</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'red'</span><span style="color: #339933;">;</span>
ctx.<span style="color: #660066;">drawString</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;red&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctx.<span style="color: #660066;">stringStyle</span>.<span style="color: #660066;">color</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'blue'</span><span style="color: #339933;">;</span>
ctx.<span style="color: #660066;">drawString</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;blue&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>
]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2006/02/textcanvas/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Javascript Beziers</title>
		<link>http://osteele.com/archives/2006/02/javascript-beziers</link>
		<comments>http://osteele.com/archives/2006/02/javascript-beziers#comments</comments>
		<pubDate>Mon, 27 Feb 2006 03:05:48 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://osteele.com/2006/02/27/javascript-beziers</guid>
		<description><![CDATA[The OpenLaszlo application below demonstrates animation along a line, a quadratic Bezier, and a cubic Bezier (the top three paths).  It also demonstrates (the bottom path) animation along a path composed of multiple segments.

<wp:flash src="/sources/javascript/bezier-demo.swf" width="320" height="300" style="border: 0"/>

Drag the slider back and forth to display the point on each path at <var>t</var>=<var>slider.value</var>/100, or click the "Animate" button to animate <var>t</var> from 0 to 1.

I wrote this in order to animate the state markers along the edges of the graph in <a href="/tools/reanimator">reAnimator</a>.  The GraphViz dot tool, which I'm using for graph layout, generates cubic beziers, so I had to write code to render and evaluate them.]]></description>
			<content:encoded><![CDATA[<p>The OpenLaszlo application below demonstrates animation along a line, a quadratic Bezier, and a cubic Bezier (the top three paths).  It also demonstrates (the bottom path) animation along a path composed of multiple segments.</p>

<p><object width="320" height="300" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"><param name="movie" value="/sources/javascript/bezier-demo.swf"><param name="quality" value="high"><param name="controller" value=""><embed src="/sources/javascript/bezier-demo.swf" width="320" height="300" quality="high" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></object></p>

<p>Drag the slider back and forth to display the point on each path at <var>t</var>=<var>slider.value</var>/100, or click the &#8220;Animate&#8221; button to animate <var>t</var> from 0 to 1.</p>

<p>I wrote this in order to animate the state markers along the edges of the graph in <a href="/tools/reanimator">reAnimator</a>.  The GraphViz dot tool, which I&#8217;m using for graph layout, generates cubic beziers, so I had to write code to render and evaluate them.</p>

<p>If you&#8217;re writing for <strike>FireFox</strike> <ins>a Browser that supports the canvas</ins> element, you can use the same code with the new <span class="caps">HTML </span><tt>canvas</tt> element.   Click on &#8220;Start Animation&#8221; to animate the points on the canvas below.  And click <a href="/sources/javascript/bezier-demo.html" target="_blank">here</a> to open the <span class="caps">HTML </span>applet in its own window.</p>

<p><iframe src="/sources/javascript/bezier-demo.html?inline=true" width="315" height="300" style="border: 0" scrolling="no"></iframe></p>

<p>Files:<br />
* <a href="/sources/javascript/bezier.js">bezier.js</a> &#8212; measurement, interpolation, sampling, and subdivision for arbitrary-order Beziers<br />
* <a href="/sources/javascript/path.js">path.js</a> &#8212; measurement, interpolation, and sampling for paths composed of multiple lines and Beziers<br />
* <a href="/sources/javascript/bezier-demo.js">bezier-demo.js</a> &#8212; the code to draw the paths in the demo.  This is platform-agnostic, and works in OpenLaszlo (bezier-demo.lzx) and <span class="caps">HTML </span>(bezier-demo.html).<br />
* <a href="/sources/javascript/bezier-demo.lzx">bezier-demo.lzx</a> &#8212; the OpenLaszlo demo<br />
* <a href="/sources/javascript/bezier-demo.html">bezier-demo.html</a> &#8212; the <span class="caps">HTML </span>demo<br />
* <a href="/sources/openlaszlo/drawview-patches.js">drawview-patches.js</a> &#8212; patches to the OpenLaszlo <tt>LzDrawView</tt>.  This includes an implementation of <tt>LzDrawView.bezierCurveTo</tt>.</p>

<p>A couple of caveats:<br />
* This animates along the Bezier parameterization, not the path length.  This was good enough for my application, but you could get animation that speeds up and slows down, depending on how you choose your control points.<br />
* <strike>The demo code is written for brevity, not speed.  In particular, it re-renders the background each time, which involves some expensive math to render the cubic.  In reAnimator, I placed the animated elements on a separate view in front of the background.  I didn&#8217;t do that here because I wanted to share code between the OpenLaszlo and <span class="caps">HTML </span>demos, and the techniques for doing overlays were too different.</strike><ins>Using a separate overlay for the background didn&#8217;t actually speed this up.  The hot spot is the parametric position calculation.</ins></p>

<p class="footnote" id="fn1"><sup>1</sup> I think the reason the code doesn&#8217;t work in Safari is that <tt>Bezier.draw</tt> uses the <tt>Function.apply</tt> method to apply methods on the graphics context, such as <tt>quadraticCurveTo</tt>, to argument lists.  It looks like Safari doesn&#8217;t implement <tt>apply</tt> when the function is a native method.  <strike>I didn&#8217;t try to work around this because in cases where I&#8217;ve actually tried to <strong>use</strong> <tt>canvas</tt> (such as the &#8220;Parse&#8221; and &#8220;Graph&#8221; tab in <a href="/tools/rework">reWork</a>), there were other problems with Safari anyway.</strike></p>

<p><strong>Update</strong>: The inline examples weren&#8217;t showing up.  Thanks to Bret Victor for both finding and diagnosing the problem.  (I was linking to my laptop, osteele.dev.  The post looked fine from my laptop!)</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2006/02/javascript-beziers/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>JSON for OpenLaszlo</title>
		<link>http://osteele.com/archives/2006/02/json-for-openlaszlo</link>
		<comments>http://osteele.com/archives/2006/02/json-for-openlaszlo#comments</comments>
		<pubDate>Mon, 20 Feb 2006 17:43:40 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://osteele.com/2006/02/20/json-for-openlaszlo</guid>
		<description><![CDATA["JSON for OpenLaszlo":/sources/openlaszlo/json/ is a "JSON":http://www.json.org/ library for OpenLaszlo.

I wrote this in order to implement my <a href="/tools/reanimator">regular expression visualizer</a>.

There's a live example below.  Clicking on a button requests some JSON text from the server and parses it on the client.  The source code to the example is <a href="sources/openlaszlo/json/json-example.lzx">here</a>.

<wp:flash src="http://osteele.com/sources/openlaszlo/json/json-example.swf" width="300" height="300"/>

(When it runs off my web site, the debugger in the example displays a warning about not being able to connect to the LPS server.  This means that the debugger can't evaluate expressions, as it could if you were running it off the SDK.  I'm just using the debugger here to print inspectable representations of the JSON parse results, and the warning doesn't affect this.)]]></description>
			<content:encoded><![CDATA[<p><a href="/sources/openlaszlo/json/"><span class="caps">JSON </span>for OpenLaszlo</a> is a <a href="http://www.json.org/"><span class="caps">JSON</span></a> library for OpenLaszlo.</p>

<p>I wrote this in order to implement my <a href="/tools/reanimator">regular expression visualizer</a>.</p>

<p>There&#8217;s a live example below.  Clicking on a button requests some <span class="caps">JSON </span>text from the server and parses it on the client.  The source code to the example is <a href="sources/openlaszlo/json/json-example.lzx">here</a>.</p>

<p><object width="300" height="300" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"><param name="movie" value="http://osteele.com/sources/openlaszlo/json/json-example.swf"><param name="quality" value="high"><param name="controller" value=""><embed src="http://osteele.com/sources/openlaszlo/json/json-example.swf" width="300" height="300" quality="high" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></object></p>

<p>(When it runs off my web site, the debugger in the example displays a warning about not being able to connect to the <span class="caps">LPS </span>server.  This means that the debugger can&#8217;t evaluate expressions, as it could if you were running it off the <span class="caps">SDK. </span> I&#8217;m just using the debugger here to print inspectable representations of the <span class="caps">JSON </span>parse results, and the warning doesn&#8217;t affect this.)</p>

<h3>Rationale</h3>

<p>OpenLaszlo implements most of JavaScript 1.5 (ECMAScript 3), but it&#8217;s missing regular expressions and <tt>throw</tt>/<tt>catch</tt>, so it can&#8217;t run <a href="http://www.json.org/js.html"><span class="caps">JSON </span>in JavaScript</a>.  And the OpenLaszlo compiler doesn&#8217;t (yet) implement the proposed JavaScript 2.0 (ECMAScript 4) extensions such as <tt>class</tt> and type declarations, so <a href="http://www.theorganization.net/work/jos/JSON.as"><span class="caps">JSON </span>in ActionScript</a> doesn&#8217;t work either.  Hence, this implementation, which doesn&#8217;t require either regular expressions or JavaScript 2.0 extensions.</p>

<p>It&#8217;s open source, of course.  (MIT License.)</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2006/02/json-for-openlaszlo/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Visualizing Regular Expressions</title>
		<link>http://osteele.com/archives/2006/02/reanimator</link>
		<comments>http://osteele.com/archives/2006/02/reanimator#comments</comments>
		<pubDate>Sun, 19 Feb 2006 21:50:19 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Visualizations]]></category>

		<guid isPermaLink="false">http://osteele.com/2006/02/19/visualizing-regular-expressions</guid>
		<description><![CDATA[<a style="float:right" href="/tools/reanimator"><img src="/images/2006/rematch-small.png"></a>

Here's something I've wanted for a long time.  So I finally <a href="/tools/reanimator">built it</a>.  "reAnimator":/tools/reanimator is a tool for visualizing how "regular expression":http://en.wikipedia.org/wiki/Regular_expression engines use "finite-state automata":http://en.wikipedia.org/wiki/Finite_state_automaton to match regular regular expression patterns against text.

This is intended to demonstrate the <em> implementation</em> of regular expressions.  If you want to learn <em>how to use them</em> instead, I recommend these references instead:]]></description>
			<content:encoded><![CDATA[<p><a style="float:right" href="/tools/reanimator"><img src="/images/2006/rematch-small.png" /></a></p>

<p>Here&#8217;s something I&#8217;ve wanted for a long time.  So I finally <a href="/tools/reanimator">built it</a>.  <a href="/tools/reanimator">reAnimator</a> is a tool for visualizing how <a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a> engines use <a href="http://en.wikipedia.org/wiki/Finite_state_automaton">finite-state automata</a> to match regular regular expression patterns against text.</p>

<p>This is intended to demonstrate the <em> implementation</em> of regular expressions.  If you want to learn <em>how to use them</em> instead, I recommend these references instead:<br />
* <a href="http://www.regular-expressions.info/">Regular-Expressions.info</a><br />
* <span class="caps">A.M.</span> Kuchling&#8217;s <a href="http://www.amk.ca/python/howto/regex/">Regular Expression <span class="caps">HOWTO</span></a><br />
* Steve Mansour <a href="http://sitescooper.org/tao_regexps.html">A Tao of Regular Expressions</a><br />
* Jeffrey Friedl&#8217;s <a href="http://www.amazon.com/gp/product/oliversteele-20/0596002890" title="Amazon">Mastering Regular Expressions</a><br />
* The Regular Expression Library&#8217;s <a href="http://www.regexlib.com/Resources.aspx">list of resources</a><br />
* <ins><strong>New</strong> My own <a href="/tools/rework">reWork</a> online regular expression workbench.</ins></p>

<h3>The User Interface</h3>

<p>The screen has these areas:</p>

<h4>The Pattern</h4>

<p>The &#8220;pattern&#8221; shows the regular expression.  Click on it to set another regular expression to match against.</p>

<p><object width="377" height="46" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="http://osteele.com/images/2006/rematch/pattern.mov"><param name="controller" value="1"><embed src="http://osteele.com/images/2006/rematch/pattern.mov" width="377" height="46" controller="1" pluginspage="http://www.apple.com/quicktime/download/"></object></p>

<h4>The Input</h4>

<p>The &#8220;input&#8221; is the string that is matched.  As you type into the input string, the color of this string indicates whether it&#8217;s a complete match (green), a partial match (blue), or a non-match (red).</p>

<p><object width="377" height="54" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="/images/2006/rematch/input.mov"><param name="controller" value="1"><embed src="/images/2006/rematch/input.mov" width="377" height="54" controller="1" pluginspage="http://www.apple.com/quicktime/download/"></object></p>

<h4>The Graphs</h4>

<p>There are two graphs, which each display a <dfn>finite-state automaton</dfn> (FSA) that corresponds to the regular expression in the &#8220;pattern&#8221; area.  As you type into the &#8220;input&#8221; area, the graphs also update, to display the state of the match.</p>

<p>A <dfn><strong>deterministic <span class="caps">FSA</span></strong></dfn> (a <span class="caps">DFA</span>) is like a board game, with a counter that is moved according to the successive letters of the input string.  The counter starts at the initial state (the leftmost circle with the arrow from off the board).  Each consecutive letter of the input string tells where to move the counter to next.  If the counter ends up in a terminal state (a double circle), there was a match.</p>

<p><object width="309" height="248" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="/images/2006/rematch/dfa.mov"><param name="controller" value="1"><embed src="/images/2006/rematch/dfa.mov" width="309" height="248" controller="1" pluginspage="http://www.apple.com/quicktime/download/"></object></p>

<p>A <dfn><strong>nondeterministic <span class="caps">FSA</span></strong></dfn> is the same except that when there&#8217;s more than one legal move, you take them both.</p>

<p><object width="222" height="250" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="/images/2006/rematch/nfa.mov"><param name="controller" value="1"><embed src="/images/2006/rematch/nfa.mov" width="222" height="250" controller="1" pluginspage="http://www.apple.com/quicktime/download/"></object></p>

<p>The nondeterministic <span class="caps">FSA </span>bears the most direct resemblance to the regular expression.  In exchange for this simplicity in its <strong>construction</strong>, it&#8217;s more complex to <strong>evaluate</strong>: instead of keeping track of just one counter, you have to keep track of a set of them.  (This is an instance of the compile-time versus execution-time trade-offs that computer science is rife with.)</p>

<p>If you want to learn more about finite-state automata, the <a href="http://en.wikipedia.org/wiki/Finite_state_automaton">wikipedia entry</a> has some useful information, but this also seems like a good place to plug my <a href="http://www.amazon.com/gp/product/oliversteele-20/0131655639/">father-in-law&#8217;s book</a>.</p>

<h3>Implementation details</h3>

<p><img src="/images/2006/rematch-architecture.png" alt="" height="358" width="517" /></p>

<p>The front end is written in <a href="http://www.openlaszlo.org">OpenLaszlo</a>, and compiled to Flash.  It uses <span class="caps">AJAX </span>and <span class="caps">JSON </span>to request the <span class="caps">FSA</span>s and the graphs.</p>

<p>The back end is written in Python and C.  The Python part is my <a href="http://osteele.com/software/python/fsa/">PyFSA</a> library, plus a bit of glue to turn various JavaScript objects and graph files into <span class="caps">JSON </span>strings.  There&#8217;s also a cache so that my shared server doesn&#8217;t get quite so stressed even if the site becomes popular.  (Having the front end logic on the client should help here too.)</p>

<p>The C portion is the wonderful <a href="http://http://www.graphviz.org">GraphViz</a>.  PyFSA creates a .dot file for each <span class="caps">FSA, </span>and uses GraphViz to lay out the graph.  The server parses the annotated .dot file into a JavaScript object, and uses <span class="caps">JSON </span>to download the resulting graph to the client.</p>

<p>An OpenLaszlo class on the client interprets the JavaScript graph description into a sequence of drawing instructions.  It also saves the node positions, so that it can animate against them.</p>

<p><strong>Update</strong>: Some of the support libraries are now available as open source.  See <a href="/archives/2006/02/json-for-openlaszlo"><span class="caps">JSON </span>for OpenLaszlo</a>, <a href="/archives/2006/02/javascript-beziers">JavaScript Beziers</a>, and <a href="/archives/2006/02/textcanvas">Canvas with Text</a>.  <a href="http://www.openlaszlo.org">OpenLaszlo</a> and <a href="/software/python/fsa/">PyFSA</a> were available previously.</p>

<h4>Implementation choices</h4>

<p><b>Client vs. server</b>: There&#8217;s no reason that this couldn&#8217;t be a client-side-only application.  I just happened to have PyFSA lying around, and didn&#8217;t feel like porting it to JavaScript.  My goal for this was one day of implementation time, and I didn&#8217;t think porting PyFSA would fit into this.  (It ended up taking three days anyway, because I forgot about implementing cubic beziers and <span class="caps">JSON, </span>and because I got carried away and added animation.)</p>

<p><b><span class="caps">CGI </span>vs. FastCGI</b>: I&#8217;ve been doing most of my server-side programming with either <span class="caps">PHP </span>or FastCGI and Ruby, so that pages don&#8217;t take so long to serve.  This is the first Python service I&#8217;ve deployed since I started using FastCGI, and I was planning to use it.  <strike>But Python doesn&#8217;t include FastCGI in its library, and the fact that there were four different third-party libraries with different <span class="caps">API</span>s, none of them endorsed, and that the <a href="http://www.python.org/peps/pep-0222.html">latest <span class="caps">PEP </span>to mention FastCGI</a> was deferred five years ago, made me unwilling to take on the project of evaluating them.</strike><ins>I&#8217;m glad to hear that I was completely off base about Python and FastCGI.  See Phillip J. Eby&#8217;s comment below.</ins>  I stuck with <span class="caps">CGI, </span>which is in the standard library.</p>

<p><b>OpenLaszlo vs. <span class="caps">DHTML</span></b>: It would be just as easy to draw the graph itself using the <a href="http://www.whatwg.org/specs/web-apps/current-work/#scs-dynamic">canvas class</a> in <span class="caps">DHTML. </span> I balked at doing the animation and user interface in <span class="caps">DHTML, </span>though.  (There&#8217;s little touches like laying the graphs out horizontally only if there&#8217;s enough room, which were only a few lines of declarative code in OpenLaszlo.)  And then it wouldn&#8217;t have worked on as many browsers.  I decided to wait until <a href="http://wiki.openlaszlo.org/DHTML_Target">OpenLaszlo compiles to <span class="caps">DHTML</span></a>, for a <span class="caps">DHTML </span>version of this.</p>

<p><b>PyFSA vs. &Atilde;&cent;&acirc;‚&not;&Acirc;&brvbar;</b>: Higher-performance &#169; implementations of <span class="caps">FSA </span>minimization and determinization exist.  I went with my own because it&#8217;s the only one I know of that has the option of preserving source location information across transformations.  I use source location information minimally in the interface, and might add more.</p>

<h3>Credits</h3>

<p>Thanks to Margaret Minsky and Gary Drescher for commenting on a draft of the application.  I used Patrick Logan&#8217;s <a href="http://sourceforge.net/projects/json-py/">json-py</a> for server-side <span class="caps">JSON. </span> The credits for <a href="http://www.graphviz.org/">GraphViz</a> are <a href="http://www.graphviz.org/Credits.php">here</a>.  Thanks to my former colleages at <a href="http://openlaszlo.org">Laszlo Systems, Inc.</a> for helping create the <a href="http://openlaszlo.org">OpenLaszlo</a> platform.  I adapted Philip J. Scheider&#8217;s code for subdividing cubic beziers; this is a compact implementation of <a href="http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm">de Casteljau&#8217;s algorithm</a> for Algol-like languages.  Thanks to Guido and company for Python.  Lastly, since people always ask, I drew the architecture diagram with <a href="http://www.omnigroup.com/applications/omnigraffle/">Omigraffle</a> (gee I wish I got a commission!) &#8212; which I like because I&#8217;m not much of a designer, and diagrams I draw with it are passable without much work.</p>

<p><strong>Update</strong>: I changed the name to reAnimator.  (It was reMatch.)  Thanks to Apache RewriteRule for letting me do this without breaking the old <span class="caps">URL</span>s!</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2006/02/reanimator/feed</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Visualizing Subversion Project Activity</title>
		<link>http://osteele.com/archives/2006/01/visualizing-project-activity</link>
		<comments>http://osteele.com/archives/2006/01/visualizing-project-activity#comments</comments>
		<pubDate>Wed, 01 Feb 2006 04:00:01 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Visualizations]]></category>

		<guid isPermaLink="false">http://osteele.com/2006/02/01/visualizing-subversion-project-activity</guid>
		<description><![CDATA[Last week I wrote a couple of tools to keep track of "subversion":http://subversion.tigris.org/ checkins:

<a href="/tools/svn2ics" style="float:right"><img src="/projects/images/svn2ics-thumb.png"></a>

The "Subversion Log Viewer":/tools/svn-viewer is a master-detail list of recent subversion revisions.  It's based on the OpenLaszlo "contactlist":http://www.laszlosystems.com/lps/examples/contactlist/contactlist.lzx example.  The nicest feature is really an afterthought: at the last moment, I added faces for authors; I think this makes projects a lot friendlier.  Right now it only adds the faces to the "OpenLaszlo":http://openlaszlo.org log; let me know if you're interested in using this for your own project, and I'll make a public API for adding faces to a repository.]]></description>
			<content:encoded><![CDATA[<p>Last week I wrote a couple of tools to keep track of <a href="http://subversion.tigris.org/">subversion</a> checkins:</p>

<p><a href="/tools/svn2ics" style="float:right"><img src="/projects/images/svn2ics-thumb.png" /></a></p>

<p>The <a href="/tools/svn-viewer">Subversion Log Viewer</a> is a master-detail list of recent subversion revisions.  It&#8217;s based on the OpenLaszlo <a href="http://www.laszlosystems.com/lps/examples/contactlist/contactlist.lzx">contactlist</a> example.  The nicest feature is really an afterthought: at the last moment, I added faces for authors; I think this makes projects a lot friendlier.  Right now it only adds the faces to the <a href="http://openlaszlo.org">OpenLaszlo</a> log; let me know if you&#8217;re interested in using this for your own project, and I&#8217;ll make a public <span class="caps">API </span>for adding faces to a repository.</p>

<p><a href="/tools/svn-viewer" style="float:right"><img src="/projects/images/svn-viewer-thumb.png" /></a></p>

<p>The <a href="/tools/svn2ics">Subversion iCalendar Gateway</a> transcodes subversion logs into iCalendar files, that you can subscribe to with Apple iCal or Mozilla Sunbird.  I find it useful for a projects that I want to check in on occasionally.  Unlike an <span class="caps">RSS </span>feed, it gives you a sense of the activity level and the change frequency, at least if you&#8217;re a spatial person like me.</p>

<p>Both of these point at the <a href="http://openlaszlo.org">OpenLaszlo</a> log by default, but they&#8217;ve got a UI for putting in any subversion repository (<tt>http:</tt> or <tt>svn:</tt> protocol only), and generating a permalink for that repository.</p>

<p>One caveat:  It takes a long time to request a complete subversion log, so the iCalendar gateway only requests the first 500 revisions the first time you (or anyone) view a given calendar, and then the next time anyone or refreshes the same calendar, it catches up to the present 500 revisions at time.</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2006/01/visualizing-project-activity/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Expialidocio.us</title>
		<link>http://osteele.com/archives/2006/01/expialidocious</link>
		<comments>http://osteele.com/archives/2006/01/expialidocious#comments</comments>
		<pubDate>Sun, 08 Jan 2006 14:14:41 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Visualizations]]></category>

		<guid isPermaLink="false">http://osteele.com/2006/01/08/expialidocious</guid>
		<description><![CDATA[<a href="http://expialidocio.us"><img src="/projects/images/expialidocious-graphics-thumb.png" style="float:right"/></a>

"Expialidocio.us":http://expialidocio.us is a tool for visualizing your "del.icio.us":http://del.icio.us posting activity.  It displays a graph of your posting activity over time.  You can select a timespan from this graph, and it will show you a tag cloud weighted by just those dates.

Expialidocio.us was inspired by a <a href="http://weblog.infoworld.com/udell/2005/12/20.html#a1357">posting by Jon Udell</a>.  Coming full circle, Udell has "posted":http://weblog.infoworld.com/udell/2006/01/05.html#a1364 since posted about this application.]]></description>
			<content:encoded><![CDATA[<p><a href="http://expialidocio.us"><img src="/projects/images/expialidocious-graphics-thumb.png" style="float:right"/></a></p>

<p><a href="http://expialidocio.us">Expialidocio.us</a> is a tool for visualizing your <a href="http://del.icio.us">del.icio.us</a> posting activity.  It displays a graph of your posting activity over time.  You can select a timespan from this graph, and it will show you a tag cloud weighted by just those dates.</p>

<p>Expialidocio.us was inspired by a <a href="http://weblog.infoworld.com/udell/2005/12/20.html#a1357">posting by Jon Udell</a>.  Coming full circle, Udell has <a href="http://weblog.infoworld.com/udell/2006/01/05.html#a1364">posted</a> since posted about this application.  Since then, I&#8217;ve published the <a href="http://expialidocio.us">sources</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2006/01/expialidocious/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OpenLaszlo Ruby library</title>
		<link>http://osteele.com/archives/2006/01/openlaszlo-ruby-library</link>
		<comments>http://osteele.com/archives/2006/01/openlaszlo-ruby-library#comments</comments>
		<pubDate>Thu, 05 Jan 2006 19:40:44 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Libraries]]></category>
		<category><![CDATA[OpenLaszlo]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://osteele.com/2006/01/05/openlaszlo-ruby-library</guid>
		<description><![CDATA[<a href="/sources/ruby/openlaszlo">openlaszlo.rb</a> is a Ruby library for compiling <a href="http://openlaszlo.org">OpenLaszlo</a> programs.  I use it to build <a href="/words">this</a>, <a href="http://expialidocio.us">this</a>, and the toolbar <a href="/projects">here</a>.  <a href="http://weblog.openlaszlo.org/archives/2006/01/deploying-openlaszlo-applications-with-rake/">This article</a> describes how to use it with <a href="http://www.martinfowler.com/articles/rake.html">Rake</a>.

<strong>Update:</strong>  This is now available as a <a href="http://rubyforge.org/ropenlaszlo">gem</a>. ]]></description>
			<content:encoded><![CDATA[<p><a href="/sources/ruby/openlaszlo">openlaszlo.rb</a> is a Ruby library for compiling <a href="http://openlaszlo.org">OpenLaszlo</a> programs.  I use it to build <a href="/words">this</a>, <a href="http://expialidocio.us">this</a>, and the toolbar <a href="/projects">here</a>.  <a href="http://weblog.openlaszlo.org/archives/2006/01/deploying-openlaszlo-applications-with-rake/">This article</a> describes how to use it with <a href="http://www.martinfowler.com/articles/rake.html">Rake</a>.</p>

<p><strong>Update:</strong>  This is now available as a <a href="http://rubyforge.org/ropenlaszlo">gem</a>.  The rdocs are <a href="http://ropenlaszlo.rubyforge.org">here</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2006/01/openlaszlo-ruby-library/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenLaszlo Blog</title>
		<link>http://osteele.com/archives/2005/11/openlaszlo-blog</link>
		<comments>http://osteele.com/archives/2005/11/openlaszlo-blog#comments</comments>
		<pubDate>Sat, 12 Nov 2005 00:33:28 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[OpenLaszlo]]></category>

		<guid isPermaLink="false">http://osteele.com/2005/11/11/openlaszlo-blog</guid>
		<description><![CDATA[It was months in the conception, weeks in the making, and minutes in the configuration, but the OpenLaszlo project now has a <a href="http://weblog.openlaszlo.org">blog</a>. Ă‚Â That blog is intended for project-related news, announcements, documentation, and musings, posted by members of the OpenLaszlo project and some of our co-workers at Laszlo Systems.  And I'll be returning this blog to more personal and broader topics.  (Those are two overlapping categories, not one.)  Plenty of Laszlo and RIA stuff where it goes beyond the immediate project work, but more other topics too.

On a related topic, Laszlo Systems has launched Laszlo Mail, a high-polish web mail product focused on cross-browser portability and on user experience .  I first wrote about Laszlo Mail <a href="http://osteele.com/archives/2005/03/laszlo-mail">here</a>.  Laszlo Mail is an excellent example of the kind of application that we created OpenLaszlo in order to enable.Ă‚Â  As Jonathan Boutelle saysĂ‚Â <http://www.jonathanboutelle.com/mt/archives/2005/11/laszlomail_serv.html>:" It feels like a candy-coated swiss army knife, an appealing mix of aesthetics and pragmatic design."]]></description>
			<content:encoded><![CDATA[<p>It was months in the conception, weeks in the making, and minutes in the configuration, but the OpenLaszlo project now has a <a href="http://weblog.openlaszlo.org">blog</a>. &Atilde;‚&Acirc;&nbsp;That blog is intended for project-related news, announcements, documentation, and musings, posted by members of the OpenLaszlo project and some of our co-workers at Laszlo Systems.  And I&#8217;ll be returning this blog to more personal and broader topics.  (Those are two overlapping categories, not one.)  Plenty of Laszlo and <span class="caps">RIA </span>stuff where it goes beyond the immediate project work, but more other topics too.</p>

<p>On a related topic, Laszlo Systems has launched Laszlo Mail, a high-polish web mail product focused on cross-browser portability and on user experience .  I first wrote about Laszlo Mail <a href="http://osteele.com/archives/2005/03/laszlo-mail">here</a>.  Laszlo Mail is an excellent example of the kind of application that we created OpenLaszlo in order to enable.&Atilde;‚&Acirc;&nbsp; As Jonathan Boutelle says&Atilde;‚&Acirc;&nbsp;<http://www.jonathanboutelle.com/mt/archives/2005/11/laszlomail_serv.html>:&#8221; It feels like a candy-coated swiss army knife, an appealing mix of aesthetics and pragmatic design.&#8221;</p>

<p>Congratulations to the Laszlo Mail team on getting this done.  The Laszlo Mail team has a blog too, <a href="http://www.laszlomail.com/blog">here</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://osteele.com/archives/2005/11/openlaszlo-blog/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
