1
YUI.add('gallery-timer', function(Y) {
4
* Losely modeled after AS3's Timer class. Provides a simple interface start,
5
* pause, resume, and stop a defined timer set with a custom callback method.
7
* @author Anthony Pipkin
11
* Losely modeled after AS3's Timer class. Provides a simple interface start,
12
* pause, resume, and stop a defined timer set with a custom callback method.
18
var STATUS_RUNNING = 'running',
19
STATUS_PAUSED = 'paused',
20
STATUS_STOPPED = 'stopped',
22
EVENT_START = 'start',
24
EVENT_PAUSE = 'pause',
25
EVENT_RESUME = 'resume',
26
EVENT_TIMER = 'timer';
29
Y.Timer = Y.Base.create('timer', Y.Base, [] , {
33
* @description The timer has started
34
* @param {Event.Facade} event An Event Facade object
35
* @type {Event.Custom}
40
* @description The timer has stopped
41
* @param {Event.Facade} event An Event Facade object
42
* @type {Event.Custom}
47
* @description The timer has paused
48
* @param {Event.Facade} event An Event Facade object
49
* @type {Event.Custom}
54
* @description The timer has resumed
55
* @param {Event.Facade} event An Event Facade object
56
* @type {Event.Custom}
60
* Fires at every interval of Y.Timer
62
* @description The timer has reached a reached zero
63
* @param {Event.Facade} event An Event Facade object
64
* @type {Event.Custom}
67
////// P U B L I C //////
70
* Initializer lifecycle implementation for the Timer class.
71
* Publishes events and subscribes
72
* to update after the status is changed.
76
* @param config {Object} Configuration object literal for
80
initializer : function(config){
81
this.after('statusChange',this._afterStatusChange,this);
82
this.publish(EVENT_START , { defaultFn : this._defStartFn });
83
this.publish(EVENT_STOP , { defaultFn : this._defStopFn });
84
this.publish(EVENT_PAUSE , { defaultFn : this._defPauseFn });
85
this.publish(EVENT_RESUME , { defaultFn : this._defResumeFn });
89
* Interface method to start the Timer. Fires timer:start
96
Y.log('Timer::start','info');
97
if(this.get('status') !== STATUS_RUNNING) {
98
this.fire(EVENT_START);
105
* Interface method to stop the Timer. Fires timer:stop
112
Y.log('Timer::stop','info');
113
if(this.get('status') === STATUS_RUNNING) {
114
this.fire(EVENT_STOP);
121
* Interface method to pause the Timer. Fires timer:pause
128
Y.log('Timer::pause','info');
129
if(this.get('status') === STATUS_RUNNING) {
130
this.fire(EVENT_PAUSE);
137
* Interface method to resume the Timer. Fires timer:resume
143
resume : function() {
144
Y.log('Timer::resume','info');
145
if(this.get('status') === STATUS_PAUSED) {
146
this.fire(EVENT_RESUME);
153
////// P R O T E C T E D //////
158
* @property {Y.later} _timerObj
167
* @property _remainingLength
171
_remainingLength: null,
174
* Checks to see if a new Timer is to be created. If so, calls
175
* _timer() after a the schedule number of milliseconds. Sets
176
* Timer pointer to the new Timer id. Sets start to the current
183
_makeTimer : function() {
184
Y.log('Timer::_makeTimer','info');
185
var timerObj = this._timerObj,
186
repeat = this.get('repeatCount');
191
this._timerObj = null;
194
if(repeat === 0 || repeat > this.get('step')) {
195
timerObj = Y.later(this._remainingLength, this, this._timer);
198
this._timerObj = timerObj;
199
this.set('timer', timerObj);
200
this.set('start', (new Date()).getTime());
201
this.set('stop', this.get('start'));
207
* @method _destroyTimer
211
_destroyTimer : function() {
212
Y.log('Timer::_destroyTimer','info');
213
var timerObj = this._timerObj;
218
this._timerObj = null;
221
this.set('timer', null);
222
this.set('stop', (new Date()).getTime());
225
this._remainingLength = this._remainingLength - (this.get('stop') - this.get('start'));
230
* Increments the step and either stops or starts a new Timer
231
* interval. Fires the timer callback method.
237
_timer : function() {
238
Y.log('Timer::_timer','info');
239
this.fire(EVENT_TIMER);
241
var step = this.get('step'),
242
repeat = this.get('repeatCount');
244
this.set('step', ++step);
246
if(repeat > 0 && repeat <= step) { // repeat at 0 is infinite loop
247
this._remainingLength = 0;
250
this._remainingLength = this.get('length');
254
this._executeCallback();
258
* Internal status change event callback. Allows status changes
259
* to fire start(), pause(), resume(), and stop() automatically.
261
* @method _statusChanged
265
_afterStatusChange : function(e){
266
Y.log('Timer::_afterStatusChange','info');
271
case STATUS_STOPPED: // overflow intentional
273
this._destroyTimer();
279
* Default function for start event.
281
* @method _defStartFn
285
_defStartFn : function(e) {
286
Y.log('Timer::_defStartFn','info');
287
var delay = this.get('startDelay');
289
this._remainingLength = this.get('length');
292
Y.later(delay, this, function(){
293
this.set('status', STATUS_RUNNING);
296
this.set('status', STATUS_RUNNING);
301
* Default function for stop event.
307
_defStopFn : function(e) {
308
Y.log('Timer::_defStopFn','info');
310
this._remainingLength = 0;
311
this.set('status', STATUS_STOPPED);
315
* Default function for pause event.
317
* @method _defPauseFn
321
_defPauseFn : function(e) {
322
Y.log('Timer::_defPauseFn','info');
323
this.set('status', STATUS_PAUSED);
327
* Default function for resume event. Starts timer with
328
* remaining time left after Timer was paused.
330
* @method _defResumeFn
334
_defResumeFn : function(e) {
335
Y.log('Timer::_defResumeFn','info');
336
this.set('status',STATUS_RUNNING);
340
* Abstracted the repeatCount validator into the prototype to
341
* encourage class extension.
343
* @method _repeatCountValidator
347
_repeatCountValidator : function(val) {
348
Y.log('Timer::_repeatCountValidator','info');
349
return (this.get('status') === STATUS_STOPPED);
353
* Used to fire the internal callback
355
* @method _executeCallback
359
_executeCallback : function() {
360
Y.log('Timer::_executeCallback','info');
361
var callback = this.get('callback');
362
if (Y.Lang.isFunction(callback)) {
363
(this.get('callback'))();
368
* Returns the time from `now` if the timer is running and returns remaining
369
* time from `stop` if the timer has stopped.
370
* @method _remainingGetter
374
_remainingGetter: function(){
375
Y.log('Timer::_remainingGetter', 'info');
376
var status = this.get('status'),
377
length = this._remainingLength,
378
maxTime = (new Date()).getTime();
380
if (status === STATUS_STOPPED) {
382
} else if (status === STATUS_PAUSED) {
385
return length - ( maxTime - this.get('start') );
391
* Static property used to define the default attribute
392
* configuration for the Timer.
401
* @description The callback method that fires when the
402
* timer interval is reached.
404
* @attribute callback
410
validator : Y.Lang.isFunction
414
* Time in milliseconds between intervals
422
setter : function(val) {
423
return parseInt(val,10);
428
* Get remaining milliseconds
430
* @attribute remaining
436
getter: '_remainingGetter'
440
* Number of times the Timer should fire before it stops
441
* - 1.1.0 - added lazyAdd false to prevent starting from
442
* overriding the validator
443
* @attribute repeatCount
448
validator : 'repeatCountValidator',
449
setter : function(val) {
450
return parseInt(val,10);
457
* Timestamp Timer was started
468
* Time in ms to wait until starting after start() has been called
469
* @attribute startDelay
479
* - 1.1.0 - Changed from state to status. state was left
482
* @default STATUS_STOPPED
487
value : STATUS_STOPPED,
492
* Number of times the Timer has looped
498
step : { // number of intervals passed
504
* Timestamp Timer was stoped or paused
515
* Timer id to used during stop()
527
* Static property provides public access to registered timer
530
* @property Timer.STATUS
535
RUNNING : STATUS_RUNNING,
536
PAUSED : STATUS_PAUSED,
537
STOPPED : STATUS_STOPPED
541
* Static property provides public access to registered timer
544
* @property Timer.EVENTS
552
RESUME : EVENT_RESUME,
559
}, 'gallery-2012.07.25-21-36' ,{requires:['base-build','event-custom']});