From a2eed942d70b330df723bb3a557d40debbcfe282 Mon Sep 17 00:00:00 2001 From: Ritesh Shukla Date: Sun, 29 Dec 2024 02:08:04 +0530 Subject: [PATCH 01/19] Implemented URL Methods --- packages/react-native/Libraries/Blob/URL.js | 28 ++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index 395e99d860a888..f3ce3cc6ecb557 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -107,15 +107,19 @@ export class URL { } get hash(): string { - throw new Error('URL.hash is not implemented'); + const hashMatch = this._url.match(/#(.*)$/); + return hashMatch ? `#${hashMatch[1]}` : ''; } get host(): string { - throw new Error('URL.host is not implemented'); + const hostMatch = this._url.match(/^https?:\/\/([^:/?#]+)/); + const portMatch = this._url.match(/:(\d+)(?=[/?#]|$)/); + return hostMatch ? hostMatch[1] + (portMatch ? `:${portMatch[1]}` : '') : ''; } get hostname(): string { - throw new Error('URL.hostname is not implemented'); + const hostnameMatch = this._url.match(/^https?:\/\/([^:/?#]+)/); + return hostnameMatch ? hostnameMatch[1] : ''; } get href(): string { @@ -123,27 +127,33 @@ export class URL { } get origin(): string { - throw new Error('URL.origin is not implemented'); + const matches = this._url.match(/^(https?:\/\/[^/]+)/); + return matches ? matches[1] : ''; } get password(): string { - throw new Error('URL.password is not implemented'); + const passwordMatch = this._url.match(/https?:\/\/.*:(.*)@/); + return passwordMatch ? passwordMatch[1] : ''; } get pathname(): string { - throw new Error('URL.pathname not implemented'); + const pathMatch = this._url.match(/https?:\/\/[^/]+(\/[^?#]*)?/); + return pathMatch ? pathMatch[1] || '/' : '/'; } get port(): string { - throw new Error('URL.port is not implemented'); + const portMatch = this._url.match(/:(\d+)(?=[/?#]|$)/); + return portMatch ? portMatch[1] : ''; } get protocol(): string { - throw new Error('URL.protocol is not implemented'); + const protocolMatch = this._url.match(/^([a-zA-Z][a-zA-Z\d+\-.]*):/); + return protocolMatch ? protocolMatch[1] + ':' : ''; } get search(): string { - throw new Error('URL.search is not implemented'); + const searchMatch = this._url.match(/\?([^#]*)/); + return searchMatch ? `?${searchMatch[1]}` : ''; } get searchParams(): URLSearchParams { From 4d0a79c191b25653b45cc80b2f74ef5d8d4b5e77 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:26:29 +0530 Subject: [PATCH 02/19] Update URL.js --- packages/react-native/Libraries/Blob/URL.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index f3ce3cc6ecb557..280bfdfe7f5ace 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -8,9 +8,9 @@ * @flow */ -import type Blob from './Blob'; +import type Blob from 'react-native/Libraries/Blob/Blob'; -import NativeBlobModule from './NativeBlobModule'; +import NativeBlobModule from 'react-native/Libraries/Blob/NativeBlobModule'; let BLOB_URL_PREFIX = null; @@ -52,7 +52,7 @@ if ( * ``` */ -export {URLSearchParams} from './URLSearchParams'; +export {URLSearchParams} from 'react-native/Libraries/Blob/URLSearchParams'; function validateBaseUrl(url: string) { // from this MIT-licensed gist: https://gist.github.com/dperini/729294 @@ -72,6 +72,7 @@ export class URL { return `${BLOB_URL_PREFIX}${blob.data.blobId}?offset=${blob.data.offset}&size=${blob.size}`; } + static revokeObjectURL(url: string) { // Do nothing. } @@ -112,13 +113,14 @@ export class URL { } get host(): string { - const hostMatch = this._url.match(/^https?:\/\/([^:/?#]+)/); + const hostMatch = this._url.match(/^https?:\/\/(?:[^@]+@)?([^:/?#]+)/); const portMatch = this._url.match(/:(\d+)(?=[/?#]|$)/); + return hostMatch ? hostMatch[1] + (portMatch ? `:${portMatch[1]}` : '') : ''; } get hostname(): string { - const hostnameMatch = this._url.match(/^https?:\/\/([^:/?#]+)/); + const hostnameMatch = this._url.match(/^https?:\/\/(?:[^@]+@)?([^:/?#]+)/); return hostnameMatch ? hostnameMatch[1] : ''; } @@ -136,6 +138,12 @@ export class URL { return passwordMatch ? passwordMatch[1] : ''; } + get username(): string { + + const usernameMatch = this._url.match(/^https?:\/\/([^:@]+)(?::[^@]*)?@/); + return usernameMatch ? usernameMatch[1] : ''; +} + get pathname(): string { const pathMatch = this._url.match(/https?:\/\/[^/]+(\/[^?#]*)?/); return pathMatch ? pathMatch[1] || '/' : '/'; @@ -177,7 +185,4 @@ export class URL { return this._url + separator + instanceString; } - get username(): string { - throw new Error('URL.username is not implemented'); - } } From ba6e546bf626ea84bcd58be2f3cc98f31d41d4a5 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:27:09 +0530 Subject: [PATCH 03/19] Update URL.js From 6db907e84b194dd570a57b149002f8668a1ed29a Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:32:07 +0530 Subject: [PATCH 04/19] Update URL.js --- packages/react-native/Libraries/Blob/URL.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index 280bfdfe7f5ace..1eb5249dc79b63 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -8,9 +8,10 @@ * @flow */ -import type Blob from 'react-native/Libraries/Blob/Blob'; +import type Blob from './Blob'; + +import NativeBlobModule from './NativeBlobModule'; -import NativeBlobModule from 'react-native/Libraries/Blob/NativeBlobModule'; let BLOB_URL_PREFIX = null; From 73b370410abd41d271b540139bd52c08964606d4 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:33:57 +0530 Subject: [PATCH 05/19] Update URL.js --- packages/react-native/Libraries/Blob/URL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index 1eb5249dc79b63..0306312c58c75d 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -53,7 +53,7 @@ if ( * ``` */ -export {URLSearchParams} from 'react-native/Libraries/Blob/URLSearchParams'; +export {URLSearchParams} from './URLSearchParams'; function validateBaseUrl(url: string) { // from this MIT-licensed gist: https://gist.github.com/dperini/729294 From 972a83fb587792c0da1d8e403ce457e6c9e740b1 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:36:31 +0530 Subject: [PATCH 06/19] Update URL-test.js --- .../Libraries/Blob/__tests__/URL-test.js | 101 +++++++++++++----- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/packages/react-native/Libraries/Blob/__tests__/URL-test.js b/packages/react-native/Libraries/Blob/__tests__/URL-test.js index c317217c8fe724..d78228e6c79657 100644 --- a/packages/react-native/Libraries/Blob/__tests__/URL-test.js +++ b/packages/react-native/Libraries/Blob/__tests__/URL-test.js @@ -13,32 +13,79 @@ const URL = require('../URL').URL; describe('URL', function () { - it('should pass Mozilla Dev Network examples', () => { - const a = new URL('/', 'https://developer.mozilla.org'); - expect(a.href).toBe('https://developer.mozilla.org/'); - const b = new URL('https://developer.mozilla.org'); - expect(b.href).toBe('https://developer.mozilla.org/'); - const c = new URL('en-US/docs', b); - expect(c.href).toBe('https://developer.mozilla.org/en-US/docs'); - const d = new URL('/en-US/docs', b); - expect(d.href).toBe('https://developer.mozilla.org/en-US/docs'); - const f = new URL('/en-US/docs', d); - expect(f.href).toBe('https://developer.mozilla.org/en-US/docs'); - // from original test suite, but requires complex implementation - // const g = new URL( - // '/en-US/docs', - // 'https://developer.mozilla.org/fr-FR/toto', - // ); - // expect(g.href).toBe('https://developer.mozilla.org/en-US/docs'); - const h = new URL('/en-US/docs', a); - expect(h.href).toBe('https://developer.mozilla.org/en-US/docs'); - const i = new URL('http://github.com', 'http://google.com'); - expect(i.href).toBe('http://github.com/'); - // Support Bare Hosts - const j = new URL('home', 'http://localhost'); - expect(j.href).toBe('http://localhost/home'); - // Insert / between Base and Path if missing - const k = new URL('en-US/docs', 'https://developer.mozilla.org'); - expect(k.href).toBe('https://developer.mozilla.org/en-US/docs'); + it('should correctly parse all URL components', () => { + const url = new URL('https://username:password@reactnative.dev:8080/docs/path?query=testQuery&key=value#fragment'); + + expect(url.hash).toBe('#fragment'); + expect(url.host).toBe('reactnative.dev:8080'); + expect(url.hostname).toBe('reactnative.dev'); + expect(url.href).toBe('https://username:password@reactnative.dev:8080/docs/path?query=testQuery&key=value#fragment'); + expect(url.origin).toBe('https://reactnative.dev:8080'); + expect(url.password).toBe('password'); + expect(url.username).toBe('username'); + expect(url.pathname).toBe('/docs/path'); + expect(url.port).toBe('8080'); + expect(url.protocol).toBe('https:'); + expect(url.search).toBe('?query=testQuery&key=value'); + + // Test searchParams parsing + expect(url.searchParams.get('query')).toBe('testQuery'); + expect(url.searchParams.get('key')).toBe('value'); + }); + + it('should handle URLs without authentication correctly', () => { + const url = new URL('https://reactnative.dev/docs'); + + expect(url.username).toBe(''); + expect(url.password).toBe(''); + }); + + it('should handle URLs without query parameters', () => { + const url = new URL('https://reactnative.dev/docs'); + + expect(url.search).toBe(''); + expect(url.searchParams.toString()).toBe(''); + }); + + it('should handle URLs without a port', () => { + const url = new URL('https://reactnative.dev/docs'); + + expect(url.port).toBe(''); + }); + + it('should handle URLs without a hash', () => { + const url = new URL('https://reactnative.dev/docs'); + + expect(url.hash).toBe(''); + }); + + it('should handle URLs with relative paths correctly', () => { + const base = new URL('https://developer.mozilla.org'); + + const url1 = new URL('/en-US/docs', base); + expect(url1.href).toBe('https://developer.mozilla.org/en-US/docs'); + + const url2 = new URL('en-US/docs', base); + expect(url2.href).toBe('https://developer.mozilla.org/en-US/docs'); + }); + + it('should support bare hosts and relative paths', () => { + const url = new URL('home', 'http://localhost'); + expect(url.href).toBe('http://localhost/home'); + }); + + it('should correctly resolve full URLs when given a base URL', () => { + const url = new URL('http://github.com', 'http://google.com'); + expect(url.href).toBe('http://github.com/'); + }); + + it('should insert / between base and path if missing', () => { + const url = new URL('en-US/docs', 'https://developer.mozilla.org'); + expect(url.href).toBe('https://developer.mozilla.org/en-US/docs'); + }); + + it('should default pathname to "/" if no path is provided', () => { + const url = new URL('https://example.com'); + expect(url.pathname).toBe('/'); }); }); From 745d5fc07f9bb16705951ba40229b29f1be662f7 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:51:17 +0530 Subject: [PATCH 07/19] Update URL.js --- packages/react-native/Libraries/Blob/URL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index 0306312c58c75d..4cad18536114de 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -109,7 +109,7 @@ export class URL { } get hash(): string { - const hashMatch = this._url.match(/#(.*)$/); + const hashMatch = this._url.match(/#([^/]*)/); return hashMatch ? `#${hashMatch[1]}` : ''; } From c7c30fd343df5714115e583ae9033d56b0b64d02 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:57:32 +0530 Subject: [PATCH 08/19] Update URL-test.js --- packages/react-native/Libraries/Blob/__tests__/URL-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-native/Libraries/Blob/__tests__/URL-test.js b/packages/react-native/Libraries/Blob/__tests__/URL-test.js index d78228e6c79657..21dba073bd8eac 100644 --- a/packages/react-native/Libraries/Blob/__tests__/URL-test.js +++ b/packages/react-native/Libraries/Blob/__tests__/URL-test.js @@ -19,7 +19,6 @@ describe('URL', function () { expect(url.hash).toBe('#fragment'); expect(url.host).toBe('reactnative.dev:8080'); expect(url.hostname).toBe('reactnative.dev'); - expect(url.href).toBe('https://username:password@reactnative.dev:8080/docs/path?query=testQuery&key=value#fragment'); expect(url.origin).toBe('https://reactnative.dev:8080'); expect(url.password).toBe('password'); expect(url.username).toBe('username'); From 8e332bb76c8a471c673bcac103023e3ddd3a5177 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:02:45 +0530 Subject: [PATCH 09/19] Update URL-test.js --- packages/react-native/Libraries/Blob/__tests__/URL-test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-native/Libraries/Blob/__tests__/URL-test.js b/packages/react-native/Libraries/Blob/__tests__/URL-test.js index 21dba073bd8eac..af0cb3178a9998 100644 --- a/packages/react-native/Libraries/Blob/__tests__/URL-test.js +++ b/packages/react-native/Libraries/Blob/__tests__/URL-test.js @@ -19,12 +19,10 @@ describe('URL', function () { expect(url.hash).toBe('#fragment'); expect(url.host).toBe('reactnative.dev:8080'); expect(url.hostname).toBe('reactnative.dev'); - expect(url.origin).toBe('https://reactnative.dev:8080'); expect(url.password).toBe('password'); expect(url.username).toBe('username'); expect(url.pathname).toBe('/docs/path'); expect(url.port).toBe('8080'); - expect(url.protocol).toBe('https:'); expect(url.search).toBe('?query=testQuery&key=value'); // Test searchParams parsing From 860665d264ff0d9052a292d03ed297b2dfb5a815 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:13:40 +0530 Subject: [PATCH 10/19] Update URL-test.js --- .../Libraries/Blob/__tests__/URL-test.js | 91 +++++++------------ 1 file changed, 32 insertions(+), 59 deletions(-) diff --git a/packages/react-native/Libraries/Blob/__tests__/URL-test.js b/packages/react-native/Libraries/Blob/__tests__/URL-test.js index af0cb3178a9998..25affaa59f79c8 100644 --- a/packages/react-native/Libraries/Blob/__tests__/URL-test.js +++ b/packages/react-native/Libraries/Blob/__tests__/URL-test.js @@ -13,7 +13,38 @@ const URL = require('../URL').URL; describe('URL', function () { - it('should correctly parse all URL components', () => { + it('should pass Mozilla Dev Network examples', () => { + const a = new URL('/', 'https://developer.mozilla.org'); + expect(a.href).toBe('https://developer.mozilla.org/'); + const b = new URL('https://developer.mozilla.org'); + expect(b.href).toBe('https://developer.mozilla.org/'); + const c = new URL('en-US/docs', b); + expect(c.href).toBe('https://developer.mozilla.org/en-US/docs'); + const d = new URL('/en-US/docs', b); + expect(d.href).toBe('https://developer.mozilla.org/en-US/docs'); + const f = new URL('/en-US/docs', d); + expect(f.href).toBe('https://developer.mozilla.org/en-US/docs'); + // from original test suite, but requires complex implementation + // const g = new URL( + // '/en-US/docs', + // 'https://developer.mozilla.org/fr-FR/toto', + // ); + // expect(g.href).toBe('https://developer.mozilla.org/en-US/docs'); + const h = new URL('/en-US/docs', a); + expect(h.href).toBe('https://developer.mozilla.org/en-US/docs'); + const i = new URL('http://github.com', 'http://google.com'); + expect(i.href).toBe('http://github.com/'); + // Support Bare Hosts + const j = new URL('home', 'http://localhost'); + expect(j.href).toBe('http://localhost/home'); + // Insert / between Base and Path if missing + const k = new URL('en-US/docs', 'https://developer.mozilla.org'); + expect(k.href).toBe('https://developer.mozilla.org/en-US/docs'); + + + + + const url = new URL('https://username:password@reactnative.dev:8080/docs/path?query=testQuery&key=value#fragment'); expect(url.hash).toBe('#fragment'); @@ -25,64 +56,6 @@ describe('URL', function () { expect(url.port).toBe('8080'); expect(url.search).toBe('?query=testQuery&key=value'); - // Test searchParams parsing - expect(url.searchParams.get('query')).toBe('testQuery'); - expect(url.searchParams.get('key')).toBe('value'); - }); - - it('should handle URLs without authentication correctly', () => { - const url = new URL('https://reactnative.dev/docs'); - - expect(url.username).toBe(''); - expect(url.password).toBe(''); - }); - - it('should handle URLs without query parameters', () => { - const url = new URL('https://reactnative.dev/docs'); - - expect(url.search).toBe(''); - expect(url.searchParams.toString()).toBe(''); - }); - - it('should handle URLs without a port', () => { - const url = new URL('https://reactnative.dev/docs'); - - expect(url.port).toBe(''); - }); - - it('should handle URLs without a hash', () => { - const url = new URL('https://reactnative.dev/docs'); - - expect(url.hash).toBe(''); - }); - - it('should handle URLs with relative paths correctly', () => { - const base = new URL('https://developer.mozilla.org'); - - const url1 = new URL('/en-US/docs', base); - expect(url1.href).toBe('https://developer.mozilla.org/en-US/docs'); - - const url2 = new URL('en-US/docs', base); - expect(url2.href).toBe('https://developer.mozilla.org/en-US/docs'); - }); - - it('should support bare hosts and relative paths', () => { - const url = new URL('home', 'http://localhost'); - expect(url.href).toBe('http://localhost/home'); - }); - - it('should correctly resolve full URLs when given a base URL', () => { - const url = new URL('http://github.com', 'http://google.com'); - expect(url.href).toBe('http://github.com/'); - }); - - it('should insert / between base and path if missing', () => { - const url = new URL('en-US/docs', 'https://developer.mozilla.org'); - expect(url.href).toBe('https://developer.mozilla.org/en-US/docs'); - }); - it('should default pathname to "/" if no path is provided', () => { - const url = new URL('https://example.com'); - expect(url.pathname).toBe('/'); }); }); From 2a48f56c4ff67238bb97a7ac3b6f1fda7902ea0b Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:14:07 +0530 Subject: [PATCH 11/19] Update URL-test.js --- packages/react-native/Libraries/Blob/__tests__/URL-test.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/react-native/Libraries/Blob/__tests__/URL-test.js b/packages/react-native/Libraries/Blob/__tests__/URL-test.js index 25affaa59f79c8..6adc412618b9a0 100644 --- a/packages/react-native/Libraries/Blob/__tests__/URL-test.js +++ b/packages/react-native/Libraries/Blob/__tests__/URL-test.js @@ -40,13 +40,8 @@ describe('URL', function () { // Insert / between Base and Path if missing const k = new URL('en-US/docs', 'https://developer.mozilla.org'); expect(k.href).toBe('https://developer.mozilla.org/en-US/docs'); - - - - - + //More cases const url = new URL('https://username:password@reactnative.dev:8080/docs/path?query=testQuery&key=value#fragment'); - expect(url.hash).toBe('#fragment'); expect(url.host).toBe('reactnative.dev:8080'); expect(url.hostname).toBe('reactnative.dev'); From fb7c83872f7564113ffd5b81c2eb8dbfda277181 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:34:23 +0530 Subject: [PATCH 12/19] Update URL.js --- packages/react-native/Libraries/Blob/URL.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index 4cad18536114de..08ef52bd2a1678 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -12,7 +12,6 @@ import type Blob from './Blob'; import NativeBlobModule from './NativeBlobModule'; - let BLOB_URL_PREFIX = null; if ( @@ -73,7 +72,6 @@ export class URL { return `${BLOB_URL_PREFIX}${blob.data.blobId}?offset=${blob.data.offset}&size=${blob.size}`; } - static revokeObjectURL(url: string) { // Do nothing. } @@ -109,14 +107,12 @@ export class URL { } get hash(): string { - const hashMatch = this._url.match(/#([^/]*)/); - return hashMatch ? `#${hashMatch[1]}` : ''; + throw new Error('URL.hash is not implemented'); } get host(): string { const hostMatch = this._url.match(/^https?:\/\/(?:[^@]+@)?([^:/?#]+)/); const portMatch = this._url.match(/:(\d+)(?=[/?#]|$)/); - return hostMatch ? hostMatch[1] + (portMatch ? `:${portMatch[1]}` : '') : ''; } @@ -139,12 +135,6 @@ export class URL { return passwordMatch ? passwordMatch[1] : ''; } - get username(): string { - - const usernameMatch = this._url.match(/^https?:\/\/([^:@]+)(?::[^@]*)?@/); - return usernameMatch ? usernameMatch[1] : ''; -} - get pathname(): string { const pathMatch = this._url.match(/https?:\/\/[^/]+(\/[^?#]*)?/); return pathMatch ? pathMatch[1] || '/' : '/'; @@ -186,4 +176,8 @@ export class URL { return this._url + separator + instanceString; } + get username(): string { + const usernameMatch = this._url.match(/^https?:\/\/([^:@]+)(?::[^@]*)?@/); + return usernameMatch ? usernameMatch[1] : ''; + } } From bbfe771f0ba8ddd29df6433d46b9f6cec90d93ec Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Shukla <75062358+riteshshukla04@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:37:46 +0530 Subject: [PATCH 13/19] Update URL.js --- packages/react-native/Libraries/Blob/URL.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index 08ef52bd2a1678..5ec76a44b6641f 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -107,7 +107,8 @@ export class URL { } get hash(): string { - throw new Error('URL.hash is not implemented'); + const hashMatch = this._url.match(/#([^/]*)/); + return hashMatch ? `#${hashMatch[1]}` : ''; } get host(): string { From 97791cad610328a0571749ce9d6a3fc00960e09e Mon Sep 17 00:00:00 2001 From: Ritesh Shukla Date: Wed, 12 Mar 2025 00:49:43 +0530 Subject: [PATCH 14/19] Lint Fix --- packages/react-native/Libraries/Blob/URL.js | 8 +++++--- .../react-native/Libraries/Blob/__tests__/URL-test.js | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js index 5ec76a44b6641f..c9f6d933a556e9 100644 --- a/packages/react-native/Libraries/Blob/URL.js +++ b/packages/react-native/Libraries/Blob/URL.js @@ -107,14 +107,16 @@ export class URL { } get hash(): string { - const hashMatch = this._url.match(/#([^/]*)/); - return hashMatch ? `#${hashMatch[1]}` : ''; + const hashMatch = this._url.match(/#([^/]*)/); + return hashMatch ? `#${hashMatch[1]}` : ''; } get host(): string { const hostMatch = this._url.match(/^https?:\/\/(?:[^@]+@)?([^:/?#]+)/); const portMatch = this._url.match(/:(\d+)(?=[/?#]|$)/); - return hostMatch ? hostMatch[1] + (portMatch ? `:${portMatch[1]}` : '') : ''; + return hostMatch + ? hostMatch[1] + (portMatch ? `:${portMatch[1]}` : '') + : ''; } get hostname(): string { diff --git a/packages/react-native/Libraries/Blob/__tests__/URL-test.js b/packages/react-native/Libraries/Blob/__tests__/URL-test.js index 6adc412618b9a0..a0d3be1b6ab1ab 100644 --- a/packages/react-native/Libraries/Blob/__tests__/URL-test.js +++ b/packages/react-native/Libraries/Blob/__tests__/URL-test.js @@ -41,7 +41,9 @@ 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'); //More cases - const url = new URL('https://username:password@reactnative.dev:8080/docs/path?query=testQuery&key=value#fragment'); + const url = new URL( + 'https://username:password@reactnative.dev:8080/docs/path?query=testQuery&key=value#fragment', + ); expect(url.hash).toBe('#fragment'); expect(url.host).toBe('reactnative.dev:8080'); expect(url.hostname).toBe('reactnative.dev'); @@ -50,7 +52,5 @@ describe('URL', function () { expect(url.pathname).toBe('/docs/path'); expect(url.port).toBe('8080'); expect(url.search).toBe('?query=testQuery&key=value'); - - }); }); From 937981146872c0ae4c7b86b30131ab7b2c3cfc8c Mon Sep 17 00:00:00 2001 From: Ritesh Shukla Date: Wed, 12 Mar 2025 06:47:34 +0530 Subject: [PATCH 15/19] Trigger CI From 7412f228eb84537cc9e0703387cd02b8c13bf389 Mon Sep 17 00:00:00 2001 From: Ritesh Shukla Date: Thu, 13 Mar 2025 00:01:03 +0530 Subject: [PATCH 16/19] Tried adding Example in RNTester From 0c1af8f59b69cc65c8863345ad0761194ff56405 Mon Sep 17 00:00:00 2001 From: Ritesh Shukla Date: Thu, 13 Mar 2025 00:01:10 +0530 Subject: [PATCH 17/19] Tried adding Example in RNTester --- .../rn-tester/js/examples/Urls/UrlExample.js | 92 +++++++++++++++++++ .../js/utils/RNTesterList.android.js | 5 + .../rn-tester/js/utils/RNTesterList.ios.js | 5 + 3 files changed, 102 insertions(+) create mode 100644 packages/rn-tester/js/examples/Urls/UrlExample.js diff --git a/packages/rn-tester/js/examples/Urls/UrlExample.js b/packages/rn-tester/js/examples/Urls/UrlExample.js new file mode 100644 index 00000000000000..7deee01f3f2129 --- /dev/null +++ b/packages/rn-tester/js/examples/Urls/UrlExample.js @@ -0,0 +1,92 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; + +import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; + +import RNTesterText from '../../components/RNTesterText'; +import React from 'react'; +import {View,StyleSheet} from 'react-native'; + +type Props = { + url:string; +} + +function URLComponent(props:Props) { + + + const url = new URL(props.url); + const parsedUrl = new URL(url); + return ( + + {`href: ${parsedUrl.href}`} + {`hash: ${parsedUrl.hash}`} + {`host: ${parsedUrl.host}`} + {`hostname: ${parsedUrl.hostname}`} + {`password: ${parsedUrl.password}`} + {`username: ${parsedUrl.username}`} + {`pathname: ${parsedUrl.pathname}`} + {`port: ${parsedUrl.port}`} + {`search: ${parsedUrl.search}`} + + ); + +} + +const styles = StyleSheet.create({ + container: { + padding: 10, + }, +}); + +exports.title = 'URL'; +exports.category = 'Basic'; +exports.description = 'URL Parameters test'; +exports.examples = [ + { + title: 'completeURL', + description: 'URL with username,password,port,and queryparams', + render(): React.Node { + return ( + + ); + }, + }, + { + title: 'basicURL', + description: 'Basic URL without username, password, or port', + render(): React.Node { + return ( + + ); + }, + }, + { + title: 'queryParamsURL', + description: 'URL with query parameters', + render(): React.Node { + return ( + + ); + }, + }, + { + title: 'authAndPortURL', + description: 'URL with username, password, and port', + render(): React.Node { + return ( + + ); + }, + }, + + +] as Array; diff --git a/packages/rn-tester/js/utils/RNTesterList.android.js b/packages/rn-tester/js/utils/RNTesterList.android.js index cde36a290befc9..5dd22bef5ae3c1 100644 --- a/packages/rn-tester/js/utils/RNTesterList.android.js +++ b/packages/rn-tester/js/utils/RNTesterList.android.js @@ -187,6 +187,11 @@ const APIs: Array = ([ category: 'Basic', module: require('../examples/AppState/AppStateExample'), }, + { + key: 'URLExample', + category: 'Basic', + module: require('../examples/Urls/UrlExample'), + }, { key: 'BorderExample', category: 'UI', diff --git a/packages/rn-tester/js/utils/RNTesterList.ios.js b/packages/rn-tester/js/utils/RNTesterList.ios.js index 6f9f1456cb6e9f..00514ce0201139 100644 --- a/packages/rn-tester/js/utils/RNTesterList.ios.js +++ b/packages/rn-tester/js/utils/RNTesterList.ios.js @@ -192,6 +192,11 @@ const APIs: Array = ([ key: 'AppStateExample', module: require('../examples/AppState/AppStateExample'), }, + { + key: 'URLExample', + category: 'Basic', + module: require('../examples/Urls/UrlExample'), + }, { key: 'BorderExample', module: require('../examples/Border/BorderExample').default, From f7440c7c465ef0058dcb2be51689002487e8f771 Mon Sep 17 00:00:00 2001 From: Ritesh Shukla Date: Thu, 13 Mar 2025 00:13:36 +0530 Subject: [PATCH 18/19] Fixing Issue with Flow --- packages/rn-tester/js/examples/Urls/UrlExample.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/rn-tester/js/examples/Urls/UrlExample.js b/packages/rn-tester/js/examples/Urls/UrlExample.js index 7deee01f3f2129..e8ace4db5d744f 100644 --- a/packages/rn-tester/js/examples/Urls/UrlExample.js +++ b/packages/rn-tester/js/examples/Urls/UrlExample.js @@ -23,8 +23,7 @@ type Props = { function URLComponent(props:Props) { - const url = new URL(props.url); - const parsedUrl = new URL(url); + const parsedUrl = new URL(props.url); return ( {`href: ${parsedUrl.href}`} From 444c7373a2044b5ac461bfe0cbd77d2b84dfd49a Mon Sep 17 00:00:00 2001 From: Ritesh Shukla Date: Thu, 13 Mar 2025 00:19:32 +0530 Subject: [PATCH 19/19] Prettier Fixed --- .../rn-tester/js/examples/Urls/UrlExample.js | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/packages/rn-tester/js/examples/Urls/UrlExample.js b/packages/rn-tester/js/examples/Urls/UrlExample.js index e8ace4db5d744f..62ee124948ba8c 100644 --- a/packages/rn-tester/js/examples/Urls/UrlExample.js +++ b/packages/rn-tester/js/examples/Urls/UrlExample.js @@ -14,30 +14,27 @@ import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; import RNTesterText from '../../components/RNTesterText'; import React from 'react'; -import {View,StyleSheet} from 'react-native'; +import {View, StyleSheet} from 'react-native'; type Props = { - url:string; -} - -function URLComponent(props:Props) { - + url: string, +}; +function URLComponent(props: Props) { const parsedUrl = new URL(props.url); return ( - {`href: ${parsedUrl.href}`} - {`hash: ${parsedUrl.hash}`} - {`host: ${parsedUrl.host}`} - {`hostname: ${parsedUrl.hostname}`} - {`password: ${parsedUrl.password}`} - {`username: ${parsedUrl.username}`} - {`pathname: ${parsedUrl.pathname}`} - {`port: ${parsedUrl.port}`} - {`search: ${parsedUrl.search}`} + {`href: ${parsedUrl.href}`} + {`hash: ${parsedUrl.hash}`} + {`host: ${parsedUrl.host}`} + {`hostname: ${parsedUrl.hostname}`} + {`password: ${parsedUrl.password}`} + {`username: ${parsedUrl.username}`} + {`pathname: ${parsedUrl.pathname}`} + {`port: ${parsedUrl.port}`} + {`search: ${parsedUrl.search}`} ); - } const styles = StyleSheet.create({ @@ -55,7 +52,11 @@ exports.examples = [ description: 'URL with username,password,port,and queryparams', render(): React.Node { return ( - + ); }, }, @@ -63,9 +64,7 @@ exports.examples = [ title: 'basicURL', description: 'Basic URL without username, password, or port', render(): React.Node { - return ( - - ); + return ; }, }, { @@ -73,7 +72,9 @@ exports.examples = [ description: 'URL with query parameters', render(): React.Node { return ( - + ); }, }, @@ -82,10 +83,10 @@ exports.examples = [ description: 'URL with username, password, and port', render(): React.Node { return ( - + ); }, }, - - ] as Array;