Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / net_internals / import_view.js
blobdeb554deb3a8af06094c14d684f695b4ea3fdee4
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.
5 /**
6  * This view displays options for importing data from a log file.
7  */
8 var ImportView = (function() {
9   'use strict';
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';
15   // We inherit from DivView.
16   var superClass = DivView;
18   /**
19    * @constructor
20    */
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);
37   }
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';
48   // Used in tests.
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,
57     /**
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
60      * still be visible.
61      */
62     onLoadLogFinish: function(polledData, unused, logDump) {
63       var input = new JsEvalContext(logDump);
64       jstProcess(input, $(ImportView.LOADED_DIV_ID));
66       setNodeDisplay(this.loadedDiv_, true);
67       return true;
68     },
70     /**
71      * Called when something is dragged over the drop target.
72      *
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.
76      */
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;
86     },
88     /**
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.
91      */
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) {
96         return;
97       }
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]);
105     },
107     /**
108      * Called when a log file is selected.
109      *
110      * Gets the log file from the input element and tries to read from it.
111      */
112     logFileChanged: function() {
113       this.loadLogFile(this.loadFileElement_.files[0]);
114     },
116     /**
117      * Attempts to read from the File |logFile|.
118      */
119     loadLogFile: function(logFile) {
120       if (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);
128       }
129     },
131     /**
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.
134      */
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.',
140           false);
141     },
143     onLoadLogFile: function(logFile, event) {
144       var result = log_util.loadLogFile(event.target.result, logFile.name);
145       this.setLoadFileStatus(result, false);
146     },
148     /**
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.
155      */
156     setLoadFileStatus: function(text, isLoading) {
157       this.enableLoadFileElement_(!isLoading);
158       this.loadStatusText_.textContent = text;
160       if (!isLoading) {
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;
168       }
170       // Style the log output differently depending on what just happened.
171       var pos = text.indexOf('Log loaded.');
172       if (isLoading) {
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';
178       } else {
179         this.loadStatusText_.className = 'import-view-error-log';
180       }
181     },
183     enableLoadFileElement_: function(enabled) {
184       this.loadFileElement_.disabled = !enabled;
185     },
186   };
188   return ImportView;
189 })();