All files / src location-element.js

96.82% Statements 61/63
88.88% Branches 8/9
100% Functions 7/7
96.82% Lines 61/63

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 631x 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
{
    // @attribute live - monitors localStorage change
    // @attribute src - URL to be parsed, defaults to `window.location`
 
    constructor()
    {
        super();
        const      state = {}
        ,       listener = e=> propagateSlice(e)
        , propagateSlice = (e)=>
        {   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]
            }
            for( let parent = this.parentElement; parent; parent = parent.parentElement)
            {   if (parent.onSlice)
                    return parent.onSlice(
                        {   detail
                            , 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( '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;
        };
        this.sliceInit()
    }
    disconnectedCallback(){ this._destroy(); }
}
 
window.customElements.define( 'location-element', LocationElement );
export default LocationElement;