├── test
├── html
│ ├── invalid
│ │ ├── improperly_closed_tag.tmpl.html
│ │ ├── missing_closing_tag.tmpl.html
│ │ ├── improperly_nested_tags.tmpl.html
│ │ └── template_missing_extension.html
│ └── valid
│ │ ├── template
│ │ ├── valid_angular_table_row.tmpl.html
│ │ ├── valid_angular.tmpl.html
│ │ └── valid_regular.tmpl.html
│ │ └── full
│ │ ├── valid_regular.html
│ │ ├── valid_angular.html
│ │ └── valid_angular_directives.html
└── htmlangular_test.js
├── .gitignore
├── .travis.yml
├── .jshintrc
├── package.json
├── LICENSE-MIT
├── tasks
└── htmlangular.js
├── Gruntfile.js
└── README.md
/test/html/invalid/improperly_closed_tag.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Some content.
4 |
--------------------------------------------------------------------------------
/test/html/invalid/improperly_nested_tags.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Very noticeable
4 |
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | tmp
4 | html-angular-validate-report.json
5 | html-angular-validate-report-checkstyle.xml
6 |
--------------------------------------------------------------------------------
/test/html/valid/template/valid_angular_table_row.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 | | {name} |
3 | {birthdate} |
4 | {address} |
5 |
--------------------------------------------------------------------------------
/test/html/valid/full/valid_regular.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Test HTML - Valid
5 |
6 |
7 |
Hi Nik!
8 |
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | node_js:
4 | - "9"
5 | - "8"
6 | - "7"
7 | - "6"
8 | - "5"
9 |
10 | branches:
11 | only:
12 | - master
13 |
14 | before_script:
15 | - npm install -g grunt-cli
16 | - grunt jshint
17 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "curly": true,
3 | "eqeqeq": true,
4 | "immed": true,
5 | "indent": 4,
6 | "latedef": true,
7 | "newcap": true,
8 | "noarg": true,
9 | "plusplus": true,
10 | "sub": true,
11 | "undef": true,
12 | "boss": true,
13 | "eqnull": true,
14 | "node": true
15 | }
16 |
--------------------------------------------------------------------------------
/test/html/valid/template/valid_angular.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
{{fragLabel}}
3 |
8 |
--------------------------------------------------------------------------------
/test/html/invalid/template_missing_extension.html:
--------------------------------------------------------------------------------
1 |
2 |
Nothing Special Div Fragment
3 |
4 |
5 | - Item One
6 | - Item Two
7 | - Item Three
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/html/valid/template/valid_regular.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
Nothing Special Div Fragment
3 |
4 |
5 | - Item One
6 | - Item Two
7 | - Item Three
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/html/valid/full/valid_angular.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Test HTML - Valid
5 |
6 |
7 |
{{paraBody}}
8 |
9 | Some sort of directive content would go here, I presume.
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/html/valid/full/valid_angular_directives.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Test HTML - Valid
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "grunt-html-angular-validate",
3 | "description": "An HTML validator aimed at AngularJS projects.",
4 | "version": "0.6.1",
5 | "homepage": "https://github.com/nikestep/grunt-html-angular-validate",
6 | "author": {
7 | "name": "Nik Estep",
8 | "email": "nik.estep@gmail.com",
9 | "url": "http://nikestep.me"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git://github.com/nikestep/grunt-html-angular-validate.git"
14 | },
15 | "bugs": {
16 | "url": "https://github.com/nikestep/grunt-html-angular-validate/issues"
17 | },
18 | "license": "MIT",
19 | "engines": {
20 | "node": ">= 5.0.0"
21 | },
22 | "scripts": {
23 | "test": "grunt test"
24 | },
25 | "devDependencies": {
26 | "ansi-styles": "^3.2.0",
27 | "grunt": "~1.0.1",
28 | "grunt-contrib-clean": "~1.1.0",
29 | "grunt-contrib-jshint": "~1.1.0",
30 | "grunt-contrib-nodeunit": "~1.0.0"
31 | },
32 | "dependencies": {
33 | "colors": "~1.1.2",
34 | "html-angular-validate": "~0.2.3"
35 | },
36 | "keywords": [
37 | "gruntplugin"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Nik Estep
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/tasks/htmlangular.js:
--------------------------------------------------------------------------------
1 | /*
2 | * grunt-html-angular-validate
3 | * https://github.com/nikestep/grunt-html-angular-validate
4 | *
5 | * Copyright (c) 2014 Nik Estep
6 | * Licensed under the MIT license.
7 | */
8 |
9 | 'use strict';
10 |
11 | var colors = require('colors');
12 | var validate = require('html-angular-validate');
13 |
14 | var writeFileErrors = function(grunt, file) {
15 | // Start writing this file
16 | grunt.log.writeln('Validating ' +
17 | file.filepath +
18 | ' ...' +
19 | 'ERROR'.red);
20 |
21 | if (file.errors[0].msg === 'Unable to validate file') {
22 | grunt.log.writeln('Validating ' +
23 | file.filepath +
24 | ' ...' +
25 | 'ERROR'.red);
26 | grunt.log.writeln('Unable to validate file'.yellow);
27 | return;
28 | }
29 |
30 | // Write each error
31 | for (var i = 0; i < file.errors.length; i += 1) {
32 | var err = file.errors[i];
33 | if (err.line !== undefined) {
34 | grunt.log.writeln('['.red +
35 | 'L'.yellow +
36 | ('' + err.line).yellow +
37 | ':'.red +
38 | 'C'.yellow +
39 | ('' + err.col).yellow +
40 | ']'.red +
41 | ' ' +
42 | err.msg.yellow);
43 | } else {
44 | grunt.log.writeln('['.red +
45 | 'file'.yellow +
46 | ']'.red +
47 | ' ' +
48 | err.msg.yellow);
49 | }
50 | }
51 | };
52 |
53 | module.exports = function(grunt) {
54 | grunt.registerMultiTask('htmlangular', 'An HTML5 validator aimed at AngularJS projects.', function() {
55 | // Merge task-specific and/or target-specific options with these defaults.
56 | var options = this.options({
57 | angular: true,
58 | customtags: [],
59 | customattrs: [],
60 | wrapping: {},
61 | relaxerror: [],
62 | tmplext: 'tmpl.html',
63 | doctype: 'HTML5',
64 | charset: 'utf-8',
65 | reportpath: 'html-angular-validate-report.json',
66 | reportCheckstylePath: 'html-angular-validate-report-checkstyle.xml',
67 | w3clocal: null,
68 | w3cproxy: null,
69 | concurrentJobs: 1,
70 | maxvalidateattempts: 3
71 | });
72 | options.concurrentjobs = options.concurrentJobs;
73 |
74 | // Delete existing reports if present
75 | if (options.reportpath !== null && grunt.file.exists(options.reportpath)) {
76 | grunt.file.delete(options.reportpath);
77 | }
78 | if (options.reportCheckstylePath !== null && grunt.file.exists(options.reportCheckstylePath)) {
79 | grunt.file.delete(options.reportCheckstylePath);
80 | }
81 |
82 | // Force task into async mode and grab a handle to the "done" function.
83 | var done = this.async();
84 |
85 | // Run the validation plug in
86 | validate.validate(this.filesSrc, options).then(function(result) {
87 | // Finished, let user and grunt know how it went
88 | if (result.allpassed) {
89 | // No errors to output - task success
90 | grunt.log.oklns(result.filessucceeded + ' files passed validation');
91 | done();
92 | } else {
93 | // Output failures - task failure
94 | for (var i = 0; i < result.failed.length; i += 1) {
95 | writeFileErrors(grunt, result.failed[i]);
96 | }
97 |
98 | // Finalize output and send control back to grunt
99 | grunt.fail.warn('HTML validation failed');
100 | done(false);
101 | }
102 | }, function(err) {
103 | // Validator failure - task failure
104 | grunt.log.errorlns('Unable to perform validation');
105 | grunt.log.errorlns('html-angular-validate error: ' + err);
106 | done(false);
107 | });
108 | });
109 | };
110 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*
2 | * grunt-html-angular-validate
3 | * https://github.com/nikestep/grunt-html-angular-validate
4 | *
5 | * Copyright (c) 2014 Nik Estep
6 | * Licensed under the MIT license.
7 | */
8 |
9 | 'use strict';
10 |
11 | module.exports = function(grunt) {
12 |
13 | // Project configuration.
14 | grunt.initConfig({
15 | jshint: {
16 | all: [
17 | 'Gruntfile.js',
18 | 'tasks/*.js',
19 | '<%= nodeunit.all %>',
20 | ],
21 | options: {
22 | jshintrc: '.jshintrc',
23 | },
24 | },
25 |
26 | // Before generating any new files, remove any previously-created files.
27 | clean: {
28 | tests: ['tmp'],
29 | },
30 |
31 | // Configurations to be run (and then tested).
32 | htmlangular: {
33 | default_options: {
34 | options: {
35 | customtags: ['custom-tag', 'custom-*'],
36 | customattrs: ['fixed-div-label', 'custom-*'],
37 | wrapping: {
38 | 'tr': '
'
39 | }
40 | },
41 | files: {
42 | src: ['test/html/valid/**/*.html']
43 | }
44 | },
45 | default_options_concurrent: {
46 | options: {
47 | customtags: ['custom-tag', 'custom-*'],
48 | customattrs: ['fixed-div-label', 'custom-*'],
49 | wrapping: {
50 | 'tr': '
'
51 | },
52 | concurrentJobs: 4
53 | },
54 | files: {
55 | src: ['test/html/valid/**/*.html']
56 | }
57 | },
58 | missing_wrapping: {
59 | options: {
60 | },
61 | files: {
62 | src: ['test/html/valid/template/valid_angular_table_row.tmpl.html']
63 | }
64 | },
65 | missing_custom_tags: {
66 | options: {
67 | },
68 | files: {
69 | src: ['test/html/valid/full/valid_angular.html']
70 | }
71 | },
72 | missing_custom_attrs: {
73 | options: {
74 | },
75 | files: {
76 | src: ['test/html/valid/template/valid_angular.tmpl.html']
77 | }
78 | },
79 | template_missing_extension: {
80 | options: {
81 | },
82 | files: {
83 | src: ['test/html/invalid/template_missing_extension.html']
84 | }
85 | },
86 | missing_closing_tag: {
87 | options: {
88 | },
89 | files: {
90 | src: ['test/html/invalid/missing_closing_tag.tmpl.html']
91 | }
92 | },
93 | improperly_closed_tag: {
94 | options: {
95 | },
96 | files: {
97 | src: ['test/html/invalid/improperly_closed_tag.tmpl.html']
98 | }
99 | },
100 | improperly_nested_tags: {
101 | options: {
102 | },
103 | files: {
104 | src: ['test/html/invalid/improperly_nested_tags.tmpl.html']
105 | }
106 | },
107 | improper_angular_operator_relaxed: {
108 | options: {
109 | relaxerror: [
110 | '“&” did not start a character reference. (“&” probably should have been escaped as “&”.)'
111 | ],
112 | },
113 | files: {
114 | src: ['test/html/invalid/improper_angular_operator.tmpl.html']
115 | }
116 | }
117 | },
118 |
119 | // Unit tests.
120 | nodeunit: {
121 | all: ['test/*_test.js'],
122 | },
123 |
124 | });
125 |
126 | // Actually load this plugin's task(s).
127 | grunt.loadTasks('tasks');
128 |
129 | // These plugins provide necessary tasks.
130 | grunt.loadNpmTasks('grunt-contrib-jshint');
131 | grunt.loadNpmTasks('grunt-contrib-clean');
132 | grunt.loadNpmTasks('grunt-contrib-nodeunit');
133 |
134 | // Whenever the "test" task is run, first clean the "tmp" dir, then run this
135 | // plugin's task(s), then test the result.
136 | grunt.registerTask('test', ['clean', 'nodeunit:all']);
137 |
138 | // By default, lint and run all tests.
139 | grunt.registerTask('default', ['clean', 'jshint', 'test']);
140 |
141 | };
142 |
--------------------------------------------------------------------------------
/test/htmlangular_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | ======== A Handy Little Nodeunit Reference ========
5 | https://github.com/caolan/nodeunit
6 |
7 | Test methods:
8 | test.expect(numAssertions)
9 | test.done()
10 | Test assertions:
11 | test.ok(value, [message])
12 | test.equal(actual, expected, [message])
13 | test.notEqual(actual, expected, [message])
14 | test.deepEqual(actual, expected, [message])
15 | test.notDeepEqual(actual, expected, [message])
16 | test.strictEqual(actual, expected, [message])
17 | test.notStrictEqual(actual, expected, [message])
18 | test.throws(block, [error], [message])
19 | test.doesNotThrow(block, [error], [message])
20 | test.ifError(value)
21 | */
22 |
23 | var
24 | path = require('path'),
25 | exec = require('child_process').exec,
26 | execOptions = {
27 | cwd: path.join(__dirname, '..')
28 | }
29 | ;
30 |
31 | exports.tests = {
32 | default_options: function(test) {
33 | test.expect(1);
34 | exec('grunt htmlangular:default_options', execOptions, function(error, stdout) {
35 | test.equal(
36 | stdout.indexOf('6 files passed validation') > -1,
37 | true,
38 | 'valid files pass'
39 | );
40 | test.done();
41 | });
42 | },
43 | default_options_concurrent: function(test) {
44 | test.expect(1);
45 | exec('grunt htmlangular:default_options_concurrent', execOptions, function(error, stdout) {
46 | test.equal(
47 | stdout.indexOf('6 files passed validation') > -1,
48 | true,
49 | 'valid files pass'
50 | );
51 | test.done();
52 | });
53 | },
54 | missing_wrapping: function(test) {
55 | test.expect(4);
56 | exec('grunt htmlangular:missing_wrapping', execOptions, function(error, stdout) {
57 | test.equal(
58 | stdout.indexOf('Stray start tag “tr”') > -1,
59 | true,
60 | 'found unwrapped starting
'
61 | );
62 | test.equal(
63 | stdout.indexOf('Stray start tag “td”') > -1,
64 | true,
65 | 'found unwrapped starting | '
66 | );
67 | test.equal(
68 | stdout.indexOf('Stray end tag “td”') > -1,
69 | true,
70 | 'found unwrapped starting | '
71 | );
72 | test.equal(
73 | stdout.indexOf('Stray end tag “tr”') > -1,
74 | true,
75 | 'found unwrapped starting |
'
76 | );
77 | test.done();
78 | });
79 | },
80 | /*missing_custom_tags: function(test) {
81 | test.expect(1);
82 | exec('grunt htmlangular:missing_custom_tags', execOptions, function(error, stdout) {
83 | test.equal(
84 | stdout.indexOf('Element “custom-tag” not allowed as child') > -1,
85 | true,
86 | 'found custom tag'
87 | );
88 | test.done();
89 | });
90 | },*/
91 | missing_custom_attrs: function(test) {
92 | test.expect(1);
93 | exec('grunt htmlangular:missing_custom_attrs', execOptions, function(error, stdout) {
94 | test.equal(
95 | stdout.indexOf('Attribute “fixed-div-label” not allowed on element') > -1,
96 | true,
97 | 'found custom attribute'
98 | );
99 | test.done();
100 | });
101 | },
102 | template_missing_extension: function(test) {
103 | test.expect(1);
104 | exec('grunt htmlangular:template_missing_extension', execOptions, function(error, stdout) {
105 | test.equal(
106 | stdout.indexOf('Element “head” is missing a required instance of child element “title”') > -1,
107 | true,
108 | 'figured out it is just template'
109 | );
110 | test.done();
111 | });
112 | },
113 | missing_closing_tag: function(test) {
114 | test.expect(1);
115 | exec('grunt htmlangular:missing_closing_tag', execOptions, function(error, stdout) {
116 | test.equal(
117 | stdout.indexOf('Unclosed element “div”') > -1,
118 | true,
119 | 'found unclosed div'
120 | );
121 | test.done();
122 | });
123 | },
124 | improperly_closed_tag: function(test) {
125 | test.expect(2);
126 | exec('grunt htmlangular:improperly_closed_tag', execOptions, function(error, stdout) {
127 | test.equal(
128 | stdout.indexOf('Self-closing syntax (“/>”) used on a non-void HTML element') > -1,
129 | true,
130 | 'found self-closed span'
131 | );
132 | test.equal(
133 | stdout.indexOf('Unclosed element “span”') > -1,
134 | true,
135 | 'found unclosed span'
136 | );
137 | test.done();
138 | });
139 | },
140 | improperly_nested_tags: function(test) {
141 | test.expect(2);
142 | exec('grunt htmlangular:improperly_nested_tags', execOptions, function(error, stdout) {
143 | test.equal(
144 | stdout.indexOf('End tag “b” violates nesting rules') > -1,
145 | true,
146 | 'found closed too early'
147 | );
148 | test.equal(
149 | stdout.indexOf('No “i” element in scope but a “i” end tag seen') > -1,
150 | true,
151 | 'found closed too late'
152 | );
153 | test.done();
154 | });
155 | },
156 | improper_angular_operator_relaxed: function(test) {
157 | test.expect(1);
158 | exec('grunt htmlangular:improper_angular_operator_relaxed', execOptions, function(error, stdout) {
159 | test.equal(
160 | stdout.indexOf('“&” did not start a character reference. (“&” probably should have been escaped as “&”.)') === -1,
161 | true,
162 | 'relaxed ignored error'
163 | );
164 | test.done();
165 | });
166 | }
167 | };
168 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # grunt-html-angular-validate
2 | [](https://travis-ci.org/nikestep/grunt-html-angular-validate) [](https://david-dm.org/nikestep/grunt-html-angular-validate) [](https://david-dm.org/nikestep/grunt-html-angular-validate#info=devDependencies)
3 | [](https://github.com/nikestep/grunt-html-angular-validate)
4 |
5 | > An HTML validator aimed at AngularJS projects.
6 |
7 | While there are other Grunt plugins that will validate HTML files, there are lacking a couple important features:
8 |
9 | * Support for AngularJS attributes and tags (both from AngularJS and custom created)
10 | * Support for templated/fragmented HTML files
11 | * Ability to concurrently validate files for greatly increased speed
12 |
13 | This plugin looks to solve these problems and provide the value that comes with having HTML validation in the build chain.
14 |
15 | Please note that this plugin works with the [w3cjs](https://github.com/thomasdavis/w3cjs) node plugin and will send files to be validated
16 | against the W3C online validator tool. W3C asks that you be considerate of their free validator service and they will block your IP if
17 | your traffic is deemed "excessive" by their servers. Such a block will automatically clear once the traffic subsides, but if your
18 | project is large enough, you may need to run your own local W3C validator server. A guide for how to do this can be found
19 | [here](https://github.com/tlvince/w3c-validator-guide). See the options below for pointing this plugin to a local validator service.
20 |
21 | ## v0.5.0 Upgrade Notes
22 | Version 0.4.2 has been published as a stop-gap between versions 0.4.1 and 0.5.0. You may use this version to maintain v0.4.1-style
23 | comptability; however, there is no guarantee that W3C will continue to support the validation path used here.
24 |
25 | If you are upgrading to use v0.5.0, there are a couple of things you should keep in mind. The warning messages have changed slightly
26 | as a result of changes in other packages used by this plugin. You may find that existing excluded messages no longer work and you'll
27 | need to update your gruntfile.
28 |
29 | If you are using a local version of the w3c validator, upgrading may cause an incompatibility. You should investigate this and also
30 | upgrading your local validator before commiting the upgrade to your project.
31 |
32 | ## Getting Started
33 | This plugin requires Grunt `~1.0.1`
34 |
35 | If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started)
36 | guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once
37 | you're familiar with that process, you may install this plugin with this command:
38 |
39 | ```shell
40 | npm install grunt-html-angular-validate --save-dev
41 | ```
42 |
43 | Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
44 |
45 | ```js
46 | grunt.loadNpmTasks('grunt-html-angular-validate');
47 | ```
48 |
49 | ## The "htmlangular" task
50 |
51 | ### Overview
52 | In your project's Gruntfile, add a section named `htmlangular` to the data object passed into `grunt.initConfig()`.
53 |
54 | ```js
55 | grunt.initConfig({
56 | htmlangular: {
57 | options: {
58 | // Task-specific options go here.
59 | },
60 | your_target: {
61 | // Target-specific file lists and/or options go here.
62 | },
63 | },
64 | });
65 | ```
66 |
67 | ### Options
68 |
69 | #### options.angular
70 | Type: `Boolean`
71 | Default value: `true`
72 |
73 | Turns on ignoring of validation errors that are caused by AngularJS.
74 |
75 | #### options.customtags
76 | Type: `Array`
77 | Default value: `[]`
78 |
79 | List all of the custom tags you have created through directives and other means here. The validator will ignore warnings about these tags.
80 |
81 | You can use the `'*'` wildcard, e.g.: `'custom-tags-*'`
82 |
83 | #### options.customattrs
84 | Type: `Array`
85 | Default value: `[]`
86 |
87 | List all of the custom attributes you have created through directives and other means here. The validator will ignore warnings about
88 | these attributes.
89 |
90 | You can use the `*` wildcard, e.g.: `'custom-attrs-*'`
91 |
92 | #### options.wrapping
93 | Type: `Object`
94 | Default value: `{}`
95 |
96 | Not all Angular templates start with tags that can be wrapped directly within the `` tag. For templates like this, they first need
97 | to be wrapped before the regular full-document wrapping that the plugin performs. As an example, a template for a row in a table might
98 | look like this:
99 |
100 |
101 | | {name} |
102 | {birthdate} |
103 | {address} |
104 |
105 |
106 | The entry into the `options.wrapping` plugin option would look like this:
107 |
108 | wrapping: {
109 | 'tr': ''
110 | }
111 |
112 | The content of the template will be placed within the `{0}` and then the whole block will be wrapped like other templates. Note that the
113 | name of the tag should not be wrapped with `<` and `>`.
114 |
115 | #### options.relaxerror
116 | Type: `Array`
117 | Default value: `[]`
118 |
119 | List the error strings you want explicitly ignored by the validator.
120 |
121 | #### options.tmplext
122 | Type: `String`
123 | Default value: `tmpl.html`
124 |
125 | The extension of HTML files that are templated or otherwise not complete and valid HTML files (i.e. do not start and end with ``). The validator will wrap these files as complete HTML pages for validation.
126 |
127 | #### options.doctype
128 | Type: `String`
129 | Default value: `HTML5`
130 |
131 | The doctype to use when validating HTML files. Set to `false` to have the validator auto-detect the doctype.
132 |
133 | #### options.charset
134 | Type: `String`
135 | Default value: `utf-8`
136 |
137 | The charset to use when validating HTML files. Set to `false` to have the validator auto-detect the charset.
138 |
139 | #### options.reportpath
140 | Type: `String`
141 | Default value: `html-angular-validate-report.json`
142 |
143 | The path to write a JSON report of validation and linting output to after completion. Set to `null` to not create this file.
144 |
145 | ### reportCheckstylePath
146 | Type: `String`
147 | Default value: `html-angular-validate-report-checkstyle.xml`
148 |
149 | The path to write a checkstyle compatible xml report of validation and linting output to after completion. Set to `null` to not create this file.
150 |
151 | #### options.w3clocal
152 | Type: `String`
153 | Default value: `null`
154 |
155 | Use this when running a local instance of the W3C validator service (e.g. `http://localhost:8080`). Do not use in conjunction with
156 | `options.w3cproxy`.
157 |
158 | #### options.w3cproxy
159 | Type: `String`
160 | Default value: `null`
161 |
162 | The proxy to the W3C validator service. Use this as an alternative when running a local instance of the W3C validator service
163 | (e.g. `http://localhost:8080`). Do not use in conjunction with `options.w3clocal`.
164 |
165 | #### options.concurrentJobs
166 | Type: `Integer`
167 | Default value: `1`
168 |
169 | The maximum number of validation jobs to run concurrently. Using a number greater than `1` can greatly increase validation speed
170 | with many files, especially when running a local validation server.
171 |
172 | This should only be used when you have your own validation server. W3C will shut you down much faster if you run concurrent
173 | requests against them.
174 |
175 | #### maxvalidateattempts
176 | Type: `Integer`
177 | Default value: `3`
178 |
179 | The maxinum number of attempts to validate a single file. Retries will be triggered if an error occurs during file validation and no
180 | result is retrieved. This is not the same as validation completing and the result having errors. Instead the aim is to guard against
181 | a flaky validator server.
182 |
183 | ### Usage Examples
184 |
185 | #### Default Options
186 | In this example, the default options are used to do something with whatever. So if the `testing` file has the content `Testing` and the `123` file had the content `1 2 3`, the generated result would be `Testing, 1 2 3.`
187 |
188 | ```js
189 | grunt.initConfig({
190 | htmlangular: {
191 | options: {
192 | tmplext: 'html.tmpl',
193 | customtags: [
194 | 'top-nav',
195 | 'left-bar',
196 | 'right-bar',
197 | 'client-footer'
198 | ],
199 | customattrs: [
200 | 'fixed-width-box',
201 | 'video-box'
202 | ],
203 | relaxerror: [
204 | 'The frameborder attribute on the iframe element is obsolete. Use CSS instead.'
205 | ],
206 | reportpath: 'target/html-angular-validate-report.json'
207 | },
208 | files: {
209 | src: ['src/www/**/*.html', 'src/www/**/*.html.tmpl']
210 | }
211 | }
212 | });
213 | ```
214 |
215 | ## Contributing
216 | In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
217 |
218 | Before submitting a pull request, please run the tests to make sure you did not break any existing functionality:
219 |
220 | ```shell
221 | grunt test
222 | ```
223 |
224 | ## Release History
225 | * 2018-02-03 v0.6.1 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate)
226 | * 2018-01-09 v0.6.0 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate) and updating Node versions
227 | * 2017-08-06 v0.5.9 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate)
228 | * 2016-05-14 v0.5.8 Fixed #35
229 | * 2015-11-09 v0.5.7 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate)
230 | * 2015-11-09 v0.5.6 Accidental unchanged version
231 | * 2015-11-09 v0.5.5 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate)
232 | * 2015-10-31 v0.5.4 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate)
233 | * 2015-09-24 v0.5.3 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate)
234 | * 2015-08-28 v0.5.2 Updating version of [html-angular-validate](https://www.npmjs.com/package/html-angular-validate)
235 | * 2015-08-09 v0.5.1 Switched to using [html-angular-validate](https://www.npmjs.com/package/html-angular-validate) npm package
236 | * 2015-06-16 v0.4.2 Patched v0.4.1 to continue working in liu of upgrading v0.5.0 (code not in repository - see #23)
237 | * 2015-06-15 v0.5.0 Fixed #22 (using new w3c validator)
238 | * 2015-03-26 v0.4.1 Fixed #17
239 | * 2014-08-08 v0.4.0 Pulled in #9 (concurrency introduced)
240 | * 2014-08-04 v0.3.5 Pulled in #7 and #8, dropped support for NodeJS 0.8
241 | * 2014-04-26 v0.3.0 Fixed #4, Fixed #5, created unit tests
242 | * 2014-02-04 v0.2.3 Fixed #2, fixed silly push mistake, add ui-* to default angular tags/attrs
243 | * 2014-02-04 v0.2.2 Fixed #1 and added W3C proxy option
244 | * 2014-01-27 v0.2.1 Renamed project
245 | * 2014-01-12 v0.2.0 Increased recognition of AngularJS caused validation erros
246 | * 2014-01-11 v0.1.0 Initial release
247 |
--------------------------------------------------------------------------------