silk.html .query( "[data-simply-data=shop][data-silk-mount=categories] := node" ) .select( function( m ) { return silk.shop.iface.categories( m.node.domNode ); } ) .publish( "shop/categories/mount" ) ; silk.html .query( "$(shop/categories/mount) := mount .silk-object.category-pulldown.nav := object" ) .select( function( m ) { return silk.shop.iface.categories.section( m.mount, m.object.domNode, false ); } ) .publish( "shop/categories/section" ) ; silk.html .query( "$(shop/categories/mount) := mount .silk-object.category-pulldown := object" ) .select( function( m ) { return silk.shop.iface.categories.section( m.mount, m.object.domNode, true ); } ) .publish( "shop/categories/section" ) ; silk.html .query( "$(shop/categories/mount) := mount .silk-object.category-pulldown.category-search := object" ) .select( function( m ) { return silk.shop.iface.categories.section_search( m.mount, m.object.domNode ); } ) .publish( "shop/categories/section" ) ; silk.html .query( "$(shop/categories/section) := section .silk-listItem := listItem > .silk-object.category-option := object" ) .select( function( m ) { return silk.shop.iface.categories.section.option( m.section, m.listItem.domNode, m.object.domNode ); } ) .publish( "shop/categories/option" ) ; silk.html .query( "[data-simply-data=shop][data-silk-mount=view] := node" ) .select( function( m ) { return silk.shop.iface.view( m.node.domNode ); } ) .publish( "shop/view/mount" ) ; silk.html .query( "$( shop/view/mount )[data-postings-view=list] := view" ) .select( function( m ) { return silk.shop.iface.view.listing( m.view, m.view.domNode ); } ) .publish( "shop/view/listing" ) ; silk.html .query( "$( shop/view/mount )[data-postings-view=detail] := view" ) .select( function( m ) { return silk.shop.iface.view.detail( m.view, m.view.domNode ); } ) .publish( "shop/view/detail" ) ; silk.html .query( "$( shop/view/listing ) := view > .silk-listItem[data-simply-template='Product List Heading'] > .silk-object := object" ) .select( function( m ) { return silk.shop.iface.view.listing.bar( m.view, m.object ); } ) .publish( "shop/view/listing/bar" ) ; silk.html .query( "$( shop/view/listing/bar ) := bar .silk-object.result-display := object" ) .select( function( m ) { return silk.shop.iface.view.listing.bar.display( m.bar, m.object ); } ) .publish( "shop/view/listing/bar/display" ) ; silk.html .query( "$( shop/view/listing/bar ) := bar .silk-object.result-sort := object" ) .select( function( m ) { return silk.shop.iface.view.listing.bar.sort( m.bar, m.object ); } ) .publish( "shop/view/listing/bar/sort" ) ; /*** Eventhandlers ***/ var followLink = function( link, preserve ) { var preserve = ( preserve === true ) ? true : false; var path = link.pathname; var shop = silk.shop; if ( typeof( shop ) !== "object" ) { return; } if ( path[ 0 ] !== "/" ) { path = "/" + path; } if ( path.indexOf( shop.config.path ) !== 0 ) { return false; } shop.navigate( link.href, preserve ); return true; } ; silk.html .query( [ "body.template-shop a[href]:not(.nonav) := link", ] ) .on( "events/click", function( evt ) { var in_m = silk.html .query( [ "$( shop/view/mount )", "$( shop/categories/section ):not(.nav)" ] ) .match( evt.target ) ; var preserve = ( in_m !== null ); if ( followLink( this.link.domNode, preserve ) ) { evt.preventDefault(); evt.stopImmediatePropagation(); } } ) ; silk.html .query( "$(shop/categories/mount) := mount" ) .on( "events/dispatcher/render", function( evt ) { this.mount.update( evt.detail.object.__index ); } ) ; silk.html .query( "$( shop/categories/section ) := section > .silk-list > .silk-listItem.category-name := name" ) .on( "events/click", function( evt ) { evt.preventDefault(); this.section.toggle(); } ) ; silk.html .query( ".silk-object.category-pulldown:not(.nav) $( shop/categories/option ) := option a := link" ) .on( "events/click", function( evt ) { evt.preventDefault(); evt.stopImmediatePropagation(); this.option.toggle( this.link.domNode ); } ) ; /* silk.html .query( "$(shop/view/listing) := view" ) .on( "events/dispatcher/render", function( evt ) { var bar = evt.target.querySelectorAll( ":scope > [data-simply-template='Product List Heading'] > .silk-object" ); console.log( "bar", bar ); //this.mount.update( evt.detail.object.__index ); } ) ; */ silk.html .query( "$( shop/categories/section ) := section input := input" ) .on( "events/mutations/change", function( evt ) { evt.preventDefault(); if ( this.input.domNode.value.length ) { this.input.domNode.classList.add( "not-empty" ); } else { this.input.domNode.classList.remove( "not-empty" ); } this.section.filter( this.input.domNode.value ); } ) ; silk.html .query( "$( shop/categories/section ) := section input := input + .silk-elm.category-filter-close" ) .on( "events/click", function( evt ) { this.input.domNode.value = ""; this.input.domNode.classList.remove( "not-empty" ); this.section.filter( this.input.domNode.value ); } ) ; silk.html .query( [ "$( shop/view/listing/bar/sort ) := sort select := select" ] ) .on( "events/mutations/change", function( evt ) { evt.stopImmediatePropagation(); var mode = [], select = this.select.domNode; for ( var i = 0, il = select.options.length; i < il; i++ ) { var option = select.options[ i ]; if ( option.selected ) { mode.push( option.value ); } } console.log( "bar.sort::select", mode ); silk.shop.selection.deselect( "offset" ); silk.shop.selection.deselect( "sort" ); for ( var i = 0, il = mode.length; i < il; i++ ) { silk.shop.selection.select( "sort", mode[ i ] ); } silk.shop.view(); } ) ; silk.html .query( [ "$( shop/view/listing/bar/display ) := display .silk-elm.icon-tiles := icon" ] ) .on( "events/click", function( evt ) { silk.shop.selection.deselect( "offset" ); this.display.select( "tiles", this.icon ); } ) ; silk.html .query( [ "$( shop/view/listing/bar/display ) := display .silk-elm.icon-detail := icon" ] ) .on( "events/click", function( evt ) { silk.shop.selection.deselect( "offset" ); this.display.select( "detail", this.icon ); } ) ; silk.html .query( [ "$( shop/view/mount ) .silk-object.content-product:not(.detail) := object" ] ) .on( "events/click", function( evt ) { if ( document.body.getAttribute( "data-simply-edit" ) !== null || evt.which !== 1 ) { return; } var link = this.object.domNode.querySelector( ".silk-elm.link > a" ); if ( link !== null ) { var preserve = ( ( typeof( silk.shop.selection.path ) !== "string" ) || !silk.shop.selection.path.length ); if ( followLink( link, true ) ) { evt.preventDefault(); evt.stopImmediatePropagation(); } } } ) ; silk.html .query( "$( shop/categories/section ) := section input := input" ) .on( "events/mutations/change", function( evt ) { evt.preventDefault(); this.section.filter( this.input.domNode.value ); } ) ; silk.shop.iface = {}; var iface = silk.shop.iface; iface.object = xb.core.object.extend( { ctor: function( domNode ) { this.domNode = domNode; } } ); iface.view = xb.core.object.extend( iface.object, { ctor: function( domNode ) { iface.object.prototype.ctor.call( this, domNode ); this.mount = silk.shop.resource.mounts[ domNode.getAttribute( "data-silk-mount" ) ]; }, } ); iface.view.list = xb.core.object.extend( iface.object, { ctor: function( view, domNode ) { iface.object.prototype.ctor.call( this, domNode ); this.view = view; }, } ); iface.view.listing = xb.core.object.extend( iface.view.list, { ctor: function( view, domNode ) { iface.view.list.prototype.ctor.call( this, view, domNode ); }, } ); iface.view.detail = xb.core.object.extend( iface.view.list, { ctor: function( view, domNode ) { iface.view.list.prototype.ctor.call( this, view, domNode ); }, } ); iface.view.listing.bar = xb.core.object.extend( iface.object, { ctor: function( view, domNode ) { iface.object.prototype.ctor.call( this, domNode ); this.view = view; }, } ); iface.view.listing.bar.display = xb.core.object.extend( iface.object, { ctor: function( bar, domNode ) { iface.object.prototype.ctor.call( this, domNode ); this.bar = bar; }, select: function( mode, domNode ) { console.log( "bar.display::select", mode ); silk.shop.selection.deselect( "display" ); silk.shop.selection.select( "display", mode ); silk.shop.view(); } } ); iface.view.listing.bar.sort = xb.core.object.extend( iface.object, { ctor: function( bar, domNode ) { iface.object.prototype.ctor.call( this, domNode ); this.bar = bar; }, } ); iface.categories = xb.core.object.extend( iface.object, { ctor: function( domNode ) { iface.object.prototype.ctor.call( this, domNode ); this.mount = silk.shop.resource.mounts[ domNode.getAttribute( "data-silk-mount" ) ]; }, update: function( index ) { var selection = silk.shop.selection; var ts = Date.now(); //console.error( "selection", selection ); var options = silk.html .query( "$(shop/categories/option) := option [data-simply-field=category-id] := id " ) .find( this.domNode ) ; for ( var i = 0, il = options.length; i < il; i++ ) { options[ i ].option.update( selection, index ); } var te = Date.now(); console.warn( "*tick*", ( te - ts) / 1000 ); }, } ); iface.categories.section = xb.core.object.extend( iface.object, { ctor: function( categories, domNode, multi ) { iface.object.prototype.ctor.call( this, domNode ); this.multi = ( multi !== false ) ? true : false; this.categories = categories; }, toggle: function() { if ( this.domNode.classList.contains( "open" ) ) { this.domNode.classList.remove( "open" ); var input = this.domNode.querySelector( "input" ); if ( input !== null && input.value.length ) { input.value = ""; this.filter( "" ); } } else { this.domNode.classList.add( "open" ); } }, filter: function( string ) { var domNodeID = this.domNode.querySelector( ".silk-id.category-id" ); var _name = domNodeID.textContent; var _value = string; var _parts = _value.toLowerCase().replace( /^\s+/, "" ).replace( /\s+$/, "" ).split( /\s+/ ); var _partsLen = _parts.join( "" ).trim().length; console.log( _name, _value ); var list = this.domNode.querySelectorAll( "[data-simply-list=category-items] [data-simply-field=category-name]" ); var query = silk.html.query( ".silk-listItem := listItem > .silk-object.category-option := object" ); for ( var i = 0, il = list.length; i < il; i++ ) { var item = list[ i ]; var m = query.match( item ); if ( m !== null ) { var content = item.getAttribute( "data-filter-content" ); if ( content === null ) { content = item.textContent; item.setAttribute( "data-filter-content", content ); } m.listItem.domNode.classList.remove( "filter-match" ); m.listItem.domNode.classList.remove( "filter-mismatch" ); if ( _partsLen === 0 ) { item.innerHTML = content; continue; } var o = -1; var f = []; var s = content.toLowerCase(); for ( j = 0, jl = _parts.length; j < jl; j++ ) { var o = s.indexOf( _parts[ j ], o ); if ( o > -1 ) { f.push( o ); } } if ( f.length === _parts.length ) { for ( var j = f.length - 1; j >= 0; j-- ) { o = f[ j ]; var str = _parts[ j ]; var _ = content.substr( 0, o ); _ += "" + content.substr( o, str.length ) + ""; content = _ + content.substr( o + str.length ); } m.listItem.domNode.classList.add( "filter-match" ); } else { m.listItem.domNode.classList.add( "filter-mismatch" ); } item.innerHTML = content; } } } } ); iface.categories.section_search = xb.core.object.extend( iface.categories.section, { ctor: function( categories, domNode ) { iface.categories.section.prototype.ctor.call( this, categories, domNode, false ); this.searches = iface.categories.section_search.searches; }, filter: function( string ) { var self = this; var domNodeID = this.domNode.querySelector( ".silk-id.category-id" ); var _name = domNodeID.textContent; var _value = string; var _parts = _value.toLowerCase().replace( /^\s+/, "" ).replace( /\s+$/, "" ).split( /\s+/ ); var _partsLen = _parts.join( "" ).trim().length; var delay = 300; var op = this.searches[ _name ]; if ( typeof( op ) === "undefined" ) { op = { ctime: Date.now(), cq: _value }; this.searches[ _name ] = op; var execute = function() { var op = self.searches[ _name ]; if ( typeof( op ) === "undefined" ) { console.error( "Canceled search op for", _name, "?" ); return; } var t = Date.now(); var dt = t - op.mtime; if ( dt > delay ) { console.log( "section_search::filter", _name, op.mq ); delete self.searches[ _name ]; silk.shop.selection.deselect( "offset" ); silk.shop.selection.deselect( _name ); silk.shop.selection.select( _name, op.mq ); silk.shop.view(); return; } window.setTimeout( execute, ( delay - dt ) + 10 ); } ; window.setTimeout( execute, delay ); } op.mq = _value; op.mtime = Date.now(); }, } ); iface.categories.section_search.searches = {}; iface.categories.section.option = xb.core.object.extend( iface.object, { ctor: function( section, domListItem, domNode ) { iface.object.prototype.ctor.call( this, domNode ); this.domListItem = domListItem; this.section = section; this.__id = null; }, id: function() { if ( this.__id !== null ) { return this.__id; } var _id = this.domNode.querySelector( "[data-simply-field=category-id]" ).textContent; this.__id = { name: _id.substr( 0, _id.indexOf( ":" ) ), value: _id.substr( _id.indexOf( ":" ) + 1 ), string: _id }; return this.__id; }, toggle: function( link ) { var id = this.id(); console.log( "click", id); if ( typeof( silk.shop.selection.values.id ) !== "undefined" ) { silk.shop.selection.path( "" ); } silk.shop.selection.deselect( "offset" ); if ( link.classList.contains( "selected" ) ) { link.classList.remove( "selected" ); this.domNode.classList.remove( "selected" ); this.domListItem.classList.remove( "selected" ); silk.shop.deselect( id.name, id.value ); } else { if ( !this.section.multi ) { silk.shop.deselect( id.name ); } link.classList.add( "selected" ); this.domNode.classList.add( "selected" ); this.domListItem.classList.add( "selected" ); silk.shop.select( id.name, id.value ); } silk.shop.view(); }, update: function( selection, index ) { var id = this.id(); var object = index[ id.string ]; var selected = selection.isSelected( id.name, id.value ); // console.log( "isSelected(", id.name, ",", id.value, ")", selected ); if ( object[ "category-empty" ] ) { this.domListItem.classList.add( "is-empty" ); } else { this.domListItem.classList.remove( "is-empty" ); } var domNodeLink = this.domListItem.querySelector( "a" ); // if ( domNodeLink.href != object[ "category-name" ].href ) { if ( domNodeLink ) { domNodeLink.href = object[ "category-name" ].href; } if ( selected ) { this.domNode.classList.add( "selected" ); this.domListItem.classList.add( "selected" ); if ( domNodeLink ) { domNodeLink.classList.add( "selected" ); } } else { this.domNode.classList.remove( "selected" ); this.domListItem.classList.remove( "selected" ); if ( domNodeLink ) { domNodeLink.classList.remove( "selected" ); } } } } );