Source/WebInspectorUI/ChangeLog

 12017-10-08 Joseph Pecoraro <pecoraro@apple.com>
 2
 3 Web Inspector: Network Tab - Search Headers Detail View
 4 https://bugs.webkit.org/show_bug.cgi?id=177981
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * UserInterface/Base/Main.js:
 9 * UserInterface/Views/LogContentView.js:
 10 (WI.LogContentView.prototype.performSearch):
 11 Rename "Dom" to "DOM" in utility function.
 12
 13 * UserInterface/Views/ResourceHeadersContentView.css:
 14 (.resource-headers.showing-find-banner .search-highlight):
 15 Search highlight styles.
 16
 17 * UserInterface/Views/ResourceHeadersContentView.js:
 18 (WI.ResourceHeadersContentView.prototype.get supportsSearch):
 19 (WI.ResourceHeadersContentView.prototype.get numberOfSearchResults):
 20 (WI.ResourceHeadersContentView.prototype.get hasPerformedSearch):
 21 (WI.ResourceHeadersContentView.prototype.set automaticallyRevealFirstSearchResult):
 22 (WI.ResourceHeadersContentView.prototype.performSearch):
 23 (WI.ResourceHeadersContentView.prototype.searchCleared):
 24 (WI.ResourceHeadersContentView.prototype.revealPreviousSearchResult):
 25 (WI.ResourceHeadersContentView.prototype.revealNextSearchResult):
 26 (WI.ResourceHeadersContentView.prototype._perfomSearchOnKeyValuePairs):
 27 (WI.ResourceHeadersContentView.prototype._revealSearchResult):
 28 Implement ContentView search behavior.
 29
1302017-10-06 Matt Baker <mattbaker@apple.com>
231
332 Web Inspector: Add Canvas tab and CanvasOverviewContentView

Source/WebInspectorUI/UserInterface/Base/Main.js

@@WI.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, c
25512551 return highlightNodes;
25522552};
25532553
2554 WI.revertDomChanges = function(domChanges)
 2554WI.revertDOMChanges = function(domChanges)
25552555{
25562556 for (var i = domChanges.length - 1; i >= 0; --i) {
25572557 var entry = domChanges[i];

Source/WebInspectorUI/UserInterface/Views/LogContentView.js

@@WI.LogContentView = class LogContentView extends WI.ContentView
950950 performSearch(searchQuery)
951951 {
952952 if (!isEmptyObject(this._searchHighlightDOMChanges))
953  WI.revertDomChanges(this._searchHighlightDOMChanges);
 953 WI.revertDOMChanges(this._searchHighlightDOMChanges);
954954
955955 this._currentSearchQuery = searchQuery;
956956 this._searchHighlightDOMChanges = [];

Source/WebInspectorUI/UserInterface/Views/ResourceHeadersContentView.css

@@body[dir=rtl] .resource-headers .details .pair {
7777 vertical-align: top;
7878 bottom: 1px;
7979}
 80
 81.resource-headers.showing-find-banner .search-highlight {
 82 color: black;
 83 background-color: hsla(53, 83%, 53%, 0.2);
 84 border-bottom: 1px solid hsl(47, 82%, 60%);
 85}

Source/WebInspectorUI/UserInterface/Views/ResourceHeadersContentView.js

@@WI.ResourceHeadersContentView = class ResourceHeadersContentView extends WI.Cont
3838
3939 this._delegate = delegate || null;
4040
 41 this._searchQuery = null;
 42 this._searchResults = null;
 43 this._searchDOMChanges = [];
 44 this._searchIndex = -1;
 45 this._automaticallyRevealFirstSearchResult = false;
 46 this._bouncyHighlightElement = null;
 47
4148 this.element.classList.add("resource-details", "resource-headers");
 49 this.element.tabIndex = 0;
4250
4351 this._needsSummaryRefresh = false;
4452 this._needsRequestHeadersRefresh = false;

@@WI.ResourceHeadersContentView = class ResourceHeadersContentView extends WI.Cont
109117 super.closed();
110118 }
111119
 120 get supportsSearch()
 121 {
 122 return true;
 123 }
 124
 125 get numberOfSearchResults()
 126 {
 127 return this._searchResults ? this._searchResults.length : null;
 128 }
 129
 130 get hasPerformedSearch()
 131 {
 132 return this._searchResults !== null;
 133 }
 134
 135 set automaticallyRevealFirstSearchResult(reveal)
 136 {
 137 this._automaticallyRevealFirstSearchResult = reveal;
 138
 139 // If we haven't shown a search result yet, reveal one now.
 140 if (this._automaticallyRevealFirstSearchResult && this.numberOfSearchResults > 0) {
 141 if (this._searchIndex === -1)
 142 this.revealNextSearchResult();
 143 }
 144 }
 145
 146 performSearch(query)
 147 {
 148 if (query === this._searchQuery)
 149 return;
 150
 151 WI.revertDOMChanges(this._searchDOMChanges);
 152
 153 this._searchQuery = query;
 154 this._searchResults = [];
 155 this._searchDOMChanges = [];
 156 this._searchIndex = -1;
 157
 158 this._perfomSearchOnKeyValuePairs();
 159
 160 this.dispatchEventToListeners(WI.ContentView.Event.NumberOfSearchResultsDidChange);
 161
 162 if (this._automaticallyRevealFirstSearchResult && this._searchResults.length > 0)
 163 this.revealNextSearchResult();
 164 }
 165
 166 searchCleared()
 167 {
 168 WI.revertDOMChanges(this._searchDOMChanges);
 169
 170 this._searchQuery = null;
 171 this._searchResults = null;
 172 this._searchDOMChanges = [];
 173 this._searchIndex = -1;
 174 }
 175
 176 revealPreviousSearchResult(changeFocus)
 177 {
 178 if (!this.numberOfSearchResults)
 179 return;
 180
 181 if (this._searchIndex > 0)
 182 --this._searchIndex;
 183 else
 184 this._searchIndex = this._searchResults.length - 1;
 185
 186 this._revealSearchResult(this._searchIndex, changeFocus);
 187 }
 188
 189 revealNextSearchResult(changeFocus)
 190 {
 191 if (!this.numberOfSearchResults)
 192 return;
 193
 194 if (this._searchIndex + 1 < this._searchResults.length)
 195 ++this._searchIndex;
 196 else
 197 this._searchIndex = 0;
 198
 199 this._revealSearchResult(this._searchIndex, changeFocus);
 200 }
 201
112202 // Private
113203
114204 _incompleteSectionWithMessage(section, message)

@@WI.ResourceHeadersContentView = class ResourceHeadersContentView extends WI.Cont
314404 this.needsLayout();
315405 }
316406
 407 _perfomSearchOnKeyValuePairs()
 408 {
 409 let searchRegex = new RegExp(this._searchQuery.escapeForRegExp(), "gi");
 410
 411 let elements = this.element.querySelectorAll(".key, .value");
 412 for (let element of elements) {
 413 let matchRanges = [];
 414 let text = element.textContent;
 415 let match;
 416 while (match = searchRegex.exec(text))
 417 matchRanges.push({offset: match.index, length: match[0].length});
 418
 419 if (matchRanges.length) {
 420 let highlightedNodes = WI.highlightRangesWithStyleClass(element, matchRanges, "search-highlight", this._searchDOMChanges);
 421 this._searchResults = this._searchResults.concat(highlightedNodes);
 422 }
 423 }
 424 }
 425
 426 _revealSearchResult(index, changeFocus)
 427 {
 428 let highlightElement = this._searchResults[index];
 429 if (!highlightElement)
 430 return;
 431
 432 highlightElement.scrollIntoViewIfNeeded();
 433
 434 if (!this._bouncyHighlightElement) {
 435 this._bouncyHighlightElement = document.createElement("div");
 436 this._bouncyHighlightElement.className = "bouncy-highlight";
 437 this._bouncyHighlightElement.addEventListener("animationend", (event) => {
 438 this._bouncyHighlightElement.remove();
 439 });
 440 }
 441
 442 this._bouncyHighlightElement.remove();
 443
 444 let computedStyles = window.getComputedStyle(highlightElement);
 445 let highlightElementRect = highlightElement.getBoundingClientRect();
 446 let contentViewRect = this.element.getBoundingClientRect();
 447 let contentViewScrollTop = this.element.scrollTop;
 448 let contentViewScrollLeft = this.element.scrollLeft;
 449
 450 this._bouncyHighlightElement.textContent = highlightElement.textContent;
 451 this._bouncyHighlightElement.style.top = (highlightElementRect.top - contentViewRect.top + contentViewScrollTop) + "px";
 452 this._bouncyHighlightElement.style.left = (highlightElementRect.left - contentViewRect.left + contentViewScrollLeft) + "px";
 453 this._bouncyHighlightElement.style.fontWeight = computedStyles.fontWeight;
 454
 455 this.element.appendChild(this._bouncyHighlightElement);
 456 }
 457
317458 _resourceRequestHeadersDidChange(event)
318459 {
319460 this._needsRequestHeadersRefresh = true;