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 * This view displays options for importing data from a log file. |
| 7 */ |
| 8 var ImportView = (function() { |
| 9 'use strict'; |
| 10 |
| 11 // This is defined in index.html, but for all intents and purposes is part |
| 12 // of this view. |
| 13 var LOAD_LOG_FILE_DROP_TARGET_ID = 'import-view-drop-target'; |
| 14 |
| 15 // We inherit from DivView. |
| 16 var superClass = DivView; |
| 17 |
| 18 /** |
| 19 * @constructor |
| 20 */ |
| 21 function ImportView() { |
| 22 assertFirstConstructorCall(ImportView); |
| 23 |
| 24 // Call superclass's constructor. |
| 25 superClass.call(this, ImportView.MAIN_BOX_ID); |
| 26 |
| 27 this.loadedDiv_ = $(ImportView.LOADED_DIV_ID); |
| 28 |
| 29 this.loadFileElement_ = $(ImportView.LOAD_LOG_FILE_ID); |
| 30 this.loadFileElement_.onchange = this.logFileChanged.bind(this); |
| 31 this.loadStatusText_ = $(ImportView.LOAD_STATUS_TEXT_ID); |
| 32 |
| 33 var dropTarget = $(LOAD_LOG_FILE_DROP_TARGET_ID); |
| 34 dropTarget.ondragenter = this.onDrag.bind(this); |
| 35 dropTarget.ondragover = this.onDrag.bind(this); |
| 36 dropTarget.ondrop = this.onDrop.bind(this); |
| 37 } |
| 38 |
| 39 ImportView.TAB_ID = 'tab-handle-import'; |
| 40 ImportView.TAB_NAME = 'Import'; |
| 41 ImportView.TAB_HASH = '#import'; |
| 42 |
| 43 // IDs for special HTML elements in import_view.html. |
| 44 ImportView.MAIN_BOX_ID = 'import-view-tab-content'; |
| 45 ImportView.LOADED_DIV_ID = 'import-view-loaded-div'; |
| 46 ImportView.LOAD_LOG_FILE_ID = 'import-view-load-log-file'; |
| 47 ImportView.LOAD_STATUS_TEXT_ID = 'import-view-load-status-text'; |
| 48 |
| 49 // IDs for HTML elements pertaining to log dump information. |
| 50 ImportView.LOADED_INFO_NUMERIC_DATE_ID = 'import-view-numericDate'; |
| 51 ImportView.LOADED_INFO_NAME_ID = 'import-view-name'; |
| 52 ImportView.LOADED_INFO_VERSION_ID = 'import-view-version'; |
| 53 ImportView.LOADED_INFO_OFFICIAL_ID = 'import-view-official'; |
| 54 ImportView.LOADED_INFO_CL_ID = 'import-view-cl'; |
| 55 ImportView.LOADED_INFO_VERSION_MOD_ID = 'import-view-version-mod'; |
| 56 ImportView.LOADED_INFO_OS_TYPE_ID = 'import-view-os-type'; |
| 57 ImportView.LOADED_INFO_COMMAND_LINE_ID = 'import-view-command-line'; |
| 58 ImportView.LOADED_INFO_ACTIVE_FIELD_TRIAL_GROUPS_ID = |
| 59 'import-view-activeFieldTrialGroups'; |
| 60 ImportView.LOADED_INFO_USER_COMMENTS_ID = 'import-view-user-comments'; |
| 61 |
| 62 cr.addSingletonGetter(ImportView); |
| 63 |
| 64 ImportView.prototype = { |
| 65 // Inherit the superclass's methods. |
| 66 __proto__: superClass.prototype, |
| 67 |
| 68 /** |
| 69 * Called when a log file is loaded, after clearing the old log entries and |
| 70 * loading the new ones. Returns true to indicate the view should |
| 71 * still be visible. |
| 72 */ |
| 73 onLoadLogFinish: function(polledData, unused, logDump) { |
| 74 $(ImportView.LOADED_INFO_NUMERIC_DATE_ID).textContent = |
| 75 timeutil.dateToString(new Date(Constants.clientInfo.numericDate)); |
| 76 $(ImportView.LOADED_INFO_NAME_ID).textContent = |
| 77 Constants.clientInfo.name; |
| 78 $(ImportView.LOADED_INFO_VERSION_ID).textContent = |
| 79 Constants.clientInfo.version; |
| 80 $(ImportView.LOADED_INFO_OFFICIAL_ID).textContent = |
| 81 Constants.clientInfo.official; |
| 82 $(ImportView.LOADED_INFO_CL_ID).textContent = |
| 83 Constants.clientInfo.cl; |
| 84 $(ImportView.LOADED_INFO_VERSION_MOD_ID).textContent = |
| 85 Constants.clientInfo.version_mod; |
| 86 $(ImportView.LOADED_INFO_OS_TYPE_ID).textContent = |
| 87 Constants.clientInfo.os_type; |
| 88 $(ImportView.LOADED_INFO_COMMAND_LINE_ID).textContent = |
| 89 Constants.clientInfo.command_line; |
| 90 $(ImportView.LOADED_INFO_ACTIVE_FIELD_TRIAL_GROUPS_ID).textContent = |
| 91 Constants.activeFieldTrialGroups; |
| 92 |
| 93 if (logDump.userComments != undefined) { |
| 94 $(ImportView.LOADED_INFO_USER_COMMENTS_ID).textContent = |
| 95 logDump.userComments; |
| 96 } else { |
| 97 $(ImportView.LOADED_INFO_USER_COMMENTS_ID).textContent = ''; |
| 98 } |
| 99 |
| 100 setNodeDisplay(this.loadedDiv_, true); |
| 101 return true; |
| 102 }, |
| 103 |
| 104 /** |
| 105 * Called when something is dragged over the drop target. |
| 106 * |
| 107 * Returns false to cancel default browser behavior when a single file is |
| 108 * being dragged. When this happens, we may not receive a list of files for |
| 109 * security reasons, which is why we allow the |files| array to be empty. |
| 110 */ |
| 111 onDrag: function(event) { |
| 112 // NOTE: Use Array.prototype.indexOf here is necessary while WebKit |
| 113 // decides which type of data structure dataTransfer.types will be |
| 114 // (currently between DOMStringList and Array). These have different APIs |
| 115 // so assuming one type or the other was breaking things. See |
| 116 // http://crbug.com/115433. TODO(dbeam): Remove when standardized more. |
| 117 var indexOf = Array.prototype.indexOf; |
| 118 return indexOf.call(event.dataTransfer.types, 'Files') == -1 || |
| 119 event.dataTransfer.files.length > 1; |
| 120 }, |
| 121 |
| 122 /** |
| 123 * Called when something is dropped onto the drop target. If it's a single |
| 124 * file, tries to load it as a log file. |
| 125 */ |
| 126 onDrop: function(event) { |
| 127 var indexOf = Array.prototype.indexOf; |
| 128 if (indexOf.call(event.dataTransfer.types, 'Files') == -1 || |
| 129 event.dataTransfer.files.length != 1) { |
| 130 return; |
| 131 } |
| 132 event.preventDefault(); |
| 133 |
| 134 // Loading a log file may hide the currently active tab. Switch to the |
| 135 // import tab to prevent this. |
| 136 document.location.hash = 'import'; |
| 137 |
| 138 this.loadLogFile(event.dataTransfer.files[0]); |
| 139 }, |
| 140 |
| 141 /** |
| 142 * Called when a log file is selected. |
| 143 * |
| 144 * Gets the log file from the input element and tries to read from it. |
| 145 */ |
| 146 logFileChanged: function() { |
| 147 this.loadLogFile(this.loadFileElement_.files[0]); |
| 148 }, |
| 149 |
| 150 /** |
| 151 * Attempts to read from the File |logFile|. |
| 152 */ |
| 153 loadLogFile: function(logFile) { |
| 154 if (logFile) { |
| 155 this.setLoadFileStatus('Loading log...', true); |
| 156 var fileReader = new FileReader(); |
| 157 |
| 158 fileReader.onload = this.onLoadLogFile.bind(this, logFile); |
| 159 fileReader.onerror = this.onLoadLogFileError.bind(this); |
| 160 |
| 161 fileReader.readAsText(logFile); |
| 162 } |
| 163 }, |
| 164 |
| 165 /** |
| 166 * Displays an error message when unable to read the selected log file. |
| 167 * Also clears the file input control, so the same file can be reloaded. |
| 168 */ |
| 169 onLoadLogFileError: function(event) { |
| 170 this.loadFileElement_.value = null; |
| 171 this.setLoadFileStatus( |
| 172 'Error ' + getKeyWithValue(FileError, event.target.error.code) + |
| 173 '. Unable to read file.', |
| 174 false); |
| 175 }, |
| 176 |
| 177 onLoadLogFile: function(logFile, event) { |
| 178 var result = log_util.loadLogFile(event.target.result, logFile.name); |
| 179 this.setLoadFileStatus(result, false); |
| 180 }, |
| 181 |
| 182 /** |
| 183 * Sets the load from file status text, displayed below the load file |
| 184 * button, to |text|. Also enables or disables the load buttons based on |
| 185 * the value of |isLoading|, which must be true if the load process is still |
| 186 * ongoing, and false when the operation has stopped, regardless of success |
| 187 * of failure. Also, when loading is done, replaces the load button so the |
| 188 * same file can be loaded again. |
| 189 */ |
| 190 setLoadFileStatus: function(text, isLoading) { |
| 191 this.enableLoadFileElement_(!isLoading); |
| 192 this.loadStatusText_.textContent = text; |
| 193 |
| 194 if (!isLoading) { |
| 195 // Clear the button, so the same file can be reloaded. Recreating the |
| 196 // element seems to be the only way to do this. |
| 197 var loadFileElementId = this.loadFileElement_.id; |
| 198 var loadFileElementOnChange = this.loadFileElement_.onchange; |
| 199 this.loadFileElement_.outerHTML = this.loadFileElement_.outerHTML; |
| 200 this.loadFileElement_ = $(loadFileElementId); |
| 201 this.loadFileElement_.onchange = loadFileElementOnChange; |
| 202 } |
| 203 |
| 204 // Style the log output differently depending on what just happened. |
| 205 var pos = text.indexOf('Log loaded.'); |
| 206 if (isLoading) { |
| 207 this.loadStatusText_.className = 'import-view-pending-log'; |
| 208 } else if (pos == 0) { |
| 209 this.loadStatusText_.className = 'import-view-success-log'; |
| 210 } else if (pos != -1) { |
| 211 this.loadStatusText_.className = 'import-view-warning-log'; |
| 212 } else { |
| 213 this.loadStatusText_.className = 'import-view-error-log'; |
| 214 } |
| 215 }, |
| 216 |
| 217 enableLoadFileElement_: function(enabled) { |
| 218 this.loadFileElement_.disabled = !enabled; |
| 219 }, |
| 220 }; |
| 221 |
| 222 return ImportView; |
| 223 })(); |
| 224 |
OLD | NEW |