silk.drivers.se = {}; se = {}; se.node = xb.core.object.extend( { factory: function( domNode ) { if ( domNode instanceof Element ) { if ( se.node.is( domNode, "field" ) ) { return new se.node.field( domNode ); } if ( se.node.is( domNode, "list" ) ) { return new se.node.list( domNode ); } if ( se.node.is( domNode, "template" ) ) { return se.node.template( domNode ); } return new se.node( domNode ); } return null; return new se.node.text( domNode ); }, ctor: function( domNode ) { this.__domNode = domNode; this.__children = this.parseChildren(); this.__domNode = this.__domNode.cloneNode(); }, render: function( data ) { var result = this.__domNode.cloneNode(); var children = this.renderChildren( data ); for ( var i = 0, il = children.length; i < il; i++ ) { result.appendChild( children[ i ] ); } return result; }, renderChildren: function( data ) { var result = []; for ( var i = 0, il = this.__children.length; i < il; i++ ) { result.push( this.__children[ i ].render( data ) ); } return result; }, children: function() { return this.__children; }, parseChildren: function( list ) { var list = ( typeof( list ) !== "undefined" ) ? list : this.__domNode.childNodes; var result = []; for ( var i = 0, il = list.length; i < il; i++ ) { var c = se.node( list[ i ] ); if ( c !== null ) { result.push( c ); } } return result; } } ); se.node.text = xb.core.object.extend( se.node, { parseChildren: function() { return []; }, render: function( data ) { return this.__domNode.cloneNode(); }, } ); se.node.is = function( domNode, type ) { switch ( type ) { case "field": if ( domNode.getAttribute( "data-simply-field" ) !== null ) { return true; } break; case "list": if ( domNode.getAttribute( "data-simply-list" ) !== null ) { return true; } break; case "template": if ( domNode.getAttribute( "data-simply-template" ) !== null ) { return true; } break; } return false; } ; se.node.template = xb.core.object.extend( se.node, { factory: function( domNode ) { var domNode = domNode; var tagName = domNode.tagName.toLowerCase(); if ( tagName === "template" ) { var name = domNode.getAttribute( "data-simply-template" ); if ( typeof( domNode.content ) !== "undefined" ) { if ( domNode.content.children.length < 1 ) { return null; } domNode = domNode.content.children[ 0 ]; } else { if ( domNode.children.length < 1 ) { return null; } domNode = domNode.children[ 0 ]; } domNode.setAttribute( "data-simply-template", name ); return new se.node.template( domNode ); } if ( tagName === "body" ) { return new se.node.body( domNode ); } return new se.node.template( domNode ); }, ctor: function( domNode ) { se.node.prototype.ctor.call( this, domNode ); this.__map = this.map(); //console.log( "*template*", this.name(), this.map() ); }, name: function() { return this.__domNode.getAttribute( "data-simply-template" ); }, map: function() { var result = {}; var f = function( node ) { var l = node.children(); for ( var i = 0, il = l.length; i < il; i++ ) { if ( l[ i ] instanceof se.node.field ) { result[ l[ i ].name() ] = l[ i ]; continue; } else if ( l[ i ] instanceof se.node.template ) { continue; } f( l[ i ] ); } } ; f( this ); return result; } } ); se.node.body = xb.core.object.extend( se.node.template, { ctor: function( domNode ) { se.node.template.prototype.ctor.call( this, domNode ); //console.log( "*template*", this.name(), this.map() ); }, name: function() { return "body"; }, } ); se.node.field = xb.core.object.extend( se.node, { ctor: function( domNode ) { se.node.prototype.ctor.call( this, domNode ); }, render: function( data ) { var result = se.node.prototype.render.call( this, data ); var value = data[ this.name() ]; if ( typeof( value ) === "undefined" ) { value = null; } if ( typeof( value ) === "object" ) { for ( var n in value ) { if ( n === "innerHTML" ) { result.innerHTML = value[ n ]; } else { result.setAttribute( n, value[ n ] ); } } } else { result.innerHTML = value; } return result; }, renderChildren: function( data ) { return []; }, name: function() { return this.__domNode.getAttribute( "data-simply-field" ); }, } ); se.node.list = xb.core.object.extend( se.node.field, { ctor: function( domNode ) { this.__map = {}; se.node.field.prototype.ctor.call( this, domNode ); }, name: function() { return this.__domNode.getAttribute( "data-simply-list" ); }, render: function( data ) { return se.node.prototype.render.call( this, data ); }, renderChildren: function( data ) { var result = []; var list = data[ this.name() ]; if ( list instanceof Array ) { for ( var i = 0, il = list.length; i < il; i++ ) { var object = list[ i ]; if ( typeof( object ) !== "object" ) { object = {}; } var tmplName = object[ "data-simply-template" ]; var tmpl = this.__map[ tmplName ]; if ( typeof( tmpl ) === "undefined" ) { tmpl = this.__children[ 0 ]; } var n = tmpl.render( list[ i ] ); n.setAttribute( "data-simply-list-item", true ); result.push( n ); } } return result; }, parseChildren: function() { var result = []; var domNode = this.__domNode; for ( var i = 0, il = domNode.children.length; i < il; i++ ) { var node = domNode.children[ i ]; if ( se.node.is( node, "template" ) ) { var tmpl = se.node( node ); if ( tmpl instanceof se.node.template ) { this.__map[ tmpl.name() ] = tmpl; result.push( tmpl ); } } } return result; } } ); silk.drivers.se.init = function( domNode ) { } ; silk.drivers.se.list = xb.core.object.extend( silk.iface.html.list, { ctor: function( domNode ) { silk.iface.html.list.prototype.ctor.call( this, domNode ); }, db: function() { return this.__domNode.dataBinding.get(); }, object: function( domNode ) { var i = this.__domNode.indexOf( domNode ); var db = this.db(); if ( i >= 0 && i < db.length ) { return db[ i ]; } return null; }, indexOf: function( object ) { return this.db().indexOf( object ); }, move: function( from, to ) { var self = this; var domNode = this.domNode(); var len = domNode.children.length; var fromObject = ( from instanceof silk.drivers.se.list.item ) ? from.object() : null; var toObject = ( to instanceof silk.drivers.se.list.item ) ? to.object() : null; return ( new Promise( function( resolve, reject ) { var i = self.indexOf( fromObject ) , j = self.indexOf( toObject ) , evtHndlr = function( evt ) { if ( domNode.children.length < len ) { console.warn( "silk.drivers.se.list::move", "remove callback?" ); return false; } domNode.removeEventListener( "databind:elementresolved", evtHndlr ) resolve( self.instance( domNode.children[ j ] ) ); } ; j = ( j >= 0 ) ? j : self.db().length; domNode.addEventListener( "databind:elementresolved", evtHndlr ); self.db().splice( i, 1 ); self.db().splice( j, 0, from.data() ); } ) ); }, remove: function( item ) { var self = this; var domNode = this.domNode(); var object = ( item instanceof silk.drivers.se.list.item ) ? item.object() : null; return ( new Promise( function( resolve, reject ) { var evtHndlr = function( evt ) { domNode.removeEventListener( "databind:elementresolved", evtHndlr ) resolve( null ); } ; domNode.addEventListener( "databind:elementresolved", evtHndlr ); var i = self.indexOf( object ); if ( i < 0 ) { return resolve( null ); } self.db().splice( i, 1 ); } ) ); }, insertBefore: function( item, refItem ) { var self = this; var newItem = null; var domNode = this.domNode(); var object = ( item instanceof silk.drivers.se.list.item ) ? item.object() : null; var refObject = ( refItem instanceof silk.drivers.se.list.item ) ? refItem.object() : null; return ( new Promise( function( resolve, reject ) { var i = -1 , data = item.data() , evtHndlr = function( evt ) { var result = domNode.children[ i ]; return resolve( ( typeof( result ) !== "undefined" ) ? self.instance( result ) : null ); } ; if ( refObject !== null ) { i = self.indexOf( refObject ); } if ( i < 0 ) { i = self.db().length; } domNode.addEventListener( "databind:elementresolved", evtHndlr ); self.db().splice( i, 0, data ); } ) ); }, } ); silk.drivers.se.list.item = xb.core.object.extend( silk.iface.html.list.item, { ctor: function( list, domNode ) { silk.iface.html.list.item.prototype.ctor.call( this, list, domNode ); this.__object = this.__list.object( domNode ); }, template: function() { if ( this.__template === null ) { var templates = this.__list.templates(); this.__template = templates.get( this.get( "data-simply-template" ) ); } return this.__template; }, object: function() { return this.__object; }, field: function( fieldName ) { return this.object()[ fieldName ]; }, data: function() { return JSON.parse( JSON.stringify( this.object() ) ) }, } ); silk.drivers.se.templates = xb.core.object.extend( { ctor: function( db ) { this.__db = db; this.__list = null; this.__list = this.list(); }, list: function() { if ( this.__list === null ) { var templates = this.__db; var result = {}; for ( var name in templates ) { result[ name ] = silk.drivers.se.templates.item( this, name, templates[ name ] ); } this.__list = result; } return this.__list; }, get: function( name ) { var list = this.list(); var result = list[ name ]; if ( typeof( result ) === "undefined" ) { console.warn( "silk.drivers.se.templates::get", name, "template not found" ); for ( name in list ) { break; } result = list[ name ]; } return ( typeof( result ) !== "undefined" ) ? result : null; }, match: function( template, data ) { var result = []; var list = this.list(); var data = ( typeof( data ) === "item" ) ? data : {}; var fields = template.fields(); for ( var name in list ) { var __template = list[ name ]; var __fields = __template.fields(); var __result = { name: name, len: 0 , template: [], data: [] }; for ( var fieldName in __fields ) { __result.len += 1; var __field = __fields[ fieldName ]; var field = fields[ fieldName ]; if ( typeof( field ) !== "undefined" && field === __field ) { __result.template.push( fieldName ); } else if ( typeof( data[ fieldName ] ) !== "undefined" ) { if ( __field === "list" && ( data[ fieldName ] instanceof Array ) ) { __result.data.push( fieldName ); } else if ( __field === "field" ) { __result.data.push( fieldName ); } } } if ( __result.template.length || __result.data.length ) { result.push( __result ); } } result.sort( function( a, b ) { var ra = ( a.template.length + a.data.length ); var rb = ( b.template.length + b.data.length ); if ( ra === rb ) { return a.len - b.len; } return rb - ra; } ); return result; }, } ); silk.drivers.se.templates.item = xb.core.object.extend( { ctor: function( list, name, template ) { this.__list = list; this.__name = name; this.__template = template; }, list: function() { return this.__list; }, name: function() { return this.__name; }, domNode: function() { return this.__template; }, fields: function() { var domNode = this.domNode() , elm = document.createElement( "div" ) // FIXME: