Uploaded ' + file.name + ' ' + (file.size ? (file.size/1024|0) + 'K' :'');
}
},"readfiles":function(arg/*,_this*/){
if( arg.files.length > 0 ){
let i, send={},dd=Libra.data.dd,
formData = dd.tests.formdata ? new FormData() : null
//Libra.data.upload = Libra.data.upload||Libra.Eav.getObject({info:true,objectName:'data.store.storeDocument.data'});
//arg.send.storeClassDataId=Libra.data.upload.objectModel.classId
arg.send.path='server://Document/upload'
arg.send.class='Document'
arg.send.fn='upload'
arg.send._bus='msg'
arg.send.busData='server'
arg.send.busDb='data'
for( i = 0; i < arg.files.length; i++){
if(dd.tests.formdata) formData.append( 'file' , arg.files[ i ])
this.previewfile( arg.files[ i ])
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function (rsc){
let res = rsc.target
if( res.readyState == 4 && res.status == 200 ) Libra.Network.requestComplete(rsc,this)
}
xhr.open( 'POST', Libra.data.path.proxy + '?_libra=' + JSON.stringify( arg.send ) + '&' + encodeURIComponent( Libra.Network.getExtraParams()))
xhr.send(formData)
}}},"start":function(arg){
arg.send = arg.send || {}
if(arg.record){
arg.send.targetBusDb=/*arg.obj._libra.busDb*/'data'//TODO
arg.send._libraDocumentId = arg.record[ Libra.data.eav.id ]
}
arg.files = arg.event.dataTransfer.files
this.readfiles( arg )
}}
dd.fileupload = add({
parent: body,
tag:'p',
hidden:true,
//stile:'display: none !important;',
id:'_libraUpload',
html:''
})
dd.filereader = add({
parent: body,
tag:'p',
hidden:true,
//id:'_libraFilereader'
})
dd.formdata = add({
parent: body,
tag:'p',
hidden:true,
//id:'_libraFormdata'
})
dd.tests = {
filereader: typeof FileReader != 'undefined',
dnd:'draggable' in document.createElement('span'),
formdata: !!window.FormData,
progress: "upload" in new XMLHttpRequest
}
dd.support = {
filereader: dd.filereader /*document.getElementById('filereader')*/,
formdata: dd.formdata/*document.getElementById('formdata')*/
}
dd.acceptedTypes = {
'image/png': true,
'image/jpeg': true,
'image/gif': true
}
//fileupload = js.Libra.Dd.obj/*document.getElementById('upload')*/
"filereader formdata".split(' ').forEach(function (api){
let dd = Libra.data.dd
if(dd.tests[api] === false) dd.support[api].className = 'fail'; else dd.support[ api ].className = 'hidden'
})
body.on( 'dragover', /*Libra.debounce( */e => {
let node
e.preventDefault()
if( e.target.tagName === 'LIBRA-TABLE' && e.target.dataset.editing === '1' ){
node = e.getRow()
if( node ) e.target.selectItem( node )
}
}/*, 100)*/)
body.on('drop',function(e){
let arg={event:e}
e.preventDefault()
e.stopPropagation()
/* let component=Libra.findComponentByElement(target),
libraView=component.up('libraView'),
libraViewArgXtype=libraView._libra.xtype,
arg={event:event}*/
//if(libraViewArgXtype)
//{
//let targetView=libraView.down(libraViewArgXtype)
//arg.obj=targetView
switch(e.target.tagName){
case 'LIBRA-TABLE':
arg.row = e.getRow()
debug(arg.row)
arg.record = arg.row.record
break
case 'libraForm':
debug('TODO DD FORM')
arg.record=e.target.record
break
}
//}
Libra.Dd.start( arg )
return false
},false)
}},
clone:function(arg){
if( arg instanceof HTMLElement || typeof arg !== 'object' ) return arg
let i, obj = arg instanceof Array ? [] : {}
for( i in arg ){
if( arg && typeof arg[ i ] === 'object' && arg [ i ] instanceof Object ) obj[ i ] = Libra.clone( arg [ i ])
else obj[ i ] = arg [ i ]
}
return obj
},
// merge:function(out,inp){
// if( !out ) return inp
// for(let prop in inp ){
// let split = prop.split(' ')
// if(split.length>1){
// out.__defineGetter__(split[1], inp.__lookupGetter__(split[1]))
// out.__defineSetter__(split[1], inp.__lookupSetter__(split[1]))
// }
// if( typeof inp[ prop ] === 'object' ) out[ prop ] = Libra.merge( out[ prop ], inp[ prop ]); else out[ prop ] = inp[ prop ];
// }
// return out
// },
Notify:{"add":function(group,arg,args=null){
let i, cnt=Libra.data.notify.count
debug('notify:',this,group,arg,args,this.btn)
/*let store = Libra.data.store.storeMessage,
msg
//TODO abilitare
if( !Array.isArray( arg )) arg = [ arg ]
for( i in arg ){
msg = { text: group, _libraObject: arg[ i ], description: JSON.stringify( arg[ i ])}
if( store.add ) store.add( msg )
else store.data.push( msg )}
if( this.btn ){
this.btn.incBadgeText( cnt )
cnt = 0}else cnt++*/
}},
Class:{
classObjects:function(arg){
if( arg === this.constructor.name ){
let i, cfg = window.class[ arg ], data = cfg.classObjects
for( i in data ) this[ data[ i ] ] = Libra.clone( window.class[ arg ][ data[ i ] ])
}
return this
},
addMethod:function(arg){
let cfg = arg.cfg , target = arg.target, method = arg.method
if( !Libra.data.class.prototypeExclude.includes( method )){
if( cfg.static && cfg.static.includes( method )) targetForMethod = target; else targetForMethod = target.prototype
if( method.trim().indexOf(' ') !== -1 ){
let gs = method.trim().split(' ')
if( gs[ 0 ] === 'get' ) targetForMethod.__defineGetter__( gs[ 1 ], cfg[ method ])
else targetForMethod.__defineSetter__( gs[ 1 ], cfg[ method ])
}else switch (typeof cfg[ method ]){
case 'function': targetForMethod[ method ] = cfg[ method ]; Object.defineProperty( targetForMethod[ method ], "name", { value: method }); break
case 'object':
default:arg.cfg.classObjects.push( method ); break
}}
},
getConstructor:function(cfg,cn,cne=null){
if( cfg.hasOwnProperty( 'constructor' )) cfg._constructor = cfg.constructor
delete( cfg.constructor )
let cc = ( cfg.hasOwnProperty( '_constructor' ) ? "window.class." + cn + "._constructor.call( that, arguments );" : "" )
if( cne ) return ( new Function( "let that = Reflect.construct( window." + cne + " || Libra.data.class." + cne + ", arguments, this.constructor ); that = Libra.Class.classObjects.call( that, '" + cn + "' );" + cc + "return that" ))
return cfg._constructor
},
extend:function( child, prototype, parent ){
if( !parent ) parent = Object
let i, cfg = window.class[ parent.name ]
child.prototype = Object.create( parent.prototype )
child.prototype.constructor = child
if( cfg ) for( i in cfg.static ){
arg = {
target: child,
cfg:{ static: [] },
method: cfg.static[ i ]
}
arg.cfg.static.push( arg.method )
arg.cfg[arg.method] = cfg[ arg.method ]
Libra.Class.addMethod( arg )
}
for( i in prototype ) if( prototype.hasOwnProperty( i )) Libra.Class.addMethod({ target: child, cfg: prototype, method: i })
let cfgParent = cfg
if( cfgParent ){
let name
for( i in cfgParent.classObjects ){
name = cfgParent.classObjects[ i ]
if( !Libra.data.class.classObjectsParentExclude.includes( name )){
if(!prototype[name]) prototype.classObjects.push( name )
prototype[ name ] = prototype[ name ] ? Libra.merge( Libra.clone( cfgParent[ name ]), prototype[ name ]) : Libra.clone( cfgParent[ name ])}}}
Libra.Class.super( child, parent )
},
super:function(Child1,Parent1){
let proto1
if( Child1.prototype ) proto1 = Child1.prototype; else proto1 = Child1
proto1.super = function( fn ){
let parent, pt = this, cfg = window.class
if( !fn ) fn = arguments.callee.caller.name
if( !pt._libraBufferFn[ fn ]){
pt.extends = pt._libraConfigExtends
while ( cfg[ pt.extends ] && !cfg[ pt.extends ].hasOwnProperty( fn )) pt.extends = cfg[ pt.extends ].extends
if( !cfg[ pt._libraClassName ].hasOwnProperty( fn )){
pt.extends = cfg[ pt.extends ].extends
while ( cfg[ pt.extends ] &&! cfg[ pt.extends ].hasOwnProperty( fn )) pt.extends = cfg[ pt.extends ].extends
}
}else while ( cfg[ pt.extends ] && !cfg[ pt.extends ].hasOwnProperty( fn )) pt.extends=cfg[ pt.extends ].extends
if( cfg[ pt.extends ]){
parent = cfg[ pt.extends ], ptPnt = parent
let oldExtends = pt.extends
pt.extends = ptPnt.extends
if( !ptPnt.hasOwnProperty( fn )) error( 'prototype ' + oldExtends + ' has no function:' + fn )
pt._libraBufferFn[ fn ] = 1
ptPnt[ fn ].call( this, ...arguments.callee.caller.arguments )
pt.extends = oldExtends
delete( pt._libraBufferFn[ fn ])
}else error( 'prototype ' + pt.extends + ' has no function:' + fn )
}
},
is:function( arg ){
arg = Libra.merge( arg, {
constructor:function(){this._doNotapplyBindOnCreateNode = 1 },
debug:Libra.data.class.libraContainer.prototype.debug,
connectedCallback:function(){
//TODO provare spostare binding in dom
let text, bind, ds = this.dataset
this.id = this.id || Libra.getId()
if(this.getAttribute( 'is' ) === 'libra-codearea' ){//TODO
this.render=function(){
//this.classList.add('card-header')
let cfg = {
readOnly:false//!!me.readOnly,//'{readOnly}'
,lineWrapping: true,
lineNumbers: true,
tabSize: 4,
indentUnit: 4
//, mode: "javascript"
//,bind:{theme:'{libraCodeMirror.theme}'}
,mode: "application/x-httpd-php-open"
,gutters: ["CodeMirror-lint-markers"],
lint: true
,styleActiveLine: true,
matchBrackets: true
}
//TODO controllare if( Libra.data.user.libraEditorCode.theme ) cfg.theme = Libra.data.user.libraEditorCode.theme
CodeMirror.modeURL = Libra.data.modules.codemirror.pathLib + 'mode/%N/%N.js'
this.editor = CodeMirror.fromTextArea( this, cfg)
if(this.className)this.editor.display.wrapper.className+=' '+this.className
this.editor.display.wrapper.className+=' '+'border indent'
//if(this.onInitEditor)this.onInitEditor(this.editor)
//this.editor.setValue(this.record)
//vmd.form.classList.add( 'h-100' )
//vmd.editor.display.wrapper.classList.add( 'h-100' )
}}
if( this.requires && ( this.requires.mod.length || this.requires.class.length )){//TODO complettare
this._wait = true
for( i in this.requires.mod ) Libra.modprobe( this.requires.mod[ i ]).then({ fn: () => { this.render();if(this.onRender)this.onRender(this)}})
//return false
}
if( this.tagName === 'BUTTON' ){
this.classList.add( 'btn' )
if( this.href ) this.on( "click", e => Libra.Utils.analizeNode(this) )
if( ds.toggling ){
ds.pressed = ds.pressed || '0'
this.value = ds.pressed.eval()
this.on( "click", e => this.value = !this.value )}}
if([ 'BUTTON','A'].includes( this.tagName )){
this.classList.add( 'cp' )
//if( ds.pressed ) this.classList.add( 'active' )
if( ds.ui ) this.classList.add( 'btn-' + ds.ui )
if( ds.iconCls ) this.classList.add( 'fa', ds.iconCls )
if( this.childNodes.length || this.innerHTML != '' || this.textContent != '' ) this.classList.add( 'famr' )
if( this.hasAttribute( 'hash' )) ds.hash = this.getAttribute( 'hash' )
if( ds.hash ){this.on( "click", e => location.hash = ds.hash )}}
if( ds.reference ) this.getViewModel().setReference( ds.reference, this )
if( ds.bind ) bind = ds.bind
if( this.bind ) bind = this.bind
if( bind ) Libra.Dom.bind({node: this, bind: bind })
}})
//TODO spostare nella class
if(arg.extends==='HTMLButtonElement'){
/*arg = Libra.merge( arg, {
getValue:function(){return this.dataset.pressed.eval()},
"get value":function(arg){debug('qui',arg,this);return this.dataset.pressed.eval()},
"set value":function(a){this.dataset.pressed=a;this.classList[a?'add':'remove']( 'active' )}})*/
arg.getValue=function(){return this.dataset.pressed.eval()}
arg["get value"]=function(arg){/*debug('qui',arg,this);*/return this.dataset.pressed.eval()}
arg["set value"]=function(a){this.dataset.pressed=a;this.classList[a?'add':'remove']( 'active' )}
}
return arg
},"init":function(arg){
let cn=arg.name, is, cfg=arg.cfg, data, cfgs = window.class, datas = Libra.data.class, parent = Object
if(!datas[cn])
{
let cne, parent,
//cfg = cfgs[ cn ],
ced = cfg.customElementsDefine,
is = ced?Libra.data.xtype[ced.replace(/^libra-/,'')].is:null
cfg.classObjects = Libra.clone( Libra.data.class.classObjectsParentExclude )
if( cfg.extends ){
cne = cfg.extends
parent = datas[ cne ] || window[ cne ]
}
if( is ) cfg = Libra.Class.is( cfg )
data = datas[ cn ] = Libra.Class.getConstructor( cfg, cn, cne )
Object.defineProperty( data, "name", { value: cn })
Libra.Class.extend( data, cfg, parent )
cfg._libraClassName = cn
cfg._libraBufferFn = {}
cfg._libraConfigExtends = cne
//TODO sistemare
if( ced ) customElements.define( ced, data, is ? { extends: ced==='libra-codearea'?'textarea':ced.replace( /^libra-/ , '' )} : null )
}
return cfg
}},
Modules:{
loaded:function( arg ){
Libra.Network.sessionCheck({ 'session': arg.session, pathLibra: arg.moduleName }, true )
Libra.data.modules.loaded[ arg.moduleName ] = true
},
modprobe:function( arg ){
let session = 'module' + Libra.getSessionId()
let ret = []
if( typeof arg === 'string' ) arg = [ arg ]
Libra.data.network.session[ session ] = { path:{}, owner:'modprobe' }
arg.forEach( function( item ){
if( Libra.data.modules.loaded[ item ] === true ) return false
try {
Libra.data.network.session[ session ].path[ item ] = item
ret.push(Libra.Modules[ item ]( session ))
} catch( err ){
error( 'module ' + item + ' is not loaded successfully' )
debug( err )
delete( Libra.data.network.session[ session ])
Libra.data.modules.loaded[ item ] = false
}
})
Libra.Network.sessionCheck({ 'session': session }, true )
return {
then:function( arg ){
if( !arg.fn ) error( 'error: then must be {fn:..,scope:..}' )
if( Libra.data.network.session[ session ]) Libra.data.network.session[ session ].cb = arg
else arg.fn.call( arg.scope, ret )
}
}
},"network":function( arg ){
Libra.Network.load({ cache: true, charset: "iso-8859-1", path: Libra.data.path.fw + "socket.io/socket.io.slim.bs.js"
},{ fn: () => Libra.Modules.loaded({ session: arg, moduleName:'network'})})
}},
Network:{
load:function( arg, args = { session: null, fn: null, scope: null }){
let i, j, ext, path, script, prior, session
if( typeof args !== 'object' ) error( 'Loader.load: args is incorrect' )
if( typeof arg.path === 'undefined' ){error( 'load:arg.path is needed' ); return false }
if( !Array.isArray( arg.path )) arg.path = [ arg.path ]
if( args.fn || args.session ){
session = args.session || Libra.getSessionId()
Libra.data.network.session[ session ] = { cb:args, path:{}}
}
for( i in arg.path ){
path = ( arg.pathPrefix ? arg.pathPrefix :'' ) + arg.path[ i ]
if( session ) Libra.data.network.session[ session ].path[ path ] = false
if( arg.cache && Libra.Network.isLoaded( path )){
if( session ) delete( Libra.data.network.session[ session ].path[ path ])
continue
}
ext = path.split( '.' )
ext = ext[ ext.length-1 ].toLowerCase()
switch ( ext ){
case 'css': script = document.createElement( 'link' ); prior = document.getElementsByTagName( 'head' )[ 0 ]; script.rel = 'stylesheet';/* script.media = 'screen' */ break
case 'js':
case 'php':
default: script = document.createElement('script'); prior = document.getElementsByTagName('script')[ 0 ]; break
}
script.async = Libra.data.network.asyncMode
script.pathLibra = path
if( session ) script.session = session
prior.parentNode.insertBefore( script, prior )
script.onerror = function(){Libra.Network.sessionCheck( this, false ); delete( Libra.data.network.session[ this.session ])}//TODO error
script.onload = script.onreadystatechange = function( _, isAbort ){
if( isAbort || !/*script*/this.readyState || /loaded|complete/.test( script.readyState )){
this.onload = this.onreadystatechange = null
if( !isAbort ){Libra.data.network.loaded[ this.pathLibra ] = 1; if( this.session ) Libra.Network.sessionCheck( this, true )}
else{ Libra.data.network.loaded[this.pathLibra]=0; if( this.session ) delete( Libra.data.network.session[ this.session ])}
}
}
let extraParams = Libra.Network.getExtraParams()
if( session ) extraParams._libraCbSession = session
let strArr=[]
for( j in extraParams ) strArr.push( j + '=' + extraParams[ j ])
path += ( path.includes( '?' ) ? '&' :'?' ) + strArr.join( '&' )
switch( ext ){
case 'css': script.href = path; break
case 'js':
case 'php':
default:
if( arg.charset ) script.charset = arg.charset
script.src = path
break
}
}
return session
},
sessionCheck:function( arg, load ){
let i = Libra.data.network.session,
j = arg.session
if( i[ j ]){
delete( i[ j ].path[ arg.pathLibra ])
if( Object.keys( i[ j ].path ).length === 0 ){
if( i[ j ].cb ) i[ j ].cb.fn.call( i[ j ].cb.scope, i[ j ].return, load )
delete( i[ j ])
}
}
},"send":function(_bus,_data=null,args={url:null,fn:null,scope:null}){
let msg = {
_bus: _bus,
_userId: Libra.data.user.id,
_siteId: Libra.data.site.id,
CID: Libra.Cookie.get( 'CID' )
},
_cb = args.fn,
_scope = args.scope
if( _data )
msg._libra = _data
//TODO rifare bene
if( args.params ) msg = Libra.merge( msg, args.params )
if( args.extraParams ) msg = Libra.merge( msg, args.extraParams )
msg = Libra.merge(msg, this.getExtraParams())
if( msg._libra && typeof msg._libra === 'string' ) msg._libra = JSON.parse( msg._libra )
if( _cb ){
msg._cbId = 'cb' + Libra.getSessionId()
//TODO unire con delle sessioni esistenti
Libra.data.requestCb[ msg._cbId ] = { fn: _cb, scope: _scope }
}
if( Libra.data.network.sync ){
msg._bus = _bus
debug( 'emit', _bus, msg )
return this.io.emit( _bus, msg )
}
else{
//delete(msg._bus);
msg._nwVector = 'http'
msg._libra = JSON.stringify( msg._libra )
let _request = {
url: args.url || Libra.data.path.proxy,
method:'POST',//'POST','GET'
//jsonData:msg
params: msg/*Ext.util.JSON.encode(msg)*/
,success: this.requestSuccess
,failure: this.requestFailure
//,headers:{
//'Content-Type':'application/json'
//}
,useDefaultXhrHeader: false
,cors: true
//,withCredentials: false
//,crossDomain: true
//,callback:Client.Network.requestFailure (options,success,response)
//,callback:_cb
//,scope:_scope
}
debug( 'send', _bus, msg )
msg._libra = encodeURIComponent( msg._libra )
let _fetch = fetch( args.url || Libra.data.path.proxy , {
method:'POST',
body: JSON.stringify( msg )
}).then( response => { //TODO elaborare status
_fetch.responseClone = response.clone()
return response.json()
}).then( responseJson => { //TODO elaborare status
return Libra.Network.requestComplete( _fetch.responseClone ,responseJson )
}).catch( debug )/*.catch(function(response){
Libra.Network.requestFailure(response)})*/
return _fetch
}
},
getExtraParams:function(){
/*TODO group developer */
let _return = {
_siteId: Libra.data.site.id,
_lang: Libra.data.user.lang,
_userId: Libra.data.user.id,
CID: Libra.Cookie.get( 'CID' ),
LibraNamespace: Libra.data.site.LibraNamespace,
_nwVector: Libra.data.network.sync ? 'ws' : 'http'
}
//TODO if(Libra.data.network.sync) _return._nwId=Libra.data.network.id
if( Libra.data.debug._libraDebug ) Libra.merge( _return, Libra.data.debug )
return _return
},"requestComplete":function ( conn, response, opt, eOpts ){
let responseJson={}
if( response.responseJson ) responseJson = response.responseJson
else if( response.responseText ){
if( response.responseText.charAt( 0 ) === '<' ) return Libra.Bus.debug( response.responseText,{ conn: conn, response: response, opt: opt, eOpts: eOpts })
//TODO send to error non debug
if( response.responseText.charAt( 0 ) === Libra.data.regex.braceBegin ) responseJson = JSON.parse( response.responseText )
}
else
responseJson = response
Libra.Bus.msg( responseJson, {conn: conn, response: response,opt: opt,eOpts: eOpts })
},"handlerCb":function(resp){
if(Libra.data.requestCb[resp._cbId]){
//TODO analizzare response callback
var cb=Libra.data.requestCb[resp._cbId]
//with(Libra.data.requestCb[resp._cbId]){
if(cb.scope)
cb.fn.call(cb.scope,resp)
else
cb.fn(resp)
//}
//var _resCb=Libra.data.requestCb[resp._cbId].fn.apply(Libra.data.requestCb[resp._cbId].scope,resp);
delete(Libra.data.requestCb[resp._cbId])
}
},"isLoaded":function( arg ){
if( Libra.data.network.loaded[ arg ] && Libra.data.network.loaded[ arg ] === 1 )
return true
return false
}},
Json:{
encode:function( obj, _a = function( key, val ){
let regex = Libra.data.regex
if( typeof val === 'function' ){
val =val + ''
if( val.slice( -4 ) === regex.functionFineTo ) val=val.rtrim( 4 ) + regex.braceEnd
val = val.rtrim( 1 ) + regex.functionFineTo
}
return val
},_b=null){
return JSON.stringify(obj,_a,_b)
},
decode:function( str, _a = function( key, val ){
if( typeof val === 'string' && val.substring( 0, 9 ) === 'function(' ){
val = val.rtrim( 4 ) + Libra.data.regex.braceEnd
val = eval( "fn=" + val )
}
return val
}){
return JSON.parse(str,_a)
},
transformLang:function( obj, prop, val ){
let res = lang( val )
if( res ) obj[ prop === 'lang' ? ( Libra.isHTML( res ) ? 'html' : 'text' ) : prop ] = res
return obj
},
transform:function(arg){
if( arg.viewName ) if( data.view[ arg.viewName ]){let _vn = arg.viewName; delete( arg.viewName ); arg = Libra.merge( arg, data.view[ _vn ] )} else error('configure: view: ', arg.viewName)
let i, arr
if( arg.lang ){
if(typeof arg.lang === 'object') for( let i in arg.lang ) arg = this.transformLang( arg, i, arg.lang[ i ] )
else arg = this.transformLang( arg, 'lang', arg.lang )
}
if( arg.text ){
if( !arg.nodeType && !arg.tag && !arg.xtype ){arg.nodeType = 3; arg.nodeValue = arg.text }
else arg.textContent = arg.text
}
arg.nodeType = arg.nodeType || 1
arg.attributes = arg.attr || {}
if( arg.xtype ){
let xtype = Libra.data.xtype[ arg.xtype ]
if( xtype.is ){
//TODO sistemare
arg.tagName = xtype.transform || arg.xtype
arg.is = 'libra-' + arg.xtype
arg.attributes.is = arg.is
}else arg.tagName = 'libra-' + arg.xtype
}
//if(arg.bind&&typeof arg.bind!=='string') arg.bind=JSON.stringify(arg.bind)
arr = { items:'childNodes', tag:'tagName', parent:'parentNode' }
for( i in arr ) if( arg.hasOwnProperty( i )) arg[ arr[ i ] ] = arg[ i ]
arr = { disabled:1, form:1, scope:1, slot:1, hidden:1, title:1, name:1, type:1, cls:'class', css:'style' }
for( i in arr ) if( arg.hasOwnProperty( i )) arg.attributes[ ( arr[ i ] === 1 ? i : arr[ i ])] = arg[ i ]
arr = { tabbed:1,hash:1,toggling:1,pressed:1,propertyValue:'property-value',statusing:1,hideTrigger:1,view:1, closing:1, tabTitle:'tab-title',viewTitle:'view-title', tpl:'template',tplName:'template-name', layout:1,/*bind:1,*/ cmd:1, ref:'reference', ui:1, select:1, editing:1, checking:1, filtering:1, storeName:'store-name', modelName:'model-name', iconCls:'icon-cls', recordId:'record-id' }
arr[ Libra.data.eav.id ] = Libra.data.eav.idAttr
arr[ Libra.data.eav.key ] = Libra.data.eav.keyAttr
for( i in arr ) if( arg.hasOwnProperty( i )) arg.attributes[ 'data-' + ( arr[ i ] === 1 ? i : arr[ i ])] = arg[ i ]
if( !arg.tagName ) arg.tagName = 'div'
return arg
},
dom:function( objs, arg = { parentNode:null, appendChild:true, scope:null }){
let parentNode, objsKey, obj, node, nodeType, i, j, len, viewController, isArray = false, ret = [],
arr = { bind:1,watch:1,/*modelName:1,*/autocomplite:1,checked:1,href:1,unselectable:1,onselectstart:1,onmousedown:1,placeholder:1,action:1,for:1,src:1,eventDetail:1,vmd:1,itemName:1,target:1,arguments:1,adding:1,/*_linkedNode:1,_linkedView:1,_linkedViewTarget:1,*/_isTabbed:1,width:1,value:1,treeParent:1,name:1, libraEventTarget:1, oldClass:1, id:1, is:1, record:1, renderBodyItemDone:1, columnKey:1, tabBody:1, /*rendered:1,*/ tbar:1, _libra:1, store:1, /*propertyValue:1,*/ html:'innerHTML', textContent:1, viewModel:1, renderChange:1,viewController:1,_itemKey:1,wmMenuViewSilent:1,defaults:1,requires:1, type:1 } //TODO forse aggiungere tutti? array di variabili che vengono passate direttamente in dom
if( typeof objs === 'string' ) try{ objs = JSON.parse( objs )} catch ( e ){ if(Libra.isHTML(objs)) objs = {html:objs};else objs = {text:objs} }
isArray = Array.isArray( objs )
if( !isArray ) objs = [ objs ]
for( objsKey in objs ){
obj = objs[ objsKey ]
if( arg.defaults ) obj = Libra.merge( Libra.clone( arg.defaults ), obj )
// obj.tag=obj.tag||'div'
if( !obj.nodeType ) obj = Libra.Json.transform( obj )
nodeType = obj.nodeType
parentNode = obj.parentNode || arg.parentNode
//TODO per errore; togliere in futuro
if(parentNode&& !(parentNode instanceof HTMLElement||parentNode instanceof ShadowRoot)){error('parentNode is not HTMLElement: obj:',objs, 'arg:',arg,'node:',node,'parentNode:',parentNode); delete(parentNode);parentNode=null}
switch ( nodeType ){
case 1: /* ELEMENT_NODE */
node = document.createElement( obj.tagName, obj.is && Libra.data.xtype[ obj.is.replace( /^libra-/, '' ) ].is ? { is:obj.is } : null )
if( parentNode ) Object.defineProperty( node, 'parentNode', { value: parentNode })
for( i in obj.attributes ) if( !( !isAria && i.match( /^aria-/ ))) node.setAttribute( i, obj.attributes[ i ])
break //TODO togliere tpl
case 3: /* TEXT_NODE */ if( obj.nodeValue ) node = document.createTextNode( obj.nodeValue )/*; else if( obj.libraTpl ) node = document.createTextNode( Libra.fillTemplate( obj.libraTpl ,arg.scope )); */;break
case 8: /* COMMENT_NODE */ node = document.createComment( obj.nodeValue ); break
case 9: /* DOCUMENT_NODE */ node = document.implementation.createDocument(); break
case 10: /*DOCUMENT_TYPE_NODE */ node = document.implementation.createDocumentType( obj.nodeName ); break
case 11: /* DOCUMENT_FRAGMENT_NODE */ node = document.createDocumentFragment(); break
default: return node
}
if( !parentNode && !arg.before && !arg.after ) error( 'warning: parentNode is ubsent:', obj, node )
for( i in arr ) if( obj.hasOwnProperty( i )){
j = ( arr[ i ] === 1 ? i : arr[ i ])
node[ j ] = node.hasOwnProperty( j )? Libra.merge( node[ j ], obj[ i ]) : obj[ i ]
}
ret.push( node )
if( obj.events ){
for( let eventName in obj.events ){
switch( eventName ){
case 'render':
setTimeout( function(){this.fn.call( this.node )}.bind({ fn: obj.events[ eventName ],node: node }), 0 )
break
default:
let fn = obj.events[ eventName ]
if( typeof fn=== 'string' ){
viewController = node.getViewController({ property: fn })
if( viewController )node.on( eventName, viewController[ fn ]); else error( 'function ' + fn + ' is not declared for node ' + node )
}
else node.on( eventName, fn )
break
}}}
if( arg.appendChild !== false ){
if( parentNode ){parentNode.appendChild( node ); if( parentNode.viewModel ) parentNode.viewModel.data.lastAddedItem = node }
else if( arg.before ) arg.before.before( node )
else if( arg.after ) arg.after.after( node )
}
if( obj.handler ){
if( typeof obj.handler === 'function' ) node.on( 'click', obj.handler )
else{
viewController = node.getViewController({ property: obj.handler })
if( viewController[ obj.handler ]) node.on( 'click', viewController[ obj.handler ])
else error('dom: handler:' + obj.handler + ' is not defined in viewController')
}}
if( obj.bind && !node._doNotapplyBindOnCreateNode ) Libra.Dom.bind({ node: node, bind: obj.bind })
if( nodeType === 1 || nodeType === 11 ){
let childNodes = obj.childNodes || [], defaults = obj.defaults || {}
for( i = 0, len = childNodes.length; i < len; i++ ){
let childNode = childNodes[ i ], addedNode, argChild
if( childNode.localName ) addedNode = node.appendChild( childNode ) //TODO applicare forse renderItem???
else{
childNode = Libra.merge( Libra.clone( defaults ), childNode )
if( childNode.bind ) childNode.bind = childNodes[ i ].bind
delete( arg.parentNode )
argChild = Libra.clone( arg )
delete( argChild.defaults )
argChild.parentNode = node
argChild.appendChild = true
if( node.template ){
childNode = node.template.use({ self: node, scope: childNode })
argChild.parentNode = node.viewModel.data.body
}
addedNode = Libra.Json.dom( childNode, argChild )
}}}
}
return isArray ? ret : ret[ 0 ]
}},
getViewModel:function(node){ return node.viewModel ? node.viewModel : ( node.getViewModel ? node.getViewModel() : null )},
Dom:{
bind:function(arg){
let t = { text:'textContent', html:'innerHTML' }
for( let i in t )
if( arg.bind[ i ] ){
arg.bind[ t[ i ]] = arg.bind[ i ]
delete arg.bind[ i ]
}
if( !arg.node.id ) arg.node.id = Libra.getId()
let bindKey, bindJson = null, argBindAll = {}
if( typeof arg.bind === 'string' ){
try{ bindJson = JSON.parse( arg.bind )} catch ( e ){ bindJson = arg.bind }
if( typeof bindJson === 'string' ){
//shema semplificata di configurazione senza indicare proprietà su cosa viene bindato; portarlo alla configurazione necessaria
arg.bind = {}
switch( arg.node.tagName ){
case 'LIBRA-FORM': targetProperty = 'record'; break
case 'INPUT': targetProperty = 'value'; break
default: targetProperty = 'textContent'; break
}
arg.bind[ targetProperty ] = bindJson
}else arg.bind = bindJson
}
for( bindKey in arg.bind ){
let sourceString = arg.bind[ bindKey ], createTextNode = false, argBind = {}
if( typeof sourceString === 'string' ) argBind = sourceString.evalBind({ node: arg.node })
//TODO COMPLETTARE get source where get value
/*if(source.split(/^this./)[1]){
//binding per this. riferito al oggetto stesso - al node
target=arg.node
source=source.split(/^this./)[1]
}else if(source.split(/^reference.|data./)[1]){
//binding riferito al Libra
target=Libra.data}
else{
let viewModel=arg.node.getViewModel({property:source})
target=viewModel.data}*/
else{
argBind = Libra.merge( argBind, sourceString )
if( sourceString.source ) argBind.source = sourceString.source
}
argBind.value = argBind.source[ argBind.sourceProperty ]
argBind.target = arg.node
switch ( arg.node.tagName ){
case 'BUTTON':
case 'LIBRA-A':
case 'LIBRA-MENU':
case 'LABEL':
if( bindKey === 'textContent' ) createTextNode = true
argBind.targetProperty = 'textContent'
break
default:
argBind.targetProperty = bindKey
break
}
//if(arg.node.nodeType===3)argBind.targetProperty='nodeValue'
let fn = function( arg ){this.node[ this.property ] = this.inverse ? !arg : arg }.bind({ inverse: argBind.inverse, property: argBind.targetProperty, node: argBind.target })
if(arg.node.nodeType===3)argBind.fn = fn
if( createTextNode && !arg.node.childNodes.length ){
argBind.target = arg.node.appendChild( arg.node.tagName==='LIBRA-MENU'?document.createElement('a'):document.createTextNode( arg.value ))
argBind.target.id = arg.node.id + '-text'
//TODO sistemare fn
argBind.fn = fn
}
switch ( bindKey ){
//case 'eventEmitter':
//case 'eventListener':
/*case 'bindEvent':
argBind.value.vmd.bindEvent = arg.node
break*/
case 'class':
case 'cls':
//if(!argBind.target.id)argBind.target.id=Libra.getId()
argBind.targetProperty = bindKey
argBind.fn = function( arg ){
let _set = ' ' + arg
this.node.bindedClass =this.node.bindedClass || ''
if( arg ) this.node.className = this.node.className.replace( this.node.bindedClass,'' ) + _set
else this.node.className = this.node.className.replace( this.node.bindedClass, '' )
this.node.bindedClass = _set
}.bind({ inverse: argBind.inverse, property: argBind.targetProperty, node: argBind.target })
break;
case 'hidden':
case 'disabled':
//TODO sistemare fn
//if(!argBind.target.id)argBind.target.id=Libra.getId()
argBind.targetProperty = bindKey
argBind.fn = function( arg ){ this.node[ this.property ] = this.inverse ?!arg : arg }.bind({ inverse: argBind.inverse, property: argBind.targetProperty, node: argBind.target })
break
}
if( !( argBind.sourceProperty in argBind.source ) && argBind.source.viewModel ){argBind.sourceObject = argBind.source; argBind.source = argBind.source.viewModel.data }
if( !( argBind.targetProperty in argBind.target ) && argBind.target.viewModel ){argBind.targetObject = argBind.target; argBind.target = argBind.target.viewModel.data }
switch ( bindKey ){
case 'store':
arg.node.viewModel.data.getStore = function(arg){
if( !arg.value.register ) arg.value = Libra.getStore( arg.value )
return arg.value
}.bind( arg.node )
arg.node.viewModel.data.setStore = function(arg){
arg.valueOld.unRegister( this )
//TODO unregister
setTimeout(() => this.reload(), 0)
}.bind( arg.node )
break
}
Libra.bind( argBind )
argBindAll[ bindKey ] = argBind
}
return argBindAll
},
json:function(node){
node = node || this
let i, obj = { nodeType: node.nodeType }
if( node.tagName ) obj.tagName = node.tagName.toLowerCase()
else if( node.nodeName ) obj.nodeName = node.nodeName
if( node.nodeValue ) obj.nodeValue = node.nodeValue
let attrs = node.attributes
if( attrs ){
let arr = obj.attributes = {}, length = attrs.length
for( i = 0; i < length; i++ ) arr[ attrs[ i ].nodeName.toString() ] = attrs[ i ].nodeValue
}
let childNodes = node.childNodes
if( childNodes ){
length = childNodes.length
arr = obj.childNodes = new Array( length )
for( i = 0; i < length; i++ ) arr[ i ] = Libra.Dom.json( childNodes[ i ])
}
return obj
}
},
getId:function(that){ Libra.data.idCounter++; return 'libra-' + Libra.data.idCounter.toString() },
getObject:function(arg){
if( !arg.sourceString && !arg.sourceProperty ) error( 'libraViewModel:getObject' )
if( arg.sourceString ) arg.source = ( 'this.' + arg.sourceString ).eval( Libra.data )
else arg.source = this.data
if( arg.source ){
arg.value = arg.source[ arg.sourceProperty ]
return arg.source
}
return null
},
bind:function(arg){
arg.sourceProperty = arg.sourceProperty || arg.property
arg.targetProperty = arg.targetProperty || arg.sourceProperty
let value = arg.target.nodeType === 3 ? arg.target.nodeValue : arg.target.text
if( !( arg.sourceProperty in arg.source )) arg.source[ arg.sourceProperty ] = arg.value
if( !arg.source._binder ) arg.source = new Libra.data.class.binder( arg.source )
if(arg.fn) arg.source._watch( arg.sourceProperty, arg.fn , 0, arg.target)
else{
if( !arg.target._binder ) arg.target = new Libra.data.class.binder( arg.target )
arg.source._bind( arg.sourceProperty, arg.target, arg.targetProperty )
}
if( arg.hasOwnProperty( 'value' )){
let value = ( typeof arg.value === 'function' ? arg.value.call(arg.source) : arg.value )
arg.target[ arg.targetProperty ] = arg.inverse ? !value : value
}
if( arg.sourceString && arg.sourceString.match( /^user./ )){
arg.source._libraObjectName = arg.sourceString + '.' + arg.sourceProperty
arg.source._libraSync = 1
}
if( arg.target.watch ){
let argWatch = arg.target.watch.evalBind({node:arg.target})
debug('_watch',arg.sourceProperty, argWatch.value)
arg.source._watch( arg.sourceProperty, argWatch.value/*,0,arg.target*/)
}
return arg
},
Layout:{
row:function(that){that.classList.add( 'd-flex', 'flex-row' )},
column:function(that){that.classList.add( 'd-flex', 'flex-column' )},
fit:function(that){that.classList.add( 'w-100', 'h-100' )},
view:function(that){that.classList.add( 'w-100', 'h-100' )},
buttongroup:function(that){that.setAttribute( 'role','group' ); that.classList.add( 'btn-group' ); if( that.dataset.ui ) that.classList.add( 'btn-' + that.dataset.ui )}
},
Template:{
get:function( arg ){return Libra.data.template[ arg ] || new Libra.data.class.libraTemplate({ name: arg })},
use:function( arg ){return Libra.Template.get( arg.name ).use( arg )}
},
getStore:function(cnf){if( typeof cnf === 'string' ) cnf = { name: cnf }; return Libra.data.store[ cnf.name ] || new Libra.data.class.libraStore( cnf )},
Eav:{
busDb:function( arg ){
if( typeof arg === 'object' ) arg = arg.targetName||arg.objectName || arg.storeObjectName
if( arg ) switch( arg.part({ what:'first' })){
case 'lang': return 'lang'
case 'php': return 'server'
case 'user': return 'user'
case 'data': return 'data'
case 'app': return 'app'
case 'js':
case 'X':
return 'client'
default: return 'client'
}
else return 'data'
},"depth":function(arg){
let i, depth, level = 1
for( i in arg ){
if( !arg.hasOwnProperty( i )) continue
if( typeof arg[ i ] === 'object' ){
depth = Libra.Eav.depth( arg[ i ]) + 1
level = Math.max( depth, level )}}
return level
},"save":function(obj,args={fn:null,group:Libra.data.groupEveryone,scope:null}){
debug('eav:save',obj,args)
if(typeof obj==='string'){
var _LibraTagFunction=[], _LibraTagFunctionSource=[], _LibraTagFunctionSourceLink=[], _LibraTagFunctionValueSource=[], _LibraTagFunctionName=[], _LibraTagFunctionLang=[], _LibraTagFunctionArgs=[], tag="var _LibraTagFunction=", js = false
try{
obj=eval('object='+obj+';')
js=true
}catch(err){}
if(js===false){
obj=obj.replace(new RegExp(Libra.data.regex.sourceLang,"g"),function(a,lang,args,e,code,g){
code=code.replace(new RegExp(Libra.data.regex.delimiterSourceLangPhpBeginRe,"gm"),'')
code=code.replace(new RegExp(Libra.data.regex.delimiterSourceLangPhpEndRe,"gm"),'')
_LibraTagFunction.push( code )
_LibraTagFunctionLang.push( lang )
_LibraTagFunctionArgs.push( args )
return tag + _LibraTagFunction.length + ';'
})
try{
obj = eval( 'object=' + obj + ';' )
delete( window.object )
}catch( err ){debug('warning: non criticval error: eval:', err) }}}
switch( typeof obj ){
case 'object':
if( Libra.Eav.depth( obj ) > 100 ){
error('Error: Depth of object is over 100')
return null
}
if( _LibraTagFunction && _LibraTagFunction.length > 0 ){
obj = Libra.Language.applyTagFunction( obj, {
_LibraTagFunctionName:_LibraTagFunctionName,
_LibraTagFunctionSource:_LibraTagFunctionSource,
_LibraTagFunctionSourceLink:_LibraTagFunctionSourceLink,
_LibraTagFunctionValueSource:_LibraTagFunctionValueSource,
_LibraTagFunction:_LibraTagFunction,
_LibraTagFunctionLang:_LibraTagFunctionLang,
_LibraTagFunctionArgs:_LibraTagFunctionArgs
})
}
obj=Libra.Json.encode(obj)
break;
case 'string':
debug('---------------------------------------save object as string -------------------------------------------');
break;
}
//obj=this.parseFunction(obj);
var arg={path:"server://Eav/saveObject",group:args.group,object:obj};
if(args.apply)
arg.apply=args.apply;
if(_LibraTagFunction&&_LibraTagFunction.length>0){
arg._LibraTagFunction=_LibraTagFunction;
arg._LibraTagFunctionLang=_LibraTagFunctionLang;
arg._LibraTagFunctionSource=_LibraTagFunctionSource;
arg._LibraTagFunctionSourceLink=_LibraTagFunctionSourceLink;
arg._LibraTagFunctionValueSource=_LibraTagFunctionValueSource;
arg._LibraTagFunctionArgs=_LibraTagFunctionArgs;
arg._LibraTagFunctionName=_LibraTagFunctionName;
}
debug('send',arg,args);
Libra.send(arg,args);
},"_getObjectRemote":function( _libra, args = {}){
var argsRemote = {}
if( args.fn ) argsRemote.fn = args.fn
else argsRemote.fn = (res) => { debug( 'server: get object:', res )}
if( args.scope ) argsRemote.scope = args.scope
else argsRemote.scope = this
_libra.path = "server://Eav/get"
Libra.send( _libra, argsRemote )
},"getObject":function( _libra, args = {}){
_libra = Libra.merge({ getProperty: false, targetTypeEav:'object', from:'local', what:'js' }, _libra )
if( _libra.targetTypeEav === 'object' && _libra.targetName ) _libra.objectName = _libra.targetName
if( !_libra.busDb && _libra.objectName ) _libra.busDb = Libra.Eav.busDb( _libra )
return this._getObjectRemote( _libra, args )
},"del":function(arg){
if(typeof arg==='string'){
arg={targetName:arg,targetTypeEav:'object'};
}
arg.busDb=Libra.Eav.busDb(arg)
arg.path="server://Eav/del";
Libra.send(arg);
}},"getModel":function(cnf){if( typeof cnf === 'string' ) cnf = { name: cnf }; return Libra.data.model[ cnf.name ] || new Libra.data.class.libraModel( cnf )},"send":function(_data,args = { fn: null, scope: null }){return Libra.Network.send(( _data._bus ? _data._bus :'msg' ), _data,args )},"getSessionId":function(){return new Date().getTime()+Math.random().toString(36).substr(2,9)},"Bus":{"pingpong":function( arg , opt = null ){debug( 'pong',arg )},"connect":function( arg, opt = null ){
let data = Libra.data
data.network.sync = true
data.socketStatus = 'yellow'
Libra.Network.send( 'init', { path: "server://Network/initSync", remoteIp: data.site.remoteIp, _nwVector:'ws' })
},"disconnect":function( arg, opt = null ){
let data = Libra.data
data.socketStatus = 'red'
data.network.sync = false
Network.send( 'msg', { path: "server://Network/clearObjectSync", siteId: data.site.id, userId: data.user.id, _nwId: data.user.CID })
},"debug":function( arg, opt = null ){
let i, len, data = Libra.data
Libra.Notify.add( 'debug', arg, opt )
switch (data.debug._libraDebugType){
case "array": debug( 'Server:', arg ); break
default:
for( i = 0; len = arg.length, i < len; i++ ){
let output = []
Object.keys( arg[ i ]).map(( key ) => {
if(key !== 'data' ){
if( key === 'file' ){arg[ i ][ key ] = arg[ i ][ key ].replace( Libra.data.path.real, ' ')}
output.push( key )
output.push( ':' )
output.push( arg[ i ][ key ])
}})
output.push( '->' )
Object.keys( arg[ i ].data ).map(( key ) => output.push( arg[ i ].data[ key ]))
debug.apply(this,output)
}}
},"sync":function( arg, opt = null ){
/*TODO add sync
for(var _i in arg){
var cmd=arg[_i],
store = Libra.Extjs.Store.get(cmd.db+cmd.table)
switch(cmd._cmd){
case 'addData':
store.autoSync=false
store.autoSyncSuspended=1
store.add(cmd.data)
store.autoSyncSuspended=0
store.autoSync=true
break;
case 'modData':debug('js.Libra.Bus.sync da fare')
break;
default:debug('js.Libra.Bus.sync da fare')
break;}}*/
},"msg":function( arg, opt = null ){
let i
if( arg._bus && arg._bus !== 'msg' ) this[ arg._bus ]( arg, opt )
for( i in arg ) if( Libra.data.bus.list.includes( i )) Libra.Bus[ i ]( arg[ i ], opt )
if( arg._cbId ) Libra.Network.handlerCb( arg, opt )
},"warning":function( arg, opt = null ){alert('TODO channel warning')},"eval":function( arg, opt = null ){
let i
for( i in arg ){
if( arg[ i ].charAt( 0 ) === '<' ) return Libra.Bus.error( arg[ i ], opt )
else try { eval( arg[ i ])} catch ( e ){
debug( e )
Libra.Notify.add( 'error', e )
}}
},"chat":function( arg, opt = null ){alert('TODO channel chat')},"system":function( arg, opt = null ){alert('TODO channel system')},"list":["chat","connect","debug","disconnect","error","eval","extjs","msg","pingpong","sync","system","warning","init"],"init":function( arg, opt = null ){Libra.data.socketStatus='green' },"error":function( arg, opt = null ){Libra.Notify.add( 'error', arg, opt )}},"debounce":function(func, wait, immediate){
let timeout
return function executedFunction(){
let context = this,
args = arguments,
later = function(){timeout = null; if( !immediate ) func.apply( context, args )},
callNow=immediate&&!timeout
clearTimeout( timeout )
timeout = setTimeout( later, wait )
if( callNow ) func.apply( context, args )
}
},"viewController":{"logout":function(){
Libra.send({ path: "server://User/logout" },{
url: Libra.data.path.virtual + 'lib/server/logout.php',
fn: () => {
//Libra.data.isLogged = false
Libra.data.user.idOld = Libra.data.user.id
Libra.data.user.id = 0
Libra.data.user.name = 'anonymous'
Libra.Cookie.set( '_userId', 0, 4 )
Libra.mergeConfig( Libra.data,{
"filter group":function( item ){return !( item._libraGroup && item._libraGroup[ 'u_' + Libra.data.user.idOld ])},
hash:'login'
})
Libra.mergeConfig(data.store.storeWmMenuNavigation,{"filter data":function( item ){return !( item._libraGroup && item._libraGroup[ 'u_' + Libra.data.user.idOld ])}})
if(Libra.Init.initUser)Libra.Init.initUser()//TODO
}})},"logged":function(arg){
let i
for( i in arg) Libra.data.user[ i ] = arg[ i ]
//Libra.data.isLogged = true
if( Libra.Init.initUser )Libra.Init.initUser() //TODO
},"close":function( e ){
debug('Libra.close',this,e)
let target
if( e ){
if( e.target.parentNode.localName === 'libra-tab' ) return e.target.parentNode.viewController.close({ target: e.target })
if( e.target.tagName === 'BUTTON' ) target = e.target; else target = e.target.up( 'button' )
target = target.libraEventTarget || target
}else target = this
//TODO remove event listeners
if( target.localName === 'libra-view' ){
if( target.libraWmMenuNavigationNode ) Libra.data.reference.wmMenuNavigation.viewModel.data.store.del( target.libraWmMenuNavigationNode.record )
target.parentNode.removeChild( target )
window.history.back()
}else target.parentNode.removeChild( target )
},"pocket":function( e ){
debug('lpp',e)
let btn = e.target,
arg = btn.arguments,
wmPocket = Libra.data.reference.wmPocket,
tgt = arg.target
//pocket.delAll()
debug('pckt',tgt)
if( btn.value ){
//TODO non distruggere pocket ma solo il tipo interno
if(tgt.vmd.pocket)tgt.vmd.pocket.destroy()
tgt.vmd.pocket = wmPocket.add({ id:'pocket-'+tgt.id,xtype:'pocket',select:1, type: arg.type, target: arg.target })
wmPocket.hidden=0
}else{
//TODO destroy pocket
wmPocket.hidden=1
if(tgt.vmd.pocket)tgt.vmd.pocket.destroy()}
//TODO rifare handler in modo tale da passare arguments di event di target come argumento, scope fade come .bind() per this
}},"setReference":function( str, arg ){
Libra.data.reference[ str ] = arg
},
Path:{
parse:function(_libra){
_libra.viewCfg = _libra.viewCfg || {}
if( _libra.path ){
let arrBus = _libra.path.split( '://' ),
arrPath
switch( arrBus.length ){
case 1:
_libra.viewName = arrBus[ 0 ]
break
default:
arrPath = arrBus[ 1 ].split( '/' )
_libra._pathLength = arrPath.length
_libra._bus = arrBus[ 0 ].split( ':' )
if(_libra._bus.length === 1 ) _libra._bus = _libra._bus[ 0 ]
else{
_libra.tabbed = _libra._bus[ 0 ]
_libra._bus = _libra._bus[ 1 ]}
switch(_libra._bus){
case 'store':
//_libra.viewCfg = _libra.viewCfg || {}
_libra.viewCfg.path = _libra.path
_libra.viewCfg.storeName = arrPath[ 0 ]
_libra.viewCfg.tplName = arrPath[ 1 ]
if( _libra._pathLength === 2 ) _libra.viewCfg.xtype = 'table'
else{
_libra.viewCfg.xtype = 'form'
if([ 'add', '+' ].includes( arrPath[ 2 ])) _libra._cmd = 'add'
else{
_libra._cmd = 'mod'
_libra.viewCfg.recordId = arrPath[ 2 ]}}
break
default:
error( 'js.Libra.Path.parse: unknown bus' )
break}
break}}
//postParse
if( _libra.viewName ){
_libra.view = Libra.data.view[ _libra.viewName ]
_libra.viewCfg = data.view[ _libra.viewName ] || {}
if(Libra.data.xtype[ _libra.viewName ]) _libra.viewCfg.xtype = _libra.viewName
}
if( _libra.viewCfg.xtype ) _libra.tabbed = Libra.data.xtype[ _libra.viewCfg.xtype ].tabbed
if( _libra.viewCfg && _libra.viewCfg.xtype && !_libra.viewCfg.id ){ //condition for get id
_libra.viewCfg.id = _libra.viewCfg.hash || _libra.path
if( _libra.viewCfg.id ) _libra.viewCfg.id = _libra.viewCfg.id.replace( /\/|:\/\/|:/g, '-' )
else _libra.viewCfg.id = _libra.viewCfg.storeName + '-' + _libra.viewCfg.tplName + '-' + _libra.viewCfg._cmd
}
if( !Object.keys( _libra.viewCfg ).length )delete( _libra.viewCfg )
else _libra.viewCfg.hash = _libra.hash || (_libra.tabbed ? _libra.viewCfg.xtype + ':' + _libra.path.replace( new RegExp( '^' + _libra.viewCfg.xtype + ':' ), '' ) : null)
_libra._pathParsed = 1
//debug('parse end:',_libra,'view:',_libra.view,_libra.viewCfg)
return _libra
},"stringify":function(_libra){
error( 'js.Libra.Path.stringify: complete' )
debug(_libra)
return _libra
}},"bootDone":function(){
if( window.location.hash.split( '#' )[ 1 ] === 'safeMode' ) Libra.data.safeMode = true
let hash = window.location.hash.substr( 1 )
if( Libra.data.safeMode && Libra.data.reference.homeLink ) Libra.data.reference.homeLink.href = '#safeMode'
else{ hash = hash || 'home' }
if( /*Libra.data.reference.wm &&*/ hash ) X.setViewByHash( hash )
},"setHash":function( hash, silent = 0 ){
hash = "#" + hash.replace( /^#/, '' )
if(window.location.hash!==hash){
Libra.data.silentHash = silent
window.location.hash = hash
}},
data:{
notify:{"count":0},
class:{
prototypeExclude:["extends","static","classObjects","1static","constructor","customElementsDefine","_constructor","1_libraClassName","1_libraConfigExtends","1_libraBufferFn","super"],
classObjectsParentExclude:["extends","_libraClassName","_libraBufferFn","_libraConfigExtends"]
},
dom:{
tagHaveViewModel:["libra-filter","libra-form","libra-table","libra-tree","libra-nav","libra-ocpanel","libra-editorcode","libra-panel","libra-editorhtml","libra-tab","libra-container"],
tagHaveViewController:["libra-form","libra-table","libra-tree","libra-nav","libra-ocpanel","libra-editorcode","libra-panel","libra-editorhtml","libra-container"]
},
eav:{
key:"_libraKey",
keyAttr:"lak",
idAttr:"loid",
id:"_",
data:{"mode":"json"}
},
idCounter:0,
isError:false,
debug:{_libraDebug:false,_libraDebugFn:null,_libraDebugFile:null},
network:{"id":"","status":null,"sync":false,"enable":true,"asyncMode":true,"loaded":[],"session":[]},
modules:{"loaded":[]},
requestAjax:[],
requestCb:[],
reference:[],
bus:{list:["connect","disconnect","debug","sync","extjs","msg","error","warning","eval","chat","system","pingpong"]},
model:[],
group:{"s_0":[]},
"proxy group":{
deleteProperty:function(target, name){for(let storeName in data.store) Libra.mergeConfig(data.store[storeName],{"filter data":function(item){return !(item._libraGroup&&item._libraGroup[name])}})},
set:function(target, name, val, receiver){/*if( !val.store ) val.store = [];*/ return val}},
"get hash":function(){return window.location.hash.split( '#' )[ 1 ] },
"set hash":function(hash){if( hash ) window.location.hash = '#' + hash },
x:{
"set wm":function(val){
let wmDiv = get( '_libraWm' )
if( wmDiv ) document.body.removeChild( wmDiv )
add( typeof val === 'string' ? data.view.wm[ val ] : val, { parentNode: document.body })
}
},
lang:[],
store:[],
silentHash:0,template:[],xtype:{container:[],carousel:[],panel:[],form:{tabbed:{menu:{text:"forms"},config:{defaults:{editing:1,closing:1}}}},tab:[],table:{tabbed:{menu:{text:"tables"},config:{defaults:{editing:1,closing:1}}}},tree:[],nav:[],code:[],pocket:[],a:{is:1},button:{is:1},input:{is:1},codearea:{is:1,transform:"textarea"},menu:[],combobox:[],editorhtml:[]},
view:{
// home:{tag:'div',html:'portale in fase di costruzione'}
}}},
class:{
libraContainer:{
extends:"HTMLElement",
customElementsDefine:"libra-container",
viewModel:{data:{renderDone:false,items:[],slot:[],body:null,storeRegister:1}},
getValue:function(){return this.value },
constructor:function(){
this._doNotapplyBindOnCreateNode = 1
this._cache = { events:{}}
this.requires = this.requires || { mod: [], class: [] }
this.continue = this.initAll
this.makeShadowRoot()
},
connectedCallback:function(a){
let i
this.itemName = this.itemName || 'item'
this.viewModel = this.viewModel || { data:{}}
if( !this.viewModel.data.renderDone ){
this.viewModel.data.body = this.viewModel.data.body || this
if( !this.viewModel || ( this.viewModel && !this.viewModel.onConnectedCallback )) this.viewModel = new Libra.data.class.libraViewModel( this )
this.vmd = this.viewModel.data
if( this.viewModel ) this.viewModel.onConnectedCallback()
if( !this.viewController || ( this.viewController && !this.viewController.onConnectedCallback )) this.viewController = new Libra.data.class.libraViewController( this )
this.shadowRoot.$$( 'slot' ).forEach( slot => { this.vmd.slot[ slot.name || 'body' ] = slot })
for( i in this.vmd.slot ) this.vmd.slot[ i ].on( 'slotchange', e => { e.stopPropagation(); this.onSlotChange( e )})
this.initConnect()
this.initAttribute()
if( this.dataset.requires ) this.requires = this.dataset.requires.split( ',' )
this.id = this.id || Libra.getId()
if( this.dataset.reference ) this.viewModel.setReference( this.dataset.reference, this )
if( this.dataset.storeName ){
this.vmd.store = Libra.getStore( this.dataset.storeName )
this.vmd.model = this.vmd.store.model
}
if( this.store ){
this.vmd.store = Libra.getStore( this.store )
this.vmd.model = this.vmd.store.model
}
if( this.dataset.modelName ){
this.vmd.model = Libra.getModel({ name: this.dataset.modelName, node: this })
if( this.vmd.model.store ) this.vmd.store = this.vmd.model.store
}
if( this.vmd.store ){
//if( !vmd.store.register ) vmd.store = Libra.getStore( vmd.store )
if( this.vmd.storeRegister ) this.vmd.store.register( this )
this.dataset.templateName = this.dataset.templateName || 'default'
}
this.initRequire()
if( this.requires.mod.length || this.requires.class.length ){//TODO complettare
this._wait = true
for( i in this.requires.mod ) Libra.modprobe( this.requires.mod[ i ]).then({ fn: () => { this.continue();if(this.onRender)this.onRender(this)}})
}
if( !this._wait ) this.initAll()
}
},
init:function(){},
makeShadowRoot:function(options={}){
( "ShadyCSS" in window ) ? ShadyCSS.styleElement( this ) : null
this.attachShadow({ mode: "open" })
const templateId = options.templateId || this.is
const templateClone = this.getTemplateCopy( templateId )
//this.shadowRoot.applyAuthorStyles=true
//this.shadowRoot.resetStyleInheritance=false
let shr = this.shadowRoot
shr.libraParent = this
shr.tagName = 'SHADOWROOT'
//shr.up=HTMLElement.prototype.up
shr.appendChild( templateClone )
shr.$ = selector => shr.querySelector( selector )
shr.$$ = selector => shr.querySelectorAll( selector )
},
getTemplateCopy:function(templateId=this.is){
const template = document.getElementById( templateId )
if( !template ) error( `Template ${templateId} is not found` )
return template.content.cloneNode( true )
},
"get is":function(){return this.localName },
debug:function(){return debug.apply( this, [ '%c ' + this.localName + ':' + this.id + ':' + arguments.callee.caller.name + ':', 'color:blue', ...arguments ])},
fireEvent:function(arg={bubbles:false},arg2){
//TODO togliere
//if( typeof arg !== 'object' ){error( 'error define fireEvent ',{el:this,arg:arg,arg2:arg2}); return false}
let bubbles = arg.bubbles, customEventInit = { bubbles }, e
if( arg.detail instanceof Object ){
if( arg.detail.item && this.itemName !== 'item' ){
arg.detail[ this.itemName ] = arg.detail.item
delete( arg.detail.item )
}
customEventInit.detail = arg.detail
}
e = new CustomEvent( arg.name, customEventInit )
this.dispatchEvent( e )
/*TODO analizare motore bindEvent
if(this.vmd.bindEvent&&!arg.detail.eventEmitter&&(!this.vmd.bindEventList||(this.vmd.bindEventList&&this.vmd.bindEventList.includes(arg.name)))){
arg.detail.eventEmitter = this
this.debug('bindEvent:1:',arg)
this.vmd.bindEvent.fireEvent( arg )}*/
},
"$":function(arg){return this.querySelector( arg )},
"$$":function(arg){return this.querySelectorAll( arg )},
render:function(){},
wait:function(){this._wait = true },
disconnectedCallback:function(){
//passato a .destroy() di initDom if( this.vmd.store && this.vmd.storeRegister ) this.vmd.store.unRegister( this )
},
onSlotChange:function(e){
if(!this.vmd) return false
let i,
path = e.path || (e.composedPath && e.composedPath()),
name = path[ 0 ].name || 'body',
items = path[ 0 ].assignedElements({}),
renderName = 'render' + name.firstToUpperCase()
if( this.vmd[ name ] && !this.vmd[ name ][ renderName + 'Done' ]){
this.vmd[ name ][ renderName + 'Done' ] = true
this[ renderName ]( items )}
for( i = 0; i < items.length; i++ ){
let item = items[ i ]
if( !item[ renderName + 'ItemDone' ] && item.tagName !== 'SLOT' ){
item[ renderName + 'ItemDone' ] = true
//item._itemKey=this.vmd.items.length
//this[ renderName + 'Item' ]( item )
if( name === 'body' ){
let sel = this.vmd.pushItemQs
if( sel ){
let push=0;
[...item.parentNode.$$(sel)].find( node => { if( node === item ){push = 1; this.vmd.items.push( item )}})
if( !push ){
let node=item.$( sel );if(node) this.vmd.items.push(node )}
}else this.vmd.items.push( item )}
this[ renderName + 'Item' ]( item )}}
if(this.renderChange)this.renderChange(e)
},
add:function(item,arg){
if( item ){
if( this.defaults ) item = Libra.mergeConfig( item, this.defaults )
item.id = item.id || Libra.getId()
item._itemKey = this.vmd.items.length
if( !arg ) arg = {}
if( !arg.parentNode && !arg.before && !arg.after ) arg.parentNode = this.vmd.body
item.vmd=item.vmd||{}
this.vmd.lastAddedItem = item instanceof HTMLElement ? this.appendChild(item):add( item, arg )
//this.vmd.lastAddedItem.record=item
this.fireEvent({ name:'add', detail:{ item: this.vmd.lastAddedItem }, bubbles:false })
if( this.vmd.lastAddedItem.dataset.hasOwnProperty( 'select' )) this.selectItem( this.vmd.lastAddedItem )
}else this.vmd.lastAddedItem = null
return this.vmd.lastAddedItem
},
del:function(node){
return node.destroy()
//let items = this.vmd.items, el, item
//passato a initDom.destroy()
//for( i in items ) if(node === items[ i ]){
//return items[ i ].destroy()
/*item = items[ i ]
if( item._linkedNode ){
//if(item._isTabbed)
item._linkedNode._linkedView = null}
el = this.vmd.body.removeChild( item )
el = null
delete items[ i ]
//delete item
//delete el
this.vmd.items = this.vmd.items.filter( Boolean )
this.fireEvent({ name:'delete',detail:{node:item}, bubles:false })
return true*///}
//return false
},
delAll:function(){while( this.vmd.body.firstChild ) this.vmd.body.removeChild( this.vmd.body.firstChild ); this.vmd.items=[]; return this },
addRecord:function(row,arg){
let tpl = this.template.use({ self: this, scope: row })
if( tpl ) return this.add( tpl, arg )
else this.vmd.lastAddedItem = null
return this.vmd.lastAddedItem
},
renderBody:function(items){},
renderBodyItem:function(item){},
initAll:function(){
if( this.dataset.templateName ) this.template = Libra.Template.get( this.dataset.templateName )
this.init()
this.renderAll()
},initRequire:function(){},
renderAll:function(){
if( this.dataset.hasOwnProperty( 'disabled' )) this.classList.add( 'disabled' ) //TODO non puoi cliccare
if( this.dataset.hasOwnProperty( 'selected' )) this.classList.add( 'active' ) //TODO non puoi cliccare
this.renderCss()
this.renderLayout()
if( !this.dataset.hasOwnProperty( 'notLoad' )) this.load()
this.viewModel.data.renderDone = true
this.render()
if(this.keyMap){
this.setAttribute('tabindex',0)
let i, j
this.keyMapCode = {}
for( i in this.keyMap ){
j = this.keyMap[ i ]
this.keyMapCode[ j.code ] = { ctrl: !!j.ctrl, alt: !!j.alt, shift: !!j.shift, mac: !!j.mac, map: j }
}
this.vmd.body.on( 'keydown', ( e ) => {
let map = this.keyMapCode[ e.keyCode ]
if( map && map.ctrl === e.ctrlKey && map.alt === e.altKey && map.shift === e.shiftKey && map.mac === e.metaKey ){
map = map.map
if( map.stop ) /*e.stopPropagation() */e.preventDefault() //TODO vedere focus
this.viewController[ map.handler ].call( this, arguments )}} ,true )}
this.renderEvent()
},
initAttribute:function(){},
renderCss:function(){},
renderLayout:function(){if( this.dataset.layout ) if( Libra.Layout[ this.dataset.layout ]) Libra.Layout[ this.dataset.layout ]( this );else error( 'layout ' + this.dataset.layout + ' not defined' )},
renderEvent:function(){
//this.on('select',e=>this.select({ e: e }))
},
reload:function( arg ){this.delAll(); return this.load( arg )},
load:function( arg ){
let i
arg=Libra.merge( this.vmd.storeFilter || [], arg )
if( this.vmd.store ){
let data = this.viewModel.data.store.getData( arg ), len = Object.keys(data).length
if( len ) for( i in data) this.addRecord( data[ i ])}
return data
},
initConnect:function(){},
delRecord:function(rec){
//this.debug(this,rec)
//TODO analizzare se serve
let vmd = this.viewModel.data
vmd.body.removeChild( vmd.body.$( '[data-' + Libra.data.eav.idAttr + '="' + rec[Libra.data.eav.id] + '"]' ))
}
},
libraPanel:{
extends:"libraContainer",
customElementsDefine:"libra-panel",
init:function(){
if( this.dataset.hasOwnProperty( 'viewTitle' )){
this.vmd.title = add({ xtype:'container', layout:'row', items:[ this.vmd.slot.title ] },{ before: this.vmd.slot.tbar })
add({ parent: this, slot:'title', tag:'div', text: this.dataset.viewTitle /*cls:'text-white ' + ( this.dataset.iconCls ? 'fa ' + this.dataset.iconCls + ' famr' :'' ),*/})
}
if(this.tbar) this.vmd.tbar = add({ xtype:'container', layout:'row', items: [ this.vmd.slot.tbar ] },{ after: this.vmd.title || this.vmd.slot.title })
},
renderTitle:function(items){
this.vmd.title.classList.add( 'card-header', 'bg-primary' )
if( this.dataset.hasOwnProperty( 'closing' )){
this.vmd.title.classList.add( 'alert-dismissible' )
add({ parentNode: this.viewModel.data.title, tag:'button',type:"button",libraEventTarget:this,handler:'close',cls:"close",attr:{'aria-label':"Close",'data-dismiss':"alert"},items:[{ tag:'span', attr:{'aria-hidden':true},html:'×'
}]})}
},
renderTitleItem:function( item ){},
renderTbar:function( items ){
//this.viewModel.data.tbar.classList.add( 'card-header' )
this.viewModel.data.tbar.style.padding = '.5rem'
},
renderTbarItem:function(item){
let i, cls=['btn','btnBar', 'btn-outline-secondary'/*,'btn-sm'*/]
//item.classList.add( 'mr-5' )
item.style[ 'margin-right' ] = '.5rem'
//item.style['margin']='0 .5rem 0 0'
if( item.nodeName === 'BUTTON' ) item.classList.add( ...cls )
if( item.children ) for( i in item.children ) if( item.children[ i ].nodeName === 'BUTTON' ) item.children[ i ].classList.add( ...cls )
},
render:function(){
this.super()
if( this.tbar ) add( this.tbar, { defaults:{ parentNode: this, slot:'tbar'}})
}},
libraTable:{
extends:"libraPanel",
customElementsDefine:"libra-table",
viewModel:{"data":{"inserting":1,"selectedRecord":null}},
dblclick:function( tr, arg ){
//TODO sistemare magari spostando in libraocpanel
if( this.viewModel.data.store instanceof Libra.data.class.libraStoreObject ){
if( !tr.record.leaf ) this.viewController.setPath( tr.record[ Libra.data.eav.id]); /*TODO oc */ else this.debug('complettare')
}else this.viewController.mod( tr.record )
},
viewController:{
add:function(e){
let arg = null
if( e instanceof Event ) arg = { e: e }
X.setView({ xtype:'form', storeName:this.viewModel.data.store.config.name, editing:1 }, arg )
},
mod:function(e){
let rec = e, arg = null
if( e instanceof Event ){
rec = this.viewModel.data.selectedRecord
arg = { e: e }}
X.setView({
xtype:'form',
storeName: this.vmd.store.config.name,
record:this.vmd.selectedRecord,
editing:1 }, arg )
},
setPath:function(arg){
this.vmd.store.setPath( arg )
this.vmd.pathText.textContent = '/' + this.vmd.store.path
//TODO binding?? tra path e store.path
},
del:function(){
let i
for( i in this.vmd.selections ) this.vmd.store.del( this.vmd.selections[ i ].record )
},
sort:function(n){
let table = this.vmd.table,
switching = true,
switchcount = 0,
dir=/*dir||*/ "asc",
rows, i, x, y, shouldSwitch
while ( switching ){
switching = false
rows = this.vmd.body.children
for( i = 0; i < (rows.length - 1); i++ ){
shouldSwitch = false
x = rows[ i ].$$( "TD" )[ n ]
y = rows[ i + 1 ].$$( "TD" )[ n ]
if( dir === "asc" ) { if( x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()){shouldSwitch = true; break }}
else if( dir === "desc" ){if( x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()){shouldSwitch = true; break }}}
if( shouldSwitch ){
rows[ i ].before( rows[ i + 1 ])
//TODO vedere la velocita tra before e insertBefore
switching = true
switchcount ++
}else{ if( switchcount === 0 && dir === "asc" ){dir = "desc"; switching = true}}
}}},
onClick:function(node){},
deselectItem:function(node){
if(!node){
for( let i in this.vmd.selections ) this.deselectItem(this.vmd.selections[ i ])
return true
}
this.value = undefined
this.vmd.selectedRecord = null
if( this.localName === 'libra-table' && this.dataset.hasOwnProperty( 'checking' )) node.$( 'th input' ).checked = 0
node.removeAttribute( 'data-selected' )
if([ 'libra-table', 'libra-tree' ].includes( this.localName )) node.classList.remove( 'table-primary' ) //TODO ???
this.vmd.selections.pop( node )
},
selectFirstItem:function(){this.selectItem(this.vmd.items[0])},
selectItem:function(node,silent = false ){
if( node.dataset.hasOwnProperty( 'selected' )) return false
this.vmd.selections.forEach( node => this.deselectItem( node ))
this.vmd.selectedRecord = node.record
this.value = node.dataset[ Libra.data.eav.idAttr ] * 1
this.vmd.selections.push( node )
if([ 'libra-table', 'libra-tree' ].includes( this.localName )) node.classList.add( 'table-primary' )
if( this.localName === 'libra-table' && this.dataset.hasOwnProperty( 'checking' )) node.$( 'th input' ).checked = 1
node.dataset.selected = 1
if( !silent ) this.fireEvent({ name:'selectItem', detail:{ item: node }, bubbles: false })
},
initAttribute:function(){
this.super()
let ds = this.dataset
ds.templateName = 'tableTr'
if( ds.hasOwnProperty('editing')) ds.sorting = ds.selecting = ds.resizing = ds.checking = ''
},
init:function(){
this.super()
//let storeText = this.vmd.store.text
this.vmd.table = this.shadowRoot.$( 'table' ) || add({ parent: this.shadowRoot, tag:'table', items:[{ tag:'thead', items:[{ tag:'tr' }] }, { tag:'tbody' }] })
this.vmd.body =this.shadowRoot.$( 'tbody' ) || this.vmd.table
this.vmd.body.dataset.xtype=this.localName.replace('libra-','')
if( this.dataset.hasOwnProperty( 'checking' )){
this._checked=this._checked||{}
this.check=e =>{ if( e.path[ 0 ].checked ) this._checked[ e.path[ 2 ].record[ Libra.data.eav.id ] ] = 1;else delete(this._checked[ e.path[ 2 ].record[ Libra.data.eav.id ] ]);this.fireEvent({name:'check',detail:{ value: e.path[ 0 ].checked,e:e, item: e.path[ 2 ] },bubbles:false})}
Object.defineProperty(this, "checked", {
get: () => { return Object.keys(this._checked).join(',')},
set:function(value){
let values = value.split( ',' ),
items = this.viewModel.data.items
for( let i = 0; i < items.length; i++)
if( values.includes( items[ i ].dataset[ Libra.data.eav.idAttr ])){
items[ i ].$( 'th input' ).checked = 1
this._checked[ items[ i ].dataset[ Libra.data.eav.idAttr ]] = 1
}else{
items[ i ].$('th input').checked = 0
delete( this._checked[ items[ i ].dataset[ Libra.data.eav.idAttr ]])}}})}
if( !this.dataset.hasOwnProperty( 'excludeHeader' )){
let i, field, items = [], item
this.vmd.header = this.shadowRoot.$( 'thead' )
this.vmd.theadTr = this.shadowRoot.$( 'thead>tr' )
this.renderHeader()
//TODO controll it se fatta con html; /*attr:{'data-sorting-disable':1},*/
if( this.dataset.hasOwnProperty( 'checking' )) items.push({ cls:'w1', items: [ { tag:'input', type:'checkbox', events:{ input: ( e ) => { let i; this.selections=[]; for( i = 0; i < this.vmd.items.length; i++ ) this[ ( e.target.checked ? '' :'de' ) + 'selectItem' ]( this.vmd.items[ i ])}}}]})
for( i in this.vmd.model.fields ){
field = this.vmd.model.fields[ i ]
items.push({ text: field.text, name: field.name, columnKey: i })
if( this.dataset.hasOwnProperty( 'sorting' )){
item = items[ items.length - 1 ]
item.events = { click: e => { if( e.target.nodeName === 'TH') this.viewController.sort( e.target.columnKey )}}
item.cls = 'cp'
}}
add( items, { defaults:{ parentNode: this.vmd.theadTr, tag:'th' }})
for( i=0; i < items.length; i++ ) this.renderHeaderItem( items[ i ])
}
if(this.dataset.hasOwnProperty( 'selecting' )){
this.vmd.selections = []
//this.vmd.selected = null
this.vmd.selectedRecord = null
this.vmd.body.on( 'click', e => {
let tr, is, tgt = e.target, path = e.path || (e.composedPath && e.composedPath())
if( path.includes( this.vmd.body )){
for( var i in path ) if( path[ i ].nodeName === 'TR' ){tr = path[ i ]; break }
is = tr.dataset.hasOwnProperty( 'selected' )
if( !is ) this.selectItem( tr )
if( tgt.nodeName === 'TD' ) this.onClick( tr )
else{
if(this[tr.record.expanded?'collapse':'expand'])this[tr.record.expanded?'collapse':'expand']( tr )}}})}
if( this.dataset.hasOwnProperty( 'editing' )) data.template.buttonEditing({ target: this })
if( this.dataset.hasOwnProperty( 'filtering' )){
this.tbar = this.tbar || []
this.tbar.push({ xtype: "input", cls:"cols-sm-1",/* offset-10*/ attr:{ placeholder: "insert firter", "aria-label": "Search" }, events:{ keyup: e => {
let input = e.target,
filter = input.value.toUpperCase(),
tr = this.viewModel.data.items,
td, tds, i, j, value
for( i = 0; i < tr.length; i++ ){
tds = tr[i].getElementsByTagName( "td" )
for( j = 0; j < tds.length; j++ ){
td = tds[ j ]
if( td ){
value = td.textContent || td.innerText || td.firstChild.shadowRoot.childNodes[ 1 ].textContent
if( value.toUpperCase().indexOf( filter ) > -1){tr[ i ].style.display = ''; break}else tr[ i ].style.display = 'none'
}}}}}})}
},"renderHeaderItem":function( item ){},"renderHeader":function( item ){this.viewModel.data.header.classList.add( 'thead-light' )},"renderCss":function(){
this.super()
this.viewModel.data.table.classList.add( 'table', 'table-bordered' )
this.viewModel.data.table.classList.add( 'table-striped' )
},"add":function( item ){
this.super()
let last = this.vmd.lastAddedItem
if( !last.renderBodyItemDone ){
last.renderBodyItemDone = true
this.renderBodyItem( last )
this.vmd.items.push( last )}},"renderEvent":function(){
this.viewModel.data.body.on("dblclick", e => { //TODO ?
let i, tr, isSelected, path = e.path || (e.composedPath && e.composedPath())
for( i in path ) if( path[ i ].nodeName === 'TR' ){
tr = path[ i ]; break}
this./*viewController.*/dblclick( tr, { event: e })
})},"tableResizable":function(table){
let row = table.getElementsByTagName( 'tr' )[ 0 ],
cols = row ? row.children : undefined
if( !cols ) return
table.style.overflow = 'hidden'
let tableHeight = table.offsetHeight
for(let i=0;i