Browse Source

change mediaQuery option to replace props inside rules instead of params

add-media-landscape
Ivan Bunin 7 years ago
parent
commit
b27637ad75
  1. 1
      .gitignore
  2. 6
      example/index.js
  3. 4
      example/main-viewport.css
  4. 50
      index.js
  5. 33
      spec/px-to-viewport.spec.js
  6. 14
      src/pixel-unit-regexp.js

1
.gitignore

@ -3,4 +3,5 @@ logs
*.log
npm-debug.log*
node_modules
.idea
postcss-px-to-em-master

6
example/index.js

@ -4,10 +4,8 @@ var fs = require('fs');
var postcss = require('postcss');
var pxToViewport = require('..');
var css = fs.readFileSync('main.css', 'utf8');
var options = {
replace: false
};
var processedCss = postcss(pxToViewport(options)).process(css).css;
var processedCss = postcss(pxToViewport()).process(css).css;
fs.writeFile('main-viewport.css', processedCss, function (err) {
if (err) {

4
example/main-viewport.css

@ -14,8 +14,8 @@
}
@media (min-width: 750px) {
.class3 {
font-size: 5vw;
line-height: 6.875vw;
font-size: 16px;
line-height: 22px;
}
}

50
index.js

@ -3,6 +3,7 @@
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',
@ -21,39 +22,32 @@ var defaults = {
module.exports = postcss.plugin('postcss-px-to-viewport', function (options) {
var opts = objectAssign({}, defaults, options);
var pxReplace = createPxReplace(opts.viewportWidth, opts.minPixelValue, opts.unitPrecision, opts.viewportUnit);
// excluding regex trick: http://www.rexegg.com/regex-best-trick.html
// Not anything inside double quotes
// Not anything inside single quotes
// Not anything inside url()
// Any digit followed by px
// !singlequotes|!doublequotes|!url()|pixelunit
var pxRegex = new RegExp('"[^"]+"|\'[^\']+\'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)' + opts.unitToConvert, 'g');
var pxRegex = getUnitRegexp(opts.unitToConvert);
var satisfyPropList = createPropListMatcher(opts.propList);
return function (css) {
css.walkRules(function (rule) {
// Add exclude option to ignore some files like 'node_modules'
var file = rule.source.input.file;
css.walkDecls(function (decl, i) {
// Add exlclude option to ignore some files like 'node_modules'
if (opts.exclude && decl.source.input.file) {
if (opts.exclude && file) {
if (Object.prototype.toString.call(opts.exclude) === '[object RegExp]') {
if (!handleExclude(opts.exclude, decl.source.input.file)) return;
if (!handleExclude(opts.exclude, 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;
for (let i = 0; i < opts.exclude.length; i++) {
if (!handleExclude(opts.exclude[i], file)) return;
}
} else {
throw new Error('options.exclude should be RegExp or Array!');
throw new Error('options.exclude should be RegExp or Array.');
}
}
if (
decl.value.indexOf(opts.unitToConvert) === -1 ||
!satisfyPropList(decl.prop) ||
blacklistedSelector(opts.selectorBlackList, decl.parent.selector)
) return;
if (rule.parent.params && !opts.mediaQuery) return;
if (blacklistedSelector(opts.selectorBlackList, rule.selector)) return;
rule.walkDecls(function(decl, i) {
if (decl.value.indexOf(opts.unitToConvert) === -1) return;
if (!satisfyPropList(decl.prop)) return;
var unit = getUnit(decl.prop, opts);
var value = decl.value.replace(pxRegex, createPxReplace(opts.viewportWidth, opts.minPixelValue, opts.unitPrecision, unit));
@ -66,23 +60,15 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) {
decl.parent.insertAfter(i, decl.clone({ value: value }));
}
});
if (opts.mediaQuery) {
css.walkAtRules('media', function (rule) {
if (rule.params.indexOf(opts.unitToConvert) === -1) return;
rule.params = rule.params.replace(pxRegex, pxReplace);
});
}
};
});
function handleExclude (reg, file) {
if (Object.prototype.toString.call(reg) !== '[object RegExp]') {
throw new Error('options.exclude should be RegExp!');
throw new Error('options.exclude should be RegExp.');
}
if (file.match(reg) !== null) return false;
return true;
return file.match(reg) === null;
}
function getUnit(prop, opts) {

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

@ -51,6 +51,13 @@ describe('px-to-viewport', function() {
expect(processed).toBe(expected);
});
it('should not replace units inside mediaQueries by default', function() {
var expected = '@media (min-width: 500px) { .rule { font-size: 16px } }';
var processed = postcss(pxToViewport()).process('@media (min-width: 500px) { .rule { font-size: 16px } }').css;
expect(processed).toBe(expected);
})
});
describe('value parsing', function() {
@ -114,7 +121,7 @@ describe('viewportWidth', function() {
var expected = '.rule { font-size: 3.125vw }';
var options = {
viewportWidth: 480
}
};
var processed = postcss(pxToViewport(options)).process(basicCSS).css;
expect(processed).toBe(expected);
@ -195,12 +202,22 @@ describe('selectorBlackList', function () {
});
describe('mediaQuery', function () {
it('should replace px in media queries', function () {
it('should replace px inside media queries if opts.mediaQuery', function() {
var options = {
mediaQuery: true
};
var processed = postcss(pxToViewport(options)).process('@media (min-width: 500px) { .rule { font-size: 16px } }').css;
var expected = '@media (min-width: 156.25vw) { .rule { font-size: 5vw } }';
var expected = '@media (min-width: 500px) { .rule { font-size: 5vw } }';
expect(processed).toBe(expected);
});
it('should not replace px inside media queries if not opts.mediaQuery', function() {
var options = {
mediaQuery: false
};
var processed = postcss(pxToViewport(options)).process('@media (min-width: 500px) { .rule { font-size: 16px } }').css;
var expected = '@media (min-width: 500px) { .rule { font-size: 16px } }';
expect(processed).toBe(expected);
});
@ -254,11 +271,11 @@ 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; }'
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;
@ -269,7 +286,7 @@ describe('exclude', function () {
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;
@ -280,7 +297,7 @@ describe('exclude', function () {
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;
@ -291,7 +308,7 @@ describe('exclude', function () {
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;

14
src/pixel-unit-regexp.js

@ -0,0 +1,14 @@
// excluding regex trick: http://www.rexegg.com/regex-best-trick.html
// Not anything inside double quotes
// Not anything inside single quotes
// Not anything inside url()
// Any digit followed by px
// !singlequotes|!doublequotes|!url()|pixelunit
function getUnitRegexp(unit) {
return new RegExp('"[^"]+"|\'[^\']+\'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)' + unit, 'g');
}
module.exports = {
getUnitRegexp
};
Loading…
Cancel
Save