8889841cREADME.md000066600000002574150441764500006045 0ustar00# [postcss][postcss]-ordered-values > Ensure values are ordered consistently in your CSS. ## Install With [npm](https://npmjs.org/package/postcss-ordered-values) do: ``` npm install postcss-ordered-values --save ``` ## Example Some CSS properties accept their values in an arbitrary order; for this reason, it is entirely possible that different developers will write their values in different orders. This module normalizes the order, making it easier for other modules to understand which declarations are duplicates. ### Input ```css h1 { border: solid 1px red; border: red solid .5em; border: rgba(0, 30, 105, 0.8) solid 1px; border: 1px solid red; } ``` ### Output ```css h1 { border: 1px solid red; border: .5em solid red; border: 1px solid rgba(0, 30, 105, 0.8); border: 1px solid red; } ``` ## Support List For more examples, see the [tests](src/__tests__/index.js). * `animation`, `-webkit-animation` * `border(border-left|right|top|bottom)` * `box-shadow` * `outline` * `flex-flow` * `transition`, `-webkit-transition` ## Usage See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for examples for your environment. ## Contributors See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md). ## License MIT © [Ben Briggs](http://beneb.info) [postcss]: https://github.com/postcss/postcss src/index.js000066600000010276150441764500007020 0ustar00'use strict'; const valueParser = require('postcss-value-parser'); const { normalizeGridAutoFlow, normalizeGridColumnRowGap, normalizeGridColumnRow, } = require('./rules/grid'); // rules const animation = require('./rules/animation'); const border = require('./rules/border'); const boxShadow = require('./rules/boxShadow'); const flexFlow = require('./rules/flexFlow'); const transition = require('./rules/transition'); const listStyle = require('./rules/listStyle'); const column = require('./rules/columns'); const vendorUnprefixed = require('./lib/vendorUnprefixed.js'); /** @type {[string, (parsed: valueParser.ParsedValue) => string][]} */ const borderRules = [ ['border', border], ['border-block', border], ['border-inline', border], ['border-block-end', border], ['border-block-start', border], ['border-inline-end', border], ['border-inline-start', border], ['border-top', border], ['border-right', border], ['border-bottom', border], ['border-left', border], ]; /** @type {[string, (parsed: valueParser.ParsedValue) => string | string[] | valueParser.ParsedValue][]} */ const grid = [ ['grid-auto-flow', normalizeGridAutoFlow], ['grid-column-gap', normalizeGridColumnRowGap], // normal | ['grid-row-gap', normalizeGridColumnRowGap], // normal | ['grid-column', normalizeGridColumnRow], // + ['grid-row', normalizeGridColumnRow], // + ['grid-row-start', normalizeGridColumnRow], // ['grid-row-end', normalizeGridColumnRow], // ['grid-column-start', normalizeGridColumnRow], // ['grid-column-end', normalizeGridColumnRow], // ]; /** @type {[string, (parsed: valueParser.ParsedValue) => string | valueParser.ParsedValue][]} */ const columnRules = [ ['column-rule', border], ['columns', column], ]; /** @type {Map string | string[] | valueParser.ParsedValue)>} */ const rules = new Map([ ['animation', animation], ['outline', border], ['box-shadow', boxShadow], ['flex-flow', flexFlow], ['list-style', listStyle], ['transition', transition], ...borderRules, ...grid, ...columnRules, ]); const variableFunctions = new Set(['var', 'env', 'constant']); /** * @param {valueParser.Node} node * @return {boolean} */ function isVariableFunctionNode(node) { if (node.type !== 'function') { return false; } return variableFunctions.has(node.value.toLowerCase()); } /** * @param {valueParser.ParsedValue} parsed * @return {boolean} */ function shouldAbort(parsed) { let abort = false; parsed.walk((node) => { if ( node.type === 'comment' || isVariableFunctionNode(node) || (node.type === 'word' && node.value.includes(`___CSS_LOADER_IMPORT___`)) ) { abort = true; return false; } }); return abort; } /** * @param {import('postcss').Declaration} decl * @return {string} */ function getValue(decl) { let { value, raws } = decl; if (raws && raws.value && raws.value.raw) { value = raws.value.raw; } return value; } /** * @type {import('postcss').PluginCreator} * @return {import('postcss').Plugin} */ function pluginCreator() { return { postcssPlugin: 'postcss-ordered-values', prepare() { const cache = new Map(); return { OnceExit(css) { css.walkDecls((decl) => { const lowerCasedProp = decl.prop.toLowerCase(); const normalizedProp = vendorUnprefixed(lowerCasedProp); const processor = rules.get(normalizedProp); if (!processor) { return; } const value = getValue(decl); if (cache.has(value)) { decl.value = cache.get(value); return; } const parsed = valueParser(value); if (parsed.nodes.length < 2 || shouldAbort(parsed)) { cache.set(value, value); return; } const result = processor(parsed); decl.value = result.toString(); cache.set(value, result.toString()); }); }, }; }, }; } pluginCreator.postcss = true; module.exports = pluginCreator; src/rules/transition.js000066600000003652150441764500011235 0ustar00'use strict'; const { unit } = require('postcss-value-parser'); const { getArguments } = require('cssnano-utils'); const addSpace = require('../lib/addSpace'); const getValue = require('../lib/getValue'); // transition: [ none | ] ||