Migrate escapeForRegExp to string-utilities

R=szuend@chromium.org

Bug: 1050549
Change-Id: I5cd76d53567108ac972bfc9bf002694c2219e00a
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2631117
Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
Auto-Submit: Tim van der Lippe <tvanderlippe@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
This commit is contained in:
Tim van der Lippe
2021-01-20 13:20:00 +00:00
committed by Commit Bot
parent 10e970269b
commit bafa3bd3e7
15 changed files with 41 additions and 44 deletions
+3 -2
View File
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import * as Common from '../common/common.js';
import * as Platform from '../platform/platform.js';
import * as SDK from '../sdk/sdk.js';
import * as Workspace from '../workspace/workspace.js';
@@ -366,7 +367,7 @@ export class IgnoreListManager {
return '';
}
if (!parsedURL.isValid) {
return '^' + url.escapeForRegExp() + '$';
return '^' + Platform.StringUtilities.escapeForRegExp(url) + '$';
}
let name = parsedURL.lastPathComponent;
if (name) {
@@ -389,7 +390,7 @@ export class IgnoreListManager {
}
prefix += '.*';
}
return prefix + name.escapeForRegExp() + (url.endsWith(name) ? '$' : '\\b');
return prefix + Platform.StringUtilities.escapeForRegExp(name) + (url.endsWith(name) ? '$' : '\\b');
}
}
+2 -1
View File
@@ -32,6 +32,7 @@ import * as Common from '../common/common.js';
import * as Components from '../components/components.js';
import * as Host from '../host/host.js';
import * as InlineEditor from '../inline_editor/inline_editor.js';
import * as Platform from '../platform/platform.js';
import {ls} from '../platform/platform.js';
import * as Root from '../root/root.js';
import * as SDK from '../sdk/sdk.js';
@@ -250,7 +251,7 @@ export class StylesSidebarPane extends ElementsSidebarPane {
input.placeholder = placeholder;
function searchHandler() {
const regex = input.value ? new RegExp(input.value.escapeForRegExp(), 'i') : null;
const regex = input.value ? new RegExp(Platform.StringUtilities.escapeForRegExp(input.value), 'i') : null;
filterCallback(regex);
}
input.addEventListener('input', searchHandler, false);
-4
View File
@@ -27,10 +27,6 @@ interface Uint32Array {
upperBound(value: number, comparator?: {(a: number, b: number): number}, left?: number, right?: number): number;
}
interface String {
escapeForRegExp(): string;
}
interface RegExp {
__fromRegExpQuery: boolean;
}
+5 -11
View File
@@ -282,14 +282,7 @@ export class NetworkLogView extends UI.Widget.VBox {
* @return {!Filter}
*/
static _createRequestDomainFilter(value) {
/**
* @param {string} string
* @return {string}
*/
function escapeForRegExp(string) {
return string.escapeForRegExp();
}
const escapedPattern = value.split('*').map(escapeForRegExp).join('.*');
const escapedPattern = value.split('*').map(Platform.StringUtilities.escapeForRegExp).join('.*');
return NetworkLogView._requestDomainFilter.bind(null, new RegExp('^' + escapedPattern + '$', 'i'));
}
@@ -506,7 +499,7 @@ export class NetworkLogView extends UI.Widget.VBox {
* @return {boolean}
*/
static _requestUrlFilter(value, request) {
const regex = new RegExp(value.escapeForRegExp(), 'i');
const regex = new RegExp(Platform.StringUtilities.escapeForRegExp(value), 'i');
return regex.test(request.url());
}
@@ -1713,13 +1706,14 @@ export class NetworkLogView extends UI.Widget.VBox {
const regex = descriptor.regex;
let filter;
if (key) {
const defaultText = (key + ':' + text).escapeForRegExp();
const defaultText = Platform.StringUtilities.escapeForRegExp(key + ':' + text);
filter = this._createSpecialFilter(/** @type {!FilterType} */ (key), text) ||
NetworkLogView._requestPathFilter.bind(null, new RegExp(defaultText, 'i'));
} else if (descriptor.regex) {
filter = NetworkLogView._requestPathFilter.bind(null, /** @type {!RegExp} */ (regex));
} else {
filter = NetworkLogView._requestPathFilter.bind(null, new RegExp(text.escapeForRegExp(), 'i'));
filter = NetworkLogView._requestPathFilter.bind(
null, new RegExp(Platform.StringUtilities.escapeForRegExp(text), 'i'));
}
return descriptor.negative ? NetworkLogView._negativeFilter.bind(null, filter) : filter;
});
+8 -3
View File
@@ -357,16 +357,17 @@ export const removeURLFragment = (inputStr: string): string => {
return url.toString();
};
const SPECIAL_REGEX_CHARACTERS = '^[]{}()\\.^$*+?|-,';
export const regexSpecialCharacters = function(): string {
return '^[]{}()\\.^$*+?|-,';
return SPECIAL_REGEX_CHARACTERS;
};
export const filterRegex = function(query: string): RegExp {
const toEscape = regexSpecialCharacters();
let regexString = '';
for (let i = 0; i < query.length; ++i) {
let c = query.charAt(i);
if (toEscape.indexOf(c) !== -1) {
if (SPECIAL_REGEX_CHARACTERS.indexOf(c) !== -1) {
c = '\\' + c;
}
if (i) {
@@ -458,3 +459,7 @@ export const trimEndWithMaxLength = (str: string, maxLength: number): string =>
}
return str.substr(0, maxLength - 1) + '…';
};
export const escapeForRegExp = (str: string): string => {
return escapeCharacters(str, SPECIAL_REGEX_CHARACTERS);
};
+1 -9
View File
@@ -33,7 +33,7 @@
* that has been migrated, it will need to be imported.
*/
import {inverse} from './map-utilities.js';
import {caseInsensetiveComparator, escapeCharacters, regexSpecialCharacters, sprintf} from './string-utilities.js';
import {caseInsensetiveComparator, regexSpecialCharacters, sprintf} from './string-utilities.js';
// Still used in the test runners that can't use ES modules :(
String.sprintf = sprintf;
@@ -43,14 +43,6 @@ String.regexSpecialCharacters = regexSpecialCharacters;
// @ts-ignore https://crbug.com/1050549
String.caseInsensetiveComparator = caseInsensetiveComparator;
/**
* @this {string}
* @return {string}
*/
String.prototype.escapeForRegExp = function() {
return escapeCharacters(this, regexSpecialCharacters());
};
/**
* @param {string} a
* @param {string} b
+2 -1
View File
@@ -7,6 +7,7 @@
import * as Common from '../common/common.js';
import * as i18n from '../i18n/i18n.js';
import * as Persistence from '../persistence/persistence.js';
import * as Platform from '../platform/platform.js';
import * as TextUtils from '../text_utils/text_utils.js'; // eslint-disable-line no-unused-vars
import * as Workspace from '../workspace/workspace.js'; // eslint-disable-line no-unused-vars
@@ -109,7 +110,7 @@ export class RecordingFileSystem extends Persistence.PlatformFileSystem.Platform
}
async searchInPath(query: string, _progress: Common.Progress.Progress): Promise<string[]> {
const re = new RegExp(query.escapeForRegExp(), 'i');
const re = new RegExp(Platform.StringUtilities.escapeForRegExp(query), 'i');
const allRecordings: Recording[] = this._recordingsSetting.get();
const matchedRecordings = allRecordings.filter(recording => recording.content.match(re));
return matchedRecordings.map(recording => `recording:///${escapeRecordingName(recording.name)}`);
+2 -1
View File
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import * as Common from '../common/common.js';
import * as Platform from '../platform/platform.js';
import * as UI from '../ui/ui.js';
export class StorageItemsView extends UI.Widget.VBox {
@@ -74,7 +75,7 @@ export class StorageItemsView extends UI.Widget.VBox {
*/
_filterChanged(event) {
const text = /** @type {?string} */ (event.data);
this._filterRegex = text ? new RegExp(text.escapeForRegExp(), 'i') : null;
this._filterRegex = text ? new RegExp(Platform.StringUtilities.escapeForRegExp(text), 'i') : null;
this.refreshItems();
}
+3 -1
View File
@@ -30,6 +30,7 @@
import * as Common from '../common/common.js';
import * as Host from '../host/host.js';
import * as Platform from '../platform/platform.js';
import * as ProtocolClient from '../protocol_client/protocol_client.js'; // eslint-disable-line no-unused-vars
import * as Root from '../root/root.js';
@@ -432,7 +433,8 @@ export class DebuggerModel extends SDKModel {
let urlRegex;
if (this.target().type() === Type.Node) {
const platformPath = Common.ParsedURL.ParsedURL.urlToPlatformPath(url, Host.Platform.isWin());
urlRegex = `${platformPath.escapeForRegExp()}|${url.escapeForRegExp()}`;
urlRegex =
`${Platform.StringUtilities.escapeForRegExp(platformPath)}|${Platform.StringUtilities.escapeForRegExp(url)}`;
}
// Adjust column if needed.
let minColumnNumber = 0;
+1 -1
View File
@@ -1234,7 +1234,7 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper {
* @return {!Array.<!NameValue>}
*/
_parseMultipartFormDataParameters(data, boundary) {
const sanitizedBoundary = boundary.escapeForRegExp();
const sanitizedBoundary = Platform.StringUtilities.escapeForRegExp(boundary);
const keyValuePattern = new RegExp(
// Header with an optional file name.
'^\\r\\ncontent-disposition\\s*:\\s*form-data\\s*;\\s*name="([^"]*)"(?:\\s*;\\s*filename="([^"]*)")?' +
@@ -7,6 +7,7 @@
import * as Common from '../common/common.js';
import * as i18n from '../i18n/i18n.js';
import * as Persistence from '../persistence/persistence.js';
import * as Platform from '../platform/platform.js';
import * as SDK from '../sdk/sdk.js';
import * as TextUtils from '../text_utils/text_utils.js'; // eslint-disable-line no-unused-vars
import * as UI from '../ui/ui.js';
@@ -110,7 +111,7 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
}
async searchInPath(query: string, _progress: Common.Progress.Progress): Promise<string[]> {
const re = new RegExp(query.escapeForRegExp(), 'i');
const re = new RegExp(Platform.StringUtilities.escapeForRegExp(query), 'i');
const allSnippets: Snippet[] = this._snippetsSetting.get();
const matchedSnippets = allSnippets.filter(snippet => snippet.content.match(re));
return matchedSnippets.map(snippet => `snippet:///${escapeSnippetName(snippet.name)}`);
@@ -1862,7 +1862,7 @@ export class SelectNextOccurrenceController {
return undefined;
}
let regexSource = textToFind.escapeForRegExp();
let regexSource = Platform.StringUtilities.escapeForRegExp(textToFind);
if (fullWord) {
regexSource = '\\b' + regexSource + '\\b';
}
+4 -2
View File
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Platform from '../platform/platform.js';
import {Suggestion, Suggestions} from './SuggestBox.js'; // eslint-disable-line no-unused-vars
export class FilterSuggestionBuilder {
@@ -37,7 +39,7 @@ export class FilterSuggestionBuilder {
/** @type {!Suggestions} */
const suggestions = [];
if (valueDelimiterIndex === -1) {
const matcher = new RegExp('^' + prefix.escapeForRegExp(), 'i');
const matcher = new RegExp('^' + Platform.StringUtilities.escapeForRegExp(prefix), 'i');
for (const key of this._keys) {
if (matcher.test(key)) {
suggestions.push(/** @type {!Suggestion} */ ({text: modifier + key + ':'}));
@@ -46,7 +48,7 @@ export class FilterSuggestionBuilder {
} else {
const key = prefix.substring(0, valueDelimiterIndex).toLowerCase();
const value = prefix.substring(valueDelimiterIndex + 1);
const matcher = new RegExp('^' + value.escapeForRegExp(), 'i');
const matcher = new RegExp('^' + Platform.StringUtilities.escapeForRegExp(value), 'i');
const values = Array.from(this._valuesMap.get(key) || new Set());
this._valueSorter(key, values);
for (const item of values) {
@@ -622,4 +622,11 @@ describe('StringUtilities', () => {
}
});
describe('escapeForRegExp', () => {
it('escapes regex characters', () => {
const inputString = '^[]{}()\\.^$*+?|-';
const outputString = Platform.StringUtilities.escapeForRegExp(inputString);
assert.strictEqual(outputString, '\\^\\[\\]\\{\\}\\(\\)\\\\\\.\\^\\$\\*\\+\\?\\|\\-');
});
});
});
@@ -108,10 +108,4 @@ describe('Utilities', () => {
}
}
});
it('escapes regex characters', () => {
const inputString = '^[]{}()\\.^$*+?|-';
const outputString = inputString.escapeForRegExp();
assert.strictEqual(outputString, '\\^\\[\\]\\{\\}\\(\\)\\\\\\.\\^\\$\\*\\+\\?\\|\\-');
});
});