All files / src location-element.js

100% Statements 62/62
100% Branches 10/10
100% Functions 9/9
100% Lines 62/62

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 621x 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);
 
export class LocationElement extends HTMLElement
{
    static observedAttributes=
            [   'value' // populated from localStorage, if defined initially, sets the value in storage
            ,   'slice'
            ,   'key'
            ,   'type' // `text|json`, defaults to text, other types are compatible with INPUT field
            ,   'live' // monitors localStorage change
            ];
 
    constructor()
    {
        super();
        const      state = {}
        ,       listener = e=> propagateSlice(e)
        , propagateSlice = ()=>
        {   const urlStr = attr(this,'src')
            const url = urlStr? new URL(urlStr) : window.location
 
            const params= {}
            const search = new URLSearchParams(url.search);
            for (const key of search.keys())
                params[key] = search.getAll(key)
 
            const detail = {params}
            for( const k in url )
            {   if ('string' === typeof url[k])
                    detail[k] = url[k]
            }
            this.value = detail;
            this.dispatchEvent( new Event('change') );
        };
        this.sliceInit = s =>
        {
            if( !state.listener && this.hasAttribute('live') )
            {   state.listener = 1;
                window.addEventListener( 'popstate'  , listener );
                window.addEventListener( 'hashchange', listener );
            }
            propagateSlice();
            return s || {}
        }
        this._destroy = ()=>
        {
            if( !state.listener )
                return;
            if(state.listener)
            {   window.removeEventListener('popstate'  , listener);
                window.removeEventListener('hashchange', listener);
            }
            delete state.listener;
        };
 
    }
    connectedCallback(){ this.sliceInit() }
    disconnectedCallback(){ this._destroy() }
}
 
window.customElements.define( 'location-element', LocationElement );
export default LocationElement;