Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add well formed unicode strings proposal
  • Loading branch information
zloirock committed Oct 14, 2022
1 parent 7765c29 commit 7959981
Show file tree
Hide file tree
Showing 16 changed files with 126 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/core-js-compat/src/data.mjs
Expand Up @@ -2352,10 +2352,14 @@ export const data = {
},
'esnext.string.code-points': {
},
'esnext.string.is-well-formed': {
},
// TODO: Remove from `core-js@4`
'esnext.string.match-all': null,
// TODO: Remove from `core-js@4`
'esnext.string.replace-all': null,
'esnext.string.to-well-formed': {
},
'esnext.symbol.async-dispose': {
},
'esnext.symbol.dispose': {
Expand Down
4 changes: 4 additions & 0 deletions packages/core-js-compat/src/modules-by-versions.mjs
Expand Up @@ -157,4 +157,8 @@ export default {
3.25: [
'es.object.proto',
],
3.26: [
'esnext.string.is-well-formed',
'esnext.string.to-well-formed',
],
};
10 changes: 10 additions & 0 deletions packages/core-js/full/instance/is-well-formed.js
@@ -0,0 +1,10 @@
var isPrototypeOf = require('../../internals/object-is-prototype-of');
var method = require('../string/virtual/is-well-formed');

var StringPrototype = String.prototype;

module.exports = function (it) {
var own = it.isWellFormed;
return typeof it == 'string' || it === StringPrototype
|| (isPrototypeOf(StringPrototype, it) && own === StringPrototype.isWellFormed) ? method : own;
};
10 changes: 10 additions & 0 deletions packages/core-js/full/instance/to-well-formed.js
@@ -0,0 +1,10 @@
var isPrototypeOf = require('../../internals/object-is-prototype-of');
var method = require('../string/virtual/to-well-formed');

var StringPrototype = String.prototype;

module.exports = function (it) {
var own = it.toWellFormed;
return typeof it == 'string' || it === StringPrototype
|| (isPrototypeOf(StringPrototype, it) && own === StringPrototype.toWellFormed) ? method : own;
};
2 changes: 2 additions & 0 deletions packages/core-js/full/string/index.js
Expand Up @@ -3,8 +3,10 @@ var parent = require('../../actual/string');
require('../../modules/esnext.string.at');
require('../../modules/esnext.string.cooked');
require('../../modules/esnext.string.code-points');
require('../../modules/esnext.string.is-well-formed');
// TODO: remove from `core-js@4`
require('../../modules/esnext.string.match-all');
require('../../modules/esnext.string.replace-all');
require('../../modules/esnext.string.to-well-formed');

module.exports = parent;
3 changes: 3 additions & 0 deletions packages/core-js/full/string/is-well-formed.js
@@ -0,0 +1,3 @@
require('../../modules/esnext.string.is-well-formed');

module.exports = require('../../internals/entry-unbind')('String', 'isWellFormed');
3 changes: 3 additions & 0 deletions packages/core-js/full/string/to-well-formed.js
@@ -0,0 +1,3 @@
require('../../modules/esnext.string.to-well-formed');

module.exports = require('../../internals/entry-unbind')('String', 'toWellFormed');
2 changes: 2 additions & 0 deletions packages/core-js/full/string/virtual/index.js
Expand Up @@ -2,8 +2,10 @@ var parent = require('../../../actual/string/virtual');
// TODO: remove from `core-js@4`
require('../../../modules/esnext.string.at');
require('../../../modules/esnext.string.code-points');
require('../../../modules/esnext.string.is-well-formed');
// TODO: remove from `core-js@4`
require('../../../modules/esnext.string.match-all');
require('../../../modules/esnext.string.replace-all');
require('../../../modules/esnext.string.to-well-formed');

module.exports = parent;
3 changes: 3 additions & 0 deletions packages/core-js/full/string/virtual/is-well-formed.js
@@ -0,0 +1,3 @@
require('../../../modules/esnext.string.is-well-formed');

module.exports = require('../../../internals/entry-virtual')('String').isWellFormed;
3 changes: 3 additions & 0 deletions packages/core-js/full/string/virtual/to-well-formed.js
@@ -0,0 +1,3 @@
require('../../../modules/esnext.string.to-well-formed');

module.exports = require('../../../internals/entry-virtual')('String').toWellFormed;
23 changes: 23 additions & 0 deletions packages/core-js/modules/esnext.string.is-well-formed.js
@@ -0,0 +1,23 @@
'use strict';
var $ = require('../internals/export');
var uncurryThis = require('../internals/function-uncurry-this');
var requireObjectCoercible = require('../internals/require-object-coercible');
var toString = require('../internals/to-string');

var charCodeAt = uncurryThis(''.charCodeAt);

// `String.prototype.isWellFormed` method
// https://github.com/tc39/proposal-is-usv-string
$({ target: 'String', proto: true, forced: true }, {
isWellFormed: function isWellFormed() {
var S = toString(requireObjectCoercible(this));
var length = S.length;
for (var i = 0; i < length; i++) {
var charCode = charCodeAt(S, i);
// single UTF-16 code unit
if ((charCode & 0xF800) != 0xD800) continue;
// unpaired surrogate
if (charCode >= 0xDC00 || ++i >= length || (charCodeAt(S, i) & 0xFC00) != 0xDC00) return false;
} return true;
}
});
33 changes: 33 additions & 0 deletions packages/core-js/modules/esnext.string.to-well-formed.js
@@ -0,0 +1,33 @@
'use strict';
var $ = require('../internals/export');
var uncurryThis = require('../internals/function-uncurry-this');
var requireObjectCoercible = require('../internals/require-object-coercible');
var toString = require('../internals/to-string');

var $Array = Array;
var charAt = uncurryThis(''.charAt);
var charCodeAt = uncurryThis(''.charCodeAt);
var join = uncurryThis([].join);
var REPLACEMENT_CHARACTER = '\uFFFD';

// `String.prototype.toWellFormed` method
// https://github.com/tc39/proposal-is-usv-string
$({ target: 'String', proto: true, forced: true }, {
toWellFormed: function toWellFormed() {
var S = toString(requireObjectCoercible(this));
var length = S.length;
var result = $Array(length);
for (var i = 0; i < length; i++) {
var charCode = charCodeAt(S, i);
// single UTF-16 code unit
if ((charCode & 0xF800) != 0xD800) result[i] = charAt(S, i);
// unpaired surrogate
else if (charCode >= 0xDC00 || i + 1 >= length || (charCodeAt(S, i + 1) & 0xFC00) != 0xDC00) result[i] = REPLACEMENT_CHARACTER;
// surrogate pair
else {
result[i] = charAt(S, i);
result[++i] = charAt(S, i);
}
} return join(result, '');
}
});
2 changes: 2 additions & 0 deletions packages/core-js/proposals/well-formed-unicode-strings.js
@@ -0,0 +1,2 @@
require('../modules/esnext.string.is-well-formed');
require('../modules/esnext.string.to-well-formed');
1 change: 1 addition & 0 deletions packages/core-js/stage/2.js
Expand Up @@ -4,6 +4,7 @@ require('../proposals/iterator-helpers');
require('../proposals/map-upsert-stage-2');
require('../proposals/set-methods');
require('../proposals/using-statement');
require('../proposals/well-formed-unicode-strings');
// TODO: Obsolete versions, remove from `core-js@4`
require('../proposals/array-grouping');
require('../proposals/decorators');
Expand Down
17 changes: 17 additions & 0 deletions tests/commonjs.mjs
Expand Up @@ -786,6 +786,10 @@ for (PATH of ['core-js-pure', 'core-js']) {
ok(load(NS, 'string/cooked')`a${ 1 }b` === 'a1b');
ok('next' in load(NS, 'string/code-points')('a'));
ok('next' in load(NS, 'string/virtual/code-points').call('a'));
ok(load(NS, 'string/is-well-formed')('a'));
ok(load(NS, 'string/virtual/is-well-formed').call('a'));
ok(load(NS, 'string/to-well-formed')('a') === 'a');
ok(load(NS, 'string/virtual/to-well-formed').call('a') === 'a');
ok(load(NS, 'symbol/async-dispose'));
ok(load(NS, 'symbol/dispose'));
ok(load(NS, 'symbol/matcher'));
Expand Down Expand Up @@ -822,6 +826,18 @@ for (PATH of ['core-js-pure', 'core-js']) {
ok(typeof instanceFilterReject([]) == 'function');
ok(instanceFilterReject([]).call([1, 2, 3], it => it % 2).length === 1);

const instanceIsWellFormed = load(NS, 'instance/is-well-formed');
ok(typeof instanceIsWellFormed == 'function');
ok(instanceIsWellFormed({}) === undefined);
ok(typeof instanceIsWellFormed('') == 'function');
ok(instanceIsWellFormed('').call('a'));

const instanceToWellFormed = load(NS, 'instance/to-well-formed');
ok(typeof instanceToWellFormed == 'function');
ok(instanceToWellFormed({}) === undefined);
ok(typeof instanceToWellFormed('') == 'function');
ok(instanceToWellFormed('').call('a') === 'a');

const instanceUniqueBy = load(NS, 'instance/unique-by');
ok(typeof instanceUniqueBy == 'function');
ok(instanceUniqueBy({}) === undefined);
Expand Down Expand Up @@ -897,6 +913,7 @@ for (PATH of ['core-js-pure', 'core-js']) {
load('proposals/url');
load('proposals/using-statement');
load('proposals/well-formed-stringify');
load('proposals/well-formed-unicode-strings');
load('proposals');

ok(load('stage/4'));
Expand Down
6 changes: 6 additions & 0 deletions tests/compat/tests.js
Expand Up @@ -1698,6 +1698,12 @@ GLOBAL.tests = {
'esnext.string.cooked': function () {
return String.cooked;
},
'esnext.string.is-well-formed': function () {
return String.prototype.isWellFormed;
},
'esnext.string.to-well-formed': function () {
return String.prototype.toWellFormed;
},
'esnext.symbol.async-dispose': function () {
return Symbol.dispose;
},
Expand Down

0 comments on commit 7959981

Please sign in to comment.