<?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; Tutorial</title>
	<atom:link href="http://www.ajaxbestiary.com/category/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ajaxbestiary.com</link>
	<description>AJAX Development, News, Techniques &#38; More</description>
	<lastBuildDate>Sat, 19 Jun 2010 13:43:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Getting and setting values for jQuery widgets</title>
		<link>http://www.ajaxbestiary.com/2009/12/11/getting-and-setting-values-for-jquery-widgets/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/11/getting-and-setting-values-for-jquery-widgets/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 22:30:34 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Widgets]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=397</guid>
		<description><![CDATA[

If you come from an OOP background you’re likely used to defining class variables like this:


class MyClass &#123;
   var internalValue1;
   var internalValue2;
   function constructor&#40;&#41; &#123;  … &#125;
&#125;


The values which are to be stored in your object are simple, straightforward, likely to be typed, and the compiler will detect [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>If you come from an OOP background you’re likely used to defining class variables like this:</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;">class</span> MyClass <span style="color: #009900;">&#123;</span>
   <span style="color: #003366; font-weight: bold;">var</span> internalValue1<span style="color: #339933;">;</span>
   <span style="color: #003366; font-weight: bold;">var</span> internalValue2<span style="color: #339933;">;</span>
   <span style="color: #003366; font-weight: bold;">function</span> constructor<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>  … <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p>The values which are to be stored in your object are simple, straightforward, likely to be typed, and the compiler will detect typos in the variable names. JavaScript, as a loosely types language which treats its objects more like collections than discrete objects, can’t really offer us those protections. Conversely, that also means that we have a great deal of flexibility.</p>
<p>In essence, we can dynamically subclass our objects, which you have to admit is a neat trick.</p>
<p>So, for jQuery.UI widgets, the variables stored within our widget are not defined until we assign them. The act of assignment defines the variable name, which can then be called upon at will.</p>
<p>Assignment is simply:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>._setData<span style="color: #009900;">&#40;</span>‘variablename’<span style="color: #339933;">,</span> variablevalue<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>Retrieval of this value is similarly straightforward:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>._getData<span style="color: #009900;">&#40;</span>‘variablename’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>This does mean that the old problem of misnamed variables is alive and well. It also means that you need to be prepared to handle an undefined response to the _getData call.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/11/getting-and-setting-values-for-jquery-widgets/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Constraining a numeric value to a range</title>
		<link>http://www.ajaxbestiary.com/2009/12/09/constraining-a-numeric-value-to-a-range/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/09/constraining-a-numeric-value-to-a-range/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 18:00:55 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=393</guid>
		<description><![CDATA[

Okay, so this doesn’t strictly have anything to do with any JavaScript library, but it’s a handy little snippet of code to keep in your arsenal.


val = Math.max&#40;cMin, Math.min&#40;val, cMax&#41;&#41;;


In one line of code, we’ve automatically constrained val between cMin and cMax. Note that if cMax and cMin are reversed (cMax is less than cMin) [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Okay, so this doesn’t strictly have anything to do with <em>any</em> JavaScript library, but it’s a handy little snippet of code to keep in your arsenal.</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">val <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>cMin<span style="color: #339933;">,</span> Math.<span style="color: #660066;">min</span><span style="color: #009900;">&#40;</span>val<span style="color: #339933;">,</span> cMax<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>In one line of code, we’ve automatically constrained val between cMin and cMax. Note that if cMax and cMin are reversed (cMax is less than cMin) val will immediately be set to cMin (the higher of the values).</p>
<p>We can, of course, rectify this when cMin and cMax are assigned values by calling</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">cMin <span style="color: #339933;">=</span> Math.<span style="color: #660066;">min</span><span style="color: #009900;">&#40;</span>cMin<span style="color: #339933;">,</span> cMax<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
cMax <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>cmin<span style="color: #339933;">,</span> cMax<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/09/constraining-a-numeric-value-to-a-range/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Event handling in jQuery widgets</title>
		<link>http://www.ajaxbestiary.com/2009/12/08/event-handling-in-jquery-widgets/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/08/event-handling-in-jquery-widgets/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 18:00:57 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=390</guid>
		<description><![CDATA[

This is simple – provided you understand that the reference the keyword this refers to changes depending on when it is called.
When called during initialization, this refers to the widget you’re initializing. When the event itself is triggered, this refers to the DOM node node and not the widget.
As such, we need to introduce a [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>This is simple – provided you understand that the reference the keyword <strong>this</strong> refers to changes depending on when it is called.</p>
<p>When called during initialization, <strong>this</strong> refers to the widget you’re initializing. When the event itself is triggered, <strong>this</strong> refers to the DOM node node and not the widget.</p>
<p>As such, we need to introduce a new variable during initialization which the jQuery.UI library calls <strong>self</strong> which is, of course, equal to the initialization <strong>this</strong>, not triggered <strong>this</strong>. (Those of you familiar with Object Oriented Programming and by-reference calls should have no issue with this concept).</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>$.<span style="color: #660066;">widget</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ui.clicker&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
   _init<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         self.<span style="color: #660066;">increment</span><span style="color: #009900;">&#40;</span>self<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         self.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
   increment<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      target.<span style="color: #660066;">value</span><span style="color: #009900;">&#40;</span>target.<span style="color: #660066;">value</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #006600; font-style: italic;">//The exact handling of target.value will be shown another day</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
   render<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">value</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
   value<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>val<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      …
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>You’ll note that we have to pass <strong>self</strong> to the increment method or the widget won’t actually be able to find itself, but the render method, which was called during initialization, is henceforth always able to correctly reference <strong>this</strong> (the widget)!</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/08/event-handling-in-jquery-widgets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Customized context menu handling with jQuery</title>
		<link>http://www.ajaxbestiary.com/2009/12/07/customized-context-menu-handling-with-jquery/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/07/customized-context-menu-handling-with-jquery/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 22:26:33 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[context menu]]></category>
		<category><![CDATA[right click]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=384</guid>
		<description><![CDATA[

Can you think of some times you might want to disable the right click context menu? Or better still, insert your own behavior or application specific context menu?
This is a simple and useful trick:


element.bind&#40;'contextmenu',function&#40;e&#41;&#123;
    //Optional customized handling here
    return false;
&#125;&#41;;


If you don’t return false, the normal context menu will [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Can you think of some times you might want to disable the right click context menu? Or better still, insert your own behavior or application specific context menu?</p>
<p>This is a simple and useful trick:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">element.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'contextmenu'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">//Optional customized handling here</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>If you don’t return false, the normal context menu will appear, which could actually be desirable, depending on what exactly you want it to do (say, exiting a field and recording it as dirty).</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/07/customized-context-menu-handling-with-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Helpful error handling in jQuery</title>
		<link>http://www.ajaxbestiary.com/2009/12/02/helpful-error-handling-in-jquery/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/02/helpful-error-handling-in-jquery/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 22:10:02 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[error handling]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=378</guid>
		<description><![CDATA[

If you’re going to build a reusable tool, you’re going to want to be able to detect, handle and report error messages in a nice, clean way. It will make you and any other dev happy.
The cleanest way of handling genuine errors for developers using your tool &#8211; namely, invalid input sent to a function [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>If you’re going to build a reusable tool, you’re going to want to be able to detect, handle and report error messages in a nice, clean way. It will make you and any other dev happy.</p>
<p>The cleanest way of handling genuine errors for developers using your tool &#8211; namely, invalid input sent to a function in the library – is to log it to the console. Doing so is refreshingly straightforward:</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> err <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Error<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
err.<span style="color: #000066;">name</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;jQuery.widget.UI.clicker.range()&quot;</span><span style="color: #339933;">;</span>
err.<span style="color: #660066;">message</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Both values must be numeric to assign range&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>This snippet comes straight from the widget I threw together. I encourage you to make the name as detailed as possible. It will make debugging so much easier. You can even pinpoint the exact point of error if the problem was say, an invalid query syntax. (Handy during the development phase; not so much in a production environment!)</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/02/helpful-error-handling-in-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom stateful jQuery widgets</title>
		<link>http://www.ajaxbestiary.com/2009/11/30/custom-stateful-jquery-widgets/</link>
		<comments>http://www.ajaxbestiary.com/2009/11/30/custom-stateful-jquery-widgets/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 00:28:27 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Widget Factory]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=370</guid>
		<description><![CDATA[The widget library included in jQuery UI is pretty cool, but sometimes you need to roll your own custom object. If it didn’t have to be reusable, you could always just use a whole slew of bind methods on a specific page. Likewise, if network bandwidth and latency weren’t an issue, you could just store everything server-side and make heavy use of XHR.]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>The widget library included in <a href="http://docs.jquery.com/UI">jQuery UI</a> is pretty cool, but sometimes you need to roll your own custom object. If it didn’t have to be reusable, you could always just use a whole slew of <a href="http://docs.jquery.com/Events/bind#typedatafn">bind methods</a> on a specific page. Likewise, if network bandwidth and latency weren’t an issue, you could just store everything server-side and make heavy use of XmlHttpRequest.</p>
<p>Of course we don’t live in that ideal world and so we need to store data locally and our objects inevitably need to be reused. Enter the <a href="http://nemikor.com/presentations/jQuery-UI-Widget-Factory.pdf">jQuery Widget Factory</a>. This nifty feature set included in jQuery UI satisfies all of these needs.</p>
<p>Further, implementing custom widgets is pretty easy. First, we’ll initialize the widget:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">widget</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ui.widgetname'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> _init<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> … <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>Then we’ll set any defaults:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ui</span>.<span style="color: #660066;">widgetname</span>.<span style="color: #660066;">defaults</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> … <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>Obviously, this can and should be in its own file. Then on the specific web page, we can instantiate the widget:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>target<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">widgetname</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>This affords us the flexibility to reuse the widget multiple times on the same page and across pages and sites. Tomorrow we’ll start working up a rather basic example of this.</p>
<p>Before then, note that we use the widgetname consistently in its definition and instantiation, so choose the name wisely. Collisions in the $.ui namespace seem unlikely, but in very complex applications, that is always a possibility.</p>
<p>You’ll also note that in the widget’s definition we included only an _init function. This is the generic constructor for the widget and the only required method; feel free to add more as needed. The underscore prefix declares the method “private” and can be used to prefix any function in the widget declaration. This being JavaScript, we know that hidden named functions are quite impossible, but it does conceal the method from the now deprecated <code>$(element).plugin('function')</code>.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/11/30/custom-stateful-jquery-widgets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross Site Scripting &#8211; the new old way</title>
		<link>http://www.ajaxbestiary.com/2009/10/20/cross-site-scripting-the-new-old-way/</link>
		<comments>http://www.ajaxbestiary.com/2009/10/20/cross-site-scripting-the-new-old-way/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 23:02:35 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[XHTML]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=361</guid>
		<description><![CDATA[

Cross Site Scripting (XSS) is a big security no-no. It’s never supposed to happen, because as we all know, any script operating within your page has full access to the entire DOM of the page.
Then again, there is so much functionality that we want to implement without reinventing the wheel. Marketing departments want to use [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Cross Site Scripting (XSS) is a big security no-no. It’s never supposed to happen, because as we all know, any script operating within your page has full access to the entire DOM of the page.</p>
<p>Then again, there is so much functionality that we want to implement without reinventing the wheel. Marketing departments want to use third-party tracking tools. The IT folks want to distribute the load for our network heavy site across the third-level domains www.domain.com, static.domain.com and data.domain.com. And users want more functionality than we can hope to provide on our own.</p>
<p>So resigned to the reality that XSS is a legitimate necessity, we need a way to do it. The old way (as far back as the mid-90’s, in fact) was straightforward:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span>‘<span style="color: #339933;">&lt;</span>script language<span style="color: #339933;">=</span>”JavaScript” type<span style="color: #339933;">=</span>”text<span style="color: #339933;">/</span>javascript” src<span style="color: #339933;">=</span>”http<span style="color: #339933;">:</span><span style="color: #006600; font-style: italic;">//data.domain.com/myscript.js”&gt;&lt;/script&gt;’);</span></pre></div></div>

<p></code></p>
<p>This is of course problematic as it treats DOM nodes improperly and may not even get processed by modern browsers. Instead, jQuery provides access to JSONP which will do the same thing – insert a new script node in the DOM – but do it in an XHTML compliant way.</p>
<p>Accessing JSONP is pretty straightforward:</p>
<p><code</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">getJSON</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;http://data.domain.com/myscript&amp;callback=?”, inPageFunction);</span></pre></div></div>

<p></code></p>
<p>The key bit is &amp;callback=? – this causes jQuery to insert a script node into the DOM, which is then immediately executed and returned to the callback function, inPageFunction, like so:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">inPageFunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>data<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;foo&quot;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p></code></p>
<p>If you forget &amp;callback=? you’ll get the error Access to restricted URI denied. And yes, since we’re inserting a script node, we’re limited to GET requests. And if the call fails, you’ll simply get nothing back – no useful error messages.</p>
<p>Further, the next generation of browsers is coming out with integrated support for cross site XMLHttpRequest, but since when have we not had to code to support multiple versions of browsers?</p>
<p>There are loads of good guides to expand your knowledge:</p>
<ul>
<li><a href="http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html">What the heck is JSONP and why should you use it?</a></li>
<li><a href="http://niryariv.wordpress.com/2009/05/05/jsonp-quickly/">JSONP, Quickly</a></li>
<li><a href="http://www.ibm.com/developerworks/library/wa-aj-jsonp1/">Cross-domain communications with JSONP</a>, Part 1</li>
<li><a href="http://www.ibm.com/developerworks/web/library/wa-aj-jsonp2/index.html">Cross-domain communications with JSONP</a>, Part 2</li>
</ul>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/10/20/cross-site-scripting-the-new-old-way/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Using the jQuery data method as a local datastore</title>
		<link>http://www.ajaxbestiary.com/2009/10/15/using-the-jquery-data-method-as-a-local-datastore/</link>
		<comments>http://www.ajaxbestiary.com/2009/10/15/using-the-jquery-data-method-as-a-local-datastore/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 23:37:37 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=346</guid>
		<description><![CDATA[

At some point, we all have to store datasets on the client. We can clutter the namespace with ever more variables and try really hard to avoid collisions. We can cram variables into some local object that we’re using in the normal execution of our script anyway. We can attach custom attributes to HTML nodes, [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>At some point, we all have to store datasets on the client. We can clutter the namespace with ever more variables and try really hard to avoid collisions. We can cram variables into some local object that we’re using in the normal execution of our script anyway. We can attach custom attributes to HTML nodes, violating the sacrosanct purity of XHTML.</p>
<p>Or we can attach the document-specific variables, in script (thus keeping those automated validators happy), to the document itself. This fairly intuitive approach has not been given the notice it deserves.</p>
<p>Some advantages:</p>
<ol>
<li><span style="color: #333333;">Arbitrary value names can be assigned and we can basically assign as many of these variables as we want.</span></li>
<li><span style="color: #333333;">They can be applied to anything jQuery can access, meaning that we can rapidly assign values to entire sets of DOM nodes without having to add CSS classes or clutter the markup.</span></li>
<li><span style="color: #333333;">They can be dynamically added, accessed, changed and removed at will, without network transfers.</span></li>
</ol>
<p><span style="color: #333333;">There is the disadvantage that they are not persistent across page loads, but we’ve lived with that problem for a long, long time, haven’t we?</span></p>
<p>So how do we use this handy method? <a href="http://docs.jquery.com/Internals/jQuery.data">The documentation</a> is pretty clear cut, but I’ll give a slightly more grounded example:</p>
<p>My HTML is very simplistic in this example:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
 <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stats&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;add&quot;</span>&gt;</span>Add Data Point<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;reset&quot;</span>&gt;</span>Reset Set<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span>
 <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
 <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;data&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span></pre></td></tr></table></div>

<p>The JavaScript is similarly intuitive:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">appExample <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
 addDataPoint<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> dat <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getDataSet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  dat<span style="color: #009900;">&#91;</span>dat.<span style="color: #660066;">length</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">floor</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #CC0000;">101</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#data'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'points'</span><span style="color: #339933;">,</span> dat<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 resetDataSet<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#data'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">removeData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'points'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 dataSize<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> dat <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getDataSet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> dat.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 getDataSet<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> dat <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#data'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'points'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>undefined <span style="color: #339933;">==</span> dat<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Array <span style="color: #339933;">!=</span> dat.<span style="color: #660066;">constructor</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#91;</span>dat<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> dat<span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 updateDisplay<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#stats'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Data Points: '</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>lim <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">dataSize</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> dat <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getDataSet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <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;">&lt;</span> lim<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   tmp <span style="color: #339933;">+=</span> dat<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> lim <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> tmp <span style="color: #339933;">+=</span> <span style="color: #3366CC;">','</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#data'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'['</span> <span style="color: #339933;">+</span> tmp <span style="color: #339933;">+</span> <span style="color: #3366CC;">']'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 appExample.<span style="color: #660066;">updateDisplay</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#add'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  appExample.<span style="color: #660066;">addDataPoint</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  appExample.<span style="color: #660066;">updateDisplay</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#reset'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  appExample.<span style="color: #660066;">resetDataSet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  appExample.<span style="color: #660066;">updateDisplay</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>In this case, I’m storing everything as an array in points. While I’m storing randomly generated integers, you can just as easily store entire objects, opening the possibility of a JSON solution.</p>
<p>Note that we can identify those objects lacking the chosen dynamic attribute by <em>calling it</em> and testing for undefined.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/10/15/using-the-jquery-data-method-as-a-local-datastore/feed/</wfw:commentRss>
		<slash:comments>1</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[Tutorial]]></category>
		<category><![CDATA[prototype]]></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>8</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[Tools]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[prototype]]></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>
	</channel>
</rss>
