filter-css
Advanced tools
Comparing version 0.0.2 to 0.0.3
79
index.js
@@ -6,2 +6,8 @@ 'use strict'; | ||
var _default = { | ||
selectors: [], | ||
declarations: [], | ||
types: [] | ||
}; | ||
function read(file) { | ||
@@ -14,19 +20,22 @@ return fs.readFileSync(file, {encoding: 'utf8'}); | ||
* Identify ignored selectors | ||
* @param {array} ignore | ||
* @param {string} key | ||
* @param {array} ignores | ||
* @param {string} pluck attribute to pluck from object | ||
* @returns {Function} | ||
*/ | ||
function identify(ignore,key) { | ||
function matcher(ignores, pluck) { | ||
return function (element) { | ||
if (_.isObject(element) && key) { | ||
element = _.result(element,key); | ||
function getValue(element) { | ||
if (pluck) { | ||
return _.result(element,pluck); | ||
} | ||
return element; | ||
} | ||
for (var i = 0; i < ignore.length; ++i) { | ||
return function (element) { | ||
for (var i = 0; i < ignores.length; ++i) { | ||
/* If ignore is RegExp and matches selector ... */ | ||
if (_.isRegExp(ignore[i]) && ignore[i].test(element)) { | ||
if (_.isRegExp(ignores[i]) && ignores[i].test(getValue(element))) { | ||
return true; | ||
} | ||
if (ignore[i] === element) { | ||
if (ignores[i] === getValue(element)) { | ||
return true; | ||
@@ -46,8 +55,11 @@ } | ||
function reduceRules(ignore) { | ||
// types to ignore are identified by leading @ | ||
var ignoreTypes = _.filter(ignore, RegExp.prototype.test, /^@/); | ||
function ignoreList(key) { | ||
return (_.isObject(ignore) && _.result(ignore,key)) || []; | ||
} | ||
return function reducer(rules, rule) { | ||
// check if whole type is ignored | ||
if (_.indexOf(ignoreTypes, '@' + rule.type) !== -1) { | ||
if (_.isFunction(ignore) && ignore('type',rule.type) || matcher(ignoreList('types'), 'type')(rule)) { | ||
return rules; | ||
@@ -64,6 +76,7 @@ } | ||
} else if (rule.type === 'rule') { | ||
rule.selectors = _.reject(rule.selectors || [], identify(ignore)); | ||
rule.selectors = _.reject(rule.selectors || [], _.isFunction(ignore) && _.partial(ignore,'selector') || matcher(ignoreList('selectors'))); | ||
if (_.size(rule.selectors)) { | ||
rule.declarations = _.reject(rule.declarations || [], identify(ignore,'value')); | ||
rule.declarations = _.reject(rule.declarations || [], _.isFunction(ignore) && _.partial(ignore,'declaration') || matcher(ignoreList('declarations'),'value')); | ||
@@ -80,7 +93,39 @@ rules.push(rule); | ||
function api(stylesheet, ignore) { | ||
if (_.isString(ignore) || _.isRegExp(ignore)) { | ||
/** | ||
* Normalize ignore to the form {types: [], selectors: [], declarations: []} | ||
* @param ignore | ||
* @returns {object|function} | ||
*/ | ||
function normalizeIgnore(ignore) { | ||
if (!ignore) { | ||
return _default; | ||
} else if (_.isFunction(ignore)) { | ||
return ignore; | ||
} else if (_.isString(ignore) || _.isRegExp(ignore)) { | ||
ignore = [ignore]; | ||
} | ||
// convert shorthands @... for type | ||
if (_.isArray(ignore)) { | ||
var parts = _.partition(ignore, RegExp.prototype.test, /^@/); | ||
return { | ||
types: _.invoke(parts[0],String.prototype.substr,1), | ||
selectors: parts[1], | ||
declarations: [] | ||
}; | ||
} | ||
return { | ||
types: _.map(ignore.types || [], function(str){ | ||
return _.isString(str) && str.replace(/^@/,'') || str; | ||
}), | ||
selectors: ignore.selectors || [], | ||
declarations: ignore.declarations || [] | ||
}; | ||
} | ||
function api(stylesheet, ignore) { | ||
var sheet; | ||
@@ -93,3 +138,3 @@ try { | ||
sheet.stylesheet.rules = _.reduce(sheet.stylesheet.rules, reduceRules(ignore || []), []); | ||
sheet.stylesheet.rules = _.reduce(sheet.stylesheet.rules, reduceRules(normalizeIgnore(ignore)), []); | ||
return css.stringify(sheet); | ||
@@ -96,0 +141,0 @@ } |
{ | ||
"name": "filter-css", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Filter CSS rules", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -15,2 +15,37 @@ # filter-css [![Build Status](https://travis-ci.org/bezoerb/filter-css.svg?branch=master)](https://travis-ci.org/bezoerb/filter-css) | ||
```js | ||
var filterCss = require('filter-css'); | ||
var filtered = filterCss('test.css',{ | ||
types: ['<type>'], | ||
selectors: ['.my-selector > p', /(some)|(regexp)/], | ||
declarations: ['url(myImage.png)', /url/], | ||
}); | ||
``` | ||
When only filtering types and seletors you can use a shorthand. | ||
Types are identified by a leading `@`. Everything else (RegExp, String) is used for selector matching. | ||
```js | ||
var filterCss = require('filter-css'); | ||
var filtered = filterCss('test.css',['@<type>','.my > complete-selector',/complete/]); | ||
``` | ||
You can also pass in a filter function. The function receives the type as first and the AST Element / String as second argument. | ||
When the function returns true, the element will be discarded. | ||
```js | ||
var filterCss = require('filter-css'); | ||
var filtered = filterCss('test.css',function(type, data){ | ||
return type === 'type' && data === 'font-face' || | ||
type === 'selector' && data.match(/test/) || | ||
type === 'declaration' && /background/.test(data.property) && /url/.test(data.value); | ||
}); | ||
``` | ||
```css | ||
@@ -17,0 +52,0 @@ body { |
8406
158
143