X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F20_ui%2F06_AbstractUINode.js;h=5919e21c85b6b3f2e06d9affdeca4f83074b0c74;hb=HEAD;hp=f3b9c1fbe8a31d2a3e82338c48bd637bc3428324;hpb=a4b6249d16b938ce6fd1c7691f144ff99729056f;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/20_ui/06_AbstractUINode.js b/0.6.x/js/20_ui/06_AbstractUINode.js index f3b9c1f..5919e21 100644 --- a/0.6.x/js/20_ui/06_AbstractUINode.js +++ b/0.6.x/js/20_ui/06_AbstractUINode.js @@ -1,62 +1,75 @@ -X.UI._AbstractUINode = X.EventDispatcher.inherits( +// TODO -> Node[ 'inherits' ] +var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 'X.UI._AbstractUINode', - X.Class.ABSTRACT | X.Class.PRIVATE_DATA, + X_Class.ABSTRACT, { + itemData : null, + phase : 0, - dirty : X.UI.Dirty.CLEAN, + dirty : XUI_Dirty.CLEAN, root : null, rootData : null, - hoverList : null, parent : null, parentData : null, xnode : null, - supportAttrs : X.UI.Attr.Support, - attrClass : X.UI.AttrClass, + usableAttrs : XUI_Attr_Support, + attrClass : XUI_AttrClass, attrObject : null, unverifiedAttrs : null, - role : null, + role : 1, pointerDisabled : false, - hoverClassName : null, hovering : false, reserveEvents : null, - gesture : null, + gestureOptions : null, + gestureActivated : null, + gestureTypes : null, + gestureTriggered : null, + gestureCanceled : null, + gestureCurrentName : '', + gestureStartEvent : null, + gestureLastEvent : null, + gestureLastMoveEvent : null, absoluteX : 0, absoluteY : 0, boxX : 0, boxY : 0, - scrollWidth : 0, - scrollHeight : 0, - boxWidth : X.UI.Attr.AUTO, - minBoxWidth : 0, - maxBoxWidth : X.UI.Attr.AUTO, - boxHeight : X.UI.Attr.AUTO, - minBoxHeight : 0, - maxBoxHeight : X.UI.Attr.AUTO, + boxWidth : XUI_Attr_AUTO, + boxWidthMin : 0, + boxWidthMax : XUI_Attr_AUTO, + boxHeight : XUI_Attr_AUTO, + boxHeightMin : 0, + boxHeightMax : XUI_Attr_AUTO, contentL : 0, contentT : 0, contentR : 0, contentB : 0, + paddingL : 0, + paddingT : 0, + borderL : 0, + borderT : 0, boxSizingOffsetLR : 0, boxSizingOffsetTB : 0, - contentWidth : X.UI.Attr.AUTO, - minContentWidth : 0, - maxContentWidth : X.UI.Attr.AUTO, - lastContentWidth : -1, - contentHeight : X.UI.Attr.AUTO, - minContentHeight : 0, - maxContentHeight : X.UI.Attr.AUTO, - lastContentHeight : -1, + contentWidth : XUI_Attr_AUTO, + contentWidthMin : 0, + contentWidthMax : XUI_Attr_AUTO, + contentWidthLast : -1, + contentHeight : XUI_Attr_AUTO, + contentHeightMin : 0, + contentHeightMax : XUI_Attr_AUTO, + contentHeightLast : -1, constraintW : false, constraintH : false, autoWidth : false, autoHeight : false, + noWidth : false, + noHeight : false, percentWidth : false, percentHeight : false, // :hover, :focus, :disabled @@ -66,17 +79,29 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( this.rootData = rootData; this.parent = parent; this.parentData = parentData; - //this.xnode = X.Node.create( 'div' ); this.phase = 1; - this.dispatch( X.UI.Event.INIT ); + this[ 'dispatch' ]( XUI_Event.INIT ); }, addToParent : function( xnodeParent ){ - xnodeParent && xnodeParent.append( this.xnode ); + var attr = this.attrObject || this.attrClass.prototype, + usableAttrs = this.usableAttrs, + i = 0, l = usableAttrs.length, def, k; + + xnodeParent && xnodeParent[ 'append' ]( this.xnode ); + + if( attr ){ + for( k in usableAttrs ){ + def = usableAttrs[ k ]; + if( def[ 2 ] === XUI_Attr_USER.XNODE && X_Object_inObject( def.No, attr ) && attr[ def.No ] !== def[ 0 ] ){ + this.xnode[ 'css' ]( XUI_Attr_Rename[ k ] || k, XUI_AbstractUINode_createCssText( this, k ) ); + }; + }; + }; this.phase = 2; - this.dispatch( X.UI.Event.ADDED ); + this[ 'dispatch' ]( XUI_Event.ADDED ); }, creationComplete : function(){ @@ -84,9 +109,10 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( l, i; this.phase = 3; - this.User.dispatch( X.UI.Event.CREATION_COMPLETE ); + this.User[ 'dispatch' ]( XUI_Event.CREATION_COMPLETE ); // html 要素が親に追加されるまで控えていたイベントの登録 + // TODO listenOnce if( events && ( l = events.length ) ){ for( i = 0; i < l; ++i ){ this.listen.apply( this, events[ i ] ); @@ -101,70 +127,71 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( * 親要素が変化した場合、unverifiedAttrs を元に attrObject を再設定. */ setAttr : function( name, def, v ){ - var attrs = X.UI.attrClassProto || this.attrObject, + var attrs = XUI_attrClassProto || this.attrObject, propID = def.No || def[ 5 ], - defaultVal = X.UI.attrClassProto ? attrs[ propID ] : this.attrClass.prototype[ propID ], // def[ 0 ], + defaultVal = XUI_attrClassProto ? attrs[ propID ] : this.attrClass.prototype[ propID ], // def[ 0 ], currentVal = attrs ? attrs[ propID ] : defaultVal, dirty = def[ 1 ], user = def[ 2 ], type = def[ 3 ], list = def[ 4 ], - length = !!( type & X.UI.Attr.Type.LENGTH ), - minusLen = !!( type & X.UI.Attr.Type.MINUS_LENGTH ), - percent = !!( type & X.UI.Attr.Type.PERCENT ), - minusPct = !!( type & X.UI.Attr.Type.MINUS_PERCENT ), - numerical = !!( type & X.UI.Attr.Type.NUMERICAL ), - auto = !!( type & X.UI.Attr.Type.AUTO ), - color = !!( type & X.UI.Attr.Type.COLOR ), - url = !!( type & X.UI.Attr.Type.URL ), - fontName = !!( type & X.UI.Attr.Type.FONT_NAME ), - flag = !!( type & X.UI.Attr.Type.BOOLEAN ), - combi = !!( type & X.UI.Attr.Type.COMBI ), - quartet = !!( type & X.UI.Attr.Type.QUARTET ), + length = !!( type & XUI_Attr_Type.LENGTH ), + minusLen = !!( type & XUI_Attr_Type.MINUS_LENGTH ), + percent = !!( type & XUI_Attr_Type.PERCENT ), + minusPct = !!( type & XUI_Attr_Type.MINUS_PERCENT ), + numerical = !!( type & XUI_Attr_Type.NUMERICAL ), + auto = !!( type & XUI_Attr_Type.AUTO ), + color = !!( type & XUI_Attr_Type.COLOR ), + url = !!( type & XUI_Attr_Type.URL ), + fontName = !!( type & XUI_Attr_Type.FONT_NAME ), + flag = !!( type & XUI_Attr_Type.BOOLEAN ), + combi = !!( type & XUI_Attr_Type.COMBI ), + quartet = !!( type & XUI_Attr_Type.QUARTET ), _v, i, l, nodes, root, roots; - if( X.Type.isString( v ) ){ + if( X_Type_isString( v ) ){ //v = v.toLowercase(); if( url || fontName ){ // good } else if( auto && v === 'auto' ){ - v = X.UI.Attr.AUTO; + v = XUI_Attr_AUTO; } else if( list && ( _v = list[ v ] ) ){ // good + console.log( v + ' ' + _v ); v = _v; } else - if( ( percent || minusPct ) && v.lastIndexOf( '%' ) !== -1 && isFinite( _v = parseFloat( v ) ) && v === _v + '%' ){ + if( ( percent || minusPct ) && v.lastIndexOf( '%' ) !== -1 && X_Type_isFinite( _v = parseFloat( v ) ) && v === _v + '%' ){ // good } else - if( ( length || minusLen ) && v.lastIndexOf( 'em' ) !== -1 && isFinite( _v = parseFloat( v ) ) && v === _v + 'em' ){ + if( ( length || minusLen ) && v.lastIndexOf( 'em' ) !== -1 && X_Type_isFinite( _v = parseFloat( v ) ) && v === _v + 'em' ){ v = _v; } else if( v.indexOf( ' ' ) !== -1 ){ v = v.split( ' ' ); } else - if( color && X.Type.isNumber( _v = X.CSS.parseColor( v ) ) ){ - v = _v; + if( color && X_Type_isNumber( _v = X_Node_CSS_parseColor( v ) ) ){ + v = _v; } else { // bad return; }; }; - if( ( quartet || combi ) && !X.Type.isArray( v ) ){ + if( ( quartet || combi ) && !X_Type_isArray( v ) ){ v = [ v ]; }; - if( X.Type.isNumber( v ) ){ + if( X_Type_isNumber( v ) ){ if( ( length && ( 0 <= v ) ) || ( minusLen && ( v <= 0 ) ) || ( percent && 0 <= v && v <= 1 ) || ( minusPct && -1 <= v && v < 0 ) || ( numerical && 0 <= v ) || - ( auto && v === X.UI.Attr.AUTO ) || - ( color && 0 <= v && v <= 0xFFFFFF ) || + ( auto && v === XUI_Attr_AUTO ) || + ( color && ( 0 <= v && v <= 0xFFFFFF ) || ( v !== v ) ) || // isNaN ( list && list[ v ] ) ){ // good @@ -173,12 +200,12 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( return; }; } else - if( X.Type.isBoolean( v ) && !flag ){ + if( X_Type_isBoolean( v ) && !flag ){ return; } else - if( X.Type.isArray( v ) ){ + if( X_Type_isArray( v ) ){ if( v.length <= 4 && quartet ){ - type &= ~X.UI.Attr.Type.QUARTET; + type &= ~XUI_Attr_Type.QUARTET; switch( v.length ){ case 1 : this.setAttr( false, [ defaultVal, user, dirty, type, list, propID ], v[ 0 ] ); @@ -207,7 +234,7 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( }; } else if( v.length === 2 && combi ){ - type &= ~X.UI.Attr.Type.COMBI; + type &= ~XUI_Attr_Type.COMBI; this.setAttr( false, [ defaultVal, user, dirty, type, list, propID ], v[ 0 ] ); this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 1 ] ); } else { @@ -215,41 +242,42 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( return; }; - if( !X.UI.attrClassProto && user === X.UI.Attr.USER.XNODE && this.xnode ){ - this.xnode.css( X.UI.Attr.Rename[ name ] || name, this._createCssText( name ) ); - //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + this._createCssText( name ) + ' ' + propID + ' ' + attrs[ propID ] ); + if( !XUI_attrClassProto && user === XUI_Attr_USER.XNODE && this.xnode ){ + this.xnode[ 'css' ]( XUI_Attr_Rename[ name ] || name, XUI_AbstractUINode_createCssText( this, name ) ); + //console.log( ( XUI_Attr_Rename[ name ] || name ) + ' ' + XUI_AbstractUINode_createCssText( this, name ) + ' ' + propID + ' ' + attrs[ propID ] ); }; return; }; if( !v && v !== 0 ) v = defaultVal; - if( X.UI.attrClassProto ){ + // UIAttrClass の初期設定の場合、ここで終わる + if( XUI_attrClassProto ){ attrs[ propID ] = v; return; }; if( currentVal !== v ){ switch( propID ){ - case X.UI.Attr.Support.left.No : - this.constraintW = attrs[ X.UI.Attr.Support.right.No ] !== null; + case XUI_Attr_Support.left.No : + this.constraintW = attrs[ XUI_Attr_Support.right.No ] !== null; break; - case X.UI.Attr.Support.right.No : - this.constraintW = attrs[ X.UI.Attr.Support.left.No ] !== null; + case XUI_Attr_Support.right.No : + this.constraintW = attrs[ XUI_Attr_Support.left.No ] !== null; break; - case X.UI.Attr.Support.top.No : - this.constraintH = attrs[ X.UI.Attr.Support.bottom.No ] !== null; + case XUI_Attr_Support.top.No : + this.constraintH = attrs[ XUI_Attr_Support.bottom.No ] !== null; break; - case X.UI.Attr.Support.bottom.No : - this.constraintH = attrs[ X.UI.Attr.Support.top.No ] !== null; + case XUI_Attr_Support.bottom.No : + this.constraintH = attrs[ XUI_Attr_Support.top.No ] !== null; break; - case X.UI.Attr.Support.width.No : - this.autoWidth = v === X.UI.Attr.AUTO; - this.percentWidth = X.Type.isString( v ); + case XUI_Attr_Support.width.No : + this.autoWidth = v === XUI_Attr_AUTO; + this.percentWidth = X_Type_isString( v ); break; - case X.UI.Attr.Support.height.No : - this.autoHeight = v === X.UI.Attr.AUTO; - this.percentHeight = X.Type.isString( v ); + case XUI_Attr_Support.height.No : + this.autoHeight = v === XUI_Attr_AUTO; + this.percentHeight = X_Type_isString( v ); break; }; @@ -260,93 +288,21 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( attrs[ propID ] = v; }; - if( name && user === X.UI.Attr.USER.XNODE && this.xnode ){ - this.xnode.css( X.UI.Attr.Rename[ name ] || name, this._createCssText( name ) ); - //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + this._createCssText( name ) + ' ' + propID + ' ' + attrs[ propID ] ); - } else - if( this.dirty < dirty ) this.dirty = dirty; - }; - }, - - _createCssText : function( name ){ - var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, - def = this.supportAttrs[ name ], - no = def.No, - v = attrs[ def.No ], - type = def[ 3 ], - list = def[ 4 ], - flag = !!( type & X.UI.Attr.Type.BOOLEAN ), - combi = !!( type & X.UI.Attr.Type.COMBI ), - quartet = !!( type & X.UI.Attr.Type.QUARTET ); - - if( quartet ){ - if( attrs[ no + 1 ] === attrs[ no + 3 ] ){ - if( v === attrs[ no + 2 ] ){ - if( v === attrs[ no + 1 ] ){ - return this._createCssValue( v, type, list ); - }; - return [ - this._createCssValue( v, type, list ), - this._createCssValue( attrs[ no + 1 ], type, list ) - ].join( ' ' ); - }; - return [ - this._createCssValue( v, type, list ), - this._createCssValue( attrs[ no + 1 ], type, list ), - this._createCssValue( attrs[ no + 2 ], type, list ) - ].join( ' ' ); + if( name && user === XUI_Attr_USER.UINODE ){ + this[ name ] = v; }; - return [ - this._createCssValue( v, type, list ), - this._createCssValue( attrs[ no + 1 ], type, list ), - this._createCssValue( attrs[ no + 2 ], type, list ), - this._createCssValue( attrs[ no + 3 ], type, list ) - ].join( ' ' ); - } else - if( combi ){ - return [ - this._createCssValue( v, type, list ), - this._createCssValue( attrs[ no + 1 ], type, list ) - ].join( ' ' ); - } else - if( flag ){ - return v ? list : 'normal'; // - }; - return this._createCssValue( v, type, list ); - }, - - _createCssValue : function( v, type, list ){ - var length = !!( type & X.UI.Attr.Type.LENGTH ), - minusLen = !!( type & X.UI.Attr.Type.MINUS_LENGTH ), - percent = !!( type & X.UI.Attr.Type.PERCENT ), - minusPct = !!( type & X.UI.Attr.Type.MINUS_PERCENT ), - numerical = !!( type & X.UI.Attr.Type.NUMERICAL ), - auto = !!( type & X.UI.Attr.Type.AUTO ), - color = !!( type & X.UI.Attr.Type.COLOR ), - url = !!( type & X.UI.Attr.Type.URL ), - fontName = !!( type & X.UI.Attr.Type.FONT_NAME ); - - if( X.Type.isNumber( v ) ){ - if( auto && v === X.UI.Attr.AUTO ) return 'auto'; - if( length || minusLen ) return v + 'em'; - if( numerical ) return v; - if( list && list[ v ] ) return list[ v ]; - if( color ){ - if( v < 0x100000 ){ - v = '00000' + v.toString( 16 ); - return '#' + v.substr( v.length - 6 ); - }; - return '#' + v.toString( 16 ); - }; - }; - if( X.Type.isString( v ) ){ - if( percent || minusPct || url || fontName ) return v; + + if( name && user === XUI_Attr_USER.XNODE && this.xnode ){ + this.xnode[ 'css' ]( XUI_Attr_Rename[ name ] || name, XUI_AbstractUINode_createCssText( this, name ) ); + //console.log( ( XUI_Attr_Rename[ name ] || name ) + ' ' + XUI_AbstractUINode_createCssText( this, name ) + ' ' + propID + ' ' + attrs[ propID ] ); + } else + if( this.dirty < dirty ) this.dirty = dirty; }; }, getAttr : function( name ){ - var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, - support = this.supportAttrs[ name ], + var attrs = this.attrObject || this.attrClass.prototype || XUI_AttrClass, + support = this.usableAttrs[ name ], v, type, list; if( !support ) return; @@ -357,19 +313,19 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( type = support[ 3 ]; // Unit - if( type & X.UI.Attr.Type.QUARTET ){ + if( type & XUI_Attr_Type.QUARTET ){ return [ this.getAttr( name + 'Top' ), this.getAttr( name + 'Right' ), this.getAttr( name + 'Bottom' ), this.getAttr( name + 'Left' ) ]; }; - if( type & X.UI.Attr.Type.COMBI ) return [ v, data[ ++propID ] ]; + if( type & XUI_Attr_Type.COMBI ) return [ v, data[ ++propID ] ]; v = attrs[ support.No ]; - if( type & X.UI.Attr.Type.AUTO && v === X.UI.Attr.AUTO ) return 'auto'; + if( type & XUI_Attr_Type.AUTO && v === XUI_Attr_AUTO ) return 'auto'; list = support[ 4 ]; if( list ) return list[ v ]; - if( type & X.UI.Attr.Type.COLOR && X.Type.isNumber( v ) ) return v; - if( !( type & X.UI.Attr.Type.NUMERICAL ) && X.Type.isNumber( v ) ) return v + 'em'; + if( type & XUI_Attr_Type.COLOR && X_Type_isNumber( v ) ) return v; + if( !( type & XUI_Attr_Type.NUMERICAL ) && X_Type_isNumber( v ) ) return v + 'em'; return v; }, @@ -386,13 +342,12 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( case 2: case 1: - this.xnode.destroy(); + this.xnode[ 'remove' ](); delete this.root; delete this.rootData; delete this.parent; delete this.parentData; - delete this.xnode; delete this.phase; }; @@ -403,36 +358,44 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( calculate : function( isNeedsDetection, x, y, allowedW, allowedH ){ this.preMesure( allowedW, allowedH ); - if( this.boxWidth === X.UI.Attr.AUTO || this.boxHeight === X.UI.Attr.AUTO ){ + this.noWidth = this.boxWidth === XUI_Attr_AUTO; + this.noHeight = this.boxHeight === XUI_Attr_AUTO; + + if( this.noWidth || this.noHeight ){ this.mesure(); this.postMesure(); }; - !isNeedsDetection && this.updateLayout( x, y ); + if( !isNeedsDetection ){ + this.boxX += x; + this.boxY += y; + }; }, - /** + /* * X_Node_BoxModel の情報を引きながら top,left,width,height,padding,border の設定 */ - updateLayout : function( x, y ){ - this.boxX = x; - this.boxY = y; + updateLayout : function(){ + var x = this.boxX + ( this.parentData ? this.parentData.paddingL : 0 ), + y = this.boxY + ( this.parentData ? this.parentData.paddingT : 0 ), + w = X_UA[ 'IE5x' ] ? this.boxWidth : this.contentWidth, // IE6 の互換モードも + h = X_UA[ 'IE5x' ] ? this.boxHeight : this.contentHeight; + this.xnode - .css( 'left', x ? x + 'em' : 0 ) - .css( 'top', y ? y + 'em' : 0 ) - .css( 'width', this.contentWidth ? X.UI._AbstractUINode.ceil( this.contentWidth ) + 'em' : 0 ) - .css( 'height', this.contentHeight ? X.UI._AbstractUINode.ceil( this.contentHeight ) + 'em' : 0 ) - .css( 'padding', this._createCssText( 'padding' ) ) - .css( 'borderWidth', this._createCssText( 'borderWidth' ) ); + [ 'css' ]( 'left', x ? x + 'em' : 0 ) // 親の padding 分ずらす + [ 'css' ]( 'top', y ? y + 'em' : 0 ) // 親の padding 分ずらす + [ 'css' ]( 'width', this.noWidth ? 'auto' : w ? w + 'em' : 0 ) + [ 'css' ]( 'height', this.noHeight ? 'auto' : h ? h + 'em' : 0 ) + [ 'css' ]( 'padding', XUI_AbstractUINode_createCssText( this, 'padding' ) ) // TODO 不要? その分 w, h に足す + [ 'css' ]( 'borderWidth', XUI_AbstractUINode_createCssText( this, 'borderWidth' ) ); }, /* * 親の サイズを元に自身のサイズを計算していく */ preMesure : function( allowedW, allowedH ){ - var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, - calc = X.UI._AbstractUINode.calcValue, - box = attrs[ X.UI.Attr.Support.sizing.No ], + var attrs = this.attrObject || this.attrClass.prototype || XUI_AttrClass, + box = attrs[ XUI_Attr_Support.sizing.No ], min, max, boxL, boxT, boxR, boxB, contentW, contentH, boxMinus, @@ -443,10 +406,10 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( // 自身が constraintW の場合 親が AUTO ではない // 自身が constraintW でない場合自身が AUTO はなくかつ親 が AUTO の場合 or 自身は % でない - paddingR = calc( attrs[ X.UI.Attr.Support.padding.No + 1 ], allowedW ); - paddingL = calc( attrs[ X.UI.Attr.Support.padding.No + 3 ], allowedW ); - borderR = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], allowedW ); - borderL = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], allowedW ); + paddingR = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 1 ], allowedW ); + paddingL = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 3 ], allowedW ); + borderR = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 1 ], allowedW ); + borderL = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 3 ], allowedW ); boxMinus = 0; switch( box ){ case 3 : // border-box @@ -457,37 +420,36 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( }; this.contentL = borderL + paddingL; this.contentR = borderR + paddingR; + this.paddingL = paddingL; + this.borderL = borderL; - if( this.constraintW ? allowedW !== X.UI.Attr.AUTO : !this.autoWidth && ( allowedW !== X.UI.Attr.AUTO || !this.percentWidth ) ){ + if( this.constraintW ? allowedW !== XUI_Attr_AUTO : !this.autoWidth && ( allowedW !== XUI_Attr_AUTO || !this.percentWidth ) ){ if( this.constraintW ){ // 制約レイアウト - contentW = allowedW - ( boxL = calc( attrs[ X.UI.Attr.Support.left.No ], allowedW ) ) - ( boxR = calc( attrs[ X.UI.Attr.Support.right.No ], allowedW ) ); + contentW = allowedW - ( boxL = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.left.No ], allowedW ) ) - ( boxR = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.right.No ], allowedW ) ); } else { - contentW = X.UI._AbstractUINode.finalValue( attrs[ X.UI.Attr.Support.width.No ], attrs[ X.UI.Attr.Support.minWidth.No ], attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW ); + contentW = XUI_AbstractUINode_calcFinalValue( attrs[ XUI_Attr_Support.width.No ], attrs[ XUI_Attr_Support.minWidth.No ], attrs[ XUI_Attr_Support.maxWidth.No ], allowedW ); }; - this.contentWidth = contentW + boxMinus; - this.scrollWidth = this.contentWidth + this.contentL + this.contentR; - this.boxWidth = contentW - boxMinus + this.contentL + this.contentR; + this.contentWidth = contentW + boxMinus; + this.boxWidth = this.contentWidth + this.contentL + this.contentR; this.boxSizingOffsetLR = boxMinus; - delete this.minContentWidth; - delete this.maxContentWidth; - delete this.minBoxWidth; - delete this.maxBoxWidth; + delete this.contentWidthMin; + delete this.contentWidthMax; + delete this.boxWidthMin; + delete this.boxWidthMax; } else { - this.minContentWidth = calc( attrs[ X.UI.Attr.Support.minWidth.No ], allowedW ) + boxMinus; - this.maxContentWidth = calc( attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW ) + boxMinus; - this.scrollWidth = this.contentWidth + this.contentL + this.contentR; - this.minBoxWidth = this.minContentWidth - boxMinus + this.contentL + this.contentR; - this.maxBoxWidth = this.maxContentWidth - boxMinus + this.contentL + this.contentR; - //delete this.contentWidth; - //delete this.scrollWidth; - //delete this.boxWidth; - //delete this.boxSizingOffsetLR; + this.contentWidthMin = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minWidth.No ], allowedW ) + boxMinus ); + this.contentWidthMax = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.maxWidth.No ], allowedW ) + boxMinus ); + this.boxWidthMin = this.contentWidthMin + this.contentL + this.contentR; + this.boxWidthMax = this.contentWidthMax + this.contentL + this.contentR; + this.contentWidth = this.contentWidthMin; + this.boxWidth = this.boxWidthMin; + this.boxSizingOffsetLR = boxMinus; }; - paddingT = calc( attrs[ X.UI.Attr.Support.padding.No + 0 ], allowedH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingB = calc( attrs[ X.UI.Attr.Support.padding.No + 2 ], allowedH ); - borderT = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 0 ], allowedH ); - borderB = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 2 ], allowedH ); + paddingT = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 0 ], allowedH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 2 ], allowedH ); + borderT = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 0 ], allowedH ); + borderB = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 2 ], allowedH ); boxMinus = 0; switch( box ){ case 3 : // border-box @@ -498,69 +460,64 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( }; this.contentT = borderT + paddingT; this.contentB = borderB + paddingB; + this.paddingT = paddingT; + this.borderT = borderT; // Height - if( this.constraintH ? allowedH !== X.UI.Attr.AUTO : !this.autoHeight && ( allowedH !== X.UI.Attr.AUTO || !this.percentHeight ) ){ + if( this.constraintH ? allowedH !== XUI_Attr_AUTO : !this.autoHeight && ( allowedH !== XUI_Attr_AUTO || !this.percentHeight ) ){ if( this.constraintH ){ // 制約レイアウト - contentH = allowedH - ( boxT = calc( attrs[ X.UI.Attr.Support.top.No ], allowedH ) ) - ( boxB = calc( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) ); + contentH = allowedH - ( boxT = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.top.No ], allowedH ) ) - ( boxB = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.bottom.No ], allowedH ) ); } else { - contentH = X.UI._AbstractUINode.finalValue( attrs[ X.UI.Attr.Support.height.No ], attrs[ X.UI.Attr.Support.minHeight.No ], attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH ); + contentH = XUI_AbstractUINode_calcFinalValue( attrs[ XUI_Attr_Support.height.No ], attrs[ XUI_Attr_Support.minHeight.No ], attrs[ XUI_Attr_Support.maxHeight.No ], allowedH ); }; - this.contentHeight = contentH + boxMinus; - this.scrollHeight = this.contentHeight + this.contentT + this.contentB; - this.boxHeight = contentH - boxMinus + this.contentT + this.contentB; // padding-box の場合 border だけ足される + this.contentHeight = contentH + boxMinus; + this.boxHeight = this.contentHeight + this.contentT + this.contentB; // padding-box の場合 border だけ足される this.boxSizingOffsetTB = boxMinus; - delete this.minContentHeight; - delete this.maxContentHeight; - delete this.minBoxHeight; - delete this.maxBoxHeight; + delete this.contentHeightMin; + delete this.contentHeightMax; + delete this.boxHeightMin; + delete this.boxHeightMax; } else { - this.minContentHeight = calc( attrs[ X.UI.Attr.Support.minHeight.No ], allowedH ) + boxMinus; - this.maxContentHeight = calc( attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH ) + boxMinus; - this.minBoxHeight = this.minContentHeight - boxMinus + this.contentT + this.contentB; - this.maxBoxHeight = this.maxContentHeight - boxMinus + this.contentT + this.contentB; - - //delete this.contentHeight; - //delete this.scrollHeight; - //delete this.boxHeight; - //delete this.boxSizingOffsetTB; + this.contentHeightMin = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minHeight.No ], allowedH ) + boxMinus ); + this.contentHeightMax = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.maxHeight.No ], allowedH ) + boxMinus ); + this.boxHeightMin = this.contentHeightMin + this.contentT + this.contentB; + this.boxHeightMax = this.contentHeightMax + this.contentT + this.contentB; + this.contentHeight = this.contentHeightMin; + this.boxHeight = this.boxHeightMin; + this.boxSizingOffsetTB = boxMinus; }; + // x if( this.parentData && this.parentData.layout.overrideAttrsForChild.left ){ - if( this.constraintW ){ - this.boxX = ( boxL || boxL === 0 ) ? boxL : calc( attrs[ X.UI.Attr.Support.left.No ], allowedW ); - } else - if( attrs[ X.UI.Attr.Support.right.No ] === null ){ - this.boxX = ( boxL || boxL === 0 ) ? boxL : calc( attrs[ X.UI.Attr.Support.left.No ], allowedW ); + if( this.constraintW || attrs[ XUI_Attr_Support.right.No ] === null ){ + this.boxX = ( boxL || boxL === 0 ) ? boxL : XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.left.No ], allowedW ); } else { - this.boxX = alllowW - this.boxWidth - ( ( boxR || boxR === 0 ) ? boxR : calc( attrs[ X.UI.Attr.Support.right.No ], allowedW ) ); + this.boxX = allowedW - this.boxWidth - ( ( boxR || boxR === 0 ) ? boxR : XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.right.No ], allowedW ) ); }; } else { delete this.boxX; }; + // y if( this.parentData && this.parentData.layout.overrideAttrsForChild.top ){ - if( this.constraintH ){ - this.boxY = ( boxT || boxT === 0 ) ? boxT : calc( attrs[ X.UI.Attr.Support.top.No ], allowedH ); - } else - if( attrs[ X.UI.Attr.Support.bottom.No ] === null ){ - this.boxY = ( boxT || boxT === 0 ) ? boxT : calc( attrs[ X.UI.Attr.Support.top.No ], allowedH ); + if( this.constraintH || attrs[ XUI_Attr_Support.bottom.No ] === null ){ + this.boxY = ( boxT || boxT === 0 ) ? boxT : XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.top.No ], allowedH ); } else { - this.boxY = allowedH - this.boxHeight - ( ( boxB || boxB === 0 ) ? boxB : calc( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) ); + this.boxY = allowedH - this.boxHeight - ( ( boxB || boxB === 0 ) ? boxB : XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.bottom.No ], allowedH ) ); }; } else { delete this.boxY; }; }, - /** - * 描画・計測を行って、contentSize, scrollSize の決定 + /* + * 描画・計測を行って、contentSize の決定 */ mesure : function(){ var dirty = this.dirty, - w, h, xnode; + w, _w, h, xnode; - if( dirty === X.UI.Dirty.CLEAN ){ + if( dirty === XUI_Dirty.CLEAN ){ if( this.percentWidth || this.percentHeight ){ }; @@ -568,14 +525,14 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( switch( dirty ){ - case X.UI.Dirty.CONTENT : // コンテンツが変更された - case X.UI.Dirty.FONT : // フォントサイズが変更された - delete this.lastContentWidth; - delete this.lastContentHeight; + case XUI_Dirty.CONTENT : // コンテンツが変更された + case XUI_Dirty.FONT : // フォントサイズが変更された + delete this.contentWidthLast; + delete this.contentHeightLast; - case X.UI.Dirty.LAYOUT : // レイアウトの再計算が必要 + case XUI_Dirty.LAYOUT : // レイアウトの再計算が必要 - default : // TODO レイアウト崩れに対処 パフォーマンス悪い! + default : // TODO レイアウト指定が不正な場合 bgcolor を変更、これ以下のレイアウトの中止 w = this.contentWidth; h = this.contentHeight; @@ -599,75 +556,77 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( * コンテンツの高さの再取得が必要 * 必要でない */ - if( xnode._xnodes && xnode._xnodes.length ){ - if( w === X.UI.Attr.AUTO ){ - w = this.contentWidth = xnode.css( 'width', 'auto' ).width() / X_Node_CSS_getCharSize( xnode ); + if( xnode[ '_xnodes' ] && xnode[ '_xnodes' ].length ){ + if( w === XUI_Attr_AUTO ){ - this.scrollWidth = w + this.contentL + this.contentR; - if( this.maxContentWidth < w - this.boxSizingOffsetLR ) this.contentWidth = this.maxContentWidth + this.boxSizingOffsetLR; - if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR; - this.lastContentWidth = this.contentWidth; - - w !== this.contentWidth && xnode.css( 'width', X.UI._AbstractUINode.ceil( this.contentWidth ) + 'em' ); - - if( h === X.UI.Attr.AUTO ){ - this.contentHeight = h = xnode.css( 'height', 'auto' ).scrollHeight() / X_Node_CSS_getCharSize( xnode ); // scrollHeight() ?? - this.scrollHeight = h + this.contentT + this.contentB; - if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; - if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; - } else { - this.scrollHeight = h + this.contentT + this.contentB; + w = _w = XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'width', 'auto' )[ 'clientWidth' ]() / X_Node_CSS_getCharSize( xnode ) ); + + if( this.contentWidthMax < w - this.boxSizingOffsetLR ){ + this.noWidth = false; + w = this.contentWidthMax + this.boxSizingOffsetLR; }; - - this.lastContentHeight = h; + if( w - this.boxSizingOffsetLR < this.contentWidthMin ){ + this.noWidth = false; + w = this.contentWidthMin + this.boxSizingOffsetLR; + }; + + if( h === XUI_Attr_AUTO ){ + w !== _w && xnode[ 'css' ]( 'width', w + 'em' ); + h = XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ) ); + w !== _w && xnode[ 'css' ]( 'width', 'auto' ); + }; + + this.contentWidthLast = this.contentWidth = w; + } else - if( h === X.UI.Attr.AUTO ){ - if( w !== this.lastContentWidth ){ - xnode.css( 'width', X.UI._AbstractUINode.ceil( w ) + 'em' ); + if( h === XUI_Attr_AUTO ){ + if( w !== this.contentWidthLast ){ + xnode[ 'css' ]( 'width', w + 'em' ); + this.contentWidthLast = w; - this.lastContentWidth = w; - this.contentHeight = h = xnode.css( 'height', 'auto' ).scrollHeight() / X_Node_CSS_getCharSize( xnode ); - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; - if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; - if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; + // ie8 clientHeight, ff scrollHeight & clientHeight + h = XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ) ); } else { - this.contentHeight = this.lastContentHeight = h = - this.lastContentHeight === -1 ? xnode.css( 'height', 'auto' ).scrollHeight() / X_Node_CSS_getCharSize( xnode ) : this.lastContentHeight; - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; + h = this.contentHeightLast === -1 ? + XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ) ) : + this.contentHeightLast; }; } else - if( dirty !== X.UI.Dirty.LAYOUT ){ - this.contentWidth = this.lastContentWidth = w; //xnode.width(); - this.contentHeight = this.lastContentHeight = xnode.css( 'height', 'auto' ).scrollHeight() / X_Node_CSS_getCharSize( xnode ); - this.scrollWidth = this.contentWidth + this.contentL + this.contentR; - this.scrollHeight = this.contentHeight + this.contentT + this.contentB; - } else { - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; - }; + if( dirty !== XUI_Dirty.LAYOUT ){ + this.contentWidth = this.contentWidthLast = w; + h = XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ) ); + }; + + if( this.contentHeightMax < h - this.boxSizingOffsetTB ){ + this.noHeight = false; + h = this.contentHeightMax + this.boxSizingOffsetTB; + }; + if( h - this.boxSizingOffsetTB < this.contentHeightMin ){ + this.noHeight = false; + h = this.contentHeightMin + this.boxSizingOffsetTB; + }; + + this.contentHeight = this.contentHeightLast = h; + } else { // コンテンツを持たないため基本のサイズは0 - if( w === X.UI.Attr.AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; - if( h === X.UI.Attr.AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; + if( w === XUI_Attr_AUTO ) this.contentWidth = w = 0 < this.contentWidthMin ? this.contentWidthMin : 0; + if( h === XUI_Attr_AUTO ) this.contentHeight = h = 0 < this.contentHeightMin ? this.contentHeightMin : 0; + this.noWidth = this.noHeight = false; }; delete this.dirty; break; - //case X.UI.Dirty.PAINT : // 再描画のみ必要 + //case XUI_Dirty.PAINT : // 再描画のみ必要 // break; }; }, - /** + /* * 自身の contentWidth, contentHeight を元に AUTO な width, height を確定していく */ postMesure : function(){ - var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, - calc = X.UI._AbstractUINode.calcValue, - box = attrs[ X.UI.Attr.Support.sizing.No ], + var attrs = this.attrObject || this.attrClass.prototype || XUI_AttrClass, + box = attrs[ XUI_Attr_Support.sizing.No ], contentW, contentH, contentPlus, paddingT, paddingR, paddingB, paddingL, @@ -675,25 +634,25 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( min, max; // Width - if( this.boxWidth === X.UI.Attr.AUTO ){ + if( this.boxWidth === XUI_Attr_AUTO ){ contentW = this.contentWidth; - paddingR = calc( attrs[ X.UI.Attr.Support.padding.No + 1 ], contentW ); - paddingL = calc( attrs[ X.UI.Attr.Support.padding.No + 3 ], contentW ); - borderR = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], contentW ); - borderL = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], contentW ); + paddingR = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 1 ], contentW ); + paddingL = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 3 ], contentW ); + borderR = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 1 ], contentW ); + borderL = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 3 ], contentW ); contentPlus = 0; switch( box ){ - case 3 : // border-box - contentPlus = borderR + borderL; + case 1 : // content-box + contentPlus = paddingR + paddingL; case 2 : // padding-box - contentPlus += paddingR + paddingL; - // case 1 : // content-box + contentPlus += borderR + borderL; + // case 3 : // border-box }; if( !this.constraintW ){ contentW += contentPlus; - min = calc( attrs[ X.UI.Attr.Support.minWidth.No ], contentW ); - max = calc( attrs[ X.UI.Attr.Support.maxWidth.No ], contentW ); + min = this.boxWidthMin = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minWidth.No ], contentW ); + max = this.boxWidthMax = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.maxWidth.No ], contentW ); if( contentW < min && contentPlus < min ){ this.contentWidth = min - contentPlus; } else @@ -703,27 +662,29 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( }; this.contentL = borderL + paddingL; this.contentR = borderR + paddingR; + this.paddingL = paddingL; + this.borderL = borderL; this.boxWidth = this.contentWidth + this.contentL + this.contentR; }; // Height - if( this.boxHeight === X.UI.Attr.AUTO ){ + if( this.boxHeight === XUI_Attr_AUTO ){ contentH = this.contentHeight; - paddingT = calc( attrs[ X.UI.Attr.Support.padding.No + 0 ], contentH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingB = calc( attrs[ X.UI.Attr.Support.padding.No + 2 ], contentH ); - borderT = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 0 ], contentH ); - borderB = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 2 ], contentH ); + paddingT = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 0 ], contentH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.padding.No + 2 ], contentH ); + borderT = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 0 ], contentH ); + borderB = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.borderWidth.No + 2 ], contentH ); contentPlus = 0; switch( box ){ - case 3 : // border-box - contentPlus = borderT + borderB; + case 1 : // content-box + contentPlus = paddingT + paddingB; case 2 : // padding-box - contentPlus += paddingT + paddingB; - // case 1 : // content-box + contentPlus += borderT + borderB; + // case 3 : // border-box }; if( !this.constraintH ){ contentH += contentPlus; - min = calc( attrs[ X.UI.Attr.Support.minHeight.No ], contentH ); - max = calc( attrs[ X.UI.Attr.Support.maxHeight.No ], contentH ); + min = this.boxHeightMin = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minHeight.No ], contentH ); + max = this.boxHeightMax = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.maxHeight.No ], contentH ); if( contentH < min && contentPlus < min ){ this.contentHeight = min - contentPlus; } else @@ -733,10 +694,13 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( }; this.contentT = borderT + paddingT; this.contentB = borderB + paddingB; + this.paddingT = paddingT; + this.borderT = borderT; this.boxHeight = this.contentHeight + this.contentT + this.contentB; }; }, + // TODO fontsize が変わることもある capcher : function( x, y ){ if( this.pointerDisabled ) return false; @@ -744,139 +708,144 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( y -= this.boxY; if( 0 <= x && x < this.boxWidth && 0 <= y && y < this.boxHeight ){ - !this.hovering && ( this.rootData.hoverList[ this.rootData.hoverList.length ] = this ); - this.rootData.targetNodeData = this; + !this.hovering && ( XUI_UINODES_HOVER[ XUI_UINODES_HOVER.length ] = this ); + XUI_uinodeTarget = this; + //console.log( 'hit ' + this.xnode.className() ) return true; }; }, + listen : XUI_$UINodeBase_listen, - listen : function( type, arg1, arg2, arg3 ){ - var root, events, counter, f; - if( X.UI.Event._START_POINTER <= type && type <= X.UI.Event._END_POINTER ){ - if( this.phase < 3 ){ - if( !( events = this.reserveEvents ) ) this.reserveEvents = events = []; - events[ events.length ] = [ type, arg1, arg2, arg3 ]; - return this; - }; - if( X.UI.Event._START_XUI_EVENT < type && type < X.UI.Event._END_XUI_EVENT ){ - if( !this.gesture ){ - this.gesture = new X.UI.Gesture( this.rootData, this, type ); - } else { - this.gesture.listen( type ); - }; - } else { - //console.log( type ); - root = this.rootData; - counter = root.eventCounter; - if( counter[ type ] ){ - ++counter[ type ]; - } else { - counter[ type ] = 1; - root.xnodeInteractiveLayer.listen( X.UI.Event.IdToName[ type ], X.UI._eventRellay ); - }; - }; - }; - f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 ); - if( !f.k ){ - return X_EventDispatcher_listen.call( this, type, this.User, f ); - } else - if( f.k === X_Callback_FUNC_ONLY ){ - return X_EventDispatcher_listen.call( this, type, this.User, f.f, f.s ); - }; - return X_EventDispatcher_listen.apply( this, arguments ); - }, - unlisten : function( type, arg1, arg2, arg3 ){ - var root, events, i, ev, counter, f; - if( X.UI.Event._START_POINTER <= type && type <= X.UI.Event._END_POINTER ){ - if( this.phase < 3 ){ - if( !( events = this.reserveEvents ) ) return this; - for( i = events.length; i; ){ - ev = events[ --i ]; - if( ev[ 0 ] === type && ev[ 1 ] === arg1 && ev[ 2 ] === arg2 ){ - events.split( i, 1 ); - return this; - }; - }; - return this; - }; - - if( X.UI.Event._START_XUI_EVENT < type && type < X.UI.Event._END_XUI_EVENT ){ - this.gesture && this.gesture.unlisten( type ); - } else { - root = this.rootData; - counter = root.eventCounter; - if( !counter[ type ] ) return this; - --counter[ type ]; - if( counter[ type ] === 0 ){ - root.xnodeInteractiveLayer.unlisten( X.UI.Event.IdToName[ type ], X.UI._eventRellay ); - delete counter[ type ]; - }; - }; - }; - f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 ); - if( !f.k ){ - return X.EventDispatcher.prototype.unlisten.apply( this, [ type, this.User, f ] ); - } else - if( f.k === X_Callback_FUNC_ONLY ){ - return X.EventDispatcher.prototype.unlisten.apply( this, [ type, this.User, f.f, f.s ] ); - }; - return X.EventDispatcher.prototype.unlisten.apply( this, arguments ); - }, + unlisten : XUI_$UINodeBase_unlisten, - dispatch : function( e ){ - //console.log( e.type + ' ' + ( this._listeners && this._listeners[ e.type ] ) ); - var xve = X.UI.Event, - ret = X_EventDispatcher_dispatch.call( this, e ), - type = e.type || e; - - // TODO captureEvent PointerEvent - if( ret & X.Callback.MONOPOLY && !this.hitChildData && ( xve._POINTER_MOVE === type || xve._MOUSE_MOVE === type || xve.FILE_DRAG === type ) ){ - this.rootData.monopolyNodeData = this; - return ret; - }; - this.rootData.monopolyNodeData = null; - if( xve._START_BUBLEUP < type && this.parentData && !( ret & X.Callback.STOP_PROPAGATION ) && !( ret & X.Callback.STOP_NOW ) ) return this.parentData.dispatch( e ); - return ret; + setItemData : function( itemData ){ + if( this.itemData === itemData ) return; + + this.itemData = itemData; + + this[ 'dispatch' ]( { type : XUI_Event.ITEMDATA_CHANGED, itemData : itemData } ); + // itemData && itemData.listen( X_Event_CHANGED ) + // dataFeild dataFormatter dataValidator + + // itemData.listen( X_Event_CHANGED ) -> this[ 'dispatch' ]( UI_Event.ITEMDATA_UPDATED ); } } ); -X.UI._AbstractUINode.calcValue = function( styleValue, srcValue ){ +function XUI_AbstractUINode_createCssText( that, name ){ + var attrs = that.attrObject || that.attrClass.prototype || XUI_AttrClass, + def = that.usableAttrs[ name ], + no = def.No, + v = attrs[ def.No ], + type = def[ 3 ], + list = def[ 4 ], + flag = !!( type & XUI_Attr_Type.BOOLEAN ), + combi = !!( type & XUI_Attr_Type.COMBI ), + quartet = !!( type & XUI_Attr_Type.QUARTET ); + + if( quartet ){ + if( attrs[ no + 1 ] === attrs[ no + 3 ] ){ + if( v === attrs[ no + 2 ] ){ + if( v === attrs[ no + 1 ] ){ + return XUI_AbstractUINode_createCssValue( v, type, list ); + }; + return [ + XUI_AbstractUINode_createCssValue( v, type, list ), + XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list ) + ].join( ' ' ); + }; + return [ + XUI_AbstractUINode_createCssValue( v, type, list ), + XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list ), + XUI_AbstractUINode_createCssValue( attrs[ no + 2 ], type, list ) + ].join( ' ' ); + }; + return [ + XUI_AbstractUINode_createCssValue( v, type, list ), + XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list ), + XUI_AbstractUINode_createCssValue( attrs[ no + 2 ], type, list ), + XUI_AbstractUINode_createCssValue( attrs[ no + 3 ], type, list ) + ].join( ' ' ); + } else + if( combi ){ + return [ + XUI_AbstractUINode_createCssValue( v, type, list ), + XUI_AbstractUINode_createCssValue( attrs[ no + 1 ], type, list ) + ].join( ' ' ); + } else + if( flag ){ + return v ? list : 'normal'; // + }; + return XUI_AbstractUINode_createCssValue( v, type, list ); +}; + +function XUI_AbstractUINode_createCssValue( v, type, list ){ + var length = !!( type & XUI_Attr_Type.LENGTH ), + minusLen = !!( type & XUI_Attr_Type.MINUS_LENGTH ), + percent = !!( type & XUI_Attr_Type.PERCENT ), + minusPct = !!( type & XUI_Attr_Type.MINUS_PERCENT ), + numerical = !!( type & XUI_Attr_Type.NUMERICAL ), + auto = !!( type & XUI_Attr_Type.AUTO ), + color = !!( type & XUI_Attr_Type.COLOR ), + url = !!( type & XUI_Attr_Type.URL ), + fontName = !!( type & XUI_Attr_Type.FONT_NAME ); + + if( X_Type_isNumber( v ) ){ + if( auto && v === XUI_Attr_AUTO ) return 'auto'; + if( length || minusLen ) return v ? v + 'em' : 0; + if( numerical ) return v; + if( list && list[ v ] ) return list[ v ]; + if( color ){ + if( v < 0x100000 ){ + v = '00000' + v.toString( 16 ); + return '#' + v.substr( v.length - 6 ); + } else + if( v !== v ){ // iSNaN + return 'none'; + }; + return '#' + v.toString( 16 ); + }; + }; + if( X_Type_isString( v ) ){ + if( percent || minusPct || url || fontName ) return v; + }; +}; + +function XUI_AbstractUINode_calcValue( styleValue, srcValue ){ /* * String の場合は必ず % */ - if( X.Type.isString( styleValue ) ){ + if( X_Type_isString( styleValue ) ){ return srcValue * parseFloat( styleValue ) / 100; }; - if( !X.Type.isNumber( styleValue ) ) return 0; + if( !X_Type_isNumber( styleValue ) ) return 0; return styleValue; }; -X.UI._AbstractUINode.finalValue = function( styleValue, styleMin, styleMax, srcValue ){ - var calc = X.UI._AbstractUINode.calcValue, - v = calc( styleValue, srcValue ), - min = calc( styleMin, srcValue ), - max = calc( styleMax, srcValue ); +function XUI_AbstractUINode_calcFinalValue( styleValue, styleMin, styleMax, srcValue ){ + var v = XUI_AbstractUINode_calcValue( styleValue, srcValue ), + min = XUI_AbstractUINode_calcValue( styleMin, srcValue ), + max = XUI_AbstractUINode_calcValue( styleMax, srcValue ); return v <= min ? min : max <= v ? max : v; }; -X.UI._AbstractUINode.ceil = function( v ){ +function XUI_AbstractUINode_ceil( v ){ if( 0 <= v ){ return ( v * 10 + 0.999 | 0 ) / 10; }; return ( -v * 10 + 0.999 | 0 ) / -10; }; -X.UI.AbstractUINode = X.Class.create( +X.UI.AbstractUINode = X_Class_create( 'AbstractUINode', - X.Class.ABSTRACT | X.Class.SUPER_ACCESS, + X_Class.ABSTRACT, { parent : function(){ - return X_Class_getPrivate( this ).parent; + return X_Pair_get( this ).parent; }, root : function(){ - return X_Class_getPrivate( this ).root; + return X_Pair_get( this ).root; }, /* @@ -884,34 +853,35 @@ X.UI.AbstractUINode = X.Class.create( * サポートされていない場合は無視される.親のレイアウトによって変わる */ attr : function( nameOrObject, valueOrUnit ){ - var p = X_Class_getPrivate( this ), + var p = X_Pair_get( this ), layout, k, def, attrs, v; - if( nameOrObject && X.Type.isObject( nameOrObject ) ){ + if( nameOrObject && X_Type_isObject( nameOrObject ) ){ // setter layout = p.parentData && p.parentData.layout.overrideAttrsForChild; // root には parent がない for( k in nameOrObject ){ + if( X_EMPTY_OBJECT[ k ] ) continue; // 親のレイアウトマネージャの許可しない if( layout && !layout[ k ] ){ continue; }; - if( def = p.supportAttrs[ k ] ){ + if( def = p.usableAttrs[ k ] ){ p.setAttr( k, def, nameOrObject[ k ] ); }; }; } else - if( X.Type.isString( nameOrObject ) ){ + if( X_Type_isString( nameOrObject ) && ( def = p.usableAttrs[ nameOrObject ] ) ){ if( valueOrUnit !== undefined ){ if( 'em,%'.indexOf( valueOrUnit ) === -1 ){ // setter - p.setAttr( nameOrObject, valueOrUnit ); + p.setAttr( nameOrObject, def, valueOrUnit ); } else { // getter with unit return p.getAttrWithUnit( nameOrObject, valueOrUnit ); }; }; // getter - if( attrs = ( p.attrObject || p.attrClass.prototype || X.UI.AttrClass ) ){ - def = p.supportAttrs[ nameOrObject ]; + if( attrs = ( p.attrObject || p.attrClass.prototype || XUI_AttrClass ) ){ + def = p.usableAttrs[ nameOrObject ]; return def && attrs[ def.No ]; }; return v; @@ -920,32 +890,48 @@ X.UI.AbstractUINode = X.Class.create( }, listen : function( type, arg1, arg2, arg3 ){ - X_Class_getPrivate( this ).listen( type, arg1, arg2, arg3 ); + var pair = X_Pair_get( this ); + + ( !arg1 || !arg1.cbKind ) && ( arg1 = X_Closure_classifyCallbackArgs( arg1, arg2, arg3, this ) ); + + if( arg1.cbKind === X_CLOSURE_FUNC_ONLY ){ + pair[ 'listen' ].apply( pair, [ type, this, arg1.func, arg1.supplement ] ); + } else { + pair[ 'listen' ]( type, arg1.context, arg1.func, arg1.supplement ); + }; return this; }, listenOnce : function( type, arg1, arg2, arg3 ){ - X_Class_getPrivate( this ).listenOnce( type, arg1, arg2, arg3 ); + X_Pair_get( this )[ 'listenOnce' ]( type, arg1, arg2, arg3 ); return this; }, listening : function( type, arg1, arg2, arg3 ){ - return X_Class_getPrivate( this ).listening( type, arg1, arg2, arg3 ); + return X_Pair_get( this )[ 'listening' ]( type, arg1, arg2, arg3 ); }, unlisten : function( type, arg1, arg2, arg3 ){ - X_Class_getPrivate( this ).unlisten( type, arg1, arg2, arg3 ); + var pair = X_Pair_get( this ); + + ( !arg1 || !arg1.cbKind ) && ( arg1 = X_Closure_classifyCallbackArgs( arg1, arg2, arg3, this ) ); + + if( arg1.cbKind === X_CLOSURE_FUNC_ONLY ){ + pair[ 'unlisten' ].apply( pair, [ type, this, arg1.func, arg1.supplement ] ); + } else { + pair[ 'unlisten' ]( type, arg1.context, arg1.func, arg1.supplement ); + }; return this; }, dispatch : function( e ){ - return X_Class_getPrivate( this ).dispatch( e ); + return X_Pair_get( this )[ 'dispatch' ]( e ); }, - getNextNode : function(){ + nextNode : function(){ }, - getPrevNode : function(){ + prevNode : function(){ }, nodeIndex : function( v ){ - var data = X_Class_getPrivate( this ); + var data = X_Pair_get( this ); if( typeof v === 'number' ){ // data.nodeIndex( v ); return this; @@ -957,44 +943,100 @@ X.UI.AbstractUINode = X.Class.create( }, getX : function(){ // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).boxX; + return X_Pair_get( this ).boxX; }, getY : function(){ // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).boxY; + return X_Pair_get( this ).boxY; }, getAbsoluteX : function(){ // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).absoluteX; + return X_Pair_get( this ).absoluteX; }, getAbsoluteY: function(){ // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).absoluteY; + return X_Pair_get( this ).absoluteY; }, getWidth : function(){ // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).boxWidth; + return X_Pair_get( this ).boxWidth; }, getHeight : function(){ // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).boxHeight; + return X_Pair_get( this ).boxHeight; }, - scrollTo : function( x, y ){ - X_Class_getPrivate( this ).scrollTo( x, y ); - }, - getScrollX : function( v ){ - // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).scrollX( v ); - }, - getScrollY : function( v ){ - // dirty の場合、rootData.calculate - return X_Class_getPrivate( this ).scrollY( v ); - }, - disabled : function( v ){ - return X_Class_getPrivate( this ).disabled( v ); - }, - cursor : function( v ){ - return X_Class_getPrivate( this ).cursor( v ); + + /* + * Repeater に於いて、繰り返されるアイテムの元(itemRenderer)からの複製に使用 + */ + clone : function( opt_cloneListener ){ + var newNode, + //newPair = X_Pair_get( newNode ), + pair = X_Pair_get( this ), + attr, listeners, type, list, i, l, k, def, f; + + // attr もコピー + if( pair.attrObject ){ + attr = {}; + for( k in pair.usableAttrs ){ + def = pair.usableAttrs[ k ]; + attr[ k ] = pair.attrObject[ def.No ]; + }; + newNode = this.constructor( attr ); + }; + + // handleEvent 等の拡張されたオブジェクトもコピーする! + for( k in this ){ + if( this[ k ] !== newNode[ k ] && !newNode[ k ] ) newNode[ k ] = this[ k ]; + }; + + // User.UINODE な値は pair にコピーされているのでこれをコピー + for( k in pair ){ + //pair[ k ] !== newPair[ k ] && !newPair[ k ] && console.log( k ); + //if( pair[ k ] !== newPair[ k ] && !newPair[ k ] && k !== 'attrObject' && k !== '_listeners' ){ + //newPair[ k ] = pair[ k ]; + //console.log( k ); + //}; + }; + + + + // listener もコピーする! + if( opt_cloneListener && ( listeners = pair[ '_listeners' ] ) ){ + for( type in listeners ){ + list = listeners[ type ]; + for( i = 0, l = list.length; i < l; ++i ){ + f = list[ i ]; + switch( f.cbKind ){ + case X_CLOSURE_THIS_FUNC : + newNode[ f.once ? 'listenOnce' : 'listen' ]( type, f.context === this ? newNode : f.context, f.func, f.supplement ); + break; + case X_CLOSURE_HANDLEEVENT : + newNode[ f.once ? 'listenOnce' : 'listen' ]( type, f.context === this ? newNode : f.context, f.supplement ); + break; + /* + case X_CLOSURE_FUNC_ONLY : + if( f.lock ){ + newNode[ 'listen' ]( type, f.func, f.supplement ); + } else { + newNode[ f.once ? 'listenOnce' : 'listen' ]( type, f.func, f.supplement ); + }; + break; + default : + newNode[ 'listen' ]( type, f ); + break; */ + }; + }; + }; + } else + if( opt_cloneListener && ( list = this.reserveEvents ) ){ + for( i = 0, l = list.length; i < l; ++i ){ + f = list[ i ]; + newNode[ f.once ? 'listenOnce' : 'listen' ]( f[ 0 ], newNode, f[ 1 ], f[ 2 ] ); + }; + }; + + return newNode; } } );