{"version":3,"file":"convert.js","names":[],"sources":["../../../src/js/convert.ts"],"sourcesContent":["/**\n * convert\n */\n\nimport {\n  CacheItem,\n  NullObject,\n  createCacheKey,\n  getCache,\n  setCache\n} 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 } from './css-calc';\nimport { resolveVar } from './css-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 = (\n  value: string,\n  opt: Options = {}\n): string | NullObject => {\n  if (!isString(value)) {\n    return new NullObject();\n  }\n  value = value.trim();\n  if (!value) {\n    return new NullObject();\n  }\n  const cacheKey: string = createCacheKey(\n    { namespace: NAMESPACE, name: 'preProcess', value },\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  let res: string | NullObject = 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 new NullObject();\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 new NullObject();\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      res = resolveColor(res, { ...opt, format: VAL_COMP, nullable: true });\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 instanceof NullObject) {\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 instanceof CacheItem) {\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 instanceof NullObject) {\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 instanceof CacheItem) {\n    if (cached.isNull) {\n      return null;\n    }\n    return cached.item as string;\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 instanceof NullObject) {\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 instanceof CacheItem) {\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":";;;;;;;;;;;;AAgCA,IAAM,YAAY;AAGlB,IAAM,cAAc,IAAI,OAAO,YAAY;AAC3C,IAAM,aAAa,IAAI,OAAO,WAAW;AACzC,IAAM,aAAa,IAAI,OAAO,WAAW;;;;;;;AAQzC,IAAa,cACX,OACA,MAAe,EAAE,KACO;AACxB,KAAI,CAAC,SAAS,MAAM,CAClB,QAAO,IAAI,YAAY;AAEzB,SAAQ,MAAM,MAAM;AACpB,KAAI,CAAC,MACH,QAAO,IAAI,YAAY;CAEzB,MAAM,WAAmB,eACvB;EAAE,WAAW;EAAW,MAAM;EAAc;EAAO,EACnD,IACD;CACD,MAAM,eAAe,SAAS,SAAS;AACvC,KAAI,wBAAwB,WAAW;AACrC,MAAI,aAAa,OACf,QAAO;AAET,SAAO,aAAa;;CAEtB,IAAI,MAA2B;AAC/B,KAAI,WAAW,KAAK,MAAM,EAAE;EAC1B,MAAM,WAAW,WAAW,OAAO,IAAI;AACvC,MAAI,SAAS,SAAS,CACpB,OAAM;OACD;AACL,YAAS,UAAU,KAAK;AACxB,UAAO,IAAI,YAAY;;;AAG3B,KAAI,SAAS,IAAI;MACX,WAAW,KAAK,IAAI,EAAE;GACxB,MAAM,WAAW,qBAAqB,KAAK,IAAI;AAC/C,OAAI,SAAS,SAAS,CACpB,OAAM;QACD;AACL,aAAS,UAAU,KAAK;AACxB,WAAO,IAAI,YAAY;;aAEhB,YAAY,KAAK,IAAI,CAC9B,OAAM,QAAQ,KAAK,IAAI;;AAG3B,KAAI,SAAS,IAAI;MACX,IAAI,WAAW,YAAY,CAC7B,OAAM,aAAa,KAAK;GAAE,GAAG;GAAK,QAAQ;GAAU,UAAU;GAAM,CAAC;;AAGzE,UAAS,UAAU,IAAI;AACvB,QAAO;;;;;;;;;AAUT,IAAM,wBACJ,MACA,QACA,cACG;CACH,MAAM,oBACJ,OACA,MAAe,EAAE,KACC;AAClB,MAAI,CAAC,SAAS,MAAM,CAClB,OAAM,IAAI,UAAU,GAAG,MAAM,mBAAmB;EAElD,MAAM,WAAW,WAAW,OAAO,IAAI;AACvC,MAAI,oBAAoB,WACtB,QAAO;GAAC;GAAG;GAAG;GAAG;GAAE;EAErB,MAAM,MAAM,SAAS,aAAa;EAClC,MAAM,WAAW,eACf;GAAE,WAAW;GAAW;GAAM,OAAO;GAAK,EAC1C,IACD;EACD,MAAM,SAAS,SAAS,SAAS;AACjC,MAAI,kBAAkB,UACpB,QAAO,OAAO;EAEhB,MAAM,SAAS,UAAU,KAAK;GAAE,GAAG;GAAK;GAAQ,CAAC;AACjD,WAAS,UAAU,OAAO;AAC1B,SAAO;;AAET,QAAO;;;;;;;AAQT,IAAa,eAAe,UAA0B,kBAAkB,MAAM;;;;;;;;AAS9E,IAAa,cAAc,OAAe,MAAe,EAAE,KAAoB;AAC7E,KAAI,CAAC,SAAS,MAAM,CAClB,OAAM,IAAI,UAAU,GAAG,MAAM,mBAAmB;CAElD,MAAM,WAAW,WAAW,OAAO,IAAI;AACvC,KAAI,oBAAoB,WACtB,QAAO;CAET,MAAM,MAAM,SAAS,aAAa;CAClC,MAAM,WAAW,eACf;EAAE,WAAW;EAAW,MAAM;EAAc,OAAO;EAAK,EACxD,IACD;CACD,MAAM,SAAS,SAAS,SAAS;AACjC,KAAI,kBAAkB,WAAW;AAC/B,MAAI,OAAO,OACT,QAAO;AAET,SAAO,OAAO;;CAEhB,MAAM,MAAM,aAAa,KAAK;EAC5B,GAAG;EACH,UAAU;EACV,QAAQ,IAAI,QAAQ,aAAa;EAClC,CAAC;AACF,KAAI,SAAS,IAAI,EAAE;AACjB,WAAS,UAAU,IAAI;AACvB,SAAO;;AAET,UAAS,UAAU,KAAK;AACxB,QAAO;;;;;;;;AAST,IAAa,aAAa,qBACxB,cACA,OACA,kBACD;;;;;;;AAQD,IAAa,aAAa,qBACxB,cACA,OACA,kBACD;;;;;;;AAQD,IAAa,aAAa,qBACxB,cACA,OACA,kBACD;;;;;;;AAQD,IAAa,aAAa,qBACxB,cACA,OACA,kBACD;;;;;;;AAQD,IAAa,eAAe,qBAC1B,gBACA,SACA,oBACD;;;;;;;AAQD,IAAa,eAAe,qBAC1B,gBACA,SACA,oBACD;;;;;;;AAQD,IAAa,aAAa,qBACxB,cACA,OACA,kBACD;;;;;;;AAQD,IAAa,cAAc,OAAe,MAAe,EAAE,KAAoB;AAC7E,KAAI,CAAC,SAAS,MAAM,CAClB,OAAM,IAAI,UAAU,GAAG,MAAM,mBAAmB;CAElD,MAAM,WAAW,WAAW,OAAO,IAAI;AACvC,KAAI,oBAAoB,WACtB,QAAO;EAAC;EAAG;EAAG;EAAG;EAAE;CAErB,MAAM,MAAM,SAAS,aAAa;CAClC,MAAM,WAAW,eACf;EAAE,WAAW;EAAW,MAAM;EAAc,OAAO;EAAK,EACxD,IACD;CACD,MAAM,SAAS,SAAS,SAAS;AACjC,KAAI,kBAAkB,UACpB,QAAO,OAAO;CAEhB,IAAI;AACJ,KAAI,IAAI,WAAW,SAAS,CAC1B,UAAS,eAAe,KAAK,IAAI;KAEjC,UAAS,gBAAgB,KAAK,IAAI;CAEpC,MAAM,GAAG,GAAG,OAAO;AACnB,UAAS,UAAU,IAAI;AACvB,QAAO;;;;;;;;AAST,IAAa,iBACX,OACA,MAAe,EAAE,KACC;AAClB,KAAI,MAAM;AACV,QAAO,WAAW,OAAO,IAAI;;AAI/B,IAAa,UAAU;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}