diff --git a/src/snapshot/filesaver.js b/src/snapshot/filesaver.js index 88109ffe7dd..667bc0c01d1 100644 --- a/src/snapshot/filesaver.js +++ b/src/snapshot/filesaver.js @@ -53,7 +53,11 @@ var fileSaver = function(url, name) { // IE 10+ (native saveAs) if(typeof navigator !== 'undefined' && navigator.msSaveBlob) { - navigator.msSaveBlob(new Blob([url]), name); + // At this point we are only dealing with a SVG encoded as + // a data URL (since IE only supports SVG) + var encoded = url.split(/^data:image\/svg\+xml,/)[1]; + var svg = decodeURIComponent(encoded); + navigator.msSaveBlob(new Blob([svg]), name); resolve(name); } diff --git a/src/snapshot/tosvg.js b/src/snapshot/tosvg.js index 7c9197ee006..99d7af279f6 100644 --- a/src/snapshot/tosvg.js +++ b/src/snapshot/tosvg.js @@ -165,7 +165,7 @@ module.exports = function toSVG(gd, format, scale) { // url in svg are single quoted // since we changed double to single // we'll need to change these to double-quoted - s = s.replace(/(\('#)([^']*)('\))/gi, '(\"$2\")'); + s = s.replace(/(\('#)([^']*)('\))/gi, '(\"#$2\")'); // font names with spaces will be escaped single-quoted // we'll need to change these to double-quoted s = s.replace(/(\\')/gi, '\"'); diff --git a/test/jasmine/tests/download_test.js b/test/jasmine/tests/download_test.js index bcb17a6c354..b8844e63f47 100644 --- a/test/jasmine/tests/download_test.js +++ b/test/jasmine/tests/download_test.js @@ -2,6 +2,9 @@ var Plotly = require('@lib/index'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); var textchartMock = require('@mocks/text_chart_arrays.json'); +var fail = require('../assets/fail_test'); + +var Lib = require('@src/lib'); var LONG_TIMEOUT_INTERVAL = 2 * jasmine.DEFAULT_TIMEOUT_INTERVAL; @@ -9,29 +12,27 @@ describe('Plotly.downloadImage', function() { 'use strict'; var gd; - // override click handler on createElement - // so these tests will not actually - // download an image each time they are run - // full credit goes to @etpinard; thanks var createElement = document.createElement; - beforeAll(function() { - document.createElement = function(args) { - var el = createElement.call(document, args); - el.click = function() {}; - return el; - }; - }); - - afterAll(function() { - document.createElement = createElement; - }); + var slzProto = (new window.XMLSerializer()).__proto__; + var serializeToString = slzProto.serializeToString; beforeEach(function() { gd = createGraphDiv(); + + // override click handler on createElement + // so these tests will not actually + // download an image each time they are run + // full credit goes to @etpinard; thanks + spyOn(document, 'createElement').and.callFake(function(args) { + var el = createElement.call(document, args); + el.click = function() {}; + return el; + }); }); afterEach(function() { destroyGraphDiv(); + delete navigator.msSaveBlob; }); it('should be attached to Plotly', function() { @@ -59,8 +60,56 @@ describe('Plotly.downloadImage', function() { it('should create link, remove link, accept options', function(done) { downloadTest(gd, 'svg', done); }, LONG_TIMEOUT_INTERVAL); -}); + it('should produce the right SVG output in IE', function(done) { + // mock up IE behavior + spyOn(Lib, 'isIE').and.callFake(function() { return true; }); + spyOn(slzProto, 'serializeToString').and.callFake(function() { + return serializeToString.apply(this, arguments) + .replace(/(\(#)([^")]*)(\))/gi, '(\"#$2\")'); + }); + var savedBlob; + navigator.msSaveBlob = function(blob) { savedBlob = blob; }; + + var expectedStart = '