The gh-pages branch is behind the master branch by 2 commits. These
two commits make the netlog viewer dogfood ready. The two commits can be
found below:
Several UI upgrades:
https://chromium.googlesource.com/external/github.com/catapult-project/catapult/+/0b4a19ad43543ac841ffff3fb937d5fe31321b1a
Removing jstemplate dependencies:
https://chromium.googlesource.com/external/github.com/catapult-project/catapult/+/0b4a19ad43543ac841ffff3fb937d5fe31321b1a
All file changes from these commits have been copied exactly from this
commit.
BUG=chromium:472699
NOTRY=true
NOPRESUBMIT=true
Review-Url: https://codereview.chromium.org/2178423002
diff --git a/netlog_viewer/alt_svc_view.html b/netlog_viewer/alt_svc_view.html
index 361e420..839c4e0 100644
--- a/netlog_viewer/alt_svc_view.html
+++ b/netlog_viewer/alt_svc_view.html
@@ -1,8 +1,8 @@
<div id=alt-svc-view-tab-content class=content-box>
<h4>Alternate Service Mappings</h4>
<div id=alt-svc-view-alternate-protocol-mappings>
- <div jsdisplay="altSvcMappings.length == 0">None</div>
- <div jsdisplay="altSvcMappings.length != 0">
+ <div id=alt-svc-view-mappings-no-content>None</div>
+ <div id=alt-svc-view-mappings-content>
<table class="styled-table">
<thead>
<tr>
@@ -10,13 +10,9 @@
<th>Alternative Service</th>
</tr>
</thead>
- <tbody>
- <tr jsselect="altSvcMappings">
- <td jscontent="server"></td>
- <td jscontent="alternative_service"></td>
- </tr>
+ <tbody id=alt-svc-view-mappings-tbody>
</tbody>
</table>
</div>
</div>
-</div>
\ No newline at end of file
+</div>
diff --git a/netlog_viewer/alt_svc_view.js b/netlog_viewer/alt_svc_view.js
index a452b21..2df33c5 100644
--- a/netlog_viewer/alt_svc_view.js
+++ b/netlog_viewer/alt_svc_view.js
@@ -31,6 +31,11 @@
AltSvcView.MAIN_BOX_ID = 'alt-svc-view-tab-content';
AltSvcView.ALTERNATE_PROTOCOL_MAPPINGS_ID =
'alt-svc-view-alternate-protocol-mappings';
+ AltSvcView.MAPPINGS_CONTENT_ID =
+ 'alt-svc-view-mappings-content';
+ AltSvcView.MAPPINGS_NO_CONTENT_ID =
+ 'alt-svc-view-mappings-no-content';
+ AltSvcView.MAPPINGS_TBODY_ID = 'alt-svc-view-mappings-tbody';
cr.addSingletonGetter(AltSvcView);
@@ -51,9 +56,24 @@
onAltSvcMappingsChanged: function(altSvcMappings) {
if (!altSvcMappings)
return false;
- // TODO(rayraymond): Update DOM without use of jstemplate.
- // var input = new JsEvalContext({altSvcMappings: altSvcMappings});
- // jstProcess(input, $(AltSvcView.ALTERNATE_PROTOCOL_MAPPINGS_ID));
+
+ var hasMappings = altSvcMappings && altSvcMappings.length > 0;
+
+ setNodeDisplay($(AltSvcView.MAPPINGS_CONTENT_ID), hasMappings);
+ setNodeDisplay($(AltSvcView.MAPPINGS_NO_CONTENT_ID), !hasMappings);
+
+ var tbody = $(AltSvcView.MAPPINGS_TBODY_ID);
+ tbody.innerHTML = '';
+
+ // Fill in the alternate service mappings table.
+ for (var i = 0; i < altSvcMappings.length; ++i) {
+ var a = altSvcMappings[i];
+ var tr = addNode(tbody, 'tr');
+
+ addNodeWithText(tr, 'td', a.server);
+ addNodeWithText(tr, 'td', a.alternative_service);
+ }
+
return true;
}
};
diff --git a/netlog_viewer/bandwidth_view.html b/netlog_viewer/bandwidth_view.html
new file mode 100644
index 0000000..5bf2234
--- /dev/null
+++ b/netlog_viewer/bandwidth_view.html
@@ -0,0 +1,53 @@
+<!-- Bandwidth info -->
+<style>
+.data-reduction-proxy-view-events-details {
+ background-color: rgb(220,220,220);
+}
+table.borderless-table,
+.borderless-table th,
+.borderless-table td {
+ border: 0px;
+ padding-left: 4px;
+ padding-right: 4px;
+}
+</style>
+<div id=bandwidth-view-tab-content class=content-box>
+ <h2>Data Reduction Proxy Status</h2>
+ <ul id=data-reduction-proxy-view-status>
+ <li>Status: <span id="data-reduction-proxy-enabled"></span></li>
+ <li>Proxy configuration: <span id="data-reduction-proxy-config"></span></li>
+ <li>Probe status: <span id="data-reduction-proxy-probe-status"></span></li>
+ <li id="data-reduction-proxy-bypass-state-container">Bypass details:
+ <span id="data-reduction-proxy-bypass-state-details"></span></li>
+ </ul>
+ <a href="#proxy">View current proxy configuration</a>
+
+ <h4>Recent events</h4>
+ <div id=data-reduction-proxy-view-events-content>
+ <table class="styled-table">
+ <thead>
+ <tr>
+ <th>Time</th>
+ <th>Action</th>
+ </tr>
+ <tr>
+ <th colspan=2>Details</th>
+ </tr>
+ </thead>
+ <tbody id=data-reduction-proxy-view-events-tbody>
+ </tbody>
+ </table>
+ </div>
+ <h4>Bandwidth Savings</h4>
+ <table class="styled-table" id="bandwidth-stats-table">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Session</th>
+ <th>Total</th>
+ </tr>
+ </thead>
+ <tbody id=bandwidth-savings-tbody>
+ </tbody>
+ </table>
+</div>
\ No newline at end of file
diff --git a/netlog_viewer/bandwidth_view.js b/netlog_viewer/bandwidth_view.js
new file mode 100644
index 0000000..2fd604c
--- /dev/null
+++ b/netlog_viewer/bandwidth_view.js
@@ -0,0 +1,364 @@
+// Copyright (c) 2012 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 summary statistics on bandwidth usage. */
+var BandwidthView = (function() {
+ 'use strict';
+
+ // We inherit from DivView.
+ var superClass = DivView;
+
+ /**
+ * @constructor
+ */
+ function BandwidthView() {
+ assertFirstConstructorCall(BandwidthView);
+
+ // Call superclass's constructor.
+ superClass.call(this, BandwidthView.MAIN_BOX_ID);
+
+ g_browser.addSessionNetworkStatsObserver(this, true);
+ g_browser.addHistoricNetworkStatsObserver(this, true);
+
+ // Register to receive data reduction proxy info.
+ g_browser.addDataReductionProxyInfoObserver(this, true);
+
+ // Register to receive bad proxy info.
+ g_browser.addBadProxiesObserver(this, true);
+
+ this.sessionNetworkStats_ = null;
+ this.historicNetworkStats_ = null;
+ }
+
+ BandwidthView.TAB_ID = 'tab-handle-bandwidth';
+ BandwidthView.TAB_NAME = 'Bandwidth';
+ BandwidthView.TAB_HASH = '#bandwidth';
+
+ // IDs for special HTML elements in bandwidth_view.html
+ BandwidthView.MAIN_BOX_ID = 'bandwidth-view-tab-content';
+ BandwidthView.ENABLED_ID = 'data-reduction-proxy-enabled';
+ BandwidthView.PROXY_CONFIG_ID = 'data-reduction-proxy-config';
+ BandwidthView.PROBE_STATUS_ID = 'data-reduction-proxy-probe-status';
+ BandwidthView.BYPASS_STATE_CONTAINER_ID =
+ 'data-reduction-proxy-bypass-state-container';
+ BandwidthView.BYPASS_STATE_ID = 'data-reduction-proxy-bypass-state-details';
+ BandwidthView.EVENTS_TBODY_ID = 'data-reduction-proxy-view-events-tbody';
+ BandwidthView.EVENTS_UL = 'data-reduction-proxy-view-events-list';
+ BandwidthView.STATS_BOX_ID = 'bandwidth-stats-table';
+ BandwidthView.SAVINGS_TBODY_ID = 'bandwidth-savings-tbody';
+
+ cr.addSingletonGetter(BandwidthView);
+
+ BandwidthView.prototype = {
+ // Inherit the superclass's methods.
+ __proto__: superClass.prototype,
+
+ data_reduction_proxy_config_: null,
+ last_bypass_: null,
+ bad_proxy_config_: null,
+
+ onLoadLogFinish: function(data) {
+ return this.onBadProxiesChanged(data.badProxies) &&
+ this.onDataReductionProxyInfoChanged(data.dataReductionProxyInfo) &&
+ (this.onSessionNetworkStatsChanged(data.sessionNetworkStats) ||
+ this.onHistoricNetworkStatsChanged(data.historicNetworkStats));
+ },
+
+ /**
+ * Retains information on bandwidth usage this session.
+ */
+ onSessionNetworkStatsChanged: function(sessionNetworkStats) {
+ this.sessionNetworkStats_ = sessionNetworkStats;
+ return this.updateBandwidthUsageTable_();
+ },
+
+ /**
+ * Displays information on bandwidth usage this session and over the
+ * browser's lifetime.
+ */
+ onHistoricNetworkStatsChanged: function(historicNetworkStats) {
+ this.historicNetworkStats_ = historicNetworkStats;
+ return this.updateBandwidthUsageTable_();
+ },
+
+ /**
+ * Updates the UI based on receiving changes in information about the
+ * data reduction proxy summary.
+ */
+ onDataReductionProxyInfoChanged: function(info) {
+ $(BandwidthView.EVENTS_TBODY_ID).innerHTML = '';
+
+ if (!info)
+ return false;
+
+ if (info.enabled) {
+ $(BandwidthView.ENABLED_ID).innerText = 'Enabled';
+ $(BandwidthView.PROBE_STATUS_ID).innerText =
+ info.probe != null ? info.probe : 'N/A';
+ this.last_bypass_ = info.last_bypass;
+ this.data_reduction_proxy_config_ = info.proxy_config.params;
+ } else {
+ $(BandwidthView.ENABLED_ID).innerText = 'Disabled';
+ $(BandwidthView.PROBE_STATUS_ID).innerText = 'N/A';
+ this.data_reduction_proxy_config_ = null;
+ }
+
+ this.updateDataReductionProxyConfig_();
+
+ for (var eventIndex = info.events.length - 1; eventIndex >= 0;
+ --eventIndex) {
+ var event = info.events[eventIndex];
+ var headerRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
+ var detailsRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
+
+ var timeCell = addNode(headerRow, 'td');
+ var actionCell = addNode(headerRow, 'td');
+ var detailsCell = addNode(detailsRow, 'td');
+ detailsCell.colSpan = 2;
+ detailsCell.className = 'data-reduction-proxy-view-events-details';
+ var eventTime = timeutil.convertTimeTicksToDate(event.time);
+ timeutil.addNodeWithDate(timeCell, eventTime);
+ this.buildEventRow_(event, actionCell, detailsCell);
+ }
+
+ return true;
+ },
+
+ /**
+ * Updates the UI based on receiving changes in information about bad
+ * proxy servers.
+ */
+ onBadProxiesChanged: function(badProxies) {
+ if (!badProxies)
+ return false;
+
+ var newBadProxies = [];
+ if (badProxies.length == 0) {
+ this.last_bypass_ = null;
+ } else {
+ for (var i = 0; i < badProxies.length; ++i) {
+ var entry = badProxies[i];
+ newBadProxies[entry.proxy_uri] = entry.bad_until;
+ }
+ }
+ this.bad_proxy_config_ = newBadProxies;
+ this.updateDataReductionProxyConfig_();
+
+ return true;
+ },
+
+ /**
+ * Update the bandwidth usage table. Returns false on failure.
+ */
+ updateBandwidthUsageTable_: function() {
+ var sessionNetworkStats = this.sessionNetworkStats_;
+ var historicNetworkStats = this.historicNetworkStats_;
+ if (!sessionNetworkStats || !historicNetworkStats)
+ return false;
+
+ var sessionOriginal = sessionNetworkStats.session_original_content_length;
+ var sessionReceived = sessionNetworkStats.session_received_content_length;
+ var historicOriginal =
+ historicNetworkStats.historic_original_content_length;
+ var historicReceived =
+ historicNetworkStats.historic_received_content_length;
+
+ var rows = [];
+ rows.push({
+ title: 'Original (KB)',
+ sessionValue: bytesToRoundedKilobytes_(sessionOriginal),
+ historicValue: bytesToRoundedKilobytes_(historicOriginal)
+ });
+ rows.push({
+ title: 'Received (KB)',
+ sessionValue: bytesToRoundedKilobytes_(sessionReceived),
+ historicValue: bytesToRoundedKilobytes_(historicReceived)
+ });
+ rows.push({
+ title: 'Savings (KB)',
+ sessionValue:
+ bytesToRoundedKilobytes_(sessionOriginal - sessionReceived),
+ historicValue:
+ bytesToRoundedKilobytes_(historicOriginal - historicReceived)
+ });
+ rows.push({
+ title: 'Savings (%)',
+ sessionValue: getPercentSavings_(sessionOriginal, sessionReceived),
+ historicValue: getPercentSavings_(historicOriginal,
+ historicReceived)
+ });
+
+ var tbody = $(BandwidthView.SAVINGS_TBODY_ID);
+ tbody.innerHTML = '';
+
+ // Fill in the bandwidth savings table.
+ for (var i = 0; i < rows.length; ++i) {
+ var r = rows[i];
+ var tr = addNode(tbody, 'tr');
+
+ addNodeWithText(tr, 'td', r.title);
+ addNodeWithText(tr, 'td', r.sessionValue);
+ addNodeWithText(tr, 'td', r.historicValue);
+ }
+
+ return true;
+ },
+
+ /**
+ * Renders a Data Reduction Proxy event into the event tbody
+ */
+ buildEventRow_: function(event, actionCell, detailsCell) {
+ if (event.type == EventType.DATA_REDUCTION_PROXY_ENABLED &&
+ event.params.enabled == 0) {
+ addTextNode(actionCell, 'DISABLED');
+ } else {
+ var actionText =
+ EventTypeNames[event.type].replace('DATA_REDUCTION_PROXY_', '');
+ if (event.phase == EventPhase.PHASE_BEGIN ||
+ event.phase == EventPhase.PHASE_END) {
+ actionText = actionText + ' (' +
+ getKeyWithValue(EventPhase, event.phase)
+ .replace('PHASE_', '') + ')';
+ }
+
+ addTextNode(actionCell, actionText);
+ this.createEventTable_(event.params, detailsCell);
+ }
+ },
+
+ /**
+ * Updates the data reduction proxy summary block.
+ */
+ updateDataReductionProxyConfig_: function() {
+ $(BandwidthView.PROXY_CONFIG_ID).innerHTML = '';
+ $(BandwidthView.BYPASS_STATE_ID).innerHTML = '';
+ setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), false);
+
+ if (this.data_reduction_proxy_config_) {
+ var hasBypassedProxy = false;
+ var now = timeutil.getCurrentTimeTicks();
+
+ if (this.last_bypass_ &&
+ this.hasTimePassedLogTime_(+this.last_bypass_.params.expiration)) {
+ // Best effort on iterating the config to search for a bad proxy.
+ // A server could exist in a string member of
+ // data_reduction_proxy_config_ or within an array of servers in an
+ // array member of data_reduction_proxy_config_. As such, search
+ // through all string members and string arrays.
+ for (var key in this.data_reduction_proxy_config_) {
+ var value = this.data_reduction_proxy_config_[key];
+ if (typeof value == 'string') {
+ if (this.isMarkedAsBad_(value)) {
+ hasBypassedProxy = true;
+ break;
+ }
+ } else if (value instanceof Array) {
+ for (var index = 1; index < value.length; index++) {
+ if (this.isMarkedAsBad_(value[index])) {
+ hasBypassedProxy = true;
+ }
+ }
+
+ if (hasBypassedProxy) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (hasBypassedProxy) {
+ this.createEventTable_(this.last_bypass_.params,
+ $(BandwidthView.BYPASS_STATE_ID));
+ }
+
+ this.createEventTable_(this.data_reduction_proxy_config_,
+ $(BandwidthView.PROXY_CONFIG_ID));
+ setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID),
+ hasBypassedProxy);
+ }
+ },
+
+ /**
+ * Checks to see if a proxy server is in marked as bad.
+ */
+ isMarkedAsBad_: function(proxy) {
+ for (var entry in this.bad_proxy_config_) {
+ if (entry == proxy &&
+ this.hasTimePassedLogTime_(this.bad_proxy_config_[entry])) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ /**
+ * Checks to see if a given time in ticks has passed the time of the
+ * the log. For real time viewing, this is "now", but for loaded logs, it
+ * is the time at which the logs were taken.
+ */
+ hasTimePassedLogTime_: function(timeTicks) {
+ var logTime;
+ if (MainView.isViewingLoadedLog() && ClientInfo.numericDate) {
+ logTime = ClientInfo.numericDate;
+ } else {
+ logTime = timeutil.getCurrentTime();
+ }
+
+ return timeutil.convertTimeTicksToTime(timeTicks) > logTime;
+ },
+
+ /**
+ * Creates a table of the object obj. Certain keys are special cased for
+ * ease of readability.
+ */
+ createEventTable_: function(obj, parentNode) {
+ if (Object.keys(obj).length > 0) {
+ var tableNode = addNode(parentNode, 'table');
+ tableNode.className = 'borderless-table';
+ for (var key in obj) {
+ var value = obj[key];
+ if (value != null && value.toString() != '') {
+ if (key == 'net_error') {
+ if (value == 0) {
+ value = 'OK';
+ } else {
+ value = netErrorToString(value);
+ }
+ } else if (key == 'bypass_type') {
+ value = getKeyWithValue(DataReductionProxyBypassEventType, value);
+ } else if (key == 'bypass_action_type') {
+ value = getKeyWithValue(DataReductionProxyBypassActionType,
+ value);
+ } else if (key == 'expiration') {
+ value = timeutil.convertTimeTicksToDate(value);
+ }
+ var tableRow = addNode(tableNode, 'tr');
+ addNodeWithText(tableRow, 'td', key);
+ addNodeWithText(tableRow, 'td', value);
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Converts bytes to kilobytes rounded to one decimal place.
+ */
+ function bytesToRoundedKilobytes_(val) {
+ return (val / 1024).toFixed(1);
+ }
+
+ /**
+ * Returns bandwidth savings as a percent rounded to one decimal place.
+ */
+ function getPercentSavings_(original, received) {
+ if (original > 0) {
+ return ((original - received) * 100 / original).toFixed(1);
+ }
+ return '0.0';
+ }
+
+ return BandwidthView;
+})();
\ No newline at end of file
diff --git a/netlog_viewer/dns_view.html b/netlog_viewer/dns_view.html
index ccdfd98..adc607e 100644
--- a/netlog_viewer/dns_view.html
+++ b/netlog_viewer/dns_view.html
@@ -20,7 +20,6 @@
<h4>
Host resolver cache
- <input type=button value="Clear host cache" id=dns-view-clear-cache class="hide-when-not-capturing">
</h4>
<ul>
<li>Capacity: <span id=dns-view-cache-capacity></span></li>
diff --git a/netlog_viewer/dns_view.js b/netlog_viewer/dns_view.js
index 2d8cba4..fa94139 100644
--- a/netlog_viewer/dns_view.js
+++ b/netlog_viewer/dns_view.js
@@ -31,9 +31,6 @@
// Call superclass's constructor.
superClass.call(this, DnsView.MAIN_BOX_ID);
- $(DnsView.CLEAR_CACHE_BUTTON_ID).onclick =
- g_browser.sendClearHostResolverCache.bind(g_browser);
-
// Register to receive changes to the host resolver info.
g_browser.addHostResolverInfoObserver(this, false);
}
@@ -50,7 +47,6 @@
'dns-view-internal-dns-invalid-config';
DnsView.INTERNAL_DNS_CONFIG_TBODY_ID = 'dns-view-internal-dns-config-tbody';
- DnsView.CLEAR_CACHE_BUTTON_ID = 'dns-view-clear-cache';
DnsView.CAPACITY_SPAN_ID = 'dns-view-cache-capacity';
DnsView.ACTIVE_SPAN_ID = 'dns-view-cache-active';
diff --git a/netlog_viewer/http_cache_view.html b/netlog_viewer/http_cache_view.html
index ac773a6..ba78f9d 100644
--- a/netlog_viewer/http_cache_view.html
+++ b/netlog_viewer/http_cache_view.html
@@ -1,8 +1,4 @@
<div id=http-cache-view-tab-content class=content-box>
- <div class="hide-when-not-capturing">
- <a href="chrome://view-http-cache" target=_blank>Explore cache entries</a>
- </div>
-
<h4>Statistics</h4>
<div id=http-cache-view-cache-stats>Nothing loaded yet.</div>
</div>
diff --git a/netlog_viewer/index.html b/netlog_viewer/index.html
index 24931d9..0717777 100644
--- a/netlog_viewer/index.html
+++ b/netlog_viewer/index.html
@@ -53,7 +53,10 @@
<script src="sockets_view.js"></script>
<script src="alt_svc_view.js"></script>
<script src="spdy_view.js"></script>
+ <script src="modules_view.js"></script>
+ <script src="prerender_view.js"></script>
<script src="chromeos_view.js"></script>
+ <script src="bandwidth_view.js"></script>
<script src="sdch_view.js"></script>
</head>
<body id=import-view-drop-target>
@@ -70,6 +73,9 @@
<link rel="import" href="spdy_view.html">
<link rel="import" href="quic_view.html">
<link rel="import" href="http_cache_view.html">
+ <link rel="import" href="bandwidth_view.html">
+ <link rel="import" href="prerender_view.html">
+ <link rel="import" href="modules_view.html">
<link rel="import" href="import_view.html">
<link rel="import" href="events_view.html">
<link rel="import" href="timeline_view.html">
diff --git a/netlog_viewer/main.css b/netlog_viewer/main.css
index 4b5dab1..1e28587 100644
--- a/netlog_viewer/main.css
+++ b/netlog_viewer/main.css
@@ -9,10 +9,20 @@
box-sizing: border-box;
}
+html {
+ direction: ltr;
+}
+
body {
+ font-family: DejaVu Sans, Arial, sans-serif;
+ font-size: 95%;
overflow: hidden; /* Prevents scroll bar flickering on resize. */
}
+button {
+ font-family: DejaVu Sans, Arial, sans-serif;
+}
+
ul {
padding-left: 2em;
}
diff --git a/netlog_viewer/main.js b/netlog_viewer/main.js
index 84ed15c..2aeb39e 100644
--- a/netlog_viewer/main.js
+++ b/netlog_viewer/main.js
@@ -68,9 +68,8 @@
this.initTabs_();
// 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.
+ // a high level status (i.e. if we are displaying a log file or not).
+ // Below it we will position the main tabs and their content area.
this.topBarView_ = TopBarView.getInstance(this);
var verticalSplitView = new VerticalSplitView(
this.topBarView_, this.tabSwitcher_);
@@ -128,10 +127,9 @@
onLoadLog: function(opt_fileName) {
isViewingLoadedLog = true;
- this.stopCapturing();
if (opt_fileName != undefined) {
- // If there's a file name, a log file was loaded, so swap out the status
- // bar to indicate we're no longer capturing events.
+ // If there's a file name, a log file was loaded, so display the
+ // file's name in the status bar.
this.topBarView_.switchToSubView('loaded').setFileName(opt_fileName);
SourceTracker.getInstance().setPrivacyStripping(false);
}
@@ -143,12 +141,6 @@
log_util.createLogDumpAsync('', log_util.loadLogFile, false);
},
- stopCapturing: function() {
- g_browser.disable();
- document.styleSheets[0].insertRule(
- '.hide-when-not-capturing { display: none; }', 0);
- },
-
initTabs_: function() {
this.tabIdToHash_ = {};
this.hashToTabId_ = {};
@@ -189,12 +181,20 @@
addTab(QuicView);
addTab(SdchView);
addTab(HttpCacheView);
- // TODO(rayraymond): Re-enable, Modules, Bandwidth, and Prerender tabs.
- // addTab(ModulesView);
- // addTab(BandwidthView);
- // addTab(PrerenderView);
+ addTab(ModulesView);
+ addTab(BandwidthView);
+ addTab(PrerenderView);
addTab(CrosView);
+ // Tab links start off hidden (besides import) since a log file has not
+ // been loaded yet. This must be done after all the tabs are added so
+ // that the width of the tab-list div is correctly styled.
+ for (var tabId in this.tabSwitcher_.getAllTabViews()) {
+ if (tabId != ImportView.TAB_ID) {
+ this.tabSwitcher_.showTabLink(tabId, false);
+ }
+ }
+
this.tabSwitcher_.showTabLink(CrosView.TAB_ID, cr.isChromeOS);
},
diff --git a/netlog_viewer/modules_view.html b/netlog_viewer/modules_view.html
new file mode 100644
index 0000000..3be1bfa
--- /dev/null
+++ b/netlog_viewer/modules_view.html
@@ -0,0 +1,67 @@
+<style>
+
+.modules-view-extension-list tr.enabled {
+ background-color: #F0FFF0;
+}
+
+.modules-view-extension-list tr:not(.enabled) {
+ background-color: #FFF0F0;
+}
+
+</style>
+
+<div id=modules-view-tab-content class=content-box>
+ <h4 style='margin-top:0'>Chrome Extensions</h4>
+ <div id="modules-view-extension-info">
+ <div id=modules-view-extension-info-unavailable>No information</div>
+ <div id=modules-view-extension-info-no-content>None</div>
+ <div id=modules-view-extension-info-content>
+ <table class=styled-table>
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>App</th>
+ <th>Enabled</th>
+ <th>Name</th>
+ <th>Version</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody id=modules-view-extension-info-tbody class=modules-view-extension-list>
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ <!-- Only shown for Windows log dumps -->
+ <div id=modules-view-windows-service-providers>
+ <h4>Layered Service Providers</h4>
+ <table class="styled-table">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Version</th>
+ <th>Type</th>
+ <th>Socket Type</th>
+ <th>Protocol</th>
+ <th>Path</th>
+ </tr>
+ </thead>
+ <tbody id=modules-view-service-providers-tbody>
+ </tbody>
+ </table>
+ <h4>Namespace Providers</h4>
+ <table class="styled-table">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Version</th>
+ <th>Namespace</th>
+ <th>Active</th>
+ </tr>
+ </thead>
+ <tbody id=modules-view-namespace-providers-tbody>
+ </tbody>
+ </table>
+ </div>
+</div>
diff --git a/netlog_viewer/modules_view.js b/netlog_viewer/modules_view.js
new file mode 100644
index 0000000..6c4f535
--- /dev/null
+++ b/netlog_viewer/modules_view.js
@@ -0,0 +1,203 @@
+// Copyright (c) 2012 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 information on installed Chrome extensions / apps as well
+ * as Winsock layered service providers and namespace providers.
+ *
+ * For each layered service provider, shows the name, dll, and type
+ * information. For each namespace provider, shows the name and
+ * whether or not it's active.
+ */
+var ModulesView = (function() {
+ 'use strict';
+
+ // We inherit from DivView.
+ var superClass = DivView;
+
+ /**
+ * @constructor
+ */
+ function ModulesView() {
+ assertFirstConstructorCall(ModulesView);
+
+ // Call superclass's constructor.
+ superClass.call(this, ModulesView.MAIN_BOX_ID);
+
+ this.serviceProvidersTbody_ =
+ $(ModulesView.SERVICE_PROVIDERS_TBODY_ID);
+ this.namespaceProvidersTbody_ =
+ $(ModulesView.NAMESPACE_PROVIDERS_TBODY_ID);
+
+ g_browser.addServiceProvidersObserver(this, false);
+ g_browser.addExtensionInfoObserver(this, true);
+ }
+
+ ModulesView.TAB_ID = 'tab-handle-modules';
+ ModulesView.TAB_NAME = 'Modules';
+ ModulesView.TAB_HASH = '#modules';
+
+ // IDs for special HTML elements in modules_view.html.
+ ModulesView.MAIN_BOX_ID = 'modules-view-tab-content';
+ ModulesView.EXTENSION_INFO_ID = 'modules-view-extension-info';
+ ModulesView.EXTENSION_INFO_UNAVAILABLE_ID =
+ 'modules-view-extension-info-unavailable';
+ ModulesView.EXTENSION_INFO_NO_CONTENT_ID =
+ 'modules-view-extension-info-no-content';
+ ModulesView.EXTENSION_INFO_CONTENT_ID =
+ 'modules-view-extension-info-content';
+ ModulesView.EXTENSION_INFO_TBODY_ID =
+ 'modules-view-extension-info-tbody';
+ ModulesView.WINDOWS_SERVICE_PROVIDERS_ID =
+ 'modules-view-windows-service-providers';
+ ModulesView.SERVICE_PROVIDERS_TBODY_ID =
+ 'modules-view-service-providers-tbody';
+ ModulesView.NAMESPACE_PROVIDERS_TBODY_ID =
+ 'modules-view-namespace-providers-tbody';
+
+ cr.addSingletonGetter(ModulesView);
+
+ ModulesView.prototype = {
+ // Inherit the superclass's methods.
+ __proto__: superClass.prototype,
+
+ onLoadLogFinish: function(data) {
+ // Show the tab if there are either service providers or extension info.
+ var hasExtensionInfo = this.onExtensionInfoChanged(data.extensionInfo);
+ var hasSpiInfo = this.onServiceProvidersChanged(data.serviceProviders);
+ return hasExtensionInfo || hasSpiInfo;
+ },
+
+ onExtensionInfoChanged: function(extensionInfo) {
+ setNodeDisplay($(ModulesView.EXTENSION_INFO_CONTENT_ID),
+ extensionInfo && extensionInfo.length > 0);
+ setNodeDisplay($(ModulesView.EXTENSION_INFO_UNAVAILABLE_ID),
+ !extensionInfo);
+ setNodeDisplay($(ModulesView.EXTENSION_INFO_NO_CONTENT_ID),
+ extensionInfo && extensionInfo.length == 0);
+
+ var tbodyExtension = $(ModulesView.EXTENSION_INFO_TBODY_ID);
+ tbodyExtension.innerHTML = '';
+
+ if (extensionInfo && extensionInfo.length > 0) {
+ // Fill in the extensions table.
+ for (var i = 0; i < extensionInfo.length; ++i) {
+ var e = extensionInfo[i];
+ var tr = addNode(tbodyExtension, 'tr');
+ tr.className = (e.enabled ? 'enabled' : '');
+
+ addNodeWithText(tr, 'td', e.id);
+ addNodeWithText(tr, 'td', e.packagedApp);
+ addNodeWithText(tr, 'td', e.enabled);
+ addNodeWithText(tr, 'td', e.name);
+ addNodeWithText(tr, 'td', e.version);
+ addNodeWithText(tr, 'td', e.description);
+ }
+ }
+
+ return !!extensionInfo;
+ },
+
+ onServiceProvidersChanged: function(serviceProviders) {
+ setNodeDisplay($(ModulesView.WINDOWS_SERVICE_PROVIDERS_ID),
+ serviceProviders);
+ if (serviceProviders) {
+ var tbodyService = $(ModulesView.SERVICE_PROVIDERS_TBODY_ID);
+ tbodyService.innerHTML = '';
+
+ // Fill in the service providers table.
+ for (var i = 0; i < serviceProviders.service_providers.length; ++i) {
+ var s = serviceProviders.service_providers[i];
+ var tr = addNode(tbodyService, 'tr');
+
+ addNodeWithText(tr, 'td', s.name);
+ addNodeWithText(tr, 'td', s.version);
+ addNodeWithText(tr, 'td',
+ ModulesView.getLayeredServiceProviderType(s));
+ addNodeWithText(tr, 'td',
+ ModulesView.getLayeredServiceProviderSocketType(s));
+ addNodeWithText(tr, 'td',
+ ModulesView.getLayeredServiceProviderProtocolType(s));
+ }
+
+ var tbodyNamespace = $(ModulesView.NAMESPACE_PROVIDERS_TBODY_ID);
+ tbodyNamespace.innerHTML = '';
+
+ // Fill in the namespace providers table.
+ for (var i = 0; i < serviceProviders.namespace_providers.length; ++i) {
+ var n = serviceProviders.namespace_providers[i];
+ var tr = addNode(tbodyNamespace, 'tr');
+
+ addNodeWithText(tr, 'td', n.name);
+ addNodeWithText(tr, 'td', n.version);
+ addNodeWithText(tr, 'td', ModulesView.getNamespaceProviderType(n));
+ addNodeWithText(tr, 'td', n.active);
+ }
+ }
+
+ return !!serviceProviders;
+ },
+ };
+
+ /**
+ * Returns type of a layered service provider.
+ */
+ ModulesView.getLayeredServiceProviderType = function(serviceProvider) {
+ if (serviceProvider.chain_length == 0)
+ return 'Layer';
+ if (serviceProvider.chain_length == 1)
+ return 'Base';
+ return 'Chain';
+ };
+
+ var SOCKET_TYPE = {
+ '1': 'SOCK_STREAM',
+ '2': 'SOCK_DGRAM',
+ '3': 'SOCK_RAW',
+ '4': 'SOCK_RDM',
+ '5': 'SOCK_SEQPACKET'
+ };
+
+ /**
+ * Returns socket type of a layered service provider as a string.
+ */
+ ModulesView.getLayeredServiceProviderSocketType = function(serviceProvider) {
+ return tryGetValueWithKey(SOCKET_TYPE, serviceProvider.socket_type);
+ };
+
+ var PROTOCOL_TYPE = {
+ '1': 'IPPROTO_ICMP',
+ '6': 'IPPROTO_TCP',
+ '17': 'IPPROTO_UDP',
+ '58': 'IPPROTO_ICMPV6'
+ };
+
+ /**
+ * Returns protocol type of a layered service provider as a string.
+ */
+ ModulesView.getLayeredServiceProviderProtocolType =
+ function(serviceProvider) {
+ return tryGetValueWithKey(PROTOCOL_TYPE, serviceProvider.socket_protocol);
+ };
+
+ var NAMESPACE_PROVIDER_PTYPE = {
+ '12': 'NS_DNS',
+ '15': 'NS_NLA',
+ '16': 'NS_BTH',
+ '32': 'NS_NTDS',
+ '37': 'NS_EMAIL',
+ '38': 'NS_PNRPNAME',
+ '39': 'NS_PNRPCLOUD'
+ };
+
+ /**
+ * Returns the type of a namespace provider as a string.
+ */
+ ModulesView.getNamespaceProviderType = function(namespaceProvider) {
+ return tryGetValueWithKey(NAMESPACE_PROVIDER_PTYPE,
+ namespaceProvider.type);
+ };
+
+ return ModulesView;
+})();
diff --git a/netlog_viewer/prerender_view.html b/netlog_viewer/prerender_view.html
new file mode 100644
index 0000000..ce3b10f
--- /dev/null
+++ b/netlog_viewer/prerender_view.html
@@ -0,0 +1,46 @@
+<style>
+
+#prerender-view-history-table tr.used {
+ background-color: #F0FFF0;
+}
+
+#prerender-view-history-table tr:not(.used) {
+ background-color: #FFF0F0;
+}
+
+</style>
+
+<div id=prerender-view-tab-content class=content-box>
+ <ul style='margin-top:0'>
+ <li>Prerender Enabled:
+ <span id=prerender-view-enabled></span>
+ <span id=prerender-view-enabled-note></span></li>
+ <li>Prerender Omnibox Enabled:
+ <span id=prerender-view-omnibox-enabled></span></li>
+ </ul>
+ <h4>Active Prerender Pages</h4>
+ <table class="styled-table">
+ <thead>
+ <tr>
+ <th>URL</th>
+ <th>Duration</th>
+ <th>Loaded</th>
+ </tr>
+ </thead>
+ <tbody id=prerender-view-active-table>
+ </tbody>
+ </table>
+ <h4>Prerender History</h4>
+ <table class="styled-table">
+ <thead>
+ <tr>
+ <th>Origin</th>
+ <th>URL</th>
+ <th>Final Status</th>
+ <th>Time</th>
+ </tr>
+ </thead>
+ <tbody id=prerender-view-history-table>
+ </tbody>
+ </table>
+</div>
diff --git a/netlog_viewer/prerender_view.js b/netlog_viewer/prerender_view.js
new file mode 100644
index 0000000..c7b8b6d
--- /dev/null
+++ b/netlog_viewer/prerender_view.js
@@ -0,0 +1,96 @@
+// Copyright (c) 2012 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 information related to Prerendering.
+ */
+var PrerenderView = (function() {
+ 'use strict';
+
+ // We inherit from DivView.
+ var superClass = DivView;
+
+ /**
+ * @constructor
+ */
+ function PrerenderView() {
+ assertFirstConstructorCall(PrerenderView);
+
+ // Call superclass's constructor.
+ superClass.call(this, PrerenderView.MAIN_BOX_ID);
+
+ g_browser.addPrerenderInfoObserver(this, true);
+ }
+
+ PrerenderView.TAB_ID = 'tab-handle-prerender';
+ PrerenderView.TAB_NAME = 'Prerender';
+ PrerenderView.TAB_HASH = '#prerender';
+
+ // IDs for special HTML elements in prerender_view.html
+ PrerenderView.MAIN_BOX_ID = 'prerender-view-tab-content';
+ PrerenderView.PRERENDER_VIEW_ENABLED_ID =
+ 'prerender-view-enabled';
+ PrerenderView.PRERENDER_VIEW_ENABLED_NOTE_ID =
+ 'prerender-view-enabled-note';
+ PrerenderView.PRERENDER_VIEW_OMNIBOX_ENABLED_ID =
+ 'prerender-view-omnibox-enabled';
+ PrerenderView.HISTORY_TABLE_ID = 'prerender-view-history-table';
+ PrerenderView.ACTIVE_TABLE_ID = 'prerender-view-active-table';
+
+ cr.addSingletonGetter(PrerenderView);
+
+ PrerenderView.prototype = {
+ // Inherit the superclass's methods.
+ __proto__: superClass.prototype,
+
+ onLoadLogFinish: function(data) {
+ return this.onPrerenderInfoChanged(data.prerenderInfo);
+ },
+
+ onPrerenderInfoChanged: function(prerenderInfo) {
+ if (!prerenderInfo)
+ return false;
+
+ $(PrerenderView.PRERENDER_VIEW_ENABLED_ID).textContent =
+ prerenderInfo.enabled;
+ $(PrerenderView.PRERENDER_VIEW_ENABLED_NOTE_ID).textContent =
+ prerenderInfo.enabled_note;
+ $(PrerenderView.PRERENDER_VIEW_OMNIBOX_ENABLED_ID).textContent =
+ prerenderInfo.omnibox_enabled;
+
+ var tbodyActive = $(PrerenderView.ACTIVE_TABLE_ID);
+ tbodyActive.innerHTML = '';
+
+ // Fill in Active Prerender Pages table
+ for (var i = 0; i < prerenderInfo.active.length; ++i) {
+ var a = prerenderInfo.active[i];
+ var tr = addNode(tbodyActive, 'tr');
+
+ addNodeWithText(tr, 'td', a.url);
+ addNodeWithText(tr, 'td', a.duration);
+ addNodeWithText(tr, 'td', a.is_loaded);
+ }
+
+ var tbodyHistory = $(PrerenderView.HISTORY_TABLE_ID);
+ tbodyHistory.innerHTML = '';
+
+ // Fill in Prerender History table
+ for (var i = 0; i < prerenderInfo.history.length; ++i) {
+ var h = prerenderInfo.history[i];
+ var tr = addNode(tbodyHistory, 'tr');
+ tr.className = h.final_status.toLowerCase();
+
+ addNodeWithText(tr, 'td', h.origin);
+ addNodeWithText(tr, 'td', h.url);
+ addNodeWithText(tr, 'td', h.final_status);
+ addNodeWithText(tr, 'td',
+ timeutil.dateToString(new Date(parseInt(h.end_time))));
+ }
+
+ return true;
+ }
+ };
+
+ return PrerenderView;
+})();
diff --git a/netlog_viewer/proxy_view.html b/netlog_viewer/proxy_view.html
index 1c21a69..7a53300 100644
--- a/netlog_viewer/proxy_view.html
+++ b/netlog_viewer/proxy_view.html
@@ -19,8 +19,6 @@
</style>
<div id=proxy-view-tab-content class=content-box>
- <input type=button value="Re-apply settings" id=proxy-view-reload-settings class="hide-when-not-capturing">
-
<div id=proxy-view-effective-content>
<h4>Effective proxy settings</h4>
<pre id=proxy-view-effective-settings></pre>
@@ -39,10 +37,7 @@
</div>
<div id=proxy-view-bad-proxies-div style='display: none'>
- <h4>
- Recently failed proxies, marked as bad
- <input type=button value="Clear bad proxies" id=proxy-view-clear-bad-proxies class="hide-when-not-capturing">
- </h4>
+ <h4>Recently failed proxies, marked as bad</h4>
<table class="styled-table">
<thead>
<tr>
diff --git a/netlog_viewer/proxy_view.js b/netlog_viewer/proxy_view.js
index 1053413..4bd5564 100644
--- a/netlog_viewer/proxy_view.js
+++ b/netlog_viewer/proxy_view.js
@@ -25,12 +25,6 @@
// Call superclass's constructor.
superClass.call(this, ProxyView.MAIN_BOX_ID);
- // Hook up the UI components.
- $(ProxyView.RELOAD_SETTINGS_BUTTON_ID).onclick =
- g_browser.sendReloadProxySettings.bind(g_browser);
- $(ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID).onclick =
- g_browser.sendClearBadProxies.bind(g_browser);
-
// Register to receive proxy information as it changes.
g_browser.addProxySettingsObserver(this, true);
g_browser.addBadProxiesObserver(this, true);
@@ -46,10 +40,8 @@
ProxyView.EFFECTIVE_SETTINGS_DIV_ID = 'proxy-view-effective-settings';
ProxyView.ORIGINAL_CONTENT_DIV_ID = 'proxy-view-original-content';
ProxyView.EFFECTIVE_CONTENT_DIV_ID = 'proxy-view-effective-content';
- ProxyView.RELOAD_SETTINGS_BUTTON_ID = 'proxy-view-reload-settings';
ProxyView.BAD_PROXIES_DIV_ID = 'proxy-view-bad-proxies-div';
ProxyView.BAD_PROXIES_TBODY_ID = 'proxy-view-bad-proxies-tbody';
- ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID = 'proxy-view-clear-bad-proxies';
ProxyView.SOCKS_HINTS_DIV_ID = 'proxy-view-socks-hints';
ProxyView.SOCKS_HINTS_FLAG_DIV_ID = 'proxy-view-socks-hints-flag';
diff --git a/netlog_viewer/quic_view.html b/netlog_viewer/quic_view.html
index 053e329..60e8d85 100644
--- a/netlog_viewer/quic_view.html
+++ b/netlog_viewer/quic_view.html
@@ -1,27 +1,28 @@
<div id=quic-view-tab-content class=content-box>
+ <h4>QUIC status</h4>
<ul style='margin-top:0'>
- <li>QUIC Enabled: <span jscontent="!!quic_enabled"></span></li>
- <li>Origins To Force QUIC On: <span jscontent="origins_to_force_quic_on"></span></li>
- <li>Connection options: <span jscontent="connection_options"></span></li>
- <li>Consistent Port Selection Enabled: <span jscontent="!!enable_quic_port_selection"></span></li>
- <li>Load Server Info Timeout Multiplier: <span jscontent="$this.load_server_info_timeout_srtt_multiplier"></span></li>
- <li>Enable Connection Racing: <span jscontent="!!enable_connection_racing"></span></li>
- <li>Disable Disk Cache: <span jscontent="!!disable_disk_cache"></span></li>
- <li>Prefer AES: <span jscontent="!!prefer_aes"></span></li>
- <li>Maximum Number Of Lossy Connections: <span jscontent="$this.max_number_of_lossy_connections"></span></li>
- <li>Packet Loss Threshold: <span jscontent="$this.packet_loss_threshold"></span></li>
- <li>Delay TCP Race: <span jscontent="!!delay_tcp_race"></span></li>
- <li>Store Server Configs In Properties File: <span jscontent="!!store_server_configs_in_properties"></span></li>
- <li>Idle Connection Timeout In Seconds: <span jscontent="$this.idle_connection_timeout_seconds"></span></li>
- <li>Disable PreConnect If 0RTT: <span jscontent="$this.disable_preconnect_if_0rtt"></span></li>
- <li>Disable QUIC On Timeout With Open Streams: <span jscontent="$this.disable_quic_on_timeout_with_open_streams"></span></li>
- <li jsdisplay="$this.disabled_reason && disabled_reason.length > 0">QUIC dynamically disabled: <span jscontent="disabled_reason"></span></li>
+ <li>QUIC Enabled: <span id=quic-view-quic-enabled></span></li>
+ <li>Origins To Force QUIC On: <span id=quic-view-origins-to-force-quic-on></span></li>
+ <li>Connection options: <span id=quic-view-connection-options></span></li>
+ <li>Consistent Port Selection Enabled: <span id=quic-view-port-selection-enabled></span></li>
+ <li>Load Server Info Timeout Multiplier: <span id=quic-view-server-info-timeout-mult></span></li>
+ <li>Enable Connection Racing: <span id=quic-view-enable-connection-racing></span></li>
+ <li>Disable Disk Cache: <span id=quic-view-disable-disk-cache></span></li>
+ <li>Prefer AES: <span id=quic-view-prefer-aes></span></li>
+ <li>Maximum Number Of Lossy Connections: <span id=quic-view-max-num-lossy-connections></span></li>
+ <li>Packet Loss Threshold: <span id=quic-view-packet-loss-threshold></span></li>
+ <li>Delay TCP Race: <span id=quic-view-delay-tcp-race></span></li>
+ <li>Store Server Configs In Properties File: <span id=quic-view-configs-in-file></span></li>
+ <li>Idle Connection Timeout In Seconds: <span id=quic-view-connection-timeout-in-secs></span></li>
+ <li>Disable PreConnect If 0RTT: <span id=quic-view-disable-preconnect-if-ortt></span></li>
+ <li>Disable QUIC On Timeout With Open Streams: <span id=quic-view-disable-quic-on-timeout-with-open-streams></span></li>
+ <li id=quic-view-dynamically-disabled-bullet-point><span id=quic-view-dynamically-disabled-span></span></li>
</ul>
<h4>QUIC sessions</h4>
<!-- Only one of these two are shown -->
- <div jsdisplay="!($this.sessions && sessions.length > 0)">None</div>
- <div jsdisplay="$this.sessions && sessions.length > 0">
+ <div id=quic-view-session-info-no-content>None</div>
+ <div id=quic-view-session-info-content>
<a href="#events&q=type:QUIC_SESSION%20is:active">View live QUIC sessions</a>
<p>
<table class="styled-table">
@@ -41,21 +42,7 @@
<th>Connected</th>
</tr>
</thead>
- <tbody>
- <tr jsselect="sessions">
- <td jscontent="$this.aliases ? $this.aliases.join(' ') : ''"></td>
- <td jscontent="!!secure"></td>
- <td jscontent="version"></td>
- <td jscontent="peer_address"></td>
- <td><a jsvalues=".href: '#events&q=type:QUIC_SESSION%20' + connection_id" jscontent="connection_id"></a></td>
- <td jscontent="open_streams"></td>
- <td jscontent="$this.active_streams && $this.active_streams.length > 0 ? $this.active_streams.join(', ') : 'None'"></td>
- <td jscontent="total_streams"></td>
- <td jscontent="packets_sent"></td>
- <td jscontent="packets_lost"></td>
- <td jscontent="packets_received"></td>
- <td jscontent="connected"></td>
- </tr>
+ <tbody id=quic-view-session-info-tbody>
</tbody>
</table>
</p>
diff --git a/netlog_viewer/quic_view.js b/netlog_viewer/quic_view.js
index 4eba9f2..2cb87de 100644
--- a/netlog_viewer/quic_view.js
+++ b/netlog_viewer/quic_view.js
@@ -30,6 +30,43 @@
// IDs for special HTML elements in quic_view.html
QuicView.MAIN_BOX_ID = 'quic-view-tab-content';
+ QuicView.STATUS_QUIC_ENABLED = 'quic-view-quic-enabled';
+ QuicView.STATUS_ORIGINS_TO_FORCE_QUIC_ON =
+ 'quic-view-origins-to-force-quic-on';
+ QuicView.STATUS_CONNECTION_OPTIONS =
+ 'quic-view-connection-options';
+ QuicView.STATUS_CONSISTENT_PORT_SELECTION_ENABLED =
+ 'quic-view-port-selection-enabled';
+ QuicView.STATUS_LOAD_SERVER_INFO_TIMEOUT_MULTIPLIER =
+ 'quic-view-server-info-timeout-mult';
+ QuicView.STATUS_ENABLE_CONNECTION_RACING =
+ 'quic-view-enable-connection-racing';
+ QuicView.STATUS_DISABLE_DISK_CACHE =
+ 'quic-view-disable-disk-cache';
+ QuicView.STATUS_PREFER_AES =
+ 'quic-view-prefer-aes';
+ QuicView.STATUS_MAX_NUM_OF_LOSSY_CONNECTIONS =
+ 'quic-view-max-num-lossy-connections';
+ QuicView.STATUS_PACKET_LOSS_THRESHOLD =
+ 'quic-view-packet-loss-threshold';
+ QuicView.STATUS_DELAY_TCP_RACE = 'quic-view-delay-tcp-race';
+ QuicView.STATUS_STORE_SERVER_CONFIGS_IN_PROPERITES_FILE =
+ 'quic-view-configs-in-file';
+ QuicView.STATUS_IDLE_CONNECTION_TIMEOUT_IN_SECS =
+ 'quic-view-connection-timeout-in-secs';
+ QuicView.STATUS_DISABLE_PRECONNECT_IF_ORTT =
+ 'quic-view-disable-preconnect-if-ortt';
+ QuicView.STATUS_DISABLE_QUIC_ON_TIMEOUT_WITH_OPEN_STREAMS =
+ 'quic-view-disable-quic-on-timeout-with-open-streams';
+ QuicView.STATUS_DYNAMICALLY_DISABLED_BULLET_POINT =
+ 'quic-view-dynamically-disabled-bullet-point';
+ QuicView.STATUS_DYNAMICALLY_DISABLED_SPAN =
+ 'quic-view-dynamically-disabled-span';
+ QuicView.SESSION_INFO_CONTENT_ID =
+ 'quic-view-session-info-content';
+ QuicView.SESSION_INFO_NO_CONTENT_ID =
+ 'quic-view-session-info-no-content';
+ QuicView.SESSION_INFO_TBODY_ID = 'quic-view-session-info-tbody';
cr.addSingletonGetter(QuicView);
@@ -48,9 +85,99 @@
onQuicInfoChanged: function(quicInfo) {
if (!quicInfo)
return false;
- // TODO(rayraymond): Update DOM without use of jstemplate.
- // var input = new JsEvalContext(quicInfo);
- // jstProcess(input, $(QuicView.MAIN_BOX_ID));
+
+ $(QuicView.STATUS_QUIC_ENABLED).textContent =
+ !!quicInfo.quic_enabled;
+
+ $(QuicView.STATUS_ORIGINS_TO_FORCE_QUIC_ON).textContent =
+ quicInfo.origins_to_force_quic_on;
+
+ $(QuicView.STATUS_CONNECTION_OPTIONS).textContent =
+ quicInfo.connection_options;
+
+ $(QuicView.STATUS_CONSISTENT_PORT_SELECTION_ENABLED).
+ textContent = !!quicInfo.enable_quic_port_selection;
+
+ $(QuicView.STATUS_LOAD_SERVER_INFO_TIMEOUT_MULTIPLIER).
+ textContent = quicInfo.load_server_info_timeout_srtt_multiplier;
+
+ $(QuicView.STATUS_ENABLE_CONNECTION_RACING).textContent =
+ !!quicInfo.enable_connection_racing;
+
+ $(QuicView.STATUS_DISABLE_DISK_CACHE).textContent =
+ !!quicInfo.disable_disk_cache;
+
+ $(QuicView.STATUS_PREFER_AES).textContent =
+ !!quicInfo.prefer_aes;
+
+ $(QuicView.STATUS_MAX_NUM_OF_LOSSY_CONNECTIONS).textContent =
+ quicInfo.max_number_of_lossy_connections;
+
+ $(QuicView.STATUS_PACKET_LOSS_THRESHOLD).textContent =
+ quicInfo.packet_loss_threshold;
+
+ $(QuicView.STATUS_DELAY_TCP_RACE).textContent =
+ !!quicInfo.delay_tcp_race;
+
+ $(QuicView.STATUS_STORE_SERVER_CONFIGS_IN_PROPERITES_FILE).
+ textContent = !!quicInfo.store_server_configs_in_properties;
+
+ $(QuicView.STATUS_IDLE_CONNECTION_TIMEOUT_IN_SECS).textContent =
+ quicInfo.idle_connection_timeout_seconds;
+
+ $(QuicView.STATUS_DISABLE_PRECONNECT_IF_ORTT).textContent =
+ quicInfo.disable_preconnect_if_0rtt;
+
+ $(QuicView.STATUS_DISABLE_QUIC_ON_TIMEOUT_WITH_OPEN_STREAMS).
+ textContent =
+ quicInfo.disable_quic_on_timeout_with_open_streams;
+
+ setNodeDisplay($(QuicView.STATUS_DYNAMICALLY_DISABLED_BULLET_POINT),
+ quicInfo.disabled_reason && quicInfo.disabled_reason.length > 0);
+ if (quicInfo.disabled_reason &&
+ quicInfo.disabled_reason.length > 0) {
+ $(QuicView.STATUS_DYNAMICALLY_DISABLED_SPAN).textContent =
+ 'QUIC dynamically disabled: ' + quicInfo.disabled_reason;
+ }
+
+ var sessions = quicInfo.sessions;
+
+ var hasSessions = sessions && sessions.length > 0;
+
+ setNodeDisplay($(QuicView.SESSION_INFO_CONTENT_ID), hasSessions);
+ setNodeDisplay($(QuicView.SESSION_INFO_NO_CONTENT_ID), !hasSessions);
+
+ var tbody = $(QuicView.SESSION_INFO_TBODY_ID);
+ tbody.innerHTML = '';
+
+ // Fill in the sessions info table.
+ for (var i = 0; i < sessions.length; ++i) {
+ var q = sessions[i];
+ var tr = addNode(tbody, 'tr');
+
+ addNodeWithText(tr, 'td', q.aliases ? q.aliases.join(' ') : '');
+ addNodeWithText(tr, 'td', !!q.secure);
+ addNodeWithText(tr, 'td', q.version);
+ addNodeWithText(tr, 'td', q.peer_address);
+
+ var connectionUIDCell = addNode(tr, 'td');
+ var a = addNode(connectionUIDCell, 'a');
+ a.href = '#events&q=type:QUIC_SESSION%20' + q.connection_id;
+ a.textContent = q.connection_id;
+
+ addNodeWithText(tr, 'td', q.open_streams);
+
+ addNodeWithText(tr, 'td',
+ q.active_streams && q.active_streams.length > 0 ?
+ q.active_streams.join(', ') : 'None');
+
+ addNodeWithText(tr, 'td', q.total_streams);
+ addNodeWithText(tr, 'td', q.packets_sent);
+ addNodeWithText(tr, 'td', q.packets_lost);
+ addNodeWithText(tr, 'td', q.packets_received);
+ addNodeWithText(tr, 'td', q.connected);
+ }
+
return true;
},
};
diff --git a/netlog_viewer/sdch_view.html b/netlog_viewer/sdch_view.html
index 446b465..4593962 100644
--- a/netlog_viewer/sdch_view.html
+++ b/netlog_viewer/sdch_view.html
@@ -1,7 +1,7 @@
<div id=sdch-view-tab-content class=content-box>
<ul style="margin-top:0">
<li>SDCH Enabled:
- <span jscontent="!!sdch_enabled" id=sdch-view-sdch-enabled></span>
+ <span id=sdch-view-sdch-enabled></span>
</li>
</ul>
@@ -24,7 +24,7 @@
</p>
<h4>
- Dictionaries loaded: <span jscontent="dictionaries.length"></span>
+ Dictionaries loaded: <span id=sdch-view-num-dictionaries-loaded></span>
</h4>
<table class="styled-table">
<thead>
@@ -37,15 +37,7 @@
<th>Url</th>
</tr>
</thead>
- <tbody id=sdch-view-dictionaries-body>
- <tr jsselect="dictionaries">
- <td jscontent="domain"></td>
- <td jscontent="path"></td>
- <td jscontent="$this.ports ? $this.ports.join(', ') : ''"></td>
- <td jscontent="server_hash"></td>
- <td jscontent="client_hash"></td>
- <td jscontent="url"></td>
- </tr>
+ <tbody id=sdch-view-dictionaries-tbody>
</tbody>
</table>
@@ -58,12 +50,7 @@
<th>Tries to back off</th>
</tr>
</thead>
- <tbody id=sdch-view-blacklist-body>
- <tr jsselect="blacklisted">
- <td jscontent="domain"></td>
- <td jscontent="sdchProblemCodeToString(reason)"></td>
- <td jscontent="tries"></td>
- </tr>
+ <tbody id=sdch-view-blacklist-tbody>
</tbody>
</table>
</div>
diff --git a/netlog_viewer/sdch_view.js b/netlog_viewer/sdch_view.js
index 59ac07b..1dd40e4 100644
--- a/netlog_viewer/sdch_view.js
+++ b/netlog_viewer/sdch_view.js
@@ -34,8 +34,9 @@
SdchView.MAIN_BOX_ID = 'sdch-view-tab-content';
SdchView.SDCH_ENABLED_SPAN_ID = 'sdch-view-sdch-enabled';
SdchView.SECURE_SCHEME_SUPPORT_SPAN_ID = 'sdch-view-secure-scheme-support';
- SdchView.BLACKLIST_TBODY_ID = 'sdch-view-blacklist-body';
- SdchView.DICTIONARIES_TBODY_ID = 'sdch-view-dictionaries-body';
+ SdchView.BLACKLIST_TBODY_ID = 'sdch-view-blacklist-tbody';
+ SdchView.NUM_DICTIONARIES_LOADED_ID = 'sdch-view-num-dictionaries-loaded';
+ SdchView.DICTIONARIES_TBODY_ID = 'sdch-view-dictionaries-tbody';
cr.addSingletonGetter(SdchView);
@@ -50,9 +51,43 @@
onSdchInfoChanged: function(sdchInfo) {
if (!sdchInfo || typeof(sdchInfo.sdch_enabled) === 'undefined')
return false;
- // TODO(rayraymond): Update DOM without use of jstemplate.
- // var input = new JsEvalContext(sdchInfo);
- // jstProcess(input, $(SdchView.MAIN_BOX_ID));
+
+ $(SdchView.SDCH_ENABLED_SPAN_ID).textContent =
+ !!sdchInfo.sdch_enabled;
+
+ $(SdchView.NUM_DICTIONARIES_LOADED_ID).textContent =
+ sdchInfo.dictionaries.length;
+
+ var tbodyDictionaries = $(SdchView.DICTIONARIES_TBODY_ID);
+ tbodyDictionaries.innerHTML = '';
+
+ // Fill in the dictionaries table.
+ for (var i = 0; i < sdchInfo.dictionaries.length; ++i) {
+ var d = sdchInfo.dictionaries[i];
+ var tr = addNode(tbodyDictionaries, 'tr');
+
+ addNodeWithText(tr, 'td', d.domain);
+ addNodeWithText(tr, 'td', d.path);
+ addNodeWithText(tr, 'td',
+ d.ports ? d.ports.join(', ') : '');
+ addNodeWithText(tr, 'td', d.server_hash);
+ addNodeWithText(tr, 'td', d.client_hash);
+ addNodeWithText(tr, 'td', d.url);
+ }
+
+ var tbodyBlacklist = $(SdchView.BLACKLIST_TBODY_ID);
+ tbodyBlacklist.innerHTML = '';
+
+ // Fill in the blacklisted table.
+ for (var i = 0; i < sdchInfo.blacklisted.length; ++i) {
+ var b = sdchInfo.blacklisted[i];
+ var tr = addNode(tbodyBlacklist, 'tr');
+
+ addNodeWithText(tr, 'td', d.domain);
+ addNodeWithText(tr, 'td', d.sdchProblemCodeToString(reason));
+ addNodeWithText(tr, 'td', d.tries);
+ }
+
return true;
},
};
diff --git a/netlog_viewer/sockets_view.html b/netlog_viewer/sockets_view.html
index 8f3d33d..662d50c 100644
--- a/netlog_viewer/sockets_view.html
+++ b/netlog_viewer/sockets_view.html
@@ -6,17 +6,7 @@
</style>
<div id=sockets-view-tab-content class=content-box>
- <ul style='margin-top:0'>
- <li class="hide-when-not-capturing">
- <input type=button value="Close idle sockets" id=sockets-view-close-idle-button>
- </li>
- <li class="hide-when-not-capturing">
- <input type=button value="Flush socket pools" id=sockets-view-flush-button>
- <span class=warning-text>May break pages with active connections</span>
- </li>
- <li><a href='#events&q=type:SOCKET%20is:active'>View live sockets</a>
- </li>
- </ul>
+ <a href='#events&q=type:SOCKET%20is:active'>View live sockets</a>
<p>
<div id=sockets-view-pool-div>
</div>
diff --git a/netlog_viewer/sockets_view.js b/netlog_viewer/sockets_view.js
index 9b12cb3..d6ef193 100644
--- a/netlog_viewer/sockets_view.js
+++ b/netlog_viewer/sockets_view.js
@@ -27,12 +27,6 @@
g_browser.addSocketPoolInfoObserver(this, true);
this.socketPoolDiv_ = $(SocketsView.SOCKET_POOL_DIV_ID);
this.socketPoolGroupsDiv_ = $(SocketsView.SOCKET_POOL_GROUPS_DIV_ID);
-
- var closeIdleButton = $(SocketsView.CLOSE_IDLE_SOCKETS_BUTTON_ID);
- closeIdleButton.onclick = this.closeIdleSockets.bind(this);
-
- var flushSocketsButton = $(SocketsView.SOCKET_POOL_FLUSH_BUTTON_ID);
- flushSocketsButton.onclick = this.flushSocketPools.bind(this);
}
SocketsView.TAB_ID = 'tab-handle-sockets';
@@ -43,8 +37,6 @@
SocketsView.MAIN_BOX_ID = 'sockets-view-tab-content';
SocketsView.SOCKET_POOL_DIV_ID = 'sockets-view-pool-div';
SocketsView.SOCKET_POOL_GROUPS_DIV_ID = 'sockets-view-pool-groups-div';
- SocketsView.CLOSE_IDLE_SOCKETS_BUTTON_ID = 'sockets-view-close-idle-button';
- SocketsView.SOCKET_POOL_FLUSH_BUTTON_ID = 'sockets-view-flush-button';
cr.addSingletonGetter(SocketsView);
@@ -77,16 +69,6 @@
}
}
return true;
- },
-
- closeIdleSockets: function() {
- g_browser.sendCloseIdleSockets();
- g_browser.checkForUpdatedInfo(false);
- },
-
- flushSocketPools: function() {
- g_browser.sendFlushSocketPools();
- g_browser.checkForUpdatedInfo(false);
}
};
diff --git a/netlog_viewer/spdy_view.html b/netlog_viewer/spdy_view.html
index 54b778f..b6061d8 100644
--- a/netlog_viewer/spdy_view.html
+++ b/netlog_viewer/spdy_view.html
@@ -1,29 +1,30 @@
<div id=spdy-view-tab-content class=content-box>
+ <h4>HTTP/2 status</h4>
<ul id=spdy-view-status style='margin-top:0'>
<!-- "enable_http2" and "enable_spdy31" are used since release 50, see
https://crrev.com/1651123002. "spdy_enabled" is here to support
importing netlog json files from earlier browsers.
TODO(bnc): Deprecate around 2016 July. -->
- <li>HTTP/2 Enabled: <span jscontent="$this.enable_http2 == undefined ? $this.spdy_enabled : $this.enable_http2"></span></li>
- <li>SPDY/3.1 Enabled: <span jscontent="$this.enable_spdy31 == undefined ? $this.spdy_enabled : $this.enable_spdy31"></span></li>
+ <li>HTTP/2 Enabled: <span id=spdy-view-http2-enabled></span></li>
+ <li>SPDY/3.1 Enabled: <span id=spdy-view-spdy31-enabled></span></li>
<!-- "use_alternative_service" is used here since release 46, see
https://crrev.com/1268313004. "use_alternate_protocols" is here to
support importing netlog json files from earlier browsers.
TODO(bnc): Deprecate around 2016 February. -->
- <li>Use Alternative Service: <span jscontent="$this.use_alternative_services == undefined ? $this.use_alternate_protocols : $this.use_alternative_services"></span></li>
+ <li>Use Alternative Service: <span id=spdy-view-alternate-service></span></li>
<!-- "alpn_protos" and "npn_protos" are used here since release 48, see
https://crrev.com/1387363004. "next_protos" is here to support
importing netlog json files from earlier browsers.
TODO(bnc): Deprecate around 2016 April. -->
- <li>ALPN Protocols: <span jscontent="$this.alpn_protos || $this.next_protos"></span></li>
- <li>NPN Protocols: <span jscontent="$this.npn_protos || $this.next_protos"></span></li>
+ <li>ALPN Protocols: <span id=spdy-view-alpn-protocols></span></li>
+ <li>NPN Protocols: <span id=spdy-view-npn-protocols></span></li>
</ul>
<h4>HTTP/2 sessions</h4>
<div id=spdy-view-session-info>
<!-- Only one of these two are shown -->
- <div jsdisplay="spdySessionInfo.length == 0">None</div>
- <div jsdisplay="spdySessionInfo.length != 0">
+ <div id=spdy-view-session-info-no-content>None</div>
+ <div id=spdy-view-session-info-content>
<a href="#events&q=type:HTTP2_SESSION%20is:active">View live HTTP/2 sessions</a>
<p>
<table class="styled-table">
@@ -50,30 +51,7 @@
<th>Error</th>
</tr>
</thead>
- <tbody>
- <tr jsselect="spdySessionInfo">
- <td><span jscontent="host_port_pair"></span>
- <span jscontent="$this.aliases ? $this.aliases.join(' ') : ''"></span>
- </td>
- <td jscontent="proxy"></td>
- <td><a jsvalues=".href: '#events&q=id:' + source_id" jscontent="source_id"></a></td>
- <td jscontent="protocol_negotiated"></td>
- <td jscontent="active_streams"></td>
- <td jscontent="unclaimed_pushed_streams"></td>
- <td jscontent="max_concurrent_streams"></td>
- <td jscontent="streams_initiated_count"></td>
- <td jscontent="streams_pushed_count"></td>
- <td jscontent="streams_pushed_and_claimed_count"></td>
- <td jscontent="streams_abandoned_count"></td>
- <td jscontent="frames_received"></td>
- <td jscontent="is_secure"></td>
- <td jscontent="sent_settings"></td>
- <td jscontent="received_settings"></td>
- <td jscontent="send_window_size"></td>
- <td jscontent="recv_window_size"></td>
- <td jscontent="unacked_recv_window_bytes"></td>
- <td jscontent="error"></td>
- </tr>
+ <tbody id=spdy-view-session-info-tbody>
</tbody>
</table>
</p>
diff --git a/netlog_viewer/spdy_view.js b/netlog_viewer/spdy_view.js
index d07b279..ca63113 100644
--- a/netlog_viewer/spdy_view.js
+++ b/netlog_viewer/spdy_view.js
@@ -32,7 +32,16 @@
// IDs for special HTML elements in spdy_view.html
SpdyView.MAIN_BOX_ID = 'spdy-view-tab-content';
SpdyView.STATUS_ID = 'spdy-view-status';
+ SpdyView.STATUS_HTTP2_ENABLED = 'spdy-view-http2-enabled';
+ SpdyView.STATUS_SPDY31_ENABLED = 'spdy-view-spdy31-enabled';
+ SpdyView.STATUS_ALTERNATE_SERVICE = 'spdy-view-alternate-service';
+ SpdyView.STATUS_ALPN_PROTOCOLS = 'spdy-view-alpn-protocols';
+ SpdyView.STATUS_NPN_PROTOCOLS = 'spdy-view-npn-protocols';
SpdyView.SESSION_INFO_ID = 'spdy-view-session-info';
+ SpdyView.SESSION_INFO_CONTENT_ID = 'spdy-view-session-info-content';
+ SpdyView.SESSION_INFO_NO_CONTENT_ID =
+ 'spdy-view-session-info-no-content';
+ SpdyView.SESSION_INFO_TBODY_ID = 'spdy-view-session-info-tbody';
cr.addSingletonGetter(SpdyView);
@@ -52,9 +61,45 @@
onSpdySessionInfoChanged: function(spdySessionInfo) {
if (!spdySessionInfo)
return false;
- // TODO(rayraymond): Update DOM without use of jstemplate.
- // var input = new JsEvalContext({ spdySessionInfo: spdySessionInfo });
- // jstProcess(input, $(SpdyView.SESSION_INFO_ID));
+
+ var hasSpdySessionInfo = spdySessionInfo && spdySessionInfo.length > 0;
+
+ setNodeDisplay($(SpdyView.SESSION_INFO_CONTENT_ID), hasSpdySessionInfo);
+ setNodeDisplay($(SpdyView.SESSION_INFO_NO_CONTENT_ID),
+ !hasSpdySessionInfo);
+
+ var tbody = $(SpdyView.SESSION_INFO_TBODY_ID);
+ tbody.innerHTML = '';
+
+ // Fill in the sessions info table.
+ for (var i = 0; i < spdySessionInfo.length; ++i) {
+ var s = spdySessionInfo[i];
+ var tr = addNode(tbody, 'tr');
+
+ var hostCell = addNode(tr, 'td');
+ addNodeWithText(hostCell, 'span', s.host_port_pair);
+ addNodeWithText(hostCell, 'span',
+ s.aliases ? ' ' + s.aliases.join(' ') : '');
+
+ addNodeWithText(tr, 'td', s.proxy);
+
+ var idCell = addNode(tr, 'td');
+ var a = addNodeWithText(idCell, 'a', s.source_id);
+ a.href = '#events&q=id:' + s.source_id;
+
+ var kFields = ['protocol_negotiated', 'active_streams',
+ 'unclaimed_pushed_streams', 'max_concurrent_streams',
+ 'streams_initiated_count', 'streams_pushed_count',
+ 'streams_pushed_and_claimed_count',
+ 'streams_abandoned_count', 'frames_received', 'is_secure',
+ 'sent_settings', 'received_settings', 'send_window_size',
+ 'recv_window_size', 'unacked_recv_window_bytes', 'error'];
+
+ for (var fieldIndex = 0; fieldIndex < kFields.length; ++fieldIndex) {
+ addNodeWithText(tr, 'td', s[kFields[fieldIndex]]);
+ }
+ }
+
return true;
},
@@ -64,9 +109,26 @@
onSpdyStatusChanged: function(spdyStatus) {
if (!spdyStatus)
return false;
- // TODO(rayraymond): Update DOM without use of jstemplate.
- // var input = new JsEvalContext(spdyStatus);
- // jstProcess(input, $(SpdyView.STATUS_ID));
+
+ $(SpdyView.STATUS_HTTP2_ENABLED).textContent =
+ (spdyStatus.enable_http2 == undefined ?
+ spdyStatus.spdy_enabled : spdyStatus.enable_http2);
+
+ $(SpdyView.STATUS_SPDY31_ENABLED).textContent =
+ (spdyStatus.enable_spdy31 == undefined ?
+ spdyStatus.spdy_enabled : spdyStatus.enable_spdy31);
+
+ $(SpdyView.STATUS_ALTERNATE_SERVICE).textContent =
+ (spdyStatus.use_alternative_services == undefined ?
+ spdyStatus.use_alternate_protocols :
+ spdyStatus.use_alternative_services);
+
+ $(SpdyView.STATUS_ALPN_PROTOCOLS).textContent =
+ (spdyStatus.alpn_protos || spdyStatus.next_protos);
+
+ $(SpdyView.STATUS_NPN_PROTOCOLS).textContent =
+ (spdyStatus.npn_protos || spdyStatus.next_protos);
+
return true;
}
};