Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ef62e5a

Browse filesBrowse files
KhafraDevRafaelGSS
authored andcommitted
url: implement URL.canParse
PR-URL: #47179 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
1 parent 337123d commit ef62e5a
Copy full SHA for ef62e5a

File tree

Expand file treeCollapse file tree

7 files changed

+122
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

7 files changed

+122
-2
lines changed
Open diff view settings
Collapse file
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
4+
const bench = common.createBenchmark(main, {
5+
type: Object.keys(common.urls),
6+
n: [25e6],
7+
});
8+
9+
function main({ type, n }) {
10+
bench.start();
11+
for (let i = 0; i < n; i += 1)
12+
URL.canParse(common.urls[type]);
13+
bench.end(n);
14+
}
Collapse file

‎doc/api/url.md‎

Copy file name to clipboardExpand all lines: doc/api/url.md
+21Lines changed: 21 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,27 @@ added: v16.7.0
662662
Removes the stored {Blob} identified by the given ID. Attempting to revoke a
663663
ID that isn't registered will silently fail.
664664

665+
#### `URL.canParse(input[, base])`
666+
667+
<!-- YAML
668+
added: REPLACEME
669+
-->
670+
671+
* `input` {string} The absolute or relative input URL to parse. If `input`
672+
is relative, then `base` is required. If `input` is absolute, the `base`
673+
is ignored. If `input` is not a string, it is [converted to a string][] first.
674+
* `base` {string} The base URL to resolve against if the `input` is not
675+
absolute. If `base` is not a string, it is [converted to a string][] first.
676+
* Returns: {boolean}
677+
678+
Checks if an `input` relative to the `base` can be parsed to a `URL`.
679+
680+
```js
681+
const isValid = URL.canParse('/foo', 'https://example.org/'); // true
682+
683+
const isNotValid = URL.canParse('/foo'); // false
684+
```
685+
665686
### Class: `URLSearchParams`
666687

667688
<!-- YAML
Collapse file

‎lib/internal/url.js‎

Copy file name to clipboardExpand all lines: lib/internal/url.js
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const {
8888
domainToASCII: _domainToASCII,
8989
domainToUnicode: _domainToUnicode,
9090
parse,
91+
canParse: _canParse,
9192
updateUrl,
9293
} = internalBinding('url');
9394

@@ -789,6 +790,16 @@ class URL {
789790
// If there's an error, it's ignored.
790791
}
791792
}
793+
794+
static canParse(url, base = undefined) {
795+
url = `${url}`;
796+
797+
if (base !== undefined) {
798+
base = `${base}`;
799+
}
800+
801+
return _canParse(url, base);
802+
}
792803
}
793804

794805
ObjectDefineProperties(URL.prototype, {
@@ -812,6 +823,12 @@ ObjectDefineProperties(URL.prototype, {
812823
ObjectDefineProperties(URL, {
813824
createObjectURL: kEnumerableProperty,
814825
revokeObjectURL: kEnumerableProperty,
826+
canParse: {
827+
__proto__: null,
828+
configurable: true,
829+
writable: true,
830+
enumerable: true,
831+
},
815832
});
816833

817834
// application/x-www-form-urlencoded parser
Collapse file

‎src/node_url.cc‎

Copy file name to clipboardExpand all lines: src/node_url.cc
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,30 @@ void Parse(const FunctionCallbackInfo<Value>& args) {
9393
args.GetReturnValue().Set(true);
9494
}
9595

96+
void CanParse(const FunctionCallbackInfo<Value>& args) {
97+
CHECK_GE(args.Length(), 2);
98+
CHECK(args[0]->IsString()); // input
99+
// args[1] // base url
100+
101+
Environment* env = Environment::GetCurrent(args);
102+
HandleScope handle_scope(env->isolate());
103+
Context::Scope context_scope(env->context());
104+
105+
Utf8Value input(env->isolate(), args[0]);
106+
ada::result base;
107+
ada::url* base_pointer = nullptr;
108+
if (args[1]->IsString()) {
109+
base = ada::parse(Utf8Value(env->isolate(), args[1]).ToString());
110+
if (!base) {
111+
return args.GetReturnValue().Set(false);
112+
}
113+
base_pointer = &base.value();
114+
}
115+
ada::result out = ada::parse(input.ToStringView(), base_pointer);
116+
117+
args.GetReturnValue().Set(out.has_value());
118+
}
119+
96120
void DomainToASCII(const FunctionCallbackInfo<Value>& args) {
97121
Environment* env = Environment::GetCurrent(args);
98122
CHECK_GE(args.Length(), 1);
@@ -285,6 +309,7 @@ void Initialize(Local<Object> target,
285309
void* priv) {
286310
SetMethod(context, target, "parse", Parse);
287311
SetMethod(context, target, "updateUrl", UpdateUrl);
312+
SetMethodNoSideEffect(context, target, "canParse", CanParse);
288313
SetMethodNoSideEffect(context, target, "formatUrl", FormatUrl);
289314

290315
SetMethodNoSideEffect(context, target, "domainToASCII", DomainToASCII);
@@ -294,6 +319,7 @@ void Initialize(Local<Object> target,
294319

295320
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
296321
registry->Register(Parse);
322+
registry->Register(CanParse);
297323
registry->Register(UpdateUrl);
298324
registry->Register(FormatUrl);
299325

Collapse file

‎test/fixtures/wpt/README.md‎

Copy file name to clipboardExpand all lines: test/fixtures/wpt/README.md
+1-1Lines changed: 1 addition & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Last update:
2727
- resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing
2828
- resources: https://github.com/web-platform-tests/wpt/tree/919874f84f/resources
2929
- streams: https://github.com/web-platform-tests/wpt/tree/51750bc8d7/streams
30-
- url: https://github.com/web-platform-tests/wpt/tree/84caeb6fbd/url
30+
- url: https://github.com/web-platform-tests/wpt/tree/7c5c3cc125/url
3131
- user-timing: https://github.com/web-platform-tests/wpt/tree/df24fb604e/user-timing
3232
- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/d8dbe6990b/wasm/jsapi
3333
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi
Collapse file
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// This intentionally does not use resources/urltestdata.json to preserve resources.
2+
[
3+
{
4+
"url": undefined,
5+
"base": undefined,
6+
"expected": false
7+
},
8+
{
9+
"url": "a:b",
10+
"base": undefined,
11+
"expected": true
12+
},
13+
{
14+
"url": undefined,
15+
"base": "a:b",
16+
"expected": false
17+
},
18+
{
19+
"url": "a:/b",
20+
"base": undefined,
21+
"expected": true
22+
},
23+
{
24+
"url": undefined,
25+
"base": "a:/b",
26+
"expected": true
27+
},
28+
{
29+
"url": "https://test:test",
30+
"base": undefined,
31+
"expected": false
32+
},
33+
{
34+
"url": "a",
35+
"base": "https://b/",
36+
"expected": true
37+
}
38+
].forEach(({ url, base, expected }) => {
39+
test(() => {
40+
assert_equals(URL.canParse(url, base), expected);
41+
}, `URL.canParse(${url}, ${base})`);
42+
});
Collapse file

‎test/fixtures/wpt/versions.json‎

Copy file name to clipboardExpand all lines: test/fixtures/wpt/versions.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"path": "streams"
6969
},
7070
"url": {
71-
"commit": "84caeb6fbdf45129f57c67448e6113ee1ced9fb3",
71+
"commit": "7c5c3cc125979b4768d414471e6ab655b473aae8",
7272
"path": "url"
7373
},
7474
"user-timing": {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.