diff --git a/src/MagicString.js b/src/MagicString.js index 5cf6717..9543c94 100644 --- a/src/MagicString.js +++ b/src/MagicString.js @@ -860,7 +860,12 @@ export default class MagicString { const index = original.indexOf(string); if (index !== -1) { - this.overwrite(index, index + string.length, replacement); + if (typeof replacement === 'function') { + replacement = replacement(string, index, original); + } + if (string !== replacement) { + this.overwrite(index, index + string.length, replacement); + } } return this; @@ -883,7 +888,11 @@ export default class MagicString { index = original.indexOf(string, index + stringLength) ) { const previous = original.slice(index, index + stringLength); - if (previous !== replacement) this.overwrite(index, index + stringLength, replacement); + let _replacement = replacement; + if (typeof replacement === 'function') { + _replacement = replacement(previous, index, original); + } + if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement); } return this; diff --git a/test/MagicString.test.js b/test/MagicString.test.js index e54a392..371bda4 100644 --- a/test/MagicString.test.js +++ b/test/MagicString.test.js @@ -1804,6 +1804,23 @@ describe('MagicString', () => { assert.strictEqual(s.toString(), '1 3 1 2'); }); + it('works with string replace and function replacer', () => { + const code = '1 2 1 2'; + const s = new MagicString(code); + let index = -1; + let _str = ''; + + s.replace('2', (match, i, str) => { + index = i; + _str = str; + return match + '-3'; + }); + + assert.strictEqual(s.toString(), '1 2-3 1 2'); + assert.strictEqual(index, 2); + assert.strictEqual(_str, code); + }); + it('Should not treat string as regexp', () => { assert.strictEqual(new MagicString('1234').replace('.', '*').toString(), '1234'); }); @@ -1879,6 +1896,22 @@ describe('MagicString', () => { it('works with string replace', () => { assert.strictEqual(new MagicString('1212').replaceAll('2', '3').toString(), '1313'); }); + it('works with string replace and function replacer', () => { + const code = '1 2 1 2'; + const s = new MagicString(code); + const indexs = []; + const _strs = []; + + s.replaceAll('2', (match, i, str) => { + indexs.push(i); + _strs.push(str); + return match + '-3'; + }); + + assert.strictEqual(s.toString(), '1 2-3 1 2-3'); + assert.deepStrictEqual(indexs, [2, 6]); + assert.deepStrictEqual(_strs, [code, code]); + }); it('Should not treat string as regexp', () => { assert.strictEqual(new MagicString('1234').replaceAll('.', '*').toString(), '1234');