diff --git a/packages/react-native/Libraries/Blob/URL.js b/packages/react-native/Libraries/Blob/URL.js
index 395e99d860a888..c9f6d933a556e9 100644
--- a/packages/react-native/Libraries/Blob/URL.js
+++ b/packages/react-native/Libraries/Blob/URL.js
@@ -107,15 +107,21 @@ 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 +129,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 {
@@ -168,6 +180,7 @@ export class URL {
}
get username(): string {
- throw new Error('URL.username is not implemented');
+ const usernameMatch = this._url.match(/^https?:\/\/([^:@]+)(?::[^@]*)?@/);
+ return usernameMatch ? usernameMatch[1] : '';
}
}
diff --git a/packages/react-native/Libraries/Blob/__tests__/URL-test.js b/packages/react-native/Libraries/Blob/__tests__/URL-test.js
index c317217c8fe724..a0d3be1b6ab1ab 100644
--- a/packages/react-native/Libraries/Blob/__tests__/URL-test.js
+++ b/packages/react-native/Libraries/Blob/__tests__/URL-test.js
@@ -40,5 +40,17 @@ 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');
+ expect(url.password).toBe('password');
+ expect(url.username).toBe('username');
+ expect(url.pathname).toBe('/docs/path');
+ expect(url.port).toBe('8080');
+ expect(url.search).toBe('?query=testQuery&key=value');
});
});
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..62ee124948ba8c
--- /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 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}`}
+
+ );
+}
+
+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,