From: itozyun Date: Sun, 7 Jun 2015 12:37:38 +0000 (+0900) Subject: Version 0.6.157, add X.Net.Form & fix X.EventDispatcher. X-Git-Url: http://git.osdn.jp/view?p=pettanr%2FclientJs.git;a=commitdiff_plain;h=094b0536bafe5efd70540698cf74ab13ece03ebb Version 0.6.157, add X.Net.Form & fix X.EventDispatcher. --- diff --git a/0.6.x/js/01_core/04_XObject.js b/0.6.x/js/01_core/04_XObject.js index 6d9941a..c12c3bd 100644 --- a/0.6.x/js/01_core/04_XObject.js +++ b/0.6.x/js/01_core/04_XObject.js @@ -3,13 +3,12 @@ * 但し for( name in object ) については構文解析エラーになる環境はありません。 * @alias X.Object.inObject * @function - * @param {string} name + * @param {string|number} name * @param {object} obj * @return {boolean} name が定義されている(値が undefined や null でも) -> true */ var X_Object_inObject = X_UA[ 'IE' ] < 5.5 ? // TODO JScript で判定 - (function( name, obj ){ - var p; + (function( name, obj, p ){ if( obj[ name ] ) return true; // quick name += ''; // 数値も許可 for( p in obj ){ @@ -17,7 +16,7 @@ var X_Object_inObject = X_UA[ 'IE' ] < 5.5 ? // TODO JScript で判定 }; return false; }) : - new Function( 'a,b', 'return a in b' );// なぜか ie5 でもerror + new Function( 'a,b', 'return a in b' ); // ------------------------------------------------------------------------- // diff --git a/0.6.x/js/01_core/05_XString.js b/0.6.x/js/01_core/05_XString.js index b77d19f..c9a9b60 100644 --- a/0.6.x/js/01_core/05_XString.js +++ b/0.6.x/js/01_core/05_XString.js @@ -88,7 +88,7 @@ function X_String_whiteSpaceToTag( text ){ function X_String_chrReferanceTo( str ){ if( str == null ) return ''; return str.toString() - .split( '"' ).join( '"' ) + .split( '"' ).join( '"' ) // first! .split( '&' ).join( '&' ) .split( '<' ).join( '<' ) .split( '>' ).join( '>' ) @@ -97,9 +97,10 @@ function X_String_chrReferanceTo( str ){ function X_String_toChrReferance( str ){ if( str == null ) return ''; + str += ''; return str.toString() - .split( '"' ).join( '"' ) .split( '&' ).join( '&' ) + .split( '"' ).join( '"' ) .split( '<' ).join( '<' ) .split( '>' ).join( '>' ) .split( ' ' ).join( ' ' ); diff --git a/0.6.x/js/01_core/10_XCallback.js b/0.6.x/js/01_core/10_XCallback.js index e427160..9094791 100644 --- a/0.6.x/js/01_core/10_XCallback.js +++ b/0.6.x/js/01_core/10_XCallback.js @@ -18,6 +18,8 @@ var X_Callback_HANDLEEVENT = 2, /** @const */ X_Callback_FUNC_ONLY = 3, + /** @const */ + X_Callback_THIS_FUNCNAME = 4, /** @const */ X_Callback_NONE = 0, @@ -177,6 +179,7 @@ function X_Callback_create( thisObject, opt_callback, opt_args /* [ listener || _obj = ret( X_Closure_COMMAND_BACK ); _obj.kind = obj.kind; + _obj.name = obj.name; _obj.func = obj.func; _obj.context = obj.context; _obj.supplement = obj.supplement; @@ -193,12 +196,16 @@ function X_Callback_create( thisObject, opt_callback, opt_args /* [ listener || function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){ var obj; - if( arg1 && X_Type_isFunction( arg2 ) ){ + if( X_Type_isObject( arg1 ) && X_Type_isFunction( arg2 ) ){ obj = { context : arg1, func : arg2, kind : X_Callback_THIS_FUNC }; } else - if( arg1 && X_Type_isFunction( arg1[ 'handleEvent' ] ) ){ - obj = { context : arg1, kind : X_Callback_HANDLEEVENT }; - arg3 = arg2; + if( X_Type_isObject( arg1 ) ){ + if( arg2 && X_Type_isString( arg2 ) ){ + obj = { context : arg1, name : arg2, kind : X_Callback_THIS_FUNCNAME }; + } else { + obj = { context : arg1, kind : X_Callback_HANDLEEVENT }; + arg3 = arg2; + }; } else if( X_Type_isFunction( arg1 ) ){ arg3 = arg2; @@ -216,6 +223,10 @@ function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){ obj = { func : arg2, kind : X_Callback_FUNC_ONLY }; }; } else + if( alt_context && X_Type_isString( arg1 ) ){ + arg3 = arg2; + obj = { context : alt_context, name : arg1, kind : X_Callback_THIS_FUNCNAME }; + } else if( alt_context ){ obj = { context : alt_context, kind : X_Callback_HANDLEEVENT }; arg3 = arg1; @@ -243,7 +254,7 @@ function X_Callback_proxyCallback( xfunc, _args ){ thisObj = xfunc.context, func = xfunc.func, supp = xfunc.supplement, - temp, ret; + temp, ret, funcName; if( supp && supp.length ){ temp = []; @@ -263,9 +274,12 @@ function X_Callback_proxyCallback( xfunc, _args ){ case X_Callback_THIS_FUNC : return args.length === 0 ? func.call( thisObj ) : func.apply( thisObj, args ); - + + case X_Callback_THIS_FUNCNAME : + funcName = xfunc.name; case X_Callback_HANDLEEVENT : - temp = thisObj[ 'handleEvent' ]; + funcName = funcName || 'handleEvent'; + temp = thisObj[ funcName ]; if( X_Type_isFunction( temp ) ){ return args.length === 0 ? thisObj[ 'handleEvent' ]() : args.length === 1 ? thisObj[ 'handleEvent' ]( args[ 0 ] ) : temp.apply( thisObj, args ); @@ -298,6 +312,7 @@ function X_Callback_correct( f ){ X_Callback_POOL_LIST[ X_Callback_POOL_LIST.length ] = f; obj = f( X_Closure_COMMAND_BACK ); delete obj.kind; + if( obj.name ) delete obj.name; if( obj.func ) delete obj.func; if( obj.context ) delete obj.context; if( obj.supplement ) delete obj.supplement; diff --git a/0.6.x/js/01_core/16_XViewPort.js b/0.6.x/js/01_core/16_XViewPort.js index a55a12e..0cc12dd 100644 --- a/0.6.x/js/01_core/16_XViewPort.js +++ b/0.6.x/js/01_core/16_XViewPort.js @@ -311,7 +311,7 @@ X[ 'ViewPort' ] = { * @alias X.Doc.html * @type {Node} */ - X[ 'Doc' ][ 'html' ] = html = X_Node_html = elmHtml && new Node( elmHtml )[ 'removeClass' ]( 'js-disabled' )[ 'addClass' ]( X_UA_classNameForHTML ); + X[ 'Doc' ][ 'html' ] = html = X_Node_html = elmHtml && Node( elmHtml )[ 'removeClass' ]( 'js-disabled' )[ 'addClass' ]( X_UA_classNameForHTML ); html[ '_flags' ] |= X_NodeFlags_IN_TREE; /** @@ -319,14 +319,14 @@ X[ 'ViewPort' ] = { * @alias X.Doc.head * @type {Node} */ - X[ 'Doc' ][ 'head' ] = head = X_Node_head = elmHead && new Node( elmHead ); + X[ 'Doc' ][ 'head' ] = head = X_Node_head = elmHead && Node( elmHead ); /** * Node( documentElement ) * @alias X.Doc.body * @type {Node} */ - X[ 'Doc' ][ 'body' ] = body = X_Node_body = new Node( elmBody ); + X[ 'Doc' ][ 'body' ] = body = X_Node_body = Node( elmBody ); body[ 'parent ' ] = head[ 'parent' ] = html; html[ '_xnodes' ] = [ head, body ]; diff --git a/0.6.x/js/05_util/01_XNinjaIframe.js b/0.6.x/js/05_util/01_XNinjaIframe.js index 9e3e810..8507c5e 100644 --- a/0.6.x/js/05_util/01_XNinjaIframe.js +++ b/0.6.x/js/05_util/01_XNinjaIframe.js @@ -75,7 +75,11 @@ X[ 'Util' ][ 'NinjaIframe' ] = Node[ 'inherits' ]( if( !opt_contentHTML && opt_contentHTML !== '' ) return this; this._contentHTML = opt_contentHTML; - X_UA[ 'IE' ] < 9 || X_Util_NinjaIframe_writeToIframe( this ); + + if( !( X_UA[ 'IE' ] < 9 ) ){ + X_Util_NinjaIframe_writeToIframe( this ); + this._ready = true; + }; return this; }, @@ -138,7 +142,6 @@ function X_Util_NinjaIframe_writeToIframe( that ){ html = that._contentHTML; delete that._contentHTML; - that._ready = true; idoc.open(); idoc.writeln( html ); diff --git a/0.6.x/js/05_util/02_XJSON.js b/0.6.x/js/05_util/02_XJSON.js index e69de29..698927a 100644 --- a/0.6.x/js/05_util/02_XJSON.js +++ b/0.6.x/js/05_util/02_XJSON.js @@ -0,0 +1,17 @@ +var X_JSON = X[ 'JSON' ] = window.JSON || { + 'stringify' : X_JSON_stringify, + + 'parse' : X_String_parseTrustedJsonString +}; + +function X_JSON_stringify( obj ){ + var json = '', k, v; + for( k in obj ){ + if( json ) json += ','; + v = obj[ k ]; + v = v || v === 0 ? v : null; + json += '"' + k + '":' + ( X_Type_isObject( v ) ? X_NET_GIMR_toJSONString( v ) : X_Type_isString( v ) ? '"' + v + '"' : v ); + }; + //console.log( json ); + return '{' + json + '}'; +}; \ No newline at end of file diff --git a/0.6.x/js/06_net/00_XNet.js b/0.6.x/js/06_net/00_XNet.js index cc402b0..55f0496 100644 --- a/0.6.x/js/06_net/00_XNet.js +++ b/0.6.x/js/06_net/00_XNet.js @@ -60,6 +60,9 @@ * // JSONP * var net = X.Net( { jsonp : urlString, staticCallbackName : callbackName, useXDomainWall : false } ); * + * // Form + * var net = X.Net( { form : urlString, method : 'POST', target : '_self', params : {} } ); // _self, _parent, _top の場合、ページから離脱する + * * // Image preload & getSize * var net = X.Net( { image : src, sizeDetection : true } ); * @@ -77,23 +80,23 @@ X[ 'Net' ] = X_EventDispatcher[ 'inherits' ]( var v, opt, url, type, auth; if( X_Type_isObject( opt = urlOrObject ) ){ - if( v = opt[ 'xhr' ] ){ + if( X_Type_isString( v = opt[ 'xhr' ] ) ){ url = v; type = X_NET_TYPE_XHR; } else - if( v = opt[ 'jsonp' ] ){ + if( X_Type_isString( v = opt[ 'jsonp' ] ) ){ url = v; type = X_NET_TYPE_JSONP; } else - if( v = opt[ 'img' ] || opt[ 'image' ] ){ + if( X_Type_isString( v = opt[ 'img' ] || opt[ 'image' ] ) ){ url = v; type = X_NET_TYPE_IMAGE; } else - if( v = opt[ 'form' ] ){ + if( X_Type_isString( v = opt[ 'form' ] ) ){ url = v; type = X_NET_TYPE_FORM; } else - if( v = opt[ 'type' ] ){ + if( X_Type_isString( v = opt[ 'type' ] ) ){ switch( v ){ case 'xhr' : @@ -113,7 +116,7 @@ X[ 'Net' ] = X_EventDispatcher[ 'inherits' ]( alert( 'X.Net args error' ); return; }; - url = opt[ 'url' ]; + url = opt[ 'url' ]; }; if( !X_Type_isString( url ) ){ @@ -317,7 +320,7 @@ function X_NET_shiftQueue(){ X_NET_currentWrapper = X_NET_JSONPWrapper || X_TEMP.X_NET_JSONP_init(); break; case X_NET_TYPE_FORM : - X_NET_currentWrapper = X_NET_FormWrapper; + X_NET_currentWrapper = X_NET_FormWrapper || X_TEMP.X_NET_Form_init(); break; case X_NET_TYPE_IMAGE : X_NET_currentWrapper = X_NET_ImageWrapper || X_TEMP.X_NET_Image_init(); diff --git a/0.6.x/js/06_net/02_XNetJSONP.js b/0.6.x/js/06_net/02_XNetJSONP.js index 43732b4..7b1c4da 100644 --- a/0.6.x/js/06_net/02_XNetJSONP.js +++ b/0.6.x/js/06_net/02_XNetJSONP.js @@ -50,12 +50,15 @@ var X_NET_JSONP_ACCESS_KEY = Math.random(), X_Net_JSONP_errorTimerID; X_TEMP.X_NET_JSONP_init = function(){ + X_NET_JSONPWrapper = X_Class_override( X[ 'Util' ][ 'NinjaIframe' ](), X_TEMP.X_NET_JSONP_params ); delete X_TEMP.X_NET_JSONP_init; + delete X_TEMP.X_NET_JSONP_params; - return X_NET_JSONPWrapper = X_Class_override( - X[ 'Util' ][ 'NinjaIframe' ](), - { + return X_NET_JSONPWrapper; +}; + +X_TEMP.X_NET_JSONP_params = { _busy : false, _canceled : false, @@ -187,14 +190,12 @@ X_TEMP.X_NET_JSONP_init = function(){ reset : function(){ X_NET_JSONPWrapper._busy = X_NET_JSONPWrapper._canceled = false; - X_Net_JSONP_onloadCount = 0; X_NET_JSONPWrapper[ 'unlisten' ]( [ 'ninjaload', 'ninjaerror' ], X_NET_JSONP_iframeListener ); X_NET_JSONPWrapper[ 'refresh' ]( '' ); X_Net_JSONP_errorTimerID && X_Timer_remove( X_Net_JSONP_errorTimerID ); + X_Net_JSONP_errorTimerID = X_Net_JSONP_onloadCount = 0; } - } - ); -}; + }; function X_NET_JSONP_iframeListener( e ){ switch( e.type ){ diff --git a/0.6.x/js/06_net/03_XNetForm.js b/0.6.x/js/06_net/03_XNetForm.js new file mode 100644 index 0000000..1dec5db --- /dev/null +++ b/0.6.x/js/06_net/03_XNetForm.js @@ -0,0 +1,102 @@ +X[ 'Net' ][ 'Form' ] = { + // 隠し iframe 使用の可否 +}; + +var X_NET_Form_errorTimerID, X_Net_Form_onloadCount = 0; + +X_TEMP.X_NET_Form_init = function(){ + X_NET_FormWrapper = X_Class_override( X[ 'Util' ][ 'NinjaIframe' ](), X_TEMP.X_NET_Form_params ); + + delete X_TEMP.X_NET_Form_init; + delete X_TEMP.X_NET_Form_params; + + return X_NET_FormWrapper; +}; + +/* + * form 構築時に ">' ); + + X_NET_FormWrapper + [ 'refresh' ]( html.join( '' ) ) + [ 'listen' ]( [ 'ninjaload', 'ninjaerror' ], X_NET_Form_iframeListener ); + + X_NET_FormWrapper._busy = true; + }, + + cancel : function(){ + X_NET_FormWrapper.reset(); + X_NET_FormWrapper._canceled = true; + }, + + reset : function(){ + X_NET_FormWrapper._busy = X_NET_FormWrapper._canceled = false; + X_NET_FormWrapper[ 'unlisten' ]( [ 'ninjaload', 'ninjaerror' ], X_NET_Form_iframeListener ); + X_NET_FormWrapper[ 'refresh' ]( '' ); + X_NET_Form_errorTimerID && X_Timer_remove( X_NET_Form_errorTimerID ); + X_NET_Form_errorTimerID = X_Net_Form_onloadCount = 0; + } + }; + +function X_NET_Form_iframeListener( e ){ + var idoc; + + switch( e.type ){ + case 'ninjaload' : + if( this.isJump ){ + return; + }; + + if( ++X_Net_Form_onloadCount === 1 ){ + X_NET_Form_errorTimerID = X_NET_FormWrapper[ 'asyncDispatch' ]( this.timeout, X_EVENT_ERROR ); + + // TODO レスポンスの html にアクセスしたい場合 + // TODO samedomain or xiframe-sender + + idoc = this[ '_rawObject' ].contentDocument || this._iwin.document, + + X_NET_FormWrapper[ 'asyncDispatch' ]( { type : X_EVENT_SUCCESS, responce : idoc && idoc.body ? idoc.body.innerHTML : '' } ); + }; + break; + case 'ninjaerror' : + console.log( 'iframe onerror' ); + X_NET_FormWrapper[ 'asyncDispatch' ]( X_EVENT_ERROR ); + break; + }; + return X_Callback_UN_LISTEN; +}; diff --git a/0.6.x/js/06_net/05_XXHRGadget.js b/0.6.x/js/06_net/05_XXHRGadget.js index 905e098..1d294e0 100644 --- a/0.6.x/js/06_net/05_XXHRGadget.js +++ b/0.6.x/js/06_net/05_XXHRGadget.js @@ -245,4 +245,3 @@ X_TEMP.X_Net_GIMR_props = { } }; - diff --git a/0.6.x/js/06_net/10_XOAuth2.js b/0.6.x/js/06_net/10_XOAuth2.js index 2d5150f..ab34837 100644 --- a/0.6.x/js/06_net/10_XOAuth2.js +++ b/0.6.x/js/06_net/10_XOAuth2.js @@ -58,7 +58,7 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( obj.updateRequest = X_NET_OAUTH2_updateRequest; if( _getAccessToken( this ) && ( expires_at = _getAccessTokenExpiry( this ) ) ){ - if( expires_at < X_Timer_now() + 300000 ){ // 寿命が5分を切った + if( expires_at < X_Timer_now() + ( obj[ 'refreshMargin' ] || 300000 ) ){ // 寿命が5分を切った this[ 'refreshToken' ](); } else { obj.oauth2State = 4; @@ -68,8 +68,8 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( this[ 'asyncDispatch' ]( X_EVENT_NEED_AUTH ); }; - // TODO canUse - // TODO kill の cancel + // TODO canUse gadgetProxy + this[ 'listen' ]( [ X_EVENT_KILL_INSTANCE, X_EVENT_SUCCESS, X_EVENT_ERROR, X_EVENT_NEED_AUTH ], X_NET_OAUTH2_handleEvent ); }, /** @@ -137,6 +137,10 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( delete pair.net; }; + if( pair.oauth2State !== 1 ){ + return; + }; + // http://kojikoji75.hatenablog.com/entry/2013/12/15/223839 X_NET_OAUTH2_authorizationWindow && X_NET_OAUTH2_authorizationWindow.open( 'about:blank', '_self' ).close(); X_NET_OAUTH2_authorizationWindow = null; @@ -151,12 +155,15 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( * アクセストークンのリフレッシュ。 */ 'refreshToken' : function(){ - // TODO 自動リフレッシュ - var pair = X_Pair_get( this ); if( pair.net ) return; + if( pair.refreshTimerID ){ + X_Timer_remove( pair.refreshTimerID ); + delete pair.refreshTimerID; + }; + pair.oauth2State = 3; pair.net = X.Net( { @@ -180,6 +187,27 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( } ); +function X_NET_OAUTH2_handleEvent( e ){ + var pair = X_Pair_get( this ); + + switch( e.type ){ + case X_EVENT_KILL_INSTANCE : + this[ 'cancelAuth' ](); + + case X_EVENT_ERROR : + case X_EVENT_NEED_AUTH : + pair.refreshTimerID && X_Timer_remove( pair.refreshTimerID ); + break; + + case X_EVENT_SUCCESS : + pair.refreshTimerID && X_Timer_remove( pair.refreshTimerID ); + if( _getRefreshToken( this ) ){ + // 自動リフレッシュ + pair.refreshTimerID = X_Timer_once( _getAccessTokenExpiry( this ) - X_Timer_now() - pair[ 'refreshMargin' ], this, this[ 'refreshToken' ] ); + }; + }; +}; + function X_Net_OAuth2_detectAuthPopup(){ var closed, search, pair = X_Pair_get( this ); diff --git a/0.6.x/js/07_audio/00_XAudio.js b/0.6.x/js/07_audio/00_XAudio.js index 1e6d9e5..017f79e 100644 --- a/0.6.x/js/07_audio/00_XAudio.js +++ b/0.6.x/js/07_audio/00_XAudio.js @@ -163,6 +163,9 @@ X[ 'Audio' ] = X_EventDispatcher[ 'inherits' ]( } ); +// TODO +X[ 'Audio' ][ 'canPlay' ] = {}; + function X_Audio_handleEvent( e ){ var backend; diff --git a/0.6.x/js/20_ui/02_XUI_Attr.js b/0.6.x/js/20_ui/02_XUI_Attr.js index 5a0bd47..2e865f3 100644 --- a/0.6.x/js/20_ui/02_XUI_Attr.js +++ b/0.6.x/js/20_ui/02_XUI_Attr.js @@ -46,7 +46,7 @@ var XUI_Attr_AUTO = 1/0,//Number.POSITIVE_INFINITY, textShadowAlpha : true }, XUI_Attr_Rename = { - bgColor : 'background-color', + bgColor : 'backgroundColor', fontColor : 'color', fontBold : 'fontWeight', fontItalic : 'fontStyle', @@ -62,12 +62,12 @@ var XUI_Attr_AUTO = 1/0,//Number.POSITIVE_INFINITY, */ XUI_Attr_Support = XUI_Attr_createAttrDef( 0, { - className : [ null, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.DEFAULT_ONLY | XUI_Attr_Type.STRING ], - pointerHoverClass : [ null, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.DEFAULT_ONLY | XUI_Attr_Type.STRING ], + className : [ '', XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.DEFAULT_ONLY | XUI_Attr_Type.STRING ], + pointerHoverClass : [ '', XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.DEFAULT_ONLY | XUI_Attr_Type.STRING ], pointerDownClass : [ null, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.DEFAULT_ONLY | XUI_Attr_Type.STRING ], invalidLayoutColor: [ null, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.DEFAULT_ONLY | XUI_Attr_Type.COLOR ], - dataFeild : [ null, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.DEFAULT_ONLY | XUI_Attr_Type.STRING ], + dataFeild : [ '', XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.INIT_ONLY | XUI_Attr_Type.STRING ], role : [ 1, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.INIT_ONLY | XUI_Attr_Type.LIST, 'none,chrome' ], selectable : [ false, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.INIT_ONLY | XUI_Attr_Type.BOOLEAN ], @@ -76,17 +76,17 @@ var XUI_Attr_AUTO = 1/0,//Number.POSITIVE_INFINITY, pointerEnabled : [ false, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], pointerChildren : [ true, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], cursor : [ 1, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.LIST, XUI_Attr_Option.CURSOR ], - tooltip : [ null, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.STRING ], + tooltip : [ '', XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.STRING ], borderWidth : [ 0, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.QUARTET | XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ], // em [ top, right, bottom, left ] padding : [ 0, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.QUARTET | XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ], - width : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], + width : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], minWidth : [ 0, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ], - maxWidth : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], - height : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], + maxWidth : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], + height : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], minHeight : [ 0, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ], - maxHeight : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], + maxHeight : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.AUTO ], sizing : [ 1, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LIST, XUI_Attr_Option.BOX_SIZING ], left : [ null, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.MINUS_LENGTH | XUI_Attr_Type.MINUS_PERCENT ], top : [ null, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT | XUI_Attr_Type.MINUS_LENGTH | XUI_Attr_Type.MINUS_PERCENT ], diff --git a/0.6.x/js/20_ui/04_XUI_Event.js b/0.6.x/js/20_ui/04_XUI_Event.js index 97ddb1f..bea9f04 100644 --- a/0.6.x/js/20_ui/04_XUI_Event.js +++ b/0.6.x/js/20_ui/04_XUI_Event.js @@ -111,9 +111,11 @@ var XUI_Event = X[ 'UI' ][ 'Event' ] = { PAGE_AFTER_HIDE : ++X_Event_last, // X.UI.Form - CHANGE : ++X_Event_last, - SUBMIT : ++X_Event_last, - SELECT : ++X_Event_last, // click or tap or enterkey + CHANGE : ++X_Event_last, + SUBMIT : ++X_Event_last, + SELECT : ++X_Event_last, // click or tap or enterkey + + ITEMDATA_CHANGED : ++X_Event_last, IdToName : {}, NameToID : {} diff --git a/0.6.x/js/20_ui/06_AbstractUINode.js b/0.6.x/js/20_ui/06_AbstractUINode.js index 4ca1595..87cea63 100644 --- a/0.6.x/js/20_ui/06_AbstractUINode.js +++ b/0.6.x/js/20_ui/06_AbstractUINode.js @@ -3,6 +3,8 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( 'X.UI._AbstractUINode', X_Class.ABSTRACT, { + itemData : null, + phase : 0, dirty : XUI_Dirty.CLEAN, @@ -77,8 +79,21 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( }, addToParent : function( xnodeParent ){ + var attr = this.attrObject || this.attrClass.prototype, + usableAttrs = this.usableAttrs, + i = 0, l = usableAttrs.length, def; + 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[ k ] !== def[ 0 ] ){ + this.xnode[ 'css' ]( XUI_Attr_Rename[ k ] || k, XUI_AbstractUINode_createCssText( this, k ) ); + }; + }; + }; + this.phase = 2; this[ 'dispatch' ]( XUI_Event.ADDED ); }, @@ -91,6 +106,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 ] ); @@ -229,6 +245,7 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( if( !v && v !== 0 ) v = defaultVal; + // UIAttrClass の初期設定の場合、ここで終わる if( XUI_attrClassProto ){ attrs[ propID ] = v; return; @@ -786,8 +803,15 @@ var XUI_AbstractUINode = X_EventDispatcher[ 'inherits' ]( return ret; }, - setItemData : function(){ - // this[ 'dispatch' ]( UI_Event.ITEMDATA_CHANGED ); + 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 ); } @@ -926,11 +950,11 @@ X.UI.AbstractUINode = X_Class_create( }; }; } 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 ); @@ -1011,11 +1035,21 @@ X.UI.AbstractUINode = X_Class_create( * Repeater に於いて、繰り返されるアイテムの元(itemRenderer)からの複製に使用 */ clone : function( opt_cloneListener ){ - var newNode = this.constructor(), - newPair = X_Pair_get( newNode ), + var newNode, + //newPair = X_Pair_get( newNode ), pair = X_Pair_get( this ), attr, listeners, type, list, i, l; + // 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 ]; @@ -1023,17 +1057,14 @@ X.UI.AbstractUINode = X_Class_create( // User.UINODE な値は pair にコピーされているのでこれをコピー for( k in pair ){ - if( pair[ k ] !== newPair[ k ] && !newPair[ k ] ) newPair[ k ] = pair[ k ]; + //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 ); + //}; }; - // attr もコピー - if( pair.attrObject ){ - attr = pair.attrClass(); - for( k in pair.attrObject ){ - if( pair.attrObject[ k ] !== attr[ k ] ) attr[ k ] = pair.attrObject[ k ]; - }; - newPair.attrObject = attr; - }; + // listener もコピーする! if( opt_cloneListener && ( listeners = pair[ '_listeners' ] ) ){ @@ -1070,6 +1101,12 @@ X.UI.AbstractUINode = X_Class_create( }; }; }; + } 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; diff --git a/0.6.x/js/20_ui/08_Box.js b/0.6.x/js/20_ui/08_Box.js index 3fb51e4..a030267 100644 --- a/0.6.x/js/20_ui/08_Box.js +++ b/0.6.x/js/20_ui/08_Box.js @@ -124,10 +124,6 @@ var XUI_Box = XUI_AbstractUINode.inherits( initialize : function( root, rootData, parent, parentData ){ var uinodes = this.uinodes, i = uinodes && uinodes.length; - this.root = root; - this.rootData = rootData; - this.parent = parent; - this.parentData = parentData; if( i ){ for( ; i; ){ @@ -135,8 +131,7 @@ var XUI_Box = XUI_AbstractUINode.inherits( }; }; - this.phase = 1; - this.User[ 'dispatch' ]( { type : XUI_Event.INIT } ); + XUI_AbstractUINode.prototype.initialize.apply( this, arguments ); }, addToParent : function( parentXNode ){ @@ -144,16 +139,13 @@ var XUI_Box = XUI_AbstractUINode.inherits( l = uinodes && uinodes.length, i; - parentXNode && parentXNode[ 'append' ]( this.xnode ); - if( l ){ for( i = 0; i < l; ++i ){ uinodes[ i ].addToParent( this.xnode ); }; }; - this.phase = 2; - this.User[ 'dispatch' ]( { type : XUI_Event.ADDED } ); + XUI_AbstractUINode.prototype.addToParent.apply( this, arguments ); }, /* Rellay */ @@ -216,7 +208,7 @@ var XUI_Box = XUI_AbstractUINode.inherits( addAt : function( index, _uinodes ){ //console.log( '# AddAt ' + this.phase ) - var uinodes = this.uinodes, + var uinodes = this.uinodes || ( this.uinodes = [] ), num = uinodes.length, p1 = 1 <= this.phase, p2 = 2 <= this.phase, diff --git a/0.6.x/js/20_ui/15_ScrollBox.js b/0.6.x/js/20_ui/15_ScrollBox.js index 47915ff..170dfe4 100644 --- a/0.6.x/js/20_ui/15_ScrollBox.js +++ b/0.6.x/js/20_ui/15_ScrollBox.js @@ -40,7 +40,6 @@ var XUI_ScrollBox = XUI_ChromeBox.inherits( directionLocked : '', startTime : 0, endTime : 0, - isAnimating : false, isInTransition : false, hasHScroll : false, @@ -244,9 +243,10 @@ function X_UI_ScrollBox_onStart( e ){ this.startTime = X_Timer_now(); // スクロール中の停止 - if( this.isInTransition || this.isAnimating ){ - this.isInTransition = this.isAnimating = false; + if( this.isInTransition ){ + this.isInTransition = false; this[ 'dispatch' ]( XUI_Event.SCROLL_END ); + // TODO current位置 this.xnodeSlider.stop(); }; @@ -272,7 +272,7 @@ function X_UI_ScrollBox_onMove( e ){ absDistX, absDistY; // 規定以上の move でスクロール開始 -console.log( 'scrollmove ' + e.buttons + ' ' + e.button ); +//console.log( 'scrollmove ' + e.buttons + ' ' + e.button ); if( !this.scrollEnabled || e.pointerType !== this.initiated ){ return ret; @@ -463,8 +463,8 @@ function X_UI_ScrollBox_resetPosition( that, time ){ return false; }; - //console.log( 'バウンド!' ); - //console.log( 'rese x:' + x + ' y:' + y ); + console.log( ' ===> resetPosition - バウンド!' ); + console.log( ' x:' + x + ' y:' + y ); that.scrollTo( x, y, time, that.bounceEasing, 1000 ); return true; @@ -509,7 +509,6 @@ function X_UI_ScrollBox_momentum( current, start, time, lowerMargin, wrapperSize }; }; -// TODO Box の継承に! X.UI.ScrollBox = X.UI.ChromeBox.inherits( 'ScrollBox', X_Class.NONE, @@ -520,7 +519,7 @@ X.UI.ScrollBox = X.UI.ChromeBox.inherits( if( XUI_ScrollBox.prototype.usableAttrs === XUI_ChromeBox.prototype.usableAttrs ){ XUI_ScrollBox.prototype.usableAttrs = supports = XUI_Attr_createAttrDef( XUI_Attr_Support, X_UI_ScrollBox_SUPPORT_ATTRS ); - XUI_ScrollBox.prototype.attrClass = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports, { width : '100%', height : '100%', bgColor : 0x111111 } ); + XUI_ScrollBox.prototype.attrClass = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports, { width : '100%', height : '100%', bgColor : 0x111111 } ); }; var args = [ @@ -580,4 +579,5 @@ X.UI.ScrollBox = X.UI.ChromeBox.inherits( } } -); \ No newline at end of file +); + diff --git a/0.6.x/js/20_ui/16_Repeater.js b/0.6.x/js/20_ui/16_Repeater.js index 3f980f8..e709360 100644 --- a/0.6.x/js/20_ui/16_Repeater.js +++ b/0.6.x/js/20_ui/16_Repeater.js @@ -13,16 +13,28 @@ var XUI_Repeater = XUI_Box.inherits( itemRenderer : null, + itemNodes : null, startIndex : 0, startRenderIndex : 0, numItemsParPage : 0, + numItemsPrev : 0, numItems : 0, + itemHeightLast : 0, + itemHeightLastEM : 0, Constructor : function( user, dataSource, itemRenderer, attr ){ this.Super( user, null, [ attr ] ); this.dataSource = dataSource; this.itemRenderer = itemRenderer; + this.itemNodes = []; + this.__item__ = X_Pair_get( itemRenderer ); + }, + + initialize : function(){ + XUI_AbstractUINode.prototype.initialize.apply( this, arguments ); + + this.parent[ 'listen' ]( XUI_Event.SCROLL_END, this ); }, /* @@ -55,56 +67,77 @@ var XUI_Repeater = XUI_Box.inherits( }, handleEvent : function( e ){ - var scrollBox, scrollY, dataSource, offsetY, startIndex, maxIndex, offset, uinodes; + var scrollBox, scrollY, dataSource, offsetY, startIndex, maxIndex, offset, itemNodes, ary, i, l; switch( e.type ){ case XUI_Event.SCROLL_END : scrollBox = this.parentData; - scrollY = scrollBox.scrollY; + scrollY = - scrollBox.scrollY; dataSource = this[ 'dataSource' ]; - uinodes = this.uinodes; + itemNodes = this.itemNodes; + itemH = this.itemHeightLast; + // transition Y を 0 付近に。 - offsetY = scrollY % this.itemHeightLast; - scrollBox.scrollTo( 0, offsetY, 0, '', 0 ); // anime無し + + // startIndex の計算 - startIndex = scrollY / this.itemHeightLast | 0; - maxIndex = dataSource.length <= this.numItems ? 0 : dataSource.length - this.numItems; + startIndex = scrollY / itemH | 0; + + /*maxIndex = dataSource.length <= this.numItems ? 0 : dataSource.length - this.numItems; + console.log( ' >>> ' + startIndex + ' ' + maxIndex ); + startIndex = startIndex < 0 ? 0 : - maxIndex < startIndex ? maxIndex : startIndex; + maxIndex < startIndex ? maxIndex : startIndex; */ // アイテムの座標の修正とレンジ外のアイテムを配列内で再配置 offset = startIndex - this.startIndex; // visible な stratIndex renderStartIndex + this.startIndex = startIndex; + + console.log( this.numItemsPrev + ' oo ' + offset ) if( 0 < offset ){ - this.addAt( last, uinodes.splice( 0, offset ) ); + itemNodes.push.apply( itemNodes, itemNodes.splice( 0, offset ) ); } else - if( offset < 0 ){ - this.addAt( 0, uinodes.splice( uinodes.length - offset ) ); + if( offset < - 0 ){ + itemNodes.unshift.apply( itemNodes, itemNodes.splice( itemNodes.length + offset ) ); }; + // 再配置されたアイテムにitemData のセット this.updateItemRenderer( this.contentWidth, this.scrollPortHeight ); + + + + offsetY = scrollY % itemH; + offsetY = offsetY === 0 ? 0 : ( offsetY - itemH ); + offsetY += ( this.startRenderIndex - this.startIndex ) * itemH; + //console.log( ' ====> ' + this.startRenderIndex + ' -> ' + this.startIndex + ' scrollY:' + offsetY ); + + //scrollBox.scrollTo( 0, - scrollY, 0, '', 0 ); // anime無し + //console.log( ' <==== ' ); break; }; }, updateItemRenderer : function( _w, _h ){ - var uinodes = this.uinodes || ( this.uinodes = [] ), + var itemNodes = this.itemNodes, attrs = this.attrObject || this.attrClass.prototype, gapY = XUI_AbstractUINode_calcValue( attrs[ this.usableAttrs.gapY.No ], _w ), dataSource = this[ 'dataSource' ], render = this[ 'itemRenderer' ], l = dataSource.length, - start = this.startIndex - ( this.numItems - this.numItemsParPage ) / 2 | 0, - itemH = this.itemHeightLast, - i, node, data, _y = 0, last, n; + start = this.startIndex - this.numItemsPrev, + itemH = this.itemHeightLastEM, + i, data, node, _y = 0, last, n; + + i = this.startRenderIndex = start = start < 0 ? 0 : start; - i = start = start < 0 ? 0 : start; + _y = ( itemH + gapY ) * i; for( ; i < l; ++i ){ - if( !( node = uinodes[ i ] ) ){ + if( !( data = itemNodes[ i ] ) ){ node = render.clone( true ); this.addAt( i, [ node ] ); - data = X_Pair_get( node ); + data = itemNodes[ i ] = X_Pair_get( node ); // init -> addToParent -> creationComplete }; data.setItemData( dataSource[ i ] ); @@ -115,40 +148,42 @@ var XUI_Repeater = XUI_Box.inherits( // 一番最初のループ。ここでページあたりのアイテム数を計算 if( !itemH && i === start ){ itemH = _y - gapY; - this.itemHeightLast = itemH * X_ViewPort_baseFontSize, + this.itemHeightLastEM = itemH; + this.itemHeightLast = itemH * X_ViewPort_baseFontSize, // scroller の miniHeight は(例えば)親の高さの300% そこにいくつのアイテムを並べることが出来るか?端数切り上げ this.numItemsParPage = _h / itemH + 0.999 | 0; n = this.numItems = ( _h * 3 ) / itemH + 0.999 | 0; // TODO boxHeight + this.numItemsPrev = ( this.numItems - this.numItemsParPage ) / 2 | 0; last = i + n; // データの最後まで、または、開始位置から 3ページ分を生成する l = last < l ? last : l; }; }; - for( l = uinodes.length; i < l; ++i ){ - // uinodes[ i ] hide + for( l = itemNodes.length; i < l; ++i ){ + // itemNodes[ i ] hide }; // TODO contentHeight は attr を無視する -> 未表示領域につくるアイテム数 GPU の有無で変わる - this.contentHeight = _y - gapY; + this.contentHeight = dataSource.length * ( itemH + gapY ) - gapY; }, onPropertyChange : function( name, newValue ){ - var uinodes, i, l, uinode, dataList, from; + var itemNodes, i, l, uinode, dataList, from; switch( name ){ case 'itemRenderer' : - for( uinodes = this.uinodes, i = uinodes && uinodes.length; i; ){ - uinodes[ --i ][ 'kill' ](); + for( itemNodes = this.itemNodes, i = itemNodes && itemNodes.length; i; ){ + itemNodes[ --i ][ 'kill' ](); }; case 'dataSource' : - if( uinodes = this.uinodes ){ - i = uinodes.length; + if( itemNodes = this.itemNodes ){ + i = itemNodes.length; l = this[ 'dataSource' ].length; while( l < i ){ - uinodes[ --i ][ 'kill' ](); - uinodes.length = i; + itemNodes[ --i ][ 'kill' ](); + itemNodes.length = i; }; }; @@ -167,7 +202,8 @@ X.UI.Repeater = X.UI.Box.inherits( var supports; if( XUI_Repeater.prototype.usableAttrs === XUI_Box.prototype.usableAttrs ){ - XUI_Repeater.prototype.usableAttrs = supports = XUI_Attr_createAttrDef( XUI_Attr_Support, XUI_Layout_Vertical.overrideAttrsForSelf ); + supports = XUI_Attr_createAttrDef( XUI_Attr_Support, X_UI_Repeater_SUPPORT_ATTRS ); + XUI_Repeater.prototype.usableAttrs = supports = XUI_Attr_createAttrDef( supports, XUI_Layout_Vertical.overrideAttrsForSelf ); XUI_Repeater.prototype.attrClass = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports ); }; @@ -185,7 +221,13 @@ X.UI.Repeater = X.UI.Box.inherits( width : 'auto', minWidth : '100%', height : 'auto', - minHeight : '100%' + minHeight : '100%', + borderColor : 0x252527, + borderWidth : [ 0.15, 0, 0 ], + borderStyle : 'solid', + height : 'auto', + bgColor : 0x444643, + gapY : 0.15 })); }, diff --git a/0.6.x/js/20_ui/17_List.js b/0.6.x/js/20_ui/17_List.js index 5112b46..76f87f9 100644 --- a/0.6.x/js/20_ui/17_List.js +++ b/0.6.x/js/20_ui/17_List.js @@ -9,9 +9,10 @@ X.UI.List = X.UI.ScrollBox.inherits( { borderColor : 0x252527, borderWidth : [ 0.15, 0, 0 ], + borderStyle : 'solid', height : 'auto', bgColor : 0x444643, - gapY : 0.1, + gapY : 0.15, scrollSlider : X.UI.Repeater.apply( 0, [ dataSource, itemRenderer ] ) } ); diff --git a/0.6.x/js/20_ui/17_Text.js b/0.6.x/js/20_ui/17_Text.js index 34820f1..5dacb25 100644 --- a/0.6.x/js/20_ui/17_Text.js +++ b/0.6.x/js/20_ui/17_Text.js @@ -1,9 +1,15 @@ +var X_UI_Text_SUPPORT_ATTRS = { + content : [ '', XUI_Dirty.CONTENT, XUI_Attr_USER.UINODE, XUI_Attr_Type.STRING ] +}; + var XUI_Text = XUI_AbstractUINode.inherits( '_Text', X_Class.NONE, { content : '', + usableAttrs : XUI_Attr_createAttrDef( XUI_AbstractUINode.prototype.usableAttrs, X_UI_Text_SUPPORT_ATTRS ), + Constructor : function( user, content ){ if( !( user[ 'instanceOf' ]( X.UI.Text ) ) ){ alert( 'Text を継承したインスタンスだけが _Text のオーナーになれます' ); @@ -23,6 +29,16 @@ var XUI_Text = XUI_AbstractUINode.inherits( }; XUI_AbstractUINode.prototype.creationComplete.apply( this, arguments ); + }, + + setItemData : function( itemData ){ + if( this.itemData === itemData ) return; + + XUI_AbstractUINode.prototype.setItemData.apply( this, arguments ); + + if( X_Type_isObject( itemData = this.itemData ) && this.dataFeild ){ + this.User.content( itemData[ this.dataFeild ] || '' ); + }; } } );