12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- import accessibleTextVirtual from './accessible-text-virtual';
- import namedFromContents from '../aria/named-from-contents';
- import getOwnedVirtual from '../aria/get-owned-virtual';
- import getElementsByContentType from '../standards/get-elements-by-content-type';
- /**
- * Get the accessible text for an element that can get its name from content
- *
- * @param {VirtualNode} element
- * @param {Object} context
- * @property {Bool} strict Should the name computation strictly follow AccName 1.1
- * @return {String} Accessible text
- */
- function subtreeText(virtualNode, context = {}) {
- const { alreadyProcessed } = accessibleTextVirtual;
- context.startNode = context.startNode || virtualNode;
- const { strict, inControlContext, inLabelledByContext } = context;
- if (
- alreadyProcessed(virtualNode, context) ||
- virtualNode.props.nodeType !== 1
- ) {
- return '';
- }
- if (
- !namedFromContents(virtualNode, { strict }) &&
- !context.subtreeDescendant
- ) {
- return '';
- }
- /**
- * Note: Strictly speaking if a child isn't named from content and it has no accessible name
- * accName says to ignore it. Browsers do this fairly consistently, but screen readers have
- * chosen to ignore this, but only for direct content, not for labels / aria-labelledby.
- * That way in `a[href] > article > #text` the text is used for the accessible name,
- * See: https://github.com/dequelabs/axe-core/issues/1461
- */
- if (!strict) {
- const subtreeDescendant = !inControlContext && !inLabelledByContext;
- context = { subtreeDescendant, ...context };
- }
- return getOwnedVirtual(virtualNode).reduce((contentText, child) => {
- return appendAccessibleText(contentText, child, context);
- }, '');
- }
- const phrasingElements = getElementsByContentType('phrasing').concat(['#text']);
- function appendAccessibleText(contentText, virtualNode, context) {
- const nodeName = virtualNode.props.nodeName;
- let contentTextAdd = accessibleTextVirtual(virtualNode, context);
- if (!contentTextAdd) {
- return contentText;
- }
- if (!phrasingElements.includes(nodeName)) {
- // Append space, if necessary
- if (contentTextAdd[0] !== ' ') {
- contentTextAdd += ' ';
- }
- // Prepend space, if necessary
- if (contentText && contentText[contentText.length - 1] !== ' ') {
- contentTextAdd = ' ' + contentTextAdd;
- }
- }
- return contentText + contentTextAdd;
- }
- export default subtreeText;
|