@@ -30,16 +30,13 @@ var saveAs = saveAs || (function(view) {
3030 var event = new MouseEvent ( "click" ) ;
3131 node . dispatchEvent ( event ) ;
3232 }
33- , is_safari = / V e r s i o n \/ [ \d \. ] + .* S a f a r i / . test ( navigator . userAgent )
34- , webkit_req_fs = view . webkitRequestFileSystem
35- , req_fs = view . requestFileSystem || webkit_req_fs || view . mozRequestFileSystem
33+ , is_safari = / c o n s t r u c t o r / i. test ( view . HTMLElement )
3634 , throw_outside = function ( ex ) {
3735 ( view . setImmediate || view . setTimeout ) ( function ( ) {
3836 throw ex ;
3937 } , 0 ) ;
4038 }
4139 , force_saveable_type = "application/octet-stream"
42- , fs_min_size = 0
4340 // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
4441 , arbitrary_revoke_timeout = 1000 * 40 // in ms
4542 , revoke = function ( file ) {
@@ -50,22 +47,6 @@ var saveAs = saveAs || (function(view) {
5047 file . remove ( ) ;
5148 }
5249 } ;
53- /* // Take note W3C:
54- var
55- uri = typeof file === "string" ? file : file.toURL()
56- , revoker = function(evt) {
57- // idealy DownloadFinishedEvent.data would be the URL requested
58- if (evt.data === uri) {
59- if (typeof file === "string") { // file is an object URL
60- get_URL().revokeObjectURL(file);
61- } else { // file is a File
62- file.remove();
63- }
64- }
65- }
66- ;
67- view.addEventListener("downloadfinished", revoker);
68- */
6950 setTimeout ( revoker , arbitrary_revoke_timeout ) ;
7051 }
7152 , dispatch = function ( filesaver , event_types , event ) {
@@ -97,20 +78,19 @@ var saveAs = saveAs || (function(view) {
9778 var
9879 filesaver = this
9980 , type = blob . type
100- , blob_changed = false
81+ , force = type === force_saveable_type
10182 , object_url
102- , target_view
10383 , dispatch_all = function ( ) {
10484 dispatch ( filesaver , "writestart progress write writeend" . split ( " " ) ) ;
10585 }
10686 // on any filesys errors revert to saving with object URLs
10787 , fs_error = function ( ) {
108- if ( target_view && is_safari && typeof FileReader !== "undefined" ) {
88+ if ( force && is_safari && view . FileReader ) {
10989 // Safari doesn't allow downloading of blob urls
11090 var reader = new FileReader ( ) ;
11191 reader . onloadend = function ( ) {
11292 var base64Data = reader . result ;
113- target_view . location . href = "data:attachment/file" + base64Data . slice ( base64Data . search ( / [ , ; ] / ) ) ;
93+ view . location . href = "data:attachment/file" + base64Data . slice ( base64Data . search ( / [ , ; ] / ) ) ;
11494 filesaver . readyState = filesaver . DONE ;
11595 dispatch_all ( ) ;
11696 } ;
@@ -119,14 +99,14 @@ var saveAs = saveAs || (function(view) {
11999 return ;
120100 }
121101 // don't create more object URLs than needed
122- if ( blob_changed || ! object_url ) {
102+ if ( ! object_url ) {
123103 object_url = get_URL ( ) . createObjectURL ( blob ) ;
124104 }
125- if ( target_view ) {
126- target_view . location . href = object_url ;
105+ if ( force ) {
106+ view . location . href = object_url ;
127107 } else {
128- var new_tab = view . open ( object_url , "_blank" ) ;
129- if ( new_tab === undefined && is_safari ) {
108+ var opened = view . open ( object_url , "_blank" ) ;
109+ if ( ! opened ) {
130110 // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
131111 view . location . href = object_url ;
132112 }
@@ -135,20 +115,9 @@ var saveAs = saveAs || (function(view) {
135115 dispatch_all ( ) ;
136116 revoke ( object_url ) ;
137117 }
138- , abortable = function ( func ) {
139- return function ( ) {
140- if ( filesaver . readyState !== filesaver . DONE ) {
141- return func . apply ( this , arguments ) ;
142- }
143- } ;
144- }
145- , create_if_not_found = { create : true , exclusive : false }
146- , slice
147118 ;
148119 filesaver . readyState = filesaver . INIT ;
149- if ( ! name ) {
150- name = "download" ;
151- }
120+
152121 if ( can_use_save_link ) {
153122 object_url = get_URL ( ) . createObjectURL ( blob ) ;
154123 setTimeout ( function ( ) {
@@ -161,93 +130,27 @@ var saveAs = saveAs || (function(view) {
161130 } ) ;
162131 return ;
163132 }
164- // Object and web filesystem URLs have a problem saving in Google Chrome when
165- // viewed in a tab, so I force save with application/octet-stream
166- // http://code.google.com/p/chromium/issues/detail?id=91158
167- // Update: Google errantly closed 91158, I submitted it again:
168- // https://code.google.com/p/chromium/issues/detail?id=389642
169- if ( view . chrome && type && type !== force_saveable_type ) {
170- slice = blob . slice || blob . webkitSlice ;
171- blob = slice . call ( blob , 0 , blob . size , force_saveable_type ) ;
172- blob_changed = true ;
173- }
174- // Since I can't be sure that the guessed media type will trigger a download
175- // in WebKit, I append .download to the filename.
176- // https://bugs.webkit.org/show_bug.cgi?id=65440
177- if ( webkit_req_fs && name !== "download" ) {
178- name += ".download" ;
179- }
180- if ( type === force_saveable_type || webkit_req_fs ) {
181- target_view = view ;
182- }
183- if ( ! req_fs ) {
184- fs_error ( ) ;
185- return ;
186- }
187- fs_min_size += blob . size ;
188- req_fs ( view . TEMPORARY , fs_min_size , abortable ( function ( fs ) {
189- fs . root . getDirectory ( "saved" , create_if_not_found , abortable ( function ( dir ) {
190- var save = function ( ) {
191- dir . getFile ( name , create_if_not_found , abortable ( function ( file ) {
192- file . createWriter ( abortable ( function ( writer ) {
193- writer . onwriteend = function ( event ) {
194- target_view . location . href = file . toURL ( ) ;
195- filesaver . readyState = filesaver . DONE ;
196- dispatch ( filesaver , "writeend" , event ) ;
197- revoke ( file ) ;
198- } ;
199- writer . onerror = function ( ) {
200- var error = writer . error ;
201- if ( error . code !== error . ABORT_ERR ) {
202- fs_error ( ) ;
203- }
204- } ;
205- "writestart progress write abort" . split ( " " ) . forEach ( function ( event ) {
206- writer [ "on" + event ] = filesaver [ "on" + event ] ;
207- } ) ;
208- writer . write ( blob ) ;
209- filesaver . abort = function ( ) {
210- writer . abort ( ) ;
211- filesaver . readyState = filesaver . DONE ;
212- } ;
213- filesaver . readyState = filesaver . WRITING ;
214- } ) , fs_error ) ;
215- } ) , fs_error ) ;
216- } ;
217- dir . getFile ( name , { create : false } , abortable ( function ( file ) {
218- // delete file if it already exists
219- file . remove ( ) ;
220- save ( ) ;
221- } ) , abortable ( function ( ex ) {
222- if ( ex . code === ex . NOT_FOUND_ERR ) {
223- save ( ) ;
224- } else {
225- fs_error ( ) ;
226- }
227- } ) ) ;
228- } ) , fs_error ) ;
229- } ) , fs_error ) ;
133+
134+ fs_error ( ) ;
230135 }
231136 , FS_proto = FileSaver . prototype
232137 , saveAs = function ( blob , name , no_auto_bom ) {
233- return new FileSaver ( blob , name , no_auto_bom ) ;
138+ return new FileSaver ( blob , name || blob . name || "download" , no_auto_bom ) ;
234139 }
235140 ;
236141 // IE 10+ (native saveAs)
237142 if ( typeof navigator !== "undefined" && navigator . msSaveOrOpenBlob ) {
238143 return function ( blob , name , no_auto_bom ) {
144+ name = name || blob . name || "download" ;
145+
239146 if ( ! no_auto_bom ) {
240147 blob = auto_bom ( blob ) ;
241148 }
242- return navigator . msSaveOrOpenBlob ( blob , name || "download" ) ;
149+ return navigator . msSaveOrOpenBlob ( blob , name ) ;
243150 } ;
244151 }
245152
246- FS_proto . abort = function ( ) {
247- var filesaver = this ;
248- filesaver . readyState = filesaver . DONE ;
249- dispatch ( filesaver , "abort" ) ;
250- } ;
153+ FS_proto . abort = function ( ) { } ;
251154 FS_proto . readyState = FS_proto . INIT = 0 ;
252155 FS_proto . WRITING = 1 ;
253156 FS_proto . DONE = 2 ;
0 commit comments