Rules
规则集包含一系列规则,其构造器通过传入的options
配置对象获取规则列表并置于array
字段中。
字段为:
options
:配置项对象,就是用户传进来的那些_keep
:保留的规则列表_remove
:删除的规则列表array
:常规规则列表blankRule
:空白节点的规则keepReplacement
:保留节点的规则defaultRule
:默认规则
function Rules (options) {
this.options = options;
this._keep = [];
this._remove = [];
this.blankRule = {
replacement: options.blankReplacement
};
this.keepReplacement = options.keepReplacement;
this.defaultRule = {
replacement: options.defaultReplacement
};
this.array = [];
for (var key in options.rules) this.array.push(options.rules[key]);
}
Rules.add()
在规则表前端插入指定规则,遍历的顺序是从前向后,所以新插入的规则会优先匹配。
add: function (key, rule) {
this.array.unshift(rule);
},
Rules.keep()
在保留列表中插入指定的过滤器。
keep: function (filter) {
this._keep.unshift({
filter: filter,
replacement: this.keepReplacement
});
},
根据构造器,this.keepReplacement
就是options.keepReplacement
,然后再看看它:
keepReplacement: function (content, node) {
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
},
保留列表的作用就是,原封不动保留匹配元素的outerHTML
。
Rules.remove()
在移除列表中插入给定的过滤器。移除列表的作用就是保证某个元素被移除。
remove: function (filter) {
this._remove.unshift({
filter: filter,
replacement: function () {
return ''
}
});
},
Rules.forEach()
等价于this.array.forEach
。
forEach: function (fn) {
for (var i = 0; i < this.array.length; i++) fn(this.array[i], i);
}
findRule()
遍历给定规则列表,使用每个规则匹配给定节点,如果匹配则返回当前规则,否则返回空值。
function findRule (rules, node, options) {
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
if (filterValue(rule, node, options)) return rule
}
return void 0
}
Rules.forNode()
寻找第一个匹配给定节点的规则。
顺序为:
- 首先通过
node.isBlank
判断节点是否为空白,是的话就返回空白节点规则。 - 依次在规则列表、保留列表、移除列表中匹配该节点,如果匹配成功返回匹配的规则
- 如果全部都不匹配,返回默认规则
forNode: function (node) {
if (node.isBlank) return this.blankRule
var rule;
if ((rule = findRule(this.array, node, this.options))) return rule
if ((rule = findRule(this._keep, node, this.options))) return rule
if ((rule = findRule(this._remove, node, this.options))) return rule
return this.defaultRule
},
其中空白节点的规则为不保留任何东西:
blankReplacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
}
默认规则为只保留它的Markdown内容:
defaultReplacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
filterValue()
考虑三种不同类型的规则(string
、string[]
和function
),判断给定规则是否匹配给定节点。
function filterValue (rule, node, options) {
var filter = rule.filter;
if (typeof filter === 'string') {
if (filter === node.nodeName.toLowerCase()) return true
} else if (Array.isArray(filter)) {
if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true
} else if (typeof filter === 'function') {
if (filter.call(rule, node, options)) return true
} else {
throw new TypeError('`filter` needs to be a string, array, or function')
}
}