Updated drag and drop thumbnails.
[chromium-blink-merge.git] / chrome / browser / resources / net_internals / source_row.js
blob5bacea6b2c35e63287415c7ffca9d3f8508cc520
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() {
6 'use strict';
8 /**
9 * A SourceRow represents the row corresponding to a single SourceEntry
10 * displayed by the EventsView.
12 * @constructor
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();
31 this.createRow_();
32 this.onSourceUpdated();
35 SourceRow.prototype = {
36 createRow_: function() {
37 // Create a row.
38 var tr = addNode(this.parentView_.tableBody_, 'tr');
39 tr._id = this.getSourceId();
40 tr.style.display = 'none';
41 this.row_ = tr;
43 var selectionCol = addNode(tr, 'td');
44 var checkbox = addNode(selectionCol, 'input');
45 selectionCol.style.borderLeft = '0';
46 checkbox.type = 'checkbox';
48 var idCell = addNode(tr, 'td');
49 idCell.style.textAlign = 'right';
51 var typeCell = addNode(tr, 'td');
52 var descriptionCell = addNode(tr, 'td');
53 this.descriptionCell_ = descriptionCell;
55 // Connect listeners.
56 checkbox.onchange = this.onCheckboxToggled_.bind(this);
58 var onclick = this.onClicked_.bind(this);
59 idCell.onclick = onclick;
60 typeCell.onclick = onclick;
61 descriptionCell.onclick = onclick;
63 tr.onmouseover = this.onMouseover_.bind(this);
64 tr.onmouseout = this.onMouseout_.bind(this);
66 // Set the cell values to match this source's data.
67 if (this.getSourceId() >= 0) {
68 addTextNode(idCell, this.getSourceId());
69 } else {
70 addTextNode(idCell, '-');
72 var sourceTypeString = this.sourceEntry_.getSourceTypeString();
73 addTextNode(typeCell, sourceTypeString);
74 this.updateDescription_();
76 // Add a CSS classname specific to this source type (so CSS can specify
77 // different stylings for different types).
78 var sourceTypeClass = sourceTypeString.toLowerCase().replace(/_/g, '-');
79 this.row_.classList.add('source-' + sourceTypeClass);
81 this.updateClass_();
84 onSourceUpdated: function() {
85 if (this.sourceEntry_.isInactive() != this.isInactive_ ||
86 this.sourceEntry_.isError() != this.isError_) {
87 this.updateClass_();
90 if (this.description_ != this.sourceEntry_.getDescription())
91 this.updateDescription_();
93 // Update filters.
94 var matchesFilter = this.matchesFilter(this.parentView_.currentFilter_);
95 this.setIsMatchedByFilter(matchesFilter);
98 /**
99 * Changes |row_|'s class based on currently set flags. Clears any previous
100 * class set by this method. This method is needed so that some styles
101 * override others.
103 updateClass_: function() {
104 this.isInactive_ = this.sourceEntry_.isInactive();
105 this.isError_ = this.sourceEntry_.isError();
107 // Each element of this list contains a property of |this| and the
108 // corresponding class name to set if that property is true. Entries
109 // earlier in the list take precedence.
110 var propertyNames = [
111 ['isSelected_', 'selected'],
112 ['isMouseOver_', 'mouseover'],
113 ['isError_', 'error'],
114 ['isInactive_', 'inactive'],
117 // Loop through |propertyNames| in order, checking if each property
118 // is true. For the first such property found, if any, add the
119 // corresponding class to the SourceEntry's row. Remove classes
120 // that correspond to any other property.
121 var noStyleSet = true;
122 for (var i = 0; i < propertyNames.length; ++i) {
123 var setStyle = noStyleSet && this[propertyNames[i][0]];
124 if (setStyle) {
125 this.row_.classList.add(propertyNames[i][1]);
126 noStyleSet = false;
127 } else {
128 this.row_.classList.remove(propertyNames[i][1]);
133 getSourceEntry: function() {
134 return this.sourceEntry_;
137 setIsMatchedByFilter: function(isMatchedByFilter) {
138 if (this.isMatchedByFilter() == isMatchedByFilter)
139 return; // No change.
141 this.isMatchedByFilter_ = isMatchedByFilter;
143 this.setFilterStyles(isMatchedByFilter);
145 if (isMatchedByFilter) {
146 this.parentView_.incrementPostfilterCount(1);
147 } else {
148 this.parentView_.incrementPostfilterCount(-1);
149 // If we are filtering an entry away, make sure it is no longer
150 // part of the selection.
151 this.setSelected(false);
155 isMatchedByFilter: function() {
156 return this.isMatchedByFilter_;
159 setFilterStyles: function(isMatchedByFilter) {
160 // Hide rows which have been filtered away.
161 if (isMatchedByFilter) {
162 this.row_.style.display = '';
163 } else {
164 this.row_.style.display = 'none';
168 matchesFilter: function(filter) {
169 if (filter.isActive && this.isInactive_)
170 return false;
171 if (filter.isInactive && !this.isInactive_)
172 return false;
173 if (filter.isError && !this.isError_)
174 return false;
175 if (filter.isNotError && this.isError_)
176 return false;
178 // Check source type, if needed.
179 if (filter.type) {
180 var i;
181 var sourceType = this.sourceEntry_.getSourceTypeString().toLowerCase();
182 for (i = 0; i < filter.type.length; ++i) {
183 if (sourceType.search(filter.type[i]) != -1)
184 break;
186 if (i == filter.type.length)
187 return false;
190 // Check source ID, if needed.
191 if (filter.id) {
192 if (filter.id.indexOf(this.getSourceId() + '') == -1)
193 return false;
196 if (filter.text == '')
197 return true;
199 // The description is not always contained in one of the log entries.
200 if (this.description_.toLowerCase().indexOf(filter.text) != -1)
201 return true;
203 // Allow specifying source types by name.
204 var sourceType = this.sourceEntry_.getSourceTypeString();
205 if (sourceType.toLowerCase().indexOf(filter.text) != -1)
206 return true;
208 return searchLogEntriesForText(
209 filter.text,
210 this.sourceEntry_.getLogEntries(),
211 SourceTracker.getInstance().getPrivacyStripping());
214 isSelected: function() {
215 return this.isSelected_;
218 setSelected: function(isSelected) {
219 if (isSelected == this.isSelected())
220 return;
222 this.isSelected_ = isSelected;
224 this.setSelectedStyles(isSelected);
225 this.parentView_.modifySelectionArray(this.getSourceId(), isSelected);
226 this.parentView_.onSelectionChanged();
229 setSelectedStyles: function(isSelected) {
230 this.isSelected_ = isSelected;
231 this.getSelectionCheckbox().checked = isSelected;
232 this.updateClass_();
235 setMouseoverStyle: function(isMouseOver) {
236 this.isMouseOver_ = isMouseOver;
237 this.updateClass_();
240 onClicked_: function() {
241 this.parentView_.clearSelection();
242 this.setSelected(true);
243 if (this.isSelected())
244 this.parentView_.scrollToSourceId(this.getSourceId());
247 onMouseover_: function() {
248 this.setMouseoverStyle(true);
251 onMouseout_: function() {
252 this.setMouseoverStyle(false);
255 updateDescription_: function() {
256 this.description_ = this.sourceEntry_.getDescription();
257 this.descriptionCell_.innerHTML = '';
258 addTextNode(this.descriptionCell_, this.description_);
261 onCheckboxToggled_: function() {
262 this.setSelected(this.getSelectionCheckbox().checked);
263 if (this.isSelected())
264 this.parentView_.scrollToSourceId(this.getSourceId());
267 getSelectionCheckbox: function() {
268 return this.row_.childNodes[0].firstChild;
271 getSourceId: function() {
272 return this.sourceEntry_.getSourceId();
276 * Returns source ID of the entry whose row is currently above this one's.
277 * Returns null if no such node exists.
279 getPreviousNodeSourceId: function() {
280 var prevNode = this.row_.previousSibling;
281 if (prevNode == null)
282 return null;
283 return prevNode._id;
287 * Returns source ID of the entry whose row is currently below this one's.
288 * Returns null if no such node exists.
290 getNextNodeSourceId: function() {
291 var nextNode = this.row_.nextSibling;
292 if (nextNode == null)
293 return null;
294 return nextNode._id;
298 * Moves current object's row before |entry|'s row.
300 moveBefore: function(entry) {
301 this.row_.parentNode.insertBefore(this.row_, entry.row_);
305 * Moves current object's row after |entry|'s row.
307 moveAfter: function(entry) {
308 this.row_.parentNode.insertBefore(this.row_, entry.row_.nextSibling);
312 return SourceRow;
313 })();