html-tag-validator
This library takes some HTML source code, provided as a string, and generates an
AST. An error will be generated describing what is malformed in the source document
if the AST cannot be generated.
Note: this project is work-in-progress and is not fully spec-compliant.
See todo.md
for plans for current and future releases.
The parser implements the basic components of the HTML 5 spec, such as:
-
doctype
definition
-
HTML 5 elements
-
HTML 5 attributes
-
Enhanced validation for script
, style
, link
and meta
elements
-
Basic support for iframe
elements
-
HTML comments
-
Conditional comments
-
Allowed <input>
element type
values and the attributes supported by each type
-
Hierarchal rules, such as: a properly-formed HTML 5 document should have a title
element with contents within the head
tag
-
Void elements
<img src="cat.gif">
<script async></script>
-
Normal attributes
<p class="foo"></p>
Install
npm install html-tag-validator
Usage
The library exposes a single function that accepts two arguments: a string
containing HTML, and a callback function. The callback should be in the form:
function (err, ast) {
if (err) {
console.log(err.message);
} else {
console.log(ast);
}
}
Default syntax
var htmlTagValidator = require('html-tag-validator'),
sampleHtml = "<html>" +
"<head><title>hello world</title></head>" +
"<body><p style='color: pink;'>my cool page</p></body>" +
"</html>";
htmlTagValidator(sampleHtml, function (err, ast) {
if (err) {
throw err;
} else {
console.log(ast);
}
});
Produces the following AST:
doctype: null
document:
-
type: element
void: false
name: html
attributes: {}
children:
-
type: element
void: false
name: head
attributes: {}
children:
-
type: title
attributes: {}
contents: hello world
-
type: element
void: false
name: body
attributes: {}
children:
-
type: element
void: false
name: p
attributes:
style: color: pink;
children:
-
type: text
contents: my cool page
Passing in options
Currently, you can provide custom attribute names to merge with the default
values, custom validation rules, and global settings such as the output format
for the validation messages.
var htmlTagValidator = require('html-tag-validator'),
sampleHtml = "<html>" +
"<head><title>hello world</title></head>" +
"<body>" +
"<p *ngFor=\"let item of items\" (click)=\"func(item)\">" +
"my cool page" +
"</p>" +
"</body>" +
"</html>";
htmlTagValidator(sampleHtml, {
settings: {
format: 'plain',
verbose: false,
preserveCase: true
},
tags: {
normal: [ 'template' ]
},
attributes: {
'_': {
mixed: /^((\*ng)|(^\[[\S]+\]$)|(^\([\S]+\)$))|(^\[\([\S]+\)\]$)/
}
}
}, function (err, ast) {
if (err) {
throw err;
} else {
console.log(ast);
}
});
var htmlTagValidator = require('html-tag-validator'),
sampleHtml = "<html>" +
"<head><title>hello world</title></head>" +
"<body><p (click)='myCoolFunc()'>my cool page</p></body>" +
"</html>";
htmlTagValidator(sampleHtml, {
'settings': {
'format': 'plain'
},
'attributes': {
'table': {
'normal': [
'align', 'bgcolor', 'border', 'cellpadding', 'cellspacing',
'frame', 'rules', 'summary', 'width'
]
},
'td': {
'normal': [
'height', 'width', 'bgcolor'
]
}
}
}, function (err, ast) {
if (err) {
throw err;
} else {
console.log(ast);
}
});
Contributing
Once the dependencies are installed, start development with the following command:
grunt test
- Automatically compile the parser and run the tests in test/index-spec.js
.
grunt debug
- Run tests with --inspect flag and extended output
grunt watch debug
- Get extended output and start a file watcher.
Publishing to npm
Publishing master as normal works for pure html implementations, but sometimes
a variation is needed, for example a PHP flavor that supports inline PHP tags.
Any variations should be on their own branch and named appropriately. These should
be published separately as well, this can be done using npm tags. First change
the version number in the package.json to include the language prefix, so for PHP
that would be something like: 1.5.0-php
then when publishing to npm do:
npm publish --tag php
. Doing this will allow you to reference this variation in
your package.json like: "html-tag-validator": "1.5.0-php"
Note on validator variations
Anything that pertains to vanilla HTML should be implemented on master and merged
into variation branches.
Writing tests
Tests refer to an HTML test file in test/html/
and the test name is a
reference to the filename of the test file. For example super test 2
as a test name points to the file test/html/superTest2.html
.
There are three options for the test helpers exposed by tree
:
tree.ok(this, done)
to assert that the test file successfully generates an ASTtree.equals(ast, this, done)
to assert that the test file generates an AST that exactly matches ast
tree.error()
to assert that a test throws an error
tree.error("This is the error message", this, done)
assert an error message
tree.error({'line': 2}, this, done)
assert an object of properties that each exist in the error
You can pass in an options
object as the 2nd-to-last argument in each method:
var options = {
'settings': {
'format': 'html'
}
};
tree.ok(this, options, done);
it('basic self closing', function(done) {
tree.ok(this, done);
});
it('basic list items', function(done) {
tree.error({
'message': 'li is not a valid self closing tag',
'line': 5
}, this, done);
});