*/\r
\r
X.Event = {\r
- COMPLETE : 1,\r
- SUCCESS : 2,\r
- ERROR : 3,\r
- PROGRESS : 4,\r
- BEFORE_CANCEL : 5,\r
- CANCELED : 6,\r
- TIMEOUT : 7,\r
- // BEFORE_KILL_INSTANCE\r
- // KILL_INSTANCE_CANCELED\r
- _LAST_EVENT : 7\r
+ COMPLETE : 1,\r
+ SUCCESS : 2,\r
+ ERROR : 3,\r
+ PROGRESS : 4,\r
+ BEFORE_CANCEL : 5,\r
+ CANCELED : 6,\r
+ TIMEOUT : 7,\r
+ BEFORE_KILL_INSTANCE : 8,\r
+ KILL_INSTANCE : 9,\r
+ KILL_INSTANCE_CANCELED : 10,\r
+ _LAST_EVENT : 10\r
};\r
\r
// ------------------------------------------------------------------------- //\r
-// --- define / local variables -------------------------------------------- //\r
+// ------------ local variables -------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
var x_eventdispatcher_once = false,\r
x_eventdispatcher_needsIndex = false,\r
\r
};\r
\r
+// ------------------------------------------------------------------------- //\r
+// --- interface ----------------------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
+\r
/**\r
* イベントターゲットをラップする場合(widnow, document, Image, XHR 等)、通常は new 時に渡します。参照:コンストラクタ実体 {@link X.EventDispatcher.Constructor}\r
* アプリケーション独自のイベントをやり取りしたいだけ、という場合、イベントターゲットは不要です。\r
- * @constructor\r
+ * @class\r
* @classdesc EventTarget オブジェクトをラップしたり、アプリケーションで独自に定義したイベントを発信するためのクラスです。\r
- * listen, unlisten, dispatch という addEventListener, removeEventListener, dispatchEvent に対応する関数を持ちます。さらに listening という as3 の hasEventListener に相当する関数を持ちます。\r
- * as3 の EventDispatcher に相当する機能に加え、イベントターゲットオブジェクト(widnow, document, HTMLElement, XHR 等)が設定されていた場合に、それらへ実際のイベント登録・解除も行います。\r
- * このイベントの登録・解除はクロスブラウザ対策が施されていて、IE5~8の独自イベントの差異を吸収し、DOM0 に対しても複数のイベントリスナを登録します。\r
- * さらに、コールバックに対して、this コンテキストや、追加の引数を指定できます。 this コンテキストを指定しなかった場合、EventDispatcher インスタンスがコールバック関数の this になります。 \r
- * @param {object=} opt_argument \r
+ * listen, unlisten, dispatch という addEventListener, removeEventListener, dispatchEvent に対応する関数を持ちます。\r
+ * さらに listening という as3 の hasEventListener に相当する関数を持ちます。\r
+ * イベントターゲットオブジェクト(widnow, document, HTMLElement, XHR 等)が _rawObject に設定されていた場合に、それらへ実際のイベント登録・解除も行います。\r
+ * このイベントの登録・解除はクロスブラウザで、IE5~8 の独自イベントの差異を吸収し、DOM0 に対しても複数のコールバックを登録することができます。\r
+ * またコールバックに対して、this コンテキストや、追加の引数を指定もできます。 this コンテキストを指定しなかった場合、EventDispatcher インスタンスがコールバックの this になります。 \r
+ * @param {object=} opt_rawObject\r
*/\r
X.EventDispatcher =\r
X.Class.create(\r
'EventDispatcher',\r
+ \r
+ /** @lends {X.EventDispatcher.prototype} */\r
{\r
\r
/**\r
* イベントリスナをイベント名(string)や数値(1~,フレームワーク内で定義)をキーとするArrayで記憶します。\r
* Arrayには、{k:種類,x:コンテキスト(thisObject),f:関数,s:サプリメントする引数の配列} というハッシュ、または関数が蓄えられています。\r
* @private\r
- * @type {Object.<(number|string), Array.<(callbackDef|function)>>}\r
+ * @type {Object.<(number|string), Array.<(callbackHash|function)>>}\r
*/\r
- _listeners : null,\r
+ '_listeners' : null,\r
\r
/**\r
* _rawObject には HTMLElement, window, document, XHR といったイベントターゲットオブジェクトを設定します。\r
* @private\r
* @type {Object}\r
*/\r
- _rawObject : null,\r
- _handleEvent : null,\r
+ '_rawObject' : null,\r
+ \r
+ /**\r
+ * _rawObject がある場合、イベントターゲットオブジェクトに対して addEventListener, attachEvent, onXX 時に実際に渡される関数。\r
+ * イベントタイプが変わっても、単一の オブジェクトを使いまわす。(但し例外は、IE8以下の XHR|MSXML に対して。)最初の listen で生成されて、最後の unlisten で削除される。\r
+ * @private\r
+ * @type {X.Callback}\r
+ */\r
+ '_handleEvent' : null,\r
\r
- _dispatching : 0, // dispatch 中の unlisten で使用\r
- _unlistens : null, // dispatch 中の unlisten で使用\r
- _reserves : null, // dispatch中に unlisten されたイベントリスナ\r
- _killReserved : false,\r
+ /*\r
+ * dispatch 中に dispatch が呼ばれた際に、そのネストの深さを保存する。\r
+ * dispatch() 終了時に _dispatching が 0 の場合に、現在のインスタンスの dispatch がすべて終わったことになる。\r
+ * @private\r
+ * @type {number}\r
+ */\r
+ '_dispatching' : 0, // dispatch 中の unlisten で使用\r
+\r
+ /*\r
+ * dispatch 中に listen が呼ばれた場合に、配列のindexがずれることを避けるため、一旦保持する。\r
+ * _dispatching が 0 のときに _reserves を使って listen() を呼び出す。\r
+ * @private\r
+ * @type {Object.<(number|string), Array.<(X.Callback|function)>>}\r
+ */\r
+ '_reserves' : null,\r
+ \r
+ /*\r
+ * dispatch 中に unlisten が呼ばれた場合に、配列のindexがずれることを避けるため、一旦保持する。\r
+ * _dispatching が 0 のときに _unlistens を使って unlisten() を呼び出す。\r
+ * @private\r
+ * @type {Object.<(number|string), Array.<(X.Callback|function)>>}\r
+ */\r
+ '_unlistens' : null,\r
+ \r
+ /*\r
+ * dispatch 中に kill が呼ばれた場合に、X.EventDispatcher インスタンスの削除を dispatch 後にずらすために立てるフラグ。\r
+ * @private\r
+ * @type {boolean}\r
+ */\r
+ '_killReserved' : false,\r
\r
/**\r
* X.EventDispatcher のコンストラクタの実体。\r
- * @private\r
+ * @constructs\r
* @this {X.EventDispatcher}\r
+ * @params {object=} opt_rawObject\r
*/\r
- Constructor : function( rawObject ){\r
- if( rawObject ){\r
- this._rawObject = rawObject;\r
+ Constructor : function( opt_rawObject ){\r
+ if( opt_rawObject ){\r
+ this._rawObject = opt_rawObject;\r
};\r
},\r
\r
* \r
* @this {X.EventDispatcher}\r
*/\r
- on : x_eventdispatcher_on,\r
- listen : x_eventdispatcher_on,\r
- \r
- listenOnce : function( type, arg1, arg2, arg3 ){\r
+ on : x_eventdispatcher_listen,\r
+ listen : x_eventdispatcher_listen,\r
+ \r
+ /**\r
+ * 一度 dispatch された時に自動で unlisten されるフラグを立てて listen する。\r
+ * @this {X.EventDispatcher}\r
+ * @return {X.EventDispatcher}\r
+ * @param {(string|number|Array.<(string,number)>)} type\r
+ * @param {(listener|function|Array)=} opt_arg1\r
+ * @param {(function|Array=} opt_arg2\r
+ * @param {Array=} opt_arg3\r
+ */\r
+ listenOnce : function( type, opt_arg1, opt_arg2, opt_arg3 ){\r
x_eventdispatcher_once = true;\r
- this.listen( type, arg1, arg2, arg3 );\r
+ this.listen( type, opt_arg1, opt_arg2, opt_arg3 );\r
x_eventdispatcher_once = false;\r
return this;\r
},\r
\r
- off : x_eventdispatcher_off,\r
- unlisten : x_eventdispatcher_off,\r
- \r
- listening : function( type, arg1, arg2, arg3 ){\r
+ off : x_eventdispatcher_unlisten,\r
+ unlisten : x_eventdispatcher_unlisten,\r
+\r
+ /**\r
+ * イベントリスナの登録状況を真偽値で返す。戻り値が数値(index)の場合もあるが、これは内部のみで使用。\r
+ * listening() と type を省略した場合、一つでも登録があれば true を返す。\r
+ * listening( type ) と type だけを与えた場合、その type に登録があれば true を返す。\r
+ * type と イベントリスナの組み合わせが登録されているかを調べる場合は、listen 時の thisObject や args(Array) も一致させて渡す必要がある。\r
+ * this.listen( [ 'myevent', 'yourevent' ], this, onMyEvent, args = [ 1, 'a' ] );\r
+ * this.listening( 'myevent', this, onMyEvent, args ) === true;\r
+ * @this {X.EventDispatcher}\r
+ * @return {(number|boolean)}\r
+ * @param {(string|number)=} opt_type\r
+ * @param {(listener|function|Array)=} opt_arg1\r
+ * @param {(function|Array=} opt_arg2\r
+ * @param {Array=} opt_arg3\r
+ */ \r
+ listening : function( opt_type, opt_arg1, opt_arg2, opt_arg3 ){\r
var list = this._listeners, unlistens, i, f, hash;\r
- if( type === undefined ) return !!list;\r
- if( !list || !( list = list[ type ] ) ) return false;\r
- if( arg1 === undefined ) return true;\r
+ if( opt_type === undefined ) return !!list;\r
+ if( !list || !( list = list[ opt_type ] ) ) return false;\r
+ if( opt_arg1 === undefined ) return true;\r
\r
- if( arg1.k ){\r
- hash = arg1;\r
+ if( opt_arg1.k ){\r
+ hash = opt_arg1;\r
} else {\r
- hash = X.Callback._classifyCallbackArgs( arg1, arg2, arg3, this );\r
+ hash = X.Callback._classifyCallbackArgs( opt_arg1, opt_arg2, opt_arg3, this );\r
};\r
\r
- if( ( unlistens = this._unlistens ) && ( unlistens = unlistens[ type ] ) ){\r
+ if( ( unlistens = this._unlistens ) && ( unlistens = unlistens[ opt_type ] ) ){\r
for( i = unlistens.length; i; ){\r
f = unlistens[ --i ];\r
if( f === hash || ( f.x === hash.x && f.f === hash.f && f.s === hash.s ) ) return false;\r
};\r
return false;\r
},\r
- /*\r
- * dispatch 中に dispatch が呼ばれるケースがあるため、\r
- * _dispatching では その深さを保存する\r
- * _dispatching が 0 のときに unlistens を削除する\r
- *\r
- */\r
+\r
+ /**\r
+ * 登録されたイベントリスナを呼び出す。イベントリスナの返り値(数値)を OR したものを返す。\r
+ * @this {X.EventDispatcher}\r
+ * @return {number}\r
+ * @param {(eventHash|string|number)} e\r
+ */ \r
dispatch : function( e ){\r
// dispatch 中の listen は?\r
- var list = this._listeners,\r
+ var list = this[ '_listeners' ],\r
ret = X.Callback.NONE,\r
- type = e.type,\r
+ type = e[ 'type' ],\r
unlistens, i, l, f, r, sysOnly;\r
\r
- if( !list ) return ret;\r
+ if( !list || !( list = list[ type || e ] ) ) return ret;\r
\r
// 数値, 文字が渡された場合\r
if( !type ){\r
- type = e;\r
- e = { type : type };\r
+ e = { type : type = e };\r
};\r
e.target = e.target || this;\r
\r
- if( !( list = list[ type ] ) ) return ret;\r
- \r
++this._dispatching;\r
\r
// todo:\r
\r
return ret;\r
},\r
- \r
- onKill : function(){\r
- if( this._dispatching ){\r
- this._killReserved = true;\r
- return false;\r
- };\r
- this._listeners && this.unlisten();\r
- },\r
- \r
+\r
+ /**\r
+ * delay(ミリ秒)後にイベントを dispatch する。戻り値は uid = X.Timer.add() のタイマーID(数値)。X.Timer.remove(uid) でタイマーを解除して dispatch を中止できる。\r
+ * @this {X.EventDispatcher}\r
+ * @return {number}\r
+ * @param {number=} delay\r
+ * @param {(eventHash|string|number)=} e\r
+ */ \r
asyncDispatch : function( delay, e ){\r
return X.Timer.add( delay, 1, this, this.dispatch, [ e ] );\r
}\r
}\r
);\r
\r
+// ------------------------------------------------------------------------- //\r
+// --- implements ---------------------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
\r
-// --- implements ------------------------------------------\r
-function x_eventdispatcher_on( type, arg1, arg2, arg3 ){\r
+/**\r
+ * \r
+ * @this {X.EventDispatcher}\r
+ * @return {X.EventDispatcher}\r
+ * @param {(string|number|Array.<(string,number)>)} type\r
+ * @param {(listener|function|Array)=} opt_arg1\r
+ * @param {(function|Array=} opt_arg2\r
+ * @param {Array=} opt_arg3\r
+ */\r
+function x_eventdispatcher_listen( type, opt_arg1, opt_arg2, opt_arg3 ){\r
var list = this._listeners,\r
i, r, f;\r
\r
if( this._dispatching ){\r
if( !this._reserves ) this._reserves = [];\r
- this._reserves[ this._reserves.length ] = [ type, arg1, arg2, arg3, x_eventdispatcher_once ];\r
+ this._reserves[ this._reserves.length ] = [ type, opt_arg1, opt_arg2, opt_arg3, x_eventdispatcher_once ];\r
return this;\r
};\r
\r
if( X.Type.isArray( type ) ){\r
for( i = type.length; i; ){\r
- this.listen( type[ --i ], arg1, arg2, arg3 );\r
+ this.listen( type[ --i ], opt_arg1, opt_arg2, opt_arg3 );\r
};\r
return this;\r
};\r
\r
( !list || !list[ type ] ) && X.Type.isString( type ) && x_eventdispatcher_actualAddEvent( this, type );\r
\r
- if( this.listening( type, arg1, arg2, arg3 ) ) return this;\r
+ if( this.listening( type, opt_arg1, opt_arg2, opt_arg3 ) ) return this;\r
\r
if( !list ) list = this._listeners = {};\r
if( !( list = list[ type ] ) ) list = this._listeners[ type ] = [];\r
\r
- f = X.Callback._classifyCallbackArgs( arg1, arg2, arg3, this );\r
+ f = X.Callback._classifyCallbackArgs( opt_arg1, opt_arg2, opt_arg3, this );\r
list[ list.length ] = f;\r
f.once = x_eventdispatcher_once;\r
\r
return this;\r
};\r
\r
-function x_eventdispatcher_off( type, arg1, arg2, arg3 ){\r
+/**\r
+ * \r
+ * @this {X.EventDispatcher}\r
+ * @return {X.EventDispatcher}\r
+ * @param {(string|number|Array.<(string,number)>)=} opt_type\r
+ * @param {(listener|function|Array)=} opt_arg1\r
+ * @param {(function|Array=} opt_arg2\r
+ * @param {Array=} opt_arg3\r
+ */\r
+function x_eventdispatcher_unlisten( opt_type, opt_arg1, opt_arg2, opt_arg3 ){\r
var list = this._listeners,\r
_list, reserves, unlistens, i, f;\r
if( !list ) return this;\r
\r
- if( X.Type.isArray( type ) ){\r
- for( i = type.length; i; ){\r
- this.unlisten( type[ --i ], arg1, arg2, arg3 );\r
+ if( X.Type.isArray( opt_type ) ){\r
+ for( i = opt_type.length; i; ){\r
+ this.unlisten( opt_type[ --i ], opt_arg1, opt_arg2, opt_arg3 );\r
};\r
return this;\r
};\r
\r
- if( type === undefined ){\r
+ if( opt_type === undefined ){\r
// 全て削除\r
- for( type in list ){\r
- _list = list[ type ];\r
+ for( opt_type in list ){\r
+ _list = list[ opt_type ];\r
for( i = _list.length; i; ){\r
- this.unlisten( type, _list[ --i ] ); // override されていることがあるので、必ず unlisten を使用\r
+ this.unlisten( opt_type, _list[ --i ] ); // override されていることがあるので、必ず unlisten を使用\r
};\r
- // this.unlisten( type ); これは無茶!\r
+ // this.unlisten( opt_type ); これは無茶!\r
};\r
return this;\r
} else\r
- if( arg1 === undefined ){\r
+ if( opt_arg1 === undefined ){\r
// 同一タイプを全て削除\r
- if( _list = list[ type ] ){\r
+ if( _list = list[ opt_type ] ){\r
for( i = _list.length; i; ){\r
- this.unlisten( type, _list[ --i ] ); // override されていることがあるので、必ず unlisten を使用\r
+ this.unlisten( opt_type, _list[ --i ] ); // override されていることがあるので、必ず unlisten を使用\r
};\r
};\r
return this;\r
if( reserves = this._reserves ){\r
for( i = reserves.length; i; ){\r
f = reserves[ --i ];\r
- if( f[ 0 ] === type && f[ 1 ] === arg1 && f[ 2 ] === arg2 && f[ 3 ] === arg3 ){\r
+ if( f[ 0 ] === opt_type && f[ 1 ] === opt_arg1 && f[ 2 ] === opt_arg2 && f[ 3 ] === opt_arg3 ){\r
reserves.splice( i, 1 );\r
if( !reserves.legth ) delete this._reserves;\r
return this;\r
};\r
\r
x_eventdispatcher_needsIndex = true;\r
- i = this.listening( type, arg1, arg2, arg3 );\r
+ i = this.listening( opt_type, opt_arg1, opt_arg2, opt_arg3 );\r
x_eventdispatcher_needsIndex = false;\r
if( i === false ) return this;\r
\r
- f = ( _list = list[ type ] )[ i ];\r
+ f = ( _list = list[ opt_type ] )[ i ];\r
if( unlistens = this._unlistens ){\r
- ( unlistens = unlistens[ type ] ) ?\r
+ ( unlistens = unlistens[ opt_type ] ) ?\r
( unlistens[ unlistens.length ] = f ) :\r
- ( this._unlistens[ type ] = [ f ] );\r
+ ( this._unlistens[ opt_type ] = [ f ] );\r
} else {\r
delete f.once;\r
// f.kill === X.Callback._kill && f.kill();\r
_list.splice( i, 1 );\r
if( !_list.length ){\r
- delete this._listeners[ type ];\r
- X.Type.isString( type ) && x_eventdispatcher_actualRemoveEvent( this, type );\r
+ delete this._listeners[ opt_type ];\r
+ X.Type.isString( opt_type ) && x_eventdispatcher_actualRemoveEvent( this, opt_type );\r
if( X.isEmptyObject( this._listeners ) ) delete this._listeners;\r
};\r
};\r