X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F01_core%2F15_XEventDispatcher.js;h=5a9864a7c49128ef149c81b9cfc1d2461e8261b8;hb=76ea1040608829b653422cf51b3490801d2ec1fa;hp=22142fe1565c43863ea2ac7004ee4bf3ceb10fcd;hpb=7d0af2a7f884c146a48cd544a1f9ad44b82c0c1f;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/01_core/15_XEventDispatcher.js b/0.6.x/js/01_core/15_XEventDispatcher.js index 22142fe..5a9864a 100644 --- a/0.6.x/js/01_core/15_XEventDispatcher.js +++ b/0.6.x/js/01_core/15_XEventDispatcher.js @@ -15,7 +15,7 @@ *
dispatch 中か?さらにインスタンス自身の dispatch がネストした場合、その深さを記憶します。 *
2:RESERVES Array *
イベント発火中に listen() が呼ばれた場合に引数を蓄え、完了時(DISPATCHING===0)に再度 listen() するための一時ストアです。 - *
3:UNLISTENS Array + *
3:UNLISTENS Object *
イベント発火中に unlisten() が呼ばれた場合に対象リスナを記憶し、リスナが呼ばれないようにします。完了時(DISPATCHING===0)に再度 unlisten() します。 *
4:KILL_RESERVED boolean *
dispatch 中に kill() が呼ばれた場合に一旦 kill をキャンセルし、完了時(DISPATCHING===0)に再度 kill() するためのフラグです。 @@ -26,37 +26,37 @@ */ var X_Listeners_; -var /** @const */ - X_LISTENERS_ACTUAL_HANDLER = 0, - /** @const */ +var X_LISTENERS_ACTUAL_HANDLER = 0, X_LISTENERS_DISPATCHING = 1, - /** @const */ X_LISTENERS_RESERVES = 2, - /** @const */ X_LISTENERS_UNLISTENS = 3, - /** @const */ X_LISTENERS_KILL_RESERVED = 4; // X.Event で、イベントIDを 5 から始めているので注意。 // ------------------------------------------------------------------------- // // ------------ local variables -------------------------------------------- // // ------------------------------------------------------------------------- // +var X_EventDispatcher_EVENT_TARGET_OTHER = 0, + X_EventDispatcher_EVENT_TARGET_XHR = 1, + X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT = 2; -var X_EventDispatcher_once = false, - X_EventDispatcher_lock = false, - X_EventDispatcher_unlock = false, - X_EventDispatcher_needsIndex = false, +var X_EventDispatcher_once = false, + X_EventDispatcher_lock = false, + X_EventDispatcher_unlock = false, + X_EventDispatcher_needsIndex = false, X_EventDispatcher_safariPreventDefault = false, // Safari3- + + X_EventDispatcher_LAZY_TIMERS = {},// Object. number は timerID - /* @const */ - X_EventDispatcher_EVENT_TARGET_OTHER = 0, - /* @const */ - X_EventDispatcher_EVENT_TARGET_XHR = 1, - /* @const */ - X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT = 2, - - X_EventDispatcher_LAZY_TIMERS = {}; // Object. number は timerID + // iOS と MacOSX Iron36 で発生。連続してアニメーションが起こると、クロージャの束縛された obj へのアクセスに失敗する。Win では起きない? + // むしろ、MacOSX のブラウザ全般で起こる?? + X_EventDispatcher_ANIME_EVENTS = ( X_UA[ 'WebKit' ] || X_UA[ 'Blink' ] ) && { + 'transitionend' : true, 'webkitTransitionEnd' : true, 'mozTransitionEnd' : true, 'oTransitionEnd' : true, 'otransitionEnd' : true, + 'animationend' : true, 'webkitAnimationEnd' : true, 'oAnimationEnd' : true, + 'animationstart' : true, 'webkitAnimationStart' : true, 'oAnimationStart' : true, + 'animationiteration' : true, 'webkitAnimationIteration' : true, 'oAnimationIteration' : true + }; // ------------------------------------------------------------------------- // // --- interface ----------------------------------------------------------- // @@ -98,7 +98,9 @@ var X_EventDispatcher = X[ 'EventDispatcher' ] = { /** - * OTHER(Node,window,document,Image,Audio), XHR, Silverlight + * EventDispatcher がラップしている EventTarget オブジェクトのタイプです。
+ * X_EventDispatcher_actualAddEvent で使用されます。
+ * OTHER:0(node,window,document,Image,Audio), XHR:1, Silverlight:2 * @private * @type {number} */ @@ -106,7 +108,7 @@ var X_EventDispatcher = X[ 'EventDispatcher' ] = /** * イベントリスナをイベント名文字列や数値(5以上、フレームワーク内で定義)をキーとするArrayで記憶します。
- * Arrayには、{kind:種類,context:コンテキスト(thisObject),func:コールバック関数,supplement:サプリメントする引数の配列} というハッシュ、または関数が蓄えられています。 + * Arrayには、{cbKind:種類,context:コンテキスト(thisObject),func:コールバック関数,supplement:サプリメントする引数の配列} というハッシュ、または関数が蓄えられています。 * * @private * @type {__Listeners__} @@ -181,22 +183,23 @@ var X_EventDispatcher = X[ 'EventDispatcher' ] = if( !listeners || !( list = listeners[ opt_type ] ) ) return false; if( opt_arg1 === undefined ) return X_EventDispatcher_needsIndex ? 0 : true; - // TODO callbackHash か?判定が不十分! - if( opt_arg1.kind ){ + // TODO callbackHash か?判定が不十分! skipConvertion + if( opt_arg1.cbKind ){ cbHash = opt_arg1; } else { - cbHash = X_Callback_classifyCallbackArgs( opt_arg1, opt_arg2, opt_arg3, this ); + cbHash = X_Closure_classifyCallbackArgs( opt_arg1, opt_arg2, opt_arg3, this ); }; if( ( unlistens = listeners[ X_LISTENERS_UNLISTENS ] ) && ( unlistens = unlistens[ opt_type ] ) ){ for( i = unlistens.length; i; ){ f = unlistens[ --i ]; - if( f === cbHash || ( f.context === cbHash.context && f.func === cbHash.func && f.name === cbHash.name && f.supplement === cbHash.supplement && f.lock === lock ) ) return false; + if( f === cbHash || ( f.context === cbHash.context && f.func === cbHash.func && f.funcName === cbHash.funcName && f.supplement === cbHash.supplement && f.lock === lock ) ) return false; }; }; + for( i = list.length; i; ){ f = list[ --i ]; - if( f === cbHash || ( f.context === cbHash.context && f.func === cbHash.func && f.name === cbHash.name && f.supplement === cbHash.supplement && f.lock === lock ) ){ + if( f === cbHash || ( f.context === cbHash.context && f.func === cbHash.func && f.funcName === cbHash.funcName && f.supplement === cbHash.supplement && f.lock === lock ) ){ // index を要求された場合、lock されていない、または unlock なら index を返す return X_EventDispatcher_needsIndex ? i : true; }; @@ -220,6 +223,9 @@ var X_EventDispatcher = X[ 'EventDispatcher' ] = e = delay; delay = 0; }; + //{+dev + delay === undefined && eval( 'throw "asyncDispatch で undefined イベントが指定されました"' ); + //}+dev timerID = X_Timer_add( delay, 1, this, X_EventDispatcher_dispatch, [ e ] ); X_EventDispatcher_LAZY_TIMERS[ timerID ] = this; return timerID; @@ -242,11 +248,11 @@ var X_EventDispatcher = X[ 'EventDispatcher' ] = */ function X_EventDispatcher_dispatch( e ){ var listeners = this[ '_listeners' ], - ret = X_Callback_NONE, + ret = X_CALLBACK_NONE, type = e[ 'type' ], list, unlistens, i, l, args, f, r, sysOnly, timerID, k; - if( !listeners || !( list = listeners[ type || e ] ) ) return X_Callback_NONE; + if( !listeners || !( list = listeners[ type || e ] ) ) return X_CALLBACK_NONE; // 数値, 文字が渡された場合 if( !type ){ @@ -260,22 +266,24 @@ function X_EventDispatcher_dispatch( e ){ } else { listeners[ X_LISTENERS_DISPATCHING ] = 1; }; - - // todo: - // type も保存 - listeners[ X_LISTENERS_UNLISTENS ] = listeners[ X_LISTENERS_UNLISTENS ] || {}; - unlistens = listeners[ X_LISTENERS_UNLISTENS ][ type ]; + + //listeners[ X_LISTENERS_UNLISTENS ] = listeners[ X_LISTENERS_UNLISTENS ] || {}; + //unlistens = listeners[ X_LISTENERS_UNLISTENS ][ type ]; for( i = 0; i < list.length; ++i ){ f = list[ i ]; + // TODO removed フラグは? + if( f.removed ) continue; + /* if( !unlistens ){ unlistens = listeners[ X_LISTENERS_UNLISTENS ][ type ]; }; if( unlistens && unlistens.indexOf( f ) !== -1 ) continue; + */ - r = X_Callback_proxyCallback( f, args || ( args = [ e ] ) ) || 0; + r = X_Closure_proxyCallback( f, args || ( args = [ e ] ) ); - if( f.once || r & X_Callback_UN_LISTEN ){ + if( f.once || ( r & X_CALLBACK_UN_LISTEN ) ){ // dispatch 中に unlisten が作られることがある if( !unlistens ){ unlistens = listeners[ X_LISTENERS_UNLISTENS ] || ( listeners[ X_LISTENERS_UNLISTENS ] = {} ); @@ -285,7 +293,7 @@ function X_EventDispatcher_dispatch( e ){ }; ret |= X_Type_isFinite( r ) ? r : 0; - if( ( r & X_Callback_STOP_NOW ) === X_Callback_STOP_NOW ){ // iOS では ( & ) 括弧が無いと判定を誤る + if( ( r & X_CALLBACK_STOP_NOW ) === X_CALLBACK_STOP_NOW ){ // iOS では ( & ) 括弧が無いと判定を誤る sysOnly = true; break; }; @@ -365,10 +373,6 @@ function X_EventDispatcher_dispatch( e ){ * this[ 'listen' ]( [ 'open', 'close', 'ready' ], onUpdate ); * * @alias EventDispatcher.prototype.listen - * @param {string|number|Array.} type 配列を指定した場合、複数のイベントタイプに対して同じコールバックを登録する。 - * @param {listener|function|Array} [opt_arg1=] - * @param {function|Array} [opt_arg2=] - * @param {Array} [opt_arg3=] コールバック時の引数を配列に入れる。引数がひとつでも配列を使用する。省略した場合引数なし。 * @return {EventDispatcher} チェインメソッド */ function X_EventDispatcher_listen( type, opt_arg1, opt_arg2, opt_arg3 ){ @@ -400,7 +404,7 @@ function X_EventDispatcher_listen( type, opt_arg1, opt_arg2, opt_arg3 ){ add && X_EventDispatcher_actualAddEvent( this, type, raw, list ); - f = X_Callback_classifyCallbackArgs( opt_arg1, opt_arg2, opt_arg3, this ); + f = X_Closure_classifyCallbackArgs( opt_arg1, opt_arg2, opt_arg3, this ); list[ list.length ] = f; f.once = X_EventDispatcher_once; f.lock = X_EventDispatcher_lock; @@ -418,13 +422,10 @@ function X_EventDispatcher_systemListen( that, type, opt_arg1, opt_arg2, opt_arg }; /** - * イベントリスナの解除を行う。登録時と同じ引数を与える必要がある。kill() ですべてのイベントが解除されるので、途中で解除されるイベント以外は kill() に任せてしまってよい。 + * イベントリスナの解除を行う。登録時と同じ引数を与える必要がある。kill() で自信に登録されたすべてのイベントが解除されるので、途中で解除されるイベント以外は kill() に任せてしまってよい。
+ * 他人に登録したイベントを解除せずに kill するのは NG。 * @alias EventDispatcher.prototype.unlisten * @return {EventDispatcher} - * @param {string|number|Array.} opt_type イベントID, イベント名、またはその配列 - * @param {listener|function|Array} opt_arg1 - * @param {function|Array} opt_arg2 - * @param {Array} opt_arg3 */ function X_EventDispatcher_unlisten( opt_type, opt_arg1, opt_arg2, opt_arg3 ){ var listeners = this[ '_listeners' ], @@ -460,13 +461,17 @@ function X_EventDispatcher_unlisten( opt_type, opt_arg1, opt_arg2, opt_arg3 ){ f = ( list = listeners[ opt_type ] )[ i ]; - if( unlistens = listeners[ X_LISTENERS_UNLISTENS ] ){ + if( listeners[ X_LISTENERS_DISPATCHING ] ){ + unlistens = listeners[ X_LISTENERS_UNLISTENS ] || ( listeners[ X_LISTENERS_UNLISTENS ] = {} ); // _unlistens に入っている callbackHash は、lock のチェックは済んでいる ( unlistens = unlistens[ opt_type ] ) ? ( unlistens[ unlistens.length ] = f ) : ( listeners[ X_LISTENERS_UNLISTENS ][ opt_type ] = [ f ] ); + f.removed = true; } else { - delete f.once; + //delete f.once; + X_Object_clear( f ); + if( list.length !== 1 ){ list.splice( i, 1 ); } else { @@ -519,6 +524,7 @@ function X_EventDispatcher_unlistenAll( that ){ function X_EventDispatcher_actualAddEvent( that, type, raw, list ){ var i, f; + X_EventDispatcher_lock || ( type = X_Event_Rename[ type ] || type ); if( X_Type_isArray( type ) ){ @@ -535,28 +541,22 @@ function X_EventDispatcher_actualAddEvent( that, type, raw, list ){ if( X_UA_EVENT.W3C ){ switch( that[ '_rawType' ] ){ case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT : - list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); + list.slcallback = X_Closure_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); list.sltoken = raw[ 'AddEventListener' ]( type, list.slcallback ); break; case X_EventDispatcher_EVENT_TARGET_XHR : if( X_UA[ 'Opera' ] < 12 ){ // Opera11- の XHR は event オブジェクトが返らないため, eventType 毎に callback を指定する addEventListener もない - raw[ 'on' + type ] = X_Callback_create( that, X_EventDispatcher_dispatch, [ type ] ); + raw[ 'on' + type ] = X_Closure_create( that, X_EventDispatcher_dispatch, [ type ] ); break; }; default : - // iOS と MacOSX Iron36 で発生。連続してアニメーションが起こると、クロージャの束縛された obj へのアクセスに失敗する。Win では起きない? - // むしろ、MacOSX のブラウザ全般で起こる?? - if( ( X_UA[ 'WebKit' ] || X_UA[ 'Blink' ] ) && - ( type === 'webkitTransitionEnd' || type === 'transitionend' || - type === 'animationend' || type === 'webkitAnimationEnd' || - type === 'animationstart' || type === 'webkitAnimationStart' || - type === 'animationiteration' || type === 'webkitAnimationIteration' ) ){ + if( X_EventDispatcher_ANIME_EVENTS && X_EventDispatcher_ANIME_EVENTS[ type ] ){ raw.addEventListener( type, X_EventDispatcher_iOSTransitionEndDispatch, false ); } else { - f = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) ); + f = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Closure_create( that, X_EventDispatcher_actualHandleEvent ) ); if( raw.addEventListener ){ raw.addEventListener( type, f, false ); @@ -570,18 +570,18 @@ function X_EventDispatcher_actualAddEvent( that, type, raw, list ){ if( X_UA_EVENT.IE ){ switch( that[ '_rawType' ] ){ case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT : - list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); + list.slcallback = X_Closure_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); list.sltoken = raw[ 'AddEventListener' ]( type, list.slcallback ); break; case X_EventDispatcher_EVENT_TARGET_XHR : console.log( 'XHR addEvent ' + type ); // ie8- の XHR は window.event が更新されないため, eventType 毎に callback を指定する - raw[ 'on' + type ] = X_Callback_create( that, X_EventDispatcher_dispatch, [ type ] ); + raw[ 'on' + type ] = X_Closure_create( that, X_EventDispatcher_dispatch, [ type ] ); break; default : - f = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) ); + f = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Closure_create( that, X_EventDispatcher_actualHandleEvent ) ); if( raw.attachEvent ){ raw.attachEvent( 'on' + type, f ); @@ -594,17 +594,17 @@ function X_EventDispatcher_actualAddEvent( that, type, raw, list ){ switch( that[ '_rawType' ] ){ case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT : // DOM0 で Silverlight ってあるの -> ie4 mobile? - list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); + list.slcallback = X_Closure_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); list.sltoken = raw[ 'AddEventListener' ]( type, list.slcallback ); break; case X_EventDispatcher_EVENT_TARGET_XHR : // ie4 mobile は XHR をサポート! - raw[ 'on' + type ] = X_Callback_create( that, X_EventDispatcher_dispatch, [ type ] ); + raw[ 'on' + type ] = X_Closure_create( that, X_EventDispatcher_dispatch, [ type ] ); break; default : - raw[ 'on' + type ] = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) ); + raw[ 'on' + type ] = that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] || ( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] = X_Closure_create( that, X_EventDispatcher_actualHandleEvent ) ); break; }; } @@ -614,7 +614,7 @@ function X_EventDispatcher_actualAddEvent( that, type, raw, list ){ /* * iOS の webkitTransitionEnd が連続して起こる場合、 - * コールバックの(that[ X_LISTENERS_ACTUAL_HANDLER ])クロージャ内の実際のコールバック(X_Callback_actualClosure:obj._)が + * コールバックの(that[ X_LISTENERS_ACTUAL_HANDLER ])クロージャ内の実際のコールバック(X_Closure_actualClosure:obj._)が * 参照できていない問題に遭遇、、、iOS3.1.3 & iOS6.1.5 で確認 * animation も怪しい、、、 */ @@ -632,6 +632,7 @@ function X_EventDispatcher_sliverLightDispatch( sender, e, type ){ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ var i; + X_EventDispatcher_unlock || ( type = X_Event_Rename[ type ] || type ); if( X_Type_isArray( type ) ){ @@ -643,7 +644,7 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ switch( that[ '_rawType' ] ){ case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT : raw[ 'RemoveEventListener' ]( type, list.sltoken ); // token - X_Callback_correct( list.slcallback ); + X_Closure_correct( list.slcallback ); delete list.sltoken; delete list.slcallback; break; @@ -651,19 +652,15 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ case X_EventDispatcher_EVENT_TARGET_XHR : if( X_UA[ 'Opera' ] < 12 ){ // Opera11- の XHR は event オブジェクトが返らないため, eventType 毎に callback を指定する addEventListener もない - X_Callback_correct( raw[ 'on' + type ] ); + X_Closure_correct( raw[ 'on' + type ] ); raw[ 'on' + type ] = ''; break; }; default : - if( ( X_UA[ 'WebKit' ] || X_UA[ 'Blink' ] ) && - ( type === 'webkitTransitionEnd' || type === 'transitionend' || - type === 'animationend' || type === 'webkitAnimationEnd' || - type === 'animationstart' || type === 'webkitAnimationStart' || - type === 'animationiteration' || type === 'webkitAnimationIteration' ) ){ + if( X_EventDispatcher_ANIME_EVENTS && X_EventDispatcher_ANIME_EVENTS[ type ] ){ raw.removeEventListener( type, X_EventDispatcher_iOSTransitionEndDispatch, false ); - } else + } else if( raw.addEventListener ){ raw.removeEventListener( type, that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ], false ); } else { @@ -671,7 +668,7 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ }; if( !skip && that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ){ - X_Callback_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ); + X_Closure_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ); delete that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ]; }; }; @@ -680,13 +677,13 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ switch( that[ '_rawType' ] ){ case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT : raw[ 'RemoveEventListener' ]( type, list.sltoken ); // token - X_Callback_correct( list.slcallback ); + X_Closure_correct( list.slcallback ); delete list.sltoken; delete list.slcallback; break; case X_EventDispatcher_EVENT_TARGET_XHR : - X_Callback_correct( raw[ 'on' + type ] ); + X_Closure_correct( raw[ 'on' + type ] ); raw[ 'on' + type ] = X_emptyFunction; raw[ 'on' + type ] = ''; console.log( 'XHR rmEvent ' + type ); @@ -695,13 +692,14 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ default : if( raw.attachEvent ){ raw.detachEvent( 'on' + type, that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ); + console.log( 'raw rmEvent ' + type ); } else { raw[ 'on' + type ] = X_emptyFunction; raw[ 'on' + type ] = ''; }; if( !skip ){ - X_Callback_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ); + X_Closure_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ); delete that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ]; }; }; @@ -709,13 +707,13 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ switch( that[ '_rawType' ] ){ case X_EventDispatcher_EVENT_TARGET_SILVER_LIGHT : raw[ 'RemoveEventListener' ]( type, list.sltoken ); // token - X_Callback_correct( list.slcallback ); + X_Closure_correct( list.slcallback ); delete list.sltoken; delete list.slcallback; break; case X_EventDispatcher_EVENT_TARGET_XHR : - X_Callback_correct( raw[ 'on' + type ] ); + X_Closure_correct( raw[ 'on' + type ] ); raw[ 'on' + type ] = X_emptyFunction; raw[ 'on' + type ] = ''; break; @@ -725,7 +723,7 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ raw[ 'on' + type ] = ''; if( !skip ){ - X_Callback_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ); + X_Closure_correct( that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ] ); delete that[ '_listeners' ][ X_LISTENERS_ACTUAL_HANDLER ]; }; }; @@ -735,6 +733,7 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ // TODO ブラウザからの呼び出しの最後に登録された関数を呼び出す機能(例えば画面の更新) +var X_EventDispatcher_CURRENT_EVENTS = []; // handleEvent を拡張可能にするために、クロージャに移動した // Is this in regard to the Safari 1.x preventDefault bug on click/dblclick? @@ -742,14 +741,19 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ var X_EventDispatcher_actualHandleEvent = X_UA_EVENT.IE4 || X_UA_EVENT.IE ? // ie45678 EVENT_IE & EVENT_DOM0 for ie4 (function(){ - var e = event, ret; + var e = event, ret, + ev = new X_DomEvent( e, this, this[ '_rawObject' ] ); + + X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length ] = ev; - ret = this[ 'dispatch' ]( new X_DomEvent( e, this, this[ '_rawObject' ] ) ); + ret = this[ 'dispatch' ]( ev ); - if( ret & X_Callback_STOP_PROPAGATION ){ + --X_EventDispatcher_CURRENT_EVENTS.length; + + if( ret & X_CALLBACK_STOP_PROPAGATION ){ e.cancelBubble = true; }; - if( ret & X_Callback_PREVENT_DEFAULT ){ + if( ret & X_CALLBACK_PREVENT_DEFAULT ){ this[ '_tag' ] === 'A' && this[ '_rawObject' ].blur(); return e.returnValue = false; }; @@ -757,14 +761,16 @@ var X_EventDispatcher_actualHandleEvent = //X_UA_EVENT.W3C || X_UA_EVENT.DOM0 (function( e ){ var ev = new X_DomEvent( e, this ), - ret = X_Callback_NONE, + ret = X_CALLBACK_NONE, i, l; - //console.log( '>>>>>>>>>> ' + e.type ); + + X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length ] = ev; + // touch event -> pointer if( X_Type_isArray( ev ) ){ if( ev.length === 0 ){ // TouchEvent の後に発生した MouseEvent のキャンセル - ret = X_Callback_STOP_PROPAGATION | X_Callback_PREVENT_DEFAULT; + ret = X_CALLBACK_STOP_PROPAGATION | X_CALLBACK_PREVENT_DEFAULT; } else { for( i = 0, l = ev.length; i < l; ++i ){ //console.log( 'handleEvent ' + ev[ i ].type ); @@ -775,10 +781,12 @@ var X_EventDispatcher_actualHandleEvent = ret = this[ 'dispatch' ]( ev ); }; - if( ret & X_Callback_STOP_PROPAGATION ){ + --X_EventDispatcher_CURRENT_EVENTS.length; + + if( ret & X_CALLBACK_STOP_PROPAGATION ){ e.stopPropagation(); }; - if( ret & X_Callback_PREVENT_DEFAULT ){ + if( ret & X_CALLBACK_PREVENT_DEFAULT ){ this[ '_tag' ] === 'A' && this[ '_rawObject' ].blur(); e.preventDefault(); if( X_UA[ 'WebKit' ] < 525.13 ){ // Safari3-