WebKit Bugzilla
Attachment 362058 Details for
Bug 192527
: Web Inspector: provide a way to make searches case sensitive or use a regular expression
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-192527-20190214141009.patch (text/plain), 54.95 KB, created by
Devin Rousso
on 2019-02-14 14:10:09 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Devin Rousso
Created:
2019-02-14 14:10:09 PST
Size:
54.95 KB
patch
obsolete
>diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index 0f674693d8e97a346bc7be1fce2a5748bc879b77..b4f5c4768f9989aeaa0046b8b356e2d5935066fe 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,77 @@ >+2019-02-14 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: provide a way to make searches case sensitive or use a regular expression >+ https://bugs.webkit.org/show_bug.cgi?id=192527 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * UserInterface/Base/SearchUtilities.js: Added. >+ (WI.SearchUtilities.get defaultSettings): >+ (WI.SearchUtilities.createSettings): >+ (WI.SearchUtilities.regExpForString): >+ (WI.SearchUtilities.createSettingsButton): >+ (WI.SearchUtilities.createSettingsButton.toggleActive): >+ * UserInterface/Views/Main.css: >+ (.search-settings): Added. >+ (.search-settings > .glyph): Added. >+ (.search-settings:active > .glyph): Added. >+ (.search-settings.active > .glyph): Added. >+ (.search-settings:active.active > .glyph): Added. >+ Create static utility class for handling settings related to searching/filtering. >+ >+ * UserInterface/Base/Setting.js: >+ * UserInterface/Views/SettingsTabContentView.js: >+ (WI.SettingsTabContentView.prototype._createGeneralSettingsView): >+ Create default search settings that apply across WebInspector, unless a more specific >+ setting has been created that overrides it (e.g. the navigation sidebar or Search tab). >+ >+ * UserInterface/Views/SearchSidebarPanel.js: >+ (WI.SearchSidebarPanel): >+ (WI.SearchSidebarPanel.prototype.performSearch.forEachMatch): >+ (WI.SearchSidebarPanel.prototype.performSearch.resourceCallback): >+ (WI.SearchSidebarPanel.prototype.performSearch.resourcesCallback): >+ (WI.SearchSidebarPanel.prototype.performSearch.searchScripts.scriptCallback): >+ (WI.SearchSidebarPanel.prototype.performSearch.searchScripts): >+ (WI.SearchSidebarPanel.prototype.performSearch.domSearchResults): >+ (WI.SearchSidebarPanel.prototype.performSearch.domCallback): >+ (WI.SearchSidebarPanel.prototype.performSearch): >+ * UserInterface/Views/SearchSidebarPanel.css: >+ (.sidebar > .panel.navigation.search > .search-bar): >+ (.sidebar > .panel.navigation.search > .search-bar > input[type="search"]): >+ Add a (*) settings "gear" after each `<input type="search">` that shows a contextmenu with >+ checkboxes for each search setting. Any settings changed for each input take precedence over >+ the default settings, but will match the corresponding default setting if it's changed. >+ >+ * UserInterface/Views/SearchResultTreeElement.js: >+ (WI.SearchResultTreeElement.truncateAndHighlightTitle): >+ Use the length of the found text, rather than the length of the query. >+ >+ * UserInterface/Views/DOMTreeElement.js: >+ (WI.DOMTreeElement.prototype._highlightSearchResults): >+ * UserInterface/Views/DataGrid.js: >+ (WI.DataGrid.prototype._updateFilter): >+ * UserInterface/Views/LogContentView.js: >+ (WI.LogContentView.prototype.performSearch): >+ * UserInterface/Views/NetworkTableContentView.js: >+ (WI.NetworkTableContentView.prototype._urlFilterDidChange): >+ * UserInterface/Views/ResourceHeadersContentView.js: >+ (WI.ResourceHeadersContentView.prototype._perfomSearchOnKeyValuePairs): >+ * UserInterface/Views/ResourceSecurityContentView.js: >+ (WI.ResourceSecurityContentView.prototype._perfomSearchOnKeyValuePairs): >+ * UserInterface/Views/SourceCodeTextEditor.js: >+ (WI.SourceCodeTextEditor.prototype.customPerformSearch.searchResultCallback): >+ (WI.SourceCodeTextEditor.prototype.customPerformSearch): >+ * UserInterface/Views/TextEditor.js: >+ (WI.TextEditor.prototype.performSearch): >+ Use the default search settings when searching/filtering. >+ >+ * UserInterface/Views/SearchBar.css: >+ (.search-bar > input[type="search"]:placeholder-shown::-webkit-search-cancel-button): Added. >+ Drive-by: prevent the (x) from appearing when no text has been entered. >+ >+ * Localizations/en.lproj/localizedStrings.js: >+ * UserInterface/Main.html: >+ > 2019-02-13 Nikita Vasilyev <nvasilyev@apple.com> > > Web Inspector: Styles: valid values in style attributes are reported as unsupported property values >diff --git a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >index db390f6e696389a631360650e5d21a596957c2c0..c2f64937518209577b24b145f70882d8b1aa03bb 100644 >--- a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >+++ b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >@@ -187,6 +187,7 @@ localizedStrings["Canvas Element"] = "Canvas Element"; > localizedStrings["Canvases"] = "Canvases"; > localizedStrings["Capture Screenshot"] = "Capture Screenshot"; > localizedStrings["Capturing"] = "Capturing"; >+localizedStrings["Case Sensitive"] = "Case Sensitive"; > localizedStrings["Catch Variables"] = "Catch Variables"; > localizedStrings["Categories"] = "Categories"; > localizedStrings["Certificate"] = "Certificate"; >@@ -828,6 +829,7 @@ localizedStrings["Scroll Into View"] = "Scroll Into View"; > localizedStrings["Search"] = "Search"; > localizedStrings["Search Again"] = "Search Again"; > localizedStrings["Search Resource Content"] = "Search Resource Content"; >+localizedStrings["Search:"] = "Search:"; > localizedStrings["Secure"] = "Secure"; > localizedStrings["Security"] = "Security"; > localizedStrings["Security Issue"] = "Security Issue"; >diff --git a/Source/WebInspectorUI/UserInterface/Base/SearchUtilities.js b/Source/WebInspectorUI/UserInterface/Base/SearchUtilities.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b55a7f7b4c1dc50abd1f60caf6120c795739d786 >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/Base/SearchUtilities.js >@@ -0,0 +1,105 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+WI.SearchUtilities = class SearchUtilities { >+ static get defaultSettings() >+ { >+ return { >+ caseSensitive: WI.settings.searchCaseSensitive, >+ regularExpression: WI.settings.searchRegularExpression, >+ }; >+ } >+ >+ static createSettings(namePrefix, options = {}) >+ { >+ let settings = {}; >+ for (let [key, defaultSetting] of Object.entries(WI.SearchUtilities.defaultSettings)) { >+ let setting = new WI.Setting(namePrefix + "-" + defaultSetting.name, defaultSetting.value); >+ defaultSetting.addEventListener(WI.Setting.Event.Changed, (event) => { >+ setting.value = defaultSetting.value; >+ }); >+ settings[key] = setting; >+ >+ if (options.handleChanged) >+ setting.addEventListener(WI.Setting.Event.Changed, options.handleChanged); >+ } >+ return settings; >+ } >+ >+ static regExpForString(query, settings = {}) >+ { >+ function checkSetting(setting) { >+ return setting instanceof WI.Setting ? setting.value : !!setting; >+ } >+ >+ if (!checkSetting(settings.regularExpression)) >+ query = simpleGlobStringToRegExp(query); >+ >+ let flags = "g"; >+ if (!checkSetting(settings.caseSensitive)) >+ flags += "i"; >+ >+ return new RegExp(query, flags); >+ } >+ >+ static createSettingsButton(settings) >+ { >+ console.assert(!isEmptyObject(settings)); >+ >+ let button = document.createElement("button"); >+ button.addEventListener("click", (event) => { >+ event.stop(); >+ >+ let contextMenu = WI.ContextMenu.createFromEvent(event); >+ >+ if (settings.caseSensitive) { >+ contextMenu.appendCheckboxItem(WI.UIString("Case Sensitive"), () => { >+ settings.caseSensitive.value = !settings.caseSensitive.value; >+ }, settings.caseSensitive.value); >+ } >+ >+ if (settings.regularExpression) { >+ contextMenu.appendCheckboxItem(WI.UIString("Regular Expression"), () => { >+ settings.regularExpression.value = !settings.regularExpression.value; >+ }, settings.regularExpression.value); >+ } >+ >+ contextMenu.show(); >+ }); >+ button.classList.add("search-settings"); >+ button.tabIndex = -1; >+ >+ button.appendChild(WI.ImageUtilities.useSVGSymbol("Images/Gear.svg", "glyph")); >+ >+ function toggleActive() { >+ button.classList.toggle("active", Object.values(settings).some((setting) => !!setting.value)); >+ } >+ settings.caseSensitive.addEventListener(WI.Setting.Event.Changed, toggleActive); >+ settings.regularExpression.addEventListener(WI.Setting.Event.Changed, toggleActive); >+ toggleActive(); >+ >+ return button; >+ } >+}; >diff --git a/Source/WebInspectorUI/UserInterface/Base/Setting.js b/Source/WebInspectorUI/UserInterface/Base/Setting.js >index 270cf26ff0483837964e6f7d8f01751d45bce13f..e7c57923b72d9308ba36e85000bae945bb7b4abd 100644 >--- a/Source/WebInspectorUI/UserInterface/Base/Setting.js >+++ b/Source/WebInspectorUI/UserInterface/Base/Setting.js >@@ -135,6 +135,8 @@ WI.settings = { > indentUnit: new WI.Setting("indent-unit", 4), > indentWithTabs: new WI.Setting("indent-with-tabs", false), > resourceCachingDisabled: new WI.Setting("disable-resource-caching", false), >+ searchCaseSensitive: new WI.Setting("search-case-sensitive", false), >+ searchRegularExpression: new WI.Setting("search-regular-expression", false), > selectedNetworkDetailContentViewIdentifier: new WI.Setting("network-detail-content-view-identifier", "preview"), > sourceMapsEnabled: new WI.Setting("source-maps-enabled", true), > showAllRequestsBreakpoint: new WI.Setting("show-all-requests-breakpoint", true), >diff --git a/Source/WebInspectorUI/UserInterface/Main.html b/Source/WebInspectorUI/UserInterface/Main.html >index 40ddf8395158d5df9546ca4befd877868f15313b..c7846cac1cef9203ea5c015f42d2ec45517c6017 100644 >--- a/Source/WebInspectorUI/UserInterface/Main.html >+++ b/Source/WebInspectorUI/UserInterface/Main.html >@@ -291,6 +291,7 @@ > <script src="Base/ObjectStore.js"></script> > <script src="Base/URLUtilities.js"></script> > <script src="Base/Utilities.js"></script> >+ <script src="Base/SearchUtilities.js"></script> > <script src="Base/Setting.js"></script> > <script src="Base/YieldableTask.js"></script> > >diff --git a/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js >index 4d22f6ba270d36fd77cec2795cf192d94e96f79e..8c45a547fcf2cddd815b23031b325138f1a5ba6a 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js >+++ b/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js >@@ -1707,7 +1707,7 @@ WI.DOMTreeElement = class DOMTreeElement extends WI.TreeElement > } > > var text = this.title.textContent; >- var searchRegex = new RegExp(this._searchQuery.escapeForRegExp(), "gi"); >+ let searchRegex = WI.SearchUtilities.regExpForString(this._searchQuery, WI.SearchUtilities.defaultSettings); > > var match = searchRegex.exec(text); > var matchRanges = []; >diff --git a/Source/WebInspectorUI/UserInterface/Views/DataGrid.js b/Source/WebInspectorUI/UserInterface/Views/DataGrid.js >index 1c0ffb4bc88ca7a68ddddce6a5f411d917f99cd7..253142769b7667f5284cf2bdbfb96c9873bd47ac 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/DataGrid.js >+++ b/Source/WebInspectorUI/UserInterface/Views/DataGrid.js >@@ -1843,7 +1843,7 @@ WI.DataGrid = class DataGrid extends WI.View > if (!this._rows.length) > return; > >- this._textFilterRegex = simpleGlobStringToRegExp(this._filterText, "i"); >+ this._textFilterRegex = WI.SearchUtilities.regExpForString(this._filterText, WI.SearchUtilities.defaultSettings); > > if (this._applyFilterToNodesTask && this._applyFilterToNodesTask.processing) > this._applyFilterToNodesTask.cancel(); >diff --git a/Source/WebInspectorUI/UserInterface/Views/LogContentView.js b/Source/WebInspectorUI/UserInterface/Views/LogContentView.js >index 1caca5c4d30bf9d153310511e3f56499503ace0a..a7b53535b1c163967c273c24f35677ec71fa3f26 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/LogContentView.js >+++ b/Source/WebInspectorUI/UserInterface/Views/LogContentView.js >@@ -1045,7 +1045,7 @@ WI.LogContentView = class LogContentView extends WI.ContentView > > this.element.classList.add(WI.LogContentView.SearchInProgressStyleClassName); > >- let searchRegex = new RegExp(this._currentSearchQuery.escapeForRegExp(), "gi"); >+ let searchRegex = WI.SearchUtilities.regExpForString(this._currentSearchQuery, WI.SearchUtilities.defaultSettings); > this._unfilteredMessageElements().forEach(function(message) { > let matchRanges = []; > let text = message.textContent; >diff --git a/Source/WebInspectorUI/UserInterface/Views/Main.css b/Source/WebInspectorUI/UserInterface/Views/Main.css >index 31a70cb19f5676ca3f12741cc3a1f38ad663c63c..2977eb35d41fabf12e9093101212f0b183db5279 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/Main.css >+++ b/Source/WebInspectorUI/UserInterface/Views/Main.css >@@ -293,6 +293,33 @@ body[dir=rtl] .go-to-arrow { > background-image: url(../Images/GoToArrow.svg#selected-active); > } > >+.search-settings { >+ display: inline-block; >+ margin: 0; >+ padding: 0; >+ background-color: transparent; >+ border: none; >+ -webkit-appearance: none; >+} >+ >+.search-settings > .glyph { >+ width: 16px; >+ height: 16px; >+ color: var(--glyph-color); >+} >+ >+.search-settings:active > .glyph { >+ color: var(--glyph-color-pressed); >+} >+ >+.search-settings.active > .glyph { >+ color: var(--glyph-color-active); >+} >+ >+.search-settings:active.active > .glyph { >+ color: var(--glyph-color-active-pressed); >+} >+ > .hidden { > display: none !important; > } >diff --git a/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js b/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js >index 43815af0131df9945095ce2187507f8f581c64ba..9b07b338348afdc5c072abc39cab487251ae30f9 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js >+++ b/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js >@@ -1859,7 +1859,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie > > this._urlFilterIsActive = true; > this._urlFilterSearchText = searchQuery; >- this._urlFilterSearchRegex = new RegExp(searchQuery.escapeForRegExp(), "i"); >+ this._urlFilterSearchRegex = WI.SearchUtilities.regExpForString(searchQuery, WI.SearchUtilities.defaultSettings); > > this._activeURLFilterResources.clear(); > >diff --git a/Source/WebInspectorUI/UserInterface/Views/ResourceHeadersContentView.js b/Source/WebInspectorUI/UserInterface/Views/ResourceHeadersContentView.js >index 3ca8415cda37dddc8d30b04418aaac1c28d80915..bcc777fe87f9c93d05d1cf2d4bc6a259a730fc8d 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/ResourceHeadersContentView.js >+++ b/Source/WebInspectorUI/UserInterface/Views/ResourceHeadersContentView.js >@@ -419,7 +419,7 @@ WI.ResourceHeadersContentView = class ResourceHeadersContentView extends WI.Cont > > _perfomSearchOnKeyValuePairs() > { >- let searchRegex = new RegExp(this._searchQuery.escapeForRegExp(), "gi"); >+ let searchRegex = WI.SearchUtilities.regExpForString(this._searchQuery, WI.SearchUtilities.defaultSettings); > > let elements = this.element.querySelectorAll(".key, .value"); > for (let element of elements) { >diff --git a/Source/WebInspectorUI/UserInterface/Views/ResourceSecurityContentView.js b/Source/WebInspectorUI/UserInterface/Views/ResourceSecurityContentView.js >index ff6426eac8b5d7f99c1bc39b96e057aec12da841..12808418f29ddc3a33ab1f0194ced96bc85c1550 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/ResourceSecurityContentView.js >+++ b/Source/WebInspectorUI/UserInterface/Views/ResourceSecurityContentView.js >@@ -286,7 +286,7 @@ WI.ResourceSecurityContentView = class ResourceSecurityContentView extends WI.Co > > _perfomSearchOnKeyValuePairs() > { >- let searchRegex = new RegExp(this._searchQuery.escapeForRegExp(), "gi"); >+ let searchRegex = WI.SearchUtilities.regExpForString(this._searchQuery, WI.SearchUtilities.defaultSettings); > > let elements = this.element.querySelectorAll(".key, .value"); > for (let element of elements) { >diff --git a/Source/WebInspectorUI/UserInterface/Views/SearchBar.css b/Source/WebInspectorUI/UserInterface/Views/SearchBar.css >index d923aa109dbf193bff9e21dc679400455cb56188..613a199df92b7f805b0c76137e1b1340caead53d 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/SearchBar.css >+++ b/Source/WebInspectorUI/UserInterface/Views/SearchBar.css >@@ -53,6 +53,10 @@ > background-color: white; > } > >+.search-bar > input[type="search"]:placeholder-shown::-webkit-search-cancel-button { >+ display: none; >+} >+ > @media (prefers-color-scheme: dark) { > :matches(.search-bar, .filter-bar) > input[type="search"], > .search-bar > input[type="search"]:not(:placeholder-shown) { >diff --git a/Source/WebInspectorUI/UserInterface/Views/SearchResultTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/SearchResultTreeElement.js >index a40825fc733b9d16f98fd6887b64a37f863e68f6..8f5018f0c6ff3cd8a6f3ddba7289e4bbcb996a3b 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/SearchResultTreeElement.js >+++ b/Source/WebInspectorUI/UserInterface/Views/SearchResultTreeElement.js >@@ -45,7 +45,8 @@ WI.SearchResultTreeElement = class SearchResultTreeElement extends WI.GeneralTre > // Use the original location, since those line/column offsets match the line text in title. > var textRange = sourceCodeTextRange.textRange; > >- var searchTermIndex = textRange.startColumn; >+ let searchTermIndex = textRange.startColumn; >+ let searchTermLength = textRange.endColumn - textRange.startColumn; > > // We should only have one line text ranges, so make sure that is the case. > console.assert(textRange.startLine === textRange.endLine); >@@ -59,9 +60,7 @@ WI.SearchResultTreeElement = class SearchResultTreeElement extends WI.GeneralTre > } else > modifiedTitle = title; > >- modifiedTitle = modifiedTitle.truncateEnd(searchTermIndex + searchTerm.length + charactersToShowAfterSearchMatch); >- >- console.assert(modifiedTitle.substring(searchTermIndex, searchTermIndex + searchTerm.length).toLowerCase() === searchTerm.toLowerCase()); >+ modifiedTitle = modifiedTitle.truncateEnd(searchTermIndex + searchTermLength + charactersToShowAfterSearchMatch); > > var highlightedTitle = document.createDocumentFragment(); > >@@ -69,10 +68,10 @@ WI.SearchResultTreeElement = class SearchResultTreeElement extends WI.GeneralTre > > var highlightSpan = document.createElement("span"); > highlightSpan.className = "highlighted"; >- highlightSpan.append(modifiedTitle.substring(searchTermIndex, searchTermIndex + searchTerm.length)); >+ highlightSpan.append(modifiedTitle.substring(searchTermIndex, searchTermIndex + searchTermLength)); > highlightedTitle.appendChild(highlightSpan); > >- highlightedTitle.append(modifiedTitle.substring(searchTermIndex + searchTerm.length)); >+ highlightedTitle.append(modifiedTitle.substring(searchTermIndex + searchTermLength)); > > return highlightedTitle; > } >diff --git a/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.css b/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.css >index 7bfe2d02ab84d64cea1a4676bff40b0dc236e472..25d66be0e4e88db94b91cde53c058bc4945b7a75 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.css >+++ b/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.css >@@ -28,15 +28,14 @@ > } > > .sidebar > .panel.navigation.search > .search-bar { >+ display: flex; >+ align-items: center; > position: absolute; > top: 0; > left: 0; > right: 0; >- >- display: flex; >- > height: calc(var(--navigation-bar-height) - 1px); >- >+ margin: 0 6px; > white-space: nowrap; > overflow: hidden; > } >@@ -44,8 +43,9 @@ > .sidebar > .panel.navigation.search > .search-bar > input[type="search"] { > display: flex; > flex: 1; >- >- margin: 3px 6px; >+ width: 100%; >+ margin: 0; >+ -webkit-margin-end: 4px; > } > > .sidebar > .panel.navigation.search > .search-bar > input[type="search"]::-webkit-search-results-button { >diff --git a/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js b/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js >index bce2c71a57c57ec40516c9d1a064d6adb099fe73..90921c19e7a65e3ab188406cdc7c346f448fffd0 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js >+++ b/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js >@@ -29,6 +29,12 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan > { > super("search", WI.UIString("Search"), true, true); > >+ this._searchInputSettings = WI.SearchUtilities.createSettings("search-sidebar", { >+ handleChanged: (event) => { >+ this.focusSearchField(true); >+ }, >+ }); >+ > var searchElement = document.createElement("div"); > searchElement.classList.add("search-bar"); > this.element.appendChild(searchElement); >@@ -43,6 +49,8 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan > this._inputElement.setAttribute("placeholder", WI.UIString("Search Resource Content")); > searchElement.appendChild(this._inputElement); > >+ searchElement.appendChild(WI.SearchUtilities.createSettingsButton(this._searchInputSettings)); >+ > this._searchQuerySetting = new WI.Setting("search-sidebar-query", ""); > this._inputElement.value = this._searchQuerySetting.value; > >@@ -89,13 +97,11 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan > if (this._changedBanner) > this._changedBanner.remove(); > >- searchQuery = searchQuery.trim(); > if (!searchQuery.length) > return; > >- // FIXME: Provide UI to toggle regex and case sensitive searches. >- var isCaseSensitive = false; >- var isRegex = false; >+ let isCaseSensitive = !!this._searchInputSettings.caseSensitive.value; >+ let isRegex = !!this._searchInputSettings.regularExpression.value; > > var updateEmptyContentPlaceholderTimeout = null; > >@@ -130,7 +136,10 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan > function forEachMatch(searchQuery, lineContent, callback) > { > var lineMatch; >- var searchRegex = new RegExp(searchQuery.escapeForRegExp(), "gi"); >+ let searchRegex = WI.SearchUtilities.regExpForString(searchQuery, { >+ caseSensitive: isCaseSensitive, >+ regularExpression: isRegex, >+ }); > while ((searchRegex.lastIndex < lineContent.length) && (lineMatch = searchRegex.exec(lineContent))) > callback(lineMatch, searchRegex.lastIndex); > } >@@ -167,6 +176,9 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan > }); > } > >+ if (!resourceTreeElement.children.length) >+ this.contentTreeOutline.removeChild(resourceTreeElement); >+ > updateEmptyContentPlaceholder.call(this); > } > >@@ -220,6 +232,9 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan > }); > } > >+ if (!scriptTreeElement.children.length) >+ this.contentTreeOutline.removeChild(scriptTreeElement); >+ > updateEmptyContentPlaceholder.call(this); > } > >@@ -280,6 +295,9 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan > createTreeElementForMatchObject.call(this, matchObject, resourceTreeElement); > } > >+ if (!resourceTreeElement.children.length) >+ this.contentTreeOutline.removeChild(resourceTreeElement); >+ > updateEmptyContentPlaceholder.call(this); > } > } >diff --git a/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js b/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js >index 52299bb09097273cf7d688054900850937efc636..57316243586b4665f0d1771f8437b0ff2976d03e 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js >+++ b/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js >@@ -211,6 +211,12 @@ WI.SettingsTabContentView = class SettingsTabContentView extends WI.TabContentVi > > generalSettingsView.addSeparator(); > >+ let searchGroup = generalSettingsView.addGroup(WI.UIString("Search:")); >+ searchGroup.addSetting(WI.settings.searchCaseSensitive, WI.UIString("Case Sensitive")); >+ searchGroup.addSetting(WI.settings.searchRegularExpression, WI.UIString("Regular Expression")); >+ >+ generalSettingsView.addSeparator(); >+ > const zoomLevels = [0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.4]; > const zoomValues = zoomLevels.map((level) => [level, Number.percentageString(level, 0)]); > >diff --git a/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js b/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js >index 7f286ae390574944c2fba27725bb7498ebfe36e4..742c4957462bd67f413cfd4afac610c37f86f67d 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js >+++ b/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js >@@ -224,7 +224,7 @@ WI.SourceCodeTextEditor = class SourceCodeTextEditor extends WI.TextEditor > return; > } > >- var queryRegex = new RegExp(query.escapeForRegExp(), "gi"); >+ let queryRegex = WI.SearchUtilities.regExpForString(query, WI.SearchUtilities.defaultSettings); > var searchResults = []; > > for (var i = 0; i < matches.length; ++i) { >diff --git a/Source/WebInspectorUI/UserInterface/Views/TextEditor.js b/Source/WebInspectorUI/UserInterface/Views/TextEditor.js >index ab96d39f37504ea1d37d8f7b95d8171eb6058528..7eac1ef7d31c7040712b74a06a3051f58995f42c 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/TextEditor.js >+++ b/Source/WebInspectorUI/UserInterface/Views/TextEditor.js >@@ -338,7 +338,7 @@ WI.TextEditor = class TextEditor extends WI.View > } > > // Go down the slow patch for all other text content. >- var queryRegex = new RegExp(query.escapeForRegExp(), "gi"); >+ let queryRegex = WI.SearchUtilities.regExpForString(query, WI.SearchUtilities.defaultSettings); > var searchCursor = this._codeMirror.getSearchCursor(queryRegex, {line: 0, ch: 0}, false); > var boundBatchSearch = batchSearch.bind(this); > var numberOfSearchResultsDidChangeTimeout = null; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 32bd451e1ce8ad432dea54bd49ed6d80cc7d6550..6e180961262b9127f4359744c4e15efd5605fd1e 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,22 @@ >+2019-02-14 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: provide a way to make searches case sensitive or use a regular expression >+ https://bugs.webkit.org/show_bug.cgi?id=192527 >+ <rdar://problem/46800955> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * inspector/debugger/search-scripts.html: >+ * inspector/debugger/search-scripts-expected.txt: >+ >+ * inspector/page/searchInResources.html: >+ * inspector/page/searchInResources-expected.txt: >+ >+ * inspector/page/resources/search-script.js: >+ * inspector/page/resources/search-stylesheet.css: >+ * inspector/page/resources/search-worker.js: >+ * inspector/page/resources/search-xhr.txt: >+ > 2019-02-14 Zalan Bujtas <zalan@apple.com> > > [LFC][BFC][MarginCollapse] Replaced boxes don't collapse through their margins >diff --git a/LayoutTests/inspector/debugger/search-scripts-expected.txt b/LayoutTests/inspector/debugger/search-scripts-expected.txt >index a0a1bfd683e8eea426e2972d9f6f2421a966c489..91b2781a8cbd26041847722a9e77a535805d1475 100644 >--- a/LayoutTests/inspector/debugger/search-scripts-expected.txt >+++ b/LayoutTests/inspector/debugger/search-scripts-expected.txt >@@ -1,28 +1,191 @@ > Test DebuggerAgent.searchInContent to search script content. > >+Script added: inspector/debugger/search-scripts.html >+Script added: inspector/debugger/search-scripts.html >+Script added: eval1.js >+Script added: eval2.js > >-SCRIPT: LayoutTests/http/tests/inspector/resources/inspector-test.js >-RESULTS: 0 >- >-SCRIPT: LayoutTests/inspector/debugger/search-scripts.html >-RESULTS: 2 >- LINE: 1 >- CONTENT: // SEARCHTEST: Comment in inline <script>. >- LINE: 28 >- CONTENT: DebuggerAgent.searchInContent(script.id, "SEARCHTEST", false, false, function(error, results) { >- >-SCRIPT: LayoutTests/inspector/debugger/search-scripts.html >+QUERY: searchtest {} >+SCRIPT: inspector/debugger/search-scripts.html > RESULTS: 1 > LINE: 1 >- CONTENT: runTest(); // SEARCHTEST: onload attribute string >+ CONTENT: runTest(); // SEARCHTEST: onload attribute string // OTHERTEST: onload attribute string > >+QUERY: searchtest {"caseSensitive":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 0 >+ >+QUERY: searchtest {"isRegex":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 1 >+ LINE: 1 >+ CONTENT: runTest(); // SEARCHTEST: onload attribute string // OTHERTEST: onload attribute string >+ >+QUERY: searchtest {"caseSensitive":true,"isRegex":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 0 >+ >+QUERY: SEARCHtest {} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 1 >+ LINE: 1 >+ CONTENT: runTest(); // SEARCHTEST: onload attribute string // OTHERTEST: onload attribute string >+ >+QUERY: SEARCHtest {"caseSensitive":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 0 >+ >+QUERY: SEARCHtest {"isRegex":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 1 >+ LINE: 1 >+ CONTENT: runTest(); // SEARCHTEST: onload attribute string // OTHERTEST: onload attribute string >+ >+QUERY: SEARCHtest {"caseSensitive":true,"isRegex":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {"caseSensitive":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {"isRegex":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 1 >+ LINE: 1 >+ CONTENT: runTest(); // SEARCHTEST: onload attribute string // OTHERTEST: onload attribute string >+ >+QUERY: (search|OTHER)TEST {"caseSensitive":true,"isRegex":true} >+SCRIPT: inspector/debugger/search-scripts.html >+RESULTS: 1 >+ LINE: 1 >+ CONTENT: runTest(); // SEARCHTEST: onload attribute string // OTHERTEST: onload attribute string >+ >+QUERY: searchtest {} > SCRIPT: eval1.js > RESULTS: 1 > LINE: 0 > CONTENT: // SEARCHTEST: Eval 1 > >+QUERY: searchtest {"caseSensitive":true} >+SCRIPT: eval1.js >+RESULTS: 0 >+ >+QUERY: searchtest {"isRegex":true} >+SCRIPT: eval1.js >+RESULTS: 1 >+ LINE: 0 >+ CONTENT: // SEARCHTEST: Eval 1 >+ >+QUERY: searchtest {"caseSensitive":true,"isRegex":true} >+SCRIPT: eval1.js >+RESULTS: 0 >+ >+QUERY: SEARCHtest {} >+SCRIPT: eval1.js >+RESULTS: 1 >+ LINE: 0 >+ CONTENT: // SEARCHTEST: Eval 1 >+ >+QUERY: SEARCHtest {"caseSensitive":true} >+SCRIPT: eval1.js >+RESULTS: 0 >+ >+QUERY: SEARCHtest {"isRegex":true} >+SCRIPT: eval1.js >+RESULTS: 1 >+ LINE: 0 >+ CONTENT: // SEARCHTEST: Eval 1 >+ >+QUERY: SEARCHtest {"caseSensitive":true,"isRegex":true} >+SCRIPT: eval1.js >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {} >+SCRIPT: eval1.js >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {"caseSensitive":true} >+SCRIPT: eval1.js >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {"isRegex":true} >+SCRIPT: eval1.js >+RESULTS: 2 >+ LINE: 0 >+ CONTENT: // SEARCHTEST: Eval 1 >+ LINE: 1 >+ CONTENT: // OTHERTEST: Eval 1 >+ >+QUERY: (search|OTHER)TEST {"caseSensitive":true,"isRegex":true} >+SCRIPT: eval1.js >+RESULTS: 1 >+ LINE: 1 >+ CONTENT: // OTHERTEST: Eval 1 >+ >+QUERY: searchtest {} > SCRIPT: eval2.js > RESULTS: 1 > LINE: 0 > CONTENT: var SEARCHTEST = "SEARCHTEST"; > >+QUERY: searchtest {"caseSensitive":true} >+SCRIPT: eval2.js >+RESULTS: 0 >+ >+QUERY: searchtest {"isRegex":true} >+SCRIPT: eval2.js >+RESULTS: 1 >+ LINE: 0 >+ CONTENT: var SEARCHTEST = "SEARCHTEST"; >+ >+QUERY: searchtest {"caseSensitive":true,"isRegex":true} >+SCRIPT: eval2.js >+RESULTS: 0 >+ >+QUERY: SEARCHtest {} >+SCRIPT: eval2.js >+RESULTS: 1 >+ LINE: 0 >+ CONTENT: var SEARCHTEST = "SEARCHTEST"; >+ >+QUERY: SEARCHtest {"caseSensitive":true} >+SCRIPT: eval2.js >+RESULTS: 0 >+ >+QUERY: SEARCHtest {"isRegex":true} >+SCRIPT: eval2.js >+RESULTS: 1 >+ LINE: 0 >+ CONTENT: var SEARCHTEST = "SEARCHTEST"; >+ >+QUERY: SEARCHtest {"caseSensitive":true,"isRegex":true} >+SCRIPT: eval2.js >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {} >+SCRIPT: eval2.js >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {"caseSensitive":true} >+SCRIPT: eval2.js >+RESULTS: 0 >+ >+QUERY: (search|OTHER)TEST {"isRegex":true} >+SCRIPT: eval2.js >+RESULTS: 2 >+ LINE: 0 >+ CONTENT: var SEARCHTEST = "SEARCHTEST"; >+ LINE: 1 >+ CONTENT: var OTHERTEST = "OTHERTEST"; >+ >+QUERY: (search|OTHER)TEST {"caseSensitive":true,"isRegex":true} >+SCRIPT: eval2.js >+RESULTS: 1 >+ LINE: 1 >+ CONTENT: var OTHERTEST = "OTHERTEST"; >+ >diff --git a/LayoutTests/inspector/debugger/search-scripts.html b/LayoutTests/inspector/debugger/search-scripts.html >index c4c81616d8b009da1ba18e018e7cc8805df83f52..4097892b163a4cf92ac4f31676f11cb51559af45 100644 >--- a/LayoutTests/inspector/debugger/search-scripts.html >+++ b/LayoutTests/inspector/debugger/search-scripts.html >@@ -7,41 +7,63 @@ > function performEvals() > { > // Find the line with the search term. >- eval("// SEARCH" + "TEST: Eval 1\n//# sourceURL=eval1.js"); >+ eval("// SEARCH" + "TEST: Eval 1\n// OTHER" + "TEST: Eval 1\n//# sourceURL=eval1.js"); > // If the search term shows up multiple times on a single line, the line is returned once. >- eval("var SEARCH" + "TEST = \"SEARCH" + "TEST\";\n//# sourceURL=eval2.js"); >+ eval("var SEARCH" + "TEST = \"SEARCH" + "TEST\";\nvar OTHER" + "TEST = \"OTHER" + "TEST\";\n//# sourceURL=eval2.js"); > }; > > function test() > { >- function sanitizeScriptURL(url) { >- return url.substring(url.indexOf("LayoutTests")); >- } >+ InspectorTest.debug(); > > function chomp(line) { > return line.replace(/\n$/, ""); > } > >- var scriptsCount = 0; >- const expectedScriptsCount = 5; >+ function searchInContent(script, query, options = {}) { >+ return DebuggerAgent.searchInContent(script.id, query, options.caseSensitive, options.isRegex) >+ .then(({result}) => { >+ InspectorTest.log(""); >+ InspectorTest.log("QUERY: " + query + " " + JSON.stringify(options)); >+ InspectorTest.log("SCRIPT: " + sanitizeURL(script.sourceURL || script.url)); >+ InspectorTest.log("RESULTS: " + result.length); >+ for (let item of result) { >+ InspectorTest.log(" LINE: " + item.lineNumber); >+ InspectorTest.log(" CONTENT: " + chomp(item.lineContent)); >+ } >+ }); >+ } >+ >+ let scripts = new Map; > > WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, function(event) { >- var script = event.data.script; >- if (!/LayoutTests/.test(script.url) && !/eval\d\.js/.test(script.sourceURL)) >+ let {script} = event.data; >+ let url = script.sourceURL || script.url; >+ if (!/LayoutTests/.test(url) && !/eval\d\.js/.test(url)) > return; > >- DebuggerAgent.searchInContent(script.id, "SEARCHTEST", false, false, function(error, results) { >- InspectorTest.log(""); >- InspectorTest.log("SCRIPT: " + sanitizeScriptURL(script.sourceURL || script.url)); >- InspectorTest.log("RESULTS: " + results.length); >- for (var result of results) { >- InspectorTest.log(" LINE: " + result.lineNumber); >- InspectorTest.log(" CONTENT: " + chomp(result.lineContent)); >+ if (url.endsWith("inspector-test.js")) >+ return; >+ >+ InspectorTest.log("Script added: " + sanitizeURL(url)); >+ >+ scripts.set(url, script); >+ >+ if (url === "eval2.js") { >+ let promiseCallbacks = []; >+ for (let item of scripts.values()) { >+ for (let query of ["search" + "test", "SEARCH" + "test", "(search|OTHER)" + "TEST"]) { >+ promiseCallbacks.push(() => searchInContent(item, query)); >+ promiseCallbacks.push(() => searchInContent(item, query, {caseSensitive: true})); >+ promiseCallbacks.push(() => searchInContent(item, query, {isRegex: true})); >+ promiseCallbacks.push(() => searchInContent(item, query, {caseSensitive: true, isRegex: true})); >+ } > } > >- if (++scriptsCount === expectedScriptsCount) >+ Promise.chain(promiseCallbacks).then(() => { > InspectorTest.completeTest(); >- }); >+ }); >+ } > }); > > InspectorTest.addEventListener(FrontendTestHarness.Event.TestPageDidLoad, () => { >@@ -52,7 +74,7 @@ function test() > } > </script> > </head> >-<body onload="runTest(); // SEARCHTEST: onload attribute string"> >+<body onload="runTest(); // SEARCHTEST: onload attribute string // OTHERTEST: onload attribute string"> > <p>Test <code>DebuggerAgent.searchInContent</code> to search script content.</p> > </body> > </html> >diff --git a/LayoutTests/inspector/page/resources/search-script.js b/LayoutTests/inspector/page/resources/search-script.js >index bf72621adcc5b16d722a38cc5a9e09042acaa618..c8f12a53e5410c7bb7a09dd323d74f5f590650e7 100644 >--- a/LayoutTests/inspector/page/resources/search-script.js >+++ b/LayoutTests/inspector/page/resources/search-script.js >@@ -1 +1,3 @@ > // Script resource with the SEARCH-STRING. >+ >+// Script resource with the OTHER-STRING. >diff --git a/LayoutTests/inspector/page/resources/search-stylesheet.css b/LayoutTests/inspector/page/resources/search-stylesheet.css >index 06ead77adb660a1e6e4c03ca2c0236967ee403ed..10f42c293de44ad51f6a6326833e2f3381807e28 100644 >--- a/LayoutTests/inspector/page/resources/search-stylesheet.css >+++ b/LayoutTests/inspector/page/resources/search-stylesheet.css >@@ -1,4 +1,7 @@ > /* Stylesheet resource with the SEARCH-STRING */ >+ >+/* Stylesheet resource with the OTHER-STRING */ >+ > body { > color: black; > } >diff --git a/LayoutTests/inspector/page/resources/search-worker.js b/LayoutTests/inspector/page/resources/search-worker.js >index 0f6a66673dcf134f01217d91df1d613c6e8ec505..2b2e0ea6d7a7b87bdba6e252002e2fc39f4b448f 100644 >--- a/LayoutTests/inspector/page/resources/search-worker.js >+++ b/LayoutTests/inspector/page/resources/search-worker.js >@@ -1,5 +1,7 @@ > // Worker resource with the SEARCH-STRING. > >+// Worker resource with the OTHER-STRING. >+ > self.addEventListener("message", (event) => { > self.postMessage("echo: " + event.data); > }); >diff --git a/LayoutTests/inspector/page/resources/search-xhr.txt b/LayoutTests/inspector/page/resources/search-xhr.txt >index 941d23f00fbad131fd0c459c955e479a3e2f96a3..e0ca3c86cad29108bd694c60a33515b472a3df72 100644 >--- a/LayoutTests/inspector/page/resources/search-xhr.txt >+++ b/LayoutTests/inspector/page/resources/search-xhr.txt >@@ -1,2 +1,5 @@ > XHR Resource with the SEARCH-STRING. > XHR Resource with the SEARCH-STRING again! >+ >+XHR Resource with the OTHER-STRING. >+XHR Resource with the OTHER-STRING again! >diff --git a/LayoutTests/inspector/page/searchInResources-expected.txt b/LayoutTests/inspector/page/searchInResources-expected.txt >index 5c5c9d454d62b886757199cac5bd024d72914c73..68964e406bfa35e0774e770c462be07186c58f0a 100644 >--- a/LayoutTests/inspector/page/searchInResources-expected.txt >+++ b/LayoutTests/inspector/page/searchInResources-expected.txt >@@ -10,12 +10,64 @@ FOUND: inspector/page/resources/search-worker.js (1) > FOUND: inspector/page/resources/search-xhr.txt (2) > FOUND: inspector/page/searchInResources.html (1) > >+-- Running test case: SearchAllResources.CaseSensitive >+PASS: Should find results in multiple resources. >+FOUND: inspector/page/resources/search-script.js (1) >+FOUND: inspector/page/resources/search-stylesheet.css (1) >+FOUND: inspector/page/resources/search-worker.js (1) >+FOUND: inspector/page/resources/search-xhr.txt (2) >+ >+-- Running test case: SearchAllResources.IsRegex >+PASS: Should find results in multiple resources. >+FOUND: inspector/page/resources/search-script.js (2) >+FOUND: inspector/page/resources/search-stylesheet.css (2) >+FOUND: inspector/page/resources/search-worker.js (2) >+FOUND: inspector/page/resources/search-xhr.txt (4) >+FOUND: inspector/page/searchInResources.html (1) >+ >+-- Running test case: SearchAllResources.CaseSensitiveIsRegex >+PASS: Should find results in multiple resources. >+FOUND: inspector/page/resources/search-script.js (1) >+FOUND: inspector/page/resources/search-stylesheet.css (1) >+FOUND: inspector/page/resources/search-worker.js (1) >+FOUND: inspector/page/resources/search-xhr.txt (2) >+ > -- Running test case: SearchInScriptResource >-PASS: Should find previously mentioned number of matches. >+PASS: Should find 1 matches. > MATCH: {"lineNumber":0,"lineContent":"// Script resource with the SEARCH-STRING.\n"} > >+-- Running test case: SearchInScriptResource.CaseSensitive >+PASS: Should find 1 matches. >+MATCH: {"lineNumber":0,"lineContent":"// Script resource with the SEARCH-STRING.\n"} >+ >+-- Running test case: SearchInScriptResource.IsRegex >+PASS: Should find 2 matches. >+MATCH: {"lineNumber":0,"lineContent":"// Script resource with the SEARCH-STRING.\n"} >+MATCH: {"lineNumber":2,"lineContent":"// Script resource with the OTHER-STRING.\n"} >+ >+-- Running test case: SearchInScriptResource.CaseSensitiveIsRegex >+PASS: Should find 1 matches. >+MATCH: {"lineNumber":2,"lineContent":"// Script resource with the OTHER-STRING.\n"} >+ > -- Running test case: SearchInXHRResource >-PASS: Should find previously mentioned number of matches. >+PASS: Should find 2 matches. > MATCH: {"lineNumber":0,"lineContent":"XHR Resource with the SEARCH-STRING.\n"} > MATCH: {"lineNumber":1,"lineContent":"XHR Resource with the SEARCH-STRING again!\n"} > >+-- Running test case: SearchInXHRResource.CaseSensitive >+PASS: Should find 2 matches. >+MATCH: {"lineNumber":0,"lineContent":"XHR Resource with the SEARCH-STRING.\n"} >+MATCH: {"lineNumber":1,"lineContent":"XHR Resource with the SEARCH-STRING again!\n"} >+ >+-- Running test case: SearchInXHRResource.IsRegex >+PASS: Should find 4 matches. >+MATCH: {"lineNumber":0,"lineContent":"XHR Resource with the SEARCH-STRING.\n"} >+MATCH: {"lineNumber":1,"lineContent":"XHR Resource with the SEARCH-STRING again!\n"} >+MATCH: {"lineNumber":3,"lineContent":"XHR Resource with the OTHER-STRING.\n"} >+MATCH: {"lineNumber":4,"lineContent":"XHR Resource with the OTHER-STRING again!\n"} >+ >+-- Running test case: SearchInXHRResource.CaseSensitiveIsRegex >+PASS: Should find 2 matches. >+MATCH: {"lineNumber":3,"lineContent":"XHR Resource with the OTHER-STRING.\n"} >+MATCH: {"lineNumber":4,"lineContent":"XHR Resource with the OTHER-STRING again!\n"} >+ >diff --git a/LayoutTests/inspector/page/searchInResources.html b/LayoutTests/inspector/page/searchInResources.html >index c48d8b43ea30943ea0ecd83d9e762eba509d08ca..17f70925e4a4ff283e3ed47b4474b953728ab158 100644 >--- a/LayoutTests/inspector/page/searchInResources.html >+++ b/LayoutTests/inspector/page/searchInResources.html >@@ -26,8 +26,14 @@ function test() > > let suite = InspectorTest.createAsyncSuite("Page.searchInResources and Page.searchInResource"); > >- let searchResults; >- const searchString = "SEARCH-STRING"; >+ const searchString = "SeArCh-StRiNg"; >+ const searchStringCaseSensitive = searchString.toUpperCase(); >+ const searchStringRegex = "(search|OTHER)-STRING"; >+ >+ let searchResults = null; >+ let searchResultsCaseSensitive = null; >+ let searchResultsIsRegex = null; >+ let searchResultsCaseSensitiveIsRegex = null; > > suite.addTestCase({ > name: "SearchAllResources", >@@ -44,6 +50,56 @@ function test() > } > }); > >+ suite.addTestCase({ >+ name: "SearchAllResources.CaseSensitive", >+ description: "Able to find text results in different resources.", >+ test(resolve, reject) { >+ const caseSensitive = true; >+ PageAgent.searchInResources(searchStringCaseSensitive, caseSensitive, (error, results) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(results.length > 0, "Should find results in multiple resources."); >+ searchResultsCaseSensitive = results.sort((a, b) => a.url.localeCompare(b.url)); >+ for (let result of searchResultsCaseSensitive) >+ InspectorTest.log(`FOUND: ${sanitizeURL(result.url)} (${result.matchesCount})`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchAllResources.IsRegex", >+ description: "Able to find text results in different resources.", >+ test(resolve, reject) { >+ const caseSensitive = undefined; >+ const isRegex = true; >+ PageAgent.searchInResources(searchStringRegex, caseSensitive, isRegex, (error, results) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(results.length > 0, "Should find results in multiple resources."); >+ searchResultsIsRegex = results.sort((a, b) => a.url.localeCompare(b.url)); >+ for (let result of searchResultsIsRegex) >+ InspectorTest.log(`FOUND: ${sanitizeURL(result.url)} (${result.matchesCount})`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchAllResources.CaseSensitiveIsRegex", >+ description: "Able to find text results in different resources.", >+ test(resolve, reject) { >+ const caseSensitive = true; >+ const isRegex = true; >+ PageAgent.searchInResources(searchStringRegex, caseSensitive, isRegex, (error, results) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(results.length > 0, "Should find results in multiple resources."); >+ searchResultsCaseSensitiveIsRegex = results.sort((a, b) => a.url.localeCompare(b.url)); >+ for (let result of searchResultsCaseSensitiveIsRegex) >+ InspectorTest.log(`FOUND: ${sanitizeURL(result.url)} (${result.matchesCount})`); >+ resolve(); >+ }); >+ } >+ }); >+ > suite.addTestCase({ > name: "SearchInScriptResource", > description: "Able to find text results in an individual Script resource.", >@@ -54,7 +110,66 @@ function test() > > PageAgent.searchInResource(result.frameId, result.url, searchString, (error, matches) => { > InspectorTest.assert(!error, "Should not be a protocol error."); >- InspectorTest.expectThat(matches.length === result.matchesCount, "Should find previously mentioned number of matches."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); >+ for (let match of matches) >+ InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchInScriptResource.CaseSensitive", >+ description: "Able to find text results in an individual Script resource.", >+ test(resolve, reject) { >+ let result = searchResultsCaseSensitive.find((result) => /search-script\.js$/.test(result.url)); >+ if (!result) >+ reject(); >+ >+ const caseSensitive = true; >+ PageAgent.searchInResource(result.frameId, result.url, searchStringCaseSensitive, caseSensitive, (error, matches) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); >+ for (let match of matches) >+ InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchInScriptResource.IsRegex", >+ description: "Able to find text results in an individual Script resource.", >+ test(resolve, reject) { >+ let result = searchResultsIsRegex.find((result) => /search-script\.js$/.test(result.url)); >+ if (!result) >+ reject(); >+ >+ const caseSensitive = undefined; >+ const isRegex = true; >+ PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, (error, matches) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); >+ for (let match of matches) >+ InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchInScriptResource.CaseSensitiveIsRegex", >+ description: "Able to find text results in an individual Script resource.", >+ test(resolve, reject) { >+ let result = searchResultsCaseSensitiveIsRegex.find((result) => /search-script\.js$/.test(result.url)); >+ if (!result) >+ reject(); >+ >+ const caseSensitive = true; >+ const isRegex = true; >+ PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, (error, matches) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); > for (let match of matches) > InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); > resolve(); >@@ -75,7 +190,70 @@ function test() > > PageAgent.searchInResource(result.frameId, result.url, searchString, caseSensitive, isRegex, result.requestId, (error, matches) => { > InspectorTest.assert(!error, "Should not be a protocol error."); >- InspectorTest.expectThat(matches.length === result.matchesCount, "Should find previously mentioned number of matches."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); >+ for (let match of matches) >+ InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchInXHRResource.CaseSensitive", >+ description: "Able to find text results in an individual XHR resource.", >+ test(resolve, reject) { >+ let result = searchResultsCaseSensitive.find((result) => /search-xhr\.txt$/.test(result.url)); >+ if (!result) >+ reject(); >+ >+ const isRegex = undefined; >+ const caseSensitive = true; >+ >+ PageAgent.searchInResource(result.frameId, result.url, searchStringCaseSensitive, caseSensitive, isRegex, result.requestId, (error, matches) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); >+ for (let match of matches) >+ InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchInXHRResource.IsRegex", >+ description: "Able to find text results in an individual XHR resource.", >+ test(resolve, reject) { >+ let result = searchResultsIsRegex.find((result) => /search-xhr\.txt$/.test(result.url)); >+ if (!result) >+ reject(); >+ >+ const isRegex = true; >+ const caseSensitive = undefined; >+ >+ PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, result.requestId, (error, matches) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); >+ for (let match of matches) >+ InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); >+ resolve(); >+ }); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "SearchInXHRResource.CaseSensitiveIsRegex", >+ description: "Able to find text results in an individual XHR resource.", >+ test(resolve, reject) { >+ let result = searchResultsCaseSensitiveIsRegex.find((result) => /search-xhr\.txt$/.test(result.url)); >+ if (!result) >+ reject(); >+ >+ const isRegex = true; >+ const caseSensitive = true; >+ >+ PageAgent.searchInResource(result.frameId, result.url, searchStringRegex, caseSensitive, isRegex, result.requestId, (error, matches) => { >+ InspectorTest.assert(!error, "Should not be a protocol error."); >+ InspectorTest.expectThat(matches.length === result.matchesCount, `Should find ${result.matchesCount} matches.`); > for (let match of matches) > InspectorTest.log(`MATCH: ${JSON.stringify(match)}`); > resolve();
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192527
:
356875
|
356876
|
356877
|
358180
|
358575
|
362058
|
362075
|
362872