UNPKG

@difizen/mana-common

Version:

471 lines (449 loc) 14.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.commonPrefixLength = commonPrefixLength; exports.commonSuffixLength = commonSuffixLength; exports.compare = compare; exports.compareIgnoreCase = compareIgnoreCase; exports.compareSubstring = compareSubstring; exports.compareSubstringIgnoreCase = compareSubstringIgnoreCase; exports.computeCodePoint = computeCodePoint; exports.convertSimple2RegExpPattern = convertSimple2RegExpPattern; exports.count = count; exports.createRegExp = createRegExp; exports.equalsIgnoreCase = equalsIgnoreCase; exports.escape = escape; exports.escapeRegExpCharacters = escapeRegExpCharacters; exports.firstNonWhitespaceIndex = firstNonWhitespaceIndex; exports.format = format; exports.getLeadingWhitespace = getLeadingWhitespace; exports.getNextCodePoint = getNextCodePoint; exports.isFalsyOrWhitespace = isFalsyOrWhitespace; exports.isHighSurrogate = isHighSurrogate; exports.isLowSurrogate = isLowSurrogate; exports.isLowerAsciiLetter = isLowerAsciiLetter; exports.isUpperAsciiLetter = isUpperAsciiLetter; exports.lastNonWhitespaceIndex = lastNonWhitespaceIndex; exports.ltrim = ltrim; exports.regExpContainsBackreference = regExpContainsBackreference; exports.regExpFlags = regExpFlags; exports.regExpLeadsToEndlessLoop = regExpLeadsToEndlessLoop; exports.rtrim = rtrim; exports.splitLines = splitLines; exports.startsWithIgnoreCase = startsWithIgnoreCase; exports.stripWildcards = stripWildcards; exports.trim = trim; exports.truncate = truncate; var _charCode = require("./charCode"); /* eslint-disable no-control-regex */ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ function isFalsyOrWhitespace(str) { if (!str || typeof str !== 'string') { return true; } return str.trim().length === 0; } var _formatRegexp = /{(\d+)}/g; /** * Helper to produce a string with a variable number of arguments. Insert variable segments * into the string using the {n} notation where N is the index of the argument following the string. * @param value string to which formatting is applied * @param args replacements for {n}-entries */ function format(value) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } if (args.length === 0) { return value; } return value.replace(_formatRegexp, function (match, group) { var idx = parseInt(group, 10); // eslint-disable-next-line no-restricted-globals return isNaN(idx) || idx < 0 || idx >= args.length ? match : args[idx]; }); } /** * Converts HTML characters inside the string to use entities instead. Makes the string safe from * being used e.g. in HTMLElement.innerHTML. */ function escape(html) { return html.replace(/[<>&]/g, function (match) { switch (match) { case '<': return '&lt;'; case '>': return '&gt;'; case '&': return '&amp;'; default: return match; } }); } /** * Escapes regular expression characters in a given string */ function escapeRegExpCharacters(value) { // eslint-disable-next-line no-useless-escape return value.replace(/[\\\{\}\*\+\?\|\^\$\.\[\]\(\)]/g, '\\$&'); } /** * Counts how often `character` occurs inside `value`. */ function count(value, character) { var result = 0; var ch = character.charCodeAt(0); for (var i = value.length - 1; i >= 0; i--) { if (value.charCodeAt(i) === ch) { result++; } } return result; } function truncate(value, maxLength) { var suffix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '…'; if (value.length <= maxLength) { return value; } return "".concat(value.substr(0, maxLength)).concat(suffix); } /** * Removes all occurrences of needle from the beginning and end of haystack. * @param haystack string to trim * @param needle the thing to trim (default is a blank) */ function trim(haystack) { var needle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ' '; var trimmed = ltrim(haystack, needle); return rtrim(trimmed, needle); } /** * Removes all occurrences of needle from the beginning of haystack. * @param haystack string to trim * @param needle the thing to trim */ function ltrim(haystack, needle) { if (!haystack || !needle) { return haystack; } var needleLen = needle.length; if (needleLen === 0 || haystack.length === 0) { return haystack; } var offset = 0; while (haystack.indexOf(needle, offset) === offset) { offset += needleLen; } return haystack.substring(offset); } /** * Removes all occurrences of needle from the end of haystack. * @param haystack string to trim * @param needle the thing to trim */ function rtrim(haystack, needle) { if (!haystack || !needle) { return haystack; } var needleLen = needle.length; var haystackLen = haystack.length; if (needleLen === 0 || haystackLen === 0) { return haystack; } var offset = haystackLen; var idx = -1; // eslint-disable-next-line no-constant-condition while (true) { idx = haystack.lastIndexOf(needle, offset - 1); if (idx === -1 || idx + needleLen !== offset) { break; } if (idx === 0) { return ''; } offset = idx; } return haystack.substring(0, offset); } function convertSimple2RegExpPattern(pattern) { // eslint-disable-next-line no-useless-escape return pattern // eslint-disable-next-line no-useless-escape .replace(/[\-\\\{\}\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&') // eslint-disable-next-line no-useless-escape .replace(/[\*]/g, '.*'); } function stripWildcards(pattern) { return pattern.replace(/\*/g, ''); } function createRegExp(searchString, isRegex) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (!searchString) { throw new Error('Cannot create regex from empty string'); } if (!isRegex) { searchString = escapeRegExpCharacters(searchString); } if (options.wholeWord) { if (!/\B/.test(searchString.charAt(0))) { searchString = "\\b".concat(searchString); } if (!/\B/.test(searchString.charAt(searchString.length - 1))) { searchString += '\\b'; } } var modifiers = ''; if (options.global) { modifiers += 'g'; } if (!options.matchCase) { modifiers += 'i'; } if (options.multiline) { modifiers += 'm'; } if (options.unicode) { modifiers += 'u'; } return new RegExp(searchString, modifiers); } function regExpLeadsToEndlessLoop(regexp) { // Exit early if it's one of these special cases which are meant to match // against an empty string if (regexp.source === '^' || regexp.source === '^$' || regexp.source === '$' || regexp.source === '^\\s*$') { return false; } // We check against an empty string. If the regular expression doesn't advance // (e.g. ends in an endless loop) it will match an empty string. var match = regexp.exec(''); return !!(match && regexp.lastIndex === 0); } function regExpContainsBackreference(regexpValue) { return !!regexpValue.match(/([^\\]|^)(\\\\)*\\\d+/); } function regExpFlags(regexp) { return (regexp.global ? 'g' : '') + (regexp.ignoreCase ? 'i' : '') + (regexp.multiline ? 'm' : '') + (regexp /* standalone editor compilation */.unicode ? 'u' : ''); } function splitLines(str) { return str.split(/\r\n|\r|\n/); } /** * Returns first index of the string that is not whitespace. * If string is empty or contains only whitespaces, returns -1 */ function firstNonWhitespaceIndex(str) { for (var i = 0, len = str.length; i < len; i++) { var chCode = str.charCodeAt(i); if (chCode !== _charCode.CharCode.Space && chCode !== _charCode.CharCode.Tab) { return i; } } return -1; } /** * Returns the leading whitespace of the string. * If the string contains only whitespaces, returns entire string */ function getLeadingWhitespace(str) { var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : str.length; for (var i = start; i < end; i++) { var chCode = str.charCodeAt(i); if (chCode !== _charCode.CharCode.Space && chCode !== _charCode.CharCode.Tab) { return str.substring(start, i); } } return str.substring(start, end); } /** * Returns last index of the string that is not whitespace. * If string is empty or contains only whitespaces, returns -1 */ function lastNonWhitespaceIndex(str) { var startIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : str.length - 1; for (var i = startIndex; i >= 0; i--) { var chCode = str.charCodeAt(i); if (chCode !== _charCode.CharCode.Space && chCode !== _charCode.CharCode.Tab) { return i; } } return -1; } function compare(a, b) { if (a < b) { return -1; } if (a > b) { return 1; } return 0; } function compareSubstring(a, b) { var aStart = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var aEnd = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : a.length; var bStart = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; var bEnd = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : b.length; for (; aStart < aEnd && bStart < bEnd; aStart++, bStart++) { var codeA = a.charCodeAt(aStart); var codeB = b.charCodeAt(bStart); if (codeA < codeB) { return -1; } if (codeA > codeB) { return 1; } } var aLen = aEnd - aStart; var bLen = bEnd - bStart; if (aLen < bLen) { return -1; } if (aLen > bLen) { return 1; } return 0; } function compareIgnoreCase(a, b) { return compareSubstringIgnoreCase(a, b, 0, a.length, 0, b.length); } function compareSubstringIgnoreCase(a, b) { var aStart = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var aEnd = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : a.length; var bStart = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; var bEnd = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : b.length; for (; aStart < aEnd && bStart < bEnd; aStart++, bStart++) { var codeA = a.charCodeAt(aStart); var codeB = b.charCodeAt(bStart); if (codeA === codeB) { // equal continue; } var diff = codeA - codeB; if (diff === 32 && isUpperAsciiLetter(codeB)) { //codeB =[65-90] && codeA =[97-122] continue; } else if (diff === -32 && isUpperAsciiLetter(codeA)) { //codeB =[97-122] && codeA =[65-90] continue; } if (isLowerAsciiLetter(codeA) && isLowerAsciiLetter(codeB)) { // return diff; } return compareSubstring(a.toLowerCase(), b.toLowerCase(), aStart, aEnd, bStart, bEnd); } var aLen = aEnd - aStart; var bLen = bEnd - bStart; if (aLen < bLen) { return -1; } if (aLen > bLen) { return 1; } return 0; } function isLowerAsciiLetter(code) { return code >= _charCode.CharCode.a && code <= _charCode.CharCode.z; } function isUpperAsciiLetter(code) { return code >= _charCode.CharCode.A && code <= _charCode.CharCode.Z; } function isAsciiLetter(code) { return isLowerAsciiLetter(code) || isUpperAsciiLetter(code); } function equalsIgnoreCase(a, b) { return a.length === b.length && doEqualsIgnoreCase(a, b); } function doEqualsIgnoreCase(a, b) { var stopAt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : a.length; for (var i = 0; i < stopAt; i++) { var codeA = a.charCodeAt(i); var codeB = b.charCodeAt(i); if (codeA === codeB) { continue; } // a-z A-Z if (isAsciiLetter(codeA) && isAsciiLetter(codeB)) { var diff = Math.abs(codeA - codeB); if (diff !== 0 && diff !== 32) { return false; } } // Any other charcode else if (String.fromCharCode(codeA).toLowerCase() !== String.fromCharCode(codeB).toLowerCase()) { return false; } } return true; } function startsWithIgnoreCase(str, candidate) { var candidateLength = candidate.length; if (candidate.length > str.length) { return false; } return doEqualsIgnoreCase(str, candidate, candidateLength); } /** * @returns the length of the common prefix of the two strings. */ function commonPrefixLength(a, b) { var i; var len = Math.min(a.length, b.length); for (i = 0; i < len; i++) { if (a.charCodeAt(i) !== b.charCodeAt(i)) { return i; } } return len; } /** * @returns the length of the common suffix of the two strings. */ function commonSuffixLength(a, b) { var i; var len = Math.min(a.length, b.length); var aLastIndex = a.length - 1; var bLastIndex = b.length - 1; for (i = 0; i < len; i++) { if (a.charCodeAt(aLastIndex - i) !== b.charCodeAt(bLastIndex - i)) { return i; } } return len; } /** * See http://en.wikipedia.org/wiki/Surrogate_pair */ function isHighSurrogate(charCode) { return charCode >= 0xd800 && charCode <= 0xdbff; } /** * See http://en.wikipedia.org/wiki/Surrogate_pair */ function isLowSurrogate(charCode) { return charCode >= 0xdc00 && charCode <= 0xdfff; } /** * See http://en.wikipedia.org/wiki/Surrogate_pair */ function computeCodePoint(highSurrogate, lowSurrogate) { return (highSurrogate - 0xd800 << 10) + (lowSurrogate - 0xdc00) + 0x10000; } /** * get the code point that begins at offset `offset` */ function getNextCodePoint(str, len, offset) { var charCode = str.charCodeAt(offset); if (isHighSurrogate(charCode) && offset + 1 < len) { var nextCharCode = str.charCodeAt(offset + 1); if (isLowSurrogate(nextCharCode)) { return computeCodePoint(charCode, nextCharCode); } } return charCode; }