Repository: rwjblue/ember-cli-template-lint (js)

Issue:
Rule: Disallow HTML comments
I can't think of a good use case for using ```<!-- HTML comments -->``` in templates since ```{{!-- handlebars comments --}}``` serve the purpose of commenting the template, but are not included in the compiled output and eventual DOM. But I'm so used to HTML comments that I always forget and use them when I don't mean to! I'd love a lint rule to catch this.

I see that the linter uses HTML comments for its instructions. Is this because brocolli-template-lint doesn't expose handlebars comments or something? Or could it instead support instructions in handlebars comments? I believe this rule could be made to work either way (obviously ignoring HTML comments that are instructions to the linter).

I'd be happy to take a crack at a PR for this if it sounds like a good idea outside of my head as well as inside of it :smile: 

Pull request:
Implement html-comments rule
Forbid HTML comments in favor of Handlebars comments (fixes #64)

Patch:
diff --git a/README.md b/README.md
index e5eff4a..e861723 100644
--- a/README.md
+++ b/README.md
@@ -111,6 +111,31 @@ The following values are valid configuration:
   * "tab" -- To indicate tab style indentation (1 char)
 
 
+#### html-comments
+
+Html comments in your templates will get compiled and rendered into the DOM at runtime. Instead you can annotate your templates using Handlebars comments, which will be stripped out when the template is compiled and have no effect at runtime.
+
+This rule forbids the following:
+
+``` hbs
+<!-- comment goes here -->
+```
+
+but allows the following:
+
+```hbs
+{{!-- comment goes here --}}
+```
+
+Html comments containing linting instructions such as:
+
+```hbs
+<!-- template-lint bare-strings=false -->
+```
+
+are of course allowed (and since the linter strips them during processing, they will not get compiled and rendered into the DOM regardless of this rule).
+
+
 #### triple-curlies
 
 Usage of triple curly braces to allow raw HTML to be injected into the DOM is large vector for exploits of your application (especially when the raw HTML is user controllable ). Instead of using `{{{foo}}}`, you should use appropriate helpers or computed properties that return a `SafeString` (via `Ember.String.htmlSafe` generally) and ensure that user supplied data is properly escaped.
diff --git a/blueprints/ember-cli-template-lint/files/.template-lintrc.js b/blueprints/ember-cli-template-lint/files/.template-lintrc.js
index d4a442c..f3c7002 100644
--- a/blueprints/ember-cli-template-lint/files/.template-lintrc.js
+++ b/blueprints/ember-cli-template-lint/files/.template-lintrc.js
@@ -4,5 +4,6 @@
 module.exports = {
   'bare-strings': ['(', ')', ',', '.', '&', '+', '-', '=', '*', '/', '#', '%', '!', '?', ':', '[', ']', '{', '}'],
   'block-indentation': 2,
+  'html-comments': true,
   'triple-curlies': true
 };
diff --git a/ext/plugins/index.js b/ext/plugins/index.js
index 3c31210..09f084f 100644
--- a/ext/plugins/index.js
+++ b/ext/plugins/index.js
@@ -3,5 +3,6 @@
 module.exports = {
   'bare-strings': require('./lint-bare-strings'),
   'block-indentation': require('./lint-block-indentation'),
+  'html-comments': require('./lint-html-comments'),
   'triple-curlies': require('./lint-triple-curlies')
 };
diff --git a/ext/plugins/lint-html-comments.js b/ext/plugins/lint-html-comments.js
new file mode 100644
index 0000000..37c0234
--- /dev/null
+++ b/ext/plugins/lint-html-comments.js
@@ -0,0 +1,37 @@
+'use strict';
+
+var calculateLocationDisplay = require('../helpers/calculate-location-display');
+var buildPlugin = require('./base');
+
+module.exports = function(addonContext) {
+  var LogHtmlComments = buildPlugin(addonContext, 'html-comments');
+
+  LogHtmlComments.prototype.parseConfig = function(config) {
+    var configType = typeof config;
+
+    var errorMessage = 'The html-comments rule accepts one of the following values.\n ' +
+          '  * boolean - `true` to enable / `false` to disable\n' +
+          '\nYou specified `' + JSON.stringify(config) + '`';
+
+    switch (configType) {
+    case 'boolean':
+      return config;
+    case 'undefined':
+      return false;
+    default:
+      throw new Error(errorMessage);
+    }
+  };
+
+  LogHtmlComments.prototype.detect = function(node) {
+    return node.type === 'CommentStatement';
+  };
+
+  LogHtmlComments.prototype.process = function(node) {
+    var location = calculateLocationDisplay(this.options.moduleName, node.loc && node.loc.start);
+    this.log('Html comment detected `<!--' + node.value + '-->` at ' + location +
+      '. Use Handlebars comment instead `{{!--' + node.value +'--}}`');
+  };
+
+  return LogHtmlComments;
+};


Test patch:
diff --git a/node-tests/unit/plugins/lint-html-comments-test.js b/node-tests/unit/plugins/lint-html-comments-test.js
new file mode 100644
index 0000000..0b33dea
--- /dev/null
+++ b/node-tests/unit/plugins/lint-html-comments-test.js
@@ -0,0 +1,28 @@
+'use strict';
+
+var generateRuleTests = require('../../helpers/rule-test-harness');
+
+generateRuleTests({
+  name: 'html-comments',
+
+  config: true,
+
+  good: [
+    '{{!-- comment here --}}',
+    '{{!--comment here--}}',
+    '<!-- template-lint bare-strings=false -->'
+  ],
+
+  bad: [
+    {
+      template: '<!-- comment here -->',
+      message: 'Html comment detected `<!-- comment here -->` at (\'layout.hbs\'). ' +
+        'Use Handlebars comment instead `{{!-- comment here --}}`'
+    },
+    {
+      template: '<!--comment here-->',
+      message: 'Html comment detected `<!--comment here-->` at (\'layout.hbs\'). ' +
+        'Use Handlebars comment instead `{{!--comment here--}}`'
+    }
+  ]
+});