Home | History | Annotate | Download | only in memory_internals
      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 
      5 var g_main_view = null;
      6 
      7 /**
      8  * This class is the root view object of the page.
      9  */
     10 var 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  */
    170 document.addEventListener('DOMContentLoaded', function() {
    171   g_main_view = new MainView();
    172 });
    173