{"version":3,"file":"index.mjs","sources":["../src/lib/get-image.ts","../src/lib/get-media.ts","../src/lib/handle-invalidation.ts","../src/index.ts","../src/lib/process-image-set.ts","../src/lib/get-comma.ts"],"sourcesContent":["import valueParser from 'postcss-value-parser';\n\nconst imageFuncRegexp = /^(cross-fade|image|(repeating-)?(conic|linear|radial)-gradient|url|var)$/i;\n\nexport function getImage(node) {\n\t// | | | \n\t// the image-set() function can not be nested inside of itself\n\tif (!node || !node.type) {\n\t\treturn false;\n\t}\n\n\tif (node.type === 'string') {\n\t\treturn 'url('+valueParser.stringify(node)+')';\n\t}\n\n\tif (\n\t\tnode.type === 'function' &&\n\t\timageFuncRegexp.test(node.value)\n\t) {\n\t\treturn valueParser.stringify(node);\n\t}\n\n\treturn false;\n}\n","import type { Node } from 'postcss-value-parser';\nimport valueParser from 'postcss-value-parser';\n\nconst dpiRatios = { dpcm: 2.54, dpi: 1, dppx: 96, x: 96 };\n\n// return a valid @media rule\nexport function getMedia(dpi: number | false, postcss) {\n\tif (typeof dpi === 'boolean') {\n\t\treturn false;\n\t}\n\n\t// calculate min-device-pixel-ratio and min-resolution\n\tconst dpr = Math.floor(dpi / dpiRatios.x * 100) / 100;\n\n\tconst media = postcss.atRule({\n\t\tname: 'media',\n\t\tparams: `(-webkit-min-device-pixel-ratio: ${dpr}), (min-resolution: ${dpi}dpi)`,\n\t});\n\n\treturn media;\n}\n\nexport function getMediaDPI(node: Node) {\n\tif (!node) {\n\t\treturn false;\n\t}\n\n\tif (node.type !== 'word') {\n\t\treturn false;\n\t}\n\n\tif (!isNumericNode(node)) {\n\t\treturn false;\n\t}\n\n\tconst unitAndValue = valueParser.unit(node.value);\n\tif (!unitAndValue) {\n\t\treturn false;\n\t}\n\n\tif (unitAndValue.unit.toLowerCase() in dpiRatios) {\n\t\t// calculate min-device-pixel-ratio and min-resolution\n\t\treturn Number(unitAndValue.number) * dpiRatios[unitAndValue.unit.toLowerCase()];\n\t} else {\n\t\treturn false;\n\t}\n}\n\nfunction isNumericNode(node): boolean {\n\tif (!node || !node.value) {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\treturn valueParser.unit(node.value) !== false;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}\n","export const handleInvalidation = (opts, message, word) => {\n\tif (opts.oninvalid === 'warn') {\n\t\topts.decl.warn(opts.result, message, { word: String(word) });\n\t} else if (opts.oninvalid === 'throw') {\n\t\tthrow opts.decl.error(message, { word: String(word) });\n\t}\n};\n","import valueParser from 'postcss-value-parser';\nimport { processImageSet } from './lib/process-image-set';\nimport type { PluginCreator } from 'postcss';\nimport { handleInvalidation } from './lib/handle-invalidation';\n\nconst imageSetValueMatchRegExp = /(^|[^\\w-])(-webkit-)?image-set\\(/i;\nconst imageSetFunctionMatchRegExp = /^(-webkit-)?image-set$/i;\n\nconst creator: PluginCreator<{ preserve: boolean, oninvalid: string }> = (opts?: { preserve: boolean, oninvalid: string }) => {\n\t// prepare options\n\tconst preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true;\n\tconst oninvalid = 'oninvalid' in Object(opts) ? opts.oninvalid : 'ignore';\n\n\treturn {\n\t\tpostcssPlugin: 'postcss-image-set-function',\n\t\tDeclaration(decl, { result, postcss }) {\n\t\t\tconst value = decl.value;\n\n\t\t\t// if a declaration likely uses an image-set() function\n\t\t\tif (!imageSetValueMatchRegExp.test(value)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet valueAST;\n\n\t\t\ttry {\n\t\t\t\tvalueAST = valueParser(value);\n\t\t\t} catch (error) {\n\t\t\t\tdecl.warn(\n\t\t\t\t\tresult,\n\t\t\t\t\t`Failed to parse value '${value}' as an image-set function. Leaving the original value intact.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (typeof valueAST === 'undefined') {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// process every image-set() function\n\t\t\tconst imageSetFunctions = [];\n\n\t\t\tvalueAST.walk((node) => {\n\t\t\t\tif (node.type !== 'function') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!imageSetFunctionMatchRegExp.test(node.value)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet foundNestedImageSet = false;\n\t\t\t\tvalueParser.walk(node.nodes, (child) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tchild.type === 'function' &&\n\t\t\t\t\t\timageSetFunctionMatchRegExp.test(child.value)\n\t\t\t\t\t) {\n\t\t\t\t\t\tfoundNestedImageSet = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (foundNestedImageSet) {\n\t\t\t\t\thandleInvalidation({\n\t\t\t\t\t\tdecl,\n\t\t\t\t\t\toninvalid,\n\t\t\t\t\t\tresult: result,\n\t\t\t\t\t}, 'nested image-set functions are not allowed', valueParser.stringify(node));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconst relevantNodes = node.nodes.filter((x) => {\n\t\t\t\t\treturn x.type !== 'comment' && x.type !== 'space';\n\t\t\t\t});\n\n\t\t\t\timageSetFunctions.push({\n\t\t\t\t\timageSetFunction: node,\n\t\t\t\t\timageSetOptionNodes: relevantNodes,\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tprocessImageSet(imageSetFunctions, decl, {\n\t\t\t\tdecl,\n\t\t\t\toninvalid,\n\t\t\t\tpreserve,\n\t\t\t\tresult: result,\n\t\t\t\tpostcss: postcss,\n\t\t\t});\n\t\t},\n\t};\n};\n\ncreator.postcss = true;\n\nexport default creator;\n\n","import valueParser from 'postcss-value-parser';\nimport { getComma } from './get-comma';\nimport { getImage } from './get-image';\nimport { getMedia, getMediaDPI } from './get-media';\nimport { handleInvalidation } from './handle-invalidation';\nimport type { AtRule, Container, Declaration, Result, Postcss } from 'postcss';\nimport type { Node } from 'postcss-value-parser';\n\ntype imageSetFunction = {\n\timageSetFunction: Node;\n\timageSetOptionNodes: Array;\n}\n\ntype mediaByDpr = {\n\tatRule: AtRule;\n\tvalue: string;\n}\n\nexport const processImageSet = (imageSetFunctions: Array, decl: Declaration, opts: { decl: Declaration, oninvalid: string, preserve: boolean, result: Result, postcss: Postcss }) => {\n\tconst parent = decl.parent;\n\tconst mediasByDpr: Map = new Map();\n\tconst declValue = decl.value;\n\n\tfor (let i = 0; i < imageSetFunctions.length; i++) {\n\t\tconst { imageSetFunction, imageSetOptionNodes } = imageSetFunctions[i];\n\t\tconst mediasByDprPerItem: Map = new Map();\n\n\t\tconst length = imageSetOptionNodes.length;\n\t\tlet index = -1;\n\n\t\twhile (index < length) {\n\t\t\tconst comma = index < 0 ? true : getComma(imageSetOptionNodes[index]);\n\t\t\tconst value = getImage(imageSetOptionNodes[index + 1]);\n\t\t\tconst mediaDPI = getMediaDPI(imageSetOptionNodes[index + 2]);\n\n\t\t\tconst media = getMedia(mediaDPI, opts.postcss);\n\n\t\t\t// handle invalidations\n\t\t\tif (!comma) {\n\t\t\t\thandleInvalidation(opts, 'expected a comma', valueParser.stringify(imageSetOptionNodes));\n\t\t\t\treturn;\n\t\t\t} else if (!value) {\n\t\t\t\thandleInvalidation(opts, 'unexpected image', valueParser.stringify(imageSetOptionNodes));\n\t\t\t\treturn;\n\t\t\t} else if (!media || !mediaDPI || mediasByDprPerItem.has(mediaDPI)) {\n\t\t\t\thandleInvalidation(opts, 'unexpected resolution', valueParser.stringify(imageSetOptionNodes));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmediasByDprPerItem.set(mediaDPI, media);\n\n\t\t\tif (mediasByDpr.has(mediaDPI)) {\n\t\t\t\tconst m = mediasByDpr.get(mediaDPI);\n\t\t\t\tm.value = m.value.replace(valueParser.stringify(imageSetFunction), value.trim());\n\t\t\t\tmediasByDpr.set(mediaDPI, m);\n\t\t\t} else {\n\t\t\t\tmediasByDpr.set(mediaDPI, {\n\t\t\t\t\tatRule: media,\n\t\t\t\t\tvalue: declValue.replace(valueParser.stringify(imageSetFunction), value.trim()),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tindex += 3;\n\t\t}\n\t}\n\n\tfor (const { atRule, value } of mediasByDpr.values()) {\n\t\t// prepare @media { decl: }\n\t\tconst parentClone = parent.clone().removeAll();\n\t\tconst declClone = decl.clone({ value: value });\n\n\t\tparentClone.append(declClone);\n\t\tatRule.append(parentClone);\n\t}\n\n\tconst medias = Array.from(mediasByDpr.keys())\n\t\t.sort((a, b) => a - b)\n\t\t.map(params => mediasByDpr.get(params).atRule);\n\n\tif (!medias.length) {\n\t\treturn;\n\t}\n\n\tconst smallestMedia = medias[0];\n\tconst mediasWithoutSmallest = medias.slice(1);\n\n\tif (mediasWithoutSmallest.length) {\n\t\tparent.after(mediasWithoutSmallest);\n\t}\n\n\tconst firstDecl = (smallestMedia.nodes[0] as Container).nodes[0] as Declaration;\n\tdecl.cloneBefore({ value: firstDecl.value.trim() });\n\n\tif (!opts.preserve) {\n\t\tdecl.remove();\n\n\t\t// and then conditionally remove its parent\n\t\tif (!parent.nodes.length) {\n\t\t\tparent.remove();\n\t\t}\n\t}\n\n\treturn;\n};\n","// return whether a node is a valid comma\nexport function getComma(node) {\n\treturn Object(node).type === 'div' && Object(node).value === ',';\n}\n"],"names":["imageFuncRegexp","getImage","node","type","valueParser","stringify","test","value","dpiRatios","dpcm","dpi","dppx","x","getMedia","postcss","dpr","Math","floor","atRule","name","params","getMediaDPI","unit","e","isNumericNode","unitAndValue","toLowerCase","Number","number","handleInvalidation","opts","message","word","oninvalid","decl","warn","result","String","error","imageSetValueMatchRegExp","imageSetFunctionMatchRegExp","creator","preserve","Object","Boolean","postcssPlugin","Declaration","valueAST","imageSetFunctions","walk","foundNestedImageSet","nodes","child","relevantNodes","filter","push","imageSetFunction","imageSetOptionNodes","parent","mediasByDpr","Map","declValue","i","length","mediasByDprPerItem","index","comma","mediaDPI","media","has","set","m","get","replace","trim","values","parentClone","clone","removeAll","declClone","append","medias","Array","from","keys","sort","a","b","map","smallestMedia","mediasWithoutSmallest","slice","after","firstDecl","cloneBefore","remove","processImageSet"],"mappings":"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"}