Skip to content

Commit 3ee15ef

Browse files
committed
feat(cdk/a11y): Respond to additional PR reviewer feedback
1 parent 97b7255 commit 3ee15ef

File tree

3 files changed

+42
-36
lines changed

3 files changed

+42
-36
lines changed

src/cdk/a11y/input-modality/input-modality-detector.ts

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import {ALT, CONTROL, META, SHIFT} from '@angular/cdk/keycodes';
1010
import {Inject, Injectable, InjectionToken, OnDestroy, Optional, NgZone} from '@angular/core';
1111
import {normalizePassiveListenerOptions, Platform} from '@angular/cdk/platform';
1212
import {DOCUMENT} from '@angular/common';
13-
import {Observable, ReplaySubject} from 'rxjs';
14-
import {distinctUntilChanged} from 'rxjs/operators';
13+
import {BehaviorSubject, Observable} from 'rxjs';
14+
import {distinctUntilChanged, skip} from 'rxjs/operators';
1515
import {
1616
isFakeMousedownFromScreenReader,
1717
isFakeTouchstartFromScreenReader,
@@ -91,14 +91,11 @@ export class InputModalityDetector implements OnDestroy {
9191

9292
/** Returns the most recently detected input modality. */
9393
get inputModality(): InputModality {
94-
return this._inputModality;
94+
return this._inputModality.value;
9595
}
9696

97-
/** The underlying ReplaySubject that emits input modality changes. */
98-
private readonly _change = new ReplaySubject<InputModality>(1);
99-
100-
/** The current / last detected input modality by this service. */
101-
private _inputModality: InputModality = null;
97+
/** The underlying BehaviorSubject that emits whenever an input modality is detected. */
98+
private readonly _inputModality = new BehaviorSubject<InputModality>(null);
10299

103100
/** Options for this InputModalityDetector. */
104101
private readonly _options: InputModalityDetectorOptions;
@@ -118,7 +115,7 @@ export class InputModalityDetector implements OnDestroy {
118115
// modality to keyboard.
119116
if (this._options?.ignoreKeys?.some(keyCode => keyCode === event.keyCode)) { return; }
120117

121-
this._updateInputModality('keyboard');
118+
this._inputModality.next('keyboard');
122119
}
123120

124121
/**
@@ -133,7 +130,7 @@ export class InputModalityDetector implements OnDestroy {
133130
// after the previous touch event.
134131
if (Date.now() - this._lastTouchMs < TOUCH_BUFFER_MS) { return; }
135132

136-
this._updateInputModality('mouse');
133+
this._inputModality.next('mouse');
137134
}
138135

139136
/**
@@ -147,27 +144,27 @@ export class InputModalityDetector implements OnDestroy {
147144
// triggered via mouse vs touch.
148145
this._lastTouchMs = Date.now();
149146

150-
this._updateInputModality('touch');
147+
this._inputModality.next('touch');
151148
}
152149

153150
constructor(
154-
private readonly _platform: Platform,
155-
ngZone: NgZone,
156-
@Inject(DOCUMENT) document: Document,
157-
@Optional()
158-
@Inject(INPUT_MODALITY_DETECTOR_OPTIONS)
159-
options?: InputModalityDetectorOptions,
151+
private readonly _platform: Platform,
152+
ngZone: NgZone,
153+
@Inject(DOCUMENT) document: Document,
154+
@Optional() @Inject(INPUT_MODALITY_DETECTOR_OPTIONS)
155+
options?: InputModalityDetectorOptions,
160156
) {
161-
// If we're not in a browser, this service should do nothing, as there's no relevant input
162-
// modality to detect.
163-
if (!_platform.isBrowser) { return; }
164-
165157
this._options = {
166158
...INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS,
167159
...options,
168160
};
169161

170-
this.inputModalityChange = this._change.pipe(distinctUntilChanged());
162+
// Only emit if the input modality changes, and skip the first emission as it's null.
163+
this.inputModalityChange = this._inputModality.pipe(distinctUntilChanged(), skip(1));
164+
165+
// If we're not in a browser, this service should do nothing, as there's no relevant input
166+
// modality to detect.
167+
if (!_platform.isBrowser) { return; }
171168

172169
// Add the event listeners used to detect the user's input modality.
173170
ngZone.runOutsideAngular(() => {
@@ -184,13 +181,4 @@ export class InputModalityDetector implements OnDestroy {
184181
document.removeEventListener('mousedown', this._onMousedown, modalityEventListenerOptions);
185182
document.removeEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);
186183
}
187-
188-
/**
189-
* Update the input modality detected by the service.
190-
* @param inputModality The newly detected input modality.
191-
*/
192-
private _updateInputModality(inputModality: InputModality): void {
193-
this._change.next(inputModality);
194-
this._inputModality = inputModality;
195-
}
196184
}

src/dev-app/input-modality/input-modality-detector-demo.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ <h2>Input Modality</h2>
99

1010
<p>
1111
Detected input modality:
12-
<b>{{_inputModalityDetector.inputModalityChange | async}}</b>
12+
<b>{{_modality || '(unknown)'}}</b>
1313
</p>
1414

1515
<button mat-raised-button>Launch</button>

src/dev-app/input-modality/input-modality-detector-demo.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,31 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Component} from '@angular/core';
10-
import {InputModalityDetector} from '@angular/cdk/a11y';
9+
import {Component, OnDestroy, NgZone} from '@angular/core';
10+
import {InputModality, InputModalityDetector} from '@angular/cdk/a11y';
11+
12+
import {Subject} from 'rxjs';
13+
import {takeUntil} from 'rxjs/operators';
1114

1215
@Component({
1316
selector: 'input-modality-detector-demo',
1417
templateUrl: 'input-modality-detector-demo.html',
1518
})
16-
export class InputModalityDetectorDemo {
17-
constructor(readonly _inputModalityDetector: InputModalityDetector) {}
19+
export class InputModalityDetectorDemo implements OnDestroy {
20+
_modality: InputModality = null;
21+
_destroyed = new Subject<void>();
22+
23+
constructor(
24+
inputModalityDetector: InputModalityDetector,
25+
ngZone: NgZone,
26+
) {
27+
inputModalityDetector.inputModalityChange
28+
.pipe(takeUntil(this._destroyed))
29+
.subscribe(modality => ngZone.run(() => { this._modality = modality; }));
30+
}
31+
32+
ngOnDestroy() {
33+
this._destroyed.next();
34+
this._destroyed.complete();
35+
}
1836
}

0 commit comments

Comments
 (0)