Repository: vuejs/eslint-plugin-vue
Pull request #2111 (2023-03-21 12:36:17)

Add suggestions for `no-template-target-blank` rule


Patch:
diff --git a/lib/rules/no-template-target-blank.js b/lib/rules/no-template-target-blank.js
index 1cbe7f40..d535b14b 100644
--- a/lib/rules/no-template-target-blank.js
+++ b/lib/rules/no-template-target-blank.js
@@ -67,6 +67,32 @@ function hasDynamicLink(node) {
   )
 }
 
+/**
+ * @param {VAttribute} node
+ * @returns {Rule.SuggestionReportDescriptor}
+ */
+function getSuggestion(node) {
+  const relAttributeNode = node.parent.attributes.find(
+    (attribute) => attribute.key.name === 'rel'
+  )
+
+  if (relAttributeNode) {
+    return {
+      desc: 'Change `rel` attribute value to `noopener noreferrer`.',
+      fix(fixer) {
+        return fixer.replaceText(relAttributeNode, 'rel="noopener noreferrer"')
+      }
+    }
+  }
+
+  return {
+    desc: 'Add `rel="noopener noreferrer"`.',
+    fix(fixer) {
+      return fixer.insertTextAfter(node, ' rel="noopener noreferrer"')
+    }
+  }
+}
+
 module.exports = {
   meta: {
     type: 'problem',
@@ -76,6 +102,7 @@ module.exports = {
       categories: undefined,
       url: 'https://eslint.vuejs.org/rules/no-template-target-blank.html'
     },
+    hasSuggestions: true,
     schema: [
       {
         type: 'object',
@@ -118,7 +145,8 @@ module.exports = {
           context.report({
             node,
             message:
-              'Using target="_blank" without rel="noopener noreferrer" is a security risk.'
+              'Using target="_blank" without rel="noopener noreferrer" is a security risk.',
+            suggest: [getSuggestion(node)]
           })
         }
       }


Test patch:
diff --git a/tests/lib/rules/no-template-target-blank.js b/tests/lib/rules/no-template-target-blank.js
index 9745fd1c..5445ae6d 100644
--- a/tests/lib/rules/no-template-target-blank.js
+++ b/tests/lib/rules/no-template-target-blank.js
@@ -49,31 +49,81 @@ ruleTester.run('no-template-target-blank', rule, {
     {
       code: '<template><a href="https://eslint.vuejs.org" target="_blank">link</a></template>',
       errors: [
-        'Using target="_blank" without rel="noopener noreferrer" is a security risk.'
+        {
+          message:
+            'Using target="_blank" without rel="noopener noreferrer" is a security risk.',
+          suggestions: [
+            {
+              desc: 'Add `rel="noopener noreferrer"`.',
+              output:
+                '<template><a href="https://eslint.vuejs.org" target="_blank" rel="noopener noreferrer">link</a></template>'
+            }
+          ]
+        }
       ]
     },
     {
       code: '<template><a href="https://eslint.vuejs.org" target="_blank" rel="noopenernoreferrer">link</a></template>',
       errors: [
-        'Using target="_blank" without rel="noopener noreferrer" is a security risk.'
+        {
+          message:
+            'Using target="_blank" without rel="noopener noreferrer" is a security risk.',
+          suggestions: [
+            {
+              desc: 'Change `rel` attribute value to `noopener noreferrer`.',
+              output:
+                '<template><a href="https://eslint.vuejs.org" target="_blank" rel="noopener noreferrer">link</a></template>'
+            }
+          ]
+        }
       ]
     },
     {
       code: '<template><a :href="link" target="_blank" rel=3>link</a></template>',
       errors: [
-        'Using target="_blank" without rel="noopener noreferrer" is a security risk.'
+        {
+          message:
+            'Using target="_blank" without rel="noopener noreferrer" is a security risk.',
+          suggestions: [
+            {
+              desc: 'Change `rel` attribute value to `noopener noreferrer`.',
+              output:
+                '<template><a :href="link" target="_blank" rel="noopener noreferrer">link</a></template>'
+            }
+          ]
+        }
       ]
     },
     {
       code: '<template><a :href="link" target="_blank">link</a></template>',
       errors: [
-        'Using target="_blank" without rel="noopener noreferrer" is a security risk.'
+        {
+          message:
+            'Using target="_blank" without rel="noopener noreferrer" is a security risk.',
+          suggestions: [
+            {
+              desc: 'Add `rel="noopener noreferrer"`.',
+              output:
+                '<template><a :href="link" target="_blank" rel="noopener noreferrer">link</a></template>'
+            }
+          ]
+        }
       ]
     },
     {
       code: '<template><a href="https://eslint.vuejs.org" target="_blank" rel="noopener">link</a></template>',
       errors: [
-        'Using target="_blank" without rel="noopener noreferrer" is a security risk.'
+        {
+          message:
+            'Using target="_blank" without rel="noopener noreferrer" is a security risk.',
+          suggestions: [
+            {
+              desc: 'Change `rel` attribute value to `noopener noreferrer`.',
+              output:
+                '<template><a href="https://eslint.vuejs.org" target="_blank" rel="noopener noreferrer">link</a></template>'
+            }
+          ]
+        }
       ]
     }
   ]