mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(focus-monitor): implement OnDestroy logic (#9305)
Similarly to most of the other DOM-related services, these changes implement `ngOnDestroy` for the `FocusMonitor` which removes the monitoring from all of the currently-monitored elements.
This commit is contained in:
committed by
Jeremy Elbourn
parent
c60483485e
commit
8972bf4e79
@@ -186,14 +186,28 @@ describe('FocusMonitor', () => {
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(buttonElement.classList.length)
|
||||
.toBe(2, 'button should have exactly 2 focus classes');
|
||||
expect(buttonElement.classList.length).toBe(2, 'button should have exactly 2 focus classes');
|
||||
|
||||
focusMonitor.stopMonitoring(buttonElement);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(buttonElement.classList.length).toBe(0, 'button should not have any focus classes');
|
||||
}));
|
||||
|
||||
it('should remove classes when destroyed', fakeAsync(() => {
|
||||
buttonElement.focus();
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(buttonElement.classList.length).toBe(2, 'button should have exactly 2 focus classes');
|
||||
|
||||
// Destroy manually since destroying the fixture won't do it.
|
||||
focusMonitor.ngOnDestroy();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(buttonElement.classList.length).toBe(0, 'button should not have any focus classes');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ type MonitoredElementInfo = {
|
||||
|
||||
/** Monitors mouse and keyboard events to determine the cause of focus events. */
|
||||
@Injectable()
|
||||
export class FocusMonitor {
|
||||
export class FocusMonitor implements OnDestroy {
|
||||
/** The focus origin that the next focus event is a result of. */
|
||||
private _origin: FocusOrigin = null;
|
||||
|
||||
@@ -58,8 +58,8 @@ export class FocusMonitor {
|
||||
/** The timeout id of the touch timeout, used to cancel timeout later. */
|
||||
private _touchTimeout: number;
|
||||
|
||||
/** Weak map of elements being monitored to their info. */
|
||||
private _elementInfo = new WeakMap<Element, MonitoredElementInfo>();
|
||||
/** Map of elements being monitored to their info. */
|
||||
private _elementInfo = new Map<HTMLElement, MonitoredElementInfo>();
|
||||
|
||||
/** A map of global objects to lists of current listeners. */
|
||||
private _unregisterGlobalListeners = () => {};
|
||||
@@ -135,7 +135,7 @@ export class FocusMonitor {
|
||||
* @param element The element to stop monitoring.
|
||||
*/
|
||||
stopMonitoring(element: HTMLElement): void {
|
||||
let elementInfo = this._elementInfo.get(element);
|
||||
const elementInfo = this._elementInfo.get(element);
|
||||
|
||||
if (elementInfo) {
|
||||
elementInfo.unlisten();
|
||||
@@ -157,6 +157,10 @@ export class FocusMonitor {
|
||||
element.focus();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._elementInfo.forEach((_info, element) => this.stopMonitoring(element));
|
||||
}
|
||||
|
||||
/** Register necessary event listeners on the document and window. */
|
||||
private _registerGlobalListeners() {
|
||||
// Do nothing if we're not on the browser platform.
|
||||
|
||||
Reference in New Issue
Block a user