郑许地铁

FileSaver.js 7.0KB

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