From 8fb4635e01c82b80ff23994edad180dd73730a98 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Tue, 22 Jun 2021 16:02:56 +0200 Subject: [PATCH] fix(accText): ignore text in embedded content elements (#3022) * fix(accText): ignore text in embedded content elements Closes #3017 * Update lib/standards/html-elms.js * Update lib/standards/html-elms.js Co-authored-by: Steven Lambert <2433219+straker@users.noreply.github.com> Co-authored-by: Steven Lambert <2433219+straker@users.noreply.github.com> --- lib/commons/text/subtree-text.js | 6 +++++- lib/standards/html-elms.js | 3 ++- test/checks/shared/has-visible-text.js | 8 ++++---- .../standards/get-elements-by-content-type.js | 1 - test/commons/text/subtree-text.js | 15 +++++++++++++++ 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/commons/text/subtree-text.js b/lib/commons/text/subtree-text.js index 909271825a..2e8b1c4395 100644 --- a/lib/commons/text/subtree-text.js +++ b/lib/commons/text/subtree-text.js @@ -2,6 +2,7 @@ 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'; +import getElementSpec from '../standards/get-element-spec' /** * Get the accessible text for an element that can get its name from content @@ -15,9 +16,11 @@ function subtreeText(virtualNode, context = {}) { const { alreadyProcessed } = accessibleTextVirtual; context.startNode = context.startNode || virtualNode; const { strict, inControlContext, inLabelledByContext } = context; + const { contentTypes } = getElementSpec(virtualNode); if ( alreadyProcessed(virtualNode, context) || - virtualNode.props.nodeType !== 1 + virtualNode.props.nodeType !== 1 || + contentTypes?.includes('embedded') // canvas, video, etc ) { return ''; } @@ -40,6 +43,7 @@ function subtreeText(virtualNode, context = {}) { const subtreeDescendant = !inControlContext && !inLabelledByContext; context = { subtreeDescendant, ...context }; } + return getOwnedVirtual(virtualNode).reduce((contentText, child) => { return appendAccessibleText(contentText, child, context); }, ''); diff --git a/lib/standards/html-elms.js b/lib/standards/html-elms.js index d6267890d8..a27ca6258b 100644 --- a/lib/standards/html-elms.js +++ b/lib/standards/html-elms.js @@ -671,7 +671,8 @@ const htmlElms = { noAriaAttrs: true }, picture: { - contentTypes: ['embedded', 'phrasing', 'flow'], + // Note: spec change (do not count as embedded), because browsers do not hide text inside the picture element + contentTypes: ['phrasing', 'flow'], allowedRoles: false, noAriaAttrs: true }, diff --git a/test/checks/shared/has-visible-text.js b/test/checks/shared/has-visible-text.js index 891cbd86c0..77b1886742 100644 --- a/test/checks/shared/has-visible-text.js +++ b/test/checks/shared/has-visible-text.js @@ -13,7 +13,7 @@ describe('has-visible-text', function() { }); it('should return false if there is no visible text', function() { - var params = checkSetup(''); + var params = checkSetup('

'); assert.isFalse( axe.testUtils .getCheckEvaluate('has-visible-text') @@ -23,7 +23,7 @@ describe('has-visible-text', function() { it('should return false if there is text, but its hidden', function() { var params = checkSetup( - 'hello!' + '

hello!

' ); assert.isFalse( axe.testUtils @@ -33,7 +33,7 @@ describe('has-visible-text', function() { }); it('should return true if there is visible text', function() { - var params = checkSetup('hello!'); + var params = checkSetup('

hello!

'); assert.isTrue( axe.testUtils .getCheckEvaluate('has-visible-text') @@ -75,7 +75,7 @@ describe('has-visible-text', function() { it('should return true if there is visible text', function() { var node = new axe.SerialVirtualNode({ - nodeName: 'object' + nodeName: 'p' }); var child = new axe.SerialVirtualNode({ nodeName: '#text', diff --git a/test/commons/standards/get-elements-by-content-type.js b/test/commons/standards/get-elements-by-content-type.js index eb2ac01cb1..4e3bb5aab4 100644 --- a/test/commons/standards/get-elements-by-content-type.js +++ b/test/commons/standards/get-elements-by-content-type.js @@ -26,7 +26,6 @@ describe('standards.getElementsByContentType', function() { 'img', 'math', 'object', - 'picture', 'svg', 'video' ]); diff --git a/test/commons/text/subtree-text.js b/test/commons/text/subtree-text.js index 1f5818a3f6..143ad71d63 100644 --- a/test/commons/text/subtree-text.js +++ b/test/commons/text/subtree-text.js @@ -34,6 +34,21 @@ describe('text.subtreeText', function() { assert.equal(subtreeText(fixture), 'foobarbazfizzbuzz'); }); + it('returns `` for embedded content', function() { + fixtureSetup( + '' + + '' + + 'foo' + + '' + + 'foo' + ); + var children = axe._tree[0].children; + assert.lengthOf(children, 5); + children.forEach(function (embeddedContent) { + assert.equal(subtreeText(embeddedContent), ''); + }); + }); + describe('context.processed', function() { beforeEach(function() { fixtureSetup('

foo

');