UNPKG

1.65 kBJavaScriptView Raw
1'use strict';
2var $ = require('../internals/export');
3var call = require('../internals/function-call');
4var uncurryThis = require('../internals/function-uncurry-this');
5var requireObjectCoercible = require('../internals/require-object-coercible');
6var toString = require('../internals/to-string');
7var fails = require('../internals/fails');
8
9var $Array = Array;
10var charAt = uncurryThis(''.charAt);
11var charCodeAt = uncurryThis(''.charCodeAt);
12var join = uncurryThis([].join);
13// eslint-disable-next-line es/no-string-prototype-iswellformed-towellformed -- safe
14var $toWellFormed = ''.toWellFormed;
15var REPLACEMENT_CHARACTER = '\uFFFD';
16
17// Safari bug
18var TO_STRING_CONVERSION_BUG = $toWellFormed && fails(function () {
19 return call($toWellFormed, 1) !== '1';
20});
21
22// `String.prototype.toWellFormed` method
23// https://github.com/tc39/proposal-is-usv-string
24$({ target: 'String', proto: true, forced: TO_STRING_CONVERSION_BUG }, {
25 toWellFormed: function toWellFormed() {
26 var S = toString(requireObjectCoercible(this));
27 if (TO_STRING_CONVERSION_BUG) return call($toWellFormed, S);
28 var length = S.length;
29 var result = $Array(length);
30 for (var i = 0; i < length; i++) {
31 var charCode = charCodeAt(S, i);
32 // single UTF-16 code unit
33 if ((charCode & 0xF800) !== 0xD800) result[i] = charAt(S, i);
34 // unpaired surrogate
35 else if (charCode >= 0xDC00 || i + 1 >= length || (charCodeAt(S, i + 1) & 0xFC00) !== 0xDC00) result[i] = REPLACEMENT_CHARACTER;
36 // surrogate pair
37 else {
38 result[i] = charAt(S, i);
39 result[++i] = charAt(S, i);
40 }
41 } return join(result, '');
42 }
43});