@@ -2,6 +2,9 @@ var Plotly = require('@lib/index');
22var createGraphDiv = require ( '../assets/create_graph_div' ) ;
33var destroyGraphDiv = require ( '../assets/destroy_graph_div' ) ;
44var textchartMock = require ( '@mocks/text_chart_arrays.json' ) ;
5+ var fail = require ( '../assets/fail_test' ) ;
6+
7+ var Lib = require ( '@src/lib' ) ;
58
69var LONG_TIMEOUT_INTERVAL = 2 * jasmine . DEFAULT_TIMEOUT_INTERVAL ;
710
@@ -14,6 +17,11 @@ describe('Plotly.downloadImage', function() {
1417 // download an image each time they are run
1518 // full credit goes to @etpinard ; thanks
1619 var createElement = document . createElement ;
20+ var msSaveBlob = navigator . msSaveBlob ;
21+ var isIE = Lib . isIE ;
22+ var slzProto = ( new window . XMLSerializer ( ) ) . __proto__ ;
23+ var serializeToString = slzProto . serializeToString ;
24+
1725 beforeAll ( function ( ) {
1826 document . createElement = function ( args ) {
1927 var el = createElement . call ( document , args ) ;
@@ -24,6 +32,7 @@ describe('Plotly.downloadImage', function() {
2432
2533 afterAll ( function ( ) {
2634 document . createElement = createElement ;
35+ navigator . msSaveBlob = msSaveBlob ;
2736 } ) ;
2837
2938 beforeEach ( function ( ) {
@@ -32,6 +41,8 @@ describe('Plotly.downloadImage', function() {
3241
3342 afterEach ( function ( ) {
3443 destroyGraphDiv ( ) ;
44+ Lib . isIE = isIE ;
45+ slzProto . serializeToString = serializeToString ;
3546 } ) ;
3647
3748 it ( 'should be attached to Plotly' , function ( ) {
@@ -59,8 +70,55 @@ describe('Plotly.downloadImage', function() {
5970 it ( 'should create link, remove link, accept options' , function ( done ) {
6071 downloadTest ( gd , 'svg' , done ) ;
6172 } , LONG_TIMEOUT_INTERVAL ) ;
62- } ) ;
6373
74+ it ( 'should produce the right SVG output in IE' , function ( done ) {
75+ // mock up IE behavior
76+ Lib . isIE = function ( ) { return true ; } ;
77+ slzProto . serializeToString = function ( ) {
78+ return serializeToString . apply ( this , arguments )
79+ . replace ( / ( \( # ) ( [ ^ " ) ] * ) ( \) ) / gi, '(\"#$2\")' ) ;
80+ } ;
81+ var savedBlob ;
82+ navigator . msSaveBlob = function ( blob ) { savedBlob = blob ; } ;
83+
84+ var expectedStart = '<svg class=\'main-svg\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\' width=\'300\' height=\'300\' style=\'\' viewBox=\'0 0 300 300\'>' ;
85+ var plotClip = / c l i p - p a t h = ' u r l \( " # c l i p [ 0 - 9 a - f ] { 6 } x y p l o t " \) / ;
86+ var legendClip = / c l i p - p a t h = \' u r l \( " # l e g e n d [ 0 - 9 a - f ] { 6 } " \) / ;
87+
88+ Plotly . plot ( gd , textchartMock . data , textchartMock . layout )
89+ . then ( function ( gd ) {
90+ savedBlob = undefined ;
91+ return Plotly . downloadImage ( gd , {
92+ format : 'svg' ,
93+ height : 300 ,
94+ width : 300 ,
95+ filename : 'plotly_download'
96+ } ) ;
97+ } )
98+ . then ( function ( ) {
99+ expect ( savedBlob ) . toBeDefined ( ) ;
100+ if ( savedBlob === undefined ) return ;
101+
102+ return new Promise ( function ( resolve , reject ) {
103+ var reader = new FileReader ( ) ;
104+ reader . onloadend = function ( ) {
105+ var res = reader . result ;
106+
107+ expect ( res . substr ( 0 , expectedStart . length ) ) . toBe ( expectedStart ) ;
108+ expect ( res . match ( plotClip ) ) . not . toBe ( null ) ;
109+ expect ( res . match ( legendClip ) ) . not . toBe ( null ) ;
110+
111+ resolve ( ) ;
112+ } ;
113+ reader . onerror = function ( e ) { reject ( e ) ; } ;
114+
115+ reader . readAsText ( savedBlob ) ;
116+ } ) ;
117+ } )
118+ . catch ( fail )
119+ . then ( done ) ;
120+ } , LONG_TIMEOUT_INTERVAL ) ;
121+ } ) ;
64122
65123function downloadTest ( gd , format , done ) {
66124 // use MutationObserver to monitor the DOM
0 commit comments