Skip to content
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

πŸš€ Enhance Pull-to-Refresh Functionality with Native Sync and Improvements πŸ”„ #48632

Closed
wants to merge 11 commits into from
45 changes: 20 additions & 25 deletions packages/react-native/Libraries/Blob/URL.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/

import type Blob from './Blob';

import NativeBlobModule from './NativeBlobModule';

let BLOB_URL_PREFIX = null;
Expand All @@ -18,9 +17,9 @@ if (
NativeBlobModule &&
typeof NativeBlobModule.getConstants().BLOB_URI_SCHEME === 'string'
) {
const constants = NativeBlobModule.getConstants();
// $FlowFixMe[incompatible-type] asserted above
// $FlowFixMe[unsafe-addition]
const constants = NativeBlobModule.getConstants();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this moved?

I understand that $FlowFixMe directives were related to the line below?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

BLOB_URL_PREFIX = constants.BLOB_URI_SCHEME + ':';
if (typeof constants.BLOB_URI_HOST === 'string') {
BLOB_URL_PREFIX += `//${constants.BLOB_URI_HOST}/`;
Expand Down Expand Up @@ -51,19 +50,17 @@ if (
* </resources>
* ```
*/

export {URLSearchParams} from './URLSearchParams';
export { URLSearchParams } from './URLSearchParams';

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-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(
url,
);
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(url);
}

export class URL {
_url: string;
_searchParamsInstance: ?URLSearchParams = null;
_parsedUrl: URL;

static createObjectURL(blob: Blob): string {
if (BLOB_URL_PREFIX === null) {
Expand All @@ -76,7 +73,6 @@ export class URL {
// Do nothing.
}

// $FlowFixMe[missing-local-annot]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

constructor(url: string, base: string | URL) {
let baseUrl = null;
if (!base || validateBaseUrl(url)) {
Expand Down Expand Up @@ -104,51 +100,54 @@ export class URL {
}
this._url = `${baseUrl}${url}`;
}

// Parsing the URL to use for accessors
this._parsedUrl = new globalThis.URL(this._url);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why globalThis here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, can this be done lazily, to avoid parsing if the accessors are not ever used?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

}

get hash(): string {
throw new Error('URL.hash is not implemented');
return this._parsedUrl.hash;
}

get host(): string {
throw new Error('URL.host is not implemented');
return this._parsedUrl.host;
}

get hostname(): string {
throw new Error('URL.hostname is not implemented');
return this._parsedUrl.hostname;
}

get href(): string {
return this.toString();
}

get origin(): string {
throw new Error('URL.origin is not implemented');
return this._parsedUrl.origin;
}

get password(): string {
throw new Error('URL.password is not implemented');
return this._parsedUrl.password;
}

get pathname(): string {
throw new Error('URL.pathname not implemented');
return this._parsedUrl.pathname;
}

get port(): string {
throw new Error('URL.port is not implemented');
return this._parsedUrl.port;
}

get protocol(): string {
throw new Error('URL.protocol is not implemented');
return this._parsedUrl.protocol;
}

get search(): string {
throw new Error('URL.search is not implemented');
return this._parsedUrl.search;
}

get searchParams(): URLSearchParams {
if (this._searchParamsInstance == null) {
this._searchParamsInstance = new URLSearchParams();
this._searchParamsInstance = new URLSearchParams(this._parsedUrl.search);
}
return this._searchParamsInstance;
}
Expand All @@ -158,16 +157,12 @@ export class URL {
}

toString(): string {
if (this._searchParamsInstance === null) {
return this._url;
}
// $FlowFixMe[incompatible-use]
const instanceString = this._searchParamsInstance.toString();
const instanceString = this._searchParamsInstance ? this._searchParamsInstance.toString() : '';
const separator = this._url.indexOf('?') > -1 ? '&' : '?';
return this._url + separator + instanceString;
return this._url + (instanceString ? separator + instanceString : '');
}

get username(): string {
throw new Error('URL.username is not implemented');
return this._parsedUrl.username;
}
}
16 changes: 16 additions & 0 deletions packages/react-native/Libraries/Blob/__tests__/URL-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,20 @@ describe('URL', function () {
const k = new URL('en-US/docs', 'https://developer.mozilla.org');
expect(k.href).toBe('https://developer.mozilla.org/en-US/docs');
});

it('should implement host, hostname, username, and password accessors correctly', () => {
const url = new URL('https://username:[email protected]:8080/en-US/docs?query=test#fragment');

// Test host
expect(url.host).toBe('developer.mozilla.org:8080');

// Test hostname
expect(url.hostname).toBe('developer.mozilla.org');

// Test username
expect(url.username).toBe('username');

// Test password
expect(url.password).toBe('password');
});
});
Loading