<?xml version="1.0" encoding="iso-8859-1" ?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
	<atom:link href="http://www.m0interactive.com/rss/articles.xml" rel="self" type="application/rss+xml" />
	<title>Mohamed Mansour | articles</title>
	<copyright>Copyright (c) 2006 Mohamed Mansour! Inc. All rights reserved.</copyright>
	<link>http://www.m0interactive.com/</link>
	<description>Mohamed Mansour RSS Feeds</description>
	<language>en-us</language> 
	<item>
		<title>Software - Introducing Proxy Anywhere Chrome Extension</title>
		<link>http://www.m0interactive.com/archives/2011/06/02/introducing_proxy_anywhere_chrome_extension.html</link>
		<description><![CDATA[<p>Do you want to connect to a proxy server while browsing? Proxy Anywhere is a simple HTML5 application that allows you enter a proxy server and will use that when visiting websites. Today Chrome has updated their Dev Channel to version 13. In this version, they have graduated the API from experimental to stable. That allowed developers to create native HTML5 extensions like this.</p>

<p>So if your in Canada and want to watch Hulu from USA, this is your chance to do it :) Head to the gallery to download <a href="https://chrome.google.com/webstore/detail/eejcbegfnjfjnmdikkplhbhnemddchbn">Proxy Anywhere Chrome Extension!</a> As always, the source code is open source at GitHub, fork and pull in your patches :) <a href="https://github.com/mohamedmansour/proxy-anywhere-extension">https://github.com/mohamedmansour/proxy-anywhere-extension</a> </p>

<p>Some screenshots!</p>
<img src="https://github.com/mohamedmansour/proxy-anywhere-extension/raw/master/screenshot/proxy_screenshot.png" />

<img src="https://github.com/mohamedmansour/proxy-anywhere-extension/raw/master/screenshot/proxy_screenshot_bypass.png" />
]]></description>
		<pubDate>Thu, 02 Jun 2011 00:15:59 -0400</pubDate>
		<guid>http://www.m0interactive.com/archives/2011/06/02/introducing_proxy_anywhere_chrome_extension.html</guid>
	</item>
	<item>
		<title>Software - Never use git-svn to convert your SVN repo to Git</title>
		<link>http://www.m0interactive.com/archives/2011/04/05/never_use_git_svn_to_convert_your_svn_repo_to_git.html</link>
		<description><![CDATA[<p>If you want to convert your SVN repository to Git, the first thing that you would try is the native built-in git-svn that comes with your distribution. Think twice when you use that approach on a 

1GB SVN repo with many branches and tags, it will take forever. It took around 8 hours for my repo. </p>

<h3>Problem with git-svn</h3>
<ul>
<li>Doesn't convert it as a bare repository, sure we can just look into .git folder.</li>
<li>It doens't respect the standard layout for tags and branches. You have to pass those values in.</li>
<li>Doesn't allow you to use an irregular layout. For example, it doesn't understand if you have two trunks, or folders in root. We have to just stick with trunk, branches, and tags. Nothing 

more.</li>
<li>It doesn't even understand what a tag is, it treats it as a branch. You have to create a script after its complete to manually tag those branches that should have originally been branches.</li>
<li>SLOW, flithy slow!</li>
</ul>

<h3>History</h3>
<p>I didn't give up finding a better way. Even though it worked, I kept on searching online for alternatives. 
Every single script and solution that users have created use git-svn. Where are you Google, you didn't help at all! I was more curious how the bigger organizations have done the conversion. First 

thing that came to my mind was KDE. I remembered KDE becuase I used gitolite before and they were on the list of adopters.</p>

<p>KDE is very old open source "true" project. When I mean "true", I mean, everything they do is in the public. I respect that in the highest level. Every feature they create, they communicate with 

the community. Every decision they make, the community is involved. Absolutely no corporate black box that is hiding how they do their project from the community, unlike many projects that I have 

seen. By saying these words, makes me super excited that I wanted to contribute to KDE. KDE converted their 64GB SVN repository in around 1 hour! I screamed in my mind when I heard that, 1 HOUR!!!! It 

took me around 10 hours to convert 1GB. Since they are open sourced, they documented every step along the way!

<h3>Native svn2git</h3>
<p>They called it, svn2git (the real one, too many fake clones out there that I tried and all use git-svn), and they have a nice wiki to explain how it is done <a 

href="http://techbase.kde.org/Projects/MoveToGit/UsingSvn2Git">http://techbase.kde.org/Projects/MoveToGit/UsingSvn2Git</a></p>

<p>It is a C++ Qt application that communicates directly to the SVN repository. It is super fast, when I mean super fast, I converted my 1GB SVN repository in a matter of minutes, under 5 minutes! 

From 10 hours to 5 minutes! This hidden tool is so powerful that it should really be known.</p>

<h3>How to use it</h3>
<p>In Red Hat Enterprise, it is a pain I had to modify some code to backport it to Qt 4.0. RHEL don't support Qt 4.7, they just support Qt 4.0 which is quite sad. But luckily, the code for svn2git was 

open source and beautiful! Easy to understand and easy to know where everythin is. It was my first time looking at Qt code, and to tell you the truth, it is beautiful!</p>

<p>Running it is pretty simple, all you have to do is: </p>
<pre>
qmake && make
./svn-all-fast-export --rules samples/standardlayout.rules ~/svn/
</pre>

<p>Within a few minutes, the whole SVN including their tags, branches, and trunk converted! git-svn didn't do that!</p>

<p>Yes, I am super happy, I can now create complext rules to convert my SVN repo to a multiple Git repos to make the organization better.</p>
]]></description>
		<pubDate>Tue, 05 Apr 2011 18:13:10 -0400</pubDate>
		<guid>http://www.m0interactive.com/archives/2011/04/05/never_use_git_svn_to_convert_your_svn_repo_to_git.html</guid>
	</item>
	<item>
		<title>Software - Chromium msysgit vs cygwin Git Performance</title>
		<link>http://www.m0interactive.com/archives/2011/03/12/chromium_msysgit_vs_cygwin_git_performance.html</link>
		<description><![CDATA[<p>I got really frustrated with the inconsistencies and problems arising with 
 Cygwins' Git support. The terminal goes haywire, awfully slow, and stuff just 
 didn't work as I wanted to unless I do some modifications. Yesterday, I 
 officially completed my set of patches to make msysgit function perfectly 
 (I hope) with Chromium! My frustration no longer exists!</p>

<h3>Some history</h3>
<p>Since the very beginning, Chromium was using SVN as its main repository, then
 around a year later some Chromium devs (Evan Martin and others) started to 
 support Git and used git-svn to commit back to Chromium repo. Msysgit wasn't
 performing well, it was causing too many problems with git-svn, since it wasn't
 fully supported. The tooling in Chromium is all done in Python to make it
 cross platform with Linux/Mac/Windows and its pretty great! Some parts of the
 code are just checking for cygwin explicitly causing msysgit not to work.
 After my frustration with cygwin, with Marc-Antoine's help, we fixed msysgit
 issues and eveything works well. Really well!</p>
 
<h3>Analysis</h3>
<p>To tell you the truth, on Windows, it feels snappier and less hassle to work
   on Chromiums source code with msysgit than cygwin. It feels faster and 
   natural. I was curious to see how well it improvement, and performed. So
   here are the averaged timings of 5 trials. Some pre info: </p>
<ul>
  <li>Windows 7 x64</li>
  <li>4GB RAM</li>
  <li>Secondary HD</li>
  <li>Latest Cygwin updates installed.</li>
  <li>Cygwin Git 1.7.4</li>
  <li>Msysgit Git 1.7.3.1</li>
</ul>

<img src="http://chart.apis.google.com/chart?chxl=1:|status|checkout|git-rm|commit|diff-master|2:|Lower+the+better+(seconds)&chxp=2,50&chxr=0,0,3|1,5,0&chxt=y,x,t&chbh=a,5&chs=460x240&cht=bvg&chco=4D89F9,FF0000&chds=0,2.5,0,2.5&chd=t:2.265,1.124,0.775,1.778,1.373|1.364,1.078,0.508,0.937,1.312&chdl=Cygwin|Msysgit&chg=-1,0,0,4&chma=5&chtt=Msysgit+vs+Cygwin+Real+Time" width="400" height="200" alt="Msysgit vs Cygwin Real Time"/>

<img src="http://chart.apis.google.com/chart?chxl=0:|status|checkout|git-rm|commit|diff-master|1:|Lower+the+better+(seconds)&chxp=1,50&chxr=0,0,3|2,0,2.5&chxt=x,t,y&chbh=a,5,10&chs=480x200&cht=bvg&chco=4D89F9,FF0000&chds=0,2.5,0,2.5&chd=t:2.167,1.012,0.701,0.857,1.293|0.015,0.031,0.032,0.03,0.031&chdl=Cygwin|Msysgit&chg=-1,0,0,4&chma=5|5&chtt=Msysgit+vs+Cygwin+CPU+Time" width="400" height="166"  alt="Msysgit vs Cygwin Central Processing Unit Time"/>

<h4>Table timings</h4>   
<table style="width: 100%">
  <thead>
    <tr>
      <th></th>
      <th>status</th>
      <th>new-checkout</th>
      <th>git-rm</th>
      <th>commit</th>
      <th>checkout-master</th>
      <th>diff-master</th>
    </tr>
  </thead>
  <tbody>
    <tr style="background-color: #eee">
      <td>cygwin real</td>
      <td>2.265</td>
      <td>1.124</td>
      <td>0.775</td>
      <td>1.778</td>
      <td>1.963</td>
      <td>1.373</td>
    </tr>
    <tr style="background-color: #eee">
      <td>msysgit real</td>
      <td>1.364</td>
      <td>1.078</td>
      <td>0.508</td>
      <td>0.937</td>
      <td>1.963</td>
      <td>1.312</td>
    </tr>
    <tr>
      <td>cygwin user+sys</td>
      <td>2.167</td>
      <td>1.012</td>
      <td>0.701</td>
      <td>0.857</td>
      <td>1.512</td>
      <td>1.293</td>
    </tr>
    <tr>
      <td>msysgit user+sys</td>
      <td>0.015</td>
      <td>0.031</td>
      <td>0.032</td>
      <td>0.030</td>
      <td>0.031</td>
      <td>0.031</td>
    </tr>
  </tbody>
</table>

<p>As shown above, the timings improved quite a bit. Around 50% to 100% on the
   operation. It does feel snappier. I no longer have to wait 2-3 seconds waiting
   for the "git status" to show up on a warm start. Even on a cold start status,
   the timings improve quite a bit with msysgit.</p>

<p>So what does user+sys represent? Basically, it tells us how much actualy CPU
   time the process used. It is quite significant ... Cygwin uses way more CPU
   time than msysgit. Okay, not that much just around one second. But still, you
   get the point.</p>
   
<h3>Conclusion</h3>
<p>Not only you get speed improvements with msysgit, you get stability
   improvements too. For example, cursor annoyances, copy paste screw-ups, terminal
   freezes, random locking annoyances, etc are all not visible anymore. I have
   been using it for around one months now, and no issues so far :) As a 
   bonus, the msysgit shell starts up super fast!</p>]]></description>
		<pubDate>Sat, 12 Mar 2011 18:27:21 -0500</pubDate>
		<guid>http://www.m0interactive.com/archives/2011/03/12/chromium_msysgit_vs_cygwin_git_performance.html</guid>
	</item>
	<item>
		<title>Software - Facebook Friend Export Chrome Extension Internals</title>
		<link>http://www.m0interactive.com/archives/2011/01/16/facebook_friend_export_chrome_extension_internals.html</link>
		<description><![CDATA[<p>There has been a lot of buzz regarding why Facebook doesn't allow you to export your friends out of Faceboook. Well, the first question many people have stated "Why can't you use Facebook's API to do this". The answer is quite simple but not obvious, Facebook does not allow their API (Application Programming Interface) to export your friends Email addresses that they made public for you to see. Hopefully in this post, I will explain the internals how this Google Chrome Extension was constructed.</p>

<h3><a href="#" name="top"></a>Table of Contents</h3>
<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#messaging">Messaging</a> to communicate from Facebook to the Worker tab back to the extension.</li>
  <li><a href="#content-scripts">Content Scripts</a> to extract your friends data quickly.</li>
  <li><a href="#web-sql-database">HTML5 Offline Database Storage</a> to cache your friends.</li>
  <li><a href="#sending-data-to-gmail">OAuth</a> to export to GMail</li>
  <li><a href="#conclusion">Conclusion</a></li>
</ul>

<h3><a href="#top" name="introduction"></a>Introduction</h3>
<p>You can download the extension from <a href="https://chrome.google.com/webstore/detail/ficlccidpkaiepnnboobcmafnnfoomga">Chrome Web Store</a>
   and the source code is hosted on <a href="https://github.com/mohamedmansour/fb-exporter">GitHub</a>
  (feel free to fork, send patches, and help me improve it)</p>

<p>Within the media, it has been concluded that Facebook owns your friends
most valuable data, their email address. In my opinion, the reason why Facebook 
became so popular is because of "us", we allowed them to export our friends and
connect to them by extracting our friends from Hotmail, MSN, Gmail, Twitter, etc.
But the reverse was not possible, there was no way for us to export them back.
Absolutely no way! I invited many, many, people to Facebook through this process
because I thought it was a neat concept and I believe in their vision. Facebook
has grown so fast, that most of my in real life friends are on Facebook and not
in my contact app (Outlook, Google Contacts). There is no way for me to connect
back to my friends unless I do that within Facebook. It feels like Facebook
is controlling the data that I have provided for them for free. That quite 
bothered me, hence the creation of this extension.</p>

<p>Without the original work from an anonymous person who hosted fb-exporter on
Google Code (which is now blocked), I have used the source code, changed it
dramatically, and made it easier, cleaner, faster, and safer to use. So whats 
new?</p>

<ul>
  <li>A different approach to fetch your friends by directly communicating
      to Facebook's JavaScript Objects, and retrieving your initial friends
      information quickly such as Name, Image, and URL.</li>
  <li>Cached results, since it takes so much time to export your friends, some
      people might accidently close their browser, or want to continue the 
      process some other time. That is now possible via HTML5 Web Storage.</li>
  <li>Not only emails are exported, it exports your contacts phone numbers,
      Google Talk, Yahoo, ICQ, Skype, QQ, and MSN (Windows Live Messenger)
      aliases. jQuery is beautiful when it comes to simplicity.</li>
  <li>It uses real time error handling, if something goes wrong, it will 
      automatically figure out what that issue is and properly handle it.</li>
  <li>New User Interface, you can see a grid of all your friends with their 
      profile photos. When you start the lengthy process, it tells you what is 
      CACHED, READY, STARTED, PROCESSED, SUCCESS and FAILED! These status
      messages help the user know what is happening in real time. Thanks to 
      Chrome Extensions Message Passing.</li>
  <li>The code is mostly refactored to make it cleaner and easier to use. As 
      you noticed, the UI differs too. It is commented fully and restructured
      to make it easier on the external contributions.</li>
</ul>
      
<h3><a href="#top" name="messaging"></a>Communications between Facebook and the Extension process</h3>
<p>In Google Chrome extension, the only way to communicate to the DOM, 
   is through <a href="http://code.google.com/chrome/extensions/content_scripts.html">
   Content Scripts</a>. But there is only one problem, they have a couple of 
   limitations that we need. Content Scripts cannot:</p>
<ul>
  <li>Use variables or functions defined by their extension's pages</li>
  <li>Use variables or functions defined by web pages or by other content scripts</li>
  <li>Make cross-site XMLHttpRequests</li>
</ul> 
<h4>Communication from the Facebook World to the Chrome Extension World</h4>
<p>We need to access our main extension page because we want to transfer our 
   data to Google Gmail Contacts through cross-site XMLHttpRequests. No fear,
   we can use Chrome's <a href="http://code.google.com/chrome/extensions/messaging.html">
   Message Passing</a> to send messages back and fourth to our extensions 
   <a href="http://code.google.com/chrome/extensions/background_pages.html">
   background page</a>, which is just an HTML page that runs in the extension 
   process. It exists for the lifetime of your extension and only one instance
   of it at a time is active. Once we reach the extension process, we 
   can send data back and fourth to Gmail as we please (of course, with the proper
   permissions set in the <a href="http://code.google.com/chrome/extensions/manifest.html#permissions">
   manifest</a>. We want our users to know what the extension has access to.)</p>
<p>In fb-exporter, we actually use Chrome's Message Passing to communicate between
   both worlds, since they are isolated. It is really simple to setup. Within the Content Script we add
   add a extension listener, <a href="http://code.google.com/chrome/extensions/extension.html#event-onRequest">
   chrome.extension.onRequest.addListener</a>, which in this case gets fired when
   a request is sent from the extension process (reduced snippet below):</p>
<pre class="code">
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
  if (request.getFriendsMap) {
    sendResponse({data: friendsMap});
  }
});
</pre>

<h4>Communication from the Extension process back to Facebook</h4>
<p>In the extension world's ( <a href="http://code.google.com/chrome/extensions/background_pages.html">background page</a>
), we maintain the Facebook's tab ID when the user first clicks on the 
"Export Friends" button on Facebook's navigation. When the "Export Friends" button
is clicked, it sends a request to our extension process to tell it to open the 
main controller (that controls the steps for exporting your friends)
window. We use <a href="http://code.google.com/chrome/extensions/extension.html#method-sendRequest">chrome.extension.sendRequest</a>
to send the request to the extension process from the content script:</p>
<pre class="code">
chrome.extension.sendRequest({switchToWorkerTab: 1});
</pre>

<p>So how does the background page listen for content script requests that comes
from Facebook? The exact same way we discussed before with the content script:</p>
<pre class="code">
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
  if (request.switchToWorkerTab) {
    facebook_id = sender.tab.id;
    chrome.tabs.create({url: 'controller.html', selected: true}, function(tab) {
      worker_id = tab.id;
    });
  }
});
</pre>

<p>What the above snippet states, when a request is coming in from the Facebook
page via Content Script, we keep track of the ID's  of those pages. We need 
those ID's so that we can send information back and fourth between different
pages directly. It becomes easier to handle.</p>

<p>Then we can use <a href="http://code.google.com/chrome/extensions/tabs.html#method-sendRequest">
chrome.tabs.sendRequest</a>, to send a request back to Facebook Content Script
and even back to the extension process:</p>

<pre class="code">
chrome.tabs.sendRequest(facebook_id, { facebookError: 1 });
chrome.tabs.sendRequest(worker_id, { facebookError: 1 });
</pre>

<h3><a href="#top" name="content-scripts"></a>Using content scripts to read the internal JavaScript directly from Facebook</h3>
<p>The traditional way of grabbing information is by screen scraping, but
   we are not doing that. If you used <a href="http://code.google.com/chrome/devtools/">
   Chrome Web Inspector</a>, you will notice an internal JavaScript variable
   hosted in Facebook is running the show. But there are some problems and 
   limitations, as we discussed before. We cannot access that variable directly
   from our Extension and even our Content Script!</p>
<p>The only way the our extension can communicate to Facebook is through
   Content Scripts, and the only way Content Scripts can communicate with the 
   <a href="http://code.google.com/chrome/extensions/content_scripts.html#host-page-communication">embedding page</a>
   is through the DOM. The DOM is what shared between both worlds, since they 
   are completely isolated from each other.</p>
<p>To do this, we inject the Facebook page with a 'script' tag that creates a
   custom event. The custom event dispatches when friends object has been retrieved.
   We use custom events because everything is asynchronous. We want to inform
   the Content Script that we have successfully grabbed the object. If you are
   familiar with how Java does drag and drop, the concept of Transfer nodes
   are similar in this case (kinda).</p>
<pre class="code">
// JS script injection to the facebook's World. This function can only be read
// in the Facebook world, it has absolutely no access to the content script
// nor our extension process.
var postFriendMap = function() {
  // Use events to notify the content script. Replicate the event the content
  // script has, so we can pass this event to that world.
  var exportEvent = document.createEvent('Event');
  exportEvent.initEvent('friendExported', true, true);
  
  // Create a transfer node DOM, since that is the only way two worlds can
  // communicate with each other.
  var transferDOM = document.getElementById('fb-transfer-dom-area');
  transferDOM.innerText = JSON.stringify(FriendSearchPane._data);
    
  // Inform our content script that we have received the object from Facebook.
  window.dispatchEvent(exportEvent);
};
 
// Create a dummy textarea DOM.
var transferDOM = document.createElement('div');
$(transferDOM).attr('id', 'fb-transfer-dom-area')
              .hide()
              .appendTo($(document.body));
  
// Start injecting the JS script.
var script = document.createElement('script');
script.setAttribute('id', 'fb-inject-area');
script.appendChild(document.createTextNode('(' + postFriendMap + ')();'));
document.body.appendChild(script); 
</pre>

<p>Our content script listens on that custom event so it will know, asynchronously, 
   when we can start processing our list of friends. And the only way to transfer data 
   through these two worlds is by the DOM as shown in the snippet above.
   A dummy transfer DIV is created on the DOM that both worlds understand.</p>

<pre class="code">
// Listen on the real DOM requests to check if the friends list has been exported.
window.addEventListener('friendExported', function() {
  // Save the map to this content script world, so our extension can read it.
  var transferDOM = $('#fb-transfer-dom-area');
  friendsMap = JSON.parse(transferDOM.text()); // Global
  
  // Clean up since we no longer need this.
  $(transferDOM).remove();
  $('#fb-inject-area').remove();
  
  // Count the number of friends.
  var i = Objects.keys(friendsMap).length;
  
  // Tell the worker tab that we are set!
  chrome.extension.sendRequest({friendListReceived: 1, count: i});
}); 
</pre>   
 
<p>The listener reads the contents stored in the transfer node, and deserializes it
   back so we can store it. It does all the cleanup afterwards since we
   no longer need it. Since we are in the content script, it asynchronously 
   notifies the extension process that we have received the friends list.</p>
   
<p>Voila, we now have read the internal data Facebook has stored.</p>

<h3><a href="#top" name="web-sql-database"></a>Caching of Friends using Web SQL Database</h3>
<p>Caching friends is really important for any lengthy process. If computer 
   restarted, tab closed, error happened, or anything strange happens, we don't
   want to redo the whole process again. The obvious way is to continue where
   we left off.</p>
<p>There are two ways to do data caching for a Web Application:</p>
<ul>
  <li>HTML5 Local Storage</li>
  <li>HTML5 Web SQL Database (no longer active, IndexDB currently in Standards)</li>
</ul>
<p>localStorage was initially going to be chosen, but the 5MB (2.5MB UTF) limitation
   was my reason of not choosing it. localStorage is just a key[value] synchronous 
   storage mechanism, which is super easy to use. Unfortunately, 2.5MB is not 
   enough to store all your friends. </p>
<p>Web SQL Database has the limitation as well, but you can override that limitation
   by specifying in the Chrome Extension manifest <a href="http://code.google.com/chrome/extensions/manifest.html#permissions">unlimitedStorage</a>
   It is an asynchronous API that uses SQL syntax. Take a look at the 
   <a href="https://github.com/mohamedmansour/fb-exporter/blob/master/js/database.js">database.js</a>
   file in the codebase on GitHub. The following snippet is how getting a freind
   from the cache is done.</p>
<pre class="code">
FriendDB.prototype.getFriend = function(id, response) {
  this.db.transaction(function(tx) {
    tx.executeSql('SELECT data FROM friend WHERE id = ?', [id],
        function (tx, rs) {
          if (rs.rows.length != 0) {
            response({status: true, data: JSON.parse(rs.rows.item(0).data)});
          }
          else {
            response({status: false});
          }
        }, this.onError
    );
  });
};
</pre>
<p>In the controller page, once the friends list is requested (so I can render
   my friends in the page), I iterate through all the friends, and check if each
   user is in the cache, if they are in the cache, I inform the Facebook page
   that a cache exists. A separate cache map is stored so when it comes to a time
   to process each friend, it skips that friend because the data is already in
   the cached map.</p>
<pre class="code">
chrome.tabs.sendRequest(bkg.facebook_id, {getFriendsMap: 1}, function(response) {
  $.each(response.data, function(key, value) {
    bkg.db.getFriend(key, function(result) {
      if (result.status) {
        chrome.tabs.sendRequest(bkg.facebook_id, ({cached: true, data: result.data}));
      }
    })
  });
});
</pre>  
 <p>The beauty of having caching, it will result in a neat progress bar :) It 
 isn't instant, because I am making an SQL call for each user. Sure, I can 
 make one big SQL query that checks each ID, but this is cooler since it 
 shows to the user something is happening :)- But it is on my TODO list.</p>

<h3><a href="#top" name="sending-data-to-gmail"></a>Sending the data to Gmail Contacts</h3>
<p>The extension uses <a href="http://oauth.net/">OAuth</a> (which is an open protocol to allow secure API
   authorization), <a href="http://code.google.com/apis/contacts/docs/3.0/developers_guide_protocol.html#CreatingGroups">Google Contacts</a>
   API (yes its public, and you  can import and export), and <a href="http://code.google.com/apis/gdata/">Google Data API</a>
   (to transfer the data in a nice format)</p>
<p>I wont explain much here, all that is done here is saving the data in Gmail Contacts.
   We use the APIs mentioned above to do this securely. Of course, there is absolutely
   no way I can know your authorization, it uses OAuth for secure Authorization.
   The first thing that happens, it creates a group called "Exported from Facebook".
   There is some smart logic there that checks for duplicate friends, and only
   adds friends that are not there. You can later log on Gmail Contacts and organize
   your friends in more groups and merge contacts together (very neat UI).</p>
   
<h3><a href="#top" name="conclusion"></a>Conclusion</h3>
<p>Well, I am not hating on Facebook. My country, Canada, due to privacy laws,
   we own our data. Our data is private information, we cannot let Facebook 
   control our data and own it. I like everything to be in the clear, and that
   is why I created this blog post, to show everyone how its done. Sure I spent
   numerous hours designing, developing, and debugging it (I have spent many
   hours behind my computer to make sure its right). But I am happy of the end
   result. All my contacts are safely in Gmail and I can happily contact my friends
   through other means, and synchronize my friends with my phones and computers.</p>
<p>I hope this post helped you understand the technology behind creating this 
   extension, and will help you create your own in the near future. The Chrome
   Extension API is very very very amusing to work with :)</p>]]></description>
		<pubDate>Sun, 16 Jan 2011 23:21:49 -0500</pubDate>
		<guid>http://www.m0interactive.com/archives/2011/01/16/facebook_friend_export_chrome_extension_internals.html</guid>
	</item>
	<item>
		<title>Software - My favourite Google Chrome extensions</title>
		<link>http://www.m0interactive.com/archives/2010/12/31/my_favourite_google_chrome_extensions.html</link>
		<description><![CDATA[<p>Well, I just want to give my shoutouts to the extensions that I love, and need recognition. I basically use them every single day. Some of them you can see, some of them run in the background. Everywhere I go, I recommend them :) Unfortunately, none on that list is what I created :)</p>

<h3>Google Quick Scroll</h3>
<a href="https://chrome.google.com/webstore/detail/okanipcmceoeemlbjnmnbdibhgpbllgc">https://chrome.google.com/webstore/detail/okanipcmceoeemlbjnmnbdibhgpbllgc</a><br />
<img alt="" src="https://chrome.google.com/webstore/img/okanipcmceoeemlbjnmnbdibhgpbllgc/1292260919.53/thumb" style="float:left;width:128px;height:128px;padding: 10px"/>
<p>
My most useful extension ever! I love exploring the web, Googling my way through
many topics and entertainment. One of my most annoying actions for Googling 
before was finding out where in that large webpage the content I Googled. Quick
Scroll lets you jump directly to the relevant bits of a Google search results.
I absolutely love it!
</p>

<h3 style="clear:left;">Feedly</h3>
<a href="https://chrome.google.com/webstore/detail/ndhinffkekpekljifjkkkkkhopnjodja">https://chrome.google.com/webstore/detail/ndhinffkekpekljifjkkkkkhopnjodja</a><br />
<img  alt="" src="https://chrome.google.com/webstore/img/ndhinffkekpekljifjkkkkkhopnjodja/1291930890.53/logo128" style="float:left;padding: 10px"/>
<p>I subscribe to many RSS feeds, and Feedly is a real clean and easy to figure 
out User Interface. It understands my Google Reader account really nicely, and I
enjoy reading my feeds on it in real time. I usually install the 
<a href="https://chrome.google.com/webstore/detail/nlbjncdgjeocebhnmkbbbdekmmmcbfjd">RSS Subscription Extension</a>
to figure out if a page has a feed or not, and if I like the author of that webpage,
I know instantaneously know I can subscribe to it. If you have other RSS readers
that connect nicely to Google Reader, please let me know.
</p>

<h3 style="clear:left;">Disconnect</h3>
<a href="https://chrome.google.com/webstore/detail/jeoacafpbcihiomhlakheieifhpjdfeo">https://chrome.google.com/webstore/detail/jeoacafpbcihiomhlakheieifhpjdfeo</a><br />
<img  alt="" src="https://chrome.google.com/webstore/img/jeoacafpbcihiomhlakheieifhpjdfeo/1293464345.48/logo128" style="float:left;padding: 10px"/>
<p>I didn't ming when every website added those sharing buttons to every single post.
But I really hated when third parties such as Facebook, Twitter, Yahoo, added some
tracking information the webpages, such as Fans. I get really distracted from 
the website itself, and I don't use those features. Disconnect, really disconnects
them from web. It really works! It uses the "beforeload" event handler so it 
guarantees those services will never make it to the website. I personally
like to control the information I make public or visible, I don't like
websites tracking me.</p>

<h3 style="clear:left;">AdBlock</h3>
<a href="https://chrome.google.com/webstore/detail/gighmmpiobklfepjocnamgkkbiglidom">https://chrome.google.com/webstore/detail/gighmmpiobklfepjocnamgkkbiglidom</a> <br />
<img  alt="" src="https://chrome.google.com/webstore/img/gighmmpiobklfepjocnamgkkbiglidom/1293566228.65/logo128" style="float:left;padding: 10px"/>
<p>This is clearly the most popular Chrome extension. The title says it all,
blocks ads all over the web. I actually enable Google search ads, I find them
relevant. But every other ad, I really don't like, they distract me from the 
content, expecially those annoying "like dislike" Facebook Ads. Horrible!
I somehow get offended seeing Facebook ads.</p>

<h3 style="clear:left;">IE Tab =)</h3>
<a href="https://chrome.google.com/webstore/detail/hehijbfgiekmjfkfjpbkbammjbdenadd">https://chrome.google.com/webstore/detail/hehijbfgiekmjfkfjpbkbammjbdenadd</a><br />
<img  alt="" src="https://chrome.google.com/webstore/img/hehijbfgiekmjfkfjpbkbammjbdenadd/1292882914.27/thumb" style="float:left;width:128px;height:128px;padding: 10px"/>
<p>So why did I pick IE? Many corporate websites of mine don't work well with Chrome,
 or render well with Chrome. Since I am on the Canary version of Google Chrome,
 sometimes Chrome messes up rendering. By clicking a simple button, the renderer
 switches to an IE renderer on that page. It is useful for testing, to see if your
 website is compatible with IE. Would be cool if there were a FireFox and Opera
 plugin. Will make testing cross browser easier.</p>
 
 
 <h3 style="clear:left;">Some other extensions that I use</h3>
 <p>I don't use these extensions alot, but they are pretty cool, and I use them
 once in a while.</p>
 <ul>
   <li><a href="https://chrome.google.com/webstore/detail/ehohhddamheegbbkabfgegbaeminghlb">exfm</a>: 
   Pretty neat way to discover music on the web and make it your library!</li>
   <li><a href="https://chrome.google.com/webstore/detail/encaiiljifbdbjlphpgpiimidegddhic">Chromed Bird</a>:
   One of the earliest Twitter clients, and if you use Twitter alot, this is pretty cool. 
   It uses the whole Extension stack.</li>
   <li><a href="https://chrome.google.com/webstore/detail/hmdcmlfkchdmnmnmheododdhjedfccka">Eye Dropper</a>:
   I love colors, I am addicted to colours! When I explore the web, any color I see,
   I love saving it to my collection and experiment with it. I used to take a 
   screenshot of my webpage, and open up my favourite image editor program and 
   extract the colours from it. That becomes a hassle, Eye Dropper, solves it with
   one click.</li>
   <li><a href="https://chrome.google.com/webstore/detail/oadboiipflhobonjjffjbfekfjcgkhco">Chrome to Phone</a>:
    I use my cell phone a lot, I am in a hurry usually, and I don't like interrupting
    what I am doing online when reading an article, watching a video, etc. This 
    solves it, sends it to my phone instantaneously. I even like it when I select
    a phone number, it calls it :)
   </li>
   <li><a href="https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc">JSON View</a>:
    Many webservices are using JSON as their response, it is the easiest to handle
    in JavaScripts. Without this extension, viewing JSON data is ugly, you don't 
    see the markup or the structure which makes JSON important. This extension solves
    that, you see a pretty structured JSON document if you visit it.
   </li>
 </ul>

 <h3>The extensions that I developed</h3>
 <p>Well, I created some extensions that helped me in some situations, but
 helped others greatly. I usually create extensions that people want, not 
 necessarily what I want. Since I am active in the Chrome mailing lists and 
 official Chrome forums, the result of these extensions were requested from
 users. Believe it or not, they wont use Chrome without these extensions :) Of
 course, as usual, everything is open sourced on my <a href="http://github.com/mohamedmansour/">GitHub</a> page!</p>
 <ul>
   <li><a href="https://chrome.google.com/webstore/detail/bfenodnbilondijnaionekngdhadmegk">Reload All Tabs</a>: 
    Many people wanted a way to reload all tabs in their window, or all windows. 
    But you couldn't do that in Chrome, while in other browsers you could. Initially
    I submitted a patch to do this natively, but it was rejected because they
    thought this is not a feature that many people want, which I agreed. When
    they implemented extensions for Chrome, I quickly made that, and it made
    many people happy!
   </li>
   <li><a href="https://chrome.google.com/webstore/detail/ddkmiidlgnkhnfhigdpadkaamogngkin">Set Image as Wallpaper</a>: 
    This was the most requested feature, thousands of people wanted it for over a year.
    This was an awesome feature to work with, a pretty complex one too. Every browser has an option to set an image
    as a wallpaper, except Google Chrome. This uses neat HTML5 technology to 
    preview before setting it. You have options to Stretch, Center, Fill, Fit, and Tile.
    It was featured on many known blogs and praised by many. Believe it or not, 
    I usually never used this feature on other browsers, but now I do :) Kinda
    cool changing your wallpaper every day or so.
   </li>
   <li><a href="https://chrome.google.com/webstore/detail/ofbafcaeafjchlcknlmcgaijglnkdnja">Open link in foreground tab</a>:
    All links in Chrome opens in background, this will add a context menu to open a link in the foreground.</li>
   <li><a href="https://chrome.google.com/webstore/detail/ndmbeogingkjkmmkoomnigifmpajmbkc">Prayer Times</a>: 
    Muslim praying times schedule that uses geolocation to get the sunset and sunrise.
    It doesn't require an online connection to get the prayer times, and it has a
    complete month to month prayer schedule by a click of a button.</li>
 </ul>]]></description>
		<pubDate>Fri, 31 Dec 2010 00:01:40 -0500</pubDate>
		<guid>http://www.m0interactive.com/archives/2010/12/31/my_favourite_google_chrome_extensions.html</guid>
	</item>
	<item>
		<title>Software - How to communicate back to JavaScript from NPAPI plugin</title>
		<link>http://www.m0interactive.com/archives/2010/10/21/how_to_communicate_back_to_javascript_from_npapi_plugin.html</link>
		<description><![CDATA[<p>I might be a bit late learning plugin development for the browser, but I really 
 wanted to know how to create a plugin. It turned out to be such an easy task and awesome 
 framework. You can do a lot with NPAPI, and the cool thing about it is the 
 ability to let your C++ code communicate back to the JavaScript world easily.</p>
 
 <h3>How to send a debug message to the browsers console</h3>
 
 <p>The best way to teach someone how to send a message back to the browser is
    with an example. Afterwards, I will explain each step in detail. So here is the 
    JavaScript code that we want to call from our C++ plugin:</p>

 <pre class="code">
   console.debug("Hello from C++");
 </pre>

 <p>The equivalent C++ code for the above JavaScript would be the following:</p>
 <pre class="code">
  // The message we want to send.
  char* message = "Hello from C++";
  
  // Get window object.
  NPObject* window = NULL;
  NPN_GetValue(npp_, NPNVWindowNPObject, &window);

  // Get console object.
  NPVariant consoleVar;
  NPIdentifier id = NPN_GetStringIdentifier("console");
  NPN_GetProperty(npp_, window, id, &consoleVar);
  NPObject* console = NPVARIANT_TO_OBJECT(consoleVar);

  // Get the debug object.
  id = NPN_GetStringIdentifier("debug");

  // Invoke the call with the message!
  NPVariant type;
  STRINGZ_TO_NPVARIANT(message, type);
  NPVariant args[] = { type };
  NPVariant voidResponse;
  NPN_Invoke(npp_, console, id, args,
             sizeof(args) / sizeof(args[0]),
             &voidResponse);

  // Cleanup all allocated objects, otherwise, reference count and
  // memory leaks will happen.
  NPN_ReleaseObject(window);
  NPN_ReleaseVariantValue(&consoleVar);
  NPN_ReleaseVariantValue(&voidResponse);
 </pre>
 
 <h3>The browser object</h3>
 <pre class="code">
  NPObject* window = NULL;
  NPN_GetValue(npp_, NPNVWindowNPObject, &window);
 </pre>
 <p>The first thing we need is an <span class="code">NPObject</span>
    representation of the browser object. From there, the functions in this API 
    can be used to get and set properties and call methods on those browser objects.</p>
 <p>The browser object in this case is javascript's <a href="https://developer.mozilla.org/en/DOM/window" class="code">window</a>
    object. The <span class="code">window</span> object represents the window itself, which
    we want to execute a property in our case the <a href="http://getfirebug.com/wiki/index.php/Console_API" class="code">console</a>.
    Console debugging is the default debugging messaging for Google Chrome and Firebug on Firefox.</p>
 <p>To access the browser object from NPAPI, it is done by using an extension to 
    <a href="https://developer.mozilla.org/en/NPN_GetValue" class="code">NPN_GetValue()</a>. The extension
    is the <span class="code">NPNVWindowNPObject</span> enumeration. By calling <span class="code">NPN_GetValue</span>
    with that enumeration, it will return an <span class="code">NPObject</span> representing the browser object.</p>
 <p>An <a href="https://developer.mozilla.org/en/NPObject" class="code">NPObject</a> is a structure that holds
    a pointer to an <span class="code">NPClass</span> which is defined within your plugin. It is the type
    that is used to express objects exposed by the browser in this case. This is the entry point of what 
    we need to execute in the JavaScript side.</p>
 <p>So now we have access to the <span class="code">window</span> object within the JavaScript DOM.</p>
 
 <h3>Calling the console property</h3>
 <pre class="code">
   // Get console object.
  NPVariant consoleVar;
  NPIdentifier id = NPN_GetStringIdentifier("console");
  NPN_GetProperty(npp_, window, id, &consoleVar);
  NPObject* console = NPVARIANT_TO_OBJECT(consoleVar);
 </pre>
 <p>The plugin now has a pointer to the browser's <span class="code">window</span>
    DOM object. Now time to call its' <span class="code">console</span> property
    which allows us to call its functions such as, <span class="code">console.debug()</span></p>
 <p>To do so, we need an <a href="https://developer.mozilla.org/en/NPIdentifier" class="code">NPIdentifer</a>
    that identies the JavaScript string that we want to call. We can use the macro,
    <a href="https://developer.mozilla.org/en/NPN_GetStringIdentifier" class="code">NPN_GetStringIdentifier</a>
    to quickly get the identifier for that string. That is used to tell NPAPI
    what to execute in the <span class="code">NPObject</span>.</p>
 <p>Since we have the <span class="code">window</span> object and <span class="code">id</span>
    identifier  we can execute that property to retrieve the console <span class="code">NPVariant.</span>
    The <a href="https://developer.mozilla.org/en/NPVariant" class="code">NPVariant</a> is a struct
    that holds a value and the type of that value. Think of it as a JavaScript representation
    of a variable in NPAPI. It is the response that comes back from the browsers,
    in this case, it is just a console <span class="code">NPObject</span>.
    Since we know its an <span class="code">NPObject</span>, we can extract the 
    <span class="code">NPVariant</span> to an <span class="code">NPObject</span> 
    with the simple to use macro, <a href="https://developer.mozilla.org/en/NPVariant" class="code">NPVARIANT_TO_OBJECT</a></p>

 <h3>Invoking debug</h3>
 <pre class="code">
  // Get the debug object.
  id = NPN_GetStringIdentifier("debug");

  // Invoke the call with the message!
  NPVariant type;
  STRINGZ_TO_NPVARIANT(message, type);
  NPVariant args[] = { type };
  NPVariant voidResponse;
  NPN_Invoke(npp_, console, id, args,
             sizeof(args) / sizeof(args[0]),
             &voidResponse); 
 </pre>
 <p>The final step is to invoke a debug function on the console <span class="code">NPObject</span>
    returned by the previous step. We do the same thing we did before, we need an
    <span class="code">NPIdentifer</span> that idenfies the javascript, in this case
    <span class="code">debug</span>. Note, we reuse the same  <span class="code">NPIdentifier</span> id.</p>
 <p>Since <span class="code">window.console.debug(message)</span> requests a string
    parameter, as we discussed before, a parameter is just an <span class="code">NPVariant</span>.
    To convert a <span class="code">char*</span> to a <span class="code">NPVariant</span> string,
    we can use a macro, <span class="code">STRINGZ_TO_NPVARIANT</span>. All the NPAPI macros are defined
    in the <a href="https://developer.mozilla.org/en/NPVariant" class="code">NPVariant</a> docs.
    You should read them, it is great to know which macros are available. Makes your 
    life easier to use them. </p>
 <p>Once we constructed our <span class="code">NPVariant</span> args array, we can
    finally invoke the console <span class="code">NPObject</span> defined earlier with
    the args we defined right now. The result would just be a void response.</p>
   
 <h3>Don't forget to cleanup!</h3>
 <pre class="code">
  // Cleanup all allocated objects, otherwise, reference count and
  // memory leaks will happen.
  NPN_ReleaseObject(window);
  NPN_ReleaseVariantValue(&consoleVar);
  NPN_ReleaseVariantValue(&voidResponse);
 </pre>
 <p>As you all know, cleaning up unused pointers is critical to any C++ application :).
    Failing to do so in NPAPI, will result in buggy plugins that will crash. Yes,
    I said it, it will "really" crash!. So cleanup your window object, and your
    variants as shown in the snippet!</p>
 <h3>Conclusion</h3>
 <p>I hope you realize how easy it is to call JavaScript directly from NPAPI,
    once you understand the code involves, it becomes easy to do anything. 
    Just be careful cleaning up afterwards, or you will have memory leaks and
    plugin crashes. I hope this article will benefit any of you, and I am
    excited to share my NPAPI journey with you in the near future!</p>
 <p>My next article will be talking about the design and architecture of a NPAPI
    plugin, and what the future has with NPAPI. Google engineers are working hard
    creating future sandboxes plugins which are safer and easier to use such as
    PEPPER and NaCL (discontinued "kinda" in favor of PEPPER) :)</p>]]></description>
		<pubDate>Thu, 21 Oct 2010 20:18:23 -0400</pubDate>
		<guid>http://www.m0interactive.com/archives/2010/10/21/how_to_communicate_back_to_javascript_from_npapi_plugin.html</guid>
	</item>
	<item>
		<title>Software - Just released RhymeBrain on Android</title>
		<link>http://www.m0interactive.com/archives/2010/09/12/just_released_rhymebrain_on_android.html</link>
		<description><![CDATA[<p>Want to figure out which words sound similar? RhymeBrain, rhyme's any word you give it
intelligently. You can drill down on every word to find out which word sounds best for you.
You can filter the words based on offensive words and you can show only real words.</p>

<h3>About</h3>
<p>Using <a href="http://stevehanov.ca">Steve Hanov's</a> awesome RhymeRank<sup>TM</sup> system, 
we created this simple to use Android App. Each result is grouped by a score that is separated
by an orange line. </p>

<p>FAQ from RhymeBrain:</p>
<pre style="overflow:hidden; border-left: 10px solid #eee; padding-left: 5px">
<span style="font-size: 1.5em; color: #ccc;font-weight:bold">Quote...</span>
Using advanced artificial intelligence techniques, RhymeBrain
figures out how to pronounce a word even if it has never seen 
it before. RhymeBrain then compares it to the 260,000 words
in its database to find ones that sound similar.
Finally, it sorts them so that the best rhymes appear first, using
our RhymeRank<sup>TM</sup> system.

<a href="http://rhymebrain.com/about.html">Source</a>
</pre>

<h3>Screenshots</h3>
<img src="http://www.m0interactive.com/images/blog/rhymebrain/device.png" alt="RhymeBrain" />
<img src="http://www.m0interactive.com/images/blog/rhymebrain/device2.png" alt="RhymeBrain" />
<br />
<img src="http://www.m0interactive.com/images/blog/rhymebrain/device3.png" alt="RhymeBrain" />
<img src="http://www.m0interactive.com/images/blog/rhymebrain/device4.png" alt="RhymeBrain" />

<h3>Download</h3>
<p>It is on the Market right now, for free so please help me test it with all the
unique devices out there. Scan this QR Code to download the app! Or search for <a href="market://details?id=com.mindtechnologies.rhymebrain">RhymeBrain</a> from the Market.</p>
<img src="http://chart.apis.google.com/chart?cht=qr&chs=400x400&chl=market://details?id=com.mindtechnologies.rhymebrain" />]]></description>
		<pubDate>Sun, 12 Sep 2010 10:34:33 -0400</pubDate>
		<guid>http://www.m0interactive.com/archives/2010/09/12/just_released_rhymebrain_on_android.html</guid>
	</item>
	<item>
		<title>Javascript - How to preload an IFrame</title>
		<link>http://www.m0interactive.com/archives/2010/06/10/how_to_preload_an_iframe.html</link>
		<description><![CDATA[<p>One of the annoyances of an IFrame is that if the frame takes time to load, you will see white space for a short moment then the page will appear. The reason why I did this is for Google Docs. I had a presentation I want to embed on my <a href="http://mohamedmansour.com/">website</a>, and it was taking time. I would like to share what I have done, although simple, but yet powerful, and hope it will help you. In this post, I will explain to you how to make a simple textual preloader for your iframe</p>

<h3>Why do we need a preloader?</h3>
<p>Sure some websites are efficient at loading, but the download time might vary. If you are adding widgets as I explained earlier, you will see that it is quite annoying having this white space in the middle and just reappear. It degrades user experience and just does not feel right. By adding a very simple preloader to that iframe, the user will know something is going to happen in that area.</p>

<h3>Small demo</h3>
<p>Refresh this page and look at this area to see how it works.</p>
<iframe src="http://yahoo.com" width="100%" height="342" id="testFrame"></iframe>

<h3>The idea</h3>
<p>It is pretty simple and straight forward! We create some sort of placeholder that contains our textual loader, in this case it will be just a div with some loading text.</p>

<p>At the end of the webpage, right before the body tag, we inject some Javascript to hide the frame and show the preloader. With a simple <a href="https://developer.mozilla.org/en/DOM/element.addEventListener">window load listener</a>, we can know when the page has been fully loaded.</p>

<p>Once the page loads, we can hide the preloader and show the iframe. Voila, a simple preloader!</p>

<h3>The code</h3>
<p>On your main page, right before the end body tag you insert the following:</p>
<pre>
  <script>
    var preloader = new IFramePreloader('testFrame');
    preloader.init();
  </script>
</pre>

<p>The iframepreloader.js is below:</p>
<pre>
/**
* Global Static Event Utilities helper that assists us to add
* cross platform events to any DOM object as well retrieving
* their target if any exists.
*
* @author Mohamed Mansour (http://mohamedmansour.com)
*/
var event_utils = {
  add: function(obj, type, callback) {
    if (obj.addEventListener)
      obj.addEventListener(type, callback, false);
    else if (obj.attachEvent)
      obj.attachEvent("on" + type, callback);
  }
}


/**
* Preloads an IFrame since it may take time to load.
*
* @param {string} id The identifier for the Iframe you want preloaded.
* @author Mohamed Mansour (http://mohamedmansour.com)
*/
IFramePreloader = function(id)
{
  that = this;
  this.id = id;
  this.iframe = document.getElementById(id);
  this.placeholder = this.createPlaceholder();
}

IFramePreloader.prototype = {

  /**
  * Initializes the preloader to wait till a load event occurs in the iframe.
  */
  init: function()
  {
    this.iframe.style.display = 'none';
    event_utils.add(this.iframe, 'load', function(e) { that.handleLoad(e); });
  },

  /**
  * Creates the placeholder for that Iframe.
  * @return {Element} The placeholder element.
  */
  createPlaceholder: function()
  {
    // Create placeholder.
    var newElement = document.createElement('div');
    newElement.id = this.id + '-placeholder';
    newElement.appendChild(document.createTextNode('Loading ...'));

    // Adding that placeholder right after the iframe. We first check if its the
    // last child, if so, we just append it. Otherwise, we insert it before the
    // next sibling.
    var parent = this.iframe.parentNode;
    if (parent.lastChild == this.iframe) {
      parent.appendChild(newElement);
    } else {
      parent.insertBefore(newElement, this.iframe.nextSibling);
    }
    return newElement;
  },

  /**
  * Show the frame, hide the preloader. Since it has been loaded!
  */
  handleLoad: function()
  {
    this.iframe.style.display = 'block';
    this.placeholder.style.display = 'none';
  }
}

</pre>

<h3>Conclusion</h3>
<p>As you have seen, it is very straight forward adding an indeterminate preloader to your iframe. Some may want images, flash, movies, or anything else. It is very easy to customize it. From the code above, <code>createPlaceholder</code> creates that placeholder. If you want an image, you can add an image easily there, same goes for any types.</p>

<p>If you have any questions, please let me know in the comments below or through email!</p>

<script>
/**
* Global Static Event Utilities helper that assists us to add
* cross platform events to any DOM object as well retrieving
* their target if any exists.
*
* @author Mohamed Mansour (http://mohamedmansour.com)
*/
var event_utils = {
  add: function(obj, type, callback) {
    if (obj.addEventListener)
      obj.addEventListener(type, callback, false);
    else if (obj.attachEvent)
      obj.attachEvent("on" + type, callback);
  }
}


/**
* Preloads an IFrame since it may take time to load.
*
* @param {string} id The identifier for the Iframe you want preloaded.
* @author Mohamed Mansour (http://mohamedmansour.com)
*/
IFramePreloader = function(id)
{
  that = this;
  this.id = id;
  this.iframe = document.getElementById(id);
  this.placeholder = this.createPlaceholder();
}

IFramePreloader.prototype = {

  /**
  * Initializes the preloader to wait till a load event occurs in the iframe.
  */
  init: function()
  {
    this.iframe.style.display = 'none';
    event_utils.add(this.iframe, 'load', function(e) { that.handleLoad(e); });
  },

  /**
  * Creates the placeholder for that Iframe.
  * @return {Element} The placeholder element.
  */
  createPlaceholder: function()
  {
    // Create placeholder.
    var newElement = document.createElement('div');
    newElement.id = this.id + '-placeholder';
    newElement.appendChild(document.createTextNode('Loading ...'));

    // Adding that placeholder right after the iframe. We first check if its the
    // last child, if so, we just append it. Otherwise, we insert it before the
    // next sibling.
    var parent = this.iframe.parentNode;
    if (parent.lastChild == this.iframe) {
      parent.appendChild(newElement);
    } else {
      parent.insertBefore(newElement, this.iframe.nextSibling);
    }
    return newElement;
  },

  /**
  * Show the frame, hide the preloader. Since it has been loaded!
  */
  handleLoad: function()
  {
    this.iframe.style.display = 'block';
    this.placeholder.style.display = 'none';
  }
}
var preloader = new IFramePreloader('testFrame');
preloader.init();
</script> ]]></description>
		<pubDate>Thu, 10 Jun 2010 12:54:45 -0400</pubDate>
		<guid>http://www.m0interactive.com/archives/2010/06/10/how_to_preload_an_iframe.html</guid>
	</item>
	<item>
		<title>Software - Chromium OS compiled in Debian running in VirtualBox</title>
		<link>http://www.m0interactive.com/archives/2009/11/20/chromium_os_compiled_in_debian_running_in_virtualbox.html</link>
		<description><![CDATA[<p>So today Google announced Chrome OS and released the source code. So I grabbed the source and started lurking! I have compiled it with Debian and created the chromiumos.vmdk drive that you can load in VirtualBox or VMWare Player. In this article, I will explain what extra stuff I needed to make it compile on Debian and you can download the working image at the end of this article.</p>

<h3>How to compile in Debian</h3>
<p>Make sure you read the dev docs here <a href="http://dev.chromium.org/chromium-os/building-chromium-os" > http://dev.chromium.org/chromium-os/building-chromium-os </a>, it works perfectly. So make sure you install: </p>
<ol>
<li>Prerequisites</li>
<li>Download the Source Code http://src.chromium.org/git/chromiumos.git</li>
<li>And build!</li>
</ol>

<p>In Debian make sure you have "qemu" installed (sudo apt-get install qemu), that is needed to create the image. And make sure you add sbin to your path (export PATH=/sbin:/usr/sbin:"$PATH" or it wont work. Thats all!</p>


<h3>How it feels</h3>
<p>Okay, it booted in 2 seconds in a VM! That is bloody quick. It seems slow in the VM but that is normal. It really seems like an unfinished product and many stuff hasn't been cleaned. Such as, many broken links (internal Google sites) still in tact. Keyboard shortcuts doesn't for many. The only thing you can make working is use the internet. Good for a start, I guess!</p>

<h3>How to run Chromium OS</h3>
<p>I used VirtualBox and VMWare Player, VirtualBox was very simple to use. All you had to do is follow these steps. Remember to download the virtual disk below:</p>
<div style="border: 1px dotted #ccc">
  <a href="http://mohamedmansour.com/" style="color:black">
    <img src="http://mohamedmansour.com/chrome/chrome-icon.png" alt="Download ChromeOS" style="float:left"/>
    <p>
      <strong><del>Download Chromium OS (Root password: chrome)</del>No longer exists.</strong><br />
      Virtual Machine Disk Format (works on VirtualBox and VMWare Player)
    </p>
  </a>
</div>
<p>Steps to run it:</p>
<ol>
<li>Download from <a href="http://www.virtualbox.org/">http://www.virtualbox.org/</a>, its free and Open Source! Install it.</li>
<li>Create a new Virtual Machine.</li>
<li>Type any name (ChromeOS)</li>
<li>The Operating System should be Linux, and the Version could be Other.</li>
<li>Use an existing hard disk, point to the chromiumos.vmdk file </li>
<li>Thats it, press start!</li>
</ol>

<img src="http://www.m0interactive.com/images/blog/chromeos/chromeos_start.jpg" alt=""/>

<img src="http://www.m0interactive.com/images/blog/chromeos/chromeos_inside.jpg" alt=""/>
]]></description>
		<pubDate>Fri, 20 Nov 2009 02:45:54 -0500</pubDate>
		<guid>http://www.m0interactive.com/archives/2009/11/20/chromium_os_compiled_in_debian_running_in_virtualbox.html</guid>
	</item>
	<item>
		<title>Technology - How to Enable WebGL on Google Chrome</title>
		<link>http://www.m0interactive.com/archives/2009/10/26/how_to_enable_webgl_on_google_chrome.html</link>
		<description><![CDATA[<p>This month, WebGL has been released in its pre-state in Firefox, Safari, and Chromium. WebGL is a cool way to display 3D content in the Web using OpenGL.</p>

<fieldset>
<legend>UPDATE</legend>
<p>It has been almost a year since we released WebGL, to enable that in Chrome / Chromium, you just need the command line argument: </p>
<p> Windows: </p>
<pre>
chrome.exe   --enable-webgl
</pre>
<p> Linux / Mac: </p>
<pre>
./chrome --enable-webgl
</pre>

<p>To edit it permanently, edit your shortcut properties by right clicking on the Chrome shortcut and choosing 'Properties', and append the command line argument above (--enable-webgl) within the target.</p>
</fieldset>


<h3>What is WebGL</h3>
<p>WebGL is a JavaScript binding to OpenGL ES 2.0 for 3D Web Graphics without installing any web plugins. The Khronos Group (the creators/maintainers of OpenGL standard) working group includes many industry leaders such as Google, Mozilla, NVIDIA, Opera, AMD, etc to work on standardizing WebGL. The press release can be read <a href="http://www.khronos.org/news/press/releases/khronos-webgl-initiative-hardware-accelerated-3d-graphics-internet">here</a>. WebGL is currently still in development, if you want to keep track of its status, you can star this issue: <a href="http://code.google.com/p/chromium/issues/detail?id=21852"> http://code.google.com/p/chromium/issues/detail?id=21852</a></p>

<h3>But how is it different than Google's O3D?</h3>
<p>Update: O3D decided to concentrate making HTML5 WebGL faster and better. O3D is now an open-source web API for creating rich, interactive 3D applications in the browser.</p>
<del>
<p>The main reason is that WebGL is still very slow, O3D is a plugin which is native. There is an interesting thread going on and some Googlers from the O3D team discussed the differences: </p>
<pre style="overflow:hidden; border-left: 10px solid #eee; padding-left: 5px">
<span style="font-size: 1.5em; color: #ccc;font-weight:bold">Quote...</span>
O3D is not going away. WebGL is a very cool initiative but it has
a lot of hurdles to overcome. The direction of WebGL is trying to
just expose straight OpenGL ES 2.0 calls to JavaScript. 

JavaScript is still slow in the large scheme of things. Maybe at 
sometime in the future WebGL will have added enough features over
basic OpenGL to be more powerful or JavaScript  will have gotten 
a few orders of magnitude faster but at the moment…

…
The WebGL team at Google and the O3D team are currently the same
team. We have every interest in seeing both WebGL and O3D succeed.

<a href="http://groups.google.com/group/o3d-discuss/browse_thread/thread/7bfa31efcc03b5f6">Read Original Source ...</a>
</pre>
</del>

<h3>How to enable WebGL on Google Chrome / Chromium?</h3>
<del><p>Make sure you are in the dev channel. Google Chrome releases updates to different release channels. Currently, there are three channels; Stable (everyone is on this when the first install Google Chrome), Beta (every month or so, you will get an update), and Dev (the developer preview channel where stuff gets tested, like WebGL). In order to use WebGL at this current time, you would need the "Beta/Dev" release channel. </p>
<ol>
<li>First, subscribe here: <a href="http://www.google.com/chrome/eula.html?extra=devchannel"> http://www.google.com/chrome/eula.html?extra=devchannel </a></li>
<li>Make sure all other windows are closed.</li>
<li>Install</li>
<li>Now you are subscribed to the Development Channel, yay!</li>
</ol>
</del>
<p>After you have subscribed to the Development channel, you would need to put some command line parameters when you launch Google Chrome. </p>
<ol>
<li>Right click on your "Chrome" icon.</li>
<li>Choose properties</li>
<li>At the end of your target line, place these parameters: 
<ul>
<li>--enable-webgl</li>
</ul>
</li>
<li>It should look like: "chrome.exe --enable-webgl"</li>
</ol>

<p>Now you have WebGL installed! Lets look at a cool example! This example of Escher Droste effect, where one image, rotated, thinking its zooming in forever. So cool! Take a look here: <a href="http://wakaba.c3.cx/w/escher_droste.html"> http://wakaba.c3.cx/w/escher_droste.html </a></p>

<p>Have fun WebGL'n!</p>]]></description>
		<pubDate>Mon, 26 Oct 2009 23:53:56 -0400</pubDate>
		<guid>http://www.m0interactive.com/archives/2009/10/26/how_to_enable_webgl_on_google_chrome.html</guid>
	</item>
</channel>
</rss><!-- m0|XML Creator v1 -->
