Socket
Socket
Sign inDemoInstall

dom-accessibility-api

Package Overview
Dependencies
1
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1 to 0.1.0

CHANGELOG.md

3

dist/accessible-name.d.ts
/**
* implements https://w3c.github.io/accname/
*/
/**
* implements https://w3c.github.io/accname/#mapping_additional_nd_te

@@ -3,0 +6,0 @@ * @param root

170

dist/accessible-name.js
"use strict";
/**
* implements https://w3c.github.io/accname/
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const getRole_1 = __importDefault(require("./getRole"));
/**

@@ -11,17 +18,2 @@ *

}
function isEmpty(s) {
return s == null || s.length === 0;
}
function appendResultWithoutSpace(result, x) {
return `${x}${result}`;
}
function appendResultWithSpace(result, x) {
return `${x} ${result}`;
}
function prependResultWithoutSpace(result, x = "") {
return `${result}${x}`;
}
function prepenResultWithSpace(result, x = "") {
return `${result} ${x}`;
}
/**

@@ -48,7 +40,13 @@ * TODO

}
function isHTMLTextAreaElement(node) {
return (isElement(node) &&
// @ts-ignore
node instanceof node.ownerDocument.defaultView.HTMLTextAreaElement);
}
function safeWindow(node) {
if (node.isConnected === false) {
throw new TypeError(`Can't reach window from disconnected node`);
const { defaultView } = node.ownerDocument === null ? node : node.ownerDocument;
if (defaultView === null) {
throw new TypeError("no window available");
}
return node.ownerDocument.defaultView;
return defaultView;
}

@@ -98,8 +96,8 @@ /**

/**
*
* @param {Node} node -
* @returns {boolean} -
* @returns {boolean} - As defined in step 2E of https://w3c.github.io/accname/#mapping_additional_nd_te
*/
function isEmbeddedControl(node) {
return false;
function isControl(node) {
return (hasAnyConcreteRoles(node, ["button", "combobox", "listbox", "textbox"]) ||
hasAbstractRole(node, "range"));
}

@@ -119,6 +117,2 @@ function hasAbstractRole(node, role) {

]);
case "textbox":
return (node.tagName === "TEXTAREA" ||
(isHTMLInputElement(node) &&
["search", "text"].indexOf(node.type) !== -1));
default:

@@ -130,26 +124,3 @@ throw new TypeError(`No knowledge about abstract role '${role}'. This is likely a bug :(`);

if (isElement(node)) {
if (node.hasAttribute("role")) {
return node
.getAttribute("role")
.split(" ")
.some(role => roles.indexOf(role) !== -1);
}
// https://w3c.github.io/html-aria/
switch (node.tagName) {
case "A":
return roles.indexOf("link") !== -1;
case "BUTTON":
return roles.indexOf("button") !== -1;
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
return roles.indexOf("heading") !== -1;
case "SELECT":
return roles.indexOf("listbox") !== -1;
case "OPTION":
return roles.indexOf("option") !== -1;
}
return roles.indexOf(getRole_1.default(node)) !== -1;
}

@@ -187,6 +158,27 @@ return false;

/**
* TODO https://w3c.github.io/aria/#namefromcontent
* https://w3c.github.io/aria/#namefromcontent
*/
function allowsNameFromContent(node) {
return hasAnyConcreteRoles(node, ["option", "heading", "link", "button"]);
return hasAnyConcreteRoles(node, [
"button",
"cell",
"checkbox",
"columnheader",
"gridcell",
"heading",
"label",
"legend",
"link",
"menuitem",
"menuitemcheckbox",
"menuitemradio",
"option",
"radio",
"row",
"rowheader",
"switch",
"tab",
"tooltip",
"treeitem"
]);
}

@@ -205,2 +197,16 @@ /**

}
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) {
const content = declaration.getPropertyValue("content");
if (/^["'].*["']$/.test(content)) {
return content.slice(1, -1);
}
return "";
}
/**

@@ -227,5 +233,5 @@ * implements https://w3c.github.io/accname/#mapping_additional_nd_te

if (isElement(node)) {
const pseudoBefore = safeWindow(node).getComputedStyle(node, ":before");
const beforeContent = pseudoBefore.getPropertyValue("content");
accumulatedText = prependResultWithoutSpace(accumulatedText, beforeContent);
const pseudoBefore = safeWindow(node).getComputedStyle(node, "::before");
const beforeContent = getTextualContent(pseudoBefore);
accumulatedText = `${beforeContent} ${accumulatedText}`;
}

@@ -248,4 +254,4 @@ for (const child of queryChildNodes(node)) {

const pseudoAfter = safeWindow(node).getComputedStyle(node, ":after");
const afterContent = pseudoAfter.getPropertyValue("content");
accumulatedText = appendResultWithoutSpace(accumulatedText, afterContent);
const afterContent = getTextualContent(pseudoAfter);
accumulatedText = `${accumulatedText} ${afterContent}`;
}

@@ -329,3 +335,6 @@ return accumulatedText;

isReferenced: true,
recursion: true
// thais isn't recursion as specified, otherwise we would skip
// `aria-label` in
// <input id="myself" aria-label="foo" aria-labelledby="myself"
recursion: false
}))

@@ -335,26 +344,26 @@ .join(" ");

// 2C
const ariaLabel = ((isElement(current) && current.getAttribute("aria-label")) ||
"").trim();
if (ariaLabel !== "") {
consultedNodes.add(current);
if (context.recursion && isEmbeddedControl(current)) {
throw new Error("Not implemented");
}
return ariaLabel;
}
// 2D
if (!hasAnyConcreteRoles(current, ["none", "presentation"])) {
const attributeTextAlternative = computeAttributeTextAlternative(current);
if (attributeTextAlternative !== null) {
const skipToStep2E = context.recursion && isControl(current);
if (!skipToStep2E) {
const ariaLabel = ((isElement(current) && current.getAttribute("aria-label")) ||
"").trim();
if (ariaLabel !== "") {
consultedNodes.add(current);
return attributeTextAlternative;
return ariaLabel;
}
const elementTextAlternative = computeElementTextAlternative(current);
if (elementTextAlternative !== null) {
consultedNodes.add(current);
return elementTextAlternative;
// 2D
if (!hasAnyConcreteRoles(current, ["none", "presentation"])) {
const elementTextAlternative = computeElementTextAlternative(current);
if (elementTextAlternative !== null) {
consultedNodes.add(current);
return elementTextAlternative;
}
const attributeTextAlternative = computeAttributeTextAlternative(current);
if (attributeTextAlternative !== null) {
consultedNodes.add(current);
return attributeTextAlternative;
}
}
}
// 2E
if (context.isReferenced || context.isEmbeddedInLabel) {
if (skipToStep2E || context.isEmbeddedInLabel || context.isReferenced) {
if (hasAnyConcreteRoles(current, ["combobox", "listbox"])) {

@@ -364,3 +373,4 @@ consultedNodes.add(current);

if (selectedOptions.length === 0) {
return "";
// defined per test `name_heading_combobox`
return isHTMLInputElement(current) ? current.value : "";
}

@@ -388,5 +398,5 @@ return Array.from(selectedOptions)

}
if (hasAbstractRole(current, "textbox")) {
if (hasAnyConcreteRoles(current, ["textbox"])) {
consultedNodes.add(current);
return current.getAttribute("value") || "";
return getValueOfTextbox(current);
}

@@ -393,0 +403,0 @@ }

export { computeAccessibleName } from "./accessible-name";
export { default as getRole } from "./getRole";
//# sourceMappingURL=index.d.ts.map

@@ -5,2 +5,4 @@ "use strict";

exports.computeAccessibleName = accessible_name_1.computeAccessibleName;
var getRole_1 = require("./getRole");
exports.getRole = getRole_1.default;
//# sourceMappingURL=index.js.map
{
"name": "dom-accessibility-api",
"version": "0.0.1",
"version": "0.1.0",
"main": "dist/index.js",

@@ -12,8 +12,14 @@ "types": "dist/index.d.ts",

"build": "tsc -p tsconfig.json",
"format": "prettier \"**/*.{json,js,md,ts}\" --write --ignore-path .prettierignore",
"format": "prettier \"**/*.{json,js,md,ts,yml}\" --write --ignore-path .prettierignore",
"lint": "eslint --report-unused-disable-directives \"sources/**/*.ts\"",
"test": "jest",
"test-wpt": "mocha tests/run-wpts.js",
"init-wpt": "git submodule update --init --recursive",
"reset-wpt": "rimraf ./tests/wpt && yarn init-wpt",
"update-wpt": "git submodule update --recursive --remote && cd tests/wpt && python wpt.py manifest --path ../wpt-manifest.json"
"test:ci": "jest --ci --config jest.ci.config.js --runInBand",
"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 init-wpt",
"wpt:update": "git submodule update --recursive --remote && cd tests/wpt && python wpt.py manifest --path ../wpt-jsdom/wpt-manifest.json"
},

@@ -24,7 +30,17 @@ "devDependencies": {

"@babel/preset-typescript": "^7.6.0",
"@semantic-release/changelog": "^3.0.5",
"@semantic-release/commit-analyzer": "^6.3.2",
"@semantic-release/git": "^7.0.18",
"@semantic-release/npm": "^5.3.4",
"@semantic-release/release-notes-generator": "^7.3.2",
"@testing-library/dom": "^6.6.0",
"@types/jest": "^24.0.18",
"@typescript-eslint/eslint-plugin": "^2.5.0",
"concurrently": "^5.0.0",
"cypress": "^3.4.1",
"eslint": "^6.6.0",
"jest": "^24.9.0",
"jest-diff": "^24.9.0",
"jest-environment-jsdom-thirteen": "^1.0.1",
"jest-junit": "^8.0.0",
"js-yaml": "^3.13.1",

@@ -39,2 +55,4 @@ "jsdom": "^15.1.1",

"request-promise-native": "^1.0.7",
"semantic-release": "^15.13.30",
"serve": "^11.2.0",
"typescript": "^3.6.3"

@@ -44,3 +62,10 @@ },

"useTabs": true
},
"dependencies": {
"@typescript-eslint/parser": "^2.5.0"
},
"repository": {
"type": "git",
"url": "https://github.com/eps1lon/dom-accessibility-api.git"
}
}
# dom-accessibility-api
https://w3c.github.io/accname/ for jsdom
[![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=master)](https://dev.azure.com/silbermannsebastian/dom-accessibility-api/_build/latest?definitionId=6&branchName=master)
![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/silbermannsebastian/dom-accessibility-api/6)
Computes the accessible name of a given DOM Element.
https://w3c.github.io/accname/ implemented in JavaScript for testing.
```bash

@@ -13,18 +18,21 @@ $ yarn add dom-accessibility-api

I wrote this down in 12 hours to get a quick overview
how complex a full implementation would be.
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.
I'm very new to working with specs so if you got any insights, something catches
your eye feel free to let me know. DMs are open.
## progress
Using https://github.com/web-platform-tests/wpt. Be sure to init submodules when
cloning.
cloning. See [the test readme](/tests/README.md) for more info about the test setup.
### browser (Chrome)
136/144 of which 5 are due to missing whitespace.
### jsdom
<details>
<summary>report 124/159 passing of which 16 are due to jsdom, 14 are accessible desc, 9 are pathological </summary>
<summary>report 126/159 passing of which 16 are due `::before { content }`, 14 are accessible desc, 7 are pathological </summary>
```bash
web-platform-tests
web-platform-tests
accname

@@ -72,3 +80,3 @@ ✓ [expected fail] description_1.0_combobox-focusable-manual.html

✓ name_from_content_of_labelledby_elements_one_of_which_is_hidden-manual.html
✓ [expected fail] name_heading-combobox-focusable-alternative-manual.html
✓ name_heading-combobox-focusable-alternative-manual.html
✓ name_image-title-manual.html

@@ -128,3 +136,3 @@ ✓ name_link-mixed-content-manual.html

✓ name_test_case_609-manual.html
✓ [expected fail] name_test_case_610-manual.html
✓ name_test_case_610-manual.html
✓ name_test_case_611-manual.html

@@ -131,0 +139,0 @@ ✓ name_test_case_612-manual.html

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc