1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Provides a countdown-based timer.
*/
'use strict';
/**
* A countdown timer.
* @interface
*/
function Countdown() {}
/**
* Sets a new timeout for this timer.
* @param {number} timeoutMillis how long, in milliseconds, the countdown lasts.
* @param {Function=} cb called back when the countdown expires.
* @return {boolean} whether the timeout could be set.
*/
Countdown.prototype.setTimeout = function(timeoutMillis, cb) {};
/** Clears this timer's timeout. Timers that are cleared become expired. */
Countdown.prototype.clearTimeout = function() {};
/**
* @return {number} how many milliseconds are remaining until the timer expires.
*/
Countdown.prototype.millisecondsUntilExpired = function() {};
/** @return {boolean} whether the timer has expired. */
Countdown.prototype.expired = function() {};
/**
* Constructs a new clone of this timer, while overriding its callback.
* @param {Function=} cb callback for new timer.
* @return {!Countdown} new clone.
*/
Countdown.prototype.clone = function(cb) {};
/**
* A factory to create countdown timers.
* @interface
*/
function CountdownFactory() {}
/**
* Creates a new timer.
* @param {number} timeoutMillis How long, in milliseconds, the countdown lasts.
* @param {function()=} opt_cb Called back when the countdown expires.
* @return {Countdown} The timer.
*/
CountdownFactory.prototype.createTimer = function(timeoutMillis, opt_cb) {};
/**
* Constructs a new timer. The timer has a very limited resolution, and does
* not attempt to be millisecond accurate. Its intended use is as a
* low-precision timer that pauses while debugging.
* @param {number=} timeoutMillis how long, in milliseconds, the countdown
* lasts.
* @param {Function=} cb called back when the countdown expires.
* @constructor
* @implements {Countdown}
*/
function CountdownTimer(timeoutMillis, cb) {
this.remainingMillis = 0;
this.setTimeout(timeoutMillis || 0, cb);
}
/** Timer interval */
CountdownTimer.TIMER_INTERVAL_MILLIS = 200;
/**
* Sets a new timeout for this timer. Only possible if the timer is not
* currently active.
* @param {number} timeoutMillis how long, in milliseconds, the countdown lasts.
* @param {Function=} cb called back when the countdown expires.
* @return {boolean} whether the timeout could be set.
*/
CountdownTimer.prototype.setTimeout = function(timeoutMillis, cb) {
if (this.timeoutId)
return false;
if (!timeoutMillis || timeoutMillis < 0)
return false;
this.remainingMillis = timeoutMillis;
this.cb = cb;
if (this.remainingMillis > CountdownTimer.TIMER_INTERVAL_MILLIS) {
this.timeoutId =
window.setInterval(this.timerTick.bind(this),
CountdownTimer.TIMER_INTERVAL_MILLIS);
} else {
// Set a one-shot timer for the last interval.
this.timeoutId =
window.setTimeout(this.timerTick.bind(this), this.remainingMillis);
}
return true;
};
/** Clears this timer's timeout. Timers that are cleared become expired. */
CountdownTimer.prototype.clearTimeout = function() {
if (this.timeoutId) {
window.clearTimeout(this.timeoutId);
this.timeoutId = undefined;
}
this.remainingMillis = 0;
};
/**
* @return {number} how many milliseconds are remaining until the timer expires.
*/
CountdownTimer.prototype.millisecondsUntilExpired = function() {
return this.remainingMillis > 0 ? this.remainingMillis : 0;
};
/** @return {boolean} whether the timer has expired. */
CountdownTimer.prototype.expired = function() {
return this.remainingMillis <= 0;
};
/**
* Constructs a new clone of this timer, while overriding its callback.
* @param {Function=} cb callback for new timer.
* @return {!Countdown} new clone.
*/
CountdownTimer.prototype.clone = function(cb) {
return new CountdownTimer(this.remainingMillis, cb);
};
/** Timer callback. */
CountdownTimer.prototype.timerTick = function() {
this.remainingMillis -= CountdownTimer.TIMER_INTERVAL_MILLIS;
if (this.expired()) {
window.clearTimeout(this.timeoutId);
this.timeoutId = undefined;
if (this.cb) {
this.cb();
}
}
};
/**
* A factory for creating CountdownTimers.
* @constructor
* @implements {CountdownFactory}
*/
function CountdownTimerFactory() {
}
/**
* Creates a new timer.
* @param {number} timeoutMillis How long, in milliseconds, the countdown lasts.
* @param {function()=} opt_cb Called back when the countdown expires.
* @return {Countdown} The timer.
*/
CountdownTimerFactory.prototype.createTimer =
function(timeoutMillis, opt_cb) {
return new CountdownTimer(timeoutMillis, opt_cb);
};
|