Skip to content

Commit 8088ed0

Browse files
authored
Revert "feat(cdk/a11y): allow safe HTML to be passed to live announcer" (#32403)
This reverts commit 3b80628.
1 parent a20aeab commit 8088ed0

File tree

4 files changed

+15
-58
lines changed

4 files changed

+15
-58
lines changed

goldens/cdk/a11y/index.api.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { OnChanges } from '@angular/core';
1818
import { OnDestroy } from '@angular/core';
1919
import { Provider } from '@angular/core';
2020
import { QueryList } from '@angular/core';
21-
import { SafeHtml } from '@angular/platform-browser';
2221
import { Signal } from '@angular/core';
2322
import { SimpleChanges } from '@angular/core';
2423
import { Subject } from 'rxjs';
@@ -405,10 +404,10 @@ export const LIVE_ANNOUNCER_ELEMENT_TOKEN: InjectionToken<HTMLElement | null>;
405404
// @public (undocumented)
406405
export class LiveAnnouncer implements OnDestroy {
407406
constructor(...args: unknown[]);
408-
announce(message: LiveAnnouncerMessage): Promise<void>;
409-
announce(message: LiveAnnouncerMessage, politeness?: AriaLivePoliteness): Promise<void>;
410-
announce(message: LiveAnnouncerMessage, duration?: number): Promise<void>;
411-
announce(message: LiveAnnouncerMessage, politeness?: AriaLivePoliteness, duration?: number): Promise<void>;
407+
announce(message: string): Promise<void>;
408+
announce(message: string, politeness?: AriaLivePoliteness): Promise<void>;
409+
announce(message: string, duration?: number): Promise<void>;
410+
announce(message: string, politeness?: AriaLivePoliteness, duration?: number): Promise<void>;
412411
clear(): void;
413412
// (undocumented)
414413
ngOnDestroy(): void;
@@ -424,9 +423,6 @@ export interface LiveAnnouncerDefaultOptions {
424423
politeness?: AriaLivePoliteness;
425424
}
426425

427-
// @public
428-
export type LiveAnnouncerMessage = string | SafeHtml;
429-
430426
// @public @deprecated
431427
export const MESSAGES_CONTAINER_ID = "cdk-describedby-message-container";
432428

src/cdk/a11y/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ ng_project(
1818
deps = [
1919
"//:node_modules/@angular/common",
2020
"//:node_modules/@angular/core",
21-
"//:node_modules/@angular/platform-browser",
2221
"//:node_modules/rxjs",
2322
"//src:dev_mode_types",
2423
"//src/cdk/coercion",

src/cdk/a11y/live-announcer/live-announcer.spec.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import {MutationObserverFactory} from '../../observers';
22
import {ComponentPortal} from '../../portal';
33
import {Component, inject, Injector} from '@angular/core';
44
import {ComponentFixture, TestBed, fakeAsync, flush, tick} from '@angular/core/testing';
5-
import {By, DomSanitizer} from '@angular/platform-browser';
5+
import {By} from '@angular/platform-browser';
66
import {A11yModule} from '../index';
7-
import {LiveAnnouncer, LiveAnnouncerMessage} from './live-announcer';
7+
import {LiveAnnouncer} from './live-announcer';
88
import {
99
AriaLivePoliteness,
1010
LIVE_ANNOUNCER_DEFAULT_OPTIONS,
@@ -202,19 +202,6 @@ describe('LiveAnnouncer', () => {
202202
tick(100);
203203
expect(modal.getAttribute('aria-owns')).toBe(`foo bar ${ariaLiveElement.id}`);
204204
}));
205-
206-
it('should be able to announce safe HTML', fakeAsync(() => {
207-
const sanitizer = TestBed.inject(DomSanitizer);
208-
const message = sanitizer.bypassSecurityTrustHtml(
209-
'<span class="message" lang="fr">Bonjour</span>',
210-
);
211-
fixture.componentInstance.announce(message);
212-
213-
// This flushes our 100ms timeout for the screenreaders.
214-
tick(100);
215-
216-
expect(ariaLiveElement.querySelector('.message')?.textContent).toBe('Bonjour');
217-
}));
218205
});
219206

220207
describe('with a custom element', () => {
@@ -391,13 +378,13 @@ function getLiveElement(): Element {
391378
}
392379

393380
@Component({
394-
template: `<button (click)="announce('Test')">Announce</button>`,
381+
template: `<button (click)="announceText('Test')">Announce</button>`,
395382
imports: [A11yModule],
396383
})
397384
class TestApp {
398385
live = inject(LiveAnnouncer);
399386

400-
announce(message: LiveAnnouncerMessage) {
387+
announceText(message: string) {
401388
this.live.announce(message);
402389
}
403390
}

src/cdk/a11y/live-announcer/live-announcer.ts

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,18 @@ import {
1717
OnDestroy,
1818
inject,
1919
DOCUMENT,
20-
SecurityContext,
2120
} from '@angular/core';
22-
import {DomSanitizer, SafeHtml} from '@angular/platform-browser';
2321
import {Subscription} from 'rxjs';
2422
import {
2523
AriaLivePoliteness,
2624
LiveAnnouncerDefaultOptions,
2725
LIVE_ANNOUNCER_ELEMENT_TOKEN,
2826
LIVE_ANNOUNCER_DEFAULT_OPTIONS,
2927
} from './live-announcer-tokens';
30-
import {_CdkPrivateStyleLoader, _VisuallyHiddenLoader, trustedHTMLFromString} from '../../private';
28+
import {_CdkPrivateStyleLoader, _VisuallyHiddenLoader} from '../../private';
3129

3230
let uniqueIds = 0;
3331

34-
/** Possible types for a message that can be announced by the `LiveAnnouncer`. */
35-
export type LiveAnnouncerMessage = string | SafeHtml;
36-
3732
@Injectable({providedIn: 'root'})
3833
export class LiveAnnouncer implements OnDestroy {
3934
private _ngZone = inject(NgZone);
@@ -43,7 +38,6 @@ export class LiveAnnouncer implements OnDestroy {
4338

4439
private _liveElement: HTMLElement;
4540
private _document = inject(DOCUMENT);
46-
private _sanitizer = inject(DomSanitizer);
4741
private _previousTimeout: ReturnType<typeof setTimeout>;
4842
private _currentPromise: Promise<void> | undefined;
4943
private _currentResolve: (() => void) | undefined;
@@ -60,15 +54,15 @@ export class LiveAnnouncer implements OnDestroy {
6054
* @param message Message to be announced to the screen reader.
6155
* @returns Promise that will be resolved when the message is added to the DOM.
6256
*/
63-
announce(message: LiveAnnouncerMessage): Promise<void>;
57+
announce(message: string): Promise<void>;
6458

6559
/**
6660
* Announces a message to screen readers.
6761
* @param message Message to be announced to the screen reader.
6862
* @param politeness The politeness of the announcer element.
6963
* @returns Promise that will be resolved when the message is added to the DOM.
7064
*/
71-
announce(message: LiveAnnouncerMessage, politeness?: AriaLivePoliteness): Promise<void>;
65+
announce(message: string, politeness?: AriaLivePoliteness): Promise<void>;
7266

7367
/**
7468
* Announces a message to screen readers.
@@ -78,7 +72,7 @@ export class LiveAnnouncer implements OnDestroy {
7872
* 100ms after `announce` has been called.
7973
* @returns Promise that will be resolved when the message is added to the DOM.
8074
*/
81-
announce(message: LiveAnnouncerMessage, duration?: number): Promise<void>;
75+
announce(message: string, duration?: number): Promise<void>;
8276

8377
/**
8478
* Announces a message to screen readers.
@@ -89,13 +83,9 @@ export class LiveAnnouncer implements OnDestroy {
8983
* 100ms after `announce` has been called.
9084
* @returns Promise that will be resolved when the message is added to the DOM.
9185
*/
92-
announce(
93-
message: LiveAnnouncerMessage,
94-
politeness?: AriaLivePoliteness,
95-
duration?: number,
96-
): Promise<void>;
86+
announce(message: string, politeness?: AriaLivePoliteness, duration?: number): Promise<void>;
9787

98-
announce(message: LiveAnnouncerMessage, ...args: any[]): Promise<void> {
88+
announce(message: string, ...args: any[]): Promise<void> {
9989
const defaultOptions = this._defaultOptions;
10090
let politeness: AriaLivePoliteness | undefined;
10191
let duration: number | undefined;
@@ -137,22 +127,7 @@ export class LiveAnnouncer implements OnDestroy {
137127

138128
clearTimeout(this._previousTimeout);
139129
this._previousTimeout = setTimeout(() => {
140-
if (!message || typeof message === 'string') {
141-
this._liveElement.textContent = message;
142-
} else {
143-
const cleanMessage = this._sanitizer.sanitize(SecurityContext.HTML, message);
144-
145-
if (cleanMessage === null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
146-
throw new Error(
147-
`The message provided to LiveAnnouncer was not trusted as safe HTML by ` +
148-
`Angular's DomSanitizer. Attempted message was "${message}".`,
149-
);
150-
}
151-
152-
this._liveElement.innerHTML = trustedHTMLFromString(
153-
cleanMessage || '',
154-
) as unknown as string;
155-
}
130+
this._liveElement.textContent = message;
156131

157132
if (typeof duration === 'number') {
158133
this._previousTimeout = setTimeout(() => this.clear(), duration);

0 commit comments

Comments
 (0)