url: implement URL.canParse
PR-URL: https://github.com/nodejs/node/pull/47179 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
This commit is contained in:
parent
7bc0e6a4e7
commit
f2651a0812
14
benchmark/url/whatwgurl-canParse.js
Normal file
14
benchmark/url/whatwgurl-canParse.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
'use strict';
|
||||||
|
const common = require('../common.js');
|
||||||
|
|
||||||
|
const bench = common.createBenchmark(main, {
|
||||||
|
type: Object.keys(common.urls),
|
||||||
|
n: [25e6],
|
||||||
|
});
|
||||||
|
|
||||||
|
function main({ type, n }) {
|
||||||
|
bench.start();
|
||||||
|
for (let i = 0; i < n; i += 1)
|
||||||
|
URL.canParse(common.urls[type]);
|
||||||
|
bench.end(n);
|
||||||
|
}
|
@ -662,6 +662,27 @@ added: v16.7.0
|
|||||||
Removes the stored {Blob} identified by the given ID. Attempting to revoke a
|
Removes the stored {Blob} identified by the given ID. Attempting to revoke a
|
||||||
ID that isn't registered will silently fail.
|
ID that isn't registered will silently fail.
|
||||||
|
|
||||||
|
#### `URL.canParse(input[, base])`
|
||||||
|
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
* `input` {string} The absolute or relative input URL to parse. If `input`
|
||||||
|
is relative, then `base` is required. If `input` is absolute, the `base`
|
||||||
|
is ignored. If `input` is not a string, it is [converted to a string][] first.
|
||||||
|
* `base` {string} The base URL to resolve against if the `input` is not
|
||||||
|
absolute. If `base` is not a string, it is [converted to a string][] first.
|
||||||
|
* Returns: {boolean}
|
||||||
|
|
||||||
|
Checks if an `input` relative to the `base` can be parsed to a `URL`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const isValid = URL.canParse('/foo', 'https://example.org/'); // true
|
||||||
|
|
||||||
|
const isNotValid = URL.canParse('/foo'); // false
|
||||||
|
```
|
||||||
|
|
||||||
### Class: `URLSearchParams`
|
### Class: `URLSearchParams`
|
||||||
|
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
|
@ -88,6 +88,7 @@ const {
|
|||||||
domainToASCII: _domainToASCII,
|
domainToASCII: _domainToASCII,
|
||||||
domainToUnicode: _domainToUnicode,
|
domainToUnicode: _domainToUnicode,
|
||||||
parse,
|
parse,
|
||||||
|
canParse: _canParse,
|
||||||
updateUrl,
|
updateUrl,
|
||||||
} = internalBinding('url');
|
} = internalBinding('url');
|
||||||
|
|
||||||
@ -713,6 +714,16 @@ class URL {
|
|||||||
toJSON() {
|
toJSON() {
|
||||||
return this.#context.href;
|
return this.#context.href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static canParse(url, base = undefined) {
|
||||||
|
url = `${url}`;
|
||||||
|
|
||||||
|
if (base !== undefined) {
|
||||||
|
base = `${base}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _canParse(url, base);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectDefineProperties(URL.prototype, {
|
ObjectDefineProperties(URL.prototype, {
|
||||||
@ -733,6 +744,15 @@ ObjectDefineProperties(URL.prototype, {
|
|||||||
toJSON: kEnumerableProperty,
|
toJSON: kEnumerableProperty,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ObjectDefineProperties(URL, {
|
||||||
|
canParse: {
|
||||||
|
__proto__: null,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
enumerable: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
function installObjectURLMethods() {
|
function installObjectURLMethods() {
|
||||||
const {
|
const {
|
||||||
storeDataObject,
|
storeDataObject,
|
||||||
|
@ -93,6 +93,30 @@ void Parse(const FunctionCallbackInfo<Value>& args) {
|
|||||||
args.GetReturnValue().Set(true);
|
args.GetReturnValue().Set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanParse(const FunctionCallbackInfo<Value>& args) {
|
||||||
|
CHECK_GE(args.Length(), 2);
|
||||||
|
CHECK(args[0]->IsString()); // input
|
||||||
|
// args[1] // base url
|
||||||
|
|
||||||
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
HandleScope handle_scope(env->isolate());
|
||||||
|
Context::Scope context_scope(env->context());
|
||||||
|
|
||||||
|
Utf8Value input(env->isolate(), args[0]);
|
||||||
|
ada::result base;
|
||||||
|
ada::url* base_pointer = nullptr;
|
||||||
|
if (args[1]->IsString()) {
|
||||||
|
base = ada::parse(Utf8Value(env->isolate(), args[1]).ToString());
|
||||||
|
if (!base) {
|
||||||
|
return args.GetReturnValue().Set(false);
|
||||||
|
}
|
||||||
|
base_pointer = &base.value();
|
||||||
|
}
|
||||||
|
ada::result out = ada::parse(input.ToStringView(), base_pointer);
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(out.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
void DomainToASCII(const FunctionCallbackInfo<Value>& args) {
|
void DomainToASCII(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
CHECK_GE(args.Length(), 1);
|
CHECK_GE(args.Length(), 1);
|
||||||
@ -285,6 +309,7 @@ void Initialize(Local<Object> target,
|
|||||||
void* priv) {
|
void* priv) {
|
||||||
SetMethod(context, target, "parse", Parse);
|
SetMethod(context, target, "parse", Parse);
|
||||||
SetMethod(context, target, "updateUrl", UpdateUrl);
|
SetMethod(context, target, "updateUrl", UpdateUrl);
|
||||||
|
SetMethodNoSideEffect(context, target, "canParse", CanParse);
|
||||||
SetMethodNoSideEffect(context, target, "formatUrl", FormatUrl);
|
SetMethodNoSideEffect(context, target, "formatUrl", FormatUrl);
|
||||||
|
|
||||||
SetMethodNoSideEffect(context, target, "domainToASCII", DomainToASCII);
|
SetMethodNoSideEffect(context, target, "domainToASCII", DomainToASCII);
|
||||||
@ -294,6 +319,7 @@ void Initialize(Local<Object> target,
|
|||||||
|
|
||||||
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||||
registry->Register(Parse);
|
registry->Register(Parse);
|
||||||
|
registry->Register(CanParse);
|
||||||
registry->Register(UpdateUrl);
|
registry->Register(UpdateUrl);
|
||||||
registry->Register(FormatUrl);
|
registry->Register(FormatUrl);
|
||||||
|
|
||||||
|
2
test/fixtures/wpt/README.md
vendored
2
test/fixtures/wpt/README.md
vendored
@ -27,7 +27,7 @@ Last update:
|
|||||||
- resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing
|
- resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing
|
||||||
- resources: https://github.com/web-platform-tests/wpt/tree/919874f84f/resources
|
- resources: https://github.com/web-platform-tests/wpt/tree/919874f84f/resources
|
||||||
- streams: https://github.com/web-platform-tests/wpt/tree/51750bc8d7/streams
|
- streams: https://github.com/web-platform-tests/wpt/tree/51750bc8d7/streams
|
||||||
- url: https://github.com/web-platform-tests/wpt/tree/84caeb6fbd/url
|
- url: https://github.com/web-platform-tests/wpt/tree/7c5c3cc125/url
|
||||||
- user-timing: https://github.com/web-platform-tests/wpt/tree/df24fb604e/user-timing
|
- user-timing: https://github.com/web-platform-tests/wpt/tree/df24fb604e/user-timing
|
||||||
- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/d8dbe6990b/wasm/jsapi
|
- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/d8dbe6990b/wasm/jsapi
|
||||||
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi
|
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi
|
||||||
|
42
test/fixtures/wpt/url/url-statics-canparse.any.js
vendored
Normal file
42
test/fixtures/wpt/url/url-statics-canparse.any.js
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// This intentionally does not use resources/urltestdata.json to preserve resources.
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"url": undefined,
|
||||||
|
"base": undefined,
|
||||||
|
"expected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "a:b",
|
||||||
|
"base": undefined,
|
||||||
|
"expected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": undefined,
|
||||||
|
"base": "a:b",
|
||||||
|
"expected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "a:/b",
|
||||||
|
"base": undefined,
|
||||||
|
"expected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": undefined,
|
||||||
|
"base": "a:/b",
|
||||||
|
"expected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://test:test",
|
||||||
|
"base": undefined,
|
||||||
|
"expected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "a",
|
||||||
|
"base": "https://b/",
|
||||||
|
"expected": true
|
||||||
|
}
|
||||||
|
].forEach(({ url, base, expected }) => {
|
||||||
|
test(() => {
|
||||||
|
assert_equals(URL.canParse(url, base), expected);
|
||||||
|
}, `URL.canParse(${url}, ${base})`);
|
||||||
|
});
|
2
test/fixtures/wpt/versions.json
vendored
2
test/fixtures/wpt/versions.json
vendored
@ -68,7 +68,7 @@
|
|||||||
"path": "streams"
|
"path": "streams"
|
||||||
},
|
},
|
||||||
"url": {
|
"url": {
|
||||||
"commit": "84caeb6fbdf45129f57c67448e6113ee1ced9fb3",
|
"commit": "7c5c3cc125979b4768d414471e6ab655b473aae8",
|
||||||
"path": "url"
|
"path": "url"
|
||||||
},
|
},
|
||||||
"user-timing": {
|
"user-timing": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user