-
Notifications
You must be signed in to change notification settings - Fork 25k
react-native\packages\react-native\Libraries\Blob\URL.js Changes #48333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
22b471c
2ce296b
9c9ad7f
d4174f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,29 +9,27 @@ | |
| */ | ||
|
|
||
| import type Blob from './Blob'; | ||
|
|
||
| import NativeBlobModule from './NativeBlobModule'; | ||
|
|
||
| let BLOB_URL_PREFIX = null; | ||
|
|
||
| // Initialize BLOB_URL_PREFIX if NativeBlobModule is available and properly configured | ||
| if ( | ||
| NativeBlobModule && | ||
| typeof NativeBlobModule.getConstants().BLOB_URI_SCHEME === 'string' | ||
| ) { | ||
| const constants = NativeBlobModule.getConstants(); | ||
| // $FlowFixMe[incompatible-type] asserted above | ||
| // $FlowFixMe[unsafe-addition] | ||
| BLOB_URL_PREFIX = constants.BLOB_URI_SCHEME + ':'; | ||
| if (typeof constants.BLOB_URI_HOST === 'string') { | ||
| BLOB_URL_PREFIX += `//${constants.BLOB_URI_HOST}/`; | ||
| 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`: | ||
| * To allow Blobs be accessed via content:// URIs, | ||
| * you need to register BlobProvider as a ContentProvider in your app's AndroidManifest.xml: | ||
| * | ||
| * ```xml | ||
| * xml | ||
| * <manifest> | ||
| * <application> | ||
| * <provider | ||
|
|
@@ -41,44 +39,50 @@ if ( | |
| * /> | ||
| * </application> | ||
| * </manifest> | ||
| * ``` | ||
| * And then define the `blob_provider_authority` string in `res/values/strings.xml`. | ||
| * | ||
| * 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 | ||
| * xml | ||
| * <resources> | ||
| * <string name="blob_provider_authority">your.app.package.blobs</string> | ||
| * </resources> | ||
| * ``` | ||
| * | ||
| */ | ||
|
|
||
| export {URLSearchParams} from './URLSearchParams'; | ||
|
|
||
| function validateBaseUrl(url: string) { | ||
| // Validate the base URL with a regular expression | ||
| function validateBaseUrl(url: string): boolean { | ||
| // 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-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)*(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/.test( | ||
| 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-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S)?$/.test( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why did you removed the |
||
| url, | ||
| ); | ||
| } | ||
|
|
||
| export class URL { | ||
| _url: string; | ||
| _searchParamsInstance: ?URLSearchParams = null; | ||
| _urlObject: URL; | ||
|
|
||
| static createObjectURL(blob: Blob): string { | ||
| if (BLOB_URL_PREFIX === null) { | ||
| throw new Error('Cannot create URL for blob!'); | ||
| throw new Error('Cannot create URL for blob! Ensure NativeBlobModule is properly configured.'); | ||
| } | ||
| if (!blob || !blob.data || !blob.data.blobId) { | ||
| throw new Error('Invalid blob data: Missing blobId or data.'); | ||
| } | ||
| return `${BLOB_URL_PREFIX}${blob.data.blobId}?offset=${blob.data.offset}&size=${blob.size}`; | ||
| return ${BLOB_URL_PREFIX}${blob.data.blobId}?offset=${blob.data.offset}&size=${blob.size}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing |
||
| } | ||
|
|
||
| static revokeObjectURL(url: string) { | ||
| // Do nothing. | ||
| // Do nothing, no implementation needed for revoking Blob URLs in this case. | ||
| } | ||
|
|
||
| // $FlowFixMe[missing-local-annot] | ||
| constructor(url: string, base: string | URL) { | ||
| let baseUrl = null; | ||
|
|
||
| // Validate URL format and handle base URL correctly | ||
| if (!base || validateBaseUrl(url)) { | ||
| this._url = url; | ||
| if (!this._url.endsWith('/')) { | ||
|
|
@@ -88,67 +92,73 @@ export class URL { | |
| if (typeof base === 'string') { | ||
| baseUrl = base; | ||
| if (!validateBaseUrl(baseUrl)) { | ||
| throw new TypeError(`Invalid base URL: ${baseUrl}`); | ||
| throw new TypeError(Invalid base URL: ${baseUrl}); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Backticks |
||
| } | ||
| } else { | ||
| baseUrl = base.toString(); | ||
| } | ||
|
|
||
| // Ensure correct URL formatting | ||
| if (baseUrl.endsWith('/')) { | ||
| baseUrl = baseUrl.slice(0, baseUrl.length - 1); | ||
| } | ||
| if (!url.startsWith('/')) { | ||
| url = `/${url}`; | ||
| url = /${url}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Backticks ` |
||
| } | ||
| if (baseUrl.endsWith(url)) { | ||
| url = ''; | ||
| } | ||
| this._url = `${baseUrl}${url}`; | ||
| this._url = ${baseUrl}${url}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Backticks ` |
||
| } | ||
|
|
||
| // Create a URL object for easier parsing (browser-like behavior) | ||
| this._urlObject = new globalThis.URL(this._url); | ||
| } | ||
|
|
||
| get hash(): string { | ||
| throw new Error('URL.hash is not implemented'); | ||
| return this._urlObject.hash || ''; // Extract the fragment part | ||
| } | ||
|
|
||
| get host(): string { | ||
| throw new Error('URL.host is not implemented'); | ||
| return this._urlObject.host || ''; // Extracts the host and port (if present) | ||
| } | ||
|
|
||
| get hostname(): string { | ||
| throw new Error('URL.hostname is not implemented'); | ||
| return this._urlObject.hostname || ''; // Extracts just the hostname (without port) | ||
| } | ||
|
|
||
| get href(): string { | ||
| return this.toString(); | ||
| } | ||
|
|
||
| get origin(): string { | ||
| throw new Error('URL.origin is not implemented'); | ||
| return this._urlObject.origin || ''; // Extracts the origin (protocol + hostname + port) | ||
| } | ||
|
|
||
| get password(): string { | ||
| throw new Error('URL.password is not implemented'); | ||
| const match = this._urlObject.href.match(/^.:\/\/(.):(.*)@/); | ||
| return match && match[2] ? match[2] : ''; // Extract password from "username:password" part | ||
| } | ||
|
|
||
| get pathname(): string { | ||
| throw new Error('URL.pathname not implemented'); | ||
| return this._urlObject.pathname || ''; // Extracts the pathname (e.g., "/path/to/resource") | ||
| } | ||
|
|
||
| get port(): string { | ||
| throw new Error('URL.port is not implemented'); | ||
| return this._urlObject.port || ''; // Extracts the port part | ||
| } | ||
|
|
||
| get protocol(): string { | ||
| throw new Error('URL.protocol is not implemented'); | ||
| return this._urlObject.protocol || ''; // Extracts the protocol (e.g., "http:" or "https:") | ||
| } | ||
|
|
||
| get search(): string { | ||
| throw new Error('URL.search is not implemented'); | ||
| return this._urlObject.search || ''; // Extracts the query string (e.g., "?id=123") | ||
| } | ||
|
|
||
| get searchParams(): URLSearchParams { | ||
| if (this._searchParamsInstance == null) { | ||
| this._searchParamsInstance = new URLSearchParams(); | ||
| this._searchParamsInstance = new URLSearchParams(this._urlObject.search); | ||
| } | ||
| return this._searchParamsInstance; | ||
| } | ||
|
|
@@ -161,13 +171,13 @@ export class URL { | |
| if (this._searchParamsInstance === null) { | ||
| return this._url; | ||
| } | ||
| // $FlowFixMe[incompatible-use] | ||
| const instanceString = this._searchParamsInstance.toString(); | ||
| const separator = this._url.indexOf('?') > -1 ? '&' : '?'; | ||
| return this._url + separator + instanceString; | ||
| } | ||
|
|
||
| get username(): string { | ||
| throw new Error('URL.username is not implemented'); | ||
| const match = this._urlObject.href.match(/^.:\/\/(.?)(?::(.*))?@/); | ||
| return match && match[1] ? match[1] : ''; // Extract username from "username:password" part | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.