summaryrefslogtreecommitdiffstats
path: root/node_modules/cssfilter/lib
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/cssfilter/lib')
-rw-r--r--node_modules/cssfilter/lib/css.js110
-rw-r--r--node_modules/cssfilter/lib/default.js398
-rw-r--r--node_modules/cssfilter/lib/index.js32
-rw-r--r--node_modules/cssfilter/lib/parser.js74
-rw-r--r--node_modules/cssfilter/lib/util.js35
5 files changed, 649 insertions, 0 deletions
diff --git a/node_modules/cssfilter/lib/css.js b/node_modules/cssfilter/lib/css.js
new file mode 100644
index 0000000..49e9707
--- /dev/null
+++ b/node_modules/cssfilter/lib/css.js
@@ -0,0 +1,110 @@
+/**
+ * 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;
diff --git a/node_modules/cssfilter/lib/default.js b/node_modules/cssfilter/lib/default.js
new file mode 100644
index 0000000..b677225
--- /dev/null
+++ b/node_modules/cssfilter/lib/default.js
@@ -0,0 +1,398 @@
+/**
+ * cssfilter
+ *
+ * @author 老雷<leizongmin@gmail.com>
+ */
+
+function getDefaultWhiteList () {
+ // 白名单值说明:
+ // true: 允许该属性
+ // Function: function (val) { } 返回true表示允许该属性,其他值均表示不允许
+ // RegExp: regexp.test(val) 返回true表示允许该属性,其他值均表示不允许
+ // 除上面列出的值外均表示不允许
+ var whiteList = {};
+
+ whiteList['align-content'] = false; // default: auto
+ whiteList['align-items'] = false; // default: auto
+ whiteList['align-self'] = false; // default: auto
+ whiteList['alignment-adjust'] = false; // default: auto
+ whiteList['alignment-baseline'] = false; // default: baseline
+ whiteList['all'] = false; // default: depending on individual properties
+ whiteList['anchor-point'] = false; // default: none
+ whiteList['animation'] = false; // default: depending on individual properties
+ whiteList['animation-delay'] = false; // default: 0
+ whiteList['animation-direction'] = false; // default: normal
+ whiteList['animation-duration'] = false; // default: 0
+ whiteList['animation-fill-mode'] = false; // default: none
+ whiteList['animation-iteration-count'] = false; // default: 1
+ whiteList['animation-name'] = false; // default: none
+ whiteList['animation-play-state'] = false; // default: running
+ whiteList['animation-timing-function'] = false; // default: ease
+ whiteList['azimuth'] = false; // default: center
+ whiteList['backface-visibility'] = false; // default: visible
+ whiteList['background'] = true; // default: depending on individual properties
+ whiteList['background-attachment'] = true; // default: scroll
+ whiteList['background-clip'] = true; // default: border-box
+ whiteList['background-color'] = true; // default: transparent
+ whiteList['background-image'] = true; // default: none
+ whiteList['background-origin'] = true; // default: padding-box
+ whiteList['background-position'] = true; // default: 0% 0%
+ whiteList['background-repeat'] = true; // default: repeat
+ whiteList['background-size'] = true; // default: auto
+ whiteList['baseline-shift'] = false; // default: baseline
+ whiteList['binding'] = false; // default: none
+ whiteList['bleed'] = false; // default: 6pt
+ whiteList['bookmark-label'] = false; // default: content()
+ whiteList['bookmark-level'] = false; // default: none
+ whiteList['bookmark-state'] = false; // default: open
+ whiteList['border'] = true; // default: depending on individual properties
+ whiteList['border-bottom'] = true; // default: depending on individual properties
+ whiteList['border-bottom-color'] = true; // default: current color
+ whiteList['border-bottom-left-radius'] = true; // default: 0
+ whiteList['border-bottom-right-radius'] = true; // default: 0
+ whiteList['border-bottom-style'] = true; // default: none
+ whiteList['border-bottom-width'] = true; // default: medium
+ whiteList['border-collapse'] = true; // default: separate
+ whiteList['border-color'] = true; // default: depending on individual properties
+ whiteList['border-image'] = true; // default: none
+ whiteList['border-image-outset'] = true; // default: 0
+ whiteList['border-image-repeat'] = true; // default: stretch
+ whiteList['border-image-slice'] = true; // default: 100%
+ whiteList['border-image-source'] = true; // default: none
+ whiteList['border-image-width'] = true; // default: 1
+ whiteList['border-left'] = true; // default: depending on individual properties
+ whiteList['border-left-color'] = true; // default: current color
+ whiteList['border-left-style'] = true; // default: none
+ whiteList['border-left-width'] = true; // default: medium
+ whiteList['border-radius'] = true; // default: 0
+ whiteList['border-right'] = true; // default: depending on individual properties
+ whiteList['border-right-color'] = true; // default: current color
+ whiteList['border-right-style'] = true; // default: none
+ whiteList['border-right-width'] = true; // default: medium
+ whiteList['border-spacing'] = true; // default: 0
+ whiteList['border-style'] = true; // default: depending on individual properties
+ whiteList['border-top'] = true; // default: depending on individual properties
+ whiteList['border-top-color'] = true; // default: current color
+ whiteList['border-top-left-radius'] = true; // default: 0
+ whiteList['border-top-right-radius'] = true; // default: 0
+ whiteList['border-top-style'] = true; // default: none
+ whiteList['border-top-width'] = true; // default: medium
+ whiteList['border-width'] = true; // default: depending on individual properties
+ whiteList['bottom'] = false; // default: auto
+ whiteList['box-decoration-break'] = true; // default: slice
+ whiteList['box-shadow'] = true; // default: none
+ whiteList['box-sizing'] = true; // default: content-box
+ whiteList['box-snap'] = true; // default: none
+ whiteList['box-suppress'] = true; // default: show
+ whiteList['break-after'] = true; // default: auto
+ whiteList['break-before'] = true; // default: auto
+ whiteList['break-inside'] = true; // default: auto
+ whiteList['caption-side'] = false; // default: top
+ whiteList['chains'] = false; // default: none
+ whiteList['clear'] = true; // default: none
+ whiteList['clip'] = false; // default: auto
+ whiteList['clip-path'] = false; // default: none
+ whiteList['clip-rule'] = false; // default: nonzero
+ whiteList['color'] = true; // default: implementation dependent
+ whiteList['color-interpolation-filters'] = true; // default: auto
+ whiteList['column-count'] = false; // default: auto
+ whiteList['column-fill'] = false; // default: balance
+ whiteList['column-gap'] = false; // default: normal
+ whiteList['column-rule'] = false; // default: depending on individual properties
+ whiteList['column-rule-color'] = false; // default: current color
+ whiteList['column-rule-style'] = false; // default: medium
+ whiteList['column-rule-width'] = false; // default: medium
+ whiteList['column-span'] = false; // default: none
+ whiteList['column-width'] = false; // default: auto
+ whiteList['columns'] = false; // default: depending on individual properties
+ whiteList['contain'] = false; // default: none
+ whiteList['content'] = false; // default: normal
+ whiteList['counter-increment'] = false; // default: none
+ whiteList['counter-reset'] = false; // default: none
+ whiteList['counter-set'] = false; // default: none
+ whiteList['crop'] = false; // default: auto
+ whiteList['cue'] = false; // default: depending on individual properties
+ whiteList['cue-after'] = false; // default: none
+ whiteList['cue-before'] = false; // default: none
+ whiteList['cursor'] = false; // default: auto
+ whiteList['direction'] = false; // default: ltr
+ whiteList['display'] = true; // default: depending on individual properties
+ whiteList['display-inside'] = true; // default: auto
+ whiteList['display-list'] = true; // default: none
+ whiteList['display-outside'] = true; // default: inline-level
+ whiteList['dominant-baseline'] = false; // default: auto
+ whiteList['elevation'] = false; // default: level
+ whiteList['empty-cells'] = false; // default: show
+ whiteList['filter'] = false; // default: none
+ whiteList['flex'] = false; // default: depending on individual properties
+ whiteList['flex-basis'] = false; // default: auto
+ whiteList['flex-direction'] = false; // default: row
+ whiteList['flex-flow'] = false; // default: depending on individual properties
+ whiteList['flex-grow'] = false; // default: 0
+ whiteList['flex-shrink'] = false; // default: 1
+ whiteList['flex-wrap'] = false; // default: nowrap
+ whiteList['float'] = false; // default: none
+ whiteList['float-offset'] = false; // default: 0 0
+ whiteList['flood-color'] = false; // default: black
+ whiteList['flood-opacity'] = false; // default: 1
+ whiteList['flow-from'] = false; // default: none
+ whiteList['flow-into'] = false; // default: none
+ whiteList['font'] = true; // default: depending on individual properties
+ whiteList['font-family'] = true; // default: implementation dependent
+ whiteList['font-feature-settings'] = true; // default: normal
+ whiteList['font-kerning'] = true; // default: auto
+ whiteList['font-language-override'] = true; // default: normal
+ whiteList['font-size'] = true; // default: medium
+ whiteList['font-size-adjust'] = true; // default: none
+ whiteList['font-stretch'] = true; // default: normal
+ whiteList['font-style'] = true; // default: normal
+ whiteList['font-synthesis'] = true; // default: weight style
+ whiteList['font-variant'] = true; // default: normal
+ whiteList['font-variant-alternates'] = true; // default: normal
+ whiteList['font-variant-caps'] = true; // default: normal
+ whiteList['font-variant-east-asian'] = true; // default: normal
+ whiteList['font-variant-ligatures'] = true; // default: normal
+ whiteList['font-variant-numeric'] = true; // default: normal
+ whiteList['font-variant-position'] = true; // default: normal
+ whiteList['font-weight'] = true; // default: normal
+ whiteList['grid'] = false; // default: depending on individual properties
+ whiteList['grid-area'] = false; // default: depending on individual properties
+ whiteList['grid-auto-columns'] = false; // default: auto
+ whiteList['grid-auto-flow'] = false; // default: none
+ whiteList['grid-auto-rows'] = false; // default: auto
+ whiteList['grid-column'] = false; // default: depending on individual properties
+ whiteList['grid-column-end'] = false; // default: auto
+ whiteList['grid-column-start'] = false; // default: auto
+ whiteList['grid-row'] = false; // default: depending on individual properties
+ whiteList['grid-row-end'] = false; // default: auto
+ whiteList['grid-row-start'] = false; // default: auto
+ whiteList['grid-template'] = false; // default: depending on individual properties
+ whiteList['grid-template-areas'] = false; // default: none
+ whiteList['grid-template-columns'] = false; // default: none
+ whiteList['grid-template-rows'] = false; // default: none
+ whiteList['hanging-punctuation'] = false; // default: none
+ whiteList['height'] = true; // default: auto
+ whiteList['hyphens'] = false; // default: manual
+ whiteList['icon'] = false; // default: auto
+ whiteList['image-orientation'] = false; // default: auto
+ whiteList['image-resolution'] = false; // default: normal
+ whiteList['ime-mode'] = false; // default: auto
+ whiteList['initial-letters'] = false; // default: normal
+ whiteList['inline-box-align'] = false; // default: last
+ whiteList['justify-content'] = false; // default: auto
+ whiteList['justify-items'] = false; // default: auto
+ whiteList['justify-self'] = false; // default: auto
+ whiteList['left'] = false; // default: auto
+ whiteList['letter-spacing'] = true; // default: normal
+ whiteList['lighting-color'] = true; // default: white
+ whiteList['line-box-contain'] = false; // default: block inline replaced
+ whiteList['line-break'] = false; // default: auto
+ whiteList['line-grid'] = false; // default: match-parent
+ whiteList['line-height'] = false; // default: normal
+ whiteList['line-snap'] = false; // default: none
+ whiteList['line-stacking'] = false; // default: depending on individual properties
+ whiteList['line-stacking-ruby'] = false; // default: exclude-ruby
+ whiteList['line-stacking-shift'] = false; // default: consider-shifts
+ whiteList['line-stacking-strategy'] = false; // default: inline-line-height
+ whiteList['list-style'] = true; // default: depending on individual properties
+ whiteList['list-style-image'] = true; // default: none
+ whiteList['list-style-position'] = true; // default: outside
+ whiteList['list-style-type'] = true; // default: disc
+ whiteList['margin'] = true; // default: depending on individual properties
+ whiteList['margin-bottom'] = true; // default: 0
+ whiteList['margin-left'] = true; // default: 0
+ whiteList['margin-right'] = true; // default: 0
+ whiteList['margin-top'] = true; // default: 0
+ whiteList['marker-offset'] = false; // default: auto
+ whiteList['marker-side'] = false; // default: list-item
+ whiteList['marks'] = false; // default: none
+ whiteList['mask'] = false; // default: border-box
+ whiteList['mask-box'] = false; // default: see individual properties
+ whiteList['mask-box-outset'] = false; // default: 0
+ whiteList['mask-box-repeat'] = false; // default: stretch
+ whiteList['mask-box-slice'] = false; // default: 0 fill
+ whiteList['mask-box-source'] = false; // default: none
+ whiteList['mask-box-width'] = false; // default: auto
+ whiteList['mask-clip'] = false; // default: border-box
+ whiteList['mask-image'] = false; // default: none
+ whiteList['mask-origin'] = false; // default: border-box
+ whiteList['mask-position'] = false; // default: center
+ whiteList['mask-repeat'] = false; // default: no-repeat
+ whiteList['mask-size'] = false; // default: border-box
+ whiteList['mask-source-type'] = false; // default: auto
+ whiteList['mask-type'] = false; // default: luminance
+ whiteList['max-height'] = true; // default: none
+ whiteList['max-lines'] = false; // default: none
+ whiteList['max-width'] = true; // default: none
+ whiteList['min-height'] = true; // default: 0
+ whiteList['min-width'] = true; // default: 0
+ whiteList['move-to'] = false; // default: normal
+ whiteList['nav-down'] = false; // default: auto
+ whiteList['nav-index'] = false; // default: auto
+ whiteList['nav-left'] = false; // default: auto
+ whiteList['nav-right'] = false; // default: auto
+ whiteList['nav-up'] = false; // default: auto
+ whiteList['object-fit'] = false; // default: fill
+ whiteList['object-position'] = false; // default: 50% 50%
+ whiteList['opacity'] = false; // default: 1
+ whiteList['order'] = false; // default: 0
+ whiteList['orphans'] = false; // default: 2
+ whiteList['outline'] = false; // default: depending on individual properties
+ whiteList['outline-color'] = false; // default: invert
+ whiteList['outline-offset'] = false; // default: 0
+ whiteList['outline-style'] = false; // default: none
+ whiteList['outline-width'] = false; // default: medium
+ whiteList['overflow'] = false; // default: depending on individual properties
+ whiteList['overflow-wrap'] = false; // default: normal
+ whiteList['overflow-x'] = false; // default: visible
+ whiteList['overflow-y'] = false; // default: visible
+ whiteList['padding'] = true; // default: depending on individual properties
+ whiteList['padding-bottom'] = true; // default: 0
+ whiteList['padding-left'] = true; // default: 0
+ whiteList['padding-right'] = true; // default: 0
+ whiteList['padding-top'] = true; // default: 0
+ whiteList['page'] = false; // default: auto
+ whiteList['page-break-after'] = false; // default: auto
+ whiteList['page-break-before'] = false; // default: auto
+ whiteList['page-break-inside'] = false; // default: auto
+ whiteList['page-policy'] = false; // default: start
+ whiteList['pause'] = false; // default: implementation dependent
+ whiteList['pause-after'] = false; // default: implementation dependent
+ whiteList['pause-before'] = false; // default: implementation dependent
+ whiteList['perspective'] = false; // default: none
+ whiteList['perspective-origin'] = false; // default: 50% 50%
+ whiteList['pitch'] = false; // default: medium
+ whiteList['pitch-range'] = false; // default: 50
+ whiteList['play-during'] = false; // default: auto
+ whiteList['position'] = false; // default: static
+ whiteList['presentation-level'] = false; // default: 0
+ whiteList['quotes'] = false; // default: text
+ whiteList['region-fragment'] = false; // default: auto
+ whiteList['resize'] = false; // default: none
+ whiteList['rest'] = false; // default: depending on individual properties
+ whiteList['rest-after'] = false; // default: none
+ whiteList['rest-before'] = false; // default: none
+ whiteList['richness'] = false; // default: 50
+ whiteList['right'] = false; // default: auto
+ whiteList['rotation'] = false; // default: 0
+ whiteList['rotation-point'] = false; // default: 50% 50%
+ whiteList['ruby-align'] = false; // default: auto
+ whiteList['ruby-merge'] = false; // default: separate
+ whiteList['ruby-position'] = false; // default: before
+ whiteList['shape-image-threshold'] = false; // default: 0.0
+ whiteList['shape-outside'] = false; // default: none
+ whiteList['shape-margin'] = false; // default: 0
+ whiteList['size'] = false; // default: auto
+ whiteList['speak'] = false; // default: auto
+ whiteList['speak-as'] = false; // default: normal
+ whiteList['speak-header'] = false; // default: once
+ whiteList['speak-numeral'] = false; // default: continuous
+ whiteList['speak-punctuation'] = false; // default: none
+ whiteList['speech-rate'] = false; // default: medium
+ whiteList['stress'] = false; // default: 50
+ whiteList['string-set'] = false; // default: none
+ whiteList['tab-size'] = false; // default: 8
+ whiteList['table-layout'] = false; // default: auto
+ whiteList['text-align'] = true; // default: start
+ whiteList['text-align-last'] = true; // default: auto
+ whiteList['text-combine-upright'] = true; // default: none
+ whiteList['text-decoration'] = true; // default: none
+ whiteList['text-decoration-color'] = true; // default: currentColor
+ whiteList['text-decoration-line'] = true; // default: none
+ whiteList['text-decoration-skip'] = true; // default: objects
+ whiteList['text-decoration-style'] = true; // default: solid
+ whiteList['text-emphasis'] = true; // default: depending on individual properties
+ whiteList['text-emphasis-color'] = true; // default: currentColor
+ whiteList['text-emphasis-position'] = true; // default: over right
+ whiteList['text-emphasis-style'] = true; // default: none
+ whiteList['text-height'] = true; // default: auto
+ whiteList['text-indent'] = true; // default: 0
+ whiteList['text-justify'] = true; // default: auto
+ whiteList['text-orientation'] = true; // default: mixed
+ whiteList['text-overflow'] = true; // default: clip
+ whiteList['text-shadow'] = true; // default: none
+ whiteList['text-space-collapse'] = true; // default: collapse
+ whiteList['text-transform'] = true; // default: none
+ whiteList['text-underline-position'] = true; // default: auto
+ whiteList['text-wrap'] = true; // default: normal
+ whiteList['top'] = false; // default: auto
+ whiteList['transform'] = false; // default: none
+ whiteList['transform-origin'] = false; // default: 50% 50% 0
+ whiteList['transform-style'] = false; // default: flat
+ whiteList['transition'] = false; // default: depending on individual properties
+ whiteList['transition-delay'] = false; // default: 0s
+ whiteList['transition-duration'] = false; // default: 0s
+ whiteList['transition-property'] = false; // default: all
+ whiteList['transition-timing-function'] = false; // default: ease
+ whiteList['unicode-bidi'] = false; // default: normal
+ whiteList['vertical-align'] = false; // default: baseline
+ whiteList['visibility'] = false; // default: visible
+ whiteList['voice-balance'] = false; // default: center
+ whiteList['voice-duration'] = false; // default: auto
+ whiteList['voice-family'] = false; // default: implementation dependent
+ whiteList['voice-pitch'] = false; // default: medium
+ whiteList['voice-range'] = false; // default: medium
+ whiteList['voice-rate'] = false; // default: normal
+ whiteList['voice-stress'] = false; // default: normal
+ whiteList['voice-volume'] = false; // default: medium
+ whiteList['volume'] = false; // default: medium
+ whiteList['white-space'] = false; // default: normal
+ whiteList['widows'] = false; // default: 2
+ whiteList['width'] = true; // default: auto
+ whiteList['will-change'] = false; // default: auto
+ whiteList['word-break'] = true; // default: normal
+ whiteList['word-spacing'] = true; // default: normal
+ whiteList['word-wrap'] = true; // default: normal
+ whiteList['wrap-flow'] = false; // default: auto
+ whiteList['wrap-through'] = false; // default: wrap
+ whiteList['writing-mode'] = false; // default: horizontal-tb
+ whiteList['z-index'] = false; // default: auto
+
+ return whiteList;
+}
+
+
+/**
+ * 匹配到白名单上的一个属性时
+ *
+ * @param {String} name
+ * @param {String} value
+ * @param {Object} options
+ * @return {String}
+ */
+function onAttr (name, value, options) {
+ // do nothing
+}
+
+/**
+ * 匹配到不在白名单上的一个属性时
+ *
+ * @param {String} name
+ * @param {String} value
+ * @param {Object} options
+ * @return {String}
+ */
+function onIgnoreAttr (name, value, options) {
+ // do nothing
+}
+
+var REGEXP_URL_JAVASCRIPT = /javascript\s*\:/img;
+
+/**
+ * 过滤属性值
+ *
+ * @param {String} name
+ * @param {String} value
+ * @return {String}
+ */
+function safeAttrValue(name, value) {
+ if (REGEXP_URL_JAVASCRIPT.test(value)) return '';
+ return value;
+}
+
+
+exports.whiteList = getDefaultWhiteList();
+exports.getDefaultWhiteList = getDefaultWhiteList;
+exports.onAttr = onAttr;
+exports.onIgnoreAttr = onIgnoreAttr;
+exports.safeAttrValue = safeAttrValue;
diff --git a/node_modules/cssfilter/lib/index.js b/node_modules/cssfilter/lib/index.js
new file mode 100644
index 0000000..712f55f
--- /dev/null
+++ b/node_modules/cssfilter/lib/index.js
@@ -0,0 +1,32 @@
+/**
+ * cssfilter
+ *
+ * @author 老雷<leizongmin@gmail.com>
+ */
+
+var DEFAULT = require('./default');
+var FilterCSS = require('./css');
+
+
+/**
+ * XSS过滤
+ *
+ * @param {String} css 要过滤的CSS代码
+ * @param {Object} options 选项:whiteList, onAttr, onIgnoreAttr
+ * @return {String}
+ */
+function filterCSS (html, options) {
+ var xss = new FilterCSS(options);
+ return xss.process(html);
+}
+
+
+// 输出
+exports = module.exports = filterCSS;
+exports.FilterCSS = FilterCSS;
+for (var i in DEFAULT) exports[i] = DEFAULT[i];
+
+// 在浏览器端使用
+if (typeof window !== 'undefined') {
+ window.filterCSS = module.exports;
+}
diff --git a/node_modules/cssfilter/lib/parser.js b/node_modules/cssfilter/lib/parser.js
new file mode 100644
index 0000000..fcb9418
--- /dev/null
+++ b/node_modules/cssfilter/lib/parser.js
@@ -0,0 +1,74 @@
+/**
+ * cssfilter
+ *
+ * @author 老雷<leizongmin@gmail.com>
+ */
+
+var _ = require('./util');
+
+
+/**
+ * 解析style
+ *
+ * @param {String} css
+ * @param {Function} onAttr 处理属性的函数
+ * 参数格式: function (sourcePosition, position, name, value, source)
+ * @return {String}
+ */
+function parseStyle (css, onAttr) {
+ css = _.trimRight(css);
+ if (css[css.length - 1] !== ';') css += ';';
+ var cssLength = css.length;
+ var isParenthesisOpen = false;
+ var lastPos = 0;
+ var i = 0;
+ var retCSS = '';
+
+ function addNewAttr () {
+ // 如果没有正常的闭合圆括号,则直接忽略当前属性
+ if (!isParenthesisOpen) {
+ var source = _.trim(css.slice(lastPos, i));
+ var j = source.indexOf(':');
+ if (j !== -1) {
+ var name = _.trim(source.slice(0, j));
+ var value = _.trim(source.slice(j + 1));
+ // 必须有属性名称
+ if (name) {
+ var ret = onAttr(lastPos, retCSS.length, name, value, source);
+ if (ret) retCSS += ret + '; ';
+ }
+ }
+ }
+ lastPos = i + 1;
+ }
+
+ for (; i < cssLength; i++) {
+ var c = css[i];
+ if (c === '/' && css[i + 1] === '*') {
+ // 备注开始
+ var j = css.indexOf('*/', i + 2);
+ // 如果没有正常的备注结束,则后面的部分全部跳过
+ if (j === -1) break;
+ // 直接将当前位置调到备注结尾,并且初始化状态
+ i = j + 1;
+ lastPos = i + 1;
+ isParenthesisOpen = false;
+ } else if (c === '(') {
+ isParenthesisOpen = true;
+ } else if (c === ')') {
+ isParenthesisOpen = false;
+ } else if (c === ';') {
+ if (isParenthesisOpen) {
+ // 在圆括号里面,忽略
+ } else {
+ addNewAttr();
+ }
+ } else if (c === '\n') {
+ addNewAttr();
+ }
+ }
+
+ return _.trim(retCSS);
+}
+
+module.exports = parseStyle;
diff --git a/node_modules/cssfilter/lib/util.js b/node_modules/cssfilter/lib/util.js
new file mode 100644
index 0000000..c8b4f7b
--- /dev/null
+++ b/node_modules/cssfilter/lib/util.js
@@ -0,0 +1,35 @@
+module.exports = {
+ indexOf: function (arr, item) {
+ var i, j;
+ if (Array.prototype.indexOf) {
+ return arr.indexOf(item);
+ }
+ for (i = 0, j = arr.length; i < j; i++) {
+ if (arr[i] === item) {
+ return i;
+ }
+ }
+ return -1;
+ },
+ forEach: function (arr, fn, scope) {
+ var i, j;
+ if (Array.prototype.forEach) {
+ return arr.forEach(fn, scope);
+ }
+ for (i = 0, j = arr.length; i < j; i++) {
+ fn.call(scope, arr[i], i, arr);
+ }
+ },
+ trim: function (str) {
+ if (String.prototype.trim) {
+ return str.trim();
+ }
+ return str.replace(/(^\s*)|(\s*$)/g, '');
+ },
+ trimRight: function (str) {
+ if (String.prototype.trimRight) {
+ return str.trimRight();
+ }
+ return str.replace(/(\s*$)/g, '');
+ }
+};