var shopSelection = xb.core.object.extend( { ctor: function( shop, values ) { this.shop = shop; this.__path = ""; this.values = ( typeof( values ) === "object" && values !== null ) ? values : {}; }, selectURL: function( url ) { var a = document.createElement( "a" ); a.href = url; var path = a.pathname; if ( path[ 0 ] !== "/" ) { path = "/" + path; } if ( path.indexOf( this.shop.config.path ) !== 0 ) { return this; } this.selectURLQuery( a.search ); if ( path.length > this.shop.config.path.length ) { this.__path = path.substr( this.shop.config.path.length ); } console.warn( this.values ); return this; }, selectURLQuery: function( query ) { if ( typeof( query ) === "string" ) { var self = this; query .replace( /[?&]+([^=&]+)=([^&]*)/gi, function( str, key, value ) { var v = []; decodeURIComponent( value ) .replace( /(([\\][|]|[^|])+)/gi, function( str, part ) { v.push( part.replace( /[\\][|]/, "|" ) ); } ) ; if ( key.substr( -2 ) === "[]" ) { key = key.substr( 0, key.length - 2 ); } for ( var i = 0, il = v.length; i < il; i++ ) { self.select( key, v[ i ] ); } } ) ; } return this; }, select: function( name, value ) { if ( ! ( this.values[ name ] instanceof Array ) ) { this.values[ name ] = []; } if ( this.values[ name ].indexOf( value ) < 0 ) { this.values[ name ].push( value ); } return this; }, deselect: function( name, value ) { if ( this.values[ name ] instanceof Array ) { if ( typeof( value ) === "undefined" || value === null ) { this.values[ name ] = []; } else { var i = this.values[ name ].indexOf( value ); if ( i > -1 ) { this.values[ name ].splice( i, 1 ); } } } return this; }, isSelected: function( name, value ) { if ( ! ( this.values[ name ] instanceof Array ) ) { return false; } return ( this.values[ name ].indexOf( value ) > -1 ); }, url: function() { var exclude = this.shop.config[ "url-settings" ][ "filters" ][ "exclude-from-search" ]; var values = this.values; var a = document.createElement( "a" ); a.href = this.shop.config.path + this.__path; a.search = ""; var s = ""; for ( var n in values ) { if ( exclude.indexOf( n ) > -1 ) { continue; } var l = []; for ( var i = 0, il = values[ n ].length; i < il; i++ ) { l.push( encodeURIComponent( values[ n ][ i ] ).replace( "|", "\\|" ) ); } if ( l.length ) { if ( s.length > 0 ) { s += "&"; } s += encodeURIComponent( n ) + "=" + l.join( "|" ); } } a.search = s; return a.href; }, path: function( p ) { if ( arguments.length ) { this.__path = p; return this; } return this.__path; }, get: function() { var result = Object.assign( {}, this.values ); result.path = this.__path; return result; }, set: function( data ) { var state = Object.assign( {}, data ); this.__path = state.path; delete state.path; this.values = state; return this; }, add: function( values ) { if ( typeof( values ) === "object" && values !== null ) { for ( var n in values ) { var value = values[ n ]; if ( value instanceof Array ) { for ( var i = 0, il = value.length; i < il; i++ ) { this.select( n, value[ i ] ); } } } } return this; } } ); silk.shop = ( xb.core.object.extend( { ctor: function() { this.resource = null; this.selection = shopSelection( this ); this.lastSelection = null; }, select: function( name, value ) { this.selection.select( name, value ); return this; }, deselect: function( name, value ) { this.selection.deselect( name, value ); return this; }, navigate: function( url, preserve ) { var selection = shopSelection( this ).selectURL( url ); if ( preserve === true ) { selection.add( this.selection.get() ); selection.deselect( "offset" ); selection.deselect( "q" ); } var queries = Array.prototype.slice.call( document.body.querySelectorAll( "input[name=q]" ) ) ; queries.forEach( function( query ) { query.value = ""; } ); this.selection = selection; this.view(); return true; }, view: function( record ) { var self = this; var state = this.selection.get(); var url = this.selection.url(); if ( this.lastSelection === null ) { history.replaceState( state, "", window.location.href ); this.lastSelection = {}; record = false; } var resource = this.resource; var config = self.config; if ( record !== false ) { history.pushState( state, "", url ); } this.lastSelection = state; return ( new Promise( function( resolve, reject ) { resource.get( config, state, function( data ) { var data = ( data === null ) ? {} : data; if ( typeof( data[ "postings-selection" ] ) !== "undefined" ) { self.selection.set( data[ "postings-selection" ] ); } data[ "postings-categories" ] = resource.getDataView( "postings-categories", data ); data[ "postings-items" ] = resource.getDataView( "postings-items", data ); for ( var view in config.views ) { if ( data[ view ] instanceof silk.data ) { continue; } data[ view ] = resource.getDataView( view, data ); } resource.load( data ); resource.view(); resource.isReady = true; resolve( resource ); } ); } ) ); }, view_update: function() { var self = this; var state = this.selection.get(); state[ "select-only-items" ] = true; var resource = this.resource; var config = self.config; return ( new Promise( function( resolve, reject ) { resource.get( config, state, function( data ) { var data = ( data === null ) ? {} : data; if ( typeof( data[ "postings-selection" ] ) !== "undefined" ) { self.selection.set( data[ "postings-selection" ] ); } if ( resource.data !== null ) { data[ "postings-categories" ] = resource.data[ "postings-categories" ]; } else { data[ "postings-categories" ] = resource.getDataView( "postings-categories", data ); } data[ "postings-items" ] = resource.getDataView( "postings-items", data ); for ( var view in config.views ) { if ( data[ view ] instanceof silk.data ) { continue; } data[ view ] = resource.getDataView( view, data ); } resource.load( data ); resource.view_update(); resource.isReady = true; resolve( resource ); } ); } ) ); }, init: function( resource ) { var self = this; var config = silk.postings.config[ resource.config.name ]; if ( typeof( config[ "url-settings" ] ) !== "object" || config[ "url-settings" ] === null ) { config[ "url-settings" ] = {}; } if ( typeof( config[ "url-settings" ][ "filters" ] ) !== "object" || config[ "url-settings" ][ "filters" ] === null ) { config[ "url-settings" ][ "filters" ] = {}; } if ( ! ( config[ "url-settings" ][ "filters" ][ "exclude-from-search" ] instanceof Array ) ) { config[ "url-settings" ][ "filters" ][ "exclude-from-search" ] = []; } config[ "url-settings" ][ "filters" ][ "exclude-from-search" ].push( "id" ); config[ "url-settings" ][ "filters" ][ "exclude-from-search" ].push( "limit" ); config[ "url-settings" ][ "filters" ][ "exclude-from-search" ].push( "offset" ); this.config = config; silk.postings.resources[ resource.config.name ] = resource; this.resource = resource; this.selection.selectURL( window.location ); window.addEventListener( "popstate", function( evt ) { if ( typeof( evt.state ) === "object" && evt.state !== null ) { console.warn( "popstate shop", evt.state ); self.selection.set( evt.state ); self.view( false ); } }, true ); }, } ) )( );