Index: chrome/browser/resources/net_internals/main.js |
=================================================================== |
--- chrome/browser/resources/net_internals/main.js (revision 70417) |
+++ chrome/browser/resources/net_internals/main.js (working copy) |
@@ -75,10 +75,12 @@ |
// 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 @@ |
// 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 @@ |
// 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 @@ |
// 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 @@ |
chrome.send('setLogLevel', ['' + logLevel]); |
} |
+BrowserBridge.prototype.loadLogFile = function(logLevel) { |
eroman
2011/01/12 05:57:34
the parameter here is unused.
mmenke
2011/01/13 03:45:29
Oops...Removed.
|
+ 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,77 @@ |
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 = []; |
+ |
+ for (var i = 0; i < lines.length; ++i) { |
+ // 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); |
+ } |
+ } catch (err) { |
+ err = err; |
eroman
2011/01/12 05:57:34
is this line intended to be a no-op?
Perhaps we s
mmenke
2011/01/13 03:45:29
Forgot to remove that line. Was using it as a bre
|
+ } |
+ } |
+ |
+ 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; |
eroman
2011/01/12 05:57:34
any reason to initialize this to true rather than
mmenke
2011/01/13 03:45:29
I was just thinking the (P) emphasizes that we're
|
+ entries[i].source.type = LogSourceType[entries[i].source.type] |
+ entries[i].type = LogEventType[entries[i].type] |
+ entries[i].phase = LogEventPhase[entries[i].phase]; |
+ if (entries[i].source.type != undefined && |
+ entries[i].type != undefined && |
+ entries[i].phase != undefined) { |
+ // 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. |
+ validEntries.push(entries[i]); |
+ } |
+ } |
+ |
+ this.numPassivelyCapturedEvents_ = validEntries.length; |
+ this.addLogEntries(validEntries); |
+ |
+ var numInvalidEntries = entries.length - validEntries.length; |
+ if (numInvalidEntries > 0) { |
+ window.alert(numInvalidEntries.toString() + |
+ " entries could not be loaded, possibly due to version differences."); |
+ } |
+} |
+ |
//------------------------------------------------------------------------------ |
/** |
+ * 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 +667,25 @@ |
}; |
/** |
+ * 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,9 +720,35 @@ |
}; |
/** |
- * If |force| is true, calls all startUpdate functions. Otherwise, just |
- * runs updates with active observers. |
+ * 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); |
+ } |
+}; |
+ |
+/** |
+ * If |force| is true, calls all startUpdate functions. Otherwise, just runs |
+ * updates with active observers. |
+ */ |
BrowserBridge.prototype.checkForUpdatedInfo = function(force) { |
for (name in this.pollableDataHelpers_) { |
var helper = this.pollableDataHelpers_[name]; |