Browse Source

Merge remote-tracking branch 'origin/master' into add-replace-flag

# Conflicts:
#	README.md
#	spec/px-to-viewport.spec.js
pull/21/head
Ivan Bunin 7 years ago
parent
commit
7553506d27
  1. 25
      README.md
  2. 29
      index.js
  3. 77
      spec/px-to-viewport.spec.js

25
README.md

@ -2,6 +2,11 @@
A plugin for [PostCSS](https://github.com/ai/postcss) that generates viewport units (vw, vh, vmin, vmax) from pixel units.
## Install
```
$ npm install postcss-px-to-viewport --save-dev
```
## Usage
If your project involves a fixed width, this script will help to convert pixels into viewport units.
@ -95,8 +100,9 @@ Default:
fontViewportUnit: 'vw', // vmin is more suitable.
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false,
replace: true,
mediaQuery: false
exclude: [] // ignore some files
}
```
- `unitToConvert` (String) unit to convert, by default, it is px.
@ -113,9 +119,12 @@ Default:
- `minPixelValue` (Number) Set the minimum pixel value to replace.
- `mediaQuery` (Boolean) Allow px to be converted in media queries.
- `replace` (Boolean) replaces rules containing rems instead of adding fallbacks.
- `exclude` (Array or Regexp) Ignore some files like 'node_modules'
- If value is regexp, will ignore the matches files.
- If value is array, the elements of the array are regexp.
### Use with gulp-postcss
add to your gulp config:
```js
var gulp = require('gulp');
var postcss = require('gulp-postcss');
@ -135,3 +144,15 @@ gulp.task('css', function () {
.pipe(gulp.dest('build/css'));
});
```
### Use with Postcss configuration file
add to postcss.config.js
```js
module.exports = {
plugins: {
...
'postcss-px-to-viewport': {
// options
}
}
}
```

29
index.js

@ -27,11 +27,25 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) {
// Not anything inside url()
// Any digit followed by px
// !singlequotes|!doublequotes|!url()|pixelunit
var pxRegex = new RegExp('"[^"]+"|\'[^\']+\'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)' + opts.unitToConvert, 'ig')
var pxRegex = new RegExp('"[^"]+"|\'[^\']+\'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)' + opts.unitToConvert, 'g')
return function (css) {
css.walkDecls(function (decl, i) {
// Add exlclude option to ignore some files like 'node_modules'
if (opts.exclude && decl.source.input.file) {
if (Object.prototype.toString.call(opts.exclude) === '[object RegExp]') {
if (!handleExclude(opts.exclude, decl.source.input.file)) return;
} else if (Object.prototype.toString.call(opts.exclude) === '[object Array]') {
for (let i = 0; i < opts.exclude.length; ++i) {
if (!handleExclude(opts.exclude[i], decl.source.input.file)) return;
}
} else {
throw new Error('options.exclude should be RegExp or Array!');
}
}
// This should be the fastest test and will remove most declarations
if (decl.value.indexOf(opts.unitToConvert) === -1) return;
@ -59,6 +73,14 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) {
};
});
function handleExclude (reg, file) {
if (Object.prototype.toString.call(reg) !== '[object RegExp]') {
throw new Error('options.exclude should be RegExp!');
}
if (file.match(reg) !== null) return false;
return true;
}
function getUnit(prop, opts) {
return prop.indexOf('font') === -1 ? opts.viewportUnit : opts.fontViewportUnit;
}
@ -68,7 +90,8 @@ function createPxReplace(viewportSize, minPixelValue, unitPrecision, viewportUni
if (!$1) return m;
var pixels = parseFloat($1);
if (pixels <= minPixelValue) return m;
return toFixed((pixels / viewportSize * 100), unitPrecision) + viewportUnit;
var parsedVal = toFixed((pixels / viewportSize * 100), unitPrecision);
return parsedVal === 0 ? '0' : parsedVal + viewportUnit;
};
}

77
spec/px-to-viewport.spec.js

@ -37,6 +37,13 @@ describe('px-to-viewport', function() {
expect(processed).toBe(expected);
});
it('should remain unitless if 0', function () {
var expected = '.rule { font-size: 0px; font-size: 0; }';
var processed = postcss(pxToViewport()).process(expected).css;
expect(processed).toBe(expected);
});
it('should not add properties that already exist', function () {
var expected = '.rule { font-size: 16px; font-size: 5vw; }';
var processed = postcss(pxToViewport()).process(expected).css;
@ -64,6 +71,14 @@ describe('value parsing', function() {
expect(processed).toBe(expected);
});
it('should not replace values with an uppercase P or X', function () {
var rules = '.rule { margin: 12px calc(100% - 14PX); height: calc(100% - 20px); font-size: 12Px; line-height: 16px; }';
var expected = '.rule { margin: 3.75vw calc(100% - 14PX); height: calc(100% - 6.25vw); font-size: 12Px; line-height: 5vw; }';
var processed = postcss(pxToViewport()).process(rules).css;
expect(processed).toBe(expected);
});
});
describe('unitToConvert', function() {
@ -204,14 +219,62 @@ describe('minPixelValue', function () {
});
});
describe('exclude', function () {
var rules = '.rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }';
var covered = '.rule { border: 1px solid #000; font-size: 5vw; margin: 1px 3.125vw; }'
it('when using regex at the time, the style should not be overwritten.', function () {
var options = {
exclude: /node_modules/
}
var processed = postcss(pxToViewport(options)).process(rules, {
from: '/node_modules/main.css'
}).css;
expect(processed).toBe(rules);
});
it('when using regex at the time, the style should be overwritten.', function () {
var options = {
exclude: /node_modules/
}
var processed = postcss(pxToViewport(options)).process(rules, {
from: '/example/main.css'
}).css;
expect(processed).toBe(covered);
});
it('when using array at the time, the style should not be overwritten.', function () {
var options = {
exclude: [/node_modules/, /exclude/]
}
var processed = postcss(pxToViewport(options)).process(rules, {
from: '/exclude/main.css'
}).css;
expect(processed).toBe(rules);
});
it('when using array at the time, the style should be overwritten.', function () {
var options = {
exclude: [/node_modules/, /exclude/]
}
var processed = postcss(pxToViewport(options)).process(rules, {
from: '/example/main.css'
}).css;
expect(processed).toBe(covered);
});
});
describe('replace', function () {
it('should leave fallback pixel unit with root em value', function () {
var options = {
replace: false
};
var processed = postcss(pxToViewport(options)).process(basicCSS).css;
var expected = '.rule { font-size: 15px; font-size: 4.6875vw }';
var options = {
replace: false
};
var processed = postcss(pxToViewport(options)).process(basicCSS).css;
var expected = '.rule { font-size: 15px; font-size: 4.6875vw }';
expect(processed).toBe(expected);
expect(processed).toBe(expected);
});
});
});
Loading…
Cancel
Save