UNPKG

eslint-plugin-sonarjs

Version:
95 lines (94 loc) • 3.72 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getElementType = void 0; exports.isPresentationTable = isPresentationTable; exports.getRole = getRole; exports.hasAccessibleNameAttribute = hasAccessibleNameAttribute; const jsx_ast_utils_x_1 = __importDefault(require("jsx-ast-utils-x")); const { getProp, getLiteralPropValue, getPropValue, elementType } = jsx_ast_utils_x_1.default; function isPresentationTable(context, node) { const DISALLOWED_VALUES = ['presentation', 'none']; const type = (0, exports.getElementType)(context)(node); if (type.toLowerCase() !== 'table') { return false; } const role = getProp(node.attributes, 'role'); if (!role) { return false; } const roleValue = String(getLiteralPropValue(role)); return DISALLOWED_VALUES.includes(roleValue?.toLowerCase()); } function getRole(node) { const roleProp = getProp(node.attributes, 'role'); if (!roleProp) { return null; } const roleValue = getLiteralPropValue(roleProp); if (typeof roleValue !== 'string') { return null; } return roleValue.toLowerCase(); } /** * Checks whether an accessible-name attribute has a statically non-empty or dynamic value. */ function hasAccessibleNameAttribute(attributes, name) { const attribute = getProp(attributes, name); if (!attribute) { return false; } if (isNonEmptyStringAttribute(attribute) || isPotentiallyNonEmptyTemplateLiteralAttribute(attribute)) { return true; } // Dynamic expressions are unknown statically, but nullish values should not suppress. return getLiteralPropValue(attribute) === null && getPropValue(attribute) != null; } function isNonEmptyStringAttribute(attribute) { if (attribute.value?.type === 'Literal') { return typeof attribute.value.value === 'string' && attribute.value.value.trim() !== ''; } if (attribute.value?.type === 'JSXExpressionContainer' && attribute.value.expression.type === 'Literal') { return (typeof attribute.value.expression.value === 'string' && attribute.value.expression.value.trim() !== ''); } return false; } function isPotentiallyNonEmptyTemplateLiteralAttribute(attribute) { if (attribute.value?.type !== 'JSXExpressionContainer' || attribute.value.expression.type !== 'TemplateLiteral') { return false; } return (attribute.value.expression.expressions.length > 0 || attribute.value.expression.quasis.some(quasi => quasi.value.cooked?.trim() !== '')); } const getElementType = (context) => { const { settings } = context; const jsxa11ySettings = settings['jsx-a11y']; const polymorphicPropName = jsxa11ySettings?.polymorphicPropName; const polymorphicAllowList = jsxa11ySettings?.polymorphicAllowList; const componentMap = jsxa11ySettings?.components; return (node) => { const prop = polymorphicPropName ? getProp(node.attributes, polymorphicPropName) : undefined; const polymorphicProp = prop ? getLiteralPropValue(prop) : undefined; let rawType = elementType(node); if (polymorphicProp && (!polymorphicAllowList || polymorphicAllowList.includes(rawType))) { rawType = `${polymorphicProp}`; } if (!componentMap) { return rawType; } return componentMap.hasOwnProperty(rawType) ? componentMap[rawType] : rawType; }; }; exports.getElementType = getElementType;