diff --git a/lib/gui/pages/finish/templates/success.tpl.html b/lib/gui/pages/finish/templates/success.tpl.html index 6777220d..cbeab4e2 100644 --- a/lib/gui/pages/finish/templates/success.tpl.html +++ b/lib/gui/pages/finish/templates/success.tpl.html @@ -1,7 +1,7 @@
-

Flash Complete!

+

Flash Complete!

Safely ejected and ready for use

diff --git a/package.json b/package.json index 1e098182..fce26f51 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,9 @@ "sass": "node-sass ./lib/gui/scss/main.scss > ./lib/gui/css/main.css", "jslint": "eslint lib tests scripts bin versionist.conf.js", "scsslint": "scss-lint lib/gui/scss", + "htmllint": "node scripts/html-lint.js", "codespell": "codespell.py lib tests", - "lint": "npm run jslint && npm run scsslint && npm run codespell", + "lint": "npm run jslint && npm run scsslint && npm run codespell && npm run htmllint", "changelog": "versionist", "start": "electron lib/start.js", "clean-shrinkwrap": "node ./scripts/clean-shrinkwrap.js" @@ -112,6 +113,7 @@ "electron-prebuilt": "1.4.4", "eslint": "^2.13.1", "file-exists": "^1.0.0", + "html-angular-validate": "^0.1.9", "jsonfile": "^2.3.1", "mochainon": "^1.0.0", "node-sass": "^3.8.0", diff --git a/scripts/html-lint.js b/scripts/html-lint.js new file mode 100644 index 00000000..e6ddc06d --- /dev/null +++ b/scripts/html-lint.js @@ -0,0 +1,86 @@ +/** + * This script setups and runs linting modules on our HTML files. + * + * See https://github.com/nikestep/html-angular-validate + * + * Usage: + * + * node scripts/html-lint.js + */ + +'use strict'; + +const chalk = require('chalk'); +const path = require('path'); +const _ = require('lodash'); +const angularValidate = require('html-angular-validate'); +const PROJECT_ROOT = path.join(__dirname, '..'); +const FILENAME = path.relative(PROJECT_ROOT, __filename); + +console.log('Scanning...'); + +angularValidate.validate( + [ + path.join(PROJECT_ROOT, 'lib', 'gui', '**/*.html') + ], + { + customattrs: [ + + // Internal + 'os-open-external', + 'os-dropzone', + 'manifest-bind', + + // External + 'hide-if-state', + 'show-if-state', + 'uib-tooltip' + + ], + angular: true, + tmplext: 'tpl.html', + doctype: 'HTML5', + charset: 'utf-8', + reportpath: null, + reportCheckstylePath: null + } +).then((result) => { + + // console.log(result); + + _.each(result.failed, (failure) => { + + // The module has a typo in the "numbers" property + console.error(chalk.red(`${failure.numerrs} errors at ${path.relative(PROJECT_ROOT, failure.filepath)}`)); + + _.each(failure.errors, (error) => { + console.error(' ' + chalk.yellow(`[${error.line}:${error.col}]`) + ` ${error.msg}`); + + if (/^Attribute (.*) not allowed on/.test(error.msg)) { + console.error(chalk.dim(` If this is a valid directive attribute, add it to the whitelist at ${FILENAME}`)); + } + }); + + console.error(''); + }); + + if (result.filessucceeded === result.fileschecked) { + console.log(chalk.green('Passed')); + } else { + console.error(chalk.red(`Total: ${result.filessucceeded}/${result.fileschecked}`)); + } + + if (!result.allpassed) { + + // Add a small timeout, otherwise the scripts exits + // before every string was printed on the screen. + setTimeout(() => { + process.exit(1); + }, 500); + + } + +}, (error) => { + console.error(error); + process.exit(1); +});