cnjm-postcss-px-to-viewport
Advanced tools
Comparing version 0.0.1 to 0.0.2
210
index.js
@@ -1,17 +0,17 @@ | ||
'use strict'; | ||
"use strict"; | ||
var postcss = require('postcss'); | ||
var objectAssign = require('object-assign'); | ||
var { createPropListMatcher } = require('./src/prop-list-matcher'); | ||
var { getUnitRegexp } = require('./src/pixel-unit-regexp'); | ||
var postcss = require("postcss"); | ||
var objectAssign = require("object-assign"); | ||
var { createPropListMatcher } = require("./src/prop-list-matcher"); | ||
var { getUnitRegexp } = require("./src/pixel-unit-regexp"); | ||
var defaults = { | ||
unitToConvert: 'px', | ||
unitToConvert: "px", | ||
viewportWidth: 320, | ||
viewportHeight: 568, // not now used; TODO: need for different units and math for different properties | ||
unitPrecision: 5, | ||
viewportUnit: 'vw', | ||
fontViewportUnit: 'vw', // vmin is more suitable. | ||
viewportUnit: "vw", | ||
fontViewportUnit: "vw", // vmin is more suitable. | ||
selectorBlackList: [], | ||
propList: ['*'], | ||
propList: ["*"], | ||
minPixelValue: 1, | ||
@@ -21,96 +21,116 @@ mediaQuery: false, | ||
landscape: false, | ||
landscapeUnit: 'vw', | ||
landscapeWidth: 568 | ||
landscapeUnit: "vw", | ||
landscapeWidth: 568, | ||
}; | ||
module.exports = postcss.plugin('postcss-px-to-viewport', function (options) { | ||
var opts = objectAssign({}, defaults, options); | ||
module.exports = postcss.plugin( | ||
"cnjm-postcss-px-to-viewport", | ||
function (options) { | ||
var opts = objectAssign({}, defaults, options); | ||
var pxRegex = getUnitRegexp(opts.unitToConvert); | ||
var satisfyPropList = createPropListMatcher(opts.propList); | ||
var landscapeRules = []; | ||
return function (css) { | ||
css.walkRules(function (rule) { | ||
if(opts.customFun){ | ||
opts.viewportWidth = opts.customFun({file:rule.source.input.file}); | ||
} | ||
var pxRegex = getUnitRegexp(opts.unitToConvert); | ||
var satisfyPropList = createPropListMatcher(opts.propList); | ||
var landscapeRules = []; | ||
// Add exclude option to ignore some files like 'node_modules' | ||
var file = rule.source && rule.source.input.file; | ||
return function (css) { | ||
css.walkRules(function (rule) { | ||
if (opts.customFun) { | ||
opts.viewportWidth = opts.customFun({ file: rule.source.input.file }); | ||
} | ||
if (opts.exclude && file) { | ||
if (Object.prototype.toString.call(opts.exclude) === '[object RegExp]') { | ||
if (isExclude(opts.exclude, file)) return; | ||
} else if (Object.prototype.toString.call(opts.exclude) === '[object Array]') { | ||
for (let i = 0; i < opts.exclude.length; i++) { | ||
if (isExclude(opts.exclude[i], file)) return; | ||
// Add exclude option to ignore some files like 'node_modules' | ||
var file = rule.source && rule.source.input.file; | ||
if (opts.exclude && file) { | ||
if ( | ||
Object.prototype.toString.call(opts.exclude) === "[object RegExp]" | ||
) { | ||
if (isExclude(opts.exclude, file)) return; | ||
} else if ( | ||
Object.prototype.toString.call(opts.exclude) === "[object Array]" | ||
) { | ||
for (let i = 0; i < opts.exclude.length; i++) { | ||
if (isExclude(opts.exclude[i], file)) return; | ||
} | ||
} else { | ||
throw new Error("options.exclude should be RegExp or Array."); | ||
} | ||
} else { | ||
throw new Error('options.exclude should be RegExp or Array.'); | ||
} | ||
} | ||
if (blacklistedSelector(opts.selectorBlackList, rule.selector)) return; | ||
if (opts.landscape && !rule.parent.params) { | ||
var landscapeRule = rule.clone().removeAll(); | ||
if (blacklistedSelector(opts.selectorBlackList, rule.selector)) return; | ||
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 unit; | ||
var size; | ||
var params = rule.parent.params; | ||
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 })); | ||
} | ||
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 })); | ||
} | ||
}); | ||
}); | ||
}); | ||
if (landscapeRules.length > 0) { | ||
var landscapeRoot = new postcss.atRule({ params: '(orientation: landscape)', name: 'media' }); | ||
landscapeRules.forEach(function(rule) { | ||
landscapeRoot.append(rule); | ||
}); | ||
css.append(landscapeRoot); | ||
} | ||
}; | ||
}); | ||
if (landscapeRules.length > 0) { | ||
var landscapeRoot = new postcss.atRule({ | ||
params: "(orientation: landscape)", | ||
name: "media", | ||
}); | ||
landscapeRules.forEach(function (rule) { | ||
landscapeRoot.append(rule); | ||
}); | ||
css.append(landscapeRoot); | ||
} | ||
}; | ||
} | ||
); | ||
function getUnit(prop, opts) { | ||
return prop.indexOf('font') === -1 ? opts.viewportUnit : opts.fontViewportUnit; | ||
return prop.indexOf("font") === -1 | ||
? opts.viewportUnit | ||
: opts.fontViewportUnit; | ||
} | ||
@@ -123,4 +143,4 @@ | ||
if (pixels <= opts.minPixelValue) return m; | ||
var parsedVal = toFixed((pixels / viewportSize * 100), opts.unitPrecision); | ||
return parsedVal === 0 ? '0' : parsedVal + viewportUnit; | ||
var parsedVal = toFixed((pixels / viewportSize) * 100, opts.unitPrecision); | ||
return parsedVal === 0 ? "0" : parsedVal + viewportUnit; | ||
}; | ||
@@ -132,9 +152,9 @@ } | ||
wholeNumber = Math.floor(number * multiplier); | ||
return Math.round(wholeNumber / 10) * 10 / multiplier; | ||
return (Math.round(wholeNumber / 10) * 10) / multiplier; | ||
} | ||
function blacklistedSelector(blacklist, selector) { | ||
if (typeof selector !== 'string') return; | ||
if (typeof selector !== "string") return; | ||
return blacklist.some(function (regex) { | ||
if (typeof regex === 'string') return selector.indexOf(regex) !== -1; | ||
if (typeof regex === "string") return selector.indexOf(regex) !== -1; | ||
return selector.match(regex); | ||
@@ -145,4 +165,4 @@ }); | ||
function isExclude(reg, file) { | ||
if (Object.prototype.toString.call(reg) !== '[object RegExp]') { | ||
throw new Error('options.exclude should be RegExp.'); | ||
if (Object.prototype.toString.call(reg) !== "[object RegExp]") { | ||
throw new Error("options.exclude should be RegExp."); | ||
} | ||
@@ -154,3 +174,3 @@ return file.match(reg) !== null; | ||
return decls.some(function (decl) { | ||
return (decl.prop === prop && decl.value === value); | ||
return decl.prop === prop && decl.value === value; | ||
}); | ||
@@ -157,0 +177,0 @@ } |
{ | ||
"name": "cnjm-postcss-px-to-viewport", | ||
"description": "A CSS post-processor that converts px to viewport units (vw, vh, vmin, vmax).", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"author": "cnjm", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
@@ -6,5 +6,5 @@ <!-- | ||
* @LastEditors: chenjiaming | ||
* @LastEditTime: 2022-04-13 15:35:22 | ||
* @LastEditTime: 2022-04-13 15:54:38 | ||
--> | ||
# postcss-px-to-viewport | ||
# cnjm-postcss-px-to-viewport | ||
[基于postcss-px-to-viewport插件稍加改造的](https://github.com/evrone/postcss-px-to-viewport) | ||
@@ -29,1 +29,38 @@ | ||
配置时使用cnjm-postcss-px-to-viewport | ||
```js | ||
const path = require("path"); | ||
module.exports = () => { | ||
return { | ||
plugins: { | ||
autoprefixer: { | ||
overrideBrowserslist: ["Android 4.1", "iOS 7.1", "Chrome > 31", "ff > 31", "ie >= 8"], | ||
}, | ||
// 修改插件名称 | ||
"cnjm-postcss-px-to-viewport": { | ||
unitToConvert: "px", // 要转化的单位 | ||
viewportWidth: 750, // UI设计稿的宽度 | ||
unitPrecision: 6, // 转换后的精度,即小数点位数 | ||
propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换 | ||
viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw | ||
fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw | ||
selectorBlackList: ["ignore"], // 指定不转换为视窗单位的类名, | ||
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换 | ||
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false | ||
replace: true, // 是否转换后直接更换属性值 | ||
exclude: [], // 设置忽略文件,用正则做目录名匹配 | ||
landscape: false, // 是否处理横屏情况 | ||
// 如果没有使用其他的尺寸来设计,下面这个方法可以不需要,比如vant是375的 | ||
customFun: ({ file }) => { | ||
// 这个自定义的方法是针对处理vant组件下的设计稿为375问题 | ||
const designWidth = path.join(file).includes(path.join("node_modules", "vant")) ? 375 : 750; | ||
return designWidth; | ||
}, | ||
}, | ||
}, | ||
}; | ||
}; | ||
``` | ||
18473
264
65