/**
|
* cssfilter
|
*
|
* @author 老雷<leizongmin@gmail.com>
|
*/
|
|
var DEFAULT = require('./default');
|
var parseStyle = require('./parser');
|
var _ = require('./util');
|
|
|
/**
|
* 返回值是否为空
|
*
|
* @param {Object} obj
|
* @return {Boolean}
|
*/
|
function isNull (obj) {
|
return (obj === undefined || obj === null);
|
}
|
|
/**
|
* 浅拷贝对象
|
*
|
* @param {Object} obj
|
* @return {Object}
|
*/
|
function shallowCopyObject (obj) {
|
var ret = {};
|
for (var i in obj) {
|
ret[i] = obj[i];
|
}
|
return ret;
|
}
|
|
/**
|
* 创建CSS过滤器
|
*
|
* @param {Object} options
|
* - {Object} whiteList
|
* - {Function} onAttr
|
* - {Function} onIgnoreAttr
|
* - {Function} safeAttrValue
|
*/
|
function FilterCSS (options) {
|
options = shallowCopyObject(options || {});
|
options.whiteList = options.whiteList || DEFAULT.whiteList;
|
options.onAttr = options.onAttr || DEFAULT.onAttr;
|
options.onIgnoreAttr = options.onIgnoreAttr || DEFAULT.onIgnoreAttr;
|
options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue;
|
this.options = options;
|
}
|
|
FilterCSS.prototype.process = function (css) {
|
// 兼容各种奇葩输入
|
css = css || '';
|
css = css.toString();
|
if (!css) return '';
|
|
var me = this;
|
var options = me.options;
|
var whiteList = options.whiteList;
|
var onAttr = options.onAttr;
|
var onIgnoreAttr = options.onIgnoreAttr;
|
var safeAttrValue = options.safeAttrValue;
|
|
var retCSS = parseStyle(css, function (sourcePosition, position, name, value, source) {
|
|
var check = whiteList[name];
|
var isWhite = false;
|
if (check === true) isWhite = check;
|
else if (typeof check === 'function') isWhite = check(value);
|
else if (check instanceof RegExp) isWhite = check.test(value);
|
if (isWhite !== true) isWhite = false;
|
|
// 如果过滤后 value 为空则直接忽略
|
value = safeAttrValue(name, value);
|
if (!value) return;
|
|
var opts = {
|
position: position,
|
sourcePosition: sourcePosition,
|
source: source,
|
isWhite: isWhite
|
};
|
|
if (isWhite) {
|
|
var ret = onAttr(name, value, opts);
|
if (isNull(ret)) {
|
return name + ':' + value;
|
} else {
|
return ret;
|
}
|
|
} else {
|
|
var ret = onIgnoreAttr(name, value, opts);
|
if (!isNull(ret)) {
|
return ret;
|
}
|
|
}
|
});
|
|
return retCSS;
|
};
|
|
|
module.exports = FilterCSS;
|