Skip to content

Commit 22a9862

Browse files
committed
refactor to use existing Platform class
1 parent 04b1461 commit 22a9862

19 files changed

+111
-85
lines changed

src/lib/button-toggle/index.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import {NgModule, ModuleWithProviders} from '@angular/core';
22
import {FormsModule} from '@angular/forms';
33
import {MdButtonToggleGroup, MdButtonToggleGroupMultiple, MdButtonToggle} from './button-toggle';
4-
import {
5-
UNIQUE_SELECTION_DISPATCHER_PROVIDER,
6-
CompatibilityModule,
7-
FocusOriginMonitor,
8-
} from '../core';
4+
import {UNIQUE_SELECTION_DISPATCHER_PROVIDER, CompatibilityModule, StyleModule} from '../core';
95

106

117
@NgModule({
12-
imports: [FormsModule, CompatibilityModule],
8+
imports: [FormsModule, CompatibilityModule, StyleModule],
139
exports: [
1410
MdButtonToggleGroup,
1511
MdButtonToggleGroupMultiple,
1612
MdButtonToggle,
1713
CompatibilityModule,
1814
],
1915
declarations: [MdButtonToggleGroup, MdButtonToggleGroupMultiple, MdButtonToggle],
20-
providers: [UNIQUE_SELECTION_DISPATCHER_PROVIDER, FocusOriginMonitor]
16+
providers: [UNIQUE_SELECTION_DISPATCHER_PROVIDER]
2117
})
2218
export class MdButtonToggleModule {
2319
/** @deprecated */

src/lib/button/button.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ import {
99
Renderer,
1010
ViewEncapsulation
1111
} from '@angular/core';
12-
import {coerceBooleanProperty, FocusOriginMonitor} from '../core';
12+
import {coerceBooleanProperty, FocusOriginMonitor, Platform} from '../core';
1313
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
14-
import {isBrowser} from '../core/platform/browser';
1514

1615

1716
// TODO(kara): Convert attribute selectors to classes when attr maps become available
@@ -111,8 +110,11 @@ export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisabl
111110
get disableRipple() { return this._disableRipple; }
112111
set disableRipple(v) { this._disableRipple = coerceBooleanProperty(v); }
113112

114-
constructor(private _elementRef: ElementRef, private _renderer: Renderer,
115-
private _focusOriginMonitor: FocusOriginMonitor) {
113+
constructor(
114+
private _elementRef: ElementRef,
115+
private _renderer: Renderer,
116+
private _platform: Platform,
117+
private _focusOriginMonitor: FocusOriginMonitor) {
116118
super();
117119
this._focusOriginMonitor.monitor(this._elementRef.nativeElement, this._renderer, true);
118120
}
@@ -159,7 +161,7 @@ export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisabl
159161
// If not on the browser, say that there are none of the attributes present.
160162
// Since these only affect how the ripple displays (and ripples only happen on the client),
161163
// detecting these attributes isn't necessary when not on the browser.
162-
if (!isBrowser()) {
164+
if (!this._platform.isBrowser) {
163165
return false;
164166
}
165167

@@ -189,8 +191,12 @@ export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisabl
189191
encapsulation: ViewEncapsulation.None
190192
})
191193
export class MdAnchor extends MdButton {
192-
constructor(elementRef: ElementRef, renderer: Renderer, focusOriginMonitor: FocusOriginMonitor) {
193-
super(elementRef, renderer, focusOriginMonitor);
194+
constructor(
195+
elementRef: ElementRef,
196+
renderer: Renderer,
197+
platform: Platform,
198+
focusOriginMonitor: FocusOriginMonitor) {
199+
super(elementRef, renderer, platform, focusOriginMonitor);
194200
}
195201

196202
/** @docs-private */

src/lib/core/a11y/live-announcer.spec.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {inject, fakeAsync, tick, ComponentFixture, TestBed} from '@angular/core/
22
import {Component} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {LiveAnnouncer, LIVE_ANNOUNCER_ELEMENT_TOKEN} from './live-announcer';
5+
import {A11yModule} from '../index';
56

67

78
describe('LiveAnnouncer', () => {
@@ -11,8 +12,8 @@ describe('LiveAnnouncer', () => {
1112

1213
describe('with default element', () => {
1314
beforeEach(() => TestBed.configureTestingModule({
15+
imports: [A11yModule],
1416
declarations: [TestApp],
15-
providers: [LiveAnnouncer]
1617
}));
1718

1819
beforeEach(fakeAsync(inject([LiveAnnouncer], (la: LiveAnnouncer) => {
@@ -77,11 +78,9 @@ describe('LiveAnnouncer', () => {
7778
customLiveElement = document.createElement('div');
7879

7980
return TestBed.configureTestingModule({
81+
imports: [A11yModule],
8082
declarations: [TestApp],
81-
providers: [
82-
{provide: LIVE_ANNOUNCER_ELEMENT_TOKEN, useValue: customLiveElement},
83-
LiveAnnouncer,
84-
],
83+
providers: [{provide: LIVE_ANNOUNCER_ELEMENT_TOKEN, useValue: customLiveElement}],
8584
});
8685
});
8786

src/lib/core/a11y/live-announcer.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
Inject,
66
SkipSelf,
77
} from '@angular/core';
8+
import {Platform} from '../platform/platform';
9+
810

911
export const LIVE_ANNOUNCER_ELEMENT_TOKEN = new OpaqueToken('liveAnnouncerElement');
1012

@@ -16,12 +18,16 @@ export class LiveAnnouncer {
1618

1719
private _liveElement: Element;
1820

19-
constructor(@Optional() @Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN) elementToken: any) {
20-
21-
// We inject the live element as `any` because the constructor signature cannot reference
22-
// browser globals (HTMLElement) on non-browser environments, since having a class decorator
23-
// causes TypeScript to preserve the constructor signature types.
24-
this._liveElement = elementToken || this._createLiveElement();
21+
constructor(
22+
@Optional() @Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN) elementToken: any,
23+
platform: Platform) {
24+
// Only do anything if we're on the browser platform.
25+
if (platform.isBrowser) {
26+
// We inject the live element as `any` because the constructor signature cannot reference
27+
// browser globals (HTMLElement) on non-browser environments, since having a class decorator
28+
// causes TypeScript to preserve the constructor signature types.
29+
this._liveElement = elementToken || this._createLiveElement();
30+
}
2531
}
2632

2733
/**
@@ -64,16 +70,18 @@ export class LiveAnnouncer {
6470

6571
}
6672

67-
export function LIVE_ANNOUNCER_PROVIDER_FACTORY(parentDispatcher: LiveAnnouncer, liveElement: any) {
68-
return parentDispatcher || new LiveAnnouncer(liveElement);
73+
export function LIVE_ANNOUNCER_PROVIDER_FACTORY(
74+
parentDispatcher: LiveAnnouncer, liveElement: any, platform: Platform) {
75+
return parentDispatcher || new LiveAnnouncer(liveElement, platform);
6976
}
7077

7178
export const LIVE_ANNOUNCER_PROVIDER = {
7279
// If there is already a LiveAnnouncer available, use that. Otherwise, provide a new one.
7380
provide: LiveAnnouncer,
7481
deps: [
7582
[new Optional(), new SkipSelf(), LiveAnnouncer],
76-
[new Optional(), new Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN)]
83+
[new Optional(), new Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN)],
84+
Platform,
7785
],
7886
useFactory: LIVE_ANNOUNCER_PROVIDER_FACTORY
7987
};

src/lib/core/overlay/overlay-directives.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {Scrollable} from './scroll/scrollable';
2727
import {coerceBooleanProperty} from '../coercion/boolean-property';
2828
import {ESCAPE} from '../keyboard/keycodes';
2929
import {Subscription} from 'rxjs/Subscription';
30+
import {ScrollDispatchModule} from './scroll/scroll-dispatcher';
3031

3132

3233
/** Default set of positions for the overlay. Follows the behavior of a dropdown. */
@@ -316,9 +317,9 @@ export class ConnectedOverlayDirective implements OnDestroy {
316317

317318

318319
@NgModule({
319-
imports: [PortalModule],
320-
exports: [ConnectedOverlayDirective, OverlayOrigin, Scrollable],
321-
declarations: [ConnectedOverlayDirective, OverlayOrigin, Scrollable],
320+
imports: [PortalModule, ScrollDispatchModule],
321+
exports: [ConnectedOverlayDirective, OverlayOrigin, ScrollDispatchModule],
322+
declarations: [ConnectedOverlayDirective, OverlayOrigin],
322323
providers: [OVERLAY_PROVIDERS],
323324
})
324325
export class OverlayModule {

src/lib/core/overlay/overlay.ts

-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {OverlayRef} from './overlay-ref';
1212
import {OverlayPositionBuilder} from './position/overlay-position-builder';
1313
import {VIEWPORT_RULER_PROVIDER} from './position/viewport-ruler';
1414
import {OverlayContainer, OVERLAY_CONTAINER_PROVIDER} from './overlay-container';
15-
import {SCROLL_DISPATCHER_PROVIDER} from './scroll/scroll-dispatcher';
1615

1716

1817
/** Next overlay unique ID. */
@@ -94,6 +93,5 @@ export const OVERLAY_PROVIDERS: Provider[] = [
9493
Overlay,
9594
OverlayPositionBuilder,
9695
VIEWPORT_RULER_PROVIDER,
97-
SCROLL_DISPATCHER_PROVIDER,
9896
OVERLAY_CONTAINER_PROVIDER,
9997
];

src/lib/core/overlay/position/connected-position-strategy.spec.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {Scrollable} from '../scroll/scrollable';
77
import {Subscription} from 'rxjs/Subscription';
88
import {TestBed, inject} from '@angular/core/testing';
99
import Spy = jasmine.Spy;
10-
import {SCROLL_DISPATCHER_PROVIDER} from '../scroll/scroll-dispatcher';
10+
import {ScrollDispatchModule} from '../scroll/scroll-dispatcher';
1111

1212

1313
// Default width and height of the overlay and origin panels throughout these tests.
@@ -23,7 +23,8 @@ describe('ConnectedPositionStrategy', () => {
2323
let viewportRuler: ViewportRuler;
2424

2525
beforeEach(() => TestBed.configureTestingModule({
26-
providers: [VIEWPORT_RULER_PROVIDER, SCROLL_DISPATCHER_PROVIDER]
26+
imports: [ScrollDispatchModule],
27+
providers: [VIEWPORT_RULER_PROVIDER]
2728
}));
2829

2930
beforeEach(inject([ViewportRuler], (_ruler: ViewportRuler) => {

src/lib/core/overlay/position/viewport-ruler.spec.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {ViewportRuler, VIEWPORT_RULER_PROVIDER} from './viewport-ruler';
22
import {TestBed, inject} from '@angular/core/testing';
3-
import {SCROLL_DISPATCHER_PROVIDER} from '../scroll/scroll-dispatcher';
3+
import {ScrollDispatchModule} from '../scroll/scroll-dispatcher';
4+
45

56
// For all tests, we assume the browser window is 1024x786 (outerWidth x outerHeight).
67
// The karma config has been set to this for local tests, and it is the default size
@@ -22,7 +23,8 @@ describe('ViewportRuler', () => {
2223
veryLargeElement.style.height = '6000px';
2324

2425
beforeEach(() => TestBed.configureTestingModule({
25-
providers: [VIEWPORT_RULER_PROVIDER, SCROLL_DISPATCHER_PROVIDER]
26+
imports: [ScrollDispatchModule],
27+
providers: [VIEWPORT_RULER_PROVIDER]
2628
}));
2729

2830
beforeEach(inject([ViewportRuler], (viewportRuler: ViewportRuler) => {

src/lib/core/overlay/scroll/scroll-dispatcher.ts

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {ElementRef, Injectable, NgZone, Optional, SkipSelf} from '@angular/core';
2-
import {isBrowser} from '../../platform/browser';
1+
import {NgModule, ElementRef, Injectable, NgZone, Optional, SkipSelf} from '@angular/core';
2+
import {Platform, PlatformModule} from '../../platform/index';
33
import {Scrollable} from './scrollable';
44
import {Subject} from 'rxjs/Subject';
55
import {Observable} from 'rxjs/Observable';
@@ -18,7 +18,7 @@ export const DEFAULT_SCROLL_TIME = 20;
1818
*/
1919
@Injectable()
2020
export class ScrollDispatcher {
21-
constructor(private _ngZone: NgZone) { }
21+
constructor(private _ngZone: NgZone, private _platform: Platform) { }
2222

2323
/** Subject for notifying that a registered scrollable reference element has been scrolled. */
2424
_scrolled: Subject<void> = new Subject<void>();
@@ -63,7 +63,8 @@ export class ScrollDispatcher {
6363
* to override the default "throttle" time.
6464
*/
6565
scrolled(auditTimeInMs: number = DEFAULT_SCROLL_TIME, callback: () => any): Subscription {
66-
if (!isBrowser()) {
66+
// Scroll events can only happen on the browser, so do nothing if we're not on the browser.
67+
if (!this._platform.isBrowser) {
6768
return Subscription.EMPTY;
6869
}
6970

@@ -131,14 +132,23 @@ export class ScrollDispatcher {
131132
}
132133
}
133134

134-
export function SCROLL_DISPATCHER_PROVIDER_FACTORY(parentDispatcher: ScrollDispatcher,
135-
ngZone: NgZone) {
136-
return parentDispatcher || new ScrollDispatcher(ngZone);
135+
export function SCROLL_DISPATCHER_PROVIDER_FACTORY(
136+
parentDispatcher: ScrollDispatcher, ngZone: NgZone, platform: Platform) {
137+
return parentDispatcher || new ScrollDispatcher(ngZone, platform);
137138
}
138139

139140
export const SCROLL_DISPATCHER_PROVIDER = {
140141
// If there is already a ScrollDispatcher available, use that. Otherwise, provide a new one.
141142
provide: ScrollDispatcher,
142-
deps: [[new Optional(), new SkipSelf(), ScrollDispatcher], NgZone],
143+
deps: [[new Optional(), new SkipSelf(), ScrollDispatcher], NgZone, Platform],
143144
useFactory: SCROLL_DISPATCHER_PROVIDER_FACTORY
144145
};
146+
147+
148+
@NgModule({
149+
imports: [PlatformModule],
150+
exports: [Scrollable],
151+
declarations: [Scrollable],
152+
providers: [SCROLL_DISPATCHER_PROVIDER],
153+
})
154+
export class ScrollDispatchModule { }

src/lib/core/platform/browser.ts

-4
This file was deleted.

src/lib/core/platform/platform.ts

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const hasV8BreakIterator = typeof(window) !== 'undefined' ?
1515
*/
1616
@Injectable()
1717
export class Platform {
18+
isBrowser: boolean = typeof document === 'object' && !!document;
19+
1820
/** Layout Engines */
1921
EDGE = /(edge)/i.test(navigator.userAgent);
2022
TRIDENT = /(msie|trident)/i.test(navigator.userAgent);

src/lib/core/ripple/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ import {ModuleWithProviders, NgModule} from '@angular/core';
22
import {MdRipple} from './ripple';
33
import {CompatibilityModule} from '../compatibility/compatibility';
44
import {VIEWPORT_RULER_PROVIDER} from '../overlay/position/viewport-ruler';
5-
import {SCROLL_DISPATCHER_PROVIDER} from '../overlay/scroll/scroll-dispatcher';
5+
import {ScrollDispatchModule} from '../overlay/scroll/scroll-dispatcher';
6+
import {PlatformModule} from '../platform/index';
67

78
export {MdRipple, RippleGlobalOptions, MD_RIPPLE_GLOBAL_OPTIONS} from './ripple';
89
export {RippleRef, RippleState} from './ripple-ref';
910
export {RippleConfig, RIPPLE_FADE_IN_DURATION, RIPPLE_FADE_OUT_DURATION} from './ripple-renderer';
1011

1112
@NgModule({
12-
imports: [CompatibilityModule],
13+
imports: [CompatibilityModule, PlatformModule, ScrollDispatchModule],
1314
exports: [MdRipple, CompatibilityModule],
1415
declarations: [MdRipple],
15-
providers: [VIEWPORT_RULER_PROVIDER, SCROLL_DISPATCHER_PROVIDER],
16+
providers: [VIEWPORT_RULER_PROVIDER],
1617
})
1718
export class MdRippleModule {
1819
/** @deprecated */

src/lib/core/ripple/ripple-renderer.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {ElementRef, NgZone} from '@angular/core';
2-
import {isBrowser} from '../platform/browser';
2+
import {Platform} from '../platform/platform';
33
import {ViewportRuler} from '../overlay/position/viewport-ruler';
44
import {RippleRef, RippleState} from './ripple-ref';
55

@@ -48,10 +48,14 @@ export class RippleRenderer {
4848
/** Whether mouse ripples should be created or not. */
4949
rippleDisabled: boolean = false;
5050

51-
constructor(_elementRef: ElementRef, private _ngZone: NgZone, private _ruler: ViewportRuler) {
51+
constructor(
52+
elementRef: ElementRef,
53+
private _ngZone: NgZone,
54+
private _ruler: ViewportRuler,
55+
platform: Platform) {
5256
// Only do anything if we're on the browser.
53-
if (isBrowser()) {
54-
this._containerElement = _elementRef.nativeElement;
57+
if (platform.isBrowser) {
58+
this._containerElement = elementRef.nativeElement;
5559

5660
// Specify events which need to be registered on the trigger.
5761
this._triggerEvents.set('mousedown', this.onMousedown.bind(this));

src/lib/core/ripple/ripple.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import {
1111
Optional,
1212
} from '@angular/core';
1313
import {RippleConfig, RippleRenderer} from './ripple-renderer';
14-
import {ViewportRuler} from '../overlay/position/viewport-ruler';
1514
import {RippleRef} from './ripple-ref';
15+
import {ViewportRuler} from '../overlay/position/viewport-ruler';
16+
import {Platform} from '../platform/platform';
1617

1718
/** OpaqueToken that can be used to specify the global ripple options. */
1819
export const MD_RIPPLE_GLOBAL_OPTIONS = new OpaqueToken('md-ripple-global-options');
@@ -26,7 +27,7 @@ export type RippleGlobalOptions = {
2627
selector: '[md-ripple], [mat-ripple], [mdRipple], [matRipple]',
2728
exportAs: 'mdRipple',
2829
host: {
29-
'[class.mat-ripple]': 'true',
30+
'class': 'mat-ripple',
3031
'[class.mat-ripple-unbounded]': 'unbounded'
3132
}
3233
})
@@ -82,10 +83,10 @@ export class MdRipple implements OnChanges, OnDestroy {
8283
elementRef: ElementRef,
8384
ngZone: NgZone,
8485
ruler: ViewportRuler,
85-
// Type needs to be `any` because of https://github.com/angular/angular/issues/12631
86-
@Optional() @Inject(MD_RIPPLE_GLOBAL_OPTIONS) globalOptions: any
86+
platform: Platform,
87+
@Optional() @Inject(MD_RIPPLE_GLOBAL_OPTIONS) globalOptions: RippleConfig
8788
) {
88-
this._rippleRenderer = new RippleRenderer(elementRef, ngZone, ruler);
89+
this._rippleRenderer = new RippleRenderer(elementRef, ngZone, ruler, platform);
8990
this._globalOptions = globalOptions ? globalOptions : {};
9091
}
9192

0 commit comments

Comments
 (0)