<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUQCRHozfSp7ImA9WhVUF0o.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656</id><updated>2012-05-23T18:19:25.485+05:30</updated><category term="weave" /><category term="yui" /><category term="openid" /><category term="gmail gadgets" /><category term="tackle" /><category term="javascript" /><category term="signonmanager" /><category term="chromahash" /><category term="wcd" /><category term="rsa" /><category term="smashup" /><category term="greasemonkey development" /><category term="open mail applications" /><category term="UI" /><category term="yui-smash" /><category term="events" /><category term="Build" /><category term="seam carving" /><category term="google custom search" /><category term="linkify" /><category term="sort-sound" /><category term="demo" /><category term="RIA" /><category term="mashups" /><category term="c programming" /><category term="Programming" /><category term="opensocial" /><category term="itrans" /><category term="indexeddb" /><category term="opensocial hacks" /><category term="firefox" /><category term="tnea" /><category term="trialtool" /><category term="ATMOS" /><category term="gids" /><category term="rupeesymbol" /><category term="animation" /><category term="quillpad" /><category term="google link cleaner" /><category term="barcampbangalore" /><category term="sneakoscope" /><category term="webtop" /><category term="apollo" /><category term="google logo" /><category term="flipring" /><category term="app engine" /><category term="Federation" /><category term="duels.com" /><category term="visionizzer" /><category term="facebook" /><category term="launchy" /><category term="ubiquity:bookmark" /><category term="gosync" /><category term="java" /><category term="aardvark" /><category term="silverlight" /><category term="mailonfeed" /><category term="snapp" /><category term="twitterpipe" /><category term="flickrsubz" /><category term="meebo" /><category term="ubiquity" /><category term="windows8" /><category term="Rich Internet Application" /><category term="barcampbangalore5" /><category term="website" /><category term="hackdayindia" /><category term="techtalks" /><category term="iimb" /><category term="reddit" /><category term="myOrkut" /><category term="CardSpace" /><category term="widgets" /><category term="thatsmymouse" /><category term="transliteration" /><category term="flashplus" /><category term="bookmarklets" /><category term="anti phishing" /><category term="twitteybot" /><category term="hacks" /><category term="Laszlo" /><category term="ANT" /><category term="delicious" /><category term="GreaseMonkey" /><category term="twitter" /><category term="tynt" /><category term="flash resizer" /><category term="YAHOO" /><category term="maps" /><category term="langfa" /><category term="reddit bar" /><category term="3dsmax" /><category term="scrapstimeout" /><title>Dy-Verse</title><subtitle type="html">The technical blog of &lt;a href="http://nparashuram.com"&gt; Parashuram &lt;/a&gt;</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.nparashuram.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>278</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Dy-verse" /><feedburner:info uri="dy-verse" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><feedburner:emailServiceId>Dy-verse</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;DU8MQX8-cSp7ImA9WhVUFkg.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-7462156883004015843</id><published>2012-05-22T09:06:00.000+05:30</published><updated>2012-05-22T09:08:00.159+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-22T09:08:00.159+05:30</app:edited><title>HTML5 Dev Conf</title><content type="html">I was &lt;a href="http://www.html5devconf.com/speakers/parashuram_narasimhan.html" target="_blank"&gt;speaking&lt;/a&gt; at the &lt;a href="http://www.html5devconf.com/" target="_blank"&gt;HTML5 Dev Conf&lt;/a&gt; on May 21, 2012 on Client Storage.&lt;br /&gt;
&lt;br /&gt;
The talk covered the state of client storage, touching on cookies and local/session storage. It looked at the WebSQL specification, the reasons it was deprecated and how IndexedDB is the next big thing for a database in the browsers.&lt;br /&gt;
It also spoke about the limitations on IndexedDB and the list of libraries that could help using IndexedDB now. Some libraries covered include &lt;a href="http://gazeljs.org/" target="_blank"&gt;gazeljs&lt;/a&gt;, &lt;a href="http://aaronpowell.github.com/db.js/"&gt;db.js&lt;/a&gt;, &lt;a href="https://github.com/philikon/queryIndexedDB"&gt;queryIndexedDB&lt;/a&gt; and backbone's &lt;a href="https://github.com/superfeedr/indexeddb-backbonejs-adapte"&gt;IndexedDB Adapter&lt;/a&gt;. I also spoke about the &lt;a href="http://nparashuram.com/jquery-indexeddb"&gt;JQuery IndexedDB&lt;/a&gt; library that I wrote, in addition to &lt;a href="http://www.kristofdegrave.be/2012/05/using-linq-to-indexed-db.html"&gt;Linq2IndexedDB&lt;/a&gt; that &lt;a href="http://www.kristofdegrave.be/"&gt;Kristof&lt;/a&gt; and I are working on. I also introduced the &lt;a href="http://nparashuram.com/IndexedDB/polyfill/"&gt;IndexedDB shim on WebSql&lt;/a&gt; that would let people use IndexedDB API on Safari, Opera - enabling it on iPad and the iPhone. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div id="__ss_13021156" style="width: 425px;"&gt;
&lt;b style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/axemclion/client-storage" target="_blank" title="Client storage"&gt;Client storage&lt;/a&gt;&lt;/b&gt; &lt;iframe frameborder="0"  marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/13021156" height = "400px" width="600px"&gt;&lt;/iframe&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-7462156883004015843?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/dNqDPVaS54k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/7462156883004015843/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/05/html5-dev-conf.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7462156883004015843?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7462156883004015843?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/dNqDPVaS54k/html5-dev-conf.html" title="HTML5 Dev Conf" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/05/html5-dev-conf.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYMR3Y9eyp7ImA9WhVUE00.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-8445432394219591100</id><published>2012-05-18T07:57:00.001+05:30</published><updated>2012-05-18T07:59:46.863+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-18T07:59:46.863+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="indexeddb" /><title>Introducing - IndexedDB Shim over WebSql</title><content type="html">&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;&lt;a href="https://github.com/axemclion/IndexedDB/" target="_blank"&gt;IndexedDB Shim over Web on Github&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a href="https://developer.mozilla.org/en/IndexedDB" target="_blank"&gt;IndexedDB&lt;/a&gt; is a client side database technology supported by Firefox, Internet Explorer and Chrome. It is a replacement to the now deprecated &lt;a href="http://www.w3.org/TR/webdatabase/" target="_blank"&gt;WebSql&lt;/a&gt; standard. Unfortunately, IndexedDB is not yet &lt;a href="http://www.caniuse.com/#search=IndexedDB" target="_blank"&gt;supported&lt;/a&gt; in Opera or Safari, make adoption of this standard slower.&lt;br /&gt;
The specification is also evolving and its implementation has differences even in the browsers that implement it. In the &lt;a href="http://blog.nparashuram.com/2012/05/indexeddb-setversion-vs-onupgradeneeded.html" target="_blank"&gt;previous post&lt;/a&gt;, I wrote about how Chrome implements setVersion, while Firefox has been supporting the onupgradeneeded method as per the newer version of the specification.&lt;br /&gt;
This post is about a project that I am currently working on - bringing the IndexedDB technology to browsers that only have WebSql as the database. WebSql iteself has &lt;a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills" target="_blank"&gt;shims&lt;/a&gt; implemented and this should work well over those shims too.&lt;br /&gt;
So far, the simpler operations like object stores, data get and put, and cursors have been implemented. The shim is based on the &lt;a href="http://hg.mozilla.org/mozilla-central/file/895e12563245/dom/indexedDB" target="_blank"&gt;implementation of IndexedDB&lt;/a&gt; in Firefox. Since WebSql provides a transactional SQLite like platform, translating IndexedDB concepts to the WebSql world was easy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;IDBDatabase&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
A database in IndexedDB corresponds directly to a database in WebSql. An additional, top level database called __sysdb__ is added to keep track of the database versions etc. WebSql database versions were not used in this implementation.Note that there is no implementation of db.close()&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;IDBTransaction&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
The transactions for IndexedDB directly correspond to transactions in WebSql. The lack of the abort method in WebSQL Transactions is overcome by throwing an exception to cancel the transaction. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;IDBObjectStore&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
An IndexedDB Object Store is corresponds to a table in WebSql. Every database also has a __sys__ table that tracks meta data like autoIncrement, keyPath, etc about object stores. Adding data to the object store is added using a record in the table that looks like {keyId, value}. I hope to use the Firefox &lt;a href="http://hg.mozilla.org/mozilla-central/file/895e12563245/dom/indexedDB/Key.cpp" target="_blank"&gt;Key implementation&lt;/a&gt; to allow collations, but for now, all keys are simply JSON strings. Values are also not obtained using the &lt;a href="https://developer.mozilla.org/en/DOM/The_structured_clone_algorithm" target="_blank"&gt;Structured Cloning algorithm&lt;/a&gt;, but using JSON.stringify for now. KeyPaths are evaluated when required using eval. Since SQLite allows only integer keys for autoIncrement, an extra inc column is added to such tables to keep track of the auto increment values. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;IDBCursors&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Cursors are implemented using &lt;a href="http://www.sqlite.org/lang_select.html#orderby" target="_blank"&gt;offset and limit&lt;/a&gt; queries in WebSql. Continue simply selects the next&amp;nbsp; element and a variable saves the offset value that should be applied to the query. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;IDBIndexes&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Indexes are still not implemented yet and I am working on getting Indexes working. I am looking at the way Firefox implements indexes.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Testing&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
You can run the tests on Chrome, Opera and Safari using the page at &lt;a href="http://nparashuram.com/IndexedDB/polyfill/"&gt;http://nparashuram.com/IndexedDB/polyfill/&lt;/a&gt;. In chome, you should be able to open the Resources tab to see the various tables created by the implementation and how they correspond to IndexedDB constructs. &lt;br /&gt;
&lt;br /&gt;
You can watch out &lt;a href="http://blog.nparashuram.com/search/label/indexeddb" target="_blank"&gt;this space&lt;/a&gt; for updates. Please feel free to fork the &lt;a href="https://github.com/axemclion/IndexedDB/" target="_blank"&gt;project on github&lt;/a&gt; and help me confirm to the standards better. I am doing test driven development, and you can run the tests at &lt;a href="http://nparashuram.com/IndexedDB/polyfill/"&gt;http://nparashuram.com/IndexedDB/polyfill/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I hope that this plugin makes the IndexedDB API available in more places, enabling faster adoption of the specification.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-8445432394219591100?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/F8G7nNrap0Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/8445432394219591100/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/05/introducing-indexeddb-shim-over-websql.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/8445432394219591100?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/8445432394219591100?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/F8G7nNrap0Q/introducing-indexeddb-shim-over-websql.html" title="Introducing - IndexedDB Shim over WebSql" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/05/introducing-indexeddb-shim-over-websql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYDR3w_fip7ImA9WhVVF0s.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-2036846444646686644</id><published>2012-05-12T01:42:00.003+05:30</published><updated>2012-05-12T01:42:56.246+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-12T01:42:56.246+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="indexeddb" /><title>IndexedDB setVersion vs onupgradeneeded</title><content type="html">&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;Try out the latest version of the plugin - &lt;a href="http://nparashuram.com/jquery-indexeddb/test/" target="_blank"&gt;http://nparashuram.com/jquery-indexeddb/test/ &lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
The &lt;a href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html" target="_blank"&gt;latest specification of IndexedDB&lt;/a&gt; has removed the setVersion method and uses the newupgradeneeded method instead. In an &lt;a href="http://blog.nparashuram.com/2012/03/jquery-plugin-for-indexeddb-api-version.html" target="_blank"&gt;older post&lt;/a&gt;, I had written about this change to the &lt;a href="https://github.com/axemclion/jquery-indexeddb" target="_blank"&gt;jquery-indexeddb plugin&lt;/a&gt;. However, Chrome still does not support the onupgradeneeded method and hence, the new version of jquery indexeddb plugin had to have a &lt;a href="https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/jquery.indexeddb.new.js" target="_blank"&gt;different name&lt;/a&gt;.&lt;br /&gt;
Over the past few weeks, I was able to work on some code that would wrap the indexeddb.open() method to allow the onupgradeneeded method. Instead of deeply coupling the setVersion-onupgradeneeded shim with the jquery plugin, I was able to get it to work as an independent shim that could also be used with standard IndexedDB applications.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Using the shim&lt;/span&gt; &lt;br /&gt;
To use the shim, simply include &lt;a href="https://gist.github.com/2656808" target="_blank"&gt;this javascript&lt;/a&gt;, and instead of calling window.indexedDB.open, call openReqShim. The events fired would be onsuccess, onerror, onblocked, and onupgradeneeded, as in the specification. The onupgradeneeded would have a versionTransaction that can be used to create/delete objectStores or Indexes.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Inside the shim&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
A database is opened when the openReqShim() call is made, very similar to indexedDB.open() call. The database name, and an optional database version are passed to this call, similar to the original call. The call returns the IDBRequest object. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;For Firefox &lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
In case of firefox, when the database is opened with the specified version greater than the database version, the onupgradeneeded method is called. This call is passed to the callback specified by the user. This is followed by a call to onsuccess, that is also passed to the user's onsuccess function.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;For Chrome&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
In case of chrome, the onupgradeneeded function is not called. The database's onsuccess function is called. Here, the existence of the setVersion method is checked. If the method exists, and the specified version is greater than the database version, a the setVersion method is called. The onsuccess of the setVersion's request call invokes the user's onupgradeneeded method with the version transaction. Once the method completes, the versionTrasnaction is committed by closing the database. The database is opened again with the latest version and this is passed to the onsuccess defined by the user.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Future&lt;/span&gt;&lt;br /&gt;
The above shim tries to make the programming interface for the IndexedDB API confirm to the specification for Chrome. The latest version of the specification has also deprecated constants like IDBTransaction.READ_WRITE, replacing them with string constants like "readwrite". This change is currently available in Firefox Aurora and Chrome Canary, and I am working on it now, so you can watch out &lt;a href="http://blog.nparashuram.com/search/label/indexeddb" target="_blank"&gt;this space&lt;/a&gt; for any updates. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/2656808.js?file=IndexedDB.setVersionShim.js"&gt;
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-2036846444646686644?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/MILpPASOTmg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/2036846444646686644/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/05/indexeddb-setversion-vs-onupgradeneeded.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/2036846444646686644?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/2036846444646686644?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/MILpPASOTmg/indexeddb-setversion-vs-onupgradeneeded.html" title="IndexedDB setVersion vs onupgradeneeded" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/05/indexeddb-setversion-vs-onupgradeneeded.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcNRXY_eSp7ImA9WhVVFkQ.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-8022987981999243767</id><published>2012-05-11T00:00:00.000+05:30</published><updated>2012-05-11T04:51:34.841+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-11T04:51:34.841+05:30</app:edited><title>Running QUnit tests sequentially in order</title><content type="html">&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;Download &lt;a href="https://gist.github.com/2561465" target="_blank"&gt;QueuedUnit.js&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Unit_testing" target="_blank"&gt;Wikipedia defines Unit Tests&lt;/a&gt; as a method to test individual pieces of code independently. This basically implies that the order in which the &lt;a href="http://docs.jquery.com/QUnit" target="_blank"&gt;QUnit tests&lt;/a&gt; run should not really matter. However, there could be cases where such tests may have to run in order and it is not very easy to do so on QUnit.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Use Case&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
There could be cases where you would like tests to run in order for better coverage, or simply because you have to write lesser setup/tear down code for each case. I have been working on a &lt;a href="http://nparashuram.com/IndexedDB" target="_blank"&gt;couple&lt;/a&gt; of API-centric &lt;a href="http://nparashuram.com/jquery-indexeddb/" target="_blank"&gt;projects&lt;/a&gt; and I found that I could be lazy and write lesser code if I could get the tests to run in order. &amp;nbsp; The projects, &lt;a href="http://nparashuram.com/IndexedDB/polyfill/" target="_blank"&gt;IndexedDB WebSql Shim&lt;/a&gt; and a &lt;a href="http://nparashuram.com/jquery-indexeddb/" target="_blank"&gt;jquery plugin for IndexedDB&lt;/a&gt; have tests where a database is first created, and sample data entered, and the subsequent tests use this setup to iterate over or search for data.&lt;/div&gt;
&lt;div&gt;
Alternatively, I could have written a common set up method that creates the mock database for every test.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Experiment&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
Looking at &lt;a href="http://jsfiddle.net/axemclion/zwXBx/" target="_blank"&gt;this code snippet&lt;/a&gt; the QUnit tests are written such that they are started long after (100&amp;nbsp;milliseconds) the script tag is encountered. This causes the first test to run, but then, the order of the tests becomes 1,4,3,2.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
If the time interval is reduced to something like 10 milliseconds, the test execution order now changes to 1,2,3,4.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
I tried playing with QUnit.config.autostart, QUnit.config.autorun, but none of them seem to get the tests to execute in order.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Solution&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
To get it working quickly, I had to brew my own solution, and the result was just a &lt;a href="https://gist.github.com/2561465" target="_blank"&gt;tiny framework&lt;/a&gt;. The gist simply loads the tests, one after another. The only changes from traditional QUnit async tests would be&amp;nbsp; &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Replace asyncTest with queuedAsyncTest(). &lt;/li&gt;
&lt;li&gt;Replace module() with queuedModule().&amp;nbsp;&lt;/li&gt;
&lt;li&gt;At all points that the test is over, the nextTest() function should be called to add the next test to the queue.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Once the tests are all ready to run, call nextText(), to start running test 1.&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
A timeout method checks if the current test has finished in time, and if it has not, the current test simply fails and it moves on to the next text. &lt;br /&gt;
Here is the modified code snippet working with the QueuedUnit function calls.&lt;br /&gt;
&lt;br /&gt;
Compare the test results - &lt;a href="http://jsfiddle.net/axemclion/zwXBx/embedded/result/" target="_blank"&gt;Before&lt;/a&gt; and &lt;a href="http://jsfiddle.net/axemclion/Jw4fb/embedded/result" target="_blank"&gt;After.&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Issues&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
The requirement to call nextTest() to start the next test seems annoying. Also, if nextTest() is not specified, QUnit simply stops, unaware if the test passed of failed, but these are errors similar to a missing start() that can be avoided. &lt;br /&gt;
&lt;br /&gt;
You can grab &lt;a href="https://raw.github.com/gist/2561465/QueuedUnit.js"&gt;QueuedUnit.js&lt;/a&gt; on github, and leave a comment letting us know if it helped you become lazier:). After all, lazy testing is better than no testing!! &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-8022987981999243767?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/Rt4HdtTl0jI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/8022987981999243767/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/05/running-qunit-tests-sequentially-in.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/8022987981999243767?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/8022987981999243767?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/Rt4HdtTl0jI/running-qunit-tests-sequentially-in.html" title="Running QUnit tests sequentially in order" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/05/running-qunit-tests-sequentially-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4NQ3k6eCp7ImA9WhVVFko.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-7383463527890982740</id><published>2012-04-27T00:58:00.000+05:30</published><updated>2012-05-11T01:13:12.710+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-11T01:13:12.710+05:30</app:edited><title>Buccolingual positioner (and CSS3 transforms)</title><content type="html">While placing a dental&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Dental_implant" target="_blank"&gt;implant&lt;/a&gt;, a dental surgeon must decide on the position and the angle of placement in the jaw bone among other things, and this needs to be communicated to the lab. The &lt;a href="https://www.3dclickguide.com/" target="_blank"&gt;3D Click guide&lt;/a&gt; is a model-based guided implant placement technology. As detailed on &lt;a href="https://www.3dclickguide.com/lab.htm" target="_blank"&gt;this page&lt;/a&gt;, the placement of the BLP is a surgical decision and one way to do it was to use it is layers in Photoshop.&lt;br /&gt;
If you are wondering, you are not on a dental blog, this is just a prelude to a project that I have been working on. It all started when &lt;a href="http://abcdentistry.blogspot.com/" target="_blank"&gt;Dr. Vidhya&lt;/a&gt; was introduced to the &lt;a href="https://www.3dclickguide.com/index.htm" target="_blank"&gt;3D click guide&lt;/a&gt; technique by &lt;a href="http://www.stumpeldds.com/MeettheDoctor.aspx" target="_blank"&gt;Dr. Lambert Stumpel&lt;/a&gt;. She noticed that the technique could use some more optimization in the way the placement of the implant is communicated with the lab. Photoshop was a really big tool and expecting labs to have Photoshop just to view the angle and placement that the dental surgeon wants. If you are still interested in learning about what the actual process was, you could check out this &lt;a href="https://www.3dclickguide.com/docs/3DCG-as-a-servive-on-the-web.pdf" target="_blank"&gt;presentation&lt;/a&gt;. &lt;br /&gt;
Seeing me working on HTML5, &lt;a href="http://abcdentistry.blogspot.com/" target="_blank"&gt;Vidhya&lt;/a&gt; realized that this is something that CSS3 Transforms and HTML5 could solve, and wanted to develop a web based approach that would make the communication a lot easier.&lt;br /&gt;
She came up with the design and requirements of the project and I decided to take a jab at writing code. The tools is live (with examples) on &lt;a href="http://drvidhya.github.com/blp/" target="_blank"&gt;github&lt;/a&gt;, and on the &lt;a href="https://www.3dclickguide.com/lab-tool/" target="_blank"&gt;site&lt;/a&gt;. Now to the CSS3 part of the tool. &lt;br /&gt;
The computer science part of the problem was the ability to resize, move and position an image on top of another image. Once it is done, the whole setup needs to be saved.&lt;br /&gt;
JQuery UI could be used to drag and resizer but it fails when CSS rotation is applied to it - the resize and drag handles do not interact well with the mouse. I started working on rolling out my own version of a library that could do this, but then stumbled across &lt;a href="http://vremenno.net/examples/jquery-ui-rotation/" target="_blank"&gt;this work&lt;/a&gt; by &lt;a href="http://vremenno.net/" target="_blank"&gt;Pavel Markovnin&lt;/a&gt;. The library basically tracks mouse drag and changes the image based on the resizee or rotation handles. Some changes to the library and I got it working for my requirement.&lt;br /&gt;
The harder part was get capture the final work, and save it as an image. Drawing the background image on a canvas was simple, the trick was in the way the foreground smaller image (called blp) had to be drawn. For getting the rotation, the transform&lt;a href="https://github.com/drvidhya/blp/blob/gh-pages/index.js#L114" target="_blank"&gt; css property&lt;/a&gt; returns the martix. This matrix can be directly applied to the canvas using the canvas context.&lt;a href="https://github.com/drvidhya/blp/blob/gh-pages/index.js#L130" target="_blank"&gt;transform&lt;/a&gt; property. However, the library applies rotation with the rotation origin being the center of the image; this is more natural when rotating the image. Canvas transforms however start at top left of the image, and hence, this difference has to be &lt;a href="https://github.com/drvidhya/blp/blob/gh-pages/index.js#L129" target="_blank"&gt;corrected&lt;/a&gt;. Also, the jQuery offset function seemed to return different values for a rotate image in Firefox 11 and Firefox 12, Chrome, etc. This additional quirk had to be take care of, before the image was obtained using canvas.toDataUrl.&lt;br /&gt;
With the image, the surgeon can send it to the lab for implementation. Thanks to &lt;a href="http://www.linkedin.com/in/vidhyavenkat" target="_blank"&gt;Dr. Vidhya&lt;/a&gt;, the BLP process is one step easier - no more Photoshop installs; just a simple web based approach to make it better !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-7383463527890982740?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/ywh7cT5pfQY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/7383463527890982740/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/04/buccolingual-positioner-and-css3.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7383463527890982740?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7383463527890982740?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/ywh7cT5pfQY/buccolingual-positioner-and-css3.html" title="Buccolingual positioner (and CSS3 transforms)" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/04/buccolingual-positioner-and-css3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANRXc7eyp7ImA9WhVTFUU.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-7912635491797217829</id><published>2012-03-01T12:39:00.000+05:30</published><updated>2012-03-01T12:39:54.903+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-01T12:39:54.903+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="indexeddb" /><title>JQuery plugin for IndexedDB API - version upgrade</title><content type="html">A new version of the Jquery library for IndexedDB API has been released and here are some useful links for you to get started.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The Javascript file - &lt;a href="https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/jquery.indexeddb.new.js"&gt;jquery.indexeddb.new.js&lt;/a&gt;. Will be renamed to &lt;a href="https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/jquery.indexeddb.js" target="_blank"&gt;jquery.indexeddb.js&lt;/a&gt; when all browsers support it. &lt;/li&gt;
&lt;li&gt;Detailed &lt;a href="https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/docs/README.md"&gt;API documentation &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nparashuram.com/jquery-indexeddb/example/"&gt;Example&lt;/a&gt; on using the new library&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nparashuram.com/jquery-indexeddb/test/"&gt;Test cases&lt;/a&gt; to see if the library runs on your browser.&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
In my &lt;a href="http://blog.nparashuram.com/2012/02/indexeddb-examples-updated-for-firefox.html"&gt;last post&lt;/a&gt;, I had written about the updates to the &lt;a href="http://nparashuram.com/trialtool/index.html#example=/IndexedDB/trialtool/moz_indexedDB.html"&gt;examples&lt;/a&gt; for IndexedDB based on the latest version supported on Firefox 12. The most significant change was the removal of the setVersion method and introduction on the &lt;a href="http://www.w3.org/TR/IndexedDB/#widl-IDBOpenDBRequest-onupgradeneeded"&gt;onupgradeneeded&lt;/a&gt; paradigm. This method gives us a new perspective on how we manage object stores and indexes in IndexedDB. &lt;br /&gt;
Over the past few days, I have also updated the &lt;a href="https://github.com/axemclion/jquery-indexeddb"&gt;Jquery plugin for IndexedDB&lt;/a&gt; to reflect this change. Though the "onupgradeneeded" method is only available in Firefox as of now, other browsers will soon implement it. The new version of the library is currently implemented as &lt;a href="https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/jquery.indexeddb.new.js"&gt;jquery.indexeddb.new.js&lt;/a&gt; but will eventually be called &lt;a href="https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/jquery.indexeddb.js"&gt;jquery.indexeddb.js&lt;/a&gt;. Note that for now, the file jquery.indexeddb.js still points to the older version that works with the implementation of IndexedDB in the stable versions of the browser.&lt;br /&gt;
In addition to adding support of onupgradeneeded, some other parts of the API have also changed. Here is the structure of the new API.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;$.indexedDB(database_name) is the way to open the database to the latest version&lt;/li&gt;
&lt;li&gt;$.indexedDB(database_name, schema) initializes the database with the schema.&lt;/li&gt;
&lt;li&gt;$.indexedDB(db_name).transaction(store_names).progress(transactionMethod) can be used to enclose a set of CRUD operations in a transaction.&lt;/li&gt;
&lt;li&gt;transaction.createObjectStore() can be used to create object stores inside the transaction method.&lt;/li&gt;
&lt;li&gt;$.indexedDB(db).objectStore(name).add() is a shorthand for creating a transaction with just the single add operation.&lt;/li&gt;
&lt;li&gt;$.indexedDB(db).objectStore(name).each() can be used to iterate over the objects in the store.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;$.indexedDB(db).objectStore(name, true) is a short hand to create an object store if it does not exist.&lt;/li&gt;
&lt;/ul&gt;
For a detailed list of APIs, you can take a look at the &lt;a href="https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/docs/README.md" target="_blank"&gt;API documentation&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;
As indicated in the &lt;a href="http://blog.nparashuram.com/2011/04/indexeddb-jquery-plugin.html" target="_blank"&gt;original blog post&lt;/a&gt; about the guidelines for this API,&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;The API has a good support for method chaining for quick and shorthand operations without having to write boiler plate code like in the native IndexedDB API. &lt;/li&gt;
&lt;li&gt;Another example of short hand operations is the use of implicit transactions using the .objectStore() syntax. Not all IndexedDB CRUD operations have to be explicitly in a transactions. &lt;/li&gt;
&lt;li&gt;Use of Jquery Deferreds makes it gel well with other parts of Jquery and frameworks that use Jquery.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Errors bubble up the method chain and hence are not required to be checked at every step of the API.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Smart defaults in the form of range, direct, automatic object store creation, etc, make it easy to start using the API without sacrificing the flexibility.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
If you have a&amp;nbsp; live project that is data intensive and where it makes sense to cache some data at the client, you could give this plugin a try. However, it may take some time before the IndexedDB implementation in browsers itself is ready for production.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-7912635491797217829?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/KwfsC46voFg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/7912635491797217829/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/03/jquery-plugin-for-indexeddb-api-version.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7912635491797217829?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7912635491797217829?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/KwfsC46voFg/jquery-plugin-for-indexeddb-api-version.html" title="JQuery plugin for IndexedDB API - version upgrade" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/03/jquery-plugin-for-indexeddb-api-version.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQFSXw8fyp7ImA9WhRbEk0.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-7521903154743419049</id><published>2012-02-02T22:51:00.003+05:30</published><updated>2012-02-02T22:51:58.277+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-02T22:51:58.277+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="indexeddb" /><title>IndexedDB Examples updated for Firefox 11 - onupgradeneeded method</title><content type="html">&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;Link to &lt;a href="http://nparashuram.com/trialtool/index.html#example=/IndexedDB/trialtool/moz_indexedDB.html"&gt;IndexedDB examples (FF 11.0a)&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
The latest &lt;a href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html"&gt;editor's draft of IndexedDB&lt;/a&gt; has been revised with changes to manage versions of the database better using the &lt;a href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#widl-IDBOpenDBRequest-onupgradeneeded"&gt;onupgradeneeded&lt;/a&gt; method. &lt;br /&gt;
The onupgradeneeded method seems so obvious in &lt;a href="https://twitter.com/#%21/SickingJ/status/164763462759759872"&gt;hindsight&lt;/a&gt; and it is a great way to manage database versions, providing migration paths. Like traditional databases, the schema of IndexedDB would change over time with requirements to create additional stores and indexes. However, unlike traditional databases, these databases are distributed may not be able to follow a simple, single step upgrade path.&lt;br /&gt;
For example&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Some users would have a version of 1, and return to the website when the version is upgraded to 2, and then to 3, etc.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;There may also be users who were on version 1, but would return to the website when the latest version is 7. The IndexedDB for such users would have to be guided through a migration path that runs the steps for upgrade in each version.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
The onupgrademethod callback will simply have migration code for all versions of IndexedDB, making database migration easier. You can take a look at the examples here - http://nparashuram.com/trialtool/index.html#example=/IndexedDB/trialtool/moz_indexedDB.html&lt;br /&gt;
&lt;br /&gt;
The onupgradeneededmethod is supported in Firefox 11.0a Aurora. It is still not available in Google Chrome 18.0.1025.2 canary yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-7521903154743419049?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/kiNuvROrBVQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/7521903154743419049/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/02/indexeddb-examples-updated-for-firefox.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7521903154743419049?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7521903154743419049?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/kiNuvROrBVQ/indexeddb-examples-updated-for-firefox.html" title="IndexedDB Examples updated for Firefox 11 - onupgradeneeded method" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/02/indexeddb-examples-updated-for-firefox.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYESH8yfCp7ImA9WhRVGEs.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-5217321642785575548</id><published>2012-01-18T11:09:00.001+05:30</published><updated>2012-01-18T11:25:09.194+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-18T11:25:09.194+05:30</app:edited><title>Wikipedia - Unblackout</title><content type="html">Just noticed that &lt;a href="http://en.wikipedia.org/wiki/Wikipedia:SOPA_initiative/Learn_more"&gt;Wikipedia blacked out&lt;/a&gt;.&lt;br /&gt;
The bad news is - &lt;b&gt;Wikipedia is blacked out. &lt;/b&gt;Knowledge as we know it, ceases to exist :(&amp;nbsp; &lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
The good news is, they are still sending the content (respect to Wikipedia for this) but just hiding it with Javascript. They have not become what they are fighting !! &lt;br /&gt;
&lt;br /&gt;
So, fully supporting what Wikipedia says, here is a a quick bookmarklet to view the contents on Wikipedia.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="javascript:(function(){var%20x%20=%20['mw-head-base',%20'mw-page-base',%20'mw-head',%20'mw-panel','content','footer'];for%20(i%20=%200;%20i%20&amp;lt;%20x.length;%20i++){window.document.getElementById(x[i]).style.display%20=%20&amp;quot;block&amp;quot;;%20document.getElementById('mw-sopaOverlay').style.display='none'}})();"&gt;UnblackOut Wikipedia&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
To see contents of Wikipedia,&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Drag the above link (that says UnblackOut Wikipedia) and drop in in your bookmarks or favourites toolbar. It becomes a bookmarklet. &lt;/li&gt;
&lt;li&gt;Visit Wikipedia and click the bookmarklet.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Become aware on why Wikipedia has blacked out - &lt;a href="http://en.wikipedia.org/wiki/Wikipedia:SOPA_initiative/Learn_more"&gt;http://en.wikipedia.org/wiki/Wikipedia:SOPA_initiative/Learn_more&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-5217321642785575548?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/Fallqsfs0nM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/5217321642785575548/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2012/01/wikipedia-unblackout.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/5217321642785575548?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/5217321642785575548?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/Fallqsfs0nM/wikipedia-unblackout.html" title="Wikipedia - Unblackout" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.nparashuram.com/2012/01/wikipedia-unblackout.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QFQ3c5fip7ImA9WhRRFEo.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-6249450572305628182</id><published>2011-11-28T15:30:00.000+05:30</published><updated>2011-11-28T15:45:12.926+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-28T15:45:12.926+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="indexeddb" /><title>IndexedDB APIs &amp; Javascript.Next</title><content type="html">Of the various specifications that are considered a part of HTML5, the &lt;a href="http://www.w3.org/TR/IndexedDB/"&gt;IndexedDB API&lt;/a&gt; is one of the few APIs that are independent of the DOM and are impacted by Javascript. It would be an interesting to analyze the impact of newer Javascript features to this API set. &lt;br /&gt;
This post looks at current features of ECMA5 in addition to &lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:proposals"&gt;proposals&lt;/a&gt; in Harmony. I had previously &lt;a href="http://blog.nparashuram.com/2011/11/jsfoo-bangalore-session-videos-and.html"&gt;posted&lt;/a&gt; slides for a talk on IndexedDB and the last slide touched briefly about this. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:modules"&gt;&lt;span style="font-size: large;"&gt;Modules&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
The module pattern has been widely accepted as a useful feature, thanks to CommonJS and specifically NodeJS implementations. Today, the IndexedDB object is a property of the global Window or WebWorker Objects. With modules, IndexedDB can be included into the code using something like require("IndexedDB") for async and require("IndexedDBSync") for the sync version of the API. With this distinction, will developers be allowed to use the sync version in non-web worker environments also? &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/b/ie/archive/2011/09/11/asynchronous-programming-in-javascript-with-promises.aspx"&gt;&lt;span style="font-size: large;"&gt;Promises&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
Like modules, the promises pattern is also gaining traction. Currently, all Async operations on IndexedDB are on a IDBRequest Object. Should IDBRequest be changed to follow the Promises pattern?&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Transaction Scope with &lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:block_scoped_bindings"&gt;Let and Var&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
With the changes in variable scopes using the let and var keywords, transaction scope will also be impacted. Transactions today &lt;a href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#dfn-commit"&gt;auto-commit&lt;/a&gt; when the transaction variable goes out of scope and no more requests can be placed against it. With the Let statement, this could happen sooner inside blocks allowing even shorter transactions. This would also avoid closure related confusions in transaction scopes. This would also ensure that transactions variables are not leaked into the global scope. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:iterators"&gt;&lt;span style="font-size: large;"&gt;Iterators&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
Iterating
 over a cursor today is done using a cursorRequest. Similar syntax should be used 
for iterating over cursors. The cursor.continue could be replaced with 
the iterator next method and the cursor could be treated as a 
collection. However, it would be interesting to see how the update and 
delete method on the cursor change for the new iterator pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:generator_expressions"&gt;Generator Expressions&lt;/a&gt; and &lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions"&gt;Array Comprehensions&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
While
 iterating over cursors, developers mostly perform some operations on 
the current item.Generator expressions are based on array comprehensions
 and make sense here, given the asynchronous nature of the API. 
Additionally, Array functions like each, filter, some, etc could also 
eliminate a lot of cursor boiler plate code.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:destructuring"&gt;&lt;span style="font-size: large;"&gt;Destructuring Assignments&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
Continuing
 the discussion about cursors, the cursor.value and cursor.key return 
the key and the value respectively. However, restructuring assignments like [key, value] = cursor.continue() would help extract the keys and values easily. Similarly, doing something like [objectValue, key] = objectStore.get(id) could also be a useful notation. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:binary_data"&gt;Binary Blobs&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
With the introduction of Binary Blobs, specially for file, WebGL and devices API, it would be interesting to see how 
the databases (LevelDB or SQLite) store binary data and how they impact 
the quotas. I am guessing that indexing based on Binary Data would not 
be possible in the near future. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;READ_WRITE/READ transaction modes and &lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies"&gt;Object Freeze/Seal&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
Objects
 can be frozen or sealed to prevent them from being manipulated. In case
 of a READ transaction, the object obtained with a get or in cursors 
could be sealed and frozen to indicated that it was obtained from a READ
 transaction as opposed to a READ_WRITE transaction. This may however be
 an extreme way to indicate the transaction type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies"&gt;&lt;span style="font-size: large;"&gt;Object Getters and Setters&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
With objects now having the ability define custom getters and setters, developers can use this method to provide a transparent abstraction that persists objects when properties are changed or loaded from a database when objects are read. Combining this with a Hibernate like query language could do ORM-magic that are traditionally done only with server-side languages. However, the logic on when to do (lazy vs eager) an async write or read would require some thought. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:classes"&gt;&lt;span style="font-size: large;"&gt;Classes&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
With the introduction of classes, it would be interesting to see schema for Object Stores. This may also change the way IndexedDB implementations could possibly change the way objects are stored internally. For example, IndexedDB on Firefox stored Blob for objects in SQLite today.&lt;br /&gt;
&lt;br /&gt;
I have not come across similar documentation that discusses how IndexedDB works with new constructs in Javascript and I think this is an interesting topic of discussion. Please leave your opinions in the comments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-6249450572305628182?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/IFg8AJHpJME" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/6249450572305628182/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/11/indexeddb-apis-javascriptnext.html#comment-form" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6249450572305628182?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6249450572305628182?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/IFg8AJHpJME/indexeddb-apis-javascriptnext.html" title="IndexedDB APIs &amp; Javascript.Next" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>13</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/11/indexeddb-apis-javascriptnext.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YMQno5cSp7ImA9WhRRFEo.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-6641796403242471136</id><published>2011-11-15T20:04:00.001+05:30</published><updated>2011-11-28T15:43:03.429+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-28T15:43:03.429+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="techtalks" /><title>jsFoo Bangalore - Session Videos and Slides</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://jsfoo.hasgeek.com/img/logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://jsfoo.hasgeek.com/img/logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;
I was speaking at jsFoo, Bangalore and here are the videos from the sessions&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;h3&gt;


Designing the IndexedDB API&lt;/h3&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="480" src="https://www.youtube.com/embed/yZ4GBSk2aKQ?rel=0" width="640"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;div id="__ss_9505387" style="width: 595px;"&gt;
&lt;b style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/axemclion/indexed-db" target="_blank" title="Indexed DB"&gt;Indexed DB&lt;/a&gt;&lt;/b&gt; &lt;iframe frameborder="0" height="497" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/9505387?rel=0" width="595"&gt;&lt;/iframe&gt; &lt;br /&gt;
&lt;h3&gt;


Understanding Javascript Engines &lt;/h3&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="480" src="https://www.youtube.com/embed/CmMf67mam9g?rel=0" width="640"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;div id="__ss_9505402" style="width: 510px;"&gt;
&lt;b style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/axemclion/understanding-javascript-engines" target="_blank" title="Understanding Javascript Engines "&gt;Understanding Javascript Engines &lt;/a&gt;&lt;/b&gt; &lt;iframe frameborder="0" height="497" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/9505402?rel=0" width="595"&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-6641796403242471136?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/lgD9bHjKHCA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/6641796403242471136/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/11/jsfoo-bangalore-session-videos-and.html#comment-form" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6641796403242471136?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6641796403242471136?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/lgD9bHjKHCA/jsfoo-bangalore-session-videos-and.html" title="jsFoo Bangalore - Session Videos and Slides" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/yZ4GBSk2aKQ/default.jpg" height="72" width="72" /><thr:total>7</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/11/jsfoo-bangalore-session-videos-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUABQHY_eCp7ImA9WhdaFk0.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-3972173447879028565</id><published>2011-10-26T10:56:00.000+05:30</published><updated>2011-10-26T11:12:31.840+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-26T11:12:31.840+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="trialtool" /><category scheme="http://www.blogger.com/atom/ns#" term="windows8" /><title>Developing Apps for Windows 8 - My Experiences and Opinions</title><content type="html">&lt;span style="font-size: x-small;"&gt;Disclaimer: The views expressed in this post are my own and do not reflect any opinions of my employer. The app was written using publicly available resources as an Independent developer.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;A few posts ago, I had written about the &lt;a href="http://blog.nparashuram.com/2011/10/trialtool-for-windows-8.html"&gt;TrialTool app for Windows 8&lt;/a&gt;. &lt;a href="http://nparashuram.com/projects/trialtool.html"&gt;TrialTool&lt;/a&gt; is a web based application that illustrates the capabilities of various Javascript APIs. It is like an API playground that lets you view, modify and run examples and this version of TrialTool specifically illustrates the various Windows 8 APIs. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;1. Background&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
The app was developed on&lt;a href="http://msdn.microsoft.com/en-us/windows/home/"&gt; Windows 8 Developer Preview&lt;/a&gt; with Visual Studio 11 Express. The entire application was written using HTML5, CSS and Javascripht. The tool does not exhaustively cover all APIs yet, but the APIs used are a good representative of the programming model in Windows 8.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;2. Development Environment&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
My primary IDE is &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; or &lt;a href="http://ace.ajax.org/"&gt;Cloud9&lt;/a&gt; and this was actually the first time I have used Visual Studio exclusively for an end to end project.&lt;br /&gt;
The application starts from choosing a pre-defined project type or a simple blank JS template in Visual Studio. The templates do a good job of creating the skeleton and filling in the boiler plate code. As with any skeletons, it may be hard to navigate the multiple files created as a part of the template for a newbie. Once you know your way around the files and the parts to edit, the templates are good. Unfortunately, looks like Visual Studio is the only option for now as I was not able to find any &lt;span style="color: #38761d;"&gt;command line utilities that I could use with Eclipse or &lt;/span&gt;&lt;a href="http://notepad-plus-plus.org/" style="color: #38761d;"&gt;Notepad++&lt;/a&gt;&lt;span style="color: #38761d;"&gt; to build, package or deploy the project&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;3. Writing Code&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Starting with a blank project is similar to writing a web page from scratch. Using a template however starts us off with the &lt;a href="http://en.wikipedia.org/wiki/Metro_%28design_language%29"&gt;Metro Style UI&lt;/a&gt;. TrialTool used the grid layout template that starts with an "index" page that displays a list of items. Each item can be clicked to take us to a "details" page.&lt;br /&gt;
The Javascript files created by the template recommend using &lt;a href="https://developer.mozilla.org/en/JavaScript/Strict_mode"&gt;strict mode&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;3.1 Single Page application &lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
The app created is inherently an equivalent of one-page website. Navigation from the "index" page to a "details" page results in the details being loaded as a DOM fragment. Loading and unloading events give us control over the content to be displayed on each action. The &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br229774%28v=VS.85%29.aspx"&gt;WinJS&lt;/a&gt; module defines events that let us access the &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br212679%28v=VS.85%29.aspx"&gt;activate&lt;/a&gt; or DOM fragment &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br229840%28v=VS.85%29.aspx"&gt;load&lt;/a&gt; events for navigation in addition to events for layout changes (portrait to landscape mode for tablets, re-size, etc. )&lt;br /&gt;
I noticed that the by default, files of type HTML, CSS and JS had a directory each. &lt;span style="color: #38761d;"&gt;I would prefer to group files by modules instead of file type; file types are distinguished by their extension anyway&lt;/span&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;3.2 CSS Grids &lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
The use of ms-grid to define the metro UI is great. &lt;a href="http://www.w3.org/TR/css3-grid-layout/"&gt;Grid layout for CSS&lt;/a&gt; are still in work in progress. Tiles are an prime to the Metro UI and the implementation of ms-grid makes building tiles in Metro UI is a lot easier. &lt;br /&gt;
Vendor prefix would be removed in the final version I guess.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;3.3 Data Binding&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
The Templates also have support for &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br229775%28v=VS.85%29.aspx"&gt;data binding&lt;/a&gt;. With the data-win-* attributes in a the HTML tags, render views can be defined. These render views can define specific controls (like ListView) and options for these controls. JSON data can be loaded via AJAX and use these "itemRenderers". &lt;br /&gt;
The concepts here are very similar to frameworks like &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone&lt;/a&gt;. However, some features like automatically changing the view when data changes, etc needs to explicitly coded unlike backbone. A way to point a itemRenderer to a URL would be even better. &lt;br /&gt;
Another feature that I would like to have is the ability to &lt;span style="color: #38761d;"&gt;declare formats in the item renderers&lt;/span&gt;. Currently, the data from the model can be converted, but that seems to be manual. &lt;span style="color: #38761d;"&gt;A data-win-option on individual elements to specify the format would be good&lt;/span&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;3.4 Promises&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
All asynchronous operations (like AJAX, File reading, etc) seem to return promises. This is definitely better for an interactive event driven application. The "async" keywork in C# &lt;br /&gt;
is the equivalent.&lt;br /&gt;
The documentation for the promised could have been better. Looks like the documentation is written for C# and force fitted to Javascript. &lt;span style="color: #38761d;"&gt;For example, in an operation like&amp;nbsp;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.pickers.fileopenpicker.picksinglefileasync%28v=VS.85%29.aspx"&gt;FilePicker&lt;/a&gt;&lt;span style="color: #38761d;"&gt;, the return value is a&amp;nbsp;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.pickers.picksinglefileoperation%28v=VS.85%29.aspx"&gt;promise&lt;/a&gt;&lt;span style="color: #38761d;"&gt;. However, to see the actual arguments passed to the promise.then() method, you have to navigate to the "&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.pickers.picksinglefileoperation.getresults%28v=VS.85%29.aspx"&gt;GetResults&lt;/a&gt;&lt;span style="color: #38761d;"&gt;" method&lt;/span&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;u&gt;&lt;b&gt;4. Windows 8 APIs&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
The main reason I would write a Windows 8 app (apart from store distribution) would be to use the Windows 8 APIs; otherwise, the app may as well be a web site viewed in the Metro IE. &lt;br /&gt;
Working with native Windows 8 APIs in Javascript is no different manipulating DOM using native DOM methods. Popping up a &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.notifications.toastnotifier%28v=VS.85%29.aspx"&gt;Windows 8 Toast&lt;/a&gt; is no different from invoking the native window.alert. Working with native File APIs, or cryptography is also very easy and straight forward.&lt;br /&gt;
The documentation on the &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br211377%28v=VS.85%29.aspx"&gt;Windows Runtime APIs&lt;/a&gt; is exhaustive but I would would have been more comfortable if they were &lt;span style="color: #38761d;"&gt;grouped better and the first list the over high level categories (like Storage) and then you could drill down to understand a specific API (Bulk Access or File properties)&lt;/span&gt;.  This would help since a lot of APIs have common concepts before we look at specific APIs. This was probably why I wrote TrialTool in the first place.  &lt;br /&gt;
The other issue I found was an example of&lt;span style="color: #38761d;"&gt; APIs that require features not present in the Javascript languag&lt;/span&gt;e. For example, &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streamreaderretrievaloperation.getresults%28v=VS.85%29.aspx"&gt;reading the contents of a file&lt;/a&gt; returns an &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.iinputstream%28v=VS.85%29.aspx"&gt;InputStream&lt;/a&gt; that does not seem to show any Javascript API. It is not very clear that &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.datareader%28v=VS.85%29.aspx"&gt;DataReader&lt;/a&gt; can in fact be used to read the data.&lt;br /&gt;
I wish that the&lt;span style="color: #38761d;"&gt; APIs converge to become similar to the&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.w3.org/TR/FileAPI/"&gt;HTML5 File/Blob APIs&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;u&gt;&lt;b&gt;5. Debugging&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
Debugging with Visual Studio is so good that you would not really miss &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; or &lt;a href="http://code.google.com/chrome/devtools/docs/overview.html"&gt;Web Developer&lt;/a&gt; toolbar. From basic features like support for logging to break points or inspecting the HTML source, the debugger is very powerful. I would recommend a dual monitor setup for for a better experience. &lt;br /&gt;
One feature that I found missing was a way to &lt;span style="color: #38761d;"&gt;profile (like &lt;/span&gt;&lt;a href="http://code.google.com/webtoolkit/speedtracer/get-started.html#quick-tour" style="color: #38761d;"&gt;Speed Tracer&lt;/a&gt;&lt;span style="color: #38761d;"&gt;) the Javascript app for performance issues&lt;/span&gt;. Adding to the wishlist would be a way to remotely debug an application (like &lt;a href="http://www.opera.com/dragonfly/"&gt;Opera dragonfly&lt;/a&gt; but that is a feature I would like in IE too).&lt;span style="color: #38761d;"&gt; Remote debugging may prove useful specially in case of tablets&lt;/span&gt;. &lt;br /&gt;
The usual annoyance of printing [object] with console.log still exists. It would be even better if we are able to &lt;span style="color: #38761d;"&gt;integrate console.log with Windows application or system logs during a production deployment&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;u&gt;&lt;b&gt;6. Packaging and Deployment&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
Though Visual Studio has a Store menu, looks like the Store is currently not available. The only option available today would be to create a local app. Packaging the app creates an appx file, a bat file and certificate file. Executing the bat file with Admin privileges install the application. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;u&gt;&lt;b&gt;7. Conclusion&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
For the Web Developers, the option of using HTML/CSS/JS for writing native windows 8 applications is definitely compelling. Existing web development knowledge can be put to use here, but to leverage the full power of the operating system, it is best to familiarize with the APIs that Windows8 provides. &lt;br /&gt;
Overall, a great approach in bringing web development to native applications - hope writing Android or iOS apps were this simple for a Web Developer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-3972173447879028565?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/nc3r_NfEvfU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/3972173447879028565/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/10/developing-apps-for-windows-8-my.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3972173447879028565?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3972173447879028565?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/nc3r_NfEvfU/developing-apps-for-windows-8-my.html" title="Developing Apps for Windows 8 - My Experiences and Opinions" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>8</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/10/developing-apps-for-windows-8-my.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8HQH48cSp7ImA9WhVXEEw.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-4106657181617894943</id><published>2011-10-24T10:30:00.000+05:30</published><updated>2012-04-10T04:53:51.079+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-10T04:53:51.079+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><title>Writing Browser Extensions - Comparing Firefox, Chrome and Opera</title><content type="html">&lt;a href="http://nparashuram.com/projects/flashresizer.html"&gt;MediaPlus&lt;/a&gt; is a browser extension that gives users more control over media elements like video, images, games, flash, etc by allowing them to move, resize, download, magnify and perform other actions on them. &lt;br /&gt;
Writing an&lt;a href="http://en.wikipedia.org/wiki/Browser_extension"&gt; extension for browsers&lt;/a&gt; is very similar to writing web pages that work across browsers - similar concepts but interesting quirks along the way; hence this post. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;1. Background&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;a href="http://blog.nparashuram.com/2011/07/mediaplus-20.html"&gt;MediaPlus&lt;/a&gt; started as a browser &lt;a href="http://en.wikipedia.org/wiki/Bookmarklet"&gt;bookmarklet&lt;/a&gt; that injected some javascript into the current web page. This javascript was responsible for identifying various media elements like flash, images, etc and mark them as actionable. When the user needs to interact with a specific media content, they move the mouse over the media content and a panel with various actions shows up. This is the core functionality of MediaPlus.&lt;br /&gt;
In addition to the above functionality, MediaPlus also needs to provide interaction points to start, suspend or stop the plugin. All these actions are folded into the bookmarklet button on the browser. &lt;br /&gt;
As an browser extension for Firefox, Opera and Chrome, MediaPlus provides these extension points. This post deals with the similarities and differences in the extension system of the three browsers.&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;The comparison boxes below are color coded to indicate the parts I felt was &lt;span style="background-color: #d9ead3;"&gt;best/easiest&lt;/span&gt; against &lt;span style="background-color: #f4cccc;"&gt;worst/hardest&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;For Firefox, the &lt;a href="https://addons.mozilla.org/en-US/developers/builder"&gt;jetpack&lt;/a&gt; way of writing extensions was used. A browser extension for Safari is under development and I am still learning to write extensions for Internet Explorer; these would be possibly covered in future posts. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;2. Parts of an extension - Concepts&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;The basic concepts of building an extension as very similar.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0" style="background-color: #d9ead3;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Chrome looks to be inspired by &lt;a href="http://en.wikipedia.org/wiki/Greasemonkey"&gt;Greasemonkey&lt;/a&gt; way of building things - just making the thing better. &lt;/td&gt;&lt;td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Opera is heavily influenced by &lt;a href="http://www.w3.org/TR/widgets/"&gt;W3C Widgets&lt;/a&gt;&lt;/td&gt;&lt;td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Firefox Heavily borrows from &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/dev-guide/addon-development/commonjs.html"&gt;commonjs&lt;/a&gt;, specifically the modules part.&amp;nbsp;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;Note that all the three browsers support userscripts, thanks to their architecture.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;2.1 Manifest File&lt;/span&gt;&lt;/b&gt; &lt;br /&gt;
All extensions start with a manifest file. This is the file that defines the basic behavior of the extension.&lt;br /&gt;
&lt;br /&gt;
They are called &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.2/dev-guide/addon-development/package-spec.html"&gt;package.json&lt;/a&gt;, &lt;a href="http://www.opera.com/docs/apis/extensions/configxmlresourceguide/"&gt;config.xml&lt;/a&gt; and &lt;a href="http://code.google.com/chrome/extensions/overview.html#H3-5"&gt;manifest.json&lt;/a&gt; in Firefox, Opera and Chrome respectively that define the name, version, description, author, icons, permissions and other meta-data about the extension. Though they are similar, Opera interestingly chooses XML over JSON. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;2.2 Additions to Browser Interface&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The manifest file also defines the different controls that the extension will add to to the Browser UI. This include things like Context Menu Items, Toolbar buttons and other panels.&lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0" style="border-collapse: collapse; border: none; width: 100%;"&gt;
 &lt;tbody&gt;
&lt;tr&gt;
  &lt;td style="background-color: #fff2cc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;For chrome, these are usually included statically in the manifest. Interface elements include context menus, URL bar plugins, menu items, etc. &lt;/td&gt;
 &lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Opera seems to be better as they provide flexibility of adding browser 
interface elements during run-time. The interface is defined in 
index.html along with its actions for clicking the button, etc. &lt;/td&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Firefox is also similar to Opera where the browser interaction elements are specified in the main module. This allows more actions to be specified by the extension based on the page. &lt;/td&gt;
 &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;2.3 Content Scripts&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The core of MediaPlus rests in the script that is injected into the page. This is called a content script or injected script. &lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Chrome is the simplest as Javascript and CSS can be inserted at any point using an API call.&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;td style="background-color: #fce5cd; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;br /&gt;
Opera does not have a direct way to inject
 script and hence, AJAX requests are made to the extension to read the 
script content and then inject it dynamically as HTML content.Opera includes all scripts in the includes folder as a part of the page. This however means that &lt;a href="http://www.opera.com/docs/apis/extensions/injectedscriptsguide/"&gt;injecting scripts&lt;/a&gt; dynamically become hard.&amp;nbsp;
&lt;/td&gt;&lt;td style="background-color: #f4cccc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Firefox provides &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.2/packages/addon-kit/docs/page-mod.html"&gt;page-mod&lt;/a&gt;
 that includes scripts. Injecting scripts into specific tabs with similar URLs using a 
page-mod is hard that forced MediaPlus to use the same mechanism 
employed in Opera where scripts were read and written with HTML tags.&amp;nbsp;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
In all three browsers, content scripts do not share the run time with the page for security reasons. Extensions usually can do more (like access local file system, cross domain ajax etc) than a script inside a webpage and hence the security boundary.&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;2.4 Background Processes and Message Passing &lt;/span&gt;&lt;/b&gt; &lt;br /&gt;
A background page is a singleton javascript loaded once in the browser that is responsible for background operations and other house keeping activities. All the three browsers have this concept with different ways to pass messages between content scripts, browser interaction parts and the background script.&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="background-color: #fff2cc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Chrome again provides the simplest model of &lt;a href="http://code.google.com/chrome/extensions/messaging.html"&gt;message passing&lt;/a&gt; using simple APIs. Messages can be relayed between content scripts, background process and browser UI (panels, popups, etc.).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Messages are handled using simple message listeners. There are also concepts of long and short lived connections. &lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;td style="background-color: #fce5cd; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Opera strictly follows the W3C &lt;a href="http://dev.opera.com/articles/view/opera-extensions-messaging/"&gt;message passing &lt;/a&gt;mechanism with Channels. Though complex, this is more powerful, providing events "onconnect", to actually start listening to a specific channel.&amp;nbsp; &lt;/span&gt;&lt;/span&gt;
&lt;/td&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Firefox seemed to be the most powerful with message passing had both channels and events. The best past of Firefox was the ability to add an &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/dev-guide/addon-development/events.html"&gt;event listener&lt;/a&gt; ("onMyMsg") to specific messages and just act on it, thus avoiding switch case.&lt;/span&gt;&lt;/span&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;3. Coding&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Any standard HTML and Javascript editor can be used for creating these extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Chrome has a dedicated &lt;span id="goog_2140219749"&gt;&lt;/span&gt;developer dashboard
 that can be used to point to the extension directory. Making changes to 
code requires hitting a reload button on the "Manage Extensions" to 
ensure that the latest code is running.&lt;/td&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;In case of Opera, the config.xml can simply be dropped onto the Opera 
Window (in developer mode) and the entire directory structure is picked 
up. Hitting the reload button is require here too.&amp;nbsp;
&lt;/td&gt;&lt;td style="background-color: #f4cccc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.2/dev-guide/addon-development/installation.html"&gt;Setting up&lt;/a&gt;
 the development environment for Firefox is the hardest given that 
Jetpack extensions are actually compiled to XPI. This also means that 
any change would mean compiling and reloading the extension - something 
not native to web developers. 
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;
The issue with Firefox may be attributed to the fact that Jetpack extensions are actually compiled to the XPI that Firefox understands. &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;4. Debugging&lt;/span&gt;&lt;/b&gt;&lt;/u&gt; &lt;br /&gt;
Once the extension is written, the ability to trace through the code and see log messages helps a log in Debugging.&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Chrome here steals the show with its web developer toolbar. With a single interface, all parts of the extension including the background process, content script and browser UI can be &lt;a href="http://code.google.com/chrome/extensions/tut_debugging.html"&gt;debugged&lt;/a&gt;. The simple console.log prints all messages in the console. &lt;/td&gt;&lt;td style="background-color: #fff2cc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Injected Scripts in Opera can be debugged with breakpoints using Dragonfly. However,&amp;nbsp; I have noticed that tracing through background index.html or browser UIs seems hard. The opera.postError is required to post messages to the Opera Error console - and it does not live well with JSON. &lt;/td&gt;&lt;td style="background-color: #fff2cc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;span style="background-color: #fff2cc;"&gt;Possibly a result of its development experience, debugging in Firefox can be hard. However, I ensured that I always pointed to a profile directory that had Venkman and Firebug. This way, I could actually debug all parts of the extension.&amp;nbsp; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;5. Publishing&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Once the extension is ready, it needs to be published to a place where users can discover and download the extension. All the three browser have a store like interface where users can discover and download the extensions. In case of all three stores, screenshots, icons and videos have to be provided in specific dimensions as required by the stores. &lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;The extension simply needs to be zipped and uploaded to the store.&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://code.google.com/chrome/webstore/docs/index.html"&gt;Chrome store&lt;/a&gt; seems to be the most mature of them. &lt;br /&gt;
There is also support for a payment system. &lt;br /&gt;
You extension needs to get approved before it is actually visible on the store.&lt;br /&gt;
The store is also one single place for apps, themes, etc.&amp;nbsp; &lt;/td&gt;&lt;td style="background-color: #fff2cc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;The OEX file (zip of extension files needs to be uploaded) &lt;br /&gt;
The Opera Store has a great/quick approval process too.&lt;br /&gt;
I have not seen the support for payments in the store. &lt;br /&gt;
&lt;br /&gt;&lt;/td&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;&lt;span style="background-color: #fff2cc;"&gt;&lt;span style="background-color: #d9ead3;"&gt;The packaged XPI file is uploaded to the store. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fff2cc;"&gt;&lt;span style="background-color: #d9ead3;"&gt;Given that Firefox had extensions even before some of the other browsers existed, it has a great eco-system of extensions.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fff2cc;"&gt;&lt;span style="background-color: #d9ead3;"&gt;Though they are no "payments", donations are supported for developers.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: #fff2cc;"&gt;&lt;span style="background-color: #d9ead3;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Auto-updating the extension when a new version is available is also great in all three browsers. All the three also provide support for hosting the extensions at places other their store with support for auto-update URLs.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;5. Analytics&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Post publication, a mechanism is needed to monitor the traffic and downloads to the extension. &lt;br /&gt;
&lt;br /&gt;
&lt;table border="1" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style="background-color: #d9ead3; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;The store page for Chrome is can be integrated with Google Analytics, providing it with great analytics. &lt;br /&gt;
Apart from traffic sources, downloads and weekly installs, with user comments are also available. &lt;/td&gt;&lt;td style="background-color: #f4cccc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Analytics in Opera store is pretty basic. Ratings, download count and user comments are the only available features. &lt;br /&gt;
Download per &lt;br /&gt;
&lt;br /&gt;&lt;/td&gt;&lt;td style="background-color: #fff2cc; border: 1pt solid windowtext; padding: 0cm 5.4pt; text-align: left; width: 260.2pt;" valign="top" width="347"&gt;Though firefox is not integrated with any powerful analytics, it does provide details like visits and downloads per time. It seems to be an in house version of an analytics system. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;6. Conclusion&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
To conclude, all the three browsers strive to provide and most powerful yet simple platforms for developing extensions. Though there are not standards (like for web pages), each browser tries their best to infer from existing ways of doing things.&lt;br /&gt;
Note that this article derive from my experiences of building MediaPlus and I may not have touched upon all aspects of extension writing.&lt;br /&gt;
&lt;br /&gt;
You can download MediaPlus for your browsers from the following links. &lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;&lt;a href="http://nparashuram.com/projects/flashresizer.html"&gt;http://nparashuram.com/projects/flashresizer.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
Edit: As people pointed out, the article deals only with building extensions for Firefox using Jetpack. You can build extensions without Jetpack, but that cannot be compared to what Opera and Chrome offer.  &lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-4106657181617894943?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/GF4odrLl2lQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/4106657181617894943/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/10/writing-browser-extensions-comparing.html#comment-form" title="19 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/4106657181617894943?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/4106657181617894943?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/GF4odrLl2lQ/writing-browser-extensions-comparing.html" title="Writing Browser Extensions - Comparing Firefox, Chrome and Opera" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>19</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/10/writing-browser-extensions-comparing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYBQXw-fCp7ImA9WhdaEUs.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-1853654975514691735</id><published>2011-10-18T13:20:00.000+05:30</published><updated>2011-10-21T08:32:30.254+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-21T08:32:30.254+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><title>Some Kudos for MediaPlus</title><content type="html">&lt;div style="text-align: center;"&gt;
Some kudos for MediaPlus&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-mXhZ7IVJ5ho/TqDgqjV95jI/AAAAAAAACn4/ar3t2Pk5QkA/s1600/262388_10150235866316647_730461646_7528409_1433917_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-mXhZ7IVJ5ho/TqDgqjV95jI/AAAAAAAACn4/ar3t2Pk5QkA/s1600/262388_10150235866316647_730461646_7528409_1433917_n.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-2dvTx14y2xY/TqDgriVUk-I/AAAAAAAACoA/3GFjAQxZxvw/s1600/269870_10150235866021647_730461646_7528408_7082652_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="382" src="http://4.bp.blogspot.com/-2dvTx14y2xY/TqDgriVUk-I/AAAAAAAACoA/3GFjAQxZxvw/s640/269870_10150235866021647_730461646_7528408_7082652_n.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
Some direct feedback on PostIt Notes :) &lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-TChCe4l61Mk/Tp0vPC8QfkI/AAAAAAAACno/Ueu2gsXNEpE/s1600/Image001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://3.bp.blogspot.com/-TChCe4l61Mk/Tp0vPC8QfkI/AAAAAAAACno/Ueu2gsXNEpE/s640/Image001.jpg" width="425" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-9P27dEYB8Ww/Tp0vQfoeQgI/AAAAAAAACnw/43eI-xk2N3s/s1600/Image002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://3.bp.blogspot.com/-9P27dEYB8Ww/Tp0vQfoeQgI/AAAAAAAACnw/43eI-xk2N3s/s640/Image002.jpg" width="425" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-1853654975514691735?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/OOev8WewR9s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/1853654975514691735/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/10/some-kudos-for-mediaplus.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/1853654975514691735?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/1853654975514691735?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/OOev8WewR9s/some-kudos-for-mediaplus.html" title="Some Kudos for MediaPlus" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-mXhZ7IVJ5ho/TqDgqjV95jI/AAAAAAAACn4/ar3t2Pk5QkA/s72-c/262388_10150235866316647_730461646_7528409_1433917_n.jpg" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/10/some-kudos-for-mediaplus.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cFSHg8fip7ImA9WhdbFEQ.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-6992504628472339325</id><published>2011-10-13T15:13:00.003+05:30</published><updated>2011-10-13T15:13:39.676+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-13T15:13:39.676+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="trialtool" /><category scheme="http://www.blogger.com/atom/ns#" term="windows8" /><title>TrialTool for Windows 8</title><content type="html">&lt;span style="font-size: x-small;"&gt;&lt;a href="http://nparashuram.com/projects/trialtool.html"&gt;TrialTool&lt;/a&gt; is a web based application that illustrates the capabilities of various Javascript APIs. It is like an API playground that lets you view, modify and run examples and see the output right inside the browser. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A few days back,&amp;nbsp; Microsoft released the &lt;a href="http://msdn.microsoft.com/en-us/windows/home/"&gt;Windows 8 Developer Preview&lt;/a&gt; that would give developers a peek into the next version of the operating system and to start &lt;a href="http://msdn.microsoft.com/en-us/windows/apps/"&gt;developing applications&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
HTML, CSS and Javascript was one of the ways to build Windows 8 native applications. The list of APIs in the &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br211369%28v=VS.85%29.aspx"&gt;reference&lt;/a&gt; was huge and I wanted a way to not just read but also play around with the APIs to understand and experience them. To this end, I ported the web version of TrialTool to illustrate the various Windows 8 APIs available.&lt;br /&gt;
&lt;br /&gt;
The video below is a &lt;a href="http://www.youtube.com/watch?v=qPkqNeciVNQ"&gt;screencast&lt;/a&gt; of how TrialTool looks like, on Windows 8 Developer Preview. 
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="480" src="https://www.youtube.com/embed/qPkqNeciVNQ?hd=1" width="640"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;br /&gt;
As show in the video above, you can browse through various sets of examples. You can click on an individual example, view the corresponding code, modify it and run it inline. &lt;br /&gt;
TrialTool is also &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.search%28v=VS.85%29.aspx"&gt;integrated with Windows Search&lt;/a&gt;. You can hit "Windows Key" + F to bring up the search panel, type in the name of the API to search and select TrialTool from the list of applications to directly navigate to the API you are interested in.&lt;br /&gt;
TrialTool is also a Windows 8 &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.datatransfer.sharetarget%28v=VS.85%29.aspx"&gt;Share Target&lt;/a&gt;. While reading MSDN documentation or looking at code sent over email or IMs, you can select the code, bring up the Start menu (usually at bottom left) and click Share. You can select TrialTool from the list of listed applications. The selected code is shown in a "code cache". You can select and add more code to the code cache and see how the snippets work. With this capability, not only can you just read documentation, you can actually see how the API works. &lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://metrialtool.codeplex.com/"&gt;project&lt;/a&gt; and the &lt;a href="http://metrialtool.codeplex.com/SourceControl/changeset/view/2589#"&gt;source code&lt;/a&gt; are available on codeplex. If you have an installation of Windows 8, simply &lt;a href="http://metrialtool.codeplex.com/releases/view/74989"&gt;download the zip file&lt;/a&gt; and run the bat file with Administrator privileges. &lt;br /&gt;
&lt;br /&gt;
As seen in the video above, not all APIs are shown yet; I am working to make more APIs available. I am also working on adding features like syntax coloring and a better search, etc for this version of TrialTool for Windows 8.&lt;br /&gt;
If you are interested in helping out, please &lt;a href="http://nparashuram.com/contact.html"&gt;contact me&lt;/a&gt;. &amp;nbsp; &lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-6992504628472339325?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/ncM2S9NXmdE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/6992504628472339325/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/10/trialtool-for-windows-8.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6992504628472339325?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6992504628472339325?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/ncM2S9NXmdE/trialtool-for-windows-8.html" title="TrialTool for Windows 8" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/qPkqNeciVNQ/default.jpg" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/10/trialtool-for-windows-8.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UER3cyeSp7ImA9WhRRFEo.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-3003147814855513891</id><published>2011-10-02T08:21:00.000+05:30</published><updated>2011-11-28T15:43:26.991+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-28T15:43:26.991+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="techtalks" /><title>jsFoo - Bangalore</title><content type="html">I was at the &lt;a href="http://jsfoo.hasgeek.com/"&gt;jsFoo Conference, Bangalore&lt;/a&gt; yesterday. &lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://jsfoo.hasgeek.com/img/logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://jsfoo.hasgeek.com/img/logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I had two sessions, one on IndexedDB and the other on how Javascript Engines work. Here are the attached slides. The videos of the sessions will be made available shortly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;div style="width:500px; text-align:center" id="__ss_9505387"&gt; &lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/axemclion/indexed-db" title="Indexed DB" target="_blank"&gt;Indexed DB&lt;/a&gt;&lt;/strong&gt; &lt;iframe src="http://www.slideshare.net/slideshow/embed_code/9505387" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;div style="padding:5px 0 12px"&gt; View more &lt;a href="http://www.slideshare.net/" target="_blank"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/axemclion" target="_blank"&gt;Parashuram Narasimhan&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;


&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="width:500px; text-align:center" id="__ss_9505402"&gt; &lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/axemclion/understanding-javascript-engines" title="Understanding Javascript Engines " target="_blank"&gt;Understanding Javascript Engines &lt;/a&gt;&lt;/strong&gt; &lt;iframe src="http://www.slideshare.net/slideshow/embed_code/9505402" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;div style="padding:5px 0 12px"&gt; View more &lt;a href="http://www.slideshare.net/" target="_blank"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/axemclion" target="_blank"&gt;Parashuram Narasimhan&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;
&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-3003147814855513891?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/Ke7yxQ9HCXA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/3003147814855513891/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/10/jsfoo-bangalore.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3003147814855513891?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3003147814855513891?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/Ke7yxQ9HCXA/jsfoo-bangalore.html" title="jsFoo - Bangalore" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/10/jsfoo-bangalore.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIEQnw6fCp7ImA9WhdVGU8.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-1500960254920710683</id><published>2011-09-25T09:33:00.000+05:30</published><updated>2011-09-25T09:35:03.214+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-25T09:35:03.214+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><category scheme="http://www.blogger.com/atom/ns#" term="flash resizer" /><title>MediaPlus - Firefox addon</title><content type="html">&lt;div style="text-align: center;"&gt;
&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/mediaplus/"&gt;&lt;span style="font-size: large;"&gt;Install MediaPlus for Firefox&amp;nbsp; &lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The last two posts described &lt;a href="http://nparashuram.com/projects/flashresizer.html"&gt;MediaPlus&lt;/a&gt; as a &lt;a href="http://bit.ly/chromemediaplus"&gt;Chrome&lt;/a&gt; and an &lt;a href="https://addons.opera.com/en/addons/extensions/details/mediaplus"&gt;Opera&lt;/a&gt; extension. To extend the browser matrix, MediaPlus is now ported to work as a Mozilla &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/mediaplus/"&gt;Firefox extension&lt;/a&gt;. As described in the &lt;a href="http://blog.nparashuram.com/2011/09/mediaplus-opera-extension.html"&gt;previous post&lt;/a&gt;, the core functionality of MediaPlus is to interact and change the contents of the web page. The peripheral functionality like stopping the plugin, re-scanning the page, etc are invoked using the browser addon UI. &lt;br /&gt;
The MediaPlus add on for Firefox uses the new &lt;a href="https://addons.mozilla.org/en-US/developers/builder"&gt;Jetpack&lt;/a&gt; way to write "no-restart" plugins. The &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.1/dev-guide/addon-development/getting-started.html"&gt;concepts&lt;/a&gt; are very similar to writing extensions on Opera or Chrome - &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;A singleton background page that runs as a background process. For firefox, this is the lib/main.js &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.1/dev-guide/addon-development/commonjs.html"&gt;CommonJS&lt;/a&gt; module. &lt;/li&gt;
&lt;li&gt;Pop out icon and the corresponding pop out &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.1/packages/addon-kit/docs/panel.html"&gt;panel&lt;/a&gt; defined in the main.js file.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.1/dev-guide/addon-development/web-content.html"&gt;Content Scripts&lt;/a&gt;, also defined in the background page. &lt;/li&gt;
&lt;/ul&gt;
As expected of the browsers, there are also significant differences and this post talks about the interesting issues that were tackled to get the firefox extension working. &lt;br /&gt;
First, there is no direct way to inject script into webpages dynamically. Though the &lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.1/packages/addon-kit/docs/page-mod.html"&gt;page_mod &lt;/a&gt;allows script injections into the web page, the page_mod cannot be changed to add more scripts later. Unfortnately, page_mods also do not share the execution context and hence, cannot communicate in a straightforward way. Hence, scripts are added to the webpage when the pop out are clicked using the&lt;a href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.1/packages/addon-kit/docs/tabs.html#attach%28options%29"&gt; tabs.activeTab.attach&lt;/a&gt; method by adding a script tag to the page. The source of this script is obtained using the data.url method, relative to the extension. &lt;br /&gt;
To communicate with these added scripts, the (ugly) unsafeWindow method is used. Since no "trusted" addon methods are leaked while using the unsafeWindow, the security concerns should be addressed. &lt;br /&gt;
The scripts added in this way are inserted into the page immediatly. This turns out to be a problem if the target webpage is still loading. Once the web page finishes loading, all the injected scripts are replaced with the new content. The icon needs to be clicked again to start the add on. Though the&lt;span id="goog_473266137"&gt;&lt;/span&gt;&lt;a href="http://draft.blogger.com/"&gt; tabs.on(ready)&lt;span id="goog_473266138"&gt;&lt;/span&gt;&lt;/a&gt; method exists, this is only invoked once the page has completed loading. Hence, we would need logic to re-load the scripts again, when the onReady (DOMContentLoaded) event is fired. I could also not find a way to unbind this event and hence, this seems to be fired for every navigation on the web page; another ugly solution. The onready could remember the all the tabs for which it was fired, but that it just too much housekeeping for now. For now, you would have to click on "Start MediaPlus" again, after the page has loaded to activate it.&lt;br /&gt;
Though the message passing was not as simple as Chrome, it looked better than the way things are done in Opera, with custom events in addition to the message channel.&lt;br /&gt;
&lt;br /&gt;
The source for Firefox extension is available &lt;a href="http://code.google.com/p/flashchrome/source/browse/?name=#hg%2Fextensions%2Ffirefox"&gt;here&lt;/a&gt; and you can &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/mediaplus/"&gt;download the addon&lt;/a&gt; from here. Follow &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;this space&lt;/a&gt; for updates on MediaPlus as a bookmarklet or as an extension for browsers. If you have suggestions or have found bugs, you can contact me &lt;a href="http://nparashuram.com/contact.html"&gt;here&lt;/a&gt; for help.&lt;br /&gt;
I have also&amp;nbsp; made the statistics for the addon public and you could see the number of users, downloads, etc &lt;a href="https://addons.mozilla.org/en-US/statistics/addon/337401"&gt;here&lt;/a&gt;. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-1500960254920710683?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/RZRPE8oYTRY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/1500960254920710683/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/09/mediaplus-firefox-addon.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/1500960254920710683?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/1500960254920710683?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/RZRPE8oYTRY/mediaplus-firefox-addon.html" title="MediaPlus - Firefox addon" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/09/mediaplus-firefox-addon.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04HQX4zeip7ImA9WhdVFks.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-5452551054213384271</id><published>2011-09-22T11:07:00.001+05:30</published><updated>2011-09-22T11:08:50.082+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-22T11:08:50.082+05:30</app:edited><title>DocType HTML5 - Chennai Edition - CSS3 and Presentations</title><content type="html">&lt;center&gt;My session on CSS3 and Presentation at &lt;a href="http://www.doctypehtml5.in/"&gt;doctypeHTML5&lt;/a&gt;, Chennai &lt;br/&gt;&lt;br/&gt;

&lt;iframe allowfullscreen="" frameborder="0" height="442" src="http://blip.tv/play/hrQIgs_tfwI.html" width="550"&gt;&lt;/iframe&gt;&lt;embed src="http://a.blip.tv/api.swf#hrQIgs_tfwI" style="display: none;" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;


Link - &lt;a href="http://blip.tv/doctype-html5/css3-and-presentation-5502619"&gt;http://blip.tv/doctype-html5/css3-and-presentation-5502619&lt;/a&gt; &lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-5452551054213384271?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/zPxWzwg9oAw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/5452551054213384271/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/09/doctype-html5-chennai-edition-css3-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/5452551054213384271?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/5452551054213384271?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/zPxWzwg9oAw/doctype-html5-chennai-edition-css3-and.html" title="DocType HTML5 - Chennai Edition - CSS3 and Presentations" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/09/doctype-html5-chennai-edition-css3-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQBQHc8eCp7ImA9WhdVGU8.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-6040508367615766949</id><published>2011-09-19T07:17:00.001+05:30</published><updated>2011-09-25T09:15:51.970+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-25T09:15:51.970+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><category scheme="http://www.blogger.com/atom/ns#" term="flash resizer" /><title>MediaPlus - Opera Extension</title><content type="html">&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;a href="https://addons.opera.com/en/addons/extensions/details/mediaplus"&gt;&lt;span style="font-size: large;"&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: large;"&gt;&lt;a href=""&gt;Install MediaPlus for Opera&lt;/a&gt;  &lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
The &lt;a href="http://blog.nparashuram.com/2011/09/mediaplus-as-chrome-extension.html"&gt;previous post&lt;/a&gt; discussed &lt;a href="http://nparashuram.com/projects/flashresizer.html"&gt;MediaPlus&lt;/a&gt; as a &lt;a href="http://bit.ly/chromemediaplus"&gt;Google Chrome Extension&lt;/a&gt;. MediaPlus lets users mpdify and take control of media content on web pages. It lets uses move, resize and change media content on the web page; all these tasks are about changing content on a web page. The &lt;a href="http://blog.nparashuram.com/2011/07/mediaplus-20.html"&gt;bookmarklet&lt;/a&gt; version of MediaPlus inserts a javascript file in a webpage and this script is responsible for displaying the charms on images or flash videos when the mouse is moved over them. &lt;br /&gt;
In addition to this core functionality, MediaPlus also has additional actions like stopping it, rescanning the page for dymanically adding content or simply turning off full screen. In case of the bookmarklet, these actions are initiated by clicking the bookmarklet again. In the case of an extension, these options can be available off an icon in the browser UI, outside the web page.&lt;br /&gt;
The Google Chrome extension does exactly this - the core functionality is handled by a content injected into the web page while the peripheral functions are displayed in a pop out panel as a part of the browser UI. Writing an extension using Opera is very similar to writing a Chrome extension. In short, the extenion has three basic parts&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;A singleton &lt;a href="http://dev.opera.com/articles/view/accessing-an-opera-extensions-background-process/"&gt;background page&lt;/a&gt; with scripts, included in index.html and the background.js referred in the index file. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.opera.com/docs/apis/extensions/popupguide/"&gt;Pop out&lt;/a&gt; button and corresponding popout.html, defined in the index.html &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.opera.com/docs/apis/extensions/injectedscriptsguide/"&gt;Content script&lt;/a&gt; in the includes directory that are injected into all web pages. &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
There are also two differences and here is how they are solved for the Opera extension. First, passing messages between the pop out and the content script is not simple and requires a background script to broker the connection the first time. &lt;a href="http://dev.opera.com/articles/view/opera-extensions-messaging/"&gt;This article&lt;/a&gt; explains how it is achieved. &lt;br /&gt;
The second issue is that external stylesheets scripts are not injected into the page using API calls, but by placing the script inside the includes folder. This unfortunately means that it is harder to inject dynamic scripts in a page. The first version injects scripts by referring to external URL, but this practice is frowned upon. The latest version does the following. The scripts can be injected by reading them using XHR using paths relative to the extension root and inserting them as textContent of script tags in the web page. Since the content scripts seem to have access to the global window object of the web page, they can communicate with the injected scripts. Note that Google Chrome separates the execution context of the web page and the content script. &lt;br /&gt;
To load images dynamically, they are added as img elements in the background page, drawn on a canvas, and the base64 &lt;a href="http://en.wikipedia.org/wiki/Data_URI_scheme"&gt;data:url&lt;/a&gt; returned by the canvas.&lt;a href="http://www.w3.org/TR/html5/the-canvas-element.html#dom-canvas-todataurl"&gt;toDataURL&lt;/a&gt; is passed back to the content script. The content script sets the data:uri as the source of the image to be drawn. Background images referred using external stylesheets are still not loaded. External stylesheets (like jquery UI css) have to be changed to have data:uri before building the runtime. &lt;br /&gt;
The Opera extension is available for download &lt;a href="https://addons.opera.com/en/addons/extensions/details/mediaplus"&gt;here&lt;/a&gt; and source code is available &lt;a href="http://code.google.com/p/flashchrome/source/browse/?name=#hg%2Fextensions%2Fopera%253Fstate%253Dclosed"&gt;here&lt;/a&gt;. To follow MediaPlus, check out this &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;page&lt;/a&gt;. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-6040508367615766949?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/ECUvWDvY8Jg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/6040508367615766949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/09/mediaplus-opera-extension.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6040508367615766949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6040508367615766949?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/ECUvWDvY8Jg/mediaplus-opera-extension.html" title="MediaPlus - Opera Extension" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/09/mediaplus-opera-extension.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04ARn06eSp7ImA9WhdWFUk.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-3843495160373023766</id><published>2011-09-09T12:02:00.001+05:30</published><updated>2011-09-09T12:02:27.311+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-09T12:02:27.311+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><category scheme="http://www.blogger.com/atom/ns#" term="flash resizer" /><title>MediaPlus as a Chrome Extension</title><content type="html">&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;a href="http://bit.ly/chromemediaplus"&gt;&lt;span style="font-size: large;"&gt;Install the MediaPlus for Google Chrome &lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
I had written about &lt;a href="http://nparashuram.com/projects/flashresizer.html"&gt;MediaPlus&lt;/a&gt;, a bookmarklet that gives you more control over media contents like Flash videos, images, games, HTML5 movies, etc. in my &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;previous posts&lt;/a&gt;. Though the &lt;a href="http://blog.nparashuram.com/2011/07/mediaplus-20.html"&gt;bookmarklet&lt;/a&gt; was powerful, it has some shortcomings inherent to bookmarklets. Many people hide the bookmarks toolbar on their browser to get more browsing space. Additionally, though the concept of adding a bookmark is known, bookmarklets with their javascript: protocol and adding them to the toolbar is still not common. Finally, people also voiced a concern that clicking on the bookmarklet icon to perform multiple actions like toggling it, rescanning the page, etc was not intuitive. &lt;br /&gt;
MediaPlus only manipulates an the DOM of an existing webpage as a result of certain user actions. The &lt;a href="https://chrome.google.com/webstore/detail/emaamodndfmmmcjepfigalbjjjemadom"&gt;MediaPlus chrome extension&lt;/a&gt; provides a better user interface for triggering these user actions. It adds an icon next to the URL bar that needs to be clicked to interact with the extension. The rest of the post is about the technical details of the implementation.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/4ebpNh0xl3ADd1nFqpzW6kEEGZtOGfS_J-tSq0bx4lfjhpDCPsLiFtbwdT3nc-bTA7HPa7gc1g=s400-h275-e365" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="275" src="http://1.bp.blogspot.com/4ebpNh0xl3ADd1nFqpzW6kEEGZtOGfS_J-tSq0bx4lfjhpDCPsLiFtbwdT3nc-bTA7HPa7gc1g=s400-h275-e365" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Extensions for chrome can inject &lt;a href="http://code.google.com/chrome/extensions/content_scripts.html"&gt;content scripts&lt;/a&gt; in a running page that can interact and change the DOM. MediaPlus chooses not to inject these scripts for all pages, but does so only when the user first clicks the "Start MediaPlus" button. The scripts are &lt;a href="http://code.google.com/chrome/extensions/tabs.html#method-executeScript"&gt;loaded&lt;/a&gt; from the extension in a &lt;a href="http://code.google.com/chrome/extensions/background_pages.html"&gt;background page&lt;/a&gt;. Since the runtime provided to this script is isloated from the javascript environment of the page, scripts and the page can have their own versions of libraries like JQuery.&lt;br /&gt;
Once the script is loaded, all media elements (flash, canvas, image, video, iframe) have a class added to them. The mouseover event handler that is added as a part of injecting the script kicks in to display the possible actions on the media element. This is the exact same code path as for the bookmarklet.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/HCkZTHb9pPAfSklzqd2PgtijciQ2aT6FDhPHvnF2d32aBAz5p-MOGIWv2LzCvvZjrF5mxp_olQ=s400-h275-e365" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="250" src="http://4.bp.blogspot.com/HCkZTHb9pPAfSklzqd2PgtijciQ2aT6FDhPHvnF2d32aBAz5p-MOGIWv2LzCvvZjrF5mxp_olQ=s400-h275-e365" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The only deviation here is the way notifications are shown. Since chrome provides &lt;a href="http://www.html5rocks.com/en/tutorials/notifications/quick/"&gt;webkit notifications&lt;/a&gt;, these are used instead of manually using divs for the bookmarklets.&lt;br /&gt;
&lt;br /&gt;
When the user makes a video full screen or darkens the background, they may want to undo the action. In case of the bookmarklet, the bookmarklet icon in the toolbar needs to be clicked. In the case of the extension, clicking the icon brings up a menu that lets the user restore the media element to the previous state.&lt;br /&gt;
&lt;br /&gt;
Except for these changes, the code path is just like the bookmarklet. Infact, the bookmarklet and the extension share the same core codebase, as illustrated in the &lt;a href="http://code.google.com/p/flashchrome/source/browse/"&gt;source repository&lt;/a&gt;.The only additional work is to pass &lt;a href="http://code.google.com/chrome/extensions/messaging.html"&gt;message&lt;/a&gt; between the popup on clicking the icon and the content script injected in the page.&lt;br /&gt;
The extension is available on the &lt;a href="https://chrome.google.com/webstore/detail/emaamodndfmmmcjepfigalbjjjemadom"&gt;Chrome Web Store&lt;/a&gt; and do give me feedback on how you find it. The &lt;a href="http://bit.ly/mymediaplus"&gt;support page&lt;/a&gt; is here, and you can report bugs &lt;a href="http://code.google.com/p/flashchrome/issues/list"&gt;here&lt;/a&gt;.&lt;br /&gt;
Watch out &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;this page&lt;/a&gt; for more updates. &lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-3843495160373023766?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/dfcLoHe3q0A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/3843495160373023766/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/09/mediaplus-as-chrome-extension.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3843495160373023766?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3843495160373023766?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/dfcLoHe3q0A/mediaplus-as-chrome-extension.html" title="MediaPlus as a Chrome Extension" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/09/mediaplus-as-chrome-extension.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EGR3Y-fSp7ImA9WhdRF0w.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-4523153580086320324</id><published>2011-07-29T13:54:00.000+05:30</published><updated>2011-08-07T16:43:46.855+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-07T16:43:46.855+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><category scheme="http://www.blogger.com/atom/ns#" term="flash resizer" /><title>MediaPlus - Video and Image Enhancements</title><content type="html">&lt;a href="http://nparashuram.com/projects/flashresizer.html"&gt;MediaPlus&lt;/a&gt; now supports the ability to edit/enhance HTML5 Videos and Images.&lt;br /&gt;
To install MediaPlus with these enhanced functions, drag and drop the following bookmarklet to your favorites/bookmarks bar. &lt;br /&gt;
&lt;br /&gt;
&lt;script src="http://flashchrome.googlecode.com/hg/extensions/bookmarklets/install.js?name=tip&amp;amp;type=single&amp;amp;version=mpp-ip"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://blog.nparashuram.com/2011/07/mediaplus-20.html"&gt;previous post&lt;/a&gt; explains how to install MediaPlus as a &lt;a href="http://en.wikipedia.org/wiki/Bookmarklet"&gt;bookmarklet&lt;/a&gt; and how it can be used to move, resize or download media content on web sites. This post describes the additional functionality added to MediaPlus to perform enhancements like brightness, contrast, color adjustment, etc on images and videos.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Architecture&lt;/span&gt;&lt;br /&gt;
MediaPlus uses &lt;a href="http://www.pixastic.com/"&gt;Pixastic&lt;/a&gt; for manipulating the media content. An image or a canvas can directly be passed to the Pixastic &lt;a href="http://www.pixastic.com/lib/docs/"&gt;processor&lt;/a&gt;. Pixastic then &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#pixel-manipulation"&gt;reads&lt;/a&gt; the image data from the image or the canvas and manipulates it. It draws the final image on the target canvas.&lt;br /&gt;
In case of videos, MediaPlus passes a canvas to Pixastic instead of the actual video. MediaPlus continuously draws the latest frame of the video onto this canvas that is picked up by Pixastic for processing.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Limitations&lt;/span&gt;&lt;br /&gt;
Since pixastic relies on &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-getimagedata"&gt;getImageData&lt;/a&gt;, it is restricted by the same domain policy. The Canvas &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#security-with-canvas-elements"&gt;Security policies&lt;/a&gt; mandate that pixel data cannot be read from a canvas if content from a different domain have been drawn on the canvas. Unfortunately, a lot of popular websites host their video content on CDN servers that has domain, different from the page. This results in the  inability to manipulate HTML5 videos from youtube or facebook. &lt;br /&gt;
Most browsers also do not support the &lt;a href="http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing"&gt;CORS&lt;/a&gt; way to reading image data yet.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Workaround for Images&lt;/span&gt;&lt;br /&gt;
The same origin restriction also apply for images. However, Images can be converted to data:uris using a &lt;a href="http://pipes.yahoo.com/pipes/pipe.info?_id=dc306286cda25674752b1ae6b76835ca"&gt;web service&lt;/a&gt; and drawn on the canvas. Such images can then be manipulates as they are not from a different domain. However, the &lt;a href="http://pipes.yahoo.com/pipes/pipe.info?_id=dc306286cda25674752b1ae6b76835ca"&gt;data:uri web service&lt;/a&gt; can only manipulate images that are directly addressed using a URL. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Image Zoom&lt;/span&gt;&lt;br /&gt;
Another addition specific to images is the ability to magnify images. The image zoom works just like most image zoom plugins,&amp;nbsp; drawing a larger image inside the magnifying glass and moving it around with the magnifying glass is dragged over the image. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Next Steps&lt;/span&gt;&lt;br /&gt;
I am working on the ability to allow rotations and C&lt;a href="http://www.webkit.org/blog/386/3d-transforms/"&gt;SS3 3D transforms&lt;/a&gt; on videos and images. This is a little trickier as I would have to ensure that other functionlity like resizing or dragging continue to working on media content that is rotates in the z axis. Watch out the &lt;a href="http://flashchrome.googlecode.com/"&gt;project page&lt;/a&gt; or &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;this blog space&lt;/a&gt; for updates.&lt;br /&gt;
If you encounter bugs when using MediaPlus, you can &lt;a href="http://code.google.com/p/flashchrome/w/list"&gt;report&lt;/a&gt; them or &lt;a href="http://nparashuram.com/contact.html"&gt;contact me&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-4523153580086320324?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/dBxvTpoUrew" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/4523153580086320324/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/07/mediaplus-video-and-image-enhancements.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/4523153580086320324?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/4523153580086320324?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/dBxvTpoUrew/mediaplus-video-and-image-enhancements.html" title="MediaPlus - Video and Image Enhancements" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/07/mediaplus-video-and-image-enhancements.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ECQXs6fCp7ImA9WhdSEUg.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-7669528430952687018</id><published>2011-07-20T16:31:00.081+05:30</published><updated>2011-07-20T16:31:00.514+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-20T16:31:00.514+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><category scheme="http://www.blogger.com/atom/ns#" term="flash resizer" /><title>MediaPlus - Technical Details</title><content type="html">In my &lt;a href="http://blog.nparashuram.com/2011/07/mediaplus-20.html"&gt;previous post&lt;/a&gt;, I had written about a &lt;a href="http://nparashuram.com/projects/flashresizer.html"&gt;MediaPlus&lt;/a&gt; - a browser &lt;a href="http://en.wikipedia.org/wiki/Bookmarklet"&gt;bookmarklet&lt;/a&gt;. MediaPlus lets you control media content on websites better. This post talks about some of the interesting technical challenges that were encountered when rewriting it from &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;FlashPlus&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;The Basics&lt;/span&gt;&lt;br /&gt;
MediaPlus can be installed by dragging the &lt;a href="javascript:document.getElementsByTagName('head')[0].appendChild(document.createElement('script')).setAttribute('src','http://flashchrome.googlecode.com/hg/extensions/Bookmarklet.js?r=bookmarklet');"&gt;MediaPlus&lt;/a&gt; link to the browser bookmarks/favorites bar. When this bookmark is clicked while browsing a web page, a &lt;a href="http://code.google.com/p/flashchrome/source/browse/extensions/Bookmarklet.js"&gt;javascript file&lt;/a&gt; is inserted into that web page. This script is responsible for all the magic from drawing borders around elements to making videos full screen. Once the bookmarklet is loaded, it loads &lt;a href="http://code.google.com/p/flashchrome/source/browse/extensions/Bookmarklet.js#35"&gt;additional&lt;/a&gt; javascript and css modules dynamically. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Element Selectors&lt;/span&gt;&lt;br /&gt;
When the mouse is moved over supported (&lt;a href="http://en.wikipedia.org/wiki/Adobe_Flash"&gt;flash&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/HTML5_video"&gt;video&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Canvas_element"&gt;canvas&lt;/a&gt;, &lt;a href="http://www.w3.org/TR/html5/the-iframe-element.html"&gt;iframes&lt;/a&gt;, silverlight) target elements on a web page, the &lt;a href="http://code.google.com/p/flashchrome/source/browse/core/js/FlashPlus.js?spec=svnee5c57f57399bc810bb0e84bd83b129ea808f068&amp;amp;r=605e557e1b76d2d266aee04851a52feeea2833bb#15"&gt;border&lt;/a&gt; that lights up around the element with the toolbox at the bottom is the element selector. These element selectors are not one single div (with a border and the height and width of the target element), but four [divs] around the corners of the element (very similar to the &lt;a href="http://karmatics.com/aardvark/bookmarklet.html"&gt;Aardvark bookmarklet&lt;/a&gt;). Though a single element would do the job just as well, placing it below or above would interfere with mouse events of the target element. Additional jquery "&lt;a href="http://api.jquery.com/mouseenter/"&gt;mouseenter&lt;/a&gt;" events are directly added to these target elements to show up the selector. The selector element is redrawn around the target element every time the mouse enters a different target element. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Proxy Substitutes&lt;/span&gt;&lt;br /&gt;
The structure explained above seems to work for all elements except embedded flash, as some browsers draw flash above all elements to prevent &lt;a href="http://en.wikipedia.org/wiki/Clickjacking"&gt;clickjacking&lt;/a&gt;. Object and Embed tags also cannot hold &lt;a href="http://api.jquery.com/data"&gt;data&lt;/a&gt;. Just for the case of Flash, a proxy &amp;lt;div&amp;gt; is placed on top of the flash. To allow the Flash element to capture its mouse events as usual, the proxy div is "sent to back" as soon as the mouse enters it, bringing the Flash Element to the top. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Moving and Resizing Elements&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
When an element is resized or moved from its position, three things happen .&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A new proxy element &amp;lt;img&amp;gt; with the dimensions of the original  target element is inserted in its place to ensure that the parent of the  target element does not collapse when the target element is moved out  of its child hierarchy. &lt;/li&gt;
&lt;li&gt;The element is given an absolute position to allow the drag. &lt;/li&gt;
&lt;li&gt;The element is also re-attached directly under the body to ensure that overflow:hidden in the parent element does not prevent the target element from being moved around.&lt;/li&gt;
&lt;/ul&gt;When an element is reattached into the DOM hierarchy, it is reset. This is the reason for flash videos or games to restart when they are moved or re-sized. Unlike the older FlashPlus, this version ensures that only those elements that are moved are re-attached and hence restarted. This also ensures that the original page layout is undisturbed. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Next Action&lt;/span&gt;&lt;br /&gt;
Some actions like full screen or switch off lights hide all other elements. To restore the page to the state prior to the action, the bookmarklet link has to be clicked again. A button on the page could have done this job, but placing one may look ugly, especially when a video is full screen. Hence, some commands like full screen or switch-off-lights define a "next-action" that is executed when the bookmarklet is clicked again. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Support for tags&lt;/span&gt;&lt;br /&gt;
This newer version has a better support for &lt;a href="http://code.google.com/p/flashchrome/source/browse/core/js/Tags.js"&gt;tags&lt;/a&gt;, and the actions that can be performed on tags. Every tag is defined by a separate object that in turn declares the commands or actions (like move, full-screen, download) that can be performed on the object. Common actions are added using a mixin like pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To look at how MediaPlus works under the cover, you can check out the source code &lt;a href="http://code.google.com/p/flashchrome/source/browse/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-7669528430952687018?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/2ajXf7KYj1E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/7669528430952687018/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/07/mediaplus-technical-details.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7669528430952687018?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/7669528430952687018?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/2ajXf7KYj1E/mediaplus-technical-details.html" title="MediaPlus - Technical Details" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/07/mediaplus-technical-details.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIFQnk4eCp7ImA9WhdRE0o.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-115868973084181918</id><published>2011-07-18T16:27:00.003+05:30</published><updated>2011-08-03T17:25:13.730+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-03T17:25:13.730+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flashplus" /><category scheme="http://www.blogger.com/atom/ns#" term="flash resizer" /><title>MediaPlus 2.0</title><content type="html">&lt;div style="text-align: center;"&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;What is MediaPlus?&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://bit.ly/mymediaplus"&gt;MediaPlus &lt;/a&gt;is a plugin for your web browser that makes media content on web site easier to use. It gives you control to move or resize videos, play flash games in full screen or popout content to a new window. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Media Content, huh ? &lt;/b&gt;&lt;br /&gt;
Media Content here refers to &lt;a href="http://en.wikipedia.org/wiki/Adobe_Flash"&gt;Flash&lt;/a&gt; videos and games, HTML5 &lt;a href="http://en.wikipedia.org/wiki/HTML5_video"&gt;Videos&lt;/a&gt;, HTML5 &lt;a href="http://en.wikipedia.org/wiki/Canvas_element"&gt;Canvas&lt;/a&gt; and &lt;a href="http://www.w3.org/TR/html5/the-iframe-element.html"&gt;iFrames&lt;/a&gt;. MediaPlus can manipulate the media content when they are inside almost any webpage.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What can MediaPlus do? &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Move and re-size media content like videos or games on web pages&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Make media content, maximized inside your browser. Play games in full screen. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Pop out media content into a new browser window&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Switch off lights on the page to view media content better on the page. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Download Media content from specific websites. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Enhance HTML5 videos by changing contrast, brightness, etc. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Delete annoying media like advertisements, etc. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;b&gt;Interesting, now how do I install it ? &lt;/b&gt;&lt;br /&gt;
Since this is a &lt;a href="http://en.wikipedia.org/wiki/Bookmarklet"&gt;bookmarklet&lt;/a&gt;, no installation is required. &lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;iframe height="250px" src="http://nparashuram.com/projects/flashresizer.html#versions" width="100%"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style="clear: both;"&gt;&lt;/div&gt;&lt;span style="clear: both; font-size: small;"&gt;We are working on making this available as extensions for Firefox, Chrome and Opera. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How do I use it? &lt;/b&gt;&lt;br /&gt;
When you are browsing a page, you could click on the MediaPlus bookmarklet link and it would get activated. You can now move your mouse over media content on the page and you should be able to see a blue highlight around the content with a toolbox below it. Place your mouse over the icons inside the toolbox to see what they do, and click on them to manipulate that media content. &lt;br /&gt;
At any time, you can click on the MediaPlus bookmarklet for additional options. For example, when your video is full screen, or the page is dark, click on the bookmarklet to restore the content to its original size or switch the lights back on. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;And how does it work? &lt;/b&gt;&lt;br /&gt;
MediaPlus is a bookmarklet. When you click the MediaPlus bookmarket in your favourites or bookmarks bar, a javascript file is injected in the page you are browser. It is this script that does all the magic. It does not transfer any content from your webpage to anywhere, so it is also safe to use. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What are the supported browsers? &lt;/b&gt;&lt;br /&gt;
MediaPlus is tested on Firefox 3.5+, IE8+, Chrome 9+ and Opera 10+. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Was this not called FlashPlus earlier?&lt;/b&gt;&lt;br /&gt;
MediaPlus is like the next version on &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;FlashPlus&lt;/a&gt;. FlashPlus only allowed manipulation on Flash content on web pages. MediaPlus is a complete rewrite of FlashPlus and is more efficient and has more functionality. See this link for more technical details. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;More details?&lt;/b&gt;&lt;br /&gt;
You can follow &lt;a href="http://blog.nparashuram.com/search/label/flashplus"&gt;this link&lt;/a&gt; for more details. The blog will be update with technical details and other major releases. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-115868973084181918?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/vUDMb6SCk7s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/115868973084181918/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/07/mediaplus-20.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/115868973084181918?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/115868973084181918?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/vUDMb6SCk7s/mediaplus-20.html" title="MediaPlus 2.0" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/07/mediaplus-20.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MMR3g-fCp7ImA9WhZbEk0.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-3632998048335143986</id><published>2011-06-16T10:48:00.000+05:30</published><updated>2011-06-16T10:48:06.654+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-16T10:48:06.654+05:30</app:edited><title>At Microsoft WebCamp, Hyderabad</title><content type="html">&lt;div style="text-align: center;"&gt;Attending the Microsoft Hyderabad WebCamps. &lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&amp;nbsp;&lt;img alt="" src="data:image/png;base64,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" /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;img alt="" src="data:image/png;base64,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" /&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
I will be speaking on Sizzlers on the Web: Web Sockets &amp;amp; Indexed DB. The presentation is available on Skydrive here - &lt;a href="https://cid-88695823769e7fbc.office.live.com/fullscreen?resid=88695823769E7FBC%21139&amp;amp;filename=Sizzlers%20on%20the%20Web%20-%20WebSockets%20and%20IndexedDB.pptx&amp;amp;wx=p&amp;amp;wv=s&amp;amp;wc=officeapps.live.com&amp;amp;wy=y"&gt;https://cid-88695823769e7fbc.office.live.com/fullscreen?resid=88695823769E7FBC!139&amp;amp;filename=Sizzlers%20on%20the%20Web%20-%20WebSockets%20and%20IndexedDB.pptx&amp;amp;wx=p&amp;amp;wv=s&amp;amp;wc=officeapps.live.com&amp;amp;wy=y&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="https://cid-88695823769e7fbc.office.live.com/fullscreen?resid=88695823769E7FBC%21139&amp;amp;filename=Sizzlers%20on%20the%20Web%20-%20WebSockets%20and%20IndexedDB.pptx&amp;amp;wx=p&amp;amp;wv=s&amp;amp;wc=officeapps.live.com&amp;amp;wy=y" style="width: 100%;height : 400px"&gt;&lt;/iframe&gt;&lt;br /&gt;
&amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-3632998048335143986?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/1ayhQzRHU7c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/3632998048335143986/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/06/at-microsoft-webcamp-hyderabad.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3632998048335143986?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/3632998048335143986?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/1ayhQzRHU7c/at-microsoft-webcamp-hyderabad.html" title="At Microsoft WebCamp, Hyderabad" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/06/at-microsoft-webcamp-hyderabad.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IASHgzfCp7ImA9WhZbEEo.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-6252009666667337291</id><published>2011-06-14T22:42:00.000+05:30</published><updated>2011-06-14T22:42:29.684+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-14T22:42:29.684+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="indexeddb" /><title>Support for Out of Line Keys - IndexedDB Jquery Plugin</title><content type="html">In a comment to a &lt;a href="http://blog.nparashuram.com/2011/05/indexeddb-plugin-making-promises-look.html%5C"&gt;previous post&lt;/a&gt;, a reader had observed that there was no way in the &lt;a href="http://nparashuram.com/IndexedDB/jquery/index.html"&gt;Jquery IndexedDB plugin&lt;/a&gt; for creating Object Stores with Out of Line Keys.&lt;br /&gt;
According to the &lt;a href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html"&gt;IndexedDB Specification&lt;/a&gt;, an out-of-line key is a type of key that is used when no key path is specified while creating the object store. In such cases, the key needs to be specified during an add or a put (update) operation as the second parameter.&lt;br /&gt;
To explain how out of line keys are supported, a quick introduction to the ways an object store can be created.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Create Statement&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;
An object store is created using the explicit &lt;a href="http://nparashuram.com/IndexedDB/jquery/index.html#Create%20Object%20Store"&gt;create statement&lt;/a&gt; that looks like&lt;br /&gt;
&lt;br /&gt;
&lt;code style="background-color: #cccccc; display: block; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;
$.indexeddb("BookShop1").createObjectStore("BookList", {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; keyPath: "id",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; autoIncrement: true&lt;br /&gt;
}).then(console.info, console.error);&lt;/code&gt;&lt;code style="background-color: #cccccc; display: block; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The second option basically defines the key generator and the key path. This option can be "undefined" or omitted to indicate out-of-line key, just like the createObjectStore statement in the original specification.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Get Object Store&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Even as I was writing application leveraging IndexedDB, I noticed that I was painful to get an object store, check for its existence, and create it if it does not exist. Since this is a very common case, the &lt;a href="http://nparashuram.com/IndexedDB/jquery/index.html#Open%20Object%20Store,%20or%20create%20if%20does%20not%20exist"&gt;get object store statement&lt;/a&gt; defaulted to creating an object store if one did not exist already. Deciding the defaults for this was tricky, but here is what I found most logical from my experiences.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;u&gt;&lt;b&gt;&lt;/b&gt;&lt;/u&gt;In most cases, the developer would love to do something like $.indexeddb("DB").objectStore("BookList").add(data) and would like BookList to be created if it does not exist. The add statement also has the key as an optional parameter.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;u&gt;&lt;b&gt;&lt;/b&gt;&lt;/u&gt;This is a case where the developer explicitly specifies the key path and key generator as the second parameter to the objectStore() function. Thought it is longer, the developer needs more control over the keyPath created. &lt;/li&gt;
&lt;li&gt;This is a case where the developer does not want the object store to be created when it does not exist. The developer would probably use the createObjectStore() call to create an object store explicitly.&lt;/li&gt;
&lt;/ul&gt;Taking these three cases into account, an acceptable default for the GetObjectStore call would be&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;If the second parameter is NOT specified, use out of line keys, and make them auto-increment. This way, the user is not required to specify the key for every add statement.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;If the second parameter is specified and set to an object, use that object and pass it to the createObjectStore IndexedDB call. The IndexedDB implementation would use the key path and generator values from this.&lt;/li&gt;
&lt;li&gt;If the second parameter is false, the user explicitly has called out the "createOption" to false - so do not create the object store.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;&amp;nbsp;Understanding this could be a little harder, but i hope that these choices make life easy for 80% of the developers who just access data store and want everything else to magically work. This has been implemented as a part of &lt;a href="https://github.com/axemclion/IndexedDB/commit/95c66ed395cd78f958e7e7ecafd7c880ebd4a224"&gt;this&lt;/a&gt; commit.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
As usual, comments are welcome. You can also follow &lt;a href="http://blog.nparashuram.com/search/label/indexeddb"&gt;this space&lt;/a&gt; for updates on the plugin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-6252009666667337291?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/QJUrx_PHhzQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/6252009666667337291/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/06/support-for-out-of-line-keys-indexeddb.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6252009666667337291?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/6252009666667337291?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/QJUrx_PHhzQ/support-for-out-of-line-keys-indexeddb.html" title="Support for Out of Line Keys - IndexedDB Jquery Plugin" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/06/support-for-out-of-line-keys-indexeddb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIHQ3s8cCp7ImA9WhZWGUo.&quot;"><id>tag:blogger.com,1999:blog-8997727588422391656.post-9108526380817227188</id><published>2011-05-21T17:02:00.000+05:30</published><updated>2011-05-21T17:02:12.578+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-21T17:02:12.578+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="indexeddb" /><title>IndexedDB Plugin - making promises look more like Jquery</title><content type="html">I had written about an &lt;a href="http://blog.nparashuram.com/2011/04/indexeddb-jquery-plugin.html"&gt;IndexedDB plugin for Jquery&lt;/a&gt;. It generated some interest in the community and was &lt;a href="http://functionsource.com/post/indexeddb-gets-some-backbone-and-jquery-love"&gt;written about&lt;/a&gt; and &lt;a href="http://www.delicious.com/url/9a7f6cd3126fc071c37c34da82e7bb19"&gt;bookmarked&lt;/a&gt;. You can play with the API using &lt;a href="http://nparashuram.com/trialtool/index.html#example=/IndexedDB/jquery/trialtool.html"&gt;TrialTool&lt;/a&gt; or on the &lt;a href="http://nparashuram.com/IndexedDB/jquery/index.html"&gt;samples page&lt;/a&gt;. &lt;br /&gt;
One feedback I got was about the inconsistencies in the way promises were exposed on individual objects. For example, when the user adds or modifies data, the user can do things like&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #eeeeee; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span class="js-variable"&gt;$&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;indexeddb&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-string"&gt;"BookShop-1"&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;objectStore&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-string"&gt;"BookList"&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;add&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-variable"&gt;book&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;then&lt;/span&gt;&lt;span class="js-punctuation"&gt;(doneMessage&lt;/span&gt;&lt;span class="js-punctuation"&gt;, e&lt;/span&gt;&lt;span class="js-variable"&gt;rror&lt;/span&gt;&lt;span class="js-punctuation"&gt;Message)&lt;/span&gt;&lt;span class="js-punctuation"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
This is exactly what Jquery provides in form of Deferred objects. However, there were ugly mismatches in cases of objects like objectStores or cursors that had a syntax like the following.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #eeeeee; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;strike&gt;&lt;span class="js-variable"&gt;$&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;indexeddb&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-string"&gt;"BookShop-1"&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;.promise.&lt;/span&gt;&lt;span class="js-property"&gt;then&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-variable"&gt;write&lt;/span&gt;&lt;span class="js-punctuation"&gt;, &lt;/span&gt;&lt;span class="js-variable"&gt;writeError&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;;&lt;/span&gt;&lt;/strike&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span class="js-punctuation"&gt;Exposing the promises as a separate property may not be a great idea. As a part of &lt;a href="https://github.com/axemclion/IndexedDB/commit/ef33efb6d4684f28679478c8739b85d5e7aa776b"&gt;this commit&lt;/a&gt;, I was able to make it follow the Jquery pattern.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="js-punctuation"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div style="background-color: #eeeeee; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span class="js-variable"&gt;$&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;indexeddb&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-string"&gt;"BookShop-1"&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;then&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-variable"&gt;write&lt;/span&gt;&lt;span class="js-punctuation"&gt;, &lt;/span&gt;&lt;span class="js-variable"&gt;writeError&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;;&lt;/span&gt;&lt;span class="js-punctuation"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span class="js-punctuation"&gt;The other interesting bug I noticed was the availability of the transaction object from an object Store. In Firefox 4, I can access a database from an opened object store using &lt;/span&gt;&lt;span class="js-punctuation"&gt;objectStore.transaction.db.name. This is however not possible in Chrome; the objectStore is much more simpler in Chrome. This was the root cause of &lt;a href="https://github.com/axemclion/IndexedDB/issues/1#issuecomment-1213766"&gt;the bug&lt;/a&gt; with indexes. This &lt;a href="https://github.com/axemclion/IndexedDB/commit/ef33efb6d4684f28679478c8739b85d5e7aa776b"&gt;commit&lt;/a&gt; fixes the issue. &lt;/span&gt;&lt;br /&gt;
&lt;span class="js-punctuation"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="js-punctuation"&gt;Right now, the library seems to have most IndexedDB objects captures. Feedback on the library and the constructs needed :)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8997727588422391656-9108526380817227188?l=blog.nparashuram.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dy-verse/~4/jBTRBErFzhU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nparashuram.com/feeds/9108526380817227188/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.nparashuram.com/2011/05/indexeddb-plugin-making-promises-look.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/9108526380817227188?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8997727588422391656/posts/default/9108526380817227188?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Dy-verse/~3/jBTRBErFzhU/indexeddb-plugin-making-promises-look.html" title="IndexedDB Plugin - making promises look more like Jquery" /><author><name>Parashuram Narasimhan</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-8mB5X1_tA_A/AAAAAAAAAAI/AAAAAAAACrE/L-U4JRfqXxY/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.nparashuram.com/2011/05/indexeddb-plugin-making-promises-look.html</feedburner:origLink></entry></feed>

