Merge pull request #125 from whiteout-io/WO-578

[WO-578] Fix downloads in browser with W3C API
This commit is contained in:
Tankred Hase 2014-09-23 16:07:21 +02:00
commit 91528f993b
4 changed files with 84 additions and 54 deletions

View File

@ -85,33 +85,21 @@ define(function(require) {
$scope.download = function(attachment) { $scope.download = function(attachment) {
// download file to disk if content is available // download file to disk if content is available
if (attachment.content) { if (attachment.content) {
saveToDisk(attachment);
return;
}
var folder = $scope.state.nav.currentFolder;
var email = $scope.state.mailList.selected;
emailDao.getAttachment({
folder: folder,
uid: email.uid,
attachment: attachment
}, function(err) {
if (err) {
$scope.onError(err);
return;
}
saveToDisk(attachment);
});
function saveToDisk(attachment) {
download.createDownload({ download.createDownload({
content: attachment.content, content: attachment.content,
filename: attachment.filename, filename: attachment.filename,
contentType: attachment.mimeType contentType: attachment.mimeType
}, $scope.onError); }, $scope.onError);
return;
} }
var folder = $scope.state.nav.currentFolder;
var email = $scope.state.mailList.selected;
emailDao.getAttachment({
folder: folder,
uid: email.uid,
attachment: attachment
}, $scope.onError);
}; };
$scope.invite = function(user) { $scope.invite = function(user) {

View File

@ -853,22 +853,25 @@ define(function(require) {
* @param {Function} callback(error, attachment) Invoked when the attachment body part was retrieved and parsed, or an error occurred * @param {Function} callback(error, attachment) Invoked when the attachment body part was retrieved and parsed, or an error occurred
*/ */
EmailDAO.prototype.getAttachment = function(options, callback) { EmailDAO.prototype.getAttachment = function(options, callback) {
var self = this; var self = this,
attachment = options.attachment;
self.busy(); self.busy();
attachment.busy = true;
self._getBodyParts({ self._getBodyParts({
folder: options.folder, folder: options.folder,
uid: options.uid, uid: options.uid,
bodyParts: [options.attachment] bodyParts: [attachment]
}, function(err, parsedBodyParts) { }, function(err, parsedBodyParts) {
attachment.busy = false;
if (err) { if (err) {
callback(err); callback(err);
return; return;
} }
self.done(); self.done();
// add the content to the original object // add the content to the original object
options.attachment.content = parsedBodyParts[0].content; attachment.content = parsedBodyParts[0].content;
callback(err, err ? undefined : options.attachment); callback(err, err ? undefined : attachment);
}); });
}; };

View File

@ -1,41 +1,79 @@
define(function() { define(function(require) {
'use strict'; 'use strict';
var util = require('js/crypto/util');
var dl = {}; var dl = {};
dl.createDownload = function(options, callback) { dl.createDownload = function(options, callback) {
var contentType = options.contentType || 'application/octet-stream'; var contentType = options.contentType || 'application/octet-stream';
var filename = options.filename || 'file';
var content = options.content;
var a = document.createElement('a');
var supportsBlob;
chrome.fileSystem.chooseEntry({ try {
type: 'saveFile', supportsBlob = !!new Blob();
suggestedName: options.filename } catch (e) {}
}, onEntry);
function onEntry(file) { if (window.chrome && window.chrome.fileSystem) {
if (!file) { // chrome app
callback(); chrome.fileSystem.chooseEntry({
return; type: 'saveFile',
} suggestedName: filename
file.createWriter(onWriter, onError); }, function(file) {
} if (!file) {
callback();
function onWriter(writer) { return;
writer.onerror = onError; }
writer.onwriteend = onEnd; file.createWriter(function(writer) {
writer.write(new Blob([options.content], { writer.onerror = callback;
writer.onwriteend = function() {
callback();
};
writer.write(new Blob([content], {
type: contentType
}));
}, callback);
});
return;
} else if (typeof a.download !== "undefined" && supportsBlob) {
// ff 30+, chrome 27+ (android: 37+)
document.body.appendChild(a);
a.style = "display: none";
a.href = window.URL.createObjectURL(new Blob([content], {
type: contentType type: contentType
})); }));
} a.download = filename;
a.click();
function onError(e) { setTimeout(function() {
callback({ window.URL.revokeObjectURL(a.href);
errMsg: 'Error exporting keypair to file!', document.body.removeChild(a);
err: e }, 10); // arbitrary, just get it off the main thread
}); } else if (window.navigator.msSaveBlob) {
} // ie 10+
window.navigator.msSaveBlob(new Blob([content], {
function onEnd() { type: contentType
callback(); }), filename);
} else if (supportsBlob) {
// safari actually makes no sense:
// - you can't open a new window
// - the file system api is dead
// - download attribute doesn't work
// - behaves randomly (opens a new tab or doesn't, downloads stuff or doesn't, ...)
var url = window.URL.createObjectURL(new Blob([content], {
type: contentType
}));
var newTab = window.open(url, "_blank");
if (!newTab) {
window.location.href = url;
}
} else {
// anything else, where anything at all is better than nothing
if (typeof content !== "string" && content.buffer) {
content = util.arrBuf2BinStr(content.buffer);
}
window.open('data:' + contentType + ';base64,' + btoa(content), "_blank");
} }
}; };

View File

@ -37,7 +37,8 @@
<span class="attachment" <span class="attachment"
ng-repeat="attachment in state.mailList.selected.attachments" ng-repeat="attachment in state.mailList.selected.attachments"
wo-touch="download(attachment)"> wo-touch="download(attachment)">
<span data-icon="&#xe003;"></span> <span ng-if="attachment.busy" class="spinner"></span>
<span ng-hide="attachment.busy" data-icon="&#xe003;"></span>
{{attachment.filename}} {{attachment.filename}}
</span><!--/.attachment--> </span><!--/.attachment-->
</div><!--/.attachments--> </div><!--/.attachments-->