Skip to content

Commit

Permalink
fix($location): parse xlink:href for SVGAElements
Browse files Browse the repository at this point in the history
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 angular#5472
Closes angular#5198
Closes angular#5199
Closes angular#4098
Closes angular#1420
  • Loading branch information
Caitlin Potter authored and jamesdaily committed Jan 27, 2014
1 parent 612bd1d commit e708367
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/ng/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
25 changes: 25 additions & 0 deletions test/ng/locationSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
});


Expand Down

0 comments on commit e708367

Please sign in to comment.