AdvanceStringIndex.js 1.3 KB

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