| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| var g_main_view = null; |
| |
| /** |
| * This class is the root view object of the page. |
| */ |
| var MainView = (function() { |
| 'use strict'; |
| |
| /** |
| * @constructor |
| */ |
| function MainView() { |
| $('button-update').onclick = function() { |
| chrome.send('update'); |
| }; |
| }; |
| |
| MainView.prototype = { |
| /** |
| * Receiving notification to display memory snapshot. |
| * @param {Object} Information about memory in JSON format. |
| */ |
| onSetSnapshot: function(browser) { |
| $('json').textContent = JSON.stringify(browser); |
| $('json').style.display = 'block'; |
| |
| $('os-value').textContent = browser['os'] + ' (' + |
| browser['os_version'] + ')'; |
| $('uptime-value').textContent = |
| secondsToHMS(Math.floor(browser['uptime'] / 1000)); |
| |
| this.updateSnapshot(browser['processes']); |
| this.updateExtensions(browser['extensions']); |
| }, |
| |
| /** |
| * Update process information table. |
| * @param {Object} processes information about memory. |
| */ |
| updateSnapshot: function(processes) { |
| // Remove existing processes. |
| var size = $('snapshot-view').getElementsByClassName('process').length; |
| for (var i = 0; i < size; ++i) { |
| $('snapshot-view').deleteRow(-1); |
| } |
| |
| var template = $('process-template').childNodes; |
| // Add processes. |
| for (var p in processes) { |
| var process = processes[p]; |
| |
| var row = $('snapshot-view').insertRow(-1); |
| // We skip |template[0]|, because it is a (invalid) Text object. |
| for (var i = 1; i < template.length; ++i) { |
| var value = '---'; |
| switch (template[i].className) { |
| case 'process-id': |
| value = process['pid']; |
| break; |
| case 'process-info': |
| value = process['type']; |
| if (process['type'].match(/^Tab/) && 'history' in process) { |
| // Append each tab's history. |
| for (var j = 0; j < process['history'].length; ++j) { |
| value += '<dl><dt>History ' + j + ':' + |
| JoinLinks(process['history'][j]) + '</dl>'; |
| } |
| } else { |
| value += '<br>' + process['titles'].join('<br>'); |
| } |
| break; |
| case 'process-memory-private': |
| value = process['memory_private']; |
| break; |
| case 'process-memory-v8': |
| if (process['v8_alloc'] !== undefined) { |
| value = process['v8_used'] + '<br>/ ' + process['v8_alloc']; |
| } |
| break; |
| } |
| var col = row.insertCell(-1); |
| col.innerHTML = value; |
| col.className = template[i].className; |
| } |
| row.setAttribute('class', 'process'); |
| } |
| }, |
| |
| /** |
| * Update extension information table. |
| * @param {Object} extensions information about memory. |
| */ |
| updateExtensions: function(extensions) { |
| // Remove existing information. |
| var size = |
| $('extension-view').getElementsByClassName('extension').length; |
| for (var i = 0; i < size; ++i) { |
| $('extension-view').deleteRow(-1); |
| } |
| |
| var template = $('extension-template').childNodes; |
| for (var id in extensions) { |
| var extension = extensions[id]; |
| |
| var row = $('extension-view').insertRow(-1); |
| // We skip |template[0]|, because it is a (invalid) Text object. |
| for (var i = 1; i < template.length; ++i) { |
| var value = '---'; |
| switch (template[i].className) { |
| case 'extension-id': |
| value = extension['pid']; |
| break; |
| case 'extension-info': |
| value = extension['titles'].join('<br>'); |
| break; |
| case 'extension-memory': |
| value = extension['memory_private']; |
| break; |
| } |
| var col = row.insertCell(-1); |
| col.innerHTML = value; |
| col.className = template[i].className; |
| } |
| row.setAttribute('class', 'extension'); |
| } |
| } |
| }; |
| |
| function JoinLinks(tab) { |
| var line = ''; |
| for (var l in tab['history']) { |
| var history = tab['history'][l]; |
| var title = (history['title'] == '') ? history['url'] : history['title']; |
| var url = '<a href="' + history['url'] + '">' + HTMLEscape(title) + |
| '</a> (' + secondsToHMS(history['time']) + ' ago)'; |
| if (l == tab['index']) { |
| url = '<strong>' + url + '</strong>'; |
| } |
| line += '<dd>' + url; |
| } |
| return line; |
| }; |
| |
| /** |
| * Produces a readable string int the format '<HH> hours <MM> min. <SS> sec.' |
| * representing the amount of time provided as the number of seconds. |
| * @param {number} totalSeconds The total amount of seconds. |
| * @return {string} The formatted HH hours/hours MM min. SS sec. string |
| */ |
| function secondsToHMS(totalSeconds) { |
| totalSeconds = Number(totalSeconds); |
| var hour = Math.floor(totalSeconds / 3600); |
| var min = Math.floor(totalSeconds % 3600 / 60); |
| var sec = Math.floor(totalSeconds % 60); |
| return (hour > 0 ? (hour + (hour > 1 ? ' hours ' : ' hour ')) : '') + |
| (min > 0 ? (min + ' min. ') : '') + |
| (sec + ' sec. '); |
| } |
| |
| return MainView; |
| })(); |
| |
| /** |
| * Initialize everything once we have access to chrome://memory-internals. |
| */ |
| document.addEventListener('DOMContentLoaded', function() { |
| g_main_view = new MainView(); |
| }); |