@github/axe-github
Advanced tools
| import type { Check, Rule } from 'axe-core'; | ||
| interface RuleOptions { | ||
| id: string; | ||
| excludeHidden?: boolean; | ||
| selector: string; | ||
| checks?: Array<(el: Element) => boolean>; | ||
| all?: string[]; | ||
| any?: string[]; | ||
| help: string; | ||
| helpUrl?: string; | ||
| } | ||
| export declare function createRule({ id, excludeHidden, selector, checks, all, any, help, helpUrl }: RuleOptions): void; | ||
| declare const _default: { | ||
| rules: Rule[]; | ||
| checks: Check[]; | ||
| }; | ||
| export default _default; |
| const interactiveElements = ['a[href]', 'button', 'summary', 'select', 'input:not([type=hidden])', 'textarea']; | ||
| const focusableElements = interactiveElements.concat(['[tabindex]']); | ||
| const generatedChecks = []; | ||
| const generatedRules = []; | ||
| createRule({ | ||
| id: 'menuitem-should-be-interactive', | ||
| selector: 'div[role="menuitem"], span[role="menuitem"], div[role="menuitemradio"], span[role="menuitemradio"], div[role="menuitemcheckbox"], span[role="menuitemcheckbox"]', | ||
| help: 'Menu items must be focusable. Use <button>, <a>, or <label tabindex="0">', | ||
| checks: [ | ||
| (el) => focusableElements.filter(s => el.matches(s)).length > 0 | ||
| ] | ||
| }); | ||
| createRule({ | ||
| id: 'empty-summary', | ||
| selector: 'summary', | ||
| help: 'Details summary element must have visible text', | ||
| any: ['has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none', 'non-empty-title'] | ||
| }); | ||
| createRule({ | ||
| id: 'submit-reset-button-must-be-in-form', | ||
| selector: 'button[type="submit"], button[type="reset"], input[type="submit"], input[type="reset"]', | ||
| help: 'Submit and reset buttons must be in a form', | ||
| checks: [ | ||
| el => { | ||
| const formId = el.getAttribute('form'); | ||
| return !!el.closest('form') || !!(formId && document.getElementById(formId)); | ||
| } | ||
| ] | ||
| }); | ||
| createRule({ | ||
| id: 'nested-forms', | ||
| selector: 'form', | ||
| help: 'Nested form is invalid HTML and should be avoided', | ||
| helpUrl: 'https://html.spec.whatwg.org/multipage/forms.html#the-form-element:concept-element-content-model', | ||
| checks: [ | ||
| el => { | ||
| return !(el.parentElement && el.parentElement.closest('form')); | ||
| } | ||
| ] | ||
| }); | ||
| createRule({ | ||
| id: 'avoid-both-disabled-and-aria-disabled', | ||
| selector: 'button, fieldset, input, optgroup, option, select, textarea', | ||
| help: '[aria-disabled] may be used in place of native HTML [disabled] to allow tab-focus on an otherwise ignored element. Setting both attributes is contradictory.', | ||
| helpUrl: 'https://www.w3.org/TR/html-aria/#docconformance-attr', | ||
| checks: [ | ||
| el => !(el.hasAttribute('aria-disabled') && el.hasAttribute('disabled')) | ||
| ] | ||
| }); | ||
| export function createRule({ id, excludeHidden = true, selector, checks = [], all = [], any = [], help, helpUrl = '' }) { | ||
| if (/[^,] /.test(selector)) { | ||
| console.warn('Try to avoid nested CSS selectors in `createRule`: %o', selector); | ||
| } | ||
| if (checks) { | ||
| checks.map((func, i) => { | ||
| const checkId = `${id}_${i}`; | ||
| if (all) | ||
| all.push(checkId); | ||
| generatedChecks.push({ | ||
| id: checkId, | ||
| evaluate: func, | ||
| metadata: { impact: 'critical' } | ||
| }); | ||
| }); | ||
| } | ||
| generatedRules.push({ id, excludeHidden, selector, all, any, metadata: { help, helpUrl }, tags: ['custom-github-rule'] }); | ||
| } | ||
| export default { | ||
| rules: generatedRules, | ||
| checks: generatedChecks | ||
| }; |
+1
-1
| { | ||
| "name": "@github/axe-github", | ||
| "version": "0.2.0", | ||
| "version": "0.3.0", | ||
| "description": "Custom rules and configuration recommendations for the `axe-core` library for GitHub projects", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
6688
104.21%5
66.67%88
Infinity%0
-100%1
Infinity%