diff --git a/src/ng/directive/a.js b/src/ng/directive/a.js index 23096147145f..581f2fec5b12 100644 --- a/src/ng/directive/a.js +++ b/src/ng/directive/a.js @@ -18,10 +18,16 @@ var htmlAnchorDirective = valueFn({ compile: function(element, attr) { if (!attr.href && !attr.xlinkHref && !attr.name) { return function(scope, element) { + // If the linked element is not an anchor tag anymore, do nothing + if (element[0].nodeName.toLowerCase() !== 'a') return; + // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute. var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ? 'xlink:href' : 'href'; element.on('click', function(event) { + // If a different element was clicked, ignore it. + if (element[0] !== event.target) return; + // if we have no href url, then don't navigate anywhere. if (!element.attr(href)) { event.preventDefault(); diff --git a/test/ng/directive/aSpec.js b/test/ng/directive/aSpec.js index 05f3c8b2eba7..460ea88bc2ff 100644 --- a/test/ng/directive/aSpec.js +++ b/test/ng/directive/aSpec.js @@ -3,6 +3,25 @@ describe('a', function() { var element, $compile, $rootScope; + beforeEach(module(function($compileProvider) { + $compileProvider. + directive('linkTo', valueFn({ + restrict: 'A', + template: '
', + replace: true, + scope: { + destination: '@linkTo' + } + })). + directive('linkNot', valueFn({ + restrict: 'A', + template: '', + replace: true, + scope: { + destination: '@linkNot' + } + })); + })); beforeEach(inject(function(_$compile_, _$rootScope_) { $compile = _$compile_; @@ -76,6 +95,40 @@ describe('a', function() { }); + it('should not preventDefault if anchor element is replaced with href-containing element', function() { + spyOn(jqLite.prototype, 'on').andCallThrough(); + element = $compile('')($rootScope); + $rootScope.$digest(); + + var child = element.children('a'); + var preventDefault = jasmine.createSpy('preventDefault'); + + child.triggerHandler({ + type: 'click', + preventDefault: preventDefault + }); + + expect(preventDefault).not.toHaveBeenCalled(); + }); + + + it('should preventDefault if anchor element is replaced with element without href attribute', function() { + spyOn(jqLite.prototype, 'on').andCallThrough(); + element = $compile('')($rootScope); + $rootScope.$digest(); + + var child = element.children('a'); + var preventDefault = jasmine.createSpy('preventDefault'); + + child.triggerHandler({ + type: 'click', + preventDefault: preventDefault + }); + + expect(preventDefault).toHaveBeenCalled(); + }); + + if (isDefined(window.SVGElement)) { describe('SVGAElement', function() { it('should prevent default action to be executed when href is empty', function() {