From 75cf2bcd9513d44c72d49d792b9bb27cccd90e5d Mon Sep 17 00:00:00 2001 From: Sam Saccone Date: Sun, 7 Jul 2024 13:46:16 -0700 Subject: [PATCH] Fix defect in calling code when building the ElementRoleMap As discovered in #554 Address the defect introduced f7f6120#r143856081 This change depends on https://github.com/A11yance/aria-query/pull/558 which when applied (as in this PR makes the teset cases pass) --- __tests__/src/elementRoleMap-test.js | 2 +- src/elementRoleMap.js | 54 +++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/__tests__/src/elementRoleMap-test.js b/__tests__/src/elementRoleMap-test.js index fcfbccc..9f9968e 100644 --- a/__tests__/src/elementRoleMap-test.js +++ b/__tests__/src/elementRoleMap-test.js @@ -230,7 +230,7 @@ describe('elementRolesMap', function () { }); describe('spread operator', function () { it('should have a specific length', function () { - expect([...elementRoleMap].length).toEqual(113); + expect([...elementRoleMap].length).toEqual(112); }); test.each([...elementRoleMap])('Testing element: %o', (obj, roles) => { expect(entriesList).toEqual( diff --git a/src/elementRoleMap.js b/src/elementRoleMap.js index 0d016a4..eeeff70 100644 --- a/src/elementRoleMap.js +++ b/src/elementRoleMap.js @@ -23,7 +23,27 @@ for (let i = 0; i < keys.length; i++) { if (relation.module === 'HTML') { const concept = relation.concept; if (concept) { - elementRoles.push([concept, [key]]); + const elementRoleRelation: ?ElementARIARoleRelationTuple = elementRoles.find(relation => ariaRoleRelationConceptEquals(relation[0], concept)); + let roles: RoleSet; + + if (elementRoleRelation) { + roles = elementRoleRelation[1]; + } else { + roles = []; + } + let isUnique = true; + for (let i = 0; i < roles.length; i++) { + if (roles[i] === key) { + isUnique = false; + break; + } + } + if (isUnique) { + roles.push(key); + } + if (!elementRoleRelation) { + elementRoles.push([concept, roles]); + } } } } @@ -63,6 +83,38 @@ const elementRoleMap: TAriaQueryMap< }, }; +function ariaRoleRelationConceptEquals(a: ARIARoleRelationConcept, b: ARIARoleRelationConcept): boolean { + return ( + a.name === b.name && + ariaRoleRelationConstraintsEquals(a.constraints, b.constraints) && + ariaRoleRelationConceptAttributeEquals(a.attributes, b.attributes) + ) +} + +function ariaRoleRelationConstraintsEquals(a?: ARIARoleRelationConcept['constraints'], b?: ARIARoleRelationConcept['constraints']): boolean { + if (a === undefined && b !== undefined) { + return false; + } + + if (a !== undefined && b === undefined) { + return false; + } + + if (a !== undefined && b !== undefined) { + if (a.length != b.length) { + return false; + } + + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) { + return false; + } + } + } + + return true; +} + function ariaRoleRelationConceptAttributeEquals( a?: Array, b?: Array,