{"version":3,"sources":["../src/utils/index.ts","../src/generate/index.ts","../src/embed/index.ts"],"names":["combinations","list","mods","index","propertyName","lastVariations","newVariables","base","s","c","i","n","r","rulesListWithoutVariations","undefined","ainsleyChildrenToAst","children","options","ainsleyRule","css","styleEl","id","t","o","e","length","firstChange","startsWith","l","variationInstruction","every","selector","variationAbbreviation","map","declaration","join"],"mappings":"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","sourcesContent":["export const isObject = (val: unknown): boolean =>\n !!(val !== null && typeof val === 'object' && !Array.isArray(val))\n\nexport const combinations = (mods: T[][]): T[][] => {\n let list: T[][] = [[]]\n let index = 0\n while (index < mods.length) {\n list = mods[index++].flatMap((option) =>\n list.map((prev) => prev.concat([option]))\n )\n }\n return list\n}\n","import {\n Ainsley,\n AinsleyRule,\n AinsleyPropertyOrPlaceholder,\n AinsleyVariableMap,\n AinsleyChild,\n AinsleyChildren,\n AinsleyGenerateOptions\n} from '../types'\nimport { combinations } from '../utils'\n\ninterface AinsleyASTNode {\n $variations: Array<[string, string]>\n $content: string | AinsleyRule\n}\ntype AinsleyAST = AinsleyASTNode[]\n\nexport const ITERATOR_REGEX = '\\\\{[a-zA-Z0-9_-]+\\\\}'\nexport const DEFAULT_OPTIONS: AinsleyGenerateOptions = {\n addVariationToSelector: (selector, variationAbbreviation) =>\n variationAbbreviation + '_' + selector,\n addPropertyToSelector: (selector, propertyAbbreviation) =>\n selector + '-' + propertyAbbreviation,\n addValueToSelector: (selector, valueAbbreviation) =>\n selector + '-' + valueAbbreviation,\n abbreviateProperty: (propertyName) => [\n propertyName\n .split('-')\n .map((word) => word[0])\n .join(''),\n propertyName\n ]\n}\n\nconst ITERATOR_SEARCH = new RegExp(ITERATOR_REGEX, 'g')\n\nexport const generate = (\n ainsley: Ainsley,\n options: Partial = {}\n): string => {\n const mergedOptions = { ...DEFAULT_OPTIONS, ...options }\n return generateFromAst(\n ainsleyToAst(ainsley, mergedOptions, {}),\n mergedOptions\n )\n}\n\n// next step:\n// get variations to append to nested variations by passing them down;\n// kinda like variables. this allows us to merge nested variations in the output\n// which is kinda fun. but mostly because I don't know another way to do it\n\n// next next step:\n// get combinations to return a read only array - avoiding the need to\n// recursively clone and concat - also means comparisons for this flattening\n// business is made much simpler\n\nconst generateFromAst = (\n ainsleyRules: AinsleyAST,\n options: AinsleyGenerateOptions\n): string => {\n let css = ''\n let lastVariations: Array<[string, string]> = []\n\n for (let i = 0; i < ainsleyRules.length; i++) {\n const ainsleyRule = ainsleyRules[i]\n\n let firstChange = 0\n while (\n firstChange < lastVariations.length &&\n lastVariations[firstChange] === ainsleyRule.$variations[firstChange]\n ) {\n firstChange += 1\n }\n\n const variationsToClose = lastVariations.slice(firstChange)\n for (const variationToClose of variationsToClose) {\n const variationInstruction = variationToClose[1]\n if (variationInstruction.startsWith('@')) {\n css += '}'\n }\n }\n const variationsToOpen = ainsleyRule.$variations.slice(firstChange)\n for (const variationToOpen of variationsToOpen) {\n const variationInstruction = variationToOpen[1]\n if (variationInstruction.startsWith('@')) {\n css += `${variationInstruction}{`\n }\n }\n\n if (typeof ainsleyRule.$content === 'string') {\n if (ainsleyRule.$variations.every((pair) => pair[1] === '')) {\n css += ainsleyRule.$content\n }\n } else {\n let selector = ainsleyRule.$content[0]\n let selectorSuffix = ''\n\n for (let i = 0; i < ainsleyRule.$variations.length; i++) {\n const variationAbbreviation = ainsleyRule.$variations[i][0]\n const variationInstruction = ainsleyRule.$variations[i][1]\n if (variationInstruction === '') continue\n if (!variationInstruction.startsWith('@')) {\n selectorSuffix += `${variationInstruction}`\n }\n selector = options.addVariationToSelector(\n selector,\n variationAbbreviation\n )\n }\n css += `.${selector}${selectorSuffix}{${ainsleyRule.$content[1]\n .map((declaration) => `${declaration[0]}:${declaration[1]}`)\n .join(';')}}`\n }\n lastVariations = ainsleyRule.$variations\n }\n for (const variationToClose of lastVariations) {\n const variationInstruction = variationToClose[1]\n if (variationInstruction.startsWith('@')) css += '}'\n }\n return css\n}\n\nconst ainsleyToAst = (\n ainsley: Ainsley,\n options: AinsleyGenerateOptions,\n inheritedVariables: AinsleyVariableMap\n): AinsleyAST => {\n // first, compute variables\n const newVariables = { ...inheritedVariables }\n if (ainsley.variables !== undefined) {\n const variables = ainsley.variables\n Object.keys(variables).map((variable: string) => {\n const modAndBase = parseVariable(variable)\n const mod = modAndBase[0]\n const base = modAndBase[1]\n if (mod === 0 || (mod === 1 && newVariables[base] === undefined)) {\n newVariables[base] = variables[variable]\n } else if (mod === 2) {\n newVariables[base] = {\n ...(inheritedVariables[base] ?? {}),\n ...variables[variable]\n }\n }\n })\n }\n\n // then, flatten children into ast\n const rulesListWithoutVariations =\n ainsley.children === undefined\n ? []\n : ainsleyChildrenToAst(ainsley.children, options, newVariables)\n\n // lastly, multiply ast with variations\n const rulesList = combinations(\n (ainsley.variations ?? []).map((variationSet) =>\n [['', ''] as [string, string]].concat(variationSet)\n )\n ).flatMap((variations) =>\n rulesListWithoutVariations.map((ainsleyASTNode) => ({\n $variations: [...variations, ...ainsleyASTNode.$variations],\n $content: ainsleyASTNode.$content\n }))\n )\n\n return rulesList\n}\n\nconst ainsleyChildrenToAst = (\n ainsleyChildren: AinsleyChildren,\n options: AinsleyGenerateOptions,\n variables: AinsleyVariableMap\n): AinsleyAST =>\n ainsleyChildren.flatMap((child: AinsleyChild) => {\n if (typeof child === 'string') {\n return [\n {\n $variations: [],\n $content: child\n }\n ]\n } else if (Array.isArray(child)) {\n if (Array.isArray(child[1])) {\n return ainsleyRuleToAst(child as AinsleyRule, options, variables)\n } else {\n return ainsleyPropertyToAst(\n child as AinsleyPropertyOrPlaceholder,\n options\n )\n }\n } else {\n return ainsleyToAst(child, options, variables)\n }\n })\n\ntype AinsleyGenerateIteratorContext = [string, string, string | number, number]\n\nconst ainsleyRuleToAst = (\n ainsleyRule: AinsleyRule,\n options: AinsleyGenerateOptions,\n variables: AinsleyVariableMap\n): AinsleyAST => {\n const selector = ainsleyRule[0]\n const declarations = ainsleyRule[1]\n const variablesFound: Array<[string, number]> = []\n declarations.map((declaration) => {\n const propertyMatches = declaration[0].match(ITERATOR_SEARCH) ?? []\n const valueMatches = `${declaration[1]}`.match(ITERATOR_SEARCH) ?? []\n propertyMatches.map((match) => variablesFound.push([match, 0]))\n valueMatches.map((match) => variablesFound.push([match, 1]))\n })\n\n return combinations(\n variablesFound.map((iteratorAndType: [string, number]) => {\n const iterator = iteratorAndType[0]\n const location = iteratorAndType[1]\n const variableName = iterator.slice(1, -1)\n\n return Object.keys(variables[variableName]).map(\n (abbreviation: string): AinsleyGenerateIteratorContext => [\n iterator,\n abbreviation,\n variables[variableName][abbreviation],\n location\n ]\n )\n })\n ).map((combination) => {\n let combinationIndex = 0\n let current: AinsleyGenerateIteratorContext = combination[combinationIndex]\n\n return {\n $variations: [],\n $content: [\n combination.reduce(\n (selector: string, part: AinsleyGenerateIteratorContext) => {\n if (part[3] === 0) {\n return options.addPropertyToSelector(selector, part[1])\n } /* if (part[3] === 1) */ else {\n return options.addValueToSelector(selector, part[1])\n }\n },\n selector\n ),\n declarations.map((declaration) => {\n const replacePart = (declarationPart: string): string => {\n while (\n combinationIndex < combination.length &&\n declarationPart.includes(current[0])\n ) {\n declarationPart = declarationPart.replace(\n current[0],\n `${current[2]}`\n )\n current = combination[++combinationIndex]\n }\n return declarationPart\n }\n return [replacePart(declaration[0]), replacePart(`${declaration[1]}`)]\n })\n ]\n }\n })\n}\n\nconst ainsleyPropertyToAst = (\n ainsleyProperty: AinsleyPropertyOrPlaceholder,\n options: AinsleyGenerateOptions\n): AinsleyAST => {\n const propertyInput = ainsleyProperty[0]\n const propertyValues = ainsleyProperty[1]\n\n const propertyData: [string, string] = options.abbreviateProperty(\n propertyInput\n )\n const propertyAbbreviation = propertyData[0]\n const propertyName = propertyData[1]\n\n return Object.keys(propertyValues).map((valueAbbreviation: string) => ({\n $variations: [],\n $content: [\n options.addValueToSelector(\n options.addPropertyToSelector('', propertyAbbreviation),\n valueAbbreviation\n ),\n [[propertyName, propertyValues[valueAbbreviation]]]\n ]\n }))\n}\n\nconst parseVariable = (variable: string): [number, string] => {\n const mod = '?+'.indexOf(variable[0]) + 1\n const base = mod > 0 ? variable.slice(1) : variable\n return [mod, base]\n}\n","// singleton embed pattern, using id as the unique identifier\nexport const embed = (css: string, id?: string): void => {\n let styleEl: HTMLStyleElement | null = null\n if (id !== undefined) styleEl = document.querySelector(`style#${id}`)\n\n if (styleEl === null) {\n styleEl = document.createElement('style')\n styleEl.type = 'text/css'\n if (id !== undefined) styleEl.setAttribute('id', id)\n document.head.appendChild(styleEl)\n }\n\n styleEl.innerHTML = css\n}\n"]}