Skip to content

Commit

Permalink
refactor: move FocusOriginMonitor into CDK
Browse files Browse the repository at this point in the history
Moves the `FocusOriginMonitor` into `@angular/cdk/a11y`, renames it to `FocusMonitor`, deprecates the `StyleModule` and updates all the references.

BREAKING CHANGE: `FocusOriginMonitor` has been renamed to `FocusMonitor`.
  • Loading branch information
crisbeto committed Sep 14, 2017
1 parent 2f1f0fd commit 9375a4f
Show file tree
Hide file tree
Showing 27 changed files with 119 additions and 123 deletions.
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
import {ComponentFixture, inject, TestBed, fakeAsync, tick} from '@angular/core/testing';
import {Component, Renderer2} from '@angular/core';
import {StyleModule} from './index';
import {A11yModule} from './index';
import {By} from '@angular/platform-browser';
import {TAB} from '../keyboard/keycodes';
import {FocusOrigin, FocusOriginMonitor, TOUCH_BUFFER_MS} from './focus-origin-monitor';
import {TAB} from '@angular/cdk/keycodes';
import {FocusOrigin, FocusMonitor, TOUCH_BUFFER_MS} from './focus-monitor';
import {dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent} from '@angular/cdk/testing';


describe('FocusOriginMonitor', () => {
describe('FocusMonitor', () => {
let fixture: ComponentFixture<PlainButton>;
let buttonElement: HTMLElement;
let buttonRenderer: Renderer2;
let focusOriginMonitor: FocusOriginMonitor;
let focusMonitor: FocusMonitor;
let changeHandler: (origin: FocusOrigin) => void;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [StyleModule],
imports: [A11yModule],
declarations: [
PlainButton,
],
}).compileComponents();
});

beforeEach(inject([FocusOriginMonitor], (fom: FocusOriginMonitor) => {
beforeEach(inject([FocusMonitor], (fm: FocusMonitor) => {
fixture = TestBed.createComponent(PlainButton);
fixture.detectChanges();

buttonElement = fixture.debugElement.query(By.css('button')).nativeElement;
buttonRenderer = fixture.componentInstance.renderer;
focusOriginMonitor = fom;
focusMonitor = fm;

changeHandler = jasmine.createSpy('focus origin change handler');
focusOriginMonitor.monitor(buttonElement, buttonRenderer, false).subscribe(changeHandler);
focusMonitor.monitor(buttonElement, buttonRenderer, false).subscribe(changeHandler);
patchElementFocus(buttonElement);
}));

Expand Down Expand Up @@ -110,7 +110,7 @@ describe('FocusOriginMonitor', () => {
}));

it('focusVia keyboard should simulate keyboard focus', fakeAsync(() => {
focusOriginMonitor.focusVia(buttonElement, 'keyboard');
focusMonitor.focusVia(buttonElement, 'keyboard');
tick();

expect(buttonElement.classList.length)
Expand All @@ -123,7 +123,7 @@ describe('FocusOriginMonitor', () => {
}));

it('focusVia mouse should simulate mouse focus', fakeAsync(() => {
focusOriginMonitor.focusVia(buttonElement, 'mouse');
focusMonitor.focusVia(buttonElement, 'mouse');
fixture.detectChanges();
tick();

Expand All @@ -137,7 +137,7 @@ describe('FocusOriginMonitor', () => {
}));

it('focusVia mouse should simulate mouse focus', fakeAsync(() => {
focusOriginMonitor.focusVia(buttonElement, 'touch');
focusMonitor.focusVia(buttonElement, 'touch');
fixture.detectChanges();
tick();

Expand All @@ -151,7 +151,7 @@ describe('FocusOriginMonitor', () => {
}));

it('focusVia program should simulate programmatic focus', fakeAsync(() => {
focusOriginMonitor.focusVia(buttonElement, 'program');
focusMonitor.focusVia(buttonElement, 'program');
fixture.detectChanges();
tick();

Expand All @@ -175,7 +175,7 @@ describe('FocusOriginMonitor', () => {

// Call `blur` directly because invoking `buttonElement.blur()` does not always trigger the
// handler on IE11 on SauceLabs.
focusOriginMonitor._onBlur({} as any, buttonElement);
focusMonitor._onBlur({} as any, buttonElement);
fixture.detectChanges();

expect(buttonElement.classList.length)
Expand All @@ -191,7 +191,7 @@ describe('FocusOriginMonitor', () => {
expect(buttonElement.classList.length)
.toBe(2, 'button should have exactly 2 focus classes');

focusOriginMonitor.stopMonitoring(buttonElement);
focusMonitor.stopMonitoring(buttonElement);
fixture.detectChanges();

expect(buttonElement.classList.length).toBe(0, 'button should not have any focus classes');
Expand All @@ -202,7 +202,7 @@ describe('FocusOriginMonitor', () => {
describe('cdkMonitorFocus', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [StyleModule],
imports: [A11yModule],
declarations: [
ButtonWithFocusClasses,
ComplexComponentWithMonitorElementFocus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import {
Renderer2,
SkipSelf,
} from '@angular/core';
import {Platform} from '@angular/cdk/platform';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
import {Subscription} from 'rxjs/Subscription';
import {Platform} from '../platform/platform';
import {of as observableOf} from 'rxjs/observable/of';


Expand All @@ -43,11 +43,11 @@ type MonitoredElementInfo = {

/** Monitors mouse and keyboard events to determine the cause of focus events. */
@Injectable()
export class FocusOriginMonitor {
export class FocusMonitor {
/** The focus origin that the next focus event is a result of. */
private _origin: FocusOrigin = null;

/** The FocusOrigin of the last focus event tracked by the FocusOriginMonitor. */
/** The FocusOrigin of the last focus event tracked by the FocusMonitor. */
private _lastFocusOrigin: FocusOrigin;

/** Whether the window has just been focused. */
Expand Down Expand Up @@ -320,30 +320,30 @@ export class CdkMonitorFocus implements OnDestroy {
private _monitorSubscription: Subscription;
@Output() cdkFocusChange = new EventEmitter<FocusOrigin>();

constructor(private _elementRef: ElementRef, private _focusOriginMonitor: FocusOriginMonitor,
constructor(private _elementRef: ElementRef, private _focusMonitor: FocusMonitor,
renderer: Renderer2) {
this._monitorSubscription = this._focusOriginMonitor.monitor(
this._monitorSubscription = this._focusMonitor.monitor(
this._elementRef.nativeElement, renderer,
this._elementRef.nativeElement.hasAttribute('cdkMonitorSubtreeFocus'))
.subscribe(origin => this.cdkFocusChange.emit(origin));
}

ngOnDestroy() {
this._focusOriginMonitor.stopMonitoring(this._elementRef.nativeElement);
this._focusMonitor.stopMonitoring(this._elementRef.nativeElement);
this._monitorSubscription.unsubscribe();
}
}

/** @docs-private */
export function FOCUS_ORIGIN_MONITOR_PROVIDER_FACTORY(
parentDispatcher: FocusOriginMonitor, ngZone: NgZone, platform: Platform) {
return parentDispatcher || new FocusOriginMonitor(ngZone, platform);
export function FOCUS_MONITOR_PROVIDER_FACTORY(
parentDispatcher: FocusMonitor, ngZone: NgZone, platform: Platform) {
return parentDispatcher || new FocusMonitor(ngZone, platform);
}

/** @docs-private */
export const FOCUS_ORIGIN_MONITOR_PROVIDER = {
// If there is already a FocusOriginMonitor available, use that. Otherwise, provide a new one.
provide: FocusOriginMonitor,
deps: [[new Optional(), new SkipSelf(), FocusOriginMonitor], NgZone, Platform],
useFactory: FOCUS_ORIGIN_MONITOR_PROVIDER_FACTORY
export const FOCUS_MONITOR_PROVIDER = {
// If there is already a FocusMonitor available, use that. Otherwise, provide a new one.
provide: FocusMonitor,
deps: [[new Optional(), new SkipSelf(), FocusMonitor], NgZone, Platform],
useFactory: FOCUS_MONITOR_PROVIDER_FACTORY
};
9 changes: 6 additions & 3 deletions src/cdk/a11y/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ import {InteractivityChecker} from './interactivity-checker';
import {CommonModule} from '@angular/common';
import {PlatformModule} from '@angular/cdk/platform';
import {AriaDescriber, ARIA_DESCRIBER_PROVIDER} from './aria-describer';
import {CdkMonitorFocus, FOCUS_MONITOR_PROVIDER} from './focus-monitor';

@NgModule({
imports: [CommonModule, PlatformModule],
declarations: [FocusTrapDirective, FocusTrapDeprecatedDirective],
exports: [FocusTrapDirective, FocusTrapDeprecatedDirective],
declarations: [FocusTrapDirective, FocusTrapDeprecatedDirective, CdkMonitorFocus],
exports: [FocusTrapDirective, FocusTrapDeprecatedDirective, CdkMonitorFocus],
providers: [
InteractivityChecker,
FocusTrapFactory,
AriaDescriber,
LIVE_ANNOUNCER_PROVIDER,
ARIA_DESCRIBER_PROVIDER
ARIA_DESCRIBER_PROVIDER,
FOCUS_MONITOR_PROVIDER,
]
})
export class A11yModule {}
Expand All @@ -36,3 +38,4 @@ export * from './focus-trap';
export * from './interactivity-checker';
export * from './list-key-manager';
export * from './live-announcer';
export * from './focus-monitor';
2 changes: 1 addition & 1 deletion src/demo-app/demo-app/demo-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class DemoApp {
{name: 'Toolbar', route: '/toolbar'},
{name: 'Tooltip', route: '/tooltip'},
{name: 'Platform', route: '/platform'},
{name: 'Style', route: '/style'},
{name: 'Focus Origin', route: '/focus-origin'},
{name: 'Typography', route: '/typography'}
];

Expand Down
4 changes: 2 additions & 2 deletions src/demo-app/demo-app/demo-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {FoggyTabContent, RainyTabContent, SunnyTabContent, TabsDemo} from '../ta
import {PlatformDemo} from '../platform/platform-demo';
import {AutocompleteDemo} from '../autocomplete/autocomplete-demo';
import {InputDemo} from '../input/input-demo';
import {StyleDemo} from '../style/style-demo';
import {FocusOriginDemo} from '../focus-origin/focus-origin-demo';
import {TableDemo} from '../table/table-demo';
import {PeopleDatabase} from '../table/people-database';
import {DatepickerDemo} from '../datepicker/datepicker-demo';
Expand Down Expand Up @@ -94,7 +94,7 @@ import {TableHeaderDemo} from '../table/table-header-demo';
SlideToggleDemo,
SpagettiPanel,
StepperDemo,
StyleDemo,
FocusOriginDemo,
TableHeaderDemo,
ToolbarDemo,
TooltipDemo,
Expand Down
4 changes: 2 additions & 2 deletions src/demo-app/demo-app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {TABS_DEMO_ROUTES} from '../tabs/routes';
import {PlatformDemo} from '../platform/platform-demo';
import {AutocompleteDemo} from '../autocomplete/autocomplete-demo';
import {InputDemo} from '../input/input-demo';
import {StyleDemo} from '../style/style-demo';
import {FocusOriginDemo} from '../focus-origin/focus-origin-demo';
import {DatepickerDemo} from '../datepicker/datepicker-demo';
import {TableDemo} from '../table/table-demo';
import {TypographyDemo} from '../typography/typography-demo';
Expand Down Expand Up @@ -76,7 +76,7 @@ export const DEMO_APP_ROUTES: Routes = [
{path: 'tooltip', component: TooltipDemo},
{path: 'snack-bar', component: SnackBarDemo},
{path: 'platform', component: PlatformDemo},
{path: 'style', component: StyleDemo},
{path: 'focus-origin', component: FocusOriginDemo},
{path: 'typography', component: TypographyDemo},
{path: 'expansion', component: ExpansionDemo},
{path: 'stepper', component: StepperDemo}
Expand Down
2 changes: 0 additions & 2 deletions src/demo-app/demo-material-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
MdTabsModule,
MdToolbarModule,
MdTooltipModule,
StyleModule,
MdStepperModule,
} from '@angular/material';
import {CdkTableModule} from '@angular/cdk/table';
Expand Down Expand Up @@ -80,7 +79,6 @@ import {PortalModule} from '@angular/cdk/portal';
MdTooltipModule,
MdNativeDateModule,
CdkTableModule,
StyleModule,
A11yModule,
BidiModule,
ObserversModule,
Expand Down
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions src/demo-app/focus-origin/focus-origin-demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {Component} from '@angular/core';
import {FocusMonitor} from '@angular/cdk/a11y';


@Component({
moduleId: module.id,
selector: 'focus-origin-demo',
templateUrl: 'focus-origin-demo.html',
styleUrls: ['focus-origin-demo.css'],
})
export class FocusOriginDemo {
constructor(public fom: FocusMonitor) {}
}
13 changes: 0 additions & 13 deletions src/demo-app/style/style-demo.ts

This file was deleted.

7 changes: 4 additions & 3 deletions src/lib/button-toggle/button-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import {
} from '@angular/core';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {UniqueSelectionDispatcher, FocusOriginMonitor} from '../core';
import {FocusMonitor} from '@angular/cdk/a11y';
import {UniqueSelectionDispatcher} from '../core';
import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled';

/** Acceptable types for a button toggle. */
Expand Down Expand Up @@ -371,7 +372,7 @@ export class MdButtonToggle implements OnInit, OnDestroy {
private _buttonToggleDispatcher: UniqueSelectionDispatcher,
private _renderer: Renderer2,
private _elementRef: ElementRef,
private _focusOriginMonitor: FocusOriginMonitor) {
private _focusMonitor: FocusMonitor) {

this.buttonToggleGroup = toggleGroup;
this.buttonToggleGroupMultiple = toggleGroupMultiple;
Expand Down Expand Up @@ -404,7 +405,7 @@ export class MdButtonToggle implements OnInit, OnDestroy {
if (this.buttonToggleGroup && this._value == this.buttonToggleGroup.value) {
this._checked = true;
}
this._focusOriginMonitor.monitor(this._elementRef.nativeElement, this._renderer, true);
this._focusMonitor.monitor(this._elementRef.nativeElement, this._renderer, true);
}

/** Focuses the button. */
Expand Down
9 changes: 3 additions & 6 deletions src/lib/button-toggle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@
*/

import {NgModule} from '@angular/core';
import {A11yModule} from '@angular/cdk/a11y';
import {MdButtonToggleGroup, MdButtonToggleGroupMultiple, MdButtonToggle} from './button-toggle';
import {
UNIQUE_SELECTION_DISPATCHER_PROVIDER,
MdCommonModule,
StyleModule,
} from '../core';
import {UNIQUE_SELECTION_DISPATCHER_PROVIDER, MdCommonModule} from '../core';


@NgModule({
imports: [MdCommonModule, StyleModule],
imports: [MdCommonModule, A11yModule],
exports: [
MdButtonToggleGroup,
MdButtonToggleGroupMultiple,
Expand Down
12 changes: 6 additions & 6 deletions src/lib/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
Inject,
} from '@angular/core';
import {Platform} from '@angular/cdk/platform';
import {FocusOriginMonitor} from '../core';
import {FocusMonitor} from '@angular/cdk/a11y';
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
import {CanColor, mixinColor} from '../core/common-behaviors/color';
import {CanDisableRipple, mixinDisableRipple} from '../core/common-behaviors/disable-ripple';
Expand Down Expand Up @@ -137,13 +137,13 @@ export class MdButton extends _MdButtonMixinBase
constructor(renderer: Renderer2,
elementRef: ElementRef,
private _platform: Platform,
private _focusOriginMonitor: FocusOriginMonitor) {
private _focusMonitor: FocusMonitor) {
super(renderer, elementRef);
this._focusOriginMonitor.monitor(this._elementRef.nativeElement, this._renderer, true);
this._focusMonitor.monitor(this._elementRef.nativeElement, this._renderer, true);
}

ngOnDestroy() {
this._focusOriginMonitor.stopMonitoring(this._elementRef.nativeElement);
this._focusMonitor.stopMonitoring(this._elementRef.nativeElement);
}

/** Focuses the button. */
Expand Down Expand Up @@ -201,10 +201,10 @@ export class MdButton extends _MdButtonMixinBase
export class MdAnchor extends MdButton {
constructor(
platform: Platform,
focusOriginMonitor: FocusOriginMonitor,
focusMonitor: FocusMonitor,
elementRef: ElementRef,
renderer: Renderer2) {
super(renderer, elementRef, platform, focusOriginMonitor);
super(renderer, elementRef, platform, focusMonitor);
}

_haltDisabledEvents(event: Event) {
Expand Down
Loading

0 comments on commit 9375a4f

Please sign in to comment.