add rule for mediaHasCaption and tests
MODIFY
packages/@romejs/diagnostics/categories.ts
packages/@romejs/diagnostics/categories.ts
@@ -149,6 +149,7 @@ type LintDiagnosticCategory =
| "lint/jsx-a11y/imgRedundantAlt"
| "lint/jsx-a11y/lang"
| "lint/jsx-a11y/mouseEventsHaveKeyEvents"
+ | "lint/jsx-a11y/mediaHasCaption"
| "lint/jsx-a11y/noAccessKey"
| "lint/jsx-a11y/noAutofocus"
| "lint/jsx-a11y/noDistractingElements"

MODIFY
packages/@romejs/diagnostics/descriptions.ts
packages/@romejs/diagnostics/descriptions.ts
@@ -303,6 +303,10 @@ export const descriptions = createMessages({
category: "lint/jsx-a11y/mouseEventsHaveKeyEvents",
message: `The mouse event <emphasis>${mouseEvent}</emphasis> should be paired with the event <emphasis>${keyboardEvent}</emphasis>`,
}),
+ JSX_A11Y_MEDIA_HAS_CAPTION: {
+ category: "lint/jsx-a11y/mediaHasCaption",
+ message: "<emphasis>audio</emphasis> and <emphasis>video</emphasis> elements should have <emphasis>track</emphasis> for captions",
+ },
REACT_NO_WILL_UPDATE_SET_STATE: {
category: "lint/react/noWillUpdateSetState",
message: "Avoid <emphasis>this.setState</emphasis> in <emphasis>componentWillUpdate</emphasis>",

MODIFY
packages/@romejs/js-compiler/lint/rules/index.ts
packages/@romejs/js-compiler/lint/rules/index.ts
@@ -63,6 +63,7 @@ import iframeHasTitle from "./jsx-a11y/iframeHasTitle";
import imgRedundantAlt from "./jsx-a11y/imgRedundantAlt";
import lang from "./jsx-a11y/lang";
import mouseEventsHaveKeyEvents from "./jsx-a11y/mouseEventsHaveKeyEvents";
+import mediaHasCaption from "./jsx-a11y/mediaHasCaption";
import noAccessKey from "./jsx-a11y/noAccessKey";
import noAutofocus from "./jsx-a11y/noAutofocus";
import noDistractingElements from "./jsx-a11y/noDistractingElements";
@@ -140,6 +141,7 @@ export const lintTransforms = [
imgRedundantAlt,
lang,
mouseEventsHaveKeyEvents,
+ mediaHasCaption,
noAccessKey,
noAutofocus,
noDistractingElements,

ADD
packages/@romejs/js-compiler/lint/rules/jsx-a11y/mediaHasCaption.test.ts
+import {test} from "rome";
+import {testLintMultiple} from "../testHelpers";
+
+test(
+ "audio and video element has caption",
+ async (t) => {
+ await testLintMultiple(
+ t,
+ [
+ // INVALID
+ "<audio {...props} />",
+ "<video {...props} />",
+ // VALID
+ "<audio><track kind='captions' {...props} /></audio>",
+ "<video><track kind='captions' {...props} /></video>",
+ "<video muted {...props} ></video>",
+ ],
+ {category: "lint/jsx-a11y/mediaHasCaption"},
+ );
+ },
+);

ADD
packages/@romejs/js-compiler/lint/rules/jsx-a11y/mediaHasCaption.ts
+import {Path, TransformExitResult} from "@romejs/js-compiler";
+import {descriptions} from "@romejs/diagnostics";
+import {JSXElement} from "@romejs/ast";
+import {hasJSXAttribute, isJSXElement} from "@romejs/js-ast-utils";
+
+function hasMuted(node: JSXElement): boolean {
+ return hasJSXAttribute(node, "muted");
+}
+
+function hasTrack(node: JSXElement): boolean {
+ return node.children.some((child) => isJSXElement(child, "track"));
+}
+
+export default {
+ name: "mediaHasCaption",
+ enter(path: Path): TransformExitResult {
+ const {node} = path;
+
+ if (!(isJSXElement(node, "video") || isJSXElement(node, "audio"))) {
+ return node;
+ }
+
+ if (isJSXElement(node, "video") && hasMuted(node)) {
+ return node;
+ }
+
+ if (!hasTrack(node)) {
+ path.context.addNodeDiagnostic(
+ node,
+ descriptions.LINT.JSX_A11Y_MEDIA_HAS_CAPTION,
+ );
+ }
+
+ return node;
+ },
+};

add rule for mediaHasCaption and tests