@tianz/postcss-px-to-viewport
Advanced tools
Comparing version
@@ -40,3 +40,3 @@ # Changelog | ||
### Added | ||
- `landscape` (Boolean) Adds `@media (orientation: landscape)` with values converted via `landscapeWidth`. | ||
- `landscape` (Boolean) Adds `@media (min-aspect-ratio: 13/9) and (orientation: landscape)` with values converted via `landscapeWidth`. | ||
- `landscapeUnit` (String) Expected unit for `landscape` option | ||
@@ -43,0 +43,0 @@ - `landscapeWidth` (Number) Viewport width for landscape orientation. |
201
index.js
@@ -28,9 +28,14 @@ 'use strict'; | ||
module.exports = function (options) { | ||
var opts = objectAssign({}, defaults, options); | ||
var optsList; | ||
options instanceof Array | ||
? optsList = options.map(function(option) { | ||
return objectAssign({}, defaults, option); | ||
}) | ||
: optsList = [objectAssign({}, defaults, options)]; | ||
checkRegExpOrArray(opts, 'exclude'); | ||
checkRegExpOrArray(opts, 'include'); | ||
optsList.forEach((opts) => { | ||
checkRegExpOrArray(opts, 'exclude'); | ||
checkRegExpOrArray(opts, 'include'); | ||
}); | ||
var pxRegex = getUnitRegexp(opts.unitToConvert); | ||
var satisfyPropList = createPropListMatcher(opts.propList); | ||
var landscapeRules = []; | ||
@@ -41,107 +46,117 @@ | ||
Once (css, { result, AtRule }) { | ||
css.walkRules(function (rule) { | ||
optsList.forEach((opts) => { | ||
var pxRegex = getUnitRegexp(opts.unitToConvert); | ||
var satisfyPropList = createPropListMatcher(opts.propList); | ||
css.walkRules(function (rule) { | ||
// Add exclude option to ignore some files like 'node_modules' | ||
var file = rule.source && rule.source.input.file; | ||
if (opts.include && file) { | ||
if (Object.prototype.toString.call(opts.include) === '[object RegExp]') { | ||
if (!opts.include.test(file)) return; | ||
} else if (Object.prototype.toString.call(opts.include) === '[object Array]') { | ||
var flag = false; | ||
for (var i = 0; i < opts.include.length; i++) { | ||
if (opts.include[i].test(file)) { | ||
flag = true; | ||
break; | ||
// in windows, path use '\' | ||
file = file && file.replace(/\\/g, '/') | ||
if (opts.include && file) { | ||
if (Object.prototype.toString.call(opts.include) === '[object RegExp]') { | ||
if (!opts.include.test(file)) return; | ||
} else if (Object.prototype.toString.call(opts.include) === '[object Array]') { | ||
var flag = false; | ||
for (var i = 0; i < opts.include.length; i++) { | ||
if (opts.include[i].test(file)) { | ||
flag = true; | ||
break; | ||
} | ||
} | ||
if (!flag) return; | ||
} | ||
if (!flag) return; | ||
} | ||
} | ||
if (opts.exclude && file) { | ||
if (Object.prototype.toString.call(opts.exclude) === '[object RegExp]') { | ||
if (opts.exclude.test(file)) return; | ||
} else if (Object.prototype.toString.call(opts.exclude) === '[object Array]') { | ||
for (var i = 0; i < opts.exclude.length; i++) { | ||
if (opts.exclude[i].test(file)) return; | ||
if (opts.exclude && file) { | ||
if (Object.prototype.toString.call(opts.exclude) === '[object RegExp]') { | ||
if (opts.exclude.test(file)) return; | ||
} else if (Object.prototype.toString.call(opts.exclude) === '[object Array]') { | ||
for (var i = 0; i < opts.exclude.length; i++) { | ||
if (opts.exclude[i].test(file)) 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(); | ||
rule.walkDecls(function(decl) { | ||
if (opts.landscape && !rule.parent.params) { | ||
var landscapeRule = rule.clone().removeAll(); | ||
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, opts.landscapeWidth)) | ||
})); | ||
}); | ||
if (landscapeRule.nodes.length > 0) { | ||
landscapeRules.push(landscapeRule); | ||
} | ||
} | ||
if (!validateParams(rule.parent.params, opts.mediaQuery)) return; | ||
rule.walkDecls(function(decl, i) { | ||
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, opts.landscapeWidth)) | ||
})); | ||
}); | ||
if (landscapeRule.nodes.length > 0) { | ||
landscapeRules.push(landscapeRule); | ||
} | ||
} | ||
if (!validateParams(rule.parent.params, opts.mediaQuery)) return; | ||
rule.walkDecls(function(decl, i) { | ||
if (decl.value.indexOf(opts.unitToConvert) === -1) return; | ||
if (!satisfyPropList(decl.prop)) return; | ||
var prev = decl.prev(); | ||
// prev declaration is ignore conversion comment at same line | ||
if (prev && prev.type === 'comment' && prev.text === ignoreNextComment) { | ||
// remove comment | ||
prev.remove(); | ||
return; | ||
} | ||
var next = decl.next(); | ||
// next declaration is ignore conversion comment at same line | ||
if (next && next.type === 'comment' && next.text === ignorePrevComment) { | ||
if (/\n/.test(next.raws.before)) { | ||
result.warn('Unexpected comment /* ' + ignorePrevComment + ' */ must be after declaration at same line.', { node: next }); | ||
} else { | ||
var prev = decl.prev(); | ||
// prev declaration is ignore conversion comment at same line | ||
if (prev && prev.type === 'comment' && prev.text === ignoreNextComment) { | ||
// remove comment | ||
next.remove(); | ||
prev.remove(); | ||
return; | ||
} | ||
} | ||
var next = decl.next(); | ||
// next declaration is ignore conversion comment at same line | ||
if (next && next.type === 'comment' && next.text === ignorePrevComment) { | ||
if (/\n/.test(next.raws.before)) { | ||
result.warn('Unexpected comment /* ' + ignorePrevComment + ' */ must be after declaration at same line.', { node: next }); | ||
} else { | ||
// remove comment | ||
next.remove(); | ||
return; | ||
} | ||
} | ||
var unit; | ||
var size; | ||
var params = rule.parent.params; | ||
if (opts.landscape && params && params.indexOf('landscape') !== -1) { | ||
unit = opts.landscapeUnit; | ||
size = opts.landscapeWidth; | ||
} else { | ||
unit = getUnit(decl.prop, opts); | ||
size = typeof opts.viewportWidth === 'function' | ||
? opts.viewportWidth(rule.source.input) | ||
: opts.viewportWidth; | ||
} | ||
var value = decl.value.replace(pxRegex, createPxReplace(opts, unit, size)); | ||
if (declarationExists(decl.parent, decl.prop, value)) return; | ||
if (opts.replace) { | ||
decl.value = value; | ||
} else { | ||
decl.parent.insertAfter(i, decl.clone({ value: value })); | ||
} | ||
}); | ||
} | ||
); | ||
if (landscapeRules.length > 0) { | ||
// When keyboard popup in Android, it with use landscape, so that it should be min-aspect-ratio but not only landscape | ||
var landscapeRoot = new AtRule({ params: '(min-aspect-ratio: 13/9) and (orientation: landscape)', name: 'media' }); | ||
var unit; | ||
var size; | ||
var params = rule.parent.params; | ||
if (opts.landscape && params && params.indexOf('landscape') !== -1) { | ||
unit = opts.landscapeUnit; | ||
size = opts.landscapeWidth; | ||
} else { | ||
unit = getUnit(decl.prop, opts); | ||
size = opts.viewportWidth; | ||
} | ||
var value = decl.value.replace(pxRegex, createPxReplace(opts, unit, size)); | ||
if (declarationExists(decl.parent, decl.prop, value)) return; | ||
if (opts.replace) { | ||
decl.value = value; | ||
} else { | ||
decl.parent.insertAfter(i, decl.clone({ value: value })); | ||
} | ||
landscapeRules.forEach(function(rule) { | ||
landscapeRoot.append(rule); | ||
}); | ||
css.append(landscapeRoot); | ||
} | ||
); | ||
if (landscapeRules.length > 0) { | ||
var landscapeRoot = new AtRule({ params: '(orientation: landscape)', name: 'media' }); | ||
landscapeRules.forEach(function(rule) { | ||
landscapeRoot.append(rule); | ||
}); | ||
css.append(landscapeRoot); | ||
} | ||
}); | ||
}, | ||
@@ -148,0 +163,0 @@ }; |
{ | ||
"name": "@tianz/postcss-px-to-viewport", | ||
"description": "A CSS post-processor that converts px to viewport units (vw, vh, vmin, vmax).", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"author": "Dmitry Karpunin <koderfunk@gmail.com>", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
# postcss-px-to-viewport | ||
[](http://badge.fury.io/js/postcss-px-to-viewport) | ||
[](https://badge.fury.io/js/@tianz%2Fpostcss-px-to-viewport) | ||
@@ -109,3 +109,3 @@ [English](README.md) | 中文 | ||
- `unitToConvert` (String) 需要转换的单位,默认为"px" | ||
- `viewportWidth` (Number) 设计稿的视口宽度 | ||
- `viewportWidth` (Number | Function) 设计稿的视口宽度,如果是函数的话,参数为**rule.source.input** | ||
- `unitPrecision` (Number) 单位转换后保留的精度 | ||
@@ -135,3 +135,3 @@ - `propList` (Array) 能转化为vw的属性列表 | ||
- 如果传入的值是一个数组,那么数组里的值必须为正则 | ||
- `landscape` (Boolean) 是否添加根据 `landscapeWidth` 生成的媒体查询条件 `@media (orientation: landscape)` | ||
- `landscape` (Boolean) 是否添加根据 `landscapeWidth` 生成的媒体查询条件 `@media (min-aspect-ratio: 13/9) and (orientation: landscape)` | ||
- `landscapeUnit` (String) 横屏时使用的单位 | ||
@@ -178,3 +178,3 @@ - `landscapeWidth` (Number) 横屏时使用的视口宽度 | ||
// ... | ||
'postcss-px-to-viewport': { | ||
'@tianz/postcss-px-to-viewport': { | ||
// options | ||
@@ -203,2 +203,12 @@ } | ||
// viewportWidth 可以是函数 | ||
var processors = [ | ||
pxtoviewport({ | ||
viewportWidth: ({ file }) => { | ||
return file.indexOf('vant') !== -1 ? 375 : 750 | ||
}, | ||
viewportUnit: 'vmin' | ||
}) | ||
] | ||
return gulp.src(['build/css/**/*.css']) | ||
@@ -205,0 +215,0 @@ .pipe(postcss(processors)) |
# postcss-px-to-viewport | ||
[](http://badge.fury.io/js/postcss-px-to-viewport) | ||
[](https://badge.fury.io/js/@tianz%2Fpostcss-px-to-viewport) | ||
@@ -109,3 +109,3 @@ English | [中文](README_CN.md) | ||
- `unitToConvert` (String) unit to convert, by default, it is px. | ||
- `viewportWidth` (Number) The width of the viewport. | ||
- `viewportWidth` (Number | Function) The width of the viewport. When it is function, the arguments will be **rule.source.input** | ||
- `unitPrecision` (Number) The decimal numbers to allow the vw units to grow to. | ||
@@ -135,3 +135,3 @@ - `propList` (Array) The properties that can change from px to vw. | ||
- If value is array, the elements of the array are regexp. | ||
- `landscape` (Boolean) Adds `@media (orientation: landscape)` with values converted via `landscapeWidth`. | ||
- `landscape` (Boolean) Adds `@media (min-aspect-ratio: 13/9) and (orientation: landscape)` with values converted via `landscapeWidth`. | ||
- `landscapeUnit` (String) Expected unit for `landscape` option | ||
@@ -178,3 +178,3 @@ - `landscapeWidth` (Number) Viewport width for landscape orientation. | ||
// ... | ||
'postcss-px-to-viewport': { | ||
'@tianz/postcss-px-to-viewport': { | ||
// options | ||
@@ -181,0 +181,0 @@ } |
163928
0.84%418
3.47%