diff --git a/app/js/lib/mtproto_wrapper.js b/app/js/lib/mtproto_wrapper.js index a523b0ce..6d9449ea 100644 --- a/app/js/lib/mtproto_wrapper.js +++ b/app/js/lib/mtproto_wrapper.js @@ -341,6 +341,9 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto']) } function downloadSmallFile(location) { + if (!FileManager.isAvailable()) { + return $q.reject({type: 'BROWSER_BLOB_NOT_SUPPORTED'}); + } // console.log('dload small', location); var fileName = getFileName(location), mimeType = 'image/jpeg', @@ -379,6 +382,10 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto']) } function downloadFile (dcID, location, size, options) { + if (!FileManager.isAvailable()) { + return $q.reject({type: 'BROWSER_BLOB_NOT_SUPPORTED'}); + } + options = options || {}; // console.log(dT(), 'Dload file', dcID, location, size); diff --git a/app/js/lib/ng_utils.js b/app/js/lib/ng_utils.js index 737b5699..5205bee9 100644 --- a/app/js/lib/ng_utils.js +++ b/app/js/lib/ng_utils.js @@ -139,6 +139,18 @@ angular.module('izhukov.utils', []) $window.URL = $window.URL || $window.webkitURL; $window.BlobBuilder = $window.BlobBuilder || $window.WebKitBlobBuilder || $window.MozBlobBuilder; + var blobSupported = true; + + try { + blobConstruct([], ''); + } catch (e) { + blobSupported = false; + } + + function isBlobAvailable () { + return blobSupported; + } + function fileCopyTo (fromFileEntry, toFileEntry) { return getFileWriter(toFileEntry).then(function (fileWriter) { return fileWriteData(fileWriter, fromFileEntry).then(function () { @@ -150,6 +162,20 @@ angular.module('izhukov.utils', []) }); } + function blobConstruct (blobParts, mimeType) { + var blob; + try { + blob = new Blob(blobParts, {type: mimeType}); + } catch (e) { + var bb = new BlobBuilder; + angular.forEach(blobParts, function(blobPart) { + bb.append(blobPart); + }); + blob = bb.getBlob(mimeType); + } + return blob; + } + function fileWriteData(fileWriter, bytes) { var deferred = $q.defer(); @@ -171,7 +197,12 @@ angular.module('izhukov.utils', []) fileWriter.write(bytes); } else { - fileWriter.write(new Blob([bytesToArrayBuffer(bytes)])); + try { + var blob = blobConstruct([bytesToArrayBuffer(bytes)]); + } catch (e) { + deferred.reject(e); + } + fileWriter.write(blob); } return deferred.promise; @@ -213,6 +244,12 @@ angular.module('izhukov.utils', []) var blobParts = [], fakeFileWriter = { write: function (blob) { + if (!blobSupported) { + if (fakeFileWriter.onerror) { + fakeFileWriter.onerror(new Error('Blob not supported by browser')); + } + return false; + } blobParts.push(blob); $timeout(function () { if (fakeFileWriter.onwriteend) { @@ -224,16 +261,7 @@ angular.module('izhukov.utils', []) blobParts = []; }, finalize: function () { - var blob; - try { - blob = new Blob(blobParts, {type: mimeType}); - } catch (e) { - var bb = new BlobBuilder; - angular.forEach(blobParts, function(blobPart) { - bb.append(blobPart); - }); - blob = bb.getBlob(mimeType); - } + var blob = blobConstruct(blobParts, mimeType); if (saveFileCallback) { saveFileCallback(blob); } @@ -275,6 +303,7 @@ angular.module('izhukov.utils', []) } return { + isAvailable: isBlobAvailable, copy: fileCopyTo, write: fileWriteData, getFileWriter: getFileWriter, diff --git a/app/js/lib/utils.js b/app/js/lib/utils.js index 609cf12e..4708c58d 100644 --- a/app/js/lib/utils.js +++ b/app/js/lib/utils.js @@ -108,3 +108,30 @@ function listUniqSorted (list) { return resultList; } + +// Bind polyfill from MDN +if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== "function") { + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function () {}, + fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + + return fBound; + }; +} +