<?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>sambroblog. &#187; Web</title>
	<atom:link href="http://sambro.is-super-awesome.com/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://sambro.is-super-awesome.com</link>
	<description>A Blog. With words. And maybe pictures.</description>
	<lastBuildDate>Wed, 01 Feb 2012 10:42:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>No.de coupon</title>
		<link>http://sambro.is-super-awesome.com/2011/03/05/no-de-coupon/</link>
		<comments>http://sambro.is-super-awesome.com/2011/03/05/no-de-coupon/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 00:36:25 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[No.de]]></category>
		<category><![CDATA[Node]]></category>
		<category><![CDATA[SSJS]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=177</guid>
		<description><![CDATA[Huzzah! Got my no.de coupon in the mail a couple of days ago. Now I just gotta figure out what I wanna host at http://sammeh.no.de/....]]></description>
			<content:encoded><![CDATA[<p>Huzzah!</p>
<p>Got my no.de coupon in the mail a couple of days ago.</p>
<p>Now I just gotta figure out what I wanna host at <a href="http://sammeh.no.de/">http://sammeh.no.de/</a>....</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2011/03/05/no-de-coupon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Platform updates &#8211; w00t!</title>
		<link>http://sambro.is-super-awesome.com/2010/08/30/facebook-platform-updates-w00t/</link>
		<comments>http://sambro.is-super-awesome.com/2010/08/30/facebook-platform-updates-w00t/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 03:44:30 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Facebook Development]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook platform]]></category>
		<category><![CDATA[fbjs]]></category>
		<category><![CDATA[fbml]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=155</guid>
		<description><![CDATA[According to this blog post over at developers.facebook.com, some exciting changes are coming to the Facebook Platform. I'm a little slow on the uptake here, the blog update I'm referring to is now 10 days old. I haven't been in the Facebook dev world of late, so I hope you'll forgive me for regurgitating old [...]]]></description>
			<content:encoded><![CDATA[<p>According to <a href="http://developers.facebook.com/blog/post/402">this blog post</a> over at developers.facebook.com, some exciting changes are coming to the Facebook Platform.</p>
<p>I'm a little slow on the uptake here, the blog update I'm referring to is now 10 days old. I haven't been in the Facebook dev world of late, so I hope you'll forgive me for regurgitating old news.</p>
<p>The big update for me is in the 4th paragraph:</p>
<blockquote><p>
We are also moving toward IFrames instead of FBML for both canvas applications and Page tabs. As a part of this process, we will be standardizing on a small set of core FBML tags that will work with both applications on Facebook and external Web pages via our JavaScript SDK, effectively eliminating the technical difference between developing an application on and off Facebook.com.
</p></blockquote>
<p>This is excellent! I have actually been holding my breath for something like this for a while now. The restriction of FBML only content for tabs has been extremely restrictive, here are a handful of reasons why:</p>
<ul>
<li><strong>Very strict HTML parsing</strong> - because the Platform was rendering tabs inline previously, it of course had to be VERY careful in how it handled offsite data, to protect users from all manner of scams/attacks. Now full flexibility is available because your iFrame is yours to control.</li>
<li><strong>Insanely strict JS parsing</strong> - same as first point, application tabs could only leverage basic Javascript and the unwieldy, poorly documented FBJS (Facebook Javascript). Now, you're free to access manipulate your IFrame document/window objects, DOM manipulate, include third party JS libs, etc, all to your hearts content.</li>
<li><strong>Embedded media was a pain</strong> - Granted, the tab FBML *did* allow you to embed Flash and AIR apps etc, but there were countless threads on the forum outlining issues they were having interacting with the host page, etc.</li>
<li><b>Tab activation policies</b> - There were some extremely frustrating rules with the way tabs were allowed to be "activated". No JS/FBJS was allowed to execute until the user had interacted with the tab in some manner, such as focusing a form element or clicking somewhere. This made it very cumbersome to implement any meaningful interactions with the user; alot of obnoxious boilerplate code had to be written for various ways in which you may actually start doing anything meaningful from JS, like AJAX requests.</li>
<li><b>... and lots more</b> Everything from CSS parsing to the occasional time where the tab would just sit in an endless loading display when clicked. When I was writing a tab page I remember bashing my head against the wall trying to get some content to sit nicely in a cross browser fashion... it would have been easy under normal circumstances, but the Platform tab flavour was refusing to accept the *display: inline IE hack in the CSS. Joy.</li>
</ul>
<p>This is going to really open up some great possibilities for interactive, rich web applications. I really cannot wait for this feature to be rolled out.</p>
<p>This news does come with some disappointment however; the sixth paragraph on the developers blog states the following:</p>
<blockquote><p>Finally, due to low usage rates, we will remove application tabs from user profiles in the next couple months. Application tabs will continue to be supported on Facebook Pages.</p></blockquote>
<p>There are plenty of great use cases to have application tabs on a user profile page. My personal Facebook profile has a tab that displays my latest last.fm scrobbles, my latest blog posts, etc. Personally, I believe that if the adoption rate for user profile tabs is low, the Facebook team should be coming up with ways to increase user acceptance of this feature, rather than removing it all together. Besides, the functionality in Facebook Page tabs is pretty much identical to the user profile equivalents... Why not support both?</p>
<p>There's other goodies in the developer blog update too, such as <a href="http://developers.facebook.com/roadmap/deprecations">cleaning up the REST API</a> considerably.</p>
<p>All in all, exciting changes coming to the Facebook platform in the coming months!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/08/30/facebook-platform-updates-w00t/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring Roo</title>
		<link>http://sambro.is-super-awesome.com/2010/06/03/spring-roo/</link>
		<comments>http://sambro.is-super-awesome.com/2010/06/03/spring-roo/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 06:01:27 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[spring roo]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=149</guid>
		<description><![CDATA[So I stumbled across Spring Roo a couple of times recently and haven't really looked into it much. I finally decided to do a little bit of reading on it, starting here. It seems like a pretty fascinating tool, providing intelligent tools to help develop an application without layering any actual IDE requirements, runtime libraries, [...]]]></description>
			<content:encoded><![CDATA[<p>So I stumbled across Spring Roo a couple of times recently and haven't really looked into it much. I finally decided to do a little bit of reading on it, starting <a href="http://static.springsource.org/spring-roo/reference/html/intro.html#intro-what-is-roo">here</a>. It seems like a pretty fascinating tool, providing intelligent tools to help develop an application without layering any actual IDE requirements, runtime libraries, bloated annotation models into the mix. I'm also especially interested to see exactly how this works in practice with Google Web Toolkit, as it could provide a very powerful framework to develop rich web client functionality and robust backend datastore+business logic facades very rapidly.</p>
<p>When I get a bit of time soon I'm definitely gonna check this out further and post more thoughts on it.</p>
<p><a href="http://www.springsource.org/roo/learn">Spring Roo</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/06/03/spring-roo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gotcha: Removing iframe border in IE.</title>
		<link>http://sambro.is-super-awesome.com/2010/06/01/gotcha-removing-border-in-ie/</link>
		<comments>http://sambro.is-super-awesome.com/2010/06/01/gotcha-removing-border-in-ie/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 02:22:54 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[border]]></category>
		<category><![CDATA[frameborder]]></category>
		<category><![CDATA[gotcha]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[ie6 sucks]]></category>
		<category><![CDATA[iframe]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=144</guid>
		<description><![CDATA[Think I'm gonna start a little mini-series of blog posts with the little "gotchas" I run into during the course of an ordinary day at work. Some of the pitfalls I've run into lately have been ridiculous. Bloody IE! Todays one is a fun one. Removing a frameborder on an iframe in Internet Explorer is [...]]]></description>
			<content:encoded><![CDATA[<p>Think I'm gonna start a little mini-series of blog posts with the little "gotchas" I run into during the course of an ordinary day at work. Some of the pitfalls I've run into lately have been ridiculous. Bloody IE!</p>
<p>Todays one is a fun one. Removing a frameborder on an iframe in Internet Explorer is case-sensitive, would you believe it!</p>
<p>That is to say:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;iframe frameborder=&quot;0&quot; src=&quot;http://www.google.com.au/&quot;&gt;&lt;/iframe&gt;
</pre>
<p>.. Probably won't work. Whereas:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;iframe frameBorder=&quot;0&quot; src=&quot;http://www.google.com.au/&quot;&gt;&lt;/iframe&gt;
</pre>
<p>Will!</p>
<p>This also extends to creating an iframe using DOM. You need to do this:<br />
Think I'm gonna start a little mini-series of blog posts with the little "gotchas" I run into during the course of an ordinary day at work. Some of the pitfalls I've run into lately have been ridiculous. Bloody IE!</p>
<p>Todays one is a fun one. Removing a frameborder on an iframe in Internet Explorer is case-sensitive, would you believe it!</p>
<p>That is to say:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
myIframeEl.setAttribute(&quot;frameborder&quot;, &quot;0&quot;);
</pre>
<p>Is not going to work in IE.</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
myIframeEl.setAttribute(&quot;frameBorder&quot;, &quot;0&quot;);
</pre>
<p>But this will.</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/06/01/gotcha-removing-border-in-ie/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fixed-height container/variable-height content Vertical Alignment using CSS</title>
		<link>http://sambro.is-super-awesome.com/2010/05/13/fixed-height-containervariable-height-content-vertical-alignment-using-css/</link>
		<comments>http://sambro.is-super-awesome.com/2010/05/13/fixed-height-containervariable-height-content-vertical-alignment-using-css/#comments</comments>
		<pubDate>Thu, 13 May 2010 00:38:55 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[cross browser]]></category>
		<category><![CDATA[iesucks]]></category>
		<category><![CDATA[standards compliant]]></category>
		<category><![CDATA[vertical alignment]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=104</guid>
		<description><![CDATA[Whew. The title is a bit long-winded eh? This short blog post highlights how to vertically center variable-height block-level content inside a fixed height container, in a cross-browser, (mostly) standards compliant manner. I've lost count of how many times I've needed to do this. Seriously. For example, you may have a block of text, or [...]]]></description>
			<content:encoded><![CDATA[<p>Whew. The title is a bit long-winded eh?</p>
<p>This short blog post highlights how to vertically center variable-height block-level content inside a fixed height container, in a cross-browser, (mostly) standards compliant manner.</p>
<p>I've lost count of how many times I've needed to do this. Seriously. For example, you may have a block of text, or an image or two that need to sit nicely in a container you've allocated for it. For quite a while now, all standards-compliant browsers have had support for the <strong>display: table</strong> CSS declaration, which makes vertical alignment a snap. Unfortunately though, Internet Explorer is way behind in the game, with both IE6+7 not supporting this declaration. There is hope however!</p>
<p>I have stumbled across the following page a few times now, it's the best resource I've found on how to overcome this problem.</p>
<p><a href="http://www.jakpsatweb.cz/css/css-vertical-center-solution.html">http://www.jakpsatweb.cz/css/css-vertical-center-solution.html</a></p>
<p>I've adapted this solution into a set of 2 CSS files that I now use when I need to vertically center something.</p>
<p><strong>valign.css</strong></p>
<pre class="brush: css; title: ; notranslate">
div.valignContainer {
	display: table;
	overflow: hidden;
}

div.valignMiddle {
	display: table-cell;
	vertical-align: middle;
}
</pre>
<p><strong>valign_ie.css</strong></p>
<pre class="brush: css; title: ; notranslate">
div.valignContainer {
	position: relative;
}

div.valignMiddle {
	position: absolute;
	top: 50%;
}

div.valignInner {
	position: relative;
	top: -50%;
}
</pre>
<p>Include it in the page like so:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;link rel=&quot;stylesheet&quot; href=&quot;valign.css&quot; type=&quot;text/css&quot;/&gt;
&lt;!--[if lte IE 7]&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;valign_ie.css&quot; type=&quot;text/css&quot;/&gt;
&lt;![endif]--&gt;
</pre>
<p>To use this solution, let's say you currently had markup like so:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;div id=&quot;myContainerThatSpecifiesAppearanceAndDimensions&quot;&gt;
  &lt;div id=&quot;myContentThatNeedsTobeVerticallyCentered&quot;&gt;
    Content that should be vertically centered!
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>You would change it to the following:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;div id=&quot;myContainerThatSpecifiesAppearanceAndDimensions&quot; class=&quot;valignContainer&quot;&gt;
  &lt;div class=&quot;valignMiddle&quot;&gt;
    &lt;div id=&quot;myContentThatNeedsTobeVerticallyCentered&quot; class=&quot;valignInner&quot;&gt;
      Content that should be vertically centered!
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>That's all, folks!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/05/13/fixed-height-containervariable-height-content-vertical-alignment-using-css/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 9&#8230;. wow?</title>
		<link>http://sambro.is-super-awesome.com/2010/03/31/internet-explorer-9-wow/</link>
		<comments>http://sambro.is-super-awesome.com/2010/03/31/internet-explorer-9-wow/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 12:27:35 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=93</guid>
		<description><![CDATA[Okay, so you'll never make a IE convert out of me. I think I speak for the web developer community as a whole when I give Internet Explorer and Microsoft a great big middle finger salute. HOWEVER! After downloading the Internet Explorer 9 Platform Preview, I got the shock of my life. An Internet Explorer [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, so you'll never make a IE convert out of me. I think I speak for the web developer community as a whole when I give Internet Explorer and Microsoft a great big middle finger salute.</p>
<p>HOWEVER! After downloading the <a href="http://ie.microsoft.com/testdrive/">Internet Explorer 9 Platform Preview</a>, I got the shock of my life. An Internet Explorer that is taking a DECENT effort in supporting web standards that are almost as old as myself?! Could this be?!</p>
<p>Seriously, their new SVG implementation is amazing. HTML5 support. Hardware accelerated Javascript processing and DOM rendering. CSS3? BORDER-RADIUS SUPPORT?! This is certainly not the Internet Explorer I've come to love to hate.</p>
<p>Of course, I can easily dismiss all of this with the simple statement "5 f*****g years too late, chump". However I can't bring myself to do so, when I am continually reminded of the fact that this family of browsers still makes up a stupid amount of the market today. Yes, IE share is slipping, but I truly wonder if we'll ever see that glorious day where IE drops below 40-50% market share. If the migration of standard consumer PCs ensures that we see a good portion of users running on IE9 rather than the joke we've come to call IE7, or the slightly less humerous joke we've come to call IE8 ... well, that's certainly the lesser of two evils isn't it?</p>
<p>Unfortunately, from what I've read, IE9 probably won't be around for another year or so. So in the meantime, I'll continue to burn baby animals on the IE altar, hoping the gods of Microsoft will hear my pleas for my mortal webapplication to function correctly in their worthless POS software (I ain't talking about no point of sale here either).</p>
<p>Hopefully in that time they'll improve their laughable ACID3 score. Then again, maybe not. Best not to make people too happy, might start putting their faith in you or something ...</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/03/31/internet-explorer-9-wow/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to access Facebook API from Chrome Extension</title>
		<link>http://sambro.is-super-awesome.com/2010/03/10/how-to-access-facebook-api-from-chrome-extension/</link>
		<comments>http://sambro.is-super-awesome.com/2010/03/10/how-to-access-facebook-api-from-chrome-extension/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 02:58:20 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Chrome Extension Development]]></category>
		<category><![CDATA[Facebook Development]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=79</guid>
		<description><![CDATA[So following on from my previous post, I decided I wanted to try two new things at once: Facebook API and a foray into developing a Google Chrome extension. With the notification API that will (hopefully) twig on in other major browsers, I'm writing an extension that will display a desktop notification when a Facebook [...]]]></description>
			<content:encoded><![CDATA[<p>So following on from my previous post, I decided I wanted to try two new things at once: Facebook API and a foray into developing a Google Chrome extension. With the notification API that will (hopefully) twig on in other major browsers, I'm writing an extension that will display a desktop notification when a Facebook notification is received. All that will be required is for Chrome to be running.</p>
<p>Step 1 was to play around with Chrome extensions. I haven't worked with plugins/extensions in any other browser, but I have to say.... Google NAILED this. It's so intuitive and straightforward. So easy to debug, so much power. I love you Google.</p>
<p>Anyway. Step 2 was where things got interesting - connecting to Facebook via the <a href="http://wiki.developers.facebook.com/index.php/JavaScript_Client_Library">Javascript API</a> and <a href="http://wiki.developers.facebook.com/index.php/Facebook_Connect">Facebook Connect</a>. This proved to be quite complex. Facebook Connect has this fascination with the whole <a href="http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel">cross domain communication channel</a> (XD for shortness) nonsense. Basically, this requirements essentially means to use the Javascript API you need to be hosting it on a standard web server to be able to add the xd_receiver.html file in a public-facing area where Facebook can see it.</p>
<p>After digging around the site for a while, I came across their fancy new <a href="http://wiki.developers.facebook.com/index.php/JavaScript_SDK_(Open_Source)">Open Source Javascript SDK</a>, I couldn't help but notice this didn't make a mention of the XD setup anywhere, so I assumed perhaps I might be able to work with this system better. As it happens, my suspicions were correct. The new JS library has some crazy voodoo magic set up so that an XD file isn't required, there's some kind of "XD proxy" running on the Facebook servers which will send login session data along the line to the JS library, using either <a href="https://developer.mozilla.org/en/DOM/window.postMessage">document.postMessage</a> or some Flash workaround thingy (not really sure how that works, don't particularly care.)</p>
<p>I immediately tried to use it in a Chrome extension, but alas! There was a few issues. I came up with workarounds for both though.</p>
<p><strong>Issue #1</strong> - the API does the following in the constructor:</p>
<p><code><br />
 _domain: {<br />
      api : window.location.protocol + '//api.facebook.com/',<br />
      cdn : (window.location.protocol == 'https:'<br />
              ? 'https://s-static.ak.fbcdn.net/'<br />
              : 'http://static.ak.fbcdn.net/'),<br />
      www : window.location.protocol + '//www.facebook.com/'<br />
    },<br />
</code></p>
<p>Great! That would be fantastic if our chrome extension was running on http, but the protocol when running from options or background.html pages is "chrome-extension://". So when the API went to make with the server side communications, it was trying to remote to chrome-extension://api.facebook.com, which of course is not really gonna work.</p>
<p>My solution to this was to just fudge it by putting the following snippet in before using the FB lib anywhere:</p>
<p><code><br />
FB._domain = {<br />
      api : 'https://api.facebook.com/',<br />
      cdn : 'https://s-static.ak.fbcdn.net/',<br />
      www : 'https://www.facebook.com/'<br />
};<br />
</code></p>
<p>With that change, the API won't have any more tantrums when trying to phone home. Easy!</p>
<p><strong>Issue #2</strong> - Facebook Connect is still broken.</p>
<p>This one was the biggie. Essentially, even though the new API does some cool hocus pocus with XD, it's still referencing the "origin domain" in the request, this original domain is of course just going to be the extension URL, which is not terribly useful, as Facebook will freak out when it gets a request coming from an invalid URL. I tried fudging the origin to a valid domain (dodgy I know, I was getting desperate). Interestingly, Facebook was fine with this, but of course when the request came back to the browser and the XD proxy tries to postMessage() the session data back, the browser freaks out as it looks like an XSS attack.</p>
<p>There might be other ways around this drama, but I opted for what I feel to be a fairly elegant solution.</p>
<p>Essentially, I opted to "pretend" I'm something of a desktop application trying to authenticate with Facebook application (which is true in a sense, I suppose). This <a href="http://wiki.developers.facebook.com/index.php/Authorization_and_Authentication_for_Desktop_Applications">Developer Wiki page</a> gave me some insight into how to authenticate my application with the FB user  the old-fashioned way.</p>
<p>The idea is this: popup the login/app-authenticate page manually with a special URL, setting the return URL to a random dummy Facebook page they have running for desktop app clients: http://www.facebook.com/connect/login_success.html. When the user visits the login page, once they have logged in and allowed the app access (or if they are already logged in and have already allowed the app), they are redirected to a page that has the session data in the querystring encoded in JSON. Login achieved.</p>
<p>So I set about doing this in my extension, simple enough to start with:</p>
<p><code><br />
var win = window.open("http://www.facebook.com/login.php?api_key=<app key>&#038;connect_display=popup&#038;v=1.0&#038;next=http://www.facebook.com/connect/login_success.html&#038;cancel_url=http://www.facebook.com/connect/login_failure.html&#038;fbconnect=true&#038;return_session=true&#038;session_key_only=true", "fbconnect", "width=400,height=400");<br />
</code></p>
<p>Great! If I was a *real* desktop application and I was running a Webkit/IE/whatever browser instance as some kind of evil overlord, I could just detect when the browser redirects to login_sucess.html, grab the querystring, parse the session data out of it, and be on my merry way! I'm running in a browser though, so how about I just access the child window that I opened with window.open, access the location.search property and parse that? "NO", says the magical little pixies living inside the browser, "That would be against my strict Same Origin Policy (SOP, kinda like ... sop story, teehee)!!!".</p>
<p>Fair enough. There was an easy enough workaround though, I just embedded a <a href="http://code.google.com/chrome/extensions/content_scripts.html">content script</a> via the Extension to sniff out the session data when it became available, and send it to the main extension. Like so:</p>
<p>Add the trigger for the content script to the extension manifest.json file:</p>
<p><code><br />
  "content_scripts": [<br />
    {<br />
	"matches": ["http://www.facebook.com/connect/login_success.html*"],<br />
	"js": ["prototype.js", "intercept_session.js"]<br />
    }<br />
  ],<br />
</code></p>
<p>I threw prototype in there just for convenience sake, as you'll see in the next step.</p>
<p>Then intercept_session.js looks like this:</p>
<p><code>var params = window.location.search.toQueryParams();</p>
<p>if(!params.session) return;<br />
var session = JSON.parse(params.session);</p>
<p>chrome.extension.sendRequest({message: "setSession", session: session}, function() {<br />
  window.close();<br />
});</code></p>
<p>What this code does is parse the querystring (using Prototype), then check if the session data is present. If it is, parse the JSON into the session object and send it off to the extension <a href="http://code.google.com/chrome/extensions/background_pages.html">Background Page</a> via the extension <a href="http://code.google.com/chrome/extensions/messaging.html">message passing system</a> to be saved.</p>
<p>The background page simply has this:</p>
<p><code><br />
var session = null;<br />
if(localStorage.session)<br />
{<br />
  session = JSON.parse(localStorage.session);<br />
}</p>
<p>chrome.extension.onRequest.addListener(<br />
  function(request, sender, sendResponse) {<br />
    if(!request.message)<br />
      return;</p>
<p>    switch(request.message)<br />
    {<br />
      case "setSession":<br />
      {<br />
	localStorage.session = JSON.stringify(request.session);<br />
	session = request.session;<br />
	sendResponse();<br />
	break;<br />
      }<br />
      case "getSession":<br />
      {<br />
	sendResponse(session);<br />
	break;<br />
      }<br />
    }<br />
  });<br />
</code></p>
<p>Again, pretty straightforward stuff. I'm using the groovy new <a href="http://dev.w3.org/html5/webstorage/">HTML5 local storage</a> to remember the session data even if the browser is closed. The message handler simply listening for a session to be passed to it. When a session is provided, it will save it to local storage and a local variable. The getSession functionality is so other areas of your chrome extension can retrieve the session as needed (for example if you have a popup and want to query FB from there or something). You could obviously use this session anywhere as needed.</p>
<p>And that's that! From here you can make API calls to your hearts content. There's obviously some important things left out here, stale checking of the session when the background page loads up for example. Also, requesting <a href="http://wiki.developers.facebook.com/index.php/Extended_permissions">extended permissions</a> is not covered here, but it's pretty much the same as how the login deal works anyway. You would just update the login_success.html intercept script to check if this was a response for extended permissions, and check the querystring to ensure the permissions were supplied.</p>
<p>I've cooked up a quick little demonstration of this stuffs. Click <a href="http://sambro.is-super-awesome.com/Example Facebook API Extension.crx">here </a>to install a demo extension that will add a button to the right of your address bar, which will show some clickable icons of 5 of your friends in a popup. You can also see the code for this extension <a href="http://sambro.is-super-awesome.com/Example Facebook API Extension.zip">here</a>.</p>
<p>Time for me to go finish this extension!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/03/10/how-to-access-facebook-api-from-chrome-extension/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Shiny Desktop Notifications from Google Chrome</title>
		<link>http://sambro.is-super-awesome.com/2010/03/08/shiny-desktop-notifications-from-google-chrome/</link>
		<comments>http://sambro.is-super-awesome.com/2010/03/08/shiny-desktop-notifications-from-google-chrome/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 05:52:12 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=50</guid>
		<description><![CDATA[So I was dicking around in Google Calendar the other day, updating settings and trolling for any cool new Labs stuff to enable... Anyway, I made some changes and clicked submit. I was provided with the ol' yellow InfoBar that asked me for permission to allow something to ... blah blah blah. I was a [...]]]></description>
			<content:encoded><![CDATA[<p>So I was dicking around in Google Calendar the other day, updating settings and trolling for any cool new Labs stuff to enable... Anyway, I made some changes and clicked submit. I was provided with the ol' yellow InfoBar that asked me for permission to allow something to ... blah blah blah. I was a on a Google site and I have pretty much entrusted my soul to Google already - so I didn't bother reading it before clicking Allow.</p>
<p>Imagine my surprise when a sexy little desktop notification popped up in the bottom right of my screen! Intrigued, I did a bit of Googling, there's a <a href="http://lifehacker.com/5350238/google-chrome-to-feature-desktop-notifications">couple</a> of <a href="http://techcrunch.com/2009/09/01/chrome-is-gaining-desktop-notifications/">news</a> posts about it, but nothing substantial... other than the <a href="http://dev.chromium.org/developers/design-documents/desktop-notifications/api-specification">design doc</a> hosted on dev.chromium.org.</p>
<p>It's currently only available in the <a href="http://dev.chromium.org/getting-involved/dev-channel">developer channel</a> of Google Chrome. If you're running the dev channel, then check out the example below:</p>
<p><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"></script><br />
<script type="text/javascript" src="/wp-content/uploads/notifications.js"></script></p>
<style>
  #notifications,#notif_unsupported {
    border: 1px solid black;
    padding: 20px;
    text-align: center;
    background-color: rgb(150, 200, 150);
  }</p>
<p>#notif_unsupported {
    background-color: rgb(200, 150, 150);
  }
</style>
<div id="notif_unsupported" style="display: none;">
Your browser does not support Desktop Notifications.
</div>
<div id="notifications">
<div id="permNeeded" style="display: none;">
You need to grant permission to this site to display notifications. <a href="javascript:requestPermission();">Grant Now</a>
</div>
<div id="permDenied" style="display: none;">
Permission for this website to display notifications has been explicitly denied. Don't you love me? ;( <a href="javascript:checkPermission();">Recheck Permission</a>
</div>
<div id="permPending" style="display: none;">
Permission requested. Check your info bar (yellow bar at the top of the browser viewport).
</div>
<div id="notifActive" style="display: none;">
There is currently a notification active. <a href="javascript:cancelNotification();">Cancel</a>
</div>
<div id="manyNotifActive" style="display: none;">
There is currently <span id="numActiveNotifs"></span> notifications active.
</div>
<div id="timedNotifTimer" style="display: none;">
A notification will appear in <span id="notifTimer"></span> seconds. Go ahead and minimize or change tabs now.
</div>
<div id="control" style="display: none;">
Desktop Notifications active. <a href="javascript:showNotification();">Show Notification</a> | <a href="javascript:showManyNotifications();">Show Many Notifications</a> | <a href="javascript:showTimedNotification();">Show Timed Notification</a>
</div>
</div>
<p>For those interested, that code that powers this little example can be found <a href='http://sambro.is-super-awesome.com/wp-content/uploads/notifications.js'>here</a>.</p>
<p>Very cool stuff. There are so many places this would come in handy. Super Facebook notifications, anyone?</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2010/03/08/shiny-desktop-notifications-from-google-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE + AJAX == Caching???</title>
		<link>http://sambro.is-super-awesome.com/2009/10/22/ie-ajax-caching/</link>
		<comments>http://sambro.is-super-awesome.com/2009/10/22/ie-ajax-caching/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 01:20:56 +0000</pubDate>
		<dc:creator>sambro</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sambro.is-super-awesome.com/?p=17</guid>
		<description><![CDATA[So I'm finishing up a fairly straightforward web booking system for a firm I'm working for. Everything is just about done so of course the final (and much dreaded) task is to make sure everything looks pretty, and works! Numerous CSS hacks and several hot showers rocking back and forth with blood-shot eyes later .... [...]]]></description>
			<content:encoded><![CDATA[<p>So I'm finishing up a fairly straightforward web booking system for a firm I'm working for. Everything is just about done so of course the final (and much dreaded) task is to make sure everything looks pretty, and works! Numerous CSS hacks and several hot showers rocking back and forth with blood-shot eyes later .... I now have the site looking fairly consistent in all the major browsers.</p>
<p>The system also has some AJAX mixed in for good measure, with standard HTML fallbacks if the client-side code falls over (you know, 'cos I have little faith in myself ...). Internet explorer was giving me some bizarre results with these AJAX methods, so I went digging.</p>
<p>As it happens, it was the same ol' story, Internet Explorer aggressively caches practically anything it can. This isn't necessarily a bad thing, but as usual Firefox, Chrome, Safari etc don't exhibit the behaviour.</p>
<p>I have actually run into this issue in several other projects, the way I generally solved it was to just generate some "entropy" in the request URL querystring to ensure IE fetched the data properly each time. This time I Google'd and looked a little deeper.</p>
<p>As it happens, caching HTTP GET requests is actually considered the "right" thing to do, so Internet Explorer actually chose this time to stick to standards and shove it in the face of everyone else. Somewhat ironic, considering they seem to go out of their way to do the complete <strong>opposite</strong> most of the time.</p>
<p>The solution is to just make POST requests to your endpoint, it seems to eliminate any caching IE thinks it should be doing. This has been posted all over the net already of course, but I felt to reiterate it because it's such an obvious solution to a very frequent and frustrating issue!</p>
]]></content:encoded>
			<wfw:commentRss>http://sambro.is-super-awesome.com/2009/10/22/ie-ajax-caching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

