diff --git a/modules/angular1_router/lib/facades.es5 b/modules/angular1_router/lib/facades.es5
index 2be12cde28..aa2153e313 100644
--- a/modules/angular1_router/lib/facades.es5
+++ b/modules/angular1_router/lib/facades.es5
@@ -316,3 +316,13 @@ Location.prototype.path = function () {
Location.prototype.go = function (path, query) {
return $location.url(path + query);
};
+Location.prototype.prepareExternalUrl = function(url) {
+ if (url.length > 0 && !url.startsWith('/')) {
+ url = '/' + url;
+ }
+ if(!$location.$$html5) {
+ return '#' + url;
+ } else {
+ return '.' + url;
+ }
+};
diff --git a/modules/angular1_router/src/ng_outlet.ts b/modules/angular1_router/src/ng_outlet.ts
index 191bd61d0e..f348020287 100644
--- a/modules/angular1_router/src/ng_outlet.ts
+++ b/modules/angular1_router/src/ng_outlet.ts
@@ -207,13 +207,13 @@ function ngLinkDirective($rootRouter, $parse) {
return;
}
- let instruction = null;
+ let navigationInstruction = null;
let link = attrs.ngLink || '';
function getLink(params) {
- instruction = router.generate(params);
+ navigationInstruction = router.generate(params);
- scope.$watch(function() { return router.isRouteActive(instruction); },
+ scope.$watch(function() { return router.isRouteActive(navigationInstruction); },
function(active) {
if (active) {
element.addClass('ng-link-active');
@@ -222,7 +222,8 @@ function ngLinkDirective($rootRouter, $parse) {
}
});
- return './' + angular.stringifyInstruction(instruction);
+ const navigationHref = navigationInstruction.toLinkUrl();
+ return $rootRouter._location.prepareExternalUrl(navigationHref);
}
let routeParamsGetter = $parse(link);
@@ -236,11 +237,11 @@ function ngLinkDirective($rootRouter, $parse) {
}
element.on('click', event => {
- if (event.which !== 1 || !instruction) {
+ if (event.which !== 1 || !navigationInstruction) {
return;
}
- $rootRouter.navigateByInstruction(instruction);
+ $rootRouter.navigateByInstruction(navigationInstruction);
event.preventDefault();
});
}
diff --git a/modules/angular1_router/test/ng_link_spec.js b/modules/angular1_router/test/ng_link_spec.js
index 22c59e63ac..4556230c2b 100644
--- a/modules/angular1_router/test/ng_link_spec.js
+++ b/modules/angular1_router/test/ng_link_spec.js
@@ -2,183 +2,173 @@
describe('ngLink', function () {
- var elt,
- $compile,
- $rootScope,
- $rootRouter,
- $compileProvider;
-
- beforeEach(function () {
- module('ng');
- module('ngComponentRouter');
- module(function (_$compileProvider_) {
- $compileProvider = _$compileProvider_;
- });
-
- inject(function (_$compile_, _$rootScope_, _$rootRouter_) {
- $compile = _$compile_;
- $rootScope = _$rootScope_;
- $rootRouter = _$rootRouter_;
- });
-
- registerComponent('userCmp', '
hello {{userCmp.$routeParams.name}}
', function () {});
- registerComponent('oneCmp', '{{oneCmp.number}}
', function () {this.number = 'one'});
- registerComponent('twoCmp', '', function () {this.number = 'two'});
- });
-
-
it('should allow linking from the parent to the child', function () {
- $rootRouter.config([
+ setup();
+ configureRouter([
{ path: '/a', component: 'oneCmp' },
{ path: '/b', component: 'twoCmp', name: 'Two' }
]);
- compile('link | outer { }');
-
- $rootRouter.navigateByUrl('/a');
- $rootScope.$digest();
+ var elt = compile('link | outer { }');
+ navigateTo('/a');
expect(elt.find('a').attr('href')).toBe('./b');
});
it('should allow linking from the child and the parent', function () {
- $rootRouter.config([
+ setup();
+ configureRouter([
{ path: '/a', component: 'oneCmp' },
{ path: '/b', component: 'twoCmp', name: 'Two' }
]);
- compile('outer { }');
-
- $rootRouter.navigateByUrl('/b');
- $rootScope.$digest();
+ var elt = compile('outer { }');
+ navigateTo('/b');
expect(elt.find('a').attr('href')).toBe('./b');
});
it('should allow params in routerLink directive', function () {
+ setup();
registerComponent('twoLinkCmp', '', function () {this.number = 'two'});
-
- $rootRouter.config([
+ configureRouter([
{ path: '/a', component: 'twoLinkCmp' },
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
]);
- compile('');
-
- $rootRouter.navigateByUrl('/a');
- $rootScope.$digest();
+ var elt = compile('');
+ navigateTo('/a');
expect(elt.find('a').attr('href')).toBe('./b/lol');
});
it('should update the href of links with bound params', function () {
- registerComponent('twoLinkCmp', '', function () {this.number = 'param'});
- $rootRouter.config([
+ setup();
+ registerComponent('twoLinkCmp', '', function () {this.number = 43});
+ configureRouter([
{ path: '/a', component: 'twoLinkCmp' },
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
]);
- compile('');
- $rootRouter.navigateByUrl('/a');
- $rootScope.$digest();
-
- expect(elt.find('a').attr('href')).toBe('./b/param');
+ var elt = compile('');
+ navigateTo('/a');
+ expect(elt.find('a').text()).toBe('43');
+ expect(elt.find('a').attr('href')).toBe('./b/43');
});
it('should navigate on left-mouse click when a link url matches a route', function () {
- $rootRouter.config([
+ setup();
+ configureRouter([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
- compile('link | ');
- $rootScope.$digest();
+ var elt = compile('link | ');
expect(elt.text()).toBe('link | one');
-
expect(elt.find('a').attr('href')).toBe('./two');
elt.find('a')[0].click();
-
- $rootScope.$digest();
+ inject(function($rootScope) { $rootScope.$digest(); });
expect(elt.text()).toBe('link | two');
});
- it('should not navigate on non-left mouse click when a link url matches a route', inject(function ($rootRouter) {
- $rootRouter.config([
+ it('should not navigate on non-left mouse click when a link url matches a route', function() {
+ setup();
+ configureRouter([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
- compile('link | ');
- $rootScope.$digest();
+ var elt = compile('link | ');
expect(elt.text()).toBe('link | one');
elt.find('a').triggerHandler({ type: 'click', which: 3 });
-
- $rootScope.$digest();
+ inject(function($rootScope) { $rootScope.$digest(); });
expect(elt.text()).toBe('link | one');
- }));
+ });
// See https://github.com/angular/router/issues/206
it('should not navigate a link without an href', function () {
- $rootRouter.config([
+ setup();
+ configureRouter([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
expect(function () {
- compile('link');
- $rootScope.$digest();
+ var elt = compile('link');
expect(elt.text()).toBe('link');
elt.find('a')[0].click();
- $rootScope.$digest();
+ inject(function($rootScope) { $rootScope.$digest(); });
}).not.toThrow();
});
- it('should add an ng-link-active class on the current link', inject(function ($rootRouter) {
- $rootRouter.config([
+ it('should add an ng-link-active class on the current link', function() {
+ setup();
+ configureRouter([
{ path: '/', component: 'oneCmp', name: 'One' }
]);
- compile('one | ');
- $rootScope.$digest();
-
- $rootRouter.navigateByUrl('/');
- $rootScope.$digest();
-
+ var elt = compile('one | ');
+ navigateTo('/');
expect(elt.find('a').attr('class')).toBe('ng-link-active');
- }));
+ });
- function registerComponent(name, template, config) {
- var controller = function () {};
+ describe('html5Mode disabled', function () {
+ it('should prepend href with a hash', function () {
+ setup({ html5Mode: false });
+ module(function($locationProvider) {
+ $locationProvider.html5Mode(false);
+ });
+ configureRouter([
+ { path: '/b', component: 'twoCmp', name: 'Two' }
+ ]);
+ var elt = compile('link');
+ expect(elt.find('a').attr('href')).toBe('#/b');
+ });
+ });
- function factory() {
- return {
+
+ function registerComponent(name, template, controller) {
+ module(function($compileProvider) {
+ $compileProvider.component(name, {
template: template,
- controllerAs: name,
controller: controller
- };
- }
+ });
+ });
+ }
- if (!template) {
- template = '';
- }
- if (angular.isArray(config)) {
- factory.annotations = [new angular.annotations.RouteConfig(config)];
- } else if (typeof config === 'function') {
- controller = config;
- } else if (typeof config === 'object') {
- if (config.canActivate) {
- controller.$canActivate = config.canActivate;
- }
- }
- $compileProvider.directive(name, factory);
+ function setup(config) {
+ var html5Mode = !(config && config.html5Mode === false);
+ module('ngComponentRouter')
+ module(function($locationProvider) {
+ $locationProvider.html5Mode(html5Mode);
+ });
+ registerComponent('userCmp', 'hello {{$ctrl.$routeParams.name}}
', function () {});
+ registerComponent('oneCmp', '{{$ctrl.number}}
', function () {this.number = 'one'});
+ registerComponent('twoCmp', '', function () {this.number = 'two'});
+ }
+
+ function configureRouter(routeConfig) {
+ inject(function($rootRouter) {
+ $rootRouter.config(routeConfig);
+ });
}
function compile(template) {
- elt = $compile('' + template + '
')($rootScope);
- $rootScope.$digest();
+ var elt;
+ inject(function($compile, $rootScope) {
+ elt = $compile('' + template + '
')($rootScope);
+ $rootScope.$digest();
+ });
return elt;
}
+
+ function navigateTo(url) {
+ inject(function($rootRouter, $rootScope) {
+ $rootRouter.navigateByUrl(url);
+ $rootScope.$digest();
+ });
+ }
});