<?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>Markus Nix &#187; dom caching</title>
	<atom:link href="http://www.markusnix.com/wp/tag/dom-caching/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.markusnix.com/wp</link>
	<description>Web Technology Afficionado</description>
	<lastBuildDate>Wed, 10 Mar 2010 14:06:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>DOM Caching Revisited</title>
		<link>http://www.markusnix.com/wp/2010/02/dom-caching-revisited/</link>
		<comments>http://www.markusnix.com/wp/2010/02/dom-caching-revisited/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 10:29:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[dom caching]]></category>

		<guid isPermaLink="false">http://www.markusnix.com/wp/?p=300</guid>
		<description><![CDATA[I recently found www.domcached.com. It was not exactly what I&#8217;ve looked for, so I changed some bits here, some bits there. This is the current version I&#8217;m currently working with. I consider adding real HTML5 database support. So what it&#8217;s for? DomCache is a trivial wrapper for the use of DOM Storage provided by modern [...]]]></description>
			<content:encoded><![CDATA[<p>I recently found <a href="http://www.domcached.com">www.domcached.com</a>. It was not exactly what I&#8217;ve looked for, so I changed some bits here, some bits there. This is the current version I&#8217;m currently working with. I consider adding real HTML5 database support. So what it&#8217;s for? DomCache is a trivial wrapper for the use of DOM Storage provided by modern browsers. It&#8217;s modelled after &#8220;memcached&#8221; and uses <a href="http://www.prototypejs.org" target="_blank">Prototype</a> for JSON handling instead of working with Strings only.</p>
<pre class="brush:javascript toolbar:false">
DomCache = ( function() {
    var storage  = {};
    var backend  = false;
    var incrdecr = function( key, delta, namespace, initial, decr ) {
        var namespace = namespace || 'default';
        var delta     = delta     || 1;
        var initial   = initial   || 0;
        var time      = time      || false;

        if ( !key || ( ( typeof key != 'string' ) &#038;&#038; ( typeof key != 'number' ) ) ) {
            throw new TypeError();
        }

        if ( ( typeof namespace != 'string' ) &#038;&#038; ( typeof namespace != 'number' ) ) {
            throw new TypeError();
        }

        if ( typeof delta != 'number' ) {
            throw new TypeError();
        }

        if ( time &#038;&#038; ( time < ( new Date() ).getTime() ) ) {
            time = ( new Date() ).getTime() + time;
        }

        if ( !storage[namespace] ) {
            storage[namespace] = {};
        }

        if ( !storage[namespace].hasOwnProperty( key ) || ( typeof storage[namespace][key] != 'number' ) ) {
            storage[namespace][key].value = initial;
            save();

            return initial;
        }

        if ( decr ) {
            storage[namespace][key].value -= delta;
        } else {
            storage[namespace][key].value += delta;
        }

        save();
        return value || true;
    };

    var save = function() {
        if ( backend ) {
            try {
                backend.dom_storage = Object.toJSON( storage );
                return true;
            } catch ( ex ) {
                if ( $( 'elm_domcached' ) ) {
                    try {
                        $( 'elm_domcached' ).setAttribute( 'domcached', backend.dom_storage );
                        $( 'elm_domcached' ).save( 'domcached' );

                        return true;
                    } catch (ex ) {
                    }
                }
            }
        }

        return false;
    };

    // initialization

    ( function() {
        if ( 'localStorage' in window ) {
            backend = window.localStorage;
        } else if ( 'globalStorage' in window ) {
            backend = window.globalStorage[document.domain];
        } else if ( 'addBehavior' in ( new Element( 'div' ) ) ) {
            $( document.getElementsByTagName( 'body' )[0] ).insert( '
<link id="elm_domcached" style="behavior:url(#default#userData)"/>' );
            $( 'elm_domcached' ).load( 'domcached' );

            try {
                var data = $( 'elm_domcached' ).getAttribute( 'domcached' );
            } catch ( ex ) {
                var data = "{}";
            }

            backend = {
                dom_storage: {}
            };

            if ( data &#038;&#038; data.length ) {
                backend.dom_storage = data;
            }
        } else {
            return;
        }

        if ( ( 'dom_storage' in backend ) &#038;&#038; backend.dom_storage ) {
            try {
                storage = String( backend.dom_storage ).evalJSON();
            } catch ( ex ) {
                backend.dom_storage = "{}";
            }
        } else {
            backend.dom_storage = "{}";
        }
    } )();

    // the public interface

    return {
        set: function( key, value, time, namespace ) {
            var namespace = namespace || 'default';
            var time      = time      || false;

            if ( !key || ( ( typeof key != 'string' ) &#038;&#038; ( typeof key != 'number' ) ) ) {
                throw new TypeError();
            }

            if ( ( typeof namespace != 'string' ) &#038;&#038; ( typeof namespace != 'number' ) ) {
                throw new TypeError();
            }

            if ( time &#038;&#038; ( time < ( new Date() ).getTime() ) ) {
                time = ( new Date() ).getTime() + Math.ceil( time );
            }

            if ( !storage[namespace] ) {
                storage[namespace] = {};
            }

            storage[namespace][key] = {
                value: value,
                time:  time
            };

            save();
            return value || true;
        },

        get: function( key, namespace ) {
            var namespace = namespace || 'default';

            if ( ( typeof namespace != 'string' ) &#038;&#038; ( typeof namespace != 'number' ) ) {
                throw new TypeError();
            }

            if ( storage[namespace] &#038;&#038; storage[namespace][key] &#038;&#038; ( !storage[namespace][key].time || ( storage[namespace][key].time < ( new Date() ).getTime() ) ) ) {
                return storage[namespace][key].value;
            }

            return null;
        },

        add: function( key, value, time, namespace ) {
            var namespace = namespace || 'default';
            var time      = time      || false;

            if ( !key || ( ( typeof key != 'string' ) &#038;&#038; ( typeof key != 'number' ) ) ) {
                throw new TypeError();
            }

            if ( ( typeof namespace != 'string' ) &#038;&#038; ( typeof namespace != 'number' ) ) {
                throw new TypeError();
            }

            if ( time &#038;&#038; ( time < ( new Date() ).getTime() ) ) {
                time = ( new Date() ).getTime() + Math.ceil( time );
            }

            if ( !storage[namespace] ) {
                storage[namespace] = {};
            }

            storage[namespace][key] = {
                value: value,
                time:  time
            };

            save();
            return value || true;
        },

        replace: function( key, value, time, namespace ) {
            var namespace = namespace || 'default';
            var time      = time      || false;

            if ( !key || ( ( typeof key != 'string' ) &#038;&#038; ( typeof key != 'number' ) ) ) {
                throw new TypeError();
            }

            if ( ( typeof namespace != 'string' ) &#038;&#038; ( typeof namespace != 'number' ) ) {
                throw new TypeError();
            }

            if ( time &#038;&#038; ( time < ( new Date() ).getTime() ) ) {
                time = ( new Date() ).getTime() + time;
            }

            if ( !storage[namespace] ) {
                storage[namespace] = {};
            }

            storage[namespace][key] = {
                value: value,
                time:  time
            };

            save();
            return value || true;
        },

        incr: function( key, delta, namespace, initial ) {
            return incrdecr( key, delta, namespace, initial );
        },

        decr: function( key, delta, namespace, initial ) {
            return incrdecr( key, delta, namespace, initial, true );
        },

        remove: function( key, namespace ) {
            var namespace = namespace || 'default';

            if ( ( typeof namespace != 'string' ) &#038;&#038; ( typeof namespace != 'number' ) ) {
                throw new TypeError();
            }

            if ( storage[namespace] &#038;&#038; storage[namespace][key] ) {
                delete storage[namespace][key];

                for ( var i in delete storage[namespace] ) {
                    if ( storage[namespace].hasOwnProperty( i ) ) {
                        return save();
                    }
                }

                delete storage[namespace];
                return save();
            }
        },

        removeAll: function() {
            storage = {};
            return save();
        }
    }
} )();
</pre>
<p></p>
<p>Here's a little example:</p>
<pre class="brush:javascript toolbar:false">
<html>
    <head>

    </head>

    <body>
        <script type="text/javascript" src="prototype.js"></script>
        <script type="text/javascript" src="domcache.js"></script>

        <script type="text/javascript">
        Event.observe( window, 'load', function() {
            var c;
            if ( c = DomCache.get( 'foo' ) ) {
                DomCache.set( 'foo', c + 'a' );
            } else {
                DomCache.add( 'foo', 'a' );
            }  

            console.log( DomCache.get( 'foo' ) );
        } );
        </script>
    </body>
</html>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.markusnix.com/wp/2010/02/dom-caching-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
