├── .nvmrc ├── scripts ├── wpt │ ├── resources │ │ ├── testdriver-vendor.js │ │ ├── test │ │ │ ├── requirements.txt │ │ │ ├── tox.ini │ │ │ ├── tests │ │ │ │ ├── functional │ │ │ │ │ ├── worker-uncaught-single.js │ │ │ │ │ ├── worker-error.js │ │ │ │ │ ├── setup-function-worker.js │ │ │ │ │ ├── worker-uncaught-allow.js │ │ │ │ │ ├── single-page-test-no-assertions.html │ │ │ │ │ ├── single-page-test-no-body.html │ │ │ │ │ ├── single-page-test-pass.html │ │ │ │ │ ├── single-page-test-fail.html │ │ │ │ │ ├── api-tests-3.html │ │ │ │ │ ├── order.html │ │ │ │ │ ├── worker.js │ │ │ │ │ ├── uncaught-exception-handle.html │ │ │ │ │ ├── uncaught-exception-ignore.html │ │ │ │ │ ├── add_cleanup_count.html │ │ │ │ │ ├── add_cleanup_err.html │ │ │ │ │ ├── step_wait_func.html │ │ │ │ │ ├── log-insertion.html │ │ │ │ │ ├── add_cleanup_sync_queue.html │ │ │ │ │ ├── abortsignal.html │ │ │ │ │ ├── worker-dedicated-uncaught-allow.html │ │ │ │ │ ├── force_timeout.html │ │ │ │ │ ├── add_cleanup_err_multi.html │ │ │ │ │ ├── api-tests-2.html │ │ │ │ │ ├── add_cleanup_async_timeout.html │ │ │ │ │ ├── add_cleanup_async_bad_return.html │ │ │ │ │ ├── assert-throws-dom.html │ │ │ │ │ ├── iframe-consolidate-errors.html │ │ │ │ │ ├── worker-dedicated-uncaught-single.html │ │ │ │ │ ├── add_cleanup_async_rejection_after_load.html │ │ │ │ │ └── add_cleanup_bad_return.html │ │ │ │ └── unit │ │ │ │ │ ├── helpers.js │ │ │ │ │ ├── IdlInterface │ │ │ │ │ ├── get_qualified_name.html │ │ │ │ │ ├── get_legacy_namespace.html │ │ │ │ │ ├── get_interface_object_owner.html │ │ │ │ │ ├── get_interface_object.html │ │ │ │ │ ├── test_primary_interface_of_undefined.html │ │ │ │ │ ├── constructors.html │ │ │ │ │ ├── has_to_json_regular_operation.html │ │ │ │ │ └── should_have_interface_object.html │ │ │ │ │ ├── promise_setup-timeout.html │ │ │ │ │ ├── IdlDictionary │ │ │ │ │ └── test_partial_dictionary.html │ │ │ │ │ ├── IdlInterfaceMember │ │ │ │ │ ├── toString.html │ │ │ │ │ └── is_to_json_regular_operation.html │ │ │ │ │ ├── assert_implements.html │ │ │ │ │ ├── assert_implements_optional.html │ │ │ │ │ └── basic.html │ │ │ ├── harness.html │ │ │ └── idl-helper.js │ │ ├── META.yml │ │ ├── chromium │ │ │ ├── webusb-test.js.headers │ │ │ ├── webxr-test.js.headers │ │ │ ├── mock-barcodedetection.js.headers │ │ │ ├── mock-battery-monitor.headers │ │ │ ├── mock-facedetection.js.headers │ │ │ ├── mock-textdetection.js.headers │ │ │ ├── webusb-child-test.js.headers │ │ │ ├── web-bluetooth-test.js.headers │ │ │ ├── webxr-test-math-helper.js.headers │ │ │ ├── enable-hyperlink-auditing.js │ │ │ ├── content-index-helpers.js │ │ │ ├── README.md │ │ │ ├── webusb-child-test.js │ │ │ └── mock-battery-monitor.js │ │ ├── webidl2 │ │ │ ├── lib │ │ │ │ ├── webidl2.js.headers │ │ │ │ ├── VERSION.md │ │ │ │ └── README.md │ │ │ └── build.sh │ │ ├── idlharness.js.headers │ │ ├── test-only-api.js.headers │ │ ├── testdriver.js.headers │ │ ├── testharness.js.headers │ │ ├── test-only-api.m.js.headers │ │ ├── testdriver-actions.js.headers │ │ ├── testdriver-vendor.js.headers │ │ ├── testharnessreport.js.headers │ │ ├── .htaccess │ │ ├── out-of-scope-test.js │ │ ├── test-only-api.m.js │ │ ├── blank.html │ │ ├── readme.md │ │ ├── test-only-api.js │ │ ├── accesskey.js │ │ ├── testharnessreport.js │ │ ├── testharness-shadowrealm-inner.js │ │ └── testharness-shadowrealm-audioworkletprocessor.js │ ├── accname │ │ ├── manual │ │ │ ├── foo.jpg │ │ │ ├── test.png │ │ │ ├── name_test_case_600-manual.html │ │ │ ├── name_file-title-manual.html │ │ │ ├── name_text-title-manual.html │ │ │ ├── name_radio-title-manual.html │ │ │ ├── name_test_case_556-manual.html │ │ │ ├── name_test_case_607-manual.html │ │ │ ├── name_test_case_543-manual.html │ │ │ ├── name_test_case_559-manual.html │ │ │ ├── name_test_case_597-manual.html │ │ │ ├── name_test_case_601-manual.html │ │ │ ├── name_test_case_544-manual.html │ │ │ ├── name_test_case_608-manual.html │ │ │ ├── description_test_case_557-manual.html │ │ │ ├── name_checkbox-title-manual.html │ │ │ ├── name_image-title-manual.html │ │ │ ├── name_password-title-manual.html │ │ │ ├── name_test_case_751-manual.html │ │ │ ├── name_test_case_539-manual.html │ │ │ ├── name_test_case_545-manual.html │ │ │ ├── name_test_case_557-manual.html │ │ │ ├── name_test_case_604-manual.html │ │ │ ├── name_test_case_749-manual.html │ │ │ ├── name_test_case_750-manual.html │ │ │ ├── name_test_case_561-manual.html │ │ │ ├── name_test_case_551-manual.html │ │ │ ├── name_test_case_611-manual.html │ │ │ ├── name_test_case_614-manual.html │ │ │ ├── name_test_case_615-manual.html │ │ │ ├── name_test_case_616-manual.html │ │ │ ├── name_test_case_752-manual.html │ │ │ ├── name_test_case_612-manual.html │ │ │ ├── name_test_case_748-manual.html │ │ │ ├── name_test_case_613-manual.html │ │ │ ├── name_test_case_725-manual.html │ │ │ ├── name_test_case_596-manual.html │ │ │ ├── name_test_case_546-manual.html │ │ │ ├── name_test_case_558-manual.html │ │ │ ├── name_test_case_603-manual.html │ │ │ ├── name_test_case_721-manual.html │ │ │ └── name_test_case_723-manual.html │ │ └── name │ │ │ ├── comp_tooltip.tentative.html │ │ │ ├── shadowdom │ │ │ └── basic.html │ │ │ ├── comp_labeledby_non_standard.html │ │ │ └── comp_name_from_content_alt_counter_invalidation.html │ └── wai-aria │ │ ├── META.yml │ │ ├── idlharness.window.js │ │ ├── role │ │ ├── generic-roles.html │ │ ├── roles.tentative.html │ │ ├── ReadMe.md │ │ ├── list-roles.html │ │ ├── contextual-roles.tentative.html │ │ ├── form-roles.html │ │ ├── listbox-roles.tentative.html │ │ ├── region-roles.html │ │ ├── list-roles.tentative.html │ │ ├── tab-roles.tentative.html │ │ ├── tree-roles.tentative.html │ │ ├── basic.html │ │ ├── listbox-roles.html │ │ ├── grid-roles.tentative.html │ │ ├── synonym-roles.html │ │ └── button-roles.html │ │ └── scripts │ │ └── manual.css └── wpt-accname.js ├── .gitignore ├── pnpm-workspace.yaml ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── 03_feature.md │ ├── 02_bug.yml │ └── 01_spec.yml ├── pull_request_template.md └── workflows │ ├── release.yml │ └── ci.yml ├── .vscode ├── extensions.json └── settings.json ├── tsconfig.build.json ├── vitest.config.ts ├── .npmignore ├── .changeset └── config.json ├── src ├── get-elements.ts ├── is-name-required.ts ├── tags │ ├── li.ts │ ├── footer.ts │ ├── header.ts │ ├── aside.ts │ ├── td.ts │ └── select.ts ├── index.ts └── get-required-attributes.ts ├── tsconfig.json ├── biome.json ├── test └── node │ ├── html-aria.bench.ts │ └── utils.test.ts ├── vitest.workspace.ts ├── LICENSE └── package.json /.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testdriver-vendor.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | dist 3 | node_modules 4 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - esbuild 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/requirements.txt: -------------------------------------------------------------------------------- 1 | html5lib==1.1 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/META.yml: -------------------------------------------------------------------------------- 1 | suggested_reviewers: 2 | - jgraham 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["biomejs.biome"] 3 | } 4 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["test"] 4 | } 5 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/webusb-test.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/webxr-test.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/webidl2/lib/webidl2.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/mock-barcodedetection.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/mock-battery-monitor.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/mock-facedetection.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/mock-textdetection.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/webusb-child-test.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/web-bluetooth-test.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/webxr-test-math-helper.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | -------------------------------------------------------------------------------- /scripts/wpt/resources/webidl2/lib/VERSION.md: -------------------------------------------------------------------------------- 1 | Currently using webidl2.js@6889aee6fc7d65915ab1267825248157dbc50486. 2 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/foo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drwpow/html-aria/HEAD/scripts/wpt/accname/manual/foo.jpg -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drwpow/html-aria/HEAD/scripts/wpt/accname/manual/test.png -------------------------------------------------------------------------------- /scripts/wpt/resources/idlharness.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test-only-api.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testdriver.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testharness.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test-only-api.m.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testdriver-actions.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testdriver-vendor.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testharnessreport.js.headers: -------------------------------------------------------------------------------- 1 | Content-Type: text/javascript; charset=utf-8 2 | Cache-Control: max-age=3600 3 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | test: {}, 5 | }); 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | **/*.config.* 2 | .changeset 3 | .github 4 | .nvmrc 5 | .vscode 6 | biome.json 7 | tsconfig.* 8 | scripts 9 | src 10 | test 11 | -------------------------------------------------------------------------------- /scripts/wpt/resources/.htaccess: -------------------------------------------------------------------------------- 1 | # make tests that use utf-16 not inherit the encoding for testharness.js et. al. 2 | AddCharset utf-8 .css .js 3 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/META.yml: -------------------------------------------------------------------------------- 1 | spec: https://w3c.github.io/aria/ 2 | suggested_reviewers: 3 | - cookiecrook 4 | - spectranaut 5 | - jnurthen 6 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/enable-hyperlink-auditing.js: -------------------------------------------------------------------------------- 1 | if (window.testRunner) 2 | testRunner.overridePreference("WebKitHyperlinkAuditingEnabled", 1); 3 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Changes 2 | 3 | _What does this PR change? Link to any related issue(s)._ 4 | 5 | ## How to Review 6 | 7 | _How can a reviewer review your changes? What should be kept in mind for this review?_ 8 | 9 | ## Checklist 10 | 11 | - [ ] Unit tests updated 12 | -------------------------------------------------------------------------------- /scripts/wpt/resources/out-of-scope-test.js: -------------------------------------------------------------------------------- 1 | // Testing that the resolution is correct using `resolve`, as you can't import 2 | // the same module twice. 3 | window.outscope_test_result = import.meta.resolve("a"); 4 | window.outscope_test_result2 = import.meta.resolve("../resources/log.sub.js?name=E"); 5 | 6 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.2/schema.json", 3 | "changelog": ["@changesets/changelog-github", { "repo": "drwpow/html-aria" }], 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main" 9 | } 10 | -------------------------------------------------------------------------------- /scripts/wpt/resources/webidl2/lib/README.md: -------------------------------------------------------------------------------- 1 | This directory contains a built version of the [webidl2.js library](https://github.com/w3c/webidl2.js). 2 | It is built by running `npm run build-debug` at the root of that repository. 3 | 4 | The `webidl2.js.headers` file is a local addition to ensure the script is interpreted as UTF-8. 5 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test-only-api.m.js: -------------------------------------------------------------------------------- 1 | /* Whether the browser is Chromium-based with MojoJS enabled */ 2 | export const isChromiumBased = 'MojoInterfaceInterceptor' in self; 3 | 4 | /* Whether the browser is WebKit-based with internal test-only API enabled */ 5 | export const isWebKitBased = !isChromiumBased && 'internals' in self; 6 | -------------------------------------------------------------------------------- /scripts/wpt/resources/webidl2/build.sh: -------------------------------------------------------------------------------- 1 | set -ex 2 | 3 | if [ ! -d "webidl2.js" ]; then 4 | git clone https://github.com/w3c/webidl2.js.git 5 | fi 6 | cd webidl2.js 7 | npm install 8 | npm run build-debug 9 | HASH=$(git rev-parse HEAD) 10 | cd .. 11 | cp webidl2.js/dist/webidl2.js lib/ 12 | echo "Currently using webidl2.js@${HASH}." > lib/VERSION.md 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[javascript]": { 3 | "editor.defaultFormatter": "biomejs.biome" 4 | }, 5 | "[json]": { 6 | "editor.defaultFormatter": "biomejs.biome" 7 | }, 8 | "[markdown]": { 9 | "editor.defaultFormatter": "esbenp.prettier-vscode" 10 | }, 11 | "[typescript]": { 12 | "editor.defaultFormatter": "biomejs.biome" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/idlharness.window.js: -------------------------------------------------------------------------------- 1 | // META: script=/resources/WebIDLParser.js 2 | // META: script=/resources/idlharness.js 3 | 4 | 'use strict'; 5 | 6 | idl_test( 7 | ['wai-aria'], 8 | ['dom'], 9 | idl_array => { 10 | idl_array.add_objects({ 11 | Element: ['element'], 12 | }); 13 | self.element = document.createElementNS(null, "test"); 14 | } 15 | ); 16 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py38,py39,py310,py311 3 | skipsdist=True 4 | 5 | [testenv] 6 | passenv=DISPLAY # Necessary for the spawned GeckoDriver process to connect to 7 | # the appropriate display. 8 | 9 | deps = 10 | -r{toxinidir}/../../tools/requirements_pytest.txt 11 | -r{toxinidir}/requirements.txt 12 | 13 | commands = pytest -vv {posargs} 14 | -------------------------------------------------------------------------------- /src/get-elements.ts: -------------------------------------------------------------------------------- 1 | import { roles } from './lib/aria-roles.js'; 2 | import type { ARIARole, VirtualElement } from './types.js'; 3 | 4 | /** 5 | * Return the representation(s) of a role in HTML, if any. 6 | */ 7 | export function getElements(role: ARIARole): VirtualElement[] | undefined { 8 | const elements = roles[role]?.elements; 9 | return elements?.length ? elements : undefined; 10 | } 11 | -------------------------------------------------------------------------------- /src/is-name-required.ts: -------------------------------------------------------------------------------- 1 | import { roles } from './lib/aria-roles.js'; 2 | import type { ARIARole } from './types.js'; 3 | 4 | /** 5 | * Given an ARIA role, return whether or not an accessible name is required. 6 | * @see https://www.w3.org/TR/wai-aria-1.3/#namecalculation 7 | */ 8 | export function isNameRequired(role: ARIARole): boolean { 9 | return roles[role]?.nameRequired ?? false; 10 | } 11 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/worker-uncaught-single.js: -------------------------------------------------------------------------------- 1 | importScripts("/resources/testharness.js"); 2 | 3 | setup({ single_test: true }); 4 | 5 | // Because this script enables the `single_test` configuration option, it 6 | // should be interpreted as a single-page test, and the uncaught exception 7 | // should be reported as a test failure (harness status: OK). 8 | throw new Error("This failure is expected."); 9 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/content-index-helpers.js: -------------------------------------------------------------------------------- 1 | import {ContentIndexService} from '/gen/third_party/blink/public/mojom/content_index/content_index.mojom.m.js'; 2 | 3 | // Returns a promise if the chromium based browser fetches icons for 4 | // content-index. 5 | export async function fetchesIcons() { 6 | const remote = ContentIndexService.getRemote(); 7 | const {iconSizes} = await remote.getIconSizes(); 8 | return iconSizes.length > 0; 9 | }; 10 | -------------------------------------------------------------------------------- /src/tags/li.ts: -------------------------------------------------------------------------------- 1 | import { type RoleData, roles } from '../lib/aria-roles.js'; 2 | import { hasListParent } from '../lib/util.js'; 3 | import type { VirtualAncestorList, VirtualElement } from '../types.js'; 4 | 5 | export function getLIRole( 6 | element: Element | VirtualElement, 7 | options?: { ancestors?: VirtualAncestorList }, 8 | ): RoleData | undefined { 9 | return hasListParent(element, options?.ancestors) ? roles.listitem : roles.generic; 10 | } 11 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/README.md: -------------------------------------------------------------------------------- 1 | This directory contains Chromium-specific test resources, including mocks for 2 | test-only APIs implemented with 3 | [MojoJS](https://chromium.googlesource.com/chromium/src/+/main/mojo/public/js/README.md). 4 | 5 | Please do **not** copy `*.mojom.m.js` into this directory. Follow this doc if you 6 | want to add new MojoJS-backed mocks: 7 | https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_platform_tests.md#mojojs 8 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/worker-error.js: -------------------------------------------------------------------------------- 1 | importScripts("/resources/testharness.js"); 2 | 3 | // The following sub-test ensures that the worker is not interpreted as a 4 | // single-page test. The subsequent uncaught exception should therefore be 5 | // interpreted as a harness error rather than a single-page test failure. 6 | test(function() {}, "worker test that completes successfully before exception"); 7 | 8 | throw new Error("This failure is expected."); 9 | -------------------------------------------------------------------------------- /scripts/wpt/resources/blank.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blank Page 6 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/tags/footer.ts: -------------------------------------------------------------------------------- 1 | import { type RoleData, roles } from '../lib/aria-roles.js'; 2 | import { tags } from '../lib/html.js'; 3 | import { hasLandmarkParent } from '../lib/util.js'; 4 | import type { VirtualAncestorList, VirtualElement } from '../types.js'; 5 | 6 | export function getFooterRole( 7 | element: Element | VirtualElement, 8 | options?: { ancestors?: VirtualAncestorList }, 9 | ): RoleData | undefined { 10 | return hasLandmarkParent(element, options?.ancestors) ? roles.generic : roles[tags.footer.defaultRole!]; 11 | } 12 | -------------------------------------------------------------------------------- /src/tags/header.ts: -------------------------------------------------------------------------------- 1 | import { type RoleData, roles } from '../lib/aria-roles.js'; 2 | import { tags } from '../lib/html.js'; 3 | import { hasLandmarkParent } from '../lib/util.js'; 4 | import type { VirtualAncestorList, VirtualElement } from '../types.js'; 5 | 6 | export function getHeaderRole( 7 | element: Element | VirtualElement, 8 | options?: { ancestors?: VirtualAncestorList }, 9 | ): RoleData | undefined { 10 | return hasLandmarkParent(element, options?.ancestors) ? roles.generic : roles[tags.header.defaultRole!]; 11 | } 12 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './get-acc-name.js'; 2 | export * from './get-elements.js'; 3 | export * from './get-required-attributes.js'; 4 | export * from './get-role.js'; 5 | export * from './get-supported-attributes.js'; 6 | export * from './get-supported-roles.js'; 7 | export * from './is-interactive.js'; 8 | export * from './is-name-required.js'; 9 | export * from './lib/aria-attributes.js'; 10 | export * from './lib/aria-roles.js'; 11 | export * from './lib/html.js'; 12 | export * from './lib/util.js'; 13 | export type * from './types.js'; 14 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/setup-function-worker.js: -------------------------------------------------------------------------------- 1 | importScripts("/resources/testharness.js"); 2 | 3 | // Regression test for https://github.com/web-platform-tests/wpt/issues/27299, 4 | // where we broke the ability for a setup function in a worker to contain an 5 | // assertion (even a passing one). 6 | setup(function() { 7 | assert_true(true, "True is true"); 8 | }); 9 | 10 | // We must define at least one test for the harness, though it is not what we 11 | // are testing here. 12 | test(function() { 13 | assert_false(false, "False is false"); 14 | }, 'Worker test'); 15 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/worker-uncaught-allow.js: -------------------------------------------------------------------------------- 1 | importScripts("/resources/testharness.js"); 2 | 3 | setup({allow_uncaught_exception:true}); 4 | 5 | async_test(function(t) { 6 | onerror = function() { 7 | // Further delay the test's completion to ensure that the worker's 8 | // `onerror` handler does not influence results in the parent context. 9 | setTimeout(function() { 10 | t.done(); 11 | }, 0); 12 | }; 13 | 14 | setTimeout(function() { 15 | throw new Error("This error is expected."); 16 | }, 0); 17 | }, 'onerror event is triggered'); 18 | 19 | done(); 20 | -------------------------------------------------------------------------------- /src/get-required-attributes.ts: -------------------------------------------------------------------------------- 1 | import { roles } from './lib/aria-roles.js'; 2 | import type { ARIAAttribute, ARIARole } from './types.js'; 3 | 4 | /** Given an HTML element, returns a list of required aria-* attributes for that element */ 5 | export function getRequiredAttributes(role: ARIARole): ARIAAttribute[] { 6 | return roles[role]?.required ?? []; 7 | } 8 | 9 | /** Helper function for getRequiredttributes that returns a boolean instead */ 10 | export function isRequiredAttribute(attribute: string, role: ARIARole): boolean { 11 | return getRequiredAttributes(role).includes(attribute as ARIAAttribute); 12 | } 13 | -------------------------------------------------------------------------------- /scripts/wpt/resources/readme.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | This directory contains utilities intended for use by tests and maintained as project infrastructure. 4 | It does not contain tests. 5 | 6 | ## `testharness.js` 7 | 8 | `testharness.js` is a framework for writing low-level tests of 9 | browser functionality in javascript. It provides a convenient API for 10 | making assertions and is intended to work for both simple synchronous 11 | tests, and tests of asynchronous behaviour. 12 | 13 | Complete documentation is available in the `docs/` directory of this repository 14 | and on the web at https://web-platform-tests.org/writing-tests/. 15 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/harness.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationMap": true, 5 | "erasableSyntaxOnly": true, 6 | "lib": ["DOM", "ESNext"], 7 | "module": "NodeNext", 8 | "moduleResolution": "nodenext", 9 | "noFallthroughCasesInSwitch": true, 10 | "noUncheckedIndexedAccess": true, 11 | "noUnusedLocals": true, 12 | "noUnusedParameters": true, 13 | "outDir": "dist", 14 | "sourceMap": true, 15 | "strict": true, 16 | "target": "ESNext", 17 | "types": ["@vitest/browser/providers/playwright"], 18 | "verbatimModuleSyntax": true 19 | }, 20 | "include": ["src"], 21 | "exclude": ["dist", "node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /src/tags/aside.ts: -------------------------------------------------------------------------------- 1 | import { type RoleData, roles } from '../lib/aria-roles.js'; 2 | import { tags } from '../lib/html.js'; 3 | import { hasSectioningContentParent } from '../lib/util.js'; 4 | import type { VirtualAncestorList, VirtualElement } from '../types.js'; 5 | 6 | /** 7 | * @see https://www.w3.org/TR/html-aam-1.0/#el-aside-ancestorbodymain 8 | * @see https://www.w3.org/TR/html-aam-1.0/#el-aside 9 | */ 10 | export function getAsideRole( 11 | element: Element | VirtualElement, 12 | options?: { ancestors?: VirtualAncestorList }, 13 | ): RoleData | undefined { 14 | return hasSectioningContentParent(element, options?.ancestors) ? roles.generic : roles[tags.aside.defaultRole!]; 15 | } 16 | -------------------------------------------------------------------------------- /src/tags/td.ts: -------------------------------------------------------------------------------- 1 | import { type RoleData, roles } from '../lib/aria-roles.js'; 2 | import { NO_CORRESPONDING_ROLE } from '../lib/html.js'; 3 | import { hasGridParent, hasTableParent } from '../lib/util.js'; 4 | import type { VirtualAncestorList, VirtualElement } from '../types.js'; 5 | 6 | /** Special behavior for element */ 7 | export function getTDRole( 8 | element: Element | VirtualElement, 9 | options?: { ancestors?: VirtualAncestorList }, 10 | ): RoleData | undefined { 11 | if (hasGridParent(element, options?.ancestors)) { 12 | return roles.gridcell; 13 | } 14 | if (hasTableParent(element, options?.ancestors)) { 15 | return roles.cell; 16 | } 17 | return NO_CORRESPONDING_ROLE; 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/03_feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ✨ Feature 3 | about: Proposing additional functionality for html-aria 4 | labels: 5 | - feature 6 | - triage 7 | --- 8 | 9 | ## Proposal 10 | 11 | ### Summary 12 | 13 | _Give a short summary of your proposed feature in a few sentences._ 14 | 15 | ### Detail 16 | 17 | _What are the advantages of this? How does this work in detail?_ 18 | 19 | ### Example 20 | 21 | _Give an example usage of this feature (pseudocode is OK)._ 22 | 23 | ## Tradeoffs / breaking changes 24 | 25 | _What would accepting this feature take away? Would this cause any breaking changes?_ 26 | 27 | ## Alternatives considered 28 | 29 | _What are the alternatives to your feature you considered?_ 30 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/single-page-test-no-assertions.html: -------------------------------------------------------------------------------- 1 | 2 | Example single page test with no asserts 3 | 4 | 5 | 9 | 26 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/helpers.js: -------------------------------------------------------------------------------- 1 | // Helper for testing assertion failure cases for a testharness.js API 2 | // 3 | // The `assert_throws_*` functions cannot be used for this purpose because they 4 | // always fail in response to AssertionError exceptions, even when this is 5 | // expressed as the expected error. 6 | function test_failure(fn, name) { 7 | test(function() { 8 | try { 9 | fn(); 10 | } catch (err) { 11 | if (err instanceof AssertionError) { 12 | return; 13 | } 14 | throw new AssertionError('Expected an AssertionError, but' + err); 15 | } 16 | throw new AssertionError( 17 | 'Expected an AssertionError, but no error was thrown' 18 | ); 19 | }, name); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/single-page-test-no-body.html: -------------------------------------------------------------------------------- 1 | 2 | Example single page test with no body 3 | 4 | 5 | 10 | 27 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/single-page-test-pass.html: -------------------------------------------------------------------------------- 1 | 2 | Example with file_is_test 3 | 4 | 5 | 12 | 29 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/idl-helper.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var typedefFrom = interfaceFrom; 4 | var dictionaryFrom = interfaceFrom; 5 | function interfaceFrom(i) { 6 | var idl = new IdlArray(); 7 | idl.add_idls(i); 8 | for (var prop in idl.members) { 9 | return idl.members[prop]; 10 | } 11 | } 12 | 13 | function memberFrom(m) { 14 | var idl = new IdlArray(); 15 | idl.add_idls('interface A { ' + m + '; };'); 16 | return idl.members["A"].members[0]; 17 | } 18 | 19 | function typeFrom(type) { 20 | var ast = WebIDL2.parse('interface Foo { ' + type + ' a(); };'); 21 | ast = ast[0]; // get the first fragment 22 | ast = ast.members[0]; // get the first member 23 | return ast.idlType; // get the type of the first field 24 | } 25 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/generic-roles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generic Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests generic.

15 | 16 |

x

17 | 18 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/single-page-test-fail.html: -------------------------------------------------------------------------------- 1 | 2 | Example with file_is_test (should fail) 3 | 4 | 5 | 12 | 29 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | changelog: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | pull-requests: write 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: actions/setup-node@v4 17 | with: 18 | node-version: 22 19 | - uses: pnpm/action-setup@v4 20 | with: 21 | run_install: true 22 | - run: pnpm run build 23 | - uses: changesets/action@v1 24 | with: 25 | version: pnpm run version 26 | publish: pnpm exec changeset publish 27 | commit: "[ci] release" 28 | title: "[ci] release" 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 32 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/get_qualified_name.html: -------------------------------------------------------------------------------- 1 | 2 | IdlInterface.prototype.get_qualified_name() 3 |
4 | 5 | 6 | 7 | 8 | 9 | 21 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/get_legacy_namespace.html: -------------------------------------------------------------------------------- 1 | 2 | IdlInterface.prototype.get_legacy_namespace() 3 |
4 | 5 | 6 | 7 | 8 | 9 | 21 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/api-tests-3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sample HTML5 API Tests 5 | 6 | 7 | 8 | 9 |

Sample HTML5 API Tests

10 |
11 | 16 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/promise_setup-timeout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | promise_setup - timeout 9 | 10 | 11 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/order.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Ordering 5 | 6 | 7 | 8 |
9 | 10 | 11 | 15 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/02_bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: I encountered an error when using this library that is NOT specification related 3 | title: 🐛 Bug 4 | labels: 5 | - bug 6 | - triage 7 | body: 8 | - type: textarea 9 | id: output 10 | attributes: 11 | label: Output 12 | description: What is the error message or output you received? 13 | validations: 14 | required: true 15 | - type: textarea 16 | id: expected 17 | attributes: 18 | label: Expected 19 | description: What were you expecting? 20 | validations: 21 | required: true 22 | - type: textarea 23 | id: notes 24 | attributes: 25 | label: Notes 26 | description: Any other additional information or comments? 27 | - type: checkboxes 28 | id: checkboxes 29 | attributes: 30 | label: Contributing 31 | options: 32 | - label: I am willing to open a Pull Request 33 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/2.1.2/schema.json", 3 | "vcs": { 4 | "enabled": false, 5 | "clientKind": "git", 6 | "useIgnoreFile": false 7 | }, 8 | "files": { 9 | "ignoreUnknown": false, 10 | "includes": ["**", "!**/dist/**", "!**/package.json", "!**/scripts/wpt"] 11 | }, 12 | "formatter": { 13 | "enabled": true, 14 | "indentStyle": "space", 15 | "lineWidth": 120 16 | }, 17 | "assist": { 18 | "actions": { 19 | "source": { 20 | "organizeImports": "on" 21 | } 22 | } 23 | }, 24 | "linter": { 25 | "enabled": true, 26 | "rules": { 27 | "recommended": true, 28 | "style": { 29 | "noNonNullAssertion": "off" 30 | }, 31 | "suspicious": { 32 | "useGuardForIn": "error" 33 | } 34 | } 35 | }, 36 | "javascript": { 37 | "formatter": { 38 | "quoteStyle": "single" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/get_interface_object_owner.html: -------------------------------------------------------------------------------- 1 | 2 | IdlInterface.prototype.get_interface_object_owner() 3 |
4 | 5 | 6 | 7 | 8 | 9 | 22 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/worker.js: -------------------------------------------------------------------------------- 1 | importScripts("/resources/testharness.js"); 2 | 3 | test( 4 | function(test) { 5 | assert_true(true, "True is true"); 6 | }, 7 | "Worker test that completes successfully"); 8 | 9 | test( 10 | function(test) { 11 | assert_true(false, "Failing test"); 12 | }, 13 | "Worker test that fails ('FAIL')"); 14 | 15 | async_test( 16 | function(test) { 17 | assert_true(true, "True is true"); 18 | }, 19 | "Worker test that times out ('TIMEOUT')"); 20 | 21 | async_test("Worker test that doesn't run ('NOT RUN')"); 22 | 23 | async_test( 24 | function(test) { 25 | self.setTimeout( 26 | function() { 27 | test.done(); 28 | }, 29 | 0); 30 | }, 31 | "Worker async_test that completes successfully"); 32 | 33 | // An explicit done() is required for dedicated and shared web workers. 34 | done(); 35 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/get_interface_object.html: -------------------------------------------------------------------------------- 1 | 2 | IdlInterface.prototype.get_interface_object() 3 |
4 | 5 | 6 | 7 | 8 | 9 | 23 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/roles.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | New Core ARIA Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests new ARIA role definitions. See comments for more info.

15 | 16 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/uncaught-exception-handle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Harness Handling Uncaught Exception 5 | 6 | 7 | 8 | 9 |

Harness Handling Uncaught Exception

10 |
11 | 15 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /test/node/html-aria.bench.ts: -------------------------------------------------------------------------------- 1 | import { elementRoles } from 'aria-query'; 2 | import { getRole as domAccessibilityApiGetRole } from 'dom-accessibility-api'; 3 | import { bench, describe } from 'vitest'; 4 | import { getRole } from '../../src/index.js'; 5 | 6 | describe('getRole (virtual)', () => { 7 | bench('html-aria', () => { 8 | getRole({ tagName: 'input', attributes: { type: 'checkbox' } }); 9 | }); 10 | 11 | bench('aria-query', () => { 12 | elementRoles.get({ 13 | name: 'input', 14 | attributes: [{ name: 'type', value: 'checkbox' }], 15 | }); 16 | }); 17 | }); 18 | 19 | if (typeof document !== 'undefined') { 20 | describe('getRole (HTMLElement)', () => { 21 | const element = document.createElement('input'); 22 | element.type = 'checkbox'; 23 | 24 | bench('html-aria', () => { 25 | getRole(element); 26 | }); 27 | 28 | bench('dom-accessibility-api', () => { 29 | domAccessibilityApiGetRole(element); 30 | }); 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/ReadMe.md: -------------------------------------------------------------------------------- 1 | 2 | # WPT Roles Tests 3 | 4 | /wai-aria/roles/ includes various files broken up by test type 5 | 6 | - **roles.html** covers simple assignment/verification of most core WAI-ARIA roles, and includes a list of cross-references to other specific files and spec directories. 7 | - role testing of *host language* implicit roles (E.g., `
-> main`) are in other directories (E.g., [html-aam](https://github.com/web-platform-tests/interop-accessibility/issues/13)) 8 | - role testing of **ARIA extension specs** are in other directories (E.g., [graphics-aria](https://github.com/web-platform-tests/interop-accessibility/issues/9)) 9 | - basic.html was the first to ensure basic test coverage of webdriver getcomputedrole 10 | - other context-dependent role tests, error handling, and edge cases are covered in separate files 11 | - list-roles.html 12 | - region-roles.html 13 | - grid, listbox, menu, tree, etc 14 | - fallback roles 15 | - invalid roles 16 | - error handling, etc. 17 | -------------------------------------------------------------------------------- /vitest.workspace.ts: -------------------------------------------------------------------------------- 1 | import { defineWorkspace } from 'vitest/config'; 2 | 3 | export default defineWorkspace([ 4 | { 5 | test: { 6 | name: 'node', 7 | include: ['./test/node/**/*.test.ts'], 8 | environment: 'node', 9 | }, 10 | }, 11 | { 12 | test: { 13 | name: 'jsdom', 14 | include: ['./test/dom/**/*.test.ts'], 15 | exclude: ['./test/dom/get-acc-name.test.ts'], // this doesn’t have full browser APIs 16 | environment: 'jsdom', 17 | }, 18 | }, 19 | { 20 | test: { 21 | name: 'happy-dom', 22 | include: ['./test/dom/**/*.test.ts'], 23 | exclude: ['./test/dom/get-acc-name.test.ts'], // this doesn’t have full browser APIs 24 | environment: 'happy-dom', 25 | }, 26 | }, 27 | { 28 | test: { 29 | name: 'browser', 30 | include: ['./test/dom/**/*.test.ts'], 31 | browser: { 32 | provider: 'playwright', 33 | enabled: true, 34 | instances: [{ browser: 'chromium' }], 35 | }, 36 | }, 37 | }, 38 | ]); 39 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/list-roles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | List-related Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests list and related roles.

15 | 16 |
17 |
x
18 |
x
19 |
20 | 21 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/contextual-roles.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tentative: Contextual Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 |
19 |
x
20 |
21 |
22 |
x
23 |
24 | 25 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/uncaught-exception-ignore.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Harness Ignoring Uncaught Exception 5 | 6 | 7 | 8 | 9 |

Harness Ignoring Uncaught Exception

10 |
11 | 17 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlDictionary/test_partial_dictionary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | idlharness: partial dictionaries 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | dictionary A {};
17 | partial dictionary A {
18 |   boolean B;
19 | };
20 | partial dictionary A {
21 |   boolean C;
22 | };
23 | 
24 | 25 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /scripts/wpt/accname/name/comp_tooltip.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name Comp: Tooltip (Tentative) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests the tentative #comp_tooltip portions of the AccName Name Computation algorithm.

15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test-only-api.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* Whether the browser is Chromium-based with MojoJS enabled */ 4 | const isChromiumBased = 'MojoInterfaceInterceptor' in self; 5 | /* Whether the browser is WebKit-based with internal test-only API enabled */ 6 | const isWebKitBased = !isChromiumBased && 'internals' in self; 7 | 8 | /** 9 | * Loads a script in a window or worker. 10 | * 11 | * @param {string} path - A script path 12 | * @returns {Promise} 13 | */ 14 | function loadScript(path) { 15 | if (typeof document === 'undefined') { 16 | // Workers (importScripts is synchronous and may throw.) 17 | importScripts(path); 18 | return Promise.resolve(); 19 | } else { 20 | // Window 21 | const script = document.createElement('script'); 22 | script.src = path; 23 | script.async = false; 24 | const p = new Promise((resolve, reject) => { 25 | script.onload = () => { resolve(); }; 26 | script.onerror = e => { reject(`Error loading ${path}`); }; 27 | }) 28 | document.head.appendChild(script); 29 | return p; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/form-roles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Form Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Verifies 9.1 Roles - handling author errors and the form role.

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/test_primary_interface_of_undefined.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | idlharness test_primary_interface_of_undefined 6 | 7 | 8 | 9 | 10 | 11 | 12 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/listbox-roles.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tentative: Listbox-related Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 23 | 24 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Drew Powers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/constructors.html: -------------------------------------------------------------------------------- 1 | 2 | IdlInterface.prototype.constructors() 3 |
4 | 5 | 6 | 7 | 8 | 9 | 27 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/region-roles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Region Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests region and related roles, as well as the "name from author" rule in 9.1 Roles - handling author errors.

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_count.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup reported count 5 | 6 | 7 | 8 | 9 |
10 | 11 | 21 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/list-roles.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tentative: List-related Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 |
x
21 |

x

22 | 23 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/tab-roles.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tentative: Tab-related Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | x 22 | 23 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/tree-roles.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tentative: Tree related Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 17 | 18 |
19 |

test heading

20 | 34 | -------------------------------------------------------------------------------- /src/tags/select.ts: -------------------------------------------------------------------------------- 1 | import { type RoleData, roles } from '../lib/aria-roles.js'; 2 | import { tags } from '../lib/html.js'; 3 | import { attr } from '../lib/util.js'; 4 | import type { ARIARole, VirtualElement } from '../types.js'; 5 | 6 | export function getSelectRole(element: Element | VirtualElement): RoleData | undefined { 7 | const size = normalizeSize(attr(element, 'size')); 8 | const multiple = attr(element, 'multiple'); 9 | if ((size && size > 1) || typeof multiple === 'string' || typeof multiple === 'boolean') { 10 | return roles.listbox; 11 | } 12 | return roles[tags.select.defaultRole!]; 13 | } 14 | 15 | export function getSelectSupportedRoles(element: Element | VirtualElement): ARIARole[] { 16 | const size = normalizeSize(attr(element, 'size')); 17 | const multiple = attr(element, 'multiple'); 18 | if ((size && size > 1) || typeof multiple === 'string' || typeof multiple === 'boolean') { 19 | return ['listbox']; 20 | } 21 | return tags.select.supportedRoles; 22 | } 23 | 24 | function normalizeSize(size: unknown): number | undefined { 25 | if (typeof size === 'number') { 26 | return size; 27 | } 28 | if (typeof size === 'string' && size !== '') { 29 | return Number.parseFloat(size) || 0; 30 | } 31 | return undefined; 32 | } 33 | -------------------------------------------------------------------------------- /scripts/wpt-accname.js: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import path from 'node:path'; 3 | import { fileURLToPath } from 'node:url'; 4 | import { glob } from 'tinyglobby'; 5 | 6 | const TEST_FILE = new URL('../test/dom/get-accdescription.test.ts', import.meta.url); 7 | const WANT_MATCH = /"property",\n\s+"accDescription",\n\s+"is",\n\s+"([^"]+)"/; 8 | const WPT_DIR = new URL('./wpt/', import.meta.url); 9 | 10 | async function main() { 11 | const tests = await glob('accname/**/*.html', { cwd: fileURLToPath(WPT_DIR), absolute: true }); 12 | 13 | const testcases = []; 14 | 15 | for (const testfile of tests) { 16 | const contents = fs.readFileSync(testfile, 'utf8'); 17 | const want = contents.match(WANT_MATCH)?.[1]; 18 | let html = contents.substring(contents.indexOf('

') + '

'.length).trim(); 19 | html = html.substring(0, html.indexOf('
')).trim(); 20 | 21 | testcases.push([ 22 | path.basename(testfile).replace(/\.html$/, ''), 23 | { 24 | given: [html, '#test'], 25 | want, 26 | }, 27 | ]); 28 | } 29 | 30 | // this just shoves them at the end. cuz I need to format anyway 31 | const old = fs.readFileSync(TEST_FILE, 'utf8'); 32 | fs.writeFileSync(TEST_FILE, `${old}${JSON.stringify(testcases)}`); 33 | } 34 | 35 | main(); 36 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_err.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup: error 5 | 6 | 7 | 8 | 9 |
10 | 21 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/has_to_json_regular_operation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IdlInterface.prototype.has_to_json_regular_operation() 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterfaceMember/toString.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IdlInterfaceMember.prototype.toString() 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/step_wait_func.html: -------------------------------------------------------------------------------- 1 | 2 | Tests for step_wait_func and step_wait_func_done 3 | 4 | 5 |
6 | 27 | 50 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterface/should_have_interface_object.html: -------------------------------------------------------------------------------- 1 | 2 | IdlInterface.prototype.should_have_interface_object() 3 |
4 | 5 | 6 | 7 | 8 | 9 | 31 | -------------------------------------------------------------------------------- /scripts/wpt/resources/accesskey.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Function that sends an accesskey using the proper key combination depending on the browser and OS. 3 | * 4 | * This needs that the test imports the following scripts: 5 | * 6 | * 7 | * 8 | */ 9 | function pressAccessKey(accessKey){ 10 | let controlKey = '\uE009'; // left Control key 11 | let altKey = '\uE00A'; // left Alt key 12 | let optionKey = altKey; // left Option key 13 | let shiftKey = '\uE008'; // left Shift key 14 | // There are differences in using accesskey across browsers and OS's. 15 | // See: // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey 16 | let isMacOSX = navigator.userAgent.indexOf("Mac") != -1; 17 | let osAccessKey = isMacOSX ? [controlKey, optionKey] : [shiftKey, altKey]; 18 | let actions = new test_driver.Actions(); 19 | // Press keys. 20 | for (let key of osAccessKey) { 21 | actions = actions.keyDown(key); 22 | } 23 | actions = actions 24 | .keyDown(accessKey) 25 | .addTick() 26 | .keyUp(accessKey); 27 | osAccessKey.reverse(); 28 | for (let key of osAccessKey) { 29 | actions = actions.keyUp(key); 30 | } 31 | return actions.send(); 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/assert_implements.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | assert_implements unittests 8 | 44 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testharnessreport.js: -------------------------------------------------------------------------------- 1 | /* global add_completion_callback */ 2 | /* global setup */ 3 | 4 | /* 5 | * This file is intended for vendors to implement code needed to integrate 6 | * testharness.js tests with their own test systems. 7 | * 8 | * Typically test system integration will attach callbacks when each test has 9 | * run, using add_result_callback(callback(test)), or when the whole test file 10 | * has completed, using 11 | * add_completion_callback(callback(tests, harness_status)). 12 | * 13 | * For more documentation about the callback functions and the 14 | * parameters they are called with see testharness.js 15 | */ 16 | 17 | /* If the parent window has a testharness_properties object, 18 | * we use this to provide the test settings. This is used by the 19 | * default in-browser runner to configure the timeout and the 20 | * rendering of results 21 | */ 22 | try { 23 | if (window.opener && "testharness_properties" in window.opener) { 24 | /* If we pass the testharness_properties object as-is here without 25 | * JSON stringifying and reparsing it, IE fails & emits the message 26 | * "Could not complete the operation due to error 80700019". 27 | */ 28 | setup(JSON.parse(JSON.stringify(window.opener.testharness_properties))); 29 | } 30 | } catch (e) { 31 | } 32 | // vim: set expandtab shiftwidth=4 tabstop=4: 33 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/log-insertion.html: -------------------------------------------------------------------------------- 1 | 2 | Log insertion 3 | 4 | 5 | 22 | 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/01_spec.yml: -------------------------------------------------------------------------------- 1 | name: Specification issue 2 | description: This library doesn’t match the W3C specification 3 | title: 📝 Spec issue 4 | labels: 5 | - bug 6 | - spec 7 | - triage 8 | body: 9 | - type: markdown 10 | attributes: 11 | value: | 12 | You’re opening an issue because this library disagrees with the [ARIA in 13 | HTML](https://www.w3.org/TR/html-aria/) specification, [WAI ARIA 14 | 1.3](https://www.w3.org/TR/wai-aria-1.3), or a related document. 15 | - type: textarea 16 | id: specs 17 | attributes: 18 | label: Specification reference(s) 19 | description: Which specification(s) are you looking at? Please list all specs. Include section 20 | placeholder: | 21 | - [document 1, section 5.3.1](https://www.w3.org) 22 | - [document 2, section 4.3.1](https://www.w3.org) 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: output 27 | attributes: 28 | label: Output 29 | description: What did this library produce? What were you expecting? 30 | validations: 31 | required: true 32 | - type: textarea 33 | id: notes 34 | attributes: 35 | label: Notes 36 | description: Any other additional information or comments? 37 | - type: checkboxes 38 | id: checkboxes 39 | attributes: 40 | label: Contributing 41 | options: 42 | - label: I am willing to open a Pull Request 43 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_sync_queue.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup: queuing tests 5 | 6 | 7 | 8 | 9 |
10 | 11 | 31 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/abortsignal.html: -------------------------------------------------------------------------------- 1 | 2 | Test#get_signal 3 | 4 | 5 | 27 | 50 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/worker-dedicated-uncaught-allow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dedicated Worker Tests - Allowed Uncaught Exception 5 | 6 | 7 | 8 | 9 |

Dedicated Web Worker Tests - Allowed Uncaught Exception

10 |

Demonstrates running testharness based tests inside a dedicated web worker. 11 |

The test harness is expected to pass despite an uncaught exception in a worker because that worker is configured to allow uncaught exceptions.

12 |
13 | 14 | 22 | 45 | 46 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/assert_implements_optional.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | assert_implements_optional unittests 8 | 44 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/force_timeout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#force_timeout 5 | 6 | 7 |

Test#force_timeout

8 |
9 | 10 | 11 | 30 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /scripts/wpt/accname/name/shadowdom/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

Tests the basic shadow DOM portions of the AccName Name Computation algorithm, coming in ARIA #167.

10 | 11 | 14 | 20 | 21 | 24 | 30 | 38 | -------------------------------------------------------------------------------- /scripts/wpt/accname/name/comp_labeledby_non_standard.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name Comp: aria-labeledby (non-standard) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests that the non-standard (misspelled) attribute name aria-labeledby is not supported.

15 | 16 |

Tests for aria-labeledby

17 | 18 |
19 |

first heading

20 |

text inside div group

21 |
22 | 23 |
24 |

+ first heading

25 |

text inside div group

26 |
27 | 28 |
29 |

+ first heading

30 |

text inside div group

31 |
32 | 33 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testharness-shadowrealm-inner.js: -------------------------------------------------------------------------------- 1 | // testharness file with ShadowRealm utilities to be imported inside ShadowRealm 2 | 3 | /** 4 | * Set up all properties on the ShadowRealm's global object that tests will 5 | * expect to be present. 6 | * 7 | * @param {string} queryString - string to use as value for location.search, 8 | * used for subsetting some tests 9 | * @param {function} fetchAdaptor - a function that takes a resource URI and 10 | * returns a function which itself takes a (resolve, reject) pair from the 11 | * hosting realm, and calls resolve with the text result of fetching the 12 | * resource, or reject with a string indicating the error that occurred 13 | */ 14 | globalThis.setShadowRealmGlobalProperties = function (queryString, fetchAdaptor) { 15 | globalThis.fetch_json = (resource) => { 16 | const executor = fetchAdaptor(resource); 17 | return new Promise(executor).then((s) => JSON.parse(s)); 18 | }; 19 | 20 | // Used only by idlharness.js 21 | globalThis.fetch_spec = (spec) => { 22 | const resource = `/interfaces/${spec}.idl`; 23 | const executor = fetchAdaptor(resource); 24 | return new Promise(executor).then( 25 | idl => ({ spec, idl }), 26 | () => { 27 | throw new IdlHarnessError(`Error fetching ${resource}.`); 28 | }); 29 | } 30 | 31 | globalThis.location = { search: queryString }; 32 | }; 33 | 34 | globalThis.GLOBAL = { 35 | isWindow: function() { return false; }, 36 | isWorker: function() { return false; }, 37 | isShadowRealm: function() { return true; }, 38 | }; 39 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_err_multi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup: multiple functions with one in error 5 | 6 | 7 | 8 | 9 |
10 | 11 | 28 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/api-tests-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sample HTML5 API Tests 5 | 6 | 7 |

Sample HTML5 API Tests

8 |

There should be two results

9 |
10 | 11 | 12 | 20 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/listbox-roles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Listbox-related Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests listbox and related roles.

15 | 16 |
17 |
x
18 |
19 | x 20 | x 21 |
22 |
x
23 |
24 | 25 | 33 | 34 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_async_timeout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup with Promise-returning functions (timeout handling) 5 | 6 | 7 | 8 | 9 |
10 | 33 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_async_bad_return.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup with non-thenable-returning function 5 | 6 | 7 | 8 | 9 |
10 | 11 | 26 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/assert-throws-dom.html: -------------------------------------------------------------------------------- 1 | 2 | assert_throws_dom 3 | 4 | 5 |
6 | 18 | 55 | 56 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/scripts/manual.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family:DejaVu Sans, Bitstream Vera Sans, Arial, Sans; 3 | } 4 | 5 | table#steps { 6 | border-collapse:collapse; 7 | table-layout:fixed; 8 | width:100%; 9 | } 10 | 11 | table#steps th:last-child, 12 | table#steps td:last-child { 13 | width:70%; 14 | } 15 | 16 | // table#steps.assertions th:last-child, 17 | // table#steps.assertions td:last-child { 18 | // width:35%; 19 | // } 20 | 21 | table#steps th { 22 | padding:0; 23 | padding-bottom:0.25; 24 | border-bottom:medium solid black; 25 | } 26 | 27 | table#steps td { 28 | padding-top:0.25em; 29 | padding-bottom:0.25em; 30 | padding-left:0.5em; 31 | padding-right:0.5em; 32 | border-right:thin solid black; 33 | border-top:thin solid black; 34 | border-bottom:thin solid black; 35 | } 36 | 37 | table#steps td.step, table#steps td.type, table#steps td.element { 38 | vertical-align:top; 39 | } 40 | table#api { 41 | border-collapse:collapse; 42 | table-layout:fixed; 43 | width:100%; 44 | } 45 | 46 | // table#steps.assertions th:last-child, 47 | // table#steps.assertions td:last-child { 48 | // width:35%; 49 | // } 50 | 51 | table#api th { 52 | padding:0; 53 | padding-bottom:0.25; 54 | border-bottom:medium solid black; 55 | } 56 | 57 | table#api td { 58 | padding-top:0.25em; 59 | padding-bottom:0.25em; 60 | padding-left:0.5em; 61 | padding-right:0.5em; 62 | border-right:thin solid black; 63 | border-top:thin solid black; 64 | border-bottom:thin solid black; 65 | } 66 | 67 | table#api td.step, table#api td.type, table#api td.element { 68 | vertical-align:top; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/IdlInterfaceMember/is_to_json_regular_operation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IdlInterfaceMember.prototype.is_to_json_regular_operation() 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/grid-roles.tentative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tentative: Grid Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | x 21 | x 22 |
x
23 | 24 |
x
25 |
x
26 | 27 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/iframe-consolidate-errors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example with iframe that consolidates errors via fetch_tests_from_window 5 | 6 | 7 | 10 | 11 | 12 |

Fetching Tests From a Child Context

13 |

This test demonstrates the use of fetch_tests_from_window to pull 14 | tests from an iframe into the primary document.

15 |

The test suite is expected to fail due to an unhandled exception in the 16 | child context.

17 |
18 | 19 | 20 | 21 | 22 | 26 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | concurrency: 10 | group: ci-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | lint: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version: 22 21 | - uses: pnpm/action-setup@v4 22 | with: 23 | run_install: true 24 | - run: pnpm run lint 25 | test-node-versions: 26 | runs-on: ubuntu-latest 27 | strategy: 28 | matrix: 29 | node-version: [20, 22, 24] 30 | steps: 31 | - uses: actions/checkout@v4 32 | - uses: actions/setup-node@v4 33 | with: 34 | node-version: ${{ matrix.node-version }} 35 | - uses: pnpm/action-setup@v4 36 | with: 37 | run_install: true 38 | - run: pnpm run build 39 | - run: pnpm exec playwright install 40 | - run: pnpm test 41 | test-macos: 42 | runs-on: macos-latest 43 | steps: 44 | - uses: actions/checkout@v4 45 | - uses: actions/setup-node@v4 46 | with: 47 | node-version: 22 48 | - uses: pnpm/action-setup@v4 49 | with: 50 | run_install: true 51 | - run: pnpm run build 52 | - run: pnpm exec playwright install 53 | - run: pnpm test 54 | test-windows: 55 | runs-on: windows-latest 56 | steps: 57 | - uses: actions/checkout@v4 58 | - uses: actions/setup-node@v4 59 | with: 60 | node-version: 22 61 | - uses: pnpm/action-setup@v4 62 | with: 63 | run_install: true 64 | - run: pnpm run build 65 | - run: pnpm exec playwright install 66 | - run: pnpm test 67 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/worker-dedicated-uncaught-single.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dedicated Worker Tests - Uncaught Exception in Single-Page Test 5 | 6 | 7 | 8 | 9 |

Dedicated Web Worker Tests - Uncaught Exception in Single-Page Test

10 |

Demonstrates running testharness based tests inside a dedicated web worker. 11 |

The test harness is expected to pass despite an uncaught exception in a worker because that worker is a single-page test.

12 |
13 | 14 | 27 | 56 | 57 | -------------------------------------------------------------------------------- /test/node/utils.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from 'vitest'; 2 | import { removeProhibited } from '../../src/index.js'; 3 | 4 | describe('removeProhibited', () => { 5 | test('default', () => { 6 | expect(removeProhibited(['aria-atomic', 'aria-label'])).toEqual(['aria-atomic', 'aria-label']); 7 | }); 8 | 9 | test('nameProhibited', () => { 10 | expect( 11 | removeProhibited( 12 | [ 13 | 'aria-atomic', 14 | 'aria-braillelabel', 15 | 'aria-brailleroledescription', 16 | 'aria-label', 17 | 'aria-labelledby', 18 | 'aria-roledescription', 19 | ], 20 | { nameProhibited: true }, 21 | ), 22 | ).toEqual(['aria-atomic', 'aria-brailleroledescription', 'aria-roledescription']); 23 | }); 24 | 25 | test('prohibited', () => { 26 | expect( 27 | removeProhibited( 28 | [ 29 | 'aria-atomic', 30 | 'aria-checked', 31 | 'aria-brailleroledescription', 32 | 'aria-label', 33 | 'aria-labelledby', 34 | 'aria-roledescription', 35 | ], 36 | { prohibited: ['aria-checked'] }, 37 | ), 38 | ).toEqual(['aria-atomic', 'aria-brailleroledescription', 'aria-label', 'aria-labelledby', 'aria-roledescription']); 39 | }); 40 | 41 | test('nameProhibited + prohibited', () => { 42 | expect( 43 | removeProhibited( 44 | [ 45 | 'aria-atomic', 46 | 'aria-checked', 47 | 'aria-brailleroledescription', 48 | 'aria-label', 49 | 'aria-labelledby', 50 | 'aria-roledescription', 51 | ], 52 | { nameProhibited: true, prohibited: ['aria-checked'] }, 53 | ), 54 | ).toEqual(['aria-atomic', 'aria-brailleroledescription', 'aria-roledescription']); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_async_rejection_after_load.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup with Promise-returning functions (rejection handling following "load" event) 5 | 6 | 7 |

Promise Tests

8 |

This test demonstrates the use of promise_test. Assumes ECMAScript 6 9 | Promise support. Some failures are expected.

10 |
11 | 12 | 13 | 30 | 53 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/unit/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | idlharness basic 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /scripts/wpt/resources/testharness-shadowrealm-audioworkletprocessor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AudioWorkletProcessor intended for hosting a ShadowRealm and running a test 3 | * inside of that ShadowRealm. 4 | */ 5 | globalThis.TestRunner = class TestRunner extends AudioWorkletProcessor { 6 | constructor() { 7 | super(); 8 | this.createShadowRealmAndStartTests(); 9 | } 10 | 11 | /** 12 | * Fetch adaptor function intended as a drop-in replacement for fetchAdaptor() 13 | * (see testharness-shadowrealm-outer.js), but it does not assume fetch() is 14 | * present in the realm. Instead, it relies on setupFakeFetchOverMessagePort() 15 | * having been called on the port on the other side of this.port's channel. 16 | */ 17 | fetchOverPortExecutor(resource) { 18 | return (resolve, reject) => { 19 | const listener = (event) => { 20 | if (typeof event.data !== "string" || !event.data.startsWith("fetchResult::")) { 21 | return; 22 | } 23 | 24 | const result = event.data.slice("fetchResult::".length); 25 | if (result.startsWith("success::")) { 26 | resolve(result.slice("success::".length)); 27 | } else { 28 | reject(result.slice("fail::".length)); 29 | } 30 | 31 | this.port.removeEventListener("message", listener); 32 | } 33 | this.port.addEventListener("message", listener); 34 | this.port.start(); 35 | this.port.postMessage(`fetchRequest::${resource}`); 36 | } 37 | } 38 | 39 | /** 40 | * Async method, which is patched over in 41 | * (test).any.audioworklet-shadowrealm.js; see serve.py 42 | */ 43 | async createShadowRealmAndStartTests() { 44 | throw new Error("Forgot to overwrite this method!"); 45 | } 46 | 47 | /** Overrides AudioWorkletProcessor.prototype.process() */ 48 | process() { 49 | return false; 50 | } 51 | }; 52 | registerProcessor("test-runner", TestRunner); 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "html-aria", 3 | "description": "Utilities for creating accessible HTML based on the latest ARIA 1.3 specs. Lightweight, performant, tree-shakeable, and 0 dependencies.", 4 | "version": "0.5.3", 5 | "type": "module", 6 | "license": "MIT", 7 | "keywords": [ 8 | "a11y", 9 | "accessibility", 10 | "aria", 11 | "react", 12 | "1.3", 13 | "aria-query", 14 | "jsx-a11y", 15 | "wai-aria", 16 | "eslint" 17 | ], 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/drwpow/html-aria.git" 21 | }, 22 | "main": "./dist/index.mjs", 23 | "exports": { 24 | ".": { 25 | "import": { 26 | "types": "./dist/index.d.ts", 27 | "default": "./dist/index.mjs" 28 | }, 29 | "require": { 30 | "types": "./dist/index.d.cts", 31 | "default": "./dist/index.cjs" 32 | }, 33 | "default": "./dist/index.mjs" 34 | }, 35 | "./*": "./dist/*.mjs", 36 | "./package.json": "./package.json" 37 | }, 38 | "author": { 39 | "name": "Drew Powers", 40 | "email": "drew@pow.rs" 41 | }, 42 | "packageManager": "pnpm@10.11.0", 43 | "scripts": { 44 | "benchmark": "vitest bench", 45 | "build": "unbuild", 46 | "format": "biome format . --write", 47 | "lint": "biome check .", 48 | "test": "vitest run", 49 | "version": "pnpm run build && changeset version" 50 | }, 51 | "devDependencies": { 52 | "@biomejs/biome": "^2.1.2", 53 | "@changesets/changelog-github": "^0.5.1", 54 | "@changesets/cli": "^2.29.5", 55 | "@types/aria-query": "^5.0.4", 56 | "@vitest/browser": "^3.2.4", 57 | "aria-query": "^5.3.2", 58 | "dom-accessibility-api": "^0.7.0", 59 | "happy-dom": "^18.0.1", 60 | "jsdom": "^25.0.1", 61 | "playwright": "^1.54.1", 62 | "tinyglobby": "^0.2.14", 63 | "typescript": "^5.8.3", 64 | "unbuild": "^3.6.0", 65 | "vitest": "^3.2.4" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/webusb-child-test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This polyfill prepares a child context to be attached to a parent context. 4 | // The parent must call navigator.usb.test.attachToContext() to attach to the 5 | // child context. 6 | (() => { 7 | if (this.constructor.name === 'DedicatedWorkerGlobalScope' || 8 | this !== window.top) { 9 | 10 | // Run Chromium specific set up code. 11 | if (typeof MojoInterfaceInterceptor !== 'undefined') { 12 | let messageChannel = new MessageChannel(); 13 | messageChannel.port1.onmessage = async (messageEvent) => { 14 | if (messageEvent.data.type === 'Attach') { 15 | messageEvent.data.interfaces.forEach(interfaceName => { 16 | let interfaceInterceptor = 17 | new MojoInterfaceInterceptor(interfaceName); 18 | interfaceInterceptor.oninterfacerequest = 19 | e => messageChannel.port1.postMessage({ 20 | type: interfaceName, 21 | handle: e.handle 22 | }, [e.handle]); 23 | interfaceInterceptor.start(); 24 | }); 25 | 26 | // Wait for a call to GetDevices() to ensure that the interface 27 | // handles are forwarded to the parent context. 28 | try { 29 | await navigator.usb.getDevices(); 30 | } catch (e) { 31 | // This can happen in case of, for example, testing usb disallowed 32 | // iframe. 33 | console.error(`getDevices() throws error: ${e.name}: ${e.message}`); 34 | } 35 | 36 | messageChannel.port1.postMessage({ type: 'Complete' }); 37 | } 38 | }; 39 | 40 | let message = { type: 'ReadyForAttachment', port: messageChannel.port2 }; 41 | if (typeof Window !== 'undefined') 42 | parent.postMessage(message, '*', [messageChannel.port2]); 43 | else 44 | postMessage(message, [messageChannel.port2]); 45 | } 46 | } 47 | })(); 48 | -------------------------------------------------------------------------------- /scripts/wpt/resources/test/tests/functional/add_cleanup_bad_return.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test#add_cleanup with value-returning function 5 | 6 | 7 | 8 | 9 |
10 | 31 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_600-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 600 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 600.

64 |
Div with text
65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_file-title-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name file-title 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name file-title.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_text-title-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name text-title 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name text-title.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_radio-title-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name radio-title 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name radio-title.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_556-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 556 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 556.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_607-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 607 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 607.

64 | ABC 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_543-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 543 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 543.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_559-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 559 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 559.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_597-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 597 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 597.

64 |
foo
65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_601-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 601 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 601.

64 |
foo
65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_544-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 544 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 544.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_608-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 608 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 608.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/description_test_case_557-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Description test case 557 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Description test case 557.

64 | a 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_checkbox-title-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name checkbox-title 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name checkbox-title.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_image-title-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name image-title 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name image-title.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_password-title-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name password-title 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name password-title.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_751-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 751 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 751.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/synonym-roles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Region Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests synonym roles image/img and none/presentation via Core-AAM Computed Role.

15 | 16 | 17 | 18 |
x
19 | 20 | 21 |
x
22 | 23 | 24 | 25 | 26 | 27 |
x
28 | 29 | 33 | 34 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_539-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 539 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 539.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_545-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 545 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 545.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_557-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 557 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 557.

64 | a 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_604-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 604 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 604.

64 | ABC 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_749-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 749 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 749.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_750-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 750 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 750.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/wai-aria/role/button-roles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Button-related Role Verification Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Tests button and related roles.

15 | 16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | 27 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_561-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 561 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 561.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_551-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 551 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 551.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_611-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 611 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 611.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_614-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 614 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 614.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_615-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 615 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 615.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_616-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 616 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 616.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_752-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 752 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 752.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_612-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 612 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 612.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_748-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 748 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 748.

64 | 65 | 66 |
67 |
68 |
69 | 70 | 71 | -------------------------------------------------------------------------------- /scripts/wpt/accname/name/comp_name_from_content_alt_counter_invalidation.html: -------------------------------------------------------------------------------- 1 | 2 | Name Comp: Name From Alt Counter in Content Invalidation 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 |

Tests the #comp_name_from_content portions of the AccName Name Computation algorithm.

18 | 19 |

This series of tests exercises the button, heading, and link elements, because each have different characteristics worthy of testing in each of the name computation algorithm scenarios:

20 | 25 | 26 |

alt counter with ::before

27 |
28 |

label

29 | label
30 |
31 | 32 | 39 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_613-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 613 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 613.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_725-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 725 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 725.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/resources/chromium/mock-battery-monitor.js: -------------------------------------------------------------------------------- 1 | import {BatteryMonitor, BatteryMonitorReceiver} from '/gen/services/device/public/mojom/battery_monitor.mojom.m.js'; 2 | 3 | class MockBatteryMonitor { 4 | constructor() { 5 | this.receiver_ = new BatteryMonitorReceiver(this); 6 | this.interceptor_ = 7 | new MojoInterfaceInterceptor(BatteryMonitor.$interfaceName); 8 | this.interceptor_.oninterfacerequest = e => 9 | this.receiver_.$.bindHandle(e.handle); 10 | this.reset(); 11 | } 12 | 13 | start() { 14 | this.interceptor_.start(); 15 | } 16 | 17 | stop() { 18 | this.interceptor_.stop(); 19 | } 20 | 21 | reset() { 22 | this.pendingRequests_ = []; 23 | this.status_ = null; 24 | this.lastKnownStatus_ = null; 25 | } 26 | 27 | queryNextStatus() { 28 | const result = new Promise(resolve => this.pendingRequests_.push(resolve)); 29 | this.runCallbacks_(); 30 | return result; 31 | } 32 | 33 | setBatteryStatus(charging, chargingTime, dischargingTime, level) { 34 | this.status_ = {charging, chargingTime, dischargingTime, level}; 35 | this.lastKnownStatus_ = this.status_; 36 | this.runCallbacks_(); 37 | } 38 | 39 | verifyBatteryStatus(manager) { 40 | assert_not_equals(manager, undefined); 41 | assert_not_equals(this.lastKnownStatus_, null); 42 | assert_equals(manager.charging, this.lastKnownStatus_.charging); 43 | assert_equals(manager.chargingTime, this.lastKnownStatus_.chargingTime); 44 | assert_equals( 45 | manager.dischargingTime, this.lastKnownStatus_.dischargingTime); 46 | assert_equals(manager.level, this.lastKnownStatus_.level); 47 | } 48 | 49 | runCallbacks_() { 50 | if (!this.status_ || !this.pendingRequests_.length) 51 | return; 52 | 53 | let result = {status: this.status_}; 54 | while (this.pendingRequests_.length) { 55 | this.pendingRequests_.pop()(result); 56 | } 57 | this.status_ = null; 58 | } 59 | } 60 | 61 | export const mockBatteryMonitor = new MockBatteryMonitor(); 62 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_596-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 596 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 596.

64 |
foo
65 | bar 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_546-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 546 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 546.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_558-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 558 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 558.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_603-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 603 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 603.

64 |
foo
65 | bar 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_721-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 721 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 721.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /scripts/wpt/accname/manual/name_test_case_723-manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Name test case 723 5 | 6 | 7 | 8 | 9 | 10 | 61 | 62 | 63 |

This test examines the ARIA properties for Name test case 723.

64 | 65 | 66 | 67 |
68 |
69 |
70 | 71 | 72 | --------------------------------------------------------------------------------