/* RSence * Copyright 2010 Riassence Inc. * http://riassence.com/ * * You should have received a copy of the GNU General Public License along * with this software package. If not, contact licensing@riassence.com */ /*** = Description ** HPropertyList uses any JSON-compliant structure as its value and displays ** its content hierarchically in three columns: ** - Key ** - Type ** - Value ** ***/ var//RSence.Lists HPropertyList = HControl.extend({ keyColumnWidth: 100, rowHeight: 15, keyIndent: 8, drawSubviews: function(){ this.propertyItems = []; this.keyRowStyle += 'height:'+this.rowHeight+'px;'; this.typeRowStyle += 'height:'+this.rowHeight+'px;'; this.valueRowStyle += 'height:'+this.rowHeight+'px;'; this.rowSeparatorStyle += 'height:'+this.rowHeight+'px;'; this.setStyle('font-size','11px'); this.setStyle('overflow-y','auto'); this.keyColumn = HView.nu( [ 0, 0, this.keyColumnWidth, 24 ], this, { style: [ [ 'border-right', '1px solid #999' ] ] } ); this.typeColumn = HView.nu( [ this.keyColumnWidth, 0, 80, 24 ], this, { style: [ [ 'border-right', '1px solid #999' ] ] } ); this.valueColumn = HView.nu( [ this.keyColumnWidth + 80, 0, 0, 24, 0, null ], this ); this.header = HView.extend({ drawSubviews: function(){ var keyColumnWidth = this.parent.keyColumnWidth; this.keyLabel = HStringView.nu( [ 0, 0, keyColumnWidth, 24 ], this, { value: 'Key', style: [ [ 'text-align', 'middle' ], [ 'text-indent', '16px' ], [ 'line-height', '24px' ] ] } ); this.typeLabel = HStringView.nu( [ keyColumnWidth, 0, 80, 24 ], this, { value: 'Type', style: [ [ 'text-align', 'middle' ], [ 'text-indent', '8px' ], [ 'line-height', '24px' ] ] } ); this.valueLabel = HStringView.nu( [ keyColumnWidth + 80, 0, 80, 24, 0, null ], this, { value: 'Value', style: [ [ 'text-align', 'middle' ], [ 'text-indent', '8px' ], [ 'line-height', '24px' ] ] } ); } }).nu( [ 0, 0, null, 24, 0, null ], this, { style: [ [ 'border-bottom', '1px solid #999' ] ] } ); this.resizeColumns = HControl.extend({ drag: function(x,y){ var parentX = x - this.parent.pageX(), keyColumnWidth = parentX-1, parentWidth = ELEM.getVisibleSize( this.parent.elemId )[0]; if(keyColumnWidth < 80){ keyColumnWidth = 80; } else if ( keyColumnWidth > parentWidth-160 ){ keyColumnWidth = parentWidth - 160; } selfX = keyColumnWidth - 2; this.rect.offsetTo( selfX, 0 ); this.drawRect(); this.parent.keyColumn.rect.setRight( keyColumnWidth ); this.parent.keyColumn.drawRect(); this.parent.header.keyLabel.rect.setWidth( keyColumnWidth ); this.parent.header.keyLabel.drawRect(); this.parent.typeColumn.rect.offsetTo( keyColumnWidth, 0 ); this.parent.typeColumn.drawRect(); this.parent.header.typeLabel.rect.offsetTo( keyColumnWidth, 0 ); this.parent.header.typeLabel.drawRect(); this.parent.valueColumn.rect.setLeft( keyColumnWidth+80 ); this.parent.valueColumn.drawRect(); this.parent.header.valueLabel.rect.setLeft( keyColumnWidth+80 ); this.parent.header.valueLabel.drawRect(); this.parent.keyColumnWidth = keyColumnWidth; } }).nu( [ this.keyColumnWidth - 2, 0, 5, 25 ], this, { events: { draggable: true }, style: [ [ 'cursor', 'ew-resize' ] ] } ); }, arrayTokens: function( arr, name ){ this.addToken( 'a', name, '('+arr.length+' items)' ); this.nodeProperties.left += this.keyIndent; var i = 0, val, type; for( ; i < arr.length; i++ ){ val = arr[i]; type = this.itemType( val ); if( type == 'h' ){ this.hashTokens( val, i ); } else if ( type == 'a' ){ this.arrayTokens( val, i ); } else { this.addToken( type, i, val ); } } this.nodeProperties.left -= this.keyIndent; }, hashLen: function( hash ){ var count = 0; for( var item in hash ){ count += 1; } return count; }, hashSortedKeys: function( hash ){ var keys = [], key; for( key in hash ){ keys.push( key ); } return keys.sort(); }, hashTokens: function( hash, name ){ this.addToken( 'h', name, '('+this.hashLen( hash )+' items)' ); this.nodeProperties.left += this.keyIndent; var key, val, type, i = 0, keys = this.hashSortedKeys( hash ); for( ; i < keys.length; i++ ){ key = keys[i]; val = hash[key]; type = this.itemType( val ); if( type == 'h' ){ this.hashTokens( val, key ); } else if ( type == 'a' ){ this.arrayTokens( val, key ); } else { this.addToken( type, key, val ); } } this.nodeProperties.left -= this.keyIndent; }, addToken: function( type, name, value ){ this.valueTokens.push( { top: this.nodeProperties.top, left: this.nodeProperties.left, type: type, name: name, value: value } ); this.nodeProperties.top += this.rowHeight; }, itemType: function( item ){ return COMM.Values.type( item ); }, typeNames: { h: 'Hash', a: 'Array', s: 'String', n: 'Number', b: 'Boolean', '~': 'Null', '-': 'Undefined' }, keyRowStyle: "position:absolute;z-index:1;right:0px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;", addKeyColumnControl: function( token, i ){ var elemId; if( i >= this.propertyItems.length ){ elemId = ELEM.make( this.keyColumn.elemId ); this.propertyItems.push( elemId ); ELEM.setCSS( elemId, 'top:'+token.top+'px;'+this.keyRowStyle ); } else { elemId = this.propertyItems[i]; } ELEM.setStyle( elemId, 'left', (token.left+10)+'px' ); if( token.type === 'h' || token.type === 'a' ){ ELEM.setStyle( elemId, 'font-weight', 'bold' ); } else { ELEM.setStyle( elemId, 'font-weight', 'inherit' ); } ELEM.setHTML( elemId, token.name ); }, typeRowStyle: "position:absolute;z-index:1;left:8px;width:72px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;", addTypeColumnControl: function( token, i ){ var elemId; if( i >= this.propertyItems.length ){ elemId = ELEM.make( this.typeColumn.elemId ); this.propertyItems.push( elemId ); ELEM.setCSS( elemId, 'top:'+token.top+'px;'+this.typeRowStyle ); } else { elemId = this.propertyItems[i]; } ELEM.setHTML( elemId, this.typeNames[token.type] ); }, valueRowStyle: "position:absolute;z-index:1;left:8px;right:0px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;", addValueColumnControl: function( token, i ){ var elemId, value; if( i >= this.propertyItems.length ){ elemId = ELEM.make( this.valueColumn.elemId ); this.propertyItems.push( elemId ); ELEM.setCSS( elemId, 'top:'+token.top+'px;'+this.valueRowStyle ); } else { elemId = this.propertyItems[i]; } if( token.type === 'h' || token.type === 'a' ){ ELEM.setStyle( elemId, 'font-style', 'italic' ); } else { ELEM.setStyle( elemId, 'font-style', 'inherit' ); } value = token.value; if(value===true){ value = 'true'; } else if(value===false){ value = 'false'; } else if(value===undefined){ value = 'undefined'; } else if(value===null){ value = 'null'; } ELEM.setHTML( elemId, value ); }, rowSeparatorStyle: "position:absolute;z-index:0;left:0px;right:0px;font-size:0px;height:1px;border-bottom:1px solid #ccc;overflow:hidden;text-overflow:ellipsis;", addRowSeparator: function( token, i, even ){ if( i >= this.propertyItems.length ){ var elemId = ELEM.make( this.elemId ); this.propertyItems.push( elemId ); ELEM.setCSS( elemId, 'top:'+token.top+'px;'+this.rowSeparatorStyle+'background-color:'+(even?'#eee':'#ddd')+';' ); } }, die: function(){ var i=0, propLen = this.propertyItems.length, elemId; for(;i