13 Commits
Author SHA1 Message Date
Jimmy Wärting 0b9d514107 docs for using url 2018-09-21 16:26:24 +02:00
Jimmy Wärting 17403f0731 don’t crash in worker 2018-09-21 16:16:50 +02:00
Jimmy Wärting 0718d9f852 new version 2018-09-21 16:10:37 +02:00
Jimmy Wärting ae32ccca4d include the list folder 2018-09-21 14:56:39 +02:00
Jimmy Wärting dcdc67deec update dev rep 2018-09-21 14:56:20 +02:00
Jimmy Wärting 465b00f11b remove old demos 2018-09-21 14:54:47 +02:00
Owen BlackerandJimmy Wärting 5db588a568 Amended link to Apple's WebKit bug (#454)
WebKit bug №102914 is no longer the ticket referencing the "iOS can't do this" problem — that ticket has been closed since it was resolved on MacOS.

The appropriate WebKit bug ticket is №167341: [iOS] Add support for the download attribute, so I have updated the link appropriately.
2018-09-20 23:18:25 +02:00
Jimmy WärtingandGitHub 1144ac42bb Add precaution note about file constructor
closes #455
2018-08-07 19:44:51 +02:00
Eli GreyandGitHub 00e540fda5 Merge pull request #450 from ps011/master
Added import statement in syntax section for ease of use
2018-07-17 10:50:43 -07:00
Soni 23d400231f Added import statement in syntax section for ease of use 2018-07-03 14:31:01 +05:30
Eli Grey e865e37af9 Revert #408 2018-03-22 14:09:13 -07:00
Christopher HuntandJimmy Wärting a606064f37 Revert interface change. (#411) 2018-03-22 19:48:05 +01:00
Bryan WainandJimmy Wärting 28a86d90c4 Fix files included with npm (#413)
the files pointed to by main and module are not included in the npm installation
2018-03-22 19:47:45 +01:00
14 changed files with 351 additions and 3317 deletions
-19
View File
@@ -1,19 +0,0 @@
{
"presets": [
["env", {
"targets": {
"browsers": [
"ie > 9"
]
}
}]
],
"plugins": [
"transform-es2015-modules-umd"
],
"env": {
"production": {
"presets": ["minify"]
}
}
}
-3
View File
@@ -1,6 +1,3 @@
node_modules/ node_modules/
.DS_Store .DS_Store
.idea/ .idea/
# Generated files
/dist/
+21 -5
View File
@@ -54,16 +54,20 @@ press <kbd>⌘</kbd>+<kbd>S</kbd> to save the file after it is opened. Using the
### iOS ### iOS
saveAs must be run within a user interaction event such as onTouchDown or onClick; setTimeout will prevent saveAs from triggering. Due to restrictions in iOS saveAs opens in a new window instead of downloading, if you want this fixed please [tell Apple](https://bugs.webkit.org/show_bug.cgi?id=102914) how this bug is affecting you. saveAs must be run within a user interaction event such as onTouchDown or onClick; setTimeout will prevent saveAs from triggering. Due to restrictions in iOS saveAs opens in a new window instead of downloading, if you want this fixed please [tell Apple how this WebKit bug is affecting you](https://bugs.webkit.org/show_bug.cgi?id=167341).
Syntax Syntax
------ ------
### Import saveAs() from file-saver
```js ```js
FileSaver saveAs(Blob/File data, optional DOMString filename, optional Boolean disableAutoBOM) import { saveAs } from 'file-saver/FileSaver';
``` ```
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)). ```js
FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Boolean autoBOM)
```
Pass `true` for `autoBOM` 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)).
Examples Examples
-------- --------
@@ -82,6 +86,16 @@ var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "hello world.txt"); FileSaver.saveAs(blob, "hello world.txt");
``` ```
### Saving urls
```js
FileSaver.saveAs("https://httpbin.org/image", "image.jpg");
```
Using urls within the same origin will just use `a[download]`
Otherwise it will first check if it supports cors header with a synchronously head request
if it dose it will download the data and save it using blob urls
if not it will try to download it using `a[download]`
The standard W3C File API [`Blob`][4] interface is not available in all browsers. The standard W3C File API [`Blob`][4] interface is not available in all browsers.
[Blob.js][5] is a cross-browser `Blob` implementation that solves this. [Blob.js][5] is a cross-browser `Blob` implementation that solves this.
@@ -102,10 +116,12 @@ Note: The standard HTML5 `canvas.toBlob()` method is not available in all browse
You can save a File constructor without specifying a filename. The 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 File itself already contains a name, There is a hand full of ways to get a file
instance (from storage, file input, new constructor) instance (from storage, file input, new constructor, clipboard event)
But if you still want to change the name, then you can change it in the 2nd argument But if you still want to change the name, then you can change it in the 2nd argument
```js ```js
// Note: Ie and Edge don't support the new File constructor,
// so it's better to construct blobs and use saveAs(blob, filename)
var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"}); var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(file); FileSaver.saveAs(file);
``` ```
+3 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "file-saver", "name": "file-saver",
"main": "dist/FileSaver.js", "main": "dist/FileSaver.min.js",
"version": "1.3.7", "version": "2.0.0-rc.1",
"homepage": "https://github.com/eligrey/FileSaver.js", "homepage": "https://github.com/eligrey/FileSaver.js",
"authors": [ "authors": [
"Eli Grey <[email protected]>" "Eli Grey <[email protected]>"
@@ -16,6 +16,7 @@
"ignore": [ "ignore": [
"*", "*",
"!FileSaver.*js", "!FileSaver.*js",
"!FileSaver.*map",
"!LICENSE.md" "!LICENSE.md"
] ]
} }
-50
View File
@@ -1,50 +0,0 @@
html {
background-color: #DDD;
}
body {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
width: 900px;
margin: 0 auto;
font-family: Verdana, Helvetica, Arial, sans-serif;
-webkit-box-shadow: 0 0 10px 2px rgba(0, 0, 0, .5);
-moz-box-shadow: 0 0 10px 2px rgba(0, 0, 0, .5);
box-shadow: 0 0 10px 2px rgba(0, 0, 0, .5);
padding: 7px 25px 70px;
background-color: #FFF;
}
h1, h2, h3, h4, h5, h6 {
font-family: Georgia, "Times New Roman", serif;
}
h2, form {
text-align: center;
}
form {
margin-top: 5px;
}
.input {
width: 500px;
height: 300px;
margin: 0 auto;
display: block;
}
section {
margin-top: 40px;
}
#canvas {
cursor: crosshair;
}
#canvas, #html {
border: 1px solid #000;
}
.filename {
text-align: right;
}
#html {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: auto;
padding: 1em;
}
-216
View File
@@ -1,216 +0,0 @@
/*! FileSaver.js demo script
* 2016-05-26
*
* By Eli Grey, http://eligrey.com
* License: MIT
* See LICENSE.md
*/
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/demo/demo.js */
/*jshint laxbreak: true, laxcomma: true, smarttabs: true*/
/*global saveAs, self*/
(function(view) {
"use strict";
// The canvas drawing portion of the demo is based off the demo at
// http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/
var
document = view.document
, $ = function(id) {
return document.getElementById(id);
}
, session = view.sessionStorage
// only get URL when necessary in case Blob.js hasn't defined it yet
, get_blob = function() {
return view.Blob;
}
, canvas = $("canvas")
, canvas_options_form = $("canvas-options")
, canvas_filename = $("canvas-filename")
, canvas_clear_button = $("canvas-clear")
, text = $("text")
, text_options_form = $("text-options")
, text_filename = $("text-filename")
, html = $("html")
, html_options_form = $("html-options")
, html_filename = $("html-filename")
, ctx = canvas.getContext("2d")
, drawing = false
, x_points = session.x_points || []
, y_points = session.y_points || []
, drag_points = session.drag_points || []
, add_point = function(x, y, dragging) {
x_points.push(x);
y_points.push(y);
drag_points.push(dragging);
}
, draw = function(){
canvas.width = canvas.width;
ctx.lineWidth = 6;
ctx.lineJoin = "round";
ctx.strokeStyle = "#000000";
var
i = 0
, len = x_points.length
;
for(; i < len; i++) {
ctx.beginPath();
if (i && drag_points[i]) {
ctx.moveTo(x_points[i-1], y_points[i-1]);
} else {
ctx.moveTo(x_points[i]-1, y_points[i]);
}
ctx.lineTo(x_points[i], y_points[i]);
ctx.closePath();
ctx.stroke();
}
}
, stop_drawing = function() {
drawing = false;
}
// Title guesser and document creator available at https://gist.github.com/1059648
, guess_title = function(doc) {
var
h = "h6 h5 h4 h3 h2 h1".split(" ")
, i = h.length
, headers
, header_text
;
while (i--) {
headers = doc.getElementsByTagName(h[i]);
for (var j = 0, len = headers.length; j < len; j++) {
header_text = headers[j].textContent.trim();
if (header_text) {
return header_text;
}
}
}
}
, doc_impl = document.implementation
, create_html_doc = function(html) {
var
dt = doc_impl.createDocumentType('html', null, null)
, doc = doc_impl.createDocument("http://www.w3.org/1999/xhtml", "html", dt)
, doc_el = doc.documentElement
, head = doc_el.appendChild(doc.createElement("head"))
, charset_meta = head.appendChild(doc.createElement("meta"))
, title = head.appendChild(doc.createElement("title"))
, body = doc_el.appendChild(doc.createElement("body"))
, i = 0
, len = html.childNodes.length
;
charset_meta.setAttribute("charset", html.ownerDocument.characterSet);
for (; i < len; i++) {
body.appendChild(doc.importNode(html.childNodes.item(i), true));
}
var title_text = guess_title(doc);
if (title_text) {
title.appendChild(doc.createTextNode(title_text));
}
return doc;
}
;
canvas.width = 500;
canvas.height = 300;
if (typeof x_points === "string") {
x_points = JSON.parse(x_points);
} if (typeof y_points === "string") {
y_points = JSON.parse(y_points);
} if (typeof drag_points === "string") {
drag_points = JSON.parse(drag_points);
} if (session.canvas_filename) {
canvas_filename.value = session.canvas_filename;
} if (session.text) {
text.value = session.text;
} if (session.text_filename) {
text_filename.value = session.text_filename;
} if (session.html) {
html.innerHTML = session.html;
} if (session.html_filename) {
html_filename.value = session.html_filename;
}
drawing = true;
draw();
drawing = false;
canvas_clear_button.addEventListener("click", function() {
canvas.width = canvas.width;
x_points.length =
y_points.length =
drag_points.length =
0;
}, false);
canvas.addEventListener("mousedown", function(event) {
event.preventDefault();
drawing = true;
add_point(event.pageX - canvas.offsetLeft, event.pageY - canvas.offsetTop, false);
draw();
}, false);
canvas.addEventListener("mousemove", function(event) {
if (drawing) {
add_point(event.pageX - canvas.offsetLeft, event.pageY - canvas.offsetTop, true);
draw();
}
}, false);
canvas.addEventListener("mouseup", stop_drawing, false);
canvas.addEventListener("mouseout", stop_drawing, false);
canvas_options_form.addEventListener("submit", function(event) {
event.preventDefault();
canvas.toBlobHD(function(blob) {
saveAs(
blob
, (canvas_filename.value || canvas_filename.placeholder) + ".png"
);
}, "image/png");
}, false);
text_options_form.addEventListener("submit", function(event) {
event.preventDefault();
var BB = get_blob();
saveAs(
new BB(
[text.value || text.placeholder]
, {type: "text/plain;charset=" + document.characterSet}
)
, (text_filename.value || text_filename.placeholder) + ".txt"
);
}, false);
html_options_form.addEventListener("submit", function(event) {
event.preventDefault();
var
BB = get_blob()
, xml_serializer = new XMLSerializer()
, doc = create_html_doc(html)
;
saveAs(
new BB(
[xml_serializer.serializeToString(doc)]
, {type: "text/plain;charset=" + document.characterSet}
)
, (html_filename.value || html_filename.placeholder) + ".xhtml"
);
}, false);
view.addEventListener("unload", function() {
session.x_points = JSON.stringify(x_points);
session.y_points = JSON.stringify(y_points);
session.drag_points = JSON.stringify(drag_points);
session.canvas_filename = canvas_filename.value;
session.text = text.value;
session.text_filename = text_filename.value;
session.html = html.innerHTML;
session.html_filename = html_filename.value;
}, false);
}(self));
-2
View File
@@ -1,2 +0,0 @@
/*! @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.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));
-57
View File
@@ -1,57 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US-x-Hixie">
<head>
<meta charset="utf-8"/>
<title>FileSaver.js demo</title>
<link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/eligrey/FileSaver.js/702cd2e820b680f88a0f299e33085c196806fc52/demo/demo.css"/>
</head>
<body>
<h1><a href="https://github.com/eligrey/FileSaver.js">FileSaver.js</a> demo</h1>
<p>
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>
<section id="image-demo">
<h2>Saving an image</h2>
<canvas class="input" id="canvas" width="500" height="300"/>
<form id="canvas-options">
<label>Filename: <input type="text" class="filename" id="canvas-filename" placeholder="doodle"/>.png</label>
<input type="submit" value="Save"/>
<input type="button" id="canvas-clear" value="Clear"/>
</form>
</section>
<section id="text-demo">
<h2>Saving text</h2>
<textarea class="input" id="text" placeholder="Once upon a time..."/>
<form id="text-options">
<label>Filename: <input type="text" class="filename" id="text-filename" placeholder="a plain document"/>.txt</label>
<input type="submit" value="Save"/>
</form>
</section>
<section id="html-demo">
<h2>Saving rich text</h2>
<div class="input" id="html" contenteditable="">
<h3>Some example rich text</h3>
<ul>
<li><del>Plain</del> <ins>Boring</ins> text.</li>
<li><em>Emphasized text!</em></li>
<li><strong>Strong text!</strong></li>
<li>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="70" height="70">
<circle cx="35" cy="35" r="35" fill="red"/>
<text x="10" y="40">image</text>
</svg>
</li>
<li><a href="https://github.com/eligrey/FileSaver.js">A link.</a></li>
</ul>
</div>
<form id="html-options">
<label>Filename: <input type="text" class="filename" id="html-filename" placeholder="a rich document"/>.xhtml</label>
<input type="submit" value="Save"/>
</form>
</section>
<script async="" src="https://cdn.rawgit.com/eligrey/Blob.js/0cef2746414269b16834878a8abc52eb9d53e6bd/Blob.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/e9d941381475b5df8b7d7691013401e171014e89/FileSaver.min.js"/>
<script async="" src="https://cdn.rawgit.com/eligrey/FileSaver.js/597b6cd0207ce408a6d34890b5b2826b13450714/demo/demo.js"/>
</body>
</html>
+170
View File
@@ -0,0 +1,170 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["exports"], factory);
} else if (typeof exports !== "undefined") {
factory(exports);
} else {
var mod = {
exports: {}
};
factory(mod.exports);
global.FileSaver = mod.exports;
}
})(this, function (_exports) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports.default = void 0;
/*
* FileSaver.js
* A saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
*
* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
* source : http://purl.eligrey.com/github/FileSaver.js
*/
// The one and only way of getting global scope in all enviorment
// https://stackoverflow.com/q/3277182/1008999
var _global = function () {
// some use content security policy to disable eval
try {
return Function('return this')() || (42, eval)('this');
} catch (e) {
// every global should have circular reference
// used for checking if someone writes var window = {}; var self = {}
return typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : this;
}
}();
function bom(blob, autoBom) {
if (!autoBom) return blob; // 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)) {
return new Blob([String.fromCharCode(0xFEFF), blob], {
type: blob.type
});
}
return blob;
}
function download(url, name, autoBom) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.onload = function () {
saveAs(xhr.response, name, autoBom);
};
xhr.onerror = function () {
console.error('could not download file');
};
xhr.send();
}
function corsEnabled(url) {
var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
xhr.open('HEAD', url, false);
xhr.send();
return xhr.status >= 200 && xhr.status <= 299;
}
var saveAs = _global.saveAs || // probably in some web worker
typeof window !== 'object' || window !== _global ? function saveAs() {}
/* noop */
// Use download attribute first if possible (#193 Lumia mobile)
: 'download' in HTMLAnchorElement.prototype ? function saveAs(blob, name, autoBom) {
var URL = _global.URL || _global.webkitURL;
var a = document.createElement('a');
name = name || blob.name || 'download';
a.download = name;
a.rel = 'noopener'; // tabnabbing
// TODO: detect chrome extensions & packaged apps
// a.target = '_blank'
if (typeof blob === 'string') {
// Support regular links
a.href = blob;
if (a.origin !== location.origin) {
corsEnabled(a.href) ? download(blob, name, autoBom) : a.click(a.target = '_blank');
} else {
a.click();
}
} else {
// Support blobs
a.href = URL.createObjectURL(blob);
setTimeout(function () {
URL.revokeObjectURL(a.href);
}, 4E4); // 40s
setTimeout(a.click.bind(a), 0);
}
} // Use msSaveOrOpenBlob as a second approch
: 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, autoBom) {
name = name || blob.name || 'download';
if (typeof blob === 'string') {
if (corsEnabled(blob)) {
download(blob, name, autoBom);
} else {
var a = document.createElement('a');
a.href = blob;
a.target = '_blank';
setTimeout(a.click.bind(a));
}
} else {
navigator.msSaveOrOpenBlob(bom(blob, autoBom), name);
}
} // Fallback to using FileReader and a popup
: function saveAs(blob, name, autoBom, popup) {
// Open a popup immediately do go around popup blocker
// Mostly only avalible on user interaction and the fileReader is async so...
popup = popup || open('', '_blank');
if (popup) {
popup.document.title = popup.document.body.innerText = 'downloading...';
}
if (typeof blob === 'string') return download(blob, name, autoBom);
var force = blob.type === 'application/octet-stream';
var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
if ((isChromeIOS || force && isSafari) && typeof FileReader === 'object') {
// Safari doesn't allow downloading of blob urls
var reader = new FileReader();
reader.onloadend = function () {
var url = reader.result;
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
if (popup) popup.location.href = url;else location = url;
popup = null; // reverse-tabnabbing #460
};
reader.readAsDataURL(blob);
} else {
var URL = _global.URL || _global.webkitURL;
var url = URL.createObjectURL(blob);
if (popup) popup.location = url;else location.href = url;
popup = null; // reverse-tabnabbing #460
setTimeout(function () {
URL.revokeObjectURL(url);
}, 4E4); // 40s
}
};
_global.saveAs = saveAs;
var _default = saveAs;
_exports.default = _default;
});
+3
View File
@@ -0,0 +1,3 @@
(function(a,b){if("function"==typeof define&&define.amd)define(["exports"],b);else if("undefined"!=typeof exports)b(exports);else{var c={exports:{}};b(c.exports),a.FileSaver=c.exports}})(this,function(a){"use strict";function b(a,b){return b?/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a:a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){f(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;return b.open("HEAD",a,!1),b.send(),200<=b.status&&299>=b.status}Object.defineProperty(a,"__esModule",{value:!0}),a.default=void 0;var e=function(){try{return Function("return this")()||(42,eval)("this")}catch(a){return"object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:this}}(),f=e.saveAs||"object"!=typeof window||window!==e?function(){}:"download"in HTMLAnchorElement.prototype?function(b,f,g){var h=e.URL||e.webkitURL,i=document.createElement("a");f=f||b.name||"download",i.download=f,i.rel="noopener","string"==typeof b?(i.href=b,i.origin===location.origin?i.click():d(i.href)?c(b,f,g):i.click(i.target="_blank")):(i.href=h.createObjectURL(b),setTimeout(function(){h.revokeObjectURL(i.href)},4E4),setTimeout(i.click.bind(i),0))}:"msSaveOrOpenBlob"in navigator?function(e,f,g){if(f=f||e.name||"download","string"!=typeof e)navigator.msSaveOrOpenBlob(b(e,g),f);else if(d(e))c(e,f,g);else{var h=document.createElement("a");h.href=e,h.target="_blank",setTimeout(h.click.bind(h))}}:function(a,b,d,f){if(f=f||open("","_blank"),f&&(f.document.title=f.document.body.innerText="downloading..."),"string"==typeof a)return c(a,b,d);var g="application/octet-stream"===a.type,h=/constructor/i.test(e.HTMLElement)||e.safari,i=/CriOS\/[\d]+/.test(navigator.userAgent);if((i||g&&h)&&"object"==typeof FileReader){var j=new FileReader;j.onloadend=function(){var a=j.result;a=i?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),f?f.location.href=a:location=a,f=null},j.readAsDataURL(a)}else{var k=e.URL||e.webkitURL,l=k.createObjectURL(a);f?f.location=l:location.href=l,f=null,setTimeout(function(){k.revokeObjectURL(l)},4E4)}};e.saveAs=f;a.default=f});
//# sourceMappingURL=FileSaver.min.js.map
+1
View File
File diff suppressed because one or more lines are too long
-2783
View File
File diff suppressed because it is too large Load Diff
+11 -9
View File
@@ -1,16 +1,18 @@
{ {
"name": "file-saver", "name": "file-saver",
"version": "1.3.7", "version": "2.0.0-rc.1",
"description": "An HTML5 saveAs() FileSaver implementation", "description": "An HTML5 saveAs() FileSaver implementation",
"main": "dist/FileSaver.js", "main": "dist/FileSaver.min.js",
"module": "src/FileSaver.js", "module": "src/FileSaver.js",
"files": [ "files": [
"dist/FileSaver.min.js" "dist/FileSaver.js",
"dist/FileSaver.min.js",
"src/FileSaver.js"
], ],
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 0", "test": "echo \"Error: no test specified\" && exit 0",
"build:development": "mkdir -p dist && babel src/FileSaver.js --out-file=dist/FileSaver.js", "build:development": "babel -o dist/FileSaver.js --plugins @babel/plugin-transform-modules-umd src/FileSaver.js",
"build:production": "NODE_ENV=production npm run build:development -- --out-file=dist/FileSaver.min.js", "build:production": "babel -o dist/FileSaver.min.js -s --plugins @babel/plugin-transform-modules-umd --presets minify src/FileSaver.js",
"build": "npm run build:development && npm run build:production", "build": "npm run build:development && npm run build:production",
"prepublishOnly": "npm run build" "prepublishOnly": "npm run build"
}, },
@@ -30,9 +32,9 @@
}, },
"homepage": "https://github.com/eligrey/FileSaver.js#readme", "homepage": "https://github.com/eligrey/FileSaver.js#readme",
"devDependencies": { "devDependencies": {
"babel-cli": "^6.26.0", "@babel/cli": "^7.1.0",
"babel-plugin-transform-es2015-modules-umd": "^6.24.1", "@babel/core": "^7.1.0",
"babel-preset-env": "^1.6.1", "@babel/plugin-transform-modules-umd": "^7.1.0",
"babel-preset-minify": "^0.2.0" "babel-preset-minify": "^0.4.3"
} }
} }
+125 -154
View File
@@ -1,181 +1,152 @@
/* FileSaver.js /*
* FileSaver.js
* A saveAs() FileSaver implementation. * A saveAs() FileSaver implementation.
* 1.3.7
* 2018-03-16 14:39:40
* *
* By Eli Grey, https://eligrey.com * By Eli Grey, http://eligrey.com
* License: MIT *
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
* source : http://purl.eligrey.com/github/FileSaver.js
*/ */
/*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/src/FileSaver.js */ // The one and only way of getting global scope in all enviorment
// https://stackoverflow.com/q/3277182/1008999
export default var saveAs = saveAs || (function(view) { var _global = (function () {
"use strict"; // some use content security policy to disable eval
// IE <10 is explicitly unsupported
if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
return;
}
var
doc = view.document
// only get URL when necessary in case Blob.js hasn't overridden it yet
, get_URL = function() {
return view.URL || view.webkitURL || view;
}
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
, can_use_save_link = "download" in save_link
, click = function(node) {
var event = new MouseEvent("click");
node.dispatchEvent(event);
}
, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
, setImmediate = view.setImmediate || view.setTimeout
, throw_outside = function(ex) {
setImmediate(function() {
throw ex;
}, 0);
}
, force_saveable_type = "application/octet-stream"
// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
, arbitrary_revoke_timeout = 1000 * 40 // in ms
, revoke = function(file) {
var revoker = function() {
if (typeof file === "string") { // file is an object URL
get_URL().revokeObjectURL(file);
} else { // file is a File
file.remove();
}
};
setTimeout(revoker, arbitrary_revoke_timeout);
}
, dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try { try {
listener.call(filesaver, event || filesaver); return Function('return this')() || (42, eval)('this')
} catch (ex) { } catch (e) {
throw_outside(ex); // every global should have circular reference
// used for checking if someone writes var window = {}; var self = {}
return typeof window === 'object' && window.window === window ? window
: typeof self === 'object' && self.self === self ? self
: typeof global === 'object' && global.global === global ? global : this
} }
} })()
}
} function bom (blob, autoBom) {
, auto_bom = function(blob) { if (!autoBom) return 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 // 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([String.fromCharCode(0xFEFF), blob], {type: blob.type}); return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })
} }
return blob; return blob
} }
, FileSaver = function(blob, name, no_auto_bom) {
if (!no_auto_bom) { function download (url, name, autoBom) {
blob = auto_bom(blob); var xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'blob'
xhr.onload = function () {
saveAs(xhr.response, name, autoBom)
} }
// First try a.download, then web filesystem, then object URLs xhr.onerror = function () {
var console.error('could not download file')
filesaver = this
, type = blob.type
, force = type === force_saveable_type
, object_url
, dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
} }
// on any filesys errors revert to saving with object URLs xhr.send()
, fs_error = function() {
if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
// Safari doesn't allow downloading of blob urls
var reader = new FileReader();
reader.onloadend = function() {
var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
var popup = view.open(url, '_blank');
if(!popup) view.location.href = url;
url=undefined; // release reference before dispatching
filesaver.readyState = filesaver.DONE;
dispatch_all();
};
reader.readAsDataURL(blob);
filesaver.readyState = filesaver.INIT;
return;
} }
// don't create more object URLs than needed
if (!object_url) { function corsEnabled (url) {
object_url = get_URL().createObjectURL(blob); var xhr = new XMLHttpRequest()
// use sync to avoid popup blocker
xhr.open('HEAD', url, false)
xhr.send()
return xhr.status >= 200 && xhr.status <= 299
} }
if (force) {
view.location.href = object_url; var saveAs = _global.saveAs ||
// probably in some web worker
(typeof window !== 'object' || window !== _global)
? function saveAs () { /* noop */ }
// Use download attribute first if possible (#193 Lumia mobile)
: 'download' in HTMLAnchorElement.prototype
? function saveAs (blob, name, autoBom) {
var URL = _global.URL || _global.webkitURL
var a = document.createElement('a')
name = name || blob.name || 'download'
a.download = name
a.rel = 'noopener' // tabnabbing
// TODO: detect chrome extensions & packaged apps
// a.target = '_blank'
if (typeof blob === 'string') {
// Support regular links
a.href = blob
if (a.origin !== location.origin) {
corsEnabled(a.href)
? download(blob, name, autoBom)
: a.click(a.target = '_blank')
} else { } else {
var opened = view.open(object_url, "_blank"); a.click()
if (!opened) { }
// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html } else {
view.location.href = object_url; // Support blobs
a.href = URL.createObjectURL(blob)
setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s
setTimeout(a.click.bind(a), 0)
} }
} }
filesaver.readyState = filesaver.DONE;
dispatch_all();
revoke(object_url);
}
;
filesaver.readyState = filesaver.INIT;
if (can_use_save_link) { // Use msSaveOrOpenBlob as a second approch
object_url = get_URL().createObjectURL(blob); : 'msSaveOrOpenBlob' in navigator
setImmediate(function() { ? function saveAs (blob, name, autoBom) {
save_link.href = object_url; name = name || blob.name || 'download'
save_link.download = name;
click(save_link); if (typeof blob === 'string') {
dispatch_all(); if (corsEnabled(blob)) {
revoke(object_url); download(blob, name, autoBom)
filesaver.readyState = filesaver.DONE; } else {
}, 0); var a = document.createElement('a')
return; a.href = blob
a.target = '_blank'
setTimeout(a.click.bind(a))
}
} else {
navigator.msSaveOrOpenBlob(bom(blob, autoBom), name)
}
} }
fs_error(); // Fallback to using FileReader and a popup
} : function saveAs (blob, name, autoBom, popup) {
, FS_proto = FileSaver.prototype // Open a popup immediately do go around popup blocker
, saveAs = function(blob, name, no_auto_bom) { // Mostly only avalible on user interaction and the fileReader is async so...
return new FileSaver(blob, name || blob.name || "download", no_auto_bom); popup = popup || open('', '_blank')
} if (popup) {
; popup.document.title =
popup.document.body.innerText = 'downloading...'
// IE 10+ (native saveAs)
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
return function(blob, name, no_auto_bom) {
name = name || blob.name || "download";
if (!no_auto_bom) {
blob = auto_bom(blob);
}
return navigator.msSaveOrOpenBlob(blob, name);
};
} }
save_link.target = "_blank"; if (typeof blob === 'string') return download(blob, name, autoBom)
FS_proto.abort = function(){}; var force = blob.type === 'application/octet-stream'
FS_proto.readyState = FS_proto.INIT = 0; var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari
FS_proto.WRITING = 1; var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent)
FS_proto.DONE = 2;
FS_proto.error = if ((isChromeIOS || (force && isSafari)) && typeof FileReader === 'object') {
FS_proto.onwritestart = // Safari doesn't allow downloading of blob urls
FS_proto.onprogress = var reader = new FileReader()
FS_proto.onwrite = reader.onloadend = function () {
FS_proto.onabort = var url = reader.result
FS_proto.onerror = url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')
FS_proto.onwriteend = if (popup) popup.location.href = url
null; else location = url
popup = null // reverse-tabnabbing #460
}
reader.readAsDataURL(blob)
} else {
var URL = _global.URL || _global.webkitURL
var url = URL.createObjectURL(blob)
if (popup) popup.location = url
else location.href = url
popup = null // reverse-tabnabbing #460
setTimeout(function () { URL.revokeObjectURL(url) }, 4E4) // 40s
}
}
return saveAs; _global.saveAs = saveAs
}(
typeof self !== "undefined" && self export default saveAs
|| typeof window !== "undefined" && window
|| this
));