Skip to content

Commit fd1d887

Browse files
authored
feat: replace(All) support replacement for functions when the first parameter is a string (#304)
1 parent 0005025 commit fd1d887

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

src/MagicString.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,12 @@ export default class MagicString {
860860
const index = original.indexOf(string);
861861

862862
if (index !== -1) {
863-
this.overwrite(index, index + string.length, replacement);
863+
if (typeof replacement === 'function') {
864+
replacement = replacement(string, index, original);
865+
}
866+
if (string !== replacement) {
867+
this.overwrite(index, index + string.length, replacement);
868+
}
864869
}
865870

866871
return this;
@@ -883,7 +888,11 @@ export default class MagicString {
883888
index = original.indexOf(string, index + stringLength)
884889
) {
885890
const previous = original.slice(index, index + stringLength);
886-
if (previous !== replacement) this.overwrite(index, index + stringLength, replacement);
891+
let _replacement = replacement;
892+
if (typeof replacement === 'function') {
893+
_replacement = replacement(previous, index, original);
894+
}
895+
if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);
887896
}
888897

889898
return this;

test/MagicString.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,6 +1804,23 @@ describe('MagicString', () => {
18041804
assert.strictEqual(s.toString(), '1 3 1 2');
18051805
});
18061806

1807+
it('works with string replace and function replacer', () => {
1808+
const code = '1 2 1 2';
1809+
const s = new MagicString(code);
1810+
let index = -1;
1811+
let _str = '';
1812+
1813+
s.replace('2', (match, i, str) => {
1814+
index = i;
1815+
_str = str;
1816+
return match + '-3';
1817+
});
1818+
1819+
assert.strictEqual(s.toString(), '1 2-3 1 2');
1820+
assert.strictEqual(index, 2);
1821+
assert.strictEqual(_str, code);
1822+
});
1823+
18071824
it('Should not treat string as regexp', () => {
18081825
assert.strictEqual(new MagicString('1234').replace('.', '*').toString(), '1234');
18091826
});
@@ -1879,6 +1896,22 @@ describe('MagicString', () => {
18791896
it('works with string replace', () => {
18801897
assert.strictEqual(new MagicString('1212').replaceAll('2', '3').toString(), '1313');
18811898
});
1899+
it('works with string replace and function replacer', () => {
1900+
const code = '1 2 1 2';
1901+
const s = new MagicString(code);
1902+
const indexs = [];
1903+
const _strs = [];
1904+
1905+
s.replaceAll('2', (match, i, str) => {
1906+
indexs.push(i);
1907+
_strs.push(str);
1908+
return match + '-3';
1909+
});
1910+
1911+
assert.strictEqual(s.toString(), '1 2-3 1 2-3');
1912+
assert.deepStrictEqual(indexs, [2, 6]);
1913+
assert.deepStrictEqual(_strs, [code, code]);
1914+
});
18821915

18831916
it('Should not treat string as regexp', () => {
18841917
assert.strictEqual(new MagicString('1234').replaceAll('.', '*').toString(), '1234');

0 commit comments

Comments
 (0)