UNPKG

eslint-plugin-better-tailwindcss

Version:

auto-wraps tailwind classes after a certain print width or class count into multiple lines to improve readability.

204 lines 7.29 kB
import { ES_CONTAINER_TYPES_TO_REPLACE_QUOTES, getESMatcherFunctions, getLiteralsByESLiteralNode, hasESNodeParentExtension, isESStringLike } from "./es.js"; import { getLiteralNodesByMatchers } from "../utils/matchers.js"; import { addAttribute, deduplicateLiterals, getContent, getIndentation, getQuotes, getWhitespace, matchesName } from "../utils/utils.js"; export const SVELTE_CONTAINER_TYPES_TO_REPLACE_QUOTES = [ ...ES_CONTAINER_TYPES_TO_REPLACE_QUOTES, "SvelteMustacheTag" ]; export const SVELTE_CONTAINER_TYPES_TO_INSERT_BRACES = []; export function getAttributesBySvelteTag(ctx, node) { return node.attributes.reduce((acc, attribute) => { if (isSvelteAttribute(attribute)) { acc.push(attribute); } return acc; }, []); } export function getDirectivesBySvelteTag(ctx, node) { return node.attributes.reduce((acc, attribute) => { if (isSvelteDirective(attribute)) { acc.push(attribute); } return acc; }, []); } export function getLiteralsBySvelteAttribute(ctx, attribute, selectors) { // skip shorthand attributes #42 if (!Array.isArray(attribute.value)) { return []; } const name = attribute.key.name; const literals = selectors.reduce((literals, selector) => { for (const value of attribute.value) { if (!matchesName(selector.name.toLowerCase(), name.toLowerCase())) { continue; } if (!selector.match) { literals.push(...getLiteralsBySvelteLiteralNode(ctx, value)); continue; } literals.push(...getLiteralsBySvelteMatchers(ctx, value, selector.match)); } return literals; }, []); return literals .filter(deduplicateLiterals) .map(addAttribute(name)); } export function getLiteralsBySvelteDirective(ctx, directive, selectors) { if (directive.kind !== "Class") { return []; } const name = `class:${directive.key.name.name}`; const literals = selectors.reduce((literals, selector) => { if (!matchesName(selector.name.toLowerCase(), name.toLowerCase())) { return literals; } if (!selector.match) { return literals; } literals.push(...getLiteralsBySvelteMatchers(ctx, directive.key.name, selector.match)); return literals; }, []); return literals .filter(deduplicateLiterals) .map(addAttribute(name)); } function getLiteralsBySvelteMatchers(ctx, node, matchers) { const matcherFunctions = getSvelteMatcherFunctions(matchers); const literalNodes = getLiteralNodesByMatchers(ctx, node, matcherFunctions); const literals = literalNodes.flatMap(literalNode => getLiteralsBySvelteLiteralNode(ctx, literalNode)); return literals.filter(deduplicateLiterals); } function getLiteralsBySvelteLiteralNode(ctx, node) { if (isSvelteStringLiteral(node)) { const stringLiteral = getStringLiteralBySvelteStringLiteral(ctx, node); if (stringLiteral) { return [stringLiteral]; } } if (isSvelteName(node)) { const stringLiteral = getStringLiteralBySvelteName(ctx, node); if (stringLiteral) { return [stringLiteral]; } } if (isSvelteMustacheTag(node)) { return getLiteralsBySvelteLiteralNode(ctx, node.expression); } if (isESStringLike(node)) { return getLiteralsBySvelteESLiteralNode(ctx, node); } return []; } function getLiteralsBySvelteESLiteralNode(ctx, node) { const literals = getLiteralsByESLiteralNode(ctx, node); return literals.map(literal => { if (!hasESNodeParentExtension(node)) { return literal; } const multilineQuotes = getMultilineQuotes(node); return { ...literal, ...multilineQuotes }; }); } function getStringLiteralBySvelteName(ctx, node) { const raw = node.name; const braces = getBracesByString(ctx, raw); const isInterpolated = getIsInterpolated(ctx, raw); const quotes = getQuotes(raw); const content = getContent(raw, quotes, braces); const whitespaces = getWhitespace(content); const line = ctx.sourceCode.lines[isInterpolated ? node.parent.loc.start.line - 1 : node.loc.start.line - 1]; const indentation = getIndentation(line); const multilineQuotes = getMultilineQuotes(node); return { ...whitespaces, ...quotes, ...braces, ...multilineQuotes, content, indentation, isInterpolated, loc: node.loc, range: node.range, // include quotes in range raw, supportsMultiline: false, type: "StringLiteral" }; } function getStringLiteralBySvelteStringLiteral(ctx, node) { const raw = ctx.sourceCode.getText(node, 1, 1); const braces = getBracesByString(ctx, raw); const isInterpolated = getIsInterpolated(ctx, raw); const quotes = getQuotes(raw); const content = getContent(raw, quotes, braces); const whitespaces = getWhitespace(content); const line = ctx.sourceCode.lines[isInterpolated ? node.parent.loc.start.line - 1 : node.loc.start.line - 1]; const indentation = getIndentation(line); const multilineQuotes = getMultilineQuotes(node); return { ...whitespaces, ...quotes, ...braces, ...multilineQuotes, content, indentation, isInterpolated, loc: node.loc, range: [node.range[0] - 1, node.range[1] + 1], // include quotes in range raw, supportsMultiline: true, type: "StringLiteral" }; } function getBracesByString(ctx, raw) { const closingBraces = raw.trim().startsWith("}") ? "}" : undefined; const openingTemplateBraces = raw.trim().endsWith("${") ? "${" : undefined; const openingBrace = raw.trim().endsWith("{") ? "{" : undefined; const openingBraces = openingTemplateBraces ?? openingBrace; return { closingBraces, openingBraces }; } function getIsInterpolated(ctx, raw) { const braces = getBracesByString(ctx, raw); return !!braces.closingBraces || !!braces.openingBraces; } function getMultilineQuotes(node) { const surroundingBraces = SVELTE_CONTAINER_TYPES_TO_INSERT_BRACES.includes(node.parent.type); const multilineQuotes = SVELTE_CONTAINER_TYPES_TO_REPLACE_QUOTES.includes(node.parent.type) ? ["'", "\"", "`"] : []; return { multilineQuotes, surroundingBraces }; } function isSvelteAttribute(node) { return node.type === "SvelteAttribute"; } function isSvelteDirective(node) { return node.type === "SvelteDirective"; } function isSvelteStringLiteral(node) { return node.type === "SvelteLiteral"; } function isSvelteName(node) { return node.type === "SvelteName"; } function isSvelteMustacheTag(node) { return node.type === "SvelteMustacheTag" && "kind" in node && node.kind === "text"; } function getSvelteMatcherFunctions(matchers) { return getESMatcherFunctions(matchers, { isStringLikeNode(node) { return isSvelteName(node) || isSvelteStringLiteral(node); } }); } //# sourceMappingURL=svelte.js.map