|
22 | 22 | /* global require, exports, module */
|
23 | 23 | /* global FILESYSTEM_PREFIX */
|
24 | 24 | /* global IDBKeyRange */
|
| 25 | + /* global FileReader */ |
| 26 | + /* global atob, btoa, Blob */ |
25 | 27 |
|
26 | 28 | /* Heavily based on https://github.com/ebidel/idb.filesystem.js */
|
27 | 29 |
|
|
685 | 687 |
|
686 | 688 | MyFile.prototype.constructor = MyFile;
|
687 | 689 |
|
| 690 | + var MyFileHelper = { |
| 691 | + toJson: function (myFile, success) { |
| 692 | + /* |
| 693 | + Safari private browse mode cannot store Blob object to indexeddb. |
| 694 | + Then use pure json object instead of Blob object. |
| 695 | + */ |
| 696 | + var fr = new FileReader(); |
| 697 | + fr.onload = function (ev) { |
| 698 | + var base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(fr.result))); |
| 699 | + success({ |
| 700 | + opt: { |
| 701 | + size: myFile.size, |
| 702 | + name: myFile.name, |
| 703 | + type: myFile.type, |
| 704 | + lastModifiedDate: myFile.lastModifiedDate, |
| 705 | + storagePath: myFile.storagePath |
| 706 | + }, |
| 707 | + base64: base64 |
| 708 | + }); |
| 709 | + }; |
| 710 | + fr.readAsArrayBuffer(myFile.blob_); |
| 711 | + }, |
| 712 | + setBase64: function (myFile, base64) { |
| 713 | + if (base64) { |
| 714 | + var arrayBuffer = (new Uint8Array( |
| 715 | + [].map.call(atob(base64), function (c) { return c.charCodeAt(0); }) |
| 716 | + )).buffer; |
| 717 | + |
| 718 | + myFile.blob_ = new Blob([arrayBuffer], { type: myFile.type }); |
| 719 | + } else { |
| 720 | + myFile.blob_ = new Blob(); |
| 721 | + } |
| 722 | + } |
| 723 | + }; |
| 724 | + |
688 | 725 | // When saving an entry, the fullPath should always lead with a slash and never
|
689 | 726 | // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute
|
690 | 727 | // one. This method ensures path is legit!
|
|
847 | 884 |
|
848 | 885 | tx.onabort = errorCallback || onError;
|
849 | 886 | tx.oncomplete = function () {
|
850 |
| - successCallback(request.result); |
| 887 | + var entry = request.result; |
| 888 | + if (entry && entry.file_json) { |
| 889 | + /* |
| 890 | + Safari private browse mode cannot store Blob object to indexeddb. |
| 891 | + Then use pure json object instead of Blob object. |
| 892 | + */ |
| 893 | + entry.file_ = new MyFile(entry.file_json.opt); |
| 894 | + MyFileHelper.setBase64(entry.file_, entry.file_json.base64); |
| 895 | + delete entry.file_json; |
| 896 | + } |
| 897 | + successCallback(entry); |
851 | 898 | };
|
852 | 899 | };
|
853 | 900 |
|
|
946 | 993 | tx.objectStore(FILE_STORE_)['delete'](fullPath);
|
947 | 994 | };
|
948 | 995 |
|
949 |
| - idb_.put = function (entry, storagePath, successCallback, errorCallback) { |
| 996 | + idb_.put = function (entry, storagePath, successCallback, errorCallback, retry) { |
950 | 997 | if (!this.db) {
|
951 | 998 | if (errorCallback) {
|
952 | 999 | errorCallback(FileError.INVALID_MODIFICATION_ERR);
|
|
961 | 1008 | successCallback(entry);
|
962 | 1009 | };
|
963 | 1010 |
|
964 |
| - tx.objectStore(FILE_STORE_).put(entry, storagePath); |
| 1011 | + try { |
| 1012 | + tx.objectStore(FILE_STORE_).put(entry, storagePath); |
| 1013 | + } catch (e) { |
| 1014 | + if (e.name === 'DataCloneError') { |
| 1015 | + tx.oncomplete = null; |
| 1016 | + /* |
| 1017 | + Safari private browse mode cannot store Blob object to indexeddb. |
| 1018 | + Then use pure json object instead of Blob object. |
| 1019 | + */ |
| 1020 | + |
| 1021 | + var successCallback2 = function (entry) { |
| 1022 | + entry.file_ = new MyFile(entry.file_json.opt); |
| 1023 | + delete entry.file_json; |
| 1024 | + successCallback(entry); |
| 1025 | + }; |
| 1026 | + |
| 1027 | + if (!retry) { |
| 1028 | + if (entry.file_ && entry.file_ instanceof MyFile && entry.file_.blob_) { |
| 1029 | + MyFileHelper.toJson(entry.file_, function (json) { |
| 1030 | + entry.file_json = json; |
| 1031 | + delete entry.file_; |
| 1032 | + idb_.put(entry, storagePath, successCallback2, errorCallback, true); |
| 1033 | + }); |
| 1034 | + return; |
| 1035 | + } |
| 1036 | + } |
| 1037 | + } |
| 1038 | + throw e; |
| 1039 | + } |
965 | 1040 | };
|
966 | 1041 |
|
967 | 1042 | // Global error handler. Errors bubble from request, to transaction, to db.
|
|
0 commit comments