Lifting the Lid on localStorage

Ever have one of those times where you’re reading one thing, and that leads you to another thing, which leads you to yet a THIRD thing, and before you know it you have four things you want to code and only enough energy to turn on the TV? And even then, once you get the TV on, you don’t have enough energy to find something else other than the Food Network to watch? I digress.

I have been doing a lot of research into AmplifyJS.com. This is a potentially powerful library. I’m looking at bringing it into use in my day job, but also see a lot of benefit for it in my personal projects as well. It doesn’t do anything that jQuery doesn’t already do, but that’s not the point. The point is that I find Amplify an excellent way to aggregate both the method of accessing Ajaxian/Restful endpoints, handling such cumbersome tasks as caching, as well as giving you a good cookie handler and pubsub mechanism, all in 8kb minified.

Admittedly, it’s in Alpha, and I hope to see it mature soon.

However, I was looking at how it handles things like localStorage, and then I saw a tweet from the substantially speedy Steve Souders regarding how he wanted to get a bookmarklet going to access localStorage. Well, after doing some research into how that could be done, I started working on one. So this post is the shameless plug post where I talk up AmplifyJS, and also the post where I talk about how I put one of those together.

I have (perhaps presumptuously) named this the jqLSAdmin. The ‘jq’ is because I use jQuery in it. The ‘LS’ denotes localStorage, and the ‘Admin’ part is because you can ‘administer’ your localStorage through the interface.

Bookmarklet: [» jqLSAdmin «][1]

Drag the bookmarklet up to your favorites bar in your browser of choice. When you are on a page where you would like to interact with the localStorage on that page, just click it. You will get a lightbox overlay on the page with the key/value pairs of your localStorage displayed. At the bottom of the list will be text boxes where  you can add new values to localStorage.

For those of you who may be concerned, I dynamically load in jQuery if it’s not already on the page, and if I did load it in I remove it when the bookmarklet is closed. I haven’t really worked the kinks out of noConflict() yet, so that isn’t handled in this release of this tool. However, as I experiment a bit further (or if someone wants to tackle it once I get the unminified code posted up), then please feel free.

Enjoy. Feedback is always appreciated.

[1]: javascript: (function(){function l(a){var b=$(’

’),e=$(’
’),d=$(’
’),f=$(’’);d.attr(‘id’,‘jqlsadmin’).css({‘-moz-border-radius’:‘8px’,‘-webkit-border-radius’:‘8px’,‘border-radius’:‘8px’,‘font-family’:‘Arial’,‘font-size’:‘12px’,width:‘800px’,margin:‘5px’});f.attr(‘id’,‘jqlsclose’).css({position:‘absolute’,bottom:‘5px’,right:‘5px’,cursor:‘pointer’,color:‘#444’}).click(function(){$(‘#jqlsoverlay’).remove();$(a).length&&$(a).remove()}).html(’» Close jqLSAdmin «’);$(‘body’).append(b); b.css({display:‘none’,position:‘fixed’,top:0,left:0,width:‘100%‘,height:‘100%’,‘background-color’:‘black’,‘z-index’:1001,‘-moz-opacity’:0.9,opacity:0.9,filter:‘alpha(opacity=90)’}).attr(‘id’,‘jqlsoverlay’).append(e);e.css({display:‘none’,position:‘absolute’,top:‘15%‘,left:‘20%‘,width:‘830px’,‘background-color’:‘#eee’,‘z-index’:1002,overflow:‘hidden’,opacity:1,filter:‘alpha(opacity=100)‘,cursor:‘default’,‘-moz-border-radius’:‘8px’,‘-webkit-border-radius’:‘8px’,‘border-radius’:‘8px’}).attr(‘id’,‘jqlscontent’).append(d).append(’
‘).append(f);$(‘#jqls
overlay, #jqlscontent’).show();h();m()}function m(){$(‘.jqlsdelete’).live(‘click’,function(){var a=$(this).parent(‘li’),b=a.attr(‘id’);b=b.substring(9);localStorage.removeItem(b);a.remove()});$(‘.jqlssave’).live(‘click’,function(){var a=$(‘#jqlsnewkey’).val(),b=$(‘#jqlsnewvalue’).val();if(a==‘New Key’||b==‘New Value’)return!1;localStorage.setItem(a,b);h()});$(‘.jqlsedit’).live(‘click’,function(){var a=$(this).parent(‘span’),b=a.hasClass(‘jqlskey’)?‘175px’:‘479px’,e=a.text(),d=new Date,f=$(’’),g=$(’’);d=d.getTime();e=e.substring(0,e.length-1);f.attr({type:‘text’,id:‘jqlseditval‘+d,name:‘jqlseditval’,value:e}).css({width:b,color:‘#999’,‘float’:‘left’});g.addClass(‘jqlseditsave’).attr(‘id’,‘save‘+d).css({margin:‘1px 0 0 2px’,‘float’:‘left’,cursor:‘pointer’}).html(’∇’);a.empty().append(f).append(g);$(‘#jqlseditval‘+d).data(‘origval’,e)});$(‘.jqlseditsave’).live(‘click’,function(){var a=$(this).parent(‘span’),b=$(this).attr(‘id’).substr(5),e=a.hasClass(‘jqlskey’),d=a.find(‘input’).data(‘origval’);b=$(‘#jqlseditval‘+b).val();b!=d&&(e?(a=$(‘#jqlskey‘+d).find(‘span.jqlsdata’).text(),a=a.substring(0,a.length-1),localStorage.removeItem(d),localStorage.setItem(b,a)):(d=a.parent(‘li’).attr(‘id’),d=d.substring(9),localStorage.setItem(d,b)));h()})}function h(){var a=localStorage.length-1,b=$(’
    ’),e=$(’’),d=$(’’),f=$(’’),g=$(’
  • ’),h=$(’’),k=$(’’);e.text(‘Values in Local Storage’).css(‘font-weight’,‘bold’);f.addClass(‘jqlsedit’).css({‘float’:‘right’,cursor:‘pointer’}).html(’Δ’);d.addClass(‘jqlsdelete’).css({display:‘block’,‘float’:‘left’,color:‘red’,‘font-weight’:‘bold’,padding:‘2px’,‘font-size’:‘21px’,margin:‘3px 0’,cursor:‘pointer’}).html(’×’);$(‘#jqlsadmin’).empty().append(e);b.attr(‘id’,‘keyValList’).css(‘list-style’,‘none’).appendTo(‘#jqlsadmin’);h.css({‘font-weight’:‘bold’,‘font-size’:‘13px’,display:‘block’,width:‘210px’,‘float’:‘left’,margin:‘3px’}).text(‘Key’).appendTo(g);k.css({‘font-weight’:‘bold’,‘font-size’:‘13px’,display:‘block’,width:‘500px’,‘float’:‘left’,margin:‘3px’}).text(‘Value’).appendTo(g);g.appendTo(b);for(i=0;i<=a;i++){e=localStorage.key(i);g=localStorage.getItem(e);h=$(’’);k=$(’’);var j=$(’
  • ’);j.attr(‘id’,‘jqlskey‘+e).addClass(‘jqlsitem’).css(‘clear’,‘both’);h.css({width:‘200px’,display:‘block’,‘float’:‘left’,‘background-color’:‘green’,border:‘1px solid #0c0’,padding:‘4px’,margin:‘3px’}).addClass(‘jqlskey’).text(e).appendTo(j);k.css({width:‘500px’,display:‘block’,‘float’:‘left’,‘background-color’:‘#0cf’,border:‘1px solid blue’,padding:‘4px’,margin:‘3px’}).addClass(‘jqlsdata’).text(g).appendTo(j);j.appendTo(b)}$(‘.jqlskey, .jqlsdata’).append(f);$(‘.jqlsitem’).append(d);a=$(’
  • ’);d=$(’’);f=$(’’);e=$(’’);d.attr({type:‘text’,name:‘jqlsnewkey’,value:‘New Key’,id:‘jqlsnewkey’}).css({color:‘#333’,margin:‘3px’,width:‘204px’,‘float’:‘left’}).focus(function(){if(this.value==‘New Key’)this.value=”}).blur(function(){if(this.value==”)this.value=‘New Key’});f.attr({type:‘text’,name:‘jqlsnewvalue’,value:‘New Value’,id:‘jqlsnewvalue’}).css({color:‘#333’,margin:‘3px’,width:‘504px’,‘float’:‘left’}).focus(function(){if(this.value==‘New Value’)this.value=”}).blur(function(){if(this.value==”)this.value=‘New Value’});e.addClass(‘jqlssave’).css({margin:‘4px 0 0 2px’,‘float’:‘left’,cursor:‘pointer’}).html(’∇’);a.css(‘clear’,‘both’).append(d,f,e);b.append(a)}if(typeof localStorage==‘undefined’)return alert(‘Your browser does not support HTML5 localStorage. Try upgrading.’),!1;else{try{localStorage.setItem(‘vkname’,‘Vankoder’)}catch(n){if(n==QUOTAEXCEEDEDERR)return alert(‘Quota exceeded!’),!1}localStorage.removeItem(‘vkname’)}!window.jQuery||1>jQuery.fn.jquery?(c=document.createElement(‘script’),c.src=‘/web/20111222183715/http://code.jquery.com/jquery-latest.min.js’,document.documentElement.childNodes[0].appendChild(c),c.onload=c.onreadystatechange=function(){(!this.readyState||this.readyState==‘loaded’||this.readyState==‘complete’)&&l(c)}):(c=”,l(c))})(); “jqLSAdmin”

Published 26 Mar 2011

Writing better code by building better JavaScript
Don Burks on Twitter