-
Notifications
You must be signed in to change notification settings - Fork 11
规则配置语法
mip-validator
采取JSON格式的配置文件,所有校验规则均来源于该文件。
本文档描述了该配置文件的语法,为规则的开发者以及MIP校验工具的其他实现提供参考。
注意:
- 本文给出的规则样例只为阐明机制,不一定是真正的MIP规则。
-
mip-validator
使用parse5作为DOM树解析工具,HTML语法错误已被容错。因而语法相关的配置无效。
规则文件应为合法的JSON格式,每个根键代表一个标签名(根键不可重复)。
根键对应的值为校验规则对象,或校验规则对象数组(见下文)。
每个校验规则对象定义了当前根键所表示的标签的校验规则,
下面示例表示script
标签在整个HTML中不允许出现(disallow规则见下文)。
{
"script": {
"disallow": true
}
}
标签规则对象的attrs
键对应的值为该标签的属性的校验规则对象,例如:
{
"input": {
"attrs": {
"name": {
"mandatory": true
}
}
}
}
指定了input
标签的name
属性有如下的校验规则对象:
{
"mandatory": true
}
表示input
标签必须定义name
属性。
标签校验规则对象和属性校验规则对象都可以形成一个数组。 此时数组的每一项都会被解析为一个独立的校验规则对象。 所有这些对象都应得到校验(与的关系,即都必须通过)。下面分别给出标签和属性的示例。
{
"script": [{
"disallow": true
},{
"mandatory": true
}]
}
mandatory
表示必须出现(见下文)。对于如上的规则,任何HTML都将无法通过校验。
因为一个规则表示script
必须出现,而另一个表示script
不允许出现。
与标签规则类似,属性规则也可以是数组,例如:
{
"meta": {
"attrs":{
"name": [{
"mandatory": true
},{
"disallow": true
}]
}
}
}
任何包含meta
标签的HTML都无法通过上述规则的校验。
因为它要求meta
标签必须有name
属性,同时禁止name
属性。
这一部分定义了校验规则对象中规则字段的语义。包括其属性路径、值的类型、默认值、以及错误代号, 并给出相应的示例。
属性:<TagName>.mandatory
类型:Boolean
或<Object>
或Array<Object>
默认:false
错误代号:"MANDATORY_TAG_MISSING"
该字段用来指定强制包含的元素:
- 当该字段为
true
时,HTML必须包含该标签,为false
则相当于不设置; - 当该字段为对象时,HTML必须包含属性匹配该对象的标签;
- 当该字段为数组时,HTML必须包含匹配该数组每一项的标签。
例如<link rel="miphtml">
与<link rel="standardhtml">
都必须出现可以写成:
{
"link": {
"mandatory": [{
"rel": "/standardhtml/"
}, {
"rel": "/miphtml/"
}]
}
}
属性:<TagName>.mandatory_or
类型:Array<Object>
默认:undefined
错误代号:"MANDATORY_TAG_MISSING"
同<TagName>.mandatory
,但数组元素是或的关系,例如检查charset
设置:
{
"meta": {
"mandatory_or": [{
"http-equiv": "/Content-Type/i",
"content": "/charset=utf-8/"
}, {
"charset": "utf-8"
}]
}
}
其中
i
为不区分大小写,参考JavaScript正则表达式。
属性:<TagName>.mandatory_ancestor
类型:String
默认:undefined
错误代号:"MANDATORY_TAG_ANCESTOR"
该字段用来指定一个标签必须拥有的祖先标签。例如<mip-input>
一定要位于<mip-form>
下:
{
"mip-input": {
"mandatory_ancestor": "mip-form"
}
}
属性:<TagName>.mandatory_parent
类型:String
默认:undefined
错误代号:"WRONG_PARENT_TAG"
该字段用来指定强制父标签。例如:
{
"head": {
"mandatory_parent": "html"
}
}
属性:<TagName>.disallow
类型:Boolean
默认:false
错误代号:"DISALLOWED_TAG"
为true
表示该标签不允许在HTML中出现,否则为允许出现。例如不允许<img>
标签出现:
{
"img": {
"disallow": true
}
}
属性:<TagName>.disallowed_ancestor
类型:String
或Array<String>
默认:undefined
错误代号:"DISALLOWED_TAG_ANCESTOR"
该字段设置不允许出现的祖先标签,可以是单个标签名,也可以是标签名数组。 例如:
{
"div": {
"disallowed_ancestor": "span"
},
"form":{
"disallowed_ancestor": ["span", "a"]
}
}
属性:<TagName>.ignore
类型:Boolean
默认:undefined
错误代号:"null"
该字段设置某个标签下所有内容可以被豁免校验 例如:
{
"template": {
"ignore": true
}
}
属性:<TagName>.inner_html
类型:String
默认:undefined
错误代号:"INVALID_INNER_HTML"
单元测试:https://github.com/mipengine/mip-validator/blob/master/test/invalid_inner_html.js
该字段设置 innerHTML
的内容规则,支持正则表达式(见下文)。例如:
{
"div": {
"inner_html": "foo"
},
"form":{
"inner_html": "/^<span>[^<]*<\/span>$/"
}
}
若需配置禁止出现的 inner_html 内容,可在正则表达式前添加
!
,例如:"!/position:\\s*fixed/"
属性:<TagName>.duplicate
类型:Object
或Array<Object>
默认:undefined
错误代号:"DUPLICATE_UNIQUE_TAG"
该属性设置一个或一组模式,符合该模式的标签不可重复,属性值采用正则表达式来书写。 如果是一个模式,则完全匹配该模式的标签不可重复,如果是多个模式则分别不可重复。 例如:
{
"meta": {
"duplicate": {
"viewport": "/.*/"
}
},
"link": {
"duplicate": [{
"rel": "miphtml"
}, {
"rel": "standardhtml"
}]
}
}
属性:<TagName>.attrs.<AttrName>.value
类型:String
默认:""
错误代号:"INVALID_ATTR_VALUE"
该字段用来校验属性值是否合法。传入的字符串将被用来构建使用正则表达式。 例如:
{
"mip-img": {
"attrs": {
"src": {
"value": "/^http:///"
}
}
}
}
属性:<TagName>.attrs.<AttrName>.properties
类型:Object
默认:undefined
错误代号:"INVALID_PROPERTY_VALUE_IN_ATTR_VALUE"
该字段用来配置attribute值中的property是否拥有合法的值。
该字段生效的前提是同一对象下的<TagName>.attrs.<AttrName>.match
与当前标签匹配。
例如:
{
"meta": {
"attrs": {
"content": {
"match": {
"name": "viewport"
},
"properties": {
"width": "device-width",
"initial-scale": "1"
}
}
}
}
}
上述规则将会对所有<meta name="viewport">
进行校验,验证content
中的属性是否合法。
比如<meta name="viewport" content="width=device-width,initial-scale=1">
是合法的。
属性:<TagName>.attrs.<AttrName>.mandatory
类型:Boolean
默认:false
错误代号:"MANDATORY_ONEOF_ATTR_MISSING"
该字段用来指定标签的某个属性是强制包含的。例如:
{
"mip-input": {
"attrs": {
"name": {
"mandatory": true
}
}
}
}
上述规则强制要求所有<mip-input>
标签拥有name
属性。
为了实现校验规则见『或』的关系,引入规则匹配字段。 每一个标签或属性的校验规则对象都可以包含规则匹配字段的声明。 规则匹配字段有多种:
- 对于节点(
node
)而言,包括match
,match_ancestor
,match_parent
。 - 对于属性(
attribute
)而言,包括match
,nomatch_descendant
。
如需要更多规则匹配语法,请提 Issue。
match
规则匹配字段可以用来匹配拥有特定属性(attribute)的节点(node)。
只有被匹配的标签才会应用当前的校验规则对象。
下面分别以标签和属性来给出规则匹配对象的例子。
{
"script": [{
"disallow": true,
"match": {
"type": "application/json",
"src": "/^https:/"
}
},{
"mandatory": true
}]
}
这样就只有属性type
的值为application/json
并且
属性src
的值为https
起始的script
标签应用disallow
规则。
与标签类似,属性规则对象也支持match
规则匹配字段。例如:
{
"meta": {
"attrs": [{
"content": [{
"match": {
"name": "viewport"
},
"mandatory": true
}]
}]
}
}
上述规则表示,只有name
属性值为viewport
的meta
标签,必须出现content
属性。
match_ancestor
用来匹配祖先标签名。只有匹配成功的校验规则对象才会生效。例如:
{
"input": {
"disallow": true,
"match_ancestor": "form"
}
}
这样我们就定义了一个奇怪的规则:只有在form
下不允许input
。
类似match_ancestor
,match_parent
用来匹配直接父标签名。
match_ancestor
和match_parent
的值都支持正则表达式(见下文)。
{
"input": {
"disallow": true,
"match_parent": "form"
}
}
上述规则表示,input
不能是form
的直接子节点,但可以是form
下的深层节点。
nomatch_descendant
用于否定匹配后代节点。例如:
{
"video": {
"attrs": {
"src": {
"mandatory": true,
"nomatch_descendant": "source"
}
}
}
}
对于不包含source
后代节点的video
标签,src
属性是强制的。
标签名、属性名、属性值、属性的属性值(property within attribute)都允许以正则表达式和字符串两种方式来规约。识别方式如下:
- 以
/
开始并以/\w*
结尾的字符串将会被解析为正则表达式,按正则来匹配。 - 其他字符串将会被解析为字符串,要求字符串全等。
下列字符串都将被识别为正则表达式:
/foo/
/foo/g
/foo/ig
!/foo/
前三项正则表达式为ECMAScript风格,见:http://www.regular-expressions.info/javascript.html。最后一项为正则表达式增强,表示对匹配结果取非。
这里的正则完全等同于JavaScript中的正则声明,不同的一点是该字符串需要转义,
因为该字符串将以new RegExp
的方式转换为正则表达式对象。
标签名允许以正则表达式的方式给出,例如:
{
"/^h/": {
"disallow": true
}
}
上述规则表示以h
起始的标签都是不允许的,即html
, header
, h1
等都不能通过校验。
与标签类似,属性名也可以正则匹配,例如:
{
"input": {
"attrs": {
"/^on.+/": {
"disallow": true
}
}
}
}
上述配置表示所有以on
起始的属性都是不允许的。
Copyright © 2017