Elim cr-checkbox
[chromium-blink-merge.git] / chrome / test / data / webui / mock_timer.js
blob37f5f6cfe130bb49606e90a2f4357270bd1d0dcb
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6 * Overrides timeout and interval callbacks to mock timing behavior.
7 * @constructor
8 */
9 function MockTimer() {
10 /**
11 * Default versions of the timing functions.
12 * @type {Object<string, !Function>}
13 * @private
15 this.originals_ = [];
17 /**
18 * Key to assign on the next creation of a scheduled timer. Each call to
19 * setTimeout or setInterval returns a unique key that can be used for
20 * clearing the timer.
21 * @type {number}
22 * @private
24 this.nextTimerKey_ = 1;
26 /**
27 * Details for active timers.
28 * @type {Array<{callback: Function,
29 * delay: number,
30 * key: number,
31 * repeats: boolean}>}
32 * @private
34 this.timers_ = [];
36 /**
37 * List of scheduled tasks.
38 * @type {Array<{when: number, key: number}>}
39 * @private
41 this.schedule_ = [];
43 /**
44 * Virtual elapsed time in milliseconds.
45 * @type {number}
46 * @private
48 this.now_ = 0;
50 /**
51 * Used to control when scheduled callbacks fire. Calling the 'tick' method
52 * inflates this parameter and triggers callbacks.
53 * @type {number}
54 * @private
56 this.until_ = 0;
59 MockTimer.prototype = {
60 /**
61 * Replaces built-in functions for scheduled callbacks.
63 install: function() {
64 this.replace_('setTimeout', this.setTimeout_.bind(this));
65 this.replace_('clearTimeout', this.clearTimeout_.bind(this));
66 this.replace_('setInterval', this.setInterval_.bind(this));
67 this.replace_('clearInterval', this.clearInterval_.bind(this));
70 /**
71 * Restores default behavior for scheduling callbacks.
73 uninstall: function() {
74 if (this.originals_) {
75 for (var key in this.originals_) {
76 window[key] = this.originals_[key];
81 /**
82 * Overrides a global function.
83 * @param {string} functionName The name of the function.
84 * @param {!Function} replacementFunction The function override.
85 * @private
87 replace_: function(functionName, replacementFunction) {
88 this.originals_[functionName] = window[functionName];
89 window[functionName] = replacementFunction;
92 /**
93 * Creates a virtual timer.
94 * @param {!Function} callback The callback function.
95 * @param {number} delayInMs The virtual delay in milliseconds.
96 * @param {boolean} repeats Indicates if the timer repeats.
97 * @return {number} Idetifier for the timer.
98 * @private
100 createTimer_: function(callback, delayInMs, repeats) {
101 var key = this.nextTimerKey_++;
102 var task = {
103 callback: callback,
104 delay: delayInMs,
105 key: key,
106 repeats: repeats
108 this.timers_[key] = task;
109 this.scheduleTask_(task);
110 return key;
114 * Schedules a callback for execution after a virtual time delay. The tasks
115 * are sorted in descending order of time delay such that the next callback
116 * to fire is at the end of the list.
117 * @param {{callback: Function,
118 * delay: number,
119 * key: number,
120 * repeats: boolean}} details The timer details.
121 * @private
123 scheduleTask_: function(details) {
124 var key = details.key;
125 var when = this.now_ + details.delay;
126 var index = this.schedule_.length;
127 while (index > 0 && this.schedule_[index - 1].when < when) {
128 index--;
130 this.schedule_.splice(index, 0, {when: when, key: key});
134 * Override of window.setInterval.
135 * @param {!Function} callback The callback function.
136 * @param {number} intervalInMs The repeat interval.
137 * @private
139 setInterval_: function(callback, intervalInMs) {
140 return this.createTimer_(callback, intervalInMs, true);
144 * Override of window.clearInterval.
145 * @param {number} key The ID of the interval timer returned from
146 * setInterval.
147 * @private
149 clearInterval_: function(key) {
150 this.timers_[key] = undefined;
154 * Override of window.setTimeout.
155 * @param {!Function} callback The callback function.
156 * @param {number} delayInMs The scheduled delay.
157 * @private
159 setTimeout_: function(callback, delayInMs) {
160 return this.createTimer_(callback, delayInMs, false);
164 * Override of window.clearTimeout.
165 * @param {number} key The ID of the schedule timeout callback returned
166 * from setTimeout.
167 * @private
169 clearTimeout_: function(key) {
170 this.timers_[key] = undefined;
174 * Simulates passage of time, triggering any scheduled callbacks whose timer
175 * has elapsed.
176 * @param {number} elapsedMs The simulated elapsed time in milliseconds.
178 tick: function(elapsedMs) {
179 this.until_ += elapsedMs;
180 this.fireElapsedCallbacks_();
184 * Triggers any callbacks that should have fired based in the simulated
185 * timing.
186 * @private
188 fireElapsedCallbacks_: function() {
189 while (this.schedule_.length > 0) {
190 var when = this.schedule_[this.schedule_.length - 1].when;
191 if (when > this.until_)
192 break;
194 var task = this.schedule_.pop();
195 var details = this.timers_[task.key];
196 if (!details)
197 continue; // Cancelled task.
199 this.now_ = when;
200 details.callback.apply(window);
201 if (details.repeats)
202 this.scheduleTask_(details);
203 else
204 this.clearTimeout_(details.key);
206 this.now_ = this.until_;