eslint-plugin-html-compat
Version:
ESLint plugin to check HTML element and attribute compatibility using browserslist and @mdn/browser-compat-data
120 lines • 5.43 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const compatibility_1 = require("../utils/compatibility");
const rule = {
meta: {
type: "problem",
docs: {
description: "Check for deprecated HTML elements and attributes",
category: "Possible Errors",
recommended: true,
},
fixable: undefined,
schema: [],
messages: {
deprecatedElement: 'HTML element "{{element}}" is deprecated{{deprecationNote}}.\n See {{mdnUrl}} for details.',
deprecatedAttribute: 'HTML attribute "{{attribute}}" on element "{{element}}" is deprecated{{deprecationNote}}.\n See {{mdnUrl}} for details.',
},
},
create(context) {
function checkJSXElement(node) {
const elementName = node.openingElement?.name?.name || node.name?.name;
if (!elementName)
return;
const deprecationResult = (0, compatibility_1.checkHtmlElementDeprecation)(elementName);
if (deprecationResult.isDeprecated) {
context.report({
node,
messageId: "deprecatedElement",
data: {
element: elementName,
deprecationNote: deprecationResult.deprecationNote
? `: ${deprecationResult.deprecationNote}`
: "",
mdnUrl: deprecationResult.mdnUrl || "",
},
});
}
const attributes = node.openingElement?.attributes || node.attributes;
if (attributes) {
for (const attr of attributes) {
if (attr.type === "JSXAttribute" && attr.name?.name) {
const attrName = attr.name.name.toLowerCase();
const jsxOnlyAttributes = [
"classname",
"htmlfor",
"defaultvalue",
"defaultchecked",
];
if (jsxOnlyAttributes.includes(attrName)) {
continue;
}
const attrDeprecationResult = (0, compatibility_1.checkHtmlAttributeDeprecation)(elementName, attrName);
if (attrDeprecationResult.isDeprecated) {
context.report({
node: attr,
messageId: "deprecatedAttribute",
data: {
attribute: attrName,
element: elementName,
deprecationNote: attrDeprecationResult.deprecationNote
? `: ${attrDeprecationResult.deprecationNote}`
: "",
mdnUrl: attrDeprecationResult.mdnUrl || "",
},
});
}
}
}
}
}
function checkHTMLElement(node) {
const elementName = node.tagName?.toLowerCase();
if (!elementName)
return;
const deprecationResult = (0, compatibility_1.checkHtmlElementDeprecation)(elementName);
if (deprecationResult.isDeprecated) {
context.report({
node,
messageId: "deprecatedElement",
data: {
element: elementName,
deprecationNote: deprecationResult.deprecationNote
? `: ${deprecationResult.deprecationNote}`
: "",
mdnUrl: deprecationResult.mdnUrl || "",
},
});
}
if (node.attributes) {
for (const attr of node.attributes) {
const attrName = attr.key?.name?.toLowerCase() || attr.name?.toLowerCase();
if (attrName) {
const attrDeprecationResult = (0, compatibility_1.checkHtmlAttributeDeprecation)(elementName, attrName);
if (attrDeprecationResult.isDeprecated) {
context.report({
node: attr,
messageId: "deprecatedAttribute",
data: {
attribute: attrName,
element: elementName,
deprecationNote: attrDeprecationResult.deprecationNote
? `: ${attrDeprecationResult.deprecationNote}`
: "",
mdnUrl: attrDeprecationResult.mdnUrl || "",
},
});
}
}
}
}
}
return {
JSXElement: checkJSXElement,
HTMLElement: checkHTMLElement,
Element: checkHTMLElement,
};
},
};
exports.default = rule;
//# sourceMappingURL=html-deprecated.js.map