-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: values should be replaced in selectors as well
- Loading branch information
Showing
4 changed files
with
141 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,119 +1,118 @@ | ||
'use strict'; | ||
'use strict' | ||
|
||
const postcss = require('postcss'); | ||
const ICSSReplaceSymbols = require('icss-replace-symbols'); | ||
const replaceSymbols = require('icss-replace-symbols'); | ||
const postcss = require('postcss') | ||
const ICSSUtils = require('icss-utils') | ||
|
||
const matchImports = /^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/; | ||
const matchValueDefinition = /(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g; | ||
const matchImport = /^([\w-]+)(?:\s+as\s+([\w-]+))?/; | ||
const matchImports = /^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/ | ||
const matchValueDefinition = /(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g | ||
const matchImport = /^([\w-]+)(?:\s+as\s+([\w-]+))?/ | ||
|
||
let options = {}; | ||
let importIndex = 0; | ||
let options = {} | ||
let importIndex = 0 | ||
let createImportedName = | ||
(options && options.createImportedName) || | ||
((importName /*, path*/) => | ||
`i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`); | ||
`i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`) | ||
|
||
module.exports = postcss.plugin( | ||
'postcss-modules-values', | ||
() => (css, result) => { | ||
const importAliases = []; | ||
const definitions = {}; | ||
const importAliases = [] | ||
const definitions = {} | ||
|
||
const addDefinition = atRule => { | ||
let matches; | ||
let matches | ||
while ((matches = matchValueDefinition.exec(atRule.params))) { | ||
let [, /*match*/ key, value] = matches; | ||
let [, /*match*/ key, value] = matches | ||
// Add to the definitions, knowing that values can refer to each other | ||
definitions[key] = replaceSymbols.replaceAll(definitions, value); | ||
atRule.remove(); | ||
definitions[key] = ICSSUtils.replaceValueSymbols(value, definitions) | ||
atRule.remove() | ||
} | ||
}; | ||
} | ||
|
||
const addImport = atRule => { | ||
const matches = matchImports.exec(atRule.params); | ||
const matches = matchImports.exec(atRule.params) | ||
if (matches) { | ||
let [, /*match*/ aliases, path] = matches; | ||
let [, /*match*/ aliases, path] = matches | ||
// We can use constants for path names | ||
if (definitions[path]) { | ||
path = definitions[path]; | ||
path = definitions[path] | ||
} | ||
const imports = aliases | ||
.replace(/^\(\s*([\s\S]+)\s*\)$/, '$1') | ||
.split(/\s*,\s*/) | ||
.map(alias => { | ||
const tokens = matchImport.exec(alias); | ||
const tokens = matchImport.exec(alias) | ||
if (tokens) { | ||
const [, /*match*/ theirName, myName = theirName] = tokens; | ||
const importedName = createImportedName(myName); | ||
definitions[myName] = importedName; | ||
return { theirName, importedName }; | ||
const [, /*match*/ theirName, myName = theirName] = tokens | ||
const importedName = createImportedName(myName) | ||
definitions[myName] = importedName | ||
return { theirName, importedName } | ||
} else { | ||
throw new Error(`@import statement "${alias}" is invalid!`); | ||
throw new Error(`@import statement "${alias}" is invalid!`) | ||
} | ||
}); | ||
importAliases.push({ path, imports }); | ||
atRule.remove(); | ||
}) | ||
importAliases.push({ path, imports }) | ||
atRule.remove() | ||
} | ||
}; | ||
} | ||
|
||
/* Look at all the @value statements and treat them as locals or as imports */ | ||
css.walkAtRules('value', atRule => { | ||
if (matchImports.exec(atRule.params)) { | ||
addImport(atRule); | ||
addImport(atRule) | ||
} else { | ||
if (atRule.params.indexOf('@value') !== -1) { | ||
result.warn('Invalid value definition: ' + atRule.params); | ||
result.warn('Invalid value definition: ' + atRule.params) | ||
} | ||
|
||
addDefinition(atRule); | ||
addDefinition(atRule) | ||
} | ||
}); | ||
}) | ||
|
||
/* We want to export anything defined by now, but don't add it to the CSS yet or | ||
it well get picked up by the replacement stuff */ | ||
const exportDeclarations = Object.keys(definitions).map(key => | ||
postcss.decl({ | ||
value: definitions[key], | ||
prop: key, | ||
raws: { before: '\n ' } | ||
raws: { before: '\n ' }, | ||
}) | ||
); | ||
) | ||
|
||
/* If we have no definitions, don't continue */ | ||
if (!Object.keys(definitions).length) { | ||
return; | ||
return | ||
} | ||
|
||
/* Perform replacements */ | ||
ICSSReplaceSymbols.default(css, definitions); | ||
ICSSUtils.replaceSymbols(css, definitions) | ||
|
||
/* Add export rules if any */ | ||
if (exportDeclarations.length > 0) { | ||
const exportRule = postcss.rule({ | ||
selector: ':export', | ||
raws: { after: '\n' } | ||
}); | ||
exportRule.append(exportDeclarations); | ||
css.prepend(exportRule); | ||
raws: { after: '\n' }, | ||
}) | ||
exportRule.append(exportDeclarations) | ||
css.prepend(exportRule) | ||
} | ||
|
||
/* Add import rules */ | ||
importAliases.reverse().forEach(({ path, imports }) => { | ||
const importRule = postcss.rule({ | ||
selector: `:import(${path})`, | ||
raws: { after: '\n' } | ||
}); | ||
raws: { after: '\n' }, | ||
}) | ||
imports.forEach(({ theirName, importedName }) => { | ||
importRule.append({ | ||
value: theirName, | ||
prop: importedName, | ||
raws: { before: '\n ' } | ||
}); | ||
}); | ||
raws: { before: '\n ' }, | ||
}) | ||
}) | ||
|
||
css.prepend(importRule); | ||
}); | ||
css.prepend(importRule) | ||
}) | ||
} | ||
); | ||
) |
Oops, something went wrong.