Skip to content

Commit

Permalink
Merge pull request #524 from zloirock/string-replace-all-stage-2
Browse files Browse the repository at this point in the history
Move `String#replaceAll` to stage 2, update behavior by the spec draft
  • Loading branch information
zloirock authored May 11, 2019
2 parents 1f8b914 + 1678ce6 commit 979940f
Show file tree
Hide file tree
Showing 19 changed files with 123 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
##### 3.1.0
- `String#matchAll` moved to stable ES, exposed `Symbol.matchAll`, [babel/proposals#57 (comment)](https://github.com/babel/proposals/issues/57#issuecomment-476783115)
- `Promise.allSettled` moved to stage 3, [babel/proposals#57 (comment)](https://github.com/babel/proposals/issues/57#issuecomment-476837985)
- `String#replaceAll` moved to stage 2, behavior updated by the spec draft, [babel/proposals#57 (comment)](https://github.com/babel/proposals/issues/57#issuecomment-476838130), [`https://tc39.github.io/proposal-string-replaceall/`](https://tc39.github.io/proposal-string-replaceall/)
- `Promise.any` moved to stage 1, [babel/proposals#57 (comment)](https://github.com/babel/proposals/issues/57#issuecomment-477335963)
- Removed `es.regexp.flags` dependency from `es.regexp.to-string`, [#536](https://github.com/zloirock/core-js/issues/536), [#537](https://github.com/zloirock/core-js/issues/537)
- Fixed IE8- non-enumerable properties support in `Object.{ assign, entries, values }`, [#541](https://github.com/zloirock/core-js/issues/541)
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,21 @@ new Set([1, 2, 3]).isDisjointFrom([4, 5, 6]); // => true
new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2, 1]); // => true
new Set([5, 4, 3, 2, 1]).isSupersetOf([1, 2, 3]); // => true
```
* `String#replaceAll` [proposal](https://github.com/tc39/proposal-string-replace-all) - module [`esnext.string.replace-all`](https://github.com/zloirock/core-js/blob/v3.0.1/packages/core-js/modules/esnext.string.replace-all.js)
```js
class String {
replaceAll(searchValue: string | RegExp, replaceString: string): string;
}
```
[*CommonJS entry points:*](#commonjs-api)
```js
core-js/proposals/string-replace-all
core-js/features/string/replace-all
```
[*Examples*](https://goo.gl/wUXNXN):
```js
'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'
```

#### Stage 1 proposals
[*CommonJS entry points:*](#commonjs-api)
Expand Down Expand Up @@ -1693,21 +1708,6 @@ array.lastItem = 4;
array; // => [1, 2, 4]
```
* `String#replaceAll` [proposal](https://github.com/tc39/proposal-string-replace-all) - module [`esnext.string.replace-all`](https://github.com/zloirock/core-js/blob/v3.0.1/packages/core-js/modules/esnext.string.replace-all.js)
```js
class String {
replaceAll(searchValue: string | RegExp, replaceString: string): string;
}
```
[*CommonJS entry points:*](#commonjs-api)
```js
core-js/proposals/string-replace-all
core-js/features/string/replace-all
```
[*Examples*](https://goo.gl/wUXNXN):
```js
'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'
```
* `Promise.try` [proposal](https://github.com/tc39/proposal-promise-try) - module [`esnext.promise.try`](https://github.com/zloirock/core-js/blob/v3.0.1/packages/core-js/modules/esnext.promise.try.js)
```js
class Promise {
Expand Down
2 changes: 2 additions & 0 deletions packages/core-js-compat/src/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,8 @@ const data = {
},
'esnext.symbol.pattern-match': {
},
'esnext.symbol.replace-all': {
},
'esnext.weak-map.delete-all': {
},
'esnext.weak-map.from': {
Expand Down
1 change: 1 addition & 0 deletions packages/core-js-compat/src/modules-by-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ module.exports = {
3.1: [
'es.string.match-all',
'es.symbol.match-all',
'esnext.symbol.replace-all',
],
};
1 change: 1 addition & 0 deletions packages/core-js/features/symbol/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ module.exports = require('../../es/symbol');
require('../../modules/esnext.symbol.dispose');
require('../../modules/esnext.symbol.observable');
require('../../modules/esnext.symbol.pattern-match');
require('../../modules/esnext.symbol.replace-all');
3 changes: 3 additions & 0 deletions packages/core-js/features/symbol/replace-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require('../../modules/esnext.symbol.replace-all');

module.exports = require('../../internals/wrapped-well-known-symbol').f('replaceAll');
44 changes: 36 additions & 8 deletions packages/core-js/modules/esnext.string.replace-all.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,50 @@
'use strict';
var hide = require('../internals/hide');
var requireObjectCoercible = require('../internals/require-object-coercible');
var anObject = require('../internals/an-object');
var isRegExp = require('../internals/is-regexp');
var getRegExpFlags = require('../internals/regexp-flags');
var speciesConstructor = require('../internals/species-constructor');
var REPLACE_ALL = require('../internals/well-known-symbol')('replaceAll');
var IS_PURE = require('../internals/is-pure');
var RegExpPrototype = RegExp.prototype;

var $replaceAll = function (string, replaceValue) {
var rx = anObject(this);
var flags = String('flags' in RegExpPrototype ? rx.flags : getRegExpFlags.call(rx));
if (!~flags.indexOf('g')) {
rx = new (speciesConstructor(rx, RegExp))(rx.source, flags + 'g');
}
return String(string).replace(rx, replaceValue);
};

// `String.prototype.replaceAll` method
// https://github.com/tc39/proposal-string-replace-all
require('../internals/export')({ target: 'String', proto: true }, {
replaceAll: function replaceAll(searchValue, replaceValue) {
var O = requireObjectCoercible(this);
var search, flags;
if (isRegExp(searchValue)) {
flags = getRegExpFlags.call(searchValue);
if (!~flags.indexOf('g')) {
search = new (speciesConstructor(searchValue, RegExp))(searchValue.source, flags + 'g');
} else search = searchValue;
return String(O).replace(search, replaceValue);
var replacer, string, searchString, template, result, i;
if (searchValue != null) {
replacer = searchValue[REPLACE_ALL];
if (replacer !== undefined) {
return replacer.call(searchValue, O, replaceValue);
} else if (IS_PURE && isRegExp(searchValue)) {
return $replaceAll.call(searchValue, O, replaceValue);
}
}
string = String(O);
searchString = String(searchValue);
template = string.split(searchString);
if (typeof replaceValue !== 'function') {
return template.join(String(replaceValue));
}
return String(O).split(searchValue).join(replaceValue);
result = template[0];
for (i = 1; i < template.length; i++) {
result += String(replaceValue(searchString, i - 1, string));
result += template[i];
}
return result;
}
});

IS_PURE || REPLACE_ALL in RegExpPrototype || hide(RegExpPrototype, REPLACE_ALL, $replaceAll);
3 changes: 3 additions & 0 deletions packages/core-js/modules/esnext.symbol.replace-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// `Symbol.replaceAll` well-known symbol
// https://tc39.github.io/proposal-string-replaceall/
require('../internals/define-well-known-symbol')('replaceAll');
1 change: 1 addition & 0 deletions packages/core-js/proposals/string-replace-all.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
require('../modules/esnext.string.replace-all');
require('../modules/esnext.symbol.replace-all');
1 change: 0 additions & 1 deletion packages/core-js/stage/1.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ require('../proposals/promise-try');
require('../proposals/keys-composition');
require('../proposals/seeded-random');
require('../proposals/string-code-points');
require('../proposals/string-replace-all');
require('../proposals/using-statement');
require('../proposals/promise-any');

Expand Down
1 change: 1 addition & 0 deletions packages/core-js/stage/2.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('../proposals/set-methods');
require('../proposals/string-replace-all');

module.exports = require('./3');
1 change: 1 addition & 0 deletions tests/commonjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ for (const _PATH of ['../packages/core-js-pure', '../packages/core-js']) {
ok(load('features/symbol/async-iterator'));
ok(load('features/symbol/observable'));
ok(load('features/symbol/pattern-match'));
ok(load('features/symbol/replace-all'));
ok(load('features/symbol/dispose'));
ok(typeof load('features/symbol/for') === 'function');
ok(typeof load('features/symbol/key-for') === 'function');
Expand Down
3 changes: 3 additions & 0 deletions tests/compat/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,9 @@ GLOBAL.tests = {
'esnext.symbol.pattern-match': function () {
return Symbol.patternMatch;
},
'esnext.symbol.replace-all': function () {
return Symbol.replaceAll;
},
'esnext.weak-map.delete-all': function () {
return WeakMap.prototype.deleteAll;
},
Expand Down
17 changes: 17 additions & 0 deletions tests/pure/esnext.string.replace-all.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import { STRICT } from '../helpers/constants';

import replaceAll from 'core-js-pure/features/string/replace-all';
import Symbol from 'core-js-pure/features/symbol';

QUnit.test('String#replaceAll', assert => {
assert.isFunction(replaceAll);
assert.same(replaceAll('q=query+string+parameters', '+', ' '), 'q=query string parameters');
assert.same(replaceAll('foo', 'o', {}), 'f[object Object][object Object]');
assert.same(replaceAll('[object Object]x[object Object]', {}, 'y'), 'yxy');
assert.same(replaceAll({}, 'bject', 'lolo'), '[ololo Ololo]');
assert.same(replaceAll('aba', 'b', (search, i, string) => {
assert.same(search, 'b', '`search` is `b`');
assert.same(i, 0, '`i` is 0');
assert.same(string, 'aba', '`string` is `aba`');
return 'c';
}), 'aca');
const searcher = {
[Symbol.replaceAll](O, replaceValue) {
assert.same(this, searcher, '`this` is `searcher`');
assert.same(String(O), 'aba', '`O` is `aba`');
assert.same(String(replaceValue), 'c', '`replaceValue` is `c`');
return 'foo';
},
};
assert.same(replaceAll('aba', searcher, 'c'), 'foo');
assert.same(replaceAll('aba', 'b'), 'aundefineda');
if (STRICT) {
assert.throws(() => replaceAll(null, 'a', 'b'), TypeError);
assert.throws(() => replaceAll(undefined, 'a', 'b'), TypeError);
Expand Down
6 changes: 6 additions & 0 deletions tests/pure/esnext.symbol.replace-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Symbol from 'core-js-pure/features/symbol';

QUnit.test('Symbol.replaceAll', assert => {
assert.ok('replaceAll' in Symbol, 'Symbol.replaceAll is available');
assert.ok(Object(Symbol.replaceAll) instanceof Symbol, 'Symbol.replaceAll is symbol');
});
2 changes: 2 additions & 0 deletions tests/pure/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,10 @@ import './esnext.set.symmetric-difference';
import './esnext.set.union';
import './esnext.string.at';
import './esnext.string.code-points';
import './esnext.symbol.dispose';
import './esnext.symbol.observable';
import './esnext.symbol.pattern-match';
import './esnext.symbol.replace-all';
import './esnext.weak-map.delete-all';
import './esnext.weak-map.from';
import './esnext.weak-map.of';
Expand Down
16 changes: 16 additions & 0 deletions tests/tests/esnext.string.replace-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ QUnit.test('String#replaceAll', assert => {
assert.same('foo'.replaceAll('o', {}), 'f[object Object][object Object]');
assert.same('[object Object]x[object Object]'.replaceAll({}, 'y'), 'yxy');
assert.same(replaceAll.call({}, 'bject', 'lolo'), '[ololo Ololo]');
assert.same('aba'.replaceAll('b', (search, i, string) => {
assert.same(search, 'b', '`search` is `b`');
assert.same(i, 0, '`i` is 0');
assert.same(string, 'aba', '`string` is `aba`');
return 'c';
}), 'aca');
const searcher = {
[Symbol.replaceAll](O, replaceValue) {
assert.same(this, searcher, '`this` is `searcher`');
assert.same(String(O), 'aba', '`O` is `aba`');
assert.same(String(replaceValue), 'c', '`replaceValue` is `c`');
return 'foo';
},
};
assert.same('aba'.replaceAll(searcher, 'c'), 'foo');
assert.same('aba'.replaceAll('b'), 'aundefineda');
if (STRICT) {
assert.throws(() => replaceAll.call(null, 'a', 'b'), TypeError);
assert.throws(() => replaceAll.call(undefined, 'a', 'b'), TypeError);
Expand Down
13 changes: 13 additions & 0 deletions tests/tests/esnext.symbol.replace-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { DESCRIPTORS } from '../helpers/constants';

QUnit.test('Symbol.replaceAll', assert => {
assert.ok('replaceAll' in Symbol, 'Symbol.replaceAll is available');
assert.nonEnumerable(Symbol, 'replaceAll');
assert.ok(Object(Symbol.replaceAll) instanceof Symbol, 'Symbol.replaceAll is symbol');
if (DESCRIPTORS) {
const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'replaceAll');
assert.ok(!descriptor.enumerble, 'non-enumerable');
assert.ok(!descriptor.writable, 'non-writable');
assert.ok(!descriptor.configurable, 'non-configurable');
}
});
1 change: 1 addition & 0 deletions tests/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ import './esnext.string.replace-all';
import './esnext.symbol.dispose';
import './esnext.symbol.observable';
import './esnext.symbol.pattern-match';
import './esnext.symbol.replace-all';
import './esnext.weak-map.delete-all';
import './esnext.weak-map.from';
import './esnext.weak-map.of';
Expand Down

0 comments on commit 979940f

Please sign in to comment.