summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/net_internals
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/resources/net_internals')
-rw-r--r--chrome/browser/resources/net_internals/capture_view.js3
-rw-r--r--chrome/browser/resources/net_internals/dns_view.js5
-rw-r--r--chrome/browser/resources/net_internals/events_view.js3
-rw-r--r--chrome/browser/resources/net_internals/export_view.js6
-rw-r--r--chrome/browser/resources/net_internals/hsts_view.js3
-rw-r--r--chrome/browser/resources/net_internals/http_cache_view.js3
-rw-r--r--chrome/browser/resources/net_internals/http_throttling_view.js3
-rw-r--r--chrome/browser/resources/net_internals/import_view.js4
-rw-r--r--chrome/browser/resources/net_internals/index.html8
-rw-r--r--chrome/browser/resources/net_internals/index.js6
-rw-r--r--chrome/browser/resources/net_internals/log_util.js237
-rw-r--r--chrome/browser/resources/net_internals/log_view_painter.js6
-rw-r--r--chrome/browser/resources/net_internals/logs_view.js3
-rw-r--r--chrome/browser/resources/net_internals/main.css4
-rw-r--r--chrome/browser/resources/net_internals/main.js605
-rw-r--r--chrome/browser/resources/net_internals/prerender_view.js3
-rw-r--r--chrome/browser/resources/net_internals/proxy_view.js8
-rw-r--r--chrome/browser/resources/net_internals/service_providers_view.js8
-rw-r--r--chrome/browser/resources/net_internals/sockets_view.js3
-rw-r--r--chrome/browser/resources/net_internals/source_entry.js4
-rw-r--r--chrome/browser/resources/net_internals/spdy_view.js3
-rw-r--r--chrome/browser/resources/net_internals/test_view.js3
-rw-r--r--chrome/browser/resources/net_internals/time_util.js37
23 files changed, 532 insertions, 436 deletions
diff --git a/chrome/browser/resources/net_internals/capture_view.js b/chrome/browser/resources/net_internals/capture_view.js
index 6e127d3..29d7b7b 100644
--- a/chrome/browser/resources/net_internals/capture_view.js
+++ b/chrome/browser/resources/net_internals/capture_view.js
@@ -47,6 +47,9 @@ var CaptureView = (function() {
g_browser.sourceTracker.addObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ CaptureView.TAB_HANDLE_ID = 'tab-handle-capture';
+
cr.addSingletonGetter(CaptureView);
CaptureView.prototype = {
diff --git a/chrome/browser/resources/net_internals/dns_view.js b/chrome/browser/resources/net_internals/dns_view.js
index a80b201..092926b 100644
--- a/chrome/browser/resources/net_internals/dns_view.js
+++ b/chrome/browser/resources/net_internals/dns_view.js
@@ -46,6 +46,9 @@ var DnsView = (function() {
g_browser.addHostResolverInfoObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ DnsView.TAB_HANDLE_ID = 'tab-handle-dns';
+
cr.addSingletonGetter(DnsView);
DnsView.prototype = {
@@ -106,7 +109,7 @@ var DnsView = (function() {
}
}
- var expiresDate = convertTimeTicksToDate(e.expiration);
+ var expiresDate = timeutil.convertTimeTicksToDate(e.expiration);
var expiresCell = addNode(tr, 'td');
addTextNode(expiresCell, expiresDate.toLocaleString());
}
diff --git a/chrome/browser/resources/net_internals/events_view.js b/chrome/browser/resources/net_internals/events_view.js
index f024fdd..a94a309 100644
--- a/chrome/browser/resources/net_internals/events_view.js
+++ b/chrome/browser/resources/net_internals/events_view.js
@@ -108,6 +108,9 @@ var EventsView = (function() {
this.initializeSourceList_();
}
+ // ID for special HTML element in category_tabs.html
+ EventsView.TAB_HANDLE_ID = 'tab-handle-events';
+
cr.addSingletonGetter(EventsView);
EventsView.prototype = {
diff --git a/chrome/browser/resources/net_internals/export_view.js b/chrome/browser/resources/net_internals/export_view.js
index e12b662..eec148c 100644
--- a/chrome/browser/resources/net_internals/export_view.js
+++ b/chrome/browser/resources/net_internals/export_view.js
@@ -46,6 +46,9 @@ var ExportView = (function() {
this.lastBlobURL_ = null;
}
+ // ID for special HTML element in category_tabs.html
+ ExportView.TAB_HANDLE_ID = 'tab-handle-export';
+
cr.addSingletonGetter(ExportView);
ExportView.prototype = {
@@ -110,7 +113,8 @@ var ExportView = (function() {
}
this.setSaveFileStatus('Preparing data...', true);
- createLogDumpAsync(userComments, this.onLogDumpCreated_.bind(this));
+ logutil.createLogDumpAsync(userComments,
+ this.onLogDumpCreated_.bind(this));
},
/**
diff --git a/chrome/browser/resources/net_internals/hsts_view.js b/chrome/browser/resources/net_internals/hsts_view.js
index b2bc94d0..add363f 100644
--- a/chrome/browser/resources/net_internals/hsts_view.js
+++ b/chrome/browser/resources/net_internals/hsts_view.js
@@ -53,6 +53,9 @@ var HSTSView = (function() {
g_browser.addHSTSObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ HSTSView.TAB_HANDLE_ID = 'tab-handle-hsts';
+
cr.addSingletonGetter(HSTSView);
HSTSView.prototype = {
diff --git a/chrome/browser/resources/net_internals/http_cache_view.js b/chrome/browser/resources/net_internals/http_cache_view.js
index 0bcc847..9f77473 100644
--- a/chrome/browser/resources/net_internals/http_cache_view.js
+++ b/chrome/browser/resources/net_internals/http_cache_view.js
@@ -30,6 +30,9 @@ var HttpCacheView = (function() {
g_browser.addHttpCacheInfoObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ HttpCacheView.TAB_HANDLE_ID = 'tab-handle-http-cache';
+
cr.addSingletonGetter(HttpCacheView);
HttpCacheView.prototype = {
diff --git a/chrome/browser/resources/net_internals/http_throttling_view.js b/chrome/browser/resources/net_internals/http_throttling_view.js
index e5d45f8..fae7489 100644
--- a/chrome/browser/resources/net_internals/http_throttling_view.js
+++ b/chrome/browser/resources/net_internals/http_throttling_view.js
@@ -30,6 +30,9 @@ var HttpThrottlingView = (function() {
g_browser.addHttpThrottlingObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ HttpThrottlingView.TAB_HANDLE_ID = 'tab-handle-http-throttling';
+
cr.addSingletonGetter(HttpThrottlingView);
HttpThrottlingView.prototype = {
diff --git a/chrome/browser/resources/net_internals/import_view.js b/chrome/browser/resources/net_internals/import_view.js
index 6504bd7..f2bf03c 100644
--- a/chrome/browser/resources/net_internals/import_view.js
+++ b/chrome/browser/resources/net_internals/import_view.js
@@ -56,6 +56,8 @@ var ImportView = (function() {
this.loadedInfoUserComments_ = $(LOADED_INFO_USER_COMMENTS_ID);
}
+ ImportView.TAB_HANDLE_ID = 'tab-handle-import';
+
cr.addSingletonGetter(ImportView);
ImportView.prototype = {
@@ -148,7 +150,7 @@ var ImportView = (function() {
},
onLoadLogFile: function(logFile, event) {
- var result = loadLogFile(event.target.result, logFile.fileName);
+ var result = logutil.loadLogFile(event.target.result, logFile.fileName);
this.setLoadFileStatus(result, false);
},
diff --git a/chrome/browser/resources/net_internals/index.html b/chrome/browser/resources/net_internals/index.html
index 25cb063..5037ac8 100644
--- a/chrome/browser/resources/net_internals/index.html
+++ b/chrome/browser/resources/net_internals/index.html
@@ -18,14 +18,14 @@ found in the LICENSE file.
</head>
<body id=import-view-drop-target>
- <div id=statusViewId>
+ <div id=status-view>
<!-- We use a different status bar when in capture mode vs file mode -->
- <div id=statusViewForCapture>
+ <div id=status-view-for-capture>
Recording network events...
</div>
- <div id=statusViewForFile style="display:none">
- Displaying log file (<span id='statusViewDumpFileName'></span>)
+ <div id=status-view-for-file style="display:none">
+ Displaying log file (<span id=status-view-dump-file-name></span>)
</div>
</div>
diff --git a/chrome/browser/resources/net_internals/index.js b/chrome/browser/resources/net_internals/index.js
index 2a5ef5c..48e168c 100644
--- a/chrome/browser/resources/net_internals/index.js
+++ b/chrome/browser/resources/net_internals/index.js
@@ -13,13 +13,15 @@
<include src="hsts_view.js"/>
<include src="browser_bridge.js"/>
<include src="source_tracker.js"/>
+<include src="resizable_vertical_split_view.js"/>
<include src="main.js"/>
+<include src="time_util.js"/>
+<include src="log_util.js"/>
<include src="dns_view.js"/>
<include src="source_row.js"/>
<include src="events_view.js"/>
<include src="details_view.js"/>
<include src="source_entry.js"/>
-<include src="resizable_vertical_split_view.js"/>
<include src="top_mid_bottom_view.js"/>
<include src="timeline_view_painter.js"/>
<include src="log_view_painter.js"/>
@@ -34,5 +36,5 @@
<include src="prerender_view.js"/>
document.addEventListener('DOMContentLoaded', function () {
- onLoaded(); // from main.js
+ MainView.getInstance(); // from main.js
});
diff --git a/chrome/browser/resources/net_internals/log_util.js b/chrome/browser/resources/net_internals/log_util.js
new file mode 100644
index 0000000..aafffec
--- /dev/null
+++ b/chrome/browser/resources/net_internals/log_util.js
@@ -0,0 +1,237 @@
+// 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.
+
+logutil = (function() {
+ /**
+ * Creates a new log dump. |events| is a list of all events, |polledData| is
+ * an object containing the results of each poll, |tabData| is an object
+ * containing data for individual tabs, and |date| is the time the dump was
+ * created, as a formatted string.
+ * Returns the new log dump as an object. |date| may be null.
+ *
+ * TODO(eroman): Use javadoc notation for these parameters.
+ *
+ * Log dumps are just JSON objects containing five values:
+ *
+ * |userComments| User-provided notes describing what this dump file is
+ * about.
+ * |constants| needed to interpret the data. This also includes some
+ * browser state information.
+ * |events| from the NetLog.
+ * |polledData| from each PollableDataHelper available on the source OS.
+ * |tabData| containing any tab-specific state that's not present in
+ * |polledData|.
+ *
+ * |polledData| and |tabData| may be empty objects, or may be missing data for
+ * tabs not present on the OS the log is from.
+ */
+ function createLogDump(userComments, constants, events, polledData, tabData,
+ date) {
+ if (g_browser.sourceTracker.getSecurityStripping())
+ events = events.map(stripCookiesAndLoginInfo);
+
+ var logDump = {
+ 'userComments': userComments,
+ 'constants': constants,
+ 'events': events,
+ 'polledData': polledData,
+ 'tabData': tabData
+ };
+
+ // Not technically client info, but it's used at the same point in the code.
+ if (date && constants.clientInfo)
+ constants.clientInfo.date = date;
+
+ return logDump;
+ }
+
+ /**
+ * Creates a full log dump using |polledData| and the return value of each
+ * tab's saveState function and passes it to |callback|.
+ */
+ function onUpdateAllCompleted(userComments, callback, polledData) {
+ // Gather any tab-specific state information.
+ var tabData = {};
+ var categoryTabSwitcher = MainView.getInstance().categoryTabSwitcher();
+ var tabIds = categoryTabSwitcher.getAllTabIds();
+ for (var i = 0; i < tabIds.length; ++i) {
+ var view = categoryTabSwitcher.findTabById(tabIds[i]).contentView;
+ if (view.saveState)
+ tabData[tabIds[i]] = view.saveState();
+ }
+
+ var logDump = createLogDump(userComments,
+ Constants,
+ g_browser.sourceTracker.getAllCapturedEvents(),
+ polledData,
+ tabData,
+ (new Date()).toLocaleString());
+ callback(JSON.stringify(logDump, null, ' '));
+ }
+
+ /**
+ * Called to create a new log dump. Must not be called once a dump has been
+ * loaded. Once a log dump has been created, |callback| is passed the dumped
+ * text as a string.
+ */
+ function createLogDumpAsync(userComments, callback) {
+ g_browser.updateAllInfo(
+ onUpdateAllCompleted.bind(null, userComments, callback));
+ }
+
+ /**
+ * Loads a full log dump. Returns a string containing a log of the load.
+ * The process goes like this:
+ * 1) Load constants. If this fails, or the version number can't be handled,
+ * abort the load. If this step succeeds, the load cannot be aborted.
+ * 2) Clear all events. Any event observers are informed of the clear as
+ * normal.
+ * 3) Call onLoadLogStart(polledData, tabData) for each view with an
+ * onLoadLogStart function. This allows tabs to clear any extra state
+ * that would affect the next step. |polledData| contains the data polled
+ * for all helpers, but |tabData| contains only the data from that
+ * specific tab.
+ * 4) Add all events from the log file.
+ * 5) Call onLoadLogFinish(polledData, tabData) for each view with an
+ * onLoadLogFinish function. The arguments are the same as in step 3. If
+ * there is no onLoadLogFinish function, it throws an exception, or it
+ * returns false instead of true, the data dump is assumed to contain no
+ * valid data for the tab, so the tab is hidden. Otherwise, the tab is
+ * shown.
+ */
+ function loadLogDump(logDump, fileName) {
+ // Perform minimal validity check, and abort if it fails.
+ if (typeof(logDump) != 'object')
+ return 'Load failed. Top level JSON data is not an object.';
+
+ // String listing text summary of load errors, if any.
+ var errorString = '';
+
+ if (!areValidConstants(logDump.constants))
+ errorString += 'Invalid constants object.\n';
+ if (typeof(logDump.events) != 'object')
+ errorString += 'NetLog events missing.\n';
+ if (typeof(logDump.constants.logFormatVersion) != 'number')
+ errorString += 'Invalid version number.\n';
+
+ if (errorString.length > 0)
+ return 'Load failed:\n\n' + errorString;
+
+ if (typeof(logDump.polledData) != 'object')
+ logDump.polledData = {};
+ if (typeof(logDump.tabData) != 'object')
+ logDump.tabData = {};
+
+ if (logDump.constants.logFormatVersion != Constants.logFormatVersion) {
+ return 'Unable to load different log version.' +
+ ' Found ' + logDump.constants.logFormatVersion +
+ ', Expected ' + Constants.logFormatVersion;
+ }
+
+ g_browser.receivedConstants(logDump.constants);
+
+ // Prevent communication with the browser. Once the constants have been
+ // loaded, it's safer to continue trying to load the log, even in the case
+ // of bad data.
+ MainView.getInstance().onLoadLogFile(fileName);
+
+ // Delete all events. This will also update all logObservers.
+ g_browser.sourceTracker.deleteAllSourceEntries();
+
+ // Inform all the views that a log file is being loaded, and pass in
+ // view-specific saved state, if any.
+ var categoryTabSwitcher = MainView.getInstance().categoryTabSwitcher();
+ var tabIds = categoryTabSwitcher.getAllTabIds();
+ for (var i = 0; i < tabIds.length; ++i) {
+ var view = categoryTabSwitcher.findTabById(tabIds[i]).contentView;
+ view.onLoadLogStart(logDump.polledData, logDump.tabData[tabIds[i]]);
+ }
+
+ // Check for validity of each log entry, and then add the ones that pass.
+ // Since the events are kept around, and we can't just hide a single view
+ // on a bad event, we have more error checking for them than other data.
+ var validPassiveEvents = [];
+ var validActiveEvents = [];
+ for (var eventIndex = 0; eventIndex < logDump.events.length; ++eventIndex) {
+ var event = logDump.events[eventIndex];
+ if (typeof(event) == 'object' && typeof(event.source) == 'object' &&
+ typeof(event.time) == 'string' &&
+ getKeyWithValue(LogEventType, event.type) != '?' &&
+ getKeyWithValue(LogSourceType, event.source.type) != '?' &&
+ getKeyWithValue(LogEventPhase, event.phase) != '?') {
+ if (event.wasPassivelyCaptured) {
+ validPassiveEvents.push(event);
+ } else {
+ validActiveEvents.push(event);
+ }
+ }
+ }
+ g_browser.sourceTracker.onReceivedPassiveLogEntries(validPassiveEvents);
+ g_browser.sourceTracker.onReceivedLogEntries(validActiveEvents);
+
+ var numInvalidEvents = logDump.events.length
+ - validPassiveEvents.length
+ - validActiveEvents.length;
+ if (numInvalidEvents > 0) {
+ errorString += 'Unable to load ' + numInvalidEvents +
+ ' events, due to invalid data.\n\n';
+ }
+
+ // Update all views with data from the file. Show only those views which
+ // successfully load the data.
+ for (var i = 0; i < tabIds.length; ++i) {
+ var view = categoryTabSwitcher.findTabById(tabIds[i]).contentView;
+ var showView = false;
+ // The try block eliminates the need for checking every single value
+ // before trying to access it.
+ try {
+ if (view.onLoadLogFinish(logDump.polledData,
+ logDump.tabData[tabIds[i]],
+ logDump.userComments)) {
+ showView = true;
+ }
+ } catch (error) {
+ }
+ categoryTabSwitcher.showTabHandleNode(tabIds[i], showView);
+ }
+
+ return errorString + 'Log loaded.';
+ }
+
+ /**
+ * Loads a log dump from the string |logFileContents|, which can be either a
+ * full net-internals dump, or a NetLog dump only. Returns a string
+ * containing a log of the load.
+ */
+ function loadLogFile(logFileContents, fileName) {
+ // Try and parse the log dump as a single JSON string. If this succeeds,
+ // it's most likely a full log dump. Otherwise, it may be a dump created by
+ // --log-net-log.
+ var parsedDump = null;
+ try {
+ parsedDump = JSON.parse(logFileContents);
+ } catch (error) {
+ try {
+ // We may have a --log-net-log=blah log dump. If so, remove the comma
+ // after the final good entry, and add the necessary close brackets.
+ var end = Math.max(logFileContents.lastIndexOf(',\n'),
+ logFileContents.lastIndexOf(',\r'));
+ if (end != -1)
+ parsedDump = JSON.parse(logFileContents.substring(0, end) + ']}');
+ }
+ catch (error) {
+ }
+ }
+
+ if (!parsedDump)
+ return 'Unable to parse log dump as JSON file.';
+ return loadLogDump(parsedDump, fileName);
+ }
+
+ // Exports.
+ return {
+ createLogDumpAsync : createLogDumpAsync,
+ loadLogFile : loadLogFile
+ };
+})();
diff --git a/chrome/browser/resources/net_internals/log_view_painter.js b/chrome/browser/resources/net_internals/log_view_painter.js
index f37e593..e0abbc1 100644
--- a/chrome/browser/resources/net_internals/log_view_painter.js
+++ b/chrome/browser/resources/net_internals/log_view_painter.js
@@ -38,7 +38,7 @@ function addSourceEntry_(node, sourceEntry) {
var nobr2 = addNode(p2, 'nobr');
var logEntries = sourceEntry.getLogEntries();
- var startDate = convertTimeTicksToDate(logEntries[0].time);
+ var startDate = timeutil.convertTimeTicksToDate(logEntries[0].time);
addTextNode(nobr2, 'Start Time: ' + startDate.toLocaleString());
var pre = addNode(div, 'pre');
@@ -60,7 +60,7 @@ PrintSourceEntriesAsText = function(sourceEntries) {
if (entries.length == 0)
return '';
- var startDate = convertTimeTicksToDate(entries[0].orig.time);
+ var startDate = timeutil.convertTimeTicksToDate(entries[0].orig.time);
var startTime = startDate.getTime();
var tablePrinter = new TablePrinter();
@@ -77,7 +77,7 @@ PrintSourceEntriesAsText = function(sourceEntries) {
tablePrinter.addCell(entry.orig.wasPassivelyCaptured ? '(P) ' : '');
tablePrinter.addCell('t=');
- var date = convertTimeTicksToDate(entry.orig.time) ;
+ var date = timeutil.convertTimeTicksToDate(entry.orig.time) ;
var tCell = tablePrinter.addCell(date.getTime());
tCell.alignRight = true;
tablePrinter.addCell(' [st=');
diff --git a/chrome/browser/resources/net_internals/logs_view.js b/chrome/browser/resources/net_internals/logs_view.js
index 5ce29f4..c5a58a5 100644
--- a/chrome/browser/resources/net_internals/logs_view.js
+++ b/chrome/browser/resources/net_internals/logs_view.js
@@ -48,6 +48,9 @@ var LogsView = (function() {
this.onLogsRefresh_.bind(this));
}
+ // ID for special HTML element in category_tabs.html
+ LogsView.TAB_HANDLE_ID = 'tab-handle-logs';
+
cr.addSingletonGetter(LogsView);
/**
diff --git a/chrome/browser/resources/net_internals/main.css b/chrome/browser/resources/net_internals/main.css
index 23e9013..96971cf 100644
--- a/chrome/browser/resources/net_internals/main.css
+++ b/chrome/browser/resources/net_internals/main.css
@@ -101,13 +101,13 @@ table.styledTable,
color: red;
}
-#statusViewForCapture {
+#status-view-for-capture {
background: red;
color: #eee;
padding: 4px;
}
-#statusViewForFile {
+#status-view-for-file {
background: #88c;
color: #eee;
padding: 4px;
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index a123e4c..5a242a3 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -3,7 +3,8 @@
// found in the LICENSE file.
/**
- * Dictionary of constants (initialized by browser, updated on load log).
+ * Dictionary of constants (Initialized soon after loading by data from browser,
+ * updated on load log).
*/
var LogEventType = null;
var LogEventPhase = null;
@@ -15,183 +16,225 @@ var LoadFlag = null;
var AddressFamily = null;
/**
+ * Dictionary of all constants, used for saving log files.
+ */
+var Constants = null;
+
+/**
* Object to communicate between the renderer and the browser.
* @type {!BrowserBridge}
*/
var g_browser = null;
/**
- * The browser gives us times in terms of "time ticks" in milliseconds.
- * This function converts the tick count to a Date() object.
- *
- * @param {String} timeTicks.
- * @returns {Date} The time that |timeTicks| represents.
+ * This class is the root view object of the page. It owns all the other
+ * views, and manages switching between them. It is also responsible for
+ * initializing the views and the BrowserBridge.
*/
-var convertTimeTicksToDate;
+var MainView = (function() {
+ 'use strict';
+
+ // IDs for special HTML elements in index.html
+ var CATEGORY_TAB_HANDLES_ID = 'category-tab-handles';
+ var SPLITTER_BOX_FOR_MAIN_TABS_ID = 'splitter-box-for-main-tabs';
+ var STATUS_VIEW_ID = 'status-view';
+ var STATUS_VIEW_FOR_CAPTURE_ID = 'status-view-for-capture';
+ var STATUS_VIEW_FOR_FILE_ID = 'status-view-for-file';
+ var STATUS_VIEW_DUMP_FILE_NAME_ID = 'status-view-dump-file-name';
+
+ // We inherit from ResizableVerticalSplitView.
+ var superClass = ResizableVerticalSplitView;
+
+ /**
+ * Main entry point. Called once the page has loaded.
+ * @constructor
+ */
+ function MainView() {
+ assertFirstConstructorCall(MainView);
+
+ // This must be initialized before the tabs, so they can register as
+ // observers.
+ g_browser = BrowserBridge.getInstance();
+
+ // This view is a left (resizable) navigation bar.
+ this.categoryTabSwitcher_ = new TabSwitcherView();
+ var tabs = this.categoryTabSwitcher_;
+
+ // Call superclass's constructor, initializing the view which lets you tab
+ // between the different sub-views.
+ superClass.call(this,
+ new DivView(CATEGORY_TAB_HANDLES_ID),
+ tabs,
+ new DivView(SPLITTER_BOX_FOR_MAIN_TABS_ID));
+
+ // By default the split for the left navbar will be at 50% of the entire
+ // width. This is not aesthetically pleasing, so we will shrink it.
+ // TODO(eroman): Should set this dynamically based on the largest tab
+ // name rather than using a fixed width.
+ this.setLeftSplit(150);
+
+ // Populate the main tabs. Even tabs that don't contain information for the
+ // running OS should be created, so they can load log dumps from other
+ // OSes.
+ tabs.addTab(CaptureView.TAB_HANDLE_ID, CaptureView.getInstance(),
+ false, true);
+ tabs.addTab(ExportView.TAB_HANDLE_ID, ExportView.getInstance(),
+ false, true);
+ tabs.addTab(ImportView.TAB_HANDLE_ID, ImportView.getInstance(),
+ false, true);
+ tabs.addTab(ProxyView.TAB_HANDLE_ID, ProxyView.getInstance(),
+ false, true);
+ tabs.addTab(EventsView.TAB_HANDLE_ID, EventsView.getInstance(),
+ false, true);
+ tabs.addTab(DnsView.TAB_HANDLE_ID, DnsView.getInstance(),
+ false, true);
+ tabs.addTab(SocketsView.TAB_HANDLE_ID, SocketsView.getInstance(),
+ false, true);
+ tabs.addTab(SpdyView.TAB_HANDLE_ID, SpdyView.getInstance(), false, true);
+ tabs.addTab(HttpCacheView.TAB_HANDLE_ID, HttpCacheView.getInstance(),
+ false, true);
+ tabs.addTab(HttpThrottlingView.TAB_HANDLE_ID,
+ HttpThrottlingView.getInstance(), false, true);
+ tabs.addTab(ServiceProvidersView.TAB_HANDLE_ID,
+ ServiceProvidersView.getInstance(), false, cr.isWindows);
+ tabs.addTab(TestView.TAB_HANDLE_ID, TestView.getInstance(), false, true);
+ tabs.addTab(HSTSView.TAB_HANDLE_ID, HSTSView.getInstance(), false, true);
+ tabs.addTab(LogsView.TAB_HANDLE_ID, LogsView.getInstance(),
+ false, cr.isChromeOS);
+ tabs.addTab(PrerenderView.TAB_HANDLE_ID, PrerenderView.getInstance(),
+ false, true);
+
+ // Build a map from the anchor name of each tab handle to its "tab ID".
+ // We will consider navigations to the #hash as a switch tab request.
+ var anchorMap = {};
+ var tabIds = tabs.getAllTabIds();
+ for (var i = 0; i < tabIds.length; ++i) {
+ var aNode = $(tabIds[i]);
+ anchorMap[aNode.hash] = tabIds[i];
+ }
+ // Default the empty hash to the data tab.
+ anchorMap['#'] = anchorMap[''] = ExportView.TAB_HANDLE_ID;
-/**
- * Called to create a new log dump. Must not be called once a dump has been
- * loaded. Once a log dump has been created, |callback| is passed the dumped
- * text as a string.
- */
-var createLogDumpAsync;
+ window.onhashchange = onUrlHashChange.bind(null, tabs, anchorMap);
-/**
- * Loads a log dump from the string |logFileContents|, which can be either a
- * full net-internals dump, or a NetLog dump only. Returns a string containing
- * a log of the load.
- */
-var loadLogFile;
+ // Cut out a small vertical strip at the top of the window, to display
+ // a high level status (i.e. if we are capturing events, or displaying a
+ // log file). Below it we will position the main tabs and their content
+ // area.
+ var statusView = new DivView(STATUS_VIEW_ID);
+ var verticalSplitView = new VerticalSplitView(statusView, this);
+ var windowView = new WindowView(verticalSplitView);
-// Start of annonymous namespace.
-(function() {
+ // Trigger initial layout.
+ windowView.resetGeometry();
-var categoryTabSwitcher;
+ // Select the initial view based on the current URL.
+ window.onhashchange();
-/**
- * Main entry point. called once the page has loaded.
- */
-onLoaded = function() {
- g_browser = new BrowserBridge();
-
- // Create a view which lets you tab between the different sub-views.
- // This view is a left (resizable) navigation bar.
- categoryTabSwitcher = new TabSwitcherView();
- var tabSwitcherSplitView = new ResizableVerticalSplitView(
- new DivView('category-tab-handles'),
- categoryTabSwitcher,
- new DivView('splitter-box-for-main-tabs'));
-
- // By default the split for the left navbar will be at 50% of the entire
- // width. This is not aesthetically pleasing, so we will shrink it.
- // TODO(eroman): Should set this dynamically based on the largest tab
- // name rather than using a fixed width.
- tabSwitcherSplitView.setLeftSplit(150);
-
- // Populate the main tabs. Even tabs that don't contain information for the
- // running OS should be created, so they can load log dumps from other
- // OSes.
- categoryTabSwitcher.addTab('tab-handle-events', EventsView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-proxy', ProxyView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-dns', DnsView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-sockets', SocketsView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-spdy', SpdyView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-http-cache',
- HttpCacheView.getInstance(), false, true);
- categoryTabSwitcher.addTab('tab-handle-import', ImportView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-export', ExportView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-capture', CaptureView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-service-providers',
- ServiceProvidersView.getInstance(),
- false, cr.isWindows);
- categoryTabSwitcher.addTab('tab-handle-tests', TestView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-hsts', HSTSView.getInstance(),
- false, true);
- categoryTabSwitcher.addTab('tab-handle-http-throttling',
- HttpThrottlingView.getInstance(), false, true);
- categoryTabSwitcher.addTab('tab-handle-logs', LogsView.getInstance(), false,
- cr.isChromeOS);
- categoryTabSwitcher.addTab('tab-handle-prerender',
- PrerenderView.getInstance(), false, true);
-
- // Build a map from the anchor name of each tab handle to its "tab ID".
- // We will consider navigations to the #hash as a switch tab request.
- var anchorMap = {};
- var tabIds = categoryTabSwitcher.getAllTabIds();
- for (var i = 0; i < tabIds.length; ++i) {
- var aNode = $(tabIds[i]);
- anchorMap[aNode.hash] = tabIds[i];
- }
- // Default the empty hash to the data tab.
- anchorMap['#'] = anchorMap[''] = 'tab-handle-export';
+ g_browser.addConstantsObserver(new ConstantsObserver());
- window.onhashchange = onUrlHashChange.bind(null, anchorMap);
-
- // Cut out a small vertical strip at the top of the window, to display
- // a high level status (i.e. if we are capturing events, or displaying a
- // log file). Below it we will position the main tabs and their content
- // area.
- var statusView = new DivView('statusViewId');
- var verticalSplitView = new VerticalSplitView(statusView,
- tabSwitcherSplitView);
- var windowView = new WindowView(verticalSplitView);
-
- // Trigger initial layout.
- windowView.resetGeometry();
+ // Tell the browser that we are ready to start receiving log events.
+ g_browser.sendReady();
+ }
- // Select the initial view based on the current URL.
- window.onhashchange();
+ cr.addSingletonGetter(MainView);
+
+ MainView.prototype = {
+ // Inherit the superclass's methods.
+ __proto__: superClass.prototype,
+
+ // This is exposed both so the log import/export code can enumerate all the
+ // tabs, and for testing.
+ categoryTabSwitcher: function() {
+ return this.categoryTabSwitcher_;
+ },
+
+ /**
+ * Prevents receiving/sending events to/from the browser, so loaded data
+ * will not be mixed with current Chrome state. Also hides any interactive
+ * HTML elements that send messages to the browser. Cannot be undone
+ * without reloading the page.
+ *
+ * @param {String} fileName The name of the log file that has been loaded.
+ */
+ onLoadLogFile: function(fileName) {
+ // Swap out the status bar to indicate we have loaded from a file.
+ setNodeDisplay($(STATUS_VIEW_FOR_CAPTURE_ID), false);
+ setNodeDisplay($(STATUS_VIEW_FOR_FILE_ID), true);
+
+ // Indicate which file is being displayed.
+ $(STATUS_VIEW_DUMP_FILE_NAME_ID).innerText = fileName;
+
+ document.styleSheets[0].insertRule('.hideOnLoadLog { display: none; }');
+
+ g_browser.sourceTracker.setSecurityStripping(false);
+ g_browser.disable();
+ }
+ };
- g_browser.addConstantsObserver(new ConstantsObserver());
- // Tell the browser that we are ready to start receiving log events.
- g_browser.sendReady();
-};
+ /*
+ * Takes the current hash in form of "#tab&param1=value1&param2=value2&...".
+ * Puts the parameters in an object, and passes the resulting object to
+ * |categoryTabSwitcher|. Uses tab and |anchorMap| to find a tab ID,
+ * which it also passes to the tab switcher.
+ *
+ * Parameters and values are decoded with decodeURIComponent().
+ */
+ function onUrlHashChange(categoryTabSwitcher, anchorMap) {
+ var parameters = window.location.hash.split('&');
+
+ var tabId = anchorMap[parameters[0]];
+ if (!tabId)
+ return;
+
+ // Split each string except the first around the '='.
+ var paramDict = null;
+ for (var i = 1; i < parameters.length; i++) {
+ var paramStrings = parameters[i].split('=');
+ if (paramStrings.length != 2)
+ continue;
+ if (paramDict == null)
+ paramDict = {};
+ var key = decodeURIComponent(paramStrings[0]);
+ var value = decodeURIComponent(paramStrings[1]);
+ paramDict[key] = value;
+ }
-/*
- * Takes the current hash in form of "#tab&param1=value1&param2=value2&...".
- * Puts the parameters in an object, and passes the resulting object to
- * |categoryTabSwitcher|. Uses tab and |anchorMap| to find a tab ID,
- * which it also passes to the tab switcher.
- *
- * Parameters and values are decoded with decodeURIComponent().
- */
-function onUrlHashChange(anchorMap) {
- var parameters = window.location.hash.split('&');
-
- var tabId = anchorMap[parameters[0]];
- if (!tabId)
- return;
-
- // Split each string except the first around the '='.
- var paramDict = null;
- for (var i = 1; i < parameters.length; i++) {
- var paramStrings = parameters[i].split('=');
- if (paramStrings.length != 2)
- continue;
- if (paramDict == null)
- paramDict = {};
- var key = decodeURIComponent(paramStrings[0]);
- var value = decodeURIComponent(paramStrings[1]);
- paramDict[key] = value;
+ categoryTabSwitcher.switchToTab(tabId, paramDict);
}
- categoryTabSwitcher.switchToTab(tabId, paramDict);
-}
+ return MainView;
+})();
+
+function ConstantsObserver() {}
/**
- * Prevents receiving/sending events to/from the browser, so loaded data will
- * not be mixed with current Chrome state. Also hides any interactive HTML
- * elements that send messages to the browser. Cannot be undone without
- * reloading the page.
- *
- * @param {String} fileName The name of the log file that has been loaded.
+ * Attempts to load all constants from |constants|. Returns false if one or
+ * more entries are missing. On failure, global dictionaries are not
+ * modified.
*/
-function onLoadLogFile(fileName) {
- // Swap out the status bar to indicate we have loaded from a file.
- setNodeDisplay($('statusViewForCapture'), false);
- setNodeDisplay($('statusViewForFile'), true);
+ConstantsObserver.prototype.onReceivedConstants =
+ function(receivedConstants) {
+ if (!areValidConstants(receivedConstants))
+ return false;
- // Indicate which file is being displayed.
- $('statusViewDumpFileName').innerText = fileName;
+ Constants = receivedConstants;
- document.styleSheets[0].insertRule('.hideOnLoadLog { display: none; }');
+ LogEventType = Constants.logEventTypes;
+ ClientInfo = Constants.clientInfo;
+ LogEventPhase = Constants.logEventPhase;
+ LogSourceType = Constants.logSourceType;
+ LogLevelType = Constants.logLevelType;
+ LoadFlag = Constants.loadFlag;
+ NetError = Constants.netError;
+ AddressFamily = Constants.addressFamily;
- g_browser.sourceTracker.setSecurityStripping(false);
- g_browser.disable();
-}
+ timeutil.setTimeTickOffset(Constants.timeTickOffset);
+};
/**
- * Returns true if |constants| appears to be a valid constants object.
+ * Returns true if it's given a valid-looking constants object.
*/
function areValidConstants(receivedConstants) {
return typeof(receivedConstants) == 'object' &&
@@ -206,263 +249,3 @@ function areValidConstants(receivedConstants) {
typeof(receivedConstants.timeTickOffset) == 'string' &&
typeof(receivedConstants.logFormatVersion) == 'number';
}
-
-/**
- * Dictionary of all constants, used for saving log files.
- */
-var constants = null;
-
-/**
- * Offset needed to convert event times to Date objects.
- */
-var timeTickOffset = 0;
-
-function ConstantsObserver() {}
-
-/**
- * Attempts to load all constants from |constants|. Returns false if one or
- * more entries are missing. On failure, global dictionaries are not modified.
- */
-ConstantsObserver.prototype.onReceivedConstants = function(receivedConstants) {
- if (!areValidConstants(receivedConstants))
- return false;
-
- constants = receivedConstants;
-
- LogEventType = constants.logEventTypes;
- ClientInfo = constants.clientInfo;
- LogEventPhase = constants.logEventPhase;
- LogSourceType = constants.logSourceType;
- LogLevelType = constants.logLevelType;
- LoadFlag = constants.loadFlag;
- NetError = constants.netError;
- AddressFamily = constants.addressFamily;
-
- // Note that the subtraction by 0 is to cast to a number (probably a float
- // since the numbers are big).
- timeTickOffset = constants.timeTickOffset - 0;
-
- return true;
-};
-
-convertTimeTicksToDate = function(timeTicks) {
- var timeStampMs = timeTickOffset + (timeTicks - 0);
- return new Date(timeStampMs);
-};
-
-/**
- * Creates a new log dump. |events| is a list of all events, |polledData| is an
- * object containing the results of each poll, |tabData| is an object containing
- * data for individual tabs, and |date| is the time the dump was created, as a
- * formatted string.
- * Returns the new log dump as an object. |date| may be null.
- *
- * TODO(eroman): Use javadoc notation for these parameters.
- *
- * Log dumps are just JSON objects containing four values:
- *
- * |userComments| User-provided notes describing what this dump file is about.
- * |constants| needed to interpret the data. This also includes some browser
- * state information
- * |events| from the NetLog,
- * |polledData| from each PollableDataHelper available on the source OS,
- * |tabData| containing any tab-specific state that's not present in
- * |polledData|.
- *
- * |polledData| and |tabData| may be empty objects, or may be missing data for
- * tabs not present on the OS the log is from.
- */
-function createLogDump(userComments, constants, events, polledData, tabData,
- date) {
- if (g_browser.sourceTracker.getSecurityStripping())
- events = events.map(stripCookiesAndLoginInfo);
-
- var logDump = {
- 'userComments': userComments,
- 'constants': constants,
- 'events': events,
- 'polledData': polledData,
- 'tabData': tabData
- };
-
- // Not technically client info, but it's used at the same point in the code.
- if (date && constants.clientInfo)
- constants.clientInfo.date = date;
-
- return logDump;
-}
-
-/**
- * Creates a full log dump using |polledData| and the return value of each tab's
- * saveState function and passes it to |callback|.
- */
-function onUpdateAllCompleted(userComments, callback, polledData) {
- // Gather any tab-specific state information.
- var tabData = {};
- var tabIds = categoryTabSwitcher.getAllTabIds();
- for (var i = 0; i < tabIds.length; ++i) {
- var view = categoryTabSwitcher.findTabById(tabIds[i]).contentView;
- if (view.saveState)
- tabData[tabIds[i]] = view.saveState();
- }
-
- var logDump = createLogDump(userComments,
- constants,
- g_browser.sourceTracker.getAllCapturedEvents(),
- polledData,
- tabData,
- (new Date()).toLocaleString());
- callback(JSON.stringify(logDump, null, ' '));
-}
-
-createLogDumpAsync = function(userComments, callback) {
- g_browser.updateAllInfo(
- onUpdateAllCompleted.bind(null, userComments, callback));
-};
-
-/**
- * Loads a full log dump. Returns a string containing a log of the load.
- * The process goes like this:
- * 1) Load constants. If this fails, or the version number can't be handled,
- * abort the load. If this step succeeds, the load cannot be aborted.
- * 2) Clear all events. Any event observers are informed of the clear as
- * normal.
- * 3) Call onLoadLogStart(polledData, tabData) for each view with an
- * onLoadLogStart function. This allows tabs to clear any extra state that
- * would affect the next step. |polledData| contains the data polled for
- * all helpers, but |tabData| contains only the data from that specific tab.
- * 4) Add all events from the log file.
- * 5) Call onLoadLogFinish(polledData, tabData) for each view with an
- * onLoadLogFinish function. The arguments are the same as in step 3. If
- * there is no onLoadLogFinish function, it throws an exception, or it
- * returns false instead of true, the data dump is assumed to contain no
- * valid data for the tab, so the tab is hidden. Otherwise, the tab is
- * shown.
- */
-function loadLogDump(logDump, fileName) {
- // Perform minimal validity check, and abort if it fails.
- if (typeof(logDump) != 'object')
- return 'Load failed. Top level JSON data is not an object.';
-
- // String listing text summary of load errors, if any.
- var errorString = '';
-
- if (!areValidConstants(logDump.constants))
- errorString += 'Invalid constants object.\n';
- if (typeof(logDump.events) != 'object')
- errorString += 'NetLog events missing.\n';
- if (typeof(logDump.constants.logFormatVersion) != 'number')
- errorString += 'Invalid version number.\n';
-
- if (errorString.length > 0)
- return 'Load failed:\n\n' + errorString;
-
- if (typeof(logDump.polledData) != 'object')
- logDump.polledData = {};
- if (typeof(logDump.tabData) != 'object')
- logDump.tabData = {};
-
- if (logDump.constants.logFormatVersion != constants.logFormatVersion) {
- return 'Unable to load different log version.' +
- ' Found ' + logDump.constants.logFormatVersion +
- ', Expected ' + constants.logFormatVersion;
- }
- if (!areValidConstants(logDump.constants))
- return 'Expected constants not found in log file.';
-
- g_browser.receivedConstants(logDump.constants);
-
- // Prevent communication with the browser. Once the constants have been
- // loaded, it's safer to continue trying to load the log, even in the case of
- // bad data.
- onLoadLogFile(fileName);
-
- // Delete all events. This will also update all logObservers.
- g_browser.sourceTracker.deleteAllSourceEntries();
-
- // Inform all the views that a log file is being loaded, and pass in
- // view-specific saved state, if any.
- var tabIds = categoryTabSwitcher.getAllTabIds();
- for (var i = 0; i < tabIds.length; ++i) {
- var view = categoryTabSwitcher.findTabById(tabIds[i]).contentView;
- view.onLoadLogStart(logDump.polledData, logDump.tabData[tabIds[i]]);
- }
-
- // Check for validity of each log entry, and then add the ones that pass.
- // Since the events are kept around, and we can't just hide a single view
- // on a bad event, we have more error checking for them than other data.
- var validPassiveEvents = [];
- var validActiveEvents = [];
- for (var eventIndex = 0; eventIndex < logDump.events.length; ++eventIndex) {
- var event = logDump.events[eventIndex];
- if (typeof(event) == 'object' && typeof(event.source) == 'object' &&
- typeof(event.time) == 'string' &&
- getKeyWithValue(LogEventType, event.type) != '?' &&
- getKeyWithValue(LogSourceType, event.source.type) != '?' &&
- getKeyWithValue(LogEventPhase, event.phase) != '?') {
- if (event.wasPassivelyCaptured) {
- validPassiveEvents.push(event);
- } else {
- validActiveEvents.push(event);
- }
- }
- }
- g_browser.sourceTracker.onReceivedPassiveLogEntries(validPassiveEvents);
- g_browser.sourceTracker.onReceivedLogEntries(validActiveEvents);
-
- var numInvalidEvents = logDump.events.length
- - validPassiveEvents.length
- - validActiveEvents.length;
- if (numInvalidEvents > 0) {
- errorString += 'Unable to load ' + numInvalidEvents +
- ' events, due to invalid data.\n\n';
- }
-
- // Update all views with data from the file. Show only those views which
- // successfully load the data.
- for (var i = 0; i < tabIds.length; ++i) {
- var view = categoryTabSwitcher.findTabById(tabIds[i]).contentView;
- var showView = false;
- // The try block eliminates the need for checking every single value before
- // trying to access it.
- try {
- if (view.onLoadLogFinish(logDump.polledData,
- logDump.tabData[tabIds[i]],
- logDump.userComments)) {
- showView = true;
- }
- } catch (error) {
- }
- categoryTabSwitcher.showTabHandleNode(tabIds[i], showView);
- }
-
- return errorString + 'Log loaded.';
-}
-
-loadLogFile = function(logFileContents, fileName) {
- // Try and parse the log dump as a single JSON string. If this succeeds,
- // it's most likely a full log dump. Otherwise, it may be a dump created by
- // --log-net-log.
- var parsedDump = null;
- try {
- parsedDump = JSON.parse(logFileContents);
- } catch (error) {
- try {
- // We may have a --log-net-log=blah log dump. If so, remove the comma
- // after the final good entry, and add the necessary close brackets.
- var end = Math.max(logFileContents.lastIndexOf(',\n'),
- logFileContents.lastIndexOf(',\r'));
- if (end != -1)
- parsedDump = JSON.parse(logFileContents.substring(0, end) + ']}');
- }
- catch (error) {
- }
- }
-
- if (!parsedDump)
- return 'Unable to parse log dump as JSON file.';
- return loadLogDump(parsedDump, fileName);
-};
-
-// End of anonymous namespace.
-})();
diff --git a/chrome/browser/resources/net_internals/prerender_view.js b/chrome/browser/resources/net_internals/prerender_view.js
index 44eafd8..be9d793 100644
--- a/chrome/browser/resources/net_internals/prerender_view.js
+++ b/chrome/browser/resources/net_internals/prerender_view.js
@@ -32,6 +32,9 @@ var PrerenderView = (function() {
this.prerenderActiveDiv_ = $(ACTIVE_DIV_ID);
}
+ // ID for special HTML element in category_tabs.html
+ PrerenderView.TAB_HANDLE_ID = 'tab-handle-prerender';
+
cr.addSingletonGetter(PrerenderView);
PrerenderView.prototype = {
diff --git a/chrome/browser/resources/net_internals/proxy_view.js b/chrome/browser/resources/net_internals/proxy_view.js
index 2d21b70..de657bb7 100644
--- a/chrome/browser/resources/net_internals/proxy_view.js
+++ b/chrome/browser/resources/net_internals/proxy_view.js
@@ -49,6 +49,9 @@ var ProxyView = (function() {
g_browser.sourceTracker.addObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ ProxyView.TAB_HANDLE_ID = 'tab-handle-proxy';
+
cr.addSingletonGetter(ProxyView);
ProxyView.prototype = {
@@ -93,9 +96,6 @@ var ProxyView = (function() {
var original = proxySettings.original;
var effective = proxySettings.effective;
- if (!original || !effective)
- return false;
-
$(ORIGINAL_SETTINGS_DIV_ID).innerText = proxySettingsToString(original);
$(EFFECTIVE_SETTINGS_DIV_ID).innerText = proxySettingsToString(effective);
return true;
@@ -110,7 +110,7 @@ var ProxyView = (function() {
// Add a table row for each bad proxy entry.
for (var i = 0; i < badProxies.length; ++i) {
var entry = badProxies[i];
- var badUntilDate = convertTimeTicksToDate(entry.bad_until);
+ var badUntilDate = timeutil.convertTimeTicksToDate(entry.bad_until);
var tr = addNode($(BAD_PROXIES_TBODY_ID), 'tr');
diff --git a/chrome/browser/resources/net_internals/service_providers_view.js b/chrome/browser/resources/net_internals/service_providers_view.js
index d7c561d..9336a89 100644
--- a/chrome/browser/resources/net_internals/service_providers_view.js
+++ b/chrome/browser/resources/net_internals/service_providers_view.js
@@ -13,8 +13,6 @@
var ServiceProvidersView = (function() {
'use strict';
- var TAB_ID = 'tab-handle-service-providers';
-
// IDs for special HTML elements in service_providers_view.html
var MAIN_BOX_ID = 'service-providers-view-tab-content';
var SERVICE_PROVIDERS_TBODY_ID = 'service-providers-view-tbody';
@@ -33,15 +31,15 @@ var ServiceProvidersView = (function() {
// Call superclass's constructor.
superClass.call(this, MAIN_BOX_ID);
- var tab = $(TAB_ID);
- setNodeDisplay(tab, true);
-
this.serviceProvidersTbody_ = $(SERVICE_PROVIDERS_TBODY_ID);
this.namespaceProvidersTbody_ = $(NAMESPACE_PROVIDERS_TBODY_ID);
g_browser.addServiceProvidersObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ ServiceProvidersView.TAB_HANDLE_ID = 'tab-handle-service-providers';
+
cr.addSingletonGetter(ServiceProvidersView);
ServiceProvidersView.prototype = {
diff --git a/chrome/browser/resources/net_internals/sockets_view.js b/chrome/browser/resources/net_internals/sockets_view.js
index 386cadd..53c52ad 100644
--- a/chrome/browser/resources/net_internals/sockets_view.js
+++ b/chrome/browser/resources/net_internals/sockets_view.js
@@ -42,6 +42,9 @@ var SocketsView = (function() {
flushSocketsButton.onclick = this.flushSocketPools.bind(this);
}
+ // ID for special HTML element in category_tabs.html
+ SocketsView.TAB_HANDLE_ID = 'tab-handle-sockets';
+
cr.addSingletonGetter(SocketsView);
SocketsView.prototype = {
diff --git a/chrome/browser/resources/net_internals/source_entry.js b/chrome/browser/resources/net_internals/source_entry.js
index 50f5321..9a151e6 100644
--- a/chrome/browser/resources/net_internals/source_entry.js
+++ b/chrome/browser/resources/net_internals/source_entry.js
@@ -178,7 +178,7 @@ SourceEntry.prototype.getEndTime = function() {
return (new Date()).getTime();
} else {
var endTicks = this.entries_[this.entries_.length - 1].time;
- return convertTimeTicksToDate(endTicks).getTime();
+ return timeutil.convertTimeTicksToDate(endTicks).getTime();
}
};
@@ -189,7 +189,7 @@ SourceEntry.prototype.getEndTime = function() {
*/
SourceEntry.prototype.getDuration = function() {
var startTicks = this.entries_[0].time;
- var startTime = convertTimeTicksToDate(startTicks).getTime();
+ var startTime = timeutil.convertTimeTicksToDate(startTicks).getTime();
var endTime = this.getEndTime();
return endTime - startTime;
};
diff --git a/chrome/browser/resources/net_internals/spdy_view.js b/chrome/browser/resources/net_internals/spdy_view.js
index b9267ab..d4f2fa0 100644
--- a/chrome/browser/resources/net_internals/spdy_view.js
+++ b/chrome/browser/resources/net_internals/spdy_view.js
@@ -51,6 +51,9 @@ var SpdyView = (function() {
this.spdySessionDiv_ = $(SESSION_DIV_ID);
}
+ // ID for special HTML element in category_tabs.html
+ SpdyView.TAB_HANDLE_ID = 'tab-handle-spdy';
+
cr.addSingletonGetter(SpdyView);
SpdyView.prototype = {
diff --git a/chrome/browser/resources/net_internals/test_view.js b/chrome/browser/resources/net_internals/test_view.js
index df71808..d3251dd 100644
--- a/chrome/browser/resources/net_internals/test_view.js
+++ b/chrome/browser/resources/net_internals/test_view.js
@@ -41,6 +41,9 @@ var TestView = (function() {
g_browser.addConnectionTestsObserver(this);
}
+ // ID for special HTML element in category_tabs.html
+ TestView.TAB_HANDLE_ID = 'tab-handle-tests';
+
cr.addSingletonGetter(TestView);
TestView.prototype = {
diff --git a/chrome/browser/resources/net_internals/time_util.js b/chrome/browser/resources/net_internals/time_util.js
new file mode 100644
index 0000000..78cd379
--- /dev/null
+++ b/chrome/browser/resources/net_internals/time_util.js
@@ -0,0 +1,37 @@
+// 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.
+
+var timeutil = (function() {
+ /**
+ * Offset needed to convert event times to Date objects.
+ * Updated whenever constants are loaded.
+ */
+ var timeTickOffset = 0;
+
+ /**
+ * Sets the offset used to convert tick counts to dates.
+ */
+ function setTimeTickOffset(offset) {
+ // Note that the subtraction by 0 is to cast to a number (probably a float
+ // since the numbers are big).
+ timeTickOffset = offset - 0;
+ }
+
+ /**
+ * The browser gives us times in terms of "time ticks" in milliseconds.
+ * This function converts the tick count to a Date() object.
+ *
+ * @param {String} timeTicks.
+ * @returns {Date} The time that |timeTicks| represents.
+ */
+ function convertTimeTicksToDate(timeTicks) {
+ var timeStampMs = timeTickOffset + (timeTicks - 0);
+ return new Date(timeStampMs);
+ }
+
+ return {
+ setTimeTickOffset: setTimeTickOffset,
+ convertTimeTicksToDate: convertTimeTicksToDate
+ };
+})();