15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This view displays network related log data and is specific fo ChromeOS.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We get log data from chrome by filtering system logs for network related
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * keywords. Logs are not fetched until we actually need them.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var LogsView = (function() {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'use strict';
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Special classes (defined in logs_view.css).
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var LOG_ROW_COLLAPSED_CLASSNAME = 'logs-view-log-row-collapsed';
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var LOG_ROW_EXPANDED_CLASSNAME = 'logs-view-log-row-expanded';
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var LOG_CELL_TEXT_CLASSNAME = 'logs-view-log-cell-text';
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var LOG_CELL_LOG_CLASSNAME = 'logs-view-log-cell-log';
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var LOG_TABLE_BUTTON_COLUMN_CLASSNAME = 'logs-view-log-table-button-column';
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var LOG_BUTTON_CLASSNAME = 'logs-view-log-button';
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We inherit from DivView.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var superClass = DivView;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * @constructor
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function LogsView() {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assertFirstConstructorCall(LogsView);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Call superclass's constructor.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    superClass.call(this, LogsView.MAIN_BOX_ID);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var tableDiv = $(LogsView.TABLE_ID);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.rows = [];
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.populateTable(tableDiv, LOG_FILTER_LIST);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    $(LogsView.GLOBAL_SHOW_BUTTON_ID).addEventListener('click',
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.onGlobalChangeVisibleClick_.bind(this, true));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    $(LogsView.GLOBAL_HIDE_BUTTON_ID).addEventListener('click',
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.onGlobalChangeVisibleClick_.bind(this, false));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    $(LogsView.REFRESH_LOGS_BUTTON_ID).addEventListener('click',
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.onLogsRefresh_.bind(this));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LogsView.TAB_ID = 'tab-handle-logs';
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LogsView.TAB_NAME = 'Logs';
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LogsView.TAB_HASH = '#logs';
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IDs for special HTML elements in logs_view.html
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogsView.MAIN_BOX_ID = 'logs-view-tab-content';
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogsView.TABLE_ID = 'logs-view-log-table';
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogsView.GLOBAL_SHOW_BUTTON_ID = 'logs-view-global-show-btn';
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogsView.GLOBAL_HIDE_BUTTON_ID = 'logs-view-global-hide-btn';
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogsView.REFRESH_LOGS_BUTTON_ID = 'logs-view-refresh-btn';
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cr.addSingletonGetter(LogsView);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * Contains log keys we are interested in.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var LOG_FILTER_LIST = [
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key: 'syslog',
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key: 'ui_log',
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key: 'chrome_system_log',
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key: 'chrome_log',
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ];
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogsView.prototype = {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Inherit the superclass's methods.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __proto__: superClass.prototype,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Called during View's initialization. Creates the row of a table logs will
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * be shown in. Each row has 4 cells.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * First cell's content will be set to |logKey|, second will contain a
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * button that will be used to show or hide third cell, which will contain
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the filtered log.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * |logKey| also tells us which log we are getting data from.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    createTableRow: function(logKey) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var row = document.createElement('tr');
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var cells = [];
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (var i = 0; i < 3; i++) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var rowCell = document.createElement('td');
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cells.push(rowCell);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        row.appendChild(rowCell);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Log key cell.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cells[0].className = LOG_CELL_TEXT_CLASSNAME;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cells[0].textContent = logKey;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Cell log is displayed in. Log content is in div element that is
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // initially hidden and empty.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cells[2].className = LOG_CELL_TEXT_CLASSNAME;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var logDiv = document.createElement('div');
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logDiv.textContent = '';
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logDiv.className = LOG_CELL_LOG_CLASSNAME;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logDiv.id = 'logs-view.log-cell.' + this.rows.length;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cells[2].appendChild(logDiv);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Button that we use to show or hide div element with log content. Logs
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // are not visible initially, so we initialize button accordingly.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var expandButton = document.createElement('button');
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expandButton.textContent = 'Show...';
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expandButton.className = LOG_BUTTON_CLASSNAME;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expandButton.addEventListener('click',
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    this.onButtonClicked_.bind(this, row));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Cell that contains show/hide button.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cells[1].appendChild(expandButton);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cells[1].className = LOG_TABLE_BUTTON_COLUMN_CLASSNAME;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Initially, log is not visible.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      row.className = LOG_ROW_COLLAPSED_CLASSNAME;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We will need those to process row buttons' onclick events.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      row.logKey = logKey;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      row.expandButton = expandButton;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      row.logDiv = logDiv;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      row.logVisible = false;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.rows.push(row);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return row;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Initializes |tableDiv| to represent data from |logList| which should be
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * of type LOG_FILTER_LIST.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    populateTable: function(tableDiv, logList) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (var i = 0; i < logList.length; i++) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var logSource = this.createTableRow(logList[i].key);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tableDiv.appendChild(logSource);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Processes clicks on buttons that show or hide log contents in log row.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Row containing the clicked button is given to the method since it
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * contains all data we need to process the click (unlike button object
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * itself).
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    onButtonClicked_: function(containingRow) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!containingRow.logVisible) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        containingRow.className = LOG_ROW_EXPANDED_CLASSNAME;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        containingRow.expandButton.textContent = 'Hide...';
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var logDiv = containingRow.logDiv;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (logDiv.textContent == '') {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          logDiv.textContent = 'Getting logs...';
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Callback will be executed by g_browser.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          g_browser.getSystemLog(containingRow.logKey,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 containingRow.logDiv.id);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        containingRow.className = LOG_ROW_COLLAPSED_CLASSNAME;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        containingRow.expandButton.textContent = 'Show...';
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      containingRow.logVisible = !containingRow.logVisible;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Processes click on one of the buttons that are used to show or hide all
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * logs we care about.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    onGlobalChangeVisibleClick_: function(isShowAll) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (var row in this.rows) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (isShowAll != this.rows[row].logVisible) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          this.onButtonClicked_(this.rows[row]);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Processes click event on the button we use to refresh fetched logs. We
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * get the newest logs from libcros, and refresh content of the visible log
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * cells.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    onLogsRefresh_: function() {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_browser.refreshSystemLogs();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var visibleLogRows = [];
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var hiddenLogRows = [];
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (var row in this.rows) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (this.rows[row].logVisible) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          visibleLogRows.push(this.rows[row]);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          hiddenLogRows.push(this.rows[row]);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We have to refresh text content in visible rows.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (row in visibleLogRows) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        visibleLogRows[row].logDiv.textContent = 'Getting logs...';
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        g_browser.getSystemLog(visibleLogRows[row].logKey,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               visibleLogRows[row].logDiv.id);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // In hidden rows we just clear potential log text, so we know we have to
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // get new contents when we show the row next time.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (row in hiddenLogRows) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hiddenLogRows[row].logDiv.textContent = '';
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return LogsView;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)})();
216