Skip to content

Commit

Permalink
fix: allow some case-sensitive svg attributes in lowercase rule (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeonjuan committed Jan 27, 2024
1 parent 4399086 commit 42c7e60
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 11 deletions.
3 changes: 2 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"**/coverage/**",
"**/out/**",
"**/node_modules/**",
"packages/website/**"
"packages/website/**",
"packages/eslint-plugin/types/**"
],
"words": [
"rehype",
Expand Down
73 changes: 73 additions & 0 deletions packages/eslint-plugin/lib/constants/svg-camel-case-attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
module.exports = [
"allowReorder",
"attributeName",
"attributeType",
"autoReverse",
"baseFrequency",
"baseProfile",
"calcMode",
"clipPath",
"clipPathUnits",
"contentScriptType",
"contentStyleType",
"diffuseConstant",
"edgeMode",
"externalResourcesRequired",
"filterRes",
"filterUnits",
"glyphRef",
"gradientTransform",
"gradientUnits",
"kernelMatrix",
"kernelUnitLength",
"keyPoints",
"keySplines",
"keyTimes",
"lengthAdjust",
"limitingConeAngle",
"markerHeight",
"markerUnits",
"markerWidth",
"maskContentUnits",
"maskUnits",
"numOctaves",
"onBlur",
"onChange",
"onClick",
"onFocus",
"onKeyUp",
"onLoad",
"pathLength",
"patternContentUnits",
"patternTransform",
"patternUnits",
"pointsAtX",
"pointsAtY",
"pointsAtZ",
"preserveAlpha",
"preserveAspectRatio",
"primitiveUnits",
"refX",
"refY",
"repeatCount",
"repeatDur",
"requiredExtensions",
"requiredFeatures",
"specularConstant",
"specularExponent",
"spreadMethod",
"startOffset",
"stdDeviation",
"stitchTiles",
"surfaceScale",
"systemLanguage",
"tableValues",
"targetX",
"targetY",
"textLength",
"viewBox",
"viewTarget",
"xChannelSelector",
"yChannelSelector",
"zoomAndPan",
];
44 changes: 43 additions & 1 deletion packages/eslint-plugin/lib/rules/lowercase.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

const { NODE_TYPES } = require("@html-eslint/parser");
const { RULE_CATEGORY } = require("../constants");
const SVG_CAMEL_CASE_ATTRIBUTES = require("../constants/svg-camel-case-attributes");

const MESSAGE_IDS = {
UNEXPECTED: "unexpected",
Expand All @@ -33,6 +34,31 @@ module.exports = {
},

create(context) {
const allowedAttrKeySet = new Set(SVG_CAMEL_CASE_ATTRIBUTES);
/**
* @type {TagNode[]}
*/
const svgStack = [];

/**
* @param {TagNode} node
*/
function enterSvg(node) {
svgStack.push(node);
}

function exitSvg() {
svgStack.pop();
}

/**
* @param {string} key
* @returns {boolean}
*/
function isAllowedAttributeKey(key) {
return !!svgStack.length && allowedAttrKeySet.has(key);
}

/**
* @param {TagNode | StyleTagNode | ScriptTagNode} node
*/
Expand Down Expand Up @@ -72,6 +98,9 @@ module.exports = {
}
if (node.attributes && node.attributes.length) {
node.attributes.forEach((attribute) => {
if (isAllowedAttributeKey(attribute.key.value)) {
return;
}
if (attribute.key.value !== attribute.key.value.toLowerCase()) {
context.report({
node: attribute.key,
Expand All @@ -92,7 +121,20 @@ module.exports = {
}

return {
Tag: check,
Tag(node) {
if (node.name.toLocaleLowerCase() === "svg") {
enterSvg(node);
}
check(node);
},
/**
* @param {TagNode} node
*/
"Tag:exit"(node) {
if (node.name.toLocaleLowerCase() === "svg") {
exitSvg();
}
},
StyleTag: check,
ScriptTag: check,
};
Expand Down
35 changes: 35 additions & 0 deletions packages/eslint-plugin/tests/rules/lowercase.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,32 @@ ruleTester.run("lowercase", rule, {
{
code: "<style></style>",
},
// svg
{
code: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"></svg>`,
},
{
code: `<svg viewBox="0 0 220 150" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="100" height="100">
<animate
attributeType="XML"
attributeName="y"
from="0"
to="50"
dur="1s"
repeatCount="5" />
</rect>
<rect x="120" y="0" width="100" height="100">
<animate
attributeType="XML"
attributeName="y"
from="0"
to="50"
dur="1s"
repeatCount="indefinite" />
</rect>
</svg>`,
},
],
invalid: [
{
Expand Down Expand Up @@ -64,5 +90,14 @@ ruleTester.run("lowercase", rule, {
},
],
},
{
code: `<svg xmlns="http://www.w3.org/2000/svg" STYLE="" viewBox="0 0 200 200"></svg>`,
output: `<svg xmlns="http://www.w3.org/2000/svg" style="" viewBox="0 0 200 200"></svg>`,
errors: [
{
message: "'STYLE' is not in lowercase.",
},
],
},
],
});
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1055,8 +1055,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "@html-eslint/cli@workspace:packages/cli"
dependencies:
"@html-eslint/eslint-plugin": "npm:^0.22.0"
"@html-eslint/parser": "npm:^0.22.0"
"@html-eslint/eslint-plugin": "npm:^0.23.0"
"@html-eslint/parser": "npm:^0.23.0"
axios: "npm:^1.6.2"
chalk: "npm:^4.1.1"
eslint: "npm:^7.27.0"
Expand All @@ -1066,11 +1066,11 @@ __metadata:
languageName: unknown
linkType: soft

"@html-eslint/eslint-plugin@npm:^0.22.0, @html-eslint/eslint-plugin@workspace:packages/eslint-plugin":
"@html-eslint/eslint-plugin@npm:^0.23.0, @html-eslint/eslint-plugin@workspace:packages/eslint-plugin":
version: 0.0.0-use.local
resolution: "@html-eslint/eslint-plugin@workspace:packages/eslint-plugin"
dependencies:
"@html-eslint/parser": "npm:^0.22.0"
"@html-eslint/parser": "npm:^0.23.0"
"@types/eslint": "npm:^8.56.2"
"@types/estree": "npm:^0.0.47"
es-html-parser: "npm:^0.0.8"
Expand All @@ -1096,7 +1096,7 @@ __metadata:
languageName: unknown
linkType: soft

"@html-eslint/parser@npm:^0.22.0, @html-eslint/parser@workspace:packages/parser":
"@html-eslint/parser@npm:^0.23.0, @html-eslint/parser@workspace:packages/parser":
version: 0.0.0-use.local
resolution: "@html-eslint/parser@workspace:packages/parser"
dependencies:
Expand All @@ -1105,7 +1105,7 @@ __metadata:
languageName: unknown
linkType: soft

"@html-eslint/web-linter@npm:^0.22.0, @html-eslint/web-linter@workspace:packages/web-linter":
"@html-eslint/web-linter@npm:^0.23.0, @html-eslint/web-linter@workspace:packages/web-linter":
version: 0.0.0-use.local
resolution: "@html-eslint/web-linter@workspace:packages/web-linter"
dependencies:
Expand Down Expand Up @@ -15743,9 +15743,9 @@ __metadata:
version: 0.0.0-use.local
resolution: "website@workspace:packages/website"
dependencies:
"@html-eslint/eslint-plugin": "npm:^0.22.0"
"@html-eslint/parser": "npm:^0.22.0"
"@html-eslint/web-linter": "npm:^0.22.0"
"@html-eslint/eslint-plugin": "npm:^0.23.0"
"@html-eslint/parser": "npm:^0.23.0"
"@html-eslint/web-linter": "npm:^0.23.0"
"@parcel/transformer-sass": "npm:2.10.3"
"@types/codemirror": "npm:^5.60.5"
"@types/eslint": "npm:^8.56.2"
Expand Down

0 comments on commit 42c7e60

Please sign in to comment.