From d94d17614c32533b6b7e6b4e4624d757350d68ee Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 7 Nov 2018 18:26:08 +0000 Subject: [PATCH] fix(bidi): preserve user dir attribute (#13859) Currently we normalize any values that aren't `ltr` or `rtl` to `ltr` in order to have a predictable value when using the directionality in components, however this ends up overwriting the consumer's value which might not necessarily be used by Angular (e.g. setting it to `auto`). These changes switch to preserving the attribute while normalizing the value for when it gets injected. Fixes #13855. --- src/cdk/bidi/dir.ts | 11 +++++++++-- src/cdk/bidi/directionality.spec.ts | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/cdk/bidi/dir.ts b/src/cdk/bidi/dir.ts index dbf24636137..ba76bb27af3 100644 --- a/src/cdk/bidi/dir.ts +++ b/src/cdk/bidi/dir.ts @@ -26,15 +26,19 @@ import {Direction, Directionality} from './directionality'; @Directive({ selector: '[dir]', providers: [{provide: Directionality, useExisting: Dir}], - host: {'[dir]': 'dir'}, + host: {'[attr.dir]': '_rawDir'}, exportAs: 'dir', }) export class Dir implements Directionality, AfterContentInit, OnDestroy { - _dir: Direction = 'ltr'; + /** Normalized direction that accounts for invalid/unsupported values. */ + private _dir: Direction = 'ltr'; /** Whether the `value` has been set to its initial value. */ private _isInitialized: boolean = false; + /** Direction as passed in by the consumer. */ + _rawDir: string; + /** Event emitted when the direction changes. */ @Output('dirChange') change = new EventEmitter(); @@ -43,7 +47,10 @@ export class Dir implements Directionality, AfterContentInit, OnDestroy { get dir(): Direction { return this._dir; } set dir(value: Direction) { const old = this._dir; + + this._rawDir = value; this._dir = (value === 'ltr' || value === 'rtl') ? value : 'ltr'; + if (old !== this._dir && this._isInitialized) { this.change.emit(this._dir); } diff --git a/src/cdk/bidi/directionality.spec.ts b/src/cdk/bidi/directionality.spec.ts index 89414a81859..da0c3dc8783 100644 --- a/src/cdk/bidi/directionality.spec.ts +++ b/src/cdk/bidi/directionality.spec.ts @@ -11,7 +11,7 @@ describe('Directionality', () => { TestBed.configureTestingModule({ imports: [BidiModule], - declarations: [ElementWithDir, InjectsDirectionality], + declarations: [ElementWithDir, ElementWithPredefinedAutoDir, InjectsDirectionality], providers: [{provide: DIR_DOCUMENT, useFactory: () => fakeDocument}], }).compileComponents(); })); @@ -123,6 +123,17 @@ describe('Directionality', () => { expect(fixture.componentInstance.dir.value).toBe('ltr'); }); + it('should preserve the consumer-provided `dir` attribute while ' + + 'normalizing the directive value', () => { + const fixture = TestBed.createComponent(ElementWithPredefinedAutoDir); + fixture.detectChanges(); + + const element = fixture.nativeElement.querySelector('div'); + + expect(element.getAttribute('dir')).toBe('auto'); + expect(fixture.componentInstance.dir.value).toBe('ltr'); + }); + }); }); @@ -140,6 +151,13 @@ class ElementWithDir { changeCount = 0; } +@Component({ + template: '
' +}) +class ElementWithPredefinedAutoDir { + @ViewChild(Dir) dir: Dir; +} + /** Test component with Dir directive. */ @Component({ selector: 'injects-directionality',