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.
6 * This view displays options for importing data from a log file.
8 var ImportView = (function() {
11 // This is defined in index.html, but for all intents and purposes is part
13 var LOAD_LOG_FILE_DROP_TARGET_ID = 'import-view-drop-target';
15 // We inherit from DivView.
16 var superClass = DivView;
21 function ImportView() {
22 assertFirstConstructorCall(ImportView);
24 // Call superclass's constructor.
25 superClass.call(this, ImportView.MAIN_BOX_ID);
27 this.loadedDiv_ = $(ImportView.LOADED_DIV_ID);
29 this.loadFileElement_ = $(ImportView.LOAD_LOG_FILE_ID);
30 this.loadFileElement_.onchange = this.logFileChanged.bind(this);
31 this.loadStatusText_ = $(ImportView.LOAD_STATUS_TEXT_ID);
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);
39 ImportView.TAB_ID = 'tab-handle-import';
40 ImportView.TAB_NAME = 'Import';
41 ImportView.TAB_HASH = '#import';
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';
49 ImportView.LOADED_INFO_USER_COMMENTS_ID = 'import-view-user-comments';
51 cr.addSingletonGetter(ImportView);
53 ImportView.prototype = {
54 // Inherit the superclass's methods.
55 __proto__: superClass.prototype,
58 * Called when a log file is loaded, after clearing the old log entries and
59 * loading the new ones. Returns true to indicate the view should
62 onLoadLogFinish: function(polledData, unused, logDump) {
63 var input = new JsEvalContext(logDump);
64 jstProcess(input, $(ImportView.LOADED_DIV_ID));
66 setNodeDisplay(this.loadedDiv_, true);
71 * Called when something is dragged over the drop target.
73 * Returns false to cancel default browser behavior when a single file is
74 * being dragged. When this happens, we may not receive a list of files for
75 * security reasons, which is why we allow the |files| array to be empty.
77 onDrag: function(event) {
78 // NOTE: Use Array.prototype.indexOf here is necessary while WebKit
79 // decides which type of data structure dataTransfer.types will be
80 // (currently between DOMStringList and Array). These have different APIs
81 // so assuming one type or the other was breaking things. See
82 // http://crbug.com/115433. TODO(dbeam): Remove when standardized more.
83 var indexOf = Array.prototype.indexOf;
84 return indexOf.call(event.dataTransfer.types, 'Files') == -1 ||
85 event.dataTransfer.files.length > 1;
89 * Called when something is dropped onto the drop target. If it's a single
90 * file, tries to load it as a log file.
92 onDrop: function(event) {
93 var indexOf = Array.prototype.indexOf;
94 if (indexOf.call(event.dataTransfer.types, 'Files') == -1 ||
95 event.dataTransfer.files.length != 1) {
98 event.preventDefault();
100 // Loading a log file may hide the currently active tab. Switch to the
101 // import tab to prevent this.
102 document.location.hash = 'import';
104 this.loadLogFile(event.dataTransfer.files[0]);
108 * Called when a log file is selected.
110 * Gets the log file from the input element and tries to read from it.
112 logFileChanged: function() {
113 this.loadLogFile(this.loadFileElement_.files[0]);
117 * Attempts to read from the File |logFile|.
119 loadLogFile: function(logFile) {
121 this.setLoadFileStatus('Loading log...', true);
122 var fileReader = new FileReader();
124 fileReader.onload = this.onLoadLogFile.bind(this, logFile);
125 fileReader.onerror = this.onLoadLogFileError.bind(this);
127 fileReader.readAsText(logFile);
132 * Displays an error message when unable to read the selected log file.
133 * Also clears the file input control, so the same file can be reloaded.
135 onLoadLogFileError: function(event) {
136 this.loadFileElement_.value = null;
137 this.setLoadFileStatus(
138 'Error ' + getKeyWithValue(FileError, event.target.error.code) +
139 '. Unable to read file.',
143 onLoadLogFile: function(logFile, event) {
144 var result = log_util.loadLogFile(event.target.result, logFile.name);
145 this.setLoadFileStatus(result, false);
149 * Sets the load from file status text, displayed below the load file
150 * button, to |text|. Also enables or disables the load buttons based on
151 * the value of |isLoading|, which must be true if the load process is still
152 * ongoing, and false when the operation has stopped, regardless of success
153 * of failure. Also, when loading is done, replaces the load button so the
154 * same file can be loaded again.
156 setLoadFileStatus: function(text, isLoading) {
157 this.enableLoadFileElement_(!isLoading);
158 this.loadStatusText_.textContent = text;
161 // Clear the button, so the same file can be reloaded. Recreating the
162 // element seems to be the only way to do this.
163 var loadFileElementId = this.loadFileElement_.id;
164 var loadFileElementOnChange = this.loadFileElement_.onchange;
165 this.loadFileElement_.outerHTML = this.loadFileElement_.outerHTML;
166 this.loadFileElement_ = $(loadFileElementId);
167 this.loadFileElement_.onchange = loadFileElementOnChange;
170 // Style the log output differently depending on what just happened.
171 var pos = text.indexOf('Log loaded.');
173 this.loadStatusText_.className = 'import-view-pending-log';
174 } else if (pos == 0) {
175 this.loadStatusText_.className = 'import-view-success-log';
176 } else if (pos != -1) {
177 this.loadStatusText_.className = 'import-view-warning-log';
179 this.loadStatusText_.className = 'import-view-error-log';
183 enableLoadFileElement_: function(enabled) {
184 this.loadFileElement_.disabled = !enabled;