|
@ -16,7 +16,9 @@ var defaults = { |
|
|
propList: ['*'], |
|
|
propList: ['*'], |
|
|
minPixelValue: 1, |
|
|
minPixelValue: 1, |
|
|
mediaQuery: false, |
|
|
mediaQuery: false, |
|
|
replace: true |
|
|
|
|
|
|
|
|
replace: true, |
|
|
|
|
|
landscape: false, |
|
|
|
|
|
landscapeUnit: 'vh' |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
module.exports = postcss.plugin('postcss-px-to-viewport', function (options) { |
|
|
module.exports = postcss.plugin('postcss-px-to-viewport', function (options) { |
|
@ -24,7 +26,8 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) { |
|
|
var opts = objectAssign({}, defaults, options); |
|
|
var opts = objectAssign({}, defaults, options); |
|
|
var pxRegex = getUnitRegexp(opts.unitToConvert); |
|
|
var pxRegex = getUnitRegexp(opts.unitToConvert); |
|
|
var satisfyPropList = createPropListMatcher(opts.propList); |
|
|
var satisfyPropList = createPropListMatcher(opts.propList); |
|
|
|
|
|
|
|
|
|
|
|
var landscapeRules = []; |
|
|
|
|
|
|
|
|
return function (css) { |
|
|
return function (css) { |
|
|
css.walkRules(function (rule) { |
|
|
css.walkRules(function (rule) { |
|
|
// Add exclude option to ignore some files like 'node_modules'
|
|
|
// Add exclude option to ignore some files like 'node_modules'
|
|
@ -42,18 +45,32 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (rule.parent.params && !opts.mediaQuery) return; |
|
|
|
|
|
|
|
|
if (!validateParams(rule.parent.params, opts.mediaQuery)) return; |
|
|
if (blacklistedSelector(opts.selectorBlackList, rule.selector)) return; |
|
|
if (blacklistedSelector(opts.selectorBlackList, rule.selector)) return; |
|
|
|
|
|
|
|
|
|
|
|
if (opts.landscape && !rule.parent.params) { |
|
|
|
|
|
var landscapeRule = rule.clone().removeAll(); |
|
|
|
|
|
landscapeRules.push(landscapeRule); |
|
|
|
|
|
|
|
|
|
|
|
rule.walkDecls(function(decl) { |
|
|
|
|
|
if (decl.value.indexOf(opts.unitToConvert) === -1) return; |
|
|
|
|
|
if (!satisfyPropList(decl.prop)) return; |
|
|
|
|
|
|
|
|
|
|
|
landscapeRule.append(decl.clone({ |
|
|
|
|
|
value: decl.value.replace(pxRegex, createPxReplace(opts, opts.landscapeUnit)) |
|
|
|
|
|
})); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
rule.walkDecls(function(decl, i) { |
|
|
rule.walkDecls(function(decl, i) { |
|
|
if (decl.value.indexOf(opts.unitToConvert) === -1) return; |
|
|
if (decl.value.indexOf(opts.unitToConvert) === -1) return; |
|
|
if (!satisfyPropList(decl.prop)) return; |
|
|
if (!satisfyPropList(decl.prop)) return; |
|
|
|
|
|
|
|
|
var unit = getUnit(decl.prop, opts); |
|
|
var unit = getUnit(decl.prop, opts); |
|
|
var value = decl.value.replace(pxRegex, createPxReplace(opts.viewportWidth, opts.minPixelValue, opts.unitPrecision, unit)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var value = decl.value.replace(pxRegex, createPxReplace(opts, unit)); |
|
|
|
|
|
|
|
|
if (declarationExists(decl.parent, decl.prop, value)) return; |
|
|
if (declarationExists(decl.parent, decl.prop, value)) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (opts.replace) { |
|
|
if (opts.replace) { |
|
|
decl.value = value; |
|
|
decl.value = value; |
|
|
} else { |
|
|
} else { |
|
@ -61,6 +78,13 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) { |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (landscapeRules.length > 0) { |
|
|
|
|
|
var landscapeRoot = new postcss.atRule({ params: '(orientation: landscape)', name: 'media' }); |
|
|
|
|
|
|
|
|
|
|
|
landscapeRules.forEach(rule => landscapeRoot.append(rule)); |
|
|
|
|
|
css.append(landscapeRoot); |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
@ -75,12 +99,12 @@ function getUnit(prop, opts) { |
|
|
return prop.indexOf('font') === -1 ? opts.viewportUnit : opts.fontViewportUnit; |
|
|
return prop.indexOf('font') === -1 ? opts.viewportUnit : opts.fontViewportUnit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function createPxReplace(viewportSize, minPixelValue, unitPrecision, viewportUnit) { |
|
|
|
|
|
|
|
|
function createPxReplace(opts, viewportUnit) { |
|
|
return function (m, $1) { |
|
|
return function (m, $1) { |
|
|
if (!$1) return m; |
|
|
if (!$1) return m; |
|
|
var pixels = parseFloat($1); |
|
|
var pixels = parseFloat($1); |
|
|
if (pixels <= minPixelValue) return m; |
|
|
|
|
|
var parsedVal = toFixed((pixels / viewportSize * 100), unitPrecision); |
|
|
|
|
|
|
|
|
if (pixels <= opts.minPixelValue) return m; |
|
|
|
|
|
var parsedVal = toFixed((pixels / opts.viewportWidth * 100), opts.unitPrecision); |
|
|
return parsedVal === 0 ? '0' : parsedVal + viewportUnit; |
|
|
return parsedVal === 0 ? '0' : parsedVal + viewportUnit; |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
@ -103,4 +127,8 @@ function declarationExists(decls, prop, value) { |
|
|
return decls.some(function (decl) { |
|
|
return decls.some(function (decl) { |
|
|
return (decl.prop === prop && decl.value === value); |
|
|
return (decl.prop === prop && decl.value === value); |
|
|
}); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function validateParams(params, mediaQuery) { |
|
|
|
|
|
return !params || (params && mediaQuery && params.indexOf('landscape') === -1); |
|
|
|
|
|
} |