| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -79,7 +79,6 @@ const path = require('path'); | |||
| 79 | 79 | ||
| 80 | 80 | const { | |
| 81 | 81 | validateFunction, | |
| 82 | - validateObject, | ||
| 83 | 82 | } = require('internal/validators'); | |
| 84 | 83 | ||
| 85 | 84 | const querystring = require('querystring'); | |
@@ -152,8 +151,6 @@ class URLContext { | |||
| 152 | 151 | password = ''; | |
| 153 | 152 | port = ''; | |
| 154 | 153 | hash = ''; | |
| 155 | - hasHost = false; | ||
| 156 | - hasOpaquePath = false; | ||
| 157 | 154 | } | |
| 158 | 155 | ||
| 159 | 156 | function isURLSearchParams(self) { | |
@@ -290,7 +287,9 @@ class URLSearchParams { | |||
| 290 | 287 | name = toUSVString(name); | |
| 291 | 288 | value = toUSVString(value); | |
| 292 | 289 | ArrayPrototypePush(this[searchParams], name, value); | |
| 293 | - update(this[context], this); | ||
| 290 | + if (this[context]) { | ||
| 291 | + this[context].search = this.toString(); | ||
| 292 | + } | ||
| 294 | 293 | } | |
| 295 | 294 | ||
| 296 | 295 | delete(name) { | |
@@ -311,7 +310,9 @@ class URLSearchParams { | |||
| 311 | 310 | i += 2; | |
| 312 | 311 | } | |
| 313 | 312 | } | |
| 314 | - update(this[context], this); | ||
| 313 | + if (this[context]) { | ||
| 314 | + this[context].search = this.toString(); | ||
| 315 | + } | ||
| 315 | 316 | } | |
| 316 | 317 | ||
| 317 | 318 | get(name) { | |
@@ -406,7 +407,9 @@ class URLSearchParams { | |||
| 406 | 407 | ArrayPrototypePush(list, name, value); | |
| 407 | 408 | } | |
| 408 | 409 | ||
| 409 | - update(this[context], this); | ||
| 410 | + if (this[context]) { | ||
| 411 | + this[context].search = this.toString(); | ||
| 412 | + } | ||
| 410 | 413 | } | |
| 411 | 414 | ||
| 412 | 415 | sort() { | |
@@ -450,7 +453,9 @@ class URLSearchParams { | |||
| 450 | 453 | } | |
| 451 | 454 | } | |
| 452 | 455 | ||
| 453 | - update(this[context], this); | ||
| 456 | + if (this[context]) { | ||
| 457 | + this[context].search = this.toString(); | ||
| 458 | + } | ||
| 454 | 459 | } | |
| 455 | 460 | ||
| 456 | 461 | // https://heycam.github.io/webidl/#es-iterators | |
@@ -536,46 +541,6 @@ function isURLThis(self) { | |||
| 536 | 541 | return self != null && ObjectPrototypeHasOwnProperty(self, context); | |
| 537 | 542 | } | |
| 538 | 543 | ||
| 539 | - function constructHref(ctx, options) { | ||
| 540 | - if (options) | ||
| 541 | - validateObject(options, 'options'); | ||
| 542 | - | ||
| 543 | - options = { | ||
| 544 | - fragment: true, | ||
| 545 | - unicode: false, | ||
| 546 | - search: true, | ||
| 547 | - auth: true, | ||
| 548 | - ...options, | ||
| 549 | - }; | ||
| 550 | - | ||
| 551 | - // https://url.spec.whatwg.org/#url-serializing | ||
| 552 | - let ret = ctx.protocol; | ||
| 553 | - if (ctx.hasHost) { | ||
| 554 | - ret += '//'; | ||
| 555 | - const hasUsername = ctx.username !== ''; | ||
| 556 | - const hasPassword = ctx.password !== ''; | ||
| 557 | - if (options.auth && (hasUsername || hasPassword)) { | ||
| 558 | - if (hasUsername) | ||
| 559 | - ret += ctx.username; | ||
| 560 | - if (hasPassword) | ||
| 561 | - ret += `:${ctx.password}`; | ||
| 562 | - ret += '@'; | ||
| 563 | - } | ||
| 564 | - ret += options.unicode ? | ||
| 565 | - domainToUnicode(ctx.hostname) : ctx.hostname; | ||
| 566 | - if (ctx.port !== '') | ||
| 567 | - ret += `:${ctx.port}`; | ||
| 568 | - } else if (!ctx.hasOpaquePath && ctx.pathname.lastIndexOf('/') !== 0 && ctx.pathname.startsWith('//')) { | ||
| 569 | - ret += '/.'; | ||
| 570 | - } | ||
| 571 | - ret += ctx.pathname; | ||
| 572 | - if (options.search) | ||
| 573 | - ret += ctx.search; | ||
| 574 | - if (options.fragment) | ||
| 575 | - ret += ctx.hash; | ||
| 576 | - return ret; | ||
| 577 | - } | ||
| 578 | - | ||
| 579 | 544 | class URL { | |
| 580 | 545 | constructor(input, base = undefined) { | |
| 581 | 546 | // toUSVString is not needed. | |
@@ -628,14 +593,8 @@ class URL { | |||
| 628 | 593 | return `${constructor.name} ${inspect(obj, opts)}`; | |
| 629 | 594 | } | |
| 630 | 595 | ||
| 631 | - [kFormat](options) { | ||
| 632 | - // TODO(@anonrig): Replace kFormat with actually calling setters. | ||
| 633 | - return constructHref(this[context], options); | ||
| 634 | - } | ||
| 635 | - | ||
| 636 | 596 | #onParseComplete = (href, origin, protocol, hostname, pathname, | |
| 637 | - search, username, password, port, hash, hasHost, | ||
| 638 | - hasOpaquePath) => { | ||
| 597 | + search, username, password, port, hash) => { | ||
| 639 | 598 | const ctx = this[context]; | |
| 640 | 599 | ctx.href = href; | |
| 641 | 600 | ctx.origin = origin; | |
@@ -647,9 +606,6 @@ class URL { | |||
| 647 | 606 | ctx.password = password; | |
| 648 | 607 | ctx.port = port; | |
| 649 | 608 | ctx.hash = hash; | |
| 650 | - // TODO(@anonrig): Remove hasHost and hasOpaquePath when kFormat is removed. | ||
| 651 | - ctx.hasHost = hasHost; | ||
| 652 | - ctx.hasOpaquePath = hasOpaquePath; | ||
| 653 | 609 | if (!this[searchParams]) { // Invoked from URL constructor | |
| 654 | 610 | this[searchParams] = new URLSearchParams(); | |
| 655 | 611 | this[searchParams][context] = this; | |
@@ -862,33 +818,6 @@ ObjectDefineProperties(URL, { | |||
| 862 | 818 | revokeObjectURL: kEnumerableProperty, | |
| 863 | 819 | }); | |
| 864 | 820 | ||
| 865 | - function update(url, params) { | ||
| 866 | - if (!url) | ||
| 867 | - return; | ||
| 868 | - | ||
| 869 | - const ctx = url[context]; | ||
| 870 | - const serializedParams = params.toString(); | ||
| 871 | - if (serializedParams.length > 0) { | ||
| 872 | - ctx.search = '?' + serializedParams; | ||
| 873 | - } else { | ||
| 874 | - ctx.search = ''; | ||
| 875 | - | ||
| 876 | - // Potentially strip trailing spaces from an opaque path | ||
| 877 | - if (ctx.hasOpaquePath && ctx.hash.length === 0) { | ||
| 878 | - let length = ctx.pathname.length; | ||
| 879 | - while (length > 0 && ctx.pathname.charCodeAt(length - 1) === 32) { | ||
| 880 | - length--; | ||
| 881 | - } | ||
| 882 | - | ||
| 883 | - // No need to copy the whole string if there is no space at the end | ||
| 884 | - if (length !== ctx.pathname.length) { | ||
| 885 | - ctx.pathname = ctx.pathname.slice(0, length); | ||
| 886 | - } | ||
| 887 | - } | ||
| 888 | - } | ||
| 889 | - ctx.href = constructHref(ctx); | ||
| 890 | - } | ||
| 891 | - | ||
| 892 | 821 | function initSearchParams(url, init) { | |
| 893 | 822 | if (!init) { | |
| 894 | 823 | url[searchParams] = []; | |
@@ -1387,7 +1316,6 @@ module.exports = { | |||
| 1387 | 1316 | domainToASCII, | |
| 1388 | 1317 | domainToUnicode, | |
| 1389 | 1318 | urlToHttpOptions, | |
| 1390 | - formatSymbol: kFormat, | ||
| 1391 | 1319 | searchParamsSymbol: searchParams, | |
| 1392 | 1320 | encodeStr, | |
| 1393 | 1321 | }; | |
| 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 | ObjectCreate, | |
| 27 | 28 | ObjectKeys, | |
@@ -38,7 +39,10 @@ const { | |||
| 38 | 39 | ERR_INVALID_ARG_TYPE, | |
| 39 | 40 | ERR_INVALID_URL, | |
| 40 | 41 | } = require('internal/errors').codes; | |
| 41 | - const { validateString } = require('internal/validators'); | ||
| 42 | + const { | ||
| 43 | + validateString, | ||
| 44 | + validateObject, | ||
| 45 | + } = require('internal/validators'); | ||
| 42 | 46 | ||
| 43 | 47 | // This ensures setURLConstructor() is called before the native | |
| 44 | 48 | // URL::ToObject() method is used. | |
@@ -51,11 +55,14 @@ const { | |||
| 51 | 55 | domainToASCII, | |
| 52 | 56 | domainToUnicode, | |
| 53 | 57 | fileURLToPath, | |
| 54 | - formatSymbol, | ||
| 55 | 58 | pathToFileURL, | |
| 56 | 59 | urlToHttpOptions, | |
| 57 | 60 | } = require('internal/url'); | |
| 58 | 61 | ||
| 62 | + const { | ||
| 63 | + formatUrl, | ||
| 64 | + } = internalBinding('url'); | ||
| 65 | + | ||
| 59 | 66 | // Original url.parse() API | |
| 60 | 67 | ||
| 61 | 68 | function Url() { | |
@@ -579,13 +586,36 @@ function urlFormat(urlObject, options) { | |||
| 579 | 586 | } else if (typeof urlObject !== 'object' || urlObject === null) { | |
| 580 | 587 | throw new ERR_INVALID_ARG_TYPE('urlObject', | |
| 581 | 588 | ['Object', 'string'], urlObject); | |
| 582 | - } else if (!(urlObject instanceof Url)) { | ||
| 583 | - const format = urlObject[formatSymbol]; | ||
| 584 | - return format ? | ||
| 585 | - format.call(urlObject, options) : | ||
| 586 | - Url.prototype.format.call(urlObject); | ||
| 589 | + } else if (urlObject instanceof URL) { | ||
| 590 | + let fragment = true; | ||
| 591 | + let unicode = false; | ||
| 592 | + let search = true; | ||
| 593 | + let auth = true; | ||
| 594 | + | ||
| 595 | + if (options) { | ||
| 596 | + validateObject(options, 'options'); | ||
| 597 | + | ||
| 598 | + if (options.fragment != null) { | ||
| 599 | + fragment = Boolean(options.fragment); | ||
| 600 | + } | ||
| 601 | + | ||
| 602 | + if (options.unicode != null) { | ||
| 603 | + unicode = Boolean(options.unicode); | ||
| 604 | + } | ||
| 605 | + | ||
| 606 | + if (options.search != null) { | ||
| 607 | + search = Boolean(options.search); | ||
| 608 | + } | ||
| 609 | + | ||
| 610 | + if (options.auth != null) { | ||
| 611 | + auth = Boolean(options.auth); | ||
| 612 | + } | ||
| 613 | + } | ||
| 614 | + | ||
| 615 | + return formatUrl(urlObject.href, fragment, unicode, search, auth); | ||
| 587 | 616 | } | |
| 588 | - return urlObject.format(); | ||
| 617 | + | ||
| 618 | + return Url.prototype.format.call(urlObject); | ||
| 589 | 619 | } | |
| 590 | 620 | ||
| 591 | 621 | // 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