blob: 279602b4cd233bf6132eeeee9540b5fdee3644f2 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2
3var GetIntrinsic = require('get-intrinsic');
4
5var IsInteger = require('./IsInteger');
6var Type = require('./Type');
7
8var MAX_SAFE_INTEGER = require('../helpers/maxSafeInteger');
9var isLeadingSurrogate = require('../helpers/isLeadingSurrogate');
10var isTrailingSurrogate = require('../helpers/isTrailingSurrogate');
11
12var $TypeError = GetIntrinsic('%TypeError%');
13
14var $charCodeAt = require('call-bind/callBound')('String.prototype.charCodeAt');
15
16// https://ecma-international.org/ecma-262/6.0/#sec-advancestringindex
17
18module.exports = function AdvanceStringIndex(S, index, unicode) {
19 if (Type(S) !== 'String') {
20 throw new $TypeError('Assertion failed: `S` must be a String');
21 }
22 if (!IsInteger(index) || index < 0 || index > MAX_SAFE_INTEGER) {
23 throw new $TypeError('Assertion failed: `length` must be an integer >= 0 and <= 2**53');
24 }
25 if (Type(unicode) !== 'Boolean') {
26 throw new $TypeError('Assertion failed: `unicode` must be a Boolean');
27 }
28 if (!unicode) {
29 return index + 1;
30 }
31 var length = S.length;
32 if ((index + 1) >= length) {
33 return index + 1;
34 }
35
36 var first = $charCodeAt(S, index);
37 if (!isLeadingSurrogate(first)) {
38 return index + 1;
39 }
40
41 var second = $charCodeAt(S, index + 1);
42 if (!isTrailingSurrogate(second)) {
43 return index + 1;
44 }
45
46 return index + 2;
47};