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