1 // Copyright (c) 2012 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.
5 var SourceRow
= (function() {
9 * A SourceRow represents the row corresponding to a single SourceEntry
10 * displayed by the EventsView.
14 function SourceRow(parentView
, sourceEntry
) {
15 this.parentView_
= parentView
;
17 this.sourceEntry_
= sourceEntry
;
18 this.isSelected_
= false;
19 this.isMatchedByFilter_
= false;
21 // Used to set CSS class for display. Must only be modified by calling
22 // corresponding set functions.
23 this.isSelected_
= false;
24 this.isMouseOver_
= false;
26 // Mirror sourceEntry's values, so we only update the DOM when necessary.
27 this.isError_
= sourceEntry
.isError();
28 this.isInactive_
= sourceEntry
.isInactive();
29 this.description_
= sourceEntry
.getDescription();
32 this.onSourceUpdated();
35 SourceRow
.prototype = {
36 createRow_: function() {
38 var tr
= addNode(this.parentView_
.tableBody_
, 'tr');
39 tr
._id
= this.getSourceId();
40 tr
.style
.display
= 'none';
43 var selectionCol
= addNode(tr
, 'td');
44 var checkbox
= addNode(selectionCol
, 'input');
45 checkbox
.title
= this.getSourceId();
46 selectionCol
.style
.borderLeft
= '0';
47 checkbox
.type
= 'checkbox';
49 var idCell
= addNode(tr
, 'td');
50 idCell
.style
.textAlign
= 'right';
52 var typeCell
= addNode(tr
, 'td');
53 var descriptionCell
= addNode(tr
, 'td');
54 this.descriptionCell_
= descriptionCell
;
57 checkbox
.onchange
= this.onCheckboxToggled_
.bind(this);
59 var onclick
= this.onClicked_
.bind(this);
60 idCell
.onclick
= onclick
;
61 typeCell
.onclick
= onclick
;
62 descriptionCell
.onclick
= onclick
;
64 tr
.onmouseover
= this.onMouseover_
.bind(this);
65 tr
.onmouseout
= this.onMouseout_
.bind(this);
67 // Set the cell values to match this source's data.
68 if (this.getSourceId() >= 0) {
69 addTextNode(idCell
, this.getSourceId());
71 addTextNode(idCell
, '-');
73 var sourceTypeString
= this.sourceEntry_
.getSourceTypeString();
74 addTextNode(typeCell
, sourceTypeString
);
75 this.updateDescription_();
77 // Add a CSS classname specific to this source type (so CSS can specify
78 // different stylings for different types).
79 var sourceTypeClass
= sourceTypeString
.toLowerCase().replace(/_
/g
, '-');
80 this.row_
.classList
.add('source-' + sourceTypeClass
);
85 onSourceUpdated: function() {
86 if (this.sourceEntry_
.isInactive() != this.isInactive_
||
87 this.sourceEntry_
.isError() != this.isError_
) {
91 if (this.description_
!= this.sourceEntry_
.getDescription())
92 this.updateDescription_();
95 var matchesFilter
= this.parentView_
.currentFilter_(this.sourceEntry_
);
96 this.setIsMatchedByFilter(matchesFilter
);
100 * Changes |row_|'s class based on currently set flags. Clears any previous
101 * class set by this method. This method is needed so that some styles
104 updateClass_: function() {
105 this.isInactive_
= this.sourceEntry_
.isInactive();
106 this.isError_
= this.sourceEntry_
.isError();
108 // Each element of this list contains a property of |this| and the
109 // corresponding class name to set if that property is true. Entries
110 // earlier in the list take precedence.
111 var propertyNames
= [
112 ['isSelected_', 'selected'],
113 ['isMouseOver_', 'mouseover'],
114 ['isError_', 'error'],
115 ['isInactive_', 'inactive'],
118 // Loop through |propertyNames| in order, checking if each property
119 // is true. For the first such property found, if any, add the
120 // corresponding class to the SourceEntry's row. Remove classes
121 // that correspond to any other property.
122 var noStyleSet
= true;
123 for (var i
= 0; i
< propertyNames
.length
; ++i
) {
124 var setStyle
= noStyleSet
&& this[propertyNames
[i
][0]];
126 this.row_
.classList
.add(propertyNames
[i
][1]);
129 this.row_
.classList
.remove(propertyNames
[i
][1]);
134 getSourceEntry: function() {
135 return this.sourceEntry_
;
138 setIsMatchedByFilter: function(isMatchedByFilter
) {
139 if (this.isMatchedByFilter() == isMatchedByFilter
)
140 return; // No change.
142 this.isMatchedByFilter_
= isMatchedByFilter
;
144 this.setFilterStyles(isMatchedByFilter
);
146 if (isMatchedByFilter
) {
147 this.parentView_
.incrementPostfilterCount(1);
149 this.parentView_
.incrementPostfilterCount(-1);
150 // If we are filtering an entry away, make sure it is no longer
151 // part of the selection.
152 this.setSelected(false);
156 isMatchedByFilter: function() {
157 return this.isMatchedByFilter_
;
160 setFilterStyles: function(isMatchedByFilter
) {
161 // Hide rows which have been filtered away.
162 if (isMatchedByFilter
) {
163 this.row_
.style
.display
= '';
165 this.row_
.style
.display
= 'none';
169 isSelected: function() {
170 return this.isSelected_
;
173 setSelected: function(isSelected
) {
174 if (isSelected
== this.isSelected())
177 this.isSelected_
= isSelected
;
179 this.setSelectedStyles(isSelected
);
180 this.parentView_
.modifySelectionArray(this.getSourceId(), isSelected
);
181 this.parentView_
.onSelectionChanged();
184 setSelectedStyles: function(isSelected
) {
185 this.isSelected_
= isSelected
;
186 this.getSelectionCheckbox().checked
= isSelected
;
190 setMouseoverStyle: function(isMouseOver
) {
191 this.isMouseOver_
= isMouseOver
;
195 onClicked_: function() {
196 this.parentView_
.clearSelection();
197 this.setSelected(true);
198 if (this.isSelected())
199 this.parentView_
.scrollToSourceId(this.getSourceId());
202 onMouseover_: function() {
203 this.setMouseoverStyle(true);
206 onMouseout_: function() {
207 this.setMouseoverStyle(false);
210 updateDescription_: function() {
211 this.description_
= this.sourceEntry_
.getDescription();
212 this.descriptionCell_
.innerHTML
= '';
213 addTextNode(this.descriptionCell_
, this.description_
);
216 onCheckboxToggled_: function() {
217 this.setSelected(this.getSelectionCheckbox().checked
);
218 if (this.isSelected())
219 this.parentView_
.scrollToSourceId(this.getSourceId());
222 getSelectionCheckbox: function() {
223 return this.row_
.childNodes
[0].firstChild
;
226 getSourceId: function() {
227 return this.sourceEntry_
.getSourceId();
231 * Returns source ID of the entry whose row is currently above this one's.
232 * Returns null if no such node exists.
234 getPreviousNodeSourceId: function() {
235 var prevNode
= this.row_
.previousSibling
;
236 if (prevNode
== null)
242 * Returns source ID of the entry whose row is currently below this one's.
243 * Returns null if no such node exists.
245 getNextNodeSourceId: function() {
246 var nextNode
= this.row_
.nextSibling
;
247 if (nextNode
== null)
253 * Moves current object's row before |entry|'s row.
255 moveBefore: function(entry
) {
256 this.row_
.parentNode
.insertBefore(this.row_
, entry
.row_
);
260 * Moves current object's row after |entry|'s row.
262 moveAfter: function(entry
) {
263 this.row_
.parentNode
.insertBefore(this.row_
, entry
.row_
.nextSibling
);