Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/network/JSONView.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/network/JSONView.js b/third_party/WebKit/Source/devtools/front_end/network/JSONView.js |
| index 20f9c5c9f6119dbb3a6ca78d7cac365e74b2332a..d9d3fc9d76c13d968e005fd6e754dfd79fbeca29 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/network/JSONView.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/network/JSONView.js |
| @@ -31,6 +31,7 @@ |
| /** |
| * @constructor |
| * @extends {WebInspector.VBox} |
| + * @implements {WebInspector.Searchable} |
| * @param {!WebInspector.ParsedJSON} parsedJSON |
| */ |
| WebInspector.JSONView = function(parsedJSON) |
| @@ -38,6 +39,32 @@ WebInspector.JSONView = function(parsedJSON) |
| WebInspector.VBox.call(this); |
| this._parsedJSON = parsedJSON; |
| this.element.classList.add("json-view"); |
| + |
| + /** @type {?WebInspector.SearchableView} */ |
| + this._searchableView; |
| + /** @type {!WebInspector.ObjectPropertiesSection} */ |
| + this._section; |
| + /** @type {number} */ |
| + this._currentSearchFocusIndex = -1; |
| + /** @type {!Array.<!TreeElement>} */ |
| + this._currentSearchTreeElements = []; |
| + /** @type {?RegExp} */ |
| + 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.
|
| +} |
| + |
| +/** |
| + * @param {!WebInspector.ParsedJSON} parsedJSON |
| + * @return {!WebInspector.SearchableView} |
| + */ |
| +WebInspector.JSONView.createSearchableView = function(parsedJSON) |
| +{ |
| + var jsonView = new WebInspector.JSONView(parsedJSON); |
| + var searchableView = new WebInspector.SearchableView(jsonView); |
| + searchableView.setPlaceholder(WebInspector.UIString("Find")); |
| + jsonView.setSearchableView(searchableView); |
| + jsonView.show(searchableView.element); |
| + jsonView.element.setAttribute("tabIndex", 0); |
| + return searchableView; |
| } |
| /** |
| @@ -121,6 +148,14 @@ WebInspector.JSONView._findBrackets = function(text, open, close) |
| } |
| WebInspector.JSONView.prototype = { |
| + /** |
| + * @param {?WebInspector.SearchableView} view |
| + */ |
| + setSearchableView: function(view) |
| + { |
| + this._searchableView = view; |
| + }, |
| + |
| wasShown: function() |
| { |
| this._initialize(); |
| @@ -134,10 +169,164 @@ WebInspector.JSONView.prototype = { |
| var obj = WebInspector.RemoteObject.fromLocalObject(this._parsedJSON.data); |
| var title = this._parsedJSON.prefix + obj.description + this._parsedJSON.suffix; |
| - var section = new WebInspector.ObjectPropertiesSection(obj, title); |
| - section.setEditable(false); |
| - section.expand(); |
| - this.element.appendChild(section.element); |
| + this._section = new WebInspector.ObjectPropertiesSection(obj, title); |
| + this._section.setEditable(false); |
| + this._section.expand(); |
| + this.element.appendChild(this._section.element); |
| + }, |
| + |
| + /** |
| + * @param {number} index |
| + */ |
| + _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
|
| + { |
| + if (!this._searchRegEx) |
| + return; |
| + var previousIndex = this._currentSearchFocusIndex; |
|
lushnikov
2016/04/26 19:22:03
no need for the variable
allada
2016/04/27 21:19:57
Done.
|
| + var newFocusElement = this._currentSearchTreeElements[index]; |
| + var previousFocusElement = this._currentSearchTreeElements[previousIndex]; |
| + |
| + if (!newFocusElement) |
| + index = -1; |
| + |
| + if (previousFocusElement) |
| + previousFocusElement.setSearchRegex(this._searchRegEx); |
| + |
| + if (newFocusElement) { |
| + newFocusElement.setSearchRegex(this._searchRegEx, WebInspector.highlightedCurrentSearchResultClassName); |
| + newFocusElement.reveal(); |
| + } |
| + this._updateSearchIndex(index); |
| + }, |
| + |
| + /** |
| + * @param {number} count |
| + */ |
| + _updateSearchCount: function(count) |
| + { |
| + if (!this._searchableView) |
| + return; |
| + this._searchableView.updateSearchMatchesCount(count); |
| + }, |
| + |
| + /** |
| + * @param {number} index |
| + */ |
| + _updateSearchIndex: function(index) |
| + { |
| + this._currentSearchFocusIndex = index; |
| + if (!this._searchableView) |
| + return; |
| + this._searchableView.updateCurrentMatchIndex(index); |
| + }, |
| + |
| + /** |
| + * @override |
| + */ |
| + searchCanceled: function() |
| + { |
| + var newIndex = -1; |
| + this._searchRegEx = null; |
| + this._currentSearchTreeElements = []; |
| + var currentElement = this._section.rootElement(); |
| + |
| + while (currentElement) { |
| + if (currentElement instanceof WebInspector.ObjectPropertyTreeElement) |
| + currentElement.revertHighlightChanges(); |
| + currentElement = currentElement.traverseNextTreeElement(false); |
| + } |
| + this._updateSearchCount(0); |
| + this._updateSearchIndex(newIndex); |
| + }, |
| + |
| + /** |
| + * @override |
| + * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| + * @param {boolean} shouldJump |
| + * @param {boolean=} jumpBackwards |
| + */ |
| + performSearch: function(searchConfig, shouldJump, jumpBackwards) |
| + { |
| + var query = searchConfig.query; |
| + var newIndex = this._currentSearchFocusIndex; |
| + var previousFocusElement = this._currentSearchTreeElements[newIndex]; |
| + this.searchCanceled(); |
| + this._searchRegEx = searchConfig.toSearchRegex(true); |
| + |
| + var currentElement = this._section.rootElement(); |
| + |
| + 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.
|
| + |
| + while (currentElement) { |
| + if (currentElement instanceof WebInspector.ObjectPropertyTreeElement) { |
| + 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
|
| + if (hasMatch) |
| + this._currentSearchTreeElements.push(currentElement); |
| + if (previousFocusElement === currentElement) |
| + focusNextSearchResult = true; |
| + 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.
|
| + focusNextSearchResult = false; |
| + if (jumpBackwards) |
| + newIndex = this._currentSearchTreeElements.length - 1; |
| + else |
| + // -2 because it will +1 inside jumpToNextSearchResult() below |
| + newIndex = this._currentSearchTreeElements.length - 2; |
| + } |
| + } |
| + currentElement = currentElement.traverseNextTreeElement(false); |
| + } |
| + this._currentSearchFocusIndex = newIndex; |
| + this._updateSearchCount(this._currentSearchTreeElements.length); |
| + if (jumpBackwards) |
| + this.jumpToPreviousSearchResult(); |
| + else |
| + this.jumpToNextSearchResult(); |
| + }, |
| + |
| + /** |
| + * @override |
| + */ |
| + jumpToNextSearchResult: function() |
| + { |
| + if (!this._currentSearchTreeElements.length) |
| + return; |
| + |
| + var currentIndex = this._currentSearchFocusIndex; |
|
lushnikov
2016/04/26 19:22:03
var newIndex = mod(this._currentSearchFocusIndex +
allada
2016/04/27 21:19:57
Done.
|
| + if (currentIndex + 1 >= this._currentSearchTreeElements.length) |
| + currentIndex = -1; |
| + this._jumpToMatch(currentIndex + 1); |
| + }, |
| + |
| + /** |
| + * @override |
| + */ |
| + jumpToPreviousSearchResult: function() |
| + { |
| + if (!this._currentSearchTreeElements.length) |
| + return; |
| + var currentIndex = this._currentSearchFocusIndex; |
|
lushnikov
2016/04/26 19:22:03
var newIndex = mod(this._currentSearchFocusIndex -
allada
2016/04/27 21:19:57
Done.
|
| + if (currentIndex <= 0) |
| + currentIndex = this._currentSearchTreeElements.length; |
| + |
| + this._jumpToMatch(currentIndex - 1); |
| + }, |
| + |
| + /** |
| + * @override |
| + * @return {boolean} |
| + */ |
| + supportsCaseSensitiveSearch: function() |
| + { |
| + return true; |
| + }, |
| + |
| + /** |
| + * @override |
| + * @return {boolean} |
| + */ |
| + supportsRegexSearch: function() |
| + { |
| + return true; |
| }, |
| __proto__: WebInspector.VBox.prototype |