CodePointAt.js 1.6 KB

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