CodePointAt.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $TypeError = GetIntrinsic('%TypeError%');
  4. var callBound = require('call-bind/callBound');
  5. var isLeadingSurrogate = require('../helpers/isLeadingSurrogate');
  6. var isTrailingSurrogate = require('../helpers/isTrailingSurrogate');
  7. var Type = require('./Type');
  8. var UTF16SurrogatePairToCodePoint = require('./UTF16SurrogatePairToCodePoint');
  9. var $charAt = callBound('String.prototype.charAt');
  10. var $charCodeAt = callBound('String.prototype.charCodeAt');
  11. // https://262.ecma-international.org/12.0/#sec-codepointat
  12. module.exports = function CodePointAt(string, position) {
  13. if (Type(string) !== 'String') {
  14. throw new $TypeError('Assertion failed: `string` must be a String');
  15. }
  16. var size = string.length;
  17. if (position < 0 || position >= size) {
  18. throw new $TypeError('Assertion failed: `position` must be >= 0, and < the length of `string`');
  19. }
  20. var first = $charCodeAt(string, position);
  21. var cp = $charAt(string, position);
  22. var firstIsLeading = isLeadingSurrogate(first);
  23. var firstIsTrailing = isTrailingSurrogate(first);
  24. if (!firstIsLeading && !firstIsTrailing) {
  25. return {
  26. '[[CodePoint]]': cp,
  27. '[[CodeUnitCount]]': 1,
  28. '[[IsUnpairedSurrogate]]': false
  29. };
  30. }
  31. if (firstIsTrailing || (position + 1 === size)) {
  32. return {
  33. '[[CodePoint]]': cp,
  34. '[[CodeUnitCount]]': 1,
  35. '[[IsUnpairedSurrogate]]': true
  36. };
  37. }
  38. var second = $charCodeAt(string, position + 1);
  39. if (!isTrailingSurrogate(second)) {
  40. return {
  41. '[[CodePoint]]': cp,
  42. '[[CodeUnitCount]]': 1,
  43. '[[IsUnpairedSurrogate]]': true
  44. };
  45. }
  46. return {
  47. '[[CodePoint]]': UTF16SurrogatePairToCodePoint(first, second),
  48. '[[CodeUnitCount]]': 2,
  49. '[[IsUnpairedSurrogate]]': false
  50. };
  51. };