2 // TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env`
3 require('../modules/es.string.iterator');
4 var $ = require('../internals/export');
5 var DESCRIPTORS = require('../internals/descriptors');
6 var USE_NATIVE_URL = require('../internals/native-url');
7 var global = require('../internals/global');
8 var defineProperties = require('../internals/object-define-properties');
9 var redefine = require('../internals/redefine');
10 var anInstance = require('../internals/an-instance');
11 var has = require('../internals/has');
12 var assign = require('../internals/object-assign');
13 var arrayFrom = require('../internals/array-from');
14 var codeAt = require('../internals/string-multibyte').codeAt;
15 var toASCII = require('../internals/string-punycode-to-ascii');
16 var setToStringTag = require('../internals/set-to-string-tag');
17 var URLSearchParamsModule = require('../modules/web.url-search-params');
18 var InternalStateModule = require('../internals/internal-state');
20 var NativeURL = global.URL;
21 var URLSearchParams = URLSearchParamsModule.URLSearchParams;
22 var getInternalSearchParamsState = URLSearchParamsModule.getState;
23 var setInternalState = InternalStateModule.set;
24 var getInternalURLState = InternalStateModule.getterFor('URL');
25 var floor = Math.floor;
28 var INVALID_AUTHORITY = 'Invalid authority';
29 var INVALID_SCHEME = 'Invalid scheme';
30 var INVALID_HOST = 'Invalid host';
31 var INVALID_PORT = 'Invalid port';
33 var ALPHA = /[A-Za-z]/;
34 var ALPHANUMERIC = /[\d+-.A-Za-z]/;
36 var HEX_START = /^(0x|0X)/;
39 var HEX = /^[\dA-Fa-f]+$/;
40 // eslint-disable-next-line no-control-regex
41 var FORBIDDEN_HOST_CODE_POINT = /[\u0000\u0009\u000A\u000D #%/:?@[\\]]/;
42 // eslint-disable-next-line no-control-regex
43 var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\u0000\u0009\u000A\u000D #/:?@[\\]]/;
44 // eslint-disable-next-line no-control-regex
45 var LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\u0000-\u001F ]+|[\u0000-\u001F ]+$/g;
46 // eslint-disable-next-line no-control-regex
47 var TAB_AND_NEW_LINE = /[\u0009\u000A\u000D]/g;
50 var parseHost = function (url, input) {
51 var result, codePoints, index;
52 if (input.charAt(0) == '[') {
53 if (input.charAt(input.length - 1) != ']') return INVALID_HOST;
54 result = parseIPv6(input.slice(1, -1));
55 if (!result) return INVALID_HOST;
58 } else if (!isSpecial(url)) {
59 if (FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT.test(input)) return INVALID_HOST;
61 codePoints = arrayFrom(input);
62 for (index = 0; index < codePoints.length; index++) {
63 result += percentEncode(codePoints[index], C0ControlPercentEncodeSet);
67 input = toASCII(input);
68 if (FORBIDDEN_HOST_CODE_POINT.test(input)) return INVALID_HOST;
69 result = parseIPv4(input);
70 if (result === null) return INVALID_HOST;
75 var parseIPv4 = function (input) {
76 var parts = input.split('.');
77 var partsLength, numbers, index, part, radix, number, ipv4;
78 if (parts.length && parts[parts.length - 1] == '') {
81 partsLength = parts.length;
82 if (partsLength > 4) return input;
84 for (index = 0; index < partsLength; index++) {
86 if (part == '') return input;
88 if (part.length > 1 && part.charAt(0) == '0') {
89 radix = HEX_START.test(part) ? 16 : 8;
90 part = part.slice(radix == 8 ? 1 : 2);
95 if (!(radix == 10 ? DEC : radix == 8 ? OCT : HEX).test(part)) return input;
96 number = parseInt(part, radix);
100 for (index = 0; index < partsLength; index++) {
101 number = numbers[index];
102 if (index == partsLength - 1) {
103 if (number >= pow(256, 5 - partsLength)) return null;
104 } else if (number > 255) return null;
106 ipv4 = numbers.pop();
107 for (index = 0; index < numbers.length; index++) {
108 ipv4 += numbers[index] * pow(256, 3 - index);
113 // eslint-disable-next-line max-statements
114 var parseIPv6 = function (input) {
115 var address = [0, 0, 0, 0, 0, 0, 0, 0];
119 var value, length, numbersSeen, ipv4Piece, number, swaps, swap;
121 var char = function () {
122 return input.charAt(pointer);
126 if (input.charAt(1) != ':') return;
129 compress = pieceIndex;
132 if (pieceIndex == 8) return;
134 if (compress !== null) return;
137 compress = pieceIndex;
141 while (length < 4 && HEX.test(char())) {
142 value = value * 16 + parseInt(char(), 16);
147 if (length == 0) return;
149 if (pieceIndex > 6) return;
153 if (numbersSeen > 0) {
154 if (char() == '.' && numbersSeen < 4) pointer++;
157 if (!DIGIT.test(char())) return;
158 while (DIGIT.test(char())) {
159 number = parseInt(char(), 10);
160 if (ipv4Piece === null) ipv4Piece = number;
161 else if (ipv4Piece == 0) return;
162 else ipv4Piece = ipv4Piece * 10 + number;
163 if (ipv4Piece > 255) return;
166 address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece;
168 if (numbersSeen == 2 || numbersSeen == 4) pieceIndex++;
170 if (numbersSeen != 4) return;
172 } else if (char() == ':') {
175 } else if (char()) return;
176 address[pieceIndex++] = value;
178 if (compress !== null) {
179 swaps = pieceIndex - compress;
181 while (pieceIndex != 0 && swaps > 0) {
182 swap = address[pieceIndex];
183 address[pieceIndex--] = address[compress + swaps - 1];
184 address[compress + --swaps] = swap;
186 } else if (pieceIndex != 8) return;
190 var findLongestZeroSequence = function (ipv6) {
193 var currStart = null;
196 for (; index < 8; index++) {
197 if (ipv6[index] !== 0) {
198 if (currLength > maxLength) {
199 maxIndex = currStart;
200 maxLength = currLength;
205 if (currStart === null) currStart = index;
209 if (currLength > maxLength) {
210 maxIndex = currStart;
211 maxLength = currLength;
216 var serializeHost = function (host) {
217 var result, index, compress, ignore0;
219 if (typeof host == 'number') {
221 for (index = 0; index < 4; index++) {
222 result.unshift(host % 256);
223 host = floor(host / 256);
224 } return result.join('.');
226 } else if (typeof host == 'object') {
228 compress = findLongestZeroSequence(host);
229 for (index = 0; index < 8; index++) {
230 if (ignore0 && host[index] === 0) continue;
231 if (ignore0) ignore0 = false;
232 if (compress === index) {
233 result += index ? ':' : '::';
236 result += host[index].toString(16);
237 if (index < 7) result += ':';
240 return '[' + result + ']';
244 var C0ControlPercentEncodeSet = {};
245 var fragmentPercentEncodeSet = assign({}, C0ControlPercentEncodeSet, {
246 ' ': 1, '"': 1, '<': 1, '>': 1, '`': 1
248 var pathPercentEncodeSet = assign({}, fragmentPercentEncodeSet, {
249 '#': 1, '?': 1, '{': 1, '}': 1
251 var userinfoPercentEncodeSet = assign({}, pathPercentEncodeSet, {
252 '/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\': 1, ']': 1, '^': 1, '|': 1
255 var percentEncode = function (char, set) {
256 var code = codeAt(char, 0);
257 return code > 0x20 && code < 0x7F && !has(set, char) ? char : encodeURIComponent(char);
260 var specialSchemes = {
269 var isSpecial = function (url) {
270 return has(specialSchemes, url.scheme);
273 var includesCredentials = function (url) {
274 return url.username != '' || url.password != '';
277 var cannotHaveUsernamePasswordPort = function (url) {
278 return !url.host || url.cannotBeABaseURL || url.scheme == 'file';
281 var isWindowsDriveLetter = function (string, normalized) {
283 return string.length == 2 && ALPHA.test(string.charAt(0))
284 && ((second = string.charAt(1)) == ':' || (!normalized && second == '|'));
287 var startsWithWindowsDriveLetter = function (string) {
289 return string.length > 1 && isWindowsDriveLetter(string.slice(0, 2)) && (
290 string.length == 2 ||
291 ((third = string.charAt(2)) === '/' || third === '\\' || third === '?' || third === '#')
295 var shortenURLsPath = function (url) {
297 var pathSize = path.length;
298 if (pathSize && (url.scheme != 'file' || pathSize != 1 || !isWindowsDriveLetter(path[0], true))) {
303 var isSingleDot = function (segment) {
304 return segment === '.' || segment.toLowerCase() === '%2e';
307 var isDoubleDot = function (segment) {
308 segment = segment.toLowerCase();
309 return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e';
313 var SCHEME_START = {};
316 var SPECIAL_RELATIVE_OR_AUTHORITY = {};
317 var PATH_OR_AUTHORITY = {};
319 var RELATIVE_SLASH = {};
320 var SPECIAL_AUTHORITY_SLASHES = {};
321 var SPECIAL_AUTHORITY_IGNORE_SLASHES = {};
331 var CANNOT_BE_A_BASE_URL_PATH = {};
335 // eslint-disable-next-line max-statements
336 var parseURL = function (url, input, stateOverride, base) {
337 var state = stateOverride || SCHEME_START;
341 var seenBracket = false;
342 var seenPasswordToken = false;
343 var codePoints, char, bufferCodePoints, failure;
345 if (!stateOverride) {
354 url.cannotBeABaseURL = false;
355 input = input.replace(LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, '');
358 input = input.replace(TAB_AND_NEW_LINE, '');
360 codePoints = arrayFrom(input);
362 while (pointer <= codePoints.length) {
363 char = codePoints[pointer];
366 if (char && ALPHA.test(char)) {
367 buffer += char.toLowerCase();
369 } else if (!stateOverride) {
372 } else return INVALID_SCHEME;
376 if (char && (ALPHANUMERIC.test(char) || char == '+' || char == '-' || char == '.')) {
377 buffer += char.toLowerCase();
378 } else if (char == ':') {
379 if (stateOverride && (
380 (isSpecial(url) != has(specialSchemes, buffer)) ||
381 (buffer == 'file' && (includesCredentials(url) || url.port !== null)) ||
382 (url.scheme == 'file' && !url.host)
386 if (isSpecial(url) && specialSchemes[url.scheme] == url.port) url.port = null;
390 if (url.scheme == 'file') {
392 } else if (isSpecial(url) && base && base.scheme == url.scheme) {
393 state = SPECIAL_RELATIVE_OR_AUTHORITY;
394 } else if (isSpecial(url)) {
395 state = SPECIAL_AUTHORITY_SLASHES;
396 } else if (codePoints[pointer + 1] == '/') {
397 state = PATH_OR_AUTHORITY;
400 url.cannotBeABaseURL = true;
402 state = CANNOT_BE_A_BASE_URL_PATH;
404 } else if (!stateOverride) {
409 } else return INVALID_SCHEME;
413 if (!base || (base.cannotBeABaseURL && char != '#')) return INVALID_SCHEME;
414 if (base.cannotBeABaseURL && char == '#') {
415 url.scheme = base.scheme;
416 url.path = base.path.slice();
417 url.query = base.query;
419 url.cannotBeABaseURL = true;
423 state = base.scheme == 'file' ? FILE : RELATIVE;
426 case SPECIAL_RELATIVE_OR_AUTHORITY:
427 if (char == '/' && codePoints[pointer + 1] == '/') {
428 state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
435 case PATH_OR_AUTHORITY:
445 url.scheme = base.scheme;
447 url.username = base.username;
448 url.password = base.password;
449 url.host = base.host;
450 url.port = base.port;
451 url.path = base.path.slice();
452 url.query = base.query;
453 } else if (char == '/' || (char == '\\' && isSpecial(url))) {
454 state = RELATIVE_SLASH;
455 } else if (char == '?') {
456 url.username = base.username;
457 url.password = base.password;
458 url.host = base.host;
459 url.port = base.port;
460 url.path = base.path.slice();
463 } else if (char == '#') {
464 url.username = base.username;
465 url.password = base.password;
466 url.host = base.host;
467 url.port = base.port;
468 url.path = base.path.slice();
469 url.query = base.query;
473 url.username = base.username;
474 url.password = base.password;
475 url.host = base.host;
476 url.port = base.port;
477 url.path = base.path.slice();
484 if (isSpecial(url) && (char == '/' || char == '\\')) {
485 state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
486 } else if (char == '/') {
489 url.username = base.username;
490 url.password = base.password;
491 url.host = base.host;
492 url.port = base.port;
497 case SPECIAL_AUTHORITY_SLASHES:
498 state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
499 if (char != '/' || buffer.charAt(pointer + 1) != '/') continue;
503 case SPECIAL_AUTHORITY_IGNORE_SLASHES:
504 if (char != '/' && char != '\\') {
511 if (seenAt) buffer = '%40' + buffer;
513 bufferCodePoints = arrayFrom(buffer);
514 for (var i = 0; i < bufferCodePoints.length; i++) {
515 var codePoint = bufferCodePoints[i];
516 if (codePoint == ':' && !seenPasswordToken) {
517 seenPasswordToken = true;
520 var encodedCodePoints = percentEncode(codePoint, userinfoPercentEncodeSet);
521 if (seenPasswordToken) url.password += encodedCodePoints;
522 else url.username += encodedCodePoints;
526 char == EOF || char == '/' || char == '?' || char == '#' ||
527 (char == '\\' && isSpecial(url))
529 if (seenAt && buffer == '') return INVALID_AUTHORITY;
530 pointer -= arrayFrom(buffer).length + 1;
533 } else buffer += char;
538 if (stateOverride && url.scheme == 'file') {
541 } else if (char == ':' && !seenBracket) {
542 if (buffer == '') return INVALID_HOST;
543 failure = parseHost(url, buffer);
544 if (failure) return failure;
547 if (stateOverride == HOSTNAME) return;
549 char == EOF || char == '/' || char == '?' || char == '#' ||
550 (char == '\\' && isSpecial(url))
552 if (isSpecial(url) && buffer == '') return INVALID_HOST;
553 if (stateOverride && buffer == '' && (includesCredentials(url) || url.port !== null)) return;
554 failure = parseHost(url, buffer);
555 if (failure) return failure;
558 if (stateOverride) return;
561 if (char == '[') seenBracket = true;
562 else if (char == ']') seenBracket = false;
567 if (DIGIT.test(char)) {
570 char == EOF || char == '/' || char == '?' || char == '#' ||
571 (char == '\\' && isSpecial(url)) ||
575 var port = parseInt(buffer, 10);
576 if (port > 0xFFFF) return INVALID_PORT;
577 url.port = (isSpecial(url) && port === specialSchemes[url.scheme]) ? null : port;
580 if (stateOverride) return;
583 } else return INVALID_PORT;
588 if (char == '/' || char == '\\') state = FILE_SLASH;
589 else if (base && base.scheme == 'file') {
591 url.host = base.host;
592 url.path = base.path.slice();
593 url.query = base.query;
594 } else if (char == '?') {
595 url.host = base.host;
596 url.path = base.path.slice();
599 } else if (char == '#') {
600 url.host = base.host;
601 url.path = base.path.slice();
602 url.query = base.query;
606 if (!startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {
607 url.host = base.host;
608 url.path = base.path.slice();
609 shortenURLsPath(url);
620 if (char == '/' || char == '\\') {
624 if (base && base.scheme == 'file' && !startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {
625 if (isWindowsDriveLetter(base.path[0], true)) url.path.push(base.path[0]);
626 else url.host = base.host;
632 if (char == EOF || char == '/' || char == '\\' || char == '?' || char == '#') {
633 if (!stateOverride && isWindowsDriveLetter(buffer)) {
635 } else if (buffer == '') {
637 if (stateOverride) return;
640 failure = parseHost(url, buffer);
641 if (failure) return failure;
642 if (url.host == 'localhost') url.host = '';
643 if (stateOverride) return;
647 } else buffer += char;
651 if (isSpecial(url)) {
653 if (char != '/' && char != '\\') continue;
654 } else if (!stateOverride && char == '?') {
657 } else if (!stateOverride && char == '#') {
660 } else if (char != EOF) {
662 if (char != '/') continue;
667 char == EOF || char == '/' ||
668 (char == '\\' && isSpecial(url)) ||
669 (!stateOverride && (char == '?' || char == '#'))
671 if (isDoubleDot(buffer)) {
672 shortenURLsPath(url);
673 if (char != '/' && !(char == '\\' && isSpecial(url))) {
676 } else if (isSingleDot(buffer)) {
677 if (char != '/' && !(char == '\\' && isSpecial(url))) {
681 if (url.scheme == 'file' && !url.path.length && isWindowsDriveLetter(buffer)) {
682 if (url.host) url.host = '';
683 buffer = buffer.charAt(0) + ':'; // normalize windows drive letter
685 url.path.push(buffer);
688 if (url.scheme == 'file' && (char == EOF || char == '?' || char == '#')) {
689 while (url.path.length > 1 && url.path[0] === '') {
696 } else if (char == '#') {
701 buffer += percentEncode(char, pathPercentEncodeSet);
704 case CANNOT_BE_A_BASE_URL_PATH:
708 } else if (char == '#') {
711 } else if (char != EOF) {
712 url.path[0] += percentEncode(char, C0ControlPercentEncodeSet);
716 if (!stateOverride && char == '#') {
719 } else if (char != EOF) {
720 if (char == "'" && isSpecial(url)) url.query += '%27';
721 else if (char == '#') url.query += '%23';
722 else url.query += percentEncode(char, C0ControlPercentEncodeSet);
726 if (char != EOF) url.fragment += percentEncode(char, fragmentPercentEncodeSet);
735 // https://url.spec.whatwg.org/#url-class
736 var URLConstructor = function URL(url /* , base */) {
737 var that = anInstance(this, URLConstructor, 'URL');
738 var base = arguments.length > 1 ? arguments[1] : undefined;
739 var urlString = String(url);
740 var state = setInternalState(that, { type: 'URL' });
741 var baseState, failure;
742 if (base !== undefined) {
743 if (base instanceof URLConstructor) baseState = getInternalURLState(base);
745 failure = parseURL(baseState = {}, String(base));
746 if (failure) throw TypeError(failure);
749 failure = parseURL(state, urlString, null, baseState);
750 if (failure) throw TypeError(failure);
751 var searchParams = state.searchParams = new URLSearchParams();
752 var searchParamsState = getInternalSearchParamsState(searchParams);
753 searchParamsState.updateSearchParams(state.query);
754 searchParamsState.updateURL = function () {
755 state.query = String(searchParams) || null;
758 that.href = serializeURL.call(that);
759 that.origin = getOrigin.call(that);
760 that.protocol = getProtocol.call(that);
761 that.username = getUsername.call(that);
762 that.password = getPassword.call(that);
763 that.host = getHost.call(that);
764 that.hostname = getHostname.call(that);
765 that.port = getPort.call(that);
766 that.pathname = getPathname.call(that);
767 that.search = getSearch.call(that);
768 that.searchParams = getSearchParams.call(that);
769 that.hash = getHash.call(that);
773 var URLPrototype = URLConstructor.prototype;
775 var serializeURL = function () {
776 var url = getInternalURLState(this);
777 var scheme = url.scheme;
778 var username = url.username;
779 var password = url.password;
783 var query = url.query;
784 var fragment = url.fragment;
785 var output = scheme + ':';
788 if (includesCredentials(url)) {
789 output += username + (password ? ':' + password : '') + '@';
791 output += serializeHost(host);
792 if (port !== null) output += ':' + port;
793 } else if (scheme == 'file') output += '//';
794 output += url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';
795 if (query !== null) output += '?' + query;
796 if (fragment !== null) output += '#' + fragment;
800 var getOrigin = function () {
801 var url = getInternalURLState(this);
802 var scheme = url.scheme;
804 if (scheme == 'blob') try {
805 return new URL(scheme.path[0]).origin;
809 if (scheme == 'file' || !isSpecial(url)) return 'null';
810 return scheme + '://' + serializeHost(url.host) + (port !== null ? ':' + port : '');
813 var getProtocol = function () {
814 return getInternalURLState(this).scheme + ':';
817 var getUsername = function () {
818 return getInternalURLState(this).username;
821 var getPassword = function () {
822 return getInternalURLState(this).password;
825 var getHost = function () {
826 var url = getInternalURLState(this);
829 return host === null ? ''
830 : port === null ? serializeHost(host)
831 : serializeHost(host) + ':' + port;
834 var getHostname = function () {
835 var host = getInternalURLState(this).host;
836 return host === null ? '' : serializeHost(host);
839 var getPort = function () {
840 var port = getInternalURLState(this).port;
841 return port === null ? '' : String(port);
844 var getPathname = function () {
845 var url = getInternalURLState(this);
847 return url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';
850 var getSearch = function () {
851 var query = getInternalURLState(this).query;
852 return query ? '?' + query : '';
855 var getSearchParams = function () {
856 return getInternalURLState(this).searchParams;
859 var getHash = function () {
860 var fragment = getInternalURLState(this).fragment;
861 return fragment ? '#' + fragment : '';
864 var accessorDescriptor = function (getter, setter) {
865 return { get: getter, set: setter, configurable: true, enumerable: true };
869 defineProperties(URLPrototype, {
870 // `URL.prototype.href` accessors pair
871 // https://url.spec.whatwg.org/#dom-url-href
872 href: accessorDescriptor(serializeURL, function (href) {
873 var url = getInternalURLState(this);
874 var urlString = String(href);
875 var failure = parseURL(url, urlString);
876 if (failure) throw TypeError(failure);
877 getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
879 // `URL.prototype.origin` getter
880 // https://url.spec.whatwg.org/#dom-url-origin
881 origin: accessorDescriptor(getOrigin),
882 // `URL.prototype.protocol` accessors pair
883 // https://url.spec.whatwg.org/#dom-url-protocol
884 protocol: accessorDescriptor(getProtocol, function (protocol) {
885 var url = getInternalURLState(this);
886 parseURL(url, String(protocol) + ':', SCHEME_START);
888 // `URL.prototype.username` accessors pair
889 // https://url.spec.whatwg.org/#dom-url-username
890 username: accessorDescriptor(getUsername, function (username) {
891 var url = getInternalURLState(this);
892 var codePoints = arrayFrom(String(username));
893 if (cannotHaveUsernamePasswordPort(url)) return;
895 for (var i = 0; i < codePoints.length; i++) {
896 url.username += percentEncode(codePoints[i], userinfoPercentEncodeSet);
899 // `URL.prototype.password` accessors pair
900 // https://url.spec.whatwg.org/#dom-url-password
901 password: accessorDescriptor(getPassword, function (password) {
902 var url = getInternalURLState(this);
903 var codePoints = arrayFrom(String(password));
904 if (cannotHaveUsernamePasswordPort(url)) return;
906 for (var i = 0; i < codePoints.length; i++) {
907 url.password += percentEncode(codePoints[i], userinfoPercentEncodeSet);
910 // `URL.prototype.host` accessors pair
911 // https://url.spec.whatwg.org/#dom-url-host
912 host: accessorDescriptor(getHost, function (host) {
913 var url = getInternalURLState(this);
914 if (url.cannotBeABaseURL) return;
915 parseURL(url, String(host), HOST);
917 // `URL.prototype.hostname` accessors pair
918 // https://url.spec.whatwg.org/#dom-url-hostname
919 hostname: accessorDescriptor(getHostname, function (hostname) {
920 var url = getInternalURLState(this);
921 if (url.cannotBeABaseURL) return;
922 parseURL(url, String(hostname), HOSTNAME);
924 // `URL.prototype.port` accessors pair
925 // https://url.spec.whatwg.org/#dom-url-port
926 port: accessorDescriptor(getPort, function (port) {
927 var url = getInternalURLState(this);
928 if (cannotHaveUsernamePasswordPort(url)) return;
930 if (port == '') url.port = null;
931 else parseURL(url, port, PORT);
933 // `URL.prototype.pathname` accessors pair
934 // https://url.spec.whatwg.org/#dom-url-pathname
935 pathname: accessorDescriptor(getPathname, function (pathname) {
936 var url = getInternalURLState(this);
937 if (url.cannotBeABaseURL) return;
939 parseURL(url, pathname + '', PATH_START);
941 // `URL.prototype.search` accessors pair
942 // https://url.spec.whatwg.org/#dom-url-search
943 search: accessorDescriptor(getSearch, function (search) {
944 var url = getInternalURLState(this);
945 search = String(search);
949 if ('?' == search.charAt(0)) search = search.slice(1);
951 parseURL(url, search, QUERY);
953 getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
955 // `URL.prototype.searchParams` getter
956 // https://url.spec.whatwg.org/#dom-url-searchparams
957 searchParams: accessorDescriptor(getSearchParams),
958 // `URL.prototype.hash` accessors pair
959 // https://url.spec.whatwg.org/#dom-url-hash
960 hash: accessorDescriptor(getHash, function (hash) {
961 var url = getInternalURLState(this);
967 if ('#' == hash.charAt(0)) hash = hash.slice(1);
969 parseURL(url, hash, FRAGMENT);
974 // `URL.prototype.toJSON` method
975 // https://url.spec.whatwg.org/#dom-url-tojson
976 redefine(URLPrototype, 'toJSON', function toJSON() {
977 return serializeURL.call(this);
978 }, { enumerable: true });
980 // `URL.prototype.toString` method
981 // https://url.spec.whatwg.org/#URL-stringification-behavior
982 redefine(URLPrototype, 'toString', function toString() {
983 return serializeURL.call(this);
984 }, { enumerable: true });
987 var nativeCreateObjectURL = NativeURL.createObjectURL;
988 var nativeRevokeObjectURL = NativeURL.revokeObjectURL;
989 // `URL.createObjectURL` method
990 // https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
991 // eslint-disable-next-line no-unused-vars
992 if (nativeCreateObjectURL) redefine(URLConstructor, 'createObjectURL', function createObjectURL(blob) {
993 return nativeCreateObjectURL.apply(NativeURL, arguments);
995 // `URL.revokeObjectURL` method
996 // https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
997 // eslint-disable-next-line no-unused-vars
998 if (nativeRevokeObjectURL) redefine(URLConstructor, 'revokeObjectURL', function revokeObjectURL(url) {
999 return nativeRevokeObjectURL.apply(NativeURL, arguments);
1003 setToStringTag(URLConstructor, 'URL');
1005 $({ global: true, forced: !USE_NATIVE_URL, sham: !DESCRIPTORS }, {