<?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>mindtrove &#187; Programming</title>
	<atom:link href="http://mindtrove.info/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://mindtrove.info</link>
	<description>Collecting ideas since 1980</description>
	<lastBuildDate>Thu, 01 Jul 2010 01:58:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Buildbot Button Chrome Extension</title>
		<link>http://mindtrove.info/buildbot-button-chrome-extension/</link>
		<comments>http://mindtrove.info/buildbot-button-chrome-extension/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 01:58:05 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[buildbot]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=324</guid>
		<description><![CDATA[To learn about Chrome extensions, I wrote a little ditty that gives a glimpse of the status of all builders on a Buildbot server. The server must be v0.8 or higher as the extension relies on the new JSON REST API. The button icon in the Chrome toolbar reflects if a build is running or [...]]]></description>
			<content:encoded><![CDATA[<p>To learn about Chrome extensions, I wrote a little ditty that gives a glimpse of the status of all builders on a <a href="http://buildbot.net">Buildbot</a> server. The server must be v0.8 or higher as the extension relies on the new JSON REST API.</p>
<p><img src="http://chrome.google.com/extensions/img/jkmacffhadpleaekipbokncalkokenpk/1277948372.32/screenshot_big/1?hl=en" alt="Buildbot extension popup screenshot" /></p>
<p>The button icon in the Chrome toolbar reflects if a build is running or not, and indicates the number of builders that failed the last time they ran. Clicking the button reveals a popup showing details about builders, builds, and build steps. Almost everything is a link leading to buildbot web status pages with additional info. There's also optional audio icons that indicate if a build is starting, has succeeded, or has failed.</p>
<p>The extension satisfies my needs, but is far from perfect. For example, if the server has a large number of builders, the XHR fetch for all the builder info can fail because the URL is too long. Likewise, the popup can grow too large to be useful. I've <a href="http://github.com/parente/bbb">open sourced the code on GitHub</a> so anyone interested can contribute patches or fork.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/buildbot-button-chrome-extension/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSonic: Speech and sound using HTML5</title>
		<link>http://mindtrove.info/jsonic-speech-and-sound-using-html5/</link>
		<comments>http://mindtrove.info/jsonic-speech-and-sound-using-html5/#comments</comments>
		<pubDate>Tue, 11 May 2010 02:37:23 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[jsonic]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[speech]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=318</guid>
		<description><![CDATA[I've released a new library called JSonic for text-to-speech synthesis and sound playback in browsers supporting HTML5 &#60;audio&#62;. The code is on GitHub along with full documentation of the JS and REST APIs. The client API is implemented as a Dojo dijit._Widget subclass. Other client implementations are possible as long as they provide the same [...]]]></description>
			<content:encoded><![CDATA[<p>I've released a new library called JSonic for text-to-speech synthesis and sound playback in browsers supporting HTML5 &lt;audio&gt;. The code is on <a href="http://github.com/parente/jsonic">GitHub</a> along with <a href="http://parente.github.com/jsonic">full documentation</a> of the JS and REST APIs.</p>
<p>The client API is implemented as a Dojo dijit._Widget subclass. Other client implementations are possible as long as they provide the same JS interface. The TTS synthesis is implemented server-side using <a href="http://espeak.sourceforge.net/">espeak</a> and <a href="http://www.tornadoweb.org/">Tornado</a>. Other server implementations are possible as long as they adhere to the REST API, and other speech engines can be plugged in rather easily.</p>
<p>The <a href="http://sites.google.com/site/uncopenweb/">UNC Open Web group</a> is looking to use JSonic to build self-voicing web games for kids with disabilities. I've already ported my <a href="http://mindtrove.info/spaceship">Spaceship!</a> game (<a href="http://github.com/parente/spaceship">also available on GitHub</a>) to use it instead of Outfox, and hope deploy it somewhere in the near future.</p>
<p>Bug reports, bug fixes, comments, questions, uses, and so on are welcome. Please use the issue tracker on the GitHub project page when reporting bugs.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/jsonic-speech-and-sound-using-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 audio caching</title>
		<link>http://mindtrove.info/html5-audio-caching/</link>
		<comments>http://mindtrove.info/html5-audio-caching/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 00:36:11 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[jsonic]]></category>
		<category><![CDATA[speech]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=284</guid>
		<description><![CDATA[One of my latest coding endeavors is a text-to-speech interface for JavaScript using HTML5 &#60;audio&#62; elements to output synthesized speech from a server. To reduce the latency between a speech request and actual speech output, I'm using various levels of caching. One of these is the regular browser disk cache based on HTTP headers. It [...]]]></description>
			<content:encoded><![CDATA[<p>One of my latest coding endeavors is a <a href="http://github.com/parente/jsonic">text-to-speech interface for JavaScript</a> using HTML5 &lt;audio&gt; elements to output synthesized speech from a server. To reduce the latency between a speech request and actual speech output, I'm using various levels of caching. One of these is the regular browser disk cache based on HTTP headers.</p>
<p>It turns out that browser caching behavior for &lt;audio&gt; data varies wildly among browsers. The following table shows the HTML5 &lt;audio&gt; caching behavior of various browsers. I tested all of them on OS X 10.6 with the standard Mac Apache server hosting all of the tested audio files.</p>
<table>
<thead>
<tr>
<th>Browser</th>
<th>&lt;audio&gt; Behavior</th>
</tr>
</thead>
<tbody>
<tr>
<td>Firefox 3.6</td>
<td>Respects cache headers for the sound data. Only contacts the server when the cache item expires. &lt;audio&gt; elements pointing to the same <code>src</code> reuse the cache data.</td>
</tr>
<tr>
<td>Chrome 5.0.322.2</td>
<td>Contacts the server on every <code>load()</code>. When it receives a 304 response, does not refetch content.*</td>
</tr>
<tr>
<td>Safari 4.0.4</td>
<td>Contacts the server to fetch first two bytes of the audio file on every <code>load()</code>. Receives a 206 response with partial content. Fetches the additional bytes from the file. Receives another 206 response with the partial content. Performs another fetch and receives a 304 response with no data. Continues to alternate between fetches that receive 206 partial data responses and 304 not modified responses. Nothing appears to get cached.</td>
</tr>
<tr>
<td>Webkit r54921</td>
<td>Same behavior as Safari 4.0.4.</td>
</tr>
</tbody>
</table>
<p><span style="font-size: smaller;">* Though not cache related, audio output in Chrome is often clipped before the end of the actual audio data. When this occurs, Chrome fires the <code>onended</code> event even before the audible output finishes.</span> </p>
<p>Except for Firefox 3.6, all of these browsers seem to exhibit pretty terrible caching behavior when it comes to audio. I've reported bugs where I thought appropriate, but maybe I'm missing something. Am I supposed to include additional headers in the server-side response? Or maybe I'm glossing over some key part of the &lt;audio&gt; API? If so, please let me know. If not, yikes: &lt;audio&gt; support has definite room for improvement.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/html5-audio-caching/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Ken Burns Effect in Dojo</title>
		<link>http://mindtrove.info/ken-burns-effect-in-dojo/</link>
		<comments>http://mindtrove.info/ken-burns-effect-in-dojo/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 03:00:45 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[demos]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=261</guid>
		<description><![CDATA[I saw a reference to the jQuery CrossSlide plug-in many moons ago. For some dojo.anim practice, I decided to implement its Ken Burns effect in a reusable Dojo widget a few days later. The code then collected dust in my Dropbox until today when I finally got around to sharing it. Below is an example [...]]]></description>
			<content:encoded><![CDATA[<p>I saw a reference to the <a href="http://www.gruppo4.com/~tobia/cross-slide.shtml">jQuery CrossSlide plug-in</a> many moons ago. For some <a href="http://docs.dojocampus.org/quickstart/Animation">dojo.anim</a> practice, I decided to implement its <a href="http://en.wikipedia.org/wiki/Ken_Burns_Effect">Ken Burns</a> effect in a reusable Dojo widget a few days later. The code then collected dust in my <a href="https://www.dropbox.com/referrals/NTI2NDI0MTk">Dropbox</a> until today when I finally got around to sharing it.</p>
<p>Below is an example instance of the widget panning, zooming, and crossfading three images. The BSD code for the widget is in <a href="http://github.com/parente/mindtrove/blob/master/KenBurns.js">KenBurns.js</a>. The code for this particular demo can be seen by viewing the source of <a href="/html/kenburns-demo.html">kenburns-demo.html</a>.</p>
<p>I didn't take the time to comment this little experiment. If you'd like more info about how to use it or how it works, drop me a comment. </p>
<p><iframe src="/html/kenburns-demo.html" style="width: 450px; height: 400px"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/ken-burns-effect-in-dojo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Spaceship! code at GitHub</title>
		<link>http://mindtrove.info/spaceship-code-at-github/</link>
		<comments>http://mindtrove.info/spaceship-code-at-github/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 02:42:22 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[spaceship]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=258</guid>
		<description><![CDATA[I cloned the code for Spaceship! at GitHub to facilitate easier development by anyone interested. I'll push any future improvements I make there and consider my personal subversion repository dead. http://github.com/parente/spaceship]]></description>
			<content:encoded><![CDATA[<p>I cloned the code for Spaceship! at GitHub to facilitate easier development by anyone interested. I'll push any future improvements I make there and consider my personal subversion repository dead.</p>
<p><a href="http://github.com/parente/spaceship">http://github.com/parente/spaceship</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/spaceship-code-at-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pyttsx</title>
		<link>http://mindtrove.info/pyttsx/</link>
		<comments>http://mindtrove.info/pyttsx/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 21:45:20 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[speech]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=250</guid>
		<description><![CDATA[pyttsx is a cross-platform text-to-speech package for Python. It has a simple API for producing speech, setting some basic engine properties, and getting start/stop/word callbacks. pyttsx currently supports SAPI5, NSSpeechSynthesizer, and espeak, but it can be extended to support other engines and libraries. The project BSD licensed and hosted on Launchpad. PyPI tracks downloads for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pypi.python.org/pypi/pyttsx/1.0">pyttsx</a> is a cross-platform text-to-speech package for Python. It has a simple API for producing speech, setting some basic engine properties, and getting start/stop/word callbacks.  pyttsx currently supports SAPI5, NSSpeechSynthesizer, and espeak, but it can be extended to support other engines and libraries.</p>
<p>The project BSD licensed and hosted on <a href="https://launchpad.net/pyttsx">Launchpad</a>. PyPI tracks <a href="http://pypi.python.org/pypi/pyttsx">downloads</a> for the latest stable version and <a href="http://packages.python.org/pyttsx/">documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/pyttsx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GtkBuilder/Glade on IronPython</title>
		<link>http://mindtrove.info/gtkbuilderglade-on-ironpython/</link>
		<comments>http://mindtrove.info/gtkbuilderglade-on-ironpython/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 12:10:48 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[pgo]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=236</guid>
		<description><![CDATA[Thanks to Stephane for his answer to my query about using GtkBuilder in IronPython. It turns out his Gtk#Beans package provides the magic sauce that is currently missing from gtk# trunk the current stable release. For completeness, here's the code I sent him that accomplishes the same thing using the older Glade.XML object for those [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to Stephane for his answer to my query about <a href="http://blog.reblochon.org/2009/08/gtkbuilder-on-ironpython.html">using GtkBuilder in IronPython</a>. It turns out his <a href="http://gitorious.org/gtk-sharp-beans">Gtk#Beans</a> package provides the magic sauce that is currently missing from <del datetime="2009-08-28T15:37:36+00:00">gtk# trunk</del> the current stable release.</p>
<p>For completeness, here's the code I sent him that accomplishes the same thing using the older Glade.XML object for those that are interested. It answers a <a href="http://lists.ironpython.com/pipermail/users-ironpython.com/2005-August/000968.html">long standing mailing list question</a> about using Glade.XML.Autoconnect in IronPython.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> clr
clr.<span style="color: black;">AddReference</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'gtk-sharp'</span><span style="color: black;">&#41;</span>
clr.<span style="color: black;">AddReference</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'glade-sharp'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">import</span> Gtk
<span style="color: #ff7700;font-weight:bold;">import</span> Glade
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> PyGladeAutoconnect<span style="color: black;">&#40;</span>gxml, target<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> _connect<span style="color: black;">&#40;</span>handler_name, event_obj, signal_name, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
        name = <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>frag.<span style="color: black;">title</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> frag <span style="color: #ff7700;font-weight:bold;">in</span> signal_name.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'_'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        event = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>event_obj, name<span style="color: black;">&#41;</span>
        event += <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>target, handler_name<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># add all widgets</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> widget <span style="color: #ff7700;font-weight:bold;">in</span> gxml.<span style="color: black;">GetWidgetPrefix</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span>target, gxml.<span style="color: black;">GetWidgetName</span><span style="color: black;">&#40;</span>widget<span style="color: black;">&#41;</span>, widget<span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># connect all signals</span>
    gxml.<span style="color: black;">SignalAutoconnectFull</span><span style="color: black;">&#40;</span>_connect<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Application:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        gxml = Glade.<span style="color: black;">XML</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;test.glade&quot;</span>, <span style="color: #483d8b;">&quot;window1&quot;</span>, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
        PyGladeAutoconnect<span style="color: black;">&#40;</span>gxml, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># window1 comes from glade file</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">window1</span>.<span style="color: black;">ShowAll</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> onWindowDelete<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, o, args<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># connected via glade file definition</span>
        Gtk.<span style="color: black;">Application</span>.<span style="color: black;">Quit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
Gtk.<span style="color: black;">Application</span>.<span style="color: black;">Init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
app = Application<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
Gtk.<span style="color: black;">Application</span>.<span style="color: black;">Run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/gtkbuilderglade-on-ironpython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Outfox in Greasemonkey revisited</title>
		<link>http://mindtrove.info/outfox-in-greasemonkey-revisited/</link>
		<comments>http://mindtrove.info/outfox-in-greasemonkey-revisited/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 02:39:30 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[outfox]]></category>
		<category><![CDATA[speech]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=219</guid>
		<description><![CDATA[There was some traffic in the Outfox group about my GMail announcer userscript failing in Outfox 0.3.x. The Outfox API has improved quite a bit since 0.1.0, so it's no surprise my script no longer works. Here's a new example script that does work with the latest Outfox 0.3.5 release. Instead of polluting the example [...]]]></description>
			<content:encoded><![CDATA[<p>There was some <a href="http://groups.google.com/group/outfox-discuss/browse_thread/thread/67c53a86a8814a2a">traffic in the Outfox group</a> about my <a href="http://mindtrove.info/outfoxing-gmail-with-greasemonkey/">GMail announcer userscript</a> failing in Outfox 0.3.x. The Outfox API has improved quite a bit since 0.1.0, so it's no surprise my script no longer works.</p>
<p>Here's a new example script that <em>does</em> work with the latest Outfox 0.3.5 release. Instead of polluting the example with all the complications of navigating the GMail DOM, I've picked a much simpler target. This script simply speaks the number of major sections (level 2 headings) in a Wikipedia article when the page loads. It's not as sexy, but the code is much easier to understand.</p>
<p>To try this script, make sure you have the Greasemonkey 0.8 and Outfox 0.3.5 extensions installed on Firefox 3.0 or 3.5. Then visit the following link to have GM install the script: <a href="/files/citation_announcer.user.js">citation_announcer.user.js</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// ==UserScript==</span>
<span style="color: #006600; font-style: italic;">// @name Sections count</span>
<span style="color: #006600; font-style: italic;">// @namespace http://www.mindtrove.info/</span>
<span style="color: #006600; font-style: italic;">// @description Speaks the number of h2 sections in a Wikipedia article</span>
<span style="color: #006600; font-style: italic;">// @include http://*.wikipedia.org/wiki/*</span>
<span style="color: #006600; font-style: italic;">// @require http://www.json.org/json2.js</span>
<span style="color: #006600; font-style: italic;">// @require http://outfox.googlecode.com/svn/trunk/js/outfox.js</span>
<span style="color: #006600; font-style: italic;">// ==/UserScript==</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// number of major sections</span>
<span style="color: #003366; font-weight: bold;">var</span> sections <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> onOutfoxAudioInit<span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// say the number of main sections</span>
    outfox.<span style="color: #660066;">audio</span>.<span style="color: #660066;">say</span><span style="color: #009900;">&#40;</span>sections <span style="color: #339933;">+</span> <span style="color: #3366CC;">' main sections'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// return the parameter for other outfox deferred callbacks</span>
    <span style="color: #000066; font-weight: bold;">return</span> response<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> onOutfoxInit<span style="color: #009900;">&#40;</span>version<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> content <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'bodyContent'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// count the number of main sections</span>
    sections <span style="color: #339933;">=</span> content.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'h2'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// take one back for the TOC heading if it's present</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'toc'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #339933;">--</span>sections<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #006600; font-style: italic;">// start the outfox audio service</span>
    <span style="color: #003366; font-weight: bold;">var</span> def <span style="color: #339933;">=</span> outfox.<span style="color: #660066;">startService</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'audio'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    def.<span style="color: #660066;">addCallback</span><span style="color: #009900;">&#40;</span>onOutfoxAudioInit<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// return the parameter for other outfox deferred callbacks</span>
    <span style="color: #000066; font-weight: bold;">return</span> version<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> onDOMContentLoaded<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// create a node for outfox use</span>
    <span style="color: #003366; font-weight: bold;">var</span> div <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>div<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// initialize outfox</span>
    <span style="color: #003366; font-weight: bold;">var</span> def <span style="color: #339933;">=</span> outfox.<span style="color: #660066;">init</span><span style="color: #009900;">&#40;</span>div<span style="color: #339933;">,</span> JSON.<span style="color: #660066;">stringify</span><span style="color: #339933;">,</span> JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    def.<span style="color: #660066;">addCallback</span><span style="color: #009900;">&#40;</span>onOutfoxInit<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// this event triggers execution of the GM script</span>
onDOMContentLoaded<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/outfox-in-greasemonkey-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spaceship!</title>
		<link>http://mindtrove.info/spaceship/</link>
		<comments>http://mindtrove.info/spaceship/#comments</comments>
		<pubDate>Sun, 24 May 2009 20:37:46 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[HCI]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[a11y]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[outfox]]></category>
		<category><![CDATA[spaceship]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=200</guid>
		<description><![CDATA[When Gary announced Outfox back in 2008, all manner of ideas for using speech and sound in the browser popped into my head. I've always had the boring demos (i.e., for adults) at Maze Day, so I decided to work first on a fun, somewhat educational, self-voicing browser game for the 2009 rendition. After all, [...]]]></description>
			<content:encoded><![CDATA[<p>When Gary announced <a href="http://wwwx.cs.unc.edu/~gb/wp/blog/2008/07/27/outfox-speech-sound-and-more-for-firefox/">Outfox</a> back in 2008, all manner of ideas for using speech and sound in the browser popped into my head. I've always had the <a href="http://mindtrove.info/clique/">boring demos</a> (i.e., for adults) at <a href="http://wwwx.cs.unc.edu/~gb/wp/blog/2008/01/22/maze-day-2008/">Maze Day</a>, so I decided to work first on a fun, somewhat educational, self-voicing browser game for <a href="http://wwwx.cs.unc.edu/~gb/wp/blog/2009/02/15/maze-day-2009/">the 2009 rendition</a>. After all, keeping the mostly under-13, soda drinking, pizza eating, game playing clientele happy is always priority #1 at Maze Day.</p>
<p>The result is Spaceship!, a JavaScript game for Firefox built using <a href="http://creativecommons.org/">Creative Commons</a> licensed music, sound, speech, and graphics; the <a href="http://dojotoolkit.org">Dojo toolkit</a>; and the <a href="http://code.google.com/p/outfox">Outfox add-on</a>. In the primary portion of the game, the player fires shots at a grid of tiles trying to hit enemy ships. When the player runs out of ammo, he or she plays a set of minigames in an attempt to earn more shots. Of course, hazards and bonuses abound to keep things interesting.</p>
<p>A text description is nice, but you're better off watching the gameplay video below to really understand what I'm jabbering about. Or, better yet, grab <a href="http://code.google.com/p/outfox">Outfox</a> and <a href="http://www.mozilla.com/en-US/firefox/personal.html?from=getfirefox">Firefox 3</a> and play it yourself online at <a href="http://spaceship.mindtrove.info">http://spaceship.mindtrove.info</a>.</p>
<p><object width="640" height="480" data="http://vimeo.com/moogaloop.swf?clip_id=4812387&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=FF7700&amp;fullscreen=1" type="application/x-shockwave-flash"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=4812387&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=FF7700&amp;fullscreen=1" /></object></p>
<p>What a great exercise this turned out to be!  The payoff has been manyfold:</p>
<ol>
<li>I learning a ton more about Dojo and writing custom widgets.</li>
<li>I developed some interesting MVC techniques for aural+visual event driven apps in Dojo. I hope to blog about these.</li>
<li>I built some nice, reusable Dojo components for future browser games.</li>
<li>I got to show off client-side music, sound, and speech in Firefox with pure JS. Maybe this will spur development of other audio apps?</li>
<li>I drummed up some interest in extending Spaceship! with new minigames. Hopefully more coming soon.</li>
<li>My wife was entertained. Yes, she will actually ask to play the game if she sees me working on it.</li>
<li>I had lots of teachers ask when the game will be online at Maze Day. Well, here it is, a month later.</li>
<li>And, most importantly, a steady stream of kids (and adults) got to play it at Maze Day. Hopefully even more can enjoy it now online.</li>
</ol>
<p>If you try it out, leave a comment. It's new, there are bugs, and there is room for improvement. But anything you report will help in making the game better.</p>
<p>I owe many thanks to the artists who made their wonderful images, songs, and sounds available under open licenses. Their names appear in the <em>Credits</em> section off the main game menu. Be sure to check them out.</p>
<p>Oh, and of course the game code itself is <a href="http://creativecommons.org/licenses/BSD/">BSD-licensed</a>. Grab the code from <del><a href="http://svn.mindtrove.info/spaceship">http://svn.mindtrove.info/spaceship</a></del> <a href="http://github.com/parente/spaceship">http://github.com/parente/spaceship</a> if you're feeling adventurous.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/spaceship/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tidbit: doh.robot initialization</title>
		<link>http://mindtrove.info/tidbit-dohrobot-initialization/</link>
		<comments>http://mindtrove.info/tidbit-dohrobot-initialization/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 13:52:53 +0000</pubDate>
		<dc:creator>Peter Parente</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[doh]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://mindtrove.info/?p=191</guid>
		<description><![CDATA[The doh.robot module for Dojo clicks a special text field inserted into the top-left of the test page during its initialization. If you obscure this magic field, the robot hangs. If you're writing your test cases separate from the page under test (always a good idea), dojo.robotx craftily hides the iframe containing the page to [...]]]></description>
			<content:encoded><![CDATA[<p>The doh.robot module for Dojo clicks a special text field inserted into the top-left of the test page during its initialization. If you obscure this magic field, the robot hangs.</p>
<p>If you're writing your test cases separate from the page under test (always a good idea), dojo.robotx craftily hides the iframe containing the page to test until the robot is ready. If you're not using dojo.robotx (my constraint), you must be careful to avoid that magic text box in a similar fashion.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindtrove.info/tidbit-dohrobot-initialization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
