Repository: rwjblue/ember-template-lint
Pull request #141 (2016-11-17 08:45:46)

Enable submit actions on form elements for invalid-interactive test
When using forms, for keyboard users it is generally better to have:

```hbs
<form {{action "submitForm" on="submit"}}>
  <input>
  <button>Submit</button>
</form>
```

instead of

```hbs
<form>
  <input>
  <button {{action "submitForm"}}>Submit</button>
</form>
```

However, this is currently reported as an error when using the invalid-interactive test.
Of course, you could whitelist `form`, but that would also allow `<form {{action "doSomethingOnClick"}}></form>`, something that shouldn't be allowed.

This PR adds a special case handling for this and allows an action on a form element, but only if `on="submit"` is set on it.


Patch:
diff --git a/lib/rules/lint-invalid-interactive.js b/lib/rules/lint-invalid-interactive.js
index 847060d..0de7f70 100644
--- a/lib/rules/lint-invalid-interactive.js
+++ b/lib/rules/lint-invalid-interactive.js
@@ -44,6 +44,11 @@ module.exports = function(addonContext) {
         var modifierName = node.path.original;
 
         if (modifierName === 'action') {
+          // Allow {{action "foo" on="submit"}} on form tags
+          if (this._element.tag === 'form' && isSubmitAction(node)) {
+            return;
+          }
+
           this.log({
             message: 'Interaction added to non-interactive element',
             line: node.loc && node.loc.start.line,
@@ -79,3 +84,19 @@ module.exports = function(addonContext) {
 
   return InvalidInteractive;
 };
+
+function isSubmitAction(node) {
+  var hashPairs = node.hash.pairs || [];
+  var i;
+  var l = hashPairs.length;
+  var hashItem;
+
+  for (i = 0; i < l; i++) {
+    hashItem = hashPairs[i];
+    if (hashItem.key === 'on' && hashItem.value.value === 'submit') {
+      return true;
+    }
+  }
+
+  return false;
+}


Test patch:
diff --git a/test/unit/rules/lint-invalid-interactive-test.js b/test/unit/rules/lint-invalid-interactive-test.js
index 0074553..a25aff5 100644
--- a/test/unit/rules/lint-invalid-interactive-test.js
+++ b/test/unit/rules/lint-invalid-interactive-test.js
@@ -11,6 +11,7 @@ generateRuleTests({
     '<button {{action "foo"}}></button>',
     '<div role="button" {{action "foo"}}></div>',
     '<li><button {{action "foo"}}></button></li>',
+    '<form {{action "foo" on="submit"}}></form>',
     {
       config: { additionalInteractiveTags: ['div'] },
       template: '<div {{action "foo"}}></div>'
@@ -42,6 +43,28 @@ generateRuleTests({
         column: 5,
         source: '<div onclick={{action \"foo\"}}></div>'
       }
+    },
+
+    {
+      template: '<form {{action "foo" on="click"}}></form>',
+
+      result: {
+        message: 'Interaction added to non-interactive element',
+        line: 1,
+        column: 6,
+        source: '<form {{action \"foo\" on=\"click\"}}></form>'
+      }
+    },
+
+    {
+      template: '<div {{action "foo" on="submit"}}></div>',
+
+      result: {
+        message: 'Interaction added to non-interactive element',
+        line: 1,
+        column: 5,
+        source: '<div {{action \"foo\" on=\"submit\"}}></div>'
+      }
     }
   ]
 });