'use strict'; // TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env` require('../modules/es.string.iterator'); var $ = require('../internals/export'); var DESCRIPTORS = require('../internals/descriptors'); var USE_NATIVE_URL = require('../internals/native-url'); var global = require('../internals/global'); var bind = require('../internals/function-bind-context'); var uncurryThis = require('../internals/function-uncurry-this'); var defineBuiltIn = require('../internals/define-built-in'); var defineBuiltInAccessor = require('../internals/define-built-in-accessor'); var anInstance = require('../internals/an-instance'); var hasOwn = require('../internals/has-own-property'); var assign = require('../internals/object-assign'); var arrayFrom = require('../internals/array-from'); var arraySlice = require('../internals/array-slice-simple'); var codeAt = require('../internals/string-multibyte').codeAt; var toASCII = require('../internals/string-punycode-to-ascii'); var $toString = require('../internals/to-string'); var setToStringTag = require('../internals/set-to-string-tag'); var validateArgumentsLength = require('../internals/validate-arguments-length'); var URLSearchParamsModule = require('../modules/web.url-search-params.constructor'); var InternalStateModule = require('../internals/internal-state'); var setInternalState = InternalStateModule.set; var getInternalURLState = InternalStateModule.getterFor('URL'); var URLSearchParams = URLSearchParamsModule.URLSearchParams; var getInternalSearchParamsState = URLSearchParamsModule.getState; var NativeURL = global.URL; var TypeError = global.TypeError; var parseInt = global.parseInt; var floor = Math.floor; var pow = Math.pow; var charAt = uncurryThis(''.charAt); var exec = uncurryThis(/./.exec); var join = uncurryThis([].join); var numberToString = uncurryThis(1.0.toString); var pop = uncurryThis([].pop); var push = uncurryThis([].push); var replace = uncurryThis(''.replace); var shift = uncurryThis([].shift); var split = uncurryThis(''.split); var stringSlice = uncurryThis(''.slice); var toLowerCase = uncurryThis(''.toLowerCase); var unshift = uncurryThis([].unshift); var INVALID_AUTHORITY = 'Invalid authority'; var INVALID_SCHEME = 'Invalid scheme'; var INVALID_HOST = 'Invalid host'; var INVALID_PORT = 'Invalid port'; var ALPHA = /[a-z]/i; // eslint-disable-next-line regexp/no-obscure-range -- safe var ALPHANUMERIC = /[\d+-.a-z]/i; var DIGIT = /\d/; var HEX_START = /^0x/i; var OCT = /^[0-7]+$/; var DEC = /^\d+$/; var HEX = /^[\da-f]+$/i; /* eslint-disable regexp/no-control-character -- safe */ var FORBIDDEN_HOST_CODE_POINT = /[\0\t\n\r #%/:<>?@[\\\]^|]/; var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\0\t\n\r #/:<>?@[\\\]^|]/; var LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\u0000-\u0020]+|[\u0000-\u0020]+$/g; var TAB_AND_NEW_LINE = /[\t\n\r]/g; /* eslint-enable regexp/no-control-character -- safe */ var EOF; // https://url.spec.whatwg.org/#ipv4-number-parser var parseIPv4 = function (input) { var parts = split(input, '.'); var partsLength, numbers, index, part, radix, number, ipv4; if (parts.length && parts[parts.length - 1] == '') { parts.length--; } partsLength = parts.length; if (partsLength > 4) return input; numbers = []; for (index = 0; index < partsLength; index++) { part = parts[index]; if (part == '') return input; radix = 10; if (part.length > 1 && charAt(part, 0) == '0') { radix = exec(HEX_START, part) ? 16 : 8; part = stringSlice(part, radix == 8 ? 1 : 2); } if (part === '') { number = 0; } else { if (!exec(radix == 10 ? DEC : radix == 8 ? OCT : HEX, part)) return input; number = parseInt(part, radix); } push(numbers, number); } for (index = 0; index < partsLength; index++) { number = numbers[index]; if (index == partsLength - 1) { if (number >= pow(256, 5 - partsLength)) return null; } else if (number > 255) return null; } ipv4 = pop(numbers); for (index = 0; index < numbers.length; index++) { ipv4 += numbers[index] * pow(256, 3 - index); } return ipv4; }; // https://url.spec.whatwg.org/#concept-ipv6-parser // eslint-disable-next-line max-statements -- TODO var parseIPv6 = function (input) { var address = [0, 0, 0, 0, 0, 0, 0, 0]; var pieceIndex = 0; var compress = null; var pointer = 0; var value, length, numbersSeen, ipv4Piece, number, swaps, swap; var chr = function () { return charAt(input, pointer); }; if (chr() == ':') { if (charAt(input, 1) != ':') return; pointer += 2; pieceIndex++; compress = pieceIndex; } while (chr()) { if (pieceIndex == 8) return; if (chr() == ':') { if (compress !== null) return; pointer++; pieceIndex++; compress = pieceIndex; continue; } value = length = 0; while (length < 4 && exec(HEX, chr())) { value = value * 16 + parseInt(chr(), 16); pointer++; length++; } if (chr() == '.') { if (length == 0) return; pointer -= length; if (pieceIndex > 6) return; numbersSeen = 0; while (chr()) { ipv4Piece = null; if (numbersSeen > 0) { if (chr() == '.' && numbersSeen < 4) pointer++; else return; } if (!exec(DIGIT, chr())) return; while (exec(DIGIT, chr())) { number = parseInt(chr(), 10); if (ipv4Piece === null) ipv4Piece = number; else if (ipv4Piece == 0) return; else ipv4Piece = ipv4Piece * 10 + number; if (ipv4Piece > 255) return; pointer++; } address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece; numbersSeen++; if (numbersSeen == 2 || numbersSeen == 4) pieceIndex++; } if (numbersSeen != 4) return; break; } else if (chr() == ':') { pointer++; if (!chr()) return; } else if (chr()) return; address[pieceIndex++] = value; } if (compress !== null) { swaps = pieceIndex - compress; pieceIndex = 7; while (pieceIndex != 0 && swaps > 0) { swap = address[pieceIndex]; address[pieceIndex--] = address[compress + swaps - 1]; address[compress + --swaps] = swap; } } else if (pieceIndex != 8) return; return address; }; var findLongestZeroSequence = function (ipv6) { var maxIndex = null; var maxLength = 1; var currStart = null; var currLength = 0; var index = 0; for (; index < 8; index++) { if (ipv6[index] !== 0) { if (currLength > maxLength) { maxIndex = currStart; maxLength = currLength; } currStart = null; currLength = 0; } else { if (currStart === null) currStart = index; ++currLength; } } if (currLength > maxLength) { maxIndex = currStart; maxLength = currLength; } return maxIndex; }; // https://url.spec.whatwg.org/#host-serializing var serializeHost = function (host) { var result, index, compress, ignore0; // ipv4 if (typeof host == 'number') { result = []; for (index = 0; index < 4; index++) { unshift(result, host % 256); host = floor(host / 256); } return join(result, '.'); // ipv6 } else if (typeof host == 'object') { result = ''; compress = findLongestZeroSequence(host); for (index = 0; index < 8; index++) { if (ignore0 && host[index] === 0) continue; if (ignore0) ignore0 = false; if (compress === index) { result += index ? ':' : '::'; ignore0 = true; } else { result += numberToString(host[index], 16); if (index < 7) result += ':'; } } return '[' + result + ']'; } return host; }; var C0ControlPercentEncodeSet = {}; var fragmentPercentEncodeSet = assign({}, C0ControlPercentEncodeSet, { ' ': 1, '"': 1, '<': 1, '>': 1, '`': 1 }); var pathPercentEncodeSet = assign({}, fragmentPercentEncodeSet, { '#': 1, '?': 1, '{': 1, '}': 1 }); var userinfoPercentEncodeSet = assign({}, pathPercentEncodeSet, { '/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\': 1, ']': 1, '^': 1, '|': 1 }); var percentEncode = function (chr, set) { var code = codeAt(chr, 0); return code > 0x20 && code < 0x7F && !hasOwn(set, chr) ? chr : encodeURIComponent(chr); }; // https://url.spec.whatwg.org/#special-scheme var specialSchemes = { ftp: 21, file: null, http: 80, https: 443, ws: 80, wss: 443 }; // https://url.spec.whatwg.org/#windows-drive-letter var isWindowsDriveLetter = function (string, normalized) { var second; return string.length == 2 && exec(ALPHA, charAt(string, 0)) && ((second = charAt(string, 1)) == ':' || (!normalized && second == '|')); }; // https://url.spec.whatwg.org/#start-with-a-windows-drive-letter var startsWithWindowsDriveLetter = function (string) { var third; return string.length > 1 && isWindowsDriveLetter(stringSlice(string, 0, 2)) && ( string.length == 2 || ((third = charAt(string, 2)) === '/' || third === '\\' || third === '?' || third === '#') ); }; // https://url.spec.whatwg.org/#single-dot-path-segment var isSingleDot = function (segment) { return segment === '.' || toLowerCase(segment) === '%2e'; }; // https://url.spec.whatwg.org/#double-dot-path-segment var isDoubleDot = function (segment) { segment = toLowerCase(segment); return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e'; }; // States: var SCHEME_START = {}; var SCHEME = {}; var NO_SCHEME = {}; var SPECIAL_RELATIVE_OR_AUTHORITY = {}; var PATH_OR_AUTHORITY = {}; var RELATIVE = {}; var RELATIVE_SLASH = {}; var SPECIAL_AUTHORITY_SLASHES = {}; var SPECIAL_AUTHORITY_IGNORE_SLASHES = {}; var AUTHORITY = {}; var HOST = {}; var HOSTNAME = {}; var PORT = {}; var FILE = {}; var FILE_SLASH = {}; var FILE_HOST = {}; var PATH_START = {}; var PATH = {}; var CANNOT_BE_A_BASE_URL_PATH = {}; var QUERY = {}; var FRAGMENT = {}; var URLState = function (url, isBase, base) { var urlString = $toString(url); var baseState, failure, searchParams; if (isBase) { failure = this.parse(urlString); if (failure) throw TypeError(failure); this.searchParams = null; } else { if (base !== undefined) baseState = new URLState(base, true); failure = this.parse(urlString, null, baseState); if (failure) throw TypeError(failure); searchParams = getInternalSearchParamsState(new URLSearchParams()); searchParams.bindURL(this); this.searchParams = searchParams; } }; URLState.prototype = { type: 'URL', // https://url.spec.whatwg.org/#url-parsing // eslint-disable-next-line max-statements -- TODO parse: function (input, stateOverride, base) { var url = this; var state = stateOverride || SCHEME_START; var pointer = 0; var buffer = ''; var seenAt = false; var seenBracket = false; var seenPasswordToken = false; var codePoints, chr, bufferCodePoints, failure; input = $toString(input); if (!stateOverride) { url.scheme = ''; url.username = ''; url.password = ''; url.host = null; url.port = null; url.path = []; url.query = null; url.fragment = null; url.cannotBeABaseURL = false; input = replace(input, LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, ''); } input = replace(input, TAB_AND_NEW_LINE, ''); codePoints = arrayFrom(input); while (pointer <= codePoints.length) { chr = codePoints[pointer]; switch (state) { case SCHEME_START: if (chr && exec(ALPHA, chr)) { buffer += toLowerCase(chr); state = SCHEME; } else if (!stateOverride) { state = NO_SCHEME; continue; } else return INVALID_SCHEME; break; case SCHEME: if (chr && (exec(ALPHANUMERIC, chr) || chr == '+' || chr == '-' || chr == '.')) { buffer += toLowerCase(chr); } else if (chr == ':') { if (stateOverride && ( (url.isSpecial() != hasOwn(specialSchemes, buffer)) || (buffer == 'file' && (url.includesCredentials() || url.port !== null)) || (url.scheme == 'file' && !url.host) )) return; url.scheme = buffer; if (stateOverride) { if (url.isSpecial() && specialSchemes[url.scheme] == url.port) url.port = null; return; } buffer = ''; if (url.scheme == 'file') { state = FILE; } else if (url.isSpecial() && base && base.scheme == url.scheme) { state = SPECIAL_RELATIVE_OR_AUTHORITY; } else if (url.isSpecial()) { state = SPECIAL_AUTHORITY_SLASHES; } else if (codePoints[pointer + 1] == '/') { state = PATH_OR_AUTHORITY; pointer++; } else { url.cannotBeABaseURL = true; push(url.path, ''); state = CANNOT_BE_A_BASE_URL_PATH; } } else if (!stateOverride) { buffer = ''; state = NO_SCHEME; pointer = 0; continue; } else return INVALID_SCHEME; break; case NO_SCHEME: if (!base || (base.cannotBeABaseURL && chr != '#')) return INVALID_SCHEME; if (base.cannotBeABaseURL && chr == '#') { url.scheme = base.scheme; url.path = arraySlice(base.path); url.query = base.query; url.fragment = ''; url.cannotBeABaseURL = true; state = FRAGMENT; break; } state = base.scheme == 'file' ? FILE : RELATIVE; continue; case SPECIAL_RELATIVE_OR_AUTHORITY: if (chr == '/' && codePoints[pointer + 1] == '/') { state = SPECIAL_AUTHORITY_IGNORE_SLASHES; pointer++; } else { state = RELATIVE; continue; } break; case PATH_OR_AUTHORITY: if (chr == '/') { state = AUTHORITY; break; } else { state = PATH; continue; } case RELATIVE: url.scheme = base.scheme; if (chr == EOF) { url.username = base.username; url.password = base.password; url.host = base.host; url.port = base.port; url.path = arraySlice(base.path); url.query = base.query; } else if (chr == '/' || (chr == '\\' && url.isSpecial())) { state = RELATIVE_SLASH; } else if (chr == '?') { url.username = base.username; url.password = base.password; url.host = base.host; url.port = base.port; url.path = arraySlice(base.path); url.query = ''; state = QUERY; } else if (chr == '#') { url.username = base.username; url.password = base.password; url.host = base.host; url.port = base.port; url.path = arraySlice(base.path); url.query = base.query; url.fragment = ''; state = FRAGMENT; } else { url.username = base.username; url.password = base.password; url.host = base.host; url.port = base.port; url.path = arraySlice(base.path); url.path.length--; state = PATH; continue; } break; case RELATIVE_SLASH: if (url.isSpecial() && (chr == '/' || chr == '\\')) { state = SPECIAL_AUTHORITY_IGNORE_SLASHES; } else if (chr == '/') { state = AUTHORITY; } else { url.username = base.username; url.password = base.password; url.host = base.host; url.port = base.port; state = PATH; continue; } break; case SPECIAL_AUTHORITY_SLASHES: state = SPECIAL_AUTHORITY_IGNORE_SLASHES; if (chr != '/' || charAt(buffer, pointer + 1) != '/') continue; pointer++; break; case SPECIAL_AUTHORITY_IGNORE_SLASHES: if (chr != '/' && chr != '\\') { state = AUTHORITY; continue; } break; case AUTHORITY: if (chr == '@') { if (seenAt) buffer = '%40' + buffer; seenAt = true; bufferCodePoints = arrayFrom(buffer); for (var i = 0; i < bufferCodePoints.length; i++) { var codePoint = bufferCodePoints[i]; if (codePoint == ':' && !seenPasswordToken) { seenPasswordToken = true; continue; } var encodedCodePoints = percentEncode(codePoint, userinfoPercentEncodeSet); if (seenPasswordToken) url.password += encodedCodePoints; else url.username += encodedCodePoints; } buffer = ''; } else if ( chr == EOF || chr == '/' || chr == '?' || chr == '#' || (chr == '\\' && url.isSpecial()) ) { if (seenAt && buffer == '') return INVALID_AUTHORITY; pointer -= arrayFrom(buffer).length + 1; buffer = ''; state = HOST; } else buffer += chr; break; case HOST: case HOSTNAME: if (stateOverride && url.scheme == 'file') { state = FILE_HOST; continue; } else if (chr == ':' && !seenBracket) { if (buffer == '') return INVALID_HOST; failure = url.parseHost(buffer); if (failure) return failure; buffer = ''; state = PORT; if (stateOverride == HOSTNAME) return; } else if ( chr == EOF || chr == '/' || chr == '?' || chr == '#' || (chr == '\\' && url.isSpecial()) ) { if (url.isSpecial() && buffer == '') return INVALID_HOST; if (stateOverride && buffer == '' && (url.includesCredentials() || url.port !== null)) return; failure = url.parseHost(buffer); if (failure) return failure; buffer = ''; state = PATH_START; if (stateOverride) return; continue; } else { if (chr == '[') seenBracket = true; else if (chr == ']') seenBracket = false; buffer += chr; } break; case PORT: if (exec(DIGIT, chr)) { buffer += chr; } else if ( chr == EOF || chr == '/' || chr == '?' || chr == '#' || (chr == '\\' && url.isSpecial()) || stateOverride ) { if (buffer != '') { var port = parseInt(buffer, 10); if (port > 0xFFFF) return INVALID_PORT; url.port = (url.isSpecial() && port === specialSchemes[url.scheme]) ? null : port; buffer = ''; } if (stateOverride) return; state = PATH_START; continue; } else return INVALID_PORT; break; case FILE: url.scheme = 'file'; if (chr == '/' || chr == '\\') state = FILE_SLASH; else if (base && base.scheme == 'file') { if (chr == EOF) { url.host = base.host; url.path = arraySlice(base.path); url.query = base.query; } else if (chr == '?') { url.host = base.host; url.path = arraySlice(base.path); url.query = ''; state = QUERY; } else if (chr == '#') { url.host = base.host; url.path = arraySlice(base.path); url.query = base.query; url.fragment = ''; state = FRAGMENT; } else { if (!startsWithWindowsDriveLetter(join(arraySlice(codePoints, pointer), ''))) { url.host = base.host; url.path = arraySlice(base.path); url.shortenPath(); } state = PATH; continue; } } else { state = PATH; continue; } break; case FILE_SLASH: if (chr == '/' || chr == '\\') { state = FILE_HOST; break; } if (base && base.scheme == 'file' && !startsWithWindowsDriveLetter(join(arraySlice(codePoints, pointer), ''))) { if (isWindowsDriveLetter(base.path[0], true)) push(url.path, base.path[0]); else url.host = base.host; } state = PATH; continue; case FILE_HOST: if (chr == EOF || chr == '/' || chr == '\\' || chr == '?' || chr == '#') { if (!stateOverride && isWindowsDriveLetter(buffer)) { state = PATH; } else if (buffer == '') { url.host = ''; if (stateOverride) return; state = PATH_START; } else { failure = url.parseHost(buffer); if (failure) return failure; if (url.host == 'localhost') url.host = ''; if (stateOverride) return; buffer = ''; state = PATH_START; } continue; } else buffer += chr; break; case PATH_START: if (url.isSpecial()) { state = PATH; if (chr != '/' && chr != '\\') continue; } else if (!stateOverride && chr == '?') { url.query = ''; state = QUERY; } else if (!stateOverride && chr == '#') { url.fragment = ''; state = FRAGMENT; } else if (chr != EOF) { state = PATH; if (chr != '/') continue; } break; case PATH: if ( chr == EOF || chr == '/' || (chr == '\\' && url.isSpecial()) || (!stateOverride && (chr == '?' || chr == '#')) ) { if (isDoubleDot(buffer)) { url.shortenPath(); if (chr != '/' && !(chr == '\\' && url.isSpecial())) { push(url.path, ''); } } else if (isSingleDot(buffer)) { if (chr != '/' && !(chr == '\\' && url.isSpecial())) { push(url.path, ''); } } else { if (url.scheme == 'file' && !url.path.length && isWindowsDriveLetter(buffer)) { if (url.host) url.host = ''; buffer = charAt(buffer, 0) + ':'; // normalize windows drive letter } push(url.path, buffer); } buffer = ''; if (url.scheme == 'file' && (chr == EOF || chr == '?' || chr == '#')) { while (url.path.length > 1 && url.path[0] === '') { shift(url.path); } } if (chr == '?') { url.query = ''; state = QUERY; } else if (chr == '#') { url.fragment = ''; state = FRAGMENT; } } else { buffer += percentEncode(chr, pathPercentEncodeSet); } break; case CANNOT_BE_A_BASE_URL_PATH: if (chr == '?') { url.query = ''; state = QUERY; } else if (chr == '#') { url.fragment = ''; state = FRAGMENT; } else if (chr != EOF) { url.path[0] += percentEncode(chr, C0ControlPercentEncodeSet); } break; case QUERY: if (!stateOverride && chr == '#') { url.fragment = ''; state = FRAGMENT; } else if (chr != EOF) { if (chr == "'" && url.isSpecial()) url.query += '%27'; else if (chr == '#') url.query += '%23'; else url.query += percentEncode(chr, C0ControlPercentEncodeSet); } break; case FRAGMENT: if (chr != EOF) url.fragment += percentEncode(chr, fragmentPercentEncodeSet); break; } pointer++; } }, // https://url.spec.whatwg.org/#host-parsing parseHost: function (input) { var result, codePoints, index; if (charAt(input, 0) == '[') { if (charAt(input, input.length - 1) != ']') return INVALID_HOST; result = parseIPv6(stringSlice(input, 1, -1)); if (!result) return INVALID_HOST; this.host = result; // opaque host } else if (!this.isSpecial()) { if (exec(FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT, input)) return INVALID_HOST; result = ''; codePoints = arrayFrom(input); for (index = 0; index < codePoints.length; index++) { result += percentEncode(codePoints[index], C0ControlPercentEncodeSet); } this.host = result; } else { input = toASCII(input); if (exec(FORBIDDEN_HOST_CODE_POINT, input)) return INVALID_HOST; result = parseIPv4(input); if (result === null) return INVALID_HOST; this.host = result; } }, // https://url.spec.whatwg.org/#cannot-have-a-username-password-port cannotHaveUsernamePasswordPort: function () { return !this.host || this.cannotBeABaseURL || this.scheme == 'file'; }, // https://url.spec.whatwg.org/#include-credentials includesCredentials: function () { return this.username != '' || this.password != ''; }, // https://url.spec.whatwg.org/#is-special isSpecial: function () { return hasOwn(specialSchemes, this.scheme); }, // https://url.spec.whatwg.org/#shorten-a-urls-path shortenPath: function () { var path = this.path; var pathSize = path.length; if (pathSize && (this.scheme != 'file' || pathSize != 1 || !isWindowsDriveLetter(path[0], true))) { path.length--; } }, // https://url.spec.whatwg.org/#concept-url-serializer serialize: function () { var url = this; var scheme = url.scheme; var username = url.username; var password = url.password; var host = url.host; var port = url.port; var path = url.path; var query = url.query; var fragment = url.fragment; var output = scheme + ':'; if (host !== null) { output += '//'; if (url.includesCredentials()) { output += username + (password ? ':' + password : '') + '@'; } output += serializeHost(host); if (port !== null) output += ':' + port; } else if (scheme == 'file') output += '//'; output += url.cannotBeABaseURL ? path[0] : path.length ? '/' + join(path, '/') : ''; if (query !== null) output += '?' + query; if (fragment !== null) output += '#' + fragment; return output; }, // https://url.spec.whatwg.org/#dom-url-href setHref: function (href) { var failure = this.parse(href); if (failure) throw TypeError(failure); this.searchParams.update(); }, // https://url.spec.whatwg.org/#dom-url-origin getOrigin: function () { var scheme = this.scheme; var port = this.port; if (scheme == 'blob') try { return new URLConstructor(scheme.path[0]).origin; } catch (error) { return 'null'; } if (scheme == 'file' || !this.isSpecial()) return 'null'; return scheme + '://' + serializeHost(this.host) + (port !== null ? ':' + port : ''); }, // https://url.spec.whatwg.org/#dom-url-protocol getProtocol: function () { return this.scheme + ':'; }, setProtocol: function (protocol) { this.parse($toString(protocol) + ':', SCHEME_START); }, // https://url.spec.whatwg.org/#dom-url-username getUsername: function () { return this.username; }, setUsername: function (username) { var codePoints = arrayFrom($toString(username)); if (this.cannotHaveUsernamePasswordPort()) return; this.username = ''; for (var i = 0; i < codePoints.length; i++) { this.username += percentEncode(codePoints[i], userinfoPercentEncodeSet); } }, // https://url.spec.whatwg.org/#dom-url-password getPassword: function () { return this.password; }, setPassword: function (password) { var codePoints = arrayFrom($toString(password)); if (this.cannotHaveUsernamePasswordPort()) return; this.password = ''; for (var i = 0; i < codePoints.length; i++) { this.password += percentEncode(codePoints[i], userinfoPercentEncodeSet); } }, // https://url.spec.whatwg.org/#dom-url-host getHost: function () { var host = this.host; var port = this.port; return host === null ? '' : port === null ? serializeHost(host) : serializeHost(host) + ':' + port; }, setHost: function (host) { if (this.cannotBeABaseURL) return; this.parse(host, HOST); }, // https://url.spec.whatwg.org/#dom-url-hostname getHostname: function () { var host = this.host; return host === null ? '' : serializeHost(host); }, setHostname: function (hostname) { if (this.cannotBeABaseURL) return; this.parse(hostname, HOSTNAME); }, // https://url.spec.whatwg.org/#dom-url-port getPort: function () { var port = this.port; return port === null ? '' : $toString(port); }, setPort: function (port) { if (this.cannotHaveUsernamePasswordPort()) return; port = $toString(port); if (port == '') this.port = null; else this.parse(port, PORT); }, // https://url.spec.whatwg.org/#dom-url-pathname getPathname: function () { var path = this.path; return this.cannotBeABaseURL ? path[0] : path.length ? '/' + join(path, '/') : ''; }, setPathname: function (pathname) { if (this.cannotBeABaseURL) return; this.path = []; this.parse(pathname, PATH_START); }, // https://url.spec.whatwg.org/#dom-url-search getSearch: function () { var query = this.query; return query ? '?' + query : ''; }, setSearch: function (search) { search = $toString(search); if (search == '') { this.query = null; } else { if ('?' == charAt(search, 0)) search = stringSlice(search, 1); this.query = ''; this.parse(search, QUERY); } this.searchParams.update(); }, // https://url.spec.whatwg.org/#dom-url-searchparams getSearchParams: function () { return this.searchParams.facade; }, // https://url.spec.whatwg.org/#dom-url-hash getHash: function () { var fragment = this.fragment; return fragment ? '#' + fragment : ''; }, setHash: function (hash) { hash = $toString(hash); if (hash == '') { this.fragment = null; return; } if ('#' == charAt(hash, 0)) hash = stringSlice(hash, 1); this.fragment = ''; this.parse(hash, FRAGMENT); }, update: function () { this.query = this.searchParams.serialize() || null; } }; // `URL` constructor // https://url.spec.whatwg.org/#url-class var URLConstructor = function URL(url /* , base */) { var that = anInstance(this, URLPrototype); var base = validateArgumentsLength(arguments.length, 1) > 1 ? arguments[1] : undefined; var state = setInternalState(that, new URLState(url, false, base)); if (!DESCRIPTORS) { that.href = state.serialize(); that.origin = state.getOrigin(); that.protocol = state.getProtocol(); that.username = state.getUsername(); that.password = state.getPassword(); that.host = state.getHost(); that.hostname = state.getHostname(); that.port = state.getPort(); that.pathname = state.getPathname(); that.search = state.getSearch(); that.searchParams = state.getSearchParams(); that.hash = state.getHash(); } }; var URLPrototype = URLConstructor.prototype; var accessorDescriptor = function (getter, setter) { return { get: function () { return getInternalURLState(this)[getter](); }, set: setter && function (value) { return getInternalURLState(this)[setter](value); }, configurable: true, enumerable: true }; }; if (DESCRIPTORS) { // `URL.prototype.href` accessors pair // https://url.spec.whatwg.org/#dom-url-href defineBuiltInAccessor(URLPrototype, 'href', accessorDescriptor('serialize', 'setHref')); // `URL.prototype.origin` getter // https://url.spec.whatwg.org/#dom-url-origin defineBuiltInAccessor(URLPrototype, 'origin', accessorDescriptor('getOrigin')); // `URL.prototype.protocol` accessors pair // https://url.spec.whatwg.org/#dom-url-protocol defineBuiltInAccessor(URLPrototype, 'protocol', accessorDescriptor('getProtocol', 'setProtocol')); // `URL.prototype.username` accessors pair // https://url.spec.whatwg.org/#dom-url-username defineBuiltInAccessor(URLPrototype, 'username', accessorDescriptor('getUsername', 'setUsername')); // `URL.prototype.password` accessors pair // https://url.spec.whatwg.org/#dom-url-password defineBuiltInAccessor(URLPrototype, 'password', accessorDescriptor('getPassword', 'setPassword')); // `URL.prototype.host` accessors pair // https://url.spec.whatwg.org/#dom-url-host defineBuiltInAccessor(URLPrototype, 'host', accessorDescriptor('getHost', 'setHost')); // `URL.prototype.hostname` accessors pair // https://url.spec.whatwg.org/#dom-url-hostname defineBuiltInAccessor(URLPrototype, 'hostname', accessorDescriptor('getHostname', 'setHostname')); // `URL.prototype.port` accessors pair // https://url.spec.whatwg.org/#dom-url-port defineBuiltInAccessor(URLPrototype, 'port', accessorDescriptor('getPort', 'setPort')); // `URL.prototype.pathname` accessors pair // https://url.spec.whatwg.org/#dom-url-pathname defineBuiltInAccessor(URLPrototype, 'pathname', accessorDescriptor('getPathname', 'setPathname')); // `URL.prototype.search` accessors pair // https://url.spec.whatwg.org/#dom-url-search defineBuiltInAccessor(URLPrototype, 'search', accessorDescriptor('getSearch', 'setSearch')); // `URL.prototype.searchParams` getter // https://url.spec.whatwg.org/#dom-url-searchparams defineBuiltInAccessor(URLPrototype, 'searchParams', accessorDescriptor('getSearchParams')); // `URL.prototype.hash` accessors pair // https://url.spec.whatwg.org/#dom-url-hash defineBuiltInAccessor(URLPrototype, 'hash', accessorDescriptor('getHash', 'setHash')); } // `URL.prototype.toJSON` method // https://url.spec.whatwg.org/#dom-url-tojson defineBuiltIn(URLPrototype, 'toJSON', function toJSON() { return getInternalURLState(this).serialize(); }, { enumerable: true }); // `URL.prototype.toString` method // https://url.spec.whatwg.org/#URL-stringification-behavior defineBuiltIn(URLPrototype, 'toString', function toString() { return getInternalURLState(this).serialize(); }, { enumerable: true }); if (NativeURL) { var nativeCreateObjectURL = NativeURL.createObjectURL; var nativeRevokeObjectURL = NativeURL.revokeObjectURL; // `URL.createObjectURL` method // https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL if (nativeCreateObjectURL) defineBuiltIn(URLConstructor, 'createObjectURL', bind(nativeCreateObjectURL, NativeURL)); // `URL.revokeObjectURL` method // https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL if (nativeRevokeObjectURL) defineBuiltIn(URLConstructor, 'revokeObjectURL', bind(nativeRevokeObjectURL, NativeURL)); } setToStringTag(URLConstructor, 'URL'); $({ global: true, constructor: true, forced: !USE_NATIVE_URL, sham: !DESCRIPTORS }, { URL: URLConstructor });