Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 /** | 31 /** |
| 32 * @constructor | 32 * @constructor |
| 33 * @extends {WebInspector.VBox} | 33 * @extends {WebInspector.VBox} |
| 34 * @implements {WebInspector.Searchable} | |
| 34 * @param {!WebInspector.ParsedJSON} parsedJSON | 35 * @param {!WebInspector.ParsedJSON} parsedJSON |
| 35 */ | 36 */ |
| 36 WebInspector.JSONView = function(parsedJSON) | 37 WebInspector.JSONView = function(parsedJSON) |
| 37 { | 38 { |
| 38 WebInspector.VBox.call(this); | 39 WebInspector.VBox.call(this); |
| 39 this._parsedJSON = parsedJSON; | 40 this._parsedJSON = parsedJSON; |
| 40 this.element.classList.add("json-view"); | 41 this.element.classList.add("json-view"); |
| 42 | |
| 43 /** @type {?WebInspector.SearchableView} */ | |
| 44 this._searchableView; | |
| 45 /** @type {!WebInspector.ObjectPropertiesSection} */ | |
| 46 this._section; | |
| 47 /** @type {number} */ | |
| 48 this._currentSearchFocusIndex = -1; | |
| 49 /** @type {!Array.<!TreeElement>} */ | |
| 50 this._currentSearchTreeElements = []; | |
| 51 /** @type {?RegExp} */ | |
| 52 this._searchRegEx = null; | |
|
lushnikov
2016/04/26 19:22:03
search front_end/ for "RegEx\b": 4 occurrences
sea
allada
2016/04/27 21:19:57
Done.
| |
| 41 } | 53 } |
| 42 | 54 |
| 43 /** | 55 /** |
| 56 * @param {!WebInspector.ParsedJSON} parsedJSON | |
| 57 * @return {!WebInspector.SearchableView} | |
| 58 */ | |
| 59 WebInspector.JSONView.createSearchableView = function(parsedJSON) | |
| 60 { | |
| 61 var jsonView = new WebInspector.JSONView(parsedJSON); | |
| 62 var searchableView = new WebInspector.SearchableView(jsonView); | |
| 63 searchableView.setPlaceholder(WebInspector.UIString("Find")); | |
| 64 jsonView.setSearchableView(searchableView); | |
| 65 jsonView.show(searchableView.element); | |
| 66 jsonView.element.setAttribute("tabIndex", 0); | |
| 67 return searchableView; | |
| 68 } | |
| 69 | |
| 70 /** | |
| 44 * @param {?string} text | 71 * @param {?string} text |
| 45 * @return {!Promise<?WebInspector.ParsedJSON>} | 72 * @return {!Promise<?WebInspector.ParsedJSON>} |
| 46 */ | 73 */ |
| 47 WebInspector.JSONView.parseJSON = function(text) | 74 WebInspector.JSONView.parseJSON = function(text) |
| 48 { | 75 { |
| 49 var returnObj = null; | 76 var returnObj = null; |
| 50 if (text) | 77 if (text) |
| 51 returnObj = WebInspector.JSONView._extractJSON(/** @type {string} */ (te xt)); | 78 returnObj = WebInspector.JSONView._extractJSON(/** @type {string} */ (te xt)); |
| 52 if (!returnObj) | 79 if (!returnObj) |
| 53 return Promise.resolve(/** @type {?WebInspector.ParsedJSON} */ (null)); | 80 return Promise.resolve(/** @type {?WebInspector.ParsedJSON} */ (null)); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 { | 141 { |
| 115 var start = text.indexOf(open); | 142 var start = text.indexOf(open); |
| 116 var end = text.lastIndexOf(close); | 143 var end = text.lastIndexOf(close); |
| 117 var length = end - start - 1; | 144 var length = end - start - 1; |
| 118 if (start == -1 || end == -1 || end < start) | 145 if (start == -1 || end == -1 || end < start) |
| 119 length = -1; | 146 length = -1; |
| 120 return {start: start, end: end, length: length}; | 147 return {start: start, end: end, length: length}; |
| 121 } | 148 } |
| 122 | 149 |
| 123 WebInspector.JSONView.prototype = { | 150 WebInspector.JSONView.prototype = { |
| 151 /** | |
| 152 * @param {?WebInspector.SearchableView} view | |
| 153 */ | |
| 154 setSearchableView: function(view) | |
| 155 { | |
| 156 this._searchableView = view; | |
| 157 }, | |
| 158 | |
| 124 wasShown: function() | 159 wasShown: function() |
| 125 { | 160 { |
| 126 this._initialize(); | 161 this._initialize(); |
| 127 }, | 162 }, |
| 128 | 163 |
| 129 _initialize: function() | 164 _initialize: function() |
| 130 { | 165 { |
| 131 if (this._initialized) | 166 if (this._initialized) |
| 132 return; | 167 return; |
| 133 this._initialized = true; | 168 this._initialized = true; |
| 134 | 169 |
| 135 var obj = WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.dat a); | 170 var obj = WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.dat a); |
| 136 var title = this._parsedJSON.prefix + obj.description + this._parsedJSON .suffix; | 171 var title = this._parsedJSON.prefix + obj.description + this._parsedJSON .suffix; |
| 137 var section = new WebInspector.ObjectPropertiesSection(obj, title); | 172 this._section = new WebInspector.ObjectPropertiesSection(obj, title); |
| 138 section.setEditable(false); | 173 this._section.setEditable(false); |
| 139 section.expand(); | 174 this._section.expand(); |
| 140 this.element.appendChild(section.element); | 175 this.element.appendChild(this._section.element); |
| 176 }, | |
| 177 | |
| 178 /** | |
| 179 * @param {number} index | |
| 180 */ | |
| 181 _jumpToMatch: function(index) | |
|
lushnikov
2016/04/26 19:22:03
let's have a contract that _jumpToMatch always has
allada
2016/04/27 21:19:57
It needs to be able to be passed with -1 in order
| |
| 182 { | |
| 183 if (!this._searchRegEx) | |
| 184 return; | |
| 185 var previousIndex = this._currentSearchFocusIndex; | |
|
lushnikov
2016/04/26 19:22:03
no need for the variable
allada
2016/04/27 21:19:57
Done.
| |
| 186 var newFocusElement = this._currentSearchTreeElements[index]; | |
| 187 var previousFocusElement = this._currentSearchTreeElements[previousIndex ]; | |
| 188 | |
| 189 if (!newFocusElement) | |
| 190 index = -1; | |
| 191 | |
| 192 if (previousFocusElement) | |
| 193 previousFocusElement.setSearchRegex(this._searchRegEx); | |
| 194 | |
| 195 if (newFocusElement) { | |
| 196 newFocusElement.setSearchRegex(this._searchRegEx, WebInspector.highl ightedCurrentSearchResultClassName); | |
| 197 newFocusElement.reveal(); | |
| 198 } | |
| 199 this._updateSearchIndex(index); | |
| 200 }, | |
| 201 | |
| 202 /** | |
| 203 * @param {number} count | |
| 204 */ | |
| 205 _updateSearchCount: function(count) | |
| 206 { | |
| 207 if (!this._searchableView) | |
| 208 return; | |
| 209 this._searchableView.updateSearchMatchesCount(count); | |
| 210 }, | |
| 211 | |
| 212 /** | |
| 213 * @param {number} index | |
| 214 */ | |
| 215 _updateSearchIndex: function(index) | |
| 216 { | |
| 217 this._currentSearchFocusIndex = index; | |
| 218 if (!this._searchableView) | |
| 219 return; | |
| 220 this._searchableView.updateCurrentMatchIndex(index); | |
| 221 }, | |
| 222 | |
| 223 /** | |
| 224 * @override | |
| 225 */ | |
| 226 searchCanceled: function() | |
| 227 { | |
| 228 var newIndex = -1; | |
| 229 this._searchRegEx = null; | |
| 230 this._currentSearchTreeElements = []; | |
| 231 var currentElement = this._section.rootElement(); | |
| 232 | |
| 233 while (currentElement) { | |
| 234 if (currentElement instanceof WebInspector.ObjectPropertyTreeElement ) | |
| 235 currentElement.revertHighlightChanges(); | |
| 236 currentElement = currentElement.traverseNextTreeElement(false); | |
| 237 } | |
| 238 this._updateSearchCount(0); | |
| 239 this._updateSearchIndex(newIndex); | |
| 240 }, | |
| 241 | |
| 242 /** | |
| 243 * @override | |
| 244 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 245 * @param {boolean} shouldJump | |
| 246 * @param {boolean=} jumpBackwards | |
| 247 */ | |
| 248 performSearch: function(searchConfig, shouldJump, jumpBackwards) | |
| 249 { | |
| 250 var query = searchConfig.query; | |
| 251 var newIndex = this._currentSearchFocusIndex; | |
| 252 var previousFocusElement = this._currentSearchTreeElements[newIndex]; | |
| 253 this.searchCanceled(); | |
| 254 this._searchRegEx = searchConfig.toSearchRegex(true); | |
| 255 | |
| 256 var currentElement = this._section.rootElement(); | |
| 257 | |
| 258 var focusNextSearchResult = newIndex === -1 ? true : false; | |
|
lushnikov
2016/04/26 19:22:03
var focusNextSearchResult = newIndex === -1;
allada
2016/04/27 21:19:57
Done.
| |
| 259 | |
| 260 while (currentElement) { | |
| 261 if (currentElement instanceof WebInspector.ObjectPropertyTreeElement ) { | |
| 262 var hasMatch = currentElement.setSearchRegex(this._searchRegEx); | |
|
lushnikov
2016/04/26 19:22:03
how will it work if there are multiple matches in
allada
2016/04/27 21:19:57
It considers multiple matches in the same element
| |
| 263 if (hasMatch) | |
| 264 this._currentSearchTreeElements.push(currentElement); | |
| 265 if (previousFocusElement === currentElement) | |
| 266 focusNextSearchResult = true; | |
| 267 if (focusNextSearchResult && hasMatch) { | |
|
lushnikov
2016/04/26 19:22:03
Why do we need this? I don't follow this logic
allada
2016/04/27 21:19:57
It keeps track of the current highlighted node wit
allada
2016/05/05 23:01:34
Ignore this... No longer follows this logic.
| |
| 268 focusNextSearchResult = false; | |
| 269 if (jumpBackwards) | |
| 270 newIndex = this._currentSearchTreeElements.length - 1; | |
| 271 else | |
| 272 // -2 because it will +1 inside jumpToNextSearchResult() below | |
| 273 newIndex = this._currentSearchTreeElements.length - 2; | |
| 274 } | |
| 275 } | |
| 276 currentElement = currentElement.traverseNextTreeElement(false); | |
| 277 } | |
| 278 this._currentSearchFocusIndex = newIndex; | |
| 279 this._updateSearchCount(this._currentSearchTreeElements.length); | |
| 280 if (jumpBackwards) | |
| 281 this.jumpToPreviousSearchResult(); | |
| 282 else | |
| 283 this.jumpToNextSearchResult(); | |
| 284 }, | |
| 285 | |
| 286 /** | |
| 287 * @override | |
| 288 */ | |
| 289 jumpToNextSearchResult: function() | |
| 290 { | |
| 291 if (!this._currentSearchTreeElements.length) | |
| 292 return; | |
| 293 | |
| 294 var currentIndex = this._currentSearchFocusIndex; | |
|
lushnikov
2016/04/26 19:22:03
var newIndex = mod(this._currentSearchFocusIndex +
allada
2016/04/27 21:19:57
Done.
| |
| 295 if (currentIndex + 1 >= this._currentSearchTreeElements.length) | |
| 296 currentIndex = -1; | |
| 297 this._jumpToMatch(currentIndex + 1); | |
| 298 }, | |
| 299 | |
| 300 /** | |
| 301 * @override | |
| 302 */ | |
| 303 jumpToPreviousSearchResult: function() | |
| 304 { | |
| 305 if (!this._currentSearchTreeElements.length) | |
| 306 return; | |
| 307 var currentIndex = this._currentSearchFocusIndex; | |
|
lushnikov
2016/04/26 19:22:03
var newIndex = mod(this._currentSearchFocusIndex -
allada
2016/04/27 21:19:57
Done.
| |
| 308 if (currentIndex <= 0) | |
| 309 currentIndex = this._currentSearchTreeElements.length; | |
| 310 | |
| 311 this._jumpToMatch(currentIndex - 1); | |
| 312 }, | |
| 313 | |
| 314 /** | |
| 315 * @override | |
| 316 * @return {boolean} | |
| 317 */ | |
| 318 supportsCaseSensitiveSearch: function() | |
| 319 { | |
| 320 return true; | |
| 321 }, | |
| 322 | |
| 323 /** | |
| 324 * @override | |
| 325 * @return {boolean} | |
| 326 */ | |
| 327 supportsRegexSearch: function() | |
| 328 { | |
| 329 return true; | |
| 141 }, | 330 }, |
| 142 | 331 |
| 143 __proto__: WebInspector.VBox.prototype | 332 __proto__: WebInspector.VBox.prototype |
| 144 } | 333 } |
| 145 | 334 |
| 146 /** | 335 /** |
| 147 * @constructor | 336 * @constructor |
| 148 * @param {*} data | 337 * @param {*} data |
| 149 * @param {string} prefix | 338 * @param {string} prefix |
| 150 * @param {string} suffix | 339 * @param {string} suffix |
| 151 */ | 340 */ |
| 152 WebInspector.ParsedJSON = function(data, prefix, suffix) | 341 WebInspector.ParsedJSON = function(data, prefix, suffix) |
| 153 { | 342 { |
| 154 this.data = data; | 343 this.data = data; |
| 155 this.prefix = prefix; | 344 this.prefix = prefix; |
| 156 this.suffix = suffix; | 345 this.suffix = suffix; |
| 157 } | 346 } |
| OLD | NEW |