1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
// Copyright (c) 2012 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.
/**
* This view displays network related log data and is specific fo ChromeOS.
* We get log data from chrome by filtering system logs for network related
* keywords. Logs are not fetched until we actually need them.
*/
var LogsView = (function() {
'use strict';
// Special classes (defined in logs_view.css).
var LOG_ROW_COLLAPSED_CLASSNAME = 'logs-view-log-row-collapsed';
var LOG_ROW_EXPANDED_CLASSNAME = 'logs-view-log-row-expanded';
var LOG_CELL_TEXT_CLASSNAME = 'logs-view-log-cell-text';
var LOG_CELL_LOG_CLASSNAME = 'logs-view-log-cell-log';
var LOG_TABLE_BUTTON_COLUMN_CLASSNAME = 'logs-view-log-table-button-column';
var LOG_BUTTON_CLASSNAME = 'logs-view-log-button';
// We inherit from DivView.
var superClass = DivView;
/**
* @constructor
*/
function LogsView() {
assertFirstConstructorCall(LogsView);
// Call superclass's constructor.
superClass.call(this, LogsView.MAIN_BOX_ID);
var tableDiv = $(LogsView.TABLE_ID);
this.rows = [];
this.populateTable(tableDiv, LOG_FILTER_LIST);
$(LogsView.GLOBAL_SHOW_BUTTON_ID).addEventListener('click',
this.onGlobalChangeVisibleClick_.bind(this, true));
$(LogsView.GLOBAL_HIDE_BUTTON_ID).addEventListener('click',
this.onGlobalChangeVisibleClick_.bind(this, false));
$(LogsView.REFRESH_LOGS_BUTTON_ID).addEventListener('click',
this.onLogsRefresh_.bind(this));
}
LogsView.TAB_ID = 'tab-handle-logs';
LogsView.TAB_NAME = 'Logs';
LogsView.TAB_HASH = '#logs';
// IDs for special HTML elements in logs_view.html
LogsView.MAIN_BOX_ID = 'logs-view-tab-content';
LogsView.TABLE_ID = 'logs-view-log-table';
LogsView.GLOBAL_SHOW_BUTTON_ID = 'logs-view-global-show-btn';
LogsView.GLOBAL_HIDE_BUTTON_ID = 'logs-view-global-hide-btn';
LogsView.REFRESH_LOGS_BUTTON_ID = 'logs-view-refresh-btn';
cr.addSingletonGetter(LogsView);
/**
* Contains log keys we are interested in.
*/
var LOG_FILTER_LIST = [
{
key: 'syslog',
},
{
key: 'ui_log',
},
{
key: 'chrome_system_log',
},
{
key: 'chrome_log',
}
];
LogsView.prototype = {
// Inherit the superclass's methods.
__proto__: superClass.prototype,
/**
* Called during View's initialization. Creates the row of a table logs will
* be shown in. Each row has 4 cells.
*
* First cell's content will be set to |logKey|, second will contain a
* button that will be used to show or hide third cell, which will contain
* the filtered log.
* |logKey| also tells us which log we are getting data from.
*/
createTableRow: function(logKey) {
var row = document.createElement('tr');
var cells = [];
for (var i = 0; i < 3; i++) {
var rowCell = document.createElement('td');
cells.push(rowCell);
row.appendChild(rowCell);
}
// Log key cell.
cells[0].className = LOG_CELL_TEXT_CLASSNAME;
cells[0].textContent = logKey;
// Cell log is displayed in. Log content is in div element that is
// initially hidden and empty.
cells[2].className = LOG_CELL_TEXT_CLASSNAME;
var logDiv = document.createElement('div');
logDiv.textContent = '';
logDiv.className = LOG_CELL_LOG_CLASSNAME;
logDiv.id = 'logs-view.log-cell.' + this.rows.length;
cells[2].appendChild(logDiv);
// Button that we use to show or hide div element with log content. Logs
// are not visible initially, so we initialize button accordingly.
var expandButton = document.createElement('button');
expandButton.textContent = 'Show...';
expandButton.className = LOG_BUTTON_CLASSNAME;
expandButton.addEventListener('click',
this.onButtonClicked_.bind(this, row));
// Cell that contains show/hide button.
cells[1].appendChild(expandButton);
cells[1].className = LOG_TABLE_BUTTON_COLUMN_CLASSNAME;
// Initially, log is not visible.
row.className = LOG_ROW_COLLAPSED_CLASSNAME;
// We will need those to process row buttons' onclick events.
row.logKey = logKey;
row.expandButton = expandButton;
row.logDiv = logDiv;
row.logVisible = false;
this.rows.push(row);
return row;
},
/**
* Initializes |tableDiv| to represent data from |logList| which should be
* of type LOG_FILTER_LIST.
*/
populateTable: function(tableDiv, logList) {
for (var i = 0; i < logList.length; i++) {
var logSource = this.createTableRow(logList[i].key);
tableDiv.appendChild(logSource);
}
},
/**
* Processes clicks on buttons that show or hide log contents in log row.
* Row containing the clicked button is given to the method since it
* contains all data we need to process the click (unlike button object
* itself).
*/
onButtonClicked_: function(containingRow) {
if (!containingRow.logVisible) {
containingRow.className = LOG_ROW_EXPANDED_CLASSNAME;
containingRow.expandButton.textContent = 'Hide...';
var logDiv = containingRow.logDiv;
if (logDiv.textContent == '') {
logDiv.textContent = 'Getting logs...';
// Callback will be executed by g_browser.
g_browser.getSystemLog(containingRow.logKey,
containingRow.logDiv.id);
}
} else {
containingRow.className = LOG_ROW_COLLAPSED_CLASSNAME;
containingRow.expandButton.textContent = 'Show...';
}
containingRow.logVisible = !containingRow.logVisible;
},
/**
* Processes click on one of the buttons that are used to show or hide all
* logs we care about.
*/
onGlobalChangeVisibleClick_: function(isShowAll) {
for (var row in this.rows) {
if (isShowAll != this.rows[row].logVisible) {
this.onButtonClicked_(this.rows[row]);
}
}
},
/**
* Processes click event on the button we use to refresh fetched logs. We
* get the newest logs from libcros, and refresh content of the visible log
* cells.
*/
onLogsRefresh_: function() {
g_browser.refreshSystemLogs();
var visibleLogRows = [];
var hiddenLogRows = [];
for (var row in this.rows) {
if (this.rows[row].logVisible) {
visibleLogRows.push(this.rows[row]);
} else {
hiddenLogRows.push(this.rows[row]);
}
}
// We have to refresh text content in visible rows.
for (row in visibleLogRows) {
visibleLogRows[row].logDiv.textContent = 'Getting logs...';
g_browser.getSystemLog(visibleLogRows[row].logKey,
visibleLogRows[row].logDiv.id);
}
// In hidden rows we just clear potential log text, so we know we have to
// get new contents when we show the row next time.
for (row in hiddenLogRows) {
hiddenLogRows[row].logDiv.textContent = '';
}
}
};
return LogsView;
})();
|