<?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>Ajax Bestiary &#187; prototype</title>
	<atom:link href="http://www.ajaxbestiary.com/category/prototype/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ajaxbestiary.com</link>
	<description>AJAX Development, News, Techniques &#38; More</description>
	<lastBuildDate>Wed, 01 Feb 2012 12:46:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Loopy Optimizations</title>
		<link>http://www.ajaxbestiary.com/2012/01/16/loopy-optimizations/</link>
		<comments>http://www.ajaxbestiary.com/2012/01/16/loopy-optimizations/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 19:11:18 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[loops]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=623</guid>
		<description><![CDATA[We all know that code optimization is important, especially when processing large quantities of data. It is also common knowledge that adding layers of code to loops reduces performance. Except this maxim doesn&#8217;t always hold when it comes to JavaScript in browsers and even native methods can vary wildly in performance. In fact, in almost [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>We all know that code optimization is important, especially when processing large quantities of data. It is also common knowledge that adding layers of code to loops reduces performance. Except this maxim doesn&#8217;t always hold when it comes to JavaScript in browsers and even native methods can vary wildly in performance. In fact, in almost all cases, Underscore, jQuery and YUI outperformed any of the native methods. Interestingly, the newest implementation for native looping, forEach, consistently trumped a traditional <code>for (var i = 0; i &lt; 2500; i++)</code> loop.</p>
<p>I set up a testing framework that looped through a normal array instantiated like so:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> v <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//This value doesn't seem to affect performance at the data size I chose</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> loops<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">//loops is defined elsewhere</span>
   data.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p>I looped through this array using the following methods:</p>
<ul>
<li>for loop</li>
<li>for &#8230; in &#8230; loop</li>
<li>forEach loop (not supported in IE9 Quirks Mode)</li>
<li>Prototype 1.7: Enumerable.each</li>
<li>jQuery 1.7.1: $.each</li>
<li>Underscore 1.2.3: _.each</li>
<li>YUI 3.1.4: YUI.each</li>
</ul>
<p>Each loop was passed the value of the array element and returned immediately, like so:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">//From the native for and for ... in ... tests</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>I eventually settled upon an array of 2500 elements and running the test 200 times to collect a reasonable number of samples. These numbers were not chosen arbitrarily. Prototype would time out on Firefox at 5000 array elements and Safari seemed to have wildly varying results on each run of the suite with fewer than 200 samples. With 200 samples, the variance in mean time between runs became a few hundredths of a millisecond, not enough to be of consequence. Disturbingly, while Prototype froze the browser with 5000 array elements and 100 samples, it had no issue with 2500 elements and 200 samples. Even so, with some tests averaging less than a hundredth of a millisecond, we will soon require much larger data sets to get meaningful results at all, which may preclude the inclusion of Prototype (and even native methods!) in future tests.</p>
<p>All tests were run in a freshly launched browser on an updated operating system (either MacOS 10.7.2 or Windows 7 Home Premium) running on a MacBook Pro with a 2.53GHz Intel Core 2 Duo processor and 4GB of 1067MHz DDR3 RAM. Firefox had all add-ons disabled and Internet Explorer had the Developer Tools open (to switch between Standards and Quirks mode).</p>
<p>So let&#8217;s look at some charts!</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/mac-safari.png" alt="Mac safari" title="mac-safari.png" border="0" width="600" height="337" /><br />
This was certainly an interesting start to the process. YUI, Underscore and jQuery all clocked in at 0.005 ms. Prototype would prove to be faster than native methods, with the exception of forEach, on all browsers. Underscore was only be outperformed on IE 9 (32-bit, Standards Mode).</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/mac-chrome.png" alt="Mac chrome" title="mac-chrome.png" border="0" width="600" height="338" /><br />
Chrome was exceptional as well, with the traditional for loop actually running slower than <code>for ... in ...</code>. This behavior was also seen on Chrome for Windows and Safari for Windows.</p>
<p>Since all of the major browsers are clearly pre-optimized for these libraries (as they themselves wrap the native looping language structures), let&#8217;s look at just the libraries:<br />
<img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/all-libraries.png" alt="Loop run times, by library" title="loop-by-library.png" border="0" width="600" height="338" /><br />
Here we can begin to see that Prototype really is behind its peers in loop performance. While we are talking fractions of a millisecond, our apps are growing larger by the day and this could become a serious issue.</p>
<p><a href="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/sans-prototype.png"><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/sans-prototype.png" alt="Run times of non-prototypical libraries by browser" title="sans-prototype.png" border="0" width="600" height="399" /></a><br />
Hey! It looks like Firefox really is slow. Curiously, IE 9 is significantly faster, which flies in the face of most generalized JavaScript performance metrics.</p>
<p>Still, something looks odd about IE:<br />
<img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/ie9-libraries.png" alt="Run times by library and version of Internet Explorer 9" title="mac-chrome.png" border="0" width="600" height="338" /><br />
Your mileage varies wildly depending on whether you choose standards or quirks mode, and not always in obvious ways. In general, 64-bit is faster, but only marginally, and most people are not using it. (You have to explicitly launch it, as it is not the default, even on 64-bit Windows). Meanwhile, quirks mode apparently embeds some performance hacks. As a note to benchmark developers, this should be evidence enough that not all IE&#8217;s are the same and we need to start breaking down by rendering mode and compilation.</p>
<p>So far, we&#8217;ve seen the average times and most browsers are quite acceptable. What are the worst case scenarios?</p>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<p>Platform</p>
</td>
<td>
<p>Browser</p>
</td>
<td>
<p>Method</p>
</td>
<td>
<p>Max (ms)</p>
</td>
<td>
<p>Mean (ms)</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Quirks)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>93</p>
</td>
<td>
<p>5.29</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Standards)</p>
</td>
<td>
<p>forEach</p>
</td>
<td>
<p>81</p>
</td>
<td>
<p>4.04</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Quirks)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>81</p>
</td>
<td>
<p>6.27</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Standards)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>76</p>
</td>
<td>
<p>9.87</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Standards)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>71</p>
</td>
<td>
<p>4.89</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Quirks)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>67</p>
</td>
<td>
<p>5.995</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Firefox 9.0.1</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>55</p>
</td>
<td>
<p>1.885</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Firefox 9.01</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>52</p>
</td>
<td>
<p>6.055</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Quirks)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>49</p>
</td>
<td>
<p>4.66</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Standards)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>48</p>
</td>
<td>
<p>4.76</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Standards)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>39</p>
</td>
<td>
<p>7.845</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Chrome 16.0.912.75 m</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>30</p>
</td>
<td>
<p>1.13</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Chrome 16.0.912.75 m</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>26</p>
</td>
<td>
<p>1.315</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Chrome 16.0.912.75</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>23</p>
</td>
<td>
<p>1.175</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Chrome 16.0.912.75</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>22</p>
</td>
<td>
<p>1.085</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Safari 5.1.2</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>16</p>
</td>
<td>
<p>1</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Firefox 9.01</p>
</td>
<td>
<p>jQuery</p>
</td>
<td>
<p>6</p>
</td>
<td>
<p>0.185</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Safari 5.1.2</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>5</p>
</td>
<td>
<p>0.52</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Firefox 9.0.1</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>5</p>
</td>
<td>
<p>0.7</p>
</td>
</tr>
</table>
<p>Those averages hid some extreme variations within Internet Explorer. Fortunately, most of these are found using native language structures, which we know better than to use.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2012/01/16/loopy-optimizations/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Converting Between Wiki Markup &amp; HTML with Prototype: Part 2 ListsAt</title>
		<link>http://www.ajaxbestiary.com/2008/12/19/converting-between-wiki-markup-html-with-prototype-part-2-listsat/</link>
		<comments>http://www.ajaxbestiary.com/2008/12/19/converting-between-wiki-markup-html-with-prototype-part-2-listsat/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 15:00:26 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Convert]]></category>
		<category><![CDATA[Curry]]></category>
		<category><![CDATA[Wiki]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=337</guid>
		<description><![CDATA[At the end of part 1 of the series, the system could easily handle direct replacement of certain html entities with their wiki markup counterparts.  Unfortunately this was a pretty limited implementation that could only handle those entities that had a direct, symmetrical relationship with html.  In the case of lists, we have to keep track of [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>At the end of part 1 of the series, the system could easily handle direct replacement of certain html entities with their wiki markup counterparts.  Unfortunately this was a pretty limited implementation that could only handle those entities that had a direct, symmetrical relationship with html.  In the case of lists, we have to keep track of depth and better cleanup the input text.  We also need to enforce default behavior on the input stream.</p>
<p>Since lists are dependent on dedicated whitespace as part of their markup, we need to clear out all unnecessary white space from the html before processing it.  To do this, we simply replace all whitespace characters with an innocuous single space to remove any extra new lines.</p>
<p><code>$(textNode).innerHTML = $(textNode).innerHTML.gsub( '\s', '' );</code></p>
<p>Next we need to cleanup the recursion.  Since we need to know significantly more about the given node to properly assess it.  We can replace the Prototype templates with simple curried function calls and migrate the recursion to the curried methods.<br />
<code><br />
var ConverterTable = {<br />
strong: Converter.curry("'''", null, true),<br />
b:  Converter.curry("'''" , null, true),<br />
em: Converter.curry( "''"  , null, true ),<br />
i:  Converter.curry( "''"  , null, true ),<br />
h1: Converter.curry( '='  , null, false ),<br />
h2: Converter.curry( '=='  , null, false ),<br />
h3: Converter.curry( '==='  , null, false ),<br />
h4: Converter.curry( '===='  , null, false ),<br />
h5: Converter.curry( '====='  , null, false ),<br />
h6: Converter.curry( '======' , null, false ),<br />
ul: Converter.curry('', {li:Converter.curry(['* ', ''], null, false)}, false),<br />
ol: Converter.curry('', {li:Converter.curry(['# ', ''], null, false)}, false),<br />
p:  Converter.curry(['','\n'], null, false)<br />
};<br />
</code><br />
The parameters passed into the individual rules are<br />
The Markup String or an array of strings for start and end tags<br />
An optional library of child rules.  These rules will be applied to any children of the given node before the default rules are applied.<br />
An indication as to the ‘inline-ability’ of the given tag.  This controls the bracketing of the resulting markup with ‘\n’ characters.</p>
<p>The modified Converter now looks to apply rules in the following order<br />
If the node is marked as a stopping point, no recursion proceeds on the branch.<br />
If any over-ridden child rules exist for the given tag, those rules are applied and a memo is passed on to child nodes to denote the depth of the recursion.<br />
Any default rules are processed as per the earlier versions of the code.  Note.  A prototype template is no longer used in favor of simple string construction.<br />
The node itself is removed from the DOM.</p>
<p><code>function Converter( markupString, nestedRules, inline, textNode, memo ){</code></p>
<p>var startString, endString;<br />
inline = inline ? &#8221; : &#8216;\n&#8217;;<br />
memo = memo ? memo : &#8221;;<br />
var children =  textNode.childElements();</p>
<p>if( typeof markupString == &#8216;object&#8217;){<br />
startString = inline + markupString[0];<br />
endString = markupString[1] + inline;<br />
} else {<br />
startString = inline + markupString;<br />
endString = markupString + inline;<br />
}</p>
<p>for( i in children){<br />
if( typeof children[i] != &#8216;function&#8217;){<br />
if( nestedRules &amp;&amp; typeof nestedRules[children[i].tagName.toLowerCase()] == &#8216;function&#8217;){<br />
startString =  memo.strip() + startString;<br />
nestedRules[ children[i].tagName.toLowerCase() ]( children[i], startString);<br />
} else if( typeof ConverterTable[children[i].tagName.toLowerCase()] == &#8216;function&#8217;){<br />
ConverterTable[children[i].tagName.toLowerCase() ](children[i]);<br />
} else { Converter( &#8221;, nestedRules, true, children[i]), memo }<br />
}<br />
}<br />
textNode.replace(  startString + textNode.innerHTML + endString  );<br />
}</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2008/12/19/converting-between-wiki-markup-html-with-prototype-part-2-listsat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Converting Between Wiki Markup &amp; HTML with Prototype</title>
		<link>http://www.ajaxbestiary.com/2008/12/18/converting-between-wiki-markup-html-with-prototype/</link>
		<comments>http://www.ajaxbestiary.com/2008/12/18/converting-between-wiki-markup-html-with-prototype/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 15:00:07 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Conversion]]></category>
		<category><![CDATA[Wiki]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=334</guid>
		<description><![CDATA[Wiki&#8217;s are amazing and powerful tools, unfortunately their dependence on specialized markup creates a huge barrier to their general adoption in many organizations.  This is a first step at building a wysiwyg editor for wiki markup.  While I will be focussing on the syntax unique to the popular MediaWiki platform, these techniques should be applicable [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Wiki&#8217;s are amazing and powerful tools, unfortunately their dependence on specialized markup creates a huge barrier to their general adoption in many organizations.  This is a first step at building a wysiwyg editor for wiki markup.  While I will be focussing on the syntax unique to the popular MediaWiki platform, these techniques should be applicable to any wiki system.</p>
<p>The general flow of the converter is as follows:</p>
<ol>
<li>Converter is passed the root node of an html fragment to translate.</li>
<li>Converter recurses through each of the child nodes and converts them.</li>
<li>Root node tag is replaced with wiki markup.</li>
</ol>
<p>There&#8217;s really only 2 key components involved in this first pass. A converter object and the recursive method.</p>
<h3>The Converter Object</h3>
<p>The converter object is little more than a collection of name value pairs.  The name corresponds to an html tag.  The value is a Prototype template to use in the direct replacement of the given node. By convention we&#8217;ll write all of the tag names for the converter object in lower case.<br />
<code><br />
var Converter = {<br />
strong: new Template("'''#{body}'''"),<br />
b:  new Template("'''#{body}'''"),<br />
em: new Template("''#{body}''"),<br />
i:  new Template("''#{body}''"),<br />
h1: new Template('=#{body}='),<br />
h2: new Template('===#{body}=='),</code><br />
h3: new Template(&#8216;===#{body}===&#8217;),<br />
h4: new Template(&#8216;====#{body}====&#8217;),<br />
h5: new Template(&#8216;=====#{body}=====&#8217;),<br />
h6: new Template(&#8216;======#{body}======&#8217;)  }</p>
<h3>The Converter Function</h3>
<p>The Converter function always performs 2 checks before attempting to convert a given node.  First it ensures that the node is in fact a node and not a stray function from the Prototype enhanced object.  Next it verifies that a converter exists for the tag.  The toLowerCase() on the tagName is necessary due to the inconsistent behavior browsers demonstrate with this attribute.  While all browsers return the variable in all caps for traditional html, they are not reliable about returning lower case values for xhtml markup.</p>
<p><code>function convertToWiki( textNode ){<br />
//make sure textNode isn't a function on the object<br />
if( typeof textNode != 'function'){</code></p>
<p><code>//provide a way to stop execution on select sub trees<br />
if( !textNode.hasClassName( 'stop')){<br />
$(textNode).childElements().each( convertToWiki );<br />
}</code></p>
<p><code>//make sure a converter exists for the given tag<br />
if( liteConverter[ textNode.tagName.toLowerCase() ] ){</code></p>
<p><code> </code></p>
<p><code>//replace the text node with a converted version of itself<br />
textNode.replace(	liteConverter[textNode.tagName.toLowerCase()]<br />
.evaluate({body:textNode.innerHTML}));<br />
} } }</code></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2008/12/18/converting-between-wiki-markup-html-with-prototype/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WysiHat Prototype Based Rich Text Editor</title>
		<link>http://www.ajaxbestiary.com/2008/10/21/wysihat-prototype-based-rich-text-editor/</link>
		<comments>http://www.ajaxbestiary.com/2008/10/21/wysihat-prototype-based-rich-text-editor/#comments</comments>
		<pubDate>Tue, 21 Oct 2008 19:59:31 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[prototype]]></category>
		<category><![CDATA[Editor]]></category>
		<category><![CDATA[WYSIWYG]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=330</guid>
		<description><![CDATA[37 Signals has recently announced a new open source rich text editor built on protoype. It&#8217;s a unique take on the Rich Text Editor that focuses on developers over the kitchen sink. WysiHat is a WYSIWYG JavaScript framework that provides an extensible foundation to design your own rich text editor. WysiHat stays out of your way and [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>37 Signals has recently announced a new open source rich text editor built on protoype.</p>
<p>It&#8217;s a unique take on the Rich Text Editor that focuses on developers over the kitchen sink.</p>
<blockquote><p>WysiHat is a <span>WYSIWYG</span> JavaScript framework that provides an extensible foundation to design your own rich text editor. WysiHat stays out of your way and leaves the UI design to you. Although WysiHat lets you get up and running with a few lines of code, the focus is on letting you customize it.</p></blockquote>
<p>Check it out here:<br />
<a href="http://github.com/37signals/wysihat/tree/master"> http://github.com/37signals/wysihat/tree/master</a></p>
<p>And Read the announcement here:<br />
<a href="http://www.37signals.com/svn/posts/1330-introducing-wysihat-an-eventually-better-open-source-wysiwyg-editor">Introducing WysiHat: An eventually better open source WYSIWYG editor</a></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2008/10/21/wysihat-prototype-based-rich-text-editor/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ajax24&#8242;s Drop Tabs.  A Creative Take on The Tab Box for Scriptaculous</title>
		<link>http://www.ajaxbestiary.com/2008/04/06/ajax24s-drop-tabs-a-creative-take-on-the-tab-box-for-scriptaculous/</link>
		<comments>http://www.ajaxbestiary.com/2008/04/06/ajax24s-drop-tabs-a-creative-take-on-the-tab-box-for-scriptaculous/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 02:18:06 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[Scriptaculous]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[tabs]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=314</guid>
		<description><![CDATA[Tab Boxes are one of the most ubiquitous and popular of widgets. They pop up in everything from news sites to accounting software and for good reason. After all, tabs are one of the simplest and most efficient ways to cram more into a given block of screen real-estate than would fit otherwise. Ajax24&#8242;s drop [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Tab Boxes are one of the most ubiquitous and popular of widgets.  They pop up in everything from news sites to accounting software and for good reason.  After all, tabs are one of the simplest and most efficient ways to cram more into a given block of screen real-estate than would fit otherwise.</p>
<p><a href="http://www.ajaxbestiary.com/wp-content/uploads/2008/04/ajax24tabs.png"><img class="alignnone size-full wp-image-315" title="ajax24tabs" src="http://www.ajaxbestiary.com/wp-content/uploads/2008/04/ajax24tabs.png" alt="" width="500" height="104" /></a></p>
<p>Ajax24&#8242;s drop tabs replace the normal tab-box behavior concept with a twist.  THese tabs pull blocks of content down from a tab bar to make them available and float them above the background content. (think window blinds or drawers as opposed to tabbed sheets of paper).  I have a few reservations about the use of a widget with such slightly unconventional behavior.  But all in all, the smooth motions of the widget and it&#8217;s novelty surely warrant exploration in more playful interfaces.</p>
<p>You can find the widget at</p>
<p><a href="http://www.flash-free.org/en/2008/04/05/e24tabmenu-–-menu-desplegable-ajax/">http://www.flash-free.org/en/2008/04/05/e24tabmenu-–-menu-desplegable-ajax/</a></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2008/04/06/ajax24s-drop-tabs-a-creative-take-on-the-tab-box-for-scriptaculous/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Templates in Prototype</title>
		<link>http://www.ajaxbestiary.com/2008/03/17/templates-in-prototype/</link>
		<comments>http://www.ajaxbestiary.com/2008/03/17/templates-in-prototype/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 01:59:17 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[prototype]]></category>
		<category><![CDATA[Templates]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/2008/03/17/templates-in-prototype/</guid>
		<description><![CDATA[ As much as I love jQuery, prototype templates have made it into more than one of my projects because of their versatility and ease of use.  They are a capable and amazing tool for formatting and displaying output on the client side and I thought I&#8217;d take a few minutes to dive into them. So [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p> As much as I love jQuery, prototype templates have made it into more than one of my projects because of their versatility and ease of use.  They are a capable and amazing tool for formatting and displaying output on the client side and I thought I&#8217;d take a few minutes to dive into them.</p>
<p>So what are templates.  In short they are a string with symbols embedded that are replaced at the time of evaluation to create a new string.  For example:<br />
<code><br />
var apple = { fruit: "apple", variety: "honeycrisp" };</code></p>
<p><code>var templ = new Template( "My favorite fruit are #{variety} #{apple}s."  );</code></p>
<p><code>console.log(  templ.evalaluate( apple ));</code></p>
<p><code>&gt;&gt;&gt; My favorite fruit are honeycrisp apples.</code></p>
<p>This basic example is really all there is to templates.  But, they can be incredibly useful for formatting and displaying JSON data. and repurposing things in universal ways across an app.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2008/03/17/templates-in-prototype/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Widget.Blender Smooth Image Morphs For Prototype</title>
		<link>http://www.ajaxbestiary.com/2008/01/11/widgetblender-smooth-image-morphs-for-prototype/</link>
		<comments>http://www.ajaxbestiary.com/2008/01/11/widgetblender-smooth-image-morphs-for-prototype/#comments</comments>
		<pubDate>Fri, 11 Jan 2008 14:27:03 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[prototype]]></category>
		<category><![CDATA[Scriptaculous]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Image]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/2008/01/11/widgetblender-smooth-image-morphs-for-prototype/</guid>
		<description><![CDATA[Widget.Blender is a handy prototype class to smoothly animate a fade/morph transition between images Features Start &#38; Stop can be triggered by events Autosizing &#38; Wrapping can be controlled Ability to set a standard base url / dir for all images Ability to start at any arbitrary image Ability to run arbitrary function before blend [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Widget.Blender is a handy prototype class to smoothly animate a fade/morph transition between images</p>
<p>Features</p>
<ul>
<li>Start &amp; Stop can be triggered by events</li>
<li>Autosizing &amp; Wrapping can be controlled</li>
<li>Ability to set a standard base url / dir for all images</li>
<li>Ability to start at any arbitrary image</li>
<li>Ability to run arbitrary function before blend (Useful for setting caption to display along with image)</li>
<li>Supported Browsers:
<ul>
<li>Firefox 2</li>
<li>Opera 9</li>
<li>IE 6</li>
<li>IE 7</li>
<li>Safari</li>
</ul>
</li>
</ul>
<p>Check out Widget.Blender at:</p>
<p><a href="http://www.eternal.co.za/scripts/blender/index.html">http://www.eternal.co.za/scripts/blender/index.html </a></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2008/01/11/widgetblender-smooth-image-morphs-for-prototype/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making The Browser &quot;Aware&quot; of AJAX Requests</title>
		<link>http://www.ajaxbestiary.com/2008/01/10/making-the-browser-aware-of-ajax-requests/</link>
		<comments>http://www.ajaxbestiary.com/2008/01/10/making-the-browser-aware-of-ajax-requests/#comments</comments>
		<pubDate>Thu, 10 Jan 2008 14:05:53 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[prototype]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Behavior]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/2008/01/10/making-the-browser-aware-of-ajax-requests/</guid>
		<description><![CDATA[I recently discovered a fascinating prototype extension called LOAJAX. While the effect of the extension is a bit hard to describe, it&#8217;s immediately obvious when you try the demo&#8217;s with and without it. Basically, LOAJAX uses an iFrame crutch to make the browser display all of the interface elements associated with a page load. How [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>I recently discovered a fascinating prototype extension called LOAJAX.  While the effect of the extension is a bit hard to describe, it&#8217;s immediately obvious when you try the demo&#8217;s with and without it.  Basically, LOAJAX uses an iFrame crutch to make the browser display all of the interface elements associated with a page load.</p>
<p>How it works:</p>
<ol>
<li><font color="#333333">A normal AJAX XMLHttpRequest is triggered by the AJAX application.</font></li>
<li><font color="#333333">LOAJAX creates a hidden iframe that points to a server script. </font></li>
<li><font color="#333333">The browser displays loading behavior while the iframe loads its source.</font></li>
<li><font color="#333333">The Server Script consists of a massive wait so the load never completes.</font></li>
<li><font color="#333333">When the XMLHttpRequest is completed, LOAJAX stops the iframe load and removes it from the DOM.</font></li>
<li><font color="#333333">The browser stops displaying page load indicators.</font></li>
</ol>
<p>You can find more about LOAJAX and check out the demo here:</p>
<p><a href="http://blog.loajax.com/" title="http://blog.loajax.com/">http://blog.loajax.com/</a></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2008/01/10/making-the-browser-aware-of-ajax-requests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proto.IPS A Fast and Easy Prototype Based Type In Place Combo Box</title>
		<link>http://www.ajaxbestiary.com/2007/12/25/protoips-a-fast-and-easy-prototype-based-type-in-place-combo-box/</link>
		<comments>http://www.ajaxbestiary.com/2007/12/25/protoips-a-fast-and-easy-prototype-based-type-in-place-combo-box/#comments</comments>
		<pubDate>Wed, 26 Dec 2007 02:56:00 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[prototype]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[edit in place]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/2007/12/25/protoips-a-fast-and-easy-prototype-based-type-in-place-combo-box/</guid>
		<description><![CDATA[Meet Proto.IPS a fast and easy prototype based combo box modeled after the gMail Chat Widget. Features: Automatically saved when user clicks outside the widget (on blur) Ability to select predefined or enter new value You can find it at Perfection Kills]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p> <img src="http://www.ajaxbestiary.com/wp-content/uploads/2007/12/ips.png" alt="Prototype In Place Select" /></p>
<p>Meet Proto.IPS a fast and easy prototype based combo box modeled after the gMail Chat Widget.</p>
<p>Features:</p>
<ul>
<li>Automatically saved when user clicks outside the widget (on blur)</li>
<li>Ability to select predefined or enter new value</li>
</ul>
<p>You can find it at <a href="http://thinkweb2.com/projects/prototype/2007/12/22/protoips-in-place-select-widget/">Perfection Kills </a></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2007/12/25/protoips-a-fast-and-easy-prototype-based-type-in-place-combo-box/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ProtoCorners: Simple Corner Styling for Prototype</title>
		<link>http://www.ajaxbestiary.com/2007/12/07/protocorners-simple-corner-styling-for-prototype/</link>
		<comments>http://www.ajaxbestiary.com/2007/12/07/protocorners-simple-corner-styling-for-prototype/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 15:45:21 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[prototype]]></category>
		<category><![CDATA[Styling]]></category>
		<category><![CDATA[Widget]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/2007/12/07/protocorners-simple-corner-styling-for-prototype/</guid>
		<description><![CDATA[Alright, so sometimes you need to throw a little extra style into a project, a bevel there, rounded corner here.  Proto.Corners allows you to simply generate them programatically. Get it at nurey.com]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p><img src="http://www.ajaxbestiary.com/wp-content/uploads/2007/12/protocorner.png" alt="Proto Corner" />Alright, so sometimes you need to throw a little extra style into a project, a bevel there, rounded corner here.  Proto.Corners allows you to simply generate them programatically. Get it at <a href="http://nurey.com/corners.html">nurey.com</a></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2007/12/07/protocorners-simple-corner-styling-for-prototype/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

