*/\r
X_Timer_now = Date.now || ( function(){ return +new Date; } ),\r
\r
- X_Timer_SET_TIMEOUT = window.setTimeout,\r
- X_Timer_CLEAR_TIMEOUT = window.clearTimeout,\r
-\r
+ // TODO X.AF.request, X.AF.cancel\r
// http://uupaa.hatenablog.com/entry/2012/02/01/083607\r
// Firefox 4 partial (request only), Mobile Firefox5 ready (request only), Firefox 11 ready (cancel impl) \r
X_Timer_REQ_ANIME_FRAME =\r
false,\r
\r
X_Timer_CANCEL_ANIME_FRAME =\r
+ window.cancelAnimationFrame ||\r
window.cancelRequestAnimationFrame ||\r
window.webkitCancelAnimationFrame ||\r
window.webkitCancelRequestAnimationFrame ||\r
var i = X_Timer_REQ_FRAME_LIST.length,\r
f;\r
i === 0 && ( X_Timer_requestID = X_Timer_REQ_ANIME_FRAME( X_Timer_onEnterFrame ) );\r
- f = X_Callback_classifyCallbackArgs( args1, args2, args3 );\r
- if( !f.kind ) f = { func : f };\r
+ f = X_Closure_classifyCallbackArgs( args1, args2, args3 );\r
+ if( !f.cbKind ) f = { func : f };\r
X_Timer_REQ_FRAME_LIST[ i ] = f;\r
- return f.uid = ++X_Timer_uid;\r
+ return f._uid = ++X_Timer_uid;\r
}) :\r
(function( args1, args2, args3 ){\r
var i = X_Timer_REQ_FRAME_LIST.length,\r
f;\r
i === 0 && ( X_Timer_requestID = X_Timer_add( 0, 1, X_Timer_onEnterFrame ) );\r
- f = X_Callback_classifyCallbackArgs( args1, args2, args3 );\r
- if( !f.kind ) f = { func : f };\r
+ f = X_Closure_classifyCallbackArgs( args1, args2, args3 );\r
+ if( !f.cbKind ) f = { func : f };\r
X_Timer_REQ_FRAME_LIST[ i ] = f;\r
- return f.uid = ++X_Timer_uid;\r
+ return f._uid = ++X_Timer_uid;\r
}),\r
\r
/**\r
X_Timer_removal[ uid ] = true;\r
} else {\r
for( ; i; ){\r
- if( ( f = list[ --i ] ).uid < uid ) break;\r
- if( f.uid == uid ){\r
+ if( ( f = list[ --i ] )._uid < uid ) break;\r
+ if( f._uid == uid ){\r
list.splice( i, 1 );\r
// gecko では cancelRequestAnimationFrame が無い場合がある\r
l === 1 && X_Timer_CANCEL_ANIME_FRAME && X_Timer_CANCEL_ANIME_FRAME( X_Timer_requestID );\r
X_Timer_removal[ uid ] = true;\r
} else {\r
for( ; i; ){\r
- if( ( f = list[ --i ] ).uid < uid ) break;\r
- if( f.uid == uid ){\r
+ if( ( f = list[ --i ] )._uid < uid ) break;\r
+ if( f._uid == uid ){\r
list.splice( i, 1 );\r
l === 1 && X_Timer_remove( X_Timer_requestID );\r
break;\r
* @alias X.Timer\r
*/ \r
X[ 'Timer' ] = {\r
+ // TODO IE4 の resolution は 64ms\r
+ 'RESOLUTION' : X_Timer_INTERVAL_TIME,\r
\r
'now' : X_Timer_now,\r
\r
function X_Timer_add( time, opt_count, args1, args2, args3 ){\r
var list = X_Timer_TICKET_LIST,\r
hash, obj;\r
+\r
time = time < X_Timer_INTERVAL_TIME ? 1 : time / X_Timer_INTERVAL_TIME | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
\r
if( !X_Type_isNumber( opt_count ) ){\r
opt_count = 0;\r
};\r
\r
- hash = X_Callback_classifyCallbackArgs( args1, args2, args3 );\r
+ hash = X_Closure_classifyCallbackArgs( args1, args2, args3 );\r
if( !hash ) return -1; // dev only\r
\r
- if( !hash.kind ) hash = { func : hash };\r
- hash.time = time;\r
- hash.last = time;\r
- hash.count = opt_count;\r
- hash.uid = ++X_Timer_uid;\r
+ if( !hash.cbKind ) hash = { func : hash };\r
+ hash._time = time;\r
+ hash.last = time;\r
+ hash._count = opt_count;\r
+ hash._uid = ++X_Timer_uid;\r
list[ list.length ] = hash;\r
\r
!X_Timer_busyTimeout && X_Timer_update();\r
X_Timer_removal[ uid ] = true;\r
} else {\r
for( ; i; ){\r
- if( ( q = list[ --i ] ).uid == uid ){ // 数字の場合と文字の場合がある\r
+ if( ( q = list[ --i ] )._uid == uid ){ // 数字の場合と文字の場合がある\r
list.splice( i, 1 );\r
\r
/*\r
};\r
\r
if( X_UA[ 'IE4' ] || X_UA[ 'MacIE' ] ){\r
- X.Timer[ '_' ] = X_Timer_onTimeout;\r
+ X[ 'Timer' ][ '_' ] = X_Timer_onTimeout;\r
X_Timer_onTimeout = 'X.Timer._()';\r
};\r
\r
for( ; i < l; ++i ){\r
q = list[ i ];\r
if(\r
- ( X_Timer_removal && X_Timer_removal[ q.uid ] ) || // timerId は remove 登録されている\r
+ ( X_Timer_removal && X_Timer_removal[ q._uid ] ) || // timerId は remove 登録されている\r
0 < ( q.last -= minus ) || // 時間が経過していない\r
heavy && ( q.last = 1 ) // 時間は経過したが、ヘビーフラグが立っている\r
){\r
continue;\r
};\r
- c = q.count;\r
+ c = q._count;\r
\r
- X_Timer_currentUID = q.uid;\r
+ X_Timer_currentUID = q._uid;\r
\r
- if( q.kind ){\r
- r = X_Callback_proxyCallback( q, [] );\r
+ if( q.cbKind ){\r
+ r = X_Closure_proxyCallback( q, [] );\r
} else {\r
r = q.func();\r
};\r
heavy = true;\r
};\r
\r
- if( r & X_Callback_UN_LISTEN || c === 1 ){\r
+ if( r & X_CALLBACK_UN_LISTEN || c === 1 ){\r
list.splice( i, 1 );\r
--i;\r
--l;\r
continue;\r
} else\r
- if( 1 < c ) --q.count;\r
- q.last = q.time;\r
+ if( 1 < c ) --q._count;\r
+ q.last = q._time;\r
};\r
X_Timer_timerId = X_Timer_currentUID = 0;\r
X_Timer_busyTimeout = false;\r
i = list.length,\r
n;\r
if( i === 0 ){\r
- X_Timer_timerId && X_Timer_CLEAR_TIMEOUT( X_Timer_timerId );\r
+ X_Timer_timerId && clearTimeout( X_Timer_timerId );\r
X_Timer_timerId = 0;\r
return;\r
};\r
\r
1 < i && list.sort( X_Timer_compareQueue );\r
\r
- n = list[ i - 1 ].last;\r
+ n = list[ 0 ].last;\r
\r
if( n < X_Timer_waitTime || X_Timer_timerId === 0 ){\r
if( X_Timer_timerId ){\r
- X_Timer_CLEAR_TIMEOUT( X_Timer_timerId );\r
- n -= ( X_Timer_now() - X_Timer_timeStamp ) / X_Timer_INTERVAL_TIME | 0;\r
+ clearTimeout( X_Timer_timerId );\r
+ n -= ( X_Timer_now() - X_Timer_timeStamp ) / X_Timer_INTERVAL_TIME;\r
0 <= n || ( n = 0 ); // 負の数は 0 に\r
};\r
X_Timer_timeStamp = X_Timer_now();\r
- X_Timer_timerId = X_Timer_SET_TIMEOUT( X_Timer_onTimeout, X_Timer_INTERVAL_TIME * n );\r
+ X_Timer_timerId = setTimeout( X_Timer_onTimeout, X_Timer_INTERVAL_TIME * n | 0 );\r
X_Timer_waitTime = n;\r
};\r
};\r
\r
-// 大きい -> 小さい\r
+// 小さい -> 大きい、 同値の場合 uid の小さいものが先\r
+// http://jsfiddle.net/warby_/X8YUZ/ Chrome で return が 0 の場合の挙動が他のブラウザと異なる\r
function X_Timer_compareQueue( a, b ){\r
- return a.last < b.last ? 1 : a.last === b.last ? 0 : -1;\r
+ if( a.last === b.last ){ // Chrome のみ\r
+ return a._uid - b._uid;\r
+ };\r
+ return a.last - b.last;\r
+ // return a.last <= b.last ? -1 : 1; //a.last === b.last ? 0 : 1;\r
};\r
\r
// http://havelog.ayumusato.com/develop/javascript/e528-ios6_scrolling_timer_notcall.html\r
window.addEventListener( 'scroll', function(){\r
var last, now;\r
if( X_Timer_timerId ){\r
- X_Timer_CLEAR_TIMEOUT( X_Timer_timerId );\r
+ clearTimeout( X_Timer_timerId );\r
now = X_Timer_now();\r
last = X_Timer_timeStamp + X_Timer_INTERVAL_TIME * X_Timer_waitTime - now;\r
- X_Timer_timerId = X_Timer_SET_TIMEOUT( X_Timer_onTimeout, 0 < last ? last : 0 );\r
+ X_Timer_timerId = setTimeout( X_Timer_onTimeout, 0 < last ? last : 0 );\r
// 更新\r
X_Timer_timeStamp = now;\r
X_Timer_waitTime = last / X_Timer_INTERVAL_TIME | 0;\r
for( ; i < l; ++i ){\r
q = list[ i ];\r
\r
- if( X_Timer_removal && X_Timer_removal[ q.uid ] ) continue;\r
+ if( X_Timer_removal && X_Timer_removal[ q._uid ] ) continue;\r
\r
- if( q.kind ){\r
- X_Callback_proxyCallback( q, args || ( args = [ time ] ) );\r
+ if( q.cbKind ){\r
+ X_Closure_proxyCallback( q, args || ( args = [ time ] ) );\r
} else {\r
q.func( time );\r
};\r