diff options
Diffstat (limited to 'node_modules/postcss-minify-font-values/src/lib/minify-family.js')
| -rw-r--r-- | node_modules/postcss-minify-font-values/src/lib/minify-family.js | 248 |
1 files changed, 0 insertions, 248 deletions
diff --git a/node_modules/postcss-minify-font-values/src/lib/minify-family.js b/node_modules/postcss-minify-font-values/src/lib/minify-family.js deleted file mode 100644 index 5d6c4851..00000000 --- a/node_modules/postcss-minify-font-values/src/lib/minify-family.js +++ /dev/null @@ -1,248 +0,0 @@ -'use strict'; -const { stringify } = require('postcss-value-parser'); - -/** - * @param {string[]} list - * @return {string[]} - */ -function uniqueFontFamilies(list) { - return list.filter((item, i) => { - if (item.toLowerCase() === 'monospace') { - return true; - } - return i === list.indexOf(item); - }); -} - -const globalKeywords = ['inherit', 'initial', 'unset']; -const genericFontFamilykeywords = new Set([ - 'sans-serif', - 'serif', - 'fantasy', - 'cursive', - 'monospace', - 'system-ui', -]); - -/** - * @param {string} value - * @param {number} length - * @return {string[]} - */ -function makeArray(value, length) { - let array = []; - while (length--) { - array[length] = value; - } - return array; -} - -// eslint-disable-next-line no-useless-escape -const regexSimpleEscapeCharacters = /[ !"#$%&'()*+,.\/;<=>?@\[\\\]^`{|}~]/; - -/** - * @param {string} string - * @param {boolean} escapeForString - * @return {string} - */ -function escape(string, escapeForString) { - let counter = 0; - let character; - let charCode; - let value; - let output = ''; - - while (counter < string.length) { - character = string.charAt(counter++); - charCode = character.charCodeAt(0); - - // \r is already tokenized away at this point - // `:` can be escaped as `\:`, but that fails in IE < 8 - if (!escapeForString && /[\t\n\v\f:]/.test(character)) { - value = '\\' + charCode.toString(16) + ' '; - } else if ( - !escapeForString && - regexSimpleEscapeCharacters.test(character) - ) { - value = '\\' + character; - } else { - value = character; - } - - output += value; - } - - if (!escapeForString) { - if (/^-[-\d]/.test(output)) { - output = '\\-' + output.slice(1); - } - - const firstChar = string.charAt(0); - - if (/\d/.test(firstChar)) { - output = '\\3' + firstChar + ' ' + output.slice(1); - } - } - - return output; -} - -const regexKeyword = new RegExp( - [...genericFontFamilykeywords].concat(globalKeywords).join('|'), - 'i' -); -const regexInvalidIdentifier = /^(-?\d|--)/; -const regexSpaceAtStart = /^\x20/; -const regexWhitespace = /[\t\n\f\r\x20]/g; -const regexIdentifierCharacter = /^[a-zA-Z\d\xa0-\uffff_-]+$/; -const regexConsecutiveSpaces = /(\\(?:[a-fA-F0-9]{1,6}\x20|\x20))?(\x20{2,})/g; -const regexTrailingEscape = /\\[a-fA-F0-9]{0,6}\x20$/; -const regexTrailingSpace = /\x20$/; - -/** - * @param {string} string - * @return {string} - */ -function escapeIdentifierSequence(string) { - let identifiers = string.split(regexWhitespace); - let index = 0; - /** @type {string[] | string} */ - let result = []; - let escapeResult; - - while (index < identifiers.length) { - let subString = identifiers[index++]; - - if (subString === '') { - result.push(subString); - continue; - } - - escapeResult = escape(subString, false); - - if (regexIdentifierCharacter.test(subString)) { - // the font family name part consists of allowed characters exclusively - if (regexInvalidIdentifier.test(subString)) { - // the font family name part starts with two hyphens, a digit, or a - // hyphen followed by a digit - if (index === 1) { - // if this is the first item - result.push(escapeResult); - } else { - // if it’s not the first item, we can simply escape the space - // between the two identifiers to merge them into a single - // identifier rather than escaping the start characters of the - // second identifier - result[index - 2] += '\\'; - result.push(escape(subString, true)); - } - } else { - // the font family name part doesn’t start with two hyphens, a digit, - // or a hyphen followed by a digit - result.push(escapeResult); - } - } else { - // the font family name part contains invalid identifier characters - result.push(escapeResult); - } - } - - result = result.join(' ').replace(regexConsecutiveSpaces, ($0, $1, $2) => { - const spaceCount = $2.length; - const escapesNeeded = Math.floor(spaceCount / 2); - const array = makeArray('\\ ', escapesNeeded); - - if (spaceCount % 2) { - array[escapesNeeded - 1] += '\\ '; - } - - return ($1 || '') + ' ' + array.join(' '); - }); - - // Escape trailing spaces unless they’re already part of an escape - if (regexTrailingSpace.test(result) && !regexTrailingEscape.test(result)) { - result = result.replace(regexTrailingSpace, '\\ '); - } - - if (regexSpaceAtStart.test(result)) { - result = '\\ ' + result.slice(1); - } - - return result; -} -/** - * @param {import('postcss-value-parser').Node[]} nodes - * @param {import('../index').Options} opts - * @return {import('postcss-value-parser').WordNode[]} - */ -module.exports = function (nodes, opts) { - /** @type {import('postcss-value-parser').Node[]} */ - const family = []; - /** @type {import('postcss-value-parser').WordNode | null} */ - let last = null; - let i, max; - - nodes.forEach((node, index, arr) => { - if (node.type === 'string' || node.type === 'function') { - family.push(node); - } else if (node.type === 'word') { - if (!last) { - last = /** @type {import('postcss-value-parser').WordNode} */ ({ - type: 'word', - value: '', - }); - family.push(last); - } - - last.value += node.value; - } else if (node.type === 'space') { - if (last && index !== arr.length - 1) { - last.value += ' '; - } - } else { - last = null; - } - }); - - let normalizedFamilies = family.map((node) => { - if (node.type === 'string') { - const isKeyword = regexKeyword.test(node.value); - - if ( - !opts.removeQuotes || - isKeyword || - /[0-9]/.test(node.value.slice(0, 1)) - ) { - return stringify(node); - } - - let escaped = escapeIdentifierSequence(node.value); - - if (escaped.length < node.value.length + 2) { - return escaped; - } - } - - return stringify(node); - }); - - if (opts.removeAfterKeyword) { - for (i = 0, max = normalizedFamilies.length; i < max; i += 1) { - if (genericFontFamilykeywords.has(normalizedFamilies[i].toLowerCase())) { - normalizedFamilies = normalizedFamilies.slice(0, i + 1); - break; - } - } - } - - if (opts.removeDuplicates) { - normalizedFamilies = uniqueFontFamilies(normalizedFamilies); - } - - return [ - /** @type {import('postcss-value-parser').WordNode} */ ({ - type: 'word', - value: normalizedFamilies.join(), - }), - ]; -}; |
