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;
     }
   };