diff --git a/docs/rules/jsx-no-invalid-rel.md b/docs/rules/jsx-no-invalid-rel.md
index 7bdf973fa6..3792aa6249 100644
--- a/docs/rules/jsx-no-invalid-rel.md
+++ b/docs/rules/jsx-no-invalid-rel.md
@@ -1,6 +1,8 @@
# Prevent usage of invalid `rel` (react/jsx-no-invalid-rel)
-The JSX elements: `a`, `area`, `link`, or `form` all have a attribute called `rel`. There is is fixed list of values that have any meaning on these tags (see [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel)). To help with minimizing confusion while reading code, only the appropriate values should be on each attribute.
+The JSX elements: `a`, `area`, `link`, or `form` all have an attribute called `rel`.
+There is is fixed list of values that have any meaning on these tags (see [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel)).
+To help with minimizing confusion while reading code, only the appropriate values should be on each attribute.
## Rule Details
diff --git a/lib/rules/jsx-no-invalid-rel.js b/lib/rules/jsx-no-invalid-rel.js
index 7c203c2228..271e9d0412 100644
--- a/lib/rules/jsx-no-invalid-rel.js
+++ b/lib/rules/jsx-no-invalid-rel.js
@@ -40,9 +40,8 @@ const standardValues = new Map(Object.entries({
}));
const components = new Set(['link', 'a', 'area', 'form']);
-function splitIntoRangedParts(node) {
+function splitIntoRangedParts(node, regex) {
const res = [];
- const regex = /\s*([^\s]+)/g;
const valueRangeStart = node.range[0] + 1; // the plus one is for the initial quote
let match;
@@ -64,7 +63,7 @@ function checkLiteralValueNode(context, node, parentNodeName) {
if (typeof node.value !== 'string') {
return context.report({
node,
- messageId: 'onlyStrings',
+ message: '"rel" attribute only supports strings.',
fix(fixer) {
return fixer.remove(node.parent.parent);
}
@@ -74,23 +73,20 @@ function checkLiteralValueNode(context, node, parentNodeName) {
if (!node.value.trim()) {
return context.report({
node,
- messageId: 'emptyRel',
+ message: 'An empty "rel" attribute is meaningless.',
fix(fixer) {
return fixer.remove(node);
}
});
}
- const parts = splitIntoRangedParts(node);
+ const parts = splitIntoRangedParts(node, /([^\s]+)/g);
for (const part of parts) {
const allowedTags = standardValues.get(part.value);
if (!allowedTags) {
context.report({
node,
- messageId: 'realRelValues',
- data: {
- value: part.reportingValue
- },
+ message: `${part.reportingValue} is never a valid "rel" attribute value.`,
fix(fixer) {
return fixer.removeRange(part.range);
}
@@ -98,17 +94,26 @@ function checkLiteralValueNode(context, node, parentNodeName) {
} else if (!allowedTags.has(parentNodeName)) {
context.report({
node,
- messageId: 'matchingRelValues',
- data: {
- value: part.reportingValue,
- tag: parentNodeName
- },
+ message: `${part.reportingValue} is not a valid "rel" attribute value for <${parentNodeName}>.`,
fix(fixer) {
return fixer.removeRange(part.range);
}
});
}
}
+
+ const whitespaceParts = splitIntoRangedParts(node, /(\s+)/g);
+ for (const whitespacePart of whitespaceParts) {
+ if (whitespacePart.value !== ' ' || whitespacePart.range[0] === (node.range[0] + 1) || whitespacePart.range[1] === (node.range[1] - 1)) {
+ context.report({
+ node,
+ message: '"rel" attribute values should be space delimited.',
+ fix(fixer) {
+ return fixer.removeRange(whitespacePart.range);
+ }
+ });
+ }
+ }
}
module.exports = {
@@ -118,13 +123,6 @@ module.exports = {
description: 'Forbid `rel` attribute with an invalid value`',
category: 'Possible Errors',
url: docsUrl('jsx-no-invalid-rel')
- },
- messages: {
- relOnlyOnSpecific: 'The "rel" attribute only has meaning on ``, ``, ``, and `