UNPKG

postcss-custom-values

Version:

[![NPM Version][npm-img]][npm-url] [![Build Status][cli-img]][cli-url] [![Support Chat][git-img]][git-url]

113 lines (90 loc) 3.45 kB
import postcss from 'postcss'; var tokens = [{ name: "number", regex: /[+-]?\d*\.?\d+/ }, { name: "integer", regex: /[+-]?[1-9]\d*|0/ }, { name: "side", regex: /top|right|bottom|left/ }]; var genericToken = /<(\w+)>/; function tokenRegex(string) { // Takes string where token is referenced as ident eg. layout_<direction> let regex; if (string.match(genericToken)) { // Create array with regex for standard token and capture name let ident = [string.match(genericToken)[0], string.match(genericToken)[1]]; // For each token definition for (let i = 0; i < tokens.length; i++) { // If defined token matches ident if (tokens[i].name === ident[1]) { string = string.replace(genericToken, "(" + tokens[i].regex.source + ")"); // Create a regex which can be used to find matching things and capture value regex = new RegExp(string); } } } else { regex = new RegExp("\\b" + string + "\\b", 'gi'); } // Outputs regex that looks for exact match of string plus token eg. /layout_(left|right)/ return regex; } // export function tokenMatches(string, regex) { // return string.match(regex)[1]; // } function getKeyword(root) { let keywords = []; // Look for every keyword definition root.walkAtRules("value", rule => { // Create object so can look for keywords in CSS let keyword = {}; let propsArray = []; let propertyThing = /property\((.+)\)/; rule.each(decl => { // Grab value if (decl.prop === "value") { keyword.value = decl.value; } // Grab array of properties if (rule.params.match(propertyThing)) { let array = rule.params.match(propertyThing)[1].split(","); for (let i = 0; i < array.length; i++) { propsArray.push(array[i].trim()); } } }); // Create regex to allow matching of properties keyword.props = new RegExp(propsArray.join("|"), 'i'); // Create regex to replace instances of word in declaration value let nameString = rule.params.toString(); let name = nameString.replace(propertyThing, "").trim(); keyword.name = tokenRegex(name); keywords.push(keyword); }); // Reverse array so that keyword definitions that are declared later in document overide earlier rules keywords.reverse(); return keywords; } var index = postcss.plugin("postcss-custom-value", () => { return root => { // console.log("root, result", root, result); const keywords = getKeyword(root); // For each keyword definition for (let i = 0; i < keywords.length; i++) { let keyword = keywords[i]; // For each declration with matching properties root.walkDecls(keyword.props, decl => { // If value if (decl.value.match(keyword.name)) { // Replace instances of keyword name with correct value var array1 = postcss.list.space(decl.value); for (let b = 0; b < array1.length; b++) { if (array1[b].match(keyword.name)) { if (keyword.value.match(/\$0/gi)) { array1[b] = keyword.value.replace(/\$0/gi, array1[b].match(keyword.name)[1]); } else { array1[b] = array1[b].replace(keyword.name, keyword.value); } } } decl.value = array1.join(" "); } }); } root.walkAtRules("value", rule => { rule.remove(); }); }; }); export default index;