mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(router): Handle routerLink directive on svg anchors. (#48857)
On svgs, the tagNames are lowercase even for non-svg related tags like `a`. fixes #48854 PR Close #48857
This commit is contained in:
committed by
Dylan Hunn
parent
6e0e94def4
commit
16ef770db8
@@ -190,8 +190,8 @@ export class RouterLink implements OnChanges, OnDestroy {
|
||||
@Attribute('tabindex') private readonly tabIndexAttribute: string|null|undefined,
|
||||
private readonly renderer: Renderer2, private readonly el: ElementRef,
|
||||
private locationStrategy?: LocationStrategy) {
|
||||
const tagName = el.nativeElement.tagName;
|
||||
this.isAnchorElement = tagName === 'A' || tagName === 'AREA';
|
||||
const tagName = el.nativeElement.tagName?.toLowerCase();
|
||||
this.isAnchorElement = tagName === 'a' || tagName === 'area';
|
||||
|
||||
if (this.isAnchorElement) {
|
||||
this.subscription = router.events.subscribe((s: Event) => {
|
||||
|
||||
@@ -39,8 +39,10 @@ describe('RouterLink', () => {
|
||||
let router: Router;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{imports: [RouterTestingModule], declarations: [LinkComponent]});
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule],
|
||||
declarations: [LinkComponent],
|
||||
});
|
||||
fixture = TestBed.createComponent(LinkComponent);
|
||||
fixture.detectChanges();
|
||||
link = fixture.debugElement.query(By.css('div')).nativeElement;
|
||||
@@ -93,56 +95,76 @@ describe('RouterLink', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('RouterLink for elements with `href` attributes', () => {
|
||||
@Component({template: `<a [routerLink]="link"></a>`})
|
||||
class LinkComponent {
|
||||
link: string|null|undefined = '/';
|
||||
}
|
||||
let fixture: ComponentFixture<LinkComponent>;
|
||||
let link: HTMLAnchorElement;
|
||||
describe('on an anchor', () => {
|
||||
describe('RouterLink for elements with `href` attributes', () => {
|
||||
@Component({template: `<a [routerLink]="link"></a>`})
|
||||
class LinkComponent {
|
||||
link: string|null|undefined = '/';
|
||||
}
|
||||
let fixture: ComponentFixture<LinkComponent>;
|
||||
let link: HTMLAnchorElement;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{imports: [RouterTestingModule], declarations: [LinkComponent]});
|
||||
fixture = TestBed.createComponent(LinkComponent);
|
||||
fixture.detectChanges();
|
||||
link = fixture.debugElement.query(By.css('a')).nativeElement;
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule],
|
||||
declarations: [LinkComponent],
|
||||
});
|
||||
fixture = TestBed.createComponent(LinkComponent);
|
||||
fixture.detectChanges();
|
||||
link = fixture.debugElement.query(By.css('a')).nativeElement;
|
||||
});
|
||||
|
||||
it('null, removes href', () => {
|
||||
expect(link.outerHTML).toContain('href');
|
||||
fixture.componentInstance.link = null;
|
||||
fixture.detectChanges();
|
||||
expect(link.outerHTML).not.toContain('href');
|
||||
});
|
||||
|
||||
it('undefined, removes href', () => {
|
||||
expect(link.outerHTML).toContain('href');
|
||||
fixture.componentInstance.link = undefined;
|
||||
fixture.detectChanges();
|
||||
expect(link.outerHTML).not.toContain('href');
|
||||
});
|
||||
|
||||
it('should coerce boolean input values', () => {
|
||||
const dir = fixture.debugElement.query(By.directive(RouterLink)).injector.get(RouterLink);
|
||||
|
||||
for (const truthy of [true, '', 'true', 'anything']) {
|
||||
dir.preserveFragment = truthy;
|
||||
dir.skipLocationChange = truthy;
|
||||
dir.replaceUrl = truthy;
|
||||
expect(dir.preserveFragment).toBeTrue();
|
||||
expect(dir.skipLocationChange).toBeTrue();
|
||||
expect(dir.replaceUrl).toBeTrue();
|
||||
}
|
||||
|
||||
for (const falsy of [false, null, undefined, 'false']) {
|
||||
dir.preserveFragment = falsy;
|
||||
dir.skipLocationChange = falsy;
|
||||
dir.replaceUrl = falsy;
|
||||
expect(dir.preserveFragment).toBeFalse();
|
||||
expect(dir.skipLocationChange).toBeFalse();
|
||||
expect(dir.replaceUrl).toBeFalse();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('null, removes href', () => {
|
||||
expect(link.outerHTML).toContain('href');
|
||||
fixture.componentInstance.link = null;
|
||||
fixture.detectChanges();
|
||||
expect(link.outerHTML).not.toContain('href');
|
||||
});
|
||||
|
||||
it('undefined, removes href', () => {
|
||||
expect(link.outerHTML).toContain('href');
|
||||
fixture.componentInstance.link = undefined;
|
||||
fixture.detectChanges();
|
||||
expect(link.outerHTML).not.toContain('href');
|
||||
});
|
||||
|
||||
it('should coerce boolean input values', () => {
|
||||
const dir = fixture.debugElement.query(By.directive(RouterLink)).injector.get(RouterLink);
|
||||
|
||||
for (const truthy of [true, '', 'true', 'anything']) {
|
||||
dir.preserveFragment = truthy;
|
||||
dir.skipLocationChange = truthy;
|
||||
dir.replaceUrl = truthy;
|
||||
expect(dir.preserveFragment).toBeTrue();
|
||||
expect(dir.skipLocationChange).toBeTrue();
|
||||
expect(dir.replaceUrl).toBeTrue();
|
||||
it('should handle routerLink in svg templates', () => {
|
||||
@Component({template: `<svg><a routerLink="test"></a></svg>`})
|
||||
class LinkComponent {
|
||||
}
|
||||
|
||||
for (const falsy of [false, null, undefined, 'false']) {
|
||||
dir.preserveFragment = falsy;
|
||||
dir.skipLocationChange = falsy;
|
||||
dir.replaceUrl = falsy;
|
||||
expect(dir.preserveFragment).toBeFalse();
|
||||
expect(dir.skipLocationChange).toBeFalse();
|
||||
expect(dir.replaceUrl).toBeFalse();
|
||||
}
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule],
|
||||
declarations: [LinkComponent],
|
||||
});
|
||||
const fixture = TestBed.createComponent(LinkComponent);
|
||||
fixture.detectChanges();
|
||||
const link = fixture.debugElement.query(By.css('a')).nativeElement;
|
||||
|
||||
expect(link.outerHTML).toContain('href');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user