From 2bce71e9dc10c8588f9eb599a0cd2e831440fc48 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Mon, 20 Jan 2014 20:59:21 -0500 Subject: [PATCH] feat(ngHref): bind ng-href to xlink:href for SVGAElement This change makes the ngHref directive useful for SVGAElements by having it bind to the xlink:href attribute rather than the href attribute. Closes #5904 --- src/ng/directive/booleanAttrs.js | 14 ++++++++++++-- test/ng/directive/booleanAttrsSpec.js | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/ng/directive/booleanAttrs.js b/src/ng/directive/booleanAttrs.js index ff3cf5eea8f9..50f118d484af 100644 --- a/src/ng/directive/booleanAttrs.js +++ b/src/ng/directive/booleanAttrs.js @@ -369,17 +369,27 @@ forEach(['src', 'srcset', 'href'], function(attrName) { return { priority: 99, // it needs to run after the attributes are interpolated link: function(scope, element, attr) { + var propName = attrName, + name = attrName; + + if (attrName === 'href' && + toString.call(element.prop('href')) === '[object SVGAnimatedString]') { + name = 'xlinkHref'; + attr.$attr[name] = 'xlink:href'; + propName = null; + } + attr.$observe(normalized, function(value) { if (!value) return; - attr.$set(attrName, value); + attr.$set(name, value); // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need // to set the property as well to achieve the desired effect. // we use attr[attrName] value since $set can sanitize the url. - if (msie) element.prop(attrName, attr[attrName]); + if (msie && propName) element.prop(propName, attr[name]); }); } }; diff --git a/test/ng/directive/booleanAttrsSpec.js b/test/ng/directive/booleanAttrsSpec.js index 83bc75e55188..2d800f5b3ab9 100644 --- a/test/ng/directive/booleanAttrsSpec.js +++ b/test/ng/directive/booleanAttrsSpec.js @@ -251,4 +251,28 @@ describe('ngHref', function() { $rootScope.$digest(); expect(element.attr('href')).toEqual('http://server'); })); + + if (isDefined(window.SVGElement)) { + describe('SVGAElement', function() { + it('should interpolate the expression and bind to xlink:href', inject(function($compile, $rootScope) { + element = $compile('')($rootScope); + var child = element.children('a'); + $rootScope.$digest(); + expect(child.attr('xlink:href')).toEqual('some/'); + + $rootScope.$apply(function() { + $rootScope.id = 1; + }); + expect(child.attr('xlink:href')).toEqual('some/1'); + })); + + + it('should bind xlink:href even if no interpolation', inject(function($rootScope, $compile) { + element = $compile('')($rootScope); + var child = element.children('a'); + $rootScope.$digest(); + expect(child.attr('xlink:href')).toEqual('http://server'); + })); + }); + } });