1
+ ( function ( global , factory ) {
2
+ if ( typeof define === "function" && define . amd ) {
3
+ define ( [ ] , factory ) ;
4
+ } else if ( typeof exports !== "undefined" ) {
5
+ factory ( ) ;
6
+ } else {
7
+ var mod = {
8
+ exports : { }
9
+ } ;
10
+ factory ( ) ;
11
+ global . FileSaver = mod . exports ;
12
+ }
13
+ } ) ( this , function ( ) {
14
+ "use strict" ;
15
+
16
+ /*
17
+ * FileSaver.js
18
+ * A saveAs() FileSaver implementation.
19
+ *
20
+ * By Eli Grey, http://eligrey.com
21
+ *
22
+ * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
23
+ * source : http://purl.eligrey.com/github/FileSaver.js
24
+ */
25
+ // The one and only way of getting global scope in all environments
26
+ // https://stackoverflow.com/q/3277182/1008999
27
+ var _global = typeof window === 'object' && window . window === window ? window : typeof self === 'object' && self . self === self ? self : typeof global === 'object' && global . global === global ? global : void 0 ;
28
+
29
+ function bom ( blob , opts ) {
30
+ if ( typeof opts === 'undefined' ) opts = {
31
+ autoBom : false
32
+ } ; else if ( typeof opts !== 'object' ) {
33
+ console . warn ( 'Deprecated: Expected third argument to be a object' ) ;
34
+ opts = {
35
+ autoBom : ! opts
36
+ } ;
37
+ } // prepend BOM for UTF-8 XML and text/* types (including HTML)
38
+ // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
39
+
40
+ if ( opts . autoBom && / ^ \s * (?: t e x t \/ \S * | a p p l i c a t i o n \/ x m l | \S * \/ \S * \+ x m l ) \s * ; .* c h a r s e t \s * = \s * u t f - 8 / i. test ( blob . type ) ) {
41
+ return new Blob ( [ String . fromCharCode ( 0xFEFF ) , blob ] , {
42
+ type : blob . type
43
+ } ) ;
44
+ }
45
+
46
+ return blob ;
47
+ }
48
+
49
+ function download ( url , name , opts ) {
50
+ var xhr = new XMLHttpRequest ( ) ;
51
+ xhr . open ( 'GET' , url ) ;
52
+ xhr . responseType = 'blob' ;
53
+
54
+ xhr . onload = function ( ) {
55
+ saveAs ( xhr . response , name , opts ) ;
56
+ } ;
57
+
58
+ xhr . onerror = function ( ) {
59
+ console . error ( 'could not download file' ) ;
60
+ } ;
61
+
62
+ xhr . send ( ) ;
63
+ }
64
+
65
+ function corsEnabled ( url ) {
66
+ var xhr = new XMLHttpRequest ( ) ; // use sync to avoid popup blocker
67
+
68
+ xhr . open ( 'HEAD' , url , false ) ;
69
+
70
+ try {
71
+ xhr . send ( ) ;
72
+ } catch ( e ) { }
73
+
74
+ return xhr . status >= 200 && xhr . status <= 299 ;
75
+ } // `a.click()` doesn't work for all browsers (#465)
76
+
77
+
78
+ function click ( node ) {
79
+ try {
80
+ node . dispatchEvent ( new MouseEvent ( 'click' ) ) ;
81
+ } catch ( e ) {
82
+ var evt = document . createEvent ( 'MouseEvents' ) ;
83
+ evt . initMouseEvent ( 'click' , true , true , window , 0 , 0 , 0 , 80 , 20 , false , false , false , false , 0 , null ) ;
84
+ node . dispatchEvent ( evt ) ;
85
+ }
86
+ } // Detect WebView inside a native macOS app by ruling out all browsers
87
+ // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
88
+ // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
89
+
90
+
91
+ var isMacOSWebView = / M a c i n t o s h / . test ( navigator . userAgent ) && / A p p l e W e b K i t / . test ( navigator . userAgent ) && ! / S a f a r i / . test ( navigator . userAgent ) ;
92
+ var saveAs = _global . saveAs || ( // probably in some web worker
93
+ typeof window !== 'object' || window !== _global ? function saveAs ( ) { }
94
+ /* noop */
95
+ // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
96
+ : 'download' in HTMLAnchorElement . prototype && ! isMacOSWebView ? function saveAs ( blob , name , opts ) {
97
+ var URL = _global . URL || _global . webkitURL ;
98
+ var a = document . createElement ( 'a' ) ;
99
+ name = name || blob . name || 'download' ;
100
+ a . download = name ;
101
+ a . rel = 'noopener' ; // tabnabbing
102
+ // TODO: detect chrome extensions & packaged apps
103
+ // a.target = '_blank'
104
+
105
+ if ( typeof blob === 'string' ) {
106
+ // Support regular links
107
+ a . href = blob ;
108
+
109
+ if ( a . origin !== location . origin ) {
110
+ corsEnabled ( a . href ) ? download ( blob , name , opts ) : click ( a , a . target = '_blank' ) ;
111
+ } else {
112
+ click ( a ) ;
113
+ }
114
+ } else {
115
+ // Support blobs
116
+ a . href = URL . createObjectURL ( blob ) ;
117
+ setTimeout ( function ( ) {
118
+ URL . revokeObjectURL ( a . href ) ;
119
+ } , 4E4 ) ; // 40s
120
+
121
+ setTimeout ( function ( ) {
122
+ click ( a ) ;
123
+ } , 0 ) ;
124
+ }
125
+ } // Use msSaveOrOpenBlob as a second approach
126
+ : 'msSaveOrOpenBlob' in navigator ? function saveAs ( blob , name , opts ) {
127
+ name = name || blob . name || 'download' ;
128
+
129
+ if ( typeof blob === 'string' ) {
130
+ if ( corsEnabled ( blob ) ) {
131
+ download ( blob , name , opts ) ;
132
+ } else {
133
+ var a = document . createElement ( 'a' ) ;
134
+ a . href = blob ;
135
+ a . target = '_blank' ;
136
+ setTimeout ( function ( ) {
137
+ click ( a ) ;
138
+ } ) ;
139
+ }
140
+ } else {
141
+ navigator . msSaveOrOpenBlob ( bom ( blob , opts ) , name ) ;
142
+ }
143
+ } // Fallback to using FileReader and a popup
144
+ : function saveAs ( blob , name , opts , popup ) {
145
+ // Open a popup immediately do go around popup blocker
146
+ // Mostly only available on user interaction and the fileReader is async so...
147
+ popup = popup || open ( '' , '_blank' ) ;
148
+
149
+ if ( popup ) {
150
+ popup . document . title = popup . document . body . innerText = 'downloading...' ;
151
+ }
152
+
153
+ if ( typeof blob === 'string' ) return download ( blob , name , opts ) ;
154
+ var force = blob . type === 'application/octet-stream' ;
155
+
156
+ var isSafari = / c o n s t r u c t o r / i. test ( _global . HTMLElement ) || _global . safari ;
157
+
158
+ var isChromeIOS = / C r i O S \/ [ \d ] + / . test ( navigator . userAgent ) ;
159
+
160
+ if ( ( isChromeIOS || force && isSafari || isMacOSWebView ) && typeof FileReader !== 'undefined' ) {
161
+ // Safari doesn't allow downloading of blob URLs
162
+ var reader = new FileReader ( ) ;
163
+
164
+ reader . onloadend = function ( ) {
165
+ var url = reader . result ;
166
+ url = isChromeIOS ? url : url . replace ( / ^ d a t a : [ ^ ; ] * ; / , 'data:attachment/file;' ) ;
167
+ if ( popup ) popup . location . href = url ; else location = url ;
168
+ popup = null ; // reverse-tabnabbing #460
169
+ } ;
170
+
171
+ reader . readAsDataURL ( blob ) ;
172
+ } else {
173
+ var URL = _global . URL || _global . webkitURL ;
174
+ var url = URL . createObjectURL ( blob ) ;
175
+ if ( popup ) popup . location = url ; else location . href = url ;
176
+ popup = null ; // reverse-tabnabbing #460
177
+
178
+ setTimeout ( function ( ) {
179
+ URL . revokeObjectURL ( url ) ;
180
+ } , 4E4 ) ; // 40s
181
+ }
182
+ } ) ;
183
+ _global . saveAs = saveAs . saveAs = saveAs ;
184
+
185
+ if ( typeof module !== 'undefined' ) {
186
+ module . exports = saveAs ;
187
+ }
188
+ } ) ;
0 commit comments