Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | const attr = (el, attr)=> el.getAttribute(attr)
, string2value = (type, v) =>
{ if( type === 'text')
return v;
if( type === 'json')
return JSON.parse( v );
const el = document.createElement('input');
el.setAttribute('type',type);
el.setAttribute('value', v );
return type==='number'? el.valueAsNumber : 'date|time|dateTimeLocal'.includes(type)? el.valueAsDate: el.value;
};
let originalSetItem;
function ensureTrackLocalStorage()
{ if( originalSetItem )
return;
originalSetItem = localStorage.setItem;
localStorage.setItem = function( key, value, ...rest )
{ originalSetItem.apply(this, [ key, value, ...rest ]);
window.dispatchEvent( new CustomEvent('local-storage',{detail:{key,value}}) );
};
}
export class LocalStorageElement extends HTMLElement
{
// @attribute live - monitors localStorage change
// @attribute type - `text|json`, defaults to text, other types are compatible with INPUT field
constructor()
{
super();
const state = {}
, type = attr(this, 'type') || 'text'
, listener = e=> e.detail.key === attr( this,'key' ) && propagateSlice()
, propagateSlice = ()=>
{ for( let parent = this.parentElement; parent; parent = parent.parentElement)
if( parent.onSlice )
return parent.onSlice(
{ detail: string2value( type, localStorage.getItem( attr( this, 'key' ) ) )
, target: this
} );
console.error(`${this.localName} used outside of custom-element`)
debugger;
};
this.sliceInit = s =>
{ if( !state.listener && this.hasAttribute('live') )
{ state.listener = 1;
window.addEventListener( 'local-storage', listener );
ensureTrackLocalStorage();
}
propagateSlice();
return s || {}
}
this._destroy = ()=>
{
if( !state.listener )
return;
state.listener && window.removeEventListener('local-storage', listener );
delete state.listener;
};
}
disconnectedCallback(){ this._destroy(); }
}
window.customElements.define( 'local-storage', LocalStorageElement );
export default LocalStorageElement; |