{"version":3,"file":"convert.js","names":[],"sources":["../../../src/js/convert.ts"],"sourcesContent":["/**\n * convert\n */\n\nimport { createCacheKey, getCache, setCache } from './cache';\nimport {\n  convertColorToHsl,\n  convertColorToHwb,\n  convertColorToLab,\n  convertColorToLch,\n  convertColorToOklab,\n  convertColorToOklch,\n  convertColorToRgb,\n  numberToHexString,\n  parseColorFunc,\n  parseColorValue\n} from './color';\nimport { isString } from './common';\nimport { cssCalc, resolveVar } from './css-calc-var';\nimport { resolveRelativeColor } from './relative-color';\nimport { resolveColor } from './resolve';\nimport { ColorChannels, ComputedColorChannels, Options } from './typedef';\n\n/* constants */\nimport { SYN_FN_CALC, SYN_FN_REL, SYN_FN_VAR, VAL_COMP } from './constant';\nconst NAMESPACE = 'convert';\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_REL = new RegExp(SYN_FN_REL);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/**\n * pre process\n * @param value - CSS color value\n * @param [opt] - options\n * @returns value\n */\nexport const preProcess = (value: string, opt: Options = {}): string | null => {\n  if (!isString(value)) {\n    return null;\n  }\n  value = value.trim();\n  if (!value) {\n    return null;\n  }\n  const cacheKey: string = createCacheKey(\n    { namespace: NAMESPACE, name: 'preProcess', value },\n    opt\n  );\n  const cachedResult = getCache(cacheKey);\n  if (cachedResult !== false) {\n    return cachedResult.item as string | null;\n  }\n  let res: string | null = value;\n  if (REG_FN_VAR.test(value)) {\n    const resolved = resolveVar(value, opt);\n    if (isString(resolved)) {\n      res = resolved;\n    } else {\n      setCache(cacheKey, null);\n      return null;\n    }\n  }\n  if (isString(res)) {\n    if (REG_FN_REL.test(res)) {\n      const resolved = resolveRelativeColor(res, opt);\n      if (isString(resolved)) {\n        res = resolved;\n      } else {\n        setCache(cacheKey, null);\n        return null;\n      }\n    } else if (REG_FN_CALC.test(res)) {\n      res = cssCalc(res, opt);\n    }\n  }\n  if (isString(res)) {\n    if (res.startsWith('color-mix')) {\n      const resolvedColorMix = resolveColor(res, {\n        ...opt,\n        format: VAL_COMP,\n        nullable: true\n      });\n      res = typeof resolvedColorMix === 'string' ? resolvedColorMix : null;\n    }\n  }\n  setCache(cacheKey, res);\n  return res;\n};\n\n/**\n * converter factory to reduce boilerplate\n * @param name - function name for cache\n * @param format - color format\n * @param convertFn - conversion function\n * @returns color converter function\n */\nconst createColorConverter = (\n  name: string,\n  format: string,\n  convertFn: Function\n) => {\n  const colorConverterFn = (\n    value: string,\n    opt: Options = {}\n  ): ColorChannels => {\n    if (!isString(value)) {\n      throw new TypeError(`${value} is not a string.`);\n    }\n    const resolved = preProcess(value, opt);\n    if (resolved === null) {\n      return [0, 0, 0, 0];\n    }\n    const val = resolved.toLowerCase();\n    const cacheKey = createCacheKey(\n      { namespace: NAMESPACE, name, value: val },\n      opt\n    );\n    const cached = getCache(cacheKey);\n    if (cached !== false) {\n      return cached.item as ColorChannels;\n    }\n    const result = convertFn(val, { ...opt, format }) as ColorChannels;\n    setCache(cacheKey, result);\n    return result;\n  };\n  return colorConverterFn;\n};\n\n/**\n * convert number to hex string\n * @param value - numeric value\n * @returns hex string: 00..ff\n */\nexport const numberToHex = (value: number): string => numberToHexString(value);\n\n/**\n * convert color to hex\n * @param value - CSS color value\n * @param [opt] - options\n * @param [opt.alpha] - enable alpha channel\n * @returns #rrggbb | #rrggbbaa | null\n */\nexport const colorToHex = (value: string, opt: Options = {}): string | null => {\n  if (!isString(value)) {\n    throw new TypeError(`${value} is not a string.`);\n  }\n  const resolved = preProcess(value, opt);\n  if (resolved === null) {\n    return null;\n  }\n  const val = resolved.toLowerCase();\n  const cacheKey = createCacheKey(\n    { namespace: NAMESPACE, name: 'colorToHex', value: val },\n    opt\n  );\n  const cached = getCache(cacheKey);\n  if (cached !== false) {\n    return cached.item as string | null;\n  }\n  const hex = resolveColor(val, {\n    ...opt,\n    nullable: true,\n    format: opt.alpha ? 'hexAlpha' : 'hex'\n  });\n  if (isString(hex)) {\n    setCache(cacheKey, hex);\n    return hex;\n  }\n  setCache(cacheKey, null);\n  return null;\n};\n\n/**\n * convert color to hsl\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [h, s, l, alpha]\n */\nexport const colorToHsl = createColorConverter(\n  'colorToHsl',\n  'hsl',\n  convertColorToHsl\n);\n\n/**\n * convert color to hwb\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [h, w, b, alpha]\n */\nexport const colorToHwb = createColorConverter(\n  'colorToHwb',\n  'hwb',\n  convertColorToHwb\n);\n\n/**\n * convert color to lab\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, a, b, alpha]\n */\nexport const colorToLab = createColorConverter(\n  'colorToLab',\n  'lab',\n  convertColorToLab\n);\n\n/**\n * convert color to lch\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, c, h, alpha]\n */\nexport const colorToLch = createColorConverter(\n  'colorToLch',\n  'lch',\n  convertColorToLch\n);\n\n/**\n * convert color to oklab\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, a, b, alpha]\n */\nexport const colorToOklab = createColorConverter(\n  'colorToOklab',\n  'oklab',\n  convertColorToOklab\n);\n\n/**\n * convert color to oklch\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [l, c, h, alpha]\n */\nexport const colorToOklch = createColorConverter(\n  'colorToOklch',\n  'oklch',\n  convertColorToOklch\n);\n\n/**\n * convert color to rgb\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [r, g, b, alpha]\n */\nexport const colorToRgb = createColorConverter(\n  'colorToRgb',\n  'rgb',\n  convertColorToRgb\n);\n\n/**\n * convert color to xyz\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [x, y, z, alpha]\n */\nexport const colorToXyz = (value: string, opt: Options = {}): ColorChannels => {\n  if (!isString(value)) {\n    throw new TypeError(`${value} is not a string.`);\n  }\n  const resolved = preProcess(value, opt);\n  if (resolved === null) {\n    return [0, 0, 0, 0];\n  }\n  const val = resolved.toLowerCase();\n  const cacheKey = createCacheKey(\n    { namespace: NAMESPACE, name: 'colorToXyz', value: val },\n    opt\n  );\n  const cached = getCache(cacheKey);\n  if (cached !== false) {\n    return cached.item as ColorChannels;\n  }\n  let parsed;\n  if (val.startsWith('color(')) {\n    parsed = parseColorFunc(val, opt);\n  } else {\n    parsed = parseColorValue(val, opt);\n  }\n  const [, ...xyz] = parsed as ComputedColorChannels;\n  setCache(cacheKey, xyz);\n  return xyz as ColorChannels;\n};\n\n/**\n * convert color to xyz-d50\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [x, y, z, alpha]\n */\nexport const colorToXyzD50 = (\n  value: string,\n  opt: Options = {}\n): ColorChannels => {\n  opt.d50 = true;\n  return colorToXyz(value, opt);\n};\n\n/* convert */\nexport const convert = {\n  colorToHex,\n  colorToHsl,\n  colorToHwb,\n  colorToLab,\n  colorToLch,\n  colorToOklab,\n  colorToOklch,\n  colorToRgb,\n  colorToXyz,\n  colorToXyzD50,\n  numberToHex\n};\n"],"mappings":"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"}