-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDownload.js
87 lines (77 loc) · 2.6 KB
/
Download.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"use strict";
class Download {
constructor () {
}
static init() {
Download.saveOn = Download.saveOnChrome;
chrome.downloads.onChanged.addListener(Download.onChanged);
}
static isFileNameIllegalOnWindows(fileName) {
for(let c of Download.illegalWindowsFileNameChars) {
if (fileName.includes(c)) {
return true;
}
}
return false;
}
/** write blob to "Downloads" directory */
static save(blob, fileName) {
let options = {
url: URL.createObjectURL(blob),
filename: fileName,
saveAs: true
};
let cleanup = () => { URL.revokeObjectURL(options.url); };
return Download.saveOn(options, cleanup);
}
static saveOnChrome(options, cleanup) {
// on Chrome call to download() will resolve when "Save As" dialog OPENS
// so need to delay return until after file is actually saved
// Otherwise, we get multiple Save As Dialogs open.
return new Promise(resolve => {
chrome.downloads.download(options,
downloadId => Download.onDownloadStarted(downloadId,
() => {
const tenSeconds = 10 * 1000;
setTimeout(cleanup, tenSeconds);
resolve();
}
)
);
});
}
static saveOnFirefox(options, cleanup) {
if (Download.isAndroid()) {
options.saveAs = false;
}
return browser.downloads.download(options).then(
// on Firefox, resolves when "Save As" dialog CLOSES, so no
// need to delay past this point.
downloadId => Download.onDownloadStarted(downloadId, cleanup)
).catch(cleanup);
}
static isAndroid() {
let agent = navigator.userAgent.toLowerCase();
return agent.includes("android") ||
navigator.platform.toLowerCase().includes("android");
}
static onChanged(delta) {
if ((delta.state != null) && (delta.state.current === "complete")) {
let action = Download.toCleanup.get(delta.id);
if (action != null) {
Download.toCleanup.delete(delta.id);
action();
}
}
}
static onDownloadStarted(downloadId, action) {
if (downloadId === undefined) {
action();
} else {
Download.toCleanup.set(downloadId, action);
}
}
}
Download.toCleanup = new Map();
Download.illegalWindowsFileNameChars = "/?<>\\:*|\"";
Download.init();