123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- */
- 'use strict';
- const Blob = require('./Blob');
- import NativeBlobModule from './NativeBlobModule';
- let BLOB_URL_PREFIX = null;
- if (
- NativeBlobModule &&
- typeof NativeBlobModule.getConstants().BLOB_URI_SCHEME === 'string'
- ) {
- const constants = NativeBlobModule.getConstants();
- BLOB_URL_PREFIX = constants.BLOB_URI_SCHEME + ':';
- if (typeof constants.BLOB_URI_HOST === 'string') {
- BLOB_URL_PREFIX += `//${constants.BLOB_URI_HOST}/`;
- }
- }
- /**
- * To allow Blobs be accessed via `content://` URIs,
- * you need to register `BlobProvider` as a ContentProvider in your app's `AndroidManifest.xml`:
- *
- * ```xml
- * <manifest>
- * <application>
- * <provider
- * android:name="com.facebook.react.modules.blob.BlobProvider"
- * android:authorities="@string/blob_provider_authority"
- * android:exported="false"
- * />
- * </application>
- * </manifest>
- * ```
- * And then define the `blob_provider_authority` string in `res/values/strings.xml`.
- * Use a dotted name that's entirely unique to your app:
- *
- * ```xml
- * <resources>
- * <string name="blob_provider_authority">your.app.package.blobs</string>
- * </resources>
- * ```
- */
- // Small subset from whatwg-url: https://github.com/jsdom/whatwg-url/tree/master/lib
- // The reference code bloat comes from Unicode issues with URLs, so those won't work here.
- export class URLSearchParams {
- _searchParams = [];
- constructor(params: any) {
- if (typeof params === 'object') {
- Object.keys(params).forEach(key => this.append(key, params[key]));
- }
- }
- append(key: string, value: string) {
- this._searchParams.push([key, value]);
- }
- delete(name) {
- throw new Error('not implemented');
- }
- get(name) {
- throw new Error('not implemented');
- }
- getAll(name) {
- throw new Error('not implemented');
- }
- has(name) {
- throw new Error('not implemented');
- }
- set(name, value) {
- throw new Error('not implemented');
- }
- sort() {
- throw new Error('not implemented');
- }
- [Symbol.iterator]() {
- return this._searchParams[Symbol.iterator]();
- }
- toString() {
- if (this._searchParams.length === 0) {
- return '';
- }
- const last = this._searchParams.length - 1;
- return this._searchParams.reduce((acc, curr, index) => {
- return acc + curr.join('=') + (index === last ? '' : '&');
- }, '');
- }
- }
- function validateBaseUrl(url: string) {
- // from this MIT-licensed gist: https://gist.github.com/dperini/729294
- return /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
- url,
- );
- }
- export class URL {
- _searchParamsInstance = null;
- static createObjectURL(blob: Blob) {
- if (BLOB_URL_PREFIX === null) {
- throw new Error('Cannot create URL for blob!');
- }
- return `${BLOB_URL_PREFIX}${blob.data.blobId}?offset=${
- blob.data.offset
- }&size=${blob.size}`;
- }
- static revokeObjectURL(url: string) {
- // Do nothing.
- }
- constructor(url: string, base: string) {
- let baseUrl = null;
- if (!base || validateBaseUrl(url)) {
- this._url = url;
- if (!this._url.endsWith('/')) {
- this._url += '/';
- }
- } else {
- if (typeof base === 'string') {
- baseUrl = base;
- if (!validateBaseUrl(baseUrl)) {
- throw new TypeError(`Invalid base URL: ${baseUrl}`);
- }
- } else if (typeof base === 'object') {
- baseUrl = base.toString();
- }
- if (baseUrl.endsWith('/')) {
- baseUrl = baseUrl.slice(0, baseUrl.length - 1);
- }
- if (!url.startsWith('/')) {
- url = `/${url}`;
- }
- if (baseUrl.endsWith(url)) {
- url = '';
- }
- this._url = `${baseUrl}${url}`;
- }
- }
- get hash() {
- throw new Error('not implemented');
- }
- get host() {
- throw new Error('not implemented');
- }
- get hostname() {
- throw new Error('not implemented');
- }
- get href(): string {
- return this.toString();
- }
- get origin() {
- throw new Error('not implemented');
- }
- get password() {
- throw new Error('not implemented');
- }
- get pathname() {
- throw new Error('not implemented');
- }
- get port() {
- throw new Error('not implemented');
- }
- get protocol() {
- throw new Error('not implemented');
- }
- get search() {
- throw new Error('not implemented');
- }
- get searchParams(): URLSearchParams {
- if (this._searchParamsInstance == null) {
- this._searchParamsInstance = new URLSearchParams();
- }
- return this._searchParamsInstance;
- }
- toJSON(): string {
- return this.toString();
- }
- toString(): string {
- if (this._searchParamsInstance === null) {
- return this._url;
- }
- const separator = this._url.indexOf('?') > -1 ? '&' : '?';
- return this._url + separator + this._searchParamsInstance.toString();
- }
- get username() {
- throw new Error('not implemented');
- }
- }
|