'use strict';
const selectorParser = require('postcss-selector-parser');
const valueParser = require('postcss-value-parser');
const { parser } = require('../parser.js');
const reducer = require('./reducer.js');
const stringifier = require('./stringifier.js');
const MATCH_CALC = /((?:-(moz|webkit)-)?calc)/i;
function transformValue(value, options, result, item) {
return valueParser(value)
.walk((node) => {
if (node.type !== 'function' || !MATCH_CALC.test(node.value)) {
return;
}
const contents = valueParser.stringify(node.nodes);
const ast = parser.parse(contents);
const reducedAst = reducer(ast, options.precision);
(node).type = 'word';
node.value = stringifier(
node.value,
reducedAst,
value,
options,
result,
item
);
return false;
})
.toString();
}
function transformSelector(value, options, result, item) {
return selectorParser((selectors) => {
selectors.walk((node) => {
if (node.type === 'attribute' && node.value) {
node.setValue(transformValue(node.value, options, result, item));
}
if (node.type === 'tag') {
node.value = transformValue(node.value, options, result, item);
}
return;
});
}).processSync(value);
}
module.exports = (node, property, options, result) => {
let value = node[property];
try {
value =
property === 'selector'
? transformSelector(node[property], options, result, node)
: transformValue(node[property], options, result, node);
} catch (error) {
if (error instanceof Error) {
result.warn(error.message, { node });
} else {
result.warn('Error', { node });
}
return;
}
if (options.preserve && node[property] !== value) {
const clone = node.clone();
clone[property] = value;
node.parent.insertBefore(node, clone);
} else {
node[property] = value;
}
};