eslint-plugin-ember
Version:
ESLint plugin for Ember.js apps
78 lines (69 loc) • 2.19 kB
JavaScript
const DEFAULT_FORBIDDEN = ['meta', 'style', 'html', 'script'];
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'disallow specific HTML elements',
category: 'Best Practices',
recommendedGjs: false,
recommendedGts: false,
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-forbidden-elements.md',
templateMode: 'both',
},
schema: [
{
oneOf: [
{ type: 'array', items: { type: 'string' } },
{ type: 'boolean' },
{
type: 'object',
properties: {
forbidden: { type: 'array', items: { type: 'string' } },
},
additionalProperties: false,
},
],
},
],
messages: { forbidden: 'Use of forbidden element <{{element}}>' },
originallyFrom: {
name: 'ember-template-lint',
rule: 'lib/rules/no-forbidden-elements.js',
docs: 'docs/rule/no-forbidden-elements.md',
tests: 'test/unit/rules/no-forbidden-elements-test.js',
},
},
create(context) {
const rawConfig = context.options[0];
let forbiddenList;
if (rawConfig === true || rawConfig === undefined) {
forbiddenList = DEFAULT_FORBIDDEN;
} else if (Array.isArray(rawConfig)) {
forbiddenList = rawConfig;
} else if (rawConfig && typeof rawConfig === 'object') {
forbiddenList = rawConfig.forbidden ?? DEFAULT_FORBIDDEN;
} else {
forbiddenList = [];
}
const forbidden = new Set(forbiddenList);
// Track element stack for <meta> in <head> exception
const elementStack = [];
return {
GlimmerElementNode(node) {
elementStack.push(node.tag);
if (!forbidden.has(node.tag)) {
return;
}
// Exception: <meta> inside <head> is allowed
if (node.tag === 'meta' && elementStack.includes('head')) {
return;
}
context.report({ node, messageId: 'forbidden', data: { element: node.tag } });
},
'GlimmerElementNode:exit'() {
elementStack.pop();
},
};
},
};