File tree Expand file tree Collapse file tree 2 files changed +22
-3
lines changed
src/cdk/a11y/aria-describer Expand file tree Collapse file tree 2 files changed +22
-3
lines changed Original file line number Diff line number Diff line change @@ -132,6 +132,13 @@ describe('AriaDescriber', () => {
132
132
// Use `querySelectorAll` with an attribute since `getElementById` will stop at the first match.
133
133
expect ( document . querySelectorAll ( `[id='${ MESSAGES_CONTAINER_ID } ']` ) . length ) . toBe ( 1 ) ;
134
134
} ) ;
135
+
136
+ it ( 'should not describe messages that match up with the aria-label of the element' , ( ) => {
137
+ component . element1 . setAttribute ( 'aria-label' , 'Hello' ) ;
138
+ ariaDescriber . describe ( component . element1 , 'Hello' ) ;
139
+ ariaDescriber . describe ( component . element1 , 'Hi' ) ;
140
+ expectMessages ( [ 'Hi' ] ) ;
141
+ } ) ;
135
142
} ) ;
136
143
137
144
function getMessagesContainer ( ) {
Original file line number Diff line number Diff line change @@ -83,7 +83,7 @@ export class AriaDescriber implements OnDestroy {
83
83
84
84
/** Removes the host element's aria-describedby reference to the message element. */
85
85
removeDescription ( hostElement : Element , message : string ) {
86
- if ( ! this . _canBeDescribed ( hostElement , message ) ) {
86
+ if ( ! this . _isElementNode ( hostElement ) ) {
87
87
return ;
88
88
}
89
89
@@ -218,10 +218,22 @@ export class AriaDescriber implements OnDestroy {
218
218
219
219
/** Determines whether a message can be described on a particular element. */
220
220
private _canBeDescribed ( element : Element , message : string ) : boolean {
221
- return element . nodeType === this . _document . ELEMENT_NODE && message != null &&
222
- ! ! `${ message } ` . trim ( ) ;
221
+ if ( ! this . _isElementNode ( element ) ) {
222
+ return false ;
223
+ }
224
+
225
+ const trimmedMessage = message == null ? '' : `${ message } ` . trim ( ) ;
226
+ const ariaLabel = element . getAttribute ( 'aria-label' ) ;
227
+
228
+ // We shouldn't set descriptions if they're exactly the same as the `aria-label` of the element,
229
+ // because screen readers will end up reading out the same text twice in a row.
230
+ return trimmedMessage ? ( ! ariaLabel || ariaLabel . trim ( ) !== trimmedMessage ) : false ;
223
231
}
224
232
233
+ /** Checks whether a node is an Element node. */
234
+ private _isElementNode ( element : Node ) : element is Element {
235
+ return element . nodeType === this . _document . ELEMENT_NODE ;
236
+ }
225
237
}
226
238
227
239
You can’t perform that action at this time.
0 commit comments