diff --git a/CHANGELOG.md b/CHANGELOG.md index 747d5f7c7c67..d5ce626f9891 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - `%TypedArray%#filterOut` - Added [array deduplication stage 1 proposal](https://github.com/tc39/proposal-array-unique) - `Array#uniqueBy` +- Added code points / code units explicit feature detection in `String#at` for preventing breakage code which use obsolete `String#at` proposal polyfill - Added the missed `(es|stable)/instance/replace-all` entries - Updated compat data mapping for Opera - from Opera 69, the difference with Chrome versions increased to 14 - Compat data mapping for modern Android WebView to Chrome moved from targets parser directly to compat data diff --git a/packages/core-js/modules/esnext.string.at-alternative.js b/packages/core-js/modules/esnext.string.at-alternative.js index 5591cbcd59bd..5158e2e75594 100644 --- a/packages/core-js/modules/esnext.string.at-alternative.js +++ b/packages/core-js/modules/esnext.string.at-alternative.js @@ -4,10 +4,15 @@ var $ = require('../internals/export'); var requireObjectCoercible = require('../internals/require-object-coercible'); var toLength = require('../internals/to-length'); var toInteger = require('../internals/to-integer'); +var fails = require('../internals/fails'); + +var FORCED = fails(function () { + return '𠮷'.at(0) !== '\uD842'; +}); // `String.prototype.at` method // https://github.com/tc39/proposal-relative-indexing-method -$({ target: 'String', proto: true }, { +$({ target: 'String', proto: true, forced: FORCED }, { at: function at(index) { var S = String(requireObjectCoercible(this)); var len = toLength(S.length); diff --git a/packages/core-js/modules/esnext.string.at.js b/packages/core-js/modules/esnext.string.at.js index fc3c44a76063..be0ce4049a40 100644 --- a/packages/core-js/modules/esnext.string.at.js +++ b/packages/core-js/modules/esnext.string.at.js @@ -1,10 +1,15 @@ 'use strict'; var $ = require('../internals/export'); var charAt = require('../internals/string-multibyte').charAt; +var fails = require('../internals/fails'); + +var FORCED = fails(function () { + return '𠮷'.at(0) !== '𠮷'; +}); // `String.prototype.at` method // https://github.com/mathiasbynens/String.prototype.at -$({ target: 'String', proto: true }, { +$({ target: 'String', proto: true, forced: FORCED }, { at: function at(pos) { return charAt(this, pos); } diff --git a/tests/compat/tests.js b/tests/compat/tests.js index 0e60dd11e051..9a8cded1617e 100644 --- a/tests/compat/tests.js +++ b/tests/compat/tests.js @@ -1425,7 +1425,7 @@ GLOBAL.tests = { return Set.prototype.union; }, 'esnext.string.at': function () { - return String.prototype.at; + return '𠮷'.at(0) === '𠮷'; }, 'esnext.string.code-points': function () { return String.prototype.codePoints; diff --git a/tests/pure/esnext.string.at-alternative.js b/tests/pure/esnext.string.at-alternative.js index bcd26e9bddff..834298592aaf 100644 --- a/tests/pure/esnext.string.at-alternative.js +++ b/tests/pure/esnext.string.at-alternative.js @@ -19,6 +19,7 @@ QUnit.test('String#at', assert => { assert.same('1', at('1', NaN)); assert.same('1', at('1')); assert.same('1', at('123', -0)); + assert.same('\uD842', at('𠮷')); assert.same('1', at({ toString() { return '123'; } }, 0)); if (STRICT) { assert.throws(() => at(null, 0), TypeError); diff --git a/tests/tests/esnext.string.at-alternative.js b/tests/tests/esnext.string.at-alternative.js index 78a070deedea..e84bcf3fadea 100644 --- a/tests/tests/esnext.string.at-alternative.js +++ b/tests/tests/esnext.string.at-alternative.js @@ -22,6 +22,7 @@ QUnit.test('String#at', assert => { assert.same('1', '1'.at(NaN)); assert.same('1', '1'.at()); assert.same('1', '123'.at(-0)); + assert.same('\uD842', '𠮷'.at()); assert.same('1', at.call({ toString() { return '123'; } }, 0)); if (STRICT) { assert.throws(() => at.call(null, 0), TypeError);