fix($location): parse xlink:href for SVGAElements

Before this fix, the xlink:href property of an SVG <a> element could not be parsed
on click, as the property is an SVGAnimatedString rather than a DOMString.

This patch parses the xlink:href's animVal into a DOMString in order to prevent
an `Object #<SVGAnimatedString> has no method 'indexOf'` exception from being thrown,
and also to update the location if necessary as expected.

Closes #5472
Closes #5198
Closes #5199
Closes #4098
Closes #1420
This commit is contained in:
Caitlin Potter 2013-12-18 17:12:02 -05:00 committed by Igor Minar
parent 8f329ffb82
commit bc3ff2cecd
2 changed files with 32 additions and 0 deletions

View file

@ -629,6 +629,13 @@ function $LocationProvider(){
}
var absHref = elm.prop('href');
if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
// SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during
// an animation.
absHref = urlResolve(absHref.animVal).href;
}
var rewrittenUrl = $location.$$rewrite(absHref);
if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) {

View file

@ -1229,6 +1229,31 @@ describe('$location', function() {
});
browserTrigger(button, 'click');
}));
it('should not throw when clicking an SVGAElement link', function() {
var base;
module(function($locationProvider) {
return function($browser) {
window.location.hash = '!someHash';
$browser.url(base = window.location.href);
base = base.split('#')[0];
$locationProvider.hashPrefix('!');
}
});
inject(function($rootScope, $compile, $browser, $rootElement, $document, $location) {
// we need to do this otherwise we can't simulate events
$document.find('body').append($rootElement);
var template = '<svg><g><a xlink:href="#!/view1"><circle r="50"></circle></a></g></svg>';
var element = $compile(template)($rootScope);
$rootElement.append(element);
var av1 = $rootElement.find('a').eq(0);
expect(function() {
browserTrigger(av1, 'click');
}).not.toThrow();
});
});
});