{"version":3,"file":"css-var.cjs","sources":["../../../src/js/css-var.ts"],"sourcesContent":["/**\n * css-var.js\n */\n\nimport { TokenType, tokenize } from '@csstools/css-tokenizer';\nimport { LRUCache } from 'lru-cache';\nimport { isString } from './common';\nimport { cssCalc } from './css-calc';\nimport { isColor, valueToJsonString } from './util';\n\n/* types */\nimport type { CSSToken } from '@csstools/css-tokenizer';\n\n/* constants */\nimport { FN_VAR, SYN_FN_MATH_CALC, SYN_FN_VAR, VAL_SPEC } from './constant';\nconst {\n CloseParen: PAREN_CLOSE,\n Comment: COMMENT,\n EOF,\n Ident: IDENT,\n Whitespace: W_SPACE\n} = TokenType;\n\n/* regexp */\nconst REG_FN_MATH_CALC = new RegExp(SYN_FN_MATH_CALC);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/* cached results */\nexport const cachedResults = new LRUCache({\n max: 4096\n});\n\n/**\n * resolve custom property\n * @param {Array.} tokens - tokens\n * @param {object} [opt] - options\n * @param {object} [opt.customProperty] - custom properties\n * @returns {Array.} - [tokens, resolvedValue]\n */\nexport function resolveCustomProperty(\n tokens: Array,\n opt: {\n customProperty?: object;\n dimension?: object;\n format?: string;\n } = {}\n): Array | undefined> {\n if (!Array.isArray(tokens)) {\n throw new TypeError(`${tokens} is not an array.`);\n }\n const { customProperty = {} } = opt;\n const items = [];\n while (tokens.length) {\n const token = tokens.shift();\n if (!Array.isArray(token)) {\n throw new TypeError(`${token} is not an array.`);\n }\n const [type, value] = token as [string, string];\n // end of var()\n if (type === PAREN_CLOSE) {\n break;\n }\n // nested var()\n if (value === FN_VAR) {\n const [restTokens, item] = resolveCustomProperty(tokens, opt) as [\n Array,\n string\n ];\n tokens = restTokens;\n if (item) {\n items.push(item);\n }\n } else if (type === IDENT) {\n if (value.startsWith('--')) {\n if (Object.hasOwnProperty.call(customProperty, value)) {\n items.push(customProperty[value as never]);\n } else if (\n typeof (\n customProperty as { callback?: (value: string) => string }\n ).callback === 'function'\n ) {\n const item = (\n customProperty as { callback: (value: string) => string }\n ).callback(value);\n if (item) {\n items.push(item);\n }\n }\n } else if (value) {\n items.push(value);\n }\n }\n }\n let resolveAsColor;\n if (items.length > 1) {\n const lastValue = items[items.length - 1];\n resolveAsColor = isColor(lastValue as string) as boolean;\n }\n let resolvedValue;\n for (let item of items) {\n item = item.trim() as string;\n if (REG_FN_VAR.test(item)) {\n // recurse cssVar()\n item = cssVar(item, opt) as string;\n if (item) {\n if (resolveAsColor) {\n if (isColor(item)) {\n resolvedValue = item;\n }\n } else {\n resolvedValue = item;\n }\n }\n } else if (REG_FN_MATH_CALC.test(item)) {\n item = cssCalc(item as string, opt) as string;\n if (resolveAsColor) {\n if (isColor(item)) {\n resolvedValue = item;\n }\n } else {\n resolvedValue = item;\n }\n } else if (\n item &&\n !/^(?:inherit|initial|revert(?:-layer)?|unset)$/.test(item)\n ) {\n if (resolveAsColor) {\n if (isColor(item)) {\n resolvedValue = item;\n }\n } else {\n resolvedValue = item;\n }\n }\n if (resolvedValue) {\n break;\n }\n }\n return [tokens, resolvedValue];\n}\n\n/**\n * parse tokens\n * @param {Array.} tokens - tokens\n * @param {object} [opt] - options\n * @returns {?Array.} - parsed tokens\n */\nexport function parseTokens(\n tokens: Array,\n opt: object = {}\n): Array | null {\n const res = [] as string[];\n while (tokens.length) {\n const token = tokens.shift();\n const [type, value] = token as [string, string];\n if (value === FN_VAR) {\n const [restTokens, resolvedValue] = resolveCustomProperty(tokens, opt);\n if (!resolvedValue) {\n return null;\n }\n tokens = restTokens as Array;\n res.push(resolvedValue as string);\n } else {\n switch (type) {\n case PAREN_CLOSE: {\n if (res.length) {\n const lastValue = res[res.length - 1];\n if (lastValue === ' ') {\n res.splice(-1, 1, value);\n } else {\n res.push(value);\n }\n } else {\n res.push(value);\n }\n break;\n }\n case W_SPACE: {\n if (res.length) {\n const lastValue = res[res.length - 1] as string;\n if (!lastValue.endsWith('(') && lastValue !== ' ') {\n res.push(value);\n }\n }\n break;\n }\n default: {\n if (type !== COMMENT && type !== EOF) {\n res.push(value);\n }\n }\n }\n }\n }\n return res;\n}\n\n/**\n * resolve CSS var()\n * @param {string} value - color value including var()\n * @param {object} [opt] - options\n * @param {object} [opt.customProperty] - custom properties\n * @returns {?string} - value\n */\nexport function cssVar(\n value: string,\n opt: {\n customProperty?: object;\n format?: string;\n } = {}\n): string | null {\n const { customProperty = {}, format } = opt;\n if (isString(value)) {\n if (!REG_FN_VAR.test(value) || format === VAL_SPEC) {\n return value;\n }\n value = value.trim();\n } else {\n throw new TypeError(`${value} is not a string.`);\n }\n let cacheKey;\n if (\n typeof (\n customProperty as { callback?: (value: string) => string }\n ).callback !== 'function'\n ) {\n cacheKey = `{cssVar:${value},opt:${valueToJsonString(opt)}}`;\n if (cachedResults.has(cacheKey)) {\n return cachedResults.get(cacheKey) as string | null;\n }\n }\n const tokens = tokenize({ css: value });\n const values = parseTokens(tokens, opt);\n if (Array.isArray(values)) {\n let color = values.join('') as string | null;\n if (REG_FN_MATH_CALC.test(color as string)) {\n color = cssCalc(color as string, opt) as string | null;\n }\n if (cacheKey) {\n cachedResults.set(cacheKey as string, color!);\n }\n return color;\n } else {\n if (cacheKey) {\n cachedResults.set(cacheKey, null!);\n }\n return null;\n }\n}\n"],"names":["TokenType","SYN_FN_MATH_CALC","SYN_FN_VAR","LRUCache","FN_VAR","isColor","cssCalc","isString","VAL_SPEC","valueToJsonString","tokenize"],"mappings":"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"}