UNPKG

3.17 kBJavaScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 * @format
9 */
10
11'use strict';
12
13const EventTarget = require('event-target-shim');
14const Blob = require('Blob');
15const {FileReaderModule} = require('NativeModules');
16
17type ReadyState =
18 | 0 // EMPTY
19 | 1 // LOADING
20 | 2; // DONE
21
22type ReaderResult = string | ArrayBuffer;
23
24const READER_EVENTS = [
25 'abort',
26 'error',
27 'load',
28 'loadstart',
29 'loadend',
30 'progress',
31];
32
33const EMPTY = 0;
34const LOADING = 1;
35const DONE = 2;
36
37class 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 // only call onreadystatechange if there is something to abort, as per spec
132 if (this._readyState !== EMPTY && this._readyState !== DONE) {
133 this._reset();
134 this._setReadyState(DONE);
135 }
136 // Reset again after, in case modified in handler
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
153module.exports = FileReader;