diff options
Diffstat (limited to 'node_modules/postcss-normalize-string/src/index.js')
| -rw-r--r-- | node_modules/postcss-normalize-string/src/index.js | 319 |
1 files changed, 0 insertions, 319 deletions
diff --git a/node_modules/postcss-normalize-string/src/index.js b/node_modules/postcss-normalize-string/src/index.js deleted file mode 100644 index fa74851c..00000000 --- a/node_modules/postcss-normalize-string/src/index.js +++ /dev/null @@ -1,319 +0,0 @@ -'use strict'; -const valueParser = require('postcss-value-parser'); - -/* - * Constants (parser usage) - */ - -const SINGLE_QUOTE = "'".charCodeAt(0); -const DOUBLE_QUOTE = '"'.charCodeAt(0); -const BACKSLASH = '\\'.charCodeAt(0); -const NEWLINE = '\n'.charCodeAt(0); -const SPACE = ' '.charCodeAt(0); -const FEED = '\f'.charCodeAt(0); -const TAB = '\t'.charCodeAt(0); -const CR = '\r'.charCodeAt(0); - -const WORD_END = /[ \n\t\r\f'"\\]/g; - -/* - * Constants (node type strings) - */ - -const C_STRING = 'string'; -const C_ESCAPED_SINGLE_QUOTE = 'escapedSingleQuote'; -const C_ESCAPED_DOUBLE_QUOTE = 'escapedDoubleQuote'; -const C_SINGLE_QUOTE = 'singleQuote'; -const C_DOUBLE_QUOTE = 'doubleQuote'; -const C_NEWLINE = 'newline'; -const C_SINGLE = 'single'; - -/* - * Literals - */ - -const L_SINGLE_QUOTE = `'`; -const L_DOUBLE_QUOTE = `"`; -const L_NEWLINE = `\\\n`; - -/* - * Parser nodes - */ - -const T_ESCAPED_SINGLE_QUOTE = { type: C_ESCAPED_SINGLE_QUOTE, value: `\\'` }; -const T_ESCAPED_DOUBLE_QUOTE = { type: C_ESCAPED_DOUBLE_QUOTE, value: `\\"` }; -const T_SINGLE_QUOTE = { type: C_SINGLE_QUOTE, value: L_SINGLE_QUOTE }; -const T_DOUBLE_QUOTE = { type: C_DOUBLE_QUOTE, value: L_DOUBLE_QUOTE }; -const T_NEWLINE = { type: C_NEWLINE, value: L_NEWLINE }; - -/** @typedef {T_ESCAPED_SINGLE_QUOTE | T_ESCAPED_DOUBLE_QUOTE | T_SINGLE_QUOTE | T_NEWLINE} StringAstNode */ -/** - * @typedef {{nodes: StringAstNode[], - * types: {escapedSingleQuote: number, escapedDoubleQuote: number, singleQuote: number, doubleQuote: number}, - * quotes: boolean}} StringAst - */ - -/** - * @param {StringAst} ast - * @return {string} - */ -function stringify(ast) { - return ast.nodes.reduce((str, { value }) => { - // Collapse multiple line strings automatically - if (value === L_NEWLINE) { - return str; - } - - return str + value; - }, ''); -} - -/** - * @param {string} str - * @return {StringAst} - */ -function parse(str) { - let code, next, value; - let pos = 0; - let len = str.length; - - /** @type StringAst */ - const ast = { - nodes: [], - types: { - escapedSingleQuote: 0, - escapedDoubleQuote: 0, - singleQuote: 0, - doubleQuote: 0, - }, - quotes: false, - }; - - while (pos < len) { - code = str.charCodeAt(pos); - - switch (code) { - case SPACE: - case TAB: - case CR: - case FEED: - next = pos; - - do { - next += 1; - code = str.charCodeAt(next); - } while ( - code === SPACE || - code === NEWLINE || - code === TAB || - code === CR || - code === FEED - ); - - ast.nodes.push({ - type: 'space', - value: str.slice(pos, next), - }); - pos = next - 1; - break; - case SINGLE_QUOTE: - ast.nodes.push(T_SINGLE_QUOTE); - ast.types[C_SINGLE_QUOTE]++; - ast.quotes = true; - break; - case DOUBLE_QUOTE: - ast.nodes.push(T_DOUBLE_QUOTE); - ast.types[C_DOUBLE_QUOTE]++; - ast.quotes = true; - break; - case BACKSLASH: - next = pos + 1; - - if (str.charCodeAt(next) === SINGLE_QUOTE) { - ast.nodes.push(T_ESCAPED_SINGLE_QUOTE); - ast.types[C_ESCAPED_SINGLE_QUOTE]++; - ast.quotes = true; - pos = next; - break; - } else if (str.charCodeAt(next) === DOUBLE_QUOTE) { - ast.nodes.push(T_ESCAPED_DOUBLE_QUOTE); - ast.types[C_ESCAPED_DOUBLE_QUOTE]++; - ast.quotes = true; - pos = next; - break; - } else if (str.charCodeAt(next) === NEWLINE) { - ast.nodes.push(T_NEWLINE); - pos = next; - break; - } - /* - * We need to fall through here to handle the token as - * a whole word. The missing 'break' is intentional. - */ - default: - WORD_END.lastIndex = pos + 1; - WORD_END.test(str); - - if (WORD_END.lastIndex === 0) { - next = len - 1; - } else { - next = WORD_END.lastIndex - 2; - } - - value = str.slice(pos, next + 1); - - ast.nodes.push({ - type: C_STRING, - value, - }); - - pos = next; - } - pos++; - } - - return ast; -} - -/** - * @param {valueParser.StringNode} node - * @param {StringAst} ast - * @return {void} - */ -function changeWrappingQuotes(node, ast) { - const { types } = ast; - - if (types[C_SINGLE_QUOTE] || types[C_DOUBLE_QUOTE]) { - return; - } - - if ( - node.quote === L_SINGLE_QUOTE && - types[C_ESCAPED_SINGLE_QUOTE] > 0 && - !types[C_ESCAPED_DOUBLE_QUOTE] - ) { - node.quote = L_DOUBLE_QUOTE; - } - - if ( - node.quote === L_DOUBLE_QUOTE && - types[C_ESCAPED_DOUBLE_QUOTE] > 0 && - !types[C_ESCAPED_SINGLE_QUOTE] - ) { - node.quote = L_SINGLE_QUOTE; - } - - ast.nodes = changeChildQuotes(ast.nodes, node.quote); -} -/** - * @param {StringAstNode[]} childNodes - * @param {string} parentQuote - * @return {StringAstNode[]} - */ -function changeChildQuotes(childNodes, parentQuote) { - const updatedChildren = []; - for (const child of childNodes) { - if ( - child.type === C_ESCAPED_DOUBLE_QUOTE && - parentQuote === L_SINGLE_QUOTE - ) { - updatedChildren.push(T_DOUBLE_QUOTE); - } else if ( - child.type === C_ESCAPED_SINGLE_QUOTE && - parentQuote === L_DOUBLE_QUOTE - ) { - updatedChildren.push(T_SINGLE_QUOTE); - } else { - updatedChildren.push(child); - } - } - return updatedChildren; -} - -/** - * @param {string} value - * @param {'single' | 'double'} preferredQuote - * @return {string} - */ -function normalize(value, preferredQuote) { - if (!value || !value.length) { - return value; - } - - return valueParser(value) - .walk((child) => { - if (child.type !== C_STRING) { - return; - } - - const ast = parse(child.value); - - if (ast.quotes) { - changeWrappingQuotes(child, ast); - } else if (preferredQuote === C_SINGLE) { - child.quote = L_SINGLE_QUOTE; - } else { - child.quote = L_DOUBLE_QUOTE; - } - - child.value = stringify(ast); - }) - .toString(); -} - -/** - * @param {string} original - * @param {Map<string, string>} cache - * @param {'single' | 'double'} preferredQuote - * @return {string} - */ -function minify(original, cache, preferredQuote) { - const key = original + '|' + preferredQuote; - if (cache.has(key)) { - return /** @type {string} */ (cache.get(key)); - } - const newValue = normalize(original, preferredQuote); - cache.set(key, newValue); - return newValue; -} - -/** @typedef {{preferredQuote?: 'double' | 'single'}} Options */ -/** - * @type {import('postcss').PluginCreator<Options>} - * @param {Options} opts - * @return {import('postcss').Plugin} - */ -function pluginCreator(opts) { - const { preferredQuote } = Object.assign( - {}, - { - preferredQuote: 'double', - }, - opts - ); - - return { - postcssPlugin: 'postcss-normalize-string', - - OnceExit(css) { - const cache = new Map(); - - css.walk((node) => { - switch (node.type) { - case 'rule': - node.selector = minify(node.selector, cache, preferredQuote); - break; - case 'decl': - node.value = minify(node.value, cache, preferredQuote); - break; - case 'atrule': - node.params = minify(node.params, cache, preferredQuote); - break; - } - }); - }, - }; -} - -pluginCreator.postcss = true; -module.exports = pluginCreator; |
