<?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>Mellow Morning &#187; Javascript</title>
	<atom:link href="http://www.mellowmorning.com/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mellowmorning.com</link>
	<description>Blogging the world of IT and Business</description>
	<lastBuildDate>Wed, 01 Feb 2012 19:00:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Django Facebook 3.0 &#8211; OAuth migration &#8211; Time to upgrade!</title>
		<link>http://www.mellowmorning.com/2011/08/13/django-facebook-3-0-oauth-migration-time-to-upgrade/</link>
		<comments>http://www.mellowmorning.com/2011/08/13/django-facebook-3-0-oauth-migration-time-to-upgrade/#comments</comments>
		<pubDate>Sat, 13 Aug 2011 14:40:16 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Fashiolista]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[django facebook]]></category>
		<category><![CDATA[open graph]]></category>
		<category><![CDATA[open graph api]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/?p=434</guid>
		<description><![CDATA[Facebook is migrating to HTTPS and OAuth to increase the safety of their users. Unfortunately these changes aren&#8217;t backwards compatible and will require some effort to follow. To support the new Facebook system you need to upgrade to Django Facebook 3.0 before October 1st.
In addition to the required migrations, this version also includes several new [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Facebook is migrating to HTTPS and OAuth to increase the safety of their users. Unfortunately these changes aren&#8217;t backwards compatible and will require some effort to follow. To support the new Facebook system you need to upgrade to <a href="https://github.com/tschellenbach/Django-facebook">Django Facebook 3.0</a> before October 1st.</strong></p>
<p>In addition to the required migrations, this version also includes several new features. The largest change is the underlying Facebook API client. You can read about the improvements here or skip down to the upgrade instructions.</p>
<h3>Open Facebook &#8211; New Python Facebook client</h3>
<p>Open Facebook is a python client to the Facebook graph API. Currently it&#8217;s included in Django Facebook, but in time it will be spun of as a separate project. The client is supported, tested and up to date with the current version of Facebook&#8217;s graph API.<br />
It handles connection issues cleanly and raises separate error classes for various Facebook error scenarios.<br />
The syntax is very straightforward to use:</p>
<pre class="python" name="code">
open_facebook = OpenFacebook(token)
#info about me
open_facebook.me()

#retrieving a page
open_facebook.get('fashiolista')

#retrieving your albums
open_facebook.get('me/albums')

#posting a message on your wall
open_facebook.set('me/feed', message='Check out Fashiolista', picture=image_url)

#setting a like
open_facebook.set('fashiolista/likes')

#fql example
result = open_facebook.fql('SELECT name FROM user WHERE uid = me()')

#authorization is handled separately from the API class
token = FacebookAuthorization.get_app_access_token()
test_user = FacebookAuthorization.create_test_user(token)
</pre>
<h4>Album upload Example</h4>
<p>Uploading pictures to Facebook is as simple as this:</p>
<pre class="python" name="code">
open_facebook = get_facebook_graph(request)
photo_urls = [
    'http://d.fashiocdn.com/images/entities/0/6/t/p/d/0.365x365.jpg',
    'http://e.fashiocdn.com/images/entities/0/5/E/b/Q/0.365x365.jpg',
]
for photo in photo_urls:
    uploaded = open_facebook.set('me/photos', url=photo,
        message='Fashiolista is awesome', name='FashiolistaTest'
    )
</pre>
<p>So there are good reasons to upgrade even if Facebook didn&#8217;t force us to :)</p>
<h3>How to upgrade to 3.0</h3>
<p><b>First Step &#8211; Install Django Facebook 3.0</b><br />
Follow the <a href="https://github.com/tschellenbach/Django-facebook/">installation instructions.</a></p>
<p><b>Javascript changes</b><br />
In your Facebook initialization code enable OAuth. </p>
<pre class="javascript" name="code">
FB.init({appId: facebookAppId, status: false, cookie: true, xfbml: true, oauth: true});
</pre>
<p>Perms has been renamed to scope.</p>
<pre class="javascript" name="code">
FB.login(function() {}, {'scope' : 'offline_access'});
</pre>
<p><b>Django Facebook changes</b><br />
The get_facebook_graph function is no longer persistent by default, if you want the old behavior use get_persistent_graph.<br />
Furthermore the FacebookUserConverter class and the core Facebook API client are now separated. get_facebook_graph returns the core facebook API client. To go from the API class to the user converter class use something like</p>
<pre class="python" name="code">
graph = get_facebook_graph(request)
facebook = FacebookUserConverter(graph)
</pre>
<p>That should be all.<br />
If you are encountering problems feel free to let me know in the comments.</p>
<p><b>Last Step &#8211; Enable the new Facebook Migrations</b><br />
Go to the <a href="https://developers.facebook.com/apps">Facebook Apps page</a> and enable the OAuth migration.<br />
Select your app -> About -> Advanced -> Migrations<br />
Enable Force OAuth<br />
Enable OAuth Migration</p>
<h3>Background reading</h3>
<p><a href="http://developers.facebook.com/blog/post/497/">Moving to OAuth 2.0 + HTTPS</a><br />
<a href="http://developers.facebook.com/blog/post/525/">Updated JavaScript SDK and OAuth 2.0 Roadmap</a><br />
<a href="http://developers.facebook.com/docs/authentication/">New Facebook Authentication Docs</a><br />
<a href="http://developers.facebook.com/blog/post/534/">PHP SDK v.3.1.1</a><br />
<a href="http://developers.facebook.com/blog/post/503/">PHP SDK v3.0.0</a></p>
<h3>We&#8217;re hiring!</h3>
<p>Do you also see the beauty in clean code? Are you experienced with high scalability web apps? Currently we&#8217;re looking for additional talent over at our Amsterdam office. Feel free to drop me a line at my personal email for more information: thierryschellenbach[at]gmail.com</p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2011%2F08%2F13%2Fdjango-facebook-3-0-oauth-migration-time-to-upgrade%2F&amp;title=Django%20Facebook%203.0%20-%20OAuth%20migration%20-%20Time%20to%20upgrade%21" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2011%2F08%2F13%2Fdjango-facebook-3-0-oauth-migration-time-to-upgrade%2F&amp;title=Django%20Facebook%203.0%20-%20OAuth%20migration%20-%20Time%20to%20upgrade%21" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2011%2F08%2F13%2Fdjango-facebook-3-0-oauth-migration-time-to-upgrade%2F&amp;title=Django%20Facebook%203.0%20-%20OAuth%20migration%20-%20Time%20to%20upgrade%21" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2011%2F08%2F13%2Fdjango-facebook-3-0-oauth-migration-time-to-upgrade%2F&amp;t=Django%20Facebook%203.0%20-%20OAuth%20migration%20-%20Time%20to%20upgrade%21" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2011%2F08%2F13%2Fdjango-facebook-3-0-oauth-migration-time-to-upgrade%2F&amp;title=Django%20Facebook%203.0%20-%20OAuth%20migration%20-%20Time%20to%20upgrade%21" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2011%2F08%2F13%2Fdjango-facebook-3-0-oauth-migration-time-to-upgrade%2F&amp;title=Django%20Facebook%203.0%20-%20OAuth%20migration%20-%20Time%20to%20upgrade%21" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2011/08/13/django-facebook-3-0-oauth-migration-time-to-upgrade/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Twitter button to pull down the internet?</title>
		<link>http://www.mellowmorning.com/2010/08/13/twitter-button-to-pull-down-the-internet/</link>
		<comments>http://www.mellowmorning.com/2010/08/13/twitter-button-to-pull-down-the-internet/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 14:39:10 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Fashiolista]]></category>
		<category><![CDATA[Google app engine]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[YouTellMe]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/?p=308</guid>
		<description><![CDATA[I was thrilled to see twitter releasing their own button. This is good news all around for us bloggers looking to promote our content. After looking at their code snippets a warning is in place though. The current twitter button implementation will severely break your site if their servers face load issues. Fortunately you can [...]]]></description>
			<content:encoded><![CDATA[<p>I was thrilled to see <a target="_blank" href="http://mashable.com/2010/08/13/tweet-button-bloggers/">twitter releasing their own button</a>. This is <a target="_blank" href="http://techcrunch.com/2010/08/12/twitter-tweet-button/">good news</a> all around for us bloggers looking to promote our content. After looking at their code snippets a warning is in place though. The current twitter button implementation will severely break your site if their servers face load issues. Fortunately you can work around this issues by slightly modifying their implementation.</p>
<h3>Technical explanation</h3>
<p>For <a  target="_blank"  href="http://www.fashiolista.com/">Fashiolista.com</a> we have been writing a lot about the <a target="_blank" href="http://www.mellowmorning.com/2010/08/03/creating-your-own-diggfacebook-liketweetmeme-button/">various techniques</a> for implementing these type of buttons. Especially important here is the way the javascript is loaded. Twitter uses a simple blocking script approach, where as digg, facebook and fashiolista use the async dynamic script approach. There are two large differences:</p>
<ol>
<li>Blocking script loads make your site slower</li>
<li>If twitter goes down, your site joins in</li>
</ol>
<h3>Example</h3>
<p>In this example we are faking slow twitter servers. (By routing it through google&#8217;s app engine and delaying the response). You can see the difference for yourself (be patient and be sure to clear your browser cache using CTRL F5).</p>
<p><a  target="_blank"  href="http://static1.fashiolista.com/other/button_twitter_fail.html">Default twitter version</a><br />
(note that site content is not loading until the twitter button is loaded)</p>
<p><a  target="_blank"  href="http://static1.fashiolista.com/other/button_twitter.html">Async twitter script</a><br />
(everything loads and then we wait for twitter)</p>
<h3>Solution</h3>
<p>Solving this is quite simple. Simply change the way the twitter javascript is loaded from the first example to the second version.</p>
<p><strong>Twitter version</strong></p>
<pre code="javascript" name="code">

&lt;script type=&quot;text/javascript&quot; src=&quot;http://platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;
</pre>
<p><strong>Async twitter implementation</strong></p>
<pre code="javascript" name="code">
&lt;script type=&quot;text/javascript&quot;&gt;
  //async script, twitter button fashiolista.com style
  (function() {
   var s = document.createElement('SCRIPT');
   var c = document.getElementsByTagName('script')[0];
   s.type = 'text/javascript';
   s.async = true;
   s.src = 'http://platform.twitter.com/widgets.js';
   c.parentNode.insertBefore(s, c);
  })();
&lt;/script&gt;
</pre>
<p>Hope the difference won&#8217;t matter and Twitter will stay up :)</p>
<p>Follow me at:<br />
<a target="_blank" href="http://twitter.com/tschellenbach">@tschellenbach</a></p>
<p>Thanks for spreading the word:<br />
<a href="http://thenextweb.com/socialmedia/2010/08/13/the-twitter-button-is-it-making-your-site-join-the-fail-whale-shuffle/">NextWeb</a></p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F13%2Ftwitter-button-to-pull-down-the-internet%2F&amp;title=Twitter%20button%20to%20pull%20down%20the%20internet%3F" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F13%2Ftwitter-button-to-pull-down-the-internet%2F&amp;title=Twitter%20button%20to%20pull%20down%20the%20internet%3F" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F13%2Ftwitter-button-to-pull-down-the-internet%2F&amp;title=Twitter%20button%20to%20pull%20down%20the%20internet%3F" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F13%2Ftwitter-button-to-pull-down-the-internet%2F&amp;t=Twitter%20button%20to%20pull%20down%20the%20internet%3F" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F13%2Ftwitter-button-to-pull-down-the-internet%2F&amp;title=Twitter%20button%20to%20pull%20down%20the%20internet%3F" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F13%2Ftwitter-button-to-pull-down-the-internet%2F&amp;title=Twitter%20button%20to%20pull%20down%20the%20internet%3F" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2010/08/13/twitter-button-to-pull-down-the-internet/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Creating your own Digg/Facebook/Tweetmeme button</title>
		<link>http://www.mellowmorning.com/2010/08/03/creating-your-own-diggfacebook-liketweetmeme-button/</link>
		<comments>http://www.mellowmorning.com/2010/08/03/creating-your-own-diggfacebook-liketweetmeme-button/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 17:58:36 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Fashiolista]]></category>
		<category><![CDATA[Google app engine]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[YouTellMe]]></category>
		<category><![CDATA[Social bookmarking]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/?p=174</guid>
		<description><![CDATA[This quick walkthrough is going to bring you up to speed on how to create your own social bookmarking button. The three prime examples are the famous Digg button, Facebook&#8217;s like functionality and the tweetmeme button. For an implementation look slightly above this paragraph or check out mashable&#8217;s version on the left of their post.
Our [...]]]></description>
			<content:encoded><![CDATA[<p>This quick walkthrough is going to bring you up to speed on how to create your own social bookmarking button. The three prime examples are the famous <a title="digg button" href="http://about.digg.com/button" target="_blank">Digg button</a>, <a target="_blank" href="http://developers.facebook.com/docs/reference/plugins/like">Facebook&#8217;s like</a> functionality and the <a title="tweetmeme button" href="http://tweetmeme.com/about/retweet_button" target="_blank">tweetmeme button</a>. For an implementation look slightly above this paragraph or check out <a title="mashable social bookmarking implementation" href="http://mashable.com/2010/07/24/facebook-like-script/" target="_blank">mashable&#8217;s version</a> on the left of their post.</p>
<p>Our button will be focusing on <a title="fashiolista fashion social bookmarking" href="http://www.fashiolista.com/" target="_blank">Fashiolista.com</a>. Fashiolista is a social bookmarking site for fashion, which has seen <a href="http://thenextweb.com/socialmedia/2010/06/29/fashiolista-celebrates-1-million-love-button-clicks-after-launching-at-the-next-web-conference/" target="_blank">rapid growth after launching at the next web</a>. This tutorial explains the javascript (client side) aspects of the button. Feedback and improvements on the code would be greatly appreciated. You can find the full 450 lines of js on <a href="http://github.com/tschellenbach/Fashiolista-Button/blob/master/buttons.js" target="_blank">github</a>.</p>
<p>This is what the end result looks like:</p>
<p><script type="text/javascript">
  (function() {
   var s = document.createElement('SCRIPT');
   var c = document.getElementsByTagName('script')[0];
   s.type = 'text/javascript';
   s.async = true;
   s.src = 'http://button.www.fashiolista.com/button/script/';
   c.parentNode.insertBefore(s, c);
  })();
</script></p>
<table width="100%">
<tbody>
<tr align="center">
<th>Compact</th>
<th>Medium</th>
<th>Large</th>
</tr>
<tr align="center">
<td width="100px"><a class="fashiolista_button fashiolista_compact" href="http://www.fashiolista.com/add_item_oe/?url=http%3A%2F%2Fwww.tillys.com%2Ftillys%2Fvariants.aspx%3Fprod%3D159872100%26ctlg%3D020_Girls%26cid%3D1090%26source%3D1%26size%3D"><br />
Love it!<br />
</a></td>
<td width="160px"><a class="fashiolista_button fashiolista_medium" href="http://www.fashiolista.com/add_item_oe/?url=http%3A%2F%2Fwww.tillys.com%2Ftillys%2Fvariants.aspx%3Fprod%3D159872100%26ctlg%3D020_Girls%26cid%3D1090%26source%3D1%26size%3D"><br />
Love it!<br />
</a></td>
<td width="100px"><a class="fashiolista_button fashiolista_large" href="http://www.fashiolista.com/add_item_oe/?url=http%3A%2F%2Fwww.tillys.com%2Ftillys%2Fvariants.aspx%3Fprod%3D159872100%26ctlg%3D020_Girls%26cid%3D1090%26source%3D1%26size%3D"><br />
Love it!<br />
</a></td>
</tr>
</tbody>
</table>
<p>(If you are working on a shop in the fashion industry have a look at our <a title="Fashiolista button installation instructions" href="http://www.fashiolista.com/content/fashiolista-button/" target="_blank">installation instuctions</a>.)</p>
<h3>Step 1 &#8211; The markup</h3>
<p>Its important to get the client side markup of the button right. Since other sites will be implementing this there is no way you can change it later on. The three major players each have their own way.</p>
<p>Facebook XFBML: Async script with XFBML or Iframe<br />
Digg button: Async script with A elements<br />
Tweetmeme: Normal script</p>
<pre class="javascript" name="code">&lt;script type="text/javascript"&gt;
  //async script, fashiolista.com version
  (function() {
   var s = document.createElement('SCRIPT');
   var c = document.getElementsByTagName('script')[0];
   s.type = 'text/javascript';
   s.async = true;
   s.src = 'http://button.www.fashiolista.com/button/script/';
   c.parentNode.insertBefore(s, c);
  })();
&lt;/script&gt;
&lt;a class="fashiolista_button fashiolista_compact"
href="http://www.fashiolista.com/item_add_oe/"&gt;Love it!&lt;/a&gt;</pre>
<p>For Fashiolista we have chosen an async script approach with A elements. Normally loading a script element is a blocking operation for the browser. Loading the script async ensures faster page load times and a better experience if your site would ever go down. (Note that not all browsers support this option so it is still <a target="_blank" href="http://developer.yahoo.com/performance/rules.html#js_bottom">recommended to include the script tag at the bottom of the page</a>). The function wrapped around the code ensures we don&#8217;t pollute the global scope. Furthermore the insertBefore in combination with a script tag technique is <a href="http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html#Snippet" target="_blank">used by GA</a> so should work in any scenario.</p>
<h3>Step 2 &#8211; Creating the buttons, Iframe vs Script</h3>
<p>The next step is to convert our A elements into actual buttons. We can choose to replace these A elements by our button&#8217;s html (digg, delicious approach) or load an iframe in their place (facebook, tweetmeme). The difference between these two approaches is actually pretty large. For Fashiolista you can see both an <a href="http://static1.fashiolista.com/other/button_test_iframe.html" target="_blank">iframe</a> and <a href="http://static1.fashiolista.com/other/button_test.html" target="_blank">script</a> approach. These are the most important differences I encountered.</p>
<p><strong>Iframe vs Script</strong></p>
<ul>
<li><strong>+ Popup communication possible</strong><br />
The script approach cannot communicate with popups it creates due to the <a href="https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript" target="_blank">same origin restrictions</a>. The iframe however can be of the same domain as the popup and freely communicate. This gives a better user experience when for instance logging in.</li>
<li><strong>+ Easier to develop</strong><br />
The iframe approach is easier to develop and requires less code.</li>
<li><strong>+ Parallel download in IE</strong><br />
IE doesn&#8217;t download the count scripts in parallel, but it does do so for the IFRAMEs. Making this approach somewhat faster.</li>
<li><strong>Independent CSS</strong><br />
External sites don&#8217;t interfere with your button&#8217;s css if you use an iframe technique. The disadvantage is that it makes things likes hovers impossible to integrate with the other site. (For example Fashiolista&#8217;s compact button).</li>
<li><strong>Independent</strong><br />
The iframe approach makes it very hard for other sites to game the users like/love action. With a script approach a foreign site can simply call your javascript to fake someone loving the product. This freedom can be abused but also allows for mashups.</li>
<li><strong>- Slower dom load</strong><br />
Creating iframes takes <a href="http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly/" target="_blank">a lot more time</a> for the browser.</li>
<li><strong>- Slower perceived load</strong><br />
The script approach allows you to format the buttons before the data is loaded. Vastly increasing the perceived load speed.</li>
<li><strong>- No shared functionality</strong><br />
Buttons can&#8217;t share functionality. So when someone logs in for one button its is not possible to update the others.</li>
</ul>
<p>The best choice differs for each project. For Fashiolista the more open script approach is currently the default.</p>
<h3>Step 3 &#8211; Cross site scripting using JSONP</h3>
<p>Essential to the bookmarking button is requesting the count for the given url. Cross site policies prevent us from using Ajax so we will do so by creating a script element.</p>
<pre class="javascript" name="code">_makeRequest: function (url) {
	//Simple create script element functionality
        var s = document.createElement('script');
        var b = document.body;

        s.setAttribute('type', 'text/javascript');
        s.setAttribute('async', 'true');
        s.setAttribute('src', url);

        b.appendChild(s);
}</pre>
<p>The trouble with the script element is that you lack the nice APIs Ajax offers you. We work around this by using an url with a callback paramater, for example <a href="http://button.www.fashiolista.com/button/love_count/?ajax=1&amp;url=http%3A%2F%2Fwww.tillys.com%2Ftillys%2Fvariants.aspx%3Fprod%3D159872100%26ctlg%3D020_Girls%26cid%3D1090%26source%3D1%26size%3D&amp;callback=button_loaded_3" target="_blank">callback=button_loaded_3</a><br />
The server side code then responds with something like this, executing the callback when the script is loaded.</p>
<pre class="javascript" name="code">button_loaded_3({"item_id": 26545, "url": "/item/26545/", "loves": 853})</pre>
<p>This technique is often referred to as <a href="http://en.wikipedia.org/wiki/JSON#JSONP" target="_blank">JSONP</a>. We bind the response function to the global button_loaded_3 using the following code:</p>
<pre class="javascript" name="code">loadButtonInformation: function (buttonId) {
		//make a request to the script with the given callback
		var buttonInstance = this.buttonDict[buttonId];
		var buttonUrl = buttonInstance.lookupUrl;
		var path = '&amp;url=' + encodeURIComponent(buttonUrl);
		var callbackFunctionName = 'button_loaded_' + buttonId;
		var scope = this;
		var callbackFunction = function(data) {
			//bind the scope and button id
			scope.buttonLoaded.call(scope, buttonId, data);
		};
		window[callbackFunctionName] = callbackFunction;
		this.makeRequest(this.countApi + path, callbackFunctionName, true);
}</pre>
<h3>Step 4 &#8211; Object oriented design</h3>
<p>Since we are loading our code into someone else&#8217;s website we should be careful not to use similar variable names. We therefore hide as much code as possible in classes.</p>
<pre class="javascript" name="code">var fashiolistaClass = function(){ this.initialize.apply(this, arguments); };
fashiolistaClass.prototype = {
	//
	//Base class implementing the fashiolista button
	//
	initialize: function () {
		//load the buttons
		this.initializeCss();
		var fashiolistaButtons = this.findButtons();
		this.initializeButtons(fashiolistaButtons);
	}
}</pre>
<p>Note that we are not simulating inheritance for these classes. Using them as simple namespaces is more than sufficient in this case.<br />
The code is organized into 3 classes:</p>
<ul>
<li>fashiolistaClass</li>
<li>fashiolistaUtilsClass</li>
<li>fashiolistaButtonClass</li>
</ul>
<p>The first one acts as a manager (finding the buttons, instantiating fashiolistaButtonClasses and retrieving counts). Fashiolista button contains the logic for individual buttons and fashiolista utils contains some string parsing and dom load functionality.</p>
<h3>Step 5 &#8211; Caching requests in the google app engine</h3>
<p><img style="float: left; padding: 5px;" title="appengine" src="http://img.brothersoft.com/icon/softimage/g/google_app_engine_sdk-314909-1260390748.jpeg" alt="appengine" />To prevent our servers from getting flooded we are routing all traffic through google servers using the google app engine. button.www.fashiolista.com is connected to a google app engine account which forwards and caches requests to fashiolista.com. This setup enables your button to withstand great amounts of traffic without killing your servers. Furthermore it immediately also acts as a cdn for our web requests, speeding up load times for our international visitors. Setting up caching in the google app engine would require another blog post though. Let us know in the comments if you would like to know more about it.</p>
<h3>Conclusion</h3>
<p>The full client side code can be found <a href="http://github.com/tschellenbach/Fashiolista-Button/blob/master/buttons.js" target="_blank">here</a>. This blog post covered the most essential parts. Code review and questions are more than welcome. Be sure to let us know in the comments. Furthermore if you are running a webshop in the fashion industry consider <a href="http://www.fashiolista.com/content/fashiolista-button/" target="_blank">implementing the button</a>.</p>
<h3>More information</h3>
<ul>
<li><a href="http://www.oexchange.org/" target="_blank">Server side standards &#8211; OExchange</a></li>
<li><a href="http://www.fashiolista.com/content/fashiolista-button/" target="_blank">Installing the fashiolista button (for shops)</a></li>
<li>Subscribe to this blog&#8217;s <a href="http://feeds.feedburner.com/MellowMorning" target="_blank">rss feed</a></li>
</ul>
<h3>Improvements/ Request for code review</h3>
<ul>
<li>The domload technique is rather verbose, does anyone know a better method?</li>
<li>The popup communication or lack thereof is not ideal for users, is there a better method?</li>
<li>Script or Iframe what do you prefer?</li>
<li>Suggestions to make it faster?</li>
</ul>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F03%2Fcreating-your-own-diggfacebook-liketweetmeme-button%2F&amp;title=Creating%20your%20own%20Digg%2FFacebook%2FTweetmeme%20button" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F03%2Fcreating-your-own-diggfacebook-liketweetmeme-button%2F&amp;title=Creating%20your%20own%20Digg%2FFacebook%2FTweetmeme%20button" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F03%2Fcreating-your-own-diggfacebook-liketweetmeme-button%2F&amp;title=Creating%20your%20own%20Digg%2FFacebook%2FTweetmeme%20button" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F03%2Fcreating-your-own-diggfacebook-liketweetmeme-button%2F&amp;t=Creating%20your%20own%20Digg%2FFacebook%2FTweetmeme%20button" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F03%2Fcreating-your-own-diggfacebook-liketweetmeme-button%2F&amp;title=Creating%20your%20own%20Digg%2FFacebook%2FTweetmeme%20button" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F08%2F03%2Fcreating-your-own-diggfacebook-liketweetmeme-button%2F&amp;title=Creating%20your%20own%20Digg%2FFacebook%2FTweetmeme%20button" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2010/08/03/creating-your-own-diggfacebook-liketweetmeme-button/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Django Facebook &#8211; Open graph API implementation</title>
		<link>http://www.mellowmorning.com/2010/05/17/django-facebook-open-graph-api-implementation/</link>
		<comments>http://www.mellowmorning.com/2010/05/17/django-facebook-open-graph-api-implementation/#comments</comments>
		<pubDate>Mon, 17 May 2010 10:40:54 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Fashiolista]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[open graph]]></category>
		<category><![CDATA[social]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/?p=166</guid>
		<description><![CDATA[Update:
This blog post is outdated, a new and vastly upgraded version of Django Facebook is now available. Read more about it here.
For Fashiolista.com  we needed to integrate with the Facebook Open Graph API. The open graph API is a very exciting facebook project, which you can read about more here and here. The code at fashiolista.com [...]]]></description>
			<content:encoded><![CDATA[<p><b>Update</b>:<br />
This blog post is outdated, a new and vastly upgraded version of Django Facebook is <a href="http://www.mellowmorning.com/2011/06/23/django-facebook-2-0-integrating-facebook/">now available</a>. Read more about it <a href="http://www.mellowmorning.com/2011/06/23/django-facebook-2-0-integrating-facebook/">here</a>.</p>
<p>For <a href="http://www.fashiolista.com/" target="_blank">Fashiolista.com <img style="float:left;" class="alignleft size-full wp-image-159" title="logo_dark_bg" src="http://www.mellowmorning.com/wp-content/uploads/2010/04/logo_dark_bg.png" alt="Fashiolista" width="220" height="100" /></a> we needed to integrate with the Facebook Open Graph API. The open graph API is a very exciting facebook project, which you can read about more <a href="http://mashable.com/2010/04/21/facebook-open-graph/" target="_blank">here </a>and <a href="http://developers.facebook.com/docs/" target="_blank">here</a>. The code at fashiolista.com allows you to register/login via facebook using the Open Graph API (similar to the old Facebook connect, but registration, instead of only logging in). Before you go try it out, fashiolista.com is aimed primarily at females so your girl friends facebook account is probably a better fit.</p>
<p>Im releasing the source code for <a href="http://github.com/tschellenbach/Django-facebook" target="_blank">Django Facebook on github</a>. Its a very early release, but it might help other developers trying to implement a facebook register/loging flow using the new open graph api. See Github for requirements and installation instructions.</p>
<p><b>Update</b>:<br />
<del datetime="2010-05-18T10:56:52+00:00">Birthday formats are currently giving some troubles for some users.</del><br />
Fixed and tests added to prevent future problems. (note Fashiolista.com may still give errors, will be resolved during our next release).</p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F05%2F17%2Fdjango-facebook-open-graph-api-implementation%2F&amp;title=Django%20Facebook%20-%20Open%20graph%20API%20implementation" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F05%2F17%2Fdjango-facebook-open-graph-api-implementation%2F&amp;title=Django%20Facebook%20-%20Open%20graph%20API%20implementation" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F05%2F17%2Fdjango-facebook-open-graph-api-implementation%2F&amp;title=Django%20Facebook%20-%20Open%20graph%20API%20implementation" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F05%2F17%2Fdjango-facebook-open-graph-api-implementation%2F&amp;t=Django%20Facebook%20-%20Open%20graph%20API%20implementation" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F05%2F17%2Fdjango-facebook-open-graph-api-implementation%2F&amp;title=Django%20Facebook%20-%20Open%20graph%20API%20implementation" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2010%2F05%2F17%2Fdjango-facebook-open-graph-api-implementation%2F&amp;title=Django%20Facebook%20-%20Open%20graph%20API%20implementation" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2010/05/17/django-facebook-open-graph-api-implementation/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>YTM launch!!</title>
		<link>http://www.mellowmorning.com/2009/12/11/ytm-launch/</link>
		<comments>http://www.mellowmorning.com/2009/12/11/ytm-launch/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 16:49:51 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Business]]></category>
		<category><![CDATA[Css]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Dutch]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[YouTellMe]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/?p=126</guid>
		<description><![CDATA[No more beta for YouTellMe.nl
The website which is taking over the Dutch product comparison market is officially going out of beta @ 8 o clock.
Party in Amsterdam, Keizersgracht 182 :) Festivities starting right now!

Things are going well, looking very forward to international launch.
We&#8217;ve changed a lot since the first reviews!

Beter pictures coming after the event [...]]]></description>
			<content:encoded><![CDATA[<p>No more beta for <a href="http://www.youtellme.nl/">YouTellMe.nl</a><br />
The website which is taking over the Dutch product comparison market is officially going out of beta @ 8 o clock.<br />
Party in Amsterdam, Keizersgracht 182 :) Festivities starting right now!</p>
<p><a href="http://www.mellowmorning.com/wp-content/uploads/2009/12/13342_350348980430_784785430_9966158_5558110_n.jpg"><img class="alignnone size-full wp-image-127" title="13342_350348980430_784785430_9966158_5558110_n" src="http://www.mellowmorning.com/wp-content/uploads/2009/12/13342_350348980430_784785430_9966158_5558110_n.jpg" alt="13342_350348980430_784785430_9966158_5558110_n" width="604" height="453" /></a></p>
<p>Things are going well, looking very forward to international launch.<br />
We&#8217;ve changed a lot since the <a href="http://www.nicolasleroy.fr/wp/2008/09/innovative-product-selection-on-youtellme/">first </a>reviews!</p>
<p><a href="http://www.mellowmorning.com/wp-content/uploads/2009/12/13342_350352790430_784785430_9966172_7726367_n1.jpg"><img class="alignnone size-full wp-image-129" title="13342_350352790430_784785430_9966172_7726367_n" src="http://www.mellowmorning.com/wp-content/uploads/2009/12/13342_350352790430_784785430_9966172_7726367_n1.jpg" alt="13342_350352790430_784785430_9966172_7726367_n" width="453" height="604" /></a></p>
<p>Beter pictures coming after the event :P</p>
<p>PS. Thanks to Python and Django, for enabling us to beat the competition :)</p>
<p>PSS.<a href="http://www.singel146.nl/2009/10/singel-office-warming-de-balans/" target="_blank"> Next2News, eduhub, come and join :)</a></p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2009%2F12%2F11%2Fytm-launch%2F&amp;title=YTM%20launch%21%21" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2009%2F12%2F11%2Fytm-launch%2F&amp;title=YTM%20launch%21%21" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2009%2F12%2F11%2Fytm-launch%2F&amp;title=YTM%20launch%21%21" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2009%2F12%2F11%2Fytm-launch%2F&amp;t=YTM%20launch%21%21" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2009%2F12%2F11%2Fytm-launch%2F&amp;title=YTM%20launch%21%21" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2009%2F12%2F11%2Fytm-launch%2F&amp;title=YTM%20launch%21%21" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2009/12/11/ytm-launch/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Javascript optimization &#8211; high performance JS apps</title>
		<link>http://www.mellowmorning.com/2008/05/18/javascript-optimization-high-performance-js-apps/</link>
		<comments>http://www.mellowmorning.com/2008/05/18/javascript-optimization-high-performance-js-apps/#comments</comments>
		<pubDate>Sun, 18 May 2008 19:49:45 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web2.0]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/?p=65</guid>
		<description><![CDATA[The most common use cases of Javascript require no optimization at all. However when you go about building substantial applications in javascript you will hit some walls rather rapidly. Fortunately the code you are currently writing can probably be accelerated substantially.
Step 0: Analyzing performance
Prior to attempting any tweaks, be sure to get firebug and use [...]]]></description>
			<content:encoded><![CDATA[<p>The most common use cases of Javascript require no optimization at all. However when you go about building substantial applications in javascript you will hit some walls rather rapidly. Fortunately the code you are currently writing can probably be accelerated substantially.</p>
<h3>Step 0: Analyzing performance</h3>
<p>Prior to attempting any tweaks, be sure to <a href="http://www.getfirebug.com/" target="_blank">get firebug</a> and use their console.profile() and console.profileEnd(). Test results will vary substantially during subsequent tests, but they serve their purpose for finding the bottlenecks.</p>
<h3>Step 1: Remove Double Dollar $$ and event binding</h3>
<p>There are <a href="http://www.sitepen.com/blog/2008/05/09/string-performance-an-analysis/" target="_blank">many small performance</a> differences, but several things are likely to really kill performance. One of the most nasty ones is using prototype&#8217;s <a href="http://www.prototypejs.org/api/utility/dollar-dollar" target="_blank">double dollar $$</a> function (or the similar Element.select). You can often avoid using the double dollar function. For example the use case of attaching events to all &#8216;report this&#8217; buttons on your site. The simple (and often good enough) approach would be to use the following code:</p>
<pre name="code" class="js">$$('.report_this').each(function(report_button) {
   var id = report_button.id.split('_')[1];
   report_button.observe('click', this.respondToReportButton.bind(this, id);
});</pre>
<p>Four things are slowing this code down: 1. the usage of the $$ function, 2. the usage of each instead of a native looping construct, 3. the retrieving of the id from the id string, 4. the repeated binding of functions.</p>
<p>There are several possible remedies against the above code:</p>
<ol>
<li>Give all report_this buttons a unique id (say for instance that you have 15 or less in a list)</li>
<li>Pre generate a list of ids using your server side language of choice and pass it to javascript</li>
<li>Manually traverse the DOM; $(&#8216;container&#8217;).childNodes can do wonders</li>
<li>Bind once to a common parent element</li>
<li>Find items by name instead of class</li>
<li>Forget about all the initializing and fall back to old school onclick=&#8221;classinstance.respondToReportButton()&#8221;</li>
</ol>
<p>This last option sort of goes against many webdevelopment principles, but is often a very pragmatic choice. <a href="http://www.vcasmo.com/video/osnow/391" target="_blank">Joseph Smarr from Plaxo</a> holds a similar opinion on the topic.</p>
<p>A better implementation using technique 1 would be:</p>
<pre name="code" class="js">this.respondToReportButtonBound = this.respondToReportButton.bind(this);
for(x=1;x&lt;16;x++) {
   button = $('report_button'+x);
   if(!button) break;
   button.observe('click', this.respondToReportButtonBound);
}</pre>
<p>In practice I&#8217;ve experienced speed improvements of over 40 times using this technique. Firstly the repondTo function is bound only once. Secondly the $$ function is no longer needed. Thirdly the each implementation has been replaced by a blazingly fast for loop. Fourthly the id is no longer extracted. A better practice is to extract it when respondToReportButton is actually executed. This last point actually brings us to the next main item.</p>
<h3>Step 2: Be Lazy!</h3>
<p>The trick here is to actually put in a bit of effort to make your code lazy. Don&#8217;t do anything until it is needed. (With the one, but large exception if doing so would hurt the user experience.) If some items are currently not visible to the user simply don&#8217;t bind events to them. If you need to extract id&#8217;s don&#8217;t do so until someone actually clicks on the item in question. Furthermore also make it lazy in the regular sense of the word. If your code only need to change one item, figure out which one it is and don&#8217;t loop about changing all just in case. This point is different for every application, but it can achieve great speed gains for a creative programmer!</p>
<h3>Step 3: Stop using prototype functions if you don&#8217;t need them</h3>
<p>Often you do not really need (as in that it barely saves you development time) some of the functionality of prototype. When comparing the speed of element.innerHTML = &#8216;hello world&#8217; versus element.update(&#8216;hello world&#8217;) the differences are substantial (60 times with large chunks of html). Also the each iterator is often not needed and can be replace by a simple for loop with checks on nodeType and tagName. The same goes for the templating system. These tools barely save you time, but really hurt performance. I am a big fan of the prototype library and for most use cases these nice helpers are great. When you really need speed, be sure to refrain from using them though.</p>
<h3>Step 4: Lower level optimizations</h3>
<p>When you are done implementing the really important optimizations there are quite some lower level optimizations which will speed up your code.</p>
<ul>
<li> Write to innerHTML instead of using document.createElement</li>
<li> Use for loops instead of for in loops</li>
<li><a href="http://blogs.msdn.com/ie/archive/2006/11/16/ie-javascript-performance-recommendations-part-2-javascript-code-inefficiencies.aspx" target="_blank"><del datetime="2008-05-19T14:52:29+00:00"> Use Array.join instead of += on a string</del></a>, see <a href="http://www.sitepen.com/blog/2008/05/09/string-performance-an-analysis/" target="_blank">SitePen</a></li>
<li><a href="http://blogs.msdn.com/ie/archive/2006/08/28/728654.aspx" target="_blank">Cache variables and functions</a></li>
<li> Limit the usage of Eval</li>
<li> Limit the usage of Try Catch statements</li>
<li><a href="http://dev.opera.com/articles/view/efficient-javascript/?page=3#modifyingtree" target="_blank"> When manipulating the DOM copy the element out of DOM change it and stick it back in</a></li>
</ul>
<p>Two generally great resources on the topic are:</p>
<ol>
<li><a href="http://www.vcasmo.com/video/osnow/391" target="_blank">Joseph Smarr (Plaxo)</a></li>
<li><a href="http://dev.opera.com/articles/view/efficient-javascript/" target="_blank">Opera Dev</a></li>
</ol>
<h3>The missing performance data</h3>
<p>One item affecting the performance of javascript interface elements is the speed by which the browsers redraws the page. Unfortunately I have barely found any documentation on how browsers determine what to redraw and what affects redraw speed. One certainty is the negative influence of transparent images on redraw speed, but other than that little seems to be known. Furthermore most browsers won&#8217;t redraw the page until your javascript function returns. This can make your interface elements feel very unresponsive. A solution to this problem is to use the setTimeout functionality.</p>
<h3 style="margin-top:50px">Message for Dutch Programmers</h3>
<p>YouTellMe is an innovative startup located in the center of Rotterdam. Talented programmers are always welcome. Have a look at the <a href="http://www.youtellme.com/blog/jobs/" target="_blank">job page</a> to get an impression of the job openings (We develop using Python/Django).</p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F05%2F18%2Fjavascript-optimization-high-performance-js-apps%2F&amp;title=Javascript%20optimization%20-%20high%20performance%20JS%20apps" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F05%2F18%2Fjavascript-optimization-high-performance-js-apps%2F&amp;title=Javascript%20optimization%20-%20high%20performance%20JS%20apps" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F05%2F18%2Fjavascript-optimization-high-performance-js-apps%2F&amp;title=Javascript%20optimization%20-%20high%20performance%20JS%20apps" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F05%2F18%2Fjavascript-optimization-high-performance-js-apps%2F&amp;t=Javascript%20optimization%20-%20high%20performance%20JS%20apps" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F05%2F18%2Fjavascript-optimization-high-performance-js-apps%2F&amp;title=Javascript%20optimization%20-%20high%20performance%20JS%20apps" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F05%2F18%2Fjavascript-optimization-high-performance-js-apps%2F&amp;title=Javascript%20optimization%20-%20high%20performance%20JS%20apps" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2008/05/18/javascript-optimization-high-performance-js-apps/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Have a Cookie</title>
		<link>http://www.mellowmorning.com/2008/02/07/have-a-cookie/</link>
		<comments>http://www.mellowmorning.com/2008/02/07/have-a-cookie/#comments</comments>
		<pubDate>Thu, 07 Feb 2008 14:27:22 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/2008/02/07/have-a-cookie/</guid>
		<description><![CDATA[Here a nice little cookie wrapper. It&#8217;s mainly based on the Quirksmode code with some nice Prototype style.
Have a look:
var cookieJar = Class.create();
cookieJar.prototype = {
initialize: function() {},
write: function(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = '';
document.cookie = name + '=' + value + expires + '; path=/';
},
writeJSON: function(name,value,days) [...]]]></description>
			<content:encoded><![CDATA[<p>Here a nice little cookie wrapper. It&#8217;s mainly based on the <a href="http://www.quirksmode.org/js/cookies.html" target="_blank">Quirksmode</a> code with some nice Prototype style.</p>
<p>Have a look:</p>
<p><code>var cookieJar = Class.create();<br />
cookieJar.prototype = {<br />
initialize: function() {},<br />
write: function(name,value,days) {<br />
if (days) {<br />
var date = new Date();<br />
date.setTime(date.getTime()+(days*24*60*60*1000));<br />
var expires = "; expires="+date.toGMTString();<br />
}<br />
else var expires = '';<br />
document.cookie = name + '=' + value + expires + '; path=/';<br />
},<br />
writeJSON: function(name,value,days) {<br />
var JSONvalue = $H(value).toJSON();<br />
this.write(name,JSONvalue,days);<br />
},<br />
read: function(name) {<br />
var nameEQ = name + '=';<br />
var ca = document.cookie.split(';');<br />
for(var i=0;i &lt; ca.length;i++) {<br />
var c = ca[i];<br />
while (c.charAt(0)==' ') c = c.substring(1,c.length);<br />
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);<br />
}<br />
return false;<br />
},<br />
readJSON: function(name) {<br />
var value = this.read(name) || '{}';<br />
value = value.evalJSON();<br />
return value;<br />
},<br />
erase: function (name) {<br />
this.create(name,"",-1);<br />
}<br />
};<br />
cJar = new cookieJar();</code></p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F02%2F07%2Fhave-a-cookie%2F&amp;title=Have%20a%20Cookie" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F02%2F07%2Fhave-a-cookie%2F&amp;title=Have%20a%20Cookie" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F02%2F07%2Fhave-a-cookie%2F&amp;title=Have%20a%20Cookie" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F02%2F07%2Fhave-a-cookie%2F&amp;t=Have%20a%20Cookie" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F02%2F07%2Fhave-a-cookie%2F&amp;title=Have%20a%20Cookie" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F02%2F07%2Fhave-a-cookie%2F&amp;title=Have%20a%20Cookie" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2008/02/07/have-a-cookie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A new job! &#8211; but no Symfony</title>
		<link>http://www.mellowmorning.com/2008/01/20/a-new-job-but-no-symfony/</link>
		<comments>http://www.mellowmorning.com/2008/01/20/a-new-job-but-no-symfony/#comments</comments>
		<pubDate>Sun, 20 Jan 2008 22:43:04 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/2008/01/20/a-new-job-but-no-symfony/</guid>
		<description><![CDATA[Note: We are actively seeking to hire exceptional PHP programmers. More on the job offering at the bottom of this posts.
After one of my posts got featured on Ajaxian many interesting offers hit my mailbox.  One of them was actually from a startup right here in Rotterdam called ZeroBubble. I was happily surprised to [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note</strong>: We are actively seeking to hire exceptional PHP programmers. More on the job offering at the bottom of this posts.</p>
<p><a href="http://www.zerobubble.nl" target="_blank" title="Zero Bubble"><img src="http://www.mellowmorning.com/wp-content/uploads/2008/01/logo-zerobubble.gif" alt="Zero Bubble" style="padding: 5px; float: right" /></a>After one of my posts got featured on <a href="http://www.ajaxian.com/">Ajaxian</a> many interesting offers hit my mailbox.  One of them was actually from a startup right here in Rotterdam called ZeroBubble. I was happily surprised to find an IT startup in Rotterdam. Especially since after talking to them it became clear that they operate at the highest level of technical possibilities and have an absolutely amazing team. Two months ago I happily joined their ranks.</p>
<p><a href="http://www.youtellme.com" title="YouTellMe"><img src="http://www.mellowmorning.com/wp-content/uploads/2008/01/logo-youtellme.gif" alt="YouTellMe" style="padding: 5px; float: right; margin-right: -20px" /></a></p>
<p>The project we are working on is called YouTellMe. I don&#8217;t want to share too much about it right now, but surely I will have plenty of exciting blog posts coming up in the next months.<br />
Currently we are working with some of the nicest tech on the net. To give some examples: our admin interface is written entirely in ExtJs, the site&#8217;s search is powered by Lucene, we use prototype 1.6 for great object extending, for ajax functionality we use yahoo history manager to keep it bookmarkable, the entire site has been optimized according to the Yslow principles and we are doing some interesting things with openSocial. Given all these you can&#8217;t help but wonder why we aren&#8217;t using Symfony.</p>
<h3>Why no Symfony?</h3>
<p>Personally I am a huge fan of the Symfony framework. The team at Sensio has done an absolutely amazing job. My opinion on the framework is best described by these blog posts <a href="http://www.mellowmorning.com/2007/08/18/ten-reasons-why-symfony-rocks-part-1/" target="_blank">Part1</a>, <a href="http://www.mellowmorning.com/2007/09/08/ten-reasons-why-symfony-rocks-part-2/" target="_blank">Part2</a>. However the current project we are working on has some special requirements. First of all the application&#8217;s calculations are very harsh on the servers. Combine this with a large amount of AJAX and you have some serious performance issues. The calculation speed has been pretty optimized by a colleague of mine, who wrote a python daemon for the task. Still it is essential to keep the PHP framework&#8217;s overhead to a minimum. Prior to my employment at this company it was decided that Symfony would be too slow to handle the task. This is a topic which often nags Symfony.</p>
<p>I am curious how fast Symfony can be. For the YouTellMe site I need a bootstrapped and blazingly fast framework. In the coming weeks I&#8217;ll be setting up some tests too see how Symfony compares to our home build framework. As a starters I&#8217;ll definitely relieve Symfony from the ORM and fancy routing. From there on I will need to test to see which components are slow and can be removed. The clean and flexible programming in Symfony should make this easy to do.</p>
<p>Our current framework is very lightweight. It even does not do auto loading. I for one have no clue what the speed gain is from not using auto loading and it would also be interesting to test it. The MVC structure is entirely home build, but the rest of the features use Zend.</p>
<p>If there are readers of this blog, which have gone through the process of stripping Symfony, be sure to leave some tips in the comments!</p>
<h4 id="jobs">Jobs at ZeroBubble</h4>
<p>ZeroBubble is currently recruiting talented PHP programmers in the Rotterdam area. We are located in the Beurs World Trade center. If you are into the latest technology and like to work with great people, software and hardware be sure to email me at thierry [at] zerobubble [dot] nl or my boss at joost [at] zerobubble [dot] nl. As mentioned we work with fun software such as Ext Js, Lucene, Zend, object oriented js with Prototype 1.6, yahoo history, Yslow principles and openSocial.<br />
We are looking for both full and partime PHP programmers. Python, ExtJs, prototype, server admin, subversion and memcached knowledge are all nice extras. As a main quality though, you have to be excited about building a unique and amazing web application.</p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F01%2F20%2Fa-new-job-but-no-symfony%2F&amp;title=A%20new%20job%21%20-%20but%20no%20Symfony" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F01%2F20%2Fa-new-job-but-no-symfony%2F&amp;title=A%20new%20job%21%20-%20but%20no%20Symfony" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F01%2F20%2Fa-new-job-but-no-symfony%2F&amp;title=A%20new%20job%21%20-%20but%20no%20Symfony" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F01%2F20%2Fa-new-job-but-no-symfony%2F&amp;t=A%20new%20job%21%20-%20but%20no%20Symfony" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F01%2F20%2Fa-new-job-but-no-symfony%2F&amp;title=A%20new%20job%21%20-%20but%20no%20Symfony" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2008%2F01%2F20%2Fa-new-job-but-no-symfony%2F&amp;title=A%20new%20job%21%20-%20but%20no%20Symfony" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2008/01/20/a-new-job-but-no-symfony/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Is the php native json_encode really broken?</title>
		<link>http://www.mellowmorning.com/2007/12/20/is-the-php-native-json_encode-really-broken/</link>
		<comments>http://www.mellowmorning.com/2007/12/20/is-the-php-native-json_encode-really-broken/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 23:48:32 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/2007/12/20/is-the-php-native-json_encode-really-broken/</guid>
		<description><![CDATA[It sure seems so:
The php:
var_dump(array('mynumber'=&#62;42.2));
var_dump(json_encode(array('mynumber'=&#62;42.2)));
The result:
array(1) {
["mynumber"]=&#62;
float(42,2)
}
string(17) "{"mynumber":42,2}"
Notice the 42,2.
&#8216;42,2&#8242; or &#8220;42.2&#8243; or 42.2 would have all been fine, but 42,2 obviously invalidates your json object.
The problem seems to arise from my &#8216;nl&#8217; internationalization setting in php. I&#8217;m guessing the same problem will occur with any language which uses the comma for decimal separations.
Currently I [...]]]></description>
			<content:encoded><![CDATA[<p>It sure seems so:</p>
<p>The php:<br />
<code>var_dump(array('mynumber'=&gt;42.2));<br />
var_dump(json_encode(array('mynumber'=&gt;42.2)));</code></p>
<p>The result:<br />
<code>array(1) {<br />
["mynumber"]=&gt;<br />
float(42,2)<br />
}<br />
string(17) "{"mynumber":42,2}"</code></p>
<p>Notice the 42,2.<br />
&#8216;42,2&#8242; or &#8220;42.2&#8243; or 42.2 would have all been fine, but 42,2 obviously invalidates your json object.</p>
<p>The problem seems to arise from my &#8216;nl&#8217; internationalization setting in php. I&#8217;m guessing the same problem will occur with any language which uses the comma for decimal separations.</p>
<p>Currently I am solving this problem by typecasting my number to a string, but there has to be a better approach.</p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F12%2F20%2Fis-the-php-native-json_encode-really-broken%2F&amp;title=Is%20the%20php%20native%20json_encode%20really%20broken%3F" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F12%2F20%2Fis-the-php-native-json_encode-really-broken%2F&amp;title=Is%20the%20php%20native%20json_encode%20really%20broken%3F" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F12%2F20%2Fis-the-php-native-json_encode-really-broken%2F&amp;title=Is%20the%20php%20native%20json_encode%20really%20broken%3F" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F12%2F20%2Fis-the-php-native-json_encode-really-broken%2F&amp;t=Is%20the%20php%20native%20json_encode%20really%20broken%3F" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F12%2F20%2Fis-the-php-native-json_encode-really-broken%2F&amp;title=Is%20the%20php%20native%20json_encode%20really%20broken%3F" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F12%2F20%2Fis-the-php-native-json_encode-really-broken%2F&amp;title=Is%20the%20php%20native%20json_encode%20really%20broken%3F" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2007/12/20/is-the-php-native-json_encode-really-broken/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated cross site ajax plugin for Prototype</title>
		<link>http://www.mellowmorning.com/2007/11/07/updated-cross-site-ajax-plugin-for-prototype/</link>
		<comments>http://www.mellowmorning.com/2007/11/07/updated-cross-site-ajax-plugin-for-prototype/#comments</comments>
		<pubDate>Wed, 07 Nov 2007 22:08:19 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/2007/11/07/updated-cross-site-ajax-plugin-for-prototype/</guid>
		<description><![CDATA[The first post on my cross site ajax plugin for Prototype (1.5.0) was received with great enthusiasm. It was very nice to see my own work on the great Ajaxian website and the delicious front page. Since that post the quality of the plug-in has improved quite a bit. Especially cross browser compatibility improved. I [...]]]></description>
			<content:encoded><![CDATA[<p>The first post on my <a href="http://www.mellowmorning.com/2007/10/25/introducing-a-cross-site-ajax-plugin-for-prototype/">cross site ajax plugin for Prototype</a> (1.5.0) was received with great enthusiasm. It was very nice to see my own work on the great <a href="http://ajaxian.com/">Ajaxian</a> website and the delicious front page. Since that post the quality of the plug-in has improved quite a bit. Especially cross browser compatibility improved. I made a test page to evaluate this; <a href="http://www.mellowmorning.com/wp-content/uploads/2007/11/testcrosssiteajax.html" title="Test" target="_blank">have a look to test your own browser</a>. Furthermore <a href="http://browsershots.org/http://www.commenthub.com/testCrossSiteAjax.html" target="_blank">some 14 screen shots</a> show that the compatibility is good.</p>
<p>Here the new version: <a href="http://www.mellowmorning.com/wp-content/uploads/2007/11/transport.js" title="Transport - Cross site ajax plugin for prototype" target="_blank">Download the cross site ajax plugin</a>.</p>
<p>The syntax remains exactly the same:</p>
<p><code>new Ajax.Request(url, {<br />
method: 'GET',<br />
crossSite: true,<br />
onLoading: function() {<br />
//things to do at the start<br />
},<br />
onSuccess: function(transport) {<br />
//things to do when everything goes well<br />
},<br />
onFailure: function(transport) {<br />
//things to do when we encounter a failure<br />
}<br />
});</code></p>
<h4>Cross Browser Compatibility</h4>
<p>First of all thanks to <a href="http://cixar.com/tracs/javascript" target="_blank">Kris Kowal</a> and Gary Gurevich for spotting the problems with Safari. Prior to the changes the plugin used three different methods to detect the loading of the script element. For Safari and Konqueror a sequential script technique was used. This technique has now been replaced with the polling technique, like in <a href="http://cows-ajax.sourceforge.net/">COWS</a>. So the following three solutions are used.</p>
<p>1.) For IE it used its proprietary onreadystatechange event<br />
2.) For Safari and Konqueror it uses the polling technique<br />
3.) For Firefox and Opera it uses the standard onload event</p>
<h4>Timing problems</h4>
<p>In addition to the cross browser compatibility problems I noticed another complication. In Prototype 1.5.0 the onLoading, onSuccess etc., are generally fired by running the onreadystatechange function. However this is not the case for a transport status below 2. Actually the onLoading event is triggered by a delayed function after the open command. I didn&#8217;t realize this initially. However if you have a script which loads rather fast it will result in onSuccess executing before onLoading. This issue was fixed by calling respondToReadyState directly.</p>
<h4>Points of Improvement</h4>
<p>Firstly the current implementation detects browsers, not capabilities. This might create problems with future or buggy versions of browsers.<br />
Secondly the usage of a global variable to indicate transport status makes it impossible to handle simultaneous requests nicely.<br />
Thirdly the script currently does not clean up the script nodes.</p>
<p>If these points turn out to be troublesome, I will use a modified version of COWS for the transport aspects.</p>
<h4>Conclusion</h4>
<p>The new version of this plug-in is widely cross browser compatible. Currently it is suitable for a large variety of applications. It is however not yet ready to deal with simultaneous requests.</p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F11%2F07%2Fupdated-cross-site-ajax-plugin-for-prototype%2F&amp;title=Updated%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F11%2F07%2Fupdated-cross-site-ajax-plugin-for-prototype%2F&amp;title=Updated%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F11%2F07%2Fupdated-cross-site-ajax-plugin-for-prototype%2F&amp;title=Updated%20cross%20site%20ajax%20plugin%20for%20Prototype" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F11%2F07%2Fupdated-cross-site-ajax-plugin-for-prototype%2F&amp;t=Updated%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F11%2F07%2Fupdated-cross-site-ajax-plugin-for-prototype%2F&amp;title=Updated%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F11%2F07%2Fupdated-cross-site-ajax-plugin-for-prototype%2F&amp;title=Updated%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2007/11/07/updated-cross-site-ajax-plugin-for-prototype/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introducing a cross site ajax plugin for Prototype</title>
		<link>http://www.mellowmorning.com/2007/10/25/introducing-a-cross-site-ajax-plugin-for-prototype/</link>
		<comments>http://www.mellowmorning.com/2007/10/25/introducing-a-cross-site-ajax-plugin-for-prototype/#comments</comments>
		<pubDate>Thu, 25 Oct 2007 20:59:59 +0000</pubDate>
		<dc:creator>tschellenbach</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.mellowmorning.com/2007/10/25/introducing-a-cross-site-ajax-plugin-for-prototype/</guid>
		<description><![CDATA[Update: there have been some improvements to this plugin. Have a look at this post regarding the update. Thanks for the feedback!
After some days of hard labor, I finished my cross site Ajax plugin for the prototype framework 1.5.0. (Download Plugin Here) While working on a new product of mine I realized I needed cross [...]]]></description>
			<content:encoded><![CDATA[<p>Update: there have been some improvements to this plugin. Have a look at <a href="http://www.mellowmorning.com/2007/11/07/updated-cross-site-ajax-plugin-for-prototype/">this post regarding the update</a>. Thanks for the feedback!</p>
<p>After some days of hard labor, I finished my cross site Ajax plugin for the <a href="http://prototypejs.org/" target="_blank">prototype framework</a> 1.5.0. (<a href="http://www.mellowmorning.com/wp-content/uploads/2007/10/transport.js" title="Transport Class" target="_blank">Download Plugin Here</a>) While working on a new product of mine I realized I needed cross site Ajax, which is not supported in the Prototype framework.</p>
<p>During cross site Ajax requests the standard <a href="http://en.wikipedia.org/wiki/XMLHttpRequest" target="_blank">XmlHttpRequest</a> approach breaks down. The problem is that XmlHttpRequest is bounded by the same site policy. Fortunately the script tag has the freedom to do as it pleases.</p>
<p>Some other libraries such as <a href="http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book25" target="_blank">dojo</a> and <a href="http://" target="_blank">jquery</a> do support the script method for doing Ajax. There is even a project on source-forge called <a href="http://cows-ajax.sourceforge.net/tech.php" target="_blank">COWS</a>, which is dedicated to this purpose. This plugin is an adaptation of the jquery plugin, but modeled to look like an XmlHttpRequest. The credits of the original code go to <a href="http://trainofthoughts.org/blog/" target="_blank">Ralf S. Engelschall</a> , which amazingly achieved to make it nicely cross browser compatible. This plugin supports FF, IE, Safari, Opera and Konqueror, but has only been properly tested in FF and IE.</p>
<p>Prototype&#8217;s structured way of doing Ajax was my main reason to choose the prototype framework. Furthermore it is also included in <a href="http://www.mellowmorning.com/2007/08/18/ten-reasons-why-symfony-rocks-part-1/" target="_blank">the</a> <a href="http://www.mellowmorning.com/2007/09/08/ten-reasons-why-symfony-rocks-part-2/" target="_blank">great</a> <a href="http://www.symfony-project.com/" target="_blank">Symfony framework</a>. In Prototype Ajax requests are written like this:</p>
<p><code>new Ajax.Request('myurl', {<br />
method: 'GET',<br />
crossSite: true,<br />
parameters: Form.serialize(obj),<br />
onLoading: function() {<br />
//things to do at the start<br />
},<br />
onSuccess: function(transport) {<br />
//things to do when everything goes well<br />
},<br />
onFailure: function(transport) {<br />
//things to do when we encounter a failure<br />
}<br />
});</code></p>
<p>The cross site plugin simply allows you to do Ajax cross site, by specifying crossSite: true (line 3 of the above example). I will now cover some technical aspects of the plugin, but if you just want to start using it simply skip to the plug and play instructions below.</p>
<h4>How it works &#8211; Technical Aspects</h4>
<p>This plugin uses the dynamic script tag technique. This basically means that we insert new &lt;script&gt; tags into the Dom. Since this script tag is not bound to the same site you can send and receive data in the Ajax way. In its most basic form the javascript would be like this:</p>
<p><code>this.node = document.createElement('SCRIPT');</code><br />
<code> this.node.type = 'text/javascript';<br />
this.node.src = 'http://www.serversite.com';<br />
var head = document.getElementsByTagName('HEAD')[0];<br />
head.appendChild(this.node);</code></p>
<p>In order to make it very easy to use with Prototype, or any other library for that matter, I decided to mimic the functions of the <a href="http://en.wikipedia.org/wiki/XMLHttpRequest" target="_blank">XmlHttpRequest</a>. This is easily achieved by implementing the functions open, send and onreadystatechange. Furthermore I needed to specify the variables readyState and status in order to support prototype&#8217;s onLoad, onSucces and onFailure.</p>
<p>Detecting the loading of a script element is not that easy. Browsers such as Safari and Konqueror simply give no indication of this at all. One <a href="http://web.archive.org/web/20070125203701/http://blog.slimc.com/dojo-penetrates-prototype/" target="_blank">common</a> <a href="http://ajaxian.com/archives/prototype-extension-dynamic-script-pattern-support" target="_blank">solution</a> to dealing with this is to use <a href="http://remysharp.com/2007/04/12/how-to-detect-when-an-external-library-has-loaded/" target="_blank">an interval</a> and perform a check. The work at <a href="http://trainofthoughts.org/blog/2007/04/12/jquery-plugin-xsajax/" target="_blank">TrainOfThoughts</a> however takes the beautiful approach of inserting a helper script. This exploits the fact that the dynamically added scripts are executed in sequence. This approach makes the plugin nicely cross browser compatible.</p>
<p>Detecting failure is rather cumbersome for the script technique. As far as I know there is no way to read the headers on the incoming file, or to inspect its contents through javascript. This leaves us with the rather blunt approach of setting a global variable using the server output. It works, but it could be prettier.</p>
<h4>Plug and Play implementation instructions</h4>
<p>Firstly you need to load the plugin javascript file: <a href="http://www.mellowmorning.com/wp-content/uploads/2007/10/transport.js" title="Transport Class" target="_blank">download cross site ajax plugin for the prototype framework 1.5.0.</a></p>
<p>Secondly you need to change your regular prototype Ajax request, by ensuring that you instruct it to use the crossSite and GET methods, as such (observe line 2 and 3):</p>
<p><code>new Ajax.Request(baseurl+'/comment/giveratingjs', {<br />
method: 'GET',<br />
crossSite: true,<br />
parameters: Form.serialize(obj),<br />
onLoading: function() {<br />
//things to do at the start<br />
},<br />
onSuccess: function(transport) {<br />
//things to do when everything goes well<br />
},<br />
onFailure: function(transport) {<br />
//things to do when we encounter a failure<br />
}<br />
});</code></p>
<p>Thirdly you might need to rewrite some of your javascript code to accommodate the instant execution of the scripts.</p>
<p>Fourthly, if you want to use onFailure for any of your scripts you need to send some javascript instructions back from the server. You need to do this both on success and on failure (since a global variable is used). This is the javascript variable you need to set:</p>
<p><code>'var _xsajax$transport_status =  200;' Or<br />
'var _xsajax$transport_status =  404;'</code></p>
<h4>Symfony specific tips</h4>
<p>Symfony detects if it receives a XmlHttpRequest and automatically turns off your debug bar and layout.  Unfortunately it is not so kind to the script technique. So in your action you need to do this manually:</p>
<p><code>sfConfig::set('sf_web_debug', false);<br />
$this-&gt;setLayout(false);</code></p>
<p>Furthermore your validation files by default only look at POST variables (this one tricked me). To instruct them to look at both, simply mention</p>
<p><code>methods:     [post, get]</code></p>
<p>at the top of your validation.yml</p>
<p>Since you will probably want to send html to the browser, I would suggest you put this little function (found in the symfony escape helpers) in your toolbox.</p>
<p><code>public static function esc_js($value) {<br />
return addcslashes($value, "\0..\37\\'\"\177..\377\/");<br />
}</code></p>
<h4>Conclusion</h4>
<p>The dynamic script tag technique opens up a wide range of possibilities. Personally I am very glad with the results and would like to thank <a href="http://trainofthoughts.org/blog/" target="_blank">Ralf S. Engelschall</a> for his <a href="http://trainofthoughts.org/blog/2007/04/12/jquery-plugin-xsajax/" target="_blank">superb cbc work</a>. Unfortunately I didn&#8217;t include an example this time. You will have to wait for the products&#8217; launch:). Comments and improvements are always appreciated. Enjoy your cross site scripting!</p>



Share and Enjoy:


	<a rel="nofollow" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F10%2F25%2Fintroducing-a-cross-site-ajax-plugin-for-prototype%2F&amp;title=Introducing%20a%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Digg"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F10%2F25%2Fintroducing-a-cross-site-ajax-plugin-for-prototype%2F&amp;title=Introducing%20a%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Sphinn"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/sphinn.gif" title="Sphinn" alt="Sphinn" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F10%2F25%2Fintroducing-a-cross-site-ajax-plugin-for-prototype%2F&amp;title=Introducing%20a%20cross%20site%20ajax%20plugin%20for%20Prototype" title="del.icio.us"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F10%2F25%2Fintroducing-a-cross-site-ajax-plugin-for-prototype%2F&amp;t=Introducing%20a%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Facebook"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F10%2F25%2Fintroducing-a-cross-site-ajax-plugin-for-prototype%2F&amp;title=Introducing%20a%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Mixx"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/mixx.png" title="Mixx" alt="Mixx" class="sociable-hovers" /></a>
	<a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.mellowmorning.com%2F2007%2F10%2F25%2Fintroducing-a-cross-site-ajax-plugin-for-prototype%2F&amp;title=Introducing%20a%20cross%20site%20ajax%20plugin%20for%20Prototype" title="Google"><img src="http://www.mellowmorning.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google" alt="Google" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.mellowmorning.com/2007/10/25/introducing-a-cross-site-ajax-plugin-for-prototype/feed/</wfw:commentRss>
		<slash:comments>47</slash:comments>
		</item>
	</channel>
</rss>

