From 5e6040d5ec56bbb29864e2dc4532058a213a4ac4 Mon Sep 17 00:00:00 2001 From: Elad Bezalel Date: Fri, 14 Apr 2017 22:35:00 -0700 Subject: [PATCH] feat(directionality): a provider to get the overall directionality - Looks at the `html` and `body` elements for `dir` attribute and sets the Directionality service value to it - Whenever someone would try to inject Directionality - if there's a Dir directive up the dom tree it would be provided fixes #3600 --- src/lib/autocomplete/autocomplete-trigger.ts | 4 +- src/lib/autocomplete/autocomplete.spec.ts | 6 +- src/lib/core/bidi/dir.ts | 49 +++++++++++++++ src/lib/core/bidi/directionality.ts | 60 ++++++++++++++++++ src/lib/core/bidi/index.ts | 7 +++ src/lib/core/core.ts | 8 +-- .../core/overlay/overlay-directives.spec.ts | 4 +- src/lib/core/overlay/overlay-directives.ts | 6 +- src/lib/core/overlay/overlay-state.ts | 4 +- src/lib/core/rtl/dir.ts | 62 ------------------- src/lib/grid-list/grid-list.ts | 4 +- src/lib/menu/menu-trigger.ts | 8 +-- src/lib/menu/menu.spec.ts | 6 +- src/lib/module.ts | 6 +- src/lib/select/select.spec.ts | 4 +- src/lib/select/select.ts | 5 +- src/lib/sidenav/sidenav.ts | 6 +- src/lib/slider/index.ts | 4 +- src/lib/slider/slider.spec.ts | 4 +- src/lib/slider/slider.ts | 5 +- src/lib/tabs/tab-body.spec.ts | 6 +- src/lib/tabs/tab-body.ts | 6 +- src/lib/tabs/tab-header.spec.ts | 8 +-- src/lib/tabs/tab-header.ts | 8 +-- src/lib/tabs/tab-nav-bar/tab-nav-bar.ts | 6 +- src/lib/tooltip/tooltip.spec.ts | 6 +- src/lib/tooltip/tooltip.ts | 7 ++- 27 files changed, 183 insertions(+), 126 deletions(-) create mode 100644 src/lib/core/bidi/dir.ts create mode 100644 src/lib/core/bidi/directionality.ts create mode 100644 src/lib/core/bidi/index.ts delete mode 100644 src/lib/core/rtl/dir.ts diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index 22dd34265699..71f9573909fb 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -17,7 +17,7 @@ import {ConnectedPositionStrategy} from '../core/overlay/position/connected-posi import {Observable} from 'rxjs/Observable'; import {MdOptionSelectionChange, MdOption} from '../core/option/option'; import {ENTER, UP_ARROW, DOWN_ARROW} from '../core/keyboard/keycodes'; -import {Dir} from '../core/rtl/dir'; +import {Directionality} from '../core/bidi/index'; import {Subscription} from 'rxjs/Subscription'; import {Subject} from 'rxjs/Subject'; import 'rxjs/add/observable/merge'; @@ -101,7 +101,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy { constructor(private _element: ElementRef, private _overlay: Overlay, private _viewContainerRef: ViewContainerRef, - @Optional() private _dir: Dir, private _zone: NgZone, + @Optional() private _dir: Directionality, private _zone: NgZone, @Optional() @Host() private _inputContainer: MdInputContainer) {} ngOnDestroy() { diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index f7ca92a28b8a..b304066a1218 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -5,7 +5,7 @@ import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {MdAutocompleteModule, MdAutocompleteTrigger} from './index'; import {OverlayContainer} from '../core/overlay/overlay-container'; import {MdInputModule} from '../input/index'; -import {Dir, LayoutDirection} from '../core/rtl/dir'; +import {Directionality, Direction} from '../core/bidi/index'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Subscription} from 'rxjs/Subscription'; import {ENTER, DOWN_ARROW, SPACE, UP_ARROW} from '../core/keyboard/keycodes'; @@ -22,7 +22,7 @@ import 'rxjs/add/operator/map'; describe('MdAutocomplete', () => { let overlayContainerElement: HTMLElement; - let dir: LayoutDirection; + let dir: Direction; beforeEach(async(() => { dir = 'ltr'; @@ -51,7 +51,7 @@ describe('MdAutocomplete', () => { return {getContainerElement: () => overlayContainerElement}; }}, - {provide: Dir, useFactory: () => { + {provide: Directionality, useFactory: () => { return {value: dir}; }}, {provide: ViewportRuler, useClass: FakeViewportRuler} diff --git a/src/lib/core/bidi/dir.ts b/src/lib/core/bidi/dir.ts new file mode 100644 index 000000000000..7d40c28d499b --- /dev/null +++ b/src/lib/core/bidi/dir.ts @@ -0,0 +1,49 @@ +import { + Directive, + HostBinding, + Output, + Input, + EventEmitter +} from '@angular/core'; + +import {Direction, Directionality} from './directionality'; + +/** + * Directive to listen for changes of direction of part of the DOM. + * + * Would provide itself in case a component looks for the Directionality service + */ +@Directive({ + selector: '[dir]', + // TODO(hansl): maybe `$implicit` isn't the best option here, but for now that's the best we got. + exportAs: '$implicit', + providers: [ + {provide: Directionality, useExisting: Dir} + ] +}) +export class Dir implements Directionality { + /** Layout direction of the element. */ + @Input('dir') _dir: Direction = 'ltr'; + + /** Event emitted when the direction changes. */ + @Output() change = new EventEmitter(); + + /** @docs-private */ + @HostBinding('attr.dir') + get dir(): Direction { + return this._dir; + } + + set dir(v: Direction) { + let old = this._dir; + this._dir = v; + if (old != this._dir) { + this.change.emit(); + } + } + + /** Current layout direction of the element. */ + get value(): Direction { return this.dir; } + set value(v: Direction) { this.dir = v; } +} + diff --git a/src/lib/core/bidi/directionality.ts b/src/lib/core/bidi/directionality.ts new file mode 100644 index 000000000000..0111925ac4b1 --- /dev/null +++ b/src/lib/core/bidi/directionality.ts @@ -0,0 +1,60 @@ +import { + EventEmitter, + Injectable, + ModuleWithProviders, + NgModule, + Optional, + SkipSelf +} from '@angular/core'; + +import {Dir} from './dir'; + +export type Direction = 'ltr' | 'rtl'; + +/** + * The directionality (LTR / RTL) context for the application (or a subtree of it). + * Exposes the current direction and a stream of direction changes. + */ +@Injectable() +export class Directionality { + value: Direction = 'ltr'; + change: EventEmitter = new EventEmitter(); + + constructor() { + if (document) { + // TODO: handle auto value - + // We still need to account for dir="auto". + // It looks like HTMLElemenet.dir is also "auto" when that's set to the attribute, + // but getComputedStyle return either "ltr" or "rtl". avoiding getComputedStyle for now + // though, we're already calling it for the theming check. + this.value = + (document.body.getAttribute('dir') || + document.documentElement.getAttribute('dir') || + 'ltr') as Direction; + } + } +} + +@NgModule({ + exports: [Dir], + declarations: [Dir], + providers: [Directionality] +}) +export class BidiModule { + /** @deprecated */ + static forRoot(): ModuleWithProviders { + return { + ngModule: BidiModule, + providers: [DIRECTIONALITY_PROVIDER] + }; + } +} + +export const DIRECTIONALITY_PROVIDER = { + // If there is already a Directionality available, use that. Otherwise, provide a new one. + provide: Directionality, + deps: [[new Optional(), new SkipSelf(), Directionality]], + useFactory: function (parentDirectionality) { + return parentDirectionality || new Directionality(); + } +}; diff --git a/src/lib/core/bidi/index.ts b/src/lib/core/bidi/index.ts new file mode 100644 index 000000000000..710b9a4f28d5 --- /dev/null +++ b/src/lib/core/bidi/index.ts @@ -0,0 +1,7 @@ +export { + Directionality, + BidiModule, + DIRECTIONALITY_PROVIDER, + Direction +} from './directionality'; +export {Dir} from './dir'; diff --git a/src/lib/core/core.ts b/src/lib/core/core.ts index 5f6ebe2731c2..9278e579c7d4 100644 --- a/src/lib/core/core.ts +++ b/src/lib/core/core.ts @@ -1,6 +1,6 @@ import {NgModule, ModuleWithProviders} from '@angular/core'; import {MdLineModule} from './line/line'; -import {RtlModule} from './rtl/dir'; +import {BidiModule} from './bidi/index'; import {ObserveContentModule} from './observe-content/observe-content'; import {MdOptionModule} from './option/option'; import {PortalModule} from './portal/portal-directives'; @@ -11,7 +11,7 @@ import {MdRippleModule} from './ripple/index'; // RTL -export {Dir, LayoutDirection, RtlModule} from './rtl/dir'; +export {Dir, Direction, Directionality, BidiModule} from './bidi/index'; // Mutation Observer export {ObserveContentModule, ObserveContent} from './observe-content/observe-content'; @@ -117,7 +117,7 @@ export {CompatibilityModule, NoConflictStyleCompatibilityMode} from './compatibi @NgModule({ imports: [ MdLineModule, - RtlModule, + BidiModule, MdRippleModule, ObserveContentModule, PortalModule, @@ -128,7 +128,7 @@ export {CompatibilityModule, NoConflictStyleCompatibilityMode} from './compatibi ], exports: [ MdLineModule, - RtlModule, + BidiModule, MdRippleModule, ObserveContentModule, PortalModule, diff --git a/src/lib/core/overlay/overlay-directives.spec.ts b/src/lib/core/overlay/overlay-directives.spec.ts index 3af7f42e7911..5bcaac109164 100644 --- a/src/lib/core/overlay/overlay-directives.spec.ts +++ b/src/lib/core/overlay/overlay-directives.spec.ts @@ -5,7 +5,7 @@ import {ConnectedOverlayDirective, OverlayModule} from './overlay-directives'; import {OverlayContainer} from './overlay-container'; import {ConnectedPositionStrategy} from './position/connected-position-strategy'; import {ConnectedOverlayPositionChange} from './position/connected-position'; -import {Dir} from '../rtl/dir'; +import {Directionality} from '../bidi/index'; describe('Overlay directives', () => { @@ -22,7 +22,7 @@ describe('Overlay directives', () => { overlayContainerElement = document.createElement('div'); return {getContainerElement: () => overlayContainerElement}; }}, - {provide: Dir, useFactory: () => { + {provide: Directionality, useFactory: () => { return dir = { value: 'ltr' }; }} ], diff --git a/src/lib/core/overlay/overlay-directives.ts b/src/lib/core/overlay/overlay-directives.ts index e643256c11cf..3c03a7689725 100644 --- a/src/lib/core/overlay/overlay-directives.ts +++ b/src/lib/core/overlay/overlay-directives.ts @@ -22,7 +22,7 @@ import { import {PortalModule} from '../portal/portal-directives'; import {ConnectedPositionStrategy} from './position/connected-position-strategy'; import {Subscription} from 'rxjs/Subscription'; -import {Dir, LayoutDirection} from '../rtl/dir'; +import {Directionality, Direction} from '../bidi/index'; import {Scrollable} from './scroll/scrollable'; import {coerceBooleanProperty} from '../coercion/boolean-property'; @@ -154,7 +154,7 @@ export class ConnectedOverlayDirective implements OnDestroy { private _overlay: Overlay, templateRef: TemplateRef, viewContainerRef: ViewContainerRef, - @Optional() private _dir: Dir) { + @Optional() private _dir: Directionality) { this._templatePortal = new TemplatePortal(templateRef, viewContainerRef); } @@ -164,7 +164,7 @@ export class ConnectedOverlayDirective implements OnDestroy { } /** The element's layout direction. */ - get dir(): LayoutDirection { + get dir(): Direction { return this._dir ? this._dir.value : 'ltr'; } diff --git a/src/lib/core/overlay/overlay-state.ts b/src/lib/core/overlay/overlay-state.ts index 09676cce9ede..055b87b4577c 100644 --- a/src/lib/core/overlay/overlay-state.ts +++ b/src/lib/core/overlay/overlay-state.ts @@ -1,5 +1,5 @@ import {PositionStrategy} from './position/position-strategy'; -import {LayoutDirection} from '../rtl/dir'; +import {Direction} from '../bidi/index'; /** @@ -29,7 +29,7 @@ export class OverlayState { minHeight: number | string; /** The direction of the text in the overlay panel. */ - direction: LayoutDirection = 'ltr'; + direction: Direction = 'ltr'; // TODO(jelbourn): configuration still to add // - focus trap diff --git a/src/lib/core/rtl/dir.ts b/src/lib/core/rtl/dir.ts deleted file mode 100644 index 05eaef60c2d2..000000000000 --- a/src/lib/core/rtl/dir.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { - NgModule, - ModuleWithProviders, - Directive, - HostBinding, - Output, - Input, - EventEmitter -} from '@angular/core'; - -export type LayoutDirection = 'ltr' | 'rtl'; - -/** - * Directive to listen for changes of direction of part of the DOM. - * - * Applications should use this directive instead of the native attribute so that Material - * components can listen on changes of direction. - */ -@Directive({ - selector: '[dir]', - // TODO(hansl): maybe `$implicit` isn't the best option here, but for now that's the best we got. - exportAs: '$implicit' -}) -export class Dir { - /** Layout direction of the element. */ - @Input('dir') _dir: LayoutDirection = 'ltr'; - - /** Event emitted when the direction changes. */ - @Output() dirChange = new EventEmitter(); - - /** @docs-private */ - @HostBinding('attr.dir') - get dir(): LayoutDirection { - return this._dir; - } - set dir(v: LayoutDirection) { - let old = this._dir; - this._dir = v; - if (old != this._dir) { - this.dirChange.emit(); - } - } - - /** Current layout direction of the element. */ - get value(): LayoutDirection { return this.dir; } - set value(v: LayoutDirection) { this.dir = v; } -} - - -@NgModule({ - exports: [Dir], - declarations: [Dir] -}) -export class RtlModule { - /** @deprecated */ - static forRoot(): ModuleWithProviders { - return { - ngModule: RtlModule, - providers: [] - }; - } -} diff --git a/src/lib/grid-list/grid-list.ts b/src/lib/grid-list/grid-list.ts index 8da4a76bceae..9d5ac4161ce1 100644 --- a/src/lib/grid-list/grid-list.ts +++ b/src/lib/grid-list/grid-list.ts @@ -14,7 +14,7 @@ import {MdGridTile} from './grid-tile'; import {TileCoordinator} from './tile-coordinator'; import {TileStyler, FitTileStyler, RatioTileStyler, FixedTileStyler} from './tile-styler'; import {MdGridListColsError} from './grid-list-errors'; -import {Dir} from '../core'; +import {Directionality} from '../core'; import { coerceToString, coerceToNumber, @@ -62,7 +62,7 @@ export class MdGridList implements OnInit, AfterContentChecked { constructor( private _renderer: Renderer, private _element: ElementRef, - @Optional() private _dir: Dir) {} + @Optional() private _dir: Directionality) {} /** Amount of columns in the grid list. */ @Input() diff --git a/src/lib/menu/menu-trigger.ts b/src/lib/menu/menu-trigger.ts index b611138e935e..40478db4359d 100644 --- a/src/lib/menu/menu-trigger.ts +++ b/src/lib/menu/menu-trigger.ts @@ -14,8 +14,8 @@ import {MdMenuPanel} from './menu-panel'; import {MdMenuMissingError} from './menu-errors'; import { isFakeMousedownFromScreenReader, - Dir, - LayoutDirection, + Directionality, + Direction, Overlay, OverlayState, OverlayRef, @@ -80,7 +80,7 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy { constructor(private _overlay: Overlay, private _element: ElementRef, private _viewContainerRef: ViewContainerRef, private _renderer: Renderer, - @Optional() private _dir: Dir) {} + @Optional() private _dir: Directionality) {} ngAfterViewInit() { this._checkMenu(); @@ -132,7 +132,7 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy { } /** The text direction of the containing app. */ - get dir(): LayoutDirection { + get dir(): Direction { return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr'; } diff --git a/src/lib/menu/menu.spec.ts b/src/lib/menu/menu.spec.ts index 849e84a8aa76..8b623e862959 100644 --- a/src/lib/menu/menu.spec.ts +++ b/src/lib/menu/menu.spec.ts @@ -19,12 +19,12 @@ import { } from './index'; import {OverlayContainer} from '../core/overlay/overlay-container'; import {ViewportRuler} from '../core/overlay/position/viewport-ruler'; -import {Dir, LayoutDirection} from '../core/rtl/dir'; +import {Directionality, Direction} from '../core/bidi/index'; import {extendObject} from '../core/util/object-extend'; describe('MdMenu', () => { let overlayContainerElement: HTMLElement; - let dir: LayoutDirection; + let dir: Direction; beforeEach(async(() => { dir = 'ltr'; @@ -44,7 +44,7 @@ describe('MdMenu', () => { document.body.style.margin = '0'; return {getContainerElement: () => overlayContainerElement}; }}, - {provide: Dir, useFactory: () => { + {provide: Directionality, useFactory: () => { return {value: dir}; }}, {provide: ViewportRuler, useClass: FakeViewportRuler} diff --git a/src/lib/module.ts b/src/lib/module.ts index 245574325ebe..9fe15b186cd5 100644 --- a/src/lib/module.ts +++ b/src/lib/module.ts @@ -2,7 +2,7 @@ import {NgModule, ModuleWithProviders} from '@angular/core'; import { MdRippleModule, - RtlModule, + BidiModule, ObserveContentModule, PortalModule, OverlayModule, @@ -63,7 +63,7 @@ const MATERIAL_MODULES = [ MdTooltipModule, OverlayModule, PortalModule, - RtlModule, + BidiModule, StyleModule, A11yModule, PlatformModule, @@ -90,7 +90,7 @@ const MATERIAL_MODULES = [ MdTabsModule.forRoot(), MdToolbarModule.forRoot(), PortalModule.forRoot(), - RtlModule.forRoot(), + BidiModule.forRoot(), ObserveContentModule.forRoot(), // These modules include providers. diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts index b53781ede656..5593b7b77202 100644 --- a/src/lib/select/select.spec.ts +++ b/src/lib/select/select.spec.ts @@ -15,7 +15,7 @@ import {OverlayContainer} from '../core/overlay/overlay-container'; import {MdSelect, MdSelectFloatPlaceholderType} from './select'; import {MdSelectDynamicMultipleError, MdSelectNonArrayValueError} from './select-errors'; import {MdOption} from '../core/option/option'; -import {Dir} from '../core/rtl/dir'; +import {Directionality} from '../core/bidi/index'; import { ControlValueAccessor, FormControl, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; @@ -64,7 +64,7 @@ describe('MdSelect', () => { return {getContainerElement: () => overlayContainerElement}; }}, - {provide: Dir, useFactory: () => { + {provide: Directionality, useFactory: () => { return dir = { value: 'ltr' }; }}, {provide: ViewportRuler, useClass: FakeViewportRuler} diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 55dd43557a05..fd8be0329eb0 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -20,7 +20,7 @@ import { import {MdOption, MdOptionSelectionChange} from '../core/option/option'; import {ENTER, SPACE} from '../core/keyboard/keycodes'; import {FocusKeyManager} from '../core/a11y/focus-key-manager'; -import {Dir} from '../core/rtl/dir'; +import {Directionality} from '../core/bidi/index'; import {Observable} from 'rxjs/Observable'; import {Subscription} from 'rxjs/Subscription'; import {transformPlaceholder, transformPanel, fadeInContent} from './select-animations'; @@ -303,7 +303,8 @@ export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlVal constructor(private _element: ElementRef, private _renderer: Renderer, private _viewportRuler: ViewportRuler, private _changeDetectorRef: ChangeDetectorRef, - @Optional() private _dir: Dir, @Self() @Optional() public _control: NgControl, + @Optional() private _dir: Directionality, + @Self() @Optional() public _control: NgControl, @Attribute('tabindex') tabIndex: string) { if (this._control) { this._control.valueAccessor = this; diff --git a/src/lib/sidenav/sidenav.ts b/src/lib/sidenav/sidenav.ts index 520b572c449f..8f6714e07c67 100644 --- a/src/lib/sidenav/sidenav.ts +++ b/src/lib/sidenav/sidenav.ts @@ -14,7 +14,7 @@ import { NgZone, OnDestroy, } from '@angular/core'; -import {Dir, MdError, coerceBooleanProperty} from '../core'; +import {Directionality, MdError, coerceBooleanProperty} from '../core'; import {FocusTrapFactory, FocusTrap} from '../core/a11y/focus-trap'; import {ESCAPE} from '../core/keyboard/keycodes'; import 'rxjs/add/operator/first'; @@ -349,12 +349,12 @@ export class MdSidenavContainer implements AfterContentInit { /** Whether to enable open/close trantions. */ _enableTransitions = false; - constructor(@Optional() private _dir: Dir, private _element: ElementRef, + constructor(@Optional() private _dir: Directionality, private _element: ElementRef, private _renderer: Renderer, private _ngZone: NgZone) { // If a `Dir` directive exists up the tree, listen direction changes and update the left/right // properties to point to the proper start/end. if (_dir != null) { - _dir.dirChange.subscribe(() => this._validateDrawers()); + _dir.change.subscribe(() => this._validateDrawers()); } } diff --git a/src/lib/slider/index.ts b/src/lib/slider/index.ts index 7fccc53ea96e..63611eca6f3c 100644 --- a/src/lib/slider/index.ts +++ b/src/lib/slider/index.ts @@ -4,11 +4,11 @@ import {CommonModule} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {CompatibilityModule, GestureConfig, StyleModule} from '../core'; import {MdSlider} from './slider'; -import {RtlModule} from '../core/rtl/dir'; +import {BidiModule} from '../core/bidi/index'; @NgModule({ - imports: [CommonModule, FormsModule, CompatibilityModule, StyleModule, RtlModule], + imports: [CommonModule, FormsModule, CompatibilityModule, StyleModule, BidiModule], exports: [MdSlider, CompatibilityModule], declarations: [MdSlider], providers: [{provide: HAMMER_GESTURE_CONFIG, useClass: GestureConfig}] diff --git a/src/lib/slider/slider.spec.ts b/src/lib/slider/slider.spec.ts index 4cb452fe5e37..232e34ebec01 100644 --- a/src/lib/slider/slider.spec.ts +++ b/src/lib/slider/slider.spec.ts @@ -4,7 +4,7 @@ import {Component, DebugElement} from '@angular/core'; import {By, HAMMER_GESTURE_CONFIG} from '@angular/platform-browser'; import {MdSlider, MdSliderModule} from './index'; import {TestGestureConfig} from './test-gesture-config'; -import {RtlModule} from '../core/rtl/dir'; +import {BidiModule} from '../core/bidi/index'; import { DOWN_ARROW, END, @@ -23,7 +23,7 @@ describe('MdSlider', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [MdSliderModule, ReactiveFormsModule, FormsModule, RtlModule], + imports: [MdSliderModule, ReactiveFormsModule, FormsModule, BidiModule], declarations: [ StandardSlider, DisabledSlider, diff --git a/src/lib/slider/slider.ts b/src/lib/slider/slider.ts index 32822f257ccd..ab995162d71a 100644 --- a/src/lib/slider/slider.ts +++ b/src/lib/slider/slider.ts @@ -12,7 +12,7 @@ import { } from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {coerceBooleanProperty, coerceNumberProperty, HammerInput} from '../core'; -import {Dir} from '../core/rtl/dir'; +import {Directionality} from '../core/bidi/index'; import { DOWN_ARROW, END, @@ -378,7 +378,8 @@ export class MdSlider implements ControlValueAccessor, OnDestroy { } constructor(renderer: Renderer, private _elementRef: ElementRef, - private _focusOriginMonitor: FocusOriginMonitor, @Optional() private _dir: Dir) { + private _focusOriginMonitor: FocusOriginMonitor, + @Optional() private _dir: Directionality) { this._focusOriginMonitor.monitor(this._elementRef.nativeElement, renderer, true) .subscribe((origin: FocusOrigin) => this._isActive = !!origin && origin !== 'keyboard'); this._renderer = new SliderRenderer(this._elementRef); diff --git a/src/lib/tabs/tab-body.spec.ts b/src/lib/tabs/tab-body.spec.ts index a205922ff0f1..08d4bed8ebd0 100644 --- a/src/lib/tabs/tab-body.spec.ts +++ b/src/lib/tabs/tab-body.spec.ts @@ -1,7 +1,7 @@ import {async, ComponentFixture, TestBed, flushMicrotasks, fakeAsync} from '@angular/core/testing'; import {Component, ViewChild, TemplateRef, ViewContainerRef} from '@angular/core'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {LayoutDirection, Dir} from '../core/rtl/dir'; +import {Direction, Directionality} from '../core/bidi/index'; import {TemplatePortal} from '../core/portal/portal'; import {MdTabBody} from './tab-body'; import {MdRippleModule} from '../core/ripple/index'; @@ -10,7 +10,7 @@ import {PortalModule} from '../core'; describe('MdTabBody', () => { - let dir: LayoutDirection = 'ltr'; + let dir: Direction = 'ltr'; beforeEach(async(() => { dir = 'ltr'; @@ -21,7 +21,7 @@ describe('MdTabBody', () => { SimpleTabBodyApp, ], providers: [ - { provide: Dir, useFactory: () => { return {value: dir}; } + { provide: Directionality, useFactory: () => { return {value: dir}; } }] }); diff --git a/src/lib/tabs/tab-body.ts b/src/lib/tabs/tab-body.ts index 09cb9084e2b5..9eccbcb5885f 100644 --- a/src/lib/tabs/tab-body.ts +++ b/src/lib/tabs/tab-body.ts @@ -19,7 +19,7 @@ import { transition, AnimationEvent, } from '@angular/animations'; -import {TemplatePortal, PortalHostDirective, Dir, LayoutDirection} from '../core'; +import {TemplatePortal, PortalHostDirective, Directionality, Direction} from '../core'; import 'rxjs/add/operator/map'; /** @@ -121,7 +121,7 @@ export class MdTabBody implements OnInit, AfterViewChecked, AfterContentChecked } constructor( - @Optional() private _dir: Dir, + @Optional() private _dir: Directionality, private _elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef) { } @@ -185,7 +185,7 @@ export class MdTabBody implements OnInit, AfterViewChecked, AfterContentChecked } /** The text direction of the containing app. */ - _getLayoutDirection(): LayoutDirection { + _getLayoutDirection(): Direction { return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr'; } diff --git a/src/lib/tabs/tab-header.spec.ts b/src/lib/tabs/tab-header.spec.ts index 89d931d4c108..9b19a5e92cc8 100644 --- a/src/lib/tabs/tab-header.spec.ts +++ b/src/lib/tabs/tab-header.spec.ts @@ -1,6 +1,6 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {Component, ViewChild, ViewContainerRef} from '@angular/core'; -import {LayoutDirection, Dir} from '../core/rtl/dir'; +import {Direction, Directionality} from '../core/bidi/index'; import {MdTabHeader} from './tab-header'; import {MdRippleModule} from '../core/ripple/index'; import {CommonModule} from '@angular/common'; @@ -15,7 +15,7 @@ import {Subject} from 'rxjs/Subject'; describe('MdTabHeader', () => { - let dir: LayoutDirection = 'ltr'; + let dir: Direction = 'ltr'; let dirChange = new Subject(); let fixture: ComponentFixture; let appComponent: SimpleTabHeaderApp; @@ -31,7 +31,7 @@ describe('MdTabHeader', () => { SimpleTabHeaderApp, ], providers: [ - {provide: Dir, useFactory: () => { + {provide: Directionality, useFactory: () => { return {value: dir, dirChange: dirChange.asObservable()}; }}, {provide: ViewportRuler, useClass: FakeViewportRuler}, @@ -245,7 +245,7 @@ class SimpleTabHeaderApp { focusedIndex: number; disabledTabIndex = 1; tabs: Tab[] = [{label: 'tab one'}, {label: 'tab one'}, {label: 'tab one'}, {label: 'tab one'}]; - dir: LayoutDirection = 'ltr'; + dir: Direction = 'ltr'; @ViewChild(MdTabHeader) mdTabHeader: MdTabHeader; diff --git a/src/lib/tabs/tab-header.ts b/src/lib/tabs/tab-header.ts index 3fee07a9f749..82e763eba8cf 100644 --- a/src/lib/tabs/tab-header.ts +++ b/src/lib/tabs/tab-header.ts @@ -13,7 +13,7 @@ import { AfterContentInit, OnDestroy, } from '@angular/core'; -import {RIGHT_ARROW, LEFT_ARROW, ENTER, Dir, LayoutDirection} from '../core'; +import {RIGHT_ARROW, LEFT_ARROW, ENTER, Directionality, Direction} from '../core'; import {MdTabLabelWrapper} from './tab-label-wrapper'; import {MdInkBar} from './ink-bar'; import {Subscription} from 'rxjs/Subscription'; @@ -106,7 +106,7 @@ export class MdTabHeader implements AfterContentChecked, AfterContentInit, OnDes /** Event emitted when a label is focused. */ @Output() indexFocused = new EventEmitter(); - constructor(private _elementRef: ElementRef, @Optional() private _dir: Dir) {} + constructor(private _elementRef: ElementRef, @Optional() private _dir: Directionality) {} ngAfterContentChecked(): void { // If the number of tab labels have changed, check if scrolling should be enabled @@ -153,7 +153,7 @@ export class MdTabHeader implements AfterContentChecked, AfterContentInit, OnDes this._alignInkBarToSelectedTab(); if (this._dir) { - this._directionChange = this._dir.dirChange.subscribe(() => this._alignInkBarToSelectedTab()); + this._directionChange = this._dir.change.subscribe(() => this._alignInkBarToSelectedTab()); } } @@ -257,7 +257,7 @@ export class MdTabHeader implements AfterContentChecked, AfterContentInit, OnDes } /** The layout direction of the containing app. */ - _getLayoutDirection(): LayoutDirection { + _getLayoutDirection(): Direction { return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr'; } diff --git a/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts b/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts index 6bc6d6dec836..b15f2c4d9781 100644 --- a/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts +++ b/src/lib/tabs/tab-nav-bar/tab-nav-bar.ts @@ -13,7 +13,7 @@ import { import {MdInkBar} from '../ink-bar'; import {MdRipple} from '../../core/ripple/index'; import {ViewportRuler} from '../../core/overlay/position/viewport-ruler'; -import {MD_RIPPLE_GLOBAL_OPTIONS, RippleGlobalOptions, Dir} from '../../core'; +import {MD_RIPPLE_GLOBAL_OPTIONS, RippleGlobalOptions, Directionality} from '../../core'; import {Subscription} from 'rxjs/Subscription'; /** @@ -37,9 +37,9 @@ export class MdTabNavBar implements OnDestroy { @ViewChild(MdInkBar) _inkBar: MdInkBar; - constructor(@Optional() private _dir: Dir) { + constructor(@Optional() private _dir: Directionality) { if (_dir) { - this._directionChange = _dir.dirChange.subscribe(() => this._alignInkBar()); + this._directionChange = _dir.change.subscribe(() => this._alignInkBar()); } } diff --git a/src/lib/tooltip/tooltip.spec.ts b/src/lib/tooltip/tooltip.spec.ts index a6c9699f3f7d..4cc786e6408a 100644 --- a/src/lib/tooltip/tooltip.spec.ts +++ b/src/lib/tooltip/tooltip.spec.ts @@ -17,7 +17,7 @@ import {By} from '@angular/platform-browser'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {TooltipPosition, MdTooltip, MdTooltipModule, SCROLL_THROTTLE_MS} from './index'; import {OverlayContainer} from '../core'; -import {Dir, LayoutDirection} from '../core/rtl/dir'; +import {Directionality, Direction} from '../core/bidi/index'; import {OverlayModule} from '../core/overlay/overlay-directives'; import {Platform} from '../core/platform/platform'; import {Scrollable} from '../core/overlay/scroll/scrollable'; @@ -28,7 +28,7 @@ const initialTooltipMessage = 'initial tooltip message'; describe('MdTooltip', () => { let overlayContainerElement: HTMLElement; - let dir: {value: LayoutDirection}; + let dir: {value: Direction}; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -41,7 +41,7 @@ describe('MdTooltip', () => { document.body.appendChild(overlayContainerElement); return {getContainerElement: () => overlayContainerElement}; }}, - {provide: Dir, useFactory: () => { + {provide: Directionality, useFactory: () => { return dir = { value: 'ltr' }; }} ] diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts index f0b258e19a7f..9aa3924413ba 100644 --- a/src/lib/tooltip/tooltip.ts +++ b/src/lib/tooltip/tooltip.ts @@ -30,7 +30,7 @@ import { import {MdTooltipInvalidPositionError} from './tooltip-errors'; import {Observable} from 'rxjs/Observable'; import {Subject} from 'rxjs/Subject'; -import {Dir} from '../core/rtl/dir'; +import {Directionality} from '../core/bidi/index'; import {Platform} from '../core/platform/index'; import 'rxjs/add/operator/first'; import {ScrollDispatcher} from '../core/overlay/scroll/scroll-dispatcher'; @@ -154,7 +154,7 @@ export class MdTooltip implements OnInit, OnDestroy { private _ngZone: NgZone, private _renderer: Renderer, private _platform: Platform, - @Optional() private _dir: Dir) { + @Optional() private _dir: Directionality) { // The mouse events shouldn't be bound on iOS devices, because // they can prevent the first tap from firing its click event. @@ -370,7 +370,8 @@ export class TooltipComponent { /** Subject for notifying that the tooltip has been hidden from the view */ private _onHide: Subject = new Subject(); - constructor(@Optional() private _dir: Dir, private _changeDetectorRef: ChangeDetectorRef) {} + constructor(@Optional() private _dir: Directionality, + private _changeDetectorRef: ChangeDetectorRef) {} /** * Shows the tooltip with an animation originating from the provided origin