Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Menu
Open sidebar
html-validate
html-validate
Commits
f88f0da0
Commit
f88f0da0
authored
Apr 03, 2021
by
David Sveningsson
Browse files
feat: add rule option schemas
parent
5b8ca066
Pipeline
#281103432
passed with stages
in 10 minutes and 42 seconds
Changes
31
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
docs/rules/__tests__/require-sri.md.spec.ts
View file @
f88f0da0
...
...
@@ -24,7 +24,7 @@ describe("docs/rules/require-sri.md", () => {
});
it
(
"
inline validation: crossorigin
"
,
()
=>
{
expect
.
assertions
(
1
);
const
htmlvalidate
=
new
HtmlValidate
({
"
rules
"
:{
"
require-sri
"
:[
"
error
"
,{
"
target
"
:
"
cross
doma
in
"
}]}});
const
htmlvalidate
=
new
HtmlValidate
({
"
rules
"
:{
"
require-sri
"
:[
"
error
"
,{
"
target
"
:
"
cross
orig
in
"
}]}});
const
report
=
htmlvalidate
.
validateString
(
markup
[
"
crossorigin
"
]);
expect
(
report
.
results
).
toMatchSnapshot
();
});
...
...
docs/rules/require-sri.md
View file @
f88f0da0
...
...
@@ -48,7 +48,7 @@ that the logic for determining crossdomain is a bit naïve, resources with a ful
url (
`protocol://`
) or implicit protocol (
`//`
) counts as crossorigin even if it
technically would point to the same origin.
<validate
name=
"crossorigin"
rules=
"require-sri"
require-sri=
'{"target": "cross
doma
in"}'
>
<validate
name=
"crossorigin"
rules=
"require-sri"
require-sri=
'{"target": "cross
orig
in"}'
>
<!--- local resource -->
<link
href=
"local.css"
>
...
...
src/rules/allowed-links.ts
View file @
f88f0da0
import
{
DynamicValue
}
from
"
../dom
"
;
import
{
AttributeEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
export
const
enum
Style
{
EXTERNAL
=
"
external
"
,
...
...
@@ -44,6 +44,23 @@ export default class AllowedLinks extends Rule<Style, RuleOptions> {
super
({
...
defaults
,
...
options
});
}
public
static
schema
():
SchemaObject
{
return
{
allowAbsolute
:
{
type
:
"
boolean
"
,
},
allowBase
:
{
type
:
"
boolean
"
,
},
allowExternal
:
{
type
:
"
boolean
"
,
},
allowRelative
:
{
type
:
"
boolean
"
,
},
};
}
public
documentation
(
context
:
Style
):
RuleDocumentation
{
const
message
=
description
[
context
]
||
"
This link type is not allowed by current configuration
"
;
...
...
src/rules/attr-case.spec.ts
View file @
f88f0da0
...
...
@@ -228,11 +228,12 @@ describe("rule attr-case", () => {
it
(
"
should throw error if configured with invalid value
"
,
()
=>
{
expect
.
assertions
(
1
);
htmlvalidate
=
new
HtmlValidate
({
rules
:
{
"
attr-case
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
expect
(()
=>
htmlvalidate
.
validateString
(
"
<foo></foo>
"
)).
toThrow
(
`Invalid style "foobar" for attr-case rule`
expect
(()
=>
{
return
new
HtmlValidate
({
rules
:
{
"
attr-case
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
}).
toThrowErrorMatchingInlineSnapshot
(
`"Rule configuration error: /rules/attr-case/1/style should be equal to one of the allowed values: lowercase, uppercase, pascalcase, camelcase"`
);
});
...
...
src/rules/attr-case.ts
View file @
f88f0da0
import
{
HtmlElement
}
from
"
../dom
"
;
import
{
AttributeEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
import
{
CaseStyle
,
CaseStyleName
}
from
"
./helper/case-style
"
;
interface
RuleOptions
{
...
...
@@ -21,6 +21,30 @@ export default class AttrCase extends Rule<void, RuleOptions> {
this
.
style
=
new
CaseStyle
(
this
.
options
.
style
,
"
attr-case
"
);
}
public
static
schema
():
SchemaObject
{
const
styleEnum
=
[
"
lowercase
"
,
"
uppercase
"
,
"
pascalcase
"
,
"
camelcase
"
];
return
{
ignoreForeign
:
{
type
:
"
boolean
"
,
},
style
:
{
anyOf
:
[
{
enum
:
styleEnum
,
type
:
"
string
"
,
},
{
items
:
{
enum
:
styleEnum
,
type
:
"
string
"
,
},
type
:
"
array
"
,
},
],
},
};
}
public
documentation
():
RuleDocumentation
{
return
{
description
:
`Attribute name must be
${
this
.
options
.
style
}
.`
,
...
...
src/rules/attr-quotes.spec.ts
View file @
f88f0da0
...
...
@@ -124,14 +124,15 @@ describe("rule attr-quotes", () => {
});
});
it
(
"
should default to double quotes for invalid style
"
,
()
=>
{
expect
.
assertions
(
2
);
htmlvalidate
=
new
HtmlValidate
({
rules
:
{
"
attr-quotes
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
const
report
=
htmlvalidate
.
validateString
(
"
<div foo='bar'></div>
"
);
expect
(
report
).
toBeInvalid
();
expect
(
report
).
toHaveError
(
"
attr-quotes
"
,
`Attribute "foo" used ' instead of expected "`
);
it
(
"
should throw error if configured with invalid value
"
,
()
=>
{
expect
.
assertions
(
1
);
expect
(()
=>
{
return
new
HtmlValidate
({
rules
:
{
"
attr-quotes
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
}).
toThrowErrorMatchingInlineSnapshot
(
`"Rule configuration error: /rules/attr-quotes/1/style should be equal to one of the allowed values: auto, double, single"`
);
});
it
(
"
should contain documentation (auto)
"
,
()
=>
{
...
...
src/rules/attr-quotes.ts
View file @
f88f0da0
import
{
ConfigError
}
from
"
../config
"
;
import
{
AttributeEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
type
QuoteMark
=
'
"
'
|
"
'
"
;
enum
QuoteStyle
{
...
...
@@ -8,19 +9,31 @@ enum QuoteStyle {
AUTO_QUOTE
=
"
auto
"
,
}
interface
Options
{
style
:
'
"
'
|
"
'
"
|
"
auto
"
;
interface
Rule
Options
{
style
:
"
auto
"
|
"
single
"
|
"
double
"
;
unquoted
:
boolean
;
}
const
defaults
:
Options
=
{
const
defaults
:
Rule
Options
=
{
style
:
"
auto
"
,
unquoted
:
false
,
};
export
default
class
AttrQuotes
extends
Rule
<
void
,
Options
>
{
export
default
class
AttrQuotes
extends
Rule
<
void
,
Rule
Options
>
{
private
style
:
QuoteStyle
;
public
static
schema
():
SchemaObject
{
return
{
style
:
{
enum
:
[
"
auto
"
,
"
double
"
,
"
single
"
],
type
:
"
string
"
,
},
unquoted
:
{
type
:
"
boolean
"
,
},
};
}
public
documentation
():
RuleDocumentation
{
if
(
this
.
options
.
style
===
"
auto
"
)
{
return
{
...
...
@@ -35,7 +48,7 @@ export default class AttrQuotes extends Rule<void, Options> {
}
}
public
constructor
(
options
:
Partial
<
Options
>
)
{
public
constructor
(
options
:
Partial
<
Rule
Options
>
)
{
super
({
...
defaults
,
...
options
});
this
.
style
=
parseStyle
(
this
.
options
.
style
);
}
...
...
@@ -82,7 +95,8 @@ function parseStyle(style: string): QuoteStyle {
return
QuoteStyle
.
DOUBLE_QUOTE
;
case
"
single
"
:
return
QuoteStyle
.
SINGLE_QUOTE
;
/* istanbul ignore next: covered by schema validation */
default
:
return
QuoteStyle
.
DOUBLE_QUOTE
;
throw
new
ConfigError
(
`Invalid style "
${
style
}
" for "attr-quotes" rule`
)
;
}
}
src/rules/attribute-boolean-style.spec.ts
View file @
f88f0da0
...
...
@@ -205,11 +205,12 @@ describe("rule attribute-boolean-style", () => {
it
(
"
should throw error if configured with invalid value
"
,
()
=>
{
expect
.
assertions
(
1
);
htmlvalidate
=
new
HtmlValidate
({
rules
:
{
"
attribute-boolean-style
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
expect
(()
=>
htmlvalidate
.
validateString
(
"
<foo></foo>
"
)).
toThrow
(
`Invalid style "foobar" for "attribute-boolean-style" rule`
expect
(()
=>
{
return
new
HtmlValidate
({
rules
:
{
"
attribute-boolean-style
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
}).
toThrowErrorMatchingInlineSnapshot
(
`"Rule configuration error: /rules/attribute-boolean-style/1/style should be equal to one of the allowed values: empty, name, omit"`
);
});
...
...
src/rules/attribute-boolean-style.ts
View file @
f88f0da0
import
{
Attribute
,
HtmlElement
}
from
"
../dom
"
;
import
{
DOMReadyEvent
}
from
"
../event
"
;
import
{
PermittedAttribute
}
from
"
../meta/element
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
Options
{
style
:
string
;
interface
Rule
Options
{
style
:
"
omit
"
|
"
empty
"
|
"
name
"
;
}
const
defaults
:
Options
=
{
const
defaults
:
Rule
Options
=
{
style
:
"
omit
"
,
};
type
checkFunction
=
(
attr
:
Attribute
)
=>
boolean
;
export
default
class
AttributeBooleanStyle
extends
Rule
<
void
,
Options
>
{
export
default
class
AttributeBooleanStyle
extends
Rule
<
void
,
Rule
Options
>
{
private
hasInvalidStyle
:
checkFunction
;
public
constructor
(
options
:
Partial
<
Options
>
)
{
public
constructor
(
options
:
Partial
<
Rule
Options
>
)
{
super
({
...
defaults
,
...
options
});
this
.
hasInvalidStyle
=
parseStyle
(
this
.
options
.
style
);
}
public
static
schema
():
SchemaObject
{
return
{
style
:
{
enum
:
[
"
empty
"
,
"
name
"
,
"
omit
"
],
type
:
"
string
"
,
},
};
}
public
documentation
():
RuleDocumentation
{
return
{
description
:
"
Require a specific style when writing boolean attributes.
"
,
...
...
@@ -71,6 +80,7 @@ function parseStyle(style: string): checkFunction {
return
(
attr
:
Attribute
)
=>
attr
.
value
!==
""
;
case
"
name
"
:
return
(
attr
:
Attribute
)
=>
attr
.
value
!==
attr
.
key
;
/* istanbul ignore next: covered by schema validation */
default
:
throw
new
Error
(
`Invalid style "
${
style
}
" for "attribute-boolean-style" rule`
);
}
...
...
src/rules/attribute-empty-style.spec.ts
View file @
f88f0da0
...
...
@@ -126,11 +126,12 @@ describe("rule attribute-empty-style", () => {
it
(
"
should throw error if configured with invalid value
"
,
()
=>
{
expect
.
assertions
(
1
);
htmlvalidate
=
new
HtmlValidate
({
rules
:
{
"
attribute-empty-style
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
expect
(()
=>
htmlvalidate
.
validateString
(
"
<foo></foo>
"
)).
toThrow
(
`Invalid style "foobar" for "attribute-empty-style" rule`
expect
(()
=>
{
return
new
HtmlValidate
({
rules
:
{
"
attribute-empty-style
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
}).
toThrowErrorMatchingInlineSnapshot
(
`"Rule configuration error: /rules/attribute-empty-style/1/style should be equal to one of the allowed values: empty, omit"`
);
});
...
...
src/rules/attribute-empty-style.ts
View file @
f88f0da0
import
{
Attribute
,
HtmlElement
}
from
"
../dom
"
;
import
{
DOMReadyEvent
}
from
"
../event
"
;
import
{
PermittedAttribute
}
from
"
../meta/element
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
Options
{
style
:
string
;
interface
Rule
Options
{
style
:
"
omit
"
|
"
empty
"
;
}
const
defaults
:
Options
=
{
const
defaults
:
Rule
Options
=
{
style
:
"
omit
"
,
};
type
checkFunction
=
(
attr
:
Attribute
)
=>
boolean
;
export
default
class
AttributeEmptyStyle
extends
Rule
<
void
,
Options
>
{
export
default
class
AttributeEmptyStyle
extends
Rule
<
void
,
Rule
Options
>
{
private
hasInvalidStyle
:
checkFunction
;
public
constructor
(
options
:
Partial
<
Options
>
)
{
public
constructor
(
options
:
Partial
<
Rule
Options
>
)
{
super
({
...
defaults
,
...
options
});
this
.
hasInvalidStyle
=
parseStyle
(
this
.
options
.
style
);
}
public
static
schema
():
SchemaObject
{
return
{
style
:
{
enum
:
[
"
empty
"
,
"
omit
"
],
type
:
"
string
"
,
},
};
}
public
documentation
():
RuleDocumentation
{
return
{
description
:
"
Require a specific style for attributes with empty values.
"
,
...
...
@@ -83,6 +92,7 @@ function parseStyle(style: string): checkFunction {
return
(
attr
:
Attribute
)
=>
attr
.
value
!==
null
;
case
"
empty
"
:
return
(
attr
:
Attribute
)
=>
attr
.
value
!==
""
;
/* istanbul ignore next: covered by schema validation */
default
:
throw
new
Error
(
`Invalid style "
${
style
}
" for "attribute-empty-style" rule`
);
}
...
...
src/rules/class-pattern.ts
View file @
f88f0da0
import
{
DOMTokenList
}
from
"
../dom
"
;
import
{
AttributeEvent
}
from
"
../event
"
;
import
{
describePattern
,
parsePattern
,
PatternName
}
from
"
../pattern
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
RuleOptions
{
pattern
:
PatternName
;
...
...
@@ -19,6 +19,14 @@ export default class ClassPattern extends Rule<void, RuleOptions> {
this
.
pattern
=
parsePattern
(
this
.
options
.
pattern
);
}
public
static
schema
():
SchemaObject
{
return
{
pattern
:
{
type
:
"
string
"
,
},
};
}
public
documentation
():
RuleDocumentation
{
const
pattern
=
describePattern
(
this
.
options
.
pattern
);
return
{
...
...
src/rules/doctype-style.ts
View file @
f88f0da0
import
{
DoctypeEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
RuleContext
{
style
:
"
uppercase
"
|
"
lowercase
"
;
...
...
@@ -18,6 +18,15 @@ export default class DoctypeStyle extends Rule<RuleContext, RuleOptions> {
super
({
...
defaults
,
...
options
});
}
public
static
schema
():
SchemaObject
{
return
{
style
:
{
enum
:
[
"
lowercase
"
,
"
uppercase
"
],
type
:
"
string
"
,
},
};
}
public
documentation
(
context
?:
RuleContext
):
RuleDocumentation
{
const
doc
:
RuleDocumentation
=
{
description
:
`While DOCTYPE is case-insensitive in the standard the current configuration requires a specific style.`
,
...
...
src/rules/element-case.spec.ts
View file @
f88f0da0
...
...
@@ -143,11 +143,12 @@ describe("rule element-case", () => {
it
(
"
should throw error if configured with invalid value
"
,
()
=>
{
expect
.
assertions
(
1
);
htmlvalidate
=
new
HtmlValidate
({
rules
:
{
"
element-case
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
expect
(()
=>
htmlvalidate
.
validateString
(
"
<foo></foo>
"
)).
toThrow
(
`Invalid style "foobar" for element-case rule`
expect
(()
=>
{
return
new
HtmlValidate
({
rules
:
{
"
element-case
"
:
[
"
error
"
,
{
style
:
"
foobar
"
}]
},
});
}).
toThrowErrorMatchingInlineSnapshot
(
`"Rule configuration error: /rules/element-case/1/style should be equal to one of the allowed values: lowercase, uppercase, pascalcase, camelcase"`
);
});
...
...
src/rules/element-case.ts
View file @
f88f0da0
import
{
Location
,
sliceLocation
}
from
"
../context
"
;
import
{
HtmlElement
}
from
"
../dom
"
;
import
{
TagEndEvent
,
TagStartEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
import
{
CaseStyle
,
CaseStyleName
}
from
"
./helper/case-style
"
;
interface
RuleOptions
{
style
:
CaseStyleName
;
style
:
CaseStyleName
|
CaseStyleName
[]
;
}
const
defaults
:
RuleOptions
=
{
...
...
@@ -20,6 +20,27 @@ export default class ElementCase extends Rule<void, RuleOptions> {
this
.
style
=
new
CaseStyle
(
this
.
options
.
style
,
"
element-case
"
);
}
public
static
schema
():
SchemaObject
{
const
styleEnum
=
[
"
lowercase
"
,
"
uppercase
"
,
"
pascalcase
"
,
"
camelcase
"
];
return
{
style
:
{
anyOf
:
[
{
enum
:
styleEnum
,
type
:
"
string
"
,
},
{
items
:
{
enum
:
styleEnum
,
type
:
"
string
"
,
},
type
:
"
array
"
,
},
],
},
};
}
public
documentation
():
RuleDocumentation
{
return
{
description
:
`Element tagname must be
${
this
.
options
.
style
}
.`
,
...
...
src/rules/element-name.ts
View file @
f88f0da0
import
{
sliceLocation
}
from
"
../context
"
;
import
{
TagStartEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
Context
{
tagName
:
string
;
...
...
@@ -30,6 +30,26 @@ export default class ElementName extends Rule<Context, RuleOptions> {
this
.
pattern
=
new
RegExp
(
this
.
options
.
pattern
);
}
public
static
schema
():
SchemaObject
{
return
{
blacklist
:
{
items
:
{
type
:
"
string
"
,
},
type
:
"
array
"
,
},
pattern
:
{
type
:
"
string
"
,
},
whitelist
:
{
items
:
{
type
:
"
string
"
,
},
type
:
"
array
"
,
},
};
}
public
documentation
(
context
:
Context
):
RuleDocumentation
{
return
{
description
:
this
.
documentationMessages
(
context
).
join
(
"
\n
"
),
...
...
src/rules/heading-level.ts
View file @
f88f0da0
...
...
@@ -2,9 +2,9 @@ import { sliceLocation } from "../context";
import
{
HtmlElement
,
Pattern
}
from
"
../dom
"
;
import
{
DOMInternalID
}
from
"
../dom/domnode
"
;
import
{
TagCloseEvent
,
TagReadyEvent
,
TagStartEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
Options
{
interface
Rule
Options
{
allowMultipleH1
:
boolean
;
sectioningRoots
:
string
[];
}
...
...
@@ -15,7 +15,7 @@ interface SectioningRoot {
h1Count
:
number
;
}
const
defaults
:
Options
=
{
const
defaults
:
Rule
Options
=
{
allowMultipleH1
:
false
,
sectioningRoots
:
[
"
dialog
"
,
'
[role="dialog"]
'
],
};
...
...
@@ -34,11 +34,11 @@ function extractLevel(node: HtmlElement): number | null {
}
}
export
default
class
HeadingLevel
extends
Rule
<
void
,
Options
>
{
export
default
class
HeadingLevel
extends
Rule
<
void
,
Rule
Options
>
{
private
sectionRoots
:
Pattern
[];
private
stack
:
SectioningRoot
[]
=
[];
public
constructor
(
options
:
Partial
<
Options
>
)
{
public
constructor
(
options
:
Partial
<
Rule
Options
>
)
{
super
({
...
defaults
,
...
options
});
this
.
sectionRoots
=
this
.
options
.
sectioningRoots
.
map
((
it
)
=>
new
Pattern
(
it
));
...
...
@@ -50,6 +50,20 @@ export default class HeadingLevel extends Rule<void, Options> {
});
}
public
static
schema
():
SchemaObject
{
return
{
allowMultipleH1
:
{
type
:
"
boolean
"
,
},
sectioningRoots
:
{
items
:
{
type
:
"
string
"
,
},
type
:
"
array
"
,
},
};
}
public
documentation
():
RuleDocumentation
{
const
text
:
string
[]
=
[];
text
.
push
(
"
Headings must start at <h1> and can only increase one level at a time.
"
);
...
...
src/rules/id-pattern.ts
View file @
f88f0da0
import
{
DynamicValue
}
from
"
../dom
"
;
import
{
AttributeEvent
}
from
"
../event
"
;
import
{
describePattern
,
parsePattern
,
PatternName
}
from
"
../pattern
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
RuleOptions
{
pattern
:
PatternName
;
...
...
@@ -19,6 +19,14 @@ export default class IdPattern extends Rule<void, RuleOptions> {
this
.
pattern
=
parsePattern
(
this
.
options
.
pattern
);
}
public
static
schema
():
SchemaObject
{
return
{
pattern
:
{
type
:
"
string
"
,
},
};
}
public
documentation
():
RuleDocumentation
{
const
pattern
=
describePattern
(
this
.
options
.
pattern
);
return
{
...
...
src/rules/long-title.ts
View file @
f88f0da0
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
RuleOptions
{
maxlength
:
number
;
...
...
@@ -16,6 +16,14 @@ export default class LongTitle extends Rule<void, RuleOptions> {
this
.
maxlength
=
this
.
options
.
maxlength
;
}
public
static
schema
():
SchemaObject
{
return
{
maxlength
:
{
type
:
"
number
"
,
},
};
}
public
documentation
():
RuleDocumentation
{
return
{
description
:
`Search engines truncates titles with long text, possibly down-ranking the page in the process.`
,
...
...
src/rules/no-autoplay.ts
View file @
f88f0da0
import
{
DynamicValue
}
from
"
../dom
"
;
import
{
AttributeEvent
}
from
"
../event
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
}
from
"
../rule
"
;
import
{
Rule
,
RuleDocumentation
,
ruleDocumentationUrl
,
SchemaObject
}
from
"
../rule
"
;
interface
RuleContext
{
tagName
:
string
;
...
...
@@ -32,6 +32,37 @@ export default class NoAutoplay extends Rule<RuleContext, RuleOptions> {
};
}
public
static
schema
():
SchemaObject
{
return
{
exclude
:
{
anyOf
:
[
{
items
:
{