Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (223064 => 223065)
--- trunk/Source/WebInspectorUI/ChangeLog 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/ChangeLog 2017-10-09 20:38:09 UTC (rev 223065)
@@ -1,5 +1,97 @@
2017-10-09 Joseph Pecoraro <[email protected]>
+ Web Inspector: Network Tab - Filter resources based on URL / Text Content
+ https://bugs.webkit.org/show_bug.cgi?id=178071
+ <rdar://problem/34071562>
+
+ Reviewed by Brian Burg.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ New strings.
+
+ * UserInterface/Views/FilterBar.css:
+ (.filter-bar.active > input[type="search"]::-webkit-search-decoration):
+ (.filter-bar.indicating-progress > input[type="search"]::-webkit-search-decoration):
+ New icon for progress / active states.
+
+ * UserInterface/Views/FilterBar.js:
+ (WI.FilterBar.prototype.get inputField):
+ (WI.FilterBar.prototype.get placeholder):
+ (WI.FilterBar.prototype.set placeholder):
+ (WI.FilterBar.prototype.get incremental):
+ (WI.FilterBar.prototype.set incremental):
+ (WI.FilterBar.prototype.get indicatingProgress):
+ (WI.FilterBar.prototype.set indicatingProgress):
+ (WI.FilterBar.prototype.get indicatingActive):
+ (WI.FilterBar.prototype.set indicatingActive):
+ (WI.FilterBar.prototype._handleFilterInputEvent):
+ When incremental is set to false on the FilterBar still dispatch an
+ event when the textfield clears.
+
+ * UserInterface/Images/FilterFieldActiveGlyph.svg: Added.
+ * UserInterface/Images/gtk/FilterFieldActiveGlyph.svg: Added.
+ New blue icon for active state.
+
+ * UserInterface/Controllers/FrameResourceManager.js:
+ (WI.FrameResourceManager.prototype.resourceForIdentifier):
+ Accessor for arbitrary resource.
+
+ * UserInterface/Views/NetworkTableContentView.css:
+ (.content-view.network .navigation-bar .filter-bar):
+ (.content-view.network .warning-banner):
+ (body[dir=ltr] .content-view.network .warning-banner):
+ (body[dir=rtl] .content-view.network .warning-banner):
+ (.content-view.network .warning-banner > a):
+ Warning banner when the filter produces no results. This matches the
+ warning in the Debugger tab when breakpoints are disabled.
+
+ * UserInterface/Views/ScopeBar.js:
+ (WI.ScopeBar.prototype.resetToDefault):
+ Provide a way to easily reset a scope bar to the default item.
+
+ * UserInterface/Views/RadioButtonNavigationItem.css:
+ (.navigation-bar .item.radio.button.text-only:active):
+ * UserInterface/Views/ScopeBar.css:
+ (.scope-bar > li:active):
+ Cleanup some styles that should be using a variable.
+
+ * UserInterface/Views/NetworkTableContentView.js:
+ (WI.NetworkTableContentView):
+ (WI.NetworkTableContentView.prototype.get filterNavigationItems):
+ (WI.NetworkTableContentView.prototype.layout):
+ (WI.NetworkTableContentView.prototype._processPendingEntries):
+ (WI.NetworkTableContentView.prototype._checkTextFilterAgainstFinishedResource):
+ (WI.NetworkTableContentView.prototype._checkTextFilterAgainstFailedResource):
+ (WI.NetworkTableContentView.prototype._updateTextFilterActiveIndicator):
+ (WI.NetworkTableContentView.prototype._updateEmptyFilterResultsWarning):
+ (WI.NetworkTableContentView.prototype._showEmptyFilterResultsWarning):
+ (WI.NetworkTableContentView.prototype._hideEmptyFilterResultsWarning):
+ (WI.NetworkTableContentView.prototype._positionEmptyFilterMessage):
+ (WI.NetworkTableContentView.prototype._resourceLoadingDidFinish):
+ (WI.NetworkTableContentView.prototype._resourceLoadingDidFail):
+ (WI.NetworkTableContentView.prototype._networkTimelineRecordAdded):
+ (WI.NetworkTableContentView.prototype._insertResourceAndReloadTable):
+ (WI.NetworkTableContentView.prototype._hasTypeFilter):
+ (WI.NetworkTableContentView.prototype._hasTextFilter):
+ (WI.NetworkTableContentView.prototype._hasActiveFilter):
+ (WI.NetworkTableContentView.prototype._passTypeFilter):
+ (WI.NetworkTableContentView.prototype._passTextFilter):
+ (WI.NetworkTableContentView.prototype._passFilter):
+ (WI.NetworkTableContentView.prototype._updateFilteredEntries):
+ (WI.NetworkTableContentView.prototype._resetFilters):
+ (WI.NetworkTableContentView.prototype._textFilterDidChange):
+ (WI.NetworkTableContentView.prototype._tableNameColumnDidChangeWidth):
+ There are now two filters.
+
+ - FilterBar - Filters URL and Full Text Content
+ - ScopeBar - Filters Resource Type
+
+ The text content filter is asynchronous. We reuse the existing Search
+ functionality when filtering on text. We need to defer text content
+ filtering until the resource finishes loading.
+
+2017-10-09 Joseph Pecoraro <[email protected]>
+
Web Inspector: Network Tab: Row wrapping (waterfall displaying behind next row's name)
https://bugs.webkit.org/show_bug.cgi?id=178015
<rdar://problem/34858720>
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (223064 => 223065)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2017-10-09 20:38:09 UTC (rev 223065)
@@ -181,6 +181,7 @@
localizedStrings["Clear Log"] = "Clear Log";
localizedStrings["Clear Network Items (%s)"] = "Clear Network Items (%s)";
localizedStrings["Clear Timeline (%s)"] = "Clear Timeline (%s)";
+localizedStrings["Clear filters"] = "Clear filters";
localizedStrings["Clear focus"] = "Clear focus";
localizedStrings["Clear log (%s or %s)"] = "Clear log (%s or %s)";
localizedStrings["Clear modified properties"] = "Clear modified properties";
@@ -403,6 +404,7 @@
localizedStrings["Fill"] = "Fill";
localizedStrings["Fill Mode"] = "Fill Mode";
localizedStrings["Filter"] = "Filter";
+localizedStrings["Filter Full URL and Text"] = "Filter Full URL and Text";
localizedStrings["Flexbox"] = "Flexbox";
localizedStrings["Float"] = "Float";
localizedStrings["Float and Clear"] = "Float and Clear";
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js 2017-10-09 20:38:09 UTC (rev 223065)
@@ -65,6 +65,11 @@
return this._frameIdentifierMap.get(frameId) || null;
}
+ resourceForRequestIdentifier(requestIdentifier)
+ {
+ return this._resourceRequestIdentifierMap.get(requestIdentifier) || null;
+ }
+
frameDidNavigate(framePayload)
{
// Called from WI.PageObserver.
Added: trunk/Source/WebInspectorUI/UserInterface/Images/FilterFieldActiveGlyph.svg (0 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Images/FilterFieldActiveGlyph.svg (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/FilterFieldActiveGlyph.svg 2017-10-09 20:38:09 UTC (rev 223065)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2017 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 13 13">
+ <g transform="translate(0.5, 0.5)" stroke="hsl(212, 92%, 54%)" stroke-width="1" fill="none">
+ <circle cx="6" cy="6" r="6"/>
+ <path d="M3 4 L 9 4" stroke-linecap="square"/>
+ <path d="M4 6 L 8 6" stroke-linecap="square"/>
+ <path d="M5 8 L 7 8" stroke-linecap="square"/>
+ </g>
+</svg>
Added: trunk/Source/WebInspectorUI/UserInterface/Images/gtk/FilterFieldActiveGlyph.svg (0 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Images/gtk/FilterFieldActiveGlyph.svg (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/gtk/FilterFieldActiveGlyph.svg 2017-10-09 20:38:09 UTC (rev 223065)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed under the Creative Commons Attribution-Share Alike 3.0 United States License (http://creativecommons.org/licenses/by-sa/3.0/) -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 13 13">
+ <path fill="hsl(212, 92%, 54%)" d="m1.5 1.3273v0.71875 0.0625c-0.001 0.13652 0.0388 0.2562 0.125 0.375l4 5.4687c0.062145 0.08767 0.14938 0.16242 0.25 0.21875v2.5016 1l1.25-1v-2.5016c0.1006-0.0563 0.1879-0.131 0.25-0.2187l4-5.4687c0.08625-0.1188 0.12631-0.23848 0.125-0.375v-0.0625-0.71875z"/>
+</svg>
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.css (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.css 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.css 2017-10-09 20:38:09 UTC (rev 223065)
@@ -90,3 +90,18 @@
-webkit-appearance: none;
}
+
+.filter-bar.active > input[type="search"]::-webkit-search-decoration {
+ background-image: url(../Images/FilterFieldActiveGlyph.svg);
+}
+
+.filter-bar.indicating-progress > input[type="search"]::-webkit-search-decoration {
+ background-image: url(../Images/IndeterminateProgressSpinner1.svg);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+
+ animation-name: discrete-spinner;
+ animation-duration: 1s;
+ animation-iteration-count: infinite;
+ animation-timing-function: step-start;
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.js (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.js 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.js 2017-10-09 20:38:09 UTC (rev 223065)
@@ -42,7 +42,8 @@
this._inputField.placeholder = WI.UIString("Filter");
this._inputField.spellcheck = false;
this._inputField.incremental = true;
- this._inputField.addEventListener("search", this._handleFilterChanged.bind(this), false);
+ this._inputField.addEventListener("search", this._handleFilterChanged.bind(this));
+ this._inputField.addEventListener("input", this._handleFilterInputEvent.bind(this));
this._element.appendChild(this._inputField);
this._lastFilterValue = this.filters;
@@ -55,21 +56,31 @@
return this._element;
}
+ get inputField()
+ {
+ return this._inputField;
+ }
+
get placeholder()
{
- return this._inputField.getAttribute("placeholder");
+ return this._inputField.placeholder;
}
set placeholder(text)
{
- this._inputField.setAttribute("placeholder", text);
+ this._inputField.placeholder = text;
}
- get inputField()
+ get incremental()
{
- return this._inputField;
+ return this._inputField.incremental;
}
+ set incremental(incremental)
+ {
+ this._inputField.incremental = incremental;
+ }
+
get filters()
{
return {text: this._inputField.value, functions: [...this._filterFunctionsMap.values()]};
@@ -85,6 +96,33 @@
this._handleFilterChanged();
}
+ get indicatingProgress()
+ {
+ return this._element.classList.contains("indicating-progress");
+ }
+
+ set indicatingProgress(progress)
+ {
+ this._element.classList.toggle("indicating-progress", !!progress);
+ }
+
+ get indicatingActive()
+ {
+ return this._element.classList.contains("active");
+ }
+
+ set indicatingActive(active)
+ {
+ this._element.classList.toggle("active", !!active);
+ }
+
+ clear()
+ {
+ this._inputField.value = "";
+ this._inputField.value = null; // Get the placeholder to show again.
+ this._lastFilterValue = this.filters;
+ }
+
addFilterBarButton(identifier, filterFunction, activatedByDefault, defaultToolTip, activatedToolTip, image, imageWidth, imageHeight)
{
var filterBarButton = new WI.FilterBarButton(identifier, filterFunction, activatedByDefault, defaultToolTip, activatedToolTip, image, imageWidth, imageHeight);
@@ -142,6 +180,17 @@
this.dispatchEventToListeners(WI.FilterBar.Event.FilterDidChange);
}
}
+
+ _handleFilterInputEvent(event)
+ {
+ // When not incremental we still want to detect if the field becomes empty.
+
+ if (this.incremental)
+ return;
+
+ if (!this._inputField.value)
+ this._handleFilterChanged();
+ }
};
WI.FilterBar.Event = {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.css (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.css 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.css 2017-10-09 20:38:09 UTC (rev 223065)
@@ -23,6 +23,10 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+.content-view.network .navigation-bar .filter-bar {
+ background: none;
+}
+
.content-view.network .network-table .icon {
position: relative;
width: 16px;
@@ -71,3 +75,38 @@
.network-table :not(.header) .cell:first-of-type {
background: rgba(0, 0, 0, 0.07);
}
+
+.content-view.network .empty-content-placeholder {
+ position: absolute;
+ top: var(--navigation-bar-height);
+ bottom: 0;
+ padding: 0;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden;
+ background: var(--odd-zebra-stripe-row-background-color);
+ --empty-content-placeholder-start: 0;
+}
+
+body[dir=ltr] .content-view.network .empty-content-placeholder {
+ left: var(--empty-content-placeholder-start);
+}
+
+body[dir=rtl] .content-view.network .empty-content-placeholder {
+ right: var(--empty-content-placeholder-start);
+}
+
+.content-view.network .empty-content-placeholder > .message {
+ display: inline-block;
+ white-space: nowrap;
+
+ font-size: var(--sidebar-no-results-message-font-size);
+ color: var(--text-color-gray-medium);
+
+ padding: 5px 15px 6px;
+ line-height: 25px;
+ text-align: center;
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2017-10-09 20:38:09 UTC (rev 223065)
@@ -34,6 +34,7 @@
this._filteredEntries = [];
this._pendingInsertions = [];
this._pendingUpdates = [];
+ this._pendingFilter = false;
this._table = null;
this._nameColumnWidthSetting = new WI.Setting("network-table-content-view-name-column-width", 250);
@@ -43,7 +44,6 @@
this._resourceDetailViewMap = new Map;
// FIXME: Network Timeline.
- // FIXME: Filter text field.
// FIXME: Throttling.
// FIXME: HAR Export.
@@ -70,8 +70,20 @@
this._typeFilterScopeBar = new WI.ScopeBar("network-type-filter-scope-bar", typeFilterScopeBarItems, typeFilterScopeBarItems[0]);
this._typeFilterScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._typeFilterScopeBarSelectionChanged, this);
+ this._textFilterSearchId = 0;
+ this._textFilterSearchText = null;
+ this._textFilterIsActive = false;
+
+ this._textFilterNavigationItem = new WI.FilterBarNavigationItem;
+ this._textFilterNavigationItem.filterBar.incremental = false;
+ this._textFilterNavigationItem.filterBar.addEventListener(WI.FilterBar.Event.FilterDidChange, this._textFilterDidChange, this);
+ this._textFilterNavigationItem.filterBar.placeholder = WI.UIString("Filter Full URL and Text");
+
this._activeTypeFilters = this._generateTypeFilter();
+ this._activeTextFilterResources = new Set;
+ this._emptyFilterResultsMessageElement = null;
+
// COMPATIBILITY (iOS 10.3): Network.setDisableResourceCaching did not exist.
if (window.NetworkAgent && NetworkAgent.setResourceCachingDisabled) {
let toolTipForDisableResourceCache = WI.UIString("Ignore the resource cache when loading resources");
@@ -142,7 +154,11 @@
get filterNavigationItems()
{
- return [this._typeFilterScopeBar];
+ let items = [];
+ if (window.PageAgent)
+ items.push(this._textFilterNavigationItem);
+ items.push(this._typeFilterScopeBar);
+ return items;
}
shown()
@@ -581,6 +597,7 @@
{
this._processPendingEntries();
this._positionDetailView();
+ this._positionEmptyFilterMessage();
}
handleClearShortcut(event)
@@ -593,9 +610,10 @@
_processPendingEntries()
{
let needsSort = this._pendingUpdates.length > 0;
+ let needsFilter = this._pendingFilter;
- // No global sort is needed, so just insert new records into their sorted position.
- if (!needsSort) {
+ // No global sort or filter is needed, so just insert new records into their sorted position.
+ if (!needsSort && !needsFilter) {
let originalLength = this._pendingInsertions.length;
for (let resource of this._pendingInsertions)
this._insertResourceAndReloadTable(resource);
@@ -612,10 +630,49 @@
this._updateEntryForResource(resource);
this._pendingUpdates = [];
+ this._pendingFilter = false;
+
this._updateSortAndFilteredEntries();
this._table.reloadData();
}
+ _checkTextFilterAgainstFinishedResource(resource)
+ {
+ let frame = resource.parentFrame;
+ if (!frame)
+ return;
+
+ let searchQuery = this._textFilterSearchText;
+ if (resource.url.includes(searchQuery)) {
+ this._activeTextFilterResources.add(resource);
+ return;
+ }
+
+ let searchId = this._textFilterSearchId;
+
+ const isCaseSensitive = true;
+ const isRegex = false;
+ PageAgent.searchInResource(frame.id, resource.url, searchQuery, isCaseSensitive, isRegex, resource.requestIdentifier, (error, searchResults) => {
+ if (searchId !== this._textFilterSearchId)
+ return;
+
+ if (error || !searchResults || !searchResults.length)
+ return;
+
+ this._activeTextFilterResources.add(resource);
+
+ this._pendingFilter = true;
+ this.needsLayout();
+ });
+ }
+
+ _checkTextFilterAgainstFailedResource(resource)
+ {
+ let searchQuery = this._textFilterSearchText;
+ if (resource.url.includes(searchQuery))
+ this._activeTextFilterResources.add(resource);
+ }
+
_rowIndexForResource(resource)
{
return this._filteredEntries.findIndex((x) => x.resource === resource);
@@ -689,6 +746,56 @@
this._table.scrollContainer.style.width = this._nameColumn.width + "px";
}
+ _updateTextFilterActiveIndicator()
+ {
+ this._textFilterNavigationItem.filterBar.indicatingActive = this._hasTextFilter();
+ }
+
+ _updateEmptyFilterResultsMessage()
+ {
+ if (this._hasActiveFilter() && !this._filteredEntries.length)
+ this._showEmptyFilterResultsMessage();
+ else
+ this._hideEmptyFilterResultsMessage();
+ }
+
+ _showEmptyFilterResultsMessage()
+ {
+ if (!this._emptyFilterResultsMessageElement) {
+ let message = WI.UIString("No Filter Results");
+ let buttonElement = document.createElement("button");
+ buttonElement.textContent = WI.UIString("Clear filters");
+ buttonElement.addEventListener("click", () => { this._resetFilters(); });
+
+ this._emptyFilterResultsMessageElement = document.createElement("div");
+ this._emptyFilterResultsMessageElement.className = "empty-content-placeholder";
+
+ let messageElement = this._emptyFilterResultsMessageElement.appendChild(document.createElement("div"));
+ messageElement.className = "message";
+ messageElement.append(message, document.createElement("br"), buttonElement);
+ }
+
+ this.element.appendChild(this._emptyFilterResultsMessageElement);
+ this._positionEmptyFilterMessage();
+ }
+
+ _hideEmptyFilterResultsMessage()
+ {
+ if (!this._emptyFilterResultsMessageElement)
+ return;
+
+ this._emptyFilterResultsMessageElement.remove();
+ }
+
+ _positionEmptyFilterMessage()
+ {
+ if (!this._emptyFilterResultsMessageElement)
+ return;
+
+ let width = this._nameColumn.width - 1; // For the 1px border.
+ this._emptyFilterResultsMessageElement.style.width = width + "px";
+ }
+
_resourceCachingDisabledSettingChanged()
{
this._disableResourceCacheNavigationItem.activated = WI.resourceCachingDisabledSetting.value;
@@ -714,6 +821,10 @@
{
let resource = event.target;
this._pendingUpdates.push(resource);
+
+ if (this._hasTextFilter())
+ this._checkTextFilterAgainstFinishedResource(resource);
+
this.needsLayout();
}
@@ -721,6 +832,10 @@
{
let resource = event.target;
this._pendingUpdates.push(resource);
+
+ if (this._hasTextFilter())
+ this._checkTextFilterAgainstFailedResource(resource);
+
this.needsLayout();
}
@@ -758,7 +873,7 @@
console.assert(resourceTimelineRecord instanceof WI.ResourceTimelineRecord);
let resource = resourceTimelineRecord.resource;
- this._insertResourceAndReloadTable(resource)
+ this._insertResourceAndReloadTable(resource);
}
_isDefaultSort()
@@ -770,6 +885,7 @@
{
if (!(WI.tabBrowser.selectedTabContentView instanceof WI.NetworkTabContentView)) {
this._pendingInsertions.push(resource);
+ this.needsLayout();
return;
}
@@ -845,14 +961,42 @@
};
}
- _passFilter(entry)
+ _hasTypeFilter()
{
- if (!this._activeTypeFilters)
+ return !!this._activeTypeFilters;
+ }
+
+ _hasTextFilter()
+ {
+ return this._textFilterIsActive;
+ }
+
+ _hasActiveFilter()
+ {
+ return this._hasTypeFilter()
+ || this._hasTextFilter();
+ }
+
+ _passTypeFilter(entry)
+ {
+ if (!this._hasTypeFilter())
return true;
-
return this._activeTypeFilters.some((checker) => checker(entry.resource.type));
}
+ _passTextFilter(entry)
+ {
+ if (!this._hasTextFilter())
+ return true;
+ return this._activeTextFilterResources.has(entry.resource);
+ }
+
+ _passFilter(entry)
+ {
+ return this._passTypeFilter(entry)
+ && this._passTextFilter(entry);
+ }
+
_updateSortAndFilteredEntries()
{
this._entries = this._entries.sort(this._entriesSortComparator);
@@ -861,12 +1005,15 @@
_updateFilteredEntries()
{
- if (this._activeTypeFilters)
+ if (this._hasActiveFilter())
this._filteredEntries = this._entries.filter(this._passFilter, this);
else
this._filteredEntries = this._entries.slice();
this._restoreSelectedRow();
+
+ this._updateTextFilterActiveIndicator();
+ this._updateEmptyFilterResultsMessage();
}
_generateTypeFilter()
@@ -878,6 +1025,29 @@
return selectedItems.map((item) => item.__checker);
}
+ _resetFilters()
+ {
+ console.assert(this._hasActiveFilter());
+
+ // Clear text filter.
+ this._textFilterSearchId++;
+ this._textFilterNavigationItem.filterBar.indicatingProgress = false;
+ this._textFilterSearchText = null;
+ this._textFilterIsActive = false;
+ this._activeTextFilterResources.clear();
+ this._textFilterNavigationItem.filterBar.clear();
+ console.assert(!this._hasTextFilter());
+
+ // Clear type filter.
+ this._typeFilterScopeBar.resetToDefault();
+ console.assert(!this._hasTypeFilter());
+
+ console.assert(!this._hasActiveFilter());
+
+ this._updateFilteredEntries();
+ this._table.reloadData();
+ }
+
_areFilterListsIdentical(listA, listB)
{
if (listA && listB) {
@@ -912,6 +1082,89 @@
this._table.reloadData();
}
+ _textFilterDidChange(event)
+ {
+ let searchQuery = this._textFilterNavigationItem.filterBar.filters.text;
+ if (searchQuery === this._textFilterSearchText)
+ return;
+
+ // Even if the selected resource would still be visible, lets close the detail view if a filter changes.
+ this._hideResourceDetailView();
+
+ let searchId = ++this._textFilterSearchId;
+
+ // Search cleared.
+ if (!searchQuery) {
+ this._textFilterNavigationItem.filterBar.indicatingProgress = false;
+ this._textFilterSearchText = null;
+ this._textFilterIsActive = false;
+ this._activeTextFilterResources.clear();
+
+ this._updateFilteredEntries();
+ this._table.reloadData();
+ return;
+ }
+
+ this._textFilterSearchText = searchQuery;
+ this._textFilterNavigationItem.filterBar.indicatingProgress = true;
+
+ // NetworkTable text filter currently searches:
+ // - Resource URL
+ // - Resource Text Content
+ // It does not search all the content in the table (like mimeType, headers, etc).
+ // For those we should provide more custom filters.
+
+ const isCaseSensitive = true;
+ const isRegex = false;
+ PageAgent.searchInResources(searchQuery, isCaseSensitive, isRegex, (error, searchResults) => {
+ if (searchId !== this._textFilterSearchId)
+ return;
+
+ this._textFilterIsActive = true;
+ this._activeTextFilterResources.clear();
+ this._textFilterNavigationItem.filterBar.indicatingProgress = false;
+
+ // Add resources based on URL.
+ for (let entry of this._entries) {
+ let resource = entry.resource;
+ if (resource.url.includes(searchQuery))
+ this._activeTextFilterResources.add(resource);
+ }
+
+ // Add resources based on content.
+ if (!error) {
+ for (let {url, frameId, requestId} of searchResults) {
+ if (requestId) {
+ let resource = WI.frameResourceManager.resourceForRequestIdentifier(requestId);
+ if (resource) {
+ this._activeTextFilterResources.add(resource);
+ continue;
+ }
+ }
+
+ if (frameId && url) {
+ let frame = WI.frameResourceManager.frameForIdentifier(frameId);
+ if (frame) {
+ if (frame.mainResource.url ="" url) {
+ this._activeTextFilterResources.add(frame.mainResource);
+ continue;
+ }
+ let resource = frame.resourceForURL(url);
+ if (resource) {
+ this._activeTextFilterResources.add(resource);
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ // Apply.
+ this._updateFilteredEntries();
+ this._table.reloadData();
+ });
+ }
+
_restoreSelectedRow()
{
if (!this._selectedResource)
@@ -932,5 +1185,6 @@
this._nameColumnWidthSetting.value = event.target.width;
this._positionDetailView();
+ this._positionEmptyFilterMessage();
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.css (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.css 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.css 2017-10-09 20:38:09 UTC (rev 223065)
@@ -43,7 +43,7 @@
.navigation-bar .item.radio.button.text-only:active {
color: var(--selected-foreground-color);
- background-color: hsla(212, 92%, 54%, 0.55);
+ background-color: var(--selected-background-color-active);
}
.navigation-bar .item.radio.button.text-only.selected:active {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScopeBar.css (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ScopeBar.css 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScopeBar.css 2017-10-09 20:38:09 UTC (rev 223065)
@@ -109,7 +109,7 @@
.scope-bar > li:active {
color: var(--selected-foreground-color);
- background-color: hsla(212, 92%, 54%, 0.55);
+ background-color: var(--selected-background-color-active);
}
.scope-bar > li.selected:active {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScopeBar.js (223064 => 223065)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ScopeBar.js 2017-10-09 20:23:32 UTC (rev 223064)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScopeBar.js 2017-10-09 20:38:09 UTC (rev 223065)
@@ -89,6 +89,19 @@
return this._items.some((item) => item.selected && item !== this._defaultItem);
}
+ resetToDefault()
+ {
+ let selectedItems = this.selectedItems;
+ if (selectedItems.length === 1 && selectedItems[0] === this._defaultItem)
+ return;
+
+ for (let item of this._items)
+ item.selected = false;
+ this._defaultItem.selected = true;
+
+ this.dispatchEventToListeners(WI.ScopeBar.Event.SelectionChanged);
+ }
+
// Private
_populate()