Skip to content

Commit 2c999d5

Browse files
authored
fix(replace): update delimiters to respect valid js identifier chars (#1938)
* fix(replace): update delimiters to respect valid js identifier chars * test: update snapshots
1 parent 2c8b0e1 commit 2c999d5

File tree

6 files changed

+64
-6
lines changed

6 files changed

+64
-6
lines changed

β€Žpackages/replace/README.mdβ€Ž

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ In addition to the properties and values specified for replacement, users may al
6161
### `delimiters`
6262

6363
Type: `Array[String, String]`<br>
64-
Default: `['\\b', '\\b(?!\\.)']`
64+
Default: `['(?<![_$a-zA-Z0-9\\xA0-\\uFFFF])', '(?![_$a-zA-Z0-9\\xA0-\\uFFFF])(?!\\.)']`
6565

66-
Specifies the boundaries around which strings will be replaced. By default, delimiters are [word boundaries](https://www.regular-expressions.info/wordboundaries.html) and also prevent replacements of instances with nested access. See [Word Boundaries](#word-boundaries) below for more information.
66+
Specifies the boundaries around which strings will be replaced. By default, delimiters match JavaScript identifier boundaries and also prevent replacements of instances with nested access. See [Word Boundaries](#word-boundaries) below for more information.
6767
For example, if you pass `typeof window` in `values` to-be-replaced, then you could expect the following scenarios:
6868

6969
- `typeof window` **will** be replaced
70-
- `typeof window.document` **will not** be replaced due to `(?!\.)` boundary
71-
- `typeof windowSmth` **will not** be replaced due to a `\b` boundary
70+
- `typeof window.document` **will not** be replaced due to the `(?!\.)` boundary
71+
- `typeof windowSmth` **will not** be replaced due to identifier boundaries
7272

7373
Delimiters will be used to build a `Regexp`. To match special characters (any of `.*+?^${}()|[]\`), be sure to [escape](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping) them.
7474

@@ -194,7 +194,7 @@ replace({
194194

195195
## Word Boundaries
196196

197-
By default, values will only match if they are surrounded by _word boundaries_.
197+
By default, values will only match if they are surrounded by _word boundaries_ that respect JavaScript's rules for valid identifiers (including `$` and `_` as valid identifier characters).
198198

199199
Consider the following options and build file:
200200

β€Žpackages/replace/src/index.jsβ€Ž

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ function expandTypeofReplacements(replacements) {
5454

5555
export default function replace(options = {}) {
5656
const filter = createFilter(options.include, options.exclude);
57-
const { delimiters = ['\\b', '\\b(?!\\.)'], preventAssignment, objectGuards } = options;
57+
const {
58+
delimiters = ['(?<![_$a-zA-Z0-9\\xA0-\\uFFFF])', '(?![_$a-zA-Z0-9\\xA0-\\uFFFF])(?!\\.)'],
59+
preventAssignment,
60+
objectGuards
61+
} = options;
5862
const replacements = getReplacements(options);
5963
if (objectGuards) expandTypeofReplacements(replacements);
6064
const functionValues = mapToFunctions(replacements);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
description: 'should not replace when followed by valid identifier characters',
3+
options: {
4+
values: {
5+
'typeof window': '"undefined"'
6+
},
7+
preventAssignment: true
8+
}
9+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* eslint-disable no-undef */
2+
// Should NOT be replaced - window$1 is a different identifier
3+
if (typeof window$1 === 'undefined') {
4+
console.log('no window$1');
5+
}
6+
7+
// Should be replaced - standalone typeof window
8+
if (typeof window === 'undefined') {
9+
console.log('no window');
10+
}
11+
12+
// Should NOT be replaced - window_ is a different identifier
13+
if (typeof window_ !== 'undefined') {
14+
console.log('has window_');
15+
}
16+
17+
// Should be replaced - typeof window followed by dot
18+
if (typeof window.document !== 'undefined') {
19+
console.log('has document');
20+
}

β€Žpackages/replace/test/snapshots/form.js.mdβ€Ž

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,31 @@ Generated by [AVA](https://avajs.dev).
2020
<%original %>␊
2121
\`);`
2222

23+
## dollar-sign-boundary: should not replace when followed by valid identifier characters
24+
25+
> Snapshot 1
26+
27+
`/* eslint-disable no-undef */␊
28+
// Should NOT be replaced - window$1 is a different identifier␊
29+
if (typeof window$1 === 'undefined') {␊
30+
console.log('no window$1');␊
31+
}␊
32+
␊
33+
// Should be replaced - standalone "undefined"␊
34+
if ("undefined" === 'undefined') {␊
35+
console.log('no window');␊
36+
}␊
37+
␊
38+
// Should NOT be replaced - window_ is a different identifier ␊
39+
if (typeof window_ !== 'undefined') {␊
40+
console.log('has window_');␊
41+
}␊
42+
␊
43+
// Should be replaced - "undefined" followed by dot␊
44+
if (typeof window.document !== 'undefined') {␊
45+
console.log('has document');␊
46+
}`
47+
2348
## match-variables: matches most specific variables
2449

2550
> Snapshot 1
173 Bytes
Binary file not shown.

0 commit comments

Comments
Β (0)