PageSourceSearch

https://reurl.cc/asset/javascripts/common/file_saver.js

js reurl.cc collected 2026-09-24 08:23:53 UTC 12,238 bytes, 295 lines download raw bytes

1/* FileSaver.js
2 *  A saveAs() & saveTextAs() FileSaver implementation.
3 *  2014-06-24
4 *
5 *  Modify by Brian Chen
6 *  Author: Eli Grey, http://eligrey.com
7 *  License: X11/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
17  // IE 10+ (native saveAs)
18  || (typeof navigator !== "undefined" &&
19      navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
20  // Everyone else
21  || (function (view) {
22      "use strict";
23      // IE <10 is explicitly unsupported
24      if (typeof navigator !== "undefined" &&
25          /MSIE [1-9]\./.test(navigator.userAgent)) {
26          return;
27      }
28      var
29            doc = view.document
30            // only get URL when necessary in case Blob.js hasn't overridden it yet
31          , get_URL = function () {
32              return view.URL || view.webkitURL || view;
33          }
34          , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
35          , can_use_save_link = !view.externalHost && "download" in save_link
36          , click = function (node) {
37              var event = doc.createEvent("MouseEvents");
38              event.initMouseEvent(
39                  "click", true, false, view, 0, 0, 0, 0, 0
40                  , false, false, false, false, 0, null
41              );
42              node.dispatchEvent(event);
43          }
44          , webkit_req_fs = view.webkitRequestFileSystem
45          , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
46          , throw_outside = function (ex) {
47              (view.setImmediate || view.setTimeout)(function () {
48                  throw ex;
49              }, 0);
50          }
51          , force_saveable_type = "application/octet-stream"
52          , fs_min_size = 0
53          , deletion_queue = []
54          , process_deletion_queue = function () {
55              var i = deletion_queue.length;
56              while (i--) {
57                  var file = deletion_queue[i];
58                  if (typeof file === "string") { // file is an object URL
59                      get_URL().revokeObjectURL(file);
60                  } else { // file is a File
61                      file.remove();
62                  }
63              }
64              deletion_queue.length = 0; // clear queue
65          }
66          , dispatch = function (filesaver, event_types, event) {
67              event_types = [].concat(event_types);
68              var i = event_types.length;
69              while (i--) {
70                  var listener = filesaver["on" + event_types[i]];
71                  if (typeof listener === "function") {
72                      try {
73                          listener.call(filesaver, event || filesaver);
74                      } catch (ex) {
75                          throw_outside(ex);
76                      }
77                  }
78              }
79          }
80          , FileSaver = function (blob, name) {
81              // First try a.download, then web filesystem, then object URLs
82              var
83                    filesaver = this
84                  , type = blob.type
85                  , blob_changed = false
86                  , object_url
87                  , target_view
88                  , get_object_url = function () {
89                      var object_url = get_URL().createObjectURL(blob);
90                      deletion_queue.push(object_url);
91                      return object_url;
92                  }
93                  , dispatch_all = function () {
94                      dispatch(filesaver, "writestart progress write writeend".split(" "));
95                  }
96                  // on any filesys errors revert to saving with object URLs
97                  , fs_error = function () {
98                      // don't create more object URLs than needed
99                      if (blob_changed || !object_url) {
100                          object_url = get_object_url(blob);
101                      }
102                      if (target_view) {
103                          target_view.location.href = object_url;
104                      } else {
105                          window.open(object_url, "_blank");
106                      }
107                      filesaver.readyState = filesaver.DONE;
108                      dispatch_all();
109                  }
110                  , abortable = function (func) {
111                      return function () {
112                          if (filesaver.readyState !== filesaver.DONE) {
113                              return func.apply(this, arguments);
114                          }
115                      };
116                  }
117                  , create_if_not_found = { create: true, exclusive: false }
118                  , slice
119              ;
120              filesaver.readyState = filesaver.INIT;
121              if (!name) {
122                  name = "download";
123              }
124              if (can_use_save_link) {
125                  object_url = get_object_url(blob);
126                  save_link.href = object_url;
127                  save_link.download = name;
128                  click(save_link);
129                  filesaver.readyState = filesaver.DONE;
130                  dispatch_all();
131                  return;
132              }
133              // Object and web filesystem URLs have a problem saving in Google Chrome when
134              // viewed in a tab, so I force save with application/octet-stream
135              // http://code.google.com/p/chromium/issues/detail?id=91158
136              if (view.chrome && type && type !== force_saveable_type) {
137                  slice = blob.slice || blob.webkitSlice;
138                  blob = slice.call(blob, 0, blob.size, force_saveable_type);
139                  blob_changed = true;
140              }
141              // Since I can't be sure that the guessed media type will trigger a download
142              // in WebKit, I append .download to the filename.
143              // https://bugs.webkit.org/show_bug.cgi?id=65440
144              if (webkit_req_fs && name !== "download") {
145                  name += ".download";
146              }
147              if (type === force_saveable_type || webkit_req_fs) {
148                  target_view = view;
149              }
150              if (!req_fs) {
151                  fs_error();
152                  return;
153              }
154              fs_min_size += blob.size;
155              req_fs(view.TEMPORARY, fs_min_size, abortable(function (fs) {
156                  fs.root.getDirectory("saved", create_if_not_found, abortable(function (dir) {
157                      var save = function () {
158                          dir.getFile(name, create_if_not_found, abortable(function (file) {
159                              file.createWriter(abortable(function (writer) {
160                                  writer.onwriteend = function (event) {
161                                      target_view.location.href = file.toURL();
162                                      deletion_queue.push(file);
163                                      filesaver.readyState = filesaver.DONE;
164                                      dispatch(filesaver, "writeend", event);
165                                  };
166                                  writer.onerror = function () {
167                                      var error = writer.error;
168                                      if (error.code !== error.ABORT_ERR) {
169                                          fs_error();
170                                      }
171                                  };
172                                  "writestart progress write abort".split(" ").forEach(function (event) {
173                                      writer["on" + event] = filesaver["on" + event];
174                                  });
175                                  writer.write(blob);
176                                  filesaver.abort = function () {
177                                      writer.abort();
178                                      filesaver.readyState = filesaver.DONE;
179                                  };
180                                  filesaver.readyState = filesaver.WRITING;
181                              }), fs_error);
182                          }), fs_error);
183                      };
184                      dir.getFile(name, { create: false }, abortable(function (file) {
185                          // delete file if it already exists
186                          file.remove();
187                          save();
188                      }), abortable(function (ex) {
189                          if (ex.code === ex.NOT_FOUND_ERR) {
190                              save();
191                          } else {
192                              fs_error();
193                          }
194                      }));
195                  }), fs_error);
196              }), fs_error);
197          }
198          , FS_proto = FileSaver.prototype
199          , saveAs = function (blob, name) {
200              return new FileSaver(blob, name);
201          }
202      ;
203      FS_proto.abort = function () {
204          var filesaver = this;
205          filesaver.readyState = filesaver.DONE;
206          dispatch(filesaver, "abort");
207      };
208      FS_proto.readyState = FS_proto.INIT = 0;
209      FS_proto.WRITING = 1;
210      FS_proto.DONE = 2;
211
212      FS_proto.error =
213      FS_proto.onwritestart =
214      FS_proto.onprogress =
215      FS_proto.onwrite =
216      FS_proto.onabort =
217      FS_proto.onerror =
218      FS_proto.onwriteend =
219          null;
220
221      view.addEventListener("unload", process_deletion_queue, false);
222      saveAs.unload = function () {
223          process_deletion_queue();
224          view.removeEventListener("unload", process_deletion_queue, false);
225      };
226      return saveAs;
227  }(
228	   typeof self !== "undefined" && self
229	|| typeof window !== "undefined" && window
230	|| this.content
231));
232// `self` is undefined in Firefox for Android content script context
233// while `this` is nsIContentFrameMessageManager
234// with an attribute `content` that corresponds to the window
235
236if (typeof module !== "undefined" && module !== null) {
237    module.exports = saveAs;
238} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
239    define([], function () {
240        return saveAs;
241    });
242}
243
244String.prototype.endsWithAny = function () {
245    var strArray = Array.prototype.slice.call(arguments),
246        $this = this.toLowerCase().toString();
247    for (var i = 0; i < strArray.length; i++) {
248        if ($this.indexOf(strArray[i], $this.length - strArray[i].length) !== -1) return true;
249    }
250    return false;
251};
252
253var saveTextAs = saveTextAs
254|| (function (textContent, fileName, charset) {
255    fileName = fileName || 'download.txt';
256    charset = charset || 'utf-8';
257    textContent = (textContent || '').replace(/\r?\n/g, "\r\n");
258    if (saveAs && Blob) {
259        var blob = new Blob([textContent], { type: "text/plain;charset=" + charset });
260        saveAs(blob, fileName);
261        return true;
262    } else {//IE9-
263        var saveTxtWindow = window.frames.saveTxtWindow;
264        if (!saveTxtWindow) {
265            saveTxtWindow = document.createElement('iframe');
266            saveTxtWindow.id = 'saveTxtWindow';
267            saveTxtWindow.style.display = 'none';
268            document.body.insertBefore(saveTxtWindow, null);
269            saveTxtWindow = window.frames.saveTxtWindow;
270            if (!saveTxtWindow) {
271                saveTxtWindow = window.open('', '_temp', 'width=100,height=100');
272                if (!saveTxtWindow) {
273                    window.alert('Sorry, download file could not be created.');
274                    return false;
275                }
276            }
277        }
278
279        var doc = saveTxtWindow.document;
280        doc.open('text/html', 'replace');
281        doc.charset = charset;
282        if (fileName.endsWithAny('.htm', '.html')) {
283            doc.close();
284            doc.body.innerHTML = '\r\n' + textContent + '\r\n';
285        } else {
286            if (!fileName.endsWithAny('.txt')) fileName += '.txt';
287            doc.write(textContent);
288            doc.close();
289        }
290
291        var retValue = doc.execCommand('SaveAs', null, fileName);
292        saveTxtWindow.close();
293        return retValue;
294    }
295})

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.