OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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. | |
4 | |
5 /** | |
6 * Constructor for the tab UI governing playback selection and running. | |
7 * All HTML controls under tag #plaback-tab, plus the tab label | |
8 * #playback-tab-label are controlled by this class. | |
9 * @param {!Object} cyclerUI The master UI class, needed for global state | |
10 * such as current capture name. | |
11 * @param {!Object} cyclerData The local FileSystem-based database of | |
12 * available captures to play back. | |
13 */ | |
14 var PlaybackTab = function (cyclerUI, cyclerData) { | |
15 /** | |
16 * Enum for different playback tab states. | |
17 * @enum {number} | |
18 * @private | |
19 */ | |
20 var EnableState_ = { | |
21 choosePlayback: 1, // Choose a playback, if none already chosen. | |
22 showPlayback: 2, // Show currently chosen playback, and offer options. | |
23 showNoCaptures: 3 // Show message indicating no captures are available. | |
24 }; | |
25 | |
26 this.cyclerUI_ = cyclerUI; | |
27 this.cyclerData_ = cyclerData; | |
28 | |
29 /** | |
30 * Create members for all UI elements with which we'll interact. | |
31 */ | |
32 this.tabLabel_ = $('#playback-tab-label'); | |
33 this.playbackTab_ = $('#playback-tab'); | |
34 this.noCaptures_ = $('#no-captures'); | |
35 this.yesCaptures_ = $('#have-captures'); | |
36 | |
37 this.playbackName_ = $('#playback-name'); | |
38 this.playbackDetails_ = $('#playback-details'); | |
39 this.playbackURLs_ = $('#playback-urls'); | |
40 this.playbackRepeats_ = $('#playback-repeats'); | |
41 this.playbackExtension_ = $('#playback-extension'); | |
42 this.doPlaybackButton_ = $('#do-playback'); | |
43 this.doDeleteButton_ = $('#do-delete'); | |
44 | |
45 /* | |
46 * Enable the playback tab, showing no current playback choice, by | |
47 * hiding the playbackDetails_ div. | |
48 * @private | |
49 */ | |
50 this.enableChoosePlayback_ = function() { | |
51 if (this.enableState != EnableState_.choosePlayback) { | |
52 this.enableState = EnableState_.choosePlayback; | |
53 this.yesCaptures_.hidden = false; | |
54 this.noCaptures_.hidden = true; | |
55 this.playbackDetails_.hidden = true; | |
56 } | |
57 }; | |
58 | |
59 /* | |
60 * Enable the playback tab, showing a current playback choice by showing | |
61 * the playbackDetails_ div. | |
62 * @private | |
63 */ | |
64 this.enableShowPlayback_ = function() { | |
65 if (this.enableState != EnableState_.showPlayback) { | |
66 this.enableState = EnableState_.showPlayback; | |
67 this.yesCaptures_.hidden = false; | |
68 this.noCaptures_.hidden = true; | |
69 this.playbackDetails_.hidden = false; | |
70 } | |
71 }; | |
72 | |
73 /* | |
74 * Enable the playback tab and adjust tab labels appropriately. Show | |
75 * no available captures by hiding the yesCaptures_ div and showing the | |
76 * noCaptures_ div instead. | |
77 * @private | |
78 */ | |
79 this.enableShowNoCaptures_ = function() { | |
80 if (this.enableState != EnableState_.showNoCaptures) { | |
81 this.enableState = EnableState_.showNoCaptures; | |
82 this.noCaptures_.hidden = false; | |
83 this.yesCaptures_.hidden = true; | |
84 } | |
85 }; | |
86 | |
87 /** | |
88 * Enable the playback tab, showing either its "no captures", "choose | |
89 * a capture" or "display chosen capture" form, depending on the state | |
90 * of existing captures and |currentCaptureName_|. | |
91 */ | |
92 this.enable = function() { | |
93 this.tabLabel_.classList.add('selected'); | |
94 this.updatePlaybackChoices_(); | |
95 | |
96 this.playbackTab_.hidden = false; | |
97 if (this.cyclerData_.getCaptures().length == 0) { | |
98 this.enableShowNoCaptures_(); | |
99 } else if (this.cyclerUI_.currentCaptureName == null) { | |
100 this.enableChoosePlayback_(); | |
101 } else { | |
102 this.enableShowPlayback_(); | |
103 } | |
104 } | |
105 | |
106 /** | |
107 * Disable the playback tab altogether, presumably in favor of some | |
108 * other tab. | |
109 */ | |
110 this.disable = function() { | |
111 this.tabLabel_.classList.remove('selected'); | |
112 this.playbackTab_.hidden = true; | |
113 } | |
114 | |
115 /** | |
116 * Utility function to refresh the selection list of captures that may | |
117 * be chosen for playback. Show all current captures, and also a | |
118 * "Choose a capture" default text if no capture is currently selected. | |
119 * @private | |
120 */ | |
121 this.updatePlaybackChoices_ = function() { | |
122 var captureNames = this.cyclerData_.getCaptures(); | |
123 var options = this.playbackName_.options; | |
124 var nextIndex = 0; | |
125 var chooseOption; | |
126 | |
127 options.length = 0; | |
128 | |
129 if (this.cyclerUI_.currentCaptureName == null) { | |
130 chooseOption = new Option('Choose a capture', null); | |
131 chooseOption.disabled = true; | |
132 options.add(chooseOption); | |
133 options.selectedIndex = nextIndex++; | |
134 } | |
135 for (var i = 0; i < captureNames.length; i++) { | |
136 options.add(new Option(captureNames[i], captureNames[i])); | |
137 if (captureNames[i] == this.cyclerUI_.currentCaptureName) { | |
138 options.selectedIndex = nextIndex; | |
139 } | |
140 nextIndex++; | |
141 } | |
142 } | |
143 | |
144 /** | |
145 * Event callback for selection of a capture to play back. Save the | |
146 * choice in |currentCaptureName_|. Update the selection list because the | |
147 * default reminder message is no longer needed when a capture is chosen. | |
148 * Change playback tab to show-chosen-capture mode. | |
149 */ | |
150 this.selectPlaybackName = function() { | |
151 this.cyclerUI_.currentCaptureName = this.playbackName_.value; | |
152 this.updatePlaybackChoices_(); | |
153 this.enableShowPlayback_(); | |
154 } | |
155 | |
156 /** | |
157 * Event callback for pressing the playback button, which button is only | |
158 * enabled if a capture has been chosen for playback. Check for errors | |
159 * on playback page, and either display a message with such errors, or | |
160 * call the extenion api to initiate a playback. | |
161 * @private | |
162 */ | |
163 this.doPlayback_ = function() { | |
164 var extensionPath = this.playbackExtension_.value; | |
165 var repeatCount = parseInt(this.playbackRepeats_.value); | |
166 var errors = []; | |
167 | |
168 // Check local errors | |
169 if (isNaN(repeatCount)) { | |
170 errors.push('Enter a number for repeat count'); | |
171 } else if (repeatCount < 1 || repeatCount > 100) { | |
172 errors.push('Repeat count must be between 1 and 100'); | |
173 } | |
174 | |
175 if (errors.length > 0) { | |
176 this.cyclerUI_.showMessage(errors.join('\n'), 'Ok'); | |
177 } else { | |
178 this.doPlaybackButton_.disabled = true; | |
179 chrome.experimental.record.replayURLs( | |
180 this.cyclerUI_.currentCaptureName, | |
181 repeatCount, | |
182 {'extensionPath': extensionPath}, | |
183 this.onPlaybackDone.bind(this)); | |
184 } | |
185 } | |
186 | |
187 /** | |
188 * Extension API calls this back when a playback is done. | |
189 * @param {!{ | |
190 * runTime: number, | |
191 * stats: string, | |
192 * errors: !Array.<string> | |
193 * }} results The results of the playback, including running time in ms, | |
194 * a string of statistics information, and a string array of errors. | |
195 */ | |
196 this.onPlaybackDone = function(results) { | |
197 this.doPlaybackButton_.disabled = false; | |
198 | |
199 if (results.errors.length > 0) { | |
200 this.cyclerUI_.showMessage(results.errors.join('\n'), 'Ok'); | |
201 } else { | |
202 this.cyclerUI_.showMessage('Test took ' + results.runTime + 'mS :\n' + | |
203 results.stats, 'Ok'); | |
204 } | |
205 } | |
206 | |
207 /** | |
208 * Delete the capture with name |currentCaptureName_|. For this method | |
209 * to be callable, there must be a selected currentCaptureName_. Change | |
210 * the displayed HTML to show no captures if none exist now, or to show | |
211 * none selected (since we just deleted the selected one). | |
212 * @private | |
213 */ | |
214 this.doDelete_ = function() { | |
215 this.cyclerData_.deleteCapture(this.cyclerUI_.currentCaptureName); | |
216 this.cyclerUI_.currentCaptureName = null; | |
217 this.updatePlaybackChoices_(); | |
218 if (this.cyclerData_.getCaptures().length == 0) { | |
219 this.enableShowNoCaptures_(); | |
220 } else { | |
221 this.enableChoosePlayback_(); | |
222 } | |
223 } | |
224 | |
225 // Set up listeners on buttons. | |
226 this.doPlaybackButton_.addEventListener('click', this.doPlayback_.bind(this)); | |
227 this.doDeleteButton_.addEventListener('click', this.doDelete_.bind(this)); | |
228 | |
229 // Set up initial selection list for existing captures, and selection | |
230 // event listener. | |
231 this.updatePlaybackChoices_(); | |
232 this.playbackName_.addEventListener('change', | |
233 this.selectPlaybackName.bind(this)); | |
234 }; | |
OLD | NEW |