diff --git a/lib/commons/text/subtree-text.js b/lib/commons/text/subtree-text.js
index 971ef51365..2708b6f3f2 100644
--- a/lib/commons/text/subtree-text.js
+++ b/lib/commons/text/subtree-text.js
@@ -13,14 +13,32 @@ import getOwnedVirtual from '../aria/get-owned-virtual';
function subtreeText(virtualNode, context = {}) {
const { alreadyProcessed } = accessibleTextVirtual;
context.startNode = context.startNode || virtualNode;
- const { strict } = context;
+ const { strict, inControlContext, inLabelledByContext } = context;
if (
alreadyProcessed(virtualNode, context) ||
- !namedFromContents(virtualNode, { strict })
+ 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);
}, '');
diff --git a/test/commons/text/accessible-text.js b/test/commons/text/accessible-text.js
index fb76a851d3..9b42b79b9f 100644
--- a/test/commons/text/accessible-text.js
+++ b/test/commons/text/accessible-text.js
@@ -257,12 +257,12 @@ describe('text.accessibleTextVirtual', function() {
axe.testUtils.flatTreeSetup(fixture);
var target = axe.utils.querySelectorAll(axe._tree, '#t2label')[0];
- // Chrome 72: This is This is a label of
- // Firefox 62: This is ARIA Label
- // Safari 12.0: This is This is a label of
+ // Chrome 86: This is This is a label of
+ // Firefox 82: This is ARIA Label everything
+ // Safari 14.0: This is This is a label of everything
assert.equal(
axe.commons.text.accessibleTextVirtual(target),
- 'This is This is a label of'
+ 'This is This is a label of everything'
);
});
diff --git a/test/integration/rules/link-name/link-name.html b/test/integration/rules/link-name/link-name.html
index fd70c3e4b8..797402245d 100644
--- a/test/integration/rules/link-name/link-name.html
+++ b/test/integration/rules/link-name/link-name.html
@@ -2,6 +2,9 @@
+
+