diff --git a/src/ng/directive/a.js b/src/ng/directive/a.js index fe50a79b19a3..9887cba535ce 100644 --- a/src/ng/directive/a.js +++ b/src/ng/directive/a.js @@ -32,11 +32,14 @@ var htmlAnchorDirective = valueFn({ element.append(document.createComment('IE fix')); } - if (!attr.href && !attr.name) { + if (!attr.href && !attr.xlinkHref && !attr.name) { return function(scope, element) { + // 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 we have no href url, then don't navigate anywhere. - if (!element.attr('href')) { + if (!element.attr(href)) { event.preventDefault(); } }); diff --git a/test/ng/directive/aSpec.js b/test/ng/directive/aSpec.js index dc0de729fe58..bd9f246dc0cd 100644 --- a/test/ng/directive/aSpec.js +++ b/test/ng/directive/aSpec.js @@ -84,4 +84,71 @@ describe('a', function() { expect(jq.prototype.on).not.toHaveBeenCalled(); }); + + + if (isDefined(window.SVGElement)) { + describe('SVGAElement', function() { + it('should prevent default action to be executed when href is empty', function() { + var orgLocation = document.location.href, + preventDefaultCalled = false, + event, + child; + + element = $compile('empty link')($rootScope); + child = element.children('a'); + + if (msie < 9) { + + event = document.createEventObject(); + expect(event.returnValue).not.toBeDefined(); + child[0].fireEvent('onclick', event); + expect(event.returnValue).toEqual(false); + + } else { + + event = document.createEvent('MouseEvent'); + event.initMouseEvent( + 'click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + + event.preventDefaultOrg = event.preventDefault; + event.preventDefault = function() { + preventDefaultCalled = true; + if (this.preventDefaultOrg) this.preventDefaultOrg(); + }; + + child[0].dispatchEvent(event); + + expect(preventDefaultCalled).toEqual(true); + } + + expect(document.location.href).toEqual(orgLocation); + }); + + + it('should not link and hookup an event if xlink:href is present at compile', function() { + var jq = jQuery || jqLite; + element = jq('hello@you'); + var linker = $compile(element); + + spyOn(jq.prototype, 'on'); + + linker($rootScope); + + expect(jq.prototype.on).not.toHaveBeenCalled(); + }); + + + it('should not link and hookup an event if name is present at compile', function() { + var jq = jQuery || jqLite; + element = jq('hello@you'); + var linker = $compile(element); + + spyOn(jq.prototype, 'on'); + + linker($rootScope); + + expect(jq.prototype.on).not.toHaveBeenCalled(); + }); + }); + } });