10 _dispatching : 0, // dispatch 中の unlisten で使用
\r
11 _unlistens : null, // dispatch 中の unlisten で使用
\r
12 _needsIndex : false, // listening で index を返す
\r
14 _killReserved : false,
\r
16 listen : function( type, arg1, arg2, arg3 ){
\r
17 var list = this._listeners,
\r
19 if( this._dispatching ){
\r
22 if( !this._reserves ) this._reserves = [];
\r
23 this._reserves[ this._reserves.length ] = [ type, arg1, arg2, arg3 ];
\r
26 if( this.listening( type, arg1, arg2, arg3 ) ) return this;
\r
28 if( !list ) list = this._listeners = {};
\r
29 if( !( list = list[ type ] ) ) list = this._listeners[ type ] = [];
\r
30 list[ list.length ] = f =
\r
33 X.Callback.create( arg1, arg2, arg3 );
\r
34 f.once = X.EventDispatcher._once;
\r
37 listenOnce : function( type, arg1, arg2, arg3 ){
\r
38 X.EventDispatcher._once = true;
\r
39 this.listen( type, arg1, arg2, arg3 );
\r
40 X.EventDispatcher._once = false;
\r
43 unlisten : function( type, arg1, arg2, arg3 ){
\r
44 var list = this._listeners,
\r
45 _list, reserves, unlistens, i, f;
\r
46 if( !list ) return this;
\r
47 if( type === undefined ){
\r
49 for( type in list ){
\r
50 _list = list[ type ];
\r
51 if( !( i = _list.length ) ) continue;
\r
53 this.unlisten( type, _list[ --i ] ); // override されていることがあるので、必ず unlisten を使用
\r
55 // this.unlisten( type ); これは無茶!
\r
59 if( arg1 === undefined ){
\r
61 if( !( list = list[ type ] ) || !( i = list.length ) ) return this;
\r
63 this.unlisten( type, list[ --i ] ); // override されていることがあるので、必ず unlisten を使用
\r
68 if( reserves = this._reserves ){
\r
69 for( i = reserves.length; i; ){
\r
70 f = reserves[ --i ];
\r
71 if( f[ 0 ] === type && f[ 1 ] === arg1 && f[ 2 ] === arg2 && f[ 3 ] === arg3 ){
\r
72 reserves.splice( i, 1 );
\r
73 if( !reserves.legth ) delete this._reserves;
\r
79 this._needsIndex = true;
\r
80 i = this.listening( type, arg1, arg2, arg3 );
\r
81 delete this._needsIndex;
\r
82 if( i === false ) return this;
\r
84 f = ( list = list[ type ] )[ i ];
\r
85 if( unlistens = this._unlistens ){
\r
86 ( unlistens = unlistens[ type ] ) ?
\r
87 ( unlistens[ unlistens.length ] = f ) :
\r
88 ( this._unlistens[ type ] = [ f ] );
\r
91 f.kill === X.Callback._kill && f.kill();
\r
92 list.splice( i, 1 );
\r
94 delete this._listeners[ type ];
\r
95 if( X.isEmptyObject( this._listeners ) ) delete this._listeners;
\r
100 listening : function( type, arg1, arg2, arg3 ){
\r
101 var list = this._listeners, unlistens, i, f;
\r
102 if( type === undefined ) return !!list;
\r
103 if( !list || !( list = list[ type ] ) ) return false;
\r
104 if( arg1 === undefined ) return true;
\r
105 if( ( unlistens = this._unlistens ) && ( unlistens = unlistens[ type ] ) ){
\r
106 for( i = unlistens.length; i; ){
\r
107 f = unlistens[ --i ];
\r
108 if( f === arg1 || ( f.same && f.same( arg1, arg2, arg3 ) ) ) return false;
\r
111 for( i = list.length; i; ){
\r
113 if( f === arg1 || ( f.same && f.same( arg1, arg2, arg3 ) ) ) return this._needsIndex ? i : true;
\r
118 * dispatch 中に dispatch が呼ばれるケースがあるため、
\r
119 * _dispatching では その深さを保存する
\r
120 * _dispatching が 0 のときに unlistens を削除する
\r
123 dispatch : function( e ){
\r
124 // dispatch 中の listen は?
\r
125 var list = this._listeners,
\r
126 ret = X.Callback.NONE,
\r
128 unlistens, i, l, f, r, sysOnly;
\r
130 if( !list || !( list = list[ type ] ) ) return ret;
\r
132 ++this._dispatching;
\r
136 this._unlistens = this._unlistens || {};
\r
137 unlistens = this._unlistens[ type ];
\r
139 for( i = 0; i < list.length; ++i ){
\r
141 if( unlistens && unlistens.indexOf( f ) !== -1 ) continue;
\r
143 r = typeof f === 'function' ? f( e ) : f.handleEvent( e );
\r
145 if( f.once === true || r & X.Callback.UN_LISTEN ){
\r
147 ( unlistens[ unlistens.length ] = f ) :
\r
148 ( unlistens = this._unlistens[ type ] = [ f ] );
\r
151 if( r & X.Callback.STOP_NOW ){
\r
157 if( ( --this._dispatching ) === 0 ){
\r
158 // dispatch 中に unlisten された要素の削除
\r
159 unlistens = this._unlistens;
\r
160 delete this._dispatching;
\r
161 delete this._unlistens;
\r
163 for( type in unlistens ){
\r
164 list = unlistens[ type ];
\r
165 for( i = list.length; i; ){
\r
166 this.unlisten( type, list[ --i ] );
\r
168 unlistens.length = 0;
\r
171 if( this._killReserved ){
\r
174 if( list = this._reserves ){
\r
175 for( i = 0, l = list.length; i < l; ++i ){
\r
177 this.listen( f[ 0 ], f[ 1 ], f[ 2 ], f[ 3 ] );
\r
181 delete this._reserves;
\r
188 onKill : function(){
\r
189 if( this._dispatching ){
\r
190 this._killReserved = true;
\r
193 this._listeners && this.unlisten();
\r
196 asyncDispatch : function( delay, e ){
\r
197 return X.Timer.once( delay, this, this.dispatch, [ e ] );
\r
202 X.EventDispatcher._once = false;
\r