@@ -726,7 +726,7 @@ describe('heatmap plot', function() {
726726 var mockCopy = Lib . extendDeep ( { } , mock ) ;
727727
728728 function getImageURL ( ) {
729- return d3Select ( '.hm > image' ) . attr ( 'href' ) ;
729+ return d3Select ( '.hm > image' ) . node ( ) . _dataUrl ;
730730 }
731731
732732 var imageURLs = [ ] ;
@@ -755,6 +755,68 @@ describe('heatmap plot', function() {
755755 . then ( done , done . fail ) ;
756756 } ) ;
757757
758+ it ( 'should show a blob URL and revoke the blob URLs that it no longer shows' , function ( done ) {
759+ const getImage = ( ) => d3Select ( '.hm > image' ) ;
760+ const revoked = [ ] ;
761+ const revokeObjectURL = URL . revokeObjectURL ;
762+ spyOn ( URL , 'revokeObjectURL' ) . and . callFake ( ( url ) => {
763+ revoked . push ( url ) ;
764+ revokeObjectURL . call ( URL , url ) ;
765+ } ) ;
766+
767+ const hrefs = [ ] ;
768+ const expectRevoked = ( ) => {
769+ hrefs . forEach ( ( href ) => expect ( revoked ) . toContain ( href ) ) ;
770+ } ;
771+
772+ Plotly . newPlot ( gd , [ { type : 'heatmap' , z : [ [ 1 , 2 ] , [ 3 , 4 ] ] } ] )
773+ . then ( ( ) => {
774+ hrefs . push ( getImage ( ) . attr ( 'href' ) ) ;
775+ expect ( hrefs [ 0 ] ) . toMatch ( / ^ b l o b : / ) ;
776+ expect ( getImage ( ) . node ( ) . _dataUrl ) . toMatch ( / ^ d a t a : i m a g e \/ p n g ; b a s e 6 4 , / ) ;
777+
778+ return Plotly . restyle ( gd , 'colorscale' , 'Greens' ) ;
779+ } )
780+ . then ( ( ) => {
781+ const href = getImage ( ) . attr ( 'href' ) ;
782+ expect ( href ) . toMatch ( / ^ b l o b : / ) ;
783+ expect ( revoked ) . toContain ( hrefs [ 0 ] ) ;
784+ expect ( revoked ) . not . toContain ( href ) ;
785+ hrefs . push ( href ) ;
786+
787+ return Plotly . react ( gd , [ { type : 'scatter' , y : [ 1 , 2 ] } ] ) ;
788+ } )
789+ . then ( ( ) => {
790+ expectRevoked ( ) ;
791+ expect ( gd . _imageBlobNodes ) . toBeUndefined ( ) ;
792+
793+ return Plotly . react ( gd , [ { type : 'heatmap' , z : [ [ 1 , 2 ] , [ 3 , 4 ] ] } ] ) ;
794+ } )
795+ . then ( ( ) => {
796+ hrefs . push ( getImage ( ) . attr ( 'href' ) ) ;
797+ Plotly . purge ( gd ) ;
798+ expectRevoked ( ) ;
799+ } )
800+ . then ( done , done . fail ) ;
801+ } ) ;
802+
803+ it ( 'should put a data URL in an exported SVG' , function ( done ) {
804+ const expectDataUrl = ( svg ) => {
805+ expect ( svg ) . toContain ( 'data:image/png;base64,' ) ;
806+ expect ( svg ) . not . toContain ( 'blob:' ) ;
807+ } ;
808+
809+ Plotly . newPlot ( gd , [ { type : 'heatmap' , z : [ [ 1 , 2 ] , [ 3 , 4 ] ] } ] )
810+ . then ( ( ) => Plotly . toImage ( gd , { format : 'svg' } ) )
811+ . then ( ( url ) => {
812+ expectDataUrl ( decodeURIComponent ( url ) ) ;
813+
814+ // Call toSVG last because it modifies the plot DOM.
815+ expectDataUrl ( Plotly . Snapshot . toSVG ( gd ) ) ;
816+ } )
817+ . then ( done , done . fail ) ;
818+ } ) ;
819+
758820 it ( 'draws canvas with correct margins' , function ( done ) {
759821 var mockWithPadding = require ( '../../image/mocks/heatmap_brick_padding.json' ) ;
760822 var mockWithoutPadding = Lib . extendDeep ( { } , mockWithPadding ) ;
0 commit comments