Skip to content

Commit

Permalink
feat: Add fixes for block-lang rule
Browse files Browse the repository at this point in the history
  • Loading branch information
Winter committed Aug 26, 2024
1 parent d117d7f commit 937acbc
Showing 1 changed file with 61 additions and 5 deletions.
66 changes: 61 additions & 5 deletions packages/eslint-plugin-svelte/src/rules/block-lang.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createRule } from '../utils';
import { getLangValue } from '../utils/ast-utils';
import { findAttribute, getLangValue } from '../utils/ast-utils';
import type { SvelteScriptElement, SvelteStyleElement } from 'svelte-eslint-parser/lib/ast';
import { getSourceCode } from '../utils/compat';

Expand All @@ -11,6 +11,7 @@ export default createRule('block-lang', {
category: 'Best Practices',
recommended: false
},
fixable: 'code',
schema: [
{
type: 'object',
Expand Down Expand Up @@ -88,7 +89,15 @@ export default createRule('block-lang', {
loc: { line: 1, column: 1 },
message: `The <script> block should be present and its lang attribute should be ${prettyPrintLangs(
allowedScriptLangs
)}.`
)}.`,
*fix(fixer) {
const langAttributeText = getLangAttributeText(allowedScriptLangs, true);

yield fixer.insertTextAfterRange(
[0, 0],
`<script${langAttributeText}>\n</script>\n\n`
);
}
});
}
for (const scriptNode of scriptNodes) {
Expand All @@ -97,7 +106,20 @@ export default createRule('block-lang', {
node: scriptNode,
message: `The lang attribute of the <script> block should be ${prettyPrintLangs(
allowedScriptLangs
)}.`
)}.`,
*fix(fixer) {
const langAttribute = findAttribute(scriptNode, 'lang');
const langAttributeText = getLangAttributeText(allowedScriptLangs, true);

if (langAttribute) {
yield fixer.replaceText(langAttribute, langAttributeText.trim());
} else {
yield fixer.insertTextBeforeRange(
[scriptNode.startTag.range[0] + 7, 0],
langAttributeText
);
}
}
});
}
}
Expand All @@ -106,7 +128,16 @@ export default createRule('block-lang', {
loc: { line: 1, column: 1 },
message: `The <style> block should be present and its lang attribute should be ${prettyPrintLangs(
allowedStyleLangs
)}.`
)}.`,
*fix(fixer) {
const sourceCode = getSourceCode(context);
const langAttributeText = getLangAttributeText(allowedScriptLangs, true);

yield fixer.insertTextAfterRange(
[sourceCode.text.length, sourceCode.text.length],
`\n\n<style${langAttributeText}>\n</style>`
);
}
});
}
for (const styleNode of styleNodes) {
Expand All @@ -115,7 +146,20 @@ export default createRule('block-lang', {
node: styleNode,
message: `The lang attribute of the <style> block should be ${prettyPrintLangs(
allowedStyleLangs
)}.`
)}.`,
*fix(fixer) {
const langAttribute = findAttribute(styleNode, 'lang');
const langAttributeText = getLangAttributeText(allowedStyleLangs, true);

if (langAttribute) {
yield fixer.replaceText(langAttribute, langAttributeText.trim());
} else {
yield fixer.insertTextBeforeRange(
[styleNode.startTag.range[0] + 6, 0],
langAttributeText
);
}
}
});
}
}
Expand All @@ -139,3 +183,15 @@ function prettyPrintLangs(langs: (string | null)[]): string {
nonNullLangs.length === 1 ? nonNullLangs[0] : `one of ${nonNullLangs.join(', ')}`;
return hasNullText + nonNullText;
}

/**
* Returns the lang attribute text, with special handling of the `null` lang option with respect to the `prependWhitespace` argument.
*/
function getLangAttributeText(langs: (string | null)[], prependWhitespace: boolean): string {
if (!langs.length || langs.includes(null)) return '';
const [firstLang] = langs;
if (langs.length === 1 && firstLang) {
return `${prependWhitespace ? ' ' : ''}lang="${firstLang}"`;
}
return '';
}

0 comments on commit 937acbc

Please sign in to comment.