X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F20_ui%2F06_AbstractUINode.js;h=5919e21c85b6b3f2e06d9affdeca4f83074b0c74;hb=ef25747bebf1799d49f9bd0d64e339da9ea61d13;hp=b2dfe240d77c6b574d79741deab4c3975ec5c9ba;hpb=8e63f506d14490e852fa557d326ca91f9cdd3baf;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 b2dfe24..5919e21 100644 --- a/0.6.x/js/20_ui/06_AbstractUINode.js +++ b/0.6.x/js/20_ui/06_AbstractUINode.js @@ -1,43 +1,50 @@ +// TODO -> Node[ 'inherits' ] var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 'X.UI._AbstractUINode', X_Class.ABSTRACT, { + itemData : null, + phase : 0, dirty : XUI_Dirty.CLEAN, root : null, rootData : null, - hoverList : null, parent : null, parentData : null, xnode : null, - supportAttrs : XUI_Attr_Support, + usableAttrs : XUI_Attr_Support, attrClass : XUI_AttrClass, attrObject : null, unverifiedAttrs : 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, // remove? - scrollHeight : 0, // remove? boxWidth : XUI_Attr_AUTO, - minBoxWidth : 0, - maxBoxWidth : XUI_Attr_AUTO, + boxWidthMin : 0, + boxWidthMax : XUI_Attr_AUTO, boxHeight : XUI_Attr_AUTO, - minBoxHeight : 0, - maxBoxHeight : XUI_Attr_AUTO, + boxHeightMin : 0, + boxHeightMax : XUI_Attr_AUTO, contentL : 0, contentT : 0, contentR : 0, @@ -49,13 +56,13 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( boxSizingOffsetLR : 0, boxSizingOffsetTB : 0, contentWidth : XUI_Attr_AUTO, - minContentWidth : 0, - maxContentWidth : XUI_Attr_AUTO, - lastContentWidth : -1, + contentWidthMin : 0, + contentWidthMax : XUI_Attr_AUTO, + contentWidthLast : -1, contentHeight : XUI_Attr_AUTO, - minContentHeight : 0, - maxContentHeight : XUI_Attr_AUTO, - lastContentHeight : -1, + contentHeightMin : 0, + contentHeightMax : XUI_Attr_AUTO, + contentHeightLast : -1, constraintW : false, constraintH : false, @@ -72,15 +79,27 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( this.rootData = rootData; this.parent = parent; this.parentData = parentData; - //this.xnode = X_Doc_create( 'div' ); this.phase = 1; this[ 'dispatch' ]( XUI_Event.INIT ); }, addToParent : function( xnodeParent ){ + 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' ]( XUI_Event.ADDED ); }, @@ -93,6 +112,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 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 ] ); @@ -142,17 +162,17 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 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_Node_CSS_objToIEFilterText( v ) ) ){ - v = _v; + if( color && X_Type_isNumber( _v = X_Node_CSS_parseColor( v ) ) ){ + v = _v; } else { // bad return; @@ -171,7 +191,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( ( minusPct && -1 <= v && v < 0 ) || ( numerical && 0 <= v ) || ( auto && v === XUI_Attr_AUTO ) || - ( color && 0 <= v && v <= 0xFFFFFF ) || + ( color && ( 0 <= v && v <= 0xFFFFFF ) || ( v !== v ) ) || // isNaN ( list && list[ v ] ) ){ // good @@ -231,6 +251,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( if( !v && v !== 0 ) v = defaultVal; + // UIAttrClass の初期設定の場合、ここで終わる if( XUI_attrClassProto ){ attrs[ propID ] = v; return; @@ -281,7 +302,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( getAttr : function( name ){ var attrs = this.attrObject || this.attrClass.prototype || XUI_AttrClass, - support = this.supportAttrs[ name ], + support = this.usableAttrs[ name ], v, type, list; if( !support ) return; @@ -321,13 +342,12 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( case 2: case 1: - this.xnode[ 'kill' ](); + this.xnode[ 'remove' ](); delete this.root; delete this.rootData; delete this.parent; delete this.parentData; - delete this.xnode; delete this.phase; }; @@ -358,7 +378,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 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, + w = X_UA[ 'IE5x' ] ? this.boxWidth : this.contentWidth, // IE6 の互換モードも h = X_UA[ 'IE5x' ] ? this.boxHeight : this.contentHeight; this.xnode @@ -366,7 +386,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( [ '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' ) ) + [ 'css' ]( 'padding', XUI_AbstractUINode_createCssText( this, 'padding' ) ) // TODO 不要? その分 w, h に足す [ 'css' ]( 'borderWidth', XUI_AbstractUINode_createCssText( this, 'borderWidth' ) ); }, @@ -412,17 +432,17 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 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 = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minWidth.No ], allowedW ) + boxMinus ); - this.maxContentWidth = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.maxWidth.No ], allowedW ) + boxMinus ); - this.minBoxWidth = this.minContentWidth + this.contentL + this.contentR; - this.maxBoxWidth = this.maxContentWidth + this.contentL + this.contentR; - this.contentWidth = this.minContentWidth; - this.boxWidth = this.minBoxWidth; + 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; }; @@ -453,38 +473,34 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 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 = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minHeight.No ], allowedH ) + boxMinus ); - this.maxContentHeight = XUI_AbstractUINode_ceil( XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.maxHeight.No ], allowedH ) + boxMinus ); - this.minBoxHeight = this.minContentHeight + this.contentT + this.contentB; - this.maxBoxHeight = this.maxContentHeight + this.contentT + this.contentB; - this.contentHeight = this.minContentHeight; - this.boxHeight = this.minBoxHeight; + 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 : XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.left.No ], allowedW ); - } else - if( attrs[ XUI_Attr_Support.right.No ] === null ){ + 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 : XUI_AbstractUINode_calcValue( attrs[ XUI_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 : XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.top.No ], allowedH ); - } else - if( attrs[ XUI_Attr_Support.bottom.No ] === null ){ + 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 : XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.bottom.No ], allowedH ) ); @@ -499,7 +515,6 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( */ mesure : function(){ var dirty = this.dirty, - //sup = X_UA[ 'Gecko' ] || ( X_UA[ 'Safari' ] && X_UA[ 'Windows' ] ) ? .01251 : 0, w, _w, h, xnode; if( dirty === XUI_Dirty.CLEAN ){ @@ -512,12 +527,12 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( case XUI_Dirty.CONTENT : // コンテンツが変更された case XUI_Dirty.FONT : // フォントサイズが変更された - delete this.lastContentWidth; - delete this.lastContentHeight; + delete this.contentWidthLast; + delete this.contentHeightLast; case XUI_Dirty.LAYOUT : // レイアウトの再計算が必要 - default : // TODO レイアウト崩れに対処 パフォーマンス悪い! + default : // TODO レイアウト指定が不正な場合 bgcolor を変更、これ以下のレイアウトの中止 w = this.contentWidth; h = this.contentHeight; @@ -546,13 +561,13 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( w = _w = XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'width', 'auto' )[ 'clientWidth' ]() / X_Node_CSS_getCharSize( xnode ) ); - if( this.maxContentWidth < w - this.boxSizingOffsetLR ){ + if( this.contentWidthMax < w - this.boxSizingOffsetLR ){ this.noWidth = false; - w = this.maxContentWidth + this.boxSizingOffsetLR; + w = this.contentWidthMax + this.boxSizingOffsetLR; }; - if( w - this.boxSizingOffsetLR < this.minContentWidth ){ + if( w - this.boxSizingOffsetLR < this.contentWidthMin ){ this.noWidth = false; - w = this.minContentWidth + this.boxSizingOffsetLR; + w = this.contentWidthMin + this.boxSizingOffsetLR; }; if( h === XUI_Attr_AUTO ){ @@ -561,42 +576,42 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( w !== _w && xnode[ 'css' ]( 'width', 'auto' ); }; - this.lastContentWidth = this.contentWidth = w; + this.contentWidthLast = this.contentWidth = w; } else if( h === XUI_Attr_AUTO ){ - if( w !== this.lastContentWidth ){ + if( w !== this.contentWidthLast ){ xnode[ 'css' ]( 'width', w + 'em' ); - this.lastContentWidth = w; + this.contentWidthLast = w; // ie8 clientHeight, ff scrollHeight & clientHeight h = XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ) ); } else { - h = this.lastContentHeight === -1 ? + h = this.contentHeightLast === -1 ? XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ) ) : - this.lastContentHeight; + this.contentHeightLast; }; } else if( dirty !== XUI_Dirty.LAYOUT ){ - this.contentWidth = this.lastContentWidth = w; + this.contentWidth = this.contentWidthLast = w; h = XUI_AbstractUINode_ceil( xnode[ 'css' ]( 'height', 'auto' )[ 'scrollHeight' ]() / X_Node_CSS_getCharSize( xnode ) ); }; - if( this.maxContentHeight < h - this.boxSizingOffsetTB ){ + if( this.contentHeightMax < h - this.boxSizingOffsetTB ){ this.noHeight = false; - h = this.maxContentHeight + this.boxSizingOffsetTB; + h = this.contentHeightMax + this.boxSizingOffsetTB; }; - if( h - this.boxSizingOffsetTB < this.minContentHeight ){ + if( h - this.boxSizingOffsetTB < this.contentHeightMin ){ this.noHeight = false; - h = this.minContentHeight + this.boxSizingOffsetTB; + h = this.contentHeightMin + this.boxSizingOffsetTB; }; - this.contentHeight = this.lastContentHeight = h; + this.contentHeight = this.contentHeightLast = h; } else { // コンテンツを持たないため基本のサイズは0 - if( w === XUI_Attr_AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; - if( h === XUI_Attr_AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; + 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; }; @@ -636,8 +651,8 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( if( !this.constraintW ){ contentW += contentPlus; - min = this.minBoxWidth = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minWidth.No ], contentW ); - max = this.maxBoxWidth = XUI_AbstractUINode_calcValue( attrs[ XUI_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 @@ -668,8 +683,8 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( }; if( !this.constraintH ){ contentH += contentPlus; - min = this.minBoxHeight = XUI_AbstractUINode_calcValue( attrs[ XUI_Attr_Support.minHeight.No ], contentH ); - max = this.maxBoxHeight = XUI_AbstractUINode_calcValue( attrs[ XUI_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 @@ -685,6 +700,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( }; }, + // TODO fontsize が変わることもある capcher : function( x, y ){ if( this.pointerDisabled ) return false; @@ -692,102 +708,27 @@ var XUI_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; }; }, - /* - * context を明示しない場合、User が context になる! - */ - listen : function( type, arg1, arg2, arg3 ){ - var root, events, counter, f; - if( XUI_Event._START_POINTER <= type && type <= XUI_Event._END_POINTER ){ - if( this.phase < 3 ){ - if( !( events = this.reserveEvents ) ) this.reserveEvents = events = []; - events[ events.length ] = [ type, arg1, arg2, arg3 ]; - return this; - }; - if( XUI_Event._START_XUI_EVENT < type && type < XUI_Event._END_XUI_EVENT ){ - if( !this.gesture ){ - this.gesture = new Hammer( 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' ]( XUI_Event.IdToName[ type ], X_UI_eventRellay ); - }; - }; - }; - arg1 && arg1.kind ? ( f = arg1 ) : ( f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 ) ); - if( !f.kind ){ - return X_EventDispatcher_listen.call( this, type, this.User, f ); - } else - if( f.kind === X_Callback_FUNC_ONLY ){ - return X_EventDispatcher_listen.call( this, type, this.User, f.func, f.supplement ); - }; - return X_EventDispatcher_listen.apply( this, arguments ); - }, - unlisten : function( type, arg1, arg2, arg3 ){ - var root, events, i, ev, counter, f; - if( XUI_Event._START_POINTER <= type && type <= XUI_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( XUI_Event._START_XUI_EVENT < type && type < XUI_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' ]( XUI_Event.IdToName[ type ], X_UI_eventRellay ); - delete counter[ type ]; - }; - }; - }; - arg1 && arg1.kind ? ( f = arg1 ) : ( f = X_Callback_classifyCallbackArgs( arg1, arg2, arg3 ) ); - if( !f.kind ){ - return X_EventDispatcher_unlisten.apply( this, [ type, this.User, f ] ); - } else - if( f.kind === X_Callback_FUNC_ONLY ){ - return X_EventDispatcher_unlisten.apply( this, [ type, this.User, f.func, f.supplement ] ); - }; - return X_EventDispatcher_unlisten.apply( this, arguments ); - }, + listen : XUI_$UINodeBase_listen, - dispatch : function( e ){ - //console.log( e.type + ' ' + ( this[ '_listeners' ] && this[ '_listeners' ][ e.type ] ) ); - var xve = XUI_Event, - ret = X_EventDispatcher_dispatch.call( this, e ), - type = e.type || e; - - // TODO captureEvent PointerEvent - if( ret & X_Callback_CAPTURE_POINTER && !this.hitChildData && XUI_Event._POINTER_MOVE === 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; + unlisten : XUI_$UINodeBase_unlisten, + + 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 ); } } @@ -795,7 +736,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( function XUI_AbstractUINode_createCssText( that, name ){ var attrs = that.attrObject || that.attrClass.prototype || XUI_AttrClass, - def = that.supportAttrs[ name ], + def = that.usableAttrs[ name ], no = def.No, v = attrs[ def.No ], type = def[ 3 ], @@ -853,13 +794,16 @@ function XUI_AbstractUINode_createCssValue( v, type, list ){ if( X_Type_isNumber( v ) ){ if( auto && v === XUI_Attr_AUTO ) return 'auto'; - if( length || minusLen ) return v + 'em'; + 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 ); }; @@ -920,16 +864,16 @@ X.UI.AbstractUINode = X_Class_create( 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 ); @@ -937,7 +881,7 @@ X.UI.AbstractUINode = X_Class_create( }; // getter if( attrs = ( p.attrObject || p.attrClass.prototype || XUI_AttrClass ) ){ - def = p.supportAttrs[ nameOrObject ]; + def = p.usableAttrs[ nameOrObject ]; return def && attrs[ def.No ]; }; return v; @@ -946,7 +890,15 @@ X.UI.AbstractUINode = X_Class_create( }, listen : function( type, arg1, arg2, arg3 ){ - X_Pair_get( 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 ){ @@ -957,7 +909,15 @@ X.UI.AbstractUINode = X_Class_create( return X_Pair_get( this )[ 'listening' ]( type, arg1, arg2, arg3 ); }, unlisten : function( type, arg1, arg2, arg3 ){ - X_Pair_get( 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 ){ @@ -1004,6 +964,79 @@ X.UI.AbstractUINode = X_Class_create( getHeight : function(){ // dirty の場合、rootData.calculate return X_Pair_get( this ).boxHeight; + }, + + /* + * 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; } } );