/* eslint-disable no-param-reassign */ import parse from 'postcss-value-parser' import camelizeStyleName from 'camelize' import transforms from './transforms/index' import TokenStream from './TokenStream' // Note if this is wrong, you'll need to change tokenTypes.js too const numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?)(?:px)?$/i const boolRe = /^true|false$/i const nullRe = /^null$/i const undefinedRe = /^undefined$/i // Undocumented export export const transformRawValue = input => { const value = input.trim() const numberMatch = value.match(numberOrLengthRe) if (numberMatch !== null) return Number(numberMatch[1]) const boolMatch = input.match(boolRe) if (boolMatch !== null) return boolMatch[0].toLowerCase() === 'true' const nullMatch = input.match(nullRe) if (nullMatch !== null) return null const undefinedMatch = input.match(undefinedRe) if (undefinedMatch !== null) return undefined return value } const baseTransformShorthandValue = (propName, inputValue) => { const ast = parse(inputValue.trim()) const tokenStream = new TokenStream(ast.nodes) return transforms[propName](tokenStream) } const transformShorthandValue = process.env.NODE_ENV === 'production' ? baseTransformShorthandValue : (propName, inputValue) => { try { return baseTransformShorthandValue(propName, inputValue) } catch (e) { throw new Error( `Failed to parse declaration "${propName}: ${inputValue}"` ) } } export const getStylesForProperty = (propName, inputValue, allowShorthand) => { const isRawValue = allowShorthand === false || !(propName in transforms) const propValues = isRawValue ? { [propName]: transformRawValue(inputValue) } : transformShorthandValue(propName, inputValue.trim()) return propValues } export const getPropertyName = propName => { const isCustomProp = /^--\w+/.test(propName) if (isCustomProp) { return propName } return camelizeStyleName(propName) } export default (rules, shorthandBlacklist = []) => rules.reduce((accum, rule) => { const propertyName = getPropertyName(rule[0]) const value = rule[1] const allowShorthand = shorthandBlacklist.indexOf(propertyName) === -1 return Object.assign( accum, getStylesForProperty(propertyName, value, allowShorthand) ) }, {})