UNPKG

voca

Version:

The ultimate JavaScript string library

95 lines (81 loc) 3.3 kB
'use strict'; require('./internal/is_nil.js'); require('./is_string.js'); var coerce_to_string = require('./internal/coerce_to_string.js'); var coerce_to_number = require('./internal/coerce_to_number.js'); var nan_default = require('./internal/nan_default.js'); var HIGH_SURROGATE_START = 0xd800; var HIGH_SURROGATE_END = 0xdbff; var LOW_SURROGATE_START = 0xdc00; var LOW_SURROGATE_END = 0xdfff; /** * Checks if `codePoint` is a high-surrogate number from range 0xD800 to 0xDBFF. * * @ignore * @param {number} codePoint The code point number to be verified * @return {boolean} Returns a boolean whether `codePoint` is a high-surrogate number. */ function isHighSurrogate(codePoint) { return codePoint >= HIGH_SURROGATE_START && codePoint <= HIGH_SURROGATE_END; } /** * Checks if `codePoint` is a low-surrogate number from range 0xDC00 to 0xDFFF. * * @ignore * @param {number} codePoint The code point number to be verified * @return {boolean} Returns a boolean whether `codePoint` is a low-surrogate number. */ function isLowSurrogate(codePoint) { return codePoint >= LOW_SURROGATE_START && codePoint <= LOW_SURROGATE_END; } /** * Get the astral code point number based on surrogate pair numbers. * * @ignore * @param {number} highSurrogate The high-surrogate code point number. * @param {number} lowSurrogate The low-surrogate code point number. * @return {number} Returns the astral symbol number. */ function getAstralNumberFromSurrogatePair(highSurrogate, lowSurrogate) { return (highSurrogate - HIGH_SURROGATE_START) * 0x400 + lowSurrogate - LOW_SURROGATE_START + 0x10000; } /** * Get the Unicode code point value of the character at `position`. <br/> * If a valid UTF-16 <a href="https://rainsoft.io/what-every-javascript-developer-should-know-about-unicode/#24surrogatepairs"> * surrogate pair</a> starts at `position`, the * <a href="https://rainsoft.io/what-every-javascript-developer-should-know-about-unicode/#astralplanes">astral code point</a> * value at `position` is returned. * * @function codePointAt * @static * @since 1.0.0 * @memberOf Chop * @param {string} [subject=''] The string to extract from. * @param {number} position The position to get the code point number. * @return {number} Returns a non-negative number less than or equal to `0x10FFFF`. * @example * v.codePointAt('rain', 1); * // => 97, or 0x0061 * * v.codePointAt('\uD83D\uDE00 is smile', 0); // or '😀 is smile' * // => 128512, or 0x1F600 */ function codePointAt(subject, position) { var subjectString = coerce_to_string.coerceToString(subject); var subjectStringLength = subjectString.length; var positionNumber = coerce_to_number.coerceToNumber(position); positionNumber = nan_default.nanDefault(positionNumber, 0); if (positionNumber < 0 || positionNumber >= subjectStringLength) { return undefined; } var firstCodePoint = subjectString.charCodeAt(positionNumber); var secondCodePoint; if (isHighSurrogate(firstCodePoint) && subjectStringLength > positionNumber + 1) { secondCodePoint = subjectString.charCodeAt(positionNumber + 1); if (isLowSurrogate(secondCodePoint)) { return getAstralNumberFromSurrogatePair(firstCodePoint, secondCodePoint); } } return firstCodePoint; } module.exports = codePointAt;