Ver código fonte

Add closed private property to Blob #44

Ben Hsieh 8 anos atrás
pai
commit
4ef854007b
2 arquivos alterados com 44 adições e 8 exclusões
  1. 43
    6
      src/polyfill/Blob.js
  2. 1
    2
      src/polyfill/index.js

+ 43
- 6
src/polyfill/Blob.js Ver arquivo

@@ -27,6 +27,7 @@ export default class Blob extends EventTarget {
27 27
   _ref:string = null;
28 28
   _blobCreated:boolean = false;
29 29
   _onCreated:Array<any> = [];
30
+  _closed:boolean = false;
30 31
 
31 32
   /**
32 33
    * Static method that remove all files in Blob cache folder.
@@ -37,6 +38,12 @@ export default class Blob extends EventTarget {
37 38
     return fs.unlink(blobCacheDir).then(() => fs.mkdir(blobCacheDir))
38 39
   }
39 40
 
41
+  static build(data:any, cType:any):Promise<Blob> {
42
+    return new Promise((resolve, reject) => {
43
+      new Blob(data, cType).onCreated(resolve)
44
+    })
45
+  }
46
+
40 47
   /**
41 48
    * RNFetchBlob Blob polyfill, create a Blob directly from file path, BASE64
42 49
    * encoded data, and string. The conversion is done implicitly according to
@@ -52,10 +59,12 @@ export default class Blob extends EventTarget {
52 59
     this.cacheName = getBlobName()
53 60
     this.isRNFetchBlobPolyfill = true
54 61
     this.type = cType.type || 'text/plain'
55
-    log.verbose('Blob constructor called', 'mime', this.type, 'type', typeof data, 'length', data.length)
62
+    log.verbose('Blob constructor called', 'mime', this.type, 'type', typeof data, 'length', data?  data.length:0)
56 63
     this._ref = blobCacheDir + this.cacheName
57 64
     let p = null
58
-    if(data instanceof Blob) {
65
+    if(!data)
66
+      data = ''
67
+    if(data.isRNFetchBlobPolyfill) {
59 68
       log.verbose('create Blob cache file from Blob object')
60 69
       let size = 0
61 70
       this._ref = String(data.getRNFetchBlobRef())
@@ -72,6 +81,28 @@ export default class Blob extends EventTarget {
72 81
                 throw `could not create Blob from path ${orgPath}, file not exists`
73 82
             })
74 83
     }
84
+    // process FormData
85
+    else if(data instanceof FormData) {
86
+      log.verbose('create Blob cache file from FormData', data)
87
+      let boundary = `--RNFetchBlob-${this.cacheName}-${Date.now()}\r\n`
88
+      let parts = data.getParts()
89
+      let formArray = []
90
+      for(let i in parts) {
91
+        formArray.push(boundary)
92
+        let part = parts[i]
93
+        for(let j in part.headers) {
94
+          formArray.push(j + part.headers[j] + ';\r\n')
95
+        }
96
+        formArray.push('\r\n')
97
+        if(part.isRNFetchBlobPolyfill)
98
+          formArray.push(part)
99
+        else
100
+          formArray.push(part.string)
101
+      }
102
+      log.verbose('FormData array', formArray)
103
+      formArray.push(boundary + '--')
104
+      p = createMixedBlobData(this._ref, formArray)
105
+    }
75 106
     // if the data is a string starts with `RNFetchBlob-file://`, append the
76 107
     // Blob data from file path
77 108
     else if(typeof data === 'string' && data.startsWith('RNFetchBlob-file://')) {
@@ -127,15 +158,16 @@ export default class Blob extends EventTarget {
127 158
    * Since Blob content will asynchronously write to a file during creation,
128 159
    * use this method to register an event handler for Blob initialized event.
129 160
    * @nonstandard
130
-   * @param  {[type]} fn:( [description]
131
-   * @return {[type]}      [description]
161
+   * @param  {(b:Blob) => void} An event handler invoked when Blob created
162
+   * @return {Blob} The Blob object instance itself
132 163
    */
133
-  onCreated(fn:() => void) {
164
+  onCreated(fn:() => void):Blob {
134 165
     log.verbose('register blob onCreated', this._onCreated.length)
135 166
     if(!this._blobCreated)
136 167
       this._onCreated.push(fn)
137 168
     else
138 169
       fn(this)
170
+    return this
139 171
   }
140 172
 
141 173
   /**
@@ -155,7 +187,9 @@ export default class Blob extends EventTarget {
155 187
    * @return {Blob}
156 188
    */
157 189
   slice(start:?number, end:?number, encoding:?string):Blob {
158
-    log.verbose('slice called')
190
+    if(this._closed)
191
+      throw 'Blob has been released.'
192
+    log.verbose('slice called', start, end, encoding)
159 193
     // TODO : fs.slice
160 194
     // return fs.slice(this.cacheName, getBlobName(), contentType, start, end)
161 195
   }
@@ -166,6 +200,9 @@ export default class Blob extends EventTarget {
166 200
    * @return {Promise}
167 201
    */
168 202
   close() {
203
+    if(this._closed)
204
+      return Promise.reject('Blob has been released.')
205
+    this._closed = true
169 206
     return fs.unlink(this._ref)
170 207
   }
171 208
 

+ 1
- 2
src/polyfill/index.js Ver arquivo

@@ -1,10 +1,9 @@
1 1
 import Blob from './Blob.js'
2 2
 import File from './File.js'
3 3
 import XMLHttpRequest from './XMLHttpRequest.js'
4
-import FormData from './FormData.js'
5 4
 import ProgressEvent from './ProgressEvent'
6 5
 import Event from './Event'
7 6
 
8 7
 export default {
9
-  Blob, File, XMLHttpRequest, FormData, ProgressEvent, Event
8
+  Blob, File, XMLHttpRequest, ProgressEvent, Event
10 9
 }