Skip to content

Commit d13ed47

Browse files
Rafael Fernandez Serrachristopherthielen
authored andcommitted
fix(uiSref): open new tab when a tag has target="_blank"
1 parent 29f2d0e commit d13ed47

File tree

2 files changed

+116
-28
lines changed

2 files changed

+116
-28
lines changed

src/directives/uiSref.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @ng2api @module directives */
22
/** */
33
import { UIRouter, UIRouterGlobals, extend, Obj, TransitionOptions, TargetState } from "@uirouter/core";
4-
import { Directive, Inject, Input, Optional, ElementRef, Renderer } from "@angular/core";
4+
import { Directive, Inject, Input, Optional, ElementRef, Renderer2 } from "@angular/core";
55
import { UIView, ParentUIViewInject } from "./uiView";
66
import { ReplaySubject } from "rxjs/ReplaySubject";
77
import { Subscription } from "rxjs/Subscription";
@@ -12,10 +12,13 @@ import { Subscription } from "rxjs/Subscription";
1212
*/
1313
@Directive({ selector: 'a[uiSref]' })
1414
export class AnchorUISref {
15-
constructor(public _el: ElementRef, public _renderer: Renderer) { }
15+
constructor(public _el: ElementRef, public _renderer: Renderer2) { }
16+
openInNewTab() {
17+
return this._el.nativeElement.target === '_blank';
18+
}
1619
update(href: string) {
1720
if (href && href != '') {
18-
this._renderer.setElementProperty(this._el.nativeElement, 'href', href);
21+
this._renderer.setProperty(this._el.nativeElement, 'href', href);
1922
} else {
2023
this._el.nativeElement.removeAttribute('href');
2124
}
@@ -161,6 +164,10 @@ export class UISref {
161164

162165
/** When triggered by a (click) event, this function transitions to the UISref's target state */
163166
go() {
167+
if (this._anchorUISref && this._anchorUISref.openInNewTab()) {
168+
return ;
169+
}
170+
164171
this._router.stateService.go(this.state, this.params, this.getOptions());
165172
return false;
166173
}

test/uiSref.spec.ts

Lines changed: 106 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,118 @@
1-
import { Component, NO_ERRORS_SCHEMA } from "@angular/core";
1+
import { Component, DebugElement } from '@angular/core';
22
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
33
import { By } from '@angular/platform-browser';
4-
import { DebugElement } from '@angular/core';
54

65
import { UIRouterModule } from '../src/uiRouterNgModule';
76
import { UISref } from '../src/directives/uiSref';
7+
import { UIRouter } from '@uirouter/core';
8+
import { Subject } from 'rxjs/Subject';
89

910
describe('uiSref', () => {
10-
describe('empty links', () => {
11-
@Component({
12-
template: `
13-
<a [uiSref]="null"></a>
14-
<a [uiSref]="''"></a>
15-
`
16-
})
17-
class TestComponent { }
18-
19-
let des: DebugElement[];
20-
let comp: TestComponent;
21-
let fixture: ComponentFixture<TestComponent>;
22-
23-
beforeEach(() => {
24-
fixture = TestBed.configureTestingModule({
25-
declarations: [ TestComponent ],
26-
imports: [ UIRouterModule ]
27-
}).createComponent(TestComponent);
28-
fixture.detectChanges();
29-
des = fixture.debugElement.queryAll(By.directive(UISref));
11+
@Component({
12+
template: `
13+
<a [uiSref]="linkA" [target]="targetA"></a>
14+
<a [uiSref]="linkB"></a>
15+
`
16+
})
17+
class TestComponent {
18+
linkA: string;
19+
targetA: string;
20+
linkB: string;
21+
22+
constructor() {
23+
this.linkA = null;
24+
this.targetA = '';
25+
this.linkB = '';
26+
}
27+
}
28+
29+
describe('when applied to a link tag', () => {
30+
describe('when the uiSref is empty', () => {
31+
let des: DebugElement[];
32+
let fixture: ComponentFixture<TestComponent>;
33+
34+
beforeEach(() => {
35+
fixture = TestBed.configureTestingModule({
36+
declarations: [TestComponent],
37+
imports: [UIRouterModule]
38+
}).createComponent(TestComponent);
39+
fixture.detectChanges();
40+
des = fixture.debugElement.queryAll(By.directive(UISref));
41+
});
42+
43+
it('should not bind "null" string to `href`', () => {
44+
expect(des[0].nativeElement.hasAttribute('href')).toBeFalsy();
45+
expect(des[1].nativeElement.hasAttribute('href')).toBeFalsy();
46+
});
3047
});
3148

32-
it('should not bind "null" string to `href`', () => {
33-
expect(des[0].nativeElement.hasAttribute('href')).toBeFalsy();
34-
expect(des[1].nativeElement.hasAttribute('href')).toBeFalsy();
49+
describe('when the uiSref is not empty', () => {
50+
let des: DebugElement[];
51+
let comp: TestComponent;
52+
let uiRouterMock: UIRouter;
53+
let fixture: ComponentFixture<TestComponent>;
54+
55+
beforeEach(async(() => {
56+
uiRouterMock = {
57+
globals: {
58+
states$: new Subject()
59+
},
60+
stateService: jasmine.createSpyObj('stateService', ['go', 'target', 'href'])
61+
} as any;
62+
TestBed.configureTestingModule({
63+
declarations: [TestComponent],
64+
imports: [UIRouterModule]
65+
}).overrideComponent(TestComponent, {
66+
set: {
67+
providers: [
68+
{ provide: UIRouter, useValue: uiRouterMock }
69+
]
70+
}
71+
}).compileComponents();
72+
}));
73+
74+
beforeEach(() => {
75+
fixture = TestBed.createComponent(TestComponent);
76+
77+
comp = fixture.componentInstance;
78+
comp.linkA = '';
79+
fixture.detectChanges();
80+
des = fixture.debugElement.queryAll(By.directive(UISref));
81+
});
82+
83+
describe('when target is _blank', () => {
84+
beforeEach(() => {
85+
comp.targetA = '_blank';
86+
fixture.detectChanges();
87+
});
88+
89+
describe('when clicked', () => {
90+
beforeEach(() => {
91+
des[0].triggerEventHandler('click', {});
92+
});
93+
94+
it('should ignore the click event', () => {
95+
expect(uiRouterMock.stateService.go).not.toHaveBeenCalled();
96+
});
97+
});
98+
});
99+
100+
describe('when target is not _blank', () => {
101+
beforeEach(() => {
102+
comp.targetA = '';
103+
fixture.detectChanges();
104+
});
105+
106+
describe('when clicked', () => {
107+
beforeEach(() => {
108+
des[0].triggerEventHandler('click', {});
109+
});
110+
111+
it('should navigate to the state', () => {
112+
expect(uiRouterMock.stateService.go).toHaveBeenCalled();
113+
});
114+
});
115+
});
35116
});
36117
});
37118
});

0 commit comments

Comments
 (0)