| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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. | |
| 4 | |
| 5 /** | |
| 6 * A SourceRow represents the row corresponding to a single SourceEntry | |
| 7 * displayed by the EventsView. | |
| 8 * | |
| 9 * @constructor | |
| 10 */ | |
| 11 function SourceRow(parentView, sourceEntry) { | |
| 12 this.parentView_ = parentView; | |
| 13 | |
| 14 this.sourceEntry_ = sourceEntry; | |
| 15 this.isSelected_ = false; | |
| 16 this.isMatchedByFilter_ = false; | |
| 17 | |
| 18 // Used to set CSS class for display. Must only be modified by calling | |
| 19 // corresponding set functions. | |
| 20 this.isSelected_ = false; | |
| 21 this.isMouseOver_ = false; | |
| 22 | |
| 23 // Mirror sourceEntry's values, so we only update the DOM when necessary. | |
| 24 this.isError_ = sourceEntry.isError(); | |
| 25 this.isInactive_ = sourceEntry.isInactive(); | |
| 26 this.description_ = sourceEntry.getDescription(); | |
| 27 | |
| 28 this.createRow_(); | |
| 29 this.onSourceUpdated(); | |
| 30 } | |
| 31 | |
| 32 SourceRow.prototype.createRow_ = function() { | |
| 33 // Create a row. | |
| 34 var tr = addNode(this.parentView_.tableBody_, 'tr'); | |
| 35 tr._id = this.sourceEntry_.getSourceId(); | |
| 36 tr.style.display = 'none'; | |
| 37 this.row_ = tr; | |
| 38 | |
| 39 var selectionCol = addNode(tr, 'td'); | |
| 40 var checkbox = addNode(selectionCol, 'input'); | |
| 41 checkbox.type = 'checkbox'; | |
| 42 | |
| 43 var idCell = addNode(tr, 'td'); | |
| 44 idCell.style.textAlign = 'right'; | |
| 45 | |
| 46 var typeCell = addNode(tr, 'td'); | |
| 47 var descriptionCell = addNode(tr, 'td'); | |
| 48 this.descriptionCell_ = descriptionCell; | |
| 49 | |
| 50 // Connect listeners. | |
| 51 checkbox.onchange = this.onCheckboxToggled_.bind(this); | |
| 52 | |
| 53 var onclick = this.onClicked_.bind(this); | |
| 54 idCell.onclick = onclick; | |
| 55 typeCell.onclick = onclick; | |
| 56 descriptionCell.onclick = onclick; | |
| 57 | |
| 58 tr.onmouseover = this.onMouseover_.bind(this); | |
| 59 tr.onmouseout = this.onMouseout_.bind(this); | |
| 60 | |
| 61 // Set the cell values to match this source's data. | |
| 62 if (this.sourceEntry_.getSourceId() >= 0) { | |
| 63 addTextNode(idCell, this.sourceEntry_.getSourceId()); | |
| 64 } else { | |
| 65 addTextNode(idCell, '-'); | |
| 66 } | |
| 67 var sourceTypeString = this.sourceEntry_.getSourceTypeString(); | |
| 68 addTextNode(typeCell, sourceTypeString); | |
| 69 this.updateDescription_(); | |
| 70 | |
| 71 // Add a CSS classname specific to this source type (so CSS can specify | |
| 72 // different stylings for different types). | |
| 73 changeClassName(this.row_, 'source_' + sourceTypeString, true); | |
| 74 | |
| 75 this.updateClass_(); | |
| 76 }; | |
| 77 | |
| 78 SourceRow.prototype.onSourceUpdated = function() { | |
| 79 if (this.sourceEntry_.isInactive() != this.isInactive_ || | |
| 80 this.sourceEntry_.isError() != this.isError_) { | |
| 81 this.updateClass_(); | |
| 82 } | |
| 83 | |
| 84 if (this.description_ != this.sourceEntry_.getDescription()) | |
| 85 this.updateDescription_(); | |
| 86 | |
| 87 // Update filters. | |
| 88 var matchesFilter = this.matchesFilter(this.parentView_.currentFilter_); | |
| 89 this.setIsMatchedByFilter(matchesFilter); | |
| 90 }; | |
| 91 | |
| 92 /** | |
| 93 * Changes |row_|'s class based on currently set flags. Clears any previous | |
| 94 * class set by this method. This method is needed so that some styles | |
| 95 * override others. | |
| 96 */ | |
| 97 SourceRow.prototype.updateClass_ = function() { | |
| 98 this.isInactive_ = this.sourceEntry_.isInactive(); | |
| 99 this.isError_ = this.sourceEntry_.isError(); | |
| 100 | |
| 101 // Each element of this list contains a property of |this| and the | |
| 102 // corresponding class name to set if that property is true. Entries earlier | |
| 103 // in the list take precedence. | |
| 104 var propertyNames = [ | |
| 105 ['isSelected_', 'selected'], | |
| 106 ['isMouseOver_', 'mouseover'], | |
| 107 ['isError_', 'error'], | |
| 108 ['isInactive_', 'inactive'], | |
| 109 ]; | |
| 110 | |
| 111 // Loop through |propertyNames| in order, checking if each property | |
| 112 // is true. For the first such property found, if any, add the | |
| 113 // corresponding class to the SourceEntry's row. Remove classes | |
| 114 // that correspond to any other property. | |
| 115 var noStyleSet = true; | |
| 116 for (var i = 0; i < propertyNames.length; ++i) { | |
| 117 var setStyle = noStyleSet && this[propertyNames[i][0]]; | |
| 118 changeClassName(this.row_, propertyNames[i][1], setStyle); | |
| 119 if (setStyle) | |
| 120 noStyleSet = false; | |
| 121 } | |
| 122 }; | |
| 123 | |
| 124 SourceRow.prototype.getSourceEntry = function() { | |
| 125 return this.sourceEntry_; | |
| 126 }; | |
| 127 | |
| 128 SourceRow.prototype.setIsMatchedByFilter = function(isMatchedByFilter) { | |
| 129 if (this.isMatchedByFilter() == isMatchedByFilter) | |
| 130 return; // No change. | |
| 131 | |
| 132 this.isMatchedByFilter_ = isMatchedByFilter; | |
| 133 | |
| 134 this.setFilterStyles(isMatchedByFilter); | |
| 135 | |
| 136 if (isMatchedByFilter) { | |
| 137 this.parentView_.incrementPostfilterCount(1); | |
| 138 } else { | |
| 139 this.parentView_.incrementPostfilterCount(-1); | |
| 140 // If we are filtering an entry away, make sure it is no longer | |
| 141 // part of the selection. | |
| 142 this.setSelected(false); | |
| 143 } | |
| 144 }; | |
| 145 | |
| 146 SourceRow.prototype.isMatchedByFilter = function() { | |
| 147 return this.isMatchedByFilter_; | |
| 148 }; | |
| 149 | |
| 150 SourceRow.prototype.setFilterStyles = function(isMatchedByFilter) { | |
| 151 // Hide rows which have been filtered away. | |
| 152 if (isMatchedByFilter) { | |
| 153 this.row_.style.display = ''; | |
| 154 } else { | |
| 155 this.row_.style.display = 'none'; | |
| 156 } | |
| 157 }; | |
| 158 | |
| 159 SourceRow.prototype.matchesFilter = function(filter) { | |
| 160 if (filter.isActive && this.isInactive_) | |
| 161 return false; | |
| 162 if (filter.isInactive && !this.isInactive_) | |
| 163 return false; | |
| 164 if (filter.isError && !this.isError_) | |
| 165 return false; | |
| 166 if (filter.isNotError && this.isError_) | |
| 167 return false; | |
| 168 | |
| 169 // Check source type, if needed. | |
| 170 if (filter.type) { | |
| 171 var sourceType = this.sourceEntry_.getSourceTypeString().toLowerCase(); | |
| 172 if (filter.type.indexOf(sourceType) == -1) | |
| 173 return false; | |
| 174 } | |
| 175 | |
| 176 // Check source ID, if needed. | |
| 177 if (filter.id) { | |
| 178 if (filter.id.indexOf(this.sourceEntry_.getSourceId() + '') == -1) | |
| 179 return false; | |
| 180 } | |
| 181 | |
| 182 if (filter.text == '') | |
| 183 return true; | |
| 184 | |
| 185 var filterText = filter.text; | |
| 186 var entryText = this.sourceEntry_.PrintEntriesAsText().toLowerCase(); | |
| 187 | |
| 188 return entryText.indexOf(filterText) != -1; | |
| 189 }; | |
| 190 | |
| 191 SourceRow.prototype.isSelected = function() { | |
| 192 return this.isSelected_; | |
| 193 }; | |
| 194 | |
| 195 SourceRow.prototype.setSelected = function(isSelected) { | |
| 196 if (isSelected == this.isSelected()) | |
| 197 return; | |
| 198 | |
| 199 this.isSelected_ = isSelected; | |
| 200 | |
| 201 this.setSelectedStyles(isSelected); | |
| 202 this.parentView_.modifySelectionArray(this, isSelected); | |
| 203 this.parentView_.onSelectionChanged(); | |
| 204 }; | |
| 205 | |
| 206 SourceRow.prototype.setSelectedStyles = function(isSelected) { | |
| 207 this.isSelected_ = isSelected; | |
| 208 this.getSelectionCheckbox().checked = isSelected; | |
| 209 this.updateClass_(); | |
| 210 }; | |
| 211 | |
| 212 SourceRow.prototype.setMouseoverStyle = function(isMouseOver) { | |
| 213 this.isMouseOver_ = isMouseOver; | |
| 214 this.updateClass_(); | |
| 215 }; | |
| 216 | |
| 217 SourceRow.prototype.onClicked_ = function() { | |
| 218 this.parentView_.clearSelection(); | |
| 219 this.setSelected(true); | |
| 220 }; | |
| 221 | |
| 222 SourceRow.prototype.onMouseover_ = function() { | |
| 223 this.setMouseoverStyle(true); | |
| 224 }; | |
| 225 | |
| 226 SourceRow.prototype.onMouseout_ = function() { | |
| 227 this.setMouseoverStyle(false); | |
| 228 }; | |
| 229 | |
| 230 SourceRow.prototype.updateDescription_ = function() { | |
| 231 this.description_ = this.sourceEntry_.getDescription(); | |
| 232 this.descriptionCell_.innerHTML = ''; | |
| 233 addTextNode(this.descriptionCell_, this.description_); | |
| 234 }; | |
| 235 | |
| 236 SourceRow.prototype.onCheckboxToggled_ = function() { | |
| 237 this.setSelected(this.getSelectionCheckbox().checked); | |
| 238 }; | |
| 239 | |
| 240 SourceRow.prototype.getSelectionCheckbox = function() { | |
| 241 return this.row_.childNodes[0].firstChild; | |
| 242 }; | |
| 243 | |
| 244 /** | |
| 245 * Returns source ID of the entry whose row is currently above this one's. | |
| 246 * Returns null if no such node exists. | |
| 247 */ | |
| 248 SourceRow.prototype.getPreviousNodeSourceId = function() { | |
| 249 var prevNode = this.row_.previousSibling; | |
| 250 if (prevNode == null) | |
| 251 return null; | |
| 252 return prevNode._id; | |
| 253 }; | |
| 254 | |
| 255 /** | |
| 256 * Returns source ID of the entry whose row is currently below this one's. | |
| 257 * Returns null if no such node exists. | |
| 258 */ | |
| 259 SourceRow.prototype.getNextNodeSourceId = function() { | |
| 260 var nextNode = this.row_.nextSibling; | |
| 261 if (nextNode == null) | |
| 262 return null; | |
| 263 return nextNode._id; | |
| 264 }; | |
| 265 | |
| 266 /** | |
| 267 * Moves current object's row before |entry|'s row. | |
| 268 */ | |
| 269 SourceRow.prototype.moveBefore = function(entry) { | |
| 270 this.row_.parentNode.insertBefore(this.row_, entry.row_); | |
| 271 }; | |
| 272 | |
| 273 /** | |
| 274 * Moves current object's row after |entry|'s row. | |
| 275 */ | |
| 276 SourceRow.prototype.moveAfter = function(entry) { | |
| 277 this.row_.parentNode.insertBefore(this.row_, entry.row_.nextSibling); | |
| 278 }; | |
| 279 | |
| 280 SourceRow.prototype.remove = function() { | |
| 281 this.setSelected(false); | |
| 282 this.setIsMatchedByFilter(false); | |
| 283 this.row_.parentNode.removeChild(this.row_); | |
| 284 }; | |
| OLD | NEW |