mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
committed by
vivian-hu
parent
4ce5ee0a6c
commit
d94d17614c
+9
-2
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user