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
|
// Copyright (c) 2010 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.
/**
* Each row in the filtered items list is backed by a SourceEntry. This
* instance contains all of the data pertaining to that row, and notifies
* its parent view (the RequestsView) whenever its data changes.
*
* @constructor
*/
function SourceEntry(parentView) {
this.entries_ = [];
this.parentView_ = parentView;
this.isSelected_ = false;
this.isMatchedByFilter_ = false;
}
SourceEntry.prototype.isSelected = function() {
return this.isSelected_;
};
SourceEntry.prototype.setSelectedStyles = function(isSelected) {
changeClassName(this.row_, 'selected', isSelected);
this.getSelectionCheckbox().checked = isSelected;
};
SourceEntry.prototype.setMouseoverStyle = function(isMouseOver) {
changeClassName(this.row_, 'mouseover', isMouseOver);
};
SourceEntry.prototype.setIsMatchedByFilter = function(isMatchedByFilter) {
if (this.isMatchedByFilter() == isMatchedByFilter)
return; // No change.
this.isMatchedByFilter_ = isMatchedByFilter;
this.setFilterStyles(isMatchedByFilter);
if (isMatchedByFilter) {
this.parentView_.incrementPostfilterCount(1);
} else {
this.parentView_.incrementPostfilterCount(-1);
// If we are filtering an entry away, make sure it is no longer
// part of the selection.
this.setSelected(false);
}
};
SourceEntry.prototype.isMatchedByFilter = function() {
return this.isMatchedByFilter_;
};
SourceEntry.prototype.setFilterStyles = function(isMatchedByFilter) {
// Hide rows which have been filtered away.
if (isMatchedByFilter) {
this.row_.style.display = '';
} else {
this.row_.style.display = 'none';
}
};
SourceEntry.prototype.update = function(logEntry) {
var prevStartEntry = this.getStartEntry_();
this.entries_.push(logEntry);
var curStartEntry = this.getStartEntry_();
// If we just got the first entry for this source.
if (!prevStartEntry && curStartEntry) {
this.createRow_();
// Only apply the filter during the first update.
// TODO(eroman): once filters use other data, apply it on each update.
var matchesFilter = this.matchesFilter(this.parentView_.currentFilter_);
this.setIsMatchedByFilter(matchesFilter);
}
};
SourceEntry.prototype.onCheckboxToggled_ = function() {
this.setSelected(this.getSelectionCheckbox().checked);
};
SourceEntry.prototype.matchesFilter = function(filterText) {
// TODO(eroman): Support more advanced filter syntax.
if (filterText == '')
return true;
var filterText = filterText.toLowerCase();
return this.getDescription().toLowerCase().indexOf(filterText) != -1 ||
this.getSourceTypeString().toLowerCase().indexOf(filterText) != -1;
};
SourceEntry.prototype.setSelected = function(isSelected) {
if (isSelected == this.isSelected())
return;
this.isSelected_ = isSelected;
this.setSelectedStyles(isSelected);
this.parentView_.modifySelectionArray(this, isSelected);
this.parentView_.onSelectionChanged();
};
SourceEntry.prototype.onClicked_ = function() {
this.parentView_.clearSelection();
this.setSelected(true);
};
SourceEntry.prototype.onMouseover_ = function() {
this.setMouseoverStyle(true);
};
SourceEntry.prototype.onMouseout_ = function() {
this.setMouseoverStyle(false);
};
SourceEntry.prototype.createRow_ = function() {
// Create a row.
var tr = addNode(this.parentView_.tableBody_, 'tr');
tr.style.display = 'none';
this.row_ = tr;
var selectionCol = addNode(tr, 'td');
var checkbox = addNode(selectionCol, 'input');
checkbox.type = 'checkbox';
var idCell = addNode(tr, 'td');
var typeCell = addNode(tr, 'td');
var descriptionCell = addNode(tr, 'td');
// Connect listeners.
checkbox.onchange = this.onCheckboxToggled_.bind(this);
var onclick = this.onClicked_.bind(this);
idCell.onclick = onclick;
typeCell.onclick = onclick;
descriptionCell.onclick = onclick;
tr.onmouseover = this.onMouseover_.bind(this);
tr.onmouseout = this.onMouseout_.bind(this);
// Set the cell values to match this source's data.
addTextNode(idCell, this.getSourceId());
var sourceTypeString = this.getSourceTypeString();
addTextNode(typeCell, sourceTypeString);
addTextNode(descriptionCell, this.getDescription());
// Add a CSS classname specific to this source type (so CSS can specify
// different stylings for different types).
changeClassName(this.row_, "source_" + sourceTypeString, true);
};
SourceEntry.prototype.getDescription = function() {
var e = this.getStartEntry_();
if (!e || e.params == undefined)
return '';
switch (e.source.type) {
case LogSourceType.URL_REQUEST:
case LogSourceType.SOCKET_STREAM:
return e.params.url;
case LogSourceType.CONNECT_JOB:
return e.params.group_name;
}
return '';
};
/**
* Returns the starting entry for this source. Conceptually this is the
* first entry that was logged to this source. However, we skip over the
* TYPE_REQUEST_ALIVE entries which wrap TYPE_URL_REQUEST_START /
* TYPE_SOCKET_STREAM_CONNECT.
*
* TODO(eroman): Get rid of TYPE_REQUEST_ALIVE so this isn't necessary.
*/
SourceEntry.prototype.getStartEntry_ = function() {
if (this.entries_.length < 1)
return undefined;
if (this.entries_[0].type != LogEventType.REQUEST_ALIVE)
return this.entries_[0];
if (this.entries_.length < 2)
return undefined;
return this.entries_[1];
};
SourceEntry.prototype.getLogEntries = function() {
return this.entries_;
};
SourceEntry.prototype.getSourceTypeString = function() {
return getKeyWithValue(LogSourceType, this.entries_[0].source.type);
};
SourceEntry.prototype.getSelectionCheckbox = function() {
return this.row_.childNodes[0].firstChild;
};
SourceEntry.prototype.getSourceId = function() {
return this.entries_[0].source.id;
};
SourceEntry.prototype.remove = function() {
this.setSelected(false);
this.setIsMatchedByFilter(false);
this.row_.parentNode.removeChild(this.row_);
};
|