diff --git a/src/js/controller/read.js b/src/js/controller/read.js index 058ee7a..b99d4ea 100644 --- a/src/js/controller/read.js +++ b/src/js/controller/read.js @@ -85,33 +85,21 @@ define(function(require) { $scope.download = function(attachment) { // download file to disk if content is available 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({ content: attachment.content, filename: attachment.filename, contentType: attachment.mimeType }, $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) { diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js index b6ceb2f..ddfa315 100644 --- a/src/js/dao/email-dao.js +++ b/src/js/dao/email-dao.js @@ -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 */ EmailDAO.prototype.getAttachment = function(options, callback) { - var self = this; + var self = this, + attachment = options.attachment; self.busy(); + attachment.busy = true; self._getBodyParts({ folder: options.folder, uid: options.uid, - bodyParts: [options.attachment] + bodyParts: [attachment] }, function(err, parsedBodyParts) { + attachment.busy = false; if (err) { callback(err); return; } self.done(); // add the content to the original object - options.attachment.content = parsedBodyParts[0].content; - callback(err, err ? undefined : options.attachment); + attachment.content = parsedBodyParts[0].content; + callback(err, err ? undefined : attachment); }); }; diff --git a/src/js/util/download.js b/src/js/util/download.js index c195740..61c06ff 100644 --- a/src/js/util/download.js +++ b/src/js/util/download.js @@ -1,41 +1,79 @@ -define(function() { +define(function(require) { 'use strict'; + var util = require('js/crypto/util'); + var dl = {}; dl.createDownload = function(options, callback) { 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({ - type: 'saveFile', - suggestedName: options.filename - }, onEntry); + try { + supportsBlob = !!new Blob(); + } catch (e) {} - function onEntry(file) { - if (!file) { - callback(); - return; - } - file.createWriter(onWriter, onError); - } - - function onWriter(writer) { - writer.onerror = onError; - writer.onwriteend = onEnd; - writer.write(new Blob([options.content], { + if (window.chrome && window.chrome.fileSystem) { + // chrome app + chrome.fileSystem.chooseEntry({ + type: 'saveFile', + suggestedName: filename + }, function(file) { + if (!file) { + callback(); + return; + } + file.createWriter(function(writer) { + 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 })); - } - - function onError(e) { - callback({ - errMsg: 'Error exporting keypair to file!', - err: e - }); - } - - function onEnd() { - callback(); + a.download = filename; + a.click(); + setTimeout(function() { + window.URL.revokeObjectURL(a.href); + document.body.removeChild(a); + }, 10); // arbitrary, just get it off the main thread + } else if (window.navigator.msSaveBlob) { + // ie 10+ + window.navigator.msSaveBlob(new Blob([content], { + type: contentType + }), 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"); } }; diff --git a/src/tpl/read.html b/src/tpl/read.html index 774b494..55f4371 100644 --- a/src/tpl/read.html +++ b/src/tpl/read.html @@ -37,7 +37,8 @@ - + + {{attachment.filename}}