mirror of
https://github.com/github/codeql-action.git
synced 2025-12-24 08:10:06 +08:00
Update checked-in dependencies
This commit is contained in:
66
node_modules/eslint-plugin-github/lib/rules/a11y-no-title-attribute.js
generated
vendored
Normal file
66
node_modules/eslint-plugin-github/lib/rules/a11y-no-title-attribute.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
const {getProp, getPropValue} = require('jsx-ast-utils')
|
||||
const {getElementType} = require('../utils/get-element-type')
|
||||
|
||||
const SEMANTIC_ELEMENTS = [
|
||||
'a',
|
||||
'button',
|
||||
'summary',
|
||||
'select',
|
||||
'option',
|
||||
'textarea',
|
||||
'input',
|
||||
'span',
|
||||
'div',
|
||||
'p',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'details',
|
||||
'summary',
|
||||
'dialog',
|
||||
'tr',
|
||||
'th',
|
||||
'td',
|
||||
'label',
|
||||
]
|
||||
|
||||
const ifSemanticElement = (context, node) => {
|
||||
const elementType = getElementType(context, node.openingElement, true)
|
||||
|
||||
for (const semanticElement of SEMANTIC_ELEMENTS) {
|
||||
if (elementType === semanticElement) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
description: 'Guards against developers using the title attribute',
|
||||
url: require('../url')(module),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
|
||||
create(context) {
|
||||
return {
|
||||
JSXElement: node => {
|
||||
const elementType = getElementType(context, node.openingElement)
|
||||
if (elementType !== `iframe` && ifSemanticElement(context, node)) {
|
||||
const titleProp = getPropValue(getProp(node.openingElement.attributes, `title`))
|
||||
if (titleProp) {
|
||||
context.report({
|
||||
node,
|
||||
message: 'The title attribute is not accessible and should never be used unless for an `<iframe>`.',
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
83
node_modules/eslint-plugin-github/lib/rules/a11y-no-visually-hidden-interactive-element.js
generated
vendored
Normal file
83
node_modules/eslint-plugin-github/lib/rules/a11y-no-visually-hidden-interactive-element.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
const {getProp, getPropValue} = require('jsx-ast-utils')
|
||||
const {getElementType} = require('../utils/get-element-type')
|
||||
const {generateObjSchema} = require('eslint-plugin-jsx-a11y/lib/util/schemas')
|
||||
|
||||
const defaultClassName = 'sr-only'
|
||||
const defaultcomponentName = 'VisuallyHidden'
|
||||
|
||||
const schema = generateObjSchema({
|
||||
className: {type: 'string'},
|
||||
componentName: {type: 'string'},
|
||||
htmlPropName: {type: 'string'},
|
||||
})
|
||||
|
||||
/** Note: we are not including input elements at this time
|
||||
* because a visually hidden input field might cause a false positive.
|
||||
* (e.g. fileUpload https://github.com/primer/react/pull/3492)
|
||||
*/
|
||||
const INTERACTIVE_ELEMENTS = ['a', 'button', 'summary', 'select', 'option', 'textarea']
|
||||
|
||||
const checkIfInteractiveElement = (context, node) => {
|
||||
const elementType = getElementType(context, node.openingElement)
|
||||
|
||||
for (const interactiveElement of INTERACTIVE_ELEMENTS) {
|
||||
if (elementType === interactiveElement) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// if the node is visually hidden recursively check if it has interactive children
|
||||
const checkIfVisuallyHiddenAndInteractive = (context, options, node, isParentVisuallyHidden) => {
|
||||
const {className, componentName} = options
|
||||
if (node.type === 'JSXElement') {
|
||||
const classes = getPropValue(getProp(node.openingElement.attributes, 'className'))
|
||||
const isVisuallyHiddenElement = node.openingElement.name.name === componentName
|
||||
const hasSROnlyClass = typeof classes !== 'undefined' && classes.includes(className)
|
||||
let isHidden = false
|
||||
if (hasSROnlyClass || isVisuallyHiddenElement || !!isParentVisuallyHidden) {
|
||||
if (checkIfInteractiveElement(context, node)) {
|
||||
return true
|
||||
}
|
||||
isHidden = true
|
||||
}
|
||||
if (node.children && node.children.length > 0) {
|
||||
return (
|
||||
typeof node.children?.find(child =>
|
||||
checkIfVisuallyHiddenAndInteractive(context, options, child, !!isParentVisuallyHidden || isHidden),
|
||||
) !== 'undefined'
|
||||
)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
description: 'Ensures that interactive elements are not visually hidden',
|
||||
url: require('../url')(module),
|
||||
},
|
||||
schema: [schema],
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const {options} = context
|
||||
const config = options[0] || {}
|
||||
const className = config.className || defaultClassName
|
||||
const componentName = config.componentName || defaultcomponentName
|
||||
|
||||
return {
|
||||
JSXElement: node => {
|
||||
if (checkIfVisuallyHiddenAndInteractive(context, {className, componentName}, node, false)) {
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
'Avoid visually hidding interactive elements. Visually hiding interactive elements can be confusing to sighted keyboard users as it appears their focus has been lost when they navigate to the hidden element.',
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
61
node_modules/eslint-plugin-github/lib/rules/a11y-role-supports-aria-props.js
generated
vendored
Normal file
61
node_modules/eslint-plugin-github/lib/rules/a11y-role-supports-aria-props.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// @ts-check
|
||||
const {aria, roles} = require('aria-query')
|
||||
const {getPropValue, propName} = require('jsx-ast-utils')
|
||||
const {getRole} = require('../utils/get-role')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
description:
|
||||
'Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`.',
|
||||
url: require('../url')(module),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
|
||||
create(context) {
|
||||
return {
|
||||
JSXOpeningElement(node) {
|
||||
// Get the element’s explicit or implicit role
|
||||
const role = getRole(context, node)
|
||||
|
||||
// Return early if role could not be determined
|
||||
if (!role) return
|
||||
|
||||
// Get allowed ARIA attributes:
|
||||
// - From the role itself
|
||||
let allowedProps = Object.keys(roles.get(role)?.props || {})
|
||||
// - From parent roles
|
||||
for (const parentRole of roles.get(role)?.superClass.flat() ?? []) {
|
||||
allowedProps = allowedProps.concat(Object.keys(roles.get(parentRole)?.props || {}))
|
||||
}
|
||||
// Dedupe, for performance
|
||||
allowedProps = Array.from(new Set(allowedProps))
|
||||
|
||||
// Get prohibited ARIA attributes:
|
||||
// - From the role itself
|
||||
let prohibitedProps = roles.get(role)?.prohibitedProps || []
|
||||
// - From parent roles
|
||||
for (const parentRole of roles.get(role)?.superClass.flat() ?? []) {
|
||||
prohibitedProps = prohibitedProps.concat(roles.get(parentRole)?.prohibitedProps || [])
|
||||
}
|
||||
// - From comparing allowed vs all ARIA attributes
|
||||
prohibitedProps = prohibitedProps.concat(aria.keys().filter(x => !allowedProps.includes(x)))
|
||||
// Dedupe, for performance
|
||||
prohibitedProps = Array.from(new Set(prohibitedProps))
|
||||
|
||||
for (const prop of node.attributes) {
|
||||
// Return early if prohibited ARIA attribute is set to an ignorable value
|
||||
if (getPropValue(prop) == null || prop.type === 'JSXSpreadAttribute') return
|
||||
|
||||
if (prohibitedProps?.includes(propName(prop))) {
|
||||
context.report({
|
||||
node,
|
||||
message: `The attribute ${propName(prop)} is not supported by the role ${role}.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
41
node_modules/eslint-plugin-github/lib/rules/a11y-svg-has-accessible-name.js
generated
vendored
Normal file
41
node_modules/eslint-plugin-github/lib/rules/a11y-svg-has-accessible-name.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
const {hasProp} = require('jsx-ast-utils')
|
||||
const {getElementType} = require('../utils/get-element-type')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
description: 'SVGs must have an accessible name',
|
||||
url: require('../url')(module),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
|
||||
create(context) {
|
||||
return {
|
||||
JSXOpeningElement: node => {
|
||||
const elementType = getElementType(context, node)
|
||||
if (elementType !== 'svg') return
|
||||
|
||||
// Check if there is a nested title element that is the first child of the `<svg>`
|
||||
const hasNestedTitleAsFirstChild =
|
||||
node.parent.children?.[0]?.type === 'JSXElement' &&
|
||||
node.parent.children?.[0]?.openingElement?.name?.name === 'title'
|
||||
|
||||
// Check if `aria-label` or `aria-labelledby` is set
|
||||
const hasAccessibleName = hasProp(node.attributes, 'aria-label') || hasProp(node.attributes, 'aria-labelledby')
|
||||
|
||||
// Check if SVG is decorative
|
||||
const isDecorative =
|
||||
hasProp(node.attributes, 'role', 'presentation') || hasProp(node.attributes, 'aria-hidden', 'true')
|
||||
|
||||
if (elementType === 'svg' && !hasAccessibleName && !isDecorative && !hasNestedTitleAsFirstChild) {
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
'`<svg>` must have an accessible name. Set `aria-label` or `aria-labelledby`, or nest a `<title>` element. However, if the `<svg>` is purely decorative, hide it with `aria-hidden="true"` or `role="presentation"`.',
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
101
node_modules/eslint-plugin-github/lib/rules/role-supports-aria-props.js
generated
vendored
101
node_modules/eslint-plugin-github/lib/rules/role-supports-aria-props.js
generated
vendored
@@ -1,101 +0,0 @@
|
||||
// @ts-check
|
||||
const {aria, elementRoles, roles} = require('aria-query')
|
||||
const {getProp, getPropValue, propName} = require('jsx-ast-utils')
|
||||
const {getElementType} = require('../utils/get-element-type')
|
||||
const ObjectMap = require('../utils/object-map')
|
||||
|
||||
// Clean-up `elementRoles` from `aria-query`
|
||||
const elementRolesMap = new ObjectMap()
|
||||
for (const [key, value] of elementRoles.entries()) {
|
||||
// - Remove unused `constraints` key
|
||||
delete key.constraints
|
||||
key.attributes = key.attributes?.filter(attribute => !('constraints' in attribute))
|
||||
// - Remove empty `attributes` key
|
||||
if (!key.attributes || key.attributes?.length === 0) {
|
||||
delete key.attributes
|
||||
}
|
||||
elementRolesMap.set(key, value)
|
||||
}
|
||||
// - Remove insufficiently-disambiguated `menuitem` entry
|
||||
elementRolesMap.delete({name: 'menuitem'})
|
||||
// - Disambiguate `menuitem` and `menu` roles by `type`
|
||||
elementRolesMap.set({name: 'menuitem', attributes: [{name: 'type', value: 'command'}]}, ['menuitem'])
|
||||
elementRolesMap.set({name: 'menuitem', attributes: [{name: 'type', value: 'radio'}]}, ['menuitemradio'])
|
||||
elementRolesMap.set({name: 'menuitem', attributes: [{name: 'type', value: 'toolbar'}]}, ['toolbar'])
|
||||
elementRolesMap.set({name: 'menu', attributes: [{name: 'type', value: 'toolbar'}]}, ['toolbar'])
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
description:
|
||||
'Enforce that elements with explicit or implicit roles defined contain only `aria-*` properties supported by that `role`.',
|
||||
url: require('../url')(module),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
|
||||
create(context) {
|
||||
return {
|
||||
JSXOpeningElement(node) {
|
||||
// Assemble a key for looking-up the element’s role in the `elementRolesMap`
|
||||
// - Get the element’s name
|
||||
const key = {name: getElementType(context, node)}
|
||||
// - Get the element’s disambiguating attributes
|
||||
for (const prop of ['aria-expanded', 'type', 'size', 'role', 'href', 'multiple', 'scope']) {
|
||||
// - Only provide `aria-expanded` when it’s required for disambiguation
|
||||
if (prop === 'aria-expanded' && key.name !== 'summary') continue
|
||||
const value = getPropValue(getProp(node.attributes, prop))
|
||||
if (value) {
|
||||
if (!('attributes' in key)) {
|
||||
key.attributes = []
|
||||
}
|
||||
if (prop === 'href') {
|
||||
key.attributes.push({name: prop})
|
||||
} else {
|
||||
key.attributes.push({name: prop, value})
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get the element’s explicit or implicit role
|
||||
const role = getPropValue(getProp(node.attributes, 'role')) ?? elementRolesMap.get(key)?.[0]
|
||||
|
||||
// Return early if role could not be determined
|
||||
if (!role) return
|
||||
|
||||
// Get allowed ARIA attributes:
|
||||
// - From the role itself
|
||||
let allowedProps = Object.keys(roles.get(role)?.props || {})
|
||||
// - From parent roles
|
||||
for (const parentRole of roles.get(role)?.superClass.flat() ?? []) {
|
||||
allowedProps = allowedProps.concat(Object.keys(roles.get(parentRole)?.props || {}))
|
||||
}
|
||||
// Dedupe, for performance
|
||||
allowedProps = Array.from(new Set(allowedProps))
|
||||
|
||||
// Get prohibited ARIA attributes:
|
||||
// - From the role itself
|
||||
let prohibitedProps = roles.get(role)?.prohibitedProps || []
|
||||
// - From parent roles
|
||||
for (const parentRole of roles.get(role)?.superClass.flat() ?? []) {
|
||||
prohibitedProps = prohibitedProps.concat(roles.get(parentRole)?.prohibitedProps || [])
|
||||
}
|
||||
// - From comparing allowed vs all ARIA attributes
|
||||
prohibitedProps = prohibitedProps.concat(aria.keys().filter(x => !allowedProps.includes(x)))
|
||||
// Dedupe, for performance
|
||||
prohibitedProps = Array.from(new Set(prohibitedProps))
|
||||
|
||||
for (const prop of node.attributes) {
|
||||
// Return early if prohibited ARIA attribute is set to an ignorable value
|
||||
if (getPropValue(prop) == null || prop.type === 'JSXSpreadAttribute') return
|
||||
|
||||
if (prohibitedProps?.includes(propName(prop))) {
|
||||
context.report({
|
||||
node,
|
||||
message: `The attribute ${propName(prop)} is not supported by the role ${role}.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user