Skip to content

Commit

Permalink
Merge pull request #3 from shepherdwind/rpx-support
Browse files Browse the repository at this point in the history
支持多个单位配置,比如 rpx
  • Loading branch information
soda-x committed Feb 15, 2017
2 parents c4cf164 + 67e1d50 commit 0a19330
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ Default:
}
```

- `rootValue` (Number) The root element font size. Default is 100.
- `rootValue` (Number|Object) The root element font size. Default is 100.
- If rootValue is an object, for example `{ px: 50, rpx: 100 }`, it will
replace rpx to 1/100 rem , and px to 1/50 rem.
- `unitPrecision` (Number) The decimal numbers to allow the REM units to grow to.
- `propWhiteList` (Array) The properties that can change from px to rem.
- Default is an empty array that means disable the white list and enable all properties.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@
"package.json",
"README.md"
]
}
}
21 changes: 15 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ const toFixed = (number, precision) => {

return Math.round(wholeNumber / 10) * 10 / multiplier;
};
const isObject = o => typeof o === 'object' && o !== null;

const createPxReplace = (rootValue, identifier, unitPrecision, minPixelValue) => (m, $1) => {
const createPxReplace = (rootValue, identifier, unitPrecision, minPixelValue) => (m, $1, $2) => {
if (!$1) return m;
if (identifier && m.indexOf(identifier) === 0) return m.replace(identifier, '');
const pixels = parseFloat($1);
if (pixels < minPixelValue) return m;
const fixedVal = toFixed((pixels / rootValue), unitPrecision);
// { px: 100, rpx: 50 }
const baseValue = isObject(rootValue) ? rootValue[$2] : rootValue;
const fixedVal = toFixed((pixels / baseValue), unitPrecision);

return `${fixedVal}rem`;
};
Expand Down Expand Up @@ -56,23 +59,29 @@ const blacklistedProp = (blacklist, prop) => {
});
};

const handleIgnoreIdentifierRegx = identifier => {
const handleIgnoreIdentifierRegx = (identifier, unit) => {
const _identifier = identifier;
let backslashfy = _identifier.split('').join('\\');
backslashfy = `\\${backslashfy}`;
const pattern = `"[^"]+"|'[^']+'|url\\([^\\)]+\\)|((${backslashfy}|\\d*)\\.?\\d+)px`;
const pattern = `"[^"]+"|'[^']+'|url\\([^\\)]+\\)|((?:${backslashfy}|\\d*)\\.?\\d+)(${unit})`;

return new RegExp(pattern, 'ig');
};

export default postcss.plugin('postcss-plugin-px2rem', options => {
const opts = { ...defaultOpts, ...options };
let pxRegex = /"[^"]+"|'[^']+'|url\([^\)]+\)|(\d*\.?\d+)px/ig;
let unit = 'px';
if (isObject(opts.rootValue)) {
unit = Object.keys(opts.rootValue).join('|');
}

const regText = `"[^"]+"|'[^']+'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)(${unit})`;
let pxRegex = new RegExp(regText, 'ig');
let identifier = opts.ignoreIdentifier;
if (identifier && typeof identifier === 'string') {
identifier = identifier.replace(/\s+/g, '');
opts.replace = true;
pxRegex = handleIgnoreIdentifierRegx(identifier);
pxRegex = handleIgnoreIdentifierRegx(identifier, unit);
} else {
identifier = false;
}
Expand Down
47 changes: 47 additions & 0 deletions test/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,50 @@ describe('minPixelValue', () => {
expect(processed).toBe(expected);
});
});

describe('rpx support', function() {
it('should work on the readme example', () => {
const input = 'h1 { margin: 0 0 20rpx 20rpx; font-size: 32px; line-height: 1.2; letter-spacing: 1rpx; }';
const output = 'h1 { margin: 0 0 0.2rem 0.2rem; font-size: 0.64rem; line-height: 1.2; letter-spacing: 0.01rem; }';
const processed = postcss(pxtorem({
rootValue: { px: 50, rpx: 100 },
})).process(input).css;

expect(processed).toBe(output);
});

it('should replace rpx in media queries', () => {
const options = {
mediaQuery: true,
rootValue: { px: 50, rpx: 100 },
};
const processed = postcss(pxtorem(options)).process('@media (min-width: 500rpx) { .rule { font-size: 16px } }').css;
const expected = '@media (min-width: 5rem) { .rule { font-size: 0.32rem } }';

expect(processed).toBe(expected);
});

it('should ignore selectors in the selector black list', () => {
const rules = '.rule { font-size: 15rpx } .rule2 { font-size: 15px }';
const expected = '.rule { font-size: 0.15rem } .rule2 { font-size: 15px }';
const options = {
selectorBlackList: ['.rule2'],
rootValue: { px: 50, rpx: 100 },
};
const processed = postcss(pxtorem(options)).process(rules).css;

expect(processed).toBe(expected);
});

it('should not replace px when ignoreIdentifier enabled', () => {
const options = {
ignoreIdentifier: '00',
rootValue: { px: 100, rpx: 100 },
};
const input = 'h1 { margin: 0 0 00.5px 16rpx; border-width: 001px; font-size: 32px; font-family: "16px"; }';
const output = 'h1 { margin: 0 0 .5px 0.16rem; border-width: 1px; font-size: 0.32rem; font-family: "16px"; }';
const processed = postcss(pxtorem(options)).process(input).css;

expect(processed).toBe(output);
});
});

0 comments on commit 0a19330

Please sign in to comment.