Move scope of variables down in compile-variables

This commit is contained in:
RMidhunSuresh 2022-06-17 16:35:18 +05:30
parent 623939c671
commit 09b2437e72

View File

@ -30,12 +30,7 @@ const valueParser = require("postcss-value-parser");
* The actual derivation is done outside the plugin in a callback. * The actual derivation is done outside the plugin in a callback.
*/ */
let aliasMap; function getValueFromAlias(alias, {aliasMap, baseVariables, resolvedMap}) {
let resolvedMap;
let baseVariables;
let isDark;
function getValueFromAlias(alias) {
const derivedVariable = aliasMap.get(alias); const derivedVariable = aliasMap.get(alias);
return baseVariables.get(derivedVariable) ?? resolvedMap.get(derivedVariable); return baseVariables.get(derivedVariable) ?? resolvedMap.get(derivedVariable);
} }
@ -68,14 +63,15 @@ function parseDeclarationValue(value) {
return variables; return variables;
} }
function resolveDerivedVariable(decl, derive) { function resolveDerivedVariable(decl, derive, maps, isDark) {
const { baseVariables, resolvedMap } = maps;
const RE_VARIABLE_VALUE = /(?:--)?((.+)--(.+)-(.+))/; const RE_VARIABLE_VALUE = /(?:--)?((.+)--(.+)-(.+))/;
const variableCollection = parseDeclarationValue(decl.value); const variableCollection = parseDeclarationValue(decl.value);
for (const variable of variableCollection) { for (const variable of variableCollection) {
const matches = variable.match(RE_VARIABLE_VALUE); const matches = variable.match(RE_VARIABLE_VALUE);
if (matches) { if (matches) {
const [, wholeVariable, baseVariable, operation, argument] = matches; const [, wholeVariable, baseVariable, operation, argument] = matches;
const value = baseVariables.get(baseVariable) ?? getValueFromAlias(baseVariable); const value = baseVariables.get(baseVariable) ?? getValueFromAlias(baseVariable, maps);
if (!value) { if (!value) {
throw new Error(`Cannot derive from ${baseVariable} because it is neither defined in config nor is it an alias!`); throw new Error(`Cannot derive from ${baseVariable} because it is neither defined in config nor is it an alias!`);
} }
@ -85,7 +81,7 @@ function resolveDerivedVariable(decl, derive) {
} }
} }
function extract(decl) { function extract(decl, {aliasMap, baseVariables}) {
if (decl.variable) { if (decl.variable) {
// see if right side is of form "var(--foo)" // see if right side is of form "var(--foo)"
const wholeVariable = decl.value.match(/var\(--(.+)\)/)?.[1]; const wholeVariable = decl.value.match(/var\(--(.+)\)/)?.[1];
@ -100,7 +96,7 @@ function extract(decl) {
} }
} }
function addResolvedVariablesToRootSelector(root, {Rule, Declaration}) { function addResolvedVariablesToRootSelector(root, {Rule, Declaration}, {resolvedMap}) {
const newRule = new Rule({ selector: ":root", source: root.source }); const newRule = new Rule({ selector: ":root", source: root.source });
// Add derived css variables to :root // Add derived css variables to :root
resolvedMap.forEach((value, key) => { resolvedMap.forEach((value, key) => {
@ -110,7 +106,7 @@ function addResolvedVariablesToRootSelector(root, {Rule, Declaration}) {
root.append(newRule); root.append(newRule);
} }
function populateMapWithDerivedVariables(map, cssFileLocation) { function populateMapWithDerivedVariables(map, cssFileLocation, {resolvedMap, aliasMap}) {
const location = cssFileLocation.match(/(.+)\/.+\.css/)?.[1]; const location = cssFileLocation.match(/(.+)\/.+\.css/)?.[1];
const derivedVariables = [ const derivedVariables = [
...([...resolvedMap.keys()].filter(v => !aliasMap.has(v))), ...([...resolvedMap.keys()].filter(v => !aliasMap.has(v))),
@ -133,10 +129,10 @@ function populateMapWithDerivedVariables(map, cssFileLocation) {
* @param {Map} opts.compiledVariables - A map that stores derived variables so that manifest source sections can be produced * @param {Map} opts.compiledVariables - A map that stores derived variables so that manifest source sections can be produced
*/ */
module.exports = (opts = {}) => { module.exports = (opts = {}) => {
aliasMap = new Map(); const aliasMap = new Map();
resolvedMap = new Map(); const resolvedMap = new Map();
baseVariables = new Map(); const baseVariables = new Map();
isDark = false; const maps = { aliasMap, resolvedMap, baseVariables };
return { return {
postcssPlugin: "postcss-compile-variables", postcssPlugin: "postcss-compile-variables",
@ -147,16 +143,16 @@ module.exports = (opts = {}) => {
// If this is a runtime theme, don't derive variables. // If this is a runtime theme, don't derive variables.
return; return;
} }
isDark = cssFileLocation.includes("dark=true"); const isDark = cssFileLocation.includes("dark=true");
/* /*
Go through the CSS file once to extract all aliases and base variables. Go through the CSS file once to extract all aliases and base variables.
We use these when resolving derived variables later. We use these when resolving derived variables later.
*/ */
root.walkDecls(decl => extract(decl)); root.walkDecls(decl => extract(decl, maps));
root.walkDecls(decl => resolveDerivedVariable(decl, opts.derive)); root.walkDecls(decl => resolveDerivedVariable(decl, opts.derive, maps, isDark));
addResolvedVariablesToRootSelector(root, {Rule, Declaration}); addResolvedVariablesToRootSelector(root, {Rule, Declaration}, maps);
if (opts.compiledVariables){ if (opts.compiledVariables){
populateMapWithDerivedVariables(opts.compiledVariables, cssFileLocation); populateMapWithDerivedVariables(opts.compiledVariables, cssFileLocation, maps);
} }
// Also produce a mapping from alias to completely resolved color // Also produce a mapping from alias to completely resolved color
const resolvedAliasMap = new Map(); const resolvedAliasMap = new Map();