mirror of
https://github.com/status-im/react-native.git
synced 2025-01-16 12:34:17 +00:00
be56a3efee
Summary: This PR is a followup to https://github.com/facebook/react-native/pull/11417 and should be merged after that one is merged. 1. Add support for creating blobs from strings, not just other blobs 1. Add the `File` constructor which is a superset of `Blob` 1. Add the `FileReader` API which can be used to read blobs as strings or data url (base64) 1. Add support for uploading and downloading blobs via `XMLHttpRequest` and `fetch` 1. Add ability to download local files on Android so you can do `fetch(uri).then(res => res.blob())` to get a blob for a local file (iOS already supported this) 1. Clone the repo https://github.com/expo/react-native-blob-test 1. Change the `package.json` and update `react-native` dependency to point to this branch, then run `npm install` 1. Run the `server.js` file with `node server.js` 1. Open the `index.common.js` file and replace `localhost` with your computer's IP address 1. Start the packager with `yarn start` and run the app on your device If everything went well, all tests should pass, and you should see a screen like this: ![screen shot 2017-06-08 at 7 53 08 pm](https://user-images.githubusercontent.com/1174278/26936407-435bbce2-4c8c-11e7-9ae3-eb104e46961e.png)! Pull to rerun all tests or tap on specific test to re-run it [GENERAL] [FEATURE] [Blob] - Implement blob support for XMLHttpRequest Closes https://github.com/facebook/react-native/pull/11573 Reviewed By: shergin Differential Revision: D6082054 Pulled By: hramos fbshipit-source-id: cc9c174fdefdfaf6e5d9fd7b300120a01a50e8c1
145 lines
3.9 KiB
JavaScript
145 lines
3.9 KiB
JavaScript
/**
|
|
* Copyright (c) 2013-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule Blob
|
|
* @flow
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import type {BlobData, BlobOptions} from 'BlobTypes';
|
|
|
|
/**
|
|
* Opaque JS representation of some binary data in native.
|
|
*
|
|
* The API is modeled after the W3C Blob API, with one caveat
|
|
* regarding explicit deallocation. Refer to the `close()`
|
|
* method for further details.
|
|
*
|
|
* Example usage in a React component:
|
|
*
|
|
* class WebSocketImage extends React.Component {
|
|
* state = {blob: null};
|
|
* componentDidMount() {
|
|
* let ws = this.ws = new WebSocket(...);
|
|
* ws.binaryType = 'blob';
|
|
* ws.onmessage = (event) => {
|
|
* if (this.state.blob) {
|
|
* this.state.blob.close();
|
|
* }
|
|
* this.setState({blob: event.data});
|
|
* };
|
|
* }
|
|
* componentUnmount() {
|
|
* if (this.state.blob) {
|
|
* this.state.blob.close();
|
|
* }
|
|
* this.ws.close();
|
|
* }
|
|
* render() {
|
|
* if (!this.state.blob) {
|
|
* return <View />;
|
|
* }
|
|
* return <Image source={{uri: URL.createObjectURL(this.state.blob)}} />;
|
|
* }
|
|
* }
|
|
*
|
|
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
|
*/
|
|
class Blob {
|
|
_data: ?BlobData;
|
|
|
|
/**
|
|
* Constructor for JS consumers.
|
|
* Currently we only support creating Blobs from other Blobs.
|
|
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob
|
|
*/
|
|
constructor(parts: Array<Blob | string> = [], options?: BlobOptions) {
|
|
const BlobManager = require('BlobManager');
|
|
this.data = BlobManager.createFromParts(parts, options).data;
|
|
}
|
|
|
|
/*
|
|
* This method is used to create a new Blob object containing
|
|
* the data in the specified range of bytes of the source Blob.
|
|
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice
|
|
*/
|
|
set data(data: ?BlobData) {
|
|
this._data = data;
|
|
}
|
|
|
|
get data(): BlobData {
|
|
if (!this._data) {
|
|
throw new Error('Blob has been closed and is no longer available');
|
|
}
|
|
|
|
return this._data;
|
|
}
|
|
|
|
slice(start?: number, end?: number): Blob {
|
|
const BlobManager = require('BlobManager');
|
|
let {offset, size} = this.data;
|
|
|
|
if (typeof start === 'number') {
|
|
if (start > size) {
|
|
start = size;
|
|
}
|
|
offset += start;
|
|
size -= start;
|
|
|
|
if (typeof end === 'number') {
|
|
if (end < 0) {
|
|
end = this.size + end;
|
|
}
|
|
size = end - start;
|
|
}
|
|
}
|
|
return BlobManager.createFromOptions({
|
|
blobId: this.data.blobId,
|
|
offset,
|
|
size,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This method is in the standard, but not actually implemented by
|
|
* any browsers at this point. It's important for how Blobs work in
|
|
* React Native, however, since we cannot de-allocate resources automatically,
|
|
* so consumers need to explicitly de-allocate them.
|
|
*
|
|
* Note that the semantics around Blobs created via `blob.slice()`
|
|
* and `new Blob([blob])` are different. `blob.slice()` creates a
|
|
* new *view* onto the same binary data, so calling `close()` on any
|
|
* of those views is enough to deallocate the data, whereas
|
|
* `new Blob([blob, ...])` actually copies the data in memory.
|
|
*/
|
|
close() {
|
|
const BlobManager = require('BlobManager');
|
|
BlobManager.release(this.data.blobId);
|
|
this.data = null;
|
|
}
|
|
|
|
/**
|
|
* Size of the data contained in the Blob object, in bytes.
|
|
*/
|
|
get size(): number {
|
|
return this.data.size;
|
|
}
|
|
|
|
/*
|
|
* String indicating the MIME type of the data contained in the Blob.
|
|
* If the type is unknown, this string is empty.
|
|
*/
|
|
get type(): string {
|
|
return this.data.type || '';
|
|
}
|
|
}
|
|
|
|
module.exports = Blob;
|