11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci Array, 51cb0ef41Sopenharmony_ci ArrayIsArray, 61cb0ef41Sopenharmony_ci ArrayPrototypeJoin, 71cb0ef41Sopenharmony_ci ArrayPrototypeMap, 81cb0ef41Sopenharmony_ci ArrayPrototypePush, 91cb0ef41Sopenharmony_ci ArrayPrototypeReduce, 101cb0ef41Sopenharmony_ci ArrayPrototypeSlice, 111cb0ef41Sopenharmony_ci Int8Array, 121cb0ef41Sopenharmony_ci IteratorPrototype, 131cb0ef41Sopenharmony_ci Number, 141cb0ef41Sopenharmony_ci ObjectCreate, 151cb0ef41Sopenharmony_ci ObjectDefineProperties, 161cb0ef41Sopenharmony_ci ObjectDefineProperty, 171cb0ef41Sopenharmony_ci ObjectGetOwnPropertySymbols, 181cb0ef41Sopenharmony_ci ObjectGetPrototypeOf, 191cb0ef41Sopenharmony_ci ObjectKeys, 201cb0ef41Sopenharmony_ci ObjectPrototypeHasOwnProperty, 211cb0ef41Sopenharmony_ci ReflectGetOwnPropertyDescriptor, 221cb0ef41Sopenharmony_ci ReflectOwnKeys, 231cb0ef41Sopenharmony_ci RegExpPrototypeSymbolReplace, 241cb0ef41Sopenharmony_ci SafeMap, 251cb0ef41Sopenharmony_ci SafeSet, 261cb0ef41Sopenharmony_ci SafeWeakMap, 271cb0ef41Sopenharmony_ci StringPrototypeCharAt, 281cb0ef41Sopenharmony_ci StringPrototypeCharCodeAt, 291cb0ef41Sopenharmony_ci StringPrototypeCodePointAt, 301cb0ef41Sopenharmony_ci StringPrototypeIncludes, 311cb0ef41Sopenharmony_ci StringPrototypeIndexOf, 321cb0ef41Sopenharmony_ci StringPrototypeSlice, 331cb0ef41Sopenharmony_ci StringPrototypeSplit, 341cb0ef41Sopenharmony_ci StringPrototypeStartsWith, 351cb0ef41Sopenharmony_ci Symbol, 361cb0ef41Sopenharmony_ci SymbolIterator, 371cb0ef41Sopenharmony_ci SymbolToStringTag, 381cb0ef41Sopenharmony_ci decodeURIComponent, 391cb0ef41Sopenharmony_ci} = primordials; 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ciconst { inspect } = require('internal/util/inspect'); 421cb0ef41Sopenharmony_ciconst { 431cb0ef41Sopenharmony_ci encodeStr, 441cb0ef41Sopenharmony_ci hexTable, 451cb0ef41Sopenharmony_ci isHexTable, 461cb0ef41Sopenharmony_ci} = require('internal/querystring'); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciconst { 491cb0ef41Sopenharmony_ci getConstructorOf, 501cb0ef41Sopenharmony_ci removeColors, 511cb0ef41Sopenharmony_ci toUSVString, 521cb0ef41Sopenharmony_ci kEnumerableProperty, 531cb0ef41Sopenharmony_ci SideEffectFreeRegExpPrototypeSymbolReplace, 541cb0ef41Sopenharmony_ci} = require('internal/util'); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ciconst { 571cb0ef41Sopenharmony_ci codes: { 581cb0ef41Sopenharmony_ci ERR_ARG_NOT_ITERABLE, 591cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 601cb0ef41Sopenharmony_ci ERR_INVALID_ARG_VALUE, 611cb0ef41Sopenharmony_ci ERR_INVALID_FILE_URL_HOST, 621cb0ef41Sopenharmony_ci ERR_INVALID_FILE_URL_PATH, 631cb0ef41Sopenharmony_ci ERR_INVALID_THIS, 641cb0ef41Sopenharmony_ci ERR_INVALID_TUPLE, 651cb0ef41Sopenharmony_ci ERR_INVALID_URL, 661cb0ef41Sopenharmony_ci ERR_INVALID_URL_SCHEME, 671cb0ef41Sopenharmony_ci ERR_MISSING_ARGS, 681cb0ef41Sopenharmony_ci ERR_NO_CRYPTO, 691cb0ef41Sopenharmony_ci }, 701cb0ef41Sopenharmony_ci} = require('internal/errors'); 711cb0ef41Sopenharmony_ciconst { 721cb0ef41Sopenharmony_ci CHAR_AMPERSAND, 731cb0ef41Sopenharmony_ci CHAR_BACKWARD_SLASH, 741cb0ef41Sopenharmony_ci CHAR_EQUAL, 751cb0ef41Sopenharmony_ci CHAR_FORWARD_SLASH, 761cb0ef41Sopenharmony_ci CHAR_LOWERCASE_A, 771cb0ef41Sopenharmony_ci CHAR_LOWERCASE_Z, 781cb0ef41Sopenharmony_ci CHAR_PERCENT, 791cb0ef41Sopenharmony_ci CHAR_PLUS, 801cb0ef41Sopenharmony_ci} = require('internal/constants'); 811cb0ef41Sopenharmony_ciconst path = require('path'); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ciconst { 841cb0ef41Sopenharmony_ci validateFunction, 851cb0ef41Sopenharmony_ci} = require('internal/validators'); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciconst querystring = require('querystring'); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ciconst { platform } = process; 901cb0ef41Sopenharmony_ciconst isWindows = platform === 'win32'; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ciconst bindingUrl = internalBinding('url'); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ciconst { 951cb0ef41Sopenharmony_ci storeDataObject, 961cb0ef41Sopenharmony_ci revokeDataObject, 971cb0ef41Sopenharmony_ci} = internalBinding('blob'); 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ciconst FORWARD_SLASH = /\//g; 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ciconst context = Symbol('context'); 1021cb0ef41Sopenharmony_ciconst searchParams = Symbol('query'); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci/** 1051cb0ef41Sopenharmony_ci * We cannot use private fields without a breaking change, so a WeakMap is the alternative. 1061cb0ef41Sopenharmony_ci * @type {WeakMap<URL,URLSearchParams>} 1071cb0ef41Sopenharmony_ci */ 1081cb0ef41Sopenharmony_ciconst internalSearchParams = new SafeWeakMap(); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci// `unsafeProtocol`, `hostlessProtocol` and `slashedProtocol` is 1111cb0ef41Sopenharmony_ci// deliberately moved to `internal/url` rather than `url`. 1121cb0ef41Sopenharmony_ci// Workers does not bootstrap URL module. Therefore, `SafeSet` 1131cb0ef41Sopenharmony_ci// is not initialized on bootstrap. This case breaks the 1141cb0ef41Sopenharmony_ci// test-require-delete-array-iterator test. 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci// Protocols that can allow "unsafe" and "unwise" chars. 1171cb0ef41Sopenharmony_ciconst unsafeProtocol = new SafeSet([ 1181cb0ef41Sopenharmony_ci 'javascript', 1191cb0ef41Sopenharmony_ci 'javascript:', 1201cb0ef41Sopenharmony_ci]); 1211cb0ef41Sopenharmony_ci// Protocols that never have a hostname. 1221cb0ef41Sopenharmony_ciconst hostlessProtocol = new SafeSet([ 1231cb0ef41Sopenharmony_ci 'javascript', 1241cb0ef41Sopenharmony_ci 'javascript:', 1251cb0ef41Sopenharmony_ci]); 1261cb0ef41Sopenharmony_ci// Protocols that always contain a // bit. 1271cb0ef41Sopenharmony_ciconst slashedProtocol = new SafeSet([ 1281cb0ef41Sopenharmony_ci 'http', 1291cb0ef41Sopenharmony_ci 'http:', 1301cb0ef41Sopenharmony_ci 'https', 1311cb0ef41Sopenharmony_ci 'https:', 1321cb0ef41Sopenharmony_ci 'ftp', 1331cb0ef41Sopenharmony_ci 'ftp:', 1341cb0ef41Sopenharmony_ci 'gopher', 1351cb0ef41Sopenharmony_ci 'gopher:', 1361cb0ef41Sopenharmony_ci 'file', 1371cb0ef41Sopenharmony_ci 'file:', 1381cb0ef41Sopenharmony_ci 'ws', 1391cb0ef41Sopenharmony_ci 'ws:', 1401cb0ef41Sopenharmony_ci 'wss', 1411cb0ef41Sopenharmony_ci 'wss:', 1421cb0ef41Sopenharmony_ci]); 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ciconst updateActions = { 1451cb0ef41Sopenharmony_ci kProtocol: 0, 1461cb0ef41Sopenharmony_ci kHost: 1, 1471cb0ef41Sopenharmony_ci kHostname: 2, 1481cb0ef41Sopenharmony_ci kPort: 3, 1491cb0ef41Sopenharmony_ci kUsername: 4, 1501cb0ef41Sopenharmony_ci kPassword: 5, 1511cb0ef41Sopenharmony_ci kPathname: 6, 1521cb0ef41Sopenharmony_ci kSearch: 7, 1531cb0ef41Sopenharmony_ci kHash: 8, 1541cb0ef41Sopenharmony_ci kHref: 9, 1551cb0ef41Sopenharmony_ci}; 1561cb0ef41Sopenharmony_cilet blob; 1571cb0ef41Sopenharmony_cilet cryptoRandom; 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_cifunction lazyBlob() { 1601cb0ef41Sopenharmony_ci blob ??= require('internal/blob'); 1611cb0ef41Sopenharmony_ci return blob; 1621cb0ef41Sopenharmony_ci} 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_cifunction lazyCryptoRandom() { 1651cb0ef41Sopenharmony_ci try { 1661cb0ef41Sopenharmony_ci cryptoRandom ??= require('internal/crypto/random'); 1671cb0ef41Sopenharmony_ci } catch { 1681cb0ef41Sopenharmony_ci // If Node.js built without crypto support, we'll fall 1691cb0ef41Sopenharmony_ci // through here and handle it later. 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci return cryptoRandom; 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci// This class provides the internal state of a URL object. An instance of this 1751cb0ef41Sopenharmony_ci// class is stored in every URL object and is accessed internally by setters 1761cb0ef41Sopenharmony_ci// and getters. It roughly corresponds to the concept of a URL record in the 1771cb0ef41Sopenharmony_ci// URL Standard, with a few differences. It is also the object transported to 1781cb0ef41Sopenharmony_ci// the C++ binding. 1791cb0ef41Sopenharmony_ci// Refs: https://url.spec.whatwg.org/#concept-url 1801cb0ef41Sopenharmony_ciclass URLContext { 1811cb0ef41Sopenharmony_ci // This is the maximum value uint32_t can get. 1821cb0ef41Sopenharmony_ci // Ada uses uint32_t(-1) for declaring omitted values. 1831cb0ef41Sopenharmony_ci static #omitted = 4294967295; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci href = ''; 1861cb0ef41Sopenharmony_ci protocol_end = 0; 1871cb0ef41Sopenharmony_ci username_end = 0; 1881cb0ef41Sopenharmony_ci host_start = 0; 1891cb0ef41Sopenharmony_ci host_end = 0; 1901cb0ef41Sopenharmony_ci pathname_start = 0; 1911cb0ef41Sopenharmony_ci search_start = 0; 1921cb0ef41Sopenharmony_ci hash_start = 0; 1931cb0ef41Sopenharmony_ci port = 0; 1941cb0ef41Sopenharmony_ci /** 1951cb0ef41Sopenharmony_ci * Refers to `ada::scheme::type` 1961cb0ef41Sopenharmony_ci * 1971cb0ef41Sopenharmony_ci * enum type : uint8_t { 1981cb0ef41Sopenharmony_ci * HTTP = 0, 1991cb0ef41Sopenharmony_ci * NOT_SPECIAL = 1, 2001cb0ef41Sopenharmony_ci * HTTPS = 2, 2011cb0ef41Sopenharmony_ci * WS = 3, 2021cb0ef41Sopenharmony_ci * FTP = 4, 2031cb0ef41Sopenharmony_ci * WSS = 5, 2041cb0ef41Sopenharmony_ci * FILE = 6 2051cb0ef41Sopenharmony_ci * }; 2061cb0ef41Sopenharmony_ci * @type {number} 2071cb0ef41Sopenharmony_ci */ 2081cb0ef41Sopenharmony_ci scheme_type = 1; 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci get hasPort() { 2111cb0ef41Sopenharmony_ci return this.port !== URLContext.#omitted; 2121cb0ef41Sopenharmony_ci } 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci get hasSearch() { 2151cb0ef41Sopenharmony_ci return this.search_start !== URLContext.#omitted; 2161cb0ef41Sopenharmony_ci } 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci get hasHash() { 2191cb0ef41Sopenharmony_ci return this.hash_start !== URLContext.#omitted; 2201cb0ef41Sopenharmony_ci } 2211cb0ef41Sopenharmony_ci} 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_cifunction isURLSearchParams(self) { 2241cb0ef41Sopenharmony_ci return self?.[searchParams]; 2251cb0ef41Sopenharmony_ci} 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ciclass URLSearchParams { 2281cb0ef41Sopenharmony_ci [searchParams] = []; 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci // "associated url object" 2311cb0ef41Sopenharmony_ci [context] = null; 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci // URL Standard says the default value is '', but as undefined and '' have 2341cb0ef41Sopenharmony_ci // the same result, undefined is used to prevent unnecessary parsing. 2351cb0ef41Sopenharmony_ci // Default parameter is necessary to keep URLSearchParams.length === 0 in 2361cb0ef41Sopenharmony_ci // accordance with Web IDL spec. 2371cb0ef41Sopenharmony_ci constructor(init = undefined) { 2381cb0ef41Sopenharmony_ci if (init == null) { 2391cb0ef41Sopenharmony_ci // Do nothing 2401cb0ef41Sopenharmony_ci } else if (typeof init === 'object' || typeof init === 'function') { 2411cb0ef41Sopenharmony_ci const method = init[SymbolIterator]; 2421cb0ef41Sopenharmony_ci if (method === this[SymbolIterator]) { 2431cb0ef41Sopenharmony_ci // While the spec does not have this branch, we can use it as a 2441cb0ef41Sopenharmony_ci // shortcut to avoid having to go through the costly generic iterator. 2451cb0ef41Sopenharmony_ci const childParams = init[searchParams]; 2461cb0ef41Sopenharmony_ci this[searchParams] = childParams.slice(); 2471cb0ef41Sopenharmony_ci } else if (method != null) { 2481cb0ef41Sopenharmony_ci // Sequence<sequence<USVString>> 2491cb0ef41Sopenharmony_ci if (typeof method !== 'function') { 2501cb0ef41Sopenharmony_ci throw new ERR_ARG_NOT_ITERABLE('Query pairs'); 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci // The following implementationd differs from the URL specification: 2541cb0ef41Sopenharmony_ci // Sequences must first be converted from ECMAScript objects before 2551cb0ef41Sopenharmony_ci // and operations are done on them, and the operation of converting 2561cb0ef41Sopenharmony_ci // the sequences would first exhaust the iterators. If the iterator 2571cb0ef41Sopenharmony_ci // returns something invalid in the middle, whether it would be called 2581cb0ef41Sopenharmony_ci // after that would be an observable change to the users. 2591cb0ef41Sopenharmony_ci // Exhausting the iterator and later converting them to USVString comes 2601cb0ef41Sopenharmony_ci // with a significant cost (~40-80%). In order optimize URLSearchParams 2611cb0ef41Sopenharmony_ci // creation duration, Node.js merges the iteration and converting 2621cb0ef41Sopenharmony_ci // iterations into a single iteration. 2631cb0ef41Sopenharmony_ci for (const pair of init) { 2641cb0ef41Sopenharmony_ci if (pair == null) { 2651cb0ef41Sopenharmony_ci throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]'); 2661cb0ef41Sopenharmony_ci } else if (ArrayIsArray(pair)) { 2671cb0ef41Sopenharmony_ci // If innerSequence's size is not 2, then throw a TypeError. 2681cb0ef41Sopenharmony_ci if (pair.length !== 2) { 2691cb0ef41Sopenharmony_ci throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]'); 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci // Append (innerSequence[0], innerSequence[1]) to querys list. 2721cb0ef41Sopenharmony_ci ArrayPrototypePush(this[searchParams], toUSVString(pair[0]), toUSVString(pair[1])); 2731cb0ef41Sopenharmony_ci } else { 2741cb0ef41Sopenharmony_ci if (((typeof pair !== 'object' && typeof pair !== 'function') || 2751cb0ef41Sopenharmony_ci typeof pair[SymbolIterator] !== 'function')) { 2761cb0ef41Sopenharmony_ci throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]'); 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci let length = 0; 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci for (const element of pair) { 2821cb0ef41Sopenharmony_ci length++; 2831cb0ef41Sopenharmony_ci ArrayPrototypePush(this[searchParams], toUSVString(element)); 2841cb0ef41Sopenharmony_ci } 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci // If innerSequence's size is not 2, then throw a TypeError. 2871cb0ef41Sopenharmony_ci if (length !== 2) { 2881cb0ef41Sopenharmony_ci throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]'); 2891cb0ef41Sopenharmony_ci } 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci } else { 2931cb0ef41Sopenharmony_ci // Record<USVString, USVString> 2941cb0ef41Sopenharmony_ci // Need to use reflection APIs for full spec compliance. 2951cb0ef41Sopenharmony_ci const visited = new SafeMap(); 2961cb0ef41Sopenharmony_ci const keys = ReflectOwnKeys(init); 2971cb0ef41Sopenharmony_ci for (let i = 0; i < keys.length; i++) { 2981cb0ef41Sopenharmony_ci const key = keys[i]; 2991cb0ef41Sopenharmony_ci const desc = ReflectGetOwnPropertyDescriptor(init, key); 3001cb0ef41Sopenharmony_ci if (desc !== undefined && desc.enumerable) { 3011cb0ef41Sopenharmony_ci const typedKey = toUSVString(key); 3021cb0ef41Sopenharmony_ci const typedValue = toUSVString(init[key]); 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ci // Two different keys may become the same USVString after normalization. 3051cb0ef41Sopenharmony_ci // In that case, we retain the later one. Refer to WPT. 3061cb0ef41Sopenharmony_ci const keyIdx = visited.get(typedKey); 3071cb0ef41Sopenharmony_ci if (keyIdx !== undefined) { 3081cb0ef41Sopenharmony_ci this[searchParams][keyIdx] = typedValue; 3091cb0ef41Sopenharmony_ci } else { 3101cb0ef41Sopenharmony_ci visited.set(typedKey, ArrayPrototypePush(this[searchParams], 3111cb0ef41Sopenharmony_ci typedKey, 3121cb0ef41Sopenharmony_ci typedValue) - 1); 3131cb0ef41Sopenharmony_ci } 3141cb0ef41Sopenharmony_ci } 3151cb0ef41Sopenharmony_ci } 3161cb0ef41Sopenharmony_ci } 3171cb0ef41Sopenharmony_ci } else { 3181cb0ef41Sopenharmony_ci // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams 3191cb0ef41Sopenharmony_ci init = toUSVString(init); 3201cb0ef41Sopenharmony_ci this[searchParams] = init ? parseParams(init) : []; 3211cb0ef41Sopenharmony_ci } 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci [inspect.custom](recurseTimes, ctx) { 3251cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 3261cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ci if (typeof recurseTimes === 'number' && recurseTimes < 0) 3291cb0ef41Sopenharmony_ci return ctx.stylize('[Object]', 'special'); 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_ci const separator = ', '; 3321cb0ef41Sopenharmony_ci const innerOpts = { ...ctx }; 3331cb0ef41Sopenharmony_ci if (recurseTimes !== null) { 3341cb0ef41Sopenharmony_ci innerOpts.depth = recurseTimes - 1; 3351cb0ef41Sopenharmony_ci } 3361cb0ef41Sopenharmony_ci const innerInspect = (v) => inspect(v, innerOpts); 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci const list = this[searchParams]; 3391cb0ef41Sopenharmony_ci const output = []; 3401cb0ef41Sopenharmony_ci for (let i = 0; i < list.length; i += 2) 3411cb0ef41Sopenharmony_ci ArrayPrototypePush( 3421cb0ef41Sopenharmony_ci output, 3431cb0ef41Sopenharmony_ci `${innerInspect(list[i])} => ${innerInspect(list[i + 1])}`); 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci const length = ArrayPrototypeReduce( 3461cb0ef41Sopenharmony_ci output, 3471cb0ef41Sopenharmony_ci (prev, cur) => prev + removeColors(cur).length + separator.length, 3481cb0ef41Sopenharmony_ci -separator.length, 3491cb0ef41Sopenharmony_ci ); 3501cb0ef41Sopenharmony_ci if (length > ctx.breakLength) { 3511cb0ef41Sopenharmony_ci return `${this.constructor.name} {\n` + 3521cb0ef41Sopenharmony_ci ` ${ArrayPrototypeJoin(output, ',\n ')} }`; 3531cb0ef41Sopenharmony_ci } else if (output.length) { 3541cb0ef41Sopenharmony_ci return `${this.constructor.name} { ` + 3551cb0ef41Sopenharmony_ci `${ArrayPrototypeJoin(output, separator)} }`; 3561cb0ef41Sopenharmony_ci } 3571cb0ef41Sopenharmony_ci return `${this.constructor.name} {}`; 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci get size() { 3611cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 3621cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 3631cb0ef41Sopenharmony_ci return this[searchParams].length / 2; 3641cb0ef41Sopenharmony_ci } 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ci append(name, value) { 3671cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 3681cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci if (arguments.length < 2) { 3711cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('name', 'value'); 3721cb0ef41Sopenharmony_ci } 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci name = toUSVString(name); 3751cb0ef41Sopenharmony_ci value = toUSVString(value); 3761cb0ef41Sopenharmony_ci ArrayPrototypePush(this[searchParams], name, value); 3771cb0ef41Sopenharmony_ci if (this[context]) { 3781cb0ef41Sopenharmony_ci this[context].search = this.toString(); 3791cb0ef41Sopenharmony_ci } 3801cb0ef41Sopenharmony_ci } 3811cb0ef41Sopenharmony_ci 3821cb0ef41Sopenharmony_ci delete(name, value = undefined) { 3831cb0ef41Sopenharmony_ci if (typeof this !== 'object' || this === null || !isURLSearchParams(this)) 3841cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci if (arguments.length < 1) { 3871cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('name'); 3881cb0ef41Sopenharmony_ci } 3891cb0ef41Sopenharmony_ci 3901cb0ef41Sopenharmony_ci const list = this[searchParams]; 3911cb0ef41Sopenharmony_ci name = toUSVString(name); 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci if (value !== undefined) { 3941cb0ef41Sopenharmony_ci value = toUSVString(value); 3951cb0ef41Sopenharmony_ci for (let i = 0; i < list.length;) { 3961cb0ef41Sopenharmony_ci if (list[i] === name && list[i + 1] === value) { 3971cb0ef41Sopenharmony_ci list.splice(i, 2); 3981cb0ef41Sopenharmony_ci } else { 3991cb0ef41Sopenharmony_ci i += 2; 4001cb0ef41Sopenharmony_ci } 4011cb0ef41Sopenharmony_ci } 4021cb0ef41Sopenharmony_ci } else { 4031cb0ef41Sopenharmony_ci for (let i = 0; i < list.length;) { 4041cb0ef41Sopenharmony_ci if (list[i] === name) { 4051cb0ef41Sopenharmony_ci list.splice(i, 2); 4061cb0ef41Sopenharmony_ci } else { 4071cb0ef41Sopenharmony_ci i += 2; 4081cb0ef41Sopenharmony_ci } 4091cb0ef41Sopenharmony_ci } 4101cb0ef41Sopenharmony_ci } 4111cb0ef41Sopenharmony_ci if (this[context]) { 4121cb0ef41Sopenharmony_ci this[context].search = this.toString(); 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci } 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci get(name) { 4171cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 4181cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 4191cb0ef41Sopenharmony_ci 4201cb0ef41Sopenharmony_ci if (arguments.length < 1) { 4211cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('name'); 4221cb0ef41Sopenharmony_ci } 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ci const list = this[searchParams]; 4251cb0ef41Sopenharmony_ci name = toUSVString(name); 4261cb0ef41Sopenharmony_ci for (let i = 0; i < list.length; i += 2) { 4271cb0ef41Sopenharmony_ci if (list[i] === name) { 4281cb0ef41Sopenharmony_ci return list[i + 1]; 4291cb0ef41Sopenharmony_ci } 4301cb0ef41Sopenharmony_ci } 4311cb0ef41Sopenharmony_ci return null; 4321cb0ef41Sopenharmony_ci } 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_ci getAll(name) { 4351cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 4361cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci if (arguments.length < 1) { 4391cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('name'); 4401cb0ef41Sopenharmony_ci } 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci const list = this[searchParams]; 4431cb0ef41Sopenharmony_ci const values = []; 4441cb0ef41Sopenharmony_ci name = toUSVString(name); 4451cb0ef41Sopenharmony_ci for (let i = 0; i < list.length; i += 2) { 4461cb0ef41Sopenharmony_ci if (list[i] === name) { 4471cb0ef41Sopenharmony_ci values.push(list[i + 1]); 4481cb0ef41Sopenharmony_ci } 4491cb0ef41Sopenharmony_ci } 4501cb0ef41Sopenharmony_ci return values; 4511cb0ef41Sopenharmony_ci } 4521cb0ef41Sopenharmony_ci 4531cb0ef41Sopenharmony_ci has(name, value = undefined) { 4541cb0ef41Sopenharmony_ci if (typeof this !== 'object' || this === null || !isURLSearchParams(this)) 4551cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 4561cb0ef41Sopenharmony_ci 4571cb0ef41Sopenharmony_ci if (arguments.length < 1) { 4581cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('name'); 4591cb0ef41Sopenharmony_ci } 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci const list = this[searchParams]; 4621cb0ef41Sopenharmony_ci name = toUSVString(name); 4631cb0ef41Sopenharmony_ci 4641cb0ef41Sopenharmony_ci if (value !== undefined) { 4651cb0ef41Sopenharmony_ci value = toUSVString(value); 4661cb0ef41Sopenharmony_ci } 4671cb0ef41Sopenharmony_ci 4681cb0ef41Sopenharmony_ci for (let i = 0; i < list.length; i += 2) { 4691cb0ef41Sopenharmony_ci if (list[i] === name) { 4701cb0ef41Sopenharmony_ci if (value === undefined || list[i + 1] === value) { 4711cb0ef41Sopenharmony_ci return true; 4721cb0ef41Sopenharmony_ci } 4731cb0ef41Sopenharmony_ci } 4741cb0ef41Sopenharmony_ci } 4751cb0ef41Sopenharmony_ci 4761cb0ef41Sopenharmony_ci return false; 4771cb0ef41Sopenharmony_ci } 4781cb0ef41Sopenharmony_ci 4791cb0ef41Sopenharmony_ci set(name, value) { 4801cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 4811cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 4821cb0ef41Sopenharmony_ci 4831cb0ef41Sopenharmony_ci if (arguments.length < 2) { 4841cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('name', 'value'); 4851cb0ef41Sopenharmony_ci } 4861cb0ef41Sopenharmony_ci 4871cb0ef41Sopenharmony_ci const list = this[searchParams]; 4881cb0ef41Sopenharmony_ci name = toUSVString(name); 4891cb0ef41Sopenharmony_ci value = toUSVString(value); 4901cb0ef41Sopenharmony_ci 4911cb0ef41Sopenharmony_ci // If there are any name-value pairs whose name is `name`, in `list`, set 4921cb0ef41Sopenharmony_ci // the value of the first such name-value pair to `value` and remove the 4931cb0ef41Sopenharmony_ci // others. 4941cb0ef41Sopenharmony_ci let found = false; 4951cb0ef41Sopenharmony_ci for (let i = 0; i < list.length;) { 4961cb0ef41Sopenharmony_ci const cur = list[i]; 4971cb0ef41Sopenharmony_ci if (cur === name) { 4981cb0ef41Sopenharmony_ci if (!found) { 4991cb0ef41Sopenharmony_ci list[i + 1] = value; 5001cb0ef41Sopenharmony_ci found = true; 5011cb0ef41Sopenharmony_ci i += 2; 5021cb0ef41Sopenharmony_ci } else { 5031cb0ef41Sopenharmony_ci list.splice(i, 2); 5041cb0ef41Sopenharmony_ci } 5051cb0ef41Sopenharmony_ci } else { 5061cb0ef41Sopenharmony_ci i += 2; 5071cb0ef41Sopenharmony_ci } 5081cb0ef41Sopenharmony_ci } 5091cb0ef41Sopenharmony_ci 5101cb0ef41Sopenharmony_ci // Otherwise, append a new name-value pair whose name is `name` and value 5111cb0ef41Sopenharmony_ci // is `value`, to `list`. 5121cb0ef41Sopenharmony_ci if (!found) { 5131cb0ef41Sopenharmony_ci ArrayPrototypePush(list, name, value); 5141cb0ef41Sopenharmony_ci } 5151cb0ef41Sopenharmony_ci 5161cb0ef41Sopenharmony_ci if (this[context]) { 5171cb0ef41Sopenharmony_ci this[context].search = this.toString(); 5181cb0ef41Sopenharmony_ci } 5191cb0ef41Sopenharmony_ci } 5201cb0ef41Sopenharmony_ci 5211cb0ef41Sopenharmony_ci sort() { 5221cb0ef41Sopenharmony_ci const a = this[searchParams]; 5231cb0ef41Sopenharmony_ci const len = a.length; 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ci if (len <= 2) { 5261cb0ef41Sopenharmony_ci // Nothing needs to be done. 5271cb0ef41Sopenharmony_ci } else if (len < 100) { 5281cb0ef41Sopenharmony_ci // 100 is found through testing. 5291cb0ef41Sopenharmony_ci // Simple stable in-place insertion sort 5301cb0ef41Sopenharmony_ci // Derived from v8/src/js/array.js 5311cb0ef41Sopenharmony_ci for (let i = 2; i < len; i += 2) { 5321cb0ef41Sopenharmony_ci const curKey = a[i]; 5331cb0ef41Sopenharmony_ci const curVal = a[i + 1]; 5341cb0ef41Sopenharmony_ci let j; 5351cb0ef41Sopenharmony_ci for (j = i - 2; j >= 0; j -= 2) { 5361cb0ef41Sopenharmony_ci if (a[j] > curKey) { 5371cb0ef41Sopenharmony_ci a[j + 2] = a[j]; 5381cb0ef41Sopenharmony_ci a[j + 3] = a[j + 1]; 5391cb0ef41Sopenharmony_ci } else { 5401cb0ef41Sopenharmony_ci break; 5411cb0ef41Sopenharmony_ci } 5421cb0ef41Sopenharmony_ci } 5431cb0ef41Sopenharmony_ci a[j + 2] = curKey; 5441cb0ef41Sopenharmony_ci a[j + 3] = curVal; 5451cb0ef41Sopenharmony_ci } 5461cb0ef41Sopenharmony_ci } else { 5471cb0ef41Sopenharmony_ci // Bottom-up iterative stable merge sort 5481cb0ef41Sopenharmony_ci const lBuffer = new Array(len); 5491cb0ef41Sopenharmony_ci const rBuffer = new Array(len); 5501cb0ef41Sopenharmony_ci for (let step = 2; step < len; step *= 2) { 5511cb0ef41Sopenharmony_ci for (let start = 0; start < len - 2; start += 2 * step) { 5521cb0ef41Sopenharmony_ci const mid = start + step; 5531cb0ef41Sopenharmony_ci let end = mid + step; 5541cb0ef41Sopenharmony_ci end = end < len ? end : len; 5551cb0ef41Sopenharmony_ci if (mid > end) 5561cb0ef41Sopenharmony_ci continue; 5571cb0ef41Sopenharmony_ci merge(a, start, mid, end, lBuffer, rBuffer); 5581cb0ef41Sopenharmony_ci } 5591cb0ef41Sopenharmony_ci } 5601cb0ef41Sopenharmony_ci } 5611cb0ef41Sopenharmony_ci 5621cb0ef41Sopenharmony_ci if (this[context]) { 5631cb0ef41Sopenharmony_ci this[context].search = this.toString(); 5641cb0ef41Sopenharmony_ci } 5651cb0ef41Sopenharmony_ci } 5661cb0ef41Sopenharmony_ci 5671cb0ef41Sopenharmony_ci // https://heycam.github.io/webidl/#es-iterators 5681cb0ef41Sopenharmony_ci // Define entries here rather than [Symbol.iterator] as the function name 5691cb0ef41Sopenharmony_ci // must be set to `entries`. 5701cb0ef41Sopenharmony_ci entries() { 5711cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 5721cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 5731cb0ef41Sopenharmony_ci 5741cb0ef41Sopenharmony_ci return createSearchParamsIterator(this, 'key+value'); 5751cb0ef41Sopenharmony_ci } 5761cb0ef41Sopenharmony_ci 5771cb0ef41Sopenharmony_ci forEach(callback, thisArg = undefined) { 5781cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 5791cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_ci validateFunction(callback, 'callback'); 5821cb0ef41Sopenharmony_ci 5831cb0ef41Sopenharmony_ci let list = this[searchParams]; 5841cb0ef41Sopenharmony_ci 5851cb0ef41Sopenharmony_ci let i = 0; 5861cb0ef41Sopenharmony_ci while (i < list.length) { 5871cb0ef41Sopenharmony_ci const key = list[i]; 5881cb0ef41Sopenharmony_ci const value = list[i + 1]; 5891cb0ef41Sopenharmony_ci callback.call(thisArg, value, key, this); 5901cb0ef41Sopenharmony_ci // In case the URL object's `search` is updated 5911cb0ef41Sopenharmony_ci list = this[searchParams]; 5921cb0ef41Sopenharmony_ci i += 2; 5931cb0ef41Sopenharmony_ci } 5941cb0ef41Sopenharmony_ci } 5951cb0ef41Sopenharmony_ci 5961cb0ef41Sopenharmony_ci // https://heycam.github.io/webidl/#es-iterable 5971cb0ef41Sopenharmony_ci keys() { 5981cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 5991cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 6001cb0ef41Sopenharmony_ci 6011cb0ef41Sopenharmony_ci return createSearchParamsIterator(this, 'key'); 6021cb0ef41Sopenharmony_ci } 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci values() { 6051cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 6061cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 6071cb0ef41Sopenharmony_ci 6081cb0ef41Sopenharmony_ci return createSearchParamsIterator(this, 'value'); 6091cb0ef41Sopenharmony_ci } 6101cb0ef41Sopenharmony_ci 6111cb0ef41Sopenharmony_ci // https://heycam.github.io/webidl/#es-stringifier 6121cb0ef41Sopenharmony_ci // https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior 6131cb0ef41Sopenharmony_ci toString() { 6141cb0ef41Sopenharmony_ci if (!isURLSearchParams(this)) 6151cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParams'); 6161cb0ef41Sopenharmony_ci 6171cb0ef41Sopenharmony_ci return serializeParams(this[searchParams]); 6181cb0ef41Sopenharmony_ci } 6191cb0ef41Sopenharmony_ci} 6201cb0ef41Sopenharmony_ci 6211cb0ef41Sopenharmony_ciObjectDefineProperties(URLSearchParams.prototype, { 6221cb0ef41Sopenharmony_ci append: kEnumerableProperty, 6231cb0ef41Sopenharmony_ci delete: kEnumerableProperty, 6241cb0ef41Sopenharmony_ci get: kEnumerableProperty, 6251cb0ef41Sopenharmony_ci getAll: kEnumerableProperty, 6261cb0ef41Sopenharmony_ci has: kEnumerableProperty, 6271cb0ef41Sopenharmony_ci set: kEnumerableProperty, 6281cb0ef41Sopenharmony_ci size: kEnumerableProperty, 6291cb0ef41Sopenharmony_ci sort: kEnumerableProperty, 6301cb0ef41Sopenharmony_ci entries: kEnumerableProperty, 6311cb0ef41Sopenharmony_ci forEach: kEnumerableProperty, 6321cb0ef41Sopenharmony_ci keys: kEnumerableProperty, 6331cb0ef41Sopenharmony_ci values: kEnumerableProperty, 6341cb0ef41Sopenharmony_ci toString: kEnumerableProperty, 6351cb0ef41Sopenharmony_ci [SymbolToStringTag]: { __proto__: null, configurable: true, value: 'URLSearchParams' }, 6361cb0ef41Sopenharmony_ci 6371cb0ef41Sopenharmony_ci // https://heycam.github.io/webidl/#es-iterable-entries 6381cb0ef41Sopenharmony_ci [SymbolIterator]: { 6391cb0ef41Sopenharmony_ci __proto__: null, 6401cb0ef41Sopenharmony_ci configurable: true, 6411cb0ef41Sopenharmony_ci writable: true, 6421cb0ef41Sopenharmony_ci value: URLSearchParams.prototype.entries, 6431cb0ef41Sopenharmony_ci }, 6441cb0ef41Sopenharmony_ci}); 6451cb0ef41Sopenharmony_ci 6461cb0ef41Sopenharmony_ci/** 6471cb0ef41Sopenharmony_ci * Checks if a value has the shape of a WHATWG URL object. 6481cb0ef41Sopenharmony_ci * 6491cb0ef41Sopenharmony_ci * Using a symbol or instanceof would not be able to recognize URL objects 6501cb0ef41Sopenharmony_ci * coming from other implementations (e.g. in Electron), so instead we are 6511cb0ef41Sopenharmony_ci * checking some well known properties for a lack of a better test. 6521cb0ef41Sopenharmony_ci * @param {*} self 6531cb0ef41Sopenharmony_ci * @returns {self is URL} 6541cb0ef41Sopenharmony_ci */ 6551cb0ef41Sopenharmony_cifunction isURL(self) { 6561cb0ef41Sopenharmony_ci return self != null && ObjectPrototypeHasOwnProperty(self, context); 6571cb0ef41Sopenharmony_ci} 6581cb0ef41Sopenharmony_ci 6591cb0ef41Sopenharmony_ciclass URL { 6601cb0ef41Sopenharmony_ci constructor(input, base = undefined) { 6611cb0ef41Sopenharmony_ci if (arguments.length === 0) { 6621cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('url'); 6631cb0ef41Sopenharmony_ci } 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci // toUSVString is not needed. 6661cb0ef41Sopenharmony_ci input = `${input}`; 6671cb0ef41Sopenharmony_ci this[context] = new URLContext(); 6681cb0ef41Sopenharmony_ci 6691cb0ef41Sopenharmony_ci if (base !== undefined) { 6701cb0ef41Sopenharmony_ci base = `${base}`; 6711cb0ef41Sopenharmony_ci } 6721cb0ef41Sopenharmony_ci 6731cb0ef41Sopenharmony_ci const href = bindingUrl.parse(input, base); 6741cb0ef41Sopenharmony_ci 6751cb0ef41Sopenharmony_ci if (!href) { 6761cb0ef41Sopenharmony_ci throw new ERR_INVALID_URL(input); 6771cb0ef41Sopenharmony_ci } 6781cb0ef41Sopenharmony_ci 6791cb0ef41Sopenharmony_ci this.#updateContext(href); 6801cb0ef41Sopenharmony_ci } 6811cb0ef41Sopenharmony_ci 6821cb0ef41Sopenharmony_ci [inspect.custom](depth, opts) { 6831cb0ef41Sopenharmony_ci if (this == null || 6841cb0ef41Sopenharmony_ci ObjectGetPrototypeOf(this[context]) !== URLContext.prototype) { 6851cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 6861cb0ef41Sopenharmony_ci } 6871cb0ef41Sopenharmony_ci 6881cb0ef41Sopenharmony_ci if (typeof depth === 'number' && depth < 0) 6891cb0ef41Sopenharmony_ci return this; 6901cb0ef41Sopenharmony_ci 6911cb0ef41Sopenharmony_ci const constructor = getConstructorOf(this) || URL; 6921cb0ef41Sopenharmony_ci const obj = ObjectCreate({ constructor }); 6931cb0ef41Sopenharmony_ci 6941cb0ef41Sopenharmony_ci obj.href = this.href; 6951cb0ef41Sopenharmony_ci obj.origin = this.origin; 6961cb0ef41Sopenharmony_ci obj.protocol = this.protocol; 6971cb0ef41Sopenharmony_ci obj.username = this.username; 6981cb0ef41Sopenharmony_ci obj.password = this.password; 6991cb0ef41Sopenharmony_ci obj.host = this.host; 7001cb0ef41Sopenharmony_ci obj.hostname = this.hostname; 7011cb0ef41Sopenharmony_ci obj.port = this.port; 7021cb0ef41Sopenharmony_ci obj.pathname = this.pathname; 7031cb0ef41Sopenharmony_ci obj.search = this.search; 7041cb0ef41Sopenharmony_ci obj.searchParams = this.searchParams; 7051cb0ef41Sopenharmony_ci obj.hash = this.hash; 7061cb0ef41Sopenharmony_ci 7071cb0ef41Sopenharmony_ci if (opts.showHidden) { 7081cb0ef41Sopenharmony_ci obj[context] = this[context]; 7091cb0ef41Sopenharmony_ci } 7101cb0ef41Sopenharmony_ci 7111cb0ef41Sopenharmony_ci return `${constructor.name} ${inspect(obj, opts)}`; 7121cb0ef41Sopenharmony_ci } 7131cb0ef41Sopenharmony_ci 7141cb0ef41Sopenharmony_ci #updateContext(href) { 7151cb0ef41Sopenharmony_ci const ctx = this[context]; 7161cb0ef41Sopenharmony_ci ctx.href = href; 7171cb0ef41Sopenharmony_ci 7181cb0ef41Sopenharmony_ci const { 7191cb0ef41Sopenharmony_ci 0: protocol_end, 7201cb0ef41Sopenharmony_ci 1: username_end, 7211cb0ef41Sopenharmony_ci 2: host_start, 7221cb0ef41Sopenharmony_ci 3: host_end, 7231cb0ef41Sopenharmony_ci 4: port, 7241cb0ef41Sopenharmony_ci 5: pathname_start, 7251cb0ef41Sopenharmony_ci 6: search_start, 7261cb0ef41Sopenharmony_ci 7: hash_start, 7271cb0ef41Sopenharmony_ci 8: scheme_type, 7281cb0ef41Sopenharmony_ci } = bindingUrl.urlComponents; 7291cb0ef41Sopenharmony_ci 7301cb0ef41Sopenharmony_ci ctx.protocol_end = protocol_end; 7311cb0ef41Sopenharmony_ci ctx.username_end = username_end; 7321cb0ef41Sopenharmony_ci ctx.host_start = host_start; 7331cb0ef41Sopenharmony_ci ctx.host_end = host_end; 7341cb0ef41Sopenharmony_ci ctx.port = port; 7351cb0ef41Sopenharmony_ci ctx.pathname_start = pathname_start; 7361cb0ef41Sopenharmony_ci ctx.search_start = search_start; 7371cb0ef41Sopenharmony_ci ctx.hash_start = hash_start; 7381cb0ef41Sopenharmony_ci ctx.scheme_type = scheme_type; 7391cb0ef41Sopenharmony_ci 7401cb0ef41Sopenharmony_ci const alreadyInstantiatedSearchParams = internalSearchParams.get(this); 7411cb0ef41Sopenharmony_ci if (alreadyInstantiatedSearchParams) { 7421cb0ef41Sopenharmony_ci if (ctx.hasSearch) { 7431cb0ef41Sopenharmony_ci alreadyInstantiatedSearchParams[searchParams] = parseParams(this.search); 7441cb0ef41Sopenharmony_ci } else { 7451cb0ef41Sopenharmony_ci alreadyInstantiatedSearchParams[searchParams] = []; 7461cb0ef41Sopenharmony_ci } 7471cb0ef41Sopenharmony_ci } 7481cb0ef41Sopenharmony_ci } 7491cb0ef41Sopenharmony_ci 7501cb0ef41Sopenharmony_ci toString() { 7511cb0ef41Sopenharmony_ci if (!isURL(this)) 7521cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 7531cb0ef41Sopenharmony_ci return this[context].href; 7541cb0ef41Sopenharmony_ci } 7551cb0ef41Sopenharmony_ci 7561cb0ef41Sopenharmony_ci get href() { 7571cb0ef41Sopenharmony_ci if (!isURL(this)) 7581cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 7591cb0ef41Sopenharmony_ci return this[context].href; 7601cb0ef41Sopenharmony_ci } 7611cb0ef41Sopenharmony_ci 7621cb0ef41Sopenharmony_ci set href(value) { 7631cb0ef41Sopenharmony_ci if (!isURL(this)) 7641cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 7651cb0ef41Sopenharmony_ci value = `${value}`; 7661cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kHref, value); 7671cb0ef41Sopenharmony_ci if (!href) { throw ERR_INVALID_URL(value); } 7681cb0ef41Sopenharmony_ci this.#updateContext(href); 7691cb0ef41Sopenharmony_ci } 7701cb0ef41Sopenharmony_ci 7711cb0ef41Sopenharmony_ci // readonly 7721cb0ef41Sopenharmony_ci get origin() { 7731cb0ef41Sopenharmony_ci if (!isURL(this)) 7741cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 7751cb0ef41Sopenharmony_ci const ctx = this[context]; 7761cb0ef41Sopenharmony_ci const protocol = StringPrototypeSlice(ctx.href, 0, ctx.protocol_end); 7771cb0ef41Sopenharmony_ci 7781cb0ef41Sopenharmony_ci // Check if scheme_type is not `NOT_SPECIAL` 7791cb0ef41Sopenharmony_ci if (ctx.scheme_type !== 1) { 7801cb0ef41Sopenharmony_ci // Check if scheme_type is `FILE` 7811cb0ef41Sopenharmony_ci if (ctx.scheme_type === 6) { 7821cb0ef41Sopenharmony_ci return 'null'; 7831cb0ef41Sopenharmony_ci } 7841cb0ef41Sopenharmony_ci return `${protocol}//${this.host}`; 7851cb0ef41Sopenharmony_ci } 7861cb0ef41Sopenharmony_ci 7871cb0ef41Sopenharmony_ci if (protocol === 'blob:') { 7881cb0ef41Sopenharmony_ci const path = this.pathname; 7891cb0ef41Sopenharmony_ci if (path.length > 0) { 7901cb0ef41Sopenharmony_ci try { 7911cb0ef41Sopenharmony_ci const out = new URL(path); 7921cb0ef41Sopenharmony_ci // Only return origin of scheme is `http` or `https` 7931cb0ef41Sopenharmony_ci // Otherwise return a new opaque origin (null). 7941cb0ef41Sopenharmony_ci if (out[context].scheme_type === 0 || out[context].scheme_type === 2) { 7951cb0ef41Sopenharmony_ci return `${out.protocol}//${out.host}`; 7961cb0ef41Sopenharmony_ci } 7971cb0ef41Sopenharmony_ci } catch { 7981cb0ef41Sopenharmony_ci // Do nothing. 7991cb0ef41Sopenharmony_ci } 8001cb0ef41Sopenharmony_ci } 8011cb0ef41Sopenharmony_ci } 8021cb0ef41Sopenharmony_ci 8031cb0ef41Sopenharmony_ci return 'null'; 8041cb0ef41Sopenharmony_ci } 8051cb0ef41Sopenharmony_ci 8061cb0ef41Sopenharmony_ci get protocol() { 8071cb0ef41Sopenharmony_ci if (!isURL(this)) 8081cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8091cb0ef41Sopenharmony_ci return StringPrototypeSlice(this[context].href, 0, this[context].protocol_end); 8101cb0ef41Sopenharmony_ci } 8111cb0ef41Sopenharmony_ci 8121cb0ef41Sopenharmony_ci set protocol(value) { 8131cb0ef41Sopenharmony_ci if (!isURL(this)) 8141cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8151cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kProtocol, `${value}`); 8161cb0ef41Sopenharmony_ci if (href) { 8171cb0ef41Sopenharmony_ci this.#updateContext(href); 8181cb0ef41Sopenharmony_ci } 8191cb0ef41Sopenharmony_ci } 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_ci get username() { 8221cb0ef41Sopenharmony_ci if (!isURL(this)) 8231cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8241cb0ef41Sopenharmony_ci const ctx = this[context]; 8251cb0ef41Sopenharmony_ci if (ctx.protocol_end + 2 < ctx.username_end) { 8261cb0ef41Sopenharmony_ci return StringPrototypeSlice(ctx.href, ctx.protocol_end + 2, ctx.username_end); 8271cb0ef41Sopenharmony_ci } 8281cb0ef41Sopenharmony_ci return ''; 8291cb0ef41Sopenharmony_ci } 8301cb0ef41Sopenharmony_ci 8311cb0ef41Sopenharmony_ci set username(value) { 8321cb0ef41Sopenharmony_ci if (!isURL(this)) 8331cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8341cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kUsername, `${value}`); 8351cb0ef41Sopenharmony_ci if (href) { 8361cb0ef41Sopenharmony_ci this.#updateContext(href); 8371cb0ef41Sopenharmony_ci } 8381cb0ef41Sopenharmony_ci } 8391cb0ef41Sopenharmony_ci 8401cb0ef41Sopenharmony_ci get password() { 8411cb0ef41Sopenharmony_ci if (!isURL(this)) 8421cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8431cb0ef41Sopenharmony_ci const ctx = this[context]; 8441cb0ef41Sopenharmony_ci if (ctx.host_start - ctx.username_end > 0) { 8451cb0ef41Sopenharmony_ci return StringPrototypeSlice(ctx.href, ctx.username_end + 1, ctx.host_start); 8461cb0ef41Sopenharmony_ci } 8471cb0ef41Sopenharmony_ci return ''; 8481cb0ef41Sopenharmony_ci } 8491cb0ef41Sopenharmony_ci 8501cb0ef41Sopenharmony_ci set password(value) { 8511cb0ef41Sopenharmony_ci if (!isURL(this)) 8521cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8531cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kPassword, `${value}`); 8541cb0ef41Sopenharmony_ci if (href) { 8551cb0ef41Sopenharmony_ci this.#updateContext(href); 8561cb0ef41Sopenharmony_ci } 8571cb0ef41Sopenharmony_ci } 8581cb0ef41Sopenharmony_ci 8591cb0ef41Sopenharmony_ci get host() { 8601cb0ef41Sopenharmony_ci if (!isURL(this)) 8611cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8621cb0ef41Sopenharmony_ci const ctx = this[context]; 8631cb0ef41Sopenharmony_ci let startsAt = ctx.host_start; 8641cb0ef41Sopenharmony_ci if (ctx.href[startsAt] === '@') { 8651cb0ef41Sopenharmony_ci startsAt++; 8661cb0ef41Sopenharmony_ci } 8671cb0ef41Sopenharmony_ci // If we have an empty host, then the space between components.host_end and 8681cb0ef41Sopenharmony_ci // components.pathname_start may be occupied by /. 8691cb0ef41Sopenharmony_ci if (startsAt === ctx.host_end) { 8701cb0ef41Sopenharmony_ci return ''; 8711cb0ef41Sopenharmony_ci } 8721cb0ef41Sopenharmony_ci return StringPrototypeSlice(ctx.href, startsAt, ctx.pathname_start); 8731cb0ef41Sopenharmony_ci } 8741cb0ef41Sopenharmony_ci 8751cb0ef41Sopenharmony_ci set host(value) { 8761cb0ef41Sopenharmony_ci if (!isURL(this)) 8771cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8781cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kHost, `${value}`); 8791cb0ef41Sopenharmony_ci if (href) { 8801cb0ef41Sopenharmony_ci this.#updateContext(href); 8811cb0ef41Sopenharmony_ci } 8821cb0ef41Sopenharmony_ci } 8831cb0ef41Sopenharmony_ci 8841cb0ef41Sopenharmony_ci get hostname() { 8851cb0ef41Sopenharmony_ci if (!isURL(this)) 8861cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8871cb0ef41Sopenharmony_ci const ctx = this[context]; 8881cb0ef41Sopenharmony_ci let startsAt = ctx.host_start; 8891cb0ef41Sopenharmony_ci // host_start might be "@" if the URL has credentials 8901cb0ef41Sopenharmony_ci if (ctx.href[startsAt] === '@') { 8911cb0ef41Sopenharmony_ci startsAt++; 8921cb0ef41Sopenharmony_ci } 8931cb0ef41Sopenharmony_ci return StringPrototypeSlice(ctx.href, startsAt, ctx.host_end); 8941cb0ef41Sopenharmony_ci } 8951cb0ef41Sopenharmony_ci 8961cb0ef41Sopenharmony_ci set hostname(value) { 8971cb0ef41Sopenharmony_ci if (!isURL(this)) 8981cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 8991cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kHostname, `${value}`); 9001cb0ef41Sopenharmony_ci if (href) { 9011cb0ef41Sopenharmony_ci this.#updateContext(href); 9021cb0ef41Sopenharmony_ci } 9031cb0ef41Sopenharmony_ci } 9041cb0ef41Sopenharmony_ci 9051cb0ef41Sopenharmony_ci get port() { 9061cb0ef41Sopenharmony_ci if (!isURL(this)) 9071cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9081cb0ef41Sopenharmony_ci if (this[context].hasPort) { 9091cb0ef41Sopenharmony_ci return `${this[context].port}`; 9101cb0ef41Sopenharmony_ci } 9111cb0ef41Sopenharmony_ci return ''; 9121cb0ef41Sopenharmony_ci } 9131cb0ef41Sopenharmony_ci 9141cb0ef41Sopenharmony_ci set port(value) { 9151cb0ef41Sopenharmony_ci if (!isURL(this)) 9161cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9171cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kPort, `${value}`); 9181cb0ef41Sopenharmony_ci if (href) { 9191cb0ef41Sopenharmony_ci this.#updateContext(href); 9201cb0ef41Sopenharmony_ci } 9211cb0ef41Sopenharmony_ci } 9221cb0ef41Sopenharmony_ci 9231cb0ef41Sopenharmony_ci get pathname() { 9241cb0ef41Sopenharmony_ci if (!isURL(this)) 9251cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9261cb0ef41Sopenharmony_ci const ctx = this[context]; 9271cb0ef41Sopenharmony_ci let endsAt; 9281cb0ef41Sopenharmony_ci if (ctx.hasSearch) { 9291cb0ef41Sopenharmony_ci endsAt = ctx.search_start; 9301cb0ef41Sopenharmony_ci } else if (ctx.hasHash) { 9311cb0ef41Sopenharmony_ci endsAt = ctx.hash_start; 9321cb0ef41Sopenharmony_ci } 9331cb0ef41Sopenharmony_ci return StringPrototypeSlice(ctx.href, ctx.pathname_start, endsAt); 9341cb0ef41Sopenharmony_ci } 9351cb0ef41Sopenharmony_ci 9361cb0ef41Sopenharmony_ci set pathname(value) { 9371cb0ef41Sopenharmony_ci if (!isURL(this)) 9381cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9391cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kPathname, `${value}`); 9401cb0ef41Sopenharmony_ci if (href) { 9411cb0ef41Sopenharmony_ci this.#updateContext(href); 9421cb0ef41Sopenharmony_ci } 9431cb0ef41Sopenharmony_ci } 9441cb0ef41Sopenharmony_ci 9451cb0ef41Sopenharmony_ci get search() { 9461cb0ef41Sopenharmony_ci if (!isURL(this)) 9471cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9481cb0ef41Sopenharmony_ci const ctx = this[context]; 9491cb0ef41Sopenharmony_ci if (!ctx.hasSearch) { return ''; } 9501cb0ef41Sopenharmony_ci let endsAt = ctx.href.length; 9511cb0ef41Sopenharmony_ci if (ctx.hasHash) { endsAt = ctx.hash_start; } 9521cb0ef41Sopenharmony_ci if (endsAt - ctx.search_start <= 1) { return ''; } 9531cb0ef41Sopenharmony_ci return StringPrototypeSlice(ctx.href, ctx.search_start, endsAt); 9541cb0ef41Sopenharmony_ci } 9551cb0ef41Sopenharmony_ci 9561cb0ef41Sopenharmony_ci set search(value) { 9571cb0ef41Sopenharmony_ci if (!isURL(this)) 9581cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9591cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kSearch, toUSVString(value)); 9601cb0ef41Sopenharmony_ci if (href) { 9611cb0ef41Sopenharmony_ci this.#updateContext(href); 9621cb0ef41Sopenharmony_ci } 9631cb0ef41Sopenharmony_ci } 9641cb0ef41Sopenharmony_ci 9651cb0ef41Sopenharmony_ci // readonly 9661cb0ef41Sopenharmony_ci get searchParams() { 9671cb0ef41Sopenharmony_ci if (!isURL(this)) 9681cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9691cb0ef41Sopenharmony_ci 9701cb0ef41Sopenharmony_ci const cachedValue = internalSearchParams.get(this); 9711cb0ef41Sopenharmony_ci if (cachedValue != null) 9721cb0ef41Sopenharmony_ci return cachedValue; 9731cb0ef41Sopenharmony_ci 9741cb0ef41Sopenharmony_ci const value = new URLSearchParams(this.search); 9751cb0ef41Sopenharmony_ci value[context] = this; 9761cb0ef41Sopenharmony_ci internalSearchParams.set(this, value); 9771cb0ef41Sopenharmony_ci return value; 9781cb0ef41Sopenharmony_ci } 9791cb0ef41Sopenharmony_ci 9801cb0ef41Sopenharmony_ci get hash() { 9811cb0ef41Sopenharmony_ci if (!isURL(this)) 9821cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9831cb0ef41Sopenharmony_ci const ctx = this[context]; 9841cb0ef41Sopenharmony_ci if (!ctx.hasHash || (ctx.href.length - ctx.hash_start <= 1)) { 9851cb0ef41Sopenharmony_ci return ''; 9861cb0ef41Sopenharmony_ci } 9871cb0ef41Sopenharmony_ci return StringPrototypeSlice(ctx.href, ctx.hash_start); 9881cb0ef41Sopenharmony_ci } 9891cb0ef41Sopenharmony_ci 9901cb0ef41Sopenharmony_ci set hash(value) { 9911cb0ef41Sopenharmony_ci if (!isURL(this)) 9921cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 9931cb0ef41Sopenharmony_ci const href = bindingUrl.update(this[context].href, updateActions.kHash, `${value}`); 9941cb0ef41Sopenharmony_ci if (href) { 9951cb0ef41Sopenharmony_ci this.#updateContext(href); 9961cb0ef41Sopenharmony_ci } 9971cb0ef41Sopenharmony_ci } 9981cb0ef41Sopenharmony_ci 9991cb0ef41Sopenharmony_ci toJSON() { 10001cb0ef41Sopenharmony_ci if (!isURL(this)) 10011cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URL'); 10021cb0ef41Sopenharmony_ci return this[context].href; 10031cb0ef41Sopenharmony_ci } 10041cb0ef41Sopenharmony_ci 10051cb0ef41Sopenharmony_ci static canParse(url, base = undefined) { 10061cb0ef41Sopenharmony_ci if (arguments.length === 0) { 10071cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('url'); 10081cb0ef41Sopenharmony_ci } 10091cb0ef41Sopenharmony_ci 10101cb0ef41Sopenharmony_ci url = `${url}`; 10111cb0ef41Sopenharmony_ci 10121cb0ef41Sopenharmony_ci if (base !== undefined) { 10131cb0ef41Sopenharmony_ci base = `${base}`; 10141cb0ef41Sopenharmony_ci } 10151cb0ef41Sopenharmony_ci 10161cb0ef41Sopenharmony_ci return bindingUrl.canParse(url, base); 10171cb0ef41Sopenharmony_ci } 10181cb0ef41Sopenharmony_ci 10191cb0ef41Sopenharmony_ci static createObjectURL(obj) { 10201cb0ef41Sopenharmony_ci const cryptoRandom = lazyCryptoRandom(); 10211cb0ef41Sopenharmony_ci if (cryptoRandom === undefined) 10221cb0ef41Sopenharmony_ci throw new ERR_NO_CRYPTO(); 10231cb0ef41Sopenharmony_ci 10241cb0ef41Sopenharmony_ci const blob = lazyBlob(); 10251cb0ef41Sopenharmony_ci if (!blob.isBlob(obj)) 10261cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('obj', 'Blob', obj); 10271cb0ef41Sopenharmony_ci 10281cb0ef41Sopenharmony_ci const id = cryptoRandom.randomUUID(); 10291cb0ef41Sopenharmony_ci 10301cb0ef41Sopenharmony_ci storeDataObject(id, obj[blob.kHandle], obj.size, obj.type); 10311cb0ef41Sopenharmony_ci 10321cb0ef41Sopenharmony_ci return `blob:nodedata:${id}`; 10331cb0ef41Sopenharmony_ci } 10341cb0ef41Sopenharmony_ci 10351cb0ef41Sopenharmony_ci static revokeObjectURL(url) { 10361cb0ef41Sopenharmony_ci url = `${url}`; 10371cb0ef41Sopenharmony_ci try { 10381cb0ef41Sopenharmony_ci // TODO(@anonrig): Remove this try/catch by calling `parse` directly. 10391cb0ef41Sopenharmony_ci const parsed = new URL(url); 10401cb0ef41Sopenharmony_ci const split = StringPrototypeSplit(parsed.pathname, ':'); 10411cb0ef41Sopenharmony_ci if (split.length === 2) 10421cb0ef41Sopenharmony_ci revokeDataObject(split[1]); 10431cb0ef41Sopenharmony_ci } catch { 10441cb0ef41Sopenharmony_ci // If there's an error, it's ignored. 10451cb0ef41Sopenharmony_ci } 10461cb0ef41Sopenharmony_ci } 10471cb0ef41Sopenharmony_ci} 10481cb0ef41Sopenharmony_ci 10491cb0ef41Sopenharmony_ciObjectDefineProperties(URL.prototype, { 10501cb0ef41Sopenharmony_ci [SymbolToStringTag]: { __proto__: null, configurable: true, value: 'URL' }, 10511cb0ef41Sopenharmony_ci toString: kEnumerableProperty, 10521cb0ef41Sopenharmony_ci href: kEnumerableProperty, 10531cb0ef41Sopenharmony_ci origin: kEnumerableProperty, 10541cb0ef41Sopenharmony_ci protocol: kEnumerableProperty, 10551cb0ef41Sopenharmony_ci username: kEnumerableProperty, 10561cb0ef41Sopenharmony_ci password: kEnumerableProperty, 10571cb0ef41Sopenharmony_ci host: kEnumerableProperty, 10581cb0ef41Sopenharmony_ci hostname: kEnumerableProperty, 10591cb0ef41Sopenharmony_ci port: kEnumerableProperty, 10601cb0ef41Sopenharmony_ci pathname: kEnumerableProperty, 10611cb0ef41Sopenharmony_ci search: kEnumerableProperty, 10621cb0ef41Sopenharmony_ci searchParams: kEnumerableProperty, 10631cb0ef41Sopenharmony_ci hash: kEnumerableProperty, 10641cb0ef41Sopenharmony_ci toJSON: kEnumerableProperty, 10651cb0ef41Sopenharmony_ci}); 10661cb0ef41Sopenharmony_ci 10671cb0ef41Sopenharmony_ciObjectDefineProperties(URL, { 10681cb0ef41Sopenharmony_ci canParse: { 10691cb0ef41Sopenharmony_ci __proto__: null, 10701cb0ef41Sopenharmony_ci configurable: true, 10711cb0ef41Sopenharmony_ci writable: true, 10721cb0ef41Sopenharmony_ci enumerable: true, 10731cb0ef41Sopenharmony_ci }, 10741cb0ef41Sopenharmony_ci createObjectURL: kEnumerableProperty, 10751cb0ef41Sopenharmony_ci revokeObjectURL: kEnumerableProperty, 10761cb0ef41Sopenharmony_ci}); 10771cb0ef41Sopenharmony_ci 10781cb0ef41Sopenharmony_ci// application/x-www-form-urlencoded parser 10791cb0ef41Sopenharmony_ci// Ref: https://url.spec.whatwg.org/#concept-urlencoded-parser 10801cb0ef41Sopenharmony_cifunction parseParams(qs) { 10811cb0ef41Sopenharmony_ci const out = []; 10821cb0ef41Sopenharmony_ci let seenSep = false; 10831cb0ef41Sopenharmony_ci let buf = ''; 10841cb0ef41Sopenharmony_ci let encoded = false; 10851cb0ef41Sopenharmony_ci let encodeCheck = 0; 10861cb0ef41Sopenharmony_ci let i = qs[0] === '?' ? 1 : 0; 10871cb0ef41Sopenharmony_ci let pairStart = i; 10881cb0ef41Sopenharmony_ci let lastPos = i; 10891cb0ef41Sopenharmony_ci for (; i < qs.length; ++i) { 10901cb0ef41Sopenharmony_ci const code = StringPrototypeCharCodeAt(qs, i); 10911cb0ef41Sopenharmony_ci 10921cb0ef41Sopenharmony_ci // Try matching key/value pair separator 10931cb0ef41Sopenharmony_ci if (code === CHAR_AMPERSAND) { 10941cb0ef41Sopenharmony_ci if (pairStart === i) { 10951cb0ef41Sopenharmony_ci // We saw an empty substring between pair separators 10961cb0ef41Sopenharmony_ci lastPos = pairStart = i + 1; 10971cb0ef41Sopenharmony_ci continue; 10981cb0ef41Sopenharmony_ci } 10991cb0ef41Sopenharmony_ci 11001cb0ef41Sopenharmony_ci if (lastPos < i) 11011cb0ef41Sopenharmony_ci buf += qs.slice(lastPos, i); 11021cb0ef41Sopenharmony_ci if (encoded) 11031cb0ef41Sopenharmony_ci buf = querystring.unescape(buf); 11041cb0ef41Sopenharmony_ci out.push(buf); 11051cb0ef41Sopenharmony_ci 11061cb0ef41Sopenharmony_ci // If `buf` is the key, add an empty value. 11071cb0ef41Sopenharmony_ci if (!seenSep) 11081cb0ef41Sopenharmony_ci out.push(''); 11091cb0ef41Sopenharmony_ci 11101cb0ef41Sopenharmony_ci seenSep = false; 11111cb0ef41Sopenharmony_ci buf = ''; 11121cb0ef41Sopenharmony_ci encoded = false; 11131cb0ef41Sopenharmony_ci encodeCheck = 0; 11141cb0ef41Sopenharmony_ci lastPos = pairStart = i + 1; 11151cb0ef41Sopenharmony_ci continue; 11161cb0ef41Sopenharmony_ci } 11171cb0ef41Sopenharmony_ci 11181cb0ef41Sopenharmony_ci // Try matching key/value separator (e.g. '=') if we haven't already 11191cb0ef41Sopenharmony_ci if (!seenSep && code === CHAR_EQUAL) { 11201cb0ef41Sopenharmony_ci // Key/value separator match! 11211cb0ef41Sopenharmony_ci if (lastPos < i) 11221cb0ef41Sopenharmony_ci buf += qs.slice(lastPos, i); 11231cb0ef41Sopenharmony_ci if (encoded) 11241cb0ef41Sopenharmony_ci buf = querystring.unescape(buf); 11251cb0ef41Sopenharmony_ci out.push(buf); 11261cb0ef41Sopenharmony_ci 11271cb0ef41Sopenharmony_ci seenSep = true; 11281cb0ef41Sopenharmony_ci buf = ''; 11291cb0ef41Sopenharmony_ci encoded = false; 11301cb0ef41Sopenharmony_ci encodeCheck = 0; 11311cb0ef41Sopenharmony_ci lastPos = i + 1; 11321cb0ef41Sopenharmony_ci continue; 11331cb0ef41Sopenharmony_ci } 11341cb0ef41Sopenharmony_ci 11351cb0ef41Sopenharmony_ci // Handle + and percent decoding. 11361cb0ef41Sopenharmony_ci if (code === CHAR_PLUS) { 11371cb0ef41Sopenharmony_ci if (lastPos < i) 11381cb0ef41Sopenharmony_ci buf += StringPrototypeSlice(qs, lastPos, i); 11391cb0ef41Sopenharmony_ci buf += ' '; 11401cb0ef41Sopenharmony_ci lastPos = i + 1; 11411cb0ef41Sopenharmony_ci } else if (!encoded) { 11421cb0ef41Sopenharmony_ci // Try to match an (valid) encoded byte (once) to minimize unnecessary 11431cb0ef41Sopenharmony_ci // calls to string decoding functions 11441cb0ef41Sopenharmony_ci if (code === CHAR_PERCENT) { 11451cb0ef41Sopenharmony_ci encodeCheck = 1; 11461cb0ef41Sopenharmony_ci } else if (encodeCheck > 0) { 11471cb0ef41Sopenharmony_ci if (isHexTable[code] === 1) { 11481cb0ef41Sopenharmony_ci if (++encodeCheck === 3) { 11491cb0ef41Sopenharmony_ci encoded = true; 11501cb0ef41Sopenharmony_ci } 11511cb0ef41Sopenharmony_ci } else { 11521cb0ef41Sopenharmony_ci encodeCheck = 0; 11531cb0ef41Sopenharmony_ci } 11541cb0ef41Sopenharmony_ci } 11551cb0ef41Sopenharmony_ci } 11561cb0ef41Sopenharmony_ci } 11571cb0ef41Sopenharmony_ci 11581cb0ef41Sopenharmony_ci // Deal with any leftover key or value data 11591cb0ef41Sopenharmony_ci 11601cb0ef41Sopenharmony_ci // There is a trailing &. No more processing is needed. 11611cb0ef41Sopenharmony_ci if (pairStart === i) 11621cb0ef41Sopenharmony_ci return out; 11631cb0ef41Sopenharmony_ci 11641cb0ef41Sopenharmony_ci if (lastPos < i) 11651cb0ef41Sopenharmony_ci buf += StringPrototypeSlice(qs, lastPos, i); 11661cb0ef41Sopenharmony_ci if (encoded) 11671cb0ef41Sopenharmony_ci buf = querystring.unescape(buf); 11681cb0ef41Sopenharmony_ci ArrayPrototypePush(out, buf); 11691cb0ef41Sopenharmony_ci 11701cb0ef41Sopenharmony_ci // If `buf` is the key, add an empty value. 11711cb0ef41Sopenharmony_ci if (!seenSep) 11721cb0ef41Sopenharmony_ci ArrayPrototypePush(out, ''); 11731cb0ef41Sopenharmony_ci 11741cb0ef41Sopenharmony_ci return out; 11751cb0ef41Sopenharmony_ci} 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_ci// Adapted from querystring's implementation. 11781cb0ef41Sopenharmony_ci// Ref: https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer 11791cb0ef41Sopenharmony_ciconst noEscape = new Int8Array([ 11801cb0ef41Sopenharmony_ci/* 11811cb0ef41Sopenharmony_ci 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F 11821cb0ef41Sopenharmony_ci*/ 11831cb0ef41Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F 11841cb0ef41Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F 11851cb0ef41Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, // 0x20 - 0x2F 11861cb0ef41Sopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F 11871cb0ef41Sopenharmony_ci 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 0x4F 11881cb0ef41Sopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 0x50 - 0x5F 11891cb0ef41Sopenharmony_ci 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6F 11901cb0ef41Sopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 0x70 - 0x7F 11911cb0ef41Sopenharmony_ci]); 11921cb0ef41Sopenharmony_ci 11931cb0ef41Sopenharmony_ci// Special version of hexTable that uses `+` for U+0020 SPACE. 11941cb0ef41Sopenharmony_ciconst paramHexTable = hexTable.slice(); 11951cb0ef41Sopenharmony_ciparamHexTable[0x20] = '+'; 11961cb0ef41Sopenharmony_ci 11971cb0ef41Sopenharmony_ci// application/x-www-form-urlencoded serializer 11981cb0ef41Sopenharmony_ci// Ref: https://url.spec.whatwg.org/#concept-urlencoded-serializer 11991cb0ef41Sopenharmony_cifunction serializeParams(array) { 12001cb0ef41Sopenharmony_ci const len = array.length; 12011cb0ef41Sopenharmony_ci if (len === 0) 12021cb0ef41Sopenharmony_ci return ''; 12031cb0ef41Sopenharmony_ci 12041cb0ef41Sopenharmony_ci const firstEncodedParam = encodeStr(array[0], noEscape, paramHexTable); 12051cb0ef41Sopenharmony_ci const firstEncodedValue = encodeStr(array[1], noEscape, paramHexTable); 12061cb0ef41Sopenharmony_ci let output = `${firstEncodedParam}=${firstEncodedValue}`; 12071cb0ef41Sopenharmony_ci 12081cb0ef41Sopenharmony_ci for (let i = 2; i < len; i += 2) { 12091cb0ef41Sopenharmony_ci const encodedParam = encodeStr(array[i], noEscape, paramHexTable); 12101cb0ef41Sopenharmony_ci const encodedValue = encodeStr(array[i + 1], noEscape, paramHexTable); 12111cb0ef41Sopenharmony_ci output += `&${encodedParam}=${encodedValue}`; 12121cb0ef41Sopenharmony_ci } 12131cb0ef41Sopenharmony_ci 12141cb0ef41Sopenharmony_ci return output; 12151cb0ef41Sopenharmony_ci} 12161cb0ef41Sopenharmony_ci 12171cb0ef41Sopenharmony_ci// Mainly to mitigate func-name-matching ESLint rule 12181cb0ef41Sopenharmony_cifunction defineIDLClass(proto, classStr, obj) { 12191cb0ef41Sopenharmony_ci // https://heycam.github.io/webidl/#dfn-class-string 12201cb0ef41Sopenharmony_ci ObjectDefineProperty(proto, SymbolToStringTag, { 12211cb0ef41Sopenharmony_ci __proto__: null, 12221cb0ef41Sopenharmony_ci writable: false, 12231cb0ef41Sopenharmony_ci enumerable: false, 12241cb0ef41Sopenharmony_ci configurable: true, 12251cb0ef41Sopenharmony_ci value: classStr, 12261cb0ef41Sopenharmony_ci }); 12271cb0ef41Sopenharmony_ci 12281cb0ef41Sopenharmony_ci // https://heycam.github.io/webidl/#es-operations 12291cb0ef41Sopenharmony_ci for (const key of ObjectKeys(obj)) { 12301cb0ef41Sopenharmony_ci ObjectDefineProperty(proto, key, { 12311cb0ef41Sopenharmony_ci __proto__: null, 12321cb0ef41Sopenharmony_ci writable: true, 12331cb0ef41Sopenharmony_ci enumerable: true, 12341cb0ef41Sopenharmony_ci configurable: true, 12351cb0ef41Sopenharmony_ci value: obj[key], 12361cb0ef41Sopenharmony_ci }); 12371cb0ef41Sopenharmony_ci } 12381cb0ef41Sopenharmony_ci for (const key of ObjectGetOwnPropertySymbols(obj)) { 12391cb0ef41Sopenharmony_ci ObjectDefineProperty(proto, key, { 12401cb0ef41Sopenharmony_ci __proto__: null, 12411cb0ef41Sopenharmony_ci writable: true, 12421cb0ef41Sopenharmony_ci enumerable: false, 12431cb0ef41Sopenharmony_ci configurable: true, 12441cb0ef41Sopenharmony_ci value: obj[key], 12451cb0ef41Sopenharmony_ci }); 12461cb0ef41Sopenharmony_ci } 12471cb0ef41Sopenharmony_ci} 12481cb0ef41Sopenharmony_ci 12491cb0ef41Sopenharmony_ci// for merge sort 12501cb0ef41Sopenharmony_cifunction merge(out, start, mid, end, lBuffer, rBuffer) { 12511cb0ef41Sopenharmony_ci const sizeLeft = mid - start; 12521cb0ef41Sopenharmony_ci const sizeRight = end - mid; 12531cb0ef41Sopenharmony_ci let l, r, o; 12541cb0ef41Sopenharmony_ci 12551cb0ef41Sopenharmony_ci for (l = 0; l < sizeLeft; l++) 12561cb0ef41Sopenharmony_ci lBuffer[l] = out[start + l]; 12571cb0ef41Sopenharmony_ci for (r = 0; r < sizeRight; r++) 12581cb0ef41Sopenharmony_ci rBuffer[r] = out[mid + r]; 12591cb0ef41Sopenharmony_ci 12601cb0ef41Sopenharmony_ci l = 0; 12611cb0ef41Sopenharmony_ci r = 0; 12621cb0ef41Sopenharmony_ci o = start; 12631cb0ef41Sopenharmony_ci while (l < sizeLeft && r < sizeRight) { 12641cb0ef41Sopenharmony_ci if (lBuffer[l] <= rBuffer[r]) { 12651cb0ef41Sopenharmony_ci out[o++] = lBuffer[l++]; 12661cb0ef41Sopenharmony_ci out[o++] = lBuffer[l++]; 12671cb0ef41Sopenharmony_ci } else { 12681cb0ef41Sopenharmony_ci out[o++] = rBuffer[r++]; 12691cb0ef41Sopenharmony_ci out[o++] = rBuffer[r++]; 12701cb0ef41Sopenharmony_ci } 12711cb0ef41Sopenharmony_ci } 12721cb0ef41Sopenharmony_ci while (l < sizeLeft) 12731cb0ef41Sopenharmony_ci out[o++] = lBuffer[l++]; 12741cb0ef41Sopenharmony_ci while (r < sizeRight) 12751cb0ef41Sopenharmony_ci out[o++] = rBuffer[r++]; 12761cb0ef41Sopenharmony_ci} 12771cb0ef41Sopenharmony_ci 12781cb0ef41Sopenharmony_ci// https://heycam.github.io/webidl/#dfn-default-iterator-object 12791cb0ef41Sopenharmony_cifunction createSearchParamsIterator(target, kind) { 12801cb0ef41Sopenharmony_ci const iterator = ObjectCreate(URLSearchParamsIteratorPrototype); 12811cb0ef41Sopenharmony_ci iterator[context] = { 12821cb0ef41Sopenharmony_ci target, 12831cb0ef41Sopenharmony_ci kind, 12841cb0ef41Sopenharmony_ci index: 0, 12851cb0ef41Sopenharmony_ci }; 12861cb0ef41Sopenharmony_ci return iterator; 12871cb0ef41Sopenharmony_ci} 12881cb0ef41Sopenharmony_ci 12891cb0ef41Sopenharmony_ci// https://heycam.github.io/webidl/#dfn-iterator-prototype-object 12901cb0ef41Sopenharmony_ciconst URLSearchParamsIteratorPrototype = ObjectCreate(IteratorPrototype); 12911cb0ef41Sopenharmony_ci 12921cb0ef41Sopenharmony_cidefineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParams Iterator', { 12931cb0ef41Sopenharmony_ci next() { 12941cb0ef41Sopenharmony_ci if (!this || 12951cb0ef41Sopenharmony_ci ObjectGetPrototypeOf(this) !== URLSearchParamsIteratorPrototype) { 12961cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParamsIterator'); 12971cb0ef41Sopenharmony_ci } 12981cb0ef41Sopenharmony_ci 12991cb0ef41Sopenharmony_ci const { 13001cb0ef41Sopenharmony_ci target, 13011cb0ef41Sopenharmony_ci kind, 13021cb0ef41Sopenharmony_ci index, 13031cb0ef41Sopenharmony_ci } = this[context]; 13041cb0ef41Sopenharmony_ci const values = target[searchParams]; 13051cb0ef41Sopenharmony_ci const len = values.length; 13061cb0ef41Sopenharmony_ci if (index >= len) { 13071cb0ef41Sopenharmony_ci return { 13081cb0ef41Sopenharmony_ci value: undefined, 13091cb0ef41Sopenharmony_ci done: true, 13101cb0ef41Sopenharmony_ci }; 13111cb0ef41Sopenharmony_ci } 13121cb0ef41Sopenharmony_ci 13131cb0ef41Sopenharmony_ci const name = values[index]; 13141cb0ef41Sopenharmony_ci const value = values[index + 1]; 13151cb0ef41Sopenharmony_ci this[context].index = index + 2; 13161cb0ef41Sopenharmony_ci 13171cb0ef41Sopenharmony_ci let result; 13181cb0ef41Sopenharmony_ci if (kind === 'key') { 13191cb0ef41Sopenharmony_ci result = name; 13201cb0ef41Sopenharmony_ci } else if (kind === 'value') { 13211cb0ef41Sopenharmony_ci result = value; 13221cb0ef41Sopenharmony_ci } else { 13231cb0ef41Sopenharmony_ci result = [name, value]; 13241cb0ef41Sopenharmony_ci } 13251cb0ef41Sopenharmony_ci 13261cb0ef41Sopenharmony_ci return { 13271cb0ef41Sopenharmony_ci value: result, 13281cb0ef41Sopenharmony_ci done: false, 13291cb0ef41Sopenharmony_ci }; 13301cb0ef41Sopenharmony_ci }, 13311cb0ef41Sopenharmony_ci [inspect.custom](recurseTimes, ctx) { 13321cb0ef41Sopenharmony_ci if (this == null || this[context] == null || this[context].target == null) 13331cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('URLSearchParamsIterator'); 13341cb0ef41Sopenharmony_ci 13351cb0ef41Sopenharmony_ci if (typeof recurseTimes === 'number' && recurseTimes < 0) 13361cb0ef41Sopenharmony_ci return ctx.stylize('[Object]', 'special'); 13371cb0ef41Sopenharmony_ci 13381cb0ef41Sopenharmony_ci const innerOpts = { ...ctx }; 13391cb0ef41Sopenharmony_ci if (recurseTimes !== null) { 13401cb0ef41Sopenharmony_ci innerOpts.depth = recurseTimes - 1; 13411cb0ef41Sopenharmony_ci } 13421cb0ef41Sopenharmony_ci const { 13431cb0ef41Sopenharmony_ci target, 13441cb0ef41Sopenharmony_ci kind, 13451cb0ef41Sopenharmony_ci index, 13461cb0ef41Sopenharmony_ci } = this[context]; 13471cb0ef41Sopenharmony_ci const output = ArrayPrototypeReduce( 13481cb0ef41Sopenharmony_ci ArrayPrototypeSlice(target[searchParams], index), 13491cb0ef41Sopenharmony_ci (prev, cur, i) => { 13501cb0ef41Sopenharmony_ci const key = i % 2 === 0; 13511cb0ef41Sopenharmony_ci if (kind === 'key' && key) { 13521cb0ef41Sopenharmony_ci ArrayPrototypePush(prev, cur); 13531cb0ef41Sopenharmony_ci } else if (kind === 'value' && !key) { 13541cb0ef41Sopenharmony_ci ArrayPrototypePush(prev, cur); 13551cb0ef41Sopenharmony_ci } else if (kind === 'key+value' && !key) { 13561cb0ef41Sopenharmony_ci ArrayPrototypePush(prev, [target[searchParams][index + i - 1], cur]); 13571cb0ef41Sopenharmony_ci } 13581cb0ef41Sopenharmony_ci return prev; 13591cb0ef41Sopenharmony_ci }, 13601cb0ef41Sopenharmony_ci [], 13611cb0ef41Sopenharmony_ci ); 13621cb0ef41Sopenharmony_ci const breakLn = StringPrototypeIncludes(inspect(output, innerOpts), '\n'); 13631cb0ef41Sopenharmony_ci const outputStrs = ArrayPrototypeMap(output, (p) => inspect(p, innerOpts)); 13641cb0ef41Sopenharmony_ci let outputStr; 13651cb0ef41Sopenharmony_ci if (breakLn) { 13661cb0ef41Sopenharmony_ci outputStr = `\n ${ArrayPrototypeJoin(outputStrs, ',\n ')}`; 13671cb0ef41Sopenharmony_ci } else { 13681cb0ef41Sopenharmony_ci outputStr = ` ${ArrayPrototypeJoin(outputStrs, ', ')}`; 13691cb0ef41Sopenharmony_ci } 13701cb0ef41Sopenharmony_ci return `${this[SymbolToStringTag]} {${outputStr} }`; 13711cb0ef41Sopenharmony_ci }, 13721cb0ef41Sopenharmony_ci}); 13731cb0ef41Sopenharmony_ci 13741cb0ef41Sopenharmony_cifunction domainToASCII(domain) { 13751cb0ef41Sopenharmony_ci if (arguments.length < 1) 13761cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('domain'); 13771cb0ef41Sopenharmony_ci 13781cb0ef41Sopenharmony_ci // toUSVString is not needed. 13791cb0ef41Sopenharmony_ci return bindingUrl.domainToASCII(`${domain}`); 13801cb0ef41Sopenharmony_ci} 13811cb0ef41Sopenharmony_ci 13821cb0ef41Sopenharmony_cifunction domainToUnicode(domain) { 13831cb0ef41Sopenharmony_ci if (arguments.length < 1) 13841cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('domain'); 13851cb0ef41Sopenharmony_ci 13861cb0ef41Sopenharmony_ci // toUSVString is not needed. 13871cb0ef41Sopenharmony_ci return bindingUrl.domainToUnicode(`${domain}`); 13881cb0ef41Sopenharmony_ci} 13891cb0ef41Sopenharmony_ci 13901cb0ef41Sopenharmony_ci/** 13911cb0ef41Sopenharmony_ci * Utility function that converts a URL object into an ordinary options object 13921cb0ef41Sopenharmony_ci * as expected by the `http.request` and `https.request` APIs. 13931cb0ef41Sopenharmony_ci * @param {URL} url 13941cb0ef41Sopenharmony_ci * @returns {Record<string, unknown>} 13951cb0ef41Sopenharmony_ci */ 13961cb0ef41Sopenharmony_cifunction urlToHttpOptions(url) { 13971cb0ef41Sopenharmony_ci const { hostname, pathname, port, username, password, search } = url; 13981cb0ef41Sopenharmony_ci const options = { 13991cb0ef41Sopenharmony_ci __proto__: null, 14001cb0ef41Sopenharmony_ci ...url, // In case the url object was extended by the user. 14011cb0ef41Sopenharmony_ci protocol: url.protocol, 14021cb0ef41Sopenharmony_ci hostname: hostname && StringPrototypeStartsWith(hostname, '[') ? 14031cb0ef41Sopenharmony_ci StringPrototypeSlice(hostname, 1, -1) : 14041cb0ef41Sopenharmony_ci hostname, 14051cb0ef41Sopenharmony_ci hash: url.hash, 14061cb0ef41Sopenharmony_ci search: search, 14071cb0ef41Sopenharmony_ci pathname: pathname, 14081cb0ef41Sopenharmony_ci path: `${pathname || ''}${search || ''}`, 14091cb0ef41Sopenharmony_ci href: url.href, 14101cb0ef41Sopenharmony_ci }; 14111cb0ef41Sopenharmony_ci if (port !== '') { 14121cb0ef41Sopenharmony_ci options.port = Number(port); 14131cb0ef41Sopenharmony_ci } 14141cb0ef41Sopenharmony_ci if (username || password) { 14151cb0ef41Sopenharmony_ci options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(password)}`; 14161cb0ef41Sopenharmony_ci } 14171cb0ef41Sopenharmony_ci return options; 14181cb0ef41Sopenharmony_ci} 14191cb0ef41Sopenharmony_ci 14201cb0ef41Sopenharmony_cifunction getPathFromURLWin32(url) { 14211cb0ef41Sopenharmony_ci const hostname = url.hostname; 14221cb0ef41Sopenharmony_ci let pathname = url.pathname; 14231cb0ef41Sopenharmony_ci for (let n = 0; n < pathname.length; n++) { 14241cb0ef41Sopenharmony_ci if (pathname[n] === '%') { 14251cb0ef41Sopenharmony_ci const third = StringPrototypeCodePointAt(pathname, n + 2) | 0x20; 14261cb0ef41Sopenharmony_ci if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F / 14271cb0ef41Sopenharmony_ci (pathname[n + 1] === '5' && third === 99)) { // 5c 5C \ 14281cb0ef41Sopenharmony_ci throw new ERR_INVALID_FILE_URL_PATH( 14291cb0ef41Sopenharmony_ci 'must not include encoded \\ or / characters', 14301cb0ef41Sopenharmony_ci ); 14311cb0ef41Sopenharmony_ci } 14321cb0ef41Sopenharmony_ci } 14331cb0ef41Sopenharmony_ci } 14341cb0ef41Sopenharmony_ci pathname = SideEffectFreeRegExpPrototypeSymbolReplace(FORWARD_SLASH, pathname, '\\'); 14351cb0ef41Sopenharmony_ci pathname = decodeURIComponent(pathname); 14361cb0ef41Sopenharmony_ci if (hostname !== '') { 14371cb0ef41Sopenharmony_ci // If hostname is set, then we have a UNC path 14381cb0ef41Sopenharmony_ci // Pass the hostname through domainToUnicode just in case 14391cb0ef41Sopenharmony_ci // it is an IDN using punycode encoding. We do not need to worry 14401cb0ef41Sopenharmony_ci // about percent encoding because the URL parser will have 14411cb0ef41Sopenharmony_ci // already taken care of that for us. Note that this only 14421cb0ef41Sopenharmony_ci // causes IDNs with an appropriate `xn--` prefix to be decoded. 14431cb0ef41Sopenharmony_ci return `\\\\${domainToUnicode(hostname)}${pathname}`; 14441cb0ef41Sopenharmony_ci } 14451cb0ef41Sopenharmony_ci // Otherwise, it's a local path that requires a drive letter 14461cb0ef41Sopenharmony_ci const letter = StringPrototypeCodePointAt(pathname, 1) | 0x20; 14471cb0ef41Sopenharmony_ci const sep = StringPrototypeCharAt(pathname, 2); 14481cb0ef41Sopenharmony_ci if (letter < CHAR_LOWERCASE_A || letter > CHAR_LOWERCASE_Z || // a..z A..Z 14491cb0ef41Sopenharmony_ci (sep !== ':')) { 14501cb0ef41Sopenharmony_ci throw new ERR_INVALID_FILE_URL_PATH('must be absolute'); 14511cb0ef41Sopenharmony_ci } 14521cb0ef41Sopenharmony_ci return StringPrototypeSlice(pathname, 1); 14531cb0ef41Sopenharmony_ci} 14541cb0ef41Sopenharmony_ci 14551cb0ef41Sopenharmony_cifunction getPathFromURLPosix(url) { 14561cb0ef41Sopenharmony_ci if (url.hostname !== '') { 14571cb0ef41Sopenharmony_ci throw new ERR_INVALID_FILE_URL_HOST(platform); 14581cb0ef41Sopenharmony_ci } 14591cb0ef41Sopenharmony_ci const pathname = url.pathname; 14601cb0ef41Sopenharmony_ci for (let n = 0; n < pathname.length; n++) { 14611cb0ef41Sopenharmony_ci if (pathname[n] === '%') { 14621cb0ef41Sopenharmony_ci const third = StringPrototypeCodePointAt(pathname, n + 2) | 0x20; 14631cb0ef41Sopenharmony_ci if (pathname[n + 1] === '2' && third === 102) { 14641cb0ef41Sopenharmony_ci throw new ERR_INVALID_FILE_URL_PATH( 14651cb0ef41Sopenharmony_ci 'must not include encoded / characters', 14661cb0ef41Sopenharmony_ci ); 14671cb0ef41Sopenharmony_ci } 14681cb0ef41Sopenharmony_ci } 14691cb0ef41Sopenharmony_ci } 14701cb0ef41Sopenharmony_ci return decodeURIComponent(pathname); 14711cb0ef41Sopenharmony_ci} 14721cb0ef41Sopenharmony_ci 14731cb0ef41Sopenharmony_cifunction fileURLToPath(path) { 14741cb0ef41Sopenharmony_ci if (typeof path === 'string') 14751cb0ef41Sopenharmony_ci path = new URL(path); 14761cb0ef41Sopenharmony_ci else if (!isURL(path)) 14771cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path); 14781cb0ef41Sopenharmony_ci if (path.protocol !== 'file:') 14791cb0ef41Sopenharmony_ci throw new ERR_INVALID_URL_SCHEME('file'); 14801cb0ef41Sopenharmony_ci return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path); 14811cb0ef41Sopenharmony_ci} 14821cb0ef41Sopenharmony_ci 14831cb0ef41Sopenharmony_ci// The following characters are percent-encoded when converting from file path 14841cb0ef41Sopenharmony_ci// to URL: 14851cb0ef41Sopenharmony_ci// - %: The percent character is the only character not encoded by the 14861cb0ef41Sopenharmony_ci// `pathname` setter. 14871cb0ef41Sopenharmony_ci// - \: Backslash is encoded on non-windows platforms since it's a valid 14881cb0ef41Sopenharmony_ci// character but the `pathname` setters replaces it by a forward slash. 14891cb0ef41Sopenharmony_ci// - LF: The newline character is stripped out by the `pathname` setter. 14901cb0ef41Sopenharmony_ci// (See whatwg/url#419) 14911cb0ef41Sopenharmony_ci// - CR: The carriage return character is also stripped out by the `pathname` 14921cb0ef41Sopenharmony_ci// setter. 14931cb0ef41Sopenharmony_ci// - TAB: The tab character is also stripped out by the `pathname` setter. 14941cb0ef41Sopenharmony_ciconst percentRegEx = /%/g; 14951cb0ef41Sopenharmony_ciconst backslashRegEx = /\\/g; 14961cb0ef41Sopenharmony_ciconst newlineRegEx = /\n/g; 14971cb0ef41Sopenharmony_ciconst carriageReturnRegEx = /\r/g; 14981cb0ef41Sopenharmony_ciconst tabRegEx = /\t/g; 14991cb0ef41Sopenharmony_ciconst questionRegex = /\?/g; 15001cb0ef41Sopenharmony_ciconst hashRegex = /#/g; 15011cb0ef41Sopenharmony_ci 15021cb0ef41Sopenharmony_cifunction encodePathChars(filepath) { 15031cb0ef41Sopenharmony_ci if (StringPrototypeIndexOf(filepath, '%') !== -1) 15041cb0ef41Sopenharmony_ci filepath = RegExpPrototypeSymbolReplace(percentRegEx, filepath, '%25'); 15051cb0ef41Sopenharmony_ci // In posix, backslash is a valid character in paths: 15061cb0ef41Sopenharmony_ci if (!isWindows && StringPrototypeIndexOf(filepath, '\\') !== -1) 15071cb0ef41Sopenharmony_ci filepath = RegExpPrototypeSymbolReplace(backslashRegEx, filepath, '%5C'); 15081cb0ef41Sopenharmony_ci if (StringPrototypeIndexOf(filepath, '\n') !== -1) 15091cb0ef41Sopenharmony_ci filepath = RegExpPrototypeSymbolReplace(newlineRegEx, filepath, '%0A'); 15101cb0ef41Sopenharmony_ci if (StringPrototypeIndexOf(filepath, '\r') !== -1) 15111cb0ef41Sopenharmony_ci filepath = RegExpPrototypeSymbolReplace(carriageReturnRegEx, filepath, '%0D'); 15121cb0ef41Sopenharmony_ci if (StringPrototypeIndexOf(filepath, '\t') !== -1) 15131cb0ef41Sopenharmony_ci filepath = RegExpPrototypeSymbolReplace(tabRegEx, filepath, '%09'); 15141cb0ef41Sopenharmony_ci return filepath; 15151cb0ef41Sopenharmony_ci} 15161cb0ef41Sopenharmony_ci 15171cb0ef41Sopenharmony_cifunction pathToFileURL(filepath) { 15181cb0ef41Sopenharmony_ci if (isWindows && StringPrototypeStartsWith(filepath, '\\\\')) { 15191cb0ef41Sopenharmony_ci const outURL = new URL('file://'); 15201cb0ef41Sopenharmony_ci // UNC path format: \\server\share\resource 15211cb0ef41Sopenharmony_ci const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', 2); 15221cb0ef41Sopenharmony_ci if (hostnameEndIndex === -1) { 15231cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE( 15241cb0ef41Sopenharmony_ci 'path', 15251cb0ef41Sopenharmony_ci filepath, 15261cb0ef41Sopenharmony_ci 'Missing UNC resource path', 15271cb0ef41Sopenharmony_ci ); 15281cb0ef41Sopenharmony_ci } 15291cb0ef41Sopenharmony_ci if (hostnameEndIndex === 2) { 15301cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE( 15311cb0ef41Sopenharmony_ci 'path', 15321cb0ef41Sopenharmony_ci filepath, 15331cb0ef41Sopenharmony_ci 'Empty UNC servername', 15341cb0ef41Sopenharmony_ci ); 15351cb0ef41Sopenharmony_ci } 15361cb0ef41Sopenharmony_ci const hostname = StringPrototypeSlice(filepath, 2, hostnameEndIndex); 15371cb0ef41Sopenharmony_ci outURL.hostname = domainToASCII(hostname); 15381cb0ef41Sopenharmony_ci outURL.pathname = encodePathChars( 15391cb0ef41Sopenharmony_ci RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/')); 15401cb0ef41Sopenharmony_ci return outURL; 15411cb0ef41Sopenharmony_ci } 15421cb0ef41Sopenharmony_ci let resolved = path.resolve(filepath); 15431cb0ef41Sopenharmony_ci // path.resolve strips trailing slashes so we must add them back 15441cb0ef41Sopenharmony_ci const filePathLast = StringPrototypeCharCodeAt(filepath, 15451cb0ef41Sopenharmony_ci filepath.length - 1); 15461cb0ef41Sopenharmony_ci if ((filePathLast === CHAR_FORWARD_SLASH || 15471cb0ef41Sopenharmony_ci (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) && 15481cb0ef41Sopenharmony_ci resolved[resolved.length - 1] !== path.sep) 15491cb0ef41Sopenharmony_ci resolved += '/'; 15501cb0ef41Sopenharmony_ci 15511cb0ef41Sopenharmony_ci // Call encodePathChars first to avoid encoding % again for ? and #. 15521cb0ef41Sopenharmony_ci resolved = encodePathChars(resolved); 15531cb0ef41Sopenharmony_ci 15541cb0ef41Sopenharmony_ci // Question and hash character should be included in pathname. 15551cb0ef41Sopenharmony_ci // Therefore, encoding is required to eliminate parsing them in different states. 15561cb0ef41Sopenharmony_ci // This is done as an optimization to not creating a URL instance and 15571cb0ef41Sopenharmony_ci // later triggering pathname setter, which impacts performance 15581cb0ef41Sopenharmony_ci if (StringPrototypeIndexOf(resolved, '?') !== -1) 15591cb0ef41Sopenharmony_ci resolved = RegExpPrototypeSymbolReplace(questionRegex, resolved, '%3F'); 15601cb0ef41Sopenharmony_ci if (StringPrototypeIndexOf(resolved, '#') !== -1) 15611cb0ef41Sopenharmony_ci resolved = RegExpPrototypeSymbolReplace(hashRegex, resolved, '%23'); 15621cb0ef41Sopenharmony_ci return new URL(`file://${resolved}`); 15631cb0ef41Sopenharmony_ci} 15641cb0ef41Sopenharmony_ci 15651cb0ef41Sopenharmony_cifunction toPathIfFileURL(fileURLOrPath) { 15661cb0ef41Sopenharmony_ci if (!isURL(fileURLOrPath)) 15671cb0ef41Sopenharmony_ci return fileURLOrPath; 15681cb0ef41Sopenharmony_ci return fileURLToPath(fileURLOrPath); 15691cb0ef41Sopenharmony_ci} 15701cb0ef41Sopenharmony_ci 15711cb0ef41Sopenharmony_cimodule.exports = { 15721cb0ef41Sopenharmony_ci toUSVString, 15731cb0ef41Sopenharmony_ci fileURLToPath, 15741cb0ef41Sopenharmony_ci pathToFileURL, 15751cb0ef41Sopenharmony_ci toPathIfFileURL, 15761cb0ef41Sopenharmony_ci URL, 15771cb0ef41Sopenharmony_ci URLSearchParams, 15781cb0ef41Sopenharmony_ci domainToASCII, 15791cb0ef41Sopenharmony_ci domainToUnicode, 15801cb0ef41Sopenharmony_ci urlToHttpOptions, 15811cb0ef41Sopenharmony_ci encodeStr, 15821cb0ef41Sopenharmony_ci isURL, 15831cb0ef41Sopenharmony_ci 15841cb0ef41Sopenharmony_ci urlUpdateActions: updateActions, 15851cb0ef41Sopenharmony_ci unsafeProtocol, 15861cb0ef41Sopenharmony_ci hostlessProtocol, 15871cb0ef41Sopenharmony_ci slashedProtocol, 15881cb0ef41Sopenharmony_ci}; 1589