1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | 'use strict';
|
12 |
|
13 | const EventTarget = require('event-target-shim');
|
14 | const Blob = require('Blob');
|
15 | const {FileReaderModule} = require('NativeModules');
|
16 |
|
17 | type ReadyState =
|
18 | | 0
|
19 | | 1
|
20 | | 2;
|
21 |
|
22 | type ReaderResult = string | ArrayBuffer;
|
23 |
|
24 | const READER_EVENTS = [
|
25 | 'abort',
|
26 | 'error',
|
27 | 'load',
|
28 | 'loadstart',
|
29 | 'loadend',
|
30 | 'progress',
|
31 | ];
|
32 |
|
33 | const EMPTY = 0;
|
34 | const LOADING = 1;
|
35 | const DONE = 2;
|
36 |
|
37 | class FileReader extends EventTarget(...READER_EVENTS) {
|
38 | static EMPTY = EMPTY;
|
39 | static LOADING = LOADING;
|
40 | static DONE = DONE;
|
41 |
|
42 | EMPTY = EMPTY;
|
43 | LOADING = LOADING;
|
44 | DONE = DONE;
|
45 |
|
46 | _readyState: ReadyState;
|
47 | _error: ?Error;
|
48 | _result: ?ReaderResult;
|
49 | _aborted: boolean = false;
|
50 | _subscriptions: Array<*> = [];
|
51 |
|
52 | constructor() {
|
53 | super();
|
54 | this._reset();
|
55 | }
|
56 |
|
57 | _reset(): void {
|
58 | this._readyState = EMPTY;
|
59 | this._error = null;
|
60 | this._result = null;
|
61 | }
|
62 |
|
63 | _clearSubscriptions(): void {
|
64 | this._subscriptions.forEach(sub => sub.remove());
|
65 | this._subscriptions = [];
|
66 | }
|
67 |
|
68 | _setReadyState(newState: ReadyState) {
|
69 | this._readyState = newState;
|
70 | this.dispatchEvent({type: 'readystatechange'});
|
71 | if (newState === DONE) {
|
72 | if (this._aborted) {
|
73 | this.dispatchEvent({type: 'abort'});
|
74 | } else if (this._error) {
|
75 | this.dispatchEvent({type: 'error'});
|
76 | } else {
|
77 | this.dispatchEvent({type: 'load'});
|
78 | }
|
79 | this.dispatchEvent({type: 'loadend'});
|
80 | }
|
81 | }
|
82 |
|
83 | readAsArrayBuffer() {
|
84 | throw new Error('FileReader.readAsArrayBuffer is not implemented');
|
85 | }
|
86 |
|
87 | readAsDataURL(blob: Blob) {
|
88 | this._aborted = false;
|
89 |
|
90 | FileReaderModule.readAsDataURL(blob.data).then(
|
91 | (text: string) => {
|
92 | if (this._aborted) {
|
93 | return;
|
94 | }
|
95 | this._result = text;
|
96 | this._setReadyState(DONE);
|
97 | },
|
98 | error => {
|
99 | if (this._aborted) {
|
100 | return;
|
101 | }
|
102 | this._error = error;
|
103 | this._setReadyState(DONE);
|
104 | },
|
105 | );
|
106 | }
|
107 |
|
108 | readAsText(blob: Blob, encoding: string = 'UTF-8') {
|
109 | this._aborted = false;
|
110 |
|
111 | FileReaderModule.readAsText(blob.data, encoding).then(
|
112 | (text: string) => {
|
113 | if (this._aborted) {
|
114 | return;
|
115 | }
|
116 | this._result = text;
|
117 | this._setReadyState(DONE);
|
118 | },
|
119 | error => {
|
120 | if (this._aborted) {
|
121 | return;
|
122 | }
|
123 | this._error = error;
|
124 | this._setReadyState(DONE);
|
125 | },
|
126 | );
|
127 | }
|
128 |
|
129 | abort() {
|
130 | this._aborted = true;
|
131 |
|
132 | if (this._readyState !== EMPTY && this._readyState !== DONE) {
|
133 | this._reset();
|
134 | this._setReadyState(DONE);
|
135 | }
|
136 |
|
137 | this._reset();
|
138 | }
|
139 |
|
140 | get readyState(): ReadyState {
|
141 | return this._readyState;
|
142 | }
|
143 |
|
144 | get error(): ?Error {
|
145 | return this._error;
|
146 | }
|
147 |
|
148 | get result(): ?ReaderResult {
|
149 | return this._result;
|
150 | }
|
151 | }
|
152 |
|
153 | module.exports = FileReader;
|