<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.1.2" -->
<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/"
	>

<channel>
	<title>The Fluid Project Blog</title>
	<link>http://fluidproject.org/blog</link>
	<description></description>
	<pubDate>Fri, 20 Jun 2008 21:44:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.1.2</generator>
	<language>en</language>
			<item>
		<title>Fearless JavaScript 2.0</title>
		<link>http://fluidproject.org/blog/2008/06/20/fearless-javascript-20/</link>
		<comments>http://fluidproject.org/blog/2008/06/20/fearless-javascript-20/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 21:44:55 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/06/20/fearless-javascript-20/</guid>
		<description><![CDATA[Back in April, Eli Cochran and I organized a half-day workshop on JavaScript development techniques at the JA-SIG Spring conference in St. Paul, MN.  Writing Fearless Javascript for Portlets, Widgets, and Portals was designed to give attendees a primer on various aspects of client-side user interface development, including JavaScript fundamentals, the use of toolkits [...]]]></description>
			<content:encoded><![CDATA[<p>Back in April, Eli Cochran and I organized a half-day workshop on JavaScript development techniques at the JA-SIG Spring conference in St. Paul, MN.  <em>Writing Fearless Javascript for Portlets, Widgets, and Portals</em> was designed to give attendees a primer on various aspects of client-side user interface development, including JavaScript fundamentals, the use of toolkits such as jQuery, and DHTML accessibility.</p>
<p>The workshop explores what I&#8217;ve been referring to as &#8220;modern&#8221; JavaScript programming, for lack of a better term. In contrast to the previous generation of JavaScript programs, where small bits of interactivity were sprinkled on top of a largely static document, modern JavaScript involves the creation of richly interactive applications and components. These days, your code probably shares the page and Javascript&#8217;s notorious global namespace with other libraries and widgets. As a result, you need to do things a bit differently to ensure your code is self-contained and won&#8217;t conflict with other libraries. <a href="http://wiki.fluidproject.org/display/fluid/Fearless+JavaScript+Workshop">Fearless JavaScript</a> gives you the techniques needed to thrive in the world of portals, plugins, and mash-ups.</p>
<p>We&#8217;ll be presenting a new edition of Fearless JavaScript at the Sakai Summer 2008 conference in Paris, France. The material has been significantly refined, and we&#8217;ve added another co-presenter: Nicolaas Matthijs from CARET at the University of Cambridge. Nico will be talking about how to create gadgets for Sakai using JSON-based data feeds. We&#8217;re working on some tutorial code that walks you through using Fluid components within a Sakai gadget. Cool stuff.</p>
<p>Nico attended the original Fearless JavaScript workshop in St. Paul, and had lots of interesting questions and suggestions for us. Afterwards, Nico and I spent an enjoyable couple of hours working together on some of his gadgets, tweaking their accessibility and talking about his designs. He&#8217;s doing some great work on MyCamTools, and I&#8217;m looking forward to sharing the stage with him and Eli for Fearless JavaScript 2.0.</p>
<p>If you&#8217;re in Paris for the Sakai conference, we&#8217;d love to see you at the workshop. If you can&#8217;t make it, we&#8217;re hoping to create a podcast of the event. Here are the details:</p>
<p><strong><a href="http://wiki.fluidproject.org/display/fluid/Fearless+JavaScript+Workshop">Fearless JavaScript</a></strong><br />
Presented by Colin Clark, Eli Cochran, and Nicolaas Matthijs<br />
Monday, June 30<br />
1:30 - 4:30 pm in Amphi 55A</p>
<p>Topics will include:</p>
<p>    * Why JavaScript?<br />
    * Fundamentals of JavaScript<br />
    * Using jQuery<br />
    * JavaScript in Sakai<br />
    * Portal and mash-up friendliness<br />
    * Accessibility</p>
<p>Everyone is welcome to attend the workshop. It&#8217;s assumed that you have some understanding of at least one programming language, and that you&#8217;ll bring a laptop to follow along with the hands-on exercises. </p>
<p>See you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/06/20/fearless-javascript-20/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Performance and Design</title>
		<link>http://fluidproject.org/blog/2008/06/16/performance-and-design/</link>
		<comments>http://fluidproject.org/blog/2008/06/16/performance-and-design/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 17:43:16 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/06/16/performance-and-design/</guid>
		<description><![CDATA[Following up on Antranig&#8217;s recent post about performance, I&#8217;d like to address the issue of code design and its relationship to performance. Antranig&#8217;s article is very comprehensive and well-considered, and it provides us with a number of guidelines for balancing the tradeoffs between code quality and speed. However, I was surprised that he didn&#8217;t remind [...]]]></description>
			<content:encoded><![CDATA[<p>Following up on Antranig&#8217;s recent post about performance, I&#8217;d like to address the issue of code design and its relationship to performance. Antranig&#8217;s article is very comprehensive and well-considered, and it provides us with a number of guidelines for balancing the tradeoffs between code quality and speed. However, I was surprised that he didn&#8217;t remind us the C.A.R. Hoare quote made famous by Donald Knuth:</p>
<p>
<blockquote>&#8220;Premature optimization is the root of all evil.&#8221;</p></blockquote>
<p>Antranig&#8217;s performance metrics are intended to help establish a gut feel about the cost of a particular operation. They&#8217;re low-level measurements, and as such they can&#8217;t take into account a fundamental variable: context. These performance metrics have very different consequences depending on the size, scale, and nature of the application. His examples are apt: intensive, highly recursive, up-front operations like template rendering show the full cost of JavaScript&#8217;s weak performance. Indeed, Antranig has used his research to good effect on our nascent client-side template renderer. In a relatively short amount of time, he was able to improve the performance of his low-level parsing algorithms by several orders of magnitude using regular expressions and fast string comparisons. Impressive stuff.</p>
<p>On the other hand, context matters a lot when it comes to user-facing behaviour, where timings may vary significantly based on the user&#8217;s choices. Many UI components, such as the Uploader, provide a fairly modal experience for the user. Such components undoubtedly have less stringent performance requirements, and our acceptance criteria should be determined by testing in real-world situations.</p>
<p>The risk with out of context performance measurements is the tendency to optimize prematurely and without accurate data. There&#8217;s only so much time in the day. Don&#8217;t lose the opportunity to add useful features to your application by starting in on time-intensive performance optimizations too early. Without good data, your hard work may only have a tiny impact on the overall perception of speediness. Worse yet, premature optimization can lead towards architectures that are poorly factored, redundant, and hard to maintain.</p>
<p>So how do we ensure good performance without compromising architectural quality?</p>
<ol>
<li>Write code with good design principles in mind</li>
<li>Continually measure performance in real world situations</li>
<li>Refine code incrementally to improve performance</li>
</ol>
<p>Let&#8217;s take jQuery as an example. If you look at the <a href="http://code.jquery.com/jquery-1.0.js">first release of jQuery</a>, you&#8217;ll find that it was mostly composed of small functions that are clear and easy to read. jQuery&#8217;s author, John Resig, has always done a very good job of carefully profiling his code with performance tests, and over time the code base has evolved in certain areas to be faster and, as a concequence, occasionally less readable. He took the time to build something real first, then he optimized strategically. This is exactly the example of how we should all handle performance optimizations: build it cleanly, then identify areas where performance optimizations are necessary. Optimization without real-world numbers is, well, evil.</p>
<p>Building on Antranig&#8217;s advice, here are some strategies to help ensure both good performance and a maintainable design in JavaScript:</p>
<h2>Avoid deep inheritance hierarchies</h2>
<p>Excess use of inheritance tends to be brittle, hard to reuse, and slow. In JavaScript, inheritance is prototypal: an object has a secret prototype link that points to its parent object. When a property isn&#8217;t found on an instance directly, the object&#8217;s prototype is searched, then the prototype&#8217;s prototype, and onwards up the inheritance chain. This can be extremely slow on objects with a long lineage. JavaScript provides more effective strategies for reuse, such as containment and dynamic mix-ins. You&#8217;re better off with a very shallow inheritance hierarchy, using these techniques to share code across objects instead.</p>
<h2>Break code into small, independent parts</h2>
<p>JavaScript is a functional language, and functions serve as the fundamental building block for all programs. Break complicated algorithms up into smaller functions that take only the data necessary to perform a given operation. Small functions are more easily tested, modified, and reused. What about the cost per function call that Antranig mentions? If you need to optimize for speed later, you can easily merge several functions back into one. Analyze frequent code paths and identify specific bottlenecks first, then selectively fold smaller functions into a larger one.</p>
<h2>Don&#8217;t deeply nest functions</h2>
<p>In JavaScript, functions can be nested inside other functions. This is a very powerful technique, since inner functions have access to the variables and scope of the outer function even after the outer function has finished executing. This is called closure, and it&#8217;s one of the best ways to encapsulate state and behaviour in JavaScript. The trick is to avoid deep nesting; don&#8217;t stick a function inside a function inside a function. Similar to the inheritance chain, each JavaScript function invocation brings with it a scope chain, providing access to variables defined in outer functions. If a reference to a particular variable isn&#8217;t found inside a function&#8217;s scope, the JavaScript runtime will climb the scope chain, searching each outer scope in turn to find the property. All this searching can get pretty slow. Limit yourself to a couple of layers of closure at the most. Here&#8217;s a slight contrived code example and an illustration of the scope chain in action:
<p><strong>Illustrated Code Example: Using a closure for event handling</strong></p>
<pre>
  function showMessage(messageToDisplay) {
  	var todaysPie = "Banana creme pie";

	return function(event) {
		alert(messageToDisplay + " " + todaysPie);
		showPictureOfPie(event.target, todaysPie);
	}
  }

  var messageClickHandler = showMessage("Welcome to my pie shop. Today's pie is:")
  $(element).click(clickHandler);
</pre>
<p>
<img src="http://wiki.fluidproject.org/download/attachments/3342621/JavaScript-Call-Stack.png" />
</p>
<h2>Identify nameable units of behaviour and encapsulate them</h2>
<p>On the client side, it&#8217;s really easy to let your application logic get all muddled up with your presentation code. Large, hard to maintain functions are often structured like this: 1) Perform some calculations; 2) fetch some data; 3) update the DOM. These are separate tasks, and your code will be significantly easier to read and reuse if you split these behaviours into independent units. The trick is to look at your code while you&#8217;re writing it and recognize &#8220;things&#8221; that are easily identified and named. Using a closure or an object, you can factor out pieces of the overall behaviour and data into a separate entity. Here&#8217;s an example of the various units of behaviour we identified within the Reorderer:</p>
<p></p>
<ul>
<li>The Reorderer is responsible for binding events to DOM elements and providing end-user APIs</li>
<li>A Layout provides an awareness of visual layout and spatial characteristics: grids, lists, portlets within columns, and so on</li>
<li>The Mover is responsible for moving elements around in the DOM, deferring to the Layout for spatial information</li>
<li>A Permissions object defines the rules for valid drop targets and operations on a specific element</li>
<li>Keyboard selections and accessibility is provided by the jQuery keyboard-a11y plugin</li>
<li>MouseDragAndDrop encapsulates our use of jQuery UI for low-level drag and drop functionality</li>
</ul>
<h2>Use closures to encapsulate data and behaviour</h2>
<p>Antranig covered this one really well in his post. Under many circumstances, you&#8217;ll pay a significantly lower cost to access data wrapped in a closure than within an object, and functional idioms tend to be more flexible and easier to maintain than object-oriented ones. This is particularly true in JavaScript, where there is no built-in support for namespaces or privacy. Just be careful not to nest your closures too deeply.</p>
<h2>Never, ever cut and paste code</h2>
<p>It almost feels silly to repeat this one here. One of the foundational principles of programming, regardless of the language you&#8217;re using, is DRY: <a href="http://c2.com/cgi/wiki?DontRepeatYourself">Don&#8217;t Repeat Yourself</a>. The bottom line is this: cut and pasted code will come back to bite you. Don&#8217;t do it. Antranig&#8217;s post hints at the idea that it&#8217;s okay to cut and past code in JavaScript. For all but the most extreme cases, I don&#8217;t buy it. If you find yourself tempted to cut and paste something, take the time to factor it into a function. It will be easier to update later, and much easier to test. Duplicate code hurts!</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/06/16/performance-and-design/feed/</wfw:commentRss>
		</item>
		<item>
		<title>&#8220;How Long, Oh Lord?&#8221;</title>
		<link>http://fluidproject.org/blog/2008/05/30/how-long-oh-lord/</link>
		<comments>http://fluidproject.org/blog/2008/05/30/how-long-oh-lord/#comments</comments>
		<pubDate>Fri, 30 May 2008 13:43:56 +0000</pubDate>
		<dc:creator>antranig</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/05/30/how-long-oh-lord/</guid>
		<description><![CDATA[Recently, I expressed to Colin the sense of &#8220;disorientation&#8221; every Java (or other &#8220;traditional&#8221;) programmer must feel at diving into the client side and trying to write idiomatic, performant code. Every reasonable coder quickly develops a &#8220;gut&#8221; feeling for the costs (both in design, and resources) for the various primitives they have at their disposal. [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I expressed to Colin the sense of &#8220;disorientation&#8221; every Java (or other &#8220;traditional&#8221;) programmer must feel at diving into the client side and trying to write idiomatic, performant code. Every reasonable coder quickly develops a &#8220;gut&#8221; feeling for the costs (both in design, and resources) for the various primitives they have at their disposal. For timings, which is mainly what I am going to talk about in this posting, this might not take the form of actual hard numbers, but certainly a kind of &#8220;order of magnitude&#8221; relative estimate.</p>
<p>What I mean here is to know, generally within a factor of 2 or 3, how much one operation is likely to cost relative to another one, and to have a similar kind of &#8220;fuzz factor&#8221; with respect to actual performance on a particular kind of machine you are familiar with. Back in the days when I was starting on <a HREF="http://www2.caret.cam.ac.uk/rsfwiki">RSF</a>, pinned to my desk was the original &#8220;How Long, Oh Lord?&#8221; which I reproduce here:</p>
<table CLASS="" SUMMARY="Java performance benchmarks circa 2005" STYLE="margin-left: auto; margin-right: auto; font-size: 1.20em">
<tr>
<th COLSPAN="2" COLSPAN="2" COLSPAN="2" COLSPAN="2" CLASS="" COLSPAN="2" COLSPAN="2" COLSPAN="2" COLSPAN="2">How Long, Oh Lord?</th>
</tr>
<tr>
<td CLASS="">Method Call</td>
<td CLASS="">8ns</td>
</tr>
<tr>
<td CLASS="">ThreadLocal Get</td>
<td CLASS="">60ns</td>
</tr>
<tr>
<td CLASS="">Constructor</td>
<td CLASS="">100ns</td>
</tr>
<tr>
<td CLASS="">Reflective Call</td>
<td CLASS="">700ns</td>
</tr>
</table>
<p>For reference, these timings were on a Windows JDK 1.4 running on a relatively weak machine in 2005, perhaps something like a c.2Ghz P4.</p>
<p>Anyway, to skip to the present, starting work on the RSF/Fluid client-side renderer, I felt similarly at sea on how to plan for a design that runs efficiently. Javascript is starting to emerge from its &#8220;ghetto folkloric&#8221; period and to become the target of determined engineering efforts, and there are a number of resources round the web focused on Javascript performance issues, such as John Resig&#8217;s excellent blog entry collection <a HREF="http://ejohn.org/blog/tags/performance/">http://ejohn.org/blog/tags/performance/</a>, and a splendid presentation by Julien Lecomte of YUI <a HREF="http://yuiblog.com/blog/2007/12/20/video-lecomte/">http://yuiblog.com/blog/2007/12/20/video-lecomte/</a>.</p>
<p>Some of the &#8220;learnings&#8221; I report here in &#8220;How Long, Oh Lord 2008&#8243; are part of Julien&#8217;s presentation, but others I have not seen before. The workhorse of these estimates is a microbenchmark collection I have put together at https://source.caret.cam.ac.uk/rsf/projects/RSFSamples/trunk/AjaxJSON/src/webapp/content/templates/perftest.html (this is just accidentally for now embedded in the middle of a wider Java/RSF/JSON/Maven development structure).</p>
<p>The benchmarks are run in (currently 5) &#8220;batches&#8221; of say 10,000 iterations, the most extreme measurements are discarded, and the average of the remaining three batches are reported as a headline figure. This is an attempt to defeat random variation caused by system business, GC collections and the like.</p>
<p>Here is a sample row and table output from the system:</p>
<style> .bench th, .bench td {border:1px solid #000;} .bench th {background-color:#696969;color:#fff;}/*dark gray*/ .bench td {text-align:left;} .bench th {text-align:left;} </style>
<table SUMMARY="Example of output from JavaScript benchmark tests." CLASS="bench">
<thead>
<th CLASS="">Count</th>
<th CLASS="">Name</th>
<th CLASS="">1</th>
<th CLASS="">2</th>
<th CLASS="">3</th>
<th CLASS="">4</th>
<th CLASS="">5</th>
<th CLASS="">Median ave</th>
</tr>
<tr>
<td CLASS="">100000</td>
<td CLASS="">Bare Function Call</td>
<td CLASS="">125.0ms: (1.250us/call)</td>
<td CLASS="">93.00ms: (0.930us/call)</td>
<td CLASS="">94.00ms: (0.940us/call)</td>
<td CLASS="">109.0ms: (1.090us/call)</td>
<td CLASS="">110.0ms: (1.100us/call)</td>
<td CLASS="">104.3ms: (1.043us/call)</td>
</tr>
</table>
<h2>Function Calls Considered Harmful</h2>
<p>I think the most central result I want to report here is the truly fantastic expense of function calls in Javascript, which to my mind generally cuts at the heart of the possibility of orderly development.</p>
<p>The bad news is that a simple function call costs around 3 microseconds on a typical machine in Firefox 2.x. Opera builds are generally much better, around the 1µs mark. The &#8220;better&#8221; news going forwards is that current builds of Firefox 3 betas are vastly improved, down to 350ns on the same hardware. All the same, the ground reality is that in the vast majority of installed system for a number of years, a Javascript function call is going to cost something in the region of 1 microsecond. Let&#8217;s put that figure into perspective with a tour of our glorious history - the heroic <a HREF="http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP2030.html">IBM System/360 Model 30</a> (Announced April 7, 1964) had a machine cycle time of 1 microsecond. On the personal computer front, the <a HREF="http://oldcomputers.net/pet2001.html">Commodore PET</a> (January 1977) was the same. In this respect (and some others) therefore Javascript sets back computer science 30 years or more. This is a little tongue-in-cheek - but not entirely. Clearly even on the most up-to-date environment, a function call in Java, say, will not execute in a single machine cycle. But the discrepancy is more like 1 order of magnitude, rather than 3 as it is in Javascript.</p>
<p><center><br />
<a HREF="http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP2030.html"><img SRC="http://ponder.org.uk/public/IBM-30.jpg" /></a><br />
</center></p>
<h3>Why is this, and what does it mean?</h3>
<p>Javascript function calls, as the most skilled practitioners of Javascript (<a HREF="http://www.crockford.com/javascript/javascript.html">Crockford</a>, etc.) will explain, are vastly powerful, vastly underappreciated pieces of machinery. Every invocation of a Javascript function brings into existence a highly complex structure, a dynamic scope chain which will allow variables to be referenced long after a function has returned — or else, require them to be garbage collected, piece by piece. Therefore a JS &#8220;stack frame&#8221; is really very much more like an &#8220;object&#8221; in a classic &#8220;OO&#8221; language in its capabilities. More on this later. This means that a truly efficient implementation of JS function calls is essentially impossible - although the Firefox 3 team are having a thoroughly good try. What is particularly happy about this situation is that, as Crockford frequently laments, the true power of Javascript functional expressiveness is lost on 99% of its practitioners, who are typically trained if at all) in far less mind-bending idioms. And for those 1% who do truly understand what a JS function call could do, how many can make more than a handful of the function calls they write count for their full power? <img src='http://fluidproject.org/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>What does this mean? It means that truly performant Javascript code is really obliged to drop back more than decades in its structural idiom. The function call is the primary, the first and most useful, unit of modular abstraction in programming, and these costs imply that efficient Javascript code must degrade to consist of few, extremely large function bodies, whereas a design based on fine-grained, flexibly composed units would be much more comprehensible and easy to maintain.</p>
<p>The most skilled Javascript programmers, framework authors, have been aware of this (implicitly or explicitly) for a long while, and it is clear that their code is following suit. As one example, <a HREF="http://code.google.com/p/trimpath/wiki/JavaScriptTemplates">TrimPath Templates</a> a very performant macro-style templating language, is implemented with a large work-horse method (actually TrimPath uses a number of other performance tricks which will be touched upon later). As another, <a HREF="http://jquery.com">JQuery</a>&#8217;s central workhorse, JQuery.find() is likewise a single monster method. In this and many other areas, &#8220;stupider is better&#8221; is often the correct answer - cut and paste, traditionally the anathema of programming, has a new lease of life in Javascript as it is frequently superior to simply repeat frequently occurring, especially small, snippets of code, rather than factor them into function calls.</p>
<h2>Scoping and storing bugbears</h2>
<p>The pattern of which operations in Javascript are performant and which are not is interestingly skew. To go into other results from &#8220;perftest&#8221;, we can discover a rule of thumb that one object property access is roughly equivalent to four string comparisons. For example, when testing a string value to be one of four possible values, looking it up as an Object member is roughly breaking even with writing out the sequential comparisons.</p>
<p>Similarly, access to objects in outer scopes carries a price. For example, again on FF2.x, simply accessing a variable not declared at the current function scope carries a penalty of 300ns. Vast, in &#8220;traditional&#8221; terms.</p>
<p>Facts like this militate for numerous &#8220;hoisting&#8221; tricks - essentially if a given expression or variable is accessed more than a single time in a particular function scope, it will almost always make sense to assign it to a local variable before use. This is obviously much more important for Object members than for &#8220;outer scope&#8221; variables. Julien Lecomte covers this in his presentation - a further comparison worth noticing is that function scopes are actually more more efficient containers for data than Objects. This further pushes forwards the Crockfordian view of &#8220;function scopes&#8221; as being the primary units of abstraction and storage in an &#8220;idiomatic Javascript&#8221; program, rather than traditional &#8220;Objects&#8221;. If one is going to pay 1 microsecond for a function call, better make it count - but better to pay 3 microsecond for a call and 300 ns for an access, than to pay 5 microseconds to construct an Object and then 500 ns per access (Firefox 2.x figures - FF3 and Opera are better, but the relative picture is unchanged).</p>
<h3>An unfortunate discovery</h3>
<p>On Firefox 2.x the already dim picture is muddied further by the discovery that simply invoking a function declared at another function scope nearly doubles the cost - even if no variables are declared or accessed at the outer scope. Since this &#8220;trick&#8221; is the now standard modern recommdation for implementing <a HREF="http://javascript.crockford.com/private.html">namespacing</a> (Crockford on Privacy) this automatically penalises those who seek to organise their code better. Again blissfully this penalty is gone from Firefox 3.</p>
<h2>Finding performant primitives</h2>
<p>Some Javascript operations essentially retain near-native performance. Boolean tests, numeric operations, local control structures such as loops and branches, all proceed pretty quickly. This would seem to at least allow the possibility of some high-performing algorithms (assuming they were structured as giant function blocks) were it not for another really unfortunate Javascript feature - the lack of any bulk &#8220;primitive&#8221; storage. Java&#8217;s primitive array support was often widely derided as a really irritating and unorthogonal language feature, but actually is the only thing that saves it as a data processing language. In Javascript one has only Strings - and even a simple charAt() call causes a complete object instantiation (as a side tip - use of the less-well-known String.charCodeAt() followed by a (much less readable) numeric test is around 20% faster than a charAt() plus String test). There is simply nowhere to put extensive data since every Array is an Array of Object.</p>
<p>This leaves one to fall back on Strings and String tricks. An interesting discovery is that String.indexOf() is a startlingly rapid operation - after what appears to be a standard &#8220;native call overhead&#8221; of something like 1.5 microseconds (abouthalf a &#8220;standard function call&#8221;) (again FF 2.x), the actual search occurs at fully native speeds. This implies you can find a given String amongst around 10K of data practically as fast as you can find it amongst 100 bytes. TrimPath makes very fruitful use of indexOf to gain a very good speed boost, helped by its simple and &#8220;easily recognisable&#8221; templating format.</p>
<p>Regexes can take up a lot of slack in some cases, but their overhead is very much higher than an indexOf. As Lecomte notes, a Regexp.test() is *somewhat* faster than a Regexp.exec() but actually not startlingly so, since the test() appears to require no &#8220;user-visible&#8221; memory allocation. Any Regexp invocation carries a standard overhead of about 2 function calls, so use with care on simple tasks.</p>
<h2>Garbage in, garbage out</h2>
<p>Investigating the costs of garbage in Javascript rounds out most of this discussion. It is very interesting to repeat the performance tests on a &#8220;huge browser image&#8221; runtime, since this immediately exposes the kinds of operations which create garbage and those which do not. I am somewhat untypical in that I am frequently running a system with around 70 top-level Opera frames (it is the only browser that will cope with this sensibly) and perhaps 20 Firefox frames. In a browser image like this, the fact that all Javascript objects are typically thrown into a global shared heap, rather than the per-frame heaps one might perhaps wish for is painfully exposed. Running perftest.js in a &#8220;mega-Opera&#8221; shows the allocating tests running perhaps 100 times slower - the data becomes very spiky, but a single micro-test can end up taking a full millisecond rather than a microsecond.<br />
This exposes that although function calls are &#8220;like&#8221; Object (heap) allocations, they are still underlyingly dealt with by different, and more efficient data structures - even in a &#8220;mega-Opera&#8221;, a bare function call is still taking 1 microsecond, whilst a true heap allocation is running at a millisecond or more. &#8220;mega-Opera&#8221; is a highly untypical environment, but it demonstrates at extremes the superior scaling costs of function frames over true garbage.</p>
<p>If there is a simple take-home message from all of this, it is -</p>
<p>i) Javascript function calls are hugely expensive compared to traditional environments, take great care not to factor your code too deeply,</p>
<p>ii) Javascript function calls are sufficiently powerful to take over many of the traditional roles of &#8220;Objects&#8221; in traditional environments, so consider designs that operate closure-based storage and reserve your true Objects for data transfer,</p>
<p>iii) make judicious use of the primitive operations which are provided (indexOf and regexps) where possible to make your code run reasonably.</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/05/30/how-long-oh-lord/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Shiny new API for the Reorderer</title>
		<link>http://fluidproject.org/blog/2008/05/29/shiny-new-api-for-the-reorderer/</link>
		<comments>http://fluidproject.org/blog/2008/05/29/shiny-new-api-for-the-reorderer/#comments</comments>
		<pubDate>Thu, 29 May 2008 16:19:17 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/05/29/shiny-new-api-for-the-reorderer/</guid>
		<description><![CDATA[We&#8217;re really close to putting out Fluid Infusion 0.3. It&#8217;ll be ready in a few days, and is shaping up to be a pretty solid release. In addition to a preview version of the Uploader, we&#8217;ve really improved the user experience and functionality of the Reorderer. We&#8217;ve added sortable layouts, customizable drag-and-drop interactions, and support [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re really close to putting out Fluid Infusion 0.3. It&#8217;ll be ready in a few days, and is shaping up to be a pretty solid release. In addition to a preview version of the <a href="http://wiki.fluidproject.org/display/fluid/Uploader">Uploader</a>, we&#8217;ve really improved the user experience and functionality of the Reorderer. We&#8217;ve added <a href="http://build.fluidproject.org/sakai-imagegallery-tool/sample-code/reorderer/portal/portal.html">sortable layouts</a>, customizable <a href="http://uidesignpatterns.org/content/drag-and-drop">drag-and-drop interactions</a>, and support for all kinds of portal-y features like locking and efficient keyboard navigation. </p>
<p>One of the things we&#8217;ve needed to improve in the Reorderer is the API. In earlier versions, it was pretty hard to initialize your own Reorderer. You needed to know a lot about the inner workings of objects such as LayoutHandlers, item finders, and so on. Infusion 0.3 solves this problem by providing clean, one-line functions for creating your favourite configurations of the Reorderer:</p>
<p><strong>Sorting Lists</strong></p>
<p><code>fluid.reorderList(containerSelector, itemSelector, orderChangedCallback, options);</code></p>
<p>Pass in a selector string to locate your list and the items within it, and you&#8217;ve got yourself an accessible, sortable list. Optionally, you can also specify a callback function that will be invoked every time the list order changes, along with a whole raft of other options for configuring the Reorderer.</p>
<p><strong>Sorting Grids</strong></p>
<p><code>fluid.reorderGrid(containerSelector, itemSelector, orderChangedCallback, options);</code></p>
<p>Same thing. Just pass in a selector string to locate your grid and the items within it, along with an optional order changed callback and some configuration options. Boom, a sortable 2D grid.</p>
<p><strong>Sorting Layouts</strong></p>
<p><code>fluid.reorderLayout(containerSelector, layoutSelectors, orderChangedCallback, options);</code></p>
<p>This one is for reordering portlets, content blocks, or other chunks of layout on a page. Pass in a selector to locate the container of your layout. Pass in an object that contains two selectors: one for the columns in the layout and one for the portlets. This function will do all the heavy lifting for you, figuring out which portlets are in each column, building a Layout object, and so on.</p>
<p>If you want all the advanced portal features of the Layout Customizer, such as locking, JSON-based layout, and permissions, you can always drop down to the lower-level API:</p>
<p><code>fluid.initLayoutCustomizer(layout, permissions, orderChangedURL, options);</code></p>
<p>This function exposes some of the more complex objects used by the Layout Customizer, the Layout and Permissions objects. The Layout is a JSON-style object representing the column and portlet structure in a DOM-agnostic way. Permissions is a complex data structure encoding all of the valid drop target permissions for each portlet and column in the layout. Generally, you&#8217;ll want to use the simpler fluid.reorderLayout() function unless you need the advanced portal features.</p>
<p><strong>Documentation</strong></p>
<p>We realize that code examples and the occasional blog post aren&#8217;t nearly enough to get you started using Infusion. Anastasia has been experimenting with some great new documentation for the 0.3 release. It&#8217;s still very much a work in progress, but check out her <a href="http://wiki.fluidproject.org/display/fluid/Using+the+Reorderer">live examples of how to use the Reorderer</a>. She&#8217;s still figuring out  the right recipe for our documentation, so please share your ideas and thoughts with her!</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/05/29/shiny-new-api-for-the-reorderer/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Welcoming Jess Mitchell, Fluid&#8217;s New Project Manager</title>
		<link>http://fluidproject.org/blog/2008/05/11/welcoming-jess-mitchell-fluids-new-project-manager/</link>
		<comments>http://fluidproject.org/blog/2008/05/11/welcoming-jess-mitchell-fluids-new-project-manager/#comments</comments>
		<pubDate>Sun, 11 May 2008 23:06:41 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Project coordination]]></category>

		<category><![CDATA[Community]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/05/11/welcoming-jess-mitchell-fluids-new-project-manager/</guid>
		<description><![CDATA[I&#8217;ve been waiting for over a year to write this blog post. I&#8217;m extremely excited to welcome Jess Mitchell on board as our new project manager for Fluid. Earlier this week, Jutta Treviranus sent out a great introduction to Jess  on the fluid-work mailing list. Here&#8217;s a quick excerpt:
&#8220;Jess comes with an incredibly rich [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been waiting for over a year to write this blog post. I&#8217;m extremely excited to welcome Jess Mitchell on board as our new project manager for Fluid. Earlier this week, Jutta Treviranus sent out a <a href="http://fluidproject.org/pipermail/fluid-work/2008-May/001791.html">great introduction to Jess</a>  on the <a href="http://fluidproject.org/mailman/listinfo/fluid-work">fluid-work mailing list</a>. Here&#8217;s a quick excerpt:</p>
<blockquote><p>&#8220;Jess comes with an incredibly rich and relevant background in managing large, complex, distributed projects. She is very familiar with the academic environment, the schools engaged in Fluid and the open source and community source development process. Until recently, Jess was the Innovative Projects Manager at Duke University and managed, among many innovative projects, the Duke Digital Initiative.&#8221;</p></blockquote>
<p>I&#8217;m impressed with how diverse Jess&#8217; background is. She has a firm grasp of technical issues and was a volunteer with the Geekcorps project to <a href="http://en.wikipedia.org/wiki/Ghana_Internet_Exchange">build independent network infrastructure in Ghana</a>. She&#8217;s managed a variety of projects in a higher ed setting, and has taught project courses at Duke University. Her academic background in Political Science and Philosophy  brings a unique perspective on community building and open source culture. And I know she&#8217;s been learning a ton about inclusive design, too!</p>
<p>A quick bit of history: Fluid has been trying to hire a dedicated Project Manager for over a year now. Hiring at a university can be pretty slow and bureaucratic, and we had several promising candidates who were unexpectedly wooed away by offers from the private sector. Throughout this process, we took the time to be sure that we hired someone who will thrive within the unique constraints of a distributed, community-driven environment. I&#8217;m thoroughly confident that Jess will excel in this role, and she is committed to helping us communicate and collaborate better as our community grows.</p>
<p>On a personal level, I&#8217;m relieved by the prospect of being able to focus on technical leadership for Fluid. With all the task-juggling and cat-herding I&#8217;ve done over the past year and a half, it&#8217;s been hard to put enough attention towards architecture and coding. Now that Jess is on board, I&#8217;ll be much more focused on development work. I have a backlog of technical writing and coding to catch up with, so expect to hear a lot more from me on the lists and this blog with code examples, screenshots of new components, and more. </p>
<p>Jess will be based in Boston, but is planning to do a fair bit of traveling over the next few months. She&#8217;s also really interested in hearing from members of the community, so don&#8217;t hesitate to <a href="mailto:&#106;&#101;s&#115;&#109;&#105;&#116;&#99;&#104;&#101;&#108;&#108;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;m">drop her a line</a>. Please join me in welcoming Jess to the Fluid community!</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/05/11/welcoming-jess-mitchell-fluids-new-project-manager/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fluid and JavaScript Toolkits</title>
		<link>http://fluidproject.org/blog/2008/04/20/fluid-and-javascript-toolkits/</link>
		<comments>http://fluidproject.org/blog/2008/04/20/fluid-and-javascript-toolkits/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 03:54:03 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Accessibility]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/04/20/fluid-and-javascript-toolkits/</guid>
		<description><![CDATA[For some time now, I&#8217;ve wanted to update everyone on Fluid&#8217;s recommendations regarding JavaScript toolkits. We&#8217;ve done a lot of research and evaluation of various open source products, and have chosen jQuery as our favoured toolkit. We think the accessibility plugins and utilities we&#8217;ve been writing with jQuery will be useful to a wide range [...]]]></description>
			<content:encoded><![CDATA[<p>For some time now, I&#8217;ve wanted to update everyone on Fluid&#8217;s recommendations regarding JavaScript toolkits. We&#8217;ve done a lot of research and evaluation of various open source products, and have chosen jQuery as our favoured toolkit. We think the accessibility plugins and utilities we&#8217;ve been writing with jQuery will be useful to a wide range of client-side developers. We&#8217;re working closely with the jQuery UI team and the rest of the community to help infuse jQuery UI with keyboard navigation, ARIA roles, and other accessibility features. We&#8217;re really excited about this collaboration and for the prospect of another accessible and usable DHTML toolkit, and we hope you&#8217;ll get involved.</p>
<p><strong>Why Use a JavaScript Toolkit at All?</strong></p>
<p>Quite simply: browser incompatibilities. There are other reasons to use a toolkit, but the foremost among these is the need to work around inconsistencies and bugs across browsers. Despite attempts at defining standards for JavaScript and the Document Object Model (DOM), there are still major differences in the way browsers handle basic constructs such as events, AJAX connections, and style sheets.</p>
<p>Anyone who writes a lot of JavaScript code without a toolkit will end up with an accumulation of workarounds and object detection checks that will eventually amount to a home-grown toolkit. Writing your own cross-browser code usually starts out easily enough, but eventually bogs down in a maze of subtle and obscure workarounds. Most good JavaScript programmers have internalized these incompatibilities over time, but this knowledge is painfully acquired through time-consuming, frustrating debugging sessions. Take a look at <a href="http://www.quirksmode.org/resources.html">Quirks Mode</a> for all the gory details about browser incompatibilities. The bottom line for me: it&#8217;s crazy not to use a JavaScript toolkit.</p>
<p>The decision boils down to cost. Do I want to pay for the all development, maintenance, and testing of an entire JavaScript toolkit? Or do I want to share that cost, and the hard expertise that goes into it, with thousands of other users of a toolkit like jQuery? For Fluid, our priority is to build great user interfaces, not to bang our heads against browser incompatibilities all day. So we knew we had to choose a toolkit.</p>
<p><strong>Evaluating Toolkits</strong></p>
<p>Picking a JavaScript toolkit can be pretty bewildering. The Web 2.0 scene is littered with options, each with very different features, philosophies, and licenses. It&#8217;s analogous to the mess we have on the server side with Java presentation frameworks. Superficially, a wide variety of choice seems like a good thing. But practically, we have a plethora of overlapping, inconsistent options that largely do the same thing. To further complicate matters, the client-side UI world is still in its infancy, so this degree of choice and fragmentation ends up leading to a lot of bugs and incomplete features.</p>
<p>Early on in the project, we came up with a set of <a href="http://wiki.fluidproject.org/display/fluid/Criteria+for+Selecting+a+DHTML+Toolkit">criteria for evaluating DHTML toolkits</a>. These included:</p>
<ul>
<li>Cross-browser support</li>
<li>Easy debugging</li>
<li>Event abstraction</li>
<li>A solid DOM manipulation library</li>
<li>A strong community and clear roadmap for improvements</li>
<li>Accessibility</li>
</ul>
<p>Accessibility is a particularly challenging issue for toolkits, opening up a whole new can of worms for Web developers. The ugly reality is that the vast majority of widgets are completely inaccessible to users who can&#8217;t use the mouse or who require an assistive technology such as a screen reader. Worse yet, the standards and techniques for <a href="http://wiki.fluidproject.org/display/fluid/An+Overview+of+DHTML+Accessibility">DHTML accessibility</a> are still being worked out, and browser support is significantly in flux.</p>
<p>We&#8217;ve been involved in the Dojo community for over a year now, assisting with their efforts to make many of the Dijit widgets more accessible. This work includes keyboard navigation, <a href="http://www.w3.org/TR/wai-aria-roadmap/">ARIA semantics</a>, and high-contrast styling. The whole team has done a first-rate job on Dijit accessibility, and continue to make excellent progress. </p>
<p>Many of you might remember our <a href="http://wiki.fluidproject.org/display/fluid/Proposal+for+Dojo+in+Fluid">initial efforts to use Dojo</a> as the toolkit of choice for Fluid. We built the Reorderer as a Dijit Widget, and used their drag and drop library extensively. Problems ensued. Some were entirely situational; the Dojo community was pushing hard for their 1.0 release and weren&#8217;t able to give as much attention to their drag and drop library as we would have liked. Others were architectural; our unobtrusive, markup-driven approach just didn&#8217;t fit well with Dojo&#8217;s more &#8220;JSF-ish&#8221; style of widget encapsulation. We genuinely hoped to leverage Dojo for Fluid, but ultimately realized that it just wasn&#8217;t aligned with our needs.</p>
<p>With a broken Reorderer and a release deadline looming, we decided to switch. In a week-long sprint, we implemented the Reorderer&#8217;s core using YUI, Ext, jQuery, and MochiKit. We were never able to do a full &#8220;apples-to-apples&#8221; comparison, but we got a pretty good feeling for each toolkit&#8217;s various strengths and weaknesses even though we had to choose quickly. YUI&#8217;s documentation was exceptionally thorough, and its feature set was excellent. MochiKit provided a nice clean library. Dojo widgets had great built-in accessibility. But ultimately, we chose jQuery because it just fit.</p>
<p><strong>jQuery Just Fits</strong></p>
<p>jQuery is a pretty remarkable API to work with because it was built with the skills of Web developers in mind. It leverages familiar Web design/development techniques such as CSS selectors, so it&#8217;s easy to apply the things you already know and get started with it quickly. John Resig, jQuery&#8217;s creator, frequently describes how non-coders are attracted to jQuery because it fits with their &#8220;user mental model&#8221; as a Web developer. And at the same time, it seamlessly encourages the use of good practices such as unobtrusive JavaScript and functional programming.</p>
<p>jQuery has a very small and focussed feature set. I&#8217;ll spare you the usual byte-for-byte comparisons, but it is tiny and carefully organized. jQuery is designed specifically to make the common, tedious tasks of DHTML development faster, easier, and more succinct. If you&#8217;ve done any JavaScript programming, you&#8217;ll know that the vast majority of time is spent finding things in the document and doing stuff with them. Recognizing this, jQuery optimizes the process of searching for elements in the DOM and performing repetitive actions on them. With jQuery, binding event handlers or applying styling to a set of elements becomes a trivial, one-line exercise without the need for verbose loops. A <a href="http://wiki.fluidproject.org/display/fluid/Comparison+of+Event+Binding+Without+a+Toolkit+and+With+jQuery#ComparisonofEventBindingWithoutaToolkitandWithjQuery-eventBinding">code example</a> is probably the best way to illustrate this point.</p>
<p>Unlike other toolkits, jQuery doesn&#8217;t bother with features such as class-based inheritance or other abstractions on top of JavaScript, and the end result is much cleaner and more comprehensible. After the switch to jQuery, our code base got much smaller. Its selectors and chainability encourage terseness in a good way; code that is minimal but clear and well-named. </p>
<p>I also like the fact that jQuery specifically makes it easier to keep your code and markup separate so that they can be changed independently. The browser environment makes separating logic from presentation feasible, and jQuery encourages this by providing quick ways to grab elements in the document and bind handlers to them when the page first loads. jQuery&#8217;s UI widgets are built in such a way that it&#8217;s easy to support <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">progressive enhancement</a>, allowing your pages to to be built on a bed of valid semantic markup which will degrade gracefully on older browsers, mobile devices, and so on. Here&#8217;s an <a href="http://wiki.fluidproject.org/display/fluid/Example+of+jQuery+UI+Tabs+Progressive+Enhancement">example of how jQuery UI Tabs take advantage of progressive enhancement</a>.</p>
<p>For features that don&#8217;t readily fit within jQuery&#8217;s compact core distribution, a &#8220;plugin&#8221; architecture is provided. I&#8217;m using quotes here, since jQuery plugins are written using a <a href="http://www.learningjquery.com/2007/10/a-plugin-development-pattern">simple set of techniques</a> that are based on JavaScript&#8217;s prototypal inheritance. There&#8217;s no special API here; if you already know how to extend objects in JavaScript, you&#8217;ll find jQuery plugins simple to write. A rich set of programming utilities and user interfaces have been released as jQuery plugins by members of the community. I still have reservations about whether the jQuery plugin model is workable in all scenarios. I expect that there will be types of services and components that don&#8217;t naturally fit within the jQuery selection-based model.</p>
<p>I mentioned the community earlier. The jQuery lists are healthy and active, and there&#8217;s a general sense of openness and welcoming from the group. I gather that, in the early days, John Resig took a lot of time out of his day to patiently answer questions, and this has clearly fostered a generous user culture.</p>
<p><strong>How You Can Benefit From Our Commitment to jQuery</strong></p>
<p>We think that a healthy, open Web should include more than one accessible DHTML toolkit. The Mozilla Foundation agrees with us, and have kindly offered us some funding to help mentor the jQuery community on accessibility issues. We&#8217;ll help ensure that the jQuery widget set is accessible, and that there are simple tools available to make third-party jQuery plugins accessible.</p>
<p>Fluid is <a href="http://wiki.fluidproject.org/display/fluid/Fluid+jQuery+Plugins">contributing a lot of the code required by DHTML developers to support accessibility</a> in their own widgets and plugins. And <a href="http://www.outstandingelephant.com/jaria/">other members of the jQuery community are getting involved</a>. We expect a rich set of accessibility and progressive enhancement tools to emerge over the coming months. Many of these accessibility plugins are ready to use now, and we&#8217;d love your feedback and suggestions for how we can improve them in the future.</p>
<p>If you&#8217;re already using jQuery, Fluid&#8217;s components will merge seamlessly with your existing code. Over time, we&#8217;re planning to build jQuery plugin interfaces for many of our components, providing a quick and idiomatic way of using Fluid components in your pages.</p>
<p><strong>Summing Up</strong></p>
<p>There&#8217;s a lot of exciting action going on in the jQuery and Fluid communities these days. The jQuery UI team is on the cusp of releasing jQuery UI 1.5, which will provide a significant reworking of the widget model and opens the door for accessibility code to be easily shared across widgets. Fluid&#8217;s upcoming Infusion 0.3 release is entirely based on jQuery, and we&#8217;re already using a pre-release version of their 1.5 drag and drop library with great success. Expect to see upcoming Fluid components incorporate other jQuery UI widgets, and we&#8217;ll contributing usability and accessibility advice back to the community.</p>
<p>We recognize that not everyone is going to make the same toolkit decisions we did, so we&#8217;ll do our best to ensure that Fluid&#8217;s code plays nice with other toolkits.</p>
<p>Oh, and if you live in Toronto and want to contribute to our work, <a href="http://jobs.ajaxian.com/job/79c46a073be2a7b5b571f16c1db33b43/?d=1&#038;source=site_home">we&#8217;re hiring</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/04/20/fluid-and-javascript-toolkits/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Passing the uCamp Torch</title>
		<link>http://fluidproject.org/blog/2008/04/01/passing-the-ucamp-torch/</link>
		<comments>http://fluidproject.org/blog/2008/04/01/passing-the-ucamp-torch/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 03:30:52 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/04/01/passing-the-ucamp-torch/</guid>
		<description><![CDATA[The Fluid team is in the midst of preparing for our 5th uCamp, this time at the JA-SIG Spring 2008 Conference in St. Paul, Minnesota. Planned as a half-day event on Wednesday, April 30th, it will bring together members of the uPortal, Kuali Student, Sakai, Fluid, and other communities to talk about user experience, design, [...]]]></description>
			<content:encoded><![CDATA[<p>The Fluid team is in the midst of preparing for our <a href="http://www.ja-sig.org/wiki/display/JCON/Spring+2008+Saint+Paul+-+UCamp+Planning">5th uCamp</a>, this time at the <a href="http://www.ja-sig.org/conferences/08spring/index.html">JA-SIG Spring 2008 Conference in St. Paul, Minnesota</a>. Planned as a half-day event on Wednesday, April 30th, it will bring together members of the uPortal, Kuali Student, Sakai, Fluid, and other communities to talk about user experience, design, and accessibility.</p>
<p><strong>What are uCamps?</strong></p>
<p>uCamps are informal, collaborative events designed for the whole spectrum of contributors to successful software projects&#8211;developers, testers, designers, and everyone in between. The idea is to get everyone in a room to discuss UX tools and techniques, share our experience, and collaborate on real projects together. </p>
<p>One of the motivations for starting the uCamp was the belief that everyone should share a basic vocabulary for user experience, and that we should promote techniques that help everyone engage in making open source software better. uCamps were modeled after the <a href="http://www.socialtext.net/dcamp/index.cgi">DCamps</a> organized by Rashmi Sinha and others in the Free/Open Source Software world. They&#8217;re intentionally ad-hoc and informal; bring your ideas, techniques, and inspiration and share them with the group. Our uCamps usually include lightning talks about various design-related topics, hands-on workshops, and time to work with your colleagues.</p>
<p>The uCamps are one of our longest-standing Fluid activities. The first uCamp was held in <a href="http://confluence.sakaiproject.org/confluence/display/UI/Atlanta+Ucamp">Atlanta back in 2006</a>, when Fluid was still just in the proposal phase. A great group of volunteers have worked hard since then to ensure that the uCamps are a central point for UX collaboration within the Sakai and uPortal communities. </p>
<p><strong>Sharing the Effort</strong></p>
<p>As many of you know, Fluid is entering its second year as a project. We dedicated our first year to community building, and the uCamps are one example of our success in this regard. Fluid has become the place to go to talk about and collaborate on great user interfaces in the community source world. In our second year, we want to build on the strong community we&#8217;ve established and focus our efforts on creating new user interface components, design patterns, and the JavaScript framework to support them. </p>
<p>To this end, we&#8217;d like to pass the uCamp torch to other members of the community. The uCamp at the JA-SIG conference in St. Paul&#8217;s will be our last Fluid-funded uCamp for awhile, but we&#8217;d still like to help other motivated members of the community offer them in the future. If you&#8217;re interested in leading the next uCamp, we&#8217;ve got a great page of <a href="http://wiki.fluidproject.org/display/fluid/Fluid+UCamps+-+Planning">resources on how to organize a uCamp</a>. Paul Zablosky, our uCamp Coordinator, is willing to help get you started. And of course, we&#8217;ll be still be here to help with lightning talks and participate in collaborative activities. </p>
<p>A special thanks to everyone who has helped with and participated in the uCamps over the past couple years. And don&#8217;t forget to join us in St. Paul&#8217;s!</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/04/01/passing-the-ucamp-torch/feed/</wfw:commentRss>
		</item>
		<item>
		<title>jQuery Tabindex Plugin</title>
		<link>http://fluidproject.org/blog/2008/01/11/jquery-tabindex-plugin/</link>
		<comments>http://fluidproject.org/blog/2008/01/11/jquery-tabindex-plugin/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 00:11:51 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Accessibility]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/01/11/jquery-tabindex-plugin/</guid>
		<description><![CDATA[In follow up to Simon&#8217;s recent posting about the intricacies of cross-browser support for the tabindex attribute, I&#8217;ve written a jQuery plugin that makes it easy to get, set, and check for the presence of tabindex values.
Getting the Source Code
The source code is currently available in the Fluid Project SVN, and will be included in [...]]]></description>
			<content:encoded><![CDATA[<p>In follow up to Simon&#8217;s recent posting about the <a href="http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/">intricacies of cross-browser support for the tabindex attribute</a>, I&#8217;ve written a jQuery plugin that makes it easy to get, set, and check for the presence of tabindex values.</p>
<p><strong>Getting the Source Code</strong></p>
<p>The <a href="http://source.fluidproject.org/svn/fluid/components/trunk/src/webapp/fluid-components/js/jquery/jquery.keyboard-a11y.js">source code</a> is currently available in the Fluid Project SVN, and will be included in the Fluid 0.3 release. Long term, we hope to include this plugin directly in jQuery UI. <a href="http://source.fluidproject.org/svn/fluid/components/trunk/src/webapp/tests/jquery-tests/js/tabindex-tests.js">jqUnit tests are also available</a>.</p>
<p>This plugin works on FireFox, Safari, Internet Explorer 6+, and Opera 9.5+. If people find this plugin useful, I&#8217;d be happy to contribute it to the jQuery Plugin repository. I&#8217;ve licensed this code in the same manner as jQuery, so it&#8217;s available under a dual GPL/MIT license.</p>
<p><strong>How to Use It</strong></p>
<p>The API is super-simple and should be familiar to jQuery users:</p>
<p><strong><code>jQuery().tabindex()</code></strong><br />
Gets the tabindex value of the first matched element. If the element doesn&#8217;t have a tabindex attribute, <em>undefined</em> is returned. The value returned is normalized to a Number, since browser implementations vary.</p>
<p><strong><code>jQuery().tabindex(value)</code></strong><br />
Sets the tabindex value on all matched elements. <code>value</code> can be either a String or a Number, but valid tabindex attributes need to be integers.</p>
<p><strong><code>jQuery().removeTabindex()</code></strong><br />
Removes the tabindex attribute from all matched elements.</p>
<p><strong><code>jQuery().hasTabindex()</code></strong><br />
Checks for the presence of a tabindex attribute on the first matched element. Returns <em>true</em> if the element has a tabindex attribute, and returns <em>false</em> if tabindex is not set. Neither Simon or I have yet to come up with a reliable method for querying tabindex attributes on versions of IE < 6, so this method will always return false on IE 5.5 and below.</p>
<p><strong>Future Directions</strong></p>
<p>I wrote this tabindex plugin as part of a larger project to build a comprehensive keyboard accessibility plugin for jQuery. While it&#8217;s not quite finished, this plugin will make it easy for developers to add keyboard handlers to their code without a lot of extra overhead. A common problem in the DHTML world is that user interfaces are built to work solely with the mouse, excluding users who need to use the keyboard to navigate. <code>jquery.keyboard-a11y</code> takes the hard work out of making your interfaces usable with the tab and arrow keys.</p>
<p>This is the first library that I know of that provides DHTML keyboard accessibility without requiring you to implement a whole model for widgets. While it doesn&#8217;t solve all your accessibility needs, it&#8217;s designed to work with lots of different types of markup and be consistent with the jQuery approach. Here&#8217;s a quick summary of the API:</p>
<p><strong><code>jQuery().tabbable()</code></strong><br />
Adds all matched elements to the tab order by giving them a tabindex attribute of &#8220;0.&#8221;</p>
<p><strong><code>jQuery().selectable(container, customHandlers, options)</code></strong><br />
Makes all matched elements selectable with the arrow keys. Provide your own <code>customHandlers</code> to inject custom styling and logic. <code>Options</code> lets you modify the plugin&#8217;s default selection behaviour.</p>
<p><strong><code>jQuery().activatable(customHandlers, options)</code></strong><br />
Makes all matched elements activatable with the Spacebar and Enter keys. Provide your own handlers to trigger custom behaviour. <code>Options</code> allow you to activate elements using other keystrokes.</p>
<p><strong>Source Code</strong></p>
<p>The in-progress code for this jQuery keyboard accessibility plugin is freely available. There&#8217;s still a lot of work be done before it will be ready for prime time, but I&#8217;d encourage you to take a look and let me know what you think.</p>
<p><a href="http://source.fluidproject.org/svn/fluid/components/trunk/src/webapp/fluid-components/js/jquery/jquery.keyboard-a11y.js">jquery.keyboard-a11y.js</a></p>
<p><strong>Summary</strong></p>
<p>We&#8217;ve been really excited about using jQuery on the Fluid Project. Our <a href="http://wiki.fluidproject.org/display/fluid/Reorderer">Reorderer</a>, an accessible library for drag-and-drop sorting of elements, is built entirely on jQuery and jQuery UI. We hope these new accessibility plugins will be helpful in enabling greater DHTML accessibility within the jQuery and Fluid communities.</p>
<p>I&#8217;d love to hear your feedback or suggestions for these plugins. Don&#8217;t hesitate to <a href="mailto:colin.clark@utoronto.ca">get in touch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/01/11/jquery-tabindex-plugin/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting, setting, and removing tabindex values with JavaScript</title>
		<link>http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/</link>
		<comments>http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/#comments</comments>
		<pubDate>Wed, 09 Jan 2008 18:31:24 +0000</pubDate>
		<dc:creator>simon</dc:creator>
		
		<category><![CDATA[Accessibility]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/</guid>
		<description><![CDATA[I recently implemented some functions for Dojo for getting, setting, and removing tabindex values. It&#8217;s not entirely straightforward &#8212; here&#8217;s what I found out:
Browsers tested

Internet Explorer 6 on Windows XP
Internet Explorer 7 on Windows XP
Firefox 2 on Windows XP
Firefox 3 beta3pre (the Minefield nightly build of 2008-01-07) on Windows XP
Safari 3.0.4 on Mac OS X [...]]]></description>
			<content:encoded><![CDATA[<p>I recently implemented some functions for Dojo for getting, setting, and removing tabindex values. It&#8217;s not entirely straightforward &mdash; here&#8217;s what I found out:</p>
<p><strong>Browsers tested</strong></p>
<ul>
<li>Internet Explorer 6 on Windows XP</li>
<li>Internet Explorer 7 on Windows XP</li>
<li>Firefox 2 on Windows XP</li>
<li>Firefox 3 beta3pre (the Minefield nightly build of 2008-01-07) on Windows XP</li>
<li>Safari 3.0.4 on Mac OS X 10.5.1</li>
<li>Opera 9.25 on Windows XP</li>
</ul>
<p><strong>Getting the tabindex value from an element</strong></p>
<p><code>Element.tabIndex</code> and <code>Element.getAttribute("tabindex")</code> can be used to get the tabindex value on both HTML and XHTML documents:</p>
<table>
<tr>
<th>input with tabindex=&#8221;1&#8243;</th>
<th>IE6 IE7</th>
<th>FF2 FF3 HTML</th>
<th>Safari 3 HTML</th>
<th>Opera 9 HTML</th>
<th>FF2 FF3 XHTML</th>
<th>Safari 3  XHTML</th>
<th>Opera 9 XHTML</th>
</tr>
<tr>
<td>elem.tabIndex</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>elem.getAttribute(&#8221;tabindex&#8221;)</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>elem.getAttribute(&#8221;tabIndex&#8221;)</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>null</td>
<td>null</td>
<td>null</td>
</tr>
</table>
<p><code>Element.getAttribute("tabIndex")</code> can be used to get the value on HTML documents. However, Firefox, Safari, and Opera treat XHTML documents case-sensitively and, when used on an XHTML document, <code>Element.getAttribute("tabIndex")</code> will return null.</p>
<p><strong>Getting the tabindex value on an element that doesn&#8217;t have one explicitly set</strong></p>
<p>On elements <a href="http://www.w3.org/TR/html401/interact/forms.html#adef-tabindex">allowed to have tabindex attributes in HTML4</a>, the <code>tabIndex</code> property defaults to 0 when no tabindex has been explicitly set:</p>
<table>
<tr>
<th>input with no tabindex</th>
<th>IE6 IE7</th>
<th>FF2 FF3</th>
<th>Safari 3</th>
<th>Opera 9</th>
</tr>
<tr>
<td>elem.tabIndex</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</table>
<p>On elements not allowed to have tabindex attributes in HTML4 (but <a href="http://developer.mozilla.org/en/docs/Key-navigable_custom_DHTML_widgets">supported by IE and Firefox</a> and the upcoming HTML5), the <code>tabIndex</code> property defaults to 0 on Internet Explorer, -1 on Firefox, and undefined on Safari 3 and Opera 9:</p>
<table>
<tr>
<th>div with no tabindex</th>
<th>IE6 IE7</th>
<th>FF2 FF3</th>
<th>Safari 3</th>
<th>Opera 9</th>
</tr>
<tr>
<td>elem.tabIndex</td>
<td>0</td>
<td>-1</td>
<td>undefined</td>
<td>undefined</td>
</tr>
</table>
<p>On Internet Explorer, <code>Element.getAttribute("tabindex")</code> returns 0 on elements that have no tabindex value explicitly set. The other browsers return null:</p>
<table>
<tr>
<th>div with no tabindex</th>
<th>IE6 IE7</th>
<th>FF2 FF3</th>
<th>Safari 3</th>
<th>Opera 9</th>
</tr>
<tr>
<td>elem.getAttribute(&#8221;tabindex&#8221;)</td>
<td>0</td>
<td>null</td>
<td>null</td>
<td>null</td>
</tr>
</table>
<p><strong>Testing if tabindex has been set on an element</strong></p>
<p>On Internet Explorer we can&#8217;t use <code>Element.getAttribute("tabindex")</code> to determine if a tabindex has been specified on an element because it returns 0 even when one hasn&#8217;t been. IE also doesn&#8217;t implement <code>Element.hasAttribute()</code>. However, IE6 and IE7 do implement <code>Element.getAttributeNode()</code> and we can use that (<code>Element.getAttributeNode()</code> is also available on Firefox, Safari, and Opera.) When it is called on Internet Explorer on an element with no tabindex value set, <code>Element.getAttributeNode()</code> will return a node whose <code>specified</code> property is false. When called on Firefox, Safari, and Opera it will return <code>null</code>. For cross-browser compatibility, we can use a test like this:</p>
<pre>var attr = elem.getAttributeNode("tabindex");
return attr ? attr.specified : false;</pre>
<p><strong>Setting the tabindex value on an element</strong></p>
<p><code>Element.setAttribute("tabIndex")</code> must be used on Internet Explorer. Either &#8220;tabindex&#8221; or &#8220;tabIndex&#8221; can be used for HTML on Firefox, Safari, and Opera, but &#8220;tabindex&#8221; must be used for XHTML:</p>
<table>
<tr>
<th>input element</th>
<th>IE6 IE7</th>
<th>FF2 FF3 HTML</th>
<th>Safari 3 HTML</th>
<th>Opera 9 HTML</th>
<th>FF2 FF3 XHTML</th>
<th>Safari 3 XHTML</th>
<th>Opera 9 XHTML</th>
</tr>
<tr>
<td>elem.setAttribute(&#8221;tabindex&#8221;)</td>
<td>N</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<td>elem.setAttribute(&#8221;tabIndex&#8221;)</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>N</td>
<td>N</td>
<td>N</td>
</tr>
</table>
<p><strong>Removing the tabindex value from an element</strong></p>
<p><code>Like <code>setAttribute()</code>, Element.removeAttribute(&#8221;tabIndex&#8221;)</code> must be used on Internet Explorer and either &#8220;tabindex&#8221; or &#8220;tabIndex&#8221; can be used for HTML on Firefox, Safari, and Opera. &#8220;tabindex&#8221; must be used for XHTML:</p>
<table>
<tr>
<th>input element</th>
<th>IE6 IE7</th>
<th>FF2 FF3 HTML</th>
<th>Safari 3 HTML</th>
<th>Opera 9 HTML</th>
<th>FF2 FF3 XHTML</th>
<th>Safari 3 XHTML</th>
<th>Opera 9 XHTML</th>
</tr>
<tr>
<td>elem.removeAttribute(&#8221;tabindex&#8221;)</td>
<td>N</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<td>elem.removeAttribute(&#8221;tabIndex&#8221;)</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>N</td>
<td>N</td>
<td>N</td>
</tr>
</table>
<p><strong>Test files, detailed results, and Dojo implementation</strong></p>
<ul>
<li><a href="http://trac.bitstructures.com/browser/collected/trunk/html-test-cases/getting-tabindex.html?format=raw">HTML test file for getting the tabindex value</a></li>
<li><a href="http://trac.bitstructures.com/browser/collected/trunk/html-test-cases/getting-tabindex.xhtml?format=raw">XHTML test file for getting the tabindex value</a></li>
<li><a href="http://trac.bitstructures.com/browser/collected/trunk/html-test-cases/getting-tabindex-results.html?format=raw">Results for getting the tabindex</a></li>
<li><a href="http://trac.bitstructures.com/browser/collected/trunk/html-test-cases/setting-and-removing-tabindex.html?format=raw">HTML test file for setting and removing the tabindex</a></li>
<li><a href="http://trac.bitstructures.com/browser/collected/trunk/html-test-cases/setting-and-removing-tabindex.xhtml?format=raw">XHTML test file for setting and removing the tabindex</a></li>
<li><a href="http://trac.bitstructures.com/browser/collected/trunk/html-test-cases/setting-and-removing-tabindex-results.txt?format=raw">Results for setting and removing the tabindex</a></li>
<li><a href="http://trac.dojotoolkit.org/browser/dojo/trunk/_base/html.js">Dojo attribute functions (search for &#8220;Element attribute Functions&#8221;)</a></li>
<li><a href="http://trac.dojotoolkit.org/browser/dojo/trunk/tests/_base/html.html">Unit tests for Dojo attribute functions</a></li>
</ul>
<p><strong>Updated 2008-01-10:</strong> corrected removeAttribute(&#8221;tabIndex&#8221;) results</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Summary of the Fluid Summit</title>
		<link>http://fluidproject.org/blog/2007/10/11/a-summary-of-the-fluid-summit/</link>
		<comments>http://fluidproject.org/blog/2007/10/11/a-summary-of-the-fluid-summit/#comments</comments>
		<pubDate>Thu, 11 Oct 2007 04:32:51 +0000</pubDate>
		<dc:creator>colin</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Design]]></category>

		<category><![CDATA[Community]]></category>

		<guid isPermaLink="false">http://fluidproject.org/blog/2007/10/11/a-summary-of-the-fluid-summit/</guid>
		<description><![CDATA[Two weeks ago we held the first Fluid Summit meeting here in Toronto. It was a resounding success, and I&#8217;d like to thank everyone who attended and brought their ideas and proposals to the table. We had a very full week of planning, coding, and  designing. Members of the Sakai, uPortal, Moodle, and Kuali [...]]]></description>
			<content:encoded><![CDATA[<p>Two weeks ago we held the first Fluid Summit meeting here in Toronto. It was a resounding success, and I&#8217;d like to thank everyone who attended and brought their ideas and proposals to the table. We had a very full week of planning, coding, and  designing. Members of the Sakai, uPortal, Moodle, and Kuali Student communities were all present.</p>
<p>For those of you who are interested in Sakai, if you haven&#8217;t already read <a href="http://sakaiblog.korcuska.net/2007/10/04/fluid-and-sakai/">Michael Korcuska&#8217;s blog entry about his impressions of the summit,</a> I&#8217;d encourage you to take a look. He&#8217;s done a great job of outlining his perspectives on our work and Fluid&#8217;s role within the Sakai community.</p>
<p>We also had strong representation from the uPortal community, including Eric Dalquist from UW-Madison, Paul and Jens from UBC, and Jennifery Bourey and Susan Bramhall via videoconference from Yale.</p>
<p>Moodle was represented by the crew from York, who brought with them interesting results from their recent UX Walkthroughs as well as a sneak peek of the new Open VULab remote testing product. Keep an eye out for more information from Ron and his team about the VULab in the coming weeks.</p>
<p>It&#8217;s been a busy two weeks with lots of project coordination tasks arising from the summit, but here&#8217;s my long-awaited summary of the week:</p>
<p><strong>Project Vision and Roadmap</strong></p>
<p>As a whole group, we discussed the project <a href="http://wiki.fluidproject.org/display/fluid/Fluid+Project+2007-9+Release+Plan">release plan</a> and <a href="http://wiki.fluidproject.org/display/fluid/Project+Vision">vision</a>. The release plan outlines the timing and deliverables for each of our quarterly release milestones, starting with a 0.1 version of the Fluid technology and UX Toolkit later this month, and culminating in a 1.0 release in March 2009. More detail needs to be fleshed out in this document based on the results coming out of our design working groups, but I think it outlines the overall structure and deliverables of the projects quite well.</p>
<p>The vision statement is a work in progress. In my mind, the challenge of writing a good project vision is to capture the goals and philosophy of the project at a high level, while still managing to keep it succinct and focussed. I&#8217;ll be revising this document in the coming weeks, and I&#8217;d appreciate any feedback you may have. </p>
<p><strong>Architecture</strong></p>
<p>The technical group discussed the latest <a href="http://wiki.fluidproject.org/display/fluid/Architecture+Overview">overview of the Fluid architecture plan</a>. One of my goals in revising the architecture overview was to provide more information about the current reality of the Fluid framework and a clearer picture of how we think the framework will evolve as we build new and more complex components. Many of the technical discussions at the summit centered around the requirements for a contract between client and server. In time for the 0.1 release, we&#8217;ll be creating comprehensive documentation about the contract of the Reorderer and other Fluid components within the wiki.</p>
<p>We also talked a lot about how a Fluid component is defined from the technical perspective. In short, a component is a reusable, embeddable chunk of user interface can be adapted to suit different contexts. A Fluid component is more than just a widget, embodying a larger workflow or activity within the system that may cut across multiple tools or portlets.</p>
<p>Technically-speaking, Fluid components are built using JavaScript, HTML, and CSS running on the client. Component logic is composed from smaller units of functionality, providing a built-in model for flexibility and adaptation. Layout handlers, keyboard bindings, and other UI behaviour can be extended or customized by setting properties of the component. A component collaborates with service logic on the server, including the request handling and markup generation capability of a server-side presentation framework.</p>
<p>I&#8217;ve pared back some of the fuzzier aspects of the architecture, including the component container, since we haven&#8217;t yet seen a need for strict life cycle control over components. I suspect that as we build up larger components with a lot of configurable properties, we may reintroduce the concept of a component container to handle some inversion of control functionality on the client. This will help make it easier to build a component out of parameterizable chunks of behaviour and wire them up at runtime. In the meantime, our approach to using standard markup and RESTful server-side conventions provides sufficient support for pluggable, reusable UI components without need for the container.</p>
<p><strong>Client-Side JavaScript Toolkits</strong></p>
<p>Joseph Scheuhammer presented an <a href="http://wiki.fluidproject.org/display/fluid/JavaScript+Toolkits+Summit+Discussion">analysis of JavaScript toolkits</a>, outlining the issues to consider when selecting a toolkit for Fluid. I think this is a very insightful analysis and is worth taking a look at. </p>
<p>Simon Bates presented the accessibility work his team here at the ATRC has been doing on the <a href="http://www.dojotoolkit.org">Dojo Toolkit</a>. It was clear that the work invested in Dojo accessibility has the potential to provide a substantial benefit to Fluid, allowing us to adopt and reuse the Dijit widget set without having to write a lot of extra code to make them accessible. Dojo is the only toolkit to date that has made a commitment to built-in accessibility. On the other hand, the technical group at the summit raised some valid concerns about Dojo&#8217;s architectural approach, particularly in light of our desire to leverage server-generated markup where appropriate.</p>
<p>Ultimately, the technical team at the summit agreed to bring a draft proposal to the community recommending the use of Dojo for building Fluid components. We&#8217;re still free to use non-Dojo widgets where necessary, but there will be a greater responsibility to ensure consistency and accessibility if we do so. With this recommendation comes a commitment to get more involved in the Dojo community and help to support and influence its direction. </p>
<p>I&#8217;ll send out a separate email documenting this proposal soon, and we&#8217;d like lots of feedback from the community about this decision. Given the lingering concerns about Dojo&#8217;s fit with Fluid&#8217;s architecture, we&#8217;ll revisit this recommendation over the next few months to assess its success.</p>
<p><strong>Server-Side Presentation Frameworks</strong></p>
<p>The technical team at the summit chose not to recommend a particular server-side presentation framework at this time. Instead, our approach is to incrementally define a set of requirements that any server-side presentation framework may conform to. We&#8217;ll build these requirements up as we create more examples of Fluid components and refine their communication with the server. Ultimately this will lead to a thin binding layer between client and server that we will implement ourselves in at least <a href="http://www2.caret.cam.ac.uk/rsfwiki/">RSF</a>and uPortal&#8217;s XML-based presentation pipeline. Spring Web/Portlet MVC is being considered as well. Users of other presentation frameworks will be able to implement this binding layer in their technology of choice, and are encouraged to do so.</p>
<p>During the technical sessions, we all recognized the hard work that Antranig Basman and the RSF team have invested in making RSF excel at delivering the markup and bindings required to enable cross-cutting user interface components on the server-side. If you&#8217;re working on a new tool or portlet, I&#8217;d suggest giving RSF serious consideration. I think there is going to be a lot of complimentary back-and-forth between the Fluid framework and RSF, particularly around the <a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=UniversalViewBus">Universal View Bus</a>, RSF&#8217;s strategy for client-side messaging.</p>
<p><strong>Coding Session and Technical Working Groups</strong></p>
<p>On Thursday, the technical group broke up into smaller teams to do some coding and flesh out a few key areas for the Fluid architecture. Eric, Anastasia Cheetham, Joseph, and Antranig all worked on <a href="http://wiki.fluidproject.org/display/fluid/Reorderer+in+uPortal">integrating the Reorderer with uPortal&#8217;s drag and drop layout preferences</a>. This will provide a more accessible solution for directly rearranging portals, tabs, and columns, and is expected to be complete in time for the uPortal 3 release in December. The technical solution cooked up by this team is really quite remarkable, and you can find more discussion of their work on the uPortal-dev and fluid-work lists.</p>
<p>Aaron Zeckoski and Michelle D&#8217;Souza worked on a new accessible <a href="http://wiki.fluidproject.org/display/fluid/AutoComplete+Component">AutoComplete component</a> based on the Dijit ComboBox widget. While in itself this is a very small component by Fluid standards, Aaron and Michelle started in on the coding work required to make all Dijit widgets bind seamlessly with RSF.</p>
<p>I missed out on most of the coding session, but had an opportunity instead to discuss the challenges of user experience development in open source communities with Sakai&#8217;s new ED, Michael Korcuska, and a few of the Sakai board members who were at the summit. I&#8217;m really impressed with Michael&#8217;s work so far, and am looking forward to Fluid&#8217;s involvement in the new Sakai UX initiative.</p>
<p><strong>User Experience Working Groups</strong></p>
<p>One of my favourite things about leading the Fluid Project is the opportunity to be involved in the design process with our UX experts. Unfortunately at the summit I wasn&#8217;t able to spend as much time in the UX meetings as I would have liked, but the team has posted a <a href="http://wiki.fluidproject.org/display/fluid/Summit+UX+Summary">great summary of the topics they discussed</a> and their planned next steps.</p>
<p>During the week, the UX group worked extremely hard to sift through a lot of raw data collected during recent UX Walkthroughs. They identified a number of problem areas that are common across all our participating projects, and <a href="http://wiki.fluidproject.org/pages/viewpage.action?pageId=1706283">prioritized them based on both the frequency and severity of the problems</a>. Based on this, the UX group has formed a number of smaller design teams that will delve deeper into specific areas and start designing solutions for the highest-priority issues. These teams will be creating new designs in the areas of <a href="http://wiki.fluidproject.org/display/fluid/Navigation+Problem+Space">Navigation</a>, <a href="http://wiki.fluidproject.org/display/fluid/Feedback+Problem+Space">User Feedback</a>, <a href="http://wiki.fluidproject.org/display/fluid/File+Management+Problem+Space">File Management</a> and <a href="http://wiki.fluidproject.org/display/fluid/File+Management+Problem+Space">Workflow</a>. It will take a bit more time before we start to see implementable components emerging from these working groups, but I&#8217;m enthusiastic about their progress to date. If you haven&#8217;t already, please consider getting involved in one of the groups and helping to design new Fluid components.</p>
<p><strong>Wrapping Up</strong></p>
<p>The most remarkable part of the summit for me was the combined sessions held with the whole group of 30 or so attendees. It was clear to me that we&#8217;ve built an effective community of contributors who are dedicated to fostering usability and accessibility within our projects. Over the five days of the summit, we worked through a vast array of topics, defining solid plans and next steps for all aspects of the project.</p>
<p>Now&#8217;s a great time to get involved in Fluid. Join a design team, contribute to the technical development, or lend a hand preparing for the upcoming 0.1 release. If you&#8217;d like to help out, or have questions about our work, please feel free to drop a note to the <a href="http://fluidproject.org/mailman/listinfo/fluid-work">fluid-work mailing list </a>or get in touch with me directly.</p>
]]></content:encoded>
			<wfw:commentRss>http://fluidproject.org/blog/2007/10/11/a-summary-of-the-fluid-summit/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
