Set up comprehensive frontend testing infrastructure

- Install Jest for unit testing with React Testing Library
- Install Playwright for end-to-end testing
- Configure Jest with proper TypeScript support and module mapping
- Create test setup files and utilities for both unit and e2e tests

Components:
* Jest configuration with coverage thresholds
* Playwright configuration with browser automation
* Unit tests for LoginForm, AuthContext, and useSocketIO hook
* E2E tests for authentication, dashboard, and agents workflows
* GitHub Actions workflow for automated testing
* Mock data and API utilities for consistent testing
* Test documentation with best practices

Testing features:
- Unit tests with 70% coverage threshold
- E2E tests with API mocking and user journey testing
- CI/CD integration for automated test runs
- Cross-browser testing support with Playwright
- Authentication system testing end-to-end

🚀 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-07-11 14:06:34 +10:00
parent c6d69695a8
commit aacb45156b
6109 changed files with 777927 additions and 1 deletions

View File

@@ -0,0 +1,6 @@
ie 11
edge >= 14
firefox >= 52
chrome >= 49
safari >= 10
node 10.0

21
frontend/node_modules/dom-accessibility-api/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Sebastian Silbermann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

222
frontend/node_modules/dom-accessibility-api/README.md generated vendored Normal file
View File

@@ -0,0 +1,222 @@
# dom-accessibility-api
[![npm version](https://badge.fury.io/js/dom-accessibility-api.svg)](https://badge.fury.io/js/dom-accessibility-api)
[![Build Status](https://dev.azure.com/silbermannsebastian/dom-accessibility-api/_apis/build/status/eps1lon.dom-accessibility-api?branchName=main)](https://dev.azure.com/silbermannsebastian/dom-accessibility-api/_build/latest?definitionId=6&branchName=main)
![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/silbermannsebastian/dom-accessibility-api/6)
Computes the accessible name or description of a given DOM Element.
https://w3c.github.io/accname/ implemented in JavaScript for testing.
```bash
$ yarn add dom-accessibility-api
```
```js
import {
computeAccessibleName,
computeAccessibleDescription,
} from "dom-accessibility-api";
```
I'm not an editor of any of the referenced specs (nor very experience with using them) so if you got any insights, something catches
your eye please open an issue.
## Supported environments
**WARNING**: Only [active node versions](https://nodejs.org/en/about/releases/) are supported.
Inactive node versions can stop working in a SemVer MINOR release.
```bash
ie 11
edge >= 14
firefox >= 52
chrome >= 49
safari >= 10
node 10.0
```
or check the published `.browserslistrc`
## progress
Using https://github.com/web-platform-tests/wpt. Be sure to init submodules when
cloning. See [the test readme](/tests/README.md) for more info about the test setup.
### browser (Chrome)
153/159
### jsdom
<details>
<summary>report 138/159 passing of which 15 are due `::before { content }`, one might be a wrong test, 5 are pathological </summary>
```bash
web-platform-tests
accname
[expected fail] description_1.0_combobox-focusable-manual.html
[expected fail] description_from_content_of_describedby_element-manual.html
✓ description_link-with-label-manual.html
✓ description_test_case_557-manual.html
✓ description_test_case_664-manual.html
✓ description_test_case_665-manual.html
✓ description_test_case_666-manual.html
✓ description_test_case_772-manual.html
✓ description_test_case_773-manual.html
✓ description_test_case_774-manual.html
✓ description_test_case_838-manual.html
✓ description_test_case_broken_reference-manual.html
✓ description_test_case_one_valid_reference-manual.html
✓ description_title-same-element-manual.html
✓ name_1.0_combobox-focusable-alternative-manual.html
✓ name_1.0_combobox-focusable-manual.html
✓ name_checkbox-label-embedded-combobox-manual.html
✓ name_checkbox-label-embedded-listbox-manual.html
✓ name_checkbox-label-embedded-menu-manual.html
✓ name_checkbox-label-embedded-select-manual.html
✓ name_checkbox-label-embedded-slider-manual.html
✓ name_checkbox-label-embedded-spinbutton-manual.html
✓ name_checkbox-label-embedded-textbox-manual.html
✓ name_checkbox-label-multiple-label-alternative-manual.html
✓ name_checkbox-label-multiple-label-manual.html
✓ name_checkbox-title-manual.html
✓ name_file-label-embedded-combobox-manual.html
✓ name_file-label-embedded-menu-manual.html
✓ name_file-label-embedded-select-manual.html
✓ name_file-label-embedded-slider-manual.html
✓ name_file-label-embedded-spinbutton-manual.html
[expected fail] name_file-label-inline-block-elements-manual.html
[expected fail] name_file-label-inline-block-styles-manual.html
✓ name_file-label-inline-hidden-elements-manual.html
✓ name_file-label-owned-combobox-manual.html
✓ name_file-label-owned-combobox-owned-listbox-manual.html
✓ name_file-title-manual.html
✓ name_from_content-manual.html
✓ name_from_content_of_label-manual.html
✓ name_from_content_of_labelledby_element-manual.html
✓ name_from_content_of_labelledby_elements_one_of_which_is_hidden-manual.html
✓ name_heading-combobox-focusable-alternative-manual.html
✓ name_image-title-manual.html
✓ name_link-mixed-content-manual.html
✓ name_link-with-label-manual.html
✓ name_password-label-embedded-combobox-manual.html
✓ name_password-label-embedded-menu-manual.html
✓ name_password-label-embedded-select-manual.html
✓ name_password-label-embedded-slider-manual.html
✓ name_password-label-embedded-spinbutton-manual.html
✓ name_password-title-manual.html
✓ name_radio-label-embedded-combobox-manual.html
✓ name_radio-label-embedded-menu-manual.html
✓ name_radio-label-embedded-select-manual.html
✓ name_radio-label-embedded-slider-manual.html
✓ name_radio-label-embedded-spinbutton-manual.html
✓ name_radio-title-manual.html
✓ name_test_case_539-manual.html
✓ name_test_case_540-manual.html
✓ name_test_case_541-manual.html
✓ name_test_case_543-manual.html
✓ name_test_case_544-manual.html
✓ name_test_case_545-manual.html
✓ name_test_case_546-manual.html
✓ name_test_case_547-manual.html
✓ name_test_case_548-manual.html
✓ name_test_case_549-manual.html
✓ name_test_case_550-manual.html
✓ name_test_case_551-manual.html
[expected fail] name_test_case_552-manual.html
[expected fail] name_test_case_553-manual.html
✓ name_test_case_556-manual.html
✓ name_test_case_557-manual.html
✓ name_test_case_558-manual.html
✓ name_test_case_559-manual.html
✓ name_test_case_560-manual.html
✓ name_test_case_561-manual.html
✓ name_test_case_562-manual.html
✓ name_test_case_563-manual.html
✓ name_test_case_564-manual.html
✓ name_test_case_565-manual.html
✓ name_test_case_566-manual.html
✓ name_test_case_596-manual.html
✓ name_test_case_597-manual.html
✓ name_test_case_598-manual.html
✓ name_test_case_599-manual.html
✓ name_test_case_600-manual.html
✓ name_test_case_601-manual.html
✓ name_test_case_602-manual.html
✓ name_test_case_603-manual.html
✓ name_test_case_604-manual.html
✓ name_test_case_605-manual.html
✓ name_test_case_606-manual.html
✓ name_test_case_607-manual.html
✓ name_test_case_608-manual.html
✓ name_test_case_609-manual.html
✓ name_test_case_610-manual.html
✓ name_test_case_611-manual.html
✓ name_test_case_612-manual.html
✓ name_test_case_613-manual.html
✓ name_test_case_614-manual.html
✓ name_test_case_615-manual.html
✓ name_test_case_616-manual.html
✓ name_test_case_617-manual.html
✓ name_test_case_618-manual.html
✓ name_test_case_619-manual.html
✓ name_test_case_620-manual.html
✓ name_test_case_621-manual.html
[expected fail] name_test_case_659-manual.html
[expected fail] name_test_case_660-manual.html
[expected fail] name_test_case_661-manual.html
[expected fail] name_test_case_662-manual.html
[expected fail] name_test_case_663a-manual.html
✓ name_test_case_721-manual.html
✓ name_test_case_723-manual.html
✓ name_test_case_724-manual.html
✓ name_test_case_725-manual.html
✓ name_test_case_726-manual.html
✓ name_test_case_727-manual.html
✓ name_test_case_728-manual.html
✓ name_test_case_729-manual.html
✓ name_test_case_730-manual.html
✓ name_test_case_731-manual.html
✓ name_test_case_733-manual.html
✓ name_test_case_734-manual.html
✓ name_test_case_735-manual.html
✓ name_test_case_736-manual.html
✓ name_test_case_737-manual.html
✓ name_test_case_738-manual.html
✓ name_test_case_739-manual.html
✓ name_test_case_740-manual.html
✓ name_test_case_741-manual.html
✓ name_test_case_742-manual.html
✓ name_test_case_743-manual.html
✓ name_test_case_744-manual.html
✓ name_test_case_745-manual.html
✓ name_test_case_746-manual.html
✓ name_test_case_747-manual.html
✓ name_test_case_748-manual.html
✓ name_test_case_749-manual.html
✓ name_test_case_750-manual.html
✓ name_test_case_751-manual.html
✓ name_test_case_752-manual.html
[expected fail] name_test_case_753-manual.html
[expected fail] name_test_case_754-manual.html
[expected fail] name_test_case_755-manual.html
[expected fail] name_test_case_756-manual.html
[expected fail] name_test_case_757-manual.html
[expected fail] name_test_case_758-manual.html
[expected fail] name_test_case_759-manual.html
[expected fail] name_test_case_760-manual.html
[expected fail] name_test_case_761-manual.html
[expected fail] name_test_case_762-manual.html
✓ name_text-label-embedded-combobox-manual.html
✓ name_text-label-embedded-menu-manual.html
✓ name_text-label-embedded-select-manual.html
✓ name_text-label-embedded-slider-manual.html
✓ name_text-label-embedded-spinbutton-manual.html
✓ name_text-title-manual.html
```
</details>
## missing
- visibility context (inherited but can reappear; currently reappearing wont't work)

View File

@@ -0,0 +1,8 @@
import { ComputeTextAlternativeOptions } from "./accessible-name-and-description";
/**
* @param root
* @param options
* @returns
*/
export declare function computeAccessibleDescription(root: Element, options?: ComputeTextAlternativeOptions): string;
//# sourceMappingURL=accessible-description.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessible-description.d.ts","sourceRoot":"","sources":["../sources/accessible-description.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,6BAA6B,EAC7B,MAAM,mCAAmC,CAAC;AAG3C;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC3C,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,6BAAkC,GACzC,MAAM,CAqBR"}

View File

@@ -0,0 +1,37 @@
"use strict";
exports.__esModule = true;
exports.computeAccessibleDescription = computeAccessibleDescription;
var _accessibleNameAndDescription = require("./accessible-name-and-description");
var _util = require("./util");
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
/**
* @param root
* @param options
* @returns
*/
function computeAccessibleDescription(root) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var description = (0, _util.queryIdRefs)(root, "aria-describedby").map(function (element) {
return (0, _accessibleNameAndDescription.computeTextAlternative)(element, _objectSpread(_objectSpread({}, options), {}, {
compute: "description"
}));
}).join(" ");
// TODO: Technically we need to make sure that node wasn't used for the accessible name
// This causes `description_1.0_combobox-focusable-manual` to fail
//
// https://www.w3.org/TR/html-aam-1.0/#accessible-name-and-description-computation
// says for so many elements to use the `title` that we assume all elements are considered
if (description === "") {
var title = root.getAttribute("title");
description = title === null ? "" : title;
}
return description;
}
//# sourceMappingURL=accessible-description.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessible-description.js","names":["computeAccessibleDescription","root","options","description","queryIdRefs","map","element","computeTextAlternative","compute","join","title","getAttribute"],"sources":["../sources/accessible-description.ts"],"sourcesContent":["import {\n\tcomputeTextAlternative,\n\tComputeTextAlternativeOptions,\n} from \"./accessible-name-and-description\";\nimport { queryIdRefs } from \"./util\";\n\n/**\n * @param root\n * @param options\n * @returns\n */\nexport function computeAccessibleDescription(\n\troot: Element,\n\toptions: ComputeTextAlternativeOptions = {}\n): string {\n\tlet description = queryIdRefs(root, \"aria-describedby\")\n\t\t.map((element) => {\n\t\t\treturn computeTextAlternative(element, {\n\t\t\t\t...options,\n\t\t\t\tcompute: \"description\",\n\t\t\t});\n\t\t})\n\t\t.join(\" \");\n\n\t// TODO: Technically we need to make sure that node wasn't used for the accessible name\n\t// This causes `description_1.0_combobox-focusable-manual` to fail\n\t//\n\t// https://www.w3.org/TR/html-aam-1.0/#accessible-name-and-description-computation\n\t// says for so many elements to use the `title` that we assume all elements are considered\n\tif (description === \"\") {\n\t\tconst title = root.getAttribute(\"title\");\n\t\tdescription = title === null ? \"\" : title;\n\t}\n\n\treturn description;\n}\n"],"mappings":";;;;AAAA;AAIA;AAAqC;AAAA;AAAA;AAAA;AAAA;AAAA;AAErC;AACA;AACA;AACA;AACA;AACO,SAASA,4BAA4B,CAC3CC,IAAa,EAEJ;EAAA,IADTC,OAAsC,uEAAG,CAAC,CAAC;EAE3C,IAAIC,WAAW,GAAG,IAAAC,iBAAW,EAACH,IAAI,EAAE,kBAAkB,CAAC,CACrDI,GAAG,CAAC,UAACC,OAAO,EAAK;IACjB,OAAO,IAAAC,oDAAsB,EAACD,OAAO,kCACjCJ,OAAO;MACVM,OAAO,EAAE;IAAa,GACrB;EACH,CAAC,CAAC,CACDC,IAAI,CAAC,GAAG,CAAC;;EAEX;EACA;EACA;EACA;EACA;EACA,IAAIN,WAAW,KAAK,EAAE,EAAE;IACvB,IAAMO,KAAK,GAAGT,IAAI,CAACU,YAAY,CAAC,OAAO,CAAC;IACxCR,WAAW,GAAGO,KAAK,KAAK,IAAI,GAAG,EAAE,GAAGA,KAAK;EAC1C;EAEA,OAAOP,WAAW;AACnB"}

View File

@@ -0,0 +1,34 @@
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
import { computeTextAlternative } from "./accessible-name-and-description.mjs";
import { queryIdRefs } from "./util.mjs";
/**
* @param root
* @param options
* @returns
*/
export function computeAccessibleDescription(root) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var description = queryIdRefs(root, "aria-describedby").map(function (element) {
return computeTextAlternative(element, _objectSpread(_objectSpread({}, options), {}, {
compute: "description"
}));
}).join(" ");
// TODO: Technically we need to make sure that node wasn't used for the accessible name
// This causes `description_1.0_combobox-focusable-manual` to fail
//
// https://www.w3.org/TR/html-aam-1.0/#accessible-name-and-description-computation
// says for so many elements to use the `title` that we assume all elements are considered
if (description === "") {
var title = root.getAttribute("title");
description = title === null ? "" : title;
}
return description;
}
//# sourceMappingURL=accessible-description.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessible-description.mjs","names":["computeTextAlternative","queryIdRefs","computeAccessibleDescription","root","options","description","map","element","compute","join","title","getAttribute"],"sources":["../sources/accessible-description.ts"],"sourcesContent":["import {\n\tcomputeTextAlternative,\n\tComputeTextAlternativeOptions,\n} from \"./accessible-name-and-description\";\nimport { queryIdRefs } from \"./util\";\n\n/**\n * @param root\n * @param options\n * @returns\n */\nexport function computeAccessibleDescription(\n\troot: Element,\n\toptions: ComputeTextAlternativeOptions = {}\n): string {\n\tlet description = queryIdRefs(root, \"aria-describedby\")\n\t\t.map((element) => {\n\t\t\treturn computeTextAlternative(element, {\n\t\t\t\t...options,\n\t\t\t\tcompute: \"description\",\n\t\t\t});\n\t\t})\n\t\t.join(\" \");\n\n\t// TODO: Technically we need to make sure that node wasn't used for the accessible name\n\t// This causes `description_1.0_combobox-focusable-manual` to fail\n\t//\n\t// https://www.w3.org/TR/html-aam-1.0/#accessible-name-and-description-computation\n\t// says for so many elements to use the `title` that we assume all elements are considered\n\tif (description === \"\") {\n\t\tconst title = root.getAttribute(\"title\");\n\t\tdescription = title === null ? \"\" : title;\n\t}\n\n\treturn description;\n}\n"],"mappings":";;;;;;AAAA,SACCA,sBAAsB,QAEhB,uCAAmC;AAC1C,SAASC,WAAW,QAAQ,YAAQ;;AAEpC;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,4BAA4B,CAC3CC,IAAa,EAEJ;EAAA,IADTC,OAAsC,uEAAG,CAAC,CAAC;EAE3C,IAAIC,WAAW,GAAGJ,WAAW,CAACE,IAAI,EAAE,kBAAkB,CAAC,CACrDG,GAAG,CAAC,UAACC,OAAO,EAAK;IACjB,OAAOP,sBAAsB,CAACO,OAAO,kCACjCH,OAAO;MACVI,OAAO,EAAE;IAAa,GACrB;EACH,CAAC,CAAC,CACDC,IAAI,CAAC,GAAG,CAAC;;EAEX;EACA;EACA;EACA;EACA;EACA,IAAIJ,WAAW,KAAK,EAAE,EAAE;IACvB,IAAMK,KAAK,GAAGP,IAAI,CAACQ,YAAY,CAAC,OAAO,CAAC;IACxCN,WAAW,GAAGK,KAAK,KAAK,IAAI,GAAG,EAAE,GAAGA,KAAK;EAC1C;EAEA,OAAOL,WAAW;AACnB"}

View File

@@ -0,0 +1,29 @@
/**
* interface for an options-bag where `window.getComputedStyle` can be mocked
*/
export interface ComputeTextAlternativeOptions {
compute?: "description" | "name";
/**
* Set to true if window.computedStyle supports the second argument.
* This should be false in JSDOM. Otherwise JSDOM will log console errors.
*/
computedStyleSupportsPseudoElements?: boolean;
/**
* mock window.getComputedStyle. Needs `content`, `display` and `visibility`
*/
getComputedStyle?: typeof window.getComputedStyle;
/**
* Set to `true` if you want to include hidden elements in the accessible name and description computation.
* Skips 2A in https://w3c.github.io/accname/#computation-steps.
* @default false
*/
hidden?: boolean;
}
/**
* implements https://w3c.github.io/accname/#mapping_additional_nd_te
* @param root
* @param options
* @returns
*/
export declare function computeTextAlternative(root: Element, options?: ComputeTextAlternativeOptions): string;
//# sourceMappingURL=accessible-name-and-description.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessible-name-and-description.d.ts","sourceRoot":"","sources":["../sources/accessible-name-and-description.ts"],"names":[],"mappings":"AA+BA;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC7C,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;IACjC;;;OAGG;IACH,mCAAmC,CAAC,EAAE,OAAO,CAAC;IAC9C;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,MAAM,CAAC,gBAAgB,CAAC;IAClD;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAqRD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,6BAAkC,GACzC,MAAM,CAsYR"}

View File

@@ -0,0 +1,534 @@
"use strict";
exports.__esModule = true;
exports.computeTextAlternative = computeTextAlternative;
var _array = _interopRequireDefault(require("./polyfills/array.from"));
var _SetLike = _interopRequireDefault(require("./polyfills/SetLike"));
var _util = require("./util");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* implements https://w3c.github.io/accname/
*/
/**
*
* @param {string} string -
* @returns {FlatString} -
*/
function asFlatString(s) {
return s.trim().replace(/\s\s+/g, " ");
}
/**
*
* @param node -
* @param options - These are not optional to prevent accidentally calling it without options in `computeAccessibleName`
* @returns {boolean} -
*/
function isHidden(node, getComputedStyleImplementation) {
if (!(0, _util.isElement)(node)) {
return false;
}
if (node.hasAttribute("hidden") || node.getAttribute("aria-hidden") === "true") {
return true;
}
var style = getComputedStyleImplementation(node);
return style.getPropertyValue("display") === "none" || style.getPropertyValue("visibility") === "hidden";
}
/**
* @param {Node} node -
* @returns {boolean} - As defined in step 2E of https://w3c.github.io/accname/#mapping_additional_nd_te
*/
function isControl(node) {
return (0, _util.hasAnyConcreteRoles)(node, ["button", "combobox", "listbox", "textbox"]) || hasAbstractRole(node, "range");
}
function hasAbstractRole(node, role) {
if (!(0, _util.isElement)(node)) {
return false;
}
switch (role) {
case "range":
return (0, _util.hasAnyConcreteRoles)(node, ["meter", "progressbar", "scrollbar", "slider", "spinbutton"]);
default:
throw new TypeError("No knowledge about abstract role '".concat(role, "'. This is likely a bug :("));
}
}
/**
* element.querySelectorAll but also considers owned tree
* @param element
* @param selectors
*/
function querySelectorAllSubtree(element, selectors) {
var elements = (0, _array.default)(element.querySelectorAll(selectors));
(0, _util.queryIdRefs)(element, "aria-owns").forEach(function (root) {
// babel transpiles this assuming an iterator
elements.push.apply(elements, (0, _array.default)(root.querySelectorAll(selectors)));
});
return elements;
}
function querySelectedOptions(listbox) {
if ((0, _util.isHTMLSelectElement)(listbox)) {
// IE11 polyfill
return listbox.selectedOptions || querySelectorAllSubtree(listbox, "[selected]");
}
return querySelectorAllSubtree(listbox, '[aria-selected="true"]');
}
function isMarkedPresentational(node) {
return (0, _util.hasAnyConcreteRoles)(node, ["none", "presentation"]);
}
/**
* Elements specifically listed in html-aam
*
* We don't need this for `label` or `legend` elements.
* Their implicit roles already allow "naming from content".
*
* sources:
*
* - https://w3c.github.io/html-aam/#table-element
*/
function isNativeHostLanguageTextAlternativeElement(node) {
return (0, _util.isHTMLTableCaptionElement)(node);
}
/**
* https://w3c.github.io/aria/#namefromcontent
*/
function allowsNameFromContent(node) {
return (0, _util.hasAnyConcreteRoles)(node, ["button", "cell", "checkbox", "columnheader", "gridcell", "heading", "label", "legend", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "row", "rowheader", "switch", "tab", "tooltip", "treeitem"]);
}
/**
* TODO https://github.com/eps1lon/dom-accessibility-api/issues/100
*/
function isDescendantOfNativeHostLanguageTextAlternativeElement(
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- not implemented yet
node) {
return false;
}
function getValueOfTextbox(element) {
if ((0, _util.isHTMLInputElement)(element) || (0, _util.isHTMLTextAreaElement)(element)) {
return element.value;
}
// https://github.com/eps1lon/dom-accessibility-api/issues/4
return element.textContent || "";
}
function getTextualContent(declaration) {
var content = declaration.getPropertyValue("content");
if (/^["'].*["']$/.test(content)) {
return content.slice(1, -1);
}
return "";
}
/**
* https://html.spec.whatwg.org/multipage/forms.html#category-label
* TODO: form-associated custom elements
* @param element
*/
function isLabelableElement(element) {
var localName = (0, _util.getLocalName)(element);
return localName === "button" || localName === "input" && element.getAttribute("type") !== "hidden" || localName === "meter" || localName === "output" || localName === "progress" || localName === "select" || localName === "textarea";
}
/**
* > [...], then the first such descendant in tree order is the label element's labeled control.
* -- https://html.spec.whatwg.org/multipage/forms.html#labeled-control
* @param element
*/
function findLabelableElement(element) {
if (isLabelableElement(element)) {
return element;
}
var labelableElement = null;
element.childNodes.forEach(function (childNode) {
if (labelableElement === null && (0, _util.isElement)(childNode)) {
var descendantLabelableElement = findLabelableElement(childNode);
if (descendantLabelableElement !== null) {
labelableElement = descendantLabelableElement;
}
}
});
return labelableElement;
}
/**
* Polyfill of HTMLLabelElement.control
* https://html.spec.whatwg.org/multipage/forms.html#labeled-control
* @param label
*/
function getControlOfLabel(label) {
if (label.control !== undefined) {
return label.control;
}
var htmlFor = label.getAttribute("for");
if (htmlFor !== null) {
return label.ownerDocument.getElementById(htmlFor);
}
return findLabelableElement(label);
}
/**
* Polyfill of HTMLInputElement.labels
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/labels
* @param element
*/
function getLabels(element) {
var labelsProperty = element.labels;
if (labelsProperty === null) {
return labelsProperty;
}
if (labelsProperty !== undefined) {
return (0, _array.default)(labelsProperty);
}
// polyfill
if (!isLabelableElement(element)) {
return null;
}
var document = element.ownerDocument;
return (0, _array.default)(document.querySelectorAll("label")).filter(function (label) {
return getControlOfLabel(label) === element;
});
}
/**
* Gets the contents of a slot used for computing the accname
* @param slot
*/
function getSlotContents(slot) {
// Computing the accessible name for elements containing slots is not
// currently defined in the spec. This implementation reflects the
// behavior of NVDA 2020.2/Firefox 81 and iOS VoiceOver/Safari 13.6.
var assignedNodes = slot.assignedNodes();
if (assignedNodes.length === 0) {
// if no nodes are assigned to the slot, it displays the default content
return (0, _array.default)(slot.childNodes);
}
return assignedNodes;
}
/**
* implements https://w3c.github.io/accname/#mapping_additional_nd_te
* @param root
* @param options
* @returns
*/
function computeTextAlternative(root) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var consultedNodes = new _SetLike.default();
var window = (0, _util.safeWindow)(root);
var _options$compute = options.compute,
compute = _options$compute === void 0 ? "name" : _options$compute,
_options$computedStyl = options.computedStyleSupportsPseudoElements,
computedStyleSupportsPseudoElements = _options$computedStyl === void 0 ? options.getComputedStyle !== undefined : _options$computedStyl,
_options$getComputedS = options.getComputedStyle,
getComputedStyle = _options$getComputedS === void 0 ? window.getComputedStyle.bind(window) : _options$getComputedS,
_options$hidden = options.hidden,
hidden = _options$hidden === void 0 ? false : _options$hidden;
// 2F.i
function computeMiscTextAlternative(node, context) {
var accumulatedText = "";
if ((0, _util.isElement)(node) && computedStyleSupportsPseudoElements) {
var pseudoBefore = getComputedStyle(node, "::before");
var beforeContent = getTextualContent(pseudoBefore);
accumulatedText = "".concat(beforeContent, " ").concat(accumulatedText);
}
// FIXME: Including aria-owns is not defined in the spec
// But it is required in the web-platform-test
var childNodes = (0, _util.isHTMLSlotElement)(node) ? getSlotContents(node) : (0, _array.default)(node.childNodes).concat((0, _util.queryIdRefs)(node, "aria-owns"));
childNodes.forEach(function (child) {
var result = computeTextAlternative(child, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false,
recursion: true
});
// TODO: Unclear why display affects delimiter
// see https://github.com/w3c/accname/issues/3
var display = (0, _util.isElement)(child) ? getComputedStyle(child).getPropertyValue("display") : "inline";
var separator = display !== "inline" ? " " : "";
// trailing separator for wpt tests
accumulatedText += "".concat(separator).concat(result).concat(separator);
});
if ((0, _util.isElement)(node) && computedStyleSupportsPseudoElements) {
var pseudoAfter = getComputedStyle(node, "::after");
var afterContent = getTextualContent(pseudoAfter);
accumulatedText = "".concat(accumulatedText, " ").concat(afterContent);
}
return accumulatedText.trim();
}
/**
*
* @param element
* @param attributeName
* @returns A string non-empty string or `null`
*/
function useAttribute(element, attributeName) {
var attribute = element.getAttributeNode(attributeName);
if (attribute !== null && !consultedNodes.has(attribute) && attribute.value.trim() !== "") {
consultedNodes.add(attribute);
return attribute.value;
}
return null;
}
function computeTooltipAttributeValue(node) {
if (!(0, _util.isElement)(node)) {
return null;
}
return useAttribute(node, "title");
}
function computeElementTextAlternative(node) {
if (!(0, _util.isElement)(node)) {
return null;
}
// https://w3c.github.io/html-aam/#fieldset-and-legend-elements
if ((0, _util.isHTMLFieldSetElement)(node)) {
consultedNodes.add(node);
var children = (0, _array.default)(node.childNodes);
for (var i = 0; i < children.length; i += 1) {
var child = children[i];
if ((0, _util.isHTMLLegendElement)(child)) {
return computeTextAlternative(child, {
isEmbeddedInLabel: false,
isReferenced: false,
recursion: false
});
}
}
} else if ((0, _util.isHTMLTableElement)(node)) {
// https://w3c.github.io/html-aam/#table-element
consultedNodes.add(node);
var _children = (0, _array.default)(node.childNodes);
for (var _i = 0; _i < _children.length; _i += 1) {
var _child = _children[_i];
if ((0, _util.isHTMLTableCaptionElement)(_child)) {
return computeTextAlternative(_child, {
isEmbeddedInLabel: false,
isReferenced: false,
recursion: false
});
}
}
} else if ((0, _util.isSVGSVGElement)(node)) {
// https://www.w3.org/TR/svg-aam-1.0/
consultedNodes.add(node);
var _children2 = (0, _array.default)(node.childNodes);
for (var _i2 = 0; _i2 < _children2.length; _i2 += 1) {
var _child2 = _children2[_i2];
if ((0, _util.isSVGTitleElement)(_child2)) {
return _child2.textContent;
}
}
return null;
} else if ((0, _util.getLocalName)(node) === "img" || (0, _util.getLocalName)(node) === "area") {
// https://w3c.github.io/html-aam/#area-element
// https://w3c.github.io/html-aam/#img-element
var nameFromAlt = useAttribute(node, "alt");
if (nameFromAlt !== null) {
return nameFromAlt;
}
} else if ((0, _util.isHTMLOptGroupElement)(node)) {
var nameFromLabel = useAttribute(node, "label");
if (nameFromLabel !== null) {
return nameFromLabel;
}
}
if ((0, _util.isHTMLInputElement)(node) && (node.type === "button" || node.type === "submit" || node.type === "reset")) {
// https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-email-input-type-url-and-textarea-element-accessible-description-computation
var nameFromValue = useAttribute(node, "value");
if (nameFromValue !== null) {
return nameFromValue;
}
// TODO: l10n
if (node.type === "submit") {
return "Submit";
}
// TODO: l10n
if (node.type === "reset") {
return "Reset";
}
}
var labels = getLabels(node);
if (labels !== null && labels.length !== 0) {
consultedNodes.add(node);
return (0, _array.default)(labels).map(function (element) {
return computeTextAlternative(element, {
isEmbeddedInLabel: true,
isReferenced: false,
recursion: true
});
}).filter(function (label) {
return label.length > 0;
}).join(" ");
}
// https://w3c.github.io/html-aam/#input-type-image-accessible-name-computation
// TODO: wpt test consider label elements but html-aam does not mention them
// We follow existing implementations over spec
if ((0, _util.isHTMLInputElement)(node) && node.type === "image") {
var _nameFromAlt = useAttribute(node, "alt");
if (_nameFromAlt !== null) {
return _nameFromAlt;
}
var nameFromTitle = useAttribute(node, "title");
if (nameFromTitle !== null) {
return nameFromTitle;
}
// TODO: l10n
return "Submit Query";
}
if ((0, _util.hasAnyConcreteRoles)(node, ["button"])) {
// https://www.w3.org/TR/html-aam-1.0/#button-element
var nameFromSubTree = computeMiscTextAlternative(node, {
isEmbeddedInLabel: false,
isReferenced: false
});
if (nameFromSubTree !== "") {
return nameFromSubTree;
}
}
return null;
}
function computeTextAlternative(current, context) {
if (consultedNodes.has(current)) {
return "";
}
// 2A
if (!hidden && isHidden(current, getComputedStyle) && !context.isReferenced) {
consultedNodes.add(current);
return "";
}
// 2B
var labelAttributeNode = (0, _util.isElement)(current) ? current.getAttributeNode("aria-labelledby") : null;
// TODO: Do we generally need to block query IdRefs of attributes we have already consulted?
var labelElements = labelAttributeNode !== null && !consultedNodes.has(labelAttributeNode) ? (0, _util.queryIdRefs)(current, "aria-labelledby") : [];
if (compute === "name" && !context.isReferenced && labelElements.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Can't be null here otherwise labelElements would be empty
consultedNodes.add(labelAttributeNode);
return labelElements.map(function (element) {
// TODO: Chrome will consider repeated values i.e. use a node multiple times while we'll bail out in computeTextAlternative.
return computeTextAlternative(element, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: true,
// this isn't recursion as specified, otherwise we would skip
// `aria-label` in
// <input id="myself" aria-label="foo" aria-labelledby="myself"
recursion: false
});
}).join(" ");
}
// 2C
// Changed from the spec in anticipation of https://github.com/w3c/accname/issues/64
// spec says we should only consider skipping if we have a non-empty label
var skipToStep2E = context.recursion && isControl(current) && compute === "name";
if (!skipToStep2E) {
var ariaLabel = ((0, _util.isElement)(current) && current.getAttribute("aria-label") || "").trim();
if (ariaLabel !== "" && compute === "name") {
consultedNodes.add(current);
return ariaLabel;
}
// 2D
if (!isMarkedPresentational(current)) {
var elementTextAlternative = computeElementTextAlternative(current);
if (elementTextAlternative !== null) {
consultedNodes.add(current);
return elementTextAlternative;
}
}
}
// special casing, cheating to make tests pass
// https://github.com/w3c/accname/issues/67
if ((0, _util.hasAnyConcreteRoles)(current, ["menu"])) {
consultedNodes.add(current);
return "";
}
// 2E
if (skipToStep2E || context.isEmbeddedInLabel || context.isReferenced) {
if ((0, _util.hasAnyConcreteRoles)(current, ["combobox", "listbox"])) {
consultedNodes.add(current);
var selectedOptions = querySelectedOptions(current);
if (selectedOptions.length === 0) {
// defined per test `name_heading_combobox`
return (0, _util.isHTMLInputElement)(current) ? current.value : "";
}
return (0, _array.default)(selectedOptions).map(function (selectedOption) {
return computeTextAlternative(selectedOption, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false,
recursion: true
});
}).join(" ");
}
if (hasAbstractRole(current, "range")) {
consultedNodes.add(current);
if (current.hasAttribute("aria-valuetext")) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- safe due to hasAttribute guard
return current.getAttribute("aria-valuetext");
}
if (current.hasAttribute("aria-valuenow")) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- safe due to hasAttribute guard
return current.getAttribute("aria-valuenow");
}
// Otherwise, use the value as specified by a host language attribute.
return current.getAttribute("value") || "";
}
if ((0, _util.hasAnyConcreteRoles)(current, ["textbox"])) {
consultedNodes.add(current);
return getValueOfTextbox(current);
}
}
// 2F: https://w3c.github.io/accname/#step2F
if (allowsNameFromContent(current) || (0, _util.isElement)(current) && context.isReferenced || isNativeHostLanguageTextAlternativeElement(current) || isDescendantOfNativeHostLanguageTextAlternativeElement(current)) {
var accumulatedText2F = computeMiscTextAlternative(current, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false
});
if (accumulatedText2F !== "") {
consultedNodes.add(current);
return accumulatedText2F;
}
}
if (current.nodeType === current.TEXT_NODE) {
consultedNodes.add(current);
return current.textContent || "";
}
if (context.recursion) {
consultedNodes.add(current);
return computeMiscTextAlternative(current, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false
});
}
var tooltipAttributeValue = computeTooltipAttributeValue(current);
if (tooltipAttributeValue !== null) {
consultedNodes.add(current);
return tooltipAttributeValue;
}
// TODO should this be reachable?
consultedNodes.add(current);
return "";
}
return asFlatString(computeTextAlternative(root, {
isEmbeddedInLabel: false,
// by spec computeAccessibleDescription starts with the referenced elements as roots
isReferenced: compute === "description",
recursion: false
}));
}
//# sourceMappingURL=accessible-name-and-description.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,533 @@
/**
* implements https://w3c.github.io/accname/
*/
import ArrayFrom from "./polyfills/array.from.mjs";
import SetLike from "./polyfills/SetLike.mjs";
import { hasAnyConcreteRoles, isElement, isHTMLTableCaptionElement, isHTMLInputElement, isHTMLSelectElement, isHTMLTextAreaElement, safeWindow, isHTMLFieldSetElement, isHTMLLegendElement, isHTMLOptGroupElement, isHTMLTableElement, isHTMLSlotElement, isSVGSVGElement, isSVGTitleElement, queryIdRefs, getLocalName } from "./util.mjs";
/**
* A string of characters where all carriage returns, newlines, tabs, and form-feeds are replaced with a single space, and multiple spaces are reduced to a single space. The string contains only character data; it does not contain any markup.
*/
/**
*
* @param {string} string -
* @returns {FlatString} -
*/
function asFlatString(s) {
return s.trim().replace(/\s\s+/g, " ");
}
/**
*
* @param node -
* @param options - These are not optional to prevent accidentally calling it without options in `computeAccessibleName`
* @returns {boolean} -
*/
function isHidden(node, getComputedStyleImplementation) {
if (!isElement(node)) {
return false;
}
if (node.hasAttribute("hidden") || node.getAttribute("aria-hidden") === "true") {
return true;
}
var style = getComputedStyleImplementation(node);
return style.getPropertyValue("display") === "none" || style.getPropertyValue("visibility") === "hidden";
}
/**
* @param {Node} node -
* @returns {boolean} - As defined in step 2E of https://w3c.github.io/accname/#mapping_additional_nd_te
*/
function isControl(node) {
return hasAnyConcreteRoles(node, ["button", "combobox", "listbox", "textbox"]) || hasAbstractRole(node, "range");
}
function hasAbstractRole(node, role) {
if (!isElement(node)) {
return false;
}
switch (role) {
case "range":
return hasAnyConcreteRoles(node, ["meter", "progressbar", "scrollbar", "slider", "spinbutton"]);
default:
throw new TypeError("No knowledge about abstract role '".concat(role, "'. This is likely a bug :("));
}
}
/**
* element.querySelectorAll but also considers owned tree
* @param element
* @param selectors
*/
function querySelectorAllSubtree(element, selectors) {
var elements = ArrayFrom(element.querySelectorAll(selectors));
queryIdRefs(element, "aria-owns").forEach(function (root) {
// babel transpiles this assuming an iterator
elements.push.apply(elements, ArrayFrom(root.querySelectorAll(selectors)));
});
return elements;
}
function querySelectedOptions(listbox) {
if (isHTMLSelectElement(listbox)) {
// IE11 polyfill
return listbox.selectedOptions || querySelectorAllSubtree(listbox, "[selected]");
}
return querySelectorAllSubtree(listbox, '[aria-selected="true"]');
}
function isMarkedPresentational(node) {
return hasAnyConcreteRoles(node, ["none", "presentation"]);
}
/**
* Elements specifically listed in html-aam
*
* We don't need this for `label` or `legend` elements.
* Their implicit roles already allow "naming from content".
*
* sources:
*
* - https://w3c.github.io/html-aam/#table-element
*/
function isNativeHostLanguageTextAlternativeElement(node) {
return isHTMLTableCaptionElement(node);
}
/**
* https://w3c.github.io/aria/#namefromcontent
*/
function allowsNameFromContent(node) {
return hasAnyConcreteRoles(node, ["button", "cell", "checkbox", "columnheader", "gridcell", "heading", "label", "legend", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "row", "rowheader", "switch", "tab", "tooltip", "treeitem"]);
}
/**
* TODO https://github.com/eps1lon/dom-accessibility-api/issues/100
*/
function isDescendantOfNativeHostLanguageTextAlternativeElement(
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- not implemented yet
node) {
return false;
}
function getValueOfTextbox(element) {
if (isHTMLInputElement(element) || isHTMLTextAreaElement(element)) {
return element.value;
}
// https://github.com/eps1lon/dom-accessibility-api/issues/4
return element.textContent || "";
}
function getTextualContent(declaration) {
var content = declaration.getPropertyValue("content");
if (/^["'].*["']$/.test(content)) {
return content.slice(1, -1);
}
return "";
}
/**
* https://html.spec.whatwg.org/multipage/forms.html#category-label
* TODO: form-associated custom elements
* @param element
*/
function isLabelableElement(element) {
var localName = getLocalName(element);
return localName === "button" || localName === "input" && element.getAttribute("type") !== "hidden" || localName === "meter" || localName === "output" || localName === "progress" || localName === "select" || localName === "textarea";
}
/**
* > [...], then the first such descendant in tree order is the label element's labeled control.
* -- https://html.spec.whatwg.org/multipage/forms.html#labeled-control
* @param element
*/
function findLabelableElement(element) {
if (isLabelableElement(element)) {
return element;
}
var labelableElement = null;
element.childNodes.forEach(function (childNode) {
if (labelableElement === null && isElement(childNode)) {
var descendantLabelableElement = findLabelableElement(childNode);
if (descendantLabelableElement !== null) {
labelableElement = descendantLabelableElement;
}
}
});
return labelableElement;
}
/**
* Polyfill of HTMLLabelElement.control
* https://html.spec.whatwg.org/multipage/forms.html#labeled-control
* @param label
*/
function getControlOfLabel(label) {
if (label.control !== undefined) {
return label.control;
}
var htmlFor = label.getAttribute("for");
if (htmlFor !== null) {
return label.ownerDocument.getElementById(htmlFor);
}
return findLabelableElement(label);
}
/**
* Polyfill of HTMLInputElement.labels
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/labels
* @param element
*/
function getLabels(element) {
var labelsProperty = element.labels;
if (labelsProperty === null) {
return labelsProperty;
}
if (labelsProperty !== undefined) {
return ArrayFrom(labelsProperty);
}
// polyfill
if (!isLabelableElement(element)) {
return null;
}
var document = element.ownerDocument;
return ArrayFrom(document.querySelectorAll("label")).filter(function (label) {
return getControlOfLabel(label) === element;
});
}
/**
* Gets the contents of a slot used for computing the accname
* @param slot
*/
function getSlotContents(slot) {
// Computing the accessible name for elements containing slots is not
// currently defined in the spec. This implementation reflects the
// behavior of NVDA 2020.2/Firefox 81 and iOS VoiceOver/Safari 13.6.
var assignedNodes = slot.assignedNodes();
if (assignedNodes.length === 0) {
// if no nodes are assigned to the slot, it displays the default content
return ArrayFrom(slot.childNodes);
}
return assignedNodes;
}
/**
* implements https://w3c.github.io/accname/#mapping_additional_nd_te
* @param root
* @param options
* @returns
*/
export function computeTextAlternative(root) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var consultedNodes = new SetLike();
var window = safeWindow(root);
var _options$compute = options.compute,
compute = _options$compute === void 0 ? "name" : _options$compute,
_options$computedStyl = options.computedStyleSupportsPseudoElements,
computedStyleSupportsPseudoElements = _options$computedStyl === void 0 ? options.getComputedStyle !== undefined : _options$computedStyl,
_options$getComputedS = options.getComputedStyle,
getComputedStyle = _options$getComputedS === void 0 ? window.getComputedStyle.bind(window) : _options$getComputedS,
_options$hidden = options.hidden,
hidden = _options$hidden === void 0 ? false : _options$hidden;
// 2F.i
function computeMiscTextAlternative(node, context) {
var accumulatedText = "";
if (isElement(node) && computedStyleSupportsPseudoElements) {
var pseudoBefore = getComputedStyle(node, "::before");
var beforeContent = getTextualContent(pseudoBefore);
accumulatedText = "".concat(beforeContent, " ").concat(accumulatedText);
}
// FIXME: Including aria-owns is not defined in the spec
// But it is required in the web-platform-test
var childNodes = isHTMLSlotElement(node) ? getSlotContents(node) : ArrayFrom(node.childNodes).concat(queryIdRefs(node, "aria-owns"));
childNodes.forEach(function (child) {
var result = computeTextAlternative(child, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false,
recursion: true
});
// TODO: Unclear why display affects delimiter
// see https://github.com/w3c/accname/issues/3
var display = isElement(child) ? getComputedStyle(child).getPropertyValue("display") : "inline";
var separator = display !== "inline" ? " " : "";
// trailing separator for wpt tests
accumulatedText += "".concat(separator).concat(result).concat(separator);
});
if (isElement(node) && computedStyleSupportsPseudoElements) {
var pseudoAfter = getComputedStyle(node, "::after");
var afterContent = getTextualContent(pseudoAfter);
accumulatedText = "".concat(accumulatedText, " ").concat(afterContent);
}
return accumulatedText.trim();
}
/**
*
* @param element
* @param attributeName
* @returns A string non-empty string or `null`
*/
function useAttribute(element, attributeName) {
var attribute = element.getAttributeNode(attributeName);
if (attribute !== null && !consultedNodes.has(attribute) && attribute.value.trim() !== "") {
consultedNodes.add(attribute);
return attribute.value;
}
return null;
}
function computeTooltipAttributeValue(node) {
if (!isElement(node)) {
return null;
}
return useAttribute(node, "title");
}
function computeElementTextAlternative(node) {
if (!isElement(node)) {
return null;
}
// https://w3c.github.io/html-aam/#fieldset-and-legend-elements
if (isHTMLFieldSetElement(node)) {
consultedNodes.add(node);
var children = ArrayFrom(node.childNodes);
for (var i = 0; i < children.length; i += 1) {
var child = children[i];
if (isHTMLLegendElement(child)) {
return computeTextAlternative(child, {
isEmbeddedInLabel: false,
isReferenced: false,
recursion: false
});
}
}
} else if (isHTMLTableElement(node)) {
// https://w3c.github.io/html-aam/#table-element
consultedNodes.add(node);
var _children = ArrayFrom(node.childNodes);
for (var _i = 0; _i < _children.length; _i += 1) {
var _child = _children[_i];
if (isHTMLTableCaptionElement(_child)) {
return computeTextAlternative(_child, {
isEmbeddedInLabel: false,
isReferenced: false,
recursion: false
});
}
}
} else if (isSVGSVGElement(node)) {
// https://www.w3.org/TR/svg-aam-1.0/
consultedNodes.add(node);
var _children2 = ArrayFrom(node.childNodes);
for (var _i2 = 0; _i2 < _children2.length; _i2 += 1) {
var _child2 = _children2[_i2];
if (isSVGTitleElement(_child2)) {
return _child2.textContent;
}
}
return null;
} else if (getLocalName(node) === "img" || getLocalName(node) === "area") {
// https://w3c.github.io/html-aam/#area-element
// https://w3c.github.io/html-aam/#img-element
var nameFromAlt = useAttribute(node, "alt");
if (nameFromAlt !== null) {
return nameFromAlt;
}
} else if (isHTMLOptGroupElement(node)) {
var nameFromLabel = useAttribute(node, "label");
if (nameFromLabel !== null) {
return nameFromLabel;
}
}
if (isHTMLInputElement(node) && (node.type === "button" || node.type === "submit" || node.type === "reset")) {
// https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-email-input-type-url-and-textarea-element-accessible-description-computation
var nameFromValue = useAttribute(node, "value");
if (nameFromValue !== null) {
return nameFromValue;
}
// TODO: l10n
if (node.type === "submit") {
return "Submit";
}
// TODO: l10n
if (node.type === "reset") {
return "Reset";
}
}
var labels = getLabels(node);
if (labels !== null && labels.length !== 0) {
consultedNodes.add(node);
return ArrayFrom(labels).map(function (element) {
return computeTextAlternative(element, {
isEmbeddedInLabel: true,
isReferenced: false,
recursion: true
});
}).filter(function (label) {
return label.length > 0;
}).join(" ");
}
// https://w3c.github.io/html-aam/#input-type-image-accessible-name-computation
// TODO: wpt test consider label elements but html-aam does not mention them
// We follow existing implementations over spec
if (isHTMLInputElement(node) && node.type === "image") {
var _nameFromAlt = useAttribute(node, "alt");
if (_nameFromAlt !== null) {
return _nameFromAlt;
}
var nameFromTitle = useAttribute(node, "title");
if (nameFromTitle !== null) {
return nameFromTitle;
}
// TODO: l10n
return "Submit Query";
}
if (hasAnyConcreteRoles(node, ["button"])) {
// https://www.w3.org/TR/html-aam-1.0/#button-element
var nameFromSubTree = computeMiscTextAlternative(node, {
isEmbeddedInLabel: false,
isReferenced: false
});
if (nameFromSubTree !== "") {
return nameFromSubTree;
}
}
return null;
}
function computeTextAlternative(current, context) {
if (consultedNodes.has(current)) {
return "";
}
// 2A
if (!hidden && isHidden(current, getComputedStyle) && !context.isReferenced) {
consultedNodes.add(current);
return "";
}
// 2B
var labelAttributeNode = isElement(current) ? current.getAttributeNode("aria-labelledby") : null;
// TODO: Do we generally need to block query IdRefs of attributes we have already consulted?
var labelElements = labelAttributeNode !== null && !consultedNodes.has(labelAttributeNode) ? queryIdRefs(current, "aria-labelledby") : [];
if (compute === "name" && !context.isReferenced && labelElements.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Can't be null here otherwise labelElements would be empty
consultedNodes.add(labelAttributeNode);
return labelElements.map(function (element) {
// TODO: Chrome will consider repeated values i.e. use a node multiple times while we'll bail out in computeTextAlternative.
return computeTextAlternative(element, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: true,
// this isn't recursion as specified, otherwise we would skip
// `aria-label` in
// <input id="myself" aria-label="foo" aria-labelledby="myself"
recursion: false
});
}).join(" ");
}
// 2C
// Changed from the spec in anticipation of https://github.com/w3c/accname/issues/64
// spec says we should only consider skipping if we have a non-empty label
var skipToStep2E = context.recursion && isControl(current) && compute === "name";
if (!skipToStep2E) {
var ariaLabel = (isElement(current) && current.getAttribute("aria-label") || "").trim();
if (ariaLabel !== "" && compute === "name") {
consultedNodes.add(current);
return ariaLabel;
}
// 2D
if (!isMarkedPresentational(current)) {
var elementTextAlternative = computeElementTextAlternative(current);
if (elementTextAlternative !== null) {
consultedNodes.add(current);
return elementTextAlternative;
}
}
}
// special casing, cheating to make tests pass
// https://github.com/w3c/accname/issues/67
if (hasAnyConcreteRoles(current, ["menu"])) {
consultedNodes.add(current);
return "";
}
// 2E
if (skipToStep2E || context.isEmbeddedInLabel || context.isReferenced) {
if (hasAnyConcreteRoles(current, ["combobox", "listbox"])) {
consultedNodes.add(current);
var selectedOptions = querySelectedOptions(current);
if (selectedOptions.length === 0) {
// defined per test `name_heading_combobox`
return isHTMLInputElement(current) ? current.value : "";
}
return ArrayFrom(selectedOptions).map(function (selectedOption) {
return computeTextAlternative(selectedOption, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false,
recursion: true
});
}).join(" ");
}
if (hasAbstractRole(current, "range")) {
consultedNodes.add(current);
if (current.hasAttribute("aria-valuetext")) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- safe due to hasAttribute guard
return current.getAttribute("aria-valuetext");
}
if (current.hasAttribute("aria-valuenow")) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- safe due to hasAttribute guard
return current.getAttribute("aria-valuenow");
}
// Otherwise, use the value as specified by a host language attribute.
return current.getAttribute("value") || "";
}
if (hasAnyConcreteRoles(current, ["textbox"])) {
consultedNodes.add(current);
return getValueOfTextbox(current);
}
}
// 2F: https://w3c.github.io/accname/#step2F
if (allowsNameFromContent(current) || isElement(current) && context.isReferenced || isNativeHostLanguageTextAlternativeElement(current) || isDescendantOfNativeHostLanguageTextAlternativeElement(current)) {
var accumulatedText2F = computeMiscTextAlternative(current, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false
});
if (accumulatedText2F !== "") {
consultedNodes.add(current);
return accumulatedText2F;
}
}
if (current.nodeType === current.TEXT_NODE) {
consultedNodes.add(current);
return current.textContent || "";
}
if (context.recursion) {
consultedNodes.add(current);
return computeMiscTextAlternative(current, {
isEmbeddedInLabel: context.isEmbeddedInLabel,
isReferenced: false
});
}
var tooltipAttributeValue = computeTooltipAttributeValue(current);
if (tooltipAttributeValue !== null) {
consultedNodes.add(current);
return tooltipAttributeValue;
}
// TODO should this be reachable?
consultedNodes.add(current);
return "";
}
return asFlatString(computeTextAlternative(root, {
isEmbeddedInLabel: false,
// by spec computeAccessibleDescription starts with the referenced elements as roots
isReferenced: compute === "description",
recursion: false
}));
}
//# sourceMappingURL=accessible-name-and-description.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
import { ComputeTextAlternativeOptions } from "./accessible-name-and-description";
/**
* implements https://w3c.github.io/accname/#mapping_additional_nd_name
* @param root
* @param options
* @returns
*/
export declare function computeAccessibleName(root: Element, options?: ComputeTextAlternativeOptions): string;
//# sourceMappingURL=accessible-name.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessible-name.d.ts","sourceRoot":"","sources":["../sources/accessible-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,6BAA6B,EAC7B,MAAM,mCAAmC,CAAC;AAsB3C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,6BAAkC,GACzC,MAAM,CAMR"}

View File

@@ -0,0 +1,27 @@
"use strict";
exports.__esModule = true;
exports.computeAccessibleName = computeAccessibleName;
var _accessibleNameAndDescription = require("./accessible-name-and-description");
var _util = require("./util");
/**
* https://w3c.github.io/aria/#namefromprohibited
*/
function prohibitsNaming(node) {
return (0, _util.hasAnyConcreteRoles)(node, ["caption", "code", "deletion", "emphasis", "generic", "insertion", "paragraph", "presentation", "strong", "subscript", "superscript"]);
}
/**
* implements https://w3c.github.io/accname/#mapping_additional_nd_name
* @param root
* @param options
* @returns
*/
function computeAccessibleName(root) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (prohibitsNaming(root)) {
return "";
}
return (0, _accessibleNameAndDescription.computeTextAlternative)(root, options);
}
//# sourceMappingURL=accessible-name.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessible-name.js","names":["prohibitsNaming","node","hasAnyConcreteRoles","computeAccessibleName","root","options","computeTextAlternative"],"sources":["../sources/accessible-name.ts"],"sourcesContent":["import {\n\tcomputeTextAlternative,\n\tComputeTextAlternativeOptions,\n} from \"./accessible-name-and-description\";\nimport { hasAnyConcreteRoles } from \"./util\";\n\n/**\n * https://w3c.github.io/aria/#namefromprohibited\n */\nfunction prohibitsNaming(node: Node): boolean {\n\treturn hasAnyConcreteRoles(node, [\n\t\t\"caption\",\n\t\t\"code\",\n\t\t\"deletion\",\n\t\t\"emphasis\",\n\t\t\"generic\",\n\t\t\"insertion\",\n\t\t\"paragraph\",\n\t\t\"presentation\",\n\t\t\"strong\",\n\t\t\"subscript\",\n\t\t\"superscript\",\n\t]);\n}\n\n/**\n * implements https://w3c.github.io/accname/#mapping_additional_nd_name\n * @param root\n * @param options\n * @returns\n */\nexport function computeAccessibleName(\n\troot: Element,\n\toptions: ComputeTextAlternativeOptions = {}\n): string {\n\tif (prohibitsNaming(root)) {\n\t\treturn \"\";\n\t}\n\n\treturn computeTextAlternative(root, options);\n}\n"],"mappings":";;;;AAAA;AAIA;AAEA;AACA;AACA;AACA,SAASA,eAAe,CAACC,IAAU,EAAW;EAC7C,OAAO,IAAAC,yBAAmB,EAACD,IAAI,EAAE,CAChC,SAAS,EACT,MAAM,EACN,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,cAAc,EACd,QAAQ,EACR,WAAW,EACX,aAAa,CACb,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,qBAAqB,CACpCC,IAAa,EAEJ;EAAA,IADTC,OAAsC,uEAAG,CAAC,CAAC;EAE3C,IAAIL,eAAe,CAACI,IAAI,CAAC,EAAE;IAC1B,OAAO,EAAE;EACV;EAEA,OAAO,IAAAE,oDAAsB,EAACF,IAAI,EAAEC,OAAO,CAAC;AAC7C"}

View File

@@ -0,0 +1,24 @@
import { computeTextAlternative } from "./accessible-name-and-description.mjs";
import { hasAnyConcreteRoles } from "./util.mjs";
/**
* https://w3c.github.io/aria/#namefromprohibited
*/
function prohibitsNaming(node) {
return hasAnyConcreteRoles(node, ["caption", "code", "deletion", "emphasis", "generic", "insertion", "paragraph", "presentation", "strong", "subscript", "superscript"]);
}
/**
* implements https://w3c.github.io/accname/#mapping_additional_nd_name
* @param root
* @param options
* @returns
*/
export function computeAccessibleName(root) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (prohibitsNaming(root)) {
return "";
}
return computeTextAlternative(root, options);
}
//# sourceMappingURL=accessible-name.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessible-name.mjs","names":["computeTextAlternative","hasAnyConcreteRoles","prohibitsNaming","node","computeAccessibleName","root","options"],"sources":["../sources/accessible-name.ts"],"sourcesContent":["import {\n\tcomputeTextAlternative,\n\tComputeTextAlternativeOptions,\n} from \"./accessible-name-and-description\";\nimport { hasAnyConcreteRoles } from \"./util\";\n\n/**\n * https://w3c.github.io/aria/#namefromprohibited\n */\nfunction prohibitsNaming(node: Node): boolean {\n\treturn hasAnyConcreteRoles(node, [\n\t\t\"caption\",\n\t\t\"code\",\n\t\t\"deletion\",\n\t\t\"emphasis\",\n\t\t\"generic\",\n\t\t\"insertion\",\n\t\t\"paragraph\",\n\t\t\"presentation\",\n\t\t\"strong\",\n\t\t\"subscript\",\n\t\t\"superscript\",\n\t]);\n}\n\n/**\n * implements https://w3c.github.io/accname/#mapping_additional_nd_name\n * @param root\n * @param options\n * @returns\n */\nexport function computeAccessibleName(\n\troot: Element,\n\toptions: ComputeTextAlternativeOptions = {}\n): string {\n\tif (prohibitsNaming(root)) {\n\t\treturn \"\";\n\t}\n\n\treturn computeTextAlternative(root, options);\n}\n"],"mappings":"AAAA,SACCA,sBAAsB,QAEhB,uCAAmC;AAC1C,SAASC,mBAAmB,QAAQ,YAAQ;;AAE5C;AACA;AACA;AACA,SAASC,eAAe,CAACC,IAAU,EAAW;EAC7C,OAAOF,mBAAmB,CAACE,IAAI,EAAE,CAChC,SAAS,EACT,MAAM,EACN,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,cAAc,EACd,QAAQ,EACR,WAAW,EACX,aAAa,CACb,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqB,CACpCC,IAAa,EAEJ;EAAA,IADTC,OAAsC,uEAAG,CAAC,CAAC;EAE3C,IAAIJ,eAAe,CAACG,IAAI,CAAC,EAAE;IAC1B,OAAO,EAAE;EACV;EAEA,OAAOL,sBAAsB,CAACK,IAAI,EAAEC,OAAO,CAAC;AAC7C"}

View File

@@ -0,0 +1,7 @@
/**
* Safe Element.localName for all supported environments
* @param element
*/
export declare function getLocalName(element: Element): string;
export default function getRole(element: Element): string | null;
//# sourceMappingURL=getRole.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getRole.d.ts","sourceRoot":"","sources":["../sources/getRole.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAOrD;AAgHD,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAa/D"}

View File

@@ -0,0 +1,190 @@
"use strict";
exports.__esModule = true;
exports.default = getRole;
exports.getLocalName = getLocalName;
// https://w3c.github.io/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-html
/**
* Safe Element.localName for all supported environments
* @param element
*/
function getLocalName(element) {
var _element$localName;
return (// eslint-disable-next-line no-restricted-properties -- actual guard for environments without localName
(_element$localName = element.localName) !== null && _element$localName !== void 0 ? _element$localName :
// eslint-disable-next-line no-restricted-properties -- required for the fallback
element.tagName.toLowerCase()
);
}
var localNameToRoleMappings = {
article: "article",
aside: "complementary",
button: "button",
datalist: "listbox",
dd: "definition",
details: "group",
dialog: "dialog",
dt: "term",
fieldset: "group",
figure: "figure",
// WARNING: Only with an accessible name
form: "form",
footer: "contentinfo",
h1: "heading",
h2: "heading",
h3: "heading",
h4: "heading",
h5: "heading",
h6: "heading",
header: "banner",
hr: "separator",
html: "document",
legend: "legend",
li: "listitem",
math: "math",
main: "main",
menu: "list",
nav: "navigation",
ol: "list",
optgroup: "group",
// WARNING: Only in certain context
option: "option",
output: "status",
progress: "progressbar",
// WARNING: Only with an accessible name
section: "region",
summary: "button",
table: "table",
tbody: "rowgroup",
textarea: "textbox",
tfoot: "rowgroup",
// WARNING: Only in certain context
td: "cell",
th: "columnheader",
thead: "rowgroup",
tr: "row",
ul: "list"
};
var prohibitedAttributes = {
caption: new Set(["aria-label", "aria-labelledby"]),
code: new Set(["aria-label", "aria-labelledby"]),
deletion: new Set(["aria-label", "aria-labelledby"]),
emphasis: new Set(["aria-label", "aria-labelledby"]),
generic: new Set(["aria-label", "aria-labelledby", "aria-roledescription"]),
insertion: new Set(["aria-label", "aria-labelledby"]),
paragraph: new Set(["aria-label", "aria-labelledby"]),
presentation: new Set(["aria-label", "aria-labelledby"]),
strong: new Set(["aria-label", "aria-labelledby"]),
subscript: new Set(["aria-label", "aria-labelledby"]),
superscript: new Set(["aria-label", "aria-labelledby"])
};
/**
*
* @param element
* @param role The role used for this element. This is specified to control whether you want to use the implicit or explicit role.
*/
function hasGlobalAriaAttributes(element, role) {
// https://rawgit.com/w3c/aria/stable/#global_states
// commented attributes are deprecated
return ["aria-atomic", "aria-busy", "aria-controls", "aria-current", "aria-describedby", "aria-details",
// "disabled",
"aria-dropeffect",
// "errormessage",
"aria-flowto", "aria-grabbed",
// "haspopup",
"aria-hidden",
// "invalid",
"aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-live", "aria-owns", "aria-relevant", "aria-roledescription"].some(function (attributeName) {
var _prohibitedAttributes;
return element.hasAttribute(attributeName) && !((_prohibitedAttributes = prohibitedAttributes[role]) !== null && _prohibitedAttributes !== void 0 && _prohibitedAttributes.has(attributeName));
});
}
function ignorePresentationalRole(element, implicitRole) {
// https://rawgit.com/w3c/aria/stable/#conflict_resolution_presentation_none
return hasGlobalAriaAttributes(element, implicitRole);
}
function getRole(element) {
var explicitRole = getExplicitRole(element);
if (explicitRole === null || explicitRole === "presentation") {
var implicitRole = getImplicitRole(element);
if (explicitRole !== "presentation" || ignorePresentationalRole(element, implicitRole || "")) {
return implicitRole;
}
}
return explicitRole;
}
function getImplicitRole(element) {
var mappedByTag = localNameToRoleMappings[getLocalName(element)];
if (mappedByTag !== undefined) {
return mappedByTag;
}
switch (getLocalName(element)) {
case "a":
case "area":
case "link":
if (element.hasAttribute("href")) {
return "link";
}
break;
case "img":
if (element.getAttribute("alt") === "" && !ignorePresentationalRole(element, "img")) {
return "presentation";
}
return "img";
case "input":
{
var _ref = element,
type = _ref.type;
switch (type) {
case "button":
case "image":
case "reset":
case "submit":
return "button";
case "checkbox":
case "radio":
return type;
case "range":
return "slider";
case "email":
case "tel":
case "text":
case "url":
if (element.hasAttribute("list")) {
return "combobox";
}
return "textbox";
case "search":
if (element.hasAttribute("list")) {
return "combobox";
}
return "searchbox";
case "number":
return "spinbutton";
default:
return null;
}
}
case "select":
if (element.hasAttribute("multiple") || element.size > 1) {
return "listbox";
}
return "combobox";
}
return null;
}
function getExplicitRole(element) {
var role = element.getAttribute("role");
if (role !== null) {
var explicitRole = role.trim().split(" ")[0];
// String.prototype.split(sep, limit) will always return an array with at least one member
// as long as limit is either undefined or > 0
if (explicitRole.length > 0) {
return explicitRole;
}
}
return null;
}
//# sourceMappingURL=getRole.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,185 @@
// https://w3c.github.io/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-html
/**
* Safe Element.localName for all supported environments
* @param element
*/
export function getLocalName(element) {
var _element$localName;
return (// eslint-disable-next-line no-restricted-properties -- actual guard for environments without localName
(_element$localName = element.localName) !== null && _element$localName !== void 0 ? _element$localName :
// eslint-disable-next-line no-restricted-properties -- required for the fallback
element.tagName.toLowerCase()
);
}
var localNameToRoleMappings = {
article: "article",
aside: "complementary",
button: "button",
datalist: "listbox",
dd: "definition",
details: "group",
dialog: "dialog",
dt: "term",
fieldset: "group",
figure: "figure",
// WARNING: Only with an accessible name
form: "form",
footer: "contentinfo",
h1: "heading",
h2: "heading",
h3: "heading",
h4: "heading",
h5: "heading",
h6: "heading",
header: "banner",
hr: "separator",
html: "document",
legend: "legend",
li: "listitem",
math: "math",
main: "main",
menu: "list",
nav: "navigation",
ol: "list",
optgroup: "group",
// WARNING: Only in certain context
option: "option",
output: "status",
progress: "progressbar",
// WARNING: Only with an accessible name
section: "region",
summary: "button",
table: "table",
tbody: "rowgroup",
textarea: "textbox",
tfoot: "rowgroup",
// WARNING: Only in certain context
td: "cell",
th: "columnheader",
thead: "rowgroup",
tr: "row",
ul: "list"
};
var prohibitedAttributes = {
caption: new Set(["aria-label", "aria-labelledby"]),
code: new Set(["aria-label", "aria-labelledby"]),
deletion: new Set(["aria-label", "aria-labelledby"]),
emphasis: new Set(["aria-label", "aria-labelledby"]),
generic: new Set(["aria-label", "aria-labelledby", "aria-roledescription"]),
insertion: new Set(["aria-label", "aria-labelledby"]),
paragraph: new Set(["aria-label", "aria-labelledby"]),
presentation: new Set(["aria-label", "aria-labelledby"]),
strong: new Set(["aria-label", "aria-labelledby"]),
subscript: new Set(["aria-label", "aria-labelledby"]),
superscript: new Set(["aria-label", "aria-labelledby"])
};
/**
*
* @param element
* @param role The role used for this element. This is specified to control whether you want to use the implicit or explicit role.
*/
function hasGlobalAriaAttributes(element, role) {
// https://rawgit.com/w3c/aria/stable/#global_states
// commented attributes are deprecated
return ["aria-atomic", "aria-busy", "aria-controls", "aria-current", "aria-describedby", "aria-details",
// "disabled",
"aria-dropeffect",
// "errormessage",
"aria-flowto", "aria-grabbed",
// "haspopup",
"aria-hidden",
// "invalid",
"aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-live", "aria-owns", "aria-relevant", "aria-roledescription"].some(function (attributeName) {
var _prohibitedAttributes;
return element.hasAttribute(attributeName) && !((_prohibitedAttributes = prohibitedAttributes[role]) !== null && _prohibitedAttributes !== void 0 && _prohibitedAttributes.has(attributeName));
});
}
function ignorePresentationalRole(element, implicitRole) {
// https://rawgit.com/w3c/aria/stable/#conflict_resolution_presentation_none
return hasGlobalAriaAttributes(element, implicitRole);
}
export default function getRole(element) {
var explicitRole = getExplicitRole(element);
if (explicitRole === null || explicitRole === "presentation") {
var implicitRole = getImplicitRole(element);
if (explicitRole !== "presentation" || ignorePresentationalRole(element, implicitRole || "")) {
return implicitRole;
}
}
return explicitRole;
}
function getImplicitRole(element) {
var mappedByTag = localNameToRoleMappings[getLocalName(element)];
if (mappedByTag !== undefined) {
return mappedByTag;
}
switch (getLocalName(element)) {
case "a":
case "area":
case "link":
if (element.hasAttribute("href")) {
return "link";
}
break;
case "img":
if (element.getAttribute("alt") === "" && !ignorePresentationalRole(element, "img")) {
return "presentation";
}
return "img";
case "input":
{
var _ref = element,
type = _ref.type;
switch (type) {
case "button":
case "image":
case "reset":
case "submit":
return "button";
case "checkbox":
case "radio":
return type;
case "range":
return "slider";
case "email":
case "tel":
case "text":
case "url":
if (element.hasAttribute("list")) {
return "combobox";
}
return "textbox";
case "search":
if (element.hasAttribute("list")) {
return "combobox";
}
return "searchbox";
case "number":
return "spinbutton";
default:
return null;
}
}
case "select":
if (element.hasAttribute("multiple") || element.size > 1) {
return "listbox";
}
return "combobox";
}
return null;
}
function getExplicitRole(element) {
var role = element.getAttribute("role");
if (role !== null) {
var explicitRole = role.trim().split(" ")[0];
// String.prototype.split(sep, limit) will always return an array with at least one member
// as long as limit is either undefined or > 0
if (explicitRole.length > 0) {
return explicitRole;
}
}
return null;
}
//# sourceMappingURL=getRole.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
export { computeAccessibleDescription } from "./accessible-description";
export { computeAccessibleName } from "./accessible-name";
export { default as getRole } from "./getRole";
export * from "./is-inaccessible";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../sources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,cAAc,mBAAmB,CAAC"}

View File

@@ -0,0 +1,24 @@
"use strict";
exports.__esModule = true;
var _exportNames = {
computeAccessibleDescription: true,
computeAccessibleName: true,
getRole: true
};
exports.getRole = exports.computeAccessibleName = exports.computeAccessibleDescription = void 0;
var _accessibleDescription = require("./accessible-description");
exports.computeAccessibleDescription = _accessibleDescription.computeAccessibleDescription;
var _accessibleName = require("./accessible-name");
exports.computeAccessibleName = _accessibleName.computeAccessibleName;
var _getRole = _interopRequireDefault(require("./getRole"));
exports.getRole = _getRole.default;
var _isInaccessible = require("./is-inaccessible");
Object.keys(_isInaccessible).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
if (key in exports && exports[key] === _isInaccessible[key]) return;
exports[key] = _isInaccessible[key];
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":[],"sources":["../sources/index.ts"],"sourcesContent":["export { computeAccessibleDescription } from \"./accessible-description\";\nexport { computeAccessibleName } from \"./accessible-name\";\nexport { default as getRole } from \"./getRole\";\nexport * from \"./is-inaccessible\";\n"],"mappings":";;;;;;;;;AAAA;AAAwE;AACxE;AAA0D;AAC1D;AAA+C;AAC/C;AAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAAkC"}

View File

@@ -0,0 +1,5 @@
export { computeAccessibleDescription } from "./accessible-description.mjs";
export { computeAccessibleName } from "./accessible-name.mjs";
export { default as getRole } from "./getRole.mjs";
export * from "./is-inaccessible.mjs";
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","names":["computeAccessibleDescription","computeAccessibleName","default","getRole"],"sources":["../sources/index.ts"],"sourcesContent":["export { computeAccessibleDescription } from \"./accessible-description\";\nexport { computeAccessibleName } from \"./accessible-name\";\nexport { default as getRole } from \"./getRole\";\nexport * from \"./is-inaccessible\";\n"],"mappings":"AAAA,SAASA,4BAA4B,QAAQ,8BAA0B;AACvE,SAASC,qBAAqB,QAAQ,uBAAmB;AACzD,SAASC,OAAO,IAAIC,OAAO,QAAQ,eAAW;AAC9C,cAAc,uBAAmB"}

View File

@@ -0,0 +1,31 @@
export interface IsInaccessibleOptions {
getComputedStyle?: typeof window.getComputedStyle;
/**
* Can be used to return cached results from previous isSubtreeInaccessible calls.
*/
isSubtreeInaccessible?: (element: Element) => boolean;
}
/**
* Partial implementation https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
* which should only be used for elements with a non-presentational role i.e.
* `role="none"` and `role="presentation"` will not be excluded.
*
* Implements aria-hidden semantics (i.e. parent overrides child)
* Ignores "Child Presentational: True" characteristics
*
* @param element
* @param options
* @returns {boolean} true if excluded, otherwise false
*/
export declare function isInaccessible(element: Element, options?: IsInaccessibleOptions): boolean;
export interface IsSubtreeInaccessibleOptions {
getComputedStyle?: typeof window.getComputedStyle;
}
/**
*
* @param element
* @param options
* @returns {boolean} - `true` if every child of the element is inaccessible
*/
export declare function isSubtreeInaccessible(element: Element, options?: IsSubtreeInaccessibleOptions): boolean;
//# sourceMappingURL=is-inaccessible.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-inaccessible.d.ts","sourceRoot":"","sources":["../sources/is-inaccessible.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACrC,gBAAgB,CAAC,EAAE,OAAO,MAAM,CAAC,gBAAgB,CAAC;IAClD;;OAEG;IACH,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;CACtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAyBT;AAED,MAAM,WAAW,4BAA4B;IAC5C,gBAAgB,CAAC,EAAE,OAAO,MAAM,CAAC,gBAAgB,CAAC;CAClD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,4BAAiC,GACxC,OAAO,CAuBT"}

View File

@@ -0,0 +1,68 @@
"use strict";
exports.__esModule = true;
exports.isInaccessible = isInaccessible;
exports.isSubtreeInaccessible = isSubtreeInaccessible;
/**
* Partial implementation https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
* which should only be used for elements with a non-presentational role i.e.
* `role="none"` and `role="presentation"` will not be excluded.
*
* Implements aria-hidden semantics (i.e. parent overrides child)
* Ignores "Child Presentational: True" characteristics
*
* @param element
* @param options
* @returns {boolean} true if excluded, otherwise false
*/
function isInaccessible(element) {
var _element$ownerDocumen;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _options$getComputedS = options.getComputedStyle,
getComputedStyle = _options$getComputedS === void 0 ? (_element$ownerDocumen = element.ownerDocument.defaultView) === null || _element$ownerDocumen === void 0 ? void 0 : _element$ownerDocumen.getComputedStyle : _options$getComputedS,
_options$isSubtreeIna = options.isSubtreeInaccessible,
isSubtreeInaccessibleImpl = _options$isSubtreeIna === void 0 ? isSubtreeInaccessible : _options$isSubtreeIna;
if (typeof getComputedStyle !== "function") {
throw new TypeError("Owner document of the element needs to have an associated window.");
}
// since visibility is inherited we can exit early
if (getComputedStyle(element).visibility === "hidden") {
return true;
}
var currentElement = element;
while (currentElement) {
if (isSubtreeInaccessibleImpl(currentElement, {
getComputedStyle: getComputedStyle
})) {
return true;
}
currentElement = currentElement.parentElement;
}
return false;
}
/**
*
* @param element
* @param options
* @returns {boolean} - `true` if every child of the element is inaccessible
*/
function isSubtreeInaccessible(element) {
var _element$ownerDocumen2;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _options$getComputedS2 = options.getComputedStyle,
getComputedStyle = _options$getComputedS2 === void 0 ? (_element$ownerDocumen2 = element.ownerDocument.defaultView) === null || _element$ownerDocumen2 === void 0 ? void 0 : _element$ownerDocumen2.getComputedStyle : _options$getComputedS2;
if (typeof getComputedStyle !== "function") {
throw new TypeError("Owner document of the element needs to have an associated window.");
}
if (element.hidden === true) {
return true;
}
if (element.getAttribute("aria-hidden") === "true") {
return true;
}
if (getComputedStyle(element).display === "none") {
return true;
}
return false;
}
//# sourceMappingURL=is-inaccessible.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-inaccessible.js","names":["isInaccessible","element","options","getComputedStyle","ownerDocument","defaultView","isSubtreeInaccessible","isSubtreeInaccessibleImpl","TypeError","visibility","currentElement","parentElement","hidden","getAttribute","display"],"sources":["../sources/is-inaccessible.ts"],"sourcesContent":["export interface IsInaccessibleOptions {\n\tgetComputedStyle?: typeof window.getComputedStyle;\n\t/**\n\t * Can be used to return cached results from previous isSubtreeInaccessible calls.\n\t */\n\tisSubtreeInaccessible?: (element: Element) => boolean;\n}\n\n/**\n * Partial implementation https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion\n * which should only be used for elements with a non-presentational role i.e.\n * `role=\"none\"` and `role=\"presentation\"` will not be excluded.\n *\n * Implements aria-hidden semantics (i.e. parent overrides child)\n * Ignores \"Child Presentational: True\" characteristics\n *\n * @param element\n * @param options\n * @returns {boolean} true if excluded, otherwise false\n */\nexport function isInaccessible(\n\telement: Element,\n\toptions: IsInaccessibleOptions = {}\n): boolean {\n\tconst {\n\t\tgetComputedStyle = element.ownerDocument.defaultView?.getComputedStyle,\n\t\tisSubtreeInaccessible: isSubtreeInaccessibleImpl = isSubtreeInaccessible,\n\t} = options;\n\tif (typeof getComputedStyle !== \"function\") {\n\t\tthrow new TypeError(\n\t\t\t\"Owner document of the element needs to have an associated window.\"\n\t\t);\n\t}\n\t// since visibility is inherited we can exit early\n\tif (getComputedStyle(element).visibility === \"hidden\") {\n\t\treturn true;\n\t}\n\n\tlet currentElement: Element | null = element;\n\twhile (currentElement) {\n\t\tif (isSubtreeInaccessibleImpl(currentElement, { getComputedStyle })) {\n\t\t\treturn true;\n\t\t}\n\n\t\tcurrentElement = currentElement.parentElement;\n\t}\n\n\treturn false;\n}\n\nexport interface IsSubtreeInaccessibleOptions {\n\tgetComputedStyle?: typeof window.getComputedStyle;\n}\n\n/**\n *\n * @param element\n * @param options\n * @returns {boolean} - `true` if every child of the element is inaccessible\n */\nexport function isSubtreeInaccessible(\n\telement: Element,\n\toptions: IsSubtreeInaccessibleOptions = {}\n): boolean {\n\tconst {\n\t\tgetComputedStyle = element.ownerDocument.defaultView?.getComputedStyle,\n\t} = options;\n\tif (typeof getComputedStyle !== \"function\") {\n\t\tthrow new TypeError(\n\t\t\t\"Owner document of the element needs to have an associated window.\"\n\t\t);\n\t}\n\n\tif ((element as HTMLElement).hidden === true) {\n\t\treturn true;\n\t}\n\n\tif (element.getAttribute(\"aria-hidden\") === \"true\") {\n\t\treturn true;\n\t}\n\n\tif (getComputedStyle(element).display === \"none\") {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n"],"mappings":";;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,cAAc,CAC7BC,OAAgB,EAEN;EAAA;EAAA,IADVC,OAA8B,uEAAG,CAAC,CAAC;EAEnC,4BAGIA,OAAO,CAFVC,gBAAgB;IAAhBA,gBAAgB,+DAAGF,OAAO,CAACG,aAAa,CAACC,WAAW,0DAAjC,sBAAmCF,gBAAgB;IAAA,wBAEnED,OAAO,CADVI,qBAAqB;IAAEC,yBAAyB,sCAAGD,qBAAqB;EAEzE,IAAI,OAAOH,gBAAgB,KAAK,UAAU,EAAE;IAC3C,MAAM,IAAIK,SAAS,CAClB,mEAAmE,CACnE;EACF;EACA;EACA,IAAIL,gBAAgB,CAACF,OAAO,CAAC,CAACQ,UAAU,KAAK,QAAQ,EAAE;IACtD,OAAO,IAAI;EACZ;EAEA,IAAIC,cAA8B,GAAGT,OAAO;EAC5C,OAAOS,cAAc,EAAE;IACtB,IAAIH,yBAAyB,CAACG,cAAc,EAAE;MAAEP,gBAAgB,EAAhBA;IAAiB,CAAC,CAAC,EAAE;MACpE,OAAO,IAAI;IACZ;IAEAO,cAAc,GAAGA,cAAc,CAACC,aAAa;EAC9C;EAEA,OAAO,KAAK;AACb;AAMA;AACA;AACA;AACA;AACA;AACA;AACO,SAASL,qBAAqB,CACpCL,OAAgB,EAEN;EAAA;EAAA,IADVC,OAAqC,uEAAG,CAAC,CAAC;EAE1C,6BAEIA,OAAO,CADVC,gBAAgB;IAAhBA,gBAAgB,iEAAGF,OAAO,CAACG,aAAa,CAACC,WAAW,2DAAjC,uBAAmCF,gBAAgB;EAEvE,IAAI,OAAOA,gBAAgB,KAAK,UAAU,EAAE;IAC3C,MAAM,IAAIK,SAAS,CAClB,mEAAmE,CACnE;EACF;EAEA,IAAKP,OAAO,CAAiBW,MAAM,KAAK,IAAI,EAAE;IAC7C,OAAO,IAAI;EACZ;EAEA,IAAIX,OAAO,CAACY,YAAY,CAAC,aAAa,CAAC,KAAK,MAAM,EAAE;IACnD,OAAO,IAAI;EACZ;EAEA,IAAIV,gBAAgB,CAACF,OAAO,CAAC,CAACa,OAAO,KAAK,MAAM,EAAE;IACjD,OAAO,IAAI;EACZ;EAEA,OAAO,KAAK;AACb"}

View File

@@ -0,0 +1,63 @@
/**
* Partial implementation https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
* which should only be used for elements with a non-presentational role i.e.
* `role="none"` and `role="presentation"` will not be excluded.
*
* Implements aria-hidden semantics (i.e. parent overrides child)
* Ignores "Child Presentational: True" characteristics
*
* @param element
* @param options
* @returns {boolean} true if excluded, otherwise false
*/
export function isInaccessible(element) {
var _element$ownerDocumen;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _options$getComputedS = options.getComputedStyle,
getComputedStyle = _options$getComputedS === void 0 ? (_element$ownerDocumen = element.ownerDocument.defaultView) === null || _element$ownerDocumen === void 0 ? void 0 : _element$ownerDocumen.getComputedStyle : _options$getComputedS,
_options$isSubtreeIna = options.isSubtreeInaccessible,
isSubtreeInaccessibleImpl = _options$isSubtreeIna === void 0 ? isSubtreeInaccessible : _options$isSubtreeIna;
if (typeof getComputedStyle !== "function") {
throw new TypeError("Owner document of the element needs to have an associated window.");
}
// since visibility is inherited we can exit early
if (getComputedStyle(element).visibility === "hidden") {
return true;
}
var currentElement = element;
while (currentElement) {
if (isSubtreeInaccessibleImpl(currentElement, {
getComputedStyle: getComputedStyle
})) {
return true;
}
currentElement = currentElement.parentElement;
}
return false;
}
/**
*
* @param element
* @param options
* @returns {boolean} - `true` if every child of the element is inaccessible
*/
export function isSubtreeInaccessible(element) {
var _element$ownerDocumen2;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _options$getComputedS2 = options.getComputedStyle,
getComputedStyle = _options$getComputedS2 === void 0 ? (_element$ownerDocumen2 = element.ownerDocument.defaultView) === null || _element$ownerDocumen2 === void 0 ? void 0 : _element$ownerDocumen2.getComputedStyle : _options$getComputedS2;
if (typeof getComputedStyle !== "function") {
throw new TypeError("Owner document of the element needs to have an associated window.");
}
if (element.hidden === true) {
return true;
}
if (element.getAttribute("aria-hidden") === "true") {
return true;
}
if (getComputedStyle(element).display === "none") {
return true;
}
return false;
}
//# sourceMappingURL=is-inaccessible.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-inaccessible.mjs","names":["isInaccessible","element","options","getComputedStyle","ownerDocument","defaultView","isSubtreeInaccessible","isSubtreeInaccessibleImpl","TypeError","visibility","currentElement","parentElement","hidden","getAttribute","display"],"sources":["../sources/is-inaccessible.ts"],"sourcesContent":["export interface IsInaccessibleOptions {\n\tgetComputedStyle?: typeof window.getComputedStyle;\n\t/**\n\t * Can be used to return cached results from previous isSubtreeInaccessible calls.\n\t */\n\tisSubtreeInaccessible?: (element: Element) => boolean;\n}\n\n/**\n * Partial implementation https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion\n * which should only be used for elements with a non-presentational role i.e.\n * `role=\"none\"` and `role=\"presentation\"` will not be excluded.\n *\n * Implements aria-hidden semantics (i.e. parent overrides child)\n * Ignores \"Child Presentational: True\" characteristics\n *\n * @param element\n * @param options\n * @returns {boolean} true if excluded, otherwise false\n */\nexport function isInaccessible(\n\telement: Element,\n\toptions: IsInaccessibleOptions = {}\n): boolean {\n\tconst {\n\t\tgetComputedStyle = element.ownerDocument.defaultView?.getComputedStyle,\n\t\tisSubtreeInaccessible: isSubtreeInaccessibleImpl = isSubtreeInaccessible,\n\t} = options;\n\tif (typeof getComputedStyle !== \"function\") {\n\t\tthrow new TypeError(\n\t\t\t\"Owner document of the element needs to have an associated window.\"\n\t\t);\n\t}\n\t// since visibility is inherited we can exit early\n\tif (getComputedStyle(element).visibility === \"hidden\") {\n\t\treturn true;\n\t}\n\n\tlet currentElement: Element | null = element;\n\twhile (currentElement) {\n\t\tif (isSubtreeInaccessibleImpl(currentElement, { getComputedStyle })) {\n\t\t\treturn true;\n\t\t}\n\n\t\tcurrentElement = currentElement.parentElement;\n\t}\n\n\treturn false;\n}\n\nexport interface IsSubtreeInaccessibleOptions {\n\tgetComputedStyle?: typeof window.getComputedStyle;\n}\n\n/**\n *\n * @param element\n * @param options\n * @returns {boolean} - `true` if every child of the element is inaccessible\n */\nexport function isSubtreeInaccessible(\n\telement: Element,\n\toptions: IsSubtreeInaccessibleOptions = {}\n): boolean {\n\tconst {\n\t\tgetComputedStyle = element.ownerDocument.defaultView?.getComputedStyle,\n\t} = options;\n\tif (typeof getComputedStyle !== \"function\") {\n\t\tthrow new TypeError(\n\t\t\t\"Owner document of the element needs to have an associated window.\"\n\t\t);\n\t}\n\n\tif ((element as HTMLElement).hidden === true) {\n\t\treturn true;\n\t}\n\n\tif (element.getAttribute(\"aria-hidden\") === \"true\") {\n\t\treturn true;\n\t}\n\n\tif (getComputedStyle(element).display === \"none\") {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n"],"mappings":"AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,cAAc,CAC7BC,OAAgB,EAEN;EAAA;EAAA,IADVC,OAA8B,uEAAG,CAAC,CAAC;EAEnC,4BAGIA,OAAO,CAFVC,gBAAgB;IAAhBA,gBAAgB,+DAAGF,OAAO,CAACG,aAAa,CAACC,WAAW,0DAAjC,sBAAmCF,gBAAgB;IAAA,wBAEnED,OAAO,CADVI,qBAAqB;IAAEC,yBAAyB,sCAAGD,qBAAqB;EAEzE,IAAI,OAAOH,gBAAgB,KAAK,UAAU,EAAE;IAC3C,MAAM,IAAIK,SAAS,CAClB,mEAAmE,CACnE;EACF;EACA;EACA,IAAIL,gBAAgB,CAACF,OAAO,CAAC,CAACQ,UAAU,KAAK,QAAQ,EAAE;IACtD,OAAO,IAAI;EACZ;EAEA,IAAIC,cAA8B,GAAGT,OAAO;EAC5C,OAAOS,cAAc,EAAE;IACtB,IAAIH,yBAAyB,CAACG,cAAc,EAAE;MAAEP,gBAAgB,EAAhBA;IAAiB,CAAC,CAAC,EAAE;MACpE,OAAO,IAAI;IACZ;IAEAO,cAAc,GAAGA,cAAc,CAACC,aAAa;EAC9C;EAEA,OAAO,KAAK;AACb;AAMA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASL,qBAAqB,CACpCL,OAAgB,EAEN;EAAA;EAAA,IADVC,OAAqC,uEAAG,CAAC,CAAC;EAE1C,6BAEIA,OAAO,CADVC,gBAAgB;IAAhBA,gBAAgB,iEAAGF,OAAO,CAACG,aAAa,CAACC,WAAW,2DAAjC,uBAAmCF,gBAAgB;EAEvE,IAAI,OAAOA,gBAAgB,KAAK,UAAU,EAAE;IAC3C,MAAM,IAAIK,SAAS,CAClB,mEAAmE,CACnE;EACF;EAEA,IAAKP,OAAO,CAAiBW,MAAM,KAAK,IAAI,EAAE;IAC7C,OAAO,IAAI;EACZ;EAEA,IAAIX,OAAO,CAACY,YAAY,CAAC,aAAa,CAAC,KAAK,MAAM,EAAE;IACnD,OAAO,IAAI;EACZ;EAEA,IAAIV,gBAAgB,CAACF,OAAO,CAAC,CAACa,OAAO,KAAK,MAAM,EAAE;IACjD,OAAO,IAAI;EACZ;EAEA,OAAO,KAAK;AACb"}

View File

@@ -0,0 +1,14 @@
declare global {
class Set<T> {
constructor(items?: T[]);
add(value: T): this;
clear(): void;
delete(value: T): boolean;
forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: unknown): void;
has(value: T): boolean;
readonly size: number;
}
}
declare const _default: typeof Set;
export default _default;
//# sourceMappingURL=SetLike.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SetLike.d.ts","sourceRoot":"","sources":["../../sources/polyfills/SetLike.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACd,MAAM,GAAG,CAAC,CAAC;oBAEE,KAAK,CAAC,EAAE,CAAC,EAAE;QACvB,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;QACnB,KAAK,IAAI,IAAI;QACb,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO;QACzB,OAAO,CACN,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EACtD,OAAO,CAAC,EAAE,OAAO,GACf,IAAI;QACP,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO;QACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KAItB;CACD;;AAuCD,wBAA0D"}

View File

@@ -0,0 +1,65 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
// for environments without Set we fallback to arrays with unique members
var SetLike = /*#__PURE__*/function () {
function SetLike() {
var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
_classCallCheck(this, SetLike);
_defineProperty(this, "items", void 0);
this.items = items;
}
_createClass(SetLike, [{
key: "add",
value: function add(value) {
if (this.has(value) === false) {
this.items.push(value);
}
return this;
}
}, {
key: "clear",
value: function clear() {
this.items = [];
}
}, {
key: "delete",
value: function _delete(value) {
var previousLength = this.items.length;
this.items = this.items.filter(function (item) {
return item !== value;
});
return previousLength !== this.items.length;
}
}, {
key: "forEach",
value: function forEach(callbackfn) {
var _this = this;
this.items.forEach(function (item) {
callbackfn(item, item, _this);
});
}
}, {
key: "has",
value: function has(value) {
return this.items.indexOf(value) !== -1;
}
}, {
key: "size",
get: function get() {
return this.items.length;
}
}]);
return SetLike;
}();
var _default = typeof Set === "undefined" ? Set : SetLike;
exports.default = _default;
//# sourceMappingURL=SetLike.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SetLike.js","names":["SetLike","items","value","has","push","previousLength","length","filter","item","callbackfn","forEach","indexOf","Set"],"sources":["../../sources/polyfills/SetLike.ts"],"sourcesContent":["declare global {\n\tclass Set<T> {\n\t\t// es2015.collection.d.ts\n\t\tconstructor(items?: T[]);\n\t\tadd(value: T): this;\n\t\tclear(): void;\n\t\tdelete(value: T): boolean;\n\t\tforEach(\n\t\t\tcallbackfn: (value: T, value2: T, set: Set<T>) => void,\n\t\t\tthisArg?: unknown\n\t\t): void;\n\t\thas(value: T): boolean;\n\t\treadonly size: number;\n\n\t\t// es2015.iterable.d.ts\n\t\t// no implemennted\n\t}\n}\n\n// for environments without Set we fallback to arrays with unique members\nclass SetLike<T> implements Set<T> {\n\tprivate items: T[];\n\n\tconstructor(items: T[] = []) {\n\t\tthis.items = items;\n\t}\n\n\tadd(value: T): this {\n\t\tif (this.has(value) === false) {\n\t\t\tthis.items.push(value);\n\t\t}\n\t\treturn this;\n\t}\n\tclear(): void {\n\t\tthis.items = [];\n\t}\n\tdelete(value: T): boolean {\n\t\tconst previousLength = this.items.length;\n\t\tthis.items = this.items.filter((item) => item !== value);\n\n\t\treturn previousLength !== this.items.length;\n\t}\n\tforEach(callbackfn: (value: T, value2: T, set: Set<T>) => void): void {\n\t\tthis.items.forEach((item) => {\n\t\t\tcallbackfn(item, item, this);\n\t\t});\n\t}\n\thas(value: T): boolean {\n\t\treturn this.items.indexOf(value) !== -1;\n\t}\n\n\tget size(): number {\n\t\treturn this.items.length;\n\t}\n}\n\nexport default typeof Set === \"undefined\" ? Set : SetLike;\n"],"mappings":";;;;;;;;;;;AAmBA;AAAA,IACMA,OAAO;EAGZ,mBAA6B;IAAA,IAAjBC,KAAU,uEAAG,EAAE;IAAA;IAAA;IAC1B,IAAI,CAACA,KAAK,GAAGA,KAAK;EACnB;EAAC;IAAA;IAAA,OAED,aAAIC,KAAQ,EAAQ;MACnB,IAAI,IAAI,CAACC,GAAG,CAACD,KAAK,CAAC,KAAK,KAAK,EAAE;QAC9B,IAAI,CAACD,KAAK,CAACG,IAAI,CAACF,KAAK,CAAC;MACvB;MACA,OAAO,IAAI;IACZ;EAAC;IAAA;IAAA,OACD,iBAAc;MACb,IAAI,CAACD,KAAK,GAAG,EAAE;IAChB;EAAC;IAAA;IAAA,OACD,iBAAOC,KAAQ,EAAW;MACzB,IAAMG,cAAc,GAAG,IAAI,CAACJ,KAAK,CAACK,MAAM;MACxC,IAAI,CAACL,KAAK,GAAG,IAAI,CAACA,KAAK,CAACM,MAAM,CAAC,UAACC,IAAI;QAAA,OAAKA,IAAI,KAAKN,KAAK;MAAA,EAAC;MAExD,OAAOG,cAAc,KAAK,IAAI,CAACJ,KAAK,CAACK,MAAM;IAC5C;EAAC;IAAA;IAAA,OACD,iBAAQG,UAAsD,EAAQ;MAAA;MACrE,IAAI,CAACR,KAAK,CAACS,OAAO,CAAC,UAACF,IAAI,EAAK;QAC5BC,UAAU,CAACD,IAAI,EAAEA,IAAI,EAAE,KAAI,CAAC;MAC7B,CAAC,CAAC;IACH;EAAC;IAAA;IAAA,OACD,aAAIN,KAAQ,EAAW;MACtB,OAAO,IAAI,CAACD,KAAK,CAACU,OAAO,CAACT,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC;EAAC;IAAA;IAAA,KAED,eAAmB;MAClB,OAAO,IAAI,CAACD,KAAK,CAACK,MAAM;IACzB;EAAC;EAAA;AAAA;AAAA,eAGa,OAAOM,GAAG,KAAK,WAAW,GAAGA,GAAG,GAAGZ,OAAO;AAAA"}

View File

@@ -0,0 +1,60 @@
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
// for environments without Set we fallback to arrays with unique members
var SetLike = /*#__PURE__*/function () {
function SetLike() {
var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
_classCallCheck(this, SetLike);
_defineProperty(this, "items", void 0);
this.items = items;
}
_createClass(SetLike, [{
key: "add",
value: function add(value) {
if (this.has(value) === false) {
this.items.push(value);
}
return this;
}
}, {
key: "clear",
value: function clear() {
this.items = [];
}
}, {
key: "delete",
value: function _delete(value) {
var previousLength = this.items.length;
this.items = this.items.filter(function (item) {
return item !== value;
});
return previousLength !== this.items.length;
}
}, {
key: "forEach",
value: function forEach(callbackfn) {
var _this = this;
this.items.forEach(function (item) {
callbackfn(item, item, _this);
});
}
}, {
key: "has",
value: function has(value) {
return this.items.indexOf(value) !== -1;
}
}, {
key: "size",
get: function get() {
return this.items.length;
}
}]);
return SetLike;
}();
export default typeof Set === "undefined" ? Set : SetLike;
//# sourceMappingURL=SetLike.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SetLike.mjs","names":["SetLike","items","value","has","push","previousLength","length","filter","item","callbackfn","forEach","indexOf","Set"],"sources":["../../sources/polyfills/SetLike.ts"],"sourcesContent":["declare global {\n\tclass Set<T> {\n\t\t// es2015.collection.d.ts\n\t\tconstructor(items?: T[]);\n\t\tadd(value: T): this;\n\t\tclear(): void;\n\t\tdelete(value: T): boolean;\n\t\tforEach(\n\t\t\tcallbackfn: (value: T, value2: T, set: Set<T>) => void,\n\t\t\tthisArg?: unknown\n\t\t): void;\n\t\thas(value: T): boolean;\n\t\treadonly size: number;\n\n\t\t// es2015.iterable.d.ts\n\t\t// no implemennted\n\t}\n}\n\n// for environments without Set we fallback to arrays with unique members\nclass SetLike<T> implements Set<T> {\n\tprivate items: T[];\n\n\tconstructor(items: T[] = []) {\n\t\tthis.items = items;\n\t}\n\n\tadd(value: T): this {\n\t\tif (this.has(value) === false) {\n\t\t\tthis.items.push(value);\n\t\t}\n\t\treturn this;\n\t}\n\tclear(): void {\n\t\tthis.items = [];\n\t}\n\tdelete(value: T): boolean {\n\t\tconst previousLength = this.items.length;\n\t\tthis.items = this.items.filter((item) => item !== value);\n\n\t\treturn previousLength !== this.items.length;\n\t}\n\tforEach(callbackfn: (value: T, value2: T, set: Set<T>) => void): void {\n\t\tthis.items.forEach((item) => {\n\t\t\tcallbackfn(item, item, this);\n\t\t});\n\t}\n\thas(value: T): boolean {\n\t\treturn this.items.indexOf(value) !== -1;\n\t}\n\n\tget size(): number {\n\t\treturn this.items.length;\n\t}\n}\n\nexport default typeof Set === \"undefined\" ? Set : SetLike;\n"],"mappings":";;;;;;;AAmBA;AAAA,IACMA,OAAO;EAGZ,mBAA6B;IAAA,IAAjBC,KAAU,uEAAG,EAAE;IAAA;IAAA;IAC1B,IAAI,CAACA,KAAK,GAAGA,KAAK;EACnB;EAAC;IAAA;IAAA,OAED,aAAIC,KAAQ,EAAQ;MACnB,IAAI,IAAI,CAACC,GAAG,CAACD,KAAK,CAAC,KAAK,KAAK,EAAE;QAC9B,IAAI,CAACD,KAAK,CAACG,IAAI,CAACF,KAAK,CAAC;MACvB;MACA,OAAO,IAAI;IACZ;EAAC;IAAA;IAAA,OACD,iBAAc;MACb,IAAI,CAACD,KAAK,GAAG,EAAE;IAChB;EAAC;IAAA;IAAA,OACD,iBAAOC,KAAQ,EAAW;MACzB,IAAMG,cAAc,GAAG,IAAI,CAACJ,KAAK,CAACK,MAAM;MACxC,IAAI,CAACL,KAAK,GAAG,IAAI,CAACA,KAAK,CAACM,MAAM,CAAC,UAACC,IAAI;QAAA,OAAKA,IAAI,KAAKN,KAAK;MAAA,EAAC;MAExD,OAAOG,cAAc,KAAK,IAAI,CAACJ,KAAK,CAACK,MAAM;IAC5C;EAAC;IAAA;IAAA,OACD,iBAAQG,UAAsD,EAAQ;MAAA;MACrE,IAAI,CAACR,KAAK,CAACS,OAAO,CAAC,UAACF,IAAI,EAAK;QAC5BC,UAAU,CAACD,IAAI,EAAEA,IAAI,EAAE,KAAI,CAAC;MAC7B,CAAC,CAAC;IACH;EAAC;IAAA;IAAA,OACD,aAAIN,KAAQ,EAAW;MACtB,OAAO,IAAI,CAACD,KAAK,CAACU,OAAO,CAACT,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC;EAAC;IAAA;IAAA,KAED,eAAmB;MAClB,OAAO,IAAI,CAACD,KAAK,CAACK,MAAM;IACzB;EAAC;EAAA;AAAA;AAGF,eAAe,OAAOM,GAAG,KAAK,WAAW,GAAGA,GAAG,GAAGZ,OAAO"}

View File

@@ -0,0 +1,6 @@
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
export default function arrayFrom<T>(iterable: Iterable<T> | ArrayLike<T>): T[];
//# sourceMappingURL=array.from.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"array.from.d.ts","sourceRoot":"","sources":["../../sources/polyfills/array.from.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC"}

View File

@@ -0,0 +1,91 @@
"use strict";
exports.__esModule = true;
exports.default = arrayFrom;
/**
* @source {https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Polyfill}
* but without thisArg (too hard to type, no need to `this`)
*/
var toStr = Object.prototype.toString;
function isCallable(fn) {
return typeof fn === "function" || toStr.call(fn) === "[object Function]";
}
function toInteger(value) {
var number = Number(value);
if (isNaN(number)) {
return 0;
}
if (number === 0 || !isFinite(number)) {
return number;
}
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
}
var maxSafeInteger = Math.pow(2, 53) - 1;
function toLength(value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
}
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
function arrayFrom(arrayLike, mapFn) {
// 1. Let C be the this value.
// edit(@eps1lon): we're not calling it as Array.from
var C = Array;
// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);
// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError("Array.from requires an array-like object - not null or undefined");
}
// 4. If mapfn is undefined, then let mapping be false.
// const mapFn = arguments.length > 1 ? arguments[1] : void undefined;
if (typeof mapFn !== "undefined") {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError("Array.from: when provided, the second argument must be a function");
}
}
// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);
// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method
// of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = mapFn(kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
}
//# sourceMappingURL=array.from.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,87 @@
/**
* @source {https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Polyfill}
* but without thisArg (too hard to type, no need to `this`)
*/
var toStr = Object.prototype.toString;
function isCallable(fn) {
return typeof fn === "function" || toStr.call(fn) === "[object Function]";
}
function toInteger(value) {
var number = Number(value);
if (isNaN(number)) {
return 0;
}
if (number === 0 || !isFinite(number)) {
return number;
}
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
}
var maxSafeInteger = Math.pow(2, 53) - 1;
function toLength(value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
}
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
export default function arrayFrom(arrayLike, mapFn) {
// 1. Let C be the this value.
// edit(@eps1lon): we're not calling it as Array.from
var C = Array;
// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);
// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError("Array.from requires an array-like object - not null or undefined");
}
// 4. If mapfn is undefined, then let mapping be false.
// const mapFn = arguments.length > 1 ? arguments[1] : void undefined;
if (typeof mapFn !== "undefined") {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError("Array.from: when provided, the second argument must be a function");
}
}
// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);
// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method
// of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = mapFn(kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
}
//# sourceMappingURL=array.from.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
"use strict";
//# sourceMappingURL=iterator.d.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"iterator.d.js","names":[],"sources":["../../sources/polyfills/iterator.d.ts"],"sourcesContent":["// copied from https://github.com/microsoft/TypeScript/blob/eaeee9cc31bdc3a16f982a2e7b784573c977fdfa/lib/\n// but with `unknown` instead of `any`\ninterface IteratorYieldResult<TYield> {\n\tdone?: false;\n\tvalue: TYield;\n}\n\ninterface IteratorReturnResult<TReturn> {\n\tdone: true;\n\tvalue: TReturn;\n}\n\ntype IteratorResult<T, TReturn = unknown> =\n\t| IteratorYieldResult<T>\n\t| IteratorReturnResult<TReturn>;\n\ninterface Iterator<T, TReturn = unknown, TNext = undefined> {\n\t// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.\n\tnext(...args: [] | [TNext]): IteratorResult<T, TReturn>;\n\treturn?(value?: TReturn): IteratorResult<T, TReturn>;\n\tthrow?(e?: unknown): IteratorResult<T, TReturn>;\n}\n\ninterface Iterable<T> {\n\t[Symbol.iterator](): Iterator<T>;\n}\n\ninterface IterableIterator<T> extends Iterator<T> {\n\t[Symbol.iterator](): IterableIterator<T>;\n}\ninterface SymbolConstructor {\n\t/**\n\t * A method that returns the default iterator for an object. Called by the semantics of the\n\t * for-of statement.\n\t */\n\treadonly iterator: symbol;\n}\n\ndeclare const Symbol: SymbolConstructor;\n"],"mappings":""}

View File

@@ -0,0 +1,2 @@
//# sourceMappingURL=iterator.d.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"iterator.d.mjs","names":[],"sources":["../../sources/polyfills/iterator.d.ts"],"sourcesContent":["// copied from https://github.com/microsoft/TypeScript/blob/eaeee9cc31bdc3a16f982a2e7b784573c977fdfa/lib/\n// but with `unknown` instead of `any`\ninterface IteratorYieldResult<TYield> {\n\tdone?: false;\n\tvalue: TYield;\n}\n\ninterface IteratorReturnResult<TReturn> {\n\tdone: true;\n\tvalue: TReturn;\n}\n\ntype IteratorResult<T, TReturn = unknown> =\n\t| IteratorYieldResult<T>\n\t| IteratorReturnResult<TReturn>;\n\ninterface Iterator<T, TReturn = unknown, TNext = undefined> {\n\t// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.\n\tnext(...args: [] | [TNext]): IteratorResult<T, TReturn>;\n\treturn?(value?: TReturn): IteratorResult<T, TReturn>;\n\tthrow?(e?: unknown): IteratorResult<T, TReturn>;\n}\n\ninterface Iterable<T> {\n\t[Symbol.iterator](): Iterator<T>;\n}\n\ninterface IterableIterator<T> extends Iterator<T> {\n\t[Symbol.iterator](): IterableIterator<T>;\n}\ninterface SymbolConstructor {\n\t/**\n\t * A method that returns the default iterator for an object. Called by the semantics of the\n\t * for-of statement.\n\t */\n\treadonly iterator: symbol;\n}\n\ndeclare const Symbol: SymbolConstructor;\n"],"mappings":""}

View File

@@ -0,0 +1,24 @@
export { getLocalName } from "./getRole";
export declare function isElement(node: Node | null): node is Element;
export declare function isHTMLTableCaptionElement(node: Node | null): node is HTMLTableCaptionElement;
export declare function isHTMLInputElement(node: Node | null): node is HTMLInputElement;
export declare function isHTMLOptGroupElement(node: Node | null): node is HTMLOptGroupElement;
export declare function isHTMLSelectElement(node: Node | null): node is HTMLSelectElement;
export declare function isHTMLTableElement(node: Node | null): node is HTMLTableElement;
export declare function isHTMLTextAreaElement(node: Node | null): node is HTMLTextAreaElement;
export declare function safeWindow(node: Node): Window;
export declare function isHTMLFieldSetElement(node: Node | null): node is HTMLFieldSetElement;
export declare function isHTMLLegendElement(node: Node | null): node is HTMLLegendElement;
export declare function isHTMLSlotElement(node: Node | null): node is HTMLSlotElement;
export declare function isSVGElement(node: Node | null): node is SVGElement;
export declare function isSVGSVGElement(node: Node | null): node is SVGSVGElement;
export declare function isSVGTitleElement(node: Node | null): node is SVGTitleElement;
/**
*
* @param {Node} node -
* @param {string} attributeName -
* @returns {Element[]} -
*/
export declare function queryIdRefs(node: Node, attributeName: string): Element[];
export declare function hasAnyConcreteRoles(node: Node, roles: Array<string | null>): node is Element;
//# sourceMappingURL=util.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../sources/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,OAAO,CAE5D;AAED,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,uBAAuB,CAEjC;AAED,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,gBAAgB,CAE1B;AAED,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,mBAAmB,CAE7B;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,iBAAiB,CAE3B;AAED,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,gBAAgB,CAE1B;AAED,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,mBAAmB,CAE7B;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAQ7C;AAED,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,mBAAmB,CAE7B;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,iBAAiB,CAE3B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,eAAe,CAE5E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,UAAU,CAElE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,aAAa,CAExE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,eAAe,CAE5E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,EAAE,CAmBxE;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,GACzB,IAAI,IAAI,OAAO,CAKjB"}

View File

@@ -0,0 +1,103 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
exports.__esModule = true;
exports.hasAnyConcreteRoles = hasAnyConcreteRoles;
exports.isElement = isElement;
exports.isHTMLFieldSetElement = isHTMLFieldSetElement;
exports.isHTMLInputElement = isHTMLInputElement;
exports.isHTMLLegendElement = isHTMLLegendElement;
exports.isHTMLOptGroupElement = isHTMLOptGroupElement;
exports.isHTMLSelectElement = isHTMLSelectElement;
exports.isHTMLSlotElement = isHTMLSlotElement;
exports.isHTMLTableCaptionElement = isHTMLTableCaptionElement;
exports.isHTMLTableElement = isHTMLTableElement;
exports.isHTMLTextAreaElement = isHTMLTextAreaElement;
exports.isSVGElement = isSVGElement;
exports.isSVGSVGElement = isSVGSVGElement;
exports.isSVGTitleElement = isSVGTitleElement;
exports.queryIdRefs = queryIdRefs;
exports.safeWindow = safeWindow;
var _getRole = _interopRequireWildcard(require("./getRole"));
exports.getLocalName = _getRole.getLocalName;
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function isElement(node) {
return node !== null && node.nodeType === node.ELEMENT_NODE;
}
function isHTMLTableCaptionElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "caption";
}
function isHTMLInputElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "input";
}
function isHTMLOptGroupElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "optgroup";
}
function isHTMLSelectElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "select";
}
function isHTMLTableElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "table";
}
function isHTMLTextAreaElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "textarea";
}
function safeWindow(node) {
var _ref = node.ownerDocument === null ? node : node.ownerDocument,
defaultView = _ref.defaultView;
if (defaultView === null) {
throw new TypeError("no window available");
}
return defaultView;
}
function isHTMLFieldSetElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "fieldset";
}
function isHTMLLegendElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "legend";
}
function isHTMLSlotElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "slot";
}
function isSVGElement(node) {
return isElement(node) && node.ownerSVGElement !== undefined;
}
function isSVGSVGElement(node) {
return isElement(node) && (0, _getRole.getLocalName)(node) === "svg";
}
function isSVGTitleElement(node) {
return isSVGElement(node) && (0, _getRole.getLocalName)(node) === "title";
}
/**
*
* @param {Node} node -
* @param {string} attributeName -
* @returns {Element[]} -
*/
function queryIdRefs(node, attributeName) {
if (isElement(node) && node.hasAttribute(attributeName)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- safe due to hasAttribute check
var ids = node.getAttribute(attributeName).split(" ");
// Browsers that don't support shadow DOM won't have getRootNode
var root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
return ids.map(function (id) {
return root.getElementById(id);
}).filter(function (element) {
return element !== null;
}
// TODO: why does this not narrow?
);
}
return [];
}
function hasAnyConcreteRoles(node, roles) {
if (isElement(node)) {
return roles.indexOf((0, _getRole.default)(node)) !== -1;
}
return false;
}
//# sourceMappingURL=util.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
export { getLocalName } from "./getRole.mjs";
import getRole, { getLocalName } from "./getRole.mjs";
export function isElement(node) {
return node !== null && node.nodeType === node.ELEMENT_NODE;
}
export function isHTMLTableCaptionElement(node) {
return isElement(node) && getLocalName(node) === "caption";
}
export function isHTMLInputElement(node) {
return isElement(node) && getLocalName(node) === "input";
}
export function isHTMLOptGroupElement(node) {
return isElement(node) && getLocalName(node) === "optgroup";
}
export function isHTMLSelectElement(node) {
return isElement(node) && getLocalName(node) === "select";
}
export function isHTMLTableElement(node) {
return isElement(node) && getLocalName(node) === "table";
}
export function isHTMLTextAreaElement(node) {
return isElement(node) && getLocalName(node) === "textarea";
}
export function safeWindow(node) {
var _ref = node.ownerDocument === null ? node : node.ownerDocument,
defaultView = _ref.defaultView;
if (defaultView === null) {
throw new TypeError("no window available");
}
return defaultView;
}
export function isHTMLFieldSetElement(node) {
return isElement(node) && getLocalName(node) === "fieldset";
}
export function isHTMLLegendElement(node) {
return isElement(node) && getLocalName(node) === "legend";
}
export function isHTMLSlotElement(node) {
return isElement(node) && getLocalName(node) === "slot";
}
export function isSVGElement(node) {
return isElement(node) && node.ownerSVGElement !== undefined;
}
export function isSVGSVGElement(node) {
return isElement(node) && getLocalName(node) === "svg";
}
export function isSVGTitleElement(node) {
return isSVGElement(node) && getLocalName(node) === "title";
}
/**
*
* @param {Node} node -
* @param {string} attributeName -
* @returns {Element[]} -
*/
export function queryIdRefs(node, attributeName) {
if (isElement(node) && node.hasAttribute(attributeName)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- safe due to hasAttribute check
var ids = node.getAttribute(attributeName).split(" ");
// Browsers that don't support shadow DOM won't have getRootNode
var root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
return ids.map(function (id) {
return root.getElementById(id);
}).filter(function (element) {
return element !== null;
}
// TODO: why does this not narrow?
);
}
return [];
}
export function hasAnyConcreteRoles(node, roles) {
if (isElement(node)) {
return roles.indexOf(getRole(node)) !== -1;
}
return false;
}
//# sourceMappingURL=util.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,92 @@
{
"name": "dom-accessibility-api",
"description": "Implements https://w3c.github.io/accname/",
"version": "0.5.16",
"main": "dist/index.js",
"module": "dist/index.mjs",
"type": "commonjs",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/eps1lon/dom-accessibility-api.git"
},
"files": [
".browserslistrc",
"dist/"
],
"scripts": {
"build": "yarn build:clean && yarn build:source && yarn build:source:cjs && yarn build:types",
"build:clean": "rimraf dist",
"build:source": "cross-env BABEL_ENV=esm babel sources --extensions \".ts\" --ignore \"**/__tests__/**/*\" --out-dir dist/ --out-file-extension=.mjs --source-maps",
"build:source:cjs": "cross-env BABEL_ENV=cjs babel sources --extensions \".ts\" --ignore \"**/__tests__/**/*\" --out-dir dist/ --out-file-extension=.js --source-maps",
"build:types": "tsc -p tsconfig.json --emitDeclarationOnly",
"format": "prettier \"**/*.{json,js,md,ts,yml}\" --write --ignore-path .prettierignore",
"lint": "eslint --report-unused-disable-directives \"{scripts,sources}/**/*.{js,ts}\"",
"release": "yarn build && yarn changeset publish",
"test": "jest --config scripts/jest/jest.config.js",
"test:ci": "jest --ci --config scripts/jest/jest.ci.config.js --runInBand",
"test:coverage": "jest --config scripts/jest/jest.coverage.config.js",
"test:types": "tsc -p tsconfig.json --noEmit",
"test:wpt:jsdom": "mocha tests/wpt-jsdom/run-wpts.js",
"test:wpt:browser": "concurrently --success first --kill-others \"yarn test:wpt:browser:run\" \"yarn test:wpt:browser:server\"",
"test:wpt:browser:run": "cypress run --project tests",
"test:wpt:browser:server": "serve tests/wpt",
"test:wpt:browser:open": "cypress open --project tests",
"wpt:init": "git submodule update --init --recursive",
"wpt:reset": "rimraf ./tests/wpt && yarn wpt:init",
"wpt:update": "git submodule update --recursive --remote && cd tests/wpt && python wpt.py manifest --path ../wpt-jsdom/wpt-manifest.json"
},
"devDependencies": {
"@babel/cli": "^7.14.3",
"@babel/core": "^7.14.3",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/preset-env": "^7.14.4",
"@babel/preset-typescript": "^7.13.0",
"@changesets/changelog-github": "^0.4.0",
"@changesets/cli": "^2.16.0",
"@testing-library/dom": "^8.0.0",
"@types/jest": "^29.0.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"concurrently": "^7.0.0",
"cross-env": "^7.0.3",
"cypress": "^12.0.0",
"eslint": "^7.27.0",
"eslint-plugin-jest": "^27.0.0",
"jest": "^29.0.0",
"jest-diff": "^29.0.0",
"jest-environment-jsdom": "^29.0.0",
"jest-junit": "^15.0.0",
"js-yaml": "^4.1.0",
"jsdom": "^20.0.0",
"minimatch": "^6.0.0",
"mocha": "^10.0.0",
"mocha-sugar-free": "^1.4.0",
"prettier": "^2.3.0",
"q": "^1.5.1",
"request": "^2.88",
"request-promise-native": "^1.0.9",
"rimraf": "^4.0.0",
"serve": "^14.0.0",
"typescript": "^4.3.2"
},
"resolutions": {
"**/kind-of": "^6.0.3",
"**/minimist": "^1.2.2"
},
"prettier": {
"useTabs": true
},
"keywords": [
"accessibility",
"ARIA",
"accname"
],
"publishConfig": {
"access": "public"
}
}