diff --git a/src/lib/svg_text_utils.js b/src/lib/svg_text_utils.js index b82d9b93bec..add53dcd3ed 100644 --- a/src/lib/svg_text_utils.js +++ b/src/lib/svg_text_utils.js @@ -469,7 +469,10 @@ function buildSVGText(containerNode, str) { var dummyAnchor = document.createElement('a'); dummyAnchor.href = href; if(PROTOCOLS.indexOf(dummyAnchor.protocol) !== -1) { - nodeSpec.href = encodeURI(href); + // Decode href to allow both already encoded and not encoded + // URIs. Without decoding prior encoding, an already encoded + // URI would be encoded twice producing a semantically different URI. + nodeSpec.href = encodeURI(decodeURI(href)); nodeSpec.target = getQuotedMatch(extra, TARGETMATCH) || '_blank'; nodeSpec.popup = getQuotedMatch(extra, POPUPMATCH); } diff --git a/test/jasmine/tests/svg_text_utils_test.js b/test/jasmine/tests/svg_text_utils_test.js index d5552976d87..c950f728add 100644 --- a/test/jasmine/tests/svg_text_utils_test.js +++ b/test/jasmine/tests/svg_text_utils_test.js @@ -173,6 +173,16 @@ describe('svg+text utils', function() { }); }); + it('allows encoded URIs in href', function() { + var node = mockTextSVGElement( + 'click' + ); + + expect(node.text()).toEqual('click'); + assertAnchorAttrs(node); + assertAnchorLink(node, 'https://example.com/?q=date%20%3E=%202018-01-01'); + }); + it('accepts `target` with links and tries to translate it to `xlink:show`', function() { var specs = [ {target: '_blank', show: 'new'},