Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Main entry point called once the page has loaded. | 6 * Main entry point called once the page has loaded. |
| 7 */ | 7 */ |
| 8 function onLoad() { | 8 function onLoad() { |
| 9 NetExportView.getInstance(); | 9 NetExportView.getInstance(); |
| 10 } | 10 } |
| 11 | 11 |
| 12 document.addEventListener('DOMContentLoaded', onLoad); | 12 document.addEventListener('DOMContentLoaded', onLoad); |
| 13 | 13 |
| 14 /** | 14 /** |
| 15 * This class handles the presentation of our profiler view. Used as a | 15 * This class handles the presentation of the net-export view. Used as a |
| 16 * singleton. | 16 * singleton. |
| 17 */ | 17 */ |
| 18 var NetExportView = (function() { | 18 var NetExportView = (function() { |
| 19 'use strict'; | 19 'use strict'; |
| 20 | 20 |
| 21 // -------------------------------------------------------------------------- | 21 // -------------------------------------------------------------------------- |
| 22 | 22 |
| 23 var kIdStateDivUninitialized = 'export-view-state-uninitialized'; | |
| 24 var kIdStateDivInitial = 'export-view-state-initial'; | |
| 25 var kIdStateDivLogging = 'export-view-state-logging'; | |
| 26 var kIdStateDivStopped = 'export-view-state-stopped'; | |
| 27 var kIdStartLoggingButton = 'export-view-start-logging'; | |
| 28 var kIdStopLoggingButton = 'export-view-stop-logging'; | |
| 29 var kIdEmailLogButton = 'export-view-mobile-email'; | |
| 30 var kIdCaptureModeLogging = 'export-view-capture-mode-logging'; | |
| 31 var kIdFilePathLogging = 'export-view-file-path-logging'; | |
| 32 var kIdCaptureModeStopped = 'export-view-capture-mode-stopped'; | |
| 33 var kIdFilePathStoppedLogging = 'export-view-file-path-stopped'; | |
| 34 var kIdStartOverButton = 'export-view-startover'; | |
| 35 var kIdReadMoreLink = 'export-view-privacy-read-more-link'; | |
| 36 var kIdReadMoreDiv = 'export-view-privacy-read-more' | |
|
xunjieli
2017/05/02 17:10:01
Do these elements need an "export-view" prefix? Th
eroman
2017/05/02 20:07:58
Done.
| |
| 37 | |
| 23 /** | 38 /** |
| 24 * @constructor | 39 * @constructor |
| 25 */ | 40 */ |
| 26 function NetExportView() { | 41 function NetExportView() { |
| 27 $('export-view-start-data').onclick = this.onStartData_.bind(this); | |
| 28 $('export-view-stop-data').onclick = this.onStopData_.bind(this); | |
| 29 if (this.useMobileUI_()) | |
| 30 $('export-view-mobile-send-data').onclick = this.onSendData_.bind(this); | |
| 31 | |
| 32 // Tell NetExportMessageHandler to notify the UI of future state changes | 42 // Tell NetExportMessageHandler to notify the UI of future state changes |
| 33 // from this point on (through onExportNetLogInfoChanged()). | 43 // from this point on (through onExportNetLogInfoChanged()). |
| 34 chrome.send('enableNotifyUIWithState'); | 44 chrome.send('enableNotifyUIWithState'); |
| 45 | |
| 46 this.infoForLoggedFile_ = null; | |
| 35 } | 47 } |
| 36 | 48 |
| 37 cr.addSingletonGetter(NetExportView); | 49 cr.addSingletonGetter(NetExportView); |
| 38 | 50 |
| 39 NetExportView.prototype = { | 51 NetExportView.prototype = { |
| 40 /** | 52 /** |
| 41 * Starts saving NetLog data to a file. | 53 * Starts saving NetLog data to a file. |
| 42 */ | 54 */ |
| 43 onStartData_: function() { | 55 onStartLogging_: function() { |
| 44 var logMode = | 56 var logMode = |
| 45 document.querySelector('input[name="log-mode"]:checked').value; | 57 document.querySelector('input[name="log-mode"]:checked').value; |
| 46 chrome.send('startNetLog', [logMode]); | 58 chrome.send('startNetLog', [logMode]); |
| 47 }, | 59 }, |
| 48 | 60 |
| 49 /** | 61 /** |
| 50 * Stops saving NetLog data to a file. | 62 * Stops saving NetLog data to a file. |
| 51 */ | 63 */ |
| 52 onStopData_: function() { | 64 onStopLogging_: function() { |
| 53 chrome.send('stopNetLog'); | 65 chrome.send('stopNetLog'); |
| 54 }, | 66 }, |
| 55 | 67 |
| 56 /** | 68 /** |
| 57 * Sends NetLog data via email from browser. | 69 * Sends NetLog data via email from browser (mobile only) |
|
xunjieli
2017/05/02 17:10:01
nit: add a period at the end.
eroman
2017/05/02 20:07:58
Done.
| |
| 58 */ | 70 */ |
| 59 onSendData_: function() { | 71 onSendEmail_: function() { |
| 60 chrome.send('sendNetLog'); | 72 chrome.send('sendNetLog'); |
| 61 }, | 73 }, |
| 62 | 74 |
| 63 /** | 75 /** |
| 64 * Updates the UI to reflect the current state. Displays the path name of | 76 * Transitions back to the "Start logging to disk" state. |
| 65 * the file where NetLog data is collected. | |
| 66 */ | 77 */ |
| 67 onExportNetLogInfoChanged: function(exportNetLogInfo) { | 78 onStartOver_: function() { |
| 68 if (exportNetLogInfo.file) { | 79 this.infoForLoggedFile_ = null; |
| 69 var message = ''; | 80 this.renderInitial_(); |
| 70 if (exportNetLogInfo.state == 'LOGGING') | 81 }, |
| 71 message = 'NetLog data is collected in: '; | |
| 72 else if (exportNetLogInfo.logType != 'NONE') | |
| 73 message = 'NetLog data to send is in: '; | |
| 74 $('export-view-file-path-text').textContent = | |
| 75 message + exportNetLogInfo.file; | |
| 76 } else { | |
| 77 $('export-view-file-path-text').textContent = ''; | |
| 78 } | |
| 79 | 82 |
| 80 // Disable all controls. Useable controls are enabled below. | 83 /** |
| 81 var controls = document.querySelectorAll('button, input'); | 84 * Updates the UI to reflect the current state. The state transitions are |
| 82 for (var i = 0; i < controls.length; ++i) { | 85 * sent by the browser controller (NetLogFileWriter): |
| 83 controls[i].disabled = true; | 86 * |
| 84 } | 87 * * UNINITIALIZED - This is the initial state when net-export is opened |
| 88 * for the first time, or there was an error during initialization. | |
| 89 * This state is short-lived and likely not observed; will | |
| 90 * immediately transition to INITIALIZING). | |
| 91 * | |
| 92 * * INITIALIZING - On desktop UI this is pretty much a no-op. On the | |
| 93 * mobile UI, this state is when the controller checks the disk for | |
| 94 * a previous net-log file (from past run of the browser). After | |
| 95 * success will transition to NOT_LOGGING. On failure will | |
| 96 * transition to UNINITIALIZED (rare). | |
| 97 * | |
| 98 * * NOT_LOGGING - This is the steady-state. It means initialization | |
| 99 * completed and we are not currently logging. Being in this state | |
| 100 * either means: | |
| 101 * (1) We were logging and then the user stopped (earlier states | |
| 102 * were STATE_LOGGING / STATE_STOPPING_LOG). | |
| 103 * (2) We have never started logging (previous state was | |
| 104 * INITIALIZING). | |
| 105 * | |
| 106 * * STARTING_LOG - This state means the user has clicked the "Start log" | |
| 107 * button and logging is about to get started (files may not have | |
| 108 * been created yet). | |
| 109 * | |
| 110 * * LOGGING - This state means that logging is currently in progress. | |
| 111 * The destination path of the log, and the capture mode are known | |
| 112 * and will be reflected in the parameters. | |
| 113 * | |
| 114 * * STOPPING_LOG - This state means the user has clicked the "Stop | |
| 115 * logging" button, and the log file is in the process of being | |
| 116 * finalized. Once the state transitions to NOT_LOGGING then the log | |
| 117 * is complete, and can safely be copied/emailed. | |
| 118 */ | |
| 119 onExportNetLogInfoChanged: function(info) { | |
| 120 switch (info.state) { | |
| 121 case 'UNINITIALIZED': | |
| 122 case 'INITIALIZING': | |
| 123 this.renderUninitialized_(); | |
| 124 break; | |
| 85 | 125 |
| 86 if (this.useMobileUI_()) { | 126 case 'NOT_LOGGING': |
| 87 $('export-view-mobile-deletes-log-text').hidden = true; | 127 if (this.infoForLoggedFile_) { |
| 88 $('export-view-mobile-private-data-text').hidden = true; | 128 // There is no "stopped logging" state. We manufacture that in the |
| 89 $('export-view-mobile-send-old-log-text').hidden = true; | 129 // UI in response to a transition from LOGGING --> NOT_LOGGING. |
| 90 } | 130 this.renderStoppedLogging_(this.infoForLoggedFile_); |
| 91 | 131 |
| 92 if (exportNetLogInfo.state == 'NOT_LOGGING') { | 132 // TODO(eroman): prevent future state transitions. In desktop UI |
| 93 // Allow making a new log. | 133 // could start logging in a new tab, and it would reset this one. |
| 94 $('export-view-strip-private-data-button').disabled = false; | 134 } else if (info.logExists) { |
| 95 $('export-view-include-private-data-button').disabled = false; | 135 // In the mobile UI, initialization may have found a |
| 96 $('export-view-log-bytes-button').disabled = false; | 136 // pre-existing log file. |
| 97 $('export-view-start-data').disabled = false; | 137 this.renderStoppedLogging_(info); |
| 138 } else { | |
| 139 this.renderInitial_(info); | |
| 140 } | |
| 141 break; | |
| 98 | 142 |
| 99 // If there's a pre-existing log, allow sending it (this only | 143 case 'STARTING_LOG': |
| 100 // applies to the mobile UI). | 144 // This is a short-lived state, no need to do anything special. |
| 101 if (this.useMobileUI_() && exportNetLogInfo.logExists) { | 145 // Disabling the buttons would be nice, however it is not crucial as |
| 102 $('export-view-mobile-deletes-log-text').hidden = false; | 146 // the controller will reject commands while in this state anyway. |
| 103 $('export-view-mobile-send-data').disabled = false; | 147 this.renderInitial_(info); |
| 104 if (!exportNetLogInfo.logCaptureModeKnown) { | 148 break; |
| 105 $('export-view-mobile-send-old-log-text').hidden = false; | 149 |
| 106 } else if (exportNetLogInfo.captureMode != 'STRIP_PRIVATE_DATA') { | 150 case 'LOGGING': |
| 107 $('export-view-mobile-private-data-text').hidden = false; | 151 // Cache the last information for this logging session, so once |
| 108 } | 152 // logging is stopped will know what path information to display. |
| 109 } | 153 this.infoForLoggedFile_ = info; |
| 110 } else if (exportNetLogInfo.state == 'LOGGING') { | 154 this.renderLogging_(info); |
| 111 // Only possible to stop logging. Radio buttons reflects current state. | 155 break; |
| 112 document | 156 |
| 113 .querySelector( | 157 case 'STOPPING_LOG': |
| 114 'input[name="log-mode"][value="' + | 158 // This is a short-lived state, no need to do anything special. |
| 115 exportNetLogInfo.captureMode + '"]') | 159 this.renderLogging_(info); |
| 116 .checked = true; | 160 break; |
| 117 $('export-view-stop-data').disabled = false; | |
| 118 } else if (exportNetLogInfo.state == 'UNINITIALIZED') { | |
| 119 $('export-view-file-path-text').textContent = | |
| 120 'Unable to initialize NetLog data file.'; | |
| 121 } | 161 } |
| 122 }, | 162 }, |
| 123 | 163 |
| 164 /** | |
| 165 * Updates the UI to display the "uninitialized" state. This is only | |
| 166 * visible for a short period of time, or longer if initialization failed | |
| 167 * (and didn't transition to a different state). | |
| 168 */ | |
| 169 renderUninitialized_: function(info) { | |
|
xunjieli
2017/05/02 17:10:01
Why do we need to pass |info| here and for renderI
eroman
2017/05/02 20:07:58
Done.
| |
| 170 this.showStateDiv_(kIdStateDivUninitialized); | |
| 171 }, | |
| 172 | |
| 173 /** | |
| 174 * Updates the UI to display the "initial" state. This is the state when | |
| 175 * logging has not been started yet, and there are controls to start | |
| 176 * logging. | |
| 177 */ | |
| 178 renderInitial_: function(info) { | |
| 179 this.showStateDiv_(kIdStateDivInitial); | |
| 180 $(kIdStartLoggingButton).onclick = this.onStartLogging_.bind(this); | |
| 181 }, | |
| 182 | |
| 183 /** | |
| 184 * Updates the UI to display the "logging" state. This is the state while | |
| 185 * capturing is in progress and being written to disk. | |
| 186 */ | |
| 187 renderLogging_: function(info) { | |
| 188 this.showStateDiv_(kIdStateDivLogging); | |
| 189 | |
| 190 $(kIdStopLoggingButton).onclick = this.onStopLogging_.bind(this); | |
| 191 $(kIdCaptureModeLogging).textContent = this.getCaptureModeText_(info); | |
| 192 $(kIdFilePathLogging).textContent = info.file; | |
| 193 }, | |
| 194 | |
| 124 /* | 195 /* |
| 125 * Returns true if the UI is being displayed for mobile, otherwise false | 196 * Updates the UI to display the state when logging has stopped. |
| 126 * for desktop. This is controlled by the HTML template. | |
| 127 */ | 197 */ |
| 128 useMobileUI_: function() { | 198 renderStoppedLogging_: function(info) { |
| 129 return !!document.getElementById('export-view-mobile-send-data'); | 199 this.showStateDiv_(kIdStateDivStopped); |
| 130 } | 200 |
| 201 // The email button is only available in the mobile UI. | |
| 202 if ($(kIdEmailLogButton)) | |
| 203 $(kIdEmailLogButton).onclick = this.onSendEmail_.bind(this); | |
| 204 $(kIdStartOverButton).onclick = this.onStartOver_.bind(this); | |
| 205 | |
| 206 $(kIdFilePathStoppedLogging).textContent = info.file; | |
| 207 | |
| 208 $(kIdCaptureModeStopped).textContent = this.getCaptureModeText_(info); | |
| 209 | |
| 210 // Hook up the "read more..." link for privacy information. | |
| 211 $(kIdReadMoreLink).onclick = this.showPrivacyReadMore_.bind(this, true); | |
| 212 this.showPrivacyReadMore_(false); | |
| 213 }, | |
| 214 | |
| 215 /** | |
| 216 * Get the textual label for a capture mode from the HTML. | |
|
xunjieli
2017/05/02 17:10:01
extra nitpicky: s/Get/Gets
eroman
2017/05/02 20:07:58
Done.
| |
| 217 */ | |
| 218 getCaptureModeText_: function(info) { | |
| 219 if (!info.logCaptureModeKnown) | |
| 220 return "Unknown"; | |
| 221 | |
| 222 let captureMode = info.captureMode; | |
|
xunjieli
2017/05/02 17:10:01
nit: this local variable is used in exactly one pl
eroman
2017/05/02 20:07:59
Done.
| |
| 223 | |
| 224 var radioButton = document.querySelector( | |
| 225 'input[name="log-mode"][value="' + captureMode + '"]'); | |
| 226 if (!radioButton) | |
| 227 return 'Unknown'; | |
| 228 return radioButton.parentElement.textContent; | |
| 229 }, | |
| 230 | |
| 231 showPrivacyReadMore_: function(show) { | |
| 232 $(kIdReadMoreDiv).hidden = !show; | |
| 233 $(kIdReadMoreLink).hidden = show; | |
| 234 }, | |
| 235 | |
| 236 showStateDiv_: function(divId) { | |
| 237 var kAllDivIds = [ | |
| 238 kIdStateDivUninitialized, | |
| 239 kIdStateDivInitial, | |
| 240 kIdStateDivLogging, | |
| 241 kIdStateDivStopped | |
| 242 ]; | |
| 243 | |
| 244 for (var curDivId of kAllDivIds) { | |
| 245 $(curDivId).hidden = divId != curDivId; | |
| 246 } | |
| 247 }, | |
| 131 }; | 248 }; |
| 132 | 249 |
| 133 return NetExportView; | 250 return NetExportView; |
| 134 })(); | 251 })(); |
| OLD | NEW |