summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/net_internals/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/resources/net_internals/main.js')
-rw-r--r--chrome/browser/resources/net_internals/main.js173
1 files changed, 157 insertions, 16 deletions
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index d879c87..de8b43c 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -75,10 +75,12 @@ function onLoaded() {
// captured data.
var dataView = new DataView('dataTabContent', 'exportedDataText',
'exportToText', 'securityStrippingCheckbox',
- 'byteLoggingCheckbox',
- 'passivelyCapturedCount',
- 'activelyCapturedCount',
- 'dataViewDeleteAll');
+ 'byteLoggingCheckbox', 'passivelyCapturedCount',
+ 'activelyCapturedCount', 'dataViewDeleteAll',
+ 'dataViewDumpDataDiv', 'dataViewLoadDataDiv',
+ 'dataViewLoadLogFile',
+ 'dataViewCapturingTextSpan',
+ 'dataViewLoggingTextSpan');
// Create a view which will display the results and controls for connection
// tests.
@@ -108,6 +110,7 @@ function onLoaded() {
// Create a view which lets you tab between the different sub-views.
var categoryTabSwitcher = new TabSwitcherView('categoryTabHandles');
+ g_browser.setTabSwitcher(categoryTabSwitcher);
// Populate the main tabs.
categoryTabSwitcher.addTab('eventsTab', eventsView, false);
@@ -144,6 +147,9 @@ function onLoaded() {
// Select the initial view based on the current URL.
window.onhashchange();
+ // Inform observers a log file is not currently being displayed.
+ g_browser.setIsViewingLogFile_(false);
+
// Tell the browser that we are ready to start receiving log events.
g_browser.sendReady();
}
@@ -191,6 +197,11 @@ function BrowserBridge() {
// Next unique id to be assigned to a log entry without a source.
// Needed to simplify deletion, identify associated GUI elements, etc.
this.nextSourcelessEventId_ = -1;
+
+ // True when viewing a log file rather than actively logged events.
+ // When viewing a log file, all tabs are hidden except the event view,
+ // and all received events are ignored.
+ this.isViewingLogFile_ = false;
}
/*
@@ -302,23 +313,19 @@ BrowserBridge.prototype.setLogLevel = function(logLevel) {
chrome.send('setLogLevel', ['' + logLevel]);
}
+BrowserBridge.prototype.loadLogFile = function() {
+ chrome.send('loadLogFile');
+}
+
//------------------------------------------------------------------------------
// Messages received from the browser
//------------------------------------------------------------------------------
BrowserBridge.prototype.receivedLogEntries = function(logEntries) {
- for (var e = 0; e < logEntries.length; ++e) {
- var logEntry = logEntries[e];
-
- // Assign unique ID, if needed.
- if (logEntry.source.id == 0) {
- logEntry.source.id = this.nextSourcelessEventId_;
- --this.nextSourcelessEventId_;
- }
- this.capturedEvents_.push(logEntry);
- for (var i = 0; i < this.logObservers_.length; ++i)
- this.logObservers_[i].onLogEntryAdded(logEntry);
- }
+ // Does nothing if viewing a log file.
+ if (this.isViewingLogFile_)
+ return;
+ this.addLogEntries(logEntries);
};
BrowserBridge.prototype.receivedLogEventTypeConstants = function(constantsMap) {
@@ -439,9 +446,91 @@ BrowserBridge.prototype.receivedHttpCacheInfo = function(info) {
this.pollableDataHelpers_.httpCacheInfo.update(info);
};
+BrowserBridge.prototype.loadedLogFile = function(logFileContents) {
+ var match;
+ // Replace carriage returns with linebreaks and then split around linebreaks.
+ var lines = logFileContents.replace(/\r/g, '\n').split('\n');
+ var entries = [];
+ var numInvalidLines = 0;
+
+ for (var i = 0; i < lines.length; ++i) {
+ if (lines[i].trim().length == 0)
+ continue;
+ // Parse all valid lines, skipping any others.
+ try {
+ var entry = JSON.parse(lines[i]);
+ if (entry &&
+ typeof(entry) == 'object' &&
+ entry.phase != undefined &&
+ entry.source != undefined &&
+ entry.time != undefined &&
+ entry.type != undefined) {
+ entries.push(entry);
+ continue;
+ }
+ } catch (err) {
+ }
+ ++numInvalidLines;
+ console.log('Unable to parse log line: ' + lines[i]);
+ }
+
+ if (entries.length == 0) {
+ window.alert('Loading log file failed.');
+ return;
+ }
+
+ this.deleteAllEvents();
+
+ this.setIsViewingLogFile_(true);
+
+ var validEntries = [];
+ for (var i = 0; i < entries.length; ++i) {
+ entries[i].wasPassivelyCaptured = true;
+ if (LogEventType[entries[i].type] != undefined &&
+ LogSourceType[entries[i].source.type] != undefined &&
+ LogEventPhase[entries[i].phase] != undefined) {
+ entries[i].type = LogEventType[entries[i].type];
+ entries[i].source.type = LogSourceType[entries[i].source.type];
+ entries[i].phase = LogEventPhase[entries[i].phase];
+ validEntries.push(entries[i]);
+ } else {
+ // TODO(mmenke): Do something reasonable when the event type isn't
+ // found, which could happen when event types are
+ // removed or added between versions. Could also happen
+ // with source types, but less likely.
+ console.log(
+ 'Unrecognized values in log entry: ' + JSON.stringify(entry));
+ }
+ }
+
+ this.numPassivelyCapturedEvents_ = validEntries.length;
+ this.addLogEntries(validEntries);
+
+ var numInvalidEntries = entries.length - validEntries.length;
+ if (numInvalidEntries > 0 || numInvalidLines > 0) {
+ window.alert(
+ numInvalidLines.toString() +
+ ' could not be parsed as JSON strings, and ' +
+ numInvalidEntries.toString() +
+ ' entries don\'t have valid data.\n\n' +
+ 'Unparseable lines may indicate log file corruption.\n' +
+ 'Entries with invalid data may be caused by version differences.\n\n' +
+ 'See console for more information.');
+ }
+}
+
//------------------------------------------------------------------------------
/**
+ * Sets the |categoryTabSwitcher_| of BrowserBridge. Since views depend on
+ * g_browser being initialized, have to have a BrowserBridge prior to tab
+ * construction.
+ */
+BrowserBridge.prototype.setTabSwitcher = function(categoryTabSwitcher) {
+ this.categoryTabSwitcher_ = categoryTabSwitcher;
+};
+
+/**
* Adds a listener of log entries. |observer| will be called back when new log
* data arrives, through:
*
@@ -592,6 +681,25 @@ BrowserBridge.prototype.getNumPassivelyCapturedEvents = function() {
};
/**
+ * Sends each entry to all log observers, and updates |capturedEvents_|.
+ * Also assigns unique ids to log entries without a source.
+ */
+BrowserBridge.prototype.addLogEntries = function(logEntries) {
+ for (var e = 0; e < logEntries.length; ++e) {
+ var logEntry = logEntries[e];
+
+ // Assign unique ID, if needed.
+ if (logEntry.source.id == 0) {
+ logEntry.source.id = this.nextSourcelessEventId_;
+ --this.nextSourcelessEventId_;
+ }
+ this.capturedEvents_.push(logEntry);
+ for (var i = 0; i < this.logObservers_.length; ++i)
+ this.logObservers_[i].onLogEntryAdded(logEntry);
+ }
+};
+
+/**
* Deletes captured events with source IDs in |sourceIds|.
*/
BrowserBridge.prototype.deleteEventsBySourceId = function(sourceIds) {
@@ -626,6 +734,39 @@ BrowserBridge.prototype.deleteAllEvents = function() {
};
/**
+ * Informs log observers whether or not future events will be from a log file.
+ * Hides all tabs except the events and data tabs when viewing a log file, shows
+ * them all otherwise.
+ */
+BrowserBridge.prototype.setIsViewingLogFile_ = function(isViewingLogFile) {
+ this.isViewingLogFile_ = isViewingLogFile;
+ var tabIds = this.categoryTabSwitcher_.getAllTabIds();
+
+ for (var i = 0; i < this.logObservers_.length; ++i)
+ this.logObservers_[i].onSetIsViewingLogFile(isViewingLogFile);
+
+ // Shows/hides tabs not used when viewing a log file.
+ for (var i = 0; i < tabIds.length; ++i) {
+ if (tabIds[i] == 'eventsTab' || tabIds[i] == 'dataTab')
+ continue;
+ this.categoryTabSwitcher_.showTabHandleNode(tabIds[i], !isViewingLogFile);
+ }
+
+ if (isViewingLogFile) {
+ var activeTab = this.categoryTabSwitcher_.findActiveTab();
+ if (activeTab.id != 'eventsTab')
+ this.categoryTabSwitcher_.switchToTab('dataTab', null);
+ }
+};
+
+/**
+ * Returns true if a log file is currently being viewed.
+ */
+BrowserBridge.prototype.isViewingLogFile = function() {
+ return this.isViewingLogFile_;
+};
+
+/**
* If |force| is true, calls all startUpdate functions. Otherwise, just
* runs updates with active observers.
*/