| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -77,7 +77,6 @@ const path = require('path'); | |||
| 77 | 77 | ||
| 78 | 78 | const { | |
| 79 | 79 | validateFunction, | |
| 80 | - validateObject, | ||
| 81 | 80 | } = require('internal/validators'); | |
| 82 | 81 | ||
| 83 | 82 | const querystring = require('querystring'); | |
@@ -150,8 +149,6 @@ class URLContext { | |||
| 150 | 149 | password = ''; | |
| 151 | 150 | port = ''; | |
| 152 | 151 | hash = ''; | |
| 153 | - hasHost = false; | ||
| 154 | - hasOpaquePath = false; | ||
| 155 | 152 | } | |
| 156 | 153 | ||
| 157 | 154 | function isURLSearchParams(self) { | |
@@ -282,7 +279,9 @@ class URLSearchParams { | |||
| 282 | 279 | name = toUSVString(name); | |
| 283 | 280 | value = toUSVString(value); | |
| 284 | 281 | ArrayPrototypePush(this[searchParams], name, value); | |
| 285 | - update(this[context], this); | ||
| 282 | + if (this[context]) { | ||
| 283 | + this[context].search = this.toString(); | ||
| 284 | + } | ||
| 286 | 285 | } | |
| 287 | 286 | ||
| 288 | 287 | delete(name) { | |
@@ -303,7 +302,9 @@ class URLSearchParams { | |||
| 303 | 302 | i += 2; | |
| 304 | 303 | } | |
| 305 | 304 | } | |
| 306 | - update(this[context], this); | ||
| 305 | + if (this[context]) { | ||
| 306 | + this[context].search = this.toString(); | ||
| 307 | + } | ||
| 307 | 308 | } | |
| 308 | 309 | ||
| 309 | 310 | get(name) { | |
@@ -398,7 +399,9 @@ class URLSearchParams { | |||
| 398 | 399 | ArrayPrototypePush(list, name, value); | |
| 399 | 400 | } | |
| 400 | 401 | ||
| 401 | - update(this[context], this); | ||
| 402 | + if (this[context]) { | ||
| 403 | + this[context].search = this.toString(); | ||
| 404 | + } | ||
| 402 | 405 | } | |
| 403 | 406 | ||
| 404 | 407 | sort() { | |
@@ -442,7 +445,9 @@ class URLSearchParams { | |||
| 442 | 445 | } | |
| 443 | 446 | } | |
| 444 | 447 | ||
| 445 | - update(this[context], this); | ||
| 448 | + if (this[context]) { | ||
| 449 | + this[context].search = this.toString(); | ||
| 450 | + } | ||
| 446 | 451 | } | |
| 447 | 452 | ||
| 448 | 453 | // https://heycam.github.io/webidl/#es-iterators | |
@@ -528,46 +533,6 @@ function isURLThis(self) { | |||
| 528 | 533 | return (self !== undefined && self !== null && self[context] !== undefined); | |
| 529 | 534 | } | |
| 530 | 535 | ||
| 531 | - function constructHref(ctx, options) { | ||
| 532 | - if (options) | ||
| 533 | - validateObject(options, 'options'); | ||
| 534 | - | ||
| 535 | - options = { | ||
| 536 | - fragment: true, | ||
| 537 | - unicode: false, | ||
| 538 | - search: true, | ||
| 539 | - auth: true, | ||
| 540 | - ...options | ||
| 541 | - }; | ||
| 542 | - | ||
| 543 | - // https://url.spec.whatwg.org/#url-serializing | ||
| 544 | - let ret = ctx.protocol; | ||
| 545 | - if (ctx.hasHost) { | ||
| 546 | - ret += '//'; | ||
| 547 | - const hasUsername = ctx.username !== ''; | ||
| 548 | - const hasPassword = ctx.password !== ''; | ||
| 549 | - if (options.auth && (hasUsername || hasPassword)) { | ||
| 550 | - if (hasUsername) | ||
| 551 | - ret += ctx.username; | ||
| 552 | - if (hasPassword) | ||
| 553 | - ret += `:${ctx.password}`; | ||
| 554 | - ret += '@'; | ||
| 555 | - } | ||
| 556 | - ret += options.unicode ? | ||
| 557 | - domainToUnicode(ctx.hostname) : ctx.hostname; | ||
| 558 | - if (ctx.port !== '') | ||
| 559 | - ret += `:${ctx.port}`; | ||
| 560 | - } else if (!ctx.hasOpaquePath && ctx.pathname.lastIndexOf('/') !== 0 && ctx.pathname.startsWith('//')) { | ||
| 561 | - ret += '/.'; | ||
| 562 | - } | ||
| 563 | - ret += ctx.pathname; | ||
| 564 | - if (options.search) | ||
| 565 | - ret += ctx.search; | ||
| 566 | - if (options.fragment) | ||
| 567 | - ret += ctx.hash; | ||
| 568 | - return ret; | ||
| 569 | - } | ||
| 570 | - | ||
| 571 | 536 | class URL { | |
| 572 | 537 | constructor(input, base = undefined) { | |
| 573 | 538 | // toUSVString is not needed. | |
@@ -620,14 +585,8 @@ class URL { | |||
| 620 | 585 | return `${constructor.name} ${inspect(obj, opts)}`; | |
| 621 | 586 | } | |
| 622 | 587 | ||
| 623 | - [kFormat](options) { | ||
| 624 | - // TODO(@anonrig): Replace kFormat with actually calling setters. | ||
| 625 | - return constructHref(this[context], options); | ||
| 626 | - } | ||
| 627 | - | ||
| 628 | 588 | #onParseComplete = (href, origin, protocol, hostname, pathname, | |
| 629 | - search, username, password, port, hash, hasHost, | ||
| 630 | - hasOpaquePath) => { | ||
| 589 | + search, username, password, port, hash) => { | ||
| 631 | 590 | const ctx = this[context]; | |
| 632 | 591 | ctx.href = href; | |
| 633 | 592 | ctx.origin = origin; | |
@@ -639,9 +598,6 @@ class URL { | |||
| 639 | 598 | ctx.password = password; | |
| 640 | 599 | ctx.port = port; | |
| 641 | 600 | ctx.hash = hash; | |
| 642 | - // TODO(@anonrig): Remove hasHost and hasOpaquePath when kFormat is removed. | ||
| 643 | - ctx.hasHost = hasHost; | ||
| 644 | - ctx.hasOpaquePath = hasOpaquePath; | ||
| 645 | 601 | if (!this[searchParams]) { // Invoked from URL constructor | |
| 646 | 602 | this[searchParams] = new URLSearchParams(); | |
| 647 | 603 | this[searchParams][context] = this; | |
@@ -854,33 +810,6 @@ ObjectDefineProperties(URL, { | |||
| 854 | 810 | revokeObjectURL: kEnumerableProperty, | |
| 855 | 811 | }); | |
| 856 | 812 | ||
| 857 | - function update(url, params) { | ||
| 858 | - if (!url) | ||
| 859 | - return; | ||
| 860 | - | ||
| 861 | - const ctx = url[context]; | ||
| 862 | - const serializedParams = params.toString(); | ||
| 863 | - if (serializedParams.length > 0) { | ||
| 864 | - ctx.search = '?' + serializedParams; | ||
| 865 | - } else { | ||
| 866 | - ctx.search = ''; | ||
| 867 | - | ||
| 868 | - // Potentially strip trailing spaces from an opaque path | ||
| 869 | - if (ctx.hasOpaquePath && ctx.hash.length === 0) { | ||
| 870 | - let length = ctx.pathname.length; | ||
| 871 | - while (length > 0 && ctx.pathname.charCodeAt(length - 1) === 32) { | ||
| 872 | - length--; | ||
| 873 | - } | ||
| 874 | - | ||
| 875 | - // No need to copy the whole string if there is no space at the end | ||
| 876 | - if (length !== ctx.pathname.length) { | ||
| 877 | - ctx.pathname = ctx.pathname.slice(0, length); | ||
| 878 | - } | ||
| 879 | - } | ||
| 880 | - } | ||
| 881 | - ctx.href = constructHref(ctx); | ||
| 882 | - } | ||
| 883 | - | ||
| 884 | 813 | function initSearchParams(url, init) { | |
| 885 | 814 | if (!init) { | |
| 886 | 815 | url[searchParams] = []; | |
@@ -1379,7 +1308,6 @@ module.exports = { | |||
| 1379 | 1308 | domainToASCII, | |
| 1380 | 1309 | domainToUnicode, | |
| 1381 | 1310 | urlToHttpOptions, | |
| 1382 | - formatSymbol: kFormat, | ||
| 1383 | 1311 | searchParamsSymbol: searchParams, | |
| 1384 | 1312 | encodeStr | |
| 1385 | 1313 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,6 +22,7 @@ | |||
| 22 | 22 | 'use strict'; | |
| 23 | 23 | ||
| 24 | 24 | const { | |
| 25 | + Boolean, | ||
| 25 | 26 | Int8Array, | |
| 26 | 27 | ObjectKeys, | |
| 27 | 28 | SafeSet, | |
@@ -37,7 +38,10 @@ const { | |||
| 37 | 38 | ERR_INVALID_ARG_TYPE, | |
| 38 | 39 | ERR_INVALID_URL, | |
| 39 | 40 | } = require('internal/errors').codes; | |
| 40 | - const { validateString } = require('internal/validators'); | ||
| 41 | + const { | ||
| 42 | + validateString, | ||
| 43 | + validateObject, | ||
| 44 | + } = require('internal/validators'); | ||
| 41 | 45 | ||
| 42 | 46 | // This ensures setURLConstructor() is called before the native | |
| 43 | 47 | // URL::ToObject() method is used. | |
@@ -50,11 +54,14 @@ const { | |||
| 50 | 54 | domainToASCII, | |
| 51 | 55 | domainToUnicode, | |
| 52 | 56 | fileURLToPath, | |
| 53 | - formatSymbol, | ||
| 54 | 57 | pathToFileURL, | |
| 55 | 58 | urlToHttpOptions, | |
| 56 | 59 | } = require('internal/url'); | |
| 57 | 60 | ||
| 61 | + const { | ||
| 62 | + formatUrl, | ||
| 63 | + } = internalBinding('url'); | ||
| 64 | + | ||
| 58 | 65 | // Original url.parse() API | |
| 59 | 66 | ||
| 60 | 67 | function Url() { | |
@@ -578,13 +585,36 @@ function urlFormat(urlObject, options) { | |||
| 578 | 585 | } else if (typeof urlObject !== 'object' || urlObject === null) { | |
| 579 | 586 | throw new ERR_INVALID_ARG_TYPE('urlObject', | |
| 580 | 587 | ['Object', 'string'], urlObject); | |
| 581 | - } else if (!(urlObject instanceof Url)) { | ||
| 582 | - const format = urlObject[formatSymbol]; | ||
| 583 | - return format ? | ||
| 584 | - format.call(urlObject, options) : | ||
| 585 | - Url.prototype.format.call(urlObject); | ||
| 588 | + } else if (urlObject instanceof URL) { | ||
| 589 | + let fragment = true; | ||
| 590 | + let unicode = false; | ||
| 591 | + let search = true; | ||
| 592 | + let auth = true; | ||
| 593 | + | ||
| 594 | + if (options) { | ||
| 595 | + validateObject(options, 'options'); | ||
| 596 | + | ||
| 597 | + if (options.fragment != null) { | ||
| 598 | + fragment = Boolean(options.fragment); | ||
| 599 | + } | ||
| 600 | + | ||
| 601 | + if (options.unicode != null) { | ||
| 602 | + unicode = Boolean(options.unicode); | ||
| 603 | + } | ||
| 604 | + | ||
| 605 | + if (options.search != null) { | ||
| 606 | + search = Boolean(options.search); | ||
| 607 | + } | ||
| 608 | + | ||
| 609 | + if (options.auth != null) { | ||
| 610 | + auth = Boolean(options.auth); | ||
| 611 | + } | ||
| 612 | + } | ||
| 613 | + | ||
| 614 | + return formatUrl(urlObject.href, fragment, unicode, search, auth); | ||
| 586 | 615 | } | |
| 587 | - return urlObject.format(); | ||
| 616 | + | ||
| 617 | + return Url.prototype.format.call(urlObject); | ||
| 588 | 618 | } | |
| 589 | 619 | ||
| 590 | 620 | // These characters do not need escaping: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | 12 | namespace node { | |
| 13 | 13 | ||
| 14 | - using v8::Boolean; | ||
| 15 | 14 | using v8::Context; | |
| 16 | 15 | using v8::Function; | |
| 17 | 16 | using v8::FunctionCallbackInfo; | |
@@ -47,7 +46,7 @@ enum url_update_action { | |||
| 47 | 46 | kHref = 9, | |
| 48 | 47 | }; | |
| 49 | 48 | ||
| 50 | - void SetArgs(Environment* env, Local<Value> argv[12], const ada::result& url) { | ||
| 49 | + void SetArgs(Environment* env, Local<Value> argv[10], const ada::result& url) { | ||
| 51 | 50 | Isolate* isolate = env->isolate(); | |
| 52 | 51 | argv[0] = Utf8String(isolate, url->get_href()); | |
| 53 | 52 | argv[1] = Utf8String(isolate, url->get_origin()); | |
@@ -59,8 +58,6 @@ void SetArgs(Environment* env, Local<Value> argv[12], const ada::result& url) { | |||
| 59 | 58 | argv[7] = Utf8String(isolate, url->get_password()); | |
| 60 | 59 | argv[8] = Utf8String(isolate, url->get_port()); | |
| 61 | 60 | argv[9] = Utf8String(isolate, url->get_hash()); | |
| 62 | - argv[10] = Boolean::New(isolate, url->host.has_value()); | ||
| 63 | - argv[11] = Boolean::New(isolate, url->has_opaque_path); | ||
| 64 | 61 | } | |
| 65 | 62 | ||
| 66 | 63 | void Parse(const FunctionCallbackInfo<Value>& args) { | |
@@ -86,8 +83,7 @@ void Parse(const FunctionCallbackInfo<Value>& args) { | |||
| 86 | 83 | } | |
| 87 | 84 | base_pointer = &base.value(); | |
| 88 | 85 | } | |
| 89 | - ada::result out = | ||
| 90 | - ada::parse(std::string_view(input.out(), input.length()), base_pointer); | ||
| 86 | + ada::result out = ada::parse(input.ToStringView(), base_pointer); | ||
| 91 | 87 | ||
| 92 | 88 | if (!out) { | |
| 93 | 89 | return args.GetReturnValue().Set(false); | |
@@ -105,8 +101,6 @@ void Parse(const FunctionCallbackInfo<Value>& args) { | |||
| 105 | 101 | undef, | |
| 106 | 102 | undef, | |
| 107 | 103 | undef, | |
| 108 | - undef, | ||
| 109 | - undef, | ||
| 110 | 104 | }; | |
| 111 | 105 | SetArgs(env, argv, out); | |
| 112 | 106 | USE(success_callback_->Call( | |
@@ -192,10 +186,8 @@ void UpdateUrl(const FunctionCallbackInfo<Value>& args) { | |||
| 192 | 186 | Utf8Value new_value(isolate, args[2].As<String>()); | |
| 193 | 187 | Local<Function> success_callback_ = args[3].As<Function>(); | |
| 194 | 188 | ||
| 195 | - std::string_view new_value_view = | ||
| 196 | - std::string_view(new_value.out(), new_value.length()); | ||
| 197 | - std::string_view input_view = std::string_view(input.out(), input.length()); | ||
| 198 | - ada::result out = ada::parse(input_view); | ||
| 189 | + std::string_view new_value_view = new_value.ToStringView(); | ||
| 190 | + ada::result out = ada::parse(input.ToStringView()); | ||
| 199 | 191 | CHECK(out); | |
| 200 | 192 | ||
| 201 | 193 | bool result{true}; | |
@@ -255,21 +247,73 @@ void UpdateUrl(const FunctionCallbackInfo<Value>& args) { | |||
| 255 | 247 | undef, | |
| 256 | 248 | undef, | |
| 257 | 249 | undef, | |
| 258 | - undef, | ||
| 259 | - undef, | ||
| 260 | 250 | }; | |
| 261 | 251 | SetArgs(env, argv, out); | |
| 262 | 252 | USE(success_callback_->Call( | |
| 263 | 253 | env->context(), args.This(), arraysize(argv), argv)); | |
| 264 | 254 | args.GetReturnValue().Set(result); | |
| 265 | 255 | } | |
| 266 | 256 | ||
| 257 | + void FormatUrl(const FunctionCallbackInfo<Value>& args) { | ||
| 258 | + CHECK_GT(args.Length(), 4); | ||
| 259 | + CHECK(args[0]->IsString()); // url href | ||
| 260 | + | ||
| 261 | + Environment* env = Environment::GetCurrent(args); | ||
| 262 | + Isolate* isolate = env->isolate(); | ||
| 263 | + | ||
| 264 | + Utf8Value href(isolate, args[0].As<String>()); | ||
| 265 | + const bool fragment = args[1]->IsTrue(); | ||
| 266 | + const bool unicode = args[2]->IsTrue(); | ||
| 267 | + const bool search = args[3]->IsTrue(); | ||
| 268 | + const bool auth = args[4]->IsTrue(); | ||
| 269 | + | ||
| 270 | + ada::result out = ada::parse(href.ToStringView()); | ||
| 271 | + CHECK(out); | ||
| 272 | + | ||
| 273 | + if (!fragment) { | ||
| 274 | + out->fragment = std::nullopt; | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + if (unicode) { | ||
| 278 | + #if defined(NODE_HAVE_I18N_SUPPORT) | ||
| 279 | + std::string hostname = out->get_hostname(); | ||
| 280 | + MaybeStackBuffer<char> buf; | ||
| 281 | + int32_t len = i18n::ToUnicode(&buf, hostname.data(), hostname.length()); | ||
| 282 | + | ||
| 283 | + if (len < 0) { | ||
| 284 | + out->host = ""; | ||
| 285 | + } else { | ||
| 286 | + out->host = buf.ToString(); | ||
| 287 | + } | ||
| 288 | + #else | ||
| 289 | + out->host = ""; | ||
| 290 | + #endif | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + if (!search) { | ||
| 294 | + out->query = std::nullopt; | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + if (!auth) { | ||
| 298 | + out->username = ""; | ||
| 299 | + out->password = ""; | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + std::string result = out->get_href(); | ||
| 303 | + args.GetReturnValue().Set(String::NewFromUtf8(env->isolate(), | ||
| 304 | + result.data(), | ||
| 305 | + NewStringType::kNormal, | ||
| 306 | + result.length()) | ||
| 307 | + .ToLocalChecked()); | ||
| 308 | + } | ||
| 309 | + | ||
| 267 | 310 | void Initialize(Local<Object> target, | |
| 268 | 311 | Local<Value> unused, | |
| 269 | 312 | Local<Context> context, | |
| 270 | 313 | void* priv) { | |
| 271 | 314 | SetMethod(context, target, "parse", Parse); | |
| 272 | 315 | SetMethod(context, target, "updateUrl", UpdateUrl); | |
| 316 | + SetMethod(context, target, "formatUrl", FormatUrl); | ||
| 273 | 317 | ||
| 274 | 318 | SetMethodNoSideEffect(context, target, "domainToASCII", DomainToASCII); | |
| 275 | 319 | SetMethodNoSideEffect(context, target, "domainToUnicode", DomainToUnicode); | |
@@ -279,6 +323,7 @@ void Initialize(Local<Object> target, | |||
| 279 | 323 | void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |
| 280 | 324 | registry->Register(Parse); | |
| 281 | 325 | registry->Register(UpdateUrl); | |
| 326 | + registry->Register(FormatUrl); | ||
| 282 | 327 | ||
| 283 | 328 | registry->Register(DomainToASCII); | |
| 284 | 329 | registry->Register(DomainToUnicode); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments