Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Unified Diff: chrome/browser/resources/net_internals/dataview.js

Issue 7155031: Save net-internals log dumps directly to disk. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Response to kinuko's comments Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/resources/net_internals/index.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/net_internals/dataview.js
===================================================================
--- chrome/browser/resources/net_internals/dataview.js (revision 89253)
+++ chrome/browser/resources/net_internals/dataview.js (working copy)
@@ -13,8 +13,8 @@
* @constructor
*/
function DataView(mainBoxId,
- outputTextBoxId,
- exportTextButtonId,
+ downloadIframeId,
+ exportFileButtonId,
securityStrippingCheckboxId,
byteLoggingCheckboxId,
passivelyCapturedCountId,
@@ -27,8 +27,6 @@
loggingTextSpanId) {
DivView.call(this, mainBoxId);
- this.textPre_ = document.getElementById(outputTextBoxId);
-
var securityStrippingCheckbox =
document.getElementById(securityStrippingCheckboxId);
securityStrippingCheckbox.onclick =
@@ -38,9 +36,11 @@
byteLoggingCheckbox.onclick =
this.onSetByteLogging_.bind(this, byteLoggingCheckbox);
- var exportTextButton = document.getElementById(exportTextButtonId);
- exportTextButton.onclick = this.onExportToText_.bind(this);
+ this.downloadIframe_ = document.getElementById(downloadIframeId);
+ this.exportFileButton_ = document.getElementById(exportFileButtonId);
+ this.exportFileButton_.onclick = this.onExportToText_.bind(this);
+
this.activelyCapturedCountBox_ =
document.getElementById(activelyCapturedCountId);
this.passivelyCapturedCountBox_ =
@@ -58,7 +58,6 @@
this.logFileChanged.bind(this, loadLogFileElement);
this.updateEventCounts_();
- this.waitingForUpdate_ = false;
g_browser.addLogObserver(this);
}
@@ -96,7 +95,6 @@
setNodeDisplay(this.dumpDataDiv_, !isViewingLogFile);
setNodeDisplay(this.capturingTextSpan_, !isViewingLogFile);
setNodeDisplay(this.loggingTextSpan_, isViewingLogFile);
- this.setText_('');
};
/**
@@ -130,12 +128,8 @@
g_browser.setSecurityStripping(securityStrippingCheckbox.checked);
};
-/**
- * Clears displayed text when security stripping is toggled.
- */
DataView.prototype.onSecurityStrippingChanged = function() {
- this.setText_('');
-}
+};
/**
* Called when a log file is selected.
@@ -152,31 +146,35 @@
fileReader.readAsText(logFile);
}
-}
+};
/**
* Displays an error message when unable to read the selected log file.
*/
DataView.prototype.onLoadLogFileError = function(event) {
alert('Error ' + event.target.error.code + '. Unable to load file.');
-}
+};
/**
* Tries to load the contents of the log file.
*/
DataView.prototype.onLoadLogFile = function(event) {
g_browser.loadedLogFile(event.target.result);
-}
+};
+DataView.prototype.enableExportFileButton_ = function(enabled) {
+ this.exportFileButton_.disabled = !enabled;
+};
+
/**
* If not already waiting for results from all updates, triggers all
* updates and starts waiting for them to complete.
*/
DataView.prototype.onExportToText_ = function() {
- if (this.waitingForUpdate_)
+ if (this.exportFileButton_.disabled)
return;
- this.waitingForUpdate = true;
- this.setText_('Generating...');
+ this.enableExportFileButton_(false);
+
g_browser.updateAllInfo(this.onUpdateAllCompleted.bind(this));
};
@@ -404,12 +402,62 @@
}
}
- // Open a new window to display this text.
- this.setText_(text.join('\n'));
+ var blobBuilder = new WebKitBlobBuilder();
+ blobBuilder.append(text.join('\n'), 'native');
+ var textBlob = blobBuilder.getBlob('octet/stream');
- this.selectText_();
+ window.webkitRequestFileSystem(
+ window.TEMPORARY, textBlob.size,
+ this.onFileSystemCreate_.bind(this, textBlob),
+ this.onFileError_.bind(this, 'Unable to create file system.'));
};
+// Once we have access to the file system, create a log file.
+DataView.prototype.onFileSystemCreate_ = function(textBlob, fileSystem) {
+ fileSystem.root.getFile(
+ 'net_internals_log.txt', {create: true},
+ this.onFileCreate_.bind(this, textBlob),
+ this.onFileError_.bind(this, 'Unable to create file.'));
+};
+
+// Once the file is created, or an existing one has been opened, create a
+// writer for it.
+DataView.prototype.onFileCreate_ = function(textBlob, fileEntry) {
+ fileEntry.createWriter(
+ this.onFileCreateWriter_.bind(this, textBlob, fileEntry),
+ this.onFileError_.bind(this, 'Unable to create writer.'));
+};
+
+// Once the |fileWriter| has been created, truncate the file, in case it already
+// existed.
+DataView.prototype.onFileCreateWriter_ = function(textBlob,
+ fileEntry, fileWriter) {
+ fileWriter.onerror = this.onFileError_.bind(this, 'Truncate failed.');
+ fileWriter.onwriteend = this.onFileTruncate_.bind(this, textBlob,
+ fileWriter, fileEntry);
+ fileWriter.truncate(0);
+};
+
+// Once the file has been truncated, write |textBlob| to the file.
+DataView.prototype.onFileTruncate_ = function(textBlob, fileWriter, fileEntry) {
+ fileWriter.onerror = this.onFileError_.bind(this, 'Write failed.');
+ fileWriter.onwriteend = this.onFileWriteComplete_.bind(this, fileEntry);
+ fileWriter.write(textBlob);
+};
+
+// Once the file has been written to, start the download.
+DataView.prototype.onFileWriteComplete_ = function(fileEntry) {
+ this.downloadIframe_.src = fileEntry.toURL();
+ this.enableExportFileButton_(true);
+};
+
+// On any Javascript File API error, enable the export button and display
+// |errorText|, followed by the specific error.
+DataView.prototype.onFileError_ = function(errorText, error) {
+ this.enableExportFileButton_(true);
+ alert(errorText + ' ' + getKeyWithValue(FileError, error.code));
+};
+
DataView.prototype.appendEventsPrintedAsText_ = function(out) {
var allEvents = g_browser.getAllCapturedEvents();
@@ -480,14 +528,6 @@
};
/**
- * Helper function to set this view's content to |text|.
- */
-DataView.prototype.setText_ = function(text) {
- this.textPre_.innerHTML = '';
- addTextNode(this.textPre_, text);
-};
-
-/**
* Format a time ticks count as a timestamp.
*/
DataView.prototype.formatExpirationTime_ = function(timeTicks) {
@@ -495,15 +535,3 @@
var isExpired = d.getTime() < (new Date()).getTime();
return 't=' + d.getTime() + (isExpired ? ' [EXPIRED]' : '');
};
-
-/**
- * Select all text from log dump.
- */
-DataView.prototype.selectText_ = function() {
- var selection = window.getSelection();
- selection.removeAllRanges();
-
- var range = document.createRange();
- range.selectNodeContents(this.textPre_);
- selection.addRange(range);
-};
« no previous file with comments | « no previous file | chrome/browser/resources/net_internals/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698