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') } }