New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@guidepup/virtual-screen-reader

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@guidepup/virtual-screen-reader - npm Package Compare versions

Comparing version 0.6.1 to 0.7.0

lib/getNodeAccessibilityData/getAccessibleAttributeLabels/postProcessAriaValueNow.d.ts

1

lib/createAccessibilityTree.d.ts

@@ -6,2 +6,3 @@ export interface AccessibilityNode {

accessibleValue: string;
allowedAccessibilityChildRoles: string[][];
childrenPresentational: boolean;

@@ -8,0 +9,0 @@ node: Node;

15

lib/createAccessibilityTree.js

@@ -21,4 +21,6 @@ "use strict";

// to include.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
accessibleName === (node.textContent || node.value)?.trim());
accessibleName ===
(node.textContent ||
`${node.value}` ||
"")?.trim());
}

@@ -44,2 +46,3 @@ function flattenTree(tree) {

accessibleValue: treeNode.accessibleValue,
allowedAccessibilityChildRoles: treeNode.allowedAccessibilityChildRoles,
childrenPresentational: treeNode.childrenPresentational,

@@ -58,3 +61,4 @@ node: treeNode.node,

}
const { accessibleAttributeLabels, accessibleDescription, accessibleName, accessibleValue, childrenPresentational, role, spokenRole, } = (0, getNodeAccessibilityData_1.getNodeAccessibilityData)({
const { accessibleAttributeLabels, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = (0, getNodeAccessibilityData_1.getNodeAccessibilityData)({
allowedAccessibilityRoles: tree.allowedAccessibilityChildRoles,
node: childNode,

@@ -68,2 +72,3 @@ inheritedImplicitPresentational: tree.childrenPresentational,

accessibleValue,
allowedAccessibilityChildRoles,
children: [],

@@ -82,3 +87,4 @@ childrenPresentational,

}
const { accessibleAttributeLabels, accessibleDescription, accessibleName, accessibleValue, childrenPresentational, role, spokenRole, } = (0, getNodeAccessibilityData_1.getNodeAccessibilityData)({
const { accessibleAttributeLabels, accessibleDescription, accessibleName, accessibleValue, allowedAccessibilityChildRoles, childrenPresentational, role, spokenRole, } = (0, getNodeAccessibilityData_1.getNodeAccessibilityData)({
allowedAccessibilityRoles: [],
node,

@@ -92,2 +98,3 @@ inheritedImplicitPresentational: false,

accessibleValue,
allowedAccessibilityChildRoles,
children: [],

@@ -94,0 +101,0 @@ childrenPresentational,

@@ -5,3 +5,3 @@ "use strict";

const aria_query_1 = require("aria-query");
const getRole_1 = require("../../getRole");
const getRole_1 = require("../getRole");
const ignoreAttributesWithAccessibleValue = ["aria-placeholder"];

@@ -8,0 +8,0 @@ const getAttributesByRole = ({ accessibleValue, role, }) => {

export declare const getLabelFromAriaAttribute: ({ attributeName, node, }: {
attributeName: string;
node: HTMLElement;
}) => any;
}) => {
label: string;
value: string;
};

@@ -7,7 +7,10 @@ "use strict";

const attributeValue = node.getAttribute(attributeName);
return (0, mapAttributeNameAndValueToLabel_1.mapAttributeNameAndValueToLabel)({
attributeName,
attributeValue,
});
return {
label: (0, mapAttributeNameAndValueToLabel_1.mapAttributeNameAndValueToLabel)({
attributeName,
attributeValue,
}),
value: attributeValue,
};
};
exports.getLabelFromAriaAttribute = getLabelFromAriaAttribute;
export declare const getLabelFromHtmlEquivalentAttribute: ({ attributeName, node, }: {
attributeName: string;
node: HTMLElement;
}) => any;
}) => {
label: string;
value: string;
};

@@ -24,3 +24,3 @@ "use strict";

if (!htmlAttribute?.length) {
return null;
return { label: "", value: "" };
}

@@ -35,7 +35,7 @@ for (const { name, negative = false } of htmlAttribute) {

if (label) {
return label;
return { label, value: attributeValue };
}
}
return null;
return { label: "", value: "" };
};
exports.getLabelFromHtmlEquivalentAttribute = getLabelFromHtmlEquivalentAttribute;
export declare const getLabelFromImplicitHtmlElementValue: ({ attributeName, node, }: {
attributeName: string;
node: HTMLElement;
}) => any;
}) => {
label: string;
value: any;
};

@@ -18,7 +18,10 @@ "use strict";

const implicitValue = mapLocalNameToImplicitValue[attributeName]?.[localName];
return (0, mapAttributeNameAndValueToLabel_1.mapAttributeNameAndValueToLabel)({
attributeName,
attributeValue: implicitValue,
});
return {
label: (0, mapAttributeNameAndValueToLabel_1.mapAttributeNameAndValueToLabel)({
attributeName,
attributeValue: implicitValue,
}),
value: implicitValue,
};
};
exports.getLabelFromImplicitHtmlElementValue = getLabelFromImplicitHtmlElementValue;

@@ -10,10 +10,11 @@ "use strict";

const mapAttributeNameAndValueToLabel_1 = require("./mapAttributeNameAndValueToLabel");
const postProcessLabels_1 = require("./postProcessLabels");
const getAccessibleAttributeLabels = ({ accessibleValue, node, role, }) => {
const labels = [];
if (!(0, isElement_1.isElement)(node)) {
return labels;
return [];
}
const labels = {};
const attributes = (0, getAttributesByRole_1.getAttributesByRole)({ accessibleValue, role });
attributes.forEach(([attributeName, implicitAttributeValue]) => {
const labelFromHtmlEquivalentAttribute = (0, getLabelFromHtmlEquivalentAttribute_1.getLabelFromHtmlEquivalentAttribute)({
const { label: labelFromHtmlEquivalentAttribute, value: valueFromHtmlEquivalentAttribute, } = (0, getLabelFromHtmlEquivalentAttribute_1.getLabelFromHtmlEquivalentAttribute)({
attributeName,

@@ -23,6 +24,9 @@ node,

if (labelFromHtmlEquivalentAttribute) {
labels.push(labelFromHtmlEquivalentAttribute);
labels[attributeName] = {
label: labelFromHtmlEquivalentAttribute,
value: valueFromHtmlEquivalentAttribute,
};
return;
}
const labelFromAriaAttribute = (0, getLabelFromAriaAttribute_1.getLabelFromAriaAttribute)({
const { label: labelFromAriaAttribute, value: valueFromAriaAttribute } = (0, getLabelFromAriaAttribute_1.getLabelFromAriaAttribute)({
attributeName,

@@ -32,6 +36,9 @@ node,

if (labelFromAriaAttribute) {
labels.push(labelFromAriaAttribute);
labels[attributeName] = {
label: labelFromAriaAttribute,
value: valueFromAriaAttribute,
};
return;
}
const labelFromImplicitHtmlElementValue = (0, getLabelFromImplicitHtmlElementValue_1.getLabelFromImplicitHtmlElementValue)({
const { label: labelFromImplicitHtmlElementValue, value: valueFromImplicitHtmlElementValue, } = (0, getLabelFromImplicitHtmlElementValue_1.getLabelFromImplicitHtmlElementValue)({
attributeName,

@@ -41,3 +48,6 @@ node,

if (labelFromImplicitHtmlElementValue) {
labels.push(labelFromImplicitHtmlElementValue);
labels[attributeName] = {
label: labelFromImplicitHtmlElementValue,
value: valueFromImplicitHtmlElementValue,
};
return;

@@ -50,8 +60,11 @@ }

if (labelFromImplicitAriaAttributeValue) {
labels.push(labelFromImplicitAriaAttributeValue);
labels[attributeName] = {
label: labelFromImplicitAriaAttributeValue,
value: implicitAttributeValue,
};
return;
}
});
return labels;
return (0, postProcessLabels_1.postProcessLabels)({ labels, role });
};
exports.getAccessibleAttributeLabels = getAccessibleAttributeLabels;

@@ -5,2 +5,2 @@ export declare const mapAttributeNameAndValueToLabel: ({ attributeName, attributeValue, negative, }: {

negative?: boolean;
}) => any;
}) => string;

@@ -59,2 +59,8 @@ "use strict";

"aria-haspopup": token({
/**
* Assistive technologies SHOULD NOT expose the aria-haspopup property if
* it has a value of false.
*
* REF: // https://w3c.github.io/aria/#aria-haspopup
*/
false: null,

@@ -108,6 +114,4 @@ true: "has popup menu",

"aria-valuemin": number("min value"),
// TODO: don't announce if have an aria-valuetext
// TODO: map to percentage as per https://w3c.github.io/aria/#aria-valuenow for certain roles
"aria-valuenow": number("current value"),
"aria-valuetext": string("current value"), // TODO: don't announce if have a value?
"aria-valuetext": string("current value"),
};

@@ -114,0 +118,0 @@ function state(stateValue) {

@@ -0,1 +1,2 @@

export type HTMLElementWithValue = HTMLButtonElement | HTMLDataElement | HTMLInputElement | HTMLLIElement | HTMLMeterElement | HTMLOptionElement | HTMLProgressElement | HTMLParamElement;
export declare function getAccessibleValue(node: Node): string;

@@ -5,6 +5,19 @@ "use strict";

const isElement_1 = require("../isElement");
const ignoredInputTypes = ["checkbox", "radio"];
const allowedLocalNames = [
"button",
"data",
"input",
// "li",
"meter",
"option",
"progress",
"param",
];
function getSelectValue(node) {
const selectedOptions = [...node.options].filter((option) => option.selected);
const selectedOptions = [...node.options].filter((optionElement) => optionElement.selected);
if (node.multiple) {
return [...selectedOptions].map((opt) => opt.value).join("; ");
return [...selectedOptions]
.map((optionElement) => getValue(optionElement))
.join("; ");
}

@@ -14,10 +27,20 @@ if (selectedOptions.length === 0) {

}
return selectedOptions[0].value;
return getValue(selectedOptions[0]);
}
function getInputValue(node) {
if (["checkbox", "radio"].includes(node.type)) {
if (ignoredInputTypes.includes(node.type)) {
return "";
}
return node.value;
return getValue(node);
}
function getValue(node) {
if (!allowedLocalNames.includes(node.localName)) {
return "";
}
if (node.getAttribute("aria-valuetext") ||
node.getAttribute("aria-valuenow")) {
return "";
}
return typeof node.value === "number" ? `${node.value}` : node.value;
}
function getAccessibleValue(node) {

@@ -35,4 +58,4 @@ if (!(0, isElement_1.isElement)(node)) {

}
return "";
return getValue(node);
}
exports.getAccessibleValue = getAccessibleValue;

@@ -1,2 +0,3 @@

export declare function getNodeAccessibilityData({ inheritedImplicitPresentational, node, }: {
export declare function getNodeAccessibilityData({ allowedAccessibilityRoles, inheritedImplicitPresentational, node, }: {
allowedAccessibilityRoles: string[][];
inheritedImplicitPresentational: boolean;

@@ -9,5 +10,6 @@ node: Node;

accessibleValue: string;
allowedAccessibilityChildRoles: string[][];
childrenPresentational: boolean;
role: string;
spokenRole: string;
spokenRole: any;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNodeAccessibilityData = void 0;
const getRole_1 = require("../getRole");
const aria_query_1 = require("aria-query");
const getRole_1 = require("./getRole");
const getAccessibleAttributeLabels_1 = require("./getAccessibleAttributeLabels");

@@ -9,8 +10,37 @@ const getAccessibleDescription_1 = require("./getAccessibleDescription");

const getAccessibleValue_1 = require("./getAccessibleValue");
function getNodeAccessibilityData({ inheritedImplicitPresentational, node, }) {
const isElement_1 = require("../isElement");
const childrenPresentationalRoles = aria_query_1.roles
.entries()
.filter(([, { childrenPresentational }]) => childrenPresentational)
.map(([key]) => key);
const getSpokenRole = ({ isGeneric, isPresentational, node, role }) => {
if (isPresentational || isGeneric) {
return "";
}
if ((0, isElement_1.isElement)(node)) {
/**
* Assistive technologies SHOULD use the value of aria-roledescription when
* presenting the role of an element, but SHOULD NOT change other
* functionality based on the role of an element that has a value for
* aria-roledescription. For example, an assistive technology that provides
* functions for navigating to the next region or button SHOULD allow those
* functions to navigate to regions and buttons that have an
* aria-roledescription.
*
* REF: https://w3c.github.io/aria/#aria-roledescription
*/
const roledescription = node.getAttribute("aria-roledescription");
if (roledescription) {
return roledescription;
}
}
return role;
};
function getNodeAccessibilityData({ allowedAccessibilityRoles, inheritedImplicitPresentational, node, }) {
const accessibleDescription = (0, getAccessibleDescription_1.getAccessibleDescription)(node);
const accessibleName = (0, getAccessibleName_1.getAccessibleName)(node);
const accessibleValue = (0, getAccessibleValue_1.getAccessibleValue)(node);
const role = (0, getRole_1.getRole)({
const { explicitRole, implicitRole, role } = (0, getRole_1.getRole)({
accessibleName,
allowedAccessibilityRoles,
inheritedImplicitPresentational,

@@ -24,8 +54,40 @@ node,

});
const amendedAccessibleDescription = accessibleDescription === accessibleName ? "" : accessibleDescription;
const isExplicitPresentational = getRole_1.presentationRoles.includes(explicitRole);
const isPresentational = getRole_1.presentationRoles.includes(role);
const isGeneric = role === "generic";
const childrenPresentational = inheritedImplicitPresentational ||
getRole_1.childrenPresentationalRoles.includes(role);
const spokenRole = isPresentational || isGeneric ? "" : role;
const amendedAccessibleDescription = accessibleDescription === accessibleName ? "" : accessibleDescription;
const spokenRole = getSpokenRole({ isGeneric, isPresentational, node, role });
const { requiredOwnedElements: allowedAccessibilityChildRoles } = aria_query_1.roles.get(role) ?? { requiredOwnedElements: [] };
const { requiredOwnedElements: implicitAllowedAccessibilityChildRoles } = aria_query_1.roles.get(implicitRole) ?? { requiredOwnedElements: [] };
/**
* Any descendants of elements that have the characteristic "Children
* Presentational: True" unless the descendant is not allowed to be
* presentational because it meets one of the conditions for exception
* described in Presentational Roles Conflict Resolution. However, the text
* content of any excluded descendants is included.
*
* REF: https://w3c.github.io/aria/#tree_exclusion
*/
const isChildrenPresentationalRole = childrenPresentationalRoles.includes(role);
/**
* When an explicit or inherited role of presentation is applied to an
* element with the implicit semantic of a WAI-ARIA role that has Allowed
* Accessibility Child Roles, in addition to the element with the explicit
* role of presentation, the user agent MUST apply an inherited role of
* presentation to any owned elements that do not have an explicit role
* defined. Also, when an explicit or inherited role of presentation is
* applied to a host language element which has specifically allowed children
* as defined by the host language specification, in addition to the element
* with the explicit role of presentation, the user agent MUST apply an
* inherited role of presentation to any specifically allowed children that
* do not have an explicit role defined.
*
* REF: https://w3c.github.io/aria/#presentational-role-inheritance
*/
const isExplicitOrInheritedPresentation = isExplicitPresentational || inheritedImplicitPresentational;
const isElementWithImplicitAllowedAccessibilityChildRoles = !!implicitAllowedAccessibilityChildRoles.length;
const childrenInheritPresentationExceptAllowedRoles = isExplicitOrInheritedPresentation &&
isElementWithImplicitAllowedAccessibilityChildRoles;
const childrenPresentational = isChildrenPresentationalRole ||
childrenInheritPresentationExceptAllowedRoles;
return {

@@ -36,2 +98,3 @@ accessibleAttributeLabels,

accessibleValue,
allowedAccessibilityChildRoles,
childrenPresentational,

@@ -38,0 +101,0 @@ role,

@@ -10,2 +10,11 @@ import { CommandOptions, ScreenReader } from "@guidepup/guidepup";

}
/**
* TODO: When an assistive technology reading cursor moves from one article to
* another, assistive technologies SHOULD set user agent focus on the article
* that contains the reading cursor. If the reading cursor lands on a focusable
* element inside the article, the assistive technology MAY set focus on that
* element in lieu of setting focus on the containing article.
*
* REF: https://w3c.github.io/aria/#feed
*/
export declare class Virtual implements ScreenReader {

@@ -12,0 +21,0 @@ #private;

@@ -50,2 +50,8 @@ "use strict";

*
* When live regions are marked as polite, assistive technologies SHOULD
* announce updates at the next graceful opportunity, such as at the end of
* speaking the current sentence or when the user pauses typing. When live
* regions are marked as assertive, assistive technologies SHOULD notify the
* user immediately.
*
* REF:

@@ -56,2 +62,3 @@ *

* - https://w3c.github.io/aria/#attrs_liveregions
* - https://w3c.github.io/aria/#aria-live
*/

@@ -63,2 +70,11 @@ /**

*/
/**
* TODO: When a modal element is displayed, assistive technologies SHOULD
* navigate to the element unless focus has explicitly been set elsewhere. Some
* assistive technologies limit navigation to the modal element's contents. If
* focus moves to an element outside the modal element, assistive technologies
* SHOULD NOT limit navigation to the modal element.
*
* REF: https://w3c.github.io/aria/#aria-modal
*/
const observeDOM = (function () {

@@ -91,2 +107,11 @@ const MutationObserver = window.MutationObserver;

}
/**
* TODO: When an assistive technology reading cursor moves from one article to
* another, assistive technologies SHOULD set user agent focus on the article
* that contains the reading cursor. If the reading cursor lands on a focusable
* element inside the article, the assistive technology MAY set focus on that
* element in lieu of setting focus on the containing article.
*
* REF: https://w3c.github.io/aria/#feed
*/
class Virtual {

@@ -350,4 +375,75 @@ #activeNode = null;

await tick();
// TODO: decide what this means as there is no established "common" command
// set for different screen readers.
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role banner.
*
* REF: https://w3c.github.io/aria/#banner
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role complementary.
*
* REF: https://w3c.github.io/aria/#complementary
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role contentinfo.
*
* REF: https://w3c.github.io/aria/#contentinfo
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* figures.
*
* REF: https://w3c.github.io/aria/#figure
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role form.
*
* REF: https://w3c.github.io/aria/#form
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* landmark regions.
*
* REF: https://w3c.github.io/aria/#landmark
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role main.
*
* REF: https://w3c.github.io/aria/#main
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role navigation.
*
* REF: https://w3c.github.io/aria/#navigation
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role region.
*
* REF: https://w3c.github.io/aria/#region
*/
/**
* TODO: Assistive technologies SHOULD enable users to quickly navigate to
* elements with role search.
*
* REF: https://w3c.github.io/aria/#search
*/
/**
* TODO: However, when aria-flowto is provided with multiple ID
* references, assistive technologies SHOULD present the referenced
* elements as path choices.
*
* In the case of one or more ID references, user agents or assistive
* technologies SHOULD give the user the option of navigating to any of the
* targeted elements. The name of the path can be determined by the name of
* the target element of the aria-flowto attribute. Accessibility APIs can
* provide named path relationships.
*
* REF: https://w3c.github.io/aria/#aria-flowto
*/
(0, notImplemented_1.notImplemented)();

@@ -354,0 +450,0 @@ }

{
"name": "@guidepup/virtual-screen-reader",
"version": "0.6.1",
"version": "0.7.0",
"description": "Virtual screen reader driver for unit test automation.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc