{"version":3,"file":"relative-color.js","names":[],"sources":["../../../src/js/relative-color.ts"],"sourcesContent":["/**\n * relative-color\n */\n\nimport { SyntaxFlag, color as colorParser } from '@csstools/css-color-parser';\nimport {\n  ComponentValue,\n  parseComponentValue\n} from '@csstools/css-parser-algorithms';\nimport { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';\nimport {\n  CacheItem,\n  NullObject,\n  createCacheKey,\n  getCache,\n  setCache\n} from './cache';\nimport { NAMED_COLORS, convertColorToRgb } from './color';\nimport { isString, isStringOrNumber } from './common';\nimport { resolveDimension, serializeCalc } from './css-calc';\nimport { resolveColor } from './resolve';\nimport { roundToPrecision, splitValue } from './util';\nimport {\n  ColorChannels,\n  MatchedRegExp,\n  Options,\n  StringColorChannels\n} from './typedef';\n\n/* constants */\nimport {\n  CS_LAB,\n  CS_LCH,\n  FN_LIGHT_DARK,\n  FN_REL,\n  FN_REL_CAPT,\n  FN_VAR,\n  NONE,\n  SYN_COLOR_TYPE,\n  SYN_FN_MATH_START,\n  SYN_FN_VAR,\n  SYN_MIX,\n  VAL_SPEC\n} from './constant';\nconst {\n  CloseParen: PAREN_CLOSE,\n  Comment: COMMENT,\n  Delim: DELIM,\n  Dimension: DIM,\n  EOF,\n  Function: FUNC,\n  Ident: IDENT,\n  Number: NUM,\n  OpenParen: PAREN_OPEN,\n  Percentage: PCT,\n  Whitespace: W_SPACE\n} = TokenType;\nconst { HasNoneKeywords: KEY_NONE } = SyntaxFlag;\nconst NAMESPACE = 'relative-color';\n\n/* constants */\nconst OCT = 8;\nconst DEC = 10;\nconst HEX = 16;\nconst MAX_PCT = 100;\nconst MAX_RGB = 255;\nconst COLOR_CHANNELS = new Map([\n  ['color', ['r', 'g', 'b', 'alpha']],\n  ['hsl', ['h', 's', 'l', 'alpha']],\n  ['hsla', ['h', 's', 'l', 'alpha']],\n  ['hwb', ['h', 'w', 'b', 'alpha']],\n  ['lab', ['l', 'a', 'b', 'alpha']],\n  ['lch', ['l', 'c', 'h', 'alpha']],\n  ['oklab', ['l', 'a', 'b', 'alpha']],\n  ['oklch', ['l', 'c', 'h', 'alpha']],\n  ['rgb', ['r', 'g', 'b', 'alpha']],\n  ['rgba', ['r', 'g', 'b', 'alpha']]\n]);\n\n/* type definitions */\n/**\n * @type NumberOrStringColorChannels - color channel\n */\ntype NumberOrStringColorChannels = ColorChannels & StringColorChannels;\n\n/* regexp */\nconst REG_COLOR_CAPT = new RegExp(\n  `^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\\\s+`\n);\nconst REG_CS_HSL = /(?:hsla?|hwb)$/;\nconst REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`);\nconst REG_FN_CALC_SUM = /^(?:abs|sig?n|cos|tan)\\(/;\nconst REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);\nconst REG_FN_REL = new RegExp(FN_REL);\nconst REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`);\nconst REG_FN_REL_START = new RegExp(`^${FN_REL}`);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/**\n * resolve relative color channels\n * @param value\n *   - CSS color value\n *   - system colors are not supported\n * @param [opt] - options\n * @param [opt.currentColor]\n *   - color to use for `currentcolor` keyword\n *   - if omitted, it will be treated as a missing color\n *     i.e. `rgb(none none none / none)`\n * @param [opt.customProperty]\n *   - custom properties\n *   - pair of `--` prefixed property name and value,\n *     e.g. `customProperty: { '--some-color': '#0000ff' }`\n *   - and/or `callback` function to get the value of the custom property,\n *     e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`\n * @param [opt.dimension]\n *   - dimension, convert relative length to pixels\n *   - pair of unit and it's value as a number in pixels,\n *     e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`\n *   - and/or `callback` function to get the value as a number in pixels,\n *     e.g. `dimension: { callback: convertUnitToPixel }`\n * @param [opt.format]\n *   - output format, one of below\n *   - `computedValue` (default), [computed value][139] of the color\n *   - `specifiedValue`, [specified value][140] of the color\n *   - `hex`, hex color notation, i.e. `rrggbb`\n *   - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`\n * @returns\n *   - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',\n *     color(color-space r g b / alpha), color(color-space x y z / alpha),\n *     lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),\n *     oklch(l c h / alpha), null\n *   - in `computedValue`, values are numbers, however `rgb()` values are\n *     integers\n *   - in `specifiedValue`, returns `empty string` for unknown and/or invalid\n *     color\n *   - in `hex`, returns `null` for `transparent`, and also returns `null` if\n *     any of `r`, `g`, `b`, `alpha` is not a number\n *   - in `hexAlpha`, returns `#00000000` for `transparent`,\n *     however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number\n */\nexport function resolveColorChannels(\n  tokens: CSSToken[],\n  opt: Options = {}\n): NumberOrStringColorChannels | NullObject {\n  if (!Array.isArray(tokens)) {\n    throw new TypeError(`${tokens} is not an array.`);\n  }\n  const { colorSpace = '', format = '' } = opt;\n  const colorChannel = COLOR_CHANNELS.get(colorSpace);\n  // invalid color channel\n  if (!colorChannel) {\n    return new NullObject();\n  }\n  const mathFunc = new Set();\n  const channels: [\n    (number | string)[],\n    (number | string)[],\n    (number | string)[],\n    (number | string)[]\n  ] = [[], [], [], []];\n  let i = 0;\n  let nest = 0;\n  let func = '';\n  let precededPct = false;\n  for (const token of tokens) {\n    if (!Array.isArray(token)) {\n      throw new TypeError(`${token} is not an array.`);\n    }\n    const [type, value, , , detail] = token as [\n      TokenType,\n      string,\n      number,\n      number,\n      { value: string | number } | undefined\n    ];\n    const channel = channels[i];\n    if (Array.isArray(channel)) {\n      switch (type) {\n        case DELIM: {\n          if (func) {\n            if (\n              (value === '+' || value === '-') &&\n              precededPct &&\n              !REG_FN_CALC_SUM.test(func)\n            ) {\n              return new NullObject();\n            }\n            precededPct = false;\n            channel.push(value);\n          }\n          break;\n        }\n        case DIM: {\n          if (!func || !REG_FN_CALC_SUM.test(func)) {\n            return new NullObject();\n          }\n          const resolvedValue = resolveDimension(token, opt);\n          if (isString(resolvedValue)) {\n            channel.push(resolvedValue);\n          } else {\n            channel.push(value);\n          }\n          break;\n        }\n        case FUNC: {\n          channel.push(value);\n          func = value;\n          nest++;\n          if (REG_FN_MATH_START.test(value)) {\n            mathFunc.add(nest);\n          }\n          break;\n        }\n        case IDENT: {\n          // invalid channel key\n          if (!colorChannel.includes(value)) {\n            return new NullObject();\n          }\n          channel.push(value);\n          if (!func) {\n            i++;\n          }\n          break;\n        }\n        case NUM: {\n          channel.push(Number(detail?.value));\n          if (!func) {\n            i++;\n          }\n          break;\n        }\n        case PAREN_OPEN: {\n          channel.push(value);\n          nest++;\n          break;\n        }\n        case PAREN_CLOSE: {\n          if (func) {\n            const lastValue = channel[channel.length - 1];\n            if (lastValue === ' ') {\n              channel[channel.length - 1] = value;\n            } else {\n              channel.push(value);\n            }\n            if (mathFunc.has(nest)) {\n              mathFunc.delete(nest);\n            }\n            nest--;\n            if (nest === 0) {\n              func = '';\n              i++;\n            }\n          }\n          break;\n        }\n        case PCT: {\n          if (!func) {\n            return new NullObject();\n          } else if (!REG_FN_CALC_SUM.test(func)) {\n            let lastValue: string | number | undefined;\n            for (let j = channel.length - 1; j >= 0; j--) {\n              if (channel[j] !== ' ') {\n                lastValue = channel[j];\n                break;\n              }\n            }\n            if (lastValue === '+' || lastValue === '-') {\n              return new NullObject();\n            } else if (lastValue === '*' || lastValue === '/') {\n              precededPct = false;\n            } else {\n              precededPct = true;\n            }\n          }\n          channel.push(Number(detail?.value) / MAX_PCT);\n          break;\n        }\n        case W_SPACE: {\n          if (channel.length && func) {\n            const lastValue = channel[channel.length - 1];\n            if (typeof lastValue === 'number') {\n              channel.push(value);\n            } else if (\n              isString(lastValue) &&\n              !lastValue.endsWith('(') &&\n              lastValue !== ' '\n            ) {\n              channel.push(value);\n            }\n          }\n          break;\n        }\n        default: {\n          if (type !== COMMENT && type !== EOF && func) {\n            channel.push(value);\n          }\n        }\n      }\n    }\n  }\n  const channelValues = [];\n  for (const channel of channels) {\n    if (channel.length === 1) {\n      const [resolvedValue] = channel;\n      if (isStringOrNumber(resolvedValue)) {\n        channelValues.push(resolvedValue);\n      }\n    } else if (channel.length) {\n      const resolvedValue = serializeCalc(channel.join(''), {\n        format\n      });\n      channelValues.push(resolvedValue);\n    }\n  }\n  return channelValues as NumberOrStringColorChannels;\n}\n\n/**\n * extract origin color\n * @param value - CSS color value\n * @param [opt] - options\n * @returns origin color value\n */\nexport function extractOriginColor(\n  value: string,\n  opt: Options = {}\n): string | NullObject {\n  const { colorScheme = 'normal', currentColor = '', format = '' } = opt;\n  if (isString(value)) {\n    value = value.toLowerCase().trim();\n    if (!value) {\n      return new NullObject();\n    }\n    if (!REG_FN_REL_START.test(value)) {\n      return value;\n    }\n  } else {\n    return new NullObject();\n  }\n  const cacheKey: string = createCacheKey(\n    {\n      namespace: NAMESPACE,\n      name: 'extractOriginColor',\n      value\n    },\n    opt\n  );\n  const cachedResult = getCache(cacheKey);\n  if (cachedResult instanceof CacheItem) {\n    if (cachedResult.isNull) {\n      return cachedResult as NullObject;\n    }\n    return cachedResult.item as string;\n  }\n  if (/currentcolor/.test(value)) {\n    if (currentColor) {\n      value = value.replace(/currentcolor/g, currentColor);\n    } else {\n      setCache(cacheKey, null);\n      return new NullObject();\n    }\n  }\n  let colorSpace = '';\n  if (REG_FN_REL_CAPT.test(value)) {\n    [, colorSpace] = value.match(REG_FN_REL_CAPT) as MatchedRegExp;\n  }\n  opt.colorSpace = colorSpace;\n  if (value.includes(FN_LIGHT_DARK)) {\n    const colorParts = value\n      .replace(new RegExp(`^${colorSpace}\\\\(`), '')\n      .replace(/\\)$/, '');\n    const [, originColor = ''] = splitValue(colorParts);\n    const specifiedOriginColor = resolveColor(originColor, {\n      colorScheme,\n      format: VAL_SPEC\n    }) as string;\n    if (specifiedOriginColor === '') {\n      setCache(cacheKey, null);\n      return new NullObject();\n    }\n    if (format === VAL_SPEC) {\n      value = value.replace(originColor, specifiedOriginColor);\n    } else {\n      const resolvedOriginColor = resolveColor(specifiedOriginColor, opt);\n      if (isString(resolvedOriginColor)) {\n        value = value.replace(originColor, resolvedOriginColor);\n      }\n    }\n  }\n  if (REG_COLOR_CAPT.test(value)) {\n    const [, originColor] = value.match(REG_COLOR_CAPT) as MatchedRegExp;\n    const [, restValue] = value.split(originColor) as MatchedRegExp;\n    if (/^[a-z]+$/.test(originColor)) {\n      if (\n        !/^transparent$/.test(originColor) &&\n        !Object.hasOwn(NAMED_COLORS, originColor)\n      ) {\n        setCache(cacheKey, null);\n        return new NullObject();\n      }\n    } else if (format === VAL_SPEC) {\n      const resolvedOriginColor = resolveColor(originColor, opt);\n      if (isString(resolvedOriginColor)) {\n        value = value.replace(originColor, resolvedOriginColor);\n      }\n    }\n    if (format === VAL_SPEC) {\n      const tokens = tokenize({ css: restValue });\n      const channelValues = resolveColorChannels(tokens, opt);\n      if (channelValues instanceof NullObject) {\n        setCache(cacheKey, null);\n        return channelValues;\n      }\n      const [v1, v2, v3, v4] = channelValues;\n      let channelValue = '';\n      if (isStringOrNumber(v4)) {\n        channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;\n      } else {\n        channelValue = ` ${channelValues.join(' ')})`;\n      }\n      if (restValue !== channelValue) {\n        value = value.replace(restValue, channelValue);\n      }\n    }\n  } else {\n    // nested relative color\n    const [, restValue] = value.split(REG_FN_REL_START) as MatchedRegExp;\n    const tokens = tokenize({ css: restValue });\n    const originColor: string[] = [];\n    let nest = 0;\n    let tokenIndex = 0;\n    for (const [type, tokenValue] of tokens) {\n      tokenIndex++;\n      switch (type) {\n        case FUNC:\n        case PAREN_OPEN: {\n          originColor.push(tokenValue);\n          nest++;\n          break;\n        }\n        case PAREN_CLOSE: {\n          const lastValue = originColor[originColor.length - 1];\n          if (lastValue === ' ') {\n            originColor[originColor.length - 1] = tokenValue;\n          } else if (isString(lastValue)) {\n            originColor.push(tokenValue);\n          }\n          nest--;\n          break;\n        }\n        case W_SPACE: {\n          const lastValue = originColor[originColor.length - 1];\n          if (\n            isString(lastValue) &&\n            !lastValue.endsWith('(') &&\n            lastValue !== ' '\n          ) {\n            originColor.push(tokenValue);\n          }\n          break;\n        }\n        default: {\n          if (type !== COMMENT && type !== EOF) {\n            originColor.push(tokenValue);\n          }\n        }\n      }\n      if (nest === 0) {\n        break;\n      }\n    }\n    const resolvedOriginColor = resolveRelativeColor(\n      originColor.join('').trim(),\n      opt\n    );\n    if (resolvedOriginColor instanceof NullObject) {\n      setCache(cacheKey, null);\n      return resolvedOriginColor;\n    }\n    const channelValues = resolveColorChannels(tokens.slice(tokenIndex), opt);\n    if (channelValues instanceof NullObject) {\n      setCache(cacheKey, null);\n      return channelValues;\n    }\n    const [v1, v2, v3, v4] = channelValues;\n    let channelValue = '';\n    if (isStringOrNumber(v4)) {\n      channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;\n    } else {\n      channelValue = ` ${channelValues.join(' ')})`;\n    }\n    value = value.replace(restValue, `${resolvedOriginColor}${channelValue}`);\n  }\n  setCache(cacheKey, value);\n  return value;\n}\n\n/**\n * resolve relative color\n * @param value - CSS relative color value\n * @param [opt] - options\n * @returns resolved value\n */\nexport function resolveRelativeColor(\n  value: string,\n  opt: Options = {}\n): string | NullObject {\n  const { format = '' } = opt;\n  if (isString(value)) {\n    if (REG_FN_VAR.test(value)) {\n      // var() must be resolved before resolveRelativeColor()\n      if (format !== VAL_SPEC) {\n        throw new SyntaxError(`Unexpected token ${FN_VAR} found.`);\n      }\n      return value;\n    } else if (!REG_FN_REL.test(value)) {\n      return value;\n    }\n    value = value.toLowerCase().trim();\n  } else {\n    throw new TypeError(`${value} is not a string.`);\n  }\n  const cacheKey: string = createCacheKey(\n    {\n      namespace: NAMESPACE,\n      name: 'resolveRelativeColor',\n      value\n    },\n    opt\n  );\n  const cachedResult = getCache(cacheKey);\n  if (cachedResult instanceof CacheItem) {\n    if (cachedResult.isNull) {\n      return cachedResult as NullObject;\n    }\n    return cachedResult.item as string;\n  }\n  const originColor = extractOriginColor(value, opt);\n  if (originColor instanceof NullObject) {\n    setCache(cacheKey, null);\n    return originColor;\n  }\n  value = originColor;\n  if (format === VAL_SPEC) {\n    if (value.startsWith('rgba(')) {\n      value = value.replace('rgba(', 'rgb(');\n    } else if (value.startsWith('hsla(')) {\n      value = value.replace('hsla(', 'hsl(');\n    }\n    return value;\n  }\n  const tokens = tokenize({ css: value });\n  const components = parseComponentValue(tokens) as ComponentValue;\n  const parsedComponents = colorParser(components);\n  if (!parsedComponents) {\n    setCache(cacheKey, null);\n    return new NullObject();\n  }\n  const {\n    alpha: alphaComponent,\n    channels: channelsComponent,\n    colorNotation,\n    syntaxFlags\n  } = parsedComponents;\n  let alpha: number | string;\n  if (Number.isNaN(Number(alphaComponent))) {\n    if (syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE)) {\n      alpha = NONE;\n    } else {\n      alpha = 0;\n    }\n  } else {\n    alpha = roundToPrecision(Number(alphaComponent), OCT);\n  }\n  let v1: number | string;\n  let v2: number | string;\n  let v3: number | string;\n  [v1, v2, v3] = channelsComponent;\n  let resolvedValue;\n  if (REG_CS_CIE.test(colorNotation)) {\n    const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);\n    if (Number.isNaN(v1)) {\n      if (hasNone) {\n        v1 = NONE;\n      } else {\n        v1 = 0;\n      }\n    } else {\n      v1 = roundToPrecision(v1, HEX);\n    }\n    if (Number.isNaN(v2)) {\n      if (hasNone) {\n        v2 = NONE;\n      } else {\n        v2 = 0;\n      }\n    } else {\n      v2 = roundToPrecision(v2, HEX);\n    }\n    if (Number.isNaN(v3)) {\n      if (hasNone) {\n        v3 = NONE;\n      } else {\n        v3 = 0;\n      }\n    } else {\n      v3 = roundToPrecision(v3, HEX);\n    }\n    if (alpha === 1) {\n      resolvedValue = `${colorNotation}(${v1} ${v2} ${v3})`;\n    } else {\n      resolvedValue = `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`;\n    }\n  } else if (REG_CS_HSL.test(colorNotation)) {\n    if (Number.isNaN(v1)) {\n      v1 = 0;\n    }\n    if (Number.isNaN(v2)) {\n      v2 = 0;\n    }\n    if (Number.isNaN(v3)) {\n      v3 = 0;\n    }\n    let [r, g, b] = convertColorToRgb(\n      `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`\n    ) as ColorChannels;\n    r = roundToPrecision(r / MAX_RGB, DEC);\n    g = roundToPrecision(g / MAX_RGB, DEC);\n    b = roundToPrecision(b / MAX_RGB, DEC);\n    if (alpha === 1) {\n      resolvedValue = `color(srgb ${r} ${g} ${b})`;\n    } else {\n      resolvedValue = `color(srgb ${r} ${g} ${b} / ${alpha})`;\n    }\n  } else {\n    const cs = colorNotation === 'rgb' ? 'srgb' : colorNotation;\n    const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);\n    if (Number.isNaN(v1)) {\n      if (hasNone) {\n        v1 = NONE;\n      } else {\n        v1 = 0;\n      }\n    } else {\n      v1 = roundToPrecision(v1, DEC);\n    }\n    if (Number.isNaN(v2)) {\n      if (hasNone) {\n        v2 = NONE;\n      } else {\n        v2 = 0;\n      }\n    } else {\n      v2 = roundToPrecision(v2, DEC);\n    }\n    if (Number.isNaN(v3)) {\n      if (hasNone) {\n        v3 = NONE;\n      } else {\n        v3 = 0;\n      }\n    } else {\n      v3 = roundToPrecision(v3, DEC);\n    }\n    if (alpha === 1) {\n      resolvedValue = `color(${cs} ${v1} ${v2} ${v3})`;\n    } else {\n      resolvedValue = `color(${cs} ${v1} ${v2} ${v3} / ${alpha})`;\n    }\n  }\n  setCache(cacheKey, resolvedValue);\n  return resolvedValue;\n}\n"],"mappings":"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"}