eslint-plugin-lit
Version:
lit-html support for ESLint
90 lines (89 loc) • 3.7 kB
JavaScript
/**
* @fileoverview Enforces the use of static styles in elements
* @author James Garbutt <https://github.com/43081j>
*/
import { TemplateAnalyzer } from '../template-analyzer.js';
import { isLitClass } from '../util.js';
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
export const rule = {
meta: {
docs: {
description: 'Enforces the use of static styles in elements',
recommended: false,
url: 'https://github.com/43081j/eslint-plugin-lit/blob/master/docs/rules/prefer-static-styles.md'
},
schema: [
{
enum: ['always', 'never']
}
],
messages: {
always: 'Static styles should be used instead of inline style tags',
never: 'Inline style tags should be used instead of static styles'
}
},
create(context) {
const source = context.getSourceCode();
const prefer = context.options[0] !== 'never';
return {
'ClassExpression,ClassDeclaration': (node) => {
if (!prefer && isLitClass(node)) {
for (const member of node.body.body) {
if (member.type === 'MethodDefinition' &&
member.kind === 'get' &&
member.static &&
member.key.type === 'Identifier' &&
member.key.name === 'styles') {
context.report({
node: member,
messageId: 'never'
});
}
if (member.type === 'PropertyDefinition' &&
member.static &&
member.key.type === 'Identifier' &&
member.key.name === 'styles') {
context.report({
node: member,
messageId: 'never'
});
}
}
}
},
AssignmentExpression: (node) => {
if (!prefer &&
node.left.type === 'MemberExpression' &&
node.left.property.type === 'Identifier' &&
node.left.property.name === 'adoptedStylesheets') {
context.report({
node,
messageId: 'never'
});
}
},
TaggedTemplateExpression: (node) => {
if (node.tag.type === 'Identifier' && node.tag.name === 'html') {
const analyzer = TemplateAnalyzer.create(node);
if (prefer) {
analyzer.traverse({
enterElement(node) {
if (node.tagName === 'style' && node.sourceCodeLocation) {
const loc = analyzer.resolveLocation(node.sourceCodeLocation, source);
if (loc) {
context.report({
loc,
messageId: 'always'
});
}
}
}
});
}
}
}
};
}
};