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.
This commit is contained in:
Kristiyan Kostadinov
2018-11-07 18:26:08 +00:00
committed by vivian-hu
parent 4ce5ee0a6c
commit d94d17614c
2 changed files with 28 additions and 3 deletions
+9 -2
View File
@@ -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<Direction>();
@@ -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);
}
+19 -1
View File
@@ -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: '<div dir="auto"></div>'
})
class ElementWithPredefinedAutoDir {
@ViewChild(Dir) dir: Dir;
}
/** Test component with Dir directive. */
@Component({
selector: 'injects-directionality',