X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F01_core%2F13_XClass.js;h=61749575a131da3789531ec0a6c1a18be8f91f72;hb=604668ba9efa027d4bc77fd8020d6b6be55d03e1;hp=343f862223ec2088aaea1171ad3d71c1a42a72a8;hpb=f74335422a0ae2d66e3ce9bfa03f0c77a107e8d1;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/01_core/13_XClass.js b/0.6.x/js/01_core/13_XClass.js index 343f862..6174957 100644 --- a/0.6.x/js/01_core/13_XClass.js +++ b/0.6.x/js/01_core/13_XClass.js @@ -15,7 +15,7 @@ var * クラス名 * @type {string} */ - name : '' + NAME : '' }, X_Class_CLASS_LIST = [], @@ -25,7 +25,10 @@ var X_Class_traits = null, X_Class_useObjectCreate = false, // !!Object.create, http://jsperf.com/prototype-vs-object-create-perf // Opera Mobile 12.10 Android11 IS01 でクラスのメンバが欠落する問題に遭遇。__proto__ を辞めると動作,,, - X_Class_use_proto_ = !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] && !!X_emptyFunction.prototype.__proto__, + X_Class_use_proto_ = !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] && + // Android で原因不明のエラーに遭遇しているのは、この辺りが怪しい... 2016.3.9 + !X_UA[ 'AOSP' ] && !X_UA[ 'ChromeWV' ] && + !!X_emptyFunction.prototype.__proto__, X_Class_constructorFix = X_UA[ 'AOSP' ] < 3 || X_UA[ 'iOS' ] < 5, X_Class_SEAL_KILLING = [], @@ -36,14 +39,14 @@ X_Class_CommonMethods = * 全ての動的メンバを削除して、インスタンスを破棄する。
* インスタンスが X.EventDispatcher とそのサブクラスの場合、次の動作をする。 *
    - *
  1. X.Event.BEFORE_KILL_INSTANCE を発火する。戻り値のビットフラグに X_Callback.PREVENT_DEFAULT が立つ場合、破棄をキャンセルし X.Event.KILL_INSTANCE_CANCELED を発火する。この間に kill() が呼ばれても無視される。 + *
  2. X.Event.BEFORE_KILL_INSTANCE を発火する。戻り値のビットフラグに X.Callback.PREVENT_DEFAULT が立つ場合、破棄をキャンセルし X.Event.KILL_INSTANCE_CANCELED を発火する。この間に kill() が呼ばれても無視される。 *
  3. 破棄に進む場合は、X.Event.KILL_INSTANCE を発火する。 *
  4. dispatch 中は、インスタンスの全ての dispatch が終了するまで実際の破棄を待つ。 *
  5. 実際の破棄では、インスタンスのメンバの削除に加えて全てのイベントリスナを解除する。 */ // TODO kill したインスタンスのイベントが残っていないか?これは開発用のみ 'kill' : function(){ - var listeners, flag, p, timers, def; + var listeners, flag, p, i, list, timers, def; // TODO 破棄済のインスタンスへの kill @@ -57,7 +60,7 @@ X_Class_CommonMethods = // listeners がない場合、イベントの登録がないため、BEFORE_KILL_INSTANCE は呼ばれない。 // KILL_RESERVED == true の場合、BEFORE_KILL_INSTANCE は呼ばれない。 if( listeners && !listeners[ X_LISTENERS_KILL_RESERVED ] && listeners[ X_EVENT_BEFORE_KILL_INSTANCE ] ){ - X_Class_SEAL_KILLING[ X_Class_SEAL_KILLING.length ] = this; + X_Class_SEAL_KILLING[ i = X_Class_SEAL_KILLING.length ] = this; if( this[ 'dispatch' ]( X_EVENT_BEFORE_KILL_INSTANCE ) & X_CALLBACK_PREVENT_DEFAULT ){ this[ 'dispatch' ]( X_EVENT_KILL_INSTANCE_CANCELED ); @@ -67,7 +70,7 @@ X_Class_CommonMethods = X_Class_SEAL_KILLING.length === 1 ? ( X_Class_SEAL_KILLING.length = 0 ) : - X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING.indexOf( this ), 1 ); + X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING[ i ] === this ? i : X_Class_SEAL_KILLING.indexOf( this ), 1 ); if( flag ) return; }; @@ -79,17 +82,26 @@ X_Class_CommonMethods = }; if( listeners[ X_EVENT_KILL_INSTANCE ] ){ - X_Class_SEAL_KILLING[ X_Class_SEAL_KILLING.length ] = this; + X_Class_SEAL_KILLING[ i = X_Class_SEAL_KILLING.length ] = this; listeners[ X_LISTENERS_KILL_RESERVED ] = false; this[ 'dispatch' ]( X_EVENT_KILL_INSTANCE ); X_Class_SEAL_KILLING.length === 1 ? ( X_Class_SEAL_KILLING.length = 0 ) : - X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING.indexOf( this ), 1 ); + X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING[ i ] === this ? i : X_Class_SEAL_KILLING.indexOf( this ), 1 ); + }; + + if( !( listeners = this[ '_listeners' ] ) ){ + for( p in listeners ){ + //if( X_EMPTY_OBJECT[ opt_type ] ) continue; + if( p <= X_LISTENERS_KILL_RESERVED ) continue; + list = listeners[ p ]; + for( i = list.length; i; ){ + this[ 'unlisten' ]( p, list[ --i ] ); + }; + }; }; - - X_EventDispatcher_unlistenAll( this ); }; if( this[ 'instanceOf' ]( Node ) ){ @@ -159,7 +171,12 @@ X_Class_CommonMethods = }; }; - if( X_Class_SUPER_STACKS[ i ] === stack ) console.log( 'スーパークラス、またはスーパークラスのコンストラクタは存在しません' ); + // index が替わっている可能性があるので取り直し + if( X_Class_SUPER_CALLER[ i ] !== me ) i = X_Class_SUPER_CALLER.indexOf( me ); + + if( X_Class_SUPER_STACKS[ i ] === stack ){ + //console.log( 'スーパークラス、またはスーパークラスのコンストラクタは存在しません' ); + }; if( stack === 0 ){ X_Class_SUPER_CALLER.splice( i, 1 ); @@ -200,7 +217,7 @@ X_Class_CommonMethods = proto = sClass.prototype, i = X_Class_SUPER_CALLER.indexOf( me ), args = arguments, - p, name, t, sFunc, ret; + p, name, stack, t, sFunc, ret; if( X_Type_isFunction( myFunc ) ){ for( p in proto ){ @@ -238,21 +255,20 @@ X_Class_CommonMethods = sFunc = sClass.prototype[ name ]; if( sFunc !== myFunc /* X_Object_own( name, sClass.prototype ) */ ){ - // this の関数と異なり、値が設定されていたら、今は手を抜いて undef か?見ている、正しくは hasOwnProperty if( X_Type_isFunction( sFunc ) ){ X_Class_SUPER_STACKS[ i ] += t; switch( args.length ){ - case 0 : - ret = sFunc.call( me ); - break; case 1 : - ret = sFunc.call( me, args[ 0 ] ); + ret = sFunc.call( me ); break; case 2 : - ret = sFunc.call( me, args[ 0 ], args[ 1 ] ); + ret = sFunc.call( me, args[ 1 ] ); break; case 3 : - ret = sFunc.call( me, args[ 0 ], args[ 1 ], args[ 2 ] ); + ret = sFunc.call( me, args[ 1 ], args[ 2 ] ); + break; + case 4 : + ret = sFunc.call( me, args[ 1 ], args[ 2 ], args[ 3 ] ); break; default : args = X_Array_copy( args ); @@ -266,6 +282,9 @@ X_Class_CommonMethods = }; }; + // index が替わっている可能性があるので取り直し + if( X_Class_SUPER_CALLER[ i ] !== me ) i = X_Class_SUPER_CALLER.indexOf( me ); + if( stack === 0 ){ X_Class_SUPER_CALLER.splice( i, 1 ); X_Class_SUPER_STACKS.splice( i, 1 ); @@ -285,6 +304,7 @@ X_Class_CommonMethods = // TODO instanceof に対応したブラウザはそちらを使用 'instanceOf' : function( klass ){ var Super = this; + if( this.constructor === klass ) return true; while( Super = X_Class_getClassDef( Super ).SuperClass ){ if( Super === klass ) return true; @@ -337,6 +357,7 @@ X[ 'Class' ] = /** @lends X.Class */ { */ 'NONE' : X_Class.NONE, + // TODO この指定、フレームワーク内だけ! /** * インスタンスは破棄時(this.kill())に回収され、次回の new MyClass() 時に再利用されます。 * @const @@ -464,7 +485,7 @@ X[ 'Class' ] = /** @lends X.Class */ { klass.prototype.constructor = klass; }; - klass[ 'name' ] = displayName; + klass[ 'NAME' ] = displayName; if( opt_abstract ){ classDef.isAbstract = true; @@ -647,7 +668,7 @@ function X_Class_actualConstructor( f, args ){ obj = def.Constructor ? def.Constructor.apply( instance, args ) : - instance[ 'Super' ].apply( instance, args ); + def.SuperClass && instance[ 'Super' ].apply( instance, args ); if( obj !== instance && ( X_Type_isObject( obj ) || X_Type_isFunction( obj ) ) ){ // Class instance[ 'kill' ]();