Skip to content

Commit

Permalink
Merge pull request cuth#29 from cuth/feature/prop-list
Browse files Browse the repository at this point in the history
Change propWhiteList to propList
  • Loading branch information
cuth authored Jan 15, 2017
2 parents e1a3bff + 93c331c commit 22898e3
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 16 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Default:
{
rootValue: 16,
unitPrecision: 5,
propWhiteList: ['font', 'font-size', 'line-height', 'letter-spacing'],
propList: ['font', 'font-size', 'line-height', 'letter-spacing'],
selectorBlackList: [],
replace: true,
mediaQuery: false,
Expand All @@ -68,9 +68,12 @@ Default:

- `rootValue` (Number) The root element font size.
- `unitPrecision` (Number) The decimal numbers to allow the REM units to grow to.
- `propWhiteList` (Array) The properties that can change from px to rem.
- Set this to an empty array to disable the white list and enable all properties.
- `propList` (Array) The properties that can change from px to rem.
- Values need to be exact matches.
- Use wildcard `*` to enable all properties. Example: `['*']`
- Use `*` at the start or end of a word. (`['*position*']` will match `background-position-y`)
- Use `!` to not match a property. Example: `['*', '!letter-spacing']`
- Combine the "not" prefix with the other prefixes. Example: `['*', '!font*']`
- `selectorBlackList` (Array) The selectors to ignore and leave as px.
- If value is string, it checks to see if selector contains the string.
- `['body']` will match `.body-class`
Expand Down
73 changes: 67 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
'use strict';

var postcss = require('postcss');
var pxRegex = require('./lib/pixel-unit-regex');
var objectAssign = require('object-assign');
var pxRegex = require('./lib/pixel-unit-regex');
var filterPropList = require('./lib/filter-prop-list');

var defaults = {
rootValue: 16,
unitPrecision: 5,
selectorBlackList: [],
propWhiteList: ['font', 'font-size', 'line-height', 'letter-spacing'],
propList: ['font', 'font-size', 'line-height', 'letter-spacing'],
replace: true,
mediaQuery: false,
minPixelValue: 0
Expand All @@ -18,8 +19,9 @@ var legacyOptions = {
'root_value': 'rootValue',
'unit_precision': 'unitPrecision',
'selector_black_list': 'selectorBlackList',
'prop_white_list': 'propWhiteList',
'media_query': 'mediaQuery'
'prop_white_list': 'propList',
'media_query': 'mediaQuery',
'propWhiteList': 'propList'
};

module.exports = postcss.plugin('postcss-pxtorem', function (options) {
Expand All @@ -29,13 +31,15 @@ module.exports = postcss.plugin('postcss-pxtorem', function (options) {
var opts = objectAssign({}, defaults, options);
var pxReplace = createPxReplace(opts.rootValue, opts.unitPrecision, opts.minPixelValue);

var satisfyPropList = createPropListMatcher(opts.propList);

return function (css) {

css.walkDecls(function (decl, i) {
// This should be the fastest test and will remove most declarations
if (decl.value.indexOf('px') === -1) return;

if (opts.propWhiteList.length && opts.propWhiteList.indexOf(decl.prop) === -1) return;
if (!satisfyPropList(decl.prop)) return;

if (blacklistedSelector(opts.selectorBlackList, decl.parent.selector)) return;

Expand Down Expand Up @@ -63,6 +67,17 @@ module.exports = postcss.plugin('postcss-pxtorem', function (options) {

function convertLegacyOptions(options) {
if (typeof options !== 'object') return;
if (
(
(typeof options['prop_white_list'] !== 'undefined' && options['prop_white_list'].length === 0) ||
(typeof options.propWhiteList !== 'undefined' && options.propWhiteList.length === 0)
) &&
typeof options.propList === 'undefined'
) {
options.propList = ['*'];
delete options['prop_white_list'];
delete options.propWhiteList;
}
Object.keys(legacyOptions).forEach(function (key) {
if (options.hasOwnProperty(key)) {
options[legacyOptions[key]] = options[key];
Expand All @@ -76,7 +91,8 @@ function createPxReplace (rootValue, unitPrecision, minPixelValue) {
if (!$1) return m;
var pixels = parseFloat($1);
if (pixels < minPixelValue) return m;
return toFixed((pixels / rootValue), unitPrecision) + 'rem';
var fixedVal = toFixed((pixels / rootValue), unitPrecision);
return (fixedVal === 0) ? '0' : fixedVal + 'rem';
};
}

Expand All @@ -99,3 +115,48 @@ function blacklistedSelector(blacklist, selector) {
return selector.match(regex);
});
}

function createPropListMatcher(propList) {
var hasWild = propList.indexOf('*') > -1;
var matchAll = (hasWild && propList.length === 1);
var lists = {
exact: filterPropList.exact(propList),
contain: filterPropList.contain(propList),
startWith: filterPropList.startWith(propList),
endWith: filterPropList.endWith(propList),
notExact: filterPropList.notExact(propList),
notContain: filterPropList.notContain(propList),
notStartWith: filterPropList.notStartWith(propList),
notEndWith: filterPropList.notEndWith(propList)
};
return function (prop) {
if (matchAll) return true;
return (
(
hasWild ||
lists.exact.indexOf(prop) > -1 ||
lists.contain.some(function (m) {
return prop.indexOf(m) > -1;
}) ||
lists.startWith.some(function (m) {
return prop.indexOf(m) === 0;
}) ||
lists.endWith.some(function (m) {
return prop.indexOf(m) === prop.length - m.length;
})
) &&
!(
lists.notExact.indexOf(prop) > -1 ||
lists.notContain.some(function (m) {
return prop.indexOf(m) > -1;
}) ||
lists.notStartWith.some(function (m) {
return prop.indexOf(m) === 0;
}) ||
lists.notEndWith.some(function (m) {
return prop.indexOf(m) === prop.length - m.length;
})
)
);
};
}
56 changes: 56 additions & 0 deletions lib/filter-prop-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module.exports = {
exact: function (list) {
return list.filter(function (m) {
return m.match(/^[^\*\!]+$/);
});
},
contain: function (list) {
return list.filter(function (m) {
return m.match(/^\*.+\*$/);
}).map(function (m) {
return m.substr(1, m.length - 2);
});
},
endWith: function (list) {
return list.filter(function (m) {
return m.match(/^\*[^\*]+$/);
}).map(function (m) {
return m.substr(1);
});
},
startWith: function (list) {
return list.filter(function (m) {
return m.match(/^[^\*\!]+\*$/);
}).map(function (m) {
return m.substr(0, m.length - 1);
});
},
notExact: function (list) {
return list.filter(function (m) {
return m.match(/^\![^\*].*$/);
}).map(function (m) {
return m.substr(1);
});
},
notContain: function (list) {
return list.filter(function (m) {
return m.match(/^\!\*.+\*$/);
}).map(function (m) {
return m.substr(2, m.length - 3);
});
},
notEndWith: function (list) {
return list.filter(function (m) {
return m.match(/^\!\*[^\*]+$/);
}).map(function (m) {
return m.substr(2);
});
},
notStartWith: function (list) {
return list.filter(function (m) {
return m.match(/^\![^\*]+\*$/);
}).map(function (m) {
return m.substr(1, m.length - 2);
});
}
};
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "postcss-pxtorem",
"description": "A CSS post-processor that converts px to rem.",
"version": "3.3.1",
"version": "4.0.0",
"author": "cuth",
"license": "MIT",
"repository": {
Expand All @@ -25,7 +25,7 @@
"postcss-plugin"
],
"dependencies": {
"object-assign": "^4.0.1",
"postcss": "^5.0.2"
"object-assign": "^4.1.0",
"postcss": "^5.2.10"
}
}
Loading

0 comments on commit 22898e3

Please sign in to comment.