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 |