| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * This view displays options for importing data from a log file. |
| */ |
| var ImportView = (function() { |
| 'use strict'; |
| |
| // This is defined in index.html, but for all intents and purposes is part |
| // of this view. |
| var LOAD_LOG_FILE_DROP_TARGET_ID = 'import-view-drop-target'; |
| |
| // We inherit from DivView. |
| var superClass = DivView; |
| |
| /** |
| * @constructor |
| */ |
| function ImportView() { |
| assertFirstConstructorCall(ImportView); |
| |
| // Call superclass's constructor. |
| superClass.call(this, ImportView.MAIN_BOX_ID); |
| |
| this.loadedDiv_ = $(ImportView.LOADED_DIV_ID); |
| |
| this.loadFileElement_ = $(ImportView.LOAD_LOG_FILE_ID); |
| this.loadFileElement_.onchange = this.logFileChanged.bind(this); |
| this.loadStatusText_ = $(ImportView.LOAD_STATUS_TEXT_ID); |
| |
| var dropTarget = $(LOAD_LOG_FILE_DROP_TARGET_ID); |
| dropTarget.ondragenter = this.onDrag.bind(this); |
| dropTarget.ondragover = this.onDrag.bind(this); |
| dropTarget.ondrop = this.onDrop.bind(this); |
| |
| $(ImportView.RELOAD_LINK_ID).onclick = this.clickedReload_.bind(this); |
| |
| this.loadedInfoBuildName_ = $(ImportView.LOADED_INFO_BUILD_NAME_ID); |
| this.loadedInfoExportDate_ = $(ImportView.LOADED_INFO_EXPORT_DATE_ID); |
| this.loadedInfoOsType_ = $(ImportView.LOADED_INFO_OS_TYPE_ID); |
| this.loadedInfoCommandLine_ = $(ImportView.LOADED_INFO_COMMAND_LINE_ID); |
| this.loadedInfoUserComments_ = $(ImportView.LOADED_INFO_USER_COMMENTS_ID); |
| } |
| |
| ImportView.TAB_HANDLE_ID = 'tab-handle-import'; |
| |
| // IDs for special HTML elements in import_view.html |
| ImportView.MAIN_BOX_ID = 'import-view-tab-content'; |
| ImportView.LOADED_DIV_ID = 'import-view-loaded-div'; |
| ImportView.LOAD_LOG_FILE_ID = 'import-view-load-log-file'; |
| ImportView.LOAD_STATUS_TEXT_ID = 'import-view-load-status-text'; |
| ImportView.RELOAD_LINK_ID = 'import-view-reloaded-link'; |
| ImportView.LOADED_INFO_EXPORT_DATE_ID = 'import-view-export-date'; |
| ImportView.LOADED_INFO_BUILD_NAME_ID = 'import-view-build-name'; |
| ImportView.LOADED_INFO_OS_TYPE_ID = 'import-view-os-type'; |
| ImportView.LOADED_INFO_COMMAND_LINE_ID = 'import-view-command-line'; |
| ImportView.LOADED_INFO_USER_COMMENTS_ID = 'import-view-user-comments'; |
| |
| cr.addSingletonGetter(ImportView); |
| |
| ImportView.prototype = { |
| // Inherit the superclass's methods. |
| __proto__: superClass.prototype, |
| |
| /** |
| * Called when a log file is loaded, after clearing the old log entries and |
| * loading the new ones. Returns true to indicate the view should |
| * still be visible. |
| */ |
| onLoadLogFinish: function(data, unused, userComments) { |
| setNodeDisplay(this.loadedDiv_, true); |
| this.updateLoadedClientInfo(userComments); |
| return true; |
| }, |
| |
| /** |
| * Called when the user clicks the "reloaded" link. |
| */ |
| clickedReload_: function() { |
| window.location.reload(); |
| return false; |
| }, |
| |
| /** |
| * Called when something is dragged over the drop target. |
| * |
| * Returns false to cancel default browser behavior when a single file is |
| * being dragged. When this happens, we may not receive a list of files for |
| * security reasons, which is why we allow the |files| array to be empty. |
| */ |
| onDrag: function(event) { |
| return event.dataTransfer.types.indexOf('Files') == -1 || |
| event.dataTransfer.files.length > 1; |
| }, |
| |
| /** |
| * Called when something is dropped onto the drop target. If it's a single |
| * file, tries to load it as a log file. |
| */ |
| onDrop: function(event) { |
| if (event.dataTransfer.types.indexOf('Files') == -1 || |
| event.dataTransfer.files.length != 1) { |
| return; |
| } |
| event.preventDefault(); |
| |
| // Loading a log file may hide the currently active tab. Switch to the |
| // import tab to prevent this. |
| document.location.hash = 'import'; |
| |
| this.loadLogFile(event.dataTransfer.files[0]); |
| }, |
| |
| /** |
| * Called when a log file is selected. |
| * |
| * Gets the log file from the input element and tries to read from it. |
| */ |
| logFileChanged: function() { |
| this.loadLogFile(this.loadFileElement_.files[0]); |
| }, |
| |
| /** |
| * Attempts to read from the File |logFile|. |
| */ |
| loadLogFile: function(logFile) { |
| if (logFile) { |
| this.setLoadFileStatus('Loading log...', true); |
| var fileReader = new FileReader(); |
| |
| fileReader.onload = this.onLoadLogFile.bind(this, logFile); |
| fileReader.onerror = this.onLoadLogFileError.bind(this); |
| |
| fileReader.readAsText(logFile); |
| } |
| }, |
| |
| /** |
| * Displays an error message when unable to read the selected log file. |
| * Also clears the file input control, so the same file can be reloaded. |
| */ |
| onLoadLogFileError: function(event) { |
| this.loadFileElement_.value = null; |
| this.setLoadFileStatus( |
| 'Error ' + getKeyWithValue(FileError, event.target.error.code) + |
| '. Unable to read file.', |
| false); |
| }, |
| |
| onLoadLogFile: function(logFile, event) { |
| var result = logutil.loadLogFile(event.target.result, logFile.fileName); |
| this.setLoadFileStatus(result, false); |
| }, |
| |
| /** |
| * Sets the load from file status text, displayed below the load file |
| * button, to |text|. Also enables or disables the load buttons based on |
| * the value of |isLoading|, which must be true if the load process is still |
| * ongoing, and false when the operation has stopped, regardless of success |
| * of failure. Also, when loading is done, replaces the load button so the |
| * same file can be loaded again. |
| */ |
| setLoadFileStatus: function(text, isLoading) { |
| this.enableLoadFileElement_(!isLoading); |
| this.loadStatusText_.textContent = text; |
| |
| if (!isLoading) { |
| // Clear the button, so the same file can be reloaded. Recreating the |
| // element seems to be the only way to do this. |
| var loadFileElementId = this.loadFileElement_.id; |
| var loadFileElementOnChange = this.loadFileElement_.onchange; |
| this.loadFileElement_.outerHTML = this.loadFileElement_.outerHTML; |
| this.loadFileElement_ = $(loadFileElementId); |
| this.loadFileElement_.onchange = loadFileElementOnChange; |
| } |
| }, |
| |
| enableLoadFileElement_: function(enabled) { |
| this.loadFileElement_.disabled = !enabled; |
| }, |
| |
| /** |
| * Prints some basic information about the environment when the log was |
| * made. |
| */ |
| updateLoadedClientInfo: function(userComments) { |
| // Reset all the fields (in case we early-return). |
| this.loadedInfoExportDate_.innerText = ''; |
| this.loadedInfoBuildName_.innerText = ''; |
| this.loadedInfoOsType_.innerText = ''; |
| this.loadedInfoCommandLine_.innerText = ''; |
| this.loadedInfoUserComments_.innerText = ''; |
| |
| if (typeof(ClientInfo) != 'object') |
| return; |
| |
| var dateString = ''; |
| // Dumps made with the command line option don't have a date, and older |
| // versions of Chrome use a formatted string. |
| // TODO(mmenke): At some point, after Chrome 17 hits stable, remove the |
| // ClientInfo.date case. |
| if (ClientInfo.numericDate) { |
| dateString = (new Date(ClientInfo.numericDate)).toLocaleString(); |
| } else if (ClientInfo.date) { |
| dateString = ClientInfo.date; |
| } |
| this.loadedInfoExportDate_.innerText = dateString; |
| |
| var buildName = |
| ClientInfo.name + |
| ' ' + ClientInfo.version + |
| ' (' + ClientInfo.official + |
| ' ' + ClientInfo.cl + |
| ') ' + ClientInfo.version_mod; |
| |
| this.loadedInfoBuildName_.innerText = buildName; |
| |
| this.loadedInfoOsType_.innerText = ClientInfo.os_type; |
| this.loadedInfoCommandLine_.innerText = ClientInfo.command_line; |
| |
| // User comments will not be available when dumped from command line. |
| this.loadedInfoUserComments_.innerText = userComments || ''; |
| } |
| }; |
| |
| return ImportView; |
| })(); |