<?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>o2.js</title>
	<atom:link href="http://o2js.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://o2js.com</link>
	<description>A Coherent Solution to Your #JavaScript Dilemma</description>
	<lastBuildDate>Tue, 30 Apr 2013 01:15:30 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Well&#8230; That&#8217;s Another Year&#8230; Or, is It?</title>
		<link>http://o2js.com/2012/12/23/2013-will-rock-more/</link>
		<comments>http://o2js.com/2012/12/23/2013-will-rock-more/#comments</comments>
		<pubDate>Sun, 23 Dec 2012 21:51:40 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[2013]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript interview questions]]></category>
		<category><![CDATA[jsiq]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[new year]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[recent]]></category>
		<category><![CDATA[the zuck]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2867</guid>
		<description><![CDATA[If you are into JavaScript Engineering / Front End Development (and chances are very high that you &#8220;are&#8221; if you are reading this) you must have realized that every year things evolve exponentially faster than the former one. In the year 2012, so many awesome articles, tools and resources were &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2873" class="wp-caption alignleft" style="width: 260px"><a href="http://o2js.com/wp-content/uploads/2012/12/newyear21.png" rel="attachment wp-att-2873"><img src="http://o2js.com/wp-content/uploads/2012/12/newyear21.png" alt="2013 Will Rock More" width="250" height="170" class="size-full wp-image-2873" /></a><p class="wp-caption-text">2013 Will Rock More</p></div>
<p>If you are into <strong>JavaScript Engineering</strong> / <strong>Front End Development</strong> (and chances are very high that you &#8220;are&#8221; if you are reading this) you must have realized that every year things evolve <strong>exponentially faster</strong> than the former one. </p>
<p>In the year 2012, so many awesome articles, tools and resources were released; and so much passion, time and energy was invested in establishing standards and finalizing new <strong>API</strong>s. </p>
<p>Also the developer tools have become <strong>even better</strong> (take <a href="https://hacks.mozilla.org/2012/07/firebug-1-10-new-features/" title="Firebug - New Features">recent changes in Firebug</a>, for example &#8212; or the &#8220;<a href="http://paulirish.com/2011/a-re-introduction-to-the-chrome-developer-tools/" title="A Re-Introduction to Chrome Developer Tools">Framed Mode</a>&#8221; in Chrome Developer tools. </p>
<blockquote><p>So for those who think <strong>HTML5</strong> won&#8217;t be ready until, say 2050… I say <strong>&#8220;Bah, humbug!&#8221;</strong>.</p></blockquote>
<p><em>Actually that phrase takes me back to the year <strong>2006</strong>, and <a href="http://lists.evolt.org/archive/Week-of-Mon-20060619/113486.html" title="JavaScript only for browsers? Bah! Humbug!">it belongs to a thought leader, whom you (have to) know</a> &#8212; sometimes I think that I&#8217;ve a photographic memory of some sort <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong></em></p>
<p>Anyways, <a href="http://www.w3.org/2012/12/html5-cr">W3C has officially announced</a> that <strong>HTML5 is done</strong> and <strong>HTML5.1</strong> is on the agenda. And browser vendors are working aggressively hard to implement as many of the HTML5 features as they can. </p>
<blockquote><p>I don&#8217;t care if some &#8220;<strong>Sugar Mountain</strong>&#8221; utters that <a href="http://techcrunch.com/2012/09/11/mark-zuckerberg-our-biggest-mistake-with-mobile-was-betting-too-much-on-html5/" title="bah!">HTML5 is not good enough</a> to be used in a mobile application &#8212; <strong>Bah, humbug!</strong></p></blockquote>
<h2>&#8220;<a href="http://o2js.com/interview-questions/" title="JavaScript Interview Questions">JavaScript Interview Questions</a>&#8221; in the New Year</h2>
<p>The rapid evolution of the industry was also a core part of what I&#8217;ve e-mailed to the readers of <strong><a href="http://o2js.com/interview-questions/" title="JavaScript Interview Questions">JavaScript Interview Questions</a></strong> today.</p>
<p>Bottom line of my message was that <a href="http://o2js.com/2012/09/09/javascript-interview-questions/" title="Ace Your Interview Like a Samurai">acing your job interview like a Samurai</a> was only part of the equation. Your aim should be to be &#8220;great&#8221; at what you do (<em><strong>not</strong> to be a great &#8220;virtual realitiy&#8221; game (i.e. interviews) player, instead</em>). </p>
<p>And it&#8217;s not only a message for the book&#8217;s audience, but also a reminder for everyone who want to be ahead of the competition. So I have an urge for repeating myself here:</p>
<blockquote><p>To be a great <strong>JavaScript Engineer</strong>, you have to keep track of everything and update yourself with a continuous stream of knowledge, technologies, and tools. I don&#8217;t know you, and I really &#8220;<strong>love</strong>&#8221; being a part of this <strong>(r)</strong>evolution! </p></blockquote>
<p>Yes everything is evolving rapidly. And during all this hassle, my aim is to come up with a &#8220;<strong>time-independent</strong>&#8221; book, that won&#8217;t get &#8220;<strong>rusted</strong>&#8220;. And to reach this aim, I&#8230;</p>
<ul style="margin-top:-20px">
<li>Try to give be as much <strong>platform/framework agnostic</strong> as possible (giving plain old <strong>JavaScript</strong> examples);</li>
<li>Try to provide enough <strong>supporting material</strong> to establish firm grounds to stand when an interviewer asks you a tricky question;</li>
<li>Try to &#8220;<strong>incept</strong>&#8221; a thirst to read an learn more in the reader (and serve this thirst by providing further reading material which is really hard to gather with a naive google search &#8211; have I told you that I have a good memory <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ?).</li>
</ul>
<blockquote><p>I&#8217;m not sure whether I&#8217;m successful in these goals. Especially the last one is the hardest and trickiest one <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  &#8212; And I&#8217;d love to hear your comments and suggestions that can make &#8220;<strong>JavaScript Interview Questions</strong>&#8221; book rock.</p></blockquote>
<p>Yet I have been (<em>and I will be</em>) thoroughly enjoying writing the book. To be honest, I even use the material for my personal reference. And it&#8217;s &#8220;<strong>awesome</strong>&#8221; to refer to something you&#8217;ve written in your daily work.</p>
<p>I hope the readers of the book are enjoying their read too.</p>
<p>And more importantly, this blog post wouldn&#8217;t have existed if it wasn&#8217;t you who have supported me through your motivational comments and emails. And even knowing that you&#8217;re reading this and I&#8217;m making a net positive difference in your perception on not only JavaScript, but also on the interview &#8220;virtual reality&#8221; as a whole, is an excellent motivation to sit on my arse and continue writing <a href="http://o2js.com/interview-questions/" title="JavaScript Interview Questions">the book</a>.</p>
<p>So I owe <strong>a big thank you</strong> to you, who help me <strong>make an impact</strong>.</p>
<p>Currently I&#8217;m working on the &#8220;<strong>Patterns</strong>&#8221; section of the book, and I believe that section will be ready by the end of January, 2013.</p>
<p>Until then, have a good one and enjoy the festive season!</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/12/23/2013-will-rock-more/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Now you can Ace that Interview Like a Samurai and Land Your Dream Job</title>
		<link>http://o2js.com/2012/09/09/javascript-interview-questions/</link>
		<comments>http://o2js.com/2012/09/09/javascript-interview-questions/#comments</comments>
		<pubDate>Sun, 09 Sep 2012 19:54:31 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[behavioral interviews]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[interview]]></category>
		<category><![CDATA[interview questions]]></category>
		<category><![CDATA[interviews]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript interview]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[technical interviews]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2825</guid>
		<description><![CDATA[It has been almost a year since I wrote about interviews. In that time frame I’ve learned a lot. Furthermore, I&#8217;ve learned most of the things the hard way. I also realized that most of the interviewing books, articles and blog posts are completely and utterly misdirections, to say the &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2826" class="wp-caption alignleft" style="width: 230px"><a href="http://o2js.com/interview-questions/"><img src="http://o2js.com/wp-content/uploads/2012/09/jsiq.png" alt="How to Nail That Job Interview" title="How to Nail That Job Interview" width="220" height="294" class="size-full wp-image-2826" /></a><p class="wp-caption-text">How to Nail That Job Interview</p></div>
<p>It has been <a href="http://o2js.com/2011/12/21/javascript-interview-questions-2012/">almost a year</a> since I wrote about <strong>interviews</strong>. In that time frame I’ve learned <strong>a lot</strong>. Furthermore, I&#8217;ve learned most of the things <strong>the hard way</strong>. </p>
<p>I also realized that <strong>most</strong> of the interviewing <strong>books</strong>, <strong>articles</strong> and <strong>blog posts</strong> are completely and utterly <strong>misdirections</strong>, to say the least. </p>
<p>From <strong>personal experience</strong> I can say that if you waste your time memorizing brain teasers, you <strong>won’t</strong> be able to get a decent <strong>JavaScript Engineering</strong> job in the <strong>Silicon Valley</strong>.</p>
<p>Any book that claims this, says virtually nothing useful about interviews. Moreover it does not reflect the facts. Here’s <strong>one true fact</strong> about interviews:</p>
<blockquote><p>Interviews are <strong>virtual realities</strong> specially designed to <strong>keep you out</strong> of the company. Since it&#8217;s a <strong>virtual</strong> environment, everyone will be <strong>extremely kind</strong> and <strong>understanding</strong> to you, and you will <strong>feel like a “<em>sir</em>”</strong>. </p>
<p>Nonetheless, the default answer in any interview is <strong>“Well&#8230; NO!”</strong><br />
and it’s up to your <strong>“persuasive ability”</strong> to turn that answer to a <strong>“Hell YES!”</strong>.</p></blockquote>
<p>Most of the time you’ll think that you <strong>literally aced</strong> that interview, while the <strong>reality</strong> is that <strong>you totally sucked</strong> at either <strong>what you say</strong>, or <strong>how you say it</strong>, or <strong>your facial expressions</strong>, or your <strong>body language</strong>.</p>
<h2><a href="http://o2js.com/interview-questions/">JavaScript Interview Questions</a></h2>
<p>Having seen all these, I decided to <a href="http://o2js.com/interview-questions/"><strong>write a book that will change the perception of people on JavaScript and Front End Engineering interviews as we know it</strong></a>.</p>
<h2>Your Resumé Stinks</h2>
<p>Every job search begins with a resumé (that&#8217;s also <strong>wrong</strong> by the way; there is something <strong>way more important</strong> than your resumé). And most of the resumés I see around <strong>stink</strong> so much that it&#8217;s a miracle to even receive a call for an interview using them. </p>
<blockquote><p>I&#8217;ll be honest here, my resumé used to <strong>stink</strong> too; and <strong>I learned the hard way</strong> what interviewers are paying attention to in a resumé.</p></blockquote>
<h2>Take the Red Pill</h2>
<p>Due to circumstances out of my control, in the last couple of years I have been to at least <strong>a hundred technical interviews</strong> on <strong>JavaScript Engineering</strong>, <strong>Front-End Development</strong>, and related positions. That&#8217;s why I&#8217;m so confident in telling you that this book will be a <a href="http://o2js.com/interview-questions/">game-changer</a>. Here&#8217;s why:</p>
<blockquote><p>Rather than giving you some HR Manager’s perspective on what interviews <strong>should</strong> look like, I&#8217;m going to hand over you the <strong>red pill</strong> and tell what the <strong>JavaScript Engineering</strong> interviews <strong>really are</strong>, and what you will <strong>need to know</strong> to get the job you want.</p></blockquote>
<p>Which means that this book is for <strong>&#8220;doers&#8221;</strong>; not spectators or readers. This book is for <strong>&#8220;believers&#8221;</strong>, for those who instinctively say <em>“yes that makes sense”</em> and dive in right away. This book is also for <strong>&#8220;skeptics&#8221;</strong>, who may <strong>doubt</strong> the efficacy and value of the material, but are <strong>open-minded</strong> enough to begin and give things an honest chance.</p>
<h2>This Book is a <strong>Game-Changer</strong></h2>
<p>Contrary to most of the programming interview books on the market, this book will teach you <strong>how to think</strong>, instead of forcing you memorize a set of <em>&#8220;how do you balance an unbalanced binary tree?&#8221;</em> kind of questions. Rather, this book will <strong>show</strong> you all the most important features of <strong>JavaScript</strong> and <strong>how they fit together</strong>.</p>
<h3>Being a <strong>Rock Star</strong> is Only a Part of the Equation</h3>
<blockquote><p>It’s part of interviewer’s job to establish a <strong>virtual reality</strong> to make you <strong>feel comfortable</strong>.</p></blockquote>
<p>Assume that you are excellent in what you do (<em>of course you are, by the way</em>), and you are a perfect match for the job. However, for some reason, you totally mess up in the interview. If the interviewer is good at what she&#8217;s doing, she will see the <strong>hidden gem</strong> in you and extend you an offer. But not all interviewers are like that.</p>
<p>The more likely scenario is that the interviewer does nothing but listen to what you tell them and take notes. </p>
<p><strong>Worse</strong>, they don’t even <strong>“get”</strong> what you’re telling them. Rather, they will believe in what they <strong>think</strong> you have told them. So <strong>being technically prepared</strong> is <strong>necessary</strong> and <strong>not sufficient</strong>. Unless you manage to deliver your answer in the expected way, you are <strong>tossed</strong>.</p>
<blockquote><p>I know that it&#8217;s unfair.<br />
And insisting that it&#8217;s unfair will not change the rules of the game <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong>.<br />
Welcome to the adult world of <strong>consequences</strong>.</p></blockquote>
<p>And <strong>even worse</strong>, even you completely mess up in the interview, you won’t understand that you&#8217;ve messed up. The interviewer will kindly thank you for your time and say that <strong>it was a great discussion</strong>.</p>
<blockquote><p>I’ve learned the hard way not to believe the sweet things I’ve been told and fight until the bitter end (<em>i.e. until I get an offer</em>). </p>
<p>If you forget everything you&#8217;ve read so far remember this: </p>
<p>&#8220;Until you&#8217;ve got somethin&#8217;; you&#8217;ve got nothin&#8217;.&#8221;</p></blockquote>
<h3>It’s not the Questions, it’s &#8220;You&#8221; that Matters</h3>
<p>Another mistake people do in studying for interviews is to memorize answers to <a href="http://en.wikipedia.org/wiki/Snowclone">snowcloned</a> interview questions.</p>
<p><strong>Blindly memorizing questions will not take you anywhere</strong>. </p>
<p>What you know is <strong>nothing</strong> when compared to <strong>how you convey</strong> that knowledge to the interviewer. </p>
<p><strong>It&#8217;s not 2005 anymore</strong>, and interviews are <strong>not</strong> about memorizing <strong>brain teasers</strong>, or about studying <strong>CS 101</strong> material. In deed <strong>there&#8217;s no spoon</strong>. That is to say,  what you are being asked is not &#8220;that&#8221; important. </p>
<blockquote><p>Interviews are all about your <strong>persuasive ability</strong>.</p></blockquote>
<p>Don’t get me wrong though. I’m not talking about any of <a href="https://www.google.com.tr/search?q=nlp+in+interviews">those NLP bullshit</a> you’ll see around. </p>
<p>The <strong>persuasive ability</strong> you’ll gain to ace any interview comes out of <strong>brutally hard technical preparation</strong>, and <strong>strategically</strong> sharpening your <strong>knowledge</strong>, <strong>skills</strong>, and <strong>abilities</strong>.</p>
<h2>Memorizing Things Will Work Against You</h2>
<blockquote><p>Interviewers hate developers parroting out some memorized jargon bubble talk. </strong>I know</strong>, because in the recent two years I have grown <strong>close connections</strong> with <strong>recruiters</strong> and <strong>decision-makers</strong>, as a side effect of being into a lot of interviews. And that&#8217;s what they&#8217;ve been telling me all the time. A skilled recruiter will understand that <a href="http://www.psychologytoday.com/blog/your-brain-work/201011/new-study-shows-humans-are-autopilot-nearly-half-the-time">you are on &#8220;auto pilot&#8221;</a> from miles apart.</p></blockquote>
<h2>Are You Ready for Hard Work?</h2>
<p><strong>It’s f*cking hard work</strong>! If it were easy, then everybody would be working in their dream jobs already. I never say it will be easy; and I don&#8217;t say it will be quick, either. Yet, if you&#8217;re <strong>persistent</strong>, <strong>stubborn</strong>, and <strong>ambitious</strong> enough, sooner than later you will reap the benefits of <a href="http://o2js.com/interview-questions">the book</a>.</p>
<blockquote><p>If you want to work in a rock star company, <strong>be a rock star</strong>: Do your homework, don&#8217;t just skim, but <strong>digest</strong> <a href="http://o2js.com/interview-questions/">the book</a>: Browse any links cited; read through any supporting materials given.</p></blockquote>
<p>If you investigate every single one of the tips, tricks and ideas presented in <a href="http://o2js.com/interview-questions/">the book</a>, all the places that you&#8217;d admire to work at will be <strong>racing against each other</strong> to have you.</p>
<h3>Still Looking for a List of Questiong to Memorize?<br />
<strong>Don’t</strong> Buy This Book!</h3>
<blockquote><p><strong><a href="http://o2js.com/interview-questions/">This book</a> is not for the faint-hearted</strong>. It is for those who want to improve themselves by working their asses out.</p></blockquote>
<p>If you merely want stuff to memorize there is a gazillion <a href="https://www.google.com.tr/search?q=technical+interview+question+samples">&#8220;interview question and their answers&#8221;</a> available on the Internet.</p>
<blockquote><p>My humble advice is to approach these techniques you&#8217;ll find over the Internet with a grain of salt. Personal experience has shown me that they are just <strong>misdirections</strong> and <strong>ill advice</strong> given by people living inside their ivory tower.</p></blockquote>
<p>As you’ll see in <a href="http://o2js.com/interview-questions/">the book</a>, it’s <strong>not</strong> the question that’s important, it’s <strong>the road</strong> that leads to it.</p>
<blockquote><p>Rather than focusing the needles on individual pine trees, try to see the forest. Then you&#8217;ll realize the relatively few topic areas that these questions <strong>converge</strong>. That way, you will be able to handle <strong>anything</strong> thrown at you.</p></blockquote>
<p>I want to re-iterate things up front. <a href="http://o2js.com/interview-questions/">The book</a> <strong>demands</strong> hard work. The more you work on yourself, the better your overall understanding would be.</p>
<h2><strong>Bonus</strong>: <a href="http://o2js.com/interview-questions/">This Book</a> Builds a <a href="http://jobs.o2js.com/">Career Network</a> Around it</h2>
<p>If you decide to <a href="http://o2js.com/interview-questions/">pre-order the book</a>, as an <strong>early bird</strong> you will have <strong>exclusive lifetime access</strong> to <a href="http://jobs.o2js.com/">o2.js Career Network</a> (<em>only valid while the book is on pre-order, so you&#8217;d better hurry up <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></em>).</p>
<p>I believe if you&#8217;re interested enough to buy a book to advance your professionalism, then you <strong>deserve</strong> exclusive professional offers too <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<blockquote><p>Have I told you, this would be the best career investment you will make, ever?</p></blockquote>
<h2>Who Else Want to Gimme a Hand?</h2>
<p>I&#8217;ve left everything, and I&#8217;m writing this book in <strong>all my free time</strong>. You&#8217;ll never know how writing a book is such a hard work, until you get into it. I&#8217;m putting an unimaginable time and effort to it; and I assure you it’ll be worth every penny you spend on it: </p>
<blockquote><p>It’ll be both an excellent <strong>technical reference material</strong>, and a great <strong>game changer</strong> in terms of your behavioral interviewing skill set.</p></blockquote>
<p>Each preorder further motivates me to finish the book as soon as possible.</p>
<p>And there are <strong>other ways</strong> you can help me out too:</p>
<ul style="margin-top:-30px;">
<li>You can help me about editing, copywriting, and proof-reading of the book &#8212; I will thank you for your efforts by explicitly mentioning you in the <strong>acknowledgments</strong> section;</li>
<li>You can share <a href="http://o2js.com/interview-questions/">the pre-order link</a> on <strong>Facebook</strong> and <strong>twitter</strong>;</li>
<li>You can <strong>write a blog post</strong>, after having read the book &#8212; I&#8217;ll really appreciate that;</li>
<li>You can send emails to you friends whom you think might benefit from this book.</li>
</ul>
<p>In short, I&#8217;d be grateful if you help me spread the word.</p>
<blockquote><p><strong>Aside:</strong><br />
Spending all my available time on <a href="http://o2js.com/interview-questions/">the book</a> also means that I won&#8217;t be updating this blog for a while. However, the book will come out to be a great reference material, and who knows, the drafts that I don’t put into the book may give birth to further blog posts too.</p></blockquote>
<p>As always, you are more than welcome to share your comments and suggestions.</p>
<p>Now back to writing a <strong>game-changer</strong>, so that you can go ace that interview!<br />
( <strong>34,546 words&#8230;</strong> for the time being, and increasing <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong> ).</p>
<p>Until then, <strong>may the odds be ever in your favor</strong>!</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/09/09/javascript-interview-questions/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>JavaScript Widget Development Best Practices (Part 6: Refactoring the Widget API)</title>
		<link>http://o2js.com/2012/08/03/javascript-widget-refactoring/</link>
		<comments>http://o2js.com/2012/08/03/javascript-widget-refactoring/#comments</comments>
		<pubDate>Fri, 03 Aug 2012 19:44:17 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Widget]]></category>
		<category><![CDATA[4 tiers]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[bpc architecture]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[module pattern]]></category>
		<category><![CDATA[observer]]></category>
		<category><![CDATA[publisher subscriber]]></category>
		<category><![CDATA[pubsub]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[widget]]></category>
		<category><![CDATA[widget development]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2779</guid>
		<description><![CDATA[In the former article of the series We rendered the user interface of our widget inside an anchor element in publisher&#8217;s website; We asynchronously loaded widget styles; We implemented a very naive authentication mechanism. We also defined a job queue _wdq (similar to google analytics&#8217; _gaq) to be able to &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2781" class="wp-caption alignleft" style="width: 250px"><a href="http://o2js.com/wp-content/uploads/2012/08/refactoring.png"><img src="http://o2js.com/wp-content/uploads/2012/08/refactoring.png" alt="refactoring the codebase into logically-related modules" title="refactoring the codebase into logically-related modules" width="240" height="300" class="size-full wp-image-2781" /></a><p class="wp-caption-text">refactoring the codebase into logically-related modules</p></div>
<p>In the <a href="http://o2js.com/2012/07/28/javascript-widgets-user-interface/" title="JavaScript Widget Development Best Practices (Part 5: Getting Your Hands Dirty) ">former article of the series</a> </p>
<ul style="margin-top:-30px">
<li style="margin-bottom:10px">We rendered the user interface of our widget inside an <strong>anchor element</strong> in publisher&#8217;s website;</li>
<li style="margin-bottom:10px">We <strong>asynchronously</strong> loaded widget <strong>styles</strong>;</li>
<li style="margin-bottom:10px">We implemented a very naive <strong>authentication</strong> mechanism.</li>
<li style="margin-bottom:10px">We also defined a job queue <strong>_wdq</strong> (similar to google analytics&#8217; <strong>_gaq</strong>) to be able to push <strong>async commands</strong> to our widget;</li>
<li>And we defined a <strong>_wdAsyncInit</strong> callback (similar to Facebook&#8217;s <strong>fbAsyncInit</strong>) to be able to notify the publisher when our widget is ready and responsive.</li>
</ul>
<div style="clear:both"></div>
<blockquote><p>In the following articles, we will improve these mechanisms.<br />
However, in this tutorial our subject matter is a little different:</p>
<p>This tutorial is <strong>not</strong> directly related to <strong>JavaScript</strong> widget development specifics;<br />
and it&#8217;s more about <strong>code reorganization</strong>.</p></blockquote>
<h2>Logically Splitting Widget API File</h2>
<p>If you remember <a href="http://o2js.com/2012/07/28/javascript-widgets-user-interface/" title="Getting our Hands Dirty">from the former article</a> we used to have a single <strong>monolithic</strong> api file (<strong>api.v.0.1.js</strong>) to manage the entire widget <strong>initialization flow</strong>, <strong>event registration</strong>, and other <strong>API behavior</strong>. In a real production application, it&#8217;s highly possible that our api code will grow over a few hunderds of thousand lines of code. We will have hard time improving, developing and debugging our codebase.</p>
<blockquote><p>My experience shows that chaos is the inevitable fate of any software project that lives for several years, and gets developed by different teams of developers along the way. Although we cannot avoid it, at least we can minimize the consequences of it, by organizing chaos in an orderly manner as much as we can.</p></blockquote>
<h2><a href="http://o2js.com/2012/03/13/the-bpc-architecture-client-side/" title="Refactoring">Refactoring</a> to the Rescue</h2>
<p>One way to manage our codebase, is to keep our files in logically-coherent modules; and to segregate those modules further into <strong>tiers</strong> (<em>we&#8217;ll come to that later</em>).</p>
<p>By splitting our code into logically-coherent modules;</p>
<ul style="margin-top:-30px">
<li>We will have <strong>less merge conflicts</strong> when working with teams,</li>
<li>And it will be <strong>easier</strong> to find the exact point of failure, when a functionality breaks.</li>
</ul>
<blockquote><p>A <strong>clever refactoring</strong> is not a waste of time. Per contra, it will gain you a lot of time, and help you easily find and fix bugs in the long run.</p></blockquote>
<p>We&#8217;ve seen <a href="http://o2js.com/2012/03/13/the-bpc-architecture-client-side/" title="BPC Architecture (client side)">a refactoring case study in the BPC architecture article</a>. </p>
<p>In this tutorial we will follow a similar approach for <strong>layering</strong> our widget codebase.</p>
<h2><a href="http://o2js.com/2012/03/13/the-bpc-architecture-client-side/" title="BPC Architecture (Client Side)">BPC Architecture</a> in Review</h2>
<p>Here&#8217;s an overview of the <strong>BPC architecture</strong> for a recap:</p>
<div id="attachment_2796" class="wp-caption alignleft" style="width: 526px"><a href="http://o2js.com/wp-content/uploads/2012/08/widger-tiers.png"><img src="http://o2js.com/wp-content/uploads/2012/08/widger-tiers.png" alt="Four Tiers of Separation" title="Four Tiers of Separation" width="516" height="206" class="size-full wp-image-2796" /></a><p class="wp-caption-text">Four Tiers of Separation</p></div>
<div style="clear:both"></div>
<p>In the figure above, the dashed arrows stand for <strong>DOM Event callbacks</strong>, and <strong>asynchronous server-side callbacks</strong> (AJAX/JSONP etc). </p>
<p>The moral of the story is: </p>
<ul style="margin-top:-30px">
<li>All callbacks go to the <strong>delegation tier</strong>.</li>
<li><strong>Delegation tier</strong> <strong>cannot</strong> call the <strong>communication tier</strong> or the <strong>presentation tier</strong> directly, it should call the <strong>behavior tier</strong> first.</li>
<li><strong>Presentation tier</strong> is the &#8220;<strong>sink</strong>&#8220;, it cannot call anyone else.</li>
<li>The only <strong>exception</strong> is the <strong>persistence tier</strong>: everyone can read from it, but only the <strong>behavior tier</strong> can write to it.</li>
</ul>
<p>Similar to the model above, in this article we will organize our codebase into well-defined <strong>behavior</strong>, <strong>communication</strong>, <strong>delegation</strong>, and <strong>persistence</strong> tiers; where each tier will contain one or more modules.</p>
<h2>Improve <a href="http://o2js.com/2012/03/13/the-bpc-architecture-client-side/" title="the BPC Architecture (client side)">BPC Architecture</a> Further</h2>
<p>And to improve the structure further, we will <strong>decouple</strong> our modules as much as we can: </p>
<blockquote><p>Instead of having modules call public methods of one another, we will be <strong>raising custom events</strong>, for <strong>inter-module communication</strong>.</p>
<p>This idiom is widely known as <a href="http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern" title="publish-subscribe pattern">the Publish-Subscribe Pattern</a>.</p></blockquote>
<p>Using the <strong>pubsub</strong> pattern, we will <strong>decouple</strong> our modules further: </p>
<blockquote><p>Any given module will not have direct knowledge of any other module talking to it. </p></blockquote>
<p>This <strong>loose coupling</strong>;</p>
<ul style="margin-top:-30px">
<li>Will give us the <strong>flexibility</strong> to easily move code pieces around;</li>
<li>And, since the modules only know about themselves and no one else, it will be easier to <strong>unit test</strong> those modules individually in their <strong>sandbox</strong>.</li>
</ul>
<h2>Application Directory Structure</h2>
<p>Enough introductory talk; now let&#8217;s see how we apply all this theory to our <strong>widget API</strong>.</p>
<p>To begin with, here&#8217;s the directory struture of our application:</p>
<div id="attachment_2802" class="wp-caption alignleft" style="width: 258px"><a href="http://o2js.com/wp-content/uploads/2012/08/widget-bpc-folder-tree.png"><img src="http://o2js.com/wp-content/uploads/2012/08/widget-bpc-folder-tree.png" alt="Widget API Directory Tree" title="Widget API Directory Tree" width="248" height="421" class="size-full wp-image-2802" /></a><p class="wp-caption-text">Widget API Directory Tree</p></div>
<div style="clear:both"></div>
<p>In the <strong>lib</strong> folder we have helper libraries (such as <strong><a href="https://github.com/v0lkan/o2.js" title="o2.js - A Coherent Solution to Your JavaScript Dilemma">o2.js</a></strong>) and <strong>widget modules</strong> (i.e. the <strong>/lib/wd/</strong> folder). </p>
<blockquote><p>The widget modules <strong>raise events</strong> for <strong>inter-module communication</strong>. The modules also directly use helper libraries for utility functions (such as <strong>JSONP</strong> calls, and <strong>DOM</strong> event delegation). </p></blockquote>
<p>We will come to the implementation of these very soon.</p>
<p>As seen in the image above we have <strong>5 tiers</strong> (represented by folders): <strong>behavior</strong>, <strong>comunication</strong>, <strong>communication</strong>, <strong>delegation</strong>, <strong>persistence</strong> and <strong>presentation</strong>. </p>
<p>Each tier, further down, contains <strong>modules</strong>.</p>
<p>And each <strong>module</strong> is nothing but a static <strong>object</strong> under <strong>window._wd.protecteds</strong> namespace.</p>
<p>For example the <strong>Init</strong> module under the <strong>behavior</strong> tier, resolves to <strong>window._wd.protecteds.Init</strong></p>
<blockquote><p>The &#8220;<strong><em>protecteds</em></strong>&#8221; namespace is an informal indicator that these modules are meant to be used by the internal functionality of our widget. </p>
<p><strong>Protected modules</strong> are <strong>not</strong> meant to be accessed publicly by the publisher. </p></blockquote>
<h2>Establishing Inter Module Communication</h2>
<p>In order to send messages to other modules, each module either publishes events:</p>
<pre class="brush: javascript">
    // protecteds/behavior/init.js

    /*
     * Load initial widget state data from the server.
     */
    function loadState(config) {
        log(&#039;Init.loadState(&#039;);
        log(config);
        log(&#039;)&#039;);

        // Behavior -&gt; Communication
        p.pub(&#039;SEND_GET_PARAMS&#039;, [config]);
    }
</pre>
<p>&#8230;or subscribes to events:</p>
<pre class="brush: javascript">
    // protecteds/communication/proxy.js

    /**
     * @function {static} Proxy.subscribe
     *
     * Subscribes to relevant events.
     */
    me.subscribe = function() {
        log(&#039;Proxy.subscribe()&#039;);

        ...

        // Get widget parameters from the server.
        sub(&#039;SEND_GET_PARAMS&#039;, function(params) {
            log(&#039;event&lt;SEND_GET_PARAMS&#039;);
            log(params);
            log(&#039;&gt;&#039;);

            get(
                concat(url.API_ROOT, path.PARAMS),
                params,
                callback.sendGetParams_complete
            );
        });

        ...
    };
</pre>
<p>One caveat though:</p>
<blockquote><p>Implementing a <strong>pubsub pattern</strong> is a bit like <strong>using a hand grenade</strong>. </p>
<p>In the hands of thoughtful experts, you can expect to have a sky scraper demolished safely and in a reasonable time frame. </p>
<p>However letting amateurs mess with the <strong>pubsub pattern</strong> is akin to <strong>giving a box of hand grenades to a gang of monkeys</strong>:</p>
<p>You&#8217;ll end up with a very noisy and messy scene <strong>when you least expect it</strong>. </p>
<p>And every once in a while, <strong>even experts act like monkeys</strong> <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong>.</p></blockquote>
<h2>Split Main API file into <strong>#region</strong>s</h2>
<p>This is a habit I grew back in my <strong>.net/C#</strong> development years.</p>
<blockquote><p>In <strong>Visual Studio</strong>, you can separate logically distinct parts of the code with <a href="http://msdn.microsoft.com/en-us/library/9a1ybwek(v=vs.71).aspx" title="#region (definition) from MSDN">#region pragmas</a>. Those <strong>#region</strong>s will be rendered distinctly to indicate that they are <strong>logicially-related</strong> groups of code.</p></blockquote>
<p>Here&#8217;s the new <strong>api.v.0.1.js</strong> split into regions<br />
(I&#8217;m replacing parts of the code with <strong>&#8230;</strong> to save some screen real estate):</p>
<pre class="brush: javascript">
...
(function(window, document, isDebugMode) {
    &#039;use strict&#039;;

    /* #region version */

        /*
         * Should match beacon version timestamp.
         */
        var versionTimestamp = &#039;20120720135547909116&#039;;

    /* #endregion */

    /* #region widget state */

        /*
         * Resources to be loaded asynchronously.
         */
        var scriptQueue = [];

        /*
         * This will be set after resource initialization.
         */
        var o2 = null;

    /* #endregion */

    /* #region module common constants */

        /*
         * Query Formation
         */
        var kAnd    = &#039;&amp;&#039;;
        var kEmpty  = &#039;&#039;;
        var kEquals = &#039;=&#039;;
        var kQuery  = &#039;?&#039;;

        /*
         * Regular Expression
         */
        var kCompleteRegExp = /loaded|complete/;

        /*
         * Tags
         */
        var kHead   = &#039;head&#039;;
        var kScript = &#039;script&#039;;

        /*
         * Mime Types
         */
        var kScriptType = &#039;text/javascript&#039;;

        /*
         * Globals
         */
        var kO2Alias     = &#039;_wd_o2&#039;;
        var kWidgetAlias = &#039;_wd&#039;;

        /*
         * Common Widget Keys
         */
        var kReadyState = &#039;readyState&#039;;

    /* #endregion */

    /* #region exported configuration */

        /*
         * Parameter Names
         */
        var param = {
            GUID     : &#039;guid&#039;,
            RANDOM   : &#039;r&#039;,
            VERSION  : &#039;v&#039;,
            USERNAME : &#039;u&#039;,
            PASSWORD : &#039;p&#039;,
            ACTION   : &#039;action&#039;,
            PAYLOAD  : &#039;payload&#039;
        };

        /*
         * Element IDs
         */
        var elm = {
            LOGIN_BUTTON : &#039;wd_btnLogin&#039;
        };

        /*
         * Widget Ready States
         */
        var readyState = {
            LOADED               : 1,
            LOADING_DEPENDENCIES : 2,
            LOADED_DEPENDENCIES  : 3,
            BEGIN_PROCESS_QUEUE  : 4,
            BEGIN_RENDER         : 5,
            COMPLETE             : 6
        };

        /*
         * URL
         */
        var url = {
            API_ROOT        : &#039;http://api.widget.www/&#039;,
            O2_ROOT         : &#039;http://api.widget.www/lib/o2.js/&#039;,
            WIDGET_LIB_ROOT : &#039;http://api.widget.www/lib/wd/v.0.1/&#039;,
            LIB_ROOT        : &#039;http://api.widget.www/lib/&#039;
        };

        /*
         * Path
         */
        var path = {
            BEACON : &#039;api/v.0.1/beacon&#039;,
            CSS    : &#039;css/v.0.1/widget.css&#039;,
            LOGIN  : &#039;api/v.0.1/login&#039;,
            PARAMS : &#039;api/v.0.1/params&#039;
        };

        /*
         * Custom Events (used for inter-module messaging)
         */
        var event = {
            BEGIN_RENDER     : &#039;wd-begin-render&#039;,
            CSS_LOADED       : &#039;wd-css-loaded&#039;,
            DELEGATE_EVENTS  : &#039;wd-delegate-events&#039;,
            FIRE_ASYNC_INIT  : &#039;wd-fire-async-init&#039;,
            INSERT_BEACON    : &#039;wd-insert-beacon&#039;,
            LOAD_STATE       : &#039;wd-load-state&#039;,
            OVERRIDE_QUEUE   : &#039;wd-override-queue&#039;,
            PROCESS_QUEUE    : &#039;wd-process-queue&#039;,
            RENDER_DOM       : &#039;wd-render-dom&#039;,
            RENDER_LOGGED_IN : &#039;wd-render-logged-in&#039;,
            RENDER_WIDGET    : &#039;wd-render-widget&#039;,
            SEND_GET_PARAMS  : &#039;wd-send-get-params&#039;,
            SEND_LOAD_CSS    : &#039;wd-send-load-css&#039;,
            SEND_USER_LOGIN  : &#039;wd-send-user-login&#039;,
            USER_LOGGED_IN   : &#039;wd-user-logged-in&#039;,
            USER_LOGIN       : &#039;wd-user-login&#039;
        };

    /* #endregion */

    /* #region helper methods (exported) */

        /*
         * Does nothing, and that&#039;s the point.
         */
        function noop() {}

        /*
         * Logs to console for debug mode.
         * Does nothing in release mode.
         */
        var log = function(stuff) {
            ...
        };

        /*
         * Sets the internal ready state.
         */
        function setReadyState(state) {
            window[kWidgetAlias][kReadyState] = readyState[state];
        }

    /* #endregion */

    /* #region sanitization */

        // Publisher has forgotten to provide initialization data.
        if (!window[kWidgetAlias]) {
            log(&#039;Widget namespace cannot be found; exiting.&#039;);

            return;
        }

        // To avoid re-defining everything if the bootloader is included in
        // more than one place in the publisher&#039;s website.
        if (window[kWidgetAlias][kReadyState]) {
            log(&#039;Widget has already been loaded; exiting.&#039;);

            return;
        }

    /* #endregion */

    /* #region protecteds namespace (export root) */

        /*
         * The &quot;protected&quot; methods are shared across modules, but they
         * are not intended for public use.
         */
        window[kWidgetAlias].protecteds = {};

    /* #endregion */

    /* #region widget initialization */

        /*
         * Asynchronously inserts a script element to the head
         * of the document.
         */
        function insertScript(root, src) {
            ...
        }

        /*
         * Revalidates cache for this bootloader script, if there&#039;s a newer
         * version available. The changes will take effect only AFTER the user
         * refreshes the page.
         */
        function checkForUpdates() {
            ...
        }

        /*
         * Exports protected methods for intra-module use.
         */
        function exportProtecteds() {
            ...
        }

        /*
         * Loads the next resource after the former one
         * has loaded successfully.
         */
        function loadNext(root, loader, callback) {
            ...
        }

        /*
         * Loads the given script.
         * &lt;strong&gt;callback&lt;/strong&gt; is the function to be executed after
         * there&#039;s no resource left to be loeded next.
         */
        var loadScript = function(root, src, callback) {
             ...
        };

        /*
         * Loads an array of scripts one after another.
         */
        function loadScripts(root, ar, callback) {
            ...
        }

        /*
         * First loads necessary o2.js components in noConflict mode.
         * Then loads protected modules.
         */
        function loadDependencies(callback) {
            log(&#039;o-&gt;loadDependencies(&#039;);
            log(callback);
            log(&#039;)&#039;);

            setReadyState(&#039;LOADING_DEPENDENCIES&#039;);

            loadScripts(url.LIB_ROOT, [
                &#039;o2.js/o2.meta.js&#039;,
                &#039;o2.js/o2.core.js&#039;,
                &#039;o2.js/o2.string.core.js&#039;,
                &#039;o2.js/o2.jsonp.core.js&#039;,
                &#039;o2.js/o2.dom.constants.js&#039;,
                &#039;o2.js/o2.dom.core.js&#039;,
                &#039;o2.js/o2.dom.load.js&#039;,
                &#039;o2.js/o2.event.constants.js&#039;,
                &#039;o2.js/o2.validation.core.js&#039;,
                &#039;o2.js/o2.event.core.js&#039;,
                &#039;o2.js/o2.event.custom.js&#039;,
                &#039;o2.js/o2.method.core.js&#039;,
                &#039;o2.js/o2.collection.core.js&#039;,

                &#039;wd/v.0.1/protecteds/behavior/init.js&#039;,
                &#039;wd/v.0.1/protecteds/behavior/queue.js&#039;,
                &#039;wd/v.0.1/protecteds/behavior/widget.js&#039;,

                &#039;wd/v.0.1/protecteds/communication/proxy.js&#039;,

                &#039;wd/v.0.1/protecteds/delegation/callback.js&#039;,
                &#039;wd/v.0.1/protecteds/delegation/event.js&#039;,

                &#039;wd/v.0.1/protecteds/persistence/config.js&#039;,

                &#039;wd/v.0.1/protecteds/presentation/dom.js&#039;,
                &#039;wd/v.0.1/protecteds/presentation/rendering.js&#039;
            ], callback);
        }

    /* #endregion */

    /* #region widget initialization flow */

        // At the end of the initialization flow, readyState will be finally
        // set to COMPLETE. When the readyState is COMPLETE, it means that
        // the widget UI has been rendered, the events have been bound,
        // widget job queue has been processed, and the widget is completely
        // ready and responsive.
        setReadyState(&#039;LOADED&#039;);

        checkForUpdates(versionTimestamp);
        loadDependencies(initialize);

    /* #endregion */
}(this, this.document, true));
</pre>
<h2>Adding Modules as Dependencies</h2>
<p>One thing we add to our widget&#8217;s initialization flow is the <strong>URL</strong>&#8216;s of our <strong>protected modules</strong>.</p>
<p>We first load them as dependencies, and let each module <strong>subscribe</strong> to custom API events once they are loaded.</p>
<p>We&#8217;ll come to the module <strong>subcription</strong> soon. </p>
<p>Here&#8217;s the set of files we load as dependencies:</p>
<pre class="brush: javascript">
        /*
         * First loads necessary o2.js components in noConflict mode.
         * Then loads protected modules.
         */
        function loadDependencies(callback) {
            log(&#039;o-&gt;loadDependencies(&#039;);
            log(callback);
            log(&#039;)&#039;);

            setReadyState(&#039;LOADING_DEPENDENCIES&#039;);

            loadScripts(url.LIB_ROOT, [
                &#039;o2.js/o2.meta.js&#039;,
                &#039;o2.js/o2.core.js&#039;,
                &#039;o2.js/o2.string.core.js&#039;,
                &#039;o2.js/o2.jsonp.core.js&#039;,
                &#039;o2.js/o2.dom.constants.js&#039;,
                &#039;o2.js/o2.dom.core.js&#039;,
                &#039;o2.js/o2.dom.load.js&#039;,
                &#039;o2.js/o2.event.constants.js&#039;,
                &#039;o2.js/o2.validation.core.js&#039;,
                &#039;o2.js/o2.event.core.js&#039;,
                &#039;o2.js/o2.event.custom.js&#039;,
                &#039;o2.js/o2.method.core.js&#039;,
                &#039;o2.js/o2.collection.core.js&#039;,

                &#039;wd/v.0.1/protecteds/behavior/init.js&#039;,
                &#039;wd/v.0.1/protecteds/behavior/queue.js&#039;,
                &#039;wd/v.0.1/protecteds/behavior/widget.js&#039;,

                &#039;wd/v.0.1/protecteds/communication/proxy.js&#039;,

                &#039;wd/v.0.1/protecteds/delegation/callback.js&#039;,
                &#039;wd/v.0.1/protecteds/delegation/event.js&#039;,

                &#039;wd/v.0.1/protecteds/persistence/config.js&#039;,

                &#039;wd/v.0.1/protecteds/presentation/dom.js&#039;,
                &#039;wd/v.0.1/protecteds/presentation/rendering.js&#039;
            ], callback);
        }
</pre>
<h2>Widget Initialization</h2>
<p>We also added a couple of extra lines to the widget initialization code:</p>
<pre class="brush: javascript">
        /*
         * Initialize after loading prerequisites.
         */
        function initialize() {
            ...

            exportProtecteds();

            var config = wp.Config.get();

            config[param.GUID] = o2.String.generateGuid();

            subscribe();

            wp.pub(&#039;LOAD_STATE&#039;, [config]);
        }
</pre>
<p>Let&#8217;s expand the above code, line by line.</p>
<p>We first export a set of methods that will be commonly used in all modules:</p>
<pre class="brush: javascript">
        /*
         * Exports protected methods for intra-module use.
         */
        function exportProtecteds() {
            log(&#039;o-&gt;exportProtecteds()&#039;);

            var wp = window[kWidgetAlias].protecteds;

            wp.sub = function(name, callback) {
                var nom = wp.event[name];

                if (!nom) {
                    log([&#039;wp.sub: No such event for &quot;&#039;, name, &#039;&quot;&#039;].join(kEmpty));

                    return;
                }

                o2.Event.subscribe(nom, callback);
            };

            wp.pub = function(name, payload) {
                var nom = wp.event[name];

                if (!nom) {
                    log([&#039;wp.pub: No such event for &quot;&#039;, name, &#039;&quot;&#039;].join(kEmpty));

                    return;
                }

                o2.Event.publish(nom, payload);
            };

            wp.event         = event;
            wp.log           = log;
            wp.noop          = noop;
            wp.o2            = o2;
            wp.path          = path;
            wp.setReadyState = setReadyState;
            wp.url           = url;
            wp.param         = param;
            wp.elm           = elm;
        }
</pre>
<p><strong>wp</strong> is an alias for <strong>window._wd.protecteds</strong> namespace. We bind a bunch of <strong>helper functions</strong> and <strong>configuration objects</strong> to that namespace to access them from other modules.</p>
<p>Then we call <strong>subscribe</strong> methods of related modules (which makes the modules <strong>subscribe</strong> to related event, as the name implies):</p>
<pre class="brush: javascript">
    /*
     * Trigger modules to subscribe to events.
     */
    function subscribe() {
        var wp = window[kWidgetAlias].protecteds;

        wp.Init.subscribe();
        wp.Queue.subscribe();
        wp.Event.subscribe();
        wp.Widget.subscribe();
        wp.Proxy.subscribe();
        wp.Rendering.subscribe();
    }
</pre>
<h2>o2.js <strong>PubSub</strong> Internals</h2>
<p>The internals of the <strong>pubsub</strong> mechanism is managed by <strong>o2.event.custom.js</strong> module, which is an extension to the <strong>o2.Event</strong> class.</p>
<p>The <strong>o2.event.custom</strong> module exports three methods: <strong>o2.Event.publish</strong>, <strong>o2.Event.subscribe</strong>, and <strong>o2.Event.unsubscribe</strong> as follows:</p>
<pre class="brush: javascript">
(function(framework) {
    &#039;use strict&#039;;

    var _         = framework.protecteds;
    var attr      = _.getAttr;
    var create    = attr(_, &#039;create&#039;);
    var def       = attr(_, &#039;define&#039;);
    var require   = attr(_, &#039;require&#039;);

    var exports = {};

    var kModuleName = &#039;Event&#039;;

    var me = create(kModuleName);

    /*
     * Aliases
     */

    var isArray = require(&#039;Validation&#039;, &#039;isArray&#039;);

    var cache = {};

    exports.publish = def(me, &#039;publish&#039;, function(name, argv) {
        if (!name) {
            return;
        }

        var delegates = cache[name];

        var args = argv || [];

        if (!isArray(args)) {
            args = [args];
        }

        var i         = 0;
        var len       = 0;

        if (!delegates) {
            return;
        }

        for (i = 0, len = delegates.length; i &lt; len; i++) {
            try {
                delegates[i].apply(null, args);
            } catch (ignore) {}
        }
    });

    exports.subscribe = def(me, &#039;subscribe&#039;, function(name, callback) {
        if (!name) {
            return;
        }

        if (!cache[name]) {
            cache[name] = [];
        }

        cache[name].push(callback);

        var handle = {
            name     : name,
            callback : callback
        };

        return handle;
    });

    exports.unsubscribe = def(me, &#039;unsubscribe&#039;, function(handle) {
        var name = handle.name;
        var callback = handle.callback;

        var delegates = cache[name];
        var i         = 0;
        var len       = 0;
        var delegate  = null;

        if (!delegates) {
            return;
        }

        for (i = 0, len = delegates.length; i &lt; len; i++) {
            delegate = delegates[i];

            if (delegate === callback) {
                delegates.splice(i, 1);
                len = delegates.length;
                i--;
            }
        }
    });
}(this.o2));
</pre>
<p>Where <strong>window._wd.pub</strong> and <strong>window._wd.sub</strong> methods wrap around <strong>o2.Event.publish</strong>, and <strong>o2.Event.subscribe</strong> methods respectively.</p>
<h2>Read the Source Luke</h2>
<p>You can view the <a href="https://github.com/v0lkan/o2.js/tree/3dce60af8d1cdbe8e95de4234bef974df3f2fc99/examples/widget-demo" title="what we've done so far">source code from this github history snapshot</a>.</p>
<h2>Conclusion</h2>
<p>That concludes our quick tour on <strong>widget refactoring</strong> <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong>.</p>
<p>In this article;</p>
<ul style="margin-top:-30px">
<li>We divided our widget into logical <strong>modules</strong>, and grouped those modules into different <strong>tiers</strong>;</li>
<li>We also implemented a custom <strong>publisher subscriber messaging system</strong> for <strong>inter-module communication</strong>;</li>
<li>As a corollary to the above; almost all of the modules <strong>never exposed</strong> public methods, and instead modules sent and received messages using the <strong>pubsub</strong> mechanism above, rather than calling methods on each other.</li>
<li>This <strong>pubsub</strong> mechanism allowed &#8220;<strong>loose coupling</strong>&#8221; between modules; which, in turn, will make it possible to <strong>unit test</strong> each module independently.</li>
</ul>
<h2>Next Up?</h2>
<blockquote><p>In the following article, we will convert our application with something more <strong>meaningful</strong>, use <strong>CORS</strong> for cross domain POST requests, detect if CORS is supported, and discuss <strong>alternatives</strong> if it&#8217;s not. We will also discuss <strong>minification</strong>, <strong>compression</strong> and <strong>deployment</strong> strategies; and ways to secure our widget and prevent it from certain XSS and CSRF attacks.</p></blockquote>
<p>In short we will try wrap things up in the next article <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong>.</p>
<p>Until then, feel free to share your comments and suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/08/03/javascript-widget-refactoring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Widget Development Best Practices (Presentation)</title>
		<link>http://o2js.com/2012/07/30/javascript-widget-presentation/</link>
		<comments>http://o2js.com/2012/07/30/javascript-widget-presentation/#comments</comments>
		<pubDate>Mon, 30 Jul 2012 06:34:48 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[jstanbul]]></category>
		<category><![CDATA[jstanbul 2012]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[slideshow]]></category>
		<category><![CDATA[widget]]></category>
		<category><![CDATA[widget development]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2747</guid>
		<description><![CDATA[After my conference on jstanbul 2012, I updated the presentation adding some bullet points for the questions and feedback from the community. &#160; &#160; You can view and download the presentation from SlideShare. And I&#8217;ll continue this blog&#8217;s series on JavaScript Widget Development Best Practices from where I left. Until &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2751" class="wp-caption alignleft" style="width: 310px"><a href="http://o2js.com/wp-content/uploads/2012/07/jstanbul1.png"><img src="http://o2js.com/wp-content/uploads/2012/07/jstanbul1.png" alt="jstanbul was a great JavaScript conference; and it was great to be a contributor!" title="jstanbul was a great JavaScript conference; and it was great to be a contributor!" width="300" height="106" class="size-full wp-image-2751" /></a><p class="wp-caption-text">jstanbul was a great JavaScript conference; and it was great to be a contributor!</p></div>
<p>After my conference on <a href="http://jstanbul.org/2012/" title="jstanbul 20212 - Istanbul JavaScript Conference">jstanbul 2012</a>, </p>
<p>I updated the presentation adding some bullet points for the questions and feedback from the community.</p>
<div class="clear:both"></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>You can <a href="http://www.slideshare.net/linkibol/external-javascript-widget-development-best-practices-updated-v11" title="External JavaScript Widget Development Best Practices (updated) (v.1.1) ">view and download the presentation from SlideShare</a>.</p>
<p>And I&#8217;ll continue this blog&#8217;s series on <strong>JavaScript Widget Development Best Practices</strong><br />
<a href="http://o2js.com/2012/07/28/javascript-widgets-user-interface/" title="Getting Your Hands Dirty">from where I left</a>.</p>
<p>Until then, feel free to add your comments <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/07/30/javascript-widget-presentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Widget Development Best Practices (Part 5: Getting Your Hands Dirty)</title>
		<link>http://o2js.com/2012/07/28/javascript-widgets-user-interface/</link>
		<comments>http://o2js.com/2012/07/28/javascript-widgets-user-interface/#comments</comments>
		<pubDate>Sat, 28 Jul 2012 19:17:58 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Widget]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[lazy loading]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[session state]]></category>
		<category><![CDATA[styling]]></category>
		<category><![CDATA[upcoming]]></category>
		<category><![CDATA[user interface]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2729</guid>
		<description><![CDATA[I&#8217;m giving a talk on JavaScript Widget development best practices tomorrow at jstanbul 2012. At the conference, I will have a 30-minute timeframe to express as much as I can with respect to external JavaScript widget development best practices. Since 30 minutes is not enough for this, my aim is &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2730" class="wp-caption alignleft" style="width: 360px"><a href="http://o2js.com/wp-content/uploads/2012/07/widget-ui.png"><img src="http://o2js.com/wp-content/uploads/2012/07/widget-ui.png" alt="getting our hands dirty" title="getting our hands dirty" width="350" height="239" class="size-full wp-image-2730" /></a><p class="wp-caption-text">getting our hands dirty</p></div>
<blockquote><p>I&#8217;m giving <a href="http://jstanbul.org/2012/" title="See you in jstanbul 2012!">a talk on JavaScript Widget development best practices tomorrow</a> at <strong>jstanbul 2012</strong>. </p>
<p>At the conference, I will have <strong>a 30-minute timeframe</strong> to express as much as I can with respect to external <strong>JavaScript</strong> widget development best practices. </p>
<div style="clear:both"></div>
<p>Since 30 minutes is not enough for this, my aim is to give a quickly overview, and send the audience to this blog for further investigation.</p></blockquote>
<p>This means that this blog article (<em>that I&#8217;m currently writing</em>) must be <strong>as complete and as coherent as possible</strong>, before  my talk tomorrow.</p>
<blockquote><p>So I&#8217;m going to cram as much things into here as possible. I will intentionally leave certain parts incomplete, and I will definitely leave (some obvious, some not so obvious) security loopholes. I will cover them in the following articles of the series.</p></blockquote>
<h2>The Result</h2>
<p>At the end of this tutorial we will be creating something similar to this:</p>
<div id="attachment_2768" class="wp-caption alignleft" style="width: 410px"><a href="http://o2js.com/wp-content/uploads/2012/07/widget_ui.png"><img src="http://o2js.com/wp-content/uploads/2012/07/widget_ui.png" alt="widget login user interface" title="widget login user interface" width="400" height="252" class="size-full wp-image-2768" /></a><p class="wp-caption-text">widget login user interface</p></div>
<div id="attachment_2769" class="wp-caption alignleft" style="width: 405px"><a href="http://o2js.com/wp-content/uploads/2012/07/widget-login.png"><img src="http://o2js.com/wp-content/uploads/2012/07/widget-login.png" alt="widget login form" title="widget login form" width="395" height="335" class="size-full wp-image-2769" /></a><p class="wp-caption-text">widget login form</p></div>
<div id="attachment_2770" class="wp-caption alignleft" style="width: 360px"><a href="http://o2js.com/wp-content/uploads/2012/07/widget_logged_in.png"><img src="http://o2js.com/wp-content/uploads/2012/07/widget_logged_in.png" alt="widget (logged in)" title="widget (logged in)" width="350" height="222" class="size-full wp-image-2770" /></a><p class="wp-caption-text">widget (logged in)</p></div>
<div id="attachment_2771" class="wp-caption alignleft" style="width: 393px"><a href="http://o2js.com/wp-content/uploads/2012/07/widget_console.png"><img src="http://o2js.com/wp-content/uploads/2012/07/widget_console.png" alt="widget console" title="widget console" width="383" height="462" class="size-full wp-image-2771" /></a><p class="wp-caption-text">widget console</p></div>
<div style="clear:both"></div>
<blockquote><p>Note that the login form above is <strong>dynamically injected</strong> from the widget provider&#8217;s domain (http://api.widget.www). And the widget lives in a totally different publisher domain (http://publisher.www). </p>
<p>That&#8217;s one of the many things that makes external <strong>JavaScript</strong> widget development complicated.</p>
<p>For a broad overview of other <strong>challenges</strong> involved in <strong>External JavaScript Widget Development</strong>, you can view <a href="http://o2js.com/2012/07/30/javascript-widget-presentation/" title="jstanbul 2012 - JavaScript Widget Development Best Practices Presentation">my <strong>#jstanbul 2012</strong> slides</a> on the topic</p></blockquote>
<p>So let&#8217;s start and get our hands dirty; shall we?</p>
<h2>Last Part in Review</h2>
<p>Here&#8217;s a recap of what we&#8217;ve done so far: <a href="http://o2js.com/2012/07/27/javascript-widgets-cross-frame/" title="JavaScript Widget Development - Cross-frame Communication">In the former article</a>, we have seen different ways to send <strong>initialization parameters</strong> to our widget, and we have also listed several techniques on how to establish <strong>cross-domain communication</strong> between the publisher&#8217;s site and the widget API server. We choosed <strong>JSONP</strong> as a <strong>cross-browser proxy</strong>, while mentioning the possible <strong>drawbacks</strong> of our choice.</p>
<h2>Let&#8217;s Render a User Interface</h2>
<p>When it comes to external <strong>JavaScript</strong> widgets, there are various ways to render. The most common two are:</p>
<ul style="margin-top:-30px">
<li>Rendering the widget&#8217;s UI by appending <strong>HTML</strong> before the widget&#8217;s <strong>script</strong> tag.</li>
<li>And rendering the widget&#8217;s UI by <strong>explicitly specifying a target location</strong> (<em>i.e. a DOM element with a specific attribute</em>) on the publisher&#8217;s website.</li>
</ul>
<p>The former technique involves traversing the publisher&#8217;s <strong>DOM</strong>, locating the instance or instances of widget bootloader scripts, and injecting <strong>HTML</strong> before each script.</p>
<p>While in the latter, we explicity specify placeholder <strong>HTML</strong> tags as an anchor positions to render the widget. We&#8217;ll see an example of this technique down below.</p>
<p>We&#8217;ll continue our tutorial with the second implementation, since&#8230; </p>
<ul style="margin-top:-30px">
<li>It gives more <strong>flexibility</strong>;</li>
<li>It is <strong>less prone to errors</strong>;</li>
<li>It does not create <strong>race conditions</strong> (<em>when we have more than one scripts on the page</em>);</li>
<li>Requires <strong>less lines of code</strong>;</li>
<li>And is a better demonstration of <strong>separation of concerns</strong>.</li>
</ul>
<h2>Create an Anchor on the Publisher&#8217;s Website</h2>
<p>Let&#8217;s start by adding a <strong>div</strong> with a special <strong>data-wd-anchor</strong> attribute.</p>
<p>Our bootloader script will detect this attribute and render our widget&#8217;s user interface inside that <strong>div</strong>.</p>
<pre class="brush: text">
-//publisher.www/index.jade
    ...
    body(lang=&#039;en&#039;)
        section#Main
            h2 Welcome to Publisher Website

            p(style=&#039;float:right;width:300px&#039;) Lorem ipsum dolor sit amet.

            p(style=&#039;float:left;width:300px&#039;) Vestibulum dui erat.

            div(data-wd-anchor, style=&#039;float:left;width:300px;margin-top:20px;margin-left:10px;&#039;)

            p(style=&#039;float:right;width:300px&#039;) Mauris ac dolor ante.
</pre>
<p>And here is the piece of code on the <strong>widget API script</strong> that does the rendering:</p>
<pre class="brush: javascript">
// api.widget.www/api.v.0.1.js

    /*
     * Renders the widget
     */
    function render(state) {
        var div = getWidgetAnchor();

        if (!div) {
            return;
        }

        o2.Dom.loadCss(
            o2.String.concat(kApiRoot, kCssPath),
            function() {
                renderWidget(div, state.data);

                processPostRenderActions();
            }
        );
    }
</pre>
<p>We will come to <strong>o2.Dom.loadCss</strong> later.<br />
For now lets focus our attention to <strong>getWidgetAnchor</strong> method:</p>
<pre class="brush: javascript">
    /*
     * Find a place to append the widget UI.
     */
    function getWidgetAnchor() {
        var div = null;

        // divs is a &quot;live&quot; node list
        var divs = document.getElementsByTagName(kDiv);
        var len  = divs.length;
        var i    = 0;

        for (i = 0; i &lt; len; i++) {
            div = divs[i];

            if (div.hasAttribute(kWidgetAnchor)) {
                return div;
            }
        }

        return null;
    }
</pre>
<p>The method simply finds the first div element with the <strong>data-wd-anchor</strong> attribute and returns it.</p>
<h2>Styling the Widget</h2>
<p>To give the desired look and feel and functionality to our widget, we have to add some <strong>CSS</strong> styling to our widget.</p>
<p>There are several ways of doing this:</p>
<ul style="margin-top:-30px">
<li>We can use <strong>inline styles</strong> (as in [div style="background:#aaccff;border:1px solid">...[/div]);</li>
<li>We can load our CSS file as a <strong>dependency</strong> at the <strong>initialization phase</strong> of the bootloader;</li>
<li>We can <strong>lazy load</strong> the <strong>CSS</strong> just before rendering the widget;</li>
<li>We can <strong>embed</strong> the <strong>CSS</strong> declerations <strong>directly into JavaScript</strong> and append them to a <strong>style</strong> node that we <strong>dynamically create</strong>.</li>
</ul>
<p>Each of these techniques have their pros and cons.<br />
In this tutorial we will continue with the &#8220;lazy loading&#8221; approach.</p>
<h2>Adding More Modules to the Dependency Loader</h2>
<p>But first we&#8217;ll need to add a couple of more <strong>JavaScript</strong> files to our dependency loader:</p>
<pre class="brush: javascript">
    /*
     * Load necessary o2.js components in noConflict mode.
     */
    function loadDependencies(callback) {
        log(&#039;o-&gt;loadDependencies(&#039;);
        log(callback);
        log(&#039;)&#039;);

        setReadyState(kLoadingDependencies);

        loadScripts(kO2Root, [
            &#039;o2.meta.js&#039;,
            &#039;o2.core.js&#039;,
            &#039;o2.string.core.js&#039;,
            &#039;o2.jsonp.core.js&#039;,
            &#039;o2.dom.constants.js&#039;,
            &#039;o2.dom.core.js&#039;,
            &#039;o2.dom.load.js&#039;,
            &#039;o2.event.constants.js&#039;,
            &#039;o2.event.core.js&#039;,
            &#039;o2.validation.core.js&#039;,
            &#039;o2.method.core.js&#039;,
            &#039;o2.collection.core.js&#039;
        ], callback);
    }
</pre>
<blockquote><p>Note that we are adding more and more files to the initializer array. Since every item in this array corresponds to one more HTTP request, in a production application we will have to <strong>merge</strong>, <strong>minify</strong> and <strong>gzip</strong> those scripts <strong>into a single file</strong> to improve speed and performance (we&#8217;ll come to that in followup articles).</p></blockquote>
<h2>Asynchronously Load Widget CSS</h2>
<p>Let&#8217;s see our render code once more:</p>
<pre class="brush: javascript">
    /*
     * Renders the widget
     */
    function render(state) {
        ...

        o2.Dom.loadCss(
            o2.String.concat(kApiRoot, kCssPath),
            function() {
                renderWidget(div, state.data);

                processPostRenderActions();
            }
        );
    }
</pre>
<p>The above code appends <strong>http://api.widget.www/css/v.0.1/widget.css</strong> file to the head of the document, and then executes the <strong>callback</strong> closure.</p>
<p>Just for a sec, assume that the CSS that we load contains the following directive</p>
<pre class="brush: css">
body {background: red !important;}
</pre>
<p>After loading the <strong>CSS</strong>, we&#8217;ll see that all of a sudden the publisher&#8217;s page background will become red.<br />
Remember? <a href="http://o2js.com/2012/07/16/javascript-widgets-setup/" title="We don't own publisher's website">We don&#8217;t own publisher&#8217;s <strong>DOM</strong></a>, so we have to constraint our styling to our widget only.</p>
<blockquote><p>Styling a widget requires a lot of testing with a combination of different demo publisher pages and user agents; since unless you&#8217;re injecting your widget with an <strong>iframe</strong> (<em>and there are good reasons to do so; one of which is preserving the look and feel</em>), the publisher&#8217;s styles can always override yours.</p></blockquote>
<p>Moreover you have to decide the following yourself?</p>
<ul style="margin-top:-30px">
<li>Shall the widget look exactly the same in every single one of the publishers?</li>
<li>Or shall the widget inherit some of the styling of the publisher, to give a more <strong>streamlined</strong> look and feel?</li>
<li>Shall we, as the widget authors, provide a way to <strong>easily modify</strong> the styling of our widget depending on their taste?</li>
<li>And if so, <strong>to what extent</strong>?</li>
</ul>
<blockquote><p>There is no silver bullet to correctly answer these questions, and you have to judge for yourself regarding how <strong>rigid</strong> or how <strong>flexible</strong> your approach may be.</p></blockquote>
<h2>Techniques to Ensure Style Consistency</h2>
<p>To avoid our styles conflict with the publisher&#8217;s we will need to <strong>prefix</strong> them with our namespace, for example:</p>
<pre class="brush: javascript">
.wd-box p {
    margin : 5px !important;
    padding: 0 !important;
}

.wd-box.wd-login {
    width : 332px;
}

.wd-boxBody {
    background   : #fefefe;
    border-top   : 1px solid #dde0e8;
    border-bottom: 1px solid #dde0e8;
    border-left  : 0;
    border-right : 0;
    padding      : 10px 20px;
}
</pre>
<p>Since <strong>.box</strong> is a really generic class name, it&#8217;s possible that our publisher may have a <strong>.box</strong> class defined already, and it may interfere with ours. So instead of using class names like <strong>.box</strong> and <strong>.login</strong>, we prefix them with our widget namespace <strong>wd-</strong> as in <strong>.wd-box</strong>, and <strong>.wd-login</strong>.</p>
<blockquote><p>As a rule of thumb, prefix anything that&#8217;s publicly reachable and modifiable (like css classes, global variables, DOM attributes&#8230;)</p></blockquote>
<p>However due to the <a href="http://www.stuffandnonsense.co.uk/archives/images/specificitywars-05v2.jpg" title="CSS Specificity Wars">rules of CSS specificity</a>, simply prefixing our classes may not provide enough protection: Our rules may be overridden by a more specific ruleset of the publisher&#8217;s.</p>
<p>If that&#8217;s the case we can <strong>over-specify</strong> our selectors like:</p>
<pre class="brush: css">
body#wd-mastercontainer #wd-wrap .wd-box.wd-login {
    width : 332px;
    margin: 10px;
}
[/sourcecodde]

Using two id selectors makes our selector &lt;strong&gt;highly unlikely&lt;/strong&gt; to be unintentionally overridden by the publisher&#039;s styles. And if the publisher &quot;intentionally&quot; overrides the styles, she should know what she&#039;s doing anyway.

Another thing we can do is to &lt;strong&gt;abuse !important&lt;/strong&gt; declarations:

[sourcecode language=&quot;css&quot;]
.wd-boxBody {
    background   : #fefefe !important;
    border-top   : 1px solid #dde0e8 !important;
    border-bottom: 1px solid #dde0e8 !important;
    border-left  : 0 !important;
    border-right : 0 !important;
    padding      : 10px 20px !important;
}
</pre>
<blockquote><p>Keep in mind that overusing <strong>!important</strong> declarations also takes away the ability give the publisher freedom to override our styles, if they want: <strong>!important</strong> declerations will always take precedence. Use them sparingly.</p></blockquote>
<h2>Render the Initial UI</h2>
<p>After loading the CSS, we render the widget UI inside the callback. That&#8217;s as easy as assigning an <strong>innerHTML</strong>.</p>
<pre class="brush: javascript">
    /*
     * Does the actual rendering.
     */
    function renderWidget(container, html) {
        if (!container) {
            return;
        }

        container.innerHTML = html;
    }
</pre>
<h2>Post-Render Processing</h2>
<p>And after rendering the widget UI, we do further processing (in <strong>processPostRenderActions</strong>):</p>
<pre class="brush: javascript">
    /*
     * Things done after the initial view is rendered.
     */
    function processPostRenderActions() {
        delegateEvents();

        processQueue();

        window[kWidgetQueueAlias] = queue;

        setReadyState(kComplete);

        fireAsyncInit();
    }
</pre>
<p>Here&#8217;s what the above code does:</p>
<ul style="margin-top:-30px">
<li>We bind <strong>event handlers</strong>;</li>
<li>Then we process the <strong>job queue</strong> that the publisher has provided us;</li>
<li>Then we <strong>overload the queue implementation</strong> with an Array-like object;</li>
<li>Then we set ready state to complete to indicate that our initialization has been completed;</li>
<li>Then we call <strong>_wdAsyncInit</strong> to tell the publisher that we are done with the <strong>widget initialization</strong>.</li>
</ul>
<p>Let&#8217;s see all those codes one by one:</p>
<h3>Event Delegation</h3>
<pre class="brush: javascript">
    /*
     * Use event delegation to bind widget events.
     */
    function delegateEvents() {
        log(&#039;o-&gt;delegateEvents()&#039;);

        o2.Event.addEventListener(document, kClick, document_click);
    }
</pre>
<p>We simply add a global event listener to document&#8217;s <strong>click</strong> event.</p>
<h3>Process Job Queue</h3>
<p>The <strong>job queue</strong> is simply an array (<strong>window._wdq</strong>) of directives <strong>that are delated to be executed</strong> until the widget is ready. Since the directives are executed async, it does not affect speed of the widget&#8217;s initialization. It also does not degrade the publisher site&#8217;s performance.</p>
<p>Here&#8217;s how we process the job queue:</p>
<pre class="brush: javascript">
    /*
     * Processes the job queue item by item.
     */
    var processQueue = function() {
        log(&#039;o-&gt;processQueue()&#039;);

        setReadyState(kBeginProcessQueue);

        var q = null;

        if (window[kWidgetQueueAlias] &amp;&amp;
                    o2.Validation.isArray(window[kWidgetQueueAlias])) {
            q = window[kWidgetQueueAlias];

            while (q.length) {
                execute(q.pop());
            }
        }

        processQueue = noop;
    };
</pre>
<p>Where the <strong>execute</strong> function is as follows:</p>
<pre class="brush: javascript">
    /*
     * Executes the job queue asyncronously.
     */
    function execute(item) {
        log(&#039;o-&gt;execute()&#039;);

        var action = item[kAction];

        switch (action) {
            case kEcho:
                log(&#039;ECHO: &#039;);
                log(item[kPayload]);

                break;
            default:
                log(&#039;ERROR: no mapping for action &quot;&#039; + action + &#039;&quot;&#039;);
        }
    }
</pre>
<p>The method simply executes API methods depending on the <strong>action</strong> parameter.</p>
<p>So the following code in the publisher&#8217;s page:</p>
<pre class="brush: javascript">
window._wdq.push({action : &#039;echo&#039;, payload : {&#039;hello&#039; : &#039;world&#039;}});
</pre>
<p>Will print</p>
<pre class="brush: text">
ECHO:
{&quot;hello&quot; : &quot;world&quot;};
</pre>
<p>on the console.</p>
<h4>Overload Queue Implementation</h4>
<p>And after that we overload the queue implementation:</p>
<pre class="brush: javascript">
window[kWidgetQueueAlias] = queue;
</pre>
<p>Where the queue implementation is:</p>
<pre class="brush: javascript">
    /*
     * An overridden version of the async job queue.
     */
    var queue = {
        items : [],

        push : function(item) {
            log(&#039;o-&gt;queue.push()&#039;);

            execute(item);
        }
    };
</pre>
<blockquote><p>We just overload the <strong>push</strong> method so that the publisher can call <strong>window._wdq.push</strong> even after we initialize our widget.</p></blockquote>
<h3>Call Async Init Function</h3>
<blockquote><p><strong>Facebook</strong> uses exactly the same approach, when initializing <strong>FB JS SDK</strong>.</p></blockquote>
<p>At the end of the flow we simply call <strong>window._wdAsyncInit</strong> to give publisher the freedom execute their post-initialization logic, if necessary.</p>
<h2>Click Event Delegation</h2>
<p>Now let&#8217;s observe the global document click event handler:</p>
<pre class="brush: javascript">
    /*
     * Global event handler on document&#039;s click event.
     */
    function document_click(evt) {
        log(&#039;document_click()&#039;);

        var target = o2.Event.getTarget(evt);

        var id = target.id;

        if (!id) {
            return;
        }

        // Just for demonstration.
        var params = {};
        params[kUsername] = &#039;dummy&#039;;
        params[kPassword] = &#039;dummy&#039;;

        if (id.indexOf(kLoginButtonId) &gt; -1) {
            o2.Jsonp.get(
                o2.String.concat(kApiRoot, kLoginPath),
                params,
                processUserLogin
            );
        }
    }
</pre>
<p>To understand what this function does let&#8217;s flashback to initialize method:</p>
<pre class="brush: javascript">
    /*
     * Initialize after loading prerequisites.
     */
    function initialize() {
        log(&#039;o-&gt;initialize()&#039;);

        setReadyState(kLoadedDependencies);

        if (!window.o2) {return;}

        window.o2.noConflict(kO2Alias);

        o2 = window[kO2Alias];

        var config = getConfiguration();

        config[kGuid] = o2.String.generateGuid();

        loadInitialState(config, processPostInitialization);
    }
</pre>
<p>We send a <strong>guid</strong> parameter (via o2.String.generateGuid()) to the server. This way, the server&#8217;s the rendered HTML will<br />
have this guid prefix appended to ids of its elements. </p>
<p>Here&#8217;s a sample view for our widget&#8217;s rendered HTML:</p>
<pre class="brush: html">
&lt;form class=&quot;wd-box wd-login&quot; id=&quot;wd_h5b9s072n8l&quot;&gt;
    &lt;fieldset class=&quot;wd-boxBody&quot;&gt;
        &lt;label for=&quot;wd_usernameh5b9s072n8l&quot;&gt;Username&lt;/label&gt;
        &lt;input type=&quot;text&quot; required=&quot;required&quot; placeholder=&quot;type in your &amp;quot;Cool Publisher&amp;quot; 
        username.&quot; tabindex=&quot;1&quot; id=&quot;wd_usernameh5b9s072n8l&quot;&gt;
        &lt;label for=&quot;wd_passwordh5b9s072n8l&quot;&gt;
        &lt;a class=&quot;wd-rLink&quot; tabindex=&quot;5&quot; href=&quot;/&quot;&gt;Forgot password?&lt;/a&gt;&lt;span&gt;Password&lt;/span&gt;&lt;/label&gt;
        &lt;input type=&quot;password&quot; required=&quot;required&quot; tabindex=&quot;2&quot; id=&quot;wd_passwordh5b9s072n8l&quot;&gt;
    &lt;/fieldset&gt;
    &lt;footer&gt;
        &lt;label for=&quot;wd_chk_rememberh5b9s072n8l&quot;&gt;
            &lt;input type=&quot;checkbox&quot; tabindex=&quot;3&quot; id=&quot;wd_chk_rememberh5b9s072n8l&quot;&gt;
            &lt;span&gt;Keep me logged in&lt;/span&gt;
        &lt;/label&gt;
        &lt;input type=&quot;button&quot; class=&quot;wd-btnLogin&quot; tabindex=&quot;4&quot; 
            value=&quot;Login&quot; id=&quot;wd_btnLoginh5b9s072n8l&quot;&gt;
    &lt;/footer&gt;
&lt;/form&gt;
</pre>
<p>So on the global <strong>document_click</strong> event handler, if the user clicks on the login button, we detect it an do a <strong>JSONP</strong> API call:</p>
<pre class="brush: javascript">
...
        if (id.indexOf(kLoginButtonId) &gt; -1) {
            o2.Jsonp.get(
                o2.String.concat(kApiRoot, kLoginPath),
                params,
                processUserLogin
            );
        }
...
</pre>
<p>When the call succeeds, <strong>processUserLogin</strong> is executed, which simply refreshes the widget view:</p>
<pre class="brush: javascript">
    /*
     * User login JSONP callback.
     */
    function processUserLogin(response) {
        var div = getWidgetAnchor();
        div.innerHTML = response.data;
    }
</pre>
<h2>Session Persistence</h2>
<p>And here&#8217;s what happens on the server when the user sends a login request:</p>
<pre class="brush: javascript">
// api.widget.wwwroot/index.js
...
        /**
         * Authenticates user.
         */
        app.get(v_0_1(route).LOGIN, function(req, res) {
            var username = req.param(parameter.USERNAME);
            var password = req.param(parameter.PASSWORD);
            var callback = req.param(parameter.CALLBACK);

            if (!username) {
                res.send(statusCode.NO_DATA);
            }

            if (!password) {
                res.send(statusCode.NO_DATA);
            }

            if (!callback) {
                res.send(statusCode.NO_DATA);
            }

            var session = req.session;

            session[parameter.USERNAME] = username;

            var params = {};

            sendJsonp(req, res, params, callback);
        });
</pre>
<p>Where <strong>sendJsonp</strong> is:</p>
<pre class="brush: javascript">
    /*
     *
     */
    function send(res, callback, result) {
        res.send(
            callback + &#039;(&#039; + JSON.stringify(result) + &#039;);&#039;
        );
    }

    /*
     *
     */
    function sendJsonp(req, res, params, callback) {
        var result = {
            data :
                isUserLoggedIn(req) ?
                createDashboard(params) :
                createLoginForm(params)
        };

        send(res, callback, result);
    }
</pre>
<p>And <strong>isUserLoggedIn</strong> is:</p>
<pre class="brush: javascript">
    /*
     *
     */
    function isUserLoggedIn(req) {
        return !!req.session[parameter.USERNAME];
    }
</pre>
<p>Without any verification, we add user&#8217;s username to the session, and send a dashboard html to the publisher to refresh its widget&#8217;s view. </p>
<blockquote><p>Note that this is just for demonstration purposes. Normally we should have validated username/password of the user against our database and send an error in the JSONP response if they don&#8217;t match. We&#8217;ll implement this in followup articles.</p></blockquote>
<p>Since we store the username in the session; when we refresh publisher&#8217;s page our widget will immediately render the dashboard instead of the login form. We will not see the login form until the user&#8217;s session expires.</p>
<h2>Third Party Issues</h2>
<p>There&#8217;s one caveat though. To persist session, we are making use of <a href="http://en.wikipedia.org/wiki/HTTP_cookie" title="HTTP Cookies">third party cookies</a>.</p>
<blockquote><p>In some of the browsers (like <strong>Safari</strong>) third party cookies are disabled by default. And in all of the browsers users can explicitly disable third party cookies. We cannot persist user date in the Session object, if third party cookies are disabled.</p></blockquote>
<p>There are ways to overcome these, which we will explore in followup articles too. For instance <strong>Facebook</strong> uses a <strong>dedicated login window in a popup</strong> in conjunction with an approach similar to the <a href="http://o2js.com/2012/07/27/javascript-widgets-cross-frame/" title="Klein Bottle and other Cross Domain Communication Techniques">klein bottle method</a>, to be able to read and write third party cookies.</p>
<h2>Size Does Matter</h2>
<p>If you have followed all the tutorials this far, you migh have seen that the size of our bootloader is growing as we add more and more feature. </p>
<p>Currently this size is manageable, however after a certain limit, you may want to submodules for each logical group, and either lazy-load them or load it while loading the initial dependencies.</p>
<blockquote><p>I&#8217;m trying to bring this tutorial series to a somewhat complete state before my seminar in <a href="http://jstanbul.org/2012/" title="jstanbul 2012">jstanbul 2012</a>, so I won&#8217;t have time for this refactoring right now. </p>
<p>However we&#8217;ll be doing this refactoring, along with certain <strong>security enhancement</strong>s, <strong>deplyoyment</strong> scripts, <strong>compression</strong> and <strong>minification</strong> in the upcoming tutorials.</p></blockquote>
<h2>Next Up?</h2>
<p>In the upcoming tutorials we will cover the following topics, and more:</p>
<ul>
<li><strong>Refactoring</strong> our API to further split into logically related modules;</li>
<li><strong>Minification</strong> and <strong>deployment</strong>;</li>
<li><strong>Authorization</strong> and <strong>authentication</strong>;</li>
<li><strong>Persisting</strong> and retrieving data using <strong>CORS</strong>;</li>
<li>Strengthening the <strong>security</strong> of our application, preventing against <strong>CSRF</strong> attacks.</li>
</ul>
<h2>Read the Source Luke</h2>
<p>You can get the source code accompanying this tutorial at <a href="https://github.com/v0lkan/o2.js/blob/9abbb3df52a72a31488dd22fa5598b48ec0e2ba4/examples/widget-demo/api.widget.wwwroot/index.js" title="get the source">this github history snapshot</a>.</p>
<h2>Conclusion</h2>
<blockquote><p>If this tutorial looks like a few articles loosely coupled together out of hassle, it probably is <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong></p></blockquote>
<p>In the followup articles we will elaborate on many of the issues we&#8217;ve just touched the surface of here.</p>
<blockquote><p>Also for the unlikely case that you are in Istanbul (<em>since 90% of my blog readers are in the Bay Area</em>), see you in <a href="http://jstanbul.org/2012/" title="jstanbul 2012">jstanbul 2012</a>!</p></blockquote>
<p>And, as always, feel free to send your comments and suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/07/28/javascript-widgets-user-interface/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Widget Development Best Practices (Part 4: Cross-Domain Communication)</title>
		<link>http://o2js.com/2012/07/27/javascript-widgets-cross-frame/</link>
		<comments>http://o2js.com/2012/07/27/javascript-widgets-cross-frame/#comments</comments>
		<pubDate>Fri, 27 Jul 2012 07:03:07 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Widget]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[cross-domain]]></category>
		<category><![CDATA[initialization]]></category>
		<category><![CDATA[jsonp]]></category>
		<category><![CDATA[klein bottle]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2693</guid>
		<description><![CDATA[In the former part of the series we&#8217;ve seen how to revalidate the cache and load our widget code using a self updating bootloader script. Now it&#8217;s time to pass initialization parameters to our widget, and request some state data from the widget API server. Let&#8217;s recap: Our lovely publisher &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2694" class="wp-caption alignleft" style="width: 336px"><a href="http://o2js.com/wp-content/uploads/2012/07/klein.png"><img src="http://o2js.com/wp-content/uploads/2012/07/klein.png" alt="outside in, inside out, that&#039;s how things work around" title="outside in, inside out, that&#039;s how things work around" width="326" height="417" class="size-full wp-image-2694" /></a><p class="wp-caption-text">outside in, inside out, that&#8217;s how things work around</p></div>
<p>In the former part of the series we&#8217;ve seen <a href="http://o2js.com/2012/07/22/javascript-widgets-cache/" title="Cache Revalidation">how to revalidate the cache</a> and load our widget code using a <strong>self updating bootloader script</strong>.</p>
<p>Now it&#8217;s time to pass initialization parameters to our widget, and request some state data from the widget API server.</p>
<p><strong>Let&#8217;s recap</strong>: </p>
<p>Our lovely publisher is including a async loading snippet to their pages. Once the script loads, any additional dependencies are loaded too. And then our widget&#8217;s <strong>initialization flow</strong> starts.</p>
<div style="clear:both"></div>
<h2>Configuration Parameters</h2>
<blockquote><p>A thing almost all of the widgets have in common is a set of <strong>initialization parameters</strong>, which give some <strong>flexibility</strong> over the widget&#8217;s <strong>initial construction</strong> and which may also be used to <strong>identify</strong> the publisher.</p></blockquote>
<p>For the sake of our example, let&#8217;s assume that we need to pass around a <strong>publisher ID</strong> to our <strong>api bootloader</strong>. </p>
<p>We, as widget provider, can use this publisher ID to send different data to different publishers, track API usage of various publishers, throttle/limit/block the API responses depending on the type of the publisher. All of these and more can be possible by simply passing a publisher ID to the server, during widget&#8217;s initialization.</p>
<blockquote><p>Note that a simple ID, or a simple API token is not enough to identify a publisher, since anyone can copy the initialization script and inject it to their site. </p>
<p>You can use this ID in conjunction with <strong> Referrer header</strong> to indicate that your request is coming from the intended publisher. There are other metrics you can use like setting <strong>third party token cookies</strong> for additional verification, but from experience I can say that <a href="http://o2js.com/2012/05/17/jfdi-jedis-feel-doin-it/" title="#JFDI">creating an application that just works</a> is far more important than working on a problem that you don&#8217;t actually have.</p>
<p>We will be working on <strong>session</strong>, <strong>persistence</strong>, <strong>authentication</strong>, and <strong>authorization</strong> in the upcoming articles too. Stay tuned <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></p></blockquote>
<p>There are different ways of sending parameters to our API layer. Let&#8217;s analyze a few:</p>
<h2>Passing Widget Configuration Through the Querystring</h2>
<p>We simply send the publisher id through the query string in the src attribute of the <strong>bootloader script</strong>.</p>
<p>Once the <strong>bootloader script</strong> loads, we parse that URL inside the script to get the publisher ID and then send it to the server to get <strong>initial state data</strong>:</p>
<pre class="brush: html">
&lt;script&gt;
(function() {
    var script = document.createElement(&#039;script&#039;);
        script.type  = &#039;text/javascript&#039;;
        script.async = true;
        script.src   = &#039;http://api.widget.www/api.v.0.1.js?pubId=123456&#039;
        var node = document.getElementsByTagName(&#039;script&#039;)[0];
        node.parentNode.insertBefore(script, node);
    }());
&lt;/script&gt;
</pre>
<p>Here&#8217;s a better way to implement this:</p>
<pre class="brush: html">
&lt;script&gt;
(function() {
        var pubId = &#039;123456&#039;;

        var script = document.createElement(&#039;script&#039;);
        script.type  = &#039;text/javascript&#039;;
        script.async = true;
        script.src   = &#039;http://api.widget.www/api.v.0.1.js?pubId=&#039; + pubId;
        var node = document.getElementsByTagName(&#039;script&#039;)[0];
        node.parentNode.insertBefore(script, node);
    }());
&lt;/script&gt;
</pre>
<p>If we use this approach, we will be able to see the publisher id on the server&#8217;s <strong>HTTP logs</strong>, since it&#8217;s transferred as a part of the <strong>URL</strong>.</p>
<h2>Passing Widget Configuration Through the Hash Fragment</h2>
<p>Another option is to pass the parameters through the hash fragment:</p>
<pre class="brush: html">
&lt;script&gt;
(function() {
    var pubId = &#039;123456&#039;;

    var script   = document.createElement(&#039;script&#039;);
    script.type  = &#039;text/javascript&#039;;
    script.async = true;
    script.src   = &#039;//api.widget.www/api.v.0.1.js?#pubId=&#039; + pubId;
    var node     = document.getElementsByTagName(&#039;script&#039;)[0];
    node.parentNode.insertBefore(script, node);
}());
&lt;/script&gt;
</pre>
<p>Please note that we are using <a href="http://www.ietf.org/rfc/rfc3986.txt" title="Protocol Relative URLs">protocol relative URLs</a> too. This will help us avoid browser&#8217;s warning when the publisher&#8217;s pages are served over <strong>HTTPS</strong>.</p>
<blockquote><p>Keeping all your assets within the same protocol prevents the dreaded &#8220;This Page Contains Both Secure and Non-Secure Items&#8221; warning message in IE.</p></blockquote>
<p>Other than that, we just send the publisher ID through the hash fragment, instead of the query string. When we do that, we won&#8217;t see the parameters in the server logs, since the hash fragments are not transmitted to the server during page requests.</p>
<h2>Passing Widget Configuration Through HTM5 Data Attributes</h2>
<p>We can also use the new kid on the block <strong>HTML5 data- attributes</strong> to pass our initialization parameters to the widget script:</p>
<pre class="brush: html">
&lt;script data-wd-pub-id=&quot;123456&quot;&gt;
(function() {
    var script   = document.createElement(&#039;script&#039;);
    script.type  = &#039;text/javascript&#039;;
    script.async = true;
    script.src   = &#039;//api.widget.www/api.v.0.1.js&#039;
    var node = document.getElementsByTagName(&#039;script&#039;)[0];
    node.parentNode.insertBefore(script, node);
}());
&lt;/script&gt;
</pre>
<p>We then simply parse DOM to get a script element with <strong>data-wd-pub-id</strong>, and use the value of this attribute in widget initialization.</p>
<p>Note that we prefix our attibute with <strong>-wd</strong> and use <strong>data-wd-pub-id</strong> instead of <strong>data-pub-id</strong>.</p>
<blockquote><p> Always keep in mind that you may not be the only widget provider that the publisher uses. </p>
<p><a href="http://o2js.com/2012/07/16/javascript-widgets-setup/" title="You don't own the publisher's website">You don&#8217;t own the publisher&#8217;s website</a>. </p>
<p>Prefix everything that&#8217;s publicly accessible (like <strong>global variables</strong>, <strong>attributes</strong>, <strong>CSS class names</strong>&#8230;) with your widget namespace, so that it does not gets overridden, or it does not conflict with the publisher&#8217;s or another widget provider&#8217;s configuration or styling data on the page.</p></blockquote>
<h2>Passing Widget Configuration Through Global Variables</h2>
<p>Another option is to pass the configuration data as global variables. Note that we are also <strong>prefixing</strong> our variable with <strong>_wd</strong> (our widget&#8217;s namespace) to avoid conflicts.</p>
<pre class="brush: html">
&lt;script&gt;
var _wd_pubId = 1234;

(function() {
    var script   = document.createElement(&#039;script&#039;);
    script.type  = &#039;text/javascript&#039;;
    script.async = true;
    script.src   = &#039;//api.widget.www/api.v.0.1.js&#039;
    var node     = document.getElementsByTagName(&#039;script&#039;)[0];
    node.parentNode.insertBefore(script, node);
}());
&lt;/script&gt;
</pre>
<p>Or it&#8217;s even better to use a common <strong>_wd</strong> namespace, to enable group a bunch of initialization parameters together:</p>
<pre class="brush: html">
&lt;script&gt;
if (!window._wd) {
    window._wd = {
        pubId : &#039;123456&#039;
    };

    (function() {
        var script = document.createElement(&#039;script&#039;);
        script.type  = &#039;text/javascript&#039;;
        script.async = true;
        script.src   = &#039;//api.widget.www/api.v.0.1.js&#039;
        var node = document.getElementsByTagName(&#039;script&#039;)[0];
        node.parentNode.insertBefore(script, node);
    }());
}
&lt;/script&gt;
</pre>
<p>In the above code there is another checks for additional safety:</p>
<p>First, we check for <strong>window._wd</strong> namespace and do not do anything if it already exists. If such a namespace exists, then it means that our widget bootloader has been included before, so there&#8217;s no need to enter the same initialization flow once again.</p>
<p>If there&#8217;s no such <strong>window._wd</strong> namespace, then we create one and asynchronously append our bootloader script as we&#8217;ve done before.</p>
<p>We also have slightly changed our bootloader, adding two guard clauses:</p>
<pre class="brush: javascript">
// api.v.0.1.js

    ...

    /*
     * Ready States
     */
    var kLoaded              = 1;
    var kLoadingDependencies = 2;
    var kLoadedDependencies  = 3;
    var kBeginProcessQueue   = 4;
    var kBeginRender         = 5;
    var kComplete            = 6;

    ...

    // Publisher has forgotten to provide initialization data.
    if (!window[kWidgetAlias]) {
        log(&#039;Widget namespace cannot be found; exiting.&#039;);

        return;
    }

    // To avoid re-defining everything if the bootloader is included in
    // more than one place in the publisher&#039;s website.
    if (window[kWidgetAlias][kReadyState]) {
        log(&#039;Widget has already been loaded; exiting.&#039;);

        return;
    }
</pre>
<p>The first &#8220;<strong>if</strong>&#8221; checks for the existence of <strong>window._wd</strong> namespace, if it does not exist, then the publisher has forgotten to include their pubId parameter, so the initialization cannot continue.</p>
<p>The second one checks whether the widget has been loaded. So even the publisher does not include the <strong>if (!window._wd)</strong> condition on their script, the initialization flow will not proceeed, because another script will have already done the initialization.</p>
<h2>Getting the Widget Configuration</h2>
<p>The next thing is to get the widget configuration. That&#8217;s relatively easy, since it&#8217;s a globally accessible variable, rather than being a data attribute, hash fragment, or query string. The latter three will require traversing the <strong>DOM</strong> and doing regular expression matches. It&#8217;s also a relatively easy task, but providing a global configuration data is <strong>faster</strong> and <strong>cleaner</strong>:</p>
<pre class="brush: javascript">
    ...

    /*
     * Parameter Names
     */
    var kPublisherId = &#039;pubId&#039;;
    var kRandom      = &#039;r&#039;;
    var kVersion     = &#039;v&#039;;

    ...

    /*
     * Globals
     */
    var kO2Alias          = &#039;_wd_o2&#039;;
    var kWidgetAlias      = &#039;_wd&#039;;
    var kWidgetQueueAlias = &#039;_wdq&#039;

    ...

    /*
     * Get widget configuration from DOM.
     */
    function getConfiguration() {
        log(&#039;o-&gt;getConfiguration()&#039;);

        var result = {};

        result[kPublisherId] = window[kWidgetAlias][kPublisherId];

        return result;
    }
</pre>
<h2>Send Configuration Data to Server</h2>
<p>Here&#8217;s where we left last time, on the widget&#8217;s <strong>initialization flow</strong>:</p>
<pre class="brush: javascript">
    /*
     * Initialize after loading prerequisites.
     */
    function initialize() {
        log(&#039;o-&gt;initialize()&#039;);

        setReadyState(kLoadedDependencies);

        if (!window.o2) {return;}

        window.o2.noConflict(kO2Alias);

        o2 = window[kO2Alias];

        var config = getConfiguration();

        loadInitialState(config, processPostInitialization);
    }
</pre>
<p>The <strong>initialize</strong> method is called once the additional dependencies are loaded by our bootloader.</p>
<p>Let&#8217;s see what those dependencies are:</p>
<pre class="brush: javascript">
    ...

    /*
     * Load necessary o2.js components in noConflict mode.
     */
    function loadDependencies(callback) {
        log(&#039;o-&gt;loadDependencies(&#039;);
        log(callback);
        log(&#039;)&#039;);

        setReadyState(kLoadingDependencies);

        loadScripts(kO2Root, [
            &#039;o2.meta.js&#039;,
            &#039;o2.core.js&#039;,
            &#039;o2.string.core.js&#039;,
            &#039;o2.jsonp.core.js&#039;
        ], callback);
    }

    checkForUpdates(versionTimestamp);
    loadDependencies(initialize);
}(this, this.document, true));
</pre>
<p>So we simply load a couple of required o2.js modules, and then call <strong>initialize</strong> function when they are all done.</p>
<p>Then we exit the initialization flow if we fail to load the o2.js framework for some reason:</p>
<pre class="brush: javascript">
        ...

        if (!window.o2) {return;}

        ...
</pre>
<blockquote><p>Since we don&#8217;t own the publisher&#8217;s <strong>DOM</strong>, we don&#8217;t also know whether the publisher has included a different version of <strong>o2.js</strong> framework on his web page. If there is such a case, our o2.js methods may conflict with that of the publisher&#8217;s.</p></blockquote>
<p>To avoid this we load o2.js onto <strong>window._wd_o2</strong> namespace, in <strong>noConflict</strong> mode.</p>
<p>This essentially:</p>
<ul style="margin-top:-20px">
<li>Loads the current framework into a new namespace;</li>
<li>Overwrites window.o2, from the cached version (the version that the publisher is using);</li>
<li>And returns a reference to the new namespace.</li>
</ul>
<p>Here&#8217;s the actual code from the <strong>o2.js</strong> source:</p>
<pre class="brush: javascript">
// o2.core.js

    exports.noConflict = def(me, &#039;noConflict&#039;, function(newName) {
        var name = newName || [myName, ((new Date()).getTime() +
            Math.random() * (1 &lt;&lt; kGuidShift)).toString(kGuidRadix
            ).replace(kDecimalPoint, kEmpty)].join(kEmpty);

        window[name] = myself;

        window[myName] = window._o2_cached;

        return window[name];
    });
</pre>
<p>Then we <strong>cache</strong> the new namespace in a local o2 <strong>alias</strong> for ease of reference:</p>
<pre class="brush: javascript">
   ...
        o2 = window[kO2Alias];
   ...
</pre>
<p>Then we get the configuration and <strong>load initial state</strong> from the API server:</p>
<pre class="brush: javascript">
    ...
        var config = getConfiguration();

        loadInitialState(config, processPostInitialization);
</pre>
<h2>Communicating with the Server</h2>
<p>Since our api server is on a different domain than the publisher&#8217;s website, we are back into the <a href="http://o2js.com/2011/05/29/jsonp-cross-domain-ajax/" title="Cross Domain AJAX Requests">cross domain boundary passing</a> problem.</p>
<p>There are different approaches to create a cross domain channel from the <strong>publisher</strong> to the <strong>widget API server</strong>.</p>
<p>These can be listed as:</p>
<ul style="margin-top:-20px">
<li><a href="http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/" title="Cross Origin Resource Sharing">Cross Origin Resource Sharing</a></li>
<li><a href="https://github.com/flensed/flXHR" title="FLXHR">Using flash as a proxy</a></li>
<li><a href="http://softwareas.com/cross-domain-communication-with-iframes" title="Cross-Domain Communication With iframes">Using iframe hash fragments</a></li>
<li><a href="http://corneliusweiss.de/2009/12/09/cross-site-ajax-window-name-proxy-for-extjsext-core/" title="Cross Site AJAX With Window.name as a proxy">Using window.name as a communication proxy</a></li>
<li><a href="http://stevehanov.ca/blog/index.php?id=109" title="Cross frame communication the HTML5 Way">Using HTML5 Cross Frame Messaging API</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/bb735305.aspx" title="Secure Cross Domain Communication in the Browser">Klein Bottle Technique</a></li>
<li><a href="http://developer.yahoo.com/javascript/howto-proxy.html" title="Using a Web Proxy for Cross Domain">Using a Web Proxy for Cross Domain Communication</a></li>
<li><a href="http://o2js.com/2011/05/29/jsonp-cross-domain-ajax/" title="JSONP">JSON With Padding (<em>JSONP</em>)</a></li>
</ul>
<blockquote><p>I&#8217;m sure there are even crazier techniques, that don&#8217;t come to my mind right now. We, web hackers, are really creative in finding loopholes and bending security limitations <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong>.</p></blockquote>
<p>Each of the above techniques have their own pros and cons. </p>
<p>And once you manage to pass the cross domain boundary, there are other beasts waiting for your exploration <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong> (which we will talk about in the followup articles) <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong>.</p>
<blockquote><p>If you are targeting relatively newer versions of browsers (<strong>IE10+, Firefox 3.5+, Chrome 3+, Safari4+, Opera12+</strong>), or if you are targeting mobile devices specifically, then you can safely use cross origin resource sharing as a modern way to do cross-domain communication. Otherwise you will need to provide a couple of fallback mechanisms.</p></blockquote>
<blockquote><p>Cross-Domain Communication is a hard problem to tackle with. There are also several libraries that choose an aproproate communication channel depending on the current user agent&#8217;s capabilities. The most popular one is <a href="http://easyxdm.net" title="EasyXDM">EasyXDM</a>. It&#8217;s a well-established library which big guys like <strong>LinkedIn</strong>, <strong>twitter</strong>, and <strong>disqus</strong> use for their cross-domain communication needs.</p></blockquote>
<p>For the sake of our argument, we will implement our solution using <strong>JSONP</strong>, which can run in almost any user agent without needing further modifications. </p>
<h2>Drawbacks of <strong>JSONP</strong></h2>
<p>However there are several limitations of <strong>JSONP</strong>. To name a few:</p>
<ul style="margin-top:-20px">
<li><a href="http://www.boutell.com/newfaq/misc/urllength.html" title="URL Length Limitation">The size of the data you can send is limited</a> (around 2000 characters);</li>
<li><strong>JSONP</strong> only works with <strong>GET</strong> requests, you cannot do <strong>POST</strong>, <strong>PUT</strong>, or <strong>DELETE</strong> requests with it;</li>
<li>There&#8217;s no error handling in <strong>JSONP</strong>, either you request succeeeds, or you do not get a response back. The only thing<br />
you can do is wait for a long enough timeout (like 10 seconds) and raise an error if there&#8217;s still no response from the server;</li>
<li><strong>JSONP</strong> requests are vulnerable to <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery" title="Cross-Site Request Forgery">CRSF attacks</a>, so you should take additional security precautions if you are using <strong>JSONP</strong> as a cross-domain proxy.</li>
</ul>
<p>Having said all these, let&#8217;s see how we communicate with our server using <strong>JSONP</strong>:</p>
<pre class="brush: javascript">
    /*
     * Loads initial widget state from the server.
     */
    function loadInitialState(config, callback) {
        log(&#039;o-&gt;loadInitialState(&#039;);
        log(config);
        log(callback);
        log(&#039;)&#039;);

        o2.Jsonp.get(
            o2.String.concat(kApiRoot, kParamsPath),
            config,
            callback
        );
    }
</pre>
<p>We simply do a <strong>JSONP</strong> request to <strong>http://api.widget.www/api/v.0.1/params</strong>.</p>
<blockquote><p>Since we&#8217;ve included <strong>o2.js</strong> <strong>JSONP</strong> module as a dependency, doing a <strong>JSONP</strong> request can be done in just a single line of code.</p></blockquote>
<p>And here&#8217;s what happens on the server:</p>
<pre class="brush: javascript">
    /**
     *
     */
    app.get(v_0_1(route).PARAMS, function(req, res) {
        var callback    = req.param(parameter.CALLBACK);
        var publisherId = req.param(parameter.PUBLISHER_ID);

            // very primitive access control.
        if (publisherId !== &#039;123456&#039;) {
            res.send(statusCode.NO_DATA);

            return;
        }

        var result = {
            data : &#039;Hello World. Hello Stars. Hello Universe!&#039;
        };

        res.send(
            callback + &#039;(&#039; + JSON.stringify(result) + &#039;);&#039;
        );
    });
</pre>
<p>We just send a dummy <strong>JSON</strong> data to the client. </p>
<blockquote><p>We will be doing more meaningful things, like rendering a login form, in the following article.</p></blockquote>
<h2>Read the Source Luke</h2>
<p>If you want to play with what we have done so far, <a href="https://github.com/v0lkan/o2.js/tree/0a9552494aa35e9b538650562df4c2edb71e9deb" title="accompanying code">you can see the code at this github history snapshot</a>.</p>
<h2>Conclusion</h2>
<p>In this article we&#8217;ve observed different ways to provide initialization parameters to our widget. </p>
<p>We&#8217;ve also learned varios approaches on cross-domain communication; and we implemented a <strong>JSONP</strong> tunnel as our cross domain proxy. </p>
<p>We mentioned various drawbacks of using a <strong>JSONP</strong> proxy, pointing to more modern alternatives such as <strong>CORS</strong>.</p>
<p>In the next article of the series, we&#8217;ll finally start creating something we can interact with. We&#8217;ll create an initial login screen, and work with authentication and authorization.</p>
<p>Until then, feel free to share your comments and suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/07/27/javascript-widgets-cross-frame/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Widget Development Best Practices (Part 3: Cache Revalidation)</title>
		<link>http://o2js.com/2012/07/22/javascript-widgets-cache/</link>
		<comments>http://o2js.com/2012/07/22/javascript-widgets-cache/#comments</comments>
		<pubDate>Sun, 22 Jul 2012 01:20:10 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Widget]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[bootloader]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[cache revalidation]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[exipres header]]></category>
		<category><![CDATA[initialization]]></category>
		<category><![CDATA[lazy loading]]></category>
		<category><![CDATA[third party]]></category>
		<category><![CDATA[versioning]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2641</guid>
		<description><![CDATA[In the former post we have outlined a broad brushstrokes initialization flow of our external JavaScript Widget: What we did was to basically create a bootloader script that first loaded required resources asynchronously and then continued its flow with the initialization and rendering of the widget. Currently, those initialization and &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2644" class="wp-caption alignleft" style="width: 319px"><a href="http://o2js.com/wp-content/uploads/2012/07/cache.png"><img src="http://o2js.com/wp-content/uploads/2012/07/cache.png" alt="setting a far future expires header and cache revalidation makes your widget load faster" title="setting a far future expires header and cache revalidation makes your widget load faster" width="309" height="202" class="size-full wp-image-2644" /></a><p class="wp-caption-text">setting a far future expires header and cache revalidation makes your widget load faster</p></div>
<p><a href="http://o2js.com/2012/07/16/javascript-widgets-setup/" title="JavaScript Widget Development Best Practices (Part 2: the Setup) ">In the former post</a> we have outlined a broad brushstrokes <strong>initialization flow</strong> of our external <strong>JavaScript Widget</strong>: </p>
<blockquote><p>What we did was to basically create a <strong>bootloader script</strong> that first loaded required resources asynchronously and then continued its flow with the initialization and rendering of the widget.</p></blockquote>
<div style="clear:both"></div>
<blockquote><p>Currently, those initialization and rendering functions are empty <strong>placeholder functions</strong> that are yet to be implemented. We will be dealing with them in the upcoming articles.</p></blockquote>
<p>For the time being, let&#8217;s focus our attention to a more important problem:</p>
<h2>Versioning and Caching</h2>
<p>For any code that you constantly upgrade an develop <strong>versioning</strong> and <strong>caching</strong> are two important things to keep in mind and to get working from day zero, if your end result will be consumed through the Internet.</p>
<p>For our external <strong>JavaScript Widget</strong> to be responsive, and to load faster it&#8217;s a good practice to serve the widget script with a <a href="http://developer.yahoo.com/performance/rules.html/" title="Yahoo! WebSite Performance Rules">far future expires header</a>.</p>
<blockquote><p>&#8220;For static components: implement &#8220;Never expire&#8221; policy by setting far future <strong>Expires</strong> header</p>
<p>A first-time visitor to your page may have to make several HTTP requests, but by using the Expires header <strong>you make those components cacheable</strong>. This avoids unnecessary HTTP requests on subsequent page views.</p>
<p>Expires headers are most often used with images, but they should be used <strong>on all components including scripts</strong>, stylesheets, and Flash components.</p>
<p>Browsers (and proxies) use a cache to reduce the number and size of HTTP requests, making web pages load faster.&#8221;</p></blockquote>
<blockquote><p>It seems, however, that the big guys have not done their homeworks well:</p>
<ul style="margin-top:-30px">
<li><strong>google</strong>&#8216;s <strong>ga.js</strong> has a <strong>2 hour</strong> cache time;</li>
<li><strong>Facebook</strong>&#8216;s <strong>all.js</strong> has a <strong>15 minute</strong> cache time;</li>
<li>And <strong>twitter</strong>&#8216;s <strong>widgets.js</strong> has a <strong>30 minute</strong> cache time.</li>
</ul>
<p>These have negative impact on these scripts&#8217; loading performance.</p>
<p>Ideally they should have a far future expiration date, say&#8230; like <strong>10 years</strong>;<br />
but heck, even <strong>1 week</strong> will be a good starting point <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong>.</p></blockquote>
<h2>And There&#8217;s a Cache&#8230;</h2>
<p>However there&#8217;s one complication with setting a far future expires header:</p>
<blockquote><p>If you change your widget code, the users may still be using older versions of your widget.</p></blockquote>
<p>One approach to solve this is to give your script a <strong>version number</strong>, and change the version number of the script every time you make a code update and ask the publishers (<em><strong>hint</strong>: not a good idea <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></em>) to update their widget loader script to reflect the change, like in the following example.</p>
<pre class="brush: javascript">
// Widget Include Code
(function() {
    var script = document.createElement(&#039;script&#039;);
    script.type  = &#039;text/javascript&#039;;
    script.async = true;

    // Ask the publishers to update this version number
    // every time you make a change.
    // This is not the most ideal approach since most
    // of the publishers will rarely want to change a
    // working code snippet that does not belong to them.
    script.src = &#039;http://api.widget.www/api.v.0.1.js&#039;

    var node = document.getElementsByTagName(&#039;script&#039;)[0];
    node.parentNode.insertBefore(script, node);
}());
</pre>
<p>Moreover, assume that what you did is a critical security update. You cannot take it for granted that all the publishers will increment the API version in their initialization scripts. </p>
<blockquote><p>From former experience, I can say that <strike>some</strike> <strong>most</strong> of the publishers will not bother changing that version number and will continue using the older version of the widget.</p></blockquote>
<h2><strong>Cache Revalidation</strong> to the Rescue</h2>
<p>We will approach the problem as follows:</p>
<ul style="margin-top:-30px">
<li>We will create a <strong>cache revalidation mechanism</strong> to push hotfixes, bugfixes, improvements and non-breaking changes to the <strong>current version</strong> of the API.</li>
<li>And we will copy our script and create a new version (like <strong>api.v.0.2.js</strong>) for <strong>major improvements</strong>, and <strong>breaking changes</strong>.</li>
</ul>
<p>Doing the latter is as easy as copying the current working file, and renaming it to give a new version number. However, implementing a cache revalidation mechanism is a bit tricky. Let&#8217;s try to work on it step by step:</p>
<h2>Add a Far Future <strong>Expires</strong> Header</h2>
<p>First start with setting a very long expires header for our <strong>API bootloader</strong>:</p>
<pre class="brush: javascript">
//api.widget.wwwroot/index.js

var express = require(&#039;express&#039;);
var app     = express.createServer();

var kOneYear = 31536000000;

/*
 * Make sure that the static assets have a far future expiration date.
 */
app.use(
    express[&#039;static&#039;](
       path.STATIC_FILE,
       config.farFutureExpiration
    )
)

//where config is:
var config = {
    farFutureExpiration : {maxAge : kOneYear},

    api_v_0_1 : {
        VERSION_TIMESTAMP : &#039;20120720135547909116&#039;
    }
};
</pre>
<h2>Cache Me, If You Can&#8230;</h2>
<blockquote><p>We will come to what <strong>VERSION_TIMESTAMP</strong> is in a minute <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong>.</p></blockquote>
<p>When we request <strong>http://api.widget.www/api.v.0.1.js</strong>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html" title="HTTP Header Field Definitions">the <strong>HTTP response headers</strong></a> we get are as follows:</p>
<pre class="brush: text">
Accept-Ranges   bytes
Cache-Control   public, max-age=31536000
Connection      keep-alive
Content-Length  6672
Content-Type    application/javascript
Date            Fri, 20 Jul 2012 20:41:55 GMT
Etag            &quot;6672-1342801807000&quot;
Last-Modified   Fri, 20 Jul 2012 16:30:07 GMT
X-Powered-By    Express
</pre>
<p>Where</p>
<pre class="brush: text">
Cache-Control   public, max-age=31536000
</pre>
<p>indicates that our bootloader script (<em>i.e. api.v.0.1.js</em>) will be cached for <strong>1 year</strong>.</p>
<p>If we refresh the webpage and analyze the browser&#8217;s cache, we&#8217;ll see that it&#8217;s in deed true:</p>
<pre class="brush: text">
Cache:
Data Size       6672
Device          disk
Expires         Sat Jul 20 2013 23:43:10 GMT+0300 (EEST)
Fetch Count     4
Last Fetched    Fri Jul 20 2012 23:43:11 GMT+0300 (EEST)
Last Modified   Fri Jul 20 2012 23:43:10 GMT+0300 (EEST)
</pre>
<p>Upon that request we will also get a <a href="http://www.checkupdown.com/status/E304.html" title="HTTP 304 Status Code">HTTP 304 Not Modified response</a> from the server as expected.</p>
<blockquote><p>Caching is an indispensable reality of the web which not only widget providers, but <strong>every web developer should know</strong>. You can read <a href="http://www.mnot.net/cache_docs/" title="Caching Tutorial for Web Authors and Developers">this caching tutorial</a> for caching best practices, and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" title="HTTP Status Codes">RFC-2616</a> for HTTP  status codes and header definitions.</p></blockquote>
<h2>Self-Updating Bootloader</h2>
<p>Now it&#8217;s time to implement a <a href="http://www.stevesouders.com/blog/2012/05/22/self-updating-scripts/" title="Self Updating Scripts">self updating bootloader script</a>:</p>
<p>To begin, let us add a version timestamp to the API first:</p>
<pre class="brush: javascript">
//api.v.0.1.js

(function(window, document, isDebugMode) {
    ...

    /*
     * Should match beacon version timestamp.
     */
    var versionTimestamp = &#039;20120720135547909116&#039;;

    ...
</pre>
<p>And then pass along that version timestamp to load a <strong>cache validator beacon</strong>:</p>
<pre class="brush: javascript">
    /*
     * Revalidates cache for this bootloader script, if there&#039;s a newer
     * version available. The changes will take effect only AFTER the user
     * refreshes the page.
     */
    function checkForUpdates() {
        log(&#039;o-&gt;checkForUpdates()&#039;);

        insertScript(kApiRoot, [kBeacon, kQuery,
            kVersion,  kEquals, versionTimestamp , kAnd,
            kRandom,   kEquals, (new Date()).getTime()
        ].join(kEmpty), noop);
    }

    //Where the constants above (and some more) are defined as follows:

    var kAnd            = &#039;&amp;&#039;;
    var kApiRoot        = &#039;http://api.widget.www/&#039;;
    var kBeacon         = &#039;api/v.0.1/beacon&#039;;
    var kCompleteRegExp = /loaded|complete/;
    var kEmpty          = &#039;&#039;;
    var kEquals         = &#039;=&#039;;
    var kHead           = &#039;head&#039;;
    var kO2Root         = &#039;http://api.widget.www/lib/o2.js/&#039;;
    var kQuery          = &#039;?&#039;;
    var kRandom         = &#039;r&#039;;
    var kScript         = &#039;script&#039;;
    var kScriptType     = &#039;text/javascript&#039;;
    var kVersion        = &#039;v&#039;;
</pre>
<p>In the above code, we basically call:</p>
<pre class="brush: javascript">
    insertScript(
        &#039;http://api.widget.www/api/v.0.1/beacon?v=20120720135547909116&amp;r={#}&#039;
    );
</pre>
<p>Where <strong>insertScript</strong> simply does what its name implies:</p>
<pre class="brush: javascript">
    /*
     * Asynchronously inserts a script element to the head
     * of the document.
     */
    function insertScript(root, src) {
        var s = document.createElement(kScript);
        var x = document.getElementsByTagName(kScript)[0] ||
            document.getElementsByTagName(kHead)[0];

        s.type  = kScriptType;
        s.async = true;
        s.src   = [root, src].join(kEmpty);

        x.parentNode.insertBefore(s, x);

        return s;
    }
</pre>
<p>Thus, what we do is to <strong>request a beacon script at each widget load</strong>.</p>
<h2>The Cache Validator Beacon</h2>
<p>Now let us look at what the beacon script does:</p>
<pre class="brush: javascript">
//api.widget.wwwroot/index.js

    ...

    /**
     * Beacon to validate the cache of the JS API.
     */
    app.get(v_0_1(route).BEACON, function(req, res) {
        res.header(&#039;Content-Type&#039;, &#039;text/javascript&#039;);

        setShortExpiresHeader(res);

        var versionTimestamp = v_0_1(config).VERSION_TIMESTAMP;

        var requestedVersion = req.param(
            parameter.VERSION,
            versionTimestamp
        );

        if (requestedVersion !== versionTimestamp) {
            res.render(template.UPDATE_SCRIPT, {
                iframeUrl : v_0_1(url).UPDATE_IFRAME
            });

            return;
        }

        res.send(204);
    });
</pre>
<p>If the requested version timestamp is identical to the what we sent, then it means that we are using the most up-to-date bootloader script, we don&#8217;t need to update the cache; and the beacon simply sends a <a href="http://benramsey.com/blog/2008/05/http-status-204-no-content-and-205-reset-content/" title="HTTP 204 no content and HTTP 205 reset content">HTTP 204 (no content)</a> response.</p>
<p>Otherwise (<em>i.e. if the versions don&#8217;t match</em>) then we conclude that the user&#8217;s cache is stale and we inject a simple <strong>JavaScript</strong> in the beacon as follows:</p>
<pre class="brush: javascript">
(function() {
    var update = function() {
        if (!document.body) {
            setTimeout(update, 500);
            return;
        }

        var loader = document.createElement(&#039;iframe&#039;);

        loader.style.display = &#039;none&#039;;
        loader.src = &#039;#{iframeUrl}&#039;;

        document.body.appendChild(loader);
    };

     update();
})();
</pre>
<p>Where we append a hidden <strong>IFRAME</strong> element to the document.</p>
<p>And the contents of that <strong>IFRAME</strong> will be (<a href="http://jade-lang.com/" title="Jade Template Engine">in Jade syntax</a>):</p>
<pre class="brush: text">
    !!! 5
    html(lang=&#039;en&#039;)
        head
            script(src= apiBootstrapUrl)
        body(lang=&#039;en&#039;)
            script
                if (!window.location.hash) {
                    window.location.hash = &#039;checked&#039;;
                    window.location.reload(true);
                }
</pre>
<p>So the hidden <strong>iframe</strong> simply reloads the api bootloader script once more, where the <strong>true</strong> parameter <a href="https://developer.mozilla.org/en/DOM/window.location" title="MDN: Window.location">forces the newest script to be retrieved from the server</a>. Which will update the browser&#8217;s cache.</p>
<blockquote><p>Note that the changes will be effective upon the <strong>next retrieval of the script</strong>:</p>
<p>The most up-to-date version of the script will be served to the end user once she reloads the publisher&#8217;s website, or navigates to another page.</p></blockquote>
<p>This concludes our <strong>cache revalidation</strong> flow.</p>
<h2>Widget Sanity Check</h2>
<p>Another issue that you may coincide as a widget developer is that the publisher may unintentionally include your <strong>widget bootloader script</strong> more than once, or worse she can include several different versions of your widget bootloader script in different parts of the page. </p>
<p>To avoid redefining of resources a sanity check on the top of the widget is required.</p>
<pre class="brush: javascript">
//api.v.0.1.js

...

// To avoid re-defining everything if the bootloader is included in
// more than one place in the publisher&#039;s website.
if (window._wd) {
    return;
}

window._wd = {};
</pre>
<blockquote><p>As always, we do our best to <strong>keep the global namespace clean</strong>. Note that <strong>window._wd</strong> is the only accessible object outside the module. </p>
<p>Our assumption here is that, nobody other than the <strong>widget provider</strong> uses the <strong>window._wd</strong> namespace, and <strong>window._wd</strong> namespace solely belongs to the <strong>widget provider</strong>. </p>
<p>So if a publisher redefines <strong>window._wd</strong> at their own peril, they should know that our widget will not work properly.</p>
<p>Later, in the upcoming tutorials, it will be our widget namespace that we will <strong>export</strong> (or expose) public methods of the module to the outside world.</p></blockquote>
<h2>Load Prerequisites</h2>
<p>Another thing we would do is to load required assets (<em>such as helper libraries</em>) before continuing with the widget&#8217;s initialization flow.</p>
<p>We do this in <strong>loadPrerequisites</strong> function as follows:</p>
<pre class="brush: javascript">
    /*
     * Load necessary o2.js components in noConflict mode.
     */
    function loadPrerequisites(callback) {
        loadScripts(kO2Root, [
            &#039;o2.meta.js&#039;,
            &#039;o2.core.js&#039;
        ], callback);
    }
</pre>
<p>Where <strong>loadScripts</strong> is:</p>
<pre class="brush: javascript">
    /*
     * Loads an array of scripts one after another.
     */
    function loadScripts(root, ar, callback) {
        // Populate global script queue.
        scriptQueue = ar;

        loadScript(root, scriptQueue.shift(), callback);
    }
</pre>
<p>And <strong>loadScript</strong> is:</p>
<pre class="brush: javascript">
    /*
     * Loads the given script.
     * &lt;strong&gt;callback&lt;/strong&gt; is the function to be executed after
     * there&#039;s no resource left to be loeded next.
     */
    var loadScript = function(root, src, callback) {
        var s = insertScript(root, src);

        function processNext() {
            loadNext(root, loadScript, callback);
        }

        s.onreadystatechange = function() {
            if(kCompleteRegExp.test(s.readyState)) {
                processNext();
            }
        };

        s.onload = function() {
            processNext();
        };
    };
</pre>
<p>So we inject an array of script one after another until all of the scripts are loaded and then execute a callback.</p>
<blockquote><p>This <strong>callback</strong> continues our <strong>widget initialization flow</strong>, which is the subject of the next article in this series.</p></blockquote>
<h2>Read the Source Luke</h2>
<p>You can download the source code of what we&#8217;ve done so far from <a href="https://github.com/v0lkan/o2.js/tree/72d255c0057d74cf0cfb0484c5a2ed60f30e40dd" title="What we have done so far">this github history snapshot</a>.</p>
<h2>Conclusion</h2>
<p>In this article we&#8217;ve built upon <a href="http://o2js.com/2012/07/16/javascript-widgets-setup/" title="WIdget Development Best Practices - The Setup">what we&#8217;ve learned last time</a>.</p>
<ul style="margin-top:-30px">
<li>We&#8217;ve implemented a <strong>cache validator beacon</strong>, that refreshes the cache whenever there&#8217;s a new version of the script;</li>
<li>We&#8217;ve implemented a way to <strong>prevent multiple widget initialization</strong> if the script is included more than once on the page;</li>
<li>We&#8217;ve also implemented a mechanism to <strong>preload required assets</strong> before continuing with the widget initialization flow.</li>
</ul>
<blockquote><p>In the upcoming article, we will continue our journey with <strong>initializing</strong> and <strong>rendering</strong> our widget.</p></blockquote>
<p>Until then, feel free to share your comments an suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/07/22/javascript-widgets-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Widget Development Best Practices (Part 2: the Setup)</title>
		<link>http://o2js.com/2012/07/16/javascript-widgets-setup/</link>
		<comments>http://o2js.com/2012/07/16/javascript-widgets-setup/#comments</comments>
		<pubDate>Mon, 16 Jul 2012 08:05:01 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Widget]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[cache revalidation]]></category>
		<category><![CDATA[cross-domain]]></category>
		<category><![CDATA[external]]></category>
		<category><![CDATA[flow control]]></category>
		<category><![CDATA[module pattern]]></category>
		<category><![CDATA[parallel execution]]></category>
		<category><![CDATA[third party]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2605</guid>
		<description><![CDATA[In the former part of the series we had a brief introduction on challenges in developing JavaScript widgets. In this article, we&#8217;re going to continue from where we left: We will start by installing necessary instruments to develop and test our code. First Things First Before we start actual coding, &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2611" class="wp-caption alignleft" style="width: 336px"><a href="http://o2js.com/wp-content/uploads/2012/07/setup_2.png"><img src="http://o2js.com/wp-content/uploads/2012/07/setup_2.png" alt="initial setup" title="initial setup" width="326" height="244" class="size-full wp-image-2611" /></a><p class="wp-caption-text">initial setup</p></div>
<p>In the former part of the series we had a brief introduction on <a href="http://o2js.com/2012/07/05/javascript-widgets-overview/" title="JavaScript Widgets Overview">challenges in developing <strong>JavaScript</strong> widgets</a>. </p>
<p>In this article, we&#8217;re going to continue from where we left: We will start by installing necessary instruments to develop and test our code.</p>
<div style="clear:both"></div>
<h2>First Things First</h2>
<p>Before we start actual coding, we need to install <strong>node.js</strong>. </p>
<p>You can download and install the most recent version of <strong>node.js</strong> from <a href="http://nodejs.org/" title="download node.js">http://nodejs.org/</a>. The installation process is pretty straightforward.</p>
<blockquote><p>Note that this article is not by no means a <strong>node.js</strong> tutorial. I assume you know enough <strong>node.js</strong> to follow through. If not, <a href="http://howtonode.org/" title="How To Node">there are excellent tutorials around</a> to get you started on <strong>node.js</strong>.</p></blockquote>
<p>Then we&#8217;ll install <a href="http://expressjs.com/" title="express.js">express.js</a> to have a higher-level abstraction on top of <strong>node.js</strong> and to be easily manage <strong>cookies</strong>, <strong>session state</strong>, <strong>templates</strong>&#8230; and the like. </p>
<p>To install express.js:</p>
<pre class="brush: sh">
$ cd /path/to/your/projects/folder/
$ npm install express
</pre>
<p>While we&#8217;re at there let&#8217;s install <a href="http://jade-lang.com/" title="Jade Language"><strong>jade</strong> template engine</a> too:</p>
<pre class="brush: sh">
$ cd /path/to/your/projects/folder/
$ npm install jade
</pre>
<h2>Create Development Servers</h2>
<p>The next thing we are going to do is to create development environments.<br />
We&#8217;ll have two server instances:</p>
<ul style="margin-top:-30px">
<li><strong>http://api.widget.www/</strong> will be our <strong>widget provider</strong>;</li>
<li>And <strong>http://publisher.www:8080/</strong> will be our <strong>publisher</strong> website.</li>
</ul>
<p>We&#8217;ll simply add these lines to our <strong>/etc/hosts</strong> file.</p>
<pre class="brush: text">
127.0.0.1 api.widget.www
127.0.0.1 publisher.www
</pre>
<h2>Project Folder Structures</h2>
<p>Initially, there&#8217;s nothing fancy:</p>
<p>Here&#8217;s the initial folder structure of our api <strong>widget provider</strong> wwwroot:</p>
<div id="attachment_2613" class="wp-caption alignleft" style="width: 160px"><a href="http://o2js.com/wp-content/uploads/2012/07/api-root.png"><img src="http://o2js.com/wp-content/uploads/2012/07/api-root.png" alt="Widget API Website Root" title="Widget API Website Root" width="150" height="81" class="size-full wp-image-2613" /></a><p class="wp-caption-text">Widget API Website Root</p></div>
<div style="clear:both"></div>
<p>And here&#8217;s the initial folder structure of our demo <strong>publisher</strong> website:</p>
<div id="attachment_2614" class="wp-caption alignleft" style="width: 213px"><a href="http://o2js.com/wp-content/uploads/2012/07/publisher-root.png"><img src="http://o2js.com/wp-content/uploads/2012/07/publisher-root.png" alt="Demo Publisher Website" title="Demo Publisher Website" width="203" height="62" class="size-full wp-image-2614" /></a><p class="wp-caption-text">Demo Publisher Website</p></div>
<div style="clear:both"></div>
<blockquote><p>You can view this initial version of the sites at <a href="https://github.com/v0lkan/o2.js/tree/0b971b654b96baf0d1ee3c9262787279591243b3/examples/widget-demo" title="initial sites">this github history snapshot</a>. We will be adding more files and changing the folder structure as proceed to the next articles of this series.</p></blockquote>
<h2>Widget Server</h2>
<p>The <strong>node.js</strong> server of the widget API website is quite simple:</p>
<pre class="brush: javascript">
var express = require(&#039;express&#039;);

var app = express.createServer();

app.use(express.static(__dirname + &#039;/static&#039;));

app.get(&#039;/api/v.0.1/login&#039;, function(req, res) {
    res.send(&#039;hello authentication&#039;);
});

app.listen(80);
</pre>
<p>We simply server everything under the api.widget.wwwroot/static folder as static content.<br />
Let&#8217;s test that it works.</p>
<pre class="brush: text">
:api.widget.wwwroot$ sudo node index.js
</pre>
<p>And then when we browse to <strong>http://api.widget.www/api.v.0.1.js</strong> we&#8217;ll see that our <strong>Widget API JavaScript</strong> is served without problem.</p>
<h2>Publisher Server</h2>
<p>And here&#8217;s the <strong>publisher</strong>&#8216;s <strong>node.js</strong> server index file:</p>
<pre class="brush: javascript">
var express = require(&#039;express&#039;);

var app = express.createServer();

app.use(express.static(__dirname + &#039;/static&#039;));

// Set path to the views (template) directory
app.set(&#039;views&#039;, &#039;./views&#039;);

app.get(&#039;/&#039;, function(req, res) {
    res.render(&#039;index.jade&#039;);
});

app.listen(8080);
</pre>
<p>And we have a very simple <a href="http://jade-lang.com/" title="Jade Templating Language">Jade template</a> to be rendered when requesting the site root (&#8220;/&#8221;):</p>
<pre class="brush: text">
# views/index.jade
!!! 5
html(lang=&#039;en&#039;)
    head
        meta(charset=&#039;utf-8&#039;)
        title= &#039;Publisher Website&#039;
        link(rel=&#039;stylesheet&#039;, media=&#039;all&#039;, href=&#039;/css/main.css&#039;);

        script
            (function() {
                var script = document.createElement(&#039;script&#039;);
                script.type  = &#039;text/javascript&#039;;
                script.async = true;
                script.src   = &#039;http://api.widget.www/api.v.0.1.js&#039;
                var node = document.getElementsByTagName(&#039;script&#039;)[0];
                node.parentNode.insertBefore(script, node);
            }());

    body(lang=&#039;en&#039;)
        section#Main
            h2 Welcome to Publisher Website
</pre>
<blockquote><p>If this were a real publisher site, the template folder structure would have been more complicated possibly with a handful of partial templates. Though this basic page is good enough for our initial setup.</p></blockquote>
<p>Let&#8217;s run</p>
<pre class="brush: text">
:publisher.wwwroot $ sudo node index.js
</pre>
<p>on <strong>publisher.wwwroot</strong>.</p>
<p>When we browse <strong>http://publisher.www:8080/</strong> we&#8217;ll get a very basic welcome page.</p>
<blockquote><p>Note that we are listening to port <strong>8080</strong> for the publisher website because our api server is already listening to port <strong>80</strong>. In a production environment we won&#8217;t need ts.his too.</p></blockquote>
<h2>Asynchronous Loading of the Bootsrapper</h2>
<p>On the publisher page we include our widget initialization script as follows:</p>
<pre class="brush: javascript">
(function() {
    var script   = document.createElement(&#039;script&#039;);
    script.type  = &#039;text/javascript&#039;;
    script.async = true;
    script.src   = &#039;http://api.widget.www/api.v.0.1.js&#039;
    var node     = document.getElementsByTagName(&#039;script&#039;)[0];
    node.parentNode.insertBefore(script, node);
}());
</pre>
<p>This structure is known as <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/" title="loading scripts without blocking">async loading pattern</a>.</p>
<p>This usage is better than simply including the script with</p>
<pre class="brush: html">
&lt;script src=&quot;http://api.widget.www/api.v.0.1.js&quot;&gt;&lt;/script&gt;
</pre>
<p>because the latter will <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/" title="Loading Scripts Without Blocking">block downloading of the resources and rendering of the page</a> until it&#8217;s fully downloaded and executed. </p>
<blockquote><p>If you remember <a href="http://o2js.com/2012/07/05/javascript-widgets-overview/" title="JavaScript Widgets Overview">from the introduction article</a>, as widget developers <strong>we don&#8217;t own the publisher&#8217;s website</strong>. Per contra, we are like <strong>thieves</strong> wandering in their home. So the less noise we make, and the less trace we leave, the better.</p></blockquote>
<p>That&#8217;s why our widget should initiate itself <strong>with minimal impact</strong> to the publisher&#8217;s performance: If you want to have faster and responsive website, loading third-party resources asynchronously is a best practice to follow.</p>
<blockquote><p>However keep in mind that the publisher should have the liberty to load your script inline (as in the second example) if she likes. If she knows the <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/" title="Loading Scripts Without Blocking">consequences</a> of it, and if she has a reason to do so, we shall not prevent her from doing it. As before, <strong>we do not own publisher&#8217;s DOM</strong>. The publisher can do anything (imaginable) and we should be <strong>flexible</strong> enough to support every possible scenario.</p></blockquote>
<h2>Widget Code</h2>
<p>Here comes the fun part <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong>. Let&#8217;s see our widget code:</p>
<pre class="brush: javascript">
(function(window, isDebugMode) {
    &#039;use strict&#039;;

    var version = &#039;v.0.1&#039;;

    function isArray(item) {
        return window._wd_o2.isArray(item);
    }

    function checkForUpdates() {
    }

    function render() {
    }

    function execute() {
    }

    var queue = {
        items : [],

        push : function(item) {
            log(&#039;o-&gt;queue.push()&#039;);

            execute(item);
        }
    };

    var processQueue = function() {
        var q = null;

        if (window._wdq &amp;&amp; isArray(window._wdq)) {
            q = window._wdq;

            while (q.length) {
                execute(q.pop());
            }
        }

        processQueue = window._wd_o2.nill;
    };

    function initialState_ready(state) {
        render(state);

        processQueue();

        window._wdq = queue;
    }

    function loadInitialState(config, callback) {
        config = null;

        callback({});
    }

    function getConfiguration() {
        return {};
    }

    function initialize() {
        var config = getConfiguration();

        loadInitialState(config, initialState_ready);
    }

    function getPrerequisites(callback) {
        callback();
    }

    checkForUpdates(version);
    getPrerequisites(initialize);
}(this, true));
</pre>
<blockquote><p>I&#8217;ve removed comments and console.log calls to make the code look cleaner.</p></blockquote>
<p>The first thing we see is we&#8217;re utilizing <a href="http://o2js.com/2011/04/24/the-module-pattern/" title="the JavaScript Module Pattern">the module pattern</a> to hide our widget&#8217;s private static context and functions from the publisher. <a href="http://o2js.com/2011/04/29/javascript-best-practices/" title="A Library-Maker's Guide to JavaScript">We should not pollute global namespace</a> as widget development best practice. </p>
<h2>Widget Initialization Flow</h2>
<p>Here&#8217;s a broad overview of the initialization flow of the widget:</p>
<div id="attachment_2617" class="wp-caption alignleft" style="width: 428px"><a href="http://o2js.com/wp-content/uploads/2012/07/widget-flow1.png"><img src="http://o2js.com/wp-content/uploads/2012/07/widget-flow1.png" alt="Widget Initialization Flow" title="Widget Initialization Flow" width="418" height="457" class="size-full wp-image-2617" /></a><p class="wp-caption-text">Widget Initialization Flow</p></div>
<div style="clear:both"></div>
<blockquote><p>Most of the methods are blank, left to be implemented in the followup articles. However, the initialization flow will more or less remain the same.</p></blockquote>
<p>In the diagram above, the <strong>gray boxes</strong> represent <strong>async operations</strong> (such as loading a beacon, or making a resource request to the server).</p>
<p>Let&#8217;s observe each of the blocks one by one:</p>
<h3>BootLoader Cache Validation</h3>
<ul style="margin-top:-20px">
<li>We start by running two requests in parallel:
<ul style="margin-top:-20px">
<li>We check for new versions of our bootloader script and update our browser cache if we find out that our version is obsolete (so that the user will load the new version from cache the next time she visits the publisher site).
<p>This will help us solve <a href="http://www.stevesouders.com/blog/2012/05/22/self-updating-scripts/" title="Self-Updating Scripts">caching issues</a>, and enable us serve a faster-loading widget.
</li>
<li>And, in parallel, we start our regular widget initialization flow.</li>
</ul>
</li>
</ul>
<h3>Widget Initialization</h3>
<p>In our widget initialization flow:</p>
<ul style="margin-top:-20px">
<li>We get additional resources (such as helper libraries) in the <strong>getPrerequsities</strong> function.</li>
<li>After we retrieve all required resources we get <strong>widget configuration data</strong> from <strong>DOM</strong> and request initial state data of our widget from the server (this is basically the <strong>&#8220;Model&#8221;</strong> data that&#8217;ll be used to render the <strong>&#8220;View&#8221;</strong> of the widget)</li>
<li>We <strong>render</strong> our widget&#8217;s initial <strong>view</strong> with the <strong>state</strong> data we acquired.</li>
<li>We process any jobs in the <strong>job queue</strong> that has been registered by the publisher to be run as soon as widget is available (this job queue works similar to the <strong>_gaq</strong> of google analytics; you can register jobs, and they will be run in order whenever the widget is able to respond).</li>
<li>We override the job queue object with an Array-like implementation.</li>
</ul>
<blockquote><p>Fear not, if these flows seem a bit complicated. Most of these methods are currently abstract anyway, and we&#8217;ll be implementing them all in the following articles. And everything will be crystal-clear. Stay tuned <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong>.</p></blockquote>
<h2>Conclusion</h2>
<p>In this article we&#8217;ve learned how to set up our environment for <strong>JavaScript</strong> widget development and testing.</p>
<p>We&#8217;ve also had an abstract overview of our widget&#8217;s <strong>cache-revalidation</strong> and <strong>initialization</strong> flow logics.</p>
<p>In the next sections, we will be filling out some of these empty functions with <strong>real code</strong>.</p>
<p>Until then, feel free to share your comments and suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/07/16/javascript-widgets-setup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Widget Development Best Practices (Part 1: Overview)</title>
		<link>http://o2js.com/2012/07/05/javascript-widgets-overview/</link>
		<comments>http://o2js.com/2012/07/05/javascript-widgets-overview/#comments</comments>
		<pubDate>Thu, 05 Jul 2012 18:58:54 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[Widget]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[cross-domain]]></category>
		<category><![CDATA[external]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[third party]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2570</guid>
		<description><![CDATA[This is the beginning of a new article series where we will see best practices, common pitfalls, and &#8220;how to&#8221;s on creating JavaScript Widgets for external sites. Throughout the examples we will be using: node.js for the server; On top of node, expres.js framework as a higher-level abstraction; mongodb for &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2572" class="wp-caption alignleft" style="width: 314px"><a href="http://o2js.com/wp-content/uploads/2012/07/widgets.png"><img src="http://o2js.com/wp-content/uploads/2012/07/widgets.png" alt="a familiy of widgets of different sized" title="a familiy of widgets of different sizes" width="304" height="219" class="size-full wp-image-2572" /></a><p class="wp-caption-text">a familiy of widgets of different sizes</p></div>
<p>This is the beginning of a new article series where we will see best practices, common pitfalls, and &#8220;how to&#8221;s on creating <strong>JavaScript Widgets</strong> for external sites.</p>
<div style="clear:both"></div>
<p>Throughout the examples we will be using:</p>
<ul style="margin-top:-20px">
<li><a href="http://nodejs.org/" title="node.js"><strong>node.js</strong></a> for the server;</li>
<li>On top of node, <a href="http://expressjs.com/" title="express.js"><strong>expres.js</strong></a> framework as a higher-level abstraction;</li>
<li><a href="http://www.mongodb.org/" title="mongodb"><strong>mongodb</strong></a> for the <strong>persistence</strong> layer;</li>
<li>And borrow some code from <a href="http://github.com/v0lkan/o2.js" title="o2.js JavaScript Framework"><strong>o2.js</strong></a> for client-side <strong>DOM</strong> interaction and <a href="http://o2js.com/2011/10/04/o2-js-javascript-conventions/" title="Event Delegation">event delegation</a>.</li>
</ul>
<p>But before we start let&#8217;s agree on the definitions:</p>
<h2>What is a <strong>JavaScript</strong> Widget?</h2>
<p>A <strong>JavaScript</strong> <a href="http://en.wikipedia.org/wiki/GUI_widget" title="Definition of Widget in Wikipedia">Widget</a> can be defined as any type of functionality that is loaded from an external site (<strong>widget provider</strong>), to different sites (<strong>publisher</strong>s) that include the widget code via a simple JavaScript include.</p>
<p>A <strong>JavaScript Widget</strong> may or may not include user interface components. An exmaple of a JavaScript Widget that does not contain a GUI counterpart is <a href="http://www.google.com/analytics/" title="google analytics">google analytics</a> code that most of us is familiar with. Examples for widgets that include GUI components are the &#8220;<strong>vote</strong>&#8220;, &#8220;<strong>share</strong>&#8220;, &#8220;<strong>like</strong>&#8220;, and &#8220;<strong>add comment</strong>&#8221; widgets of social networks such as <strong>twitter</strong> and <strong>Facebook</strong>.</p>
<p>During the article series we will use the terms <strong>publisher</strong> and <strong>widget provider</strong> frequently. So it&#8217;s important to understand the distinction: </p>
<blockquote><p>A <strong>widget provider</strong> is the source website where anyone can get a widget to their sites by adding a few lines of <strong>JavaScript</strong> that the <strong>provider</strong> provides (hence the name &#8220;<strong>provider</strong>&#8220;). </p>
<p>A <strong>publisher</strong> is a website that publishes these widgets (hence the name &#8220;<strong>publisher</strong>&#8220;) to enhance its functionality. The <strong>publish</strong> operation is nothing but simply adding the <strong>JavaScript</strong> snippets that the provider implements.</p></blockquote>
<h2>Stateful Widgets vs Stateless Widgets</h2>
<p>Just like a regular website a <strong>JavaScript Widget</strong> can have state information (i.e. persist user-specific data in a <strong>session</strong> object on the <strong>widget provider</strong> servers); or it can be <strong>stateless</strong>. A <strong>stateless</strong> widget does not store data in <strong>widget provider</strong>&#8216;s session.</p>
<blockquote><p>To have a stateful widget, you will need third-party cookie support; which is one of the many challenges listed below.</p></blockquote>
<h2>Challenges in <strong>JavaScript Widget</strong> Development</h2>
<p>There are many challenges one can face when developing a JavaScript Widget. The list below only covers the tip of the iceberg:</p>
<h3>Versioning can be a Hassle</h3>
<p>You need to define a consistent way to distribute different versions of your code to publishers. So that when you add a new functionality to your existing widget API, it does not break the working code on the publisher sites.</p>
<p>You have to enable different versions of your widget, so that you can introduce major changes in the newer versions of the API, and let publishers gradually upgrade their widgets at their convenience.</p>
<h3>You Don&#8217;t Own the Execution Environment</h3>
<blockquote><p>When you don&#8217;t own the <strong>DOM</strong>, really careful you should be.<br />
&#8211; <strong>Yoda</strong></p></blockquote>
<p>The environment that the widget will run is totally unknown to the <strong>widget provider</strong>. Worse, the <strong>widget provider</strong> has almost zero control over that environment.</p>
<blockquote><p>The execution environment can be a mobile device, a tablet, a power pc, a developer machine, an emulator or simulator, a really old browser&#8230; Our widget script has to run equally well in a wide spectrum of <strong>doctypes</strong>, <strong>platforms</strong>, and <strong>configurations</strong> (where some of these configurations can even be overridden by the user).</p></blockquote>
<p>Moreover the <strong>publisher</strong> may include your script inside <strong>head&#8230;/head</strong>, or at the middle of <strong>body</strong>, or just before <strong>/body</strong>. And the publisher may include the widget script multiple times either intentionally, or by mistake.</p>
<h3>Execution Environment is Shared</h3>
<blockquote><p>Developing a <strong>JavaScript Widget</strong> is like doing business in a public dorm, where the kitchen, bedroom and the bathroom is shared: &#8220;Anything&#8221; can happen.</p></blockquote>
<p>Not only you don&#8217;t own the execution environment, but you also share that environment with guys whom you have no idea where they come from.</p>
<p>Our beloved widget has to happily coexist with <strong>other widgets</strong>, <strong>user-defined scripts</strong>, and <strong>copy/pasted JavaScript snippets</strong> (most of which are a pile of &#8220;junk&#8221;). Some of these script may even override standard <strong>JavaScript</strong> objects and methods that you rely on.</p>
<p>Therefore our widget has to do its best to:</p>
<ul style="margin-top:-20px">
<li><a href="http://o2js.com/2011/04/24/the-module-pattern/" title="the Module Pattern">Keep the global namespace clean</a> and be a self-contained piece of code.</li>
<li>And try to protect itself from badly-written scripts that coexist with it. If not taken proper precautions, these scripts may adversley affect the behavior and performance of our widget.</li>
</ul>
<h3>Passing the <a href="http://o2js.com/2011/06/04/creating-a-mobile-javascript-chat-cross-domain-restrictions/" title="Cross Domain Restrictions">Cross Domain Boundary</a></h3>
<p>Since our widget is hosted on an external site, the good old <a href="http://en.wikipedia.org/wiki/Same_origin_policy" title="Same Origin Policy (Wikipedia)">cross domain restrictions</a> apply.</p>
<blockquote><p>We need to find ways to create a two-way <strong>communication channel</strong> between the publisher (www.publisher.com) site and the widget provider site (api.mywidget.com). We&#8217;ll explore different techniques to accomplish this in the followup articles.</p></blockquote>
<h3>Hack It Like A Thief: Act, but Don&#8217;t be Seen</h3>
<p>That&#8217;s a corollary to the &#8220;you don&#8217;t own the context&#8221; item above.</p>
<blockquote><p>Since you are a guest, <strong>behave like one</strong>.</p></blockquote>
<p>The less our widget changes how provider site works, the better. </p>
<p>And there are several things we can do to decrease the effect of our widget script on the publisher site:</p>
<ul style="margin-top:-30px">
<li>Use a <strong>single namespace</strong>;</li>
<li><strong>Prefix</strong> common classes, ids, and attributes;</li>
<li>Utilize <a href="http://www.stevesouders.com/blog/2012/01/13/javascript-performance/" title="JavaScript Performance Mania"><strong>async script includes</strong></a>;</li>
<li>use <a href="http://o2js.com/2011/04/29/javascript-best-practices/" title="A Library Maker's Guide to JavaScript"><strong>lazy loading</strong> patterns</a> to delay execution of code that will not be needed immediately.</li>
</ul>
<p>We&#8217;ll come to each and every single one of those items in the followup articles of this series.</p>
<h3>Problems With Persisting and Retieving State</h3>
<p>In a good old web application, the application state is persisted on the server in the <strong>Session</strong> object; and genrally <strong>&#8220;cookies&#8221;</strong> are used to pass a <strong>session ID</strong> around to share the session state while browsing different pages.</p>
<blockquote><p>Since our widget code lives in a different domain than the publisher site, the client <a href="http://www.ravelrumba.com/blog/third-party-cookies/" title="third party cookies">may impose restictions on saving cookies</a> as well. By the time of this writing, Safari browser, for instance, disables <strong>third party cookies</strong> by default.</p></blockquote>
<p>For our widget to share and persist state information with the widget api server we need to use <strong>third party cookies</strong>. And since we have no control over the environment our widget script executes (see above), our widget script may be executing in an environment where third-party cookie reading or writing may not be allowed.</p>
<p>There are ways to bypass this restriction too, which we&#8217;ll cover in the upcoming articles.</p>
<h2>What&#8217;s Next?</h2>
<p>That&#8217;s was a brief introduction on the things to watch out while architecting a <strong>JavaScript Widget</strong>. </p>
<p>We will explore everything mentioned in this post (and more) in the followup articles.</p>
<p>In the next of the series, we will be preparing our development environment. The interested may get their feet wet by <a href="http://nodejs.org/" title="node.js">starting to install node.js</a>.</p>
<p>&#8230;</p>
<p>Do you develop external widgets to be distributed to a variety of publisher websites?</p>
<p>I&#8217;d love to hear your experiences.</p>
<p>Feel free to share your ideas and suggestions as comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/07/05/javascript-widgets-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Now you can have o2.js as a node.js module and require it from npm too</title>
		<link>http://o2js.com/2012/06/28/o2-nodejs-module/</link>
		<comments>http://o2js.com/2012/06/28/o2-nodejs-module/#comments</comments>
		<pubDate>Thu, 28 Jun 2012 11:23:41 +0000</pubDate>
		<dc:creator>Volkan Özçelik</dc:creator>
				<category><![CDATA[o2.js Modules]]></category>
		<category><![CDATA[IISNode]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[npm]]></category>
		<category><![CDATA[o2.js]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://o2js.com/?p=2549</guid>
		<description><![CDATA[Unless you have been living in a cave for the recent two years, you should known that node.js is a highly efficient platform built on Chrome&#8217;s JavaScript runtime for easily building fast, scalable network applications, by using an event-driven, non-blocking I/O model. node.js is lightweight and efficient; perfect for data-intensive &#8230;]]></description>
				<content:encoded><![CDATA[<div id="attachment_2556" class="wp-caption alignleft" style="width: 241px"><a href="http://o2js.com/wp-content/uploads/2012/06/o2nodenpm1.png"><img src="http://o2js.com/wp-content/uploads/2012/06/o2nodenpm1.png" alt="o2.js + node.js + npm" title="o2.js + node.js + npm" width="231" height="210" class="size-full wp-image-2556" /></a><p class="wp-caption-text">o2.js + node.js + npm</p></div>
<blockquote><p>Unless you have been living in a cave for the recent two years, you should known that <a href="http://nodejs.org" title="node.js">node.js</a> is a <strong>highly efficient</strong> platform built on Chrome&#8217;s JavaScript runtime for easily building <strong>fast</strong>, <strong>scalable</strong> network applications, by using an <strong>event-driven</strong>, <strong>non-blocking</strong> I/O model. </p>
<p><strong>node.js</strong> is <strong>lightweight</strong> and <strong>efficient</strong>; perfect for data-intensive real-time applications that run across <strong>distributed</strong> devices.</p></blockquote>
<p>And if you are a regular reader of this blog, then you know about <a href="http://o2js.com/2012/05/17/jfdi-jedis-feel-doin-it/" title="Jedis Feel Doin' It">the <strong>#JFDI</strong> movement</a>, and its successor project <a href="http://github.com/v0lkan/sarmal" title="sarmal on github"><strong>sarmal</strong> (on github)</a>.</p>
<blockquote><p><a href="http://github.com/v0lkan/sarmal" title="sarmal on github">sarmal</a> is an MIT-licensed web project that uses Microsoft <strong>IIS</strong> and <a href="http://nodejs.org" title="node.js">node.js</a>. It&#8217;s doing it the Jedi way in the evil empire <strong> <img src='http://o2js.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></p></blockquote>
<h2>Why Export <strong>o2.js</strong> as a <strong>node.js</strong> module?</h2>
<blockquote><p><strong>o2.js</strong> has helpful <strong>functional</strong> programming, <strong>string</strong> manipulation, and <strong>collection</strong> manipulation methods, and a <strong>unit testing</strong> library. Thus, exporting it to as an <strong>npm</strong> module may be useful to the <strong>node.js</strong> community.</p></blockquote>
<p>And since the <strong>sarmal</strong> uses <strong>node.js</strong>, I thought it&#8217;d be cool to export <strong>o2.js</strong> as a <strong>node.js</strong> module. Then I could be able to use it on the server-side components of <strong>sarmal</strong>.</p>
<p>Let&#8217;s step by step analyze this <strong>node.js</strong> module creation process; how to modify <strong>o2.js</strong> to be exported as a <strong>node.js</strong> module, and how to publish it to the <a href="http://search.npmjs.org/#/o2" title="o2 on the npm registry"><strong>npm</strong> registry</a>:</p>
<h2>Install <strong>npm</strong></h2>
<p><strong>npm</strong> stands for <strong>node package manager</strong>. It is the de-facto package manager for <strong>node.js</strong> modules.</p>
<p>The first thing we&#8217;ll need is to install npm. The easiest way to do it is to <a href="http://nodejs.org/#download" title="Download and Install node.js">install node.js</a>, because <strong>npm</strong> comes automatically with <strong>node.js</strong>.</p>
<h2>Add A User</h2>
<p>After installing npm, we&#8217;ll need to add a user with <strong>npm adduser</strong> command.</p>
<pre class="brush: text">
Volkans-MacBook-Pro:o2.js volkanozcelik$ npm adduser
Username: (volkan) 
Email: (volkan@o2js.com) 
</pre>
<h2>Create a Package Descriptor (<em>package.json</em>)</h2>
<p>Then to publish our package to the <strong>npm</strong> registry, we&#8217;ll need to describe the package meta data in <strong>package.json</strong>:</p>
<p>The <strong>package.json</strong> is the meta descriptor of our <strong>node.js</strong> module.</p>
<p>Here&#8217;s the <strong>package.json</strong> we&#8217;ll be using for <strong>o2.js</strong>:</p>
<pre class="brush: javascript">
{
    &quot;name&quot;         : &quot;o2&quot;,
    &quot;version&quot;      : &quot;0.25.8&quot;,
    &quot;author&quot;       : &quot;Volkan Özçelik &lt;volkan@o2js.com&gt;&quot;,
    &quot;description&quot;  : &quot;Node.js module export for o2.js JavaScript Framework&quot;,
    &quot;preferGlobal&quot; : &quot;true&quot;,
    &quot;main&quot;         : &quot;./o2.js/index.js&quot;,
    &quot;keywords&quot; : [
        &quot;o2.js&quot;,
        &quot;collection&quot;,
        &quot;array&quot;,
        &quot;ajax&quot;,
        &quot;functional&quot;,
        &quot;string&quot;,
        &quot;unit test&quot;,
        &quot;validation&quot;,
        &quot;helper&quot;
    ],
    &quot;repository&quot; : {
        &quot;type&quot; : &quot;git&quot;,
        &quot;url&quot;  : &quot;https://github.com/v0lkan/o2.js.git&quot;
    },
    &quot;license&quot; : &quot;MIT&quot;,
    &quot;engines&quot; : { &quot;node&quot;: &quot;*&quot; }
}
</pre>
<p>You can see the most up-to-date version of o2.js <strong>package.json</strong> <a href="https://github.com/v0lkan/o2.js/blob/master/package.json" title="o2.js package.json at github">at github</a>.</p>
<blockquote><p>One important thing give special care is the <strong>version number</strong>. Ideally, any change in the minor version (<em>i.e. 0.25.8 to 0.25.9</em>) should be non-breaking; and any change in the major version (<em>i.e. 0.25.8 to 0.26.0</em>) will be breaking.</p></blockquote>
<p>The <strong>package.json</strong> can have many other fields, which are <a href="http://package.json.jit.su/" title="sample package.json with annotation">annotated in package.json.jit.su</a>.</p>
<h2>Merge Script</h2>
<p>The next thing is to write a simple shell script to merge <strong>o2.js</strong> modules into a single file to be exported (which will be the <strong>./o2.js/index.js</strong> we see in the package descriptor).</p>
<pre class="brush: text">
# batch/node_export.sh
#
# o2.js NodeJS Export Script.
# Exports entire o2.js to o2.js/index.js, as a NodeJS Module, by properly
# ordering and merging the files.

echo &#039;Starting node.js export...&#039;

cat \
../o2.js/o2.nodejs.header.js \
../o2.js/o2.meta.js \
../o2.js/o2.core.js \
../o2.js/o2.string.core.js \
../o2.js/o2.string.encode.js \
../o2.js/o2.string.strip.js \
../o2.js/o2.string.transform.js \
../o2.js/o2.event.constants.js \
../o2.js/o2.event.core.js \
../o2.js/o2.event.extend.js \
../o2.js/o2.ajax.core.js \
../o2.js/o2.ajax.extend.js \
../o2.js/o2.ajaxstate.core.js \
../o2.js/o2.ajaxcontroller.core.js \
../o2.js/o2.validation.core.js \
../o2.js/o2.validation.regexp.js \
../o2.js/o2.method.core.js \
../o2.js/o2.method.event.js \
../o2.js/o2.method.inherit.js \
../o2.js/o2.method.repeat.js \
../o2.js/o2.method.timer.js \
../o2.js/o2.method.transpose.js \
../o2.js/o2.collection.core.js \
../o2.js/o2.convert.core.js \
../o2.js/o2.cookie.core.js \
../o2.js/o2.date.core.js \
../o2.js/o2.debugger.core.js \
../o2.js/o2.dom.class.js \
../o2.js/o2.dom.collide.js \
../o2.js/o2.dom.constants.js \
../o2.js/o2.dom.coordinate.js \
../o2.js/o2.dom.core.js \
../o2.js/o2.dom.style.js \
../o2.js/o2.dom.dimension.js \
../o2.js/o2.dom.form.js \
../o2.js/o2.dom.load.js \
../o2.js/o2.dom.modify.js \
../o2.js/o2.dom.ready.js \
../o2.js/o2.dom.scroll.js \
../o2.js/o2.dom.traverse.js \
../o2.js/o2.effect.core.js \
../o2.js/o2.object.core.js \
../o2.js/o2.jsonpstate.core.js \
../o2.js/o2.jsonpcontroller.core.js \
../o2.js/o2.jsonp.core.js \
../o2.js/o2.querystring.core.js \
../o2.js/o2.sortdelegate.core.js \
../o2.js/o2.supports.core.js \
../o2.js/o2.template.core.js \
../o2.js/o2.timer.core.js \
../o2.js/o2.try.core.js \
../o2.js/o2.unit.core.js \
../o2.js/o2.nodejs.footer.js \
&gt; ../o2.js/index.js

echo &#039;Completed node.js export.&#039;
</pre>
<p>There are two files that draw immediate attention <strong>o2.node.js.header.js</strong> and <strong>o2.nodejs.footer.js</strong>. These files are not a part of <strong>o2.js Framework</strong>. They are helper files to help export <strong>o2.js</strong> classes to the <strong>node.js</strong> runtime.</p>
<h2>o2.node.header.js</h2>
<p>Since <strong>node.js</strong> runtime does not have <strong>DOM</strong> objects and methods, we create a very basic <strong>DOM</strong> mockup in <strong>o2.node.header.js</strong> to make the framework function properly:</p>
<pre class="brush: javascript">
if (!document) {
    var document = {
        getElementsByName      : function() {},
        createElement          : function() {},
        createTextNode         : function() {},
        createDocumentFragment : function() {},
        getElementsByTagName   : function() {},
        styleSheets            : []
    };

    this.document      = document;
    this.setTimeout    = setTimeout;
    this.setInterval   = setInterval;
    this.clearTimeout  = clearTimeout;
    this.clearInterval = clearInterval;
    this.escape        = escape;
    this.navigator     = {
        userAgent : &#039;o2.js DOM Mockup for Node.JS&#039;
    }
    this.self          = {};
    this.Image         = {};
    this.scrollTo      = function() {};
    this.location      = {};
}
</pre>
<p>When we are using <strong>o2.js</strong> in a browser environment the global <strong>this</strong> reference will refer to the <strong>window</strong> object; and <strong>document</strong> will be an alias to <strong>window.document</strong>. However inside a <strong>node.js</strong> module there&#8217;s neither <strong>window</strong>, nor <strong>document</strong>. We&#8217;ll need to fake them, so that <strong>o2.js</strong> self-consistency checking mechanism does not to throw errors.</p>
<blockquote><p>This may even be the starting point of a <strong>node.js DOM mockup module</strong>.</p></blockquote>
<h2>o2.nodejs.footer.js</h2>
<p>And the <strong>o2.nodejs.footer.js</strong> simply consists of one line that exports the entire <strong>o2</strong> namespace:</p>
<pre class="brush: javascript">
exports.o2 = this.o2;
</pre>
<blockquote><p>Without this <strong>exports</strong> statement, <strong>o2</strong> will not be available to the consumers of this module.</p></blockquote>
<p>After running <strong>batch/node_export.sh</strong> our module will be ready to be published to the <a href="http://search.npmjs.org/#/o2" title="npm registry"><strong>npm</strong> registry</a>.</p>
<h2>Publish the Module to <strong>npm</strong></h2>
<p>To publish our package to the <a href="http://search.npmjs.org/#/o2" title="npm registry"><strong>npm</strong> registry</a> we simply execute <strong>npm publish</strong> from the project root (where we the <strong>package.json</strong> file is located as well).</p>
<p>A typical output will be as follows:</p>
<pre class="brush: text">
Volkans-MacBook-Pro:o2.js volkanozcelik$ npm publish
npm http 200 https://registry.npmjs.org/o2/-/o2-0.25.8.tgz/-rev/16-6c390d4126b7a1898094568951e899ab
- o2@0.25.8
npm http PUT https://registry.npmjs.org/o2
npm http 409 https://registry.npmjs.org/o2
npm http GET https://registry.npmjs.org/o2
npm http 200 https://registry.npmjs.org/o2
npm http PUT https://registry.npmjs.org/o2/0.25.8/-tag/latest
npm http 201 https://registry.npmjs.org/o2/0.25.8/-tag/latest
npm http GET https://registry.npmjs.org/o2
npm http 200 https://registry.npmjs.org/o2
npm http PUT https://registry.npmjs.org/o2/-/o2-0.25.8.tgz/-rev/18-e4db0577a9ff287373344943a58c2587
npm http 201 https://registry.npmjs.org/o2/-/o2-0.25.8.tgz/-rev/18-e4db0577a9ff287373344943a58c2587
+ o2@0.25.8
</pre>
<p>This will make <strong>o2.js</strong> <a href="http://search.npmjs.org/#/o2" title="o2.js on npm registry">available on the <strong>npm</strong> registry</a></p>
<div id="attachment_2559" class="wp-caption alignleft" style="width: 552px"><a href="http://o2js.com/wp-content/uploads/2012/06/o2npmsrc.png"><img src="http://o2js.com/wp-content/uploads/2012/06/o2npmsrc.png" alt="o2.js on npm registry" title="o2.js on npm registry" width="542" height="312" class="size-full wp-image-2559" /></a><p class="wp-caption-text">o2.js on npm registry</p></div>
<div style="clear:both"></div>
<p>You can also search npm registry from the command line:</p>
<pre class="brush: text">
Volkans-MacBook-Pro:o2.js volkanozcelik$ npm search o2.js
NAME DESCRIPTION                                           AUTHOR   DATE              KEYWORDS
o2  Node.js module export for o2.js JavaScript Framework  =volkan  2012-06-27 22:42  o2.js collection array ajax functional string u
npm http GET https://registry.npmjs.org/-/all/since?stale=update_after&amp;startkey=1340838514000
</pre>
<h2>Use <strong>o2.js</strong> as a <strong>node.js</strong> Module</h2>
<p>To use<strong> o2.js</strong> inside our <strong>node.js</strong> application we&#8217;ll need to install it first:</p>
<pre class="brush: text">
Volkans-MacBook-Pro:~ volkanozcelik$ npm install o2
npm http GET https://registry.npmjs.org/o2
npm http 200 https://registry.npmjs.org/o2
npm WARN prefer global o2@0.25.8 should be installed with -g
o2@0.25.8 ./node_modules/o2
</pre>
<p>And to use <strong>o2.js</strong> in our <strong>node.js</strong> application, we&#8217;ll need to require it first.<br />
Here&#8217;s a very basic example that does <strong>String</strong> formatting:</p>
<pre class="brush: javascript">
var o2 = require(&#039;o2&#039;).o2;

var stuff = o2.String.format(&#039;Hello {0}!&#039;, &#039;Universe&#039;);

// stuff will be &#039;Hello Universe!&#039;
</pre>
<h2>Summary</h2>
<p>In this short tutorial we&#8217;ve seen that it&#8217;s really easy to create a <strong>node.js</strong> module out of a JavaScript framework;<br />
We&#8217;ve seen how to <strong>install npm</strong>;<br />
We&#8217;ve also seen that it&#8217;s really easy to <strong>publish</strong> our newly created <strong>node.js</strong> module to the <strong>npm registry</strong>;<br />
We&#8217;ve also briefly looked at how to search the nmp registry either from <strong>search.nmpjs.org</strong> or from the command line;<br />
And then how to install and use a node.js module from the nmp registry.</p>
<blockquote><p>Although this tutorial was mainly focused on <strong>o2.js</strong>, you can use it as a starting point to export your own libraries as node.js modules.</p></blockquote>
<p>Was it helpful?</p>
<p>Feel free to share your ideas and suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://o2js.com/2012/06/28/o2-nodejs-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
