Repository: ember-template-lint/ember-template-lint
Pull request #788 (2019-07-28 03:46:21)

Add support for handling `<button tabindex={{if this.foo 0 -1}}><button>` to no-positive-tabindex rule
https://github.com/ember-template-lint/ember-template-lint/pull/743


Patch:
diff --git a/lib/rules/lint-no-positive-tabindex.js b/lib/rules/lint-no-positive-tabindex.js
index d2b8ce1d..6177c635 100644
--- a/lib/rules/lint-no-positive-tabindex.js
+++ b/lib/rules/lint-no-positive-tabindex.js
@@ -6,6 +6,44 @@ const Rule = require('./base');
 const errorMessage = 'Avoid positive integer values for tabindex.';
 const errorMessageForNaNCase = 'Tabindex values must be negative numeric.';
 
+function literalValueToNumber(astNode) {
+  if (astNode.type === 'NumberLiteral') {
+    return astNode.original;
+  } else if (astNode.type === 'StringLiteral') {
+    return parseInt(astNode.original, 10);
+  } else {
+    return NaN;
+  }
+}
+
+function maybeLiteralValue(astNode, defaultValue) {
+  if (['NumberLiteral', 'StringLiteral'].includes(astNode.type)) {
+    return literalValueToNumber(astNode);
+  } else {
+    return defaultValue;
+  }
+}
+
+function parseTabIndexFromMustache(mustacheNode) {
+  let tabindexValue;
+
+  if (['NumberLiteral', 'StringLiteral'].includes(mustacheNode.path.type)) {
+    tabindexValue = literalValueToNumber(mustacheNode.path);
+  } else if (mustacheNode.path.type === 'PathExpression' && mustacheNode.path.original === 'if') {
+    if (mustacheNode.params.length === 2 || mustacheNode.params.length === 3) {
+      tabindexValue = maybeLiteralValue(mustacheNode.params[1], tabindexValue);
+    }
+    if (mustacheNode.params.length === 3) {
+      let maybeTabindexValue = maybeLiteralValue(mustacheNode.params[2], tabindexValue);
+      if (maybeTabindexValue > tabindexValue) {
+        tabindexValue = maybeTabindexValue;
+      }
+    }
+  }
+
+  return tabindexValue;
+}
+
 module.exports = class NoPositiveTabindex extends Rule {
   visitor() {
     return {
@@ -20,20 +58,12 @@ module.exports = class NoPositiveTabindex extends Rule {
 
         if (tabindex.value.type === 'MustacheStatement') {
           if (tabindex.value.path) {
-            if (tabindex.value.path.type === 'NumberLiteral') {
-              tabindexValue = tabindex.value.path.original;
-            } else if (tabindex.value.path.type === 'StringLiteral') {
-              tabindexValue = parseInt(tabindex.value.path.original, 10);
-            }
+            tabindexValue = parseTabIndexFromMustache(tabindex.value);
           }
         } else if (tabindex.value.type === 'ConcatStatement') {
           let part = tabindex.value.parts[0];
           if (part.type === 'MustacheStatement') {
-            if (part.path.type === 'NumberLiteral') {
-              tabindexValue = part.path.original;
-            } else if (part.path.type === 'StringLiteral') {
-              tabindexValue = parseInt(part.path.original, 10);
-            }
+            tabindexValue = parseTabIndexFromMustache(part);
           }
         } else if (tabindex.value.type === 'TextNode') {
           tabindexValue = parseInt(tabindex.value.chars, 10);


Test patch:
diff --git a/test/unit/rules/lint-no-positive-tabindex-test.js b/test/unit/rules/lint-no-positive-tabindex-test.js
index 80c5d43c..3e4a95fb 100644
--- a/test/unit/rules/lint-no-positive-tabindex-test.js
+++ b/test/unit/rules/lint-no-positive-tabindex-test.js
@@ -10,10 +10,16 @@ generateRuleTests({
   good: [
     '<button tabindex="0"></button>',
     '<button tabindex="-1"></button>',
-    '<span tabindex={{-1}}>baz</span>',
-    '<span tabindex={{"-1"}}>baz</span>',
-    '<span tabindex="{{-1}}">baz</span>',
-    '<span tabindex="{{"-1"}}">baz</span>',
+    '<button tabindex={{-1}}>baz</button>',
+    '<button tabindex={{"-1"}}>baz</button>',
+    '<button tabindex="{{-1}}">baz</button>',
+    '<button tabindex="{{"-1"}}">baz</button>',
+    '<button tabindex="{{if this.show -1}}">baz</button>',
+    '<button tabindex="{{if this.show "-1" "0"}}">baz</button>',
+    '<button tabindex="{{if (not this.show) "-1" "0"}}">baz</button>',
+    '<button tabindex={{if this.show -1}}>baz</button>',
+    '<button tabindex={{if this.show "-1" "0"}}>baz</button>',
+    '<button tabindex={{if (not this.show) "-1" "0"}}>baz</button>',
   ],
 
   bad: [
@@ -83,5 +89,49 @@ generateRuleTests({
         column: 0,
       },
     },
+    {
+      template: '<button tabindex="{{if a 1 -1}}"></button>',
+
+      result: {
+        message: 'Avoid positive integer values for tabindex.',
+        moduleId: 'layout.hbs',
+        source: 'tabindex="{{if a 1 -1}}"',
+        line: 1,
+        column: 0,
+      },
+    },
+    {
+      template: '<button tabindex="{{if a -1 1}}"></button>',
+
+      result: {
+        message: 'Avoid positive integer values for tabindex.',
+        moduleId: 'layout.hbs',
+        source: 'tabindex="{{if a -1 1}}"',
+        line: 1,
+        column: 0,
+      },
+    },
+    {
+      template: '<button tabindex="{{if a 1}}"></button>',
+
+      result: {
+        message: 'Avoid positive integer values for tabindex.',
+        moduleId: 'layout.hbs',
+        source: 'tabindex="{{if a 1}}"',
+        line: 1,
+        column: 0,
+      },
+    },
+    {
+      template: '<button tabindex="{{if (not a) 1}}"></button>',
+
+      result: {
+        message: 'Avoid positive integer values for tabindex.',
+        moduleId: 'layout.hbs',
+        source: 'tabindex="{{if (not a) 1}}"',
+        line: 1,
+        column: 0,
+      },
+    },
   ],
 });