1/* FileSaver.js 2 * A saveAs() FileSaver implementation. 3 * 1.3.2 4 * 2016-06-16 18:25:19 5 * 6 * By Eli Grey, http://eligrey.com 7 * License: MIT 8 * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md 9 */ 10 11/*global self */ 12/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ 13 14/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ 15 16var saveAs = saveAs || (function(view) { 17 "use strict"; 18 // IE <10 is explicitly unsupported 19 if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { 20 return; 21 } 22 var 23 doc = view.document 24 // only get URL when necessary in case Blob.js hasn't overridden it yet 25 , get_URL = function() { 26 return view.URL || view.webkitURL || view; 27 } 28 , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") 29 , can_use_save_link = "download" in save_link 30 , click = function(node) { 31 var event = new MouseEvent("click"); 32 node.dispatchEvent(event); 33 } 34 , is_safari = /constructor/i.test(view.HTMLElement) 35 , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) 36 , throw_outside = function(ex) { 37 (view.setImmediate || view.setTimeout)(function() { 38 throw ex; 39 }, 0); 40 } 41 , force_saveable_type = "application/octet-stream" 42 // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to 43 , arbitrary_revoke_timeout = 1000 * 40 // in ms 44 , revoke = function(file) { 45 var revoker = function() { 46 if (typeof file === "string") { // file is an object URL 47 get_URL().revokeObjectURL(file); 48 } else { // file is a File 49 file.remove(); 50 } 51 }; 52 setTimeout(revoker, arbitrary_revoke_timeout); 53 } 54 , dispatch = function(filesaver, event_types, event) { 55 event_types = [].concat(event_types); 56 var i = event_types.length; 57 while (i--) { 58 var listener = filesaver["on" + event_types[i]]; 59 if (typeof listener === "function") { 60 try { 61 listener.call(filesaver, event || filesaver); 62 } catch (ex) { 63 throw_outside(ex); 64 } 65 } 66 } 67 } 68 , auto_bom = function(blob) { 69 // prepend BOM for UTF-8 XML and text/* types (including HTML) 70 // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF 71 if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { 72 return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); 73 } 74 return blob; 75 } 76 , FileSaver = function(blob, name, no_auto_bom) { 77 console.log('FileSaver function(blob, name, no_auto_bom): ',blob, name, no_auto_bom); 78 if (!no_auto_bom) { 79 blob = auto_bom(blob); 80 } 81 // First try a.download, then web filesystem, then object URLs 82 var 83 filesaver = this 84 , type = blob.type 85 , force = type === force_saveable_type 86 , object_url 87 , dispatch_all = function() { 88 dispatch(filesaver, "writestart progress write writeend".split(" ")); 89 } 90 // on any filesys errors revert to saving with object URLs 91 , fs_error = function() { 92 if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { 93 // Safari doesn't allow downloading of blob urls 94 var reader = new FileReader(); 95 reader.onloadend = function() { 96 var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); 97 var popup = view.open(url, '_blank'); 98 if(!popup) view.location.href = url; 99 url=undefined; // release reference before dispatching 100 filesaver.readyState = filesaver.DONE; 101 dispatch_all(); 102 }; 103 reader.readAsDataURL(blob); 104 filesaver.readyState = filesaver.INIT; 105 return; 106 } 107 // don't create more object URLs than needed 108 if (!object_url) { 109 object_url = get_URL().createObjectURL(blob); 110 } 111 if (force) { 112 view.location.href = object_url; 113 } else { 114 var opened = view.open(object_url, "_blank"); 115 if (!opened) { 116 // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html 117 view.location.href = object_url; 118 } 119 } 120 filesaver.readyState = filesaver.DONE; 121 dispatch_all(); 122 revoke(object_url); 123 } 124 ; 125 filesaver.readyState = filesaver.INIT; 126 127 if (can_use_save_link) { 128 object_url = get_URL().createObjectURL(blob); 129 setTimeout(function() { 130 save_link.href = object_url;
131 save_link.download = name; 132 click(save_link); 133 dispatch_all(); 134 revoke(object_url); 135 filesaver.readyState = filesaver.DONE; 136 }); 137 return; 138 } 139 140 fs_error(); 141 } 142 , FS_proto = FileSaver.prototype 143 , saveAs = function(blob, name, no_auto_bom) { 144 return new FileSaver(blob, name || blob.name || "download", no_auto_bom); 145 } 146 ; 147 // IE 10+ (native saveAs) 148 if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { 149 return function(blob, name, no_auto_bom) { 150 name = name || blob.name || "download"; 151 152 if (!no_auto_bom) { 153 blob = auto_bom(blob); 154 } 155 return navigator.msSaveOrOpenBlob(blob, name); 156 }; 157 } 158 159 FS_proto.abort = function(){}; 160 FS_proto.readyState = FS_proto.INIT = 0; 161 FS_proto.WRITING = 1; 162 FS_proto.DONE = 2; 163 164 FS_proto.error = 165 FS_proto.onwritestart = 166 FS_proto.onprogress = 167 FS_proto.onwrite = 168 FS_proto.onabort = 169 FS_proto.onerror = 170 FS_proto.onwriteend = 171 null; 172 173 return saveAs; 174}( 175 typeof self !== "undefined" && self 176 || typeof window !== "undefined" && window 177 || this.content 178)); 179// `self` is undefined in Firefox for Android content script context 180// while `this` is nsIContentFrameMessageManager 181// with an attribute `content` that corresponds to the window 182 183if (typeof module !== "undefined" && module.exports) { 184 module.exports.saveAs = saveAs; 185} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) { 186 define([], function() { 187 return saveAs; 188 }); 189}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.