Skip to content

Commit

Permalink
feat(rules): add empty-tag-not-self-closed rule (#696)
Browse files Browse the repository at this point in the history
Fixes #311.
  • Loading branch information
zcorpan committed Oct 29, 2021
1 parent 28069e5 commit ec171ac
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 2 deletions.
26 changes: 26 additions & 0 deletions src/core/rules/empty-tag-not-self-closed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Rule } from '../types'

export default {
id: 'empty-tag-not-self-closed',
description: 'Empty tags must not use self closed syntax.',
init(parser, reporter) {
const mapEmptyTags = parser.makeMap(
'area,base,basefont,bgsound,br,col,frame,hr,img,input,isindex,link,meta,param,embed,track,command,source,keygen,wbr'
) //HTML 4.01 + HTML 5

parser.addListener('tagstart', (event) => {
const tagName = event.tagName.toLowerCase()
if (mapEmptyTags[tagName] !== undefined) {
if (event.close) {
reporter.error(
`The empty tag : [ ${tagName} ] must not use self closed syntax.`,
event.line,
event.col,
this,
event.raw
)
}
}
})
},
} as Rule
1 change: 1 addition & 0 deletions src/core/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export { default as srcNotEmpty } from './src-not-empty'
export { default as styleDisabled } from './style-disabled'
export { default as tagPair } from './tag-pair'
export { default as tagSelfClose } from './tag-self-close'
export { default as emptyTagNotSelfClosed } from './empty-tag-not-self-closed'
export { default as tagnameLowercase } from './tagname-lowercase'
export { default as tagnameSpecialChars } from './tagname-specialchars'
export { default as titleRequire } from './title-require'
Expand Down
2 changes: 1 addition & 1 deletion src/core/rules/tag-self-close.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default {
description: 'Empty tags must be self closed.',
init(parser, reporter) {
const mapEmptyTags = parser.makeMap(
'area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,track,command,source,keygen,wbr'
'area,base,basefont,bgsound,br,col,frame,hr,img,input,isindex,link,meta,param,embed,track,command,source,keygen,wbr'
) //HTML 4.01 + HTML 5

parser.addListener('tagstart', (event) => {
Expand Down
1 change: 1 addition & 0 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface Ruleset {
'attr-whitespace'?: boolean
'doctype-first'?: boolean
'doctype-html5'?: boolean
'empty-tag-not-self-closed'?: boolean
'head-script-disabled'?: boolean
'href-abs-or-rel'?: 'abs' | 'rel'
'id-class-ad-disabled'?: boolean
Expand Down
30 changes: 30 additions & 0 deletions test/rules/empty-tag-not-self-closed.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const expect = require('expect.js')

const HTMLHint = require('../../dist/htmlhint.js').HTMLHint

const ruldId = 'empty-tag-not-self-closed'
const ruleOptions = {}

ruleOptions[ruldId] = true

describe(`Rules: ${ruldId}`, () => {
it('The empty tag no closed should not result in an error', () => {
const code = '<br><img src="test.jpg">'
const messages = HTMLHint.verify(code, ruleOptions)
expect(messages.length).to.be(0)
})

it('Closed empty tag should result in an error', () => {
const code = '<br /><img src="a.jpg"/>'
const messages = HTMLHint.verify(code, ruleOptions)
expect(messages.length).to.be(2)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
expect(messages[0].col).to.be(1)
expect(messages[0].type).to.be('error')
expect(messages[1].rule.id).to.be(ruldId)
expect(messages[1].line).to.be(1)
expect(messages[1].col).to.be(7)
expect(messages[1].type).to.be('error')
})
})
1 change: 0 additions & 1 deletion test/rules/tag-self-close.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ describe(`Rules: ${ruldId}`, () => {
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
expect(messages[0].col).to.be(1)
console.log('lll', messages[0].type)
expect(messages[0].type).to.be('warning')
expect(messages[1].rule.id).to.be(ruldId)
expect(messages[1].line).to.be(1)
Expand Down

0 comments on commit ec171ac

Please sign in to comment.