Skip to content

Commit

Permalink
fix(snack-bar): prevent content from overriding configured aria-live …
Browse files Browse the repository at this point in the history
…message (#12294)

* Currently the `announcementMessage` config option is always being overwritten when opening a simple snackbar.
  • Loading branch information
devversion authored and mmalerba committed Jul 29, 2018
1 parent fba4a93 commit 0958cbb
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
5 changes: 4 additions & 1 deletion src/lib/snack-bar/snack-bar-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ export class MatSnackBarConfig<D = any> {
/** The politeness level for the MatAriaLiveAnnouncer announcement. */
politeness?: AriaLivePoliteness = 'assertive';

/** Message to be announced by the MatAriaLiveAnnouncer */
/**
* Message to be announced by the LiveAnnouncer. When opening a snackbar without a custom
* component or template, the announcement message will default to the specified message.
*/
announcementMessage?: string = '';

/** The view container to place the overlay for the snack bar into. */
Expand Down
54 changes: 42 additions & 12 deletions src/lib/snack-bar/snack-bar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,21 @@ describe('MatSnackBar', () => {
.toBe('alert', 'Expected snack bar container to have role="alert"');
});

it('should open and close a snackbar without a ViewContainerRef', fakeAsync(() => {
let snackBarRef = snackBar.open('Snack time!', 'Chew');
viewContainerFixture.detectChanges();
it('should open and close a snackbar without a ViewContainerRef', fakeAsync(() => {
let snackBarRef = snackBar.open('Snack time!', 'Chew');
viewContainerFixture.detectChanges();

let messageElement = overlayContainerElement.querySelector('snack-bar-container')!;
expect(messageElement.textContent).toContain('Snack time!',
'Expected snack bar to show a message without a ViewContainerRef');
let messageElement = overlayContainerElement.querySelector('snack-bar-container')!;
expect(messageElement.textContent).toContain('Snack time!',
'Expected snack bar to show a message without a ViewContainerRef');

snackBarRef.dismiss();
viewContainerFixture.detectChanges();
flush();
snackBarRef.dismiss();
viewContainerFixture.detectChanges();
flush();

expect(overlayContainerElement.childNodes.length)
.toBe(0, 'Expected snack bar to be dismissed without a ViewContainerRef');
}));
expect(overlayContainerElement.childNodes.length)
.toBe(0, 'Expected snack bar to be dismissed without a ViewContainerRef');
}));

it('should open a simple message with a button', () => {
let config: MatSnackBarConfig = {viewContainerRef: testViewContainerRef};
Expand Down Expand Up @@ -153,6 +153,36 @@ describe('MatSnackBar', () => {
.toBe(0, 'Expected the overlay container element to have no child elements');
}));


it('should default to the passed message for the announcement message', fakeAsync(() => {
spyOn(liveAnnouncer, 'announce');

snackBar.open(simpleMessage);
viewContainerFixture.detectChanges();

expect(overlayContainerElement.childElementCount)
.toBe(1, 'Expected the overlay with the default announcement message to be added');

// Expect the live announcer to have been called with the display message and some
// string for the politeness. We do not want to test for the default politeness here.
expect(liveAnnouncer.announce).toHaveBeenCalledWith(simpleMessage, jasmine.any(String));
}));

it('should be able to specify a custom announcement message', fakeAsync(() => {
spyOn(liveAnnouncer, 'announce');

snackBar.open(simpleMessage, '', {
announcementMessage: 'Custom announcement',
politeness: 'assertive'
});
viewContainerFixture.detectChanges();

expect(overlayContainerElement.childElementCount)
.toBe(1, 'Expected the overlay with a custom `announcementMessage` to be added');

expect(liveAnnouncer.announce).toHaveBeenCalledWith('Custom announcement', 'assertive');
}));

it('should be able to get dismissed through the service', fakeAsync(() => {
snackBar.open(simpleMessage);
viewContainerFixture.detectChanges();
Expand Down
5 changes: 4 additions & 1 deletion src/lib/snack-bar/snack-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ export class MatSnackBar {
// Since the user doesn't have access to the component, we can
// override the data to pass in our own message and action.
_config.data = {message, action};
_config.announcementMessage = message;

if (!_config.announcementMessage) {
_config.announcementMessage = message;
}

return this.openFromComponent(SimpleSnackBar, _config);
}
Expand Down

0 comments on commit 0958cbb

Please sign in to comment.