1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5var g_main_view = null; 6 7/** 8 * This class is the root view object of the page. 9 */ 10var MainView = (function() { 11 'use strict'; 12 13 /** 14 * @constructor 15 */ 16 function MainView() { 17 $('button-update').onclick = function() { 18 chrome.send('update'); 19 }; 20 }; 21 22 MainView.prototype = { 23 /** 24 * Receiving notification to display memory snapshot. 25 * @param {Object} Information about memory in JSON format. 26 */ 27 onSetSnapshot: function(browser) { 28 $('json').textContent = JSON.stringify(browser); 29 $('json').style.display = 'block'; 30 31 $('os-value').textContent = browser['os'] + ' (' + 32 browser['os_version'] + ')'; 33 $('uptime-value').textContent = 34 secondsToHMS(Math.floor(browser['uptime'] / 1000)); 35 36 this.updateSnapshot(browser['processes']); 37 this.updateExtensions(browser['extensions']); 38 }, 39 40 /** 41 * Update process information table. 42 * @param {Object} processes information about memory. 43 */ 44 updateSnapshot: function(processes) { 45 // Remove existing processes. 46 var size = $('snapshot-view').getElementsByClassName('process').length; 47 for (var i = 0; i < size; ++i) { 48 $('snapshot-view').deleteRow(-1); 49 } 50 51 var template = $('process-template').childNodes; 52 // Add processes. 53 for (var p in processes) { 54 var process = processes[p]; 55 56 var row = $('snapshot-view').insertRow(-1); 57 // We skip |template[0]|, because it is a (invalid) Text object. 58 for (var i = 1; i < template.length; ++i) { 59 var value = '---'; 60 switch (template[i].className) { 61 case 'process-id': 62 value = process['pid']; 63 break; 64 case 'process-info': 65 value = process['type']; 66 if (process['type'].match(/^Tab/) && 'history' in process) { 67 // Append each tab's history. 68 for (var j = 0; j < process['history'].length; ++j) { 69 value += '<dl><dt>History ' + j + ':' + 70 JoinLinks(process['history'][j]) + '</dl>'; 71 } 72 } else { 73 value += '<br>' + process['titles'].join('<br>'); 74 } 75 break; 76 case 'process-memory-private': 77 value = process['memory_private']; 78 break; 79 case 'process-memory-v8': 80 if (process['v8_alloc'] !== undefined) { 81 value = process['v8_used'] + '<br>/ ' + process['v8_alloc']; 82 } 83 break; 84 } 85 var col = row.insertCell(-1); 86 col.innerHTML = value; 87 col.className = template[i].className; 88 } 89 row.setAttribute('class', 'process'); 90 } 91 }, 92 93 /** 94 * Update extension information table. 95 * @param {Object} extensions information about memory. 96 */ 97 updateExtensions: function(extensions) { 98 // Remove existing information. 99 var size = 100 $('extension-view').getElementsByClassName('extension').length; 101 for (var i = 0; i < size; ++i) { 102 $('extension-view').deleteRow(-1); 103 } 104 105 var template = $('extension-template').childNodes; 106 for (var id in extensions) { 107 var extension = extensions[id]; 108 109 var row = $('extension-view').insertRow(-1); 110 // We skip |template[0]|, because it is a (invalid) Text object. 111 for (var i = 1; i < template.length; ++i) { 112 var value = '---'; 113 switch (template[i].className) { 114 case 'extension-id': 115 value = extension['pid']; 116 break; 117 case 'extension-info': 118 value = extension['titles'].join('<br>'); 119 break; 120 case 'extension-memory': 121 value = extension['memory_private']; 122 break; 123 } 124 var col = row.insertCell(-1); 125 col.innerHTML = value; 126 col.className = template[i].className; 127 } 128 row.setAttribute('class', 'extension'); 129 } 130 } 131 }; 132 133 function JoinLinks(tab) { 134 var line = ''; 135 for (var l in tab['history']) { 136 var history = tab['history'][l]; 137 var title = (history['title'] == '') ? history['url'] : history['title']; 138 var url = '<a href="' + history['url'] + '">' + HTMLEscape(title) + 139 '</a> (' + secondsToHMS(history['time']) + ' ago)'; 140 if (l == tab['index']) { 141 url = '<strong>' + url + '</strong>'; 142 } 143 line += '<dd>' + url; 144 } 145 return line; 146 }; 147 148 /** 149 * Produces a readable string int the format '<HH> hours <MM> min. <SS> sec.' 150 * representing the amount of time provided as the number of seconds. 151 * @param {number} totalSeconds The total amount of seconds. 152 * @return {string} The formatted HH hours/hours MM min. SS sec. string 153 */ 154 function secondsToHMS(totalSeconds) { 155 totalSeconds = Number(totalSeconds); 156 var hour = Math.floor(totalSeconds / 3600); 157 var min = Math.floor(totalSeconds % 3600 / 60); 158 var sec = Math.floor(totalSeconds % 60); 159 return (hour > 0 ? (hour + (hour > 1 ? ' hours ' : ' hour ')) : '') + 160 (min > 0 ? (min + ' min. ') : '') + 161 (sec + ' sec. '); 162 } 163 164 return MainView; 165})(); 166 167/** 168 * Initialize everything once we have access to chrome://memory-internals. 169 */ 170document.addEventListener('DOMContentLoaded', function() { 171 g_main_view = new MainView(); 172}); 173