1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var g_main_view = null;
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/**
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * This class is the root view object of the page.
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var MainView = (function() {
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  'use strict';
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /**
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   * @constructor
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   */
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function MainView() {
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    $('button-update').onclick = function() {
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chrome.send('update');
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    };
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MainView.prototype = {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Receiving notification to display memory snapshot.
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @param {Object}  Information about memory in JSON format.
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    onSetSnapshot: function(browser) {
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      $('json').textContent = JSON.stringify(browser);
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      $('json').style.display = 'block';
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      $('os-value').textContent = browser['os'] + ' (' +
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          browser['os_version'] + ')';
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      $('uptime-value').textContent =
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          secondsToHMS(Math.floor(browser['uptime'] / 1000));
35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this.updateSnapshot(browser['processes']);
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this.updateExtensions(browser['extensions']);
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    },
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    /**
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)     * Update process information table.
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)     * @param {Object} processes information about memory.
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)     */
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    updateSnapshot: function(processes) {
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      // Remove existing processes.
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      var size = $('snapshot-view').getElementsByClassName('process').length;
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      for (var i = 0; i < size; ++i) {
48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        $('snapshot-view').deleteRow(-1);
49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      }
50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      var template = $('process-template').childNodes;
52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      // Add processes.
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (var p in processes) {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        var process = processes[p];
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        var row = $('snapshot-view').insertRow(-1);
57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        // We skip |template[0]|, because it is a (invalid) Text object.
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        for (var i = 1; i < template.length; ++i) {
59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          var value = '---';
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          switch (template[i].className) {
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          case 'process-id':
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            value = process['pid'];
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            break;
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          case 'process-info':
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            value = process['type'];
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            if (process['type'].match(/^Tab/) && 'history' in process) {
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              // Append each tab's history.
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              for (var j = 0; j < process['history'].length; ++j) {
69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                value += '<dl><dt>History ' + j + ':' +
70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                    JoinLinks(process['history'][j]) + '</dl>';
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              }
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            } else {
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              value += '<br>' + process['titles'].join('<br>');
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            }
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            break;
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          case 'process-memory-private':
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            value = process['memory_private'];
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            break;
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          case 'process-memory-v8':
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            if (process['v8_alloc'] !== undefined) {
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              value = process['v8_used'] + '<br>/ ' + process['v8_alloc'];
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            }
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            break;
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          }
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          var col = row.insertCell(-1);
86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          col.innerHTML = value;
87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          col.className = template[i].className;
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        }
89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        row.setAttribute('class', 'process');
90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      }
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    },
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /**
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     * Update extension information table.
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     * @param {Object} extensions information about memory.
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     */
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    updateExtensions: function(extensions) {
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Remove existing information.
99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      var size =
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          $('extension-view').getElementsByClassName('extension').length;
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      for (var i = 0; i < size; ++i) {
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        $('extension-view').deleteRow(-1);
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      var template = $('extension-template').childNodes;
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      for (var id in extensions) {
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        var extension = extensions[id];
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        var row = $('extension-view').insertRow(-1);
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // We skip |template[0]|, because it is a (invalid) Text object.
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        for (var i = 1; i < template.length; ++i) {
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          var value = '---';
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          switch (template[i].className) {
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          case 'extension-id':
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            value = extension['pid'];
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            break;
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          case 'extension-info':
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            value = extension['titles'].join('<br>');
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            break;
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          case 'extension-memory':
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            value = extension['memory_private'];
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            break;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          }
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          var col = row.insertCell(-1);
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          col.innerHTML = value;
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          col.className = template[i].className;
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        row.setAttribute('class', 'extension');
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  function JoinLinks(tab) {
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    var line = '';
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (var l in tab['history']) {
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      var history = tab['history'][l];
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      var title = (history['title'] == '') ? history['url'] : history['title'];
13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      var url = '<a href="' + history['url'] + '">' + HTMLEscape(title) +
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          '</a> (' + secondsToHMS(history['time']) + ' ago)';
140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (l == tab['index']) {
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        url = '<strong>' + url + '</strong>';
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      line += '<dd>' + url;
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return line;
146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  };
147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /**
149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   * Produces a readable string int the format '<HH> hours <MM> min. <SS> sec.'
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   * representing the amount of time provided as the number of seconds.
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   * @param {number} totalSeconds The total amount of seconds.
152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   * @return {string} The formatted HH hours/hours MM min. SS sec. string
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   */
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  function secondsToHMS(totalSeconds) {
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    totalSeconds = Number(totalSeconds);
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var hour = Math.floor(totalSeconds / 3600);
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var min = Math.floor(totalSeconds % 3600 / 60);
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    var sec = Math.floor(totalSeconds % 60);
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return (hour > 0 ? (hour + (hour > 1 ? ' hours ' : ' hour ')) : '') +
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch           (min > 0 ? (min + ' min. ') : '') +
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch           (sec + ' sec. ');
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return MainView;
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)})();
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/**
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Initialize everything once we have access to chrome://memory-internals.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)document.addEventListener('DOMContentLoaded', function() {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g_main_view = new MainView();
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)});
173