<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Underneath the already known &#187; storage</title>
	<atom:link href="http://vaskas.ru/tag/storage/feed/" rel="self" type="application/rss+xml" />
	<link>http://vaskas.ru</link>
	<description>What Vaskas thinks</description>
	<lastBuildDate>Mon, 13 Jul 2009 19:38:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Browser persistence</title>
		<link>http://vaskas.ru/2008/08/06/browser-persistence/</link>
		<comments>http://vaskas.ru/2008/08/06/browser-persistence/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 12:22:38 +0000</pubDate>
		<dc:creator>vaskas</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[storage]]></category>
		<category><![CDATA[userData behavior]]></category>

		<guid isPermaLink="false">http://vaskas.ru/?p=34</guid>
		<description><![CDATA[Why use server-side data storage, if you don&#8217;t do any data processing on server? There are many cases when you&#8217;d rather keep your data structures on the client side. In Inshaker, we had to manipulate and persist large amounts of user-specific data on the client side. Cookies were not an option because of the 4kb [...]]]></description>
			<content:encoded><![CDATA[<p>Why use server-side data storage, if you don&#8217;t do any data processing on server? There are many cases when you&#8217;d rather keep your data structures on the client side. In <a href="http://www.inshaker.ru">Inshaker,</a> we had to manipulate and persist large amounts of user-specific data on the client side. Cookies were not an option because of the 4kb limit. So we used <a href="http://browserpersistence.ru">the persistency library by Ilya Kantor</a> with slight modifications. It makes use of window.globalStorage object in Mozilla, userData behavior in MSIE and Flash storage in other cases (we will be implementing Safari sqlite storage too). All three mechanisms are different: flash storage is loaded asynchronously and userData values can&#8217;t be accessed in other paths (i.e. /page.html and /dir/otherpage.html won&#8217;t be sharing the same data). That&#8217;s why we use a &#8220;proxy&#8221; page, which is loaded in an iframe. The data we persist is &#8220;attached&#8221; to an element in this page. </p>
<p>Usage is rather simple:</p>
<pre><code class="javascript">
	// needs callback because it's asynchronous in case of flash
	Storage.init(function(){
		Storage.put("js", "cool language");
		var desc = Storage.get("js");
		Storage.remove("js");
		Storage.put("objc", "pretty too");
		alert(Storage.get("objc"));
		Storage.clear();
	});
</code></pre>
<p><span id="more-34"></span><br />
<a href="http://browserpersistence.ru/storage.zip">Get the library from Ilya&#8217;s site</a>. If you need cross-directory storage sharing for IE, replace his Storage.userData section with this snippet:</p>
<pre><code class="javascript">
Storage.userData = function(onready) {
    var namespace = "data";

    if (!document.body.addBehavior) {
        throw new Error("No addBehavior available");
    }

	var e = document.createElement("iframe");
	e.setAttribute('id', 'storageFrame');
	e.style.border = '0';
	e.style.width  = '0';
	e.style.height = '0';
	var iframe = document.body.appendChild(e);
	iframe.src='proxy.html';

	iframe.addEventListener('load', function(e){
		var storage = iframe.contentWindow.document.getElementById('storageElement');
		storage.load(namespace);

	    Storage = {
	        get: function(key) {
	            return storage.getAttribute(key);
	        },

	        put: function(key, value) {
	            storage.setAttribute(key, value);
	            storage.save(namespace);
	        },

	        remove: function(key) {
	            storage.removeAttribute(key);
	            storage.save(namespace);
	        },

	        clear: function() {
	            var attrs = storage.XMLDocument.documentElement.attributes;

	            for(var i = 0; i < attrs.length; i++) storage.removeAttribute(attrs[i].name);
	            storage.save(namespace);
	        },

	        getKeys: function() {
	            var res = [];
	            var attrs = storage.XMLDocument.documentElement.attributes;

	            for(var i = 0; i < attrs.length; i++) res.push(attrs[i].name);
	            return res;
	        }
	    }
	    onready();
	}, false);
};
</code></pre>
<p>proxy.html is very simple:</p>
<pre><code class="html">
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;userData proxy object&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;span id=\&quot;storageElement\&quot; style=\&quot;behavior:url(\'#default#userData\')\&quot;&gt;&lt;/span&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://vaskas.ru/2008/08/06/browser-persistence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
