Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ed507ef8a | ||
|
|
eb8d76f845 | ||
|
|
8739c467c6 | ||
|
|
d8870ded68 | ||
|
|
9751591281 | ||
|
|
b3cad8efea | ||
|
|
3843680045 | ||
|
|
4ac2c6d6c2 | ||
|
|
f1a8bf9fb0 | ||
|
|
b2bf6d86f5 | ||
|
|
0b137cf80a | ||
|
|
d84a5c2f3a | ||
|
|
47ff4cd74a | ||
|
|
c0c85f387b | ||
|
|
3eeddf1145 | ||
|
|
bc0ba24aaa | ||
|
|
ae387dbbac | ||
|
|
b610731175 | ||
|
|
9aee871752 | ||
|
|
1bb6b90443 | ||
|
|
a5a0ae83db | ||
|
|
8e64e56f47 | ||
|
|
53b6226cb8 | ||
|
|
e9d9413814 | ||
|
|
3937bb4c33 | ||
|
|
8407c874d2 | ||
|
|
d2b5086afc | ||
|
|
597b6cd020 | ||
|
|
242c1dccc1 | ||
|
|
89a12bd9ac | ||
|
|
3247084327 | ||
|
|
cb8e076073 | ||
|
|
7b242c2d78 |
+27
-119
@@ -1,6 +1,7 @@
|
|||||||
/* FileSaver.js
|
/* FileSaver.js
|
||||||
* A saveAs() FileSaver implementation.
|
* A saveAs() FileSaver implementation.
|
||||||
* 1.2.0
|
* 1.3.2
|
||||||
|
* 2016-06-16 18:25:19
|
||||||
*
|
*
|
||||||
* By Eli Grey, http://eligrey.com
|
* By Eli Grey, http://eligrey.com
|
||||||
* License: MIT
|
* License: MIT
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
var saveAs = saveAs || (function(view) {
|
var saveAs = saveAs || (function(view) {
|
||||||
"use strict";
|
"use strict";
|
||||||
// IE <10 is explicitly unsupported
|
// IE <10 is explicitly unsupported
|
||||||
if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
|
if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
@@ -30,16 +31,14 @@ var saveAs = saveAs || (function(view) {
|
|||||||
var event = new MouseEvent("click");
|
var event = new MouseEvent("click");
|
||||||
node.dispatchEvent(event);
|
node.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
, is_safari = /Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
|
, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
|
||||||
, webkit_req_fs = view.webkitRequestFileSystem
|
, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
|
||||||
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
|
|
||||||
, throw_outside = function(ex) {
|
, throw_outside = function(ex) {
|
||||||
(view.setImmediate || view.setTimeout)(function() {
|
(view.setImmediate || view.setTimeout)(function() {
|
||||||
throw ex;
|
throw ex;
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
, force_saveable_type = "application/octet-stream"
|
, force_saveable_type = "application/octet-stream"
|
||||||
, fs_min_size = 0
|
|
||||||
// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
|
// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
|
||||||
, arbitrary_revoke_timeout = 1000 * 40 // in ms
|
, arbitrary_revoke_timeout = 1000 * 40 // in ms
|
||||||
, revoke = function(file) {
|
, revoke = function(file) {
|
||||||
@@ -50,22 +49,6 @@ var saveAs = saveAs || (function(view) {
|
|||||||
file.remove();
|
file.remove();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/* // Take note W3C:
|
|
||||||
var
|
|
||||||
uri = typeof file === "string" ? file : file.toURL()
|
|
||||||
, revoker = function(evt) {
|
|
||||||
// idealy DownloadFinishedEvent.data would be the URL requested
|
|
||||||
if (evt.data === uri) {
|
|
||||||
if (typeof file === "string") { // file is an object URL
|
|
||||||
get_URL().revokeObjectURL(file);
|
|
||||||
} else { // file is a File
|
|
||||||
file.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
view.addEventListener("downloadfinished", revoker);
|
|
||||||
*/
|
|
||||||
setTimeout(revoker, arbitrary_revoke_timeout);
|
setTimeout(revoker, arbitrary_revoke_timeout);
|
||||||
}
|
}
|
||||||
, dispatch = function(filesaver, event_types, event) {
|
, dispatch = function(filesaver, event_types, event) {
|
||||||
@@ -84,8 +67,9 @@ var saveAs = saveAs || (function(view) {
|
|||||||
}
|
}
|
||||||
, auto_bom = function(blob) {
|
, auto_bom = function(blob) {
|
||||||
// prepend BOM for UTF-8 XML and text/* types (including HTML)
|
// prepend BOM for UTF-8 XML and text/* types (including HTML)
|
||||||
|
// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
|
||||||
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
|
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
|
||||||
return new Blob(["\xEF\xBB\xBF", blob], {type: blob.type});
|
return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
|
||||||
}
|
}
|
||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
@@ -97,20 +81,21 @@ var saveAs = saveAs || (function(view) {
|
|||||||
var
|
var
|
||||||
filesaver = this
|
filesaver = this
|
||||||
, type = blob.type
|
, type = blob.type
|
||||||
, blob_changed = false
|
, force = type === force_saveable_type
|
||||||
, object_url
|
, object_url
|
||||||
, target_view
|
|
||||||
, dispatch_all = function() {
|
, dispatch_all = function() {
|
||||||
dispatch(filesaver, "writestart progress write writeend".split(" "));
|
dispatch(filesaver, "writestart progress write writeend".split(" "));
|
||||||
}
|
}
|
||||||
// on any filesys errors revert to saving with object URLs
|
// on any filesys errors revert to saving with object URLs
|
||||||
, fs_error = function() {
|
, fs_error = function() {
|
||||||
if (target_view && is_safari && typeof FileReader !== "undefined") {
|
if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
|
||||||
// Safari doesn't allow downloading of blob urls
|
// Safari doesn't allow downloading of blob urls
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onloadend = function() {
|
reader.onloadend = function() {
|
||||||
var base64Data = reader.result;
|
var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
|
||||||
target_view.location.href = "data:attachment/file" + base64Data.slice(base64Data.search(/[,;]/));
|
var popup = view.open(url, '_blank');
|
||||||
|
if(!popup) view.location.href = url;
|
||||||
|
url=undefined; // release reference before dispatching
|
||||||
filesaver.readyState = filesaver.DONE;
|
filesaver.readyState = filesaver.DONE;
|
||||||
dispatch_all();
|
dispatch_all();
|
||||||
};
|
};
|
||||||
@@ -119,14 +104,14 @@ var saveAs = saveAs || (function(view) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// don't create more object URLs than needed
|
// don't create more object URLs than needed
|
||||||
if (blob_changed || !object_url) {
|
if (!object_url) {
|
||||||
object_url = get_URL().createObjectURL(blob);
|
object_url = get_URL().createObjectURL(blob);
|
||||||
}
|
}
|
||||||
if (target_view) {
|
if (force) {
|
||||||
target_view.location.href = object_url;
|
view.location.href = object_url;
|
||||||
} else {
|
} else {
|
||||||
var new_tab = view.open(object_url, "_blank");
|
var opened = view.open(object_url, "_blank");
|
||||||
if (new_tab === undefined && is_safari) {
|
if (!opened) {
|
||||||
// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
|
// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
|
||||||
view.location.href = object_url;
|
view.location.href = object_url;
|
||||||
}
|
}
|
||||||
@@ -135,20 +120,9 @@ var saveAs = saveAs || (function(view) {
|
|||||||
dispatch_all();
|
dispatch_all();
|
||||||
revoke(object_url);
|
revoke(object_url);
|
||||||
}
|
}
|
||||||
, abortable = function(func) {
|
|
||||||
return function() {
|
|
||||||
if (filesaver.readyState !== filesaver.DONE) {
|
|
||||||
return func.apply(this, arguments);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
, create_if_not_found = {create: true, exclusive: false}
|
|
||||||
, slice
|
|
||||||
;
|
;
|
||||||
filesaver.readyState = filesaver.INIT;
|
filesaver.readyState = filesaver.INIT;
|
||||||
if (!name) {
|
|
||||||
name = "download";
|
|
||||||
}
|
|
||||||
if (can_use_save_link) {
|
if (can_use_save_link) {
|
||||||
object_url = get_URL().createObjectURL(blob);
|
object_url = get_URL().createObjectURL(blob);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@@ -161,93 +135,27 @@ var saveAs = saveAs || (function(view) {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Object and web filesystem URLs have a problem saving in Google Chrome when
|
|
||||||
// viewed in a tab, so I force save with application/octet-stream
|
fs_error();
|
||||||
// http://code.google.com/p/chromium/issues/detail?id=91158
|
|
||||||
// Update: Google errantly closed 91158, I submitted it again:
|
|
||||||
// https://code.google.com/p/chromium/issues/detail?id=389642
|
|
||||||
if (view.chrome && type && type !== force_saveable_type) {
|
|
||||||
slice = blob.slice || blob.webkitSlice;
|
|
||||||
blob = slice.call(blob, 0, blob.size, force_saveable_type);
|
|
||||||
blob_changed = true;
|
|
||||||
}
|
|
||||||
// Since I can't be sure that the guessed media type will trigger a download
|
|
||||||
// in WebKit, I append .download to the filename.
|
|
||||||
// https://bugs.webkit.org/show_bug.cgi?id=65440
|
|
||||||
if (webkit_req_fs && name !== "download") {
|
|
||||||
name += ".download";
|
|
||||||
}
|
|
||||||
if (type === force_saveable_type || webkit_req_fs) {
|
|
||||||
target_view = view;
|
|
||||||
}
|
|
||||||
if (!req_fs) {
|
|
||||||
fs_error();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fs_min_size += blob.size;
|
|
||||||
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
|
|
||||||
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
|
|
||||||
var save = function() {
|
|
||||||
dir.getFile(name, create_if_not_found, abortable(function(file) {
|
|
||||||
file.createWriter(abortable(function(writer) {
|
|
||||||
writer.onwriteend = function(event) {
|
|
||||||
target_view.location.href = file.toURL();
|
|
||||||
filesaver.readyState = filesaver.DONE;
|
|
||||||
dispatch(filesaver, "writeend", event);
|
|
||||||
revoke(file);
|
|
||||||
};
|
|
||||||
writer.onerror = function() {
|
|
||||||
var error = writer.error;
|
|
||||||
if (error.code !== error.ABORT_ERR) {
|
|
||||||
fs_error();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
"writestart progress write abort".split(" ").forEach(function(event) {
|
|
||||||
writer["on" + event] = filesaver["on" + event];
|
|
||||||
});
|
|
||||||
writer.write(blob);
|
|
||||||
filesaver.abort = function() {
|
|
||||||
writer.abort();
|
|
||||||
filesaver.readyState = filesaver.DONE;
|
|
||||||
};
|
|
||||||
filesaver.readyState = filesaver.WRITING;
|
|
||||||
}), fs_error);
|
|
||||||
}), fs_error);
|
|
||||||
};
|
|
||||||
dir.getFile(name, {create: false}, abortable(function(file) {
|
|
||||||
// delete file if it already exists
|
|
||||||
file.remove();
|
|
||||||
save();
|
|
||||||
}), abortable(function(ex) {
|
|
||||||
if (ex.code === ex.NOT_FOUND_ERR) {
|
|
||||||
save();
|
|
||||||
} else {
|
|
||||||
fs_error();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}), fs_error);
|
|
||||||
}), fs_error);
|
|
||||||
}
|
}
|
||||||
, FS_proto = FileSaver.prototype
|
, FS_proto = FileSaver.prototype
|
||||||
, saveAs = function(blob, name, no_auto_bom) {
|
, saveAs = function(blob, name, no_auto_bom) {
|
||||||
return new FileSaver(blob, name, no_auto_bom);
|
return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
// IE 10+ (native saveAs)
|
// IE 10+ (native saveAs)
|
||||||
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
|
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
|
||||||
return function(blob, name, no_auto_bom) {
|
return function(blob, name, no_auto_bom) {
|
||||||
|
name = name || blob.name || "download";
|
||||||
|
|
||||||
if (!no_auto_bom) {
|
if (!no_auto_bom) {
|
||||||
blob = auto_bom(blob);
|
blob = auto_bom(blob);
|
||||||
}
|
}
|
||||||
return navigator.msSaveOrOpenBlob(blob, name || "download");
|
return navigator.msSaveOrOpenBlob(blob, name);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
FS_proto.abort = function() {
|
FS_proto.abort = function(){};
|
||||||
var filesaver = this;
|
|
||||||
filesaver.readyState = filesaver.DONE;
|
|
||||||
dispatch(filesaver, "abort");
|
|
||||||
};
|
|
||||||
FS_proto.readyState = FS_proto.INIT = 0;
|
FS_proto.readyState = FS_proto.INIT = 0;
|
||||||
FS_proto.WRITING = 1;
|
FS_proto.WRITING = 1;
|
||||||
FS_proto.DONE = 2;
|
FS_proto.DONE = 2;
|
||||||
@@ -274,7 +182,7 @@ var saveAs = saveAs || (function(view) {
|
|||||||
if (typeof module !== "undefined" && module.exports) {
|
if (typeof module !== "undefined" && module.exports) {
|
||||||
module.exports.saveAs = saveAs;
|
module.exports.saveAs = saveAs;
|
||||||
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
|
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
|
||||||
define([], function() {
|
define("FileSaver.js", function() {
|
||||||
return saveAs;
|
return saveAs;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
||||||
var saveAs=saveAs||function(e){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var t=e.document,n=function(){return e.URL||e.webkitURL||e},o=t.createElementNS("http://www.w3.org/1999/xhtml","a"),r="download"in o,i=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),c=e.webkitRequestFileSystem,d=e.requestFileSystem||c||e.mozRequestFileSystem,u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},f="application/octet-stream",s=0,l=4e4,v=function(e){var t=function(){"string"==typeof e?n().revokeObjectURL(e):e.remove()};setTimeout(t,l)},p=function(e,t,n){t=[].concat(t);for(var o=t.length;o--;){var r=e["on"+t[o]];if("function"==typeof r)try{r.call(e,n||e)}catch(i){u(i)}}},w=function(e){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob(["\xEF\xBB\xBF",e],{type:e.type}):e},y=function(t,u,l){l||(t=w(t));var y,m,S,h=this,R=t.type,O=!1,g=function(){p(h,"writestart progress write writeend".split(" "))},b=function(){if(m&&a&&"undefined"!=typeof FileReader){var o=new FileReader;return o.onloadend=function(){var e=o.result;m.location.href="data:attachment/file"+e.slice(e.search(/[,;]/)),h.readyState=h.DONE,g()},o.readAsDataURL(t),void(h.readyState=h.INIT)}if(!O&&y||(y=n().createObjectURL(t)),m)m.location.href=y;else{var r=e.open(y,"_blank");void 0===r&&a&&(e.location.href=y)}h.readyState=h.DONE,g(),v(y)},E=function(e){return function(){return h.readyState!==h.DONE?e.apply(this,arguments):void 0}},N={create:!0,exclusive:!1};return h.readyState=h.INIT,u||(u="download"),r?(y=n().createObjectURL(t),void setTimeout(function(){o.href=y,o.download=u,i(o),g(),v(y),h.readyState=h.DONE})):(e.chrome&&R&&R!==f&&(S=t.slice||t.webkitSlice,t=S.call(t,0,t.size,f),O=!0),c&&"download"!==u&&(u+=".download"),(R===f||c)&&(m=e),d?(s+=t.size,void d(e.TEMPORARY,s,E(function(e){e.root.getDirectory("saved",N,E(function(e){var n=function(){e.getFile(u,N,E(function(e){e.createWriter(E(function(n){n.onwriteend=function(t){m.location.href=e.toURL(),h.readyState=h.DONE,p(h,"writeend",t),v(e)},n.onerror=function(){var e=n.error;e.code!==e.ABORT_ERR&&b()},"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=h["on"+e]}),n.write(t),h.abort=function(){n.abort(),h.readyState=h.DONE},h.readyState=h.WRITING}),b)}),b)};e.getFile(u,{create:!1},E(function(e){e.remove(),n()}),E(function(e){e.code===e.NOT_FOUND_ERR?n():b()}))}),b)}),b)):void b())},m=y.prototype,S=function(e,t,n){return new y(e,t,n)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t,n){return n||(e=w(e)),navigator.msSaveOrOpenBlob(e,t||"download")}:(m.abort=function(){var e=this;e.readyState=e.DONE,p(e,"abort")},m.readyState=m.INIT=0,m.WRITING=1,m.DONE=2,m.error=m.onwritestart=m.onprogress=m.onwrite=m.onabort=m.onerror=m.onwriteend=null,S)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!==define.amd&&define([],function(){return saveAs});
|
var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
The MIT License
|
||||||
|
|
||||||
Copyright © 2016 [Eli Grey][1].
|
Copyright © 2016 [Eli Grey][1].
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
|
If you need to save really large files bigger then the blob's size limitation or don't have
|
||||||
|
enough RAM, then have a look at the more advanced [StreamSaver.js](https://github.com/jimmywarting/StreamSaver.js)
|
||||||
|
that can save data directly to the hard drive asynchronously with the power of the new streams API. That will have
|
||||||
|
support for progress, cancelation and knowing when it's done writing
|
||||||
|
|
||||||
FileSaver.js
|
FileSaver.js
|
||||||
============
|
============
|
||||||
|
|
||||||
FileSaver.js implements the HTML5 W3C `saveAs()` FileSaver interface in browsers that do
|
FileSaver.js implements the `saveAs()` FileSaver interface in browsers that do
|
||||||
not natively support it. There is a [FileSaver.js demo][1] that demonstrates saving
|
not natively support it. There is a [FileSaver.js demo][1] that demonstrates saving
|
||||||
various media types.
|
various media types.
|
||||||
|
|
||||||
@@ -54,7 +59,7 @@ Syntax
|
|||||||
------
|
------
|
||||||
|
|
||||||
```js
|
```js
|
||||||
FileSaver saveAs(Blob data, DOMString filename, optional Boolean disableAutoBOM)
|
FileSaver saveAs(Blob/File data, optional DOMString filename, optional Boolean disableAutoBOM)
|
||||||
```
|
```
|
||||||
|
|
||||||
Pass `true` for `disableAutoBOM` if you don't want FileSaver.js to automatically provide Unicode text encoding hints (see: [byte order mark](https://en.wikipedia.org/wiki/Byte_order_mark)).
|
Pass `true` for `disableAutoBOM` if you don't want FileSaver.js to automatically provide Unicode text encoding hints (see: [byte order mark](https://en.wikipedia.org/wiki/Byte_order_mark)).
|
||||||
@@ -85,6 +90,19 @@ canvas.toBlob(function(blob) {
|
|||||||
Note: The standard HTML5 `canvas.toBlob()` method is not available in all browsers.
|
Note: The standard HTML5 `canvas.toBlob()` method is not available in all browsers.
|
||||||
[canvas-toBlob.js][6] is a cross-browser `canvas.toBlob()` that polyfills this.
|
[canvas-toBlob.js][6] is a cross-browser `canvas.toBlob()` that polyfills this.
|
||||||
|
|
||||||
|
### Saving File
|
||||||
|
|
||||||
|
You can save a File constructor without specifying a filename. The
|
||||||
|
File itself already contains a name, There is a hand full of ways to get a file
|
||||||
|
instance (from storage, file input, new constructor)
|
||||||
|
But if you still want to change the name, then you can change it in the 2nd argument
|
||||||
|
|
||||||
|
```js
|
||||||
|
var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});
|
||||||
|
saveAs(file);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -102,11 +120,16 @@ The `FileSaver.js` distribution file is compiled with Uglify.js like so:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
uglifyjs FileSaver.js --mangle --comments /@source/ > FileSaver.min.js
|
uglifyjs FileSaver.js --mangle --comments /@source/ > FileSaver.min.js
|
||||||
|
# or simply:
|
||||||
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
Please make sure you build a production version before submitting a pull request.
|
Please make sure you build a production version before submitting a pull request.
|
||||||
|
|
||||||
Bower Installation
|
Installation
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Please see the [this repo](http://github.com/Teleborder/FileSaver.js) for a bower-compatible fork of FileSaver.js, available under the package name `file-saver.js`.
|
```bash
|
||||||
|
npm install file-saver --save
|
||||||
|
bower install file-saver
|
||||||
|
```
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "file-saver",
|
||||||
|
"main": "FileSaver.js",
|
||||||
|
"version": "1.3.3",
|
||||||
|
"homepage": "https://github.com/eligrey/FileSaver.js",
|
||||||
|
"authors": [
|
||||||
|
"Eli Grey <[email protected]>"
|
||||||
|
],
|
||||||
|
"description": "An HTML5 saveAs() FileSaver implementation",
|
||||||
|
"keywords": [
|
||||||
|
"filesaver",
|
||||||
|
"saveas",
|
||||||
|
"blob"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"ignore": [
|
||||||
|
"*",
|
||||||
|
"!FileSaver.*js",
|
||||||
|
"!LICENSE.md"
|
||||||
|
]
|
||||||
|
}
|
||||||
Regular → Executable
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
/*! FileSaver.js demo script
|
/*! FileSaver.js demo script
|
||||||
* 2012-01-23
|
* 2016-05-26
|
||||||
*
|
*
|
||||||
* By Eli Grey, http://eligrey.com
|
* By Eli Grey, http://eligrey.com
|
||||||
* License: X11/MIT
|
* License: MIT
|
||||||
* See LICENSE.md
|
* See LICENSE.md
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ canvas.addEventListener("mouseout", stop_drawing, false);
|
|||||||
|
|
||||||
canvas_options_form.addEventListener("submit", function(event) {
|
canvas_options_form.addEventListener("submit", function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
canvas.toBlob(function(blob) {
|
canvas.toBlobHD(function(blob) {
|
||||||
saveAs(
|
saveAs(
|
||||||
blob
|
blob
|
||||||
, (canvas_filename.value || canvas_filename.placeholder) + ".png"
|
, (canvas_filename.value || canvas_filename.placeholder) + ".png"
|
||||||
@@ -195,7 +195,7 @@ html_options_form.addEventListener("submit", function(event) {
|
|||||||
saveAs(
|
saveAs(
|
||||||
new BB(
|
new BB(
|
||||||
[xml_serializer.serializeToString(doc)]
|
[xml_serializer.serializeToString(doc)]
|
||||||
, {type: "application/xhtml+xml;charset=" + document.characterSet}
|
, {type: "text/plain;charset=" + document.characterSet}
|
||||||
)
|
)
|
||||||
, (html_filename.value || html_filename.placeholder) + ".xhtml"
|
, (html_filename.value || html_filename.placeholder) + ".xhtml"
|
||||||
);
|
);
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/demo/demo.js */
|
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/demo/demo.js */
|
||||||
(function(n){"use strict";var s=n.document,g=function(A){return s.getElementById(A)},b=n.sessionStorage,x=function(){return n.Blob},f=g("canvas"),r=g("canvas-options"),y=g("canvas-filename"),p=g("canvas-clear"),q=g("text"),t=g("text-options"),h=g("text-filename"),m=g("html"),e=g("html-options"),i=g("html-filename"),u=f.getContext("2d"),z=false,a=b.x_points||[],o=b.y_points||[],d=b.drag_points||[],j=function(A,C,B){a.push(A);o.push(C);d.push(B)},l=function(){f.width=f.width;u.lineWidth=6;u.lineJoin="round";u.strokeStyle="#000000";var B=0,A=a.length;for(;B<A;B++){u.beginPath();if(B&&d[B]){u.moveTo(a[B-1],o[B-1])}else{u.moveTo(a[B]-1,o[B])}u.lineTo(a[B],o[B]);u.closePath();u.stroke()}},c=function(){z=false},w=function(E){var D="h6 h5 h4 h3 h2 h1".split(" "),C=D.length,F,G;while(C--){F=E.getElementsByTagName(D[C]);for(var B=0,A=F.length;B<A;B++){G=F[B].textContent.trim();if(G){return G}}}},v=s.implementation,k=function(D){var B=v.createDocumentType("html",null,null),J=v.createDocument("http://www.w3.org/1999/xhtml","html",B),A=J.documentElement,H=A.appendChild(J.createElement("head")),K=H.appendChild(J.createElement("meta")),I=H.appendChild(J.createElement("title")),E=A.appendChild(J.createElement("body")),C=0,G=D.childNodes.length;K.setAttribute("charset",D.ownerDocument.characterSet);for(;C<G;C++){E.appendChild(J.importNode(D.childNodes.item(C),true))}var F=w(J);if(F){I.appendChild(J.createTextNode(F))}return J};f.width=500;f.height=300;if(typeof a==="string"){a=JSON.parse(a)}if(typeof o==="string"){o=JSON.parse(o)}if(typeof d==="string"){d=JSON.parse(d)}if(b.canvas_filename){y.value=b.canvas_filename}if(b.text){q.value=b.text}if(b.text_filename){h.value=b.text_filename}if(b.html){m.innerHTML=b.html}if(b.html_filename){i.value=b.html_filename}z=true;l();z=false;p.addEventListener("click",function(){f.width=f.width;a.length=o.length=d.length=0},false);f.addEventListener("mousedown",function(A){A.preventDefault();z=true;j(A.pageX-f.offsetLeft,A.pageY-f.offsetTop,false);l()},false);f.addEventListener("mousemove",function(A){if(z){j(A.pageX-f.offsetLeft,A.pageY-f.offsetTop,true);l()}},false);f.addEventListener("mouseup",c,false);f.addEventListener("mouseout",c,false);r.addEventListener("submit",function(A){A.preventDefault();f.toBlob(function(B){saveAs(B,(y.value||y.placeholder)+".png")},"image/png")},false);t.addEventListener("submit",function(A){A.preventDefault();var B=x();saveAs(new B([q.value||q.placeholder],{type:"text/plain;charset="+s.characterSet}),(h.value||h.placeholder)+".txt")},false);e.addEventListener("submit",function(B){B.preventDefault();var D=x(),A=new XMLSerializer,C=k(m);saveAs(new D([A.serializeToString(C)],{type:"application/xhtml+xml;charset="+s.characterSet}),(i.value||i.placeholder)+".xhtml")},false);n.addEventListener("unload",function(){b.x_points=JSON.stringify(a);b.y_points=JSON.stringify(o);b.drag_points=JSON.stringify(d);b.canvas_filename=y.value;b.text=q.value;b.text_filename=h.value;b.html=m.innerHTML;b.html_filename=i.value},false)}(self));
|
(function(n){"use strict";var s=n.document,g=function(A){return s.getElementById(A)},b=n.sessionStorage,x=function(){return n.Blob},f=g("canvas"),r=g("canvas-options"),y=g("canvas-filename"),p=g("canvas-clear"),q=g("text"),t=g("text-options"),h=g("text-filename"),m=g("html"),e=g("html-options"),i=g("html-filename"),u=f.getContext("2d"),z=false,a=b.x_points||[],o=b.y_points||[],d=b.drag_points||[],j=function(A,C,B){a.push(A);o.push(C);d.push(B)},l=function(){f.width=f.width;u.lineWidth=6;u.lineJoin="round";u.strokeStyle="#000000";var B=0,A=a.length;for(;B<A;B++){u.beginPath();if(B&&d[B]){u.moveTo(a[B-1],o[B-1])}else{u.moveTo(a[B]-1,o[B])}u.lineTo(a[B],o[B]);u.closePath();u.stroke()}},c=function(){z=false},w=function(E){var D="h6 h5 h4 h3 h2 h1".split(" "),C=D.length,F,G;while(C--){F=E.getElementsByTagName(D[C]);for(var B=0,A=F.length;B<A;B++){G=F[B].textContent.trim();if(G){return G}}}},v=s.implementation,k=function(D){var B=v.createDocumentType("html",null,null),J=v.createDocument("http://www.w3.org/1999/xhtml","html",B),A=J.documentElement,H=A.appendChild(J.createElement("head")),K=H.appendChild(J.createElement("meta")),I=H.appendChild(J.createElement("title")),E=A.appendChild(J.createElement("body")),C=0,G=D.childNodes.length;K.setAttribute("charset",D.ownerDocument.characterSet);for(;C<G;C++){E.appendChild(J.importNode(D.childNodes.item(C),true))}var F=w(J);if(F){I.appendChild(J.createTextNode(F))}return J};f.width=500;f.height=300;if(typeof a==="string"){a=JSON.parse(a)}if(typeof o==="string"){o=JSON.parse(o)}if(typeof d==="string"){d=JSON.parse(d)}if(b.canvas_filename){y.value=b.canvas_filename}if(b.text){q.value=b.text}if(b.text_filename){h.value=b.text_filename}if(b.html){m.innerHTML=b.html}if(b.html_filename){i.value=b.html_filename}z=true;l();z=false;p.addEventListener("click",function(){f.width=f.width;a.length=o.length=d.length=0},false);f.addEventListener("mousedown",function(A){A.preventDefault();z=true;j(A.pageX-f.offsetLeft,A.pageY-f.offsetTop,false);l()},false);f.addEventListener("mousemove",function(A){if(z){j(A.pageX-f.offsetLeft,A.pageY-f.offsetTop,true);l()}},false);f.addEventListener("mouseup",c,false);f.addEventListener("mouseout",c,false);r.addEventListener("submit",function(A){A.preventDefault();f.toBlobHD(function(B){saveAs(B,(y.value||y.placeholder)+".png")},"image/png")},false);t.addEventListener("submit",function(A){A.preventDefault();var B=x();saveAs(new B([q.value||q.placeholder],{type:"text/plain;charset="+s.characterSet}),(h.value||h.placeholder)+".txt")},false);e.addEventListener("submit",function(B){B.preventDefault();var D=x(),A=new XMLSerializer,C=k(m);saveAs(new D([A.serializeToString(C)],{type:"text/plain;charset="+s.characterSet}),(i.value||i.placeholder)+".xhtml")},false);n.addEventListener("unload",function(){b.x_points=JSON.stringify(a);b.y_points=JSON.stringify(o);b.drag_points=JSON.stringify(d);b.canvas_filename=y.value;b.text=q.value;b.text_filename=h.value;b.html=m.innerHTML;b.html_filename=i.value},false)}(self));
|
||||||
+5
-5
@@ -3,12 +3,12 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<title>FileSaver.js demo</title>
|
<title>FileSaver.js demo</title>
|
||||||
<link rel="stylesheet" type="text/css" href="demo.css"/>
|
<link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/eligrey/FileSaver.js/702cd2e820b680f88a0f299e33085c196806fc52/demo/demo.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1><a href="https://github.com/eligrey/FileSaver.js">FileSaver.js</a> demo</h1>
|
<h1><a href="https://github.com/eligrey/FileSaver.js">FileSaver.js</a> demo</h1>
|
||||||
<p>
|
<p>
|
||||||
The following examples demonstrate how it is possible to generate and save any type of data right in the browser using the W3C <code>saveAs()</code> FileSaver interface, without contacting any servers.
|
The following examples demonstrate how it is possible to generate and save any type of data right in the browser using the <code>saveAs()</code> FileSaver interface, without contacting any servers.
|
||||||
</p>
|
</p>
|
||||||
<section id="image-demo">
|
<section id="image-demo">
|
||||||
<h2>Saving an image</h2>
|
<h2>Saving an image</h2>
|
||||||
@@ -50,8 +50,8 @@
|
|||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
<script async="" src="https://cdn.rawgit.com/eligrey/Blob.js/0cef2746414269b16834878a8abc52eb9d53e6bd/Blob.js"/>
|
<script async="" src="https://cdn.rawgit.com/eligrey/Blob.js/0cef2746414269b16834878a8abc52eb9d53e6bd/Blob.js"/>
|
||||||
<script async="" src="https://cdn.rawgit.com/eligrey/canvas-toBlob.js/8316fb3ee6d67f68f44089a82ab87bf580d2a5e3/canvas-toBlob.js"/>
|
<script async="" src="https://cdn.rawgit.com/eligrey/canvas-toBlob.js/f1a01896135ab378aa5c0118eadd81da55e698d8/canvas-toBlob.js"/>
|
||||||
<script async="" src="https://cdn.rawgit.com/eligrey/FileSaver.js/62d219a0fac54b94cd4f230e7bfc55aa3f8dcfa4/FileSaver.js"/>
|
<script async="" src="https://cdn.rawgit.com/eligrey/FileSaver.js/e9d941381475b5df8b7d7691013401e171014e89/FileSaver.min.js"/>
|
||||||
<script async="" src="https://cdn.rawgit.com/eligrey/FileSaver.js/702cd2e820b680f88a0f299e33085c196806fc52/demo/demo.js"/>
|
<script async="" src="https://cdn.rawgit.com/eligrey/FileSaver.js/597b6cd0207ce408a6d34890b5b2826b13450714/demo/demo.js"/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "file-saver",
|
||||||
|
"version": "1.3.3",
|
||||||
|
"description": "An HTML5 saveAs() FileSaver implementation",
|
||||||
|
"main": "FileSaver.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 0",
|
||||||
|
"build": "node_modules/.bin/uglifyjs FileSaver.js --mangle --comments /@source/ > FileSaver.min.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/eligrey/FileSaver.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"filesaver",
|
||||||
|
"saveas",
|
||||||
|
"blob"
|
||||||
|
],
|
||||||
|
"author": "Eli Grey <[email protected]>",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/eligrey/FileSaver.js/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/eligrey/FileSaver.js#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"uglify-js": "^2.6.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user