* \r
* <dl>\r
* <dt>0:ACTUAL_HANDLER\r
- * <dd>ã\82¤ã\83\99ã\83³ã\83\88ã\82¿ã\83¼ã\82²ã\83\83ã\83\88ã\81® addEventListener ç\89ã\81«æ¸¡ã\81\95ã\82\8cã\82\8bå®\9fé\9a\9bã\81®é\96¢æ\95°(å\86\8då\88©ç\94¨å\8f¯è\83½ã\82¯ã\83ã\83¼ã\82¸ã\83£)を控えています。\r
+ * <dd>ã\82¤ã\83\99ã\83³ã\83\88ã\82¿ã\83¼ã\82²ã\83\83ã\83\88ã\81® addEventListener ç\89ã\81«æ¸¡ã\81\95ã\82\8cã\82\8bå®\9fé\9a\9bã\81®é\96¢æ\95°(å¤\9aã\81\8fã\81®å ´å\90\88ã\80\81å\86\8då\88©ç\94¨å\8f¯è\83½ã\82¯ã\83ã\83¼ã\82¸ã\83£ã\80\81ã\81\9dã\82\8c以å¤\96ã\81¯é\80\9a常ã\81®é\96¢æ\95°)を控えています。\r
* <dt>1:DISPATCHING number\r
* <dd>dispatch 中か?さらにインスタンス自身の dispatch がネストした場合、その深さを記憶します。\r
* <dt>2:RESERVES Array\r
* <dd>dispatch 中に kill() が呼ばれた場合に一旦 kill をキャンセルし、完了時(DISPATCHING===0)に再度 kill() するためのフラグです。\r
* </dl>\r
* \r
- * @class __X_EventDispatcher_Listeners__\r
+ * @class __Listeners__\r
* @private\r
* @abstract\r
*/\r
-var\r
- /** @enum {number} */\r
- X_Listeners_ =\r
- /** @lends __X_EventDispatcher_Listeners__ */\r
- {\r
- ACTUAL_HANDLER : 0,\r
- DISPATCHING : 1,\r
- RESERVES : 2,\r
- UNLISTENS : 3,\r
- KILL_RESERVED : 4 // X.Event で、イベントIDを 5 から始めているので注意。\r
- };\r
+var X_Listeners_;\r
+\r
+var /** @const */\r
+ X_LISTENERS_ACTUAL_HANDLER = 0,\r
+ /** @const */\r
+ X_LISTENERS_DISPATCHING = 1,\r
+ /** @const */\r
+ X_LISTENERS_RESERVES = 2,\r
+ /** @const */\r
+ X_LISTENERS_UNLISTENS = 3,\r
+ /** @const */\r
+ X_LISTENERS_KILL_RESERVED = 4; // X.Event で、イベントIDを 5 から始めているので注意。\r
\r
\r
\r
cbHash = X_Callback_classifyCallbackArgs( opt_arg1, opt_arg2, opt_arg3, this );\r
};\r
\r
- if( ( unlistens = listeners[ X_Listeners_.UNLISTENS ] ) && ( unlistens = unlistens[ opt_type ] ) ){\r
+ if( ( unlistens = listeners[ X_LISTENERS_UNLISTENS ] ) && ( unlistens = unlistens[ opt_type ] ) ){\r
for( i = unlistens.length; i; ){\r
f = unlistens[ --i ];\r
if( f === cbHash || ( f.context === cbHash.context && f.func === cbHash.func && f.supplement === cbHash.supplement && f.lock === lock ) ) return false;\r
e[ 'target' ] = e[ 'target' ] || this;\r
e[ 'currentTarget' ] = e[ 'currentTarget' ] || this;\r
\r
- if( listeners[ X_Listeners_.DISPATCHING ] ){\r
- ++listeners[ X_Listeners_.DISPATCHING ];\r
+ if( listeners[ X_LISTENERS_DISPATCHING ] ){\r
+ ++listeners[ X_LISTENERS_DISPATCHING ];\r
} else {\r
- listeners[ X_Listeners_.DISPATCHING ] = 1;\r
+ listeners[ X_LISTENERS_DISPATCHING ] = 1;\r
};\r
\r
// todo:\r
// type も保存\r
- listeners[ X_Listeners_.UNLISTENS ] = listeners[ X_Listeners_.UNLISTENS ] || {};\r
- unlistens = listeners[ X_Listeners_.UNLISTENS ][ type ];\r
+ listeners[ X_LISTENERS_UNLISTENS ] = listeners[ X_LISTENERS_UNLISTENS ] || {};\r
+ unlistens = listeners[ X_LISTENERS_UNLISTENS ][ type ];\r
\r
for( i = 0; i < list.length; ++i ){\r
f = list[ i ];\r
if( !unlistens ){\r
- unlistens = listeners[ X_Listeners_.UNLISTENS ][ type ];\r
+ unlistens = listeners[ X_LISTENERS_UNLISTENS ][ type ];\r
};\r
if( unlistens && unlistens.indexOf( f ) !== -1 ) continue;\r
\r
if( f.once || r & X_Callback_UN_LISTEN ){\r
// dispatch 中に unlisten が作られることがある\r
if( !unlistens ){\r
- unlistens = listeners[ X_Listeners_.UNLISTENS ] || ( listeners[ X_Listeners_.UNLISTENS ] = {} );\r
+ unlistens = listeners[ X_LISTENERS_UNLISTENS ] || ( listeners[ X_LISTENERS_UNLISTENS ] = {} );\r
unlistens = unlistens[ type ] || ( unlistens[ type ] = [] );\r
};\r
unlistens.indexOf( f ) === -1 && ( unlistens[ unlistens.length ] = f );\r
};\r
ret |= X_Type_isFinite( r ) ? r : 0;\r
\r
- if( r & X_Callback_STOP_NOW ){\r
+ if( r & X_Callback_STOP_NOW === X_Callback_STOP_NOW ){\r
sysOnly = true;\r
break;\r
}; \r
};\r
\r
- if( ( --listeners[ X_Listeners_.DISPATCHING ] ) === 0 ){\r
+ if( ( --listeners[ X_LISTENERS_DISPATCHING ] ) === 0 ){\r
\r
- delete listeners[ X_Listeners_.DISPATCHING ];\r
+ delete listeners[ X_LISTENERS_DISPATCHING ];\r
\r
// dispatch 中に listen されたイベントの追加\r
- if( list = listeners[ X_Listeners_.RESERVES ] ){\r
+ if( list = listeners[ X_LISTENERS_RESERVES ] ){\r
for( i = 0, l = list.length; i < l; ++i ){\r
f = list[ i ];\r
X_EventDispatcher_once = f[ 4 ];\r
};\r
list.length = 0;\r
X_EventDispatcher_once = X_EventDispatcher_lock = false;\r
- delete listeners[ X_Listeners_.RESERVES ];\r
+ delete listeners[ X_LISTENERS_RESERVES ];\r
}; \r
\r
// dispatch 中に unlisten されたイベントの削除\r
- if( unlistens = listeners[ X_Listeners_.UNLISTENS ] ){\r
- delete listeners[ X_Listeners_.UNLISTENS ];\r
+ if( unlistens = listeners[ X_LISTENERS_UNLISTENS ] ){\r
+ delete listeners[ X_LISTENERS_UNLISTENS ];\r
\r
// _unlistens に入っている callbackHash は、lock をクリアしている\r
X_EventDispatcher_unlock = true;\r
delete X_EventDispatcher_LAZY_TIMERS[ X_Timer_currentUID ];\r
};\r
\r
- if( listeners[ X_Listeners_.KILL_RESERVED ] ){\r
+ if( listeners[ X_LISTENERS_KILL_RESERVED ] ){\r
/*\r
for( timerID in X_EventDispatcher_LAZY_TIMERS ){\r
if( X_EventDispatcher_LAZY_TIMERS[ timerID ] === this ) return ret;\r
\r
if( !type ) return this;\r
\r
- if( listeners && listeners[ X_Listeners_.DISPATCHING ] ){\r
- if( !listeners[ X_Listeners_.RESERVES ] ) listeners[ X_Listeners_.RESERVES ] = [];\r
- listeners[ X_Listeners_.RESERVES ][ listeners[ X_Listeners_.RESERVES ].length ] = [ type, opt_arg1, opt_arg2, opt_arg3, X_EventDispatcher_once, X_EventDispatcher_lock ];\r
+ if( listeners && listeners[ X_LISTENERS_DISPATCHING ] ){\r
+ if( !listeners[ X_LISTENERS_RESERVES ] ) listeners[ X_LISTENERS_RESERVES ] = [];\r
+ listeners[ X_LISTENERS_RESERVES ][ listeners[ X_LISTENERS_RESERVES ].length ] = [ type, opt_arg1, opt_arg2, opt_arg3, X_EventDispatcher_once, X_EventDispatcher_lock ];\r
return this;\r
};\r
\r
return this;\r
};\r
\r
- if( reserves = listeners[ X_Listeners_.RESERVES ] ){\r
+ if( reserves = listeners[ X_LISTENERS_RESERVES ] ){\r
for( i = reserves.length; i; ){\r
f = reserves[ --i ];\r
if( f[ 0 ] === opt_type && f[ 1 ] === opt_arg1 && f[ 2 ] === opt_arg2 && f[ 3 ] === opt_arg3 && ( !f[ 5 ] || X_EventDispatcher_unlock ) ){\r
reserves.splice( i, 1 );\r
- if( !reserves.legth ) delete listeners[ X_Listeners_.RESERVES ];\r
+ if( !reserves.legth ) delete listeners[ X_LISTENERS_RESERVES ];\r
return this;\r
};\r
};\r
\r
f = ( list = listeners[ opt_type ] )[ i ];\r
\r
- if( unlistens = listeners[ X_Listeners_.UNLISTENS ] ){\r
+ if( unlistens = listeners[ X_LISTENERS_UNLISTENS ] ){\r
// _unlistens に入っている callbackHash は、lock のチェックは済んでいる\r
( unlistens = unlistens[ opt_type ] ) ?\r
( unlistens[ unlistens.length ] = f ) :\r
- ( listeners[ X_Listeners_.UNLISTENS ][ opt_type ] = [ f ] );\r
+ ( listeners[ X_LISTENERS_UNLISTENS ][ opt_type ] = [ f ] );\r
} else {\r
delete f.once;\r
list.splice( i, 1 );\r
// TODO カウンター\r
empty = true;\r
for( k in listeners ){\r
- if( k <= X_Listeners_.KILL_RESERVED ) continue;\r
+ if( k <= X_LISTENERS_KILL_RESERVED ) continue;\r
empty = false;\r
break;\r
};\r
\r
for( type in listeners ){\r
//if( X_EMPTY_OBJECT[ opt_type ] ) continue;\r
- if( type <= X_Listeners_.KILL_RESERVED ) continue;\r
+ if( type <= X_LISTENERS_KILL_RESERVED ) continue;\r
list = listeners[ type ];\r
for( i = list.length; i; ){\r
that[ 'unlisten' ]( type, list[ --i ] );\r
};\r
\r
function X_EventDispatcher_addEvent( that, type, raw, list ){\r
- var i;\r
+ var i, f;\r
X_EventDispatcher_lock || ( type = X_Event_Rename[ type ] || type );\r
\r
if( X_Type_isArray( type ) ){\r
console.log( 'events fix > ' + type[ i ] );\r
};\r
} else {\r
- X_EventDispatcher_actualAddEvent( that, type, raw, list );\r
- };\r
-};\r
-\r
-var X_EventDispatcher_actualAddEvent =\r
+ \r
// Days on the Moon DOM Events とブラウザの実装 \r
// http://nanto.asablo.jp/blog/2007/03/23/1339502\r
// Safari 2 では関数オブジェクトしか EventListener として使えませんが、Safari のナイトリービルドでは handleEvent メソッドを持つオブジェクトも EventListener として使えるようです。\r
- X_UA_EVENT.W3C ?\r
- (function( that, type, raw, list ){\r
- var f;\r
+ \r
+ if( X_UA_EVENT.W3C ){\r
switch( that[ '_rawType' ] ){\r
case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT :\r
list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] );\r
- list.sltoken = raw.AddEventListener( type, list.slcallback );\r
+ list.sltoken = raw[ 'AddEventListener' ]( type, list.slcallback );\r
break;\r
\r
case X_EventDispatcher_EVENT_TARGET_XHR :\r
type === 'animationiteration' || type === 'webkitAnimationIteration' ) ){\r
raw.addEventListener( type, X_EventDispatcher_iOSTransitionEndDispatch, false );\r
} else {\r
- f = that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) );\r
+ f = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) );\r
\r
if( raw.addEventListener ){\r
raw.addEventListener( type, f, false );\r
};\r
};\r
};\r
- }) :\r
- X_UA_EVENT.IE ?\r
- (function( that, type, raw, list ){\r
- var f;\r
+ } else\r
+ if( X_UA_EVENT.IE ){\r
switch( that[ '_rawType' ] ){ \r
case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT :\r
list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] );\r
- list.sltoken = raw.AddEventListener( type, list.slcallback );\r
+ list.sltoken = raw[ 'AddEventListener' ]( type, list.slcallback );\r
break; \r
\r
case X_EventDispatcher_EVENT_TARGET_XHR :\r
break;\r
\r
default :\r
- f = that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) );\r
+ f = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) );\r
\r
if( raw.attachEvent ){\r
raw.attachEvent( 'on' + type, f );\r
};\r
break;\r
};\r
- }) :\r
- (function( that, type, raw, list ){\r
+ } else {\r
switch( that[ '_rawType' ] ){\r
case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT :\r
// DOM0 で Silverlight ってあるの -> ie4 mobile?\r
list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] );\r
- list.sltoken = raw.AddEventListener( type, list.slcallback );\r
+ list.sltoken = raw[ 'AddEventListener' ]( type, list.slcallback );\r
break; \r
\r
case X_EventDispatcher_EVENT_TARGET_XHR :\r
break;\r
\r
default :\r
- raw[ 'on' + type ] = that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) );\r
+ raw[ 'on' + type ] = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) );\r
break;\r
};\r
- });\r
+ }\r
+ };\r
+};\r
+\r
\r
/*\r
* iOS の webkitTransitionEnd が連続して起こる場合、\r
- * コールバックの(that[ X_Listeners_.ACTUAL_HANDLER ])クロージャ内の実際のコールバック(X_Callback_actualClosure:obj._)が\r
+ * コールバックの(that[ X_LISTENERS_ACTUAL_HANDLER ])クロージャ内の実際のコールバック(X_Callback_actualClosure:obj._)が\r
* 参照できていない問題に遭遇、、、iOS3.1.3 & iOS6.1.5 で確認\r
* animation も怪しい、、、\r
*/\r
X_EventDispatcher_systemUnlisten( that, type[ --i ], X_emptyFunction );\r
};\r
} else {\r
- X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip );\r
- };\r
-};\r
-\r
-var X_EventDispatcher_actualRemoveEvent =\r
- X_UA_EVENT.W3C ?\r
- (function( that, type, raw, list, skip ){\r
+ if( X_UA_EVENT.W3C ){\r
switch( that[ '_rawType' ] ){\r
case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT :\r
- raw.RemoveEventListener( type, list.sltoken ); // token\r
+ raw[ 'RemoveEventListener' ]( type, list.sltoken ); // token\r
X_Callback_correct( list.slcallback );\r
delete list.sltoken;\r
delete list.slcallback;\r
raw.removeEventListener( type, X_EventDispatcher_iOSTransitionEndDispatch, false );\r
} else \r
if( raw.addEventListener ){\r
- raw.removeEventListener( type, that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ], false );\r
+ raw.removeEventListener( type, that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ], false );\r
} else {\r
raw[ 'on' + type ] = null;\r
};\r
\r
- if( !skip && that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] ){\r
- X_Callback_correct( that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] );\r
- delete that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ];\r
+ if( !skip && that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ){\r
+ X_Callback_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] );\r
+ delete that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ];\r
};\r
};\r
- }) :\r
- X_UA_EVENT.IE ?\r
- (function( that, type, raw, list, skip ){\r
+ } else\r
+ if( X_UA_EVENT.IE ){\r
switch( that[ '_rawType' ] ){\r
case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT :\r
- raw.RemoveEventListener( type, list.sltoken ); // token\r
+ raw[ 'RemoveEventListener' ]( type, list.sltoken ); // token\r
X_Callback_correct( list.slcallback );\r
delete list.sltoken;\r
delete list.slcallback;\r
\r
default :\r
if( raw.attachEvent ){\r
- raw.detachEvent( 'on' + type, that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] );\r
+ raw.detachEvent( 'on' + type, that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] );\r
} else {\r
raw[ 'on' + type ] = X_emptyFunction;\r
raw[ 'on' + type ] = '';\r
};\r
\r
if( !skip ){\r
- X_Callback_correct( that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] );\r
- delete that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ];\r
+ X_Callback_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] );\r
+ delete that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ];\r
};\r
};\r
- }) :\r
- (function( that, type, raw, list, skip ){\r
+ } else {\r
switch( that[ '_rawType' ] ){\r
case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT :\r
- raw.RemoveEventListener( type, list.sltoken ); // token\r
+ raw[ 'RemoveEventListener' ]( type, list.sltoken ); // token\r
X_Callback_correct( list.slcallback );\r
delete list.sltoken;\r
delete list.slcallback;\r
raw[ 'on' + type ] = '';\r
\r
if( !skip ){\r
- X_Callback_correct( that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ] );\r
- delete that[ '_listeners' ][ X_Listeners_.ACTUAL_HANDLER ];\r
+ X_Callback_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] );\r
+ delete that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ];\r
};\r
};\r
- });\r
+ };\r
+ };\r
+};\r
\r
\r
// TODO ブラウザからの呼び出しの最後に登録された関数を呼び出す機能(例えば画面の更新)\r
if( !list || !raw ) return;\r
for( type in list ){\r
//if( X_EMPTY_OBJECT[ type ] ) continue;\r
- //if( type <= X_Listeners_.KILL_RESERVED ) continue;\r
+ //if( type <= X_LISTENERS_KILL_RESERVED ) continue;\r
// 数字イベントの除外\r
if( !X_String_isNumberString( type ) ){\r
// TODO type rename はここ\r