[6a3a178] | 1 | 'use strict';
|
---|
| 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 $toString = require('../internals/to-string');
|
---|
| 17 | var setToStringTag = require('../internals/set-to-string-tag');
|
---|
| 18 | var URLSearchParamsModule = require('../modules/web.url-search-params');
|
---|
| 19 | var InternalStateModule = require('../internals/internal-state');
|
---|
| 20 |
|
---|
| 21 | var NativeURL = global.URL;
|
---|
| 22 | var URLSearchParams = URLSearchParamsModule.URLSearchParams;
|
---|
| 23 | var getInternalSearchParamsState = URLSearchParamsModule.getState;
|
---|
| 24 | var setInternalState = InternalStateModule.set;
|
---|
| 25 | var getInternalURLState = InternalStateModule.getterFor('URL');
|
---|
| 26 | var floor = Math.floor;
|
---|
| 27 | var pow = Math.pow;
|
---|
| 28 |
|
---|
| 29 | var INVALID_AUTHORITY = 'Invalid authority';
|
---|
| 30 | var INVALID_SCHEME = 'Invalid scheme';
|
---|
| 31 | var INVALID_HOST = 'Invalid host';
|
---|
| 32 | var INVALID_PORT = 'Invalid port';
|
---|
| 33 |
|
---|
| 34 | var ALPHA = /[A-Za-z]/;
|
---|
| 35 | // eslint-disable-next-line regexp/no-obscure-range -- safe
|
---|
| 36 | var ALPHANUMERIC = /[\d+-.A-Za-z]/;
|
---|
| 37 | var DIGIT = /\d/;
|
---|
| 38 | var HEX_START = /^0x/i;
|
---|
| 39 | var OCT = /^[0-7]+$/;
|
---|
| 40 | var DEC = /^\d+$/;
|
---|
| 41 | var HEX = /^[\dA-Fa-f]+$/;
|
---|
| 42 | /* eslint-disable no-control-regex -- safe */
|
---|
| 43 | var FORBIDDEN_HOST_CODE_POINT = /[\0\t\n\r #%/:<>?@[\\\]^|]/;
|
---|
| 44 | var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\0\t\n\r #/:<>?@[\\\]^|]/;
|
---|
| 45 | var LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\u0000-\u0020]+|[\u0000-\u0020]+$/g;
|
---|
| 46 | var TAB_AND_NEW_LINE = /[\t\n\r]/g;
|
---|
| 47 | /* eslint-enable no-control-regex -- safe */
|
---|
| 48 | var EOF;
|
---|
| 49 |
|
---|
| 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;
|
---|
| 56 | url.host = result;
|
---|
| 57 | // opaque host
|
---|
| 58 | } else if (!isSpecial(url)) {
|
---|
| 59 | if (FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT.test(input)) return INVALID_HOST;
|
---|
| 60 | result = '';
|
---|
| 61 | codePoints = arrayFrom(input);
|
---|
| 62 | for (index = 0; index < codePoints.length; index++) {
|
---|
| 63 | result += percentEncode(codePoints[index], C0ControlPercentEncodeSet);
|
---|
| 64 | }
|
---|
| 65 | url.host = result;
|
---|
| 66 | } else {
|
---|
| 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;
|
---|
| 71 | url.host = result;
|
---|
| 72 | }
|
---|
| 73 | };
|
---|
| 74 |
|
---|
| 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] == '') {
|
---|
| 79 | parts.pop();
|
---|
| 80 | }
|
---|
| 81 | partsLength = parts.length;
|
---|
| 82 | if (partsLength > 4) return input;
|
---|
| 83 | numbers = [];
|
---|
| 84 | for (index = 0; index < partsLength; index++) {
|
---|
| 85 | part = parts[index];
|
---|
| 86 | if (part == '') return input;
|
---|
| 87 | radix = 10;
|
---|
| 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);
|
---|
| 91 | }
|
---|
| 92 | if (part === '') {
|
---|
| 93 | number = 0;
|
---|
| 94 | } else {
|
---|
| 95 | if (!(radix == 10 ? DEC : radix == 8 ? OCT : HEX).test(part)) return input;
|
---|
| 96 | number = parseInt(part, radix);
|
---|
| 97 | }
|
---|
| 98 | numbers.push(number);
|
---|
| 99 | }
|
---|
| 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;
|
---|
| 105 | }
|
---|
| 106 | ipv4 = numbers.pop();
|
---|
| 107 | for (index = 0; index < numbers.length; index++) {
|
---|
| 108 | ipv4 += numbers[index] * pow(256, 3 - index);
|
---|
| 109 | }
|
---|
| 110 | return ipv4;
|
---|
| 111 | };
|
---|
| 112 |
|
---|
| 113 | // eslint-disable-next-line max-statements -- TODO
|
---|
| 114 | var parseIPv6 = function (input) {
|
---|
| 115 | var address = [0, 0, 0, 0, 0, 0, 0, 0];
|
---|
| 116 | var pieceIndex = 0;
|
---|
| 117 | var compress = null;
|
---|
| 118 | var pointer = 0;
|
---|
| 119 | var value, length, numbersSeen, ipv4Piece, number, swaps, swap;
|
---|
| 120 |
|
---|
| 121 | var char = function () {
|
---|
| 122 | return input.charAt(pointer);
|
---|
| 123 | };
|
---|
| 124 |
|
---|
| 125 | if (char() == ':') {
|
---|
| 126 | if (input.charAt(1) != ':') return;
|
---|
| 127 | pointer += 2;
|
---|
| 128 | pieceIndex++;
|
---|
| 129 | compress = pieceIndex;
|
---|
| 130 | }
|
---|
| 131 | while (char()) {
|
---|
| 132 | if (pieceIndex == 8) return;
|
---|
| 133 | if (char() == ':') {
|
---|
| 134 | if (compress !== null) return;
|
---|
| 135 | pointer++;
|
---|
| 136 | pieceIndex++;
|
---|
| 137 | compress = pieceIndex;
|
---|
| 138 | continue;
|
---|
| 139 | }
|
---|
| 140 | value = length = 0;
|
---|
| 141 | while (length < 4 && HEX.test(char())) {
|
---|
| 142 | value = value * 16 + parseInt(char(), 16);
|
---|
| 143 | pointer++;
|
---|
| 144 | length++;
|
---|
| 145 | }
|
---|
| 146 | if (char() == '.') {
|
---|
| 147 | if (length == 0) return;
|
---|
| 148 | pointer -= length;
|
---|
| 149 | if (pieceIndex > 6) return;
|
---|
| 150 | numbersSeen = 0;
|
---|
| 151 | while (char()) {
|
---|
| 152 | ipv4Piece = null;
|
---|
| 153 | if (numbersSeen > 0) {
|
---|
| 154 | if (char() == '.' && numbersSeen < 4) pointer++;
|
---|
| 155 | else return;
|
---|
| 156 | }
|
---|
| 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;
|
---|
| 164 | pointer++;
|
---|
| 165 | }
|
---|
| 166 | address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece;
|
---|
| 167 | numbersSeen++;
|
---|
| 168 | if (numbersSeen == 2 || numbersSeen == 4) pieceIndex++;
|
---|
| 169 | }
|
---|
| 170 | if (numbersSeen != 4) return;
|
---|
| 171 | break;
|
---|
| 172 | } else if (char() == ':') {
|
---|
| 173 | pointer++;
|
---|
| 174 | if (!char()) return;
|
---|
| 175 | } else if (char()) return;
|
---|
| 176 | address[pieceIndex++] = value;
|
---|
| 177 | }
|
---|
| 178 | if (compress !== null) {
|
---|
| 179 | swaps = pieceIndex - compress;
|
---|
| 180 | pieceIndex = 7;
|
---|
| 181 | while (pieceIndex != 0 && swaps > 0) {
|
---|
| 182 | swap = address[pieceIndex];
|
---|
| 183 | address[pieceIndex--] = address[compress + swaps - 1];
|
---|
| 184 | address[compress + --swaps] = swap;
|
---|
| 185 | }
|
---|
| 186 | } else if (pieceIndex != 8) return;
|
---|
| 187 | return address;
|
---|
| 188 | };
|
---|
| 189 |
|
---|
| 190 | var findLongestZeroSequence = function (ipv6) {
|
---|
| 191 | var maxIndex = null;
|
---|
| 192 | var maxLength = 1;
|
---|
| 193 | var currStart = null;
|
---|
| 194 | var currLength = 0;
|
---|
| 195 | var index = 0;
|
---|
| 196 | for (; index < 8; index++) {
|
---|
| 197 | if (ipv6[index] !== 0) {
|
---|
| 198 | if (currLength > maxLength) {
|
---|
| 199 | maxIndex = currStart;
|
---|
| 200 | maxLength = currLength;
|
---|
| 201 | }
|
---|
| 202 | currStart = null;
|
---|
| 203 | currLength = 0;
|
---|
| 204 | } else {
|
---|
| 205 | if (currStart === null) currStart = index;
|
---|
| 206 | ++currLength;
|
---|
| 207 | }
|
---|
| 208 | }
|
---|
| 209 | if (currLength > maxLength) {
|
---|
| 210 | maxIndex = currStart;
|
---|
| 211 | maxLength = currLength;
|
---|
| 212 | }
|
---|
| 213 | return maxIndex;
|
---|
| 214 | };
|
---|
| 215 |
|
---|
| 216 | var serializeHost = function (host) {
|
---|
| 217 | var result, index, compress, ignore0;
|
---|
| 218 | // ipv4
|
---|
| 219 | if (typeof host == 'number') {
|
---|
| 220 | result = [];
|
---|
| 221 | for (index = 0; index < 4; index++) {
|
---|
| 222 | result.unshift(host % 256);
|
---|
| 223 | host = floor(host / 256);
|
---|
| 224 | } return result.join('.');
|
---|
| 225 | // ipv6
|
---|
| 226 | } else if (typeof host == 'object') {
|
---|
| 227 | result = '';
|
---|
| 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 ? ':' : '::';
|
---|
| 234 | ignore0 = true;
|
---|
| 235 | } else {
|
---|
| 236 | result += host[index].toString(16);
|
---|
| 237 | if (index < 7) result += ':';
|
---|
| 238 | }
|
---|
| 239 | }
|
---|
| 240 | return '[' + result + ']';
|
---|
| 241 | } return host;
|
---|
| 242 | };
|
---|
| 243 |
|
---|
| 244 | var C0ControlPercentEncodeSet = {};
|
---|
| 245 | var fragmentPercentEncodeSet = assign({}, C0ControlPercentEncodeSet, {
|
---|
| 246 | ' ': 1, '"': 1, '<': 1, '>': 1, '`': 1
|
---|
| 247 | });
|
---|
| 248 | var pathPercentEncodeSet = assign({}, fragmentPercentEncodeSet, {
|
---|
| 249 | '#': 1, '?': 1, '{': 1, '}': 1
|
---|
| 250 | });
|
---|
| 251 | var userinfoPercentEncodeSet = assign({}, pathPercentEncodeSet, {
|
---|
| 252 | '/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\': 1, ']': 1, '^': 1, '|': 1
|
---|
| 253 | });
|
---|
| 254 |
|
---|
| 255 | var percentEncode = function (char, set) {
|
---|
| 256 | var code = codeAt(char, 0);
|
---|
| 257 | return code > 0x20 && code < 0x7F && !has(set, char) ? char : encodeURIComponent(char);
|
---|
| 258 | };
|
---|
| 259 |
|
---|
| 260 | var specialSchemes = {
|
---|
| 261 | ftp: 21,
|
---|
| 262 | file: null,
|
---|
| 263 | http: 80,
|
---|
| 264 | https: 443,
|
---|
| 265 | ws: 80,
|
---|
| 266 | wss: 443
|
---|
| 267 | };
|
---|
| 268 |
|
---|
| 269 | var isSpecial = function (url) {
|
---|
| 270 | return has(specialSchemes, url.scheme);
|
---|
| 271 | };
|
---|
| 272 |
|
---|
| 273 | var includesCredentials = function (url) {
|
---|
| 274 | return url.username != '' || url.password != '';
|
---|
| 275 | };
|
---|
| 276 |
|
---|
| 277 | var cannotHaveUsernamePasswordPort = function (url) {
|
---|
| 278 | return !url.host || url.cannotBeABaseURL || url.scheme == 'file';
|
---|
| 279 | };
|
---|
| 280 |
|
---|
| 281 | var isWindowsDriveLetter = function (string, normalized) {
|
---|
| 282 | var second;
|
---|
| 283 | return string.length == 2 && ALPHA.test(string.charAt(0))
|
---|
| 284 | && ((second = string.charAt(1)) == ':' || (!normalized && second == '|'));
|
---|
| 285 | };
|
---|
| 286 |
|
---|
| 287 | var startsWithWindowsDriveLetter = function (string) {
|
---|
| 288 | var third;
|
---|
| 289 | return string.length > 1 && isWindowsDriveLetter(string.slice(0, 2)) && (
|
---|
| 290 | string.length == 2 ||
|
---|
| 291 | ((third = string.charAt(2)) === '/' || third === '\\' || third === '?' || third === '#')
|
---|
| 292 | );
|
---|
| 293 | };
|
---|
| 294 |
|
---|
| 295 | var shortenURLsPath = function (url) {
|
---|
| 296 | var path = url.path;
|
---|
| 297 | var pathSize = path.length;
|
---|
| 298 | if (pathSize && (url.scheme != 'file' || pathSize != 1 || !isWindowsDriveLetter(path[0], true))) {
|
---|
| 299 | path.pop();
|
---|
| 300 | }
|
---|
| 301 | };
|
---|
| 302 |
|
---|
| 303 | var isSingleDot = function (segment) {
|
---|
| 304 | return segment === '.' || segment.toLowerCase() === '%2e';
|
---|
| 305 | };
|
---|
| 306 |
|
---|
| 307 | var isDoubleDot = function (segment) {
|
---|
| 308 | segment = segment.toLowerCase();
|
---|
| 309 | return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e';
|
---|
| 310 | };
|
---|
| 311 |
|
---|
| 312 | // States:
|
---|
| 313 | var SCHEME_START = {};
|
---|
| 314 | var SCHEME = {};
|
---|
| 315 | var NO_SCHEME = {};
|
---|
| 316 | var SPECIAL_RELATIVE_OR_AUTHORITY = {};
|
---|
| 317 | var PATH_OR_AUTHORITY = {};
|
---|
| 318 | var RELATIVE = {};
|
---|
| 319 | var RELATIVE_SLASH = {};
|
---|
| 320 | var SPECIAL_AUTHORITY_SLASHES = {};
|
---|
| 321 | var SPECIAL_AUTHORITY_IGNORE_SLASHES = {};
|
---|
| 322 | var AUTHORITY = {};
|
---|
| 323 | var HOST = {};
|
---|
| 324 | var HOSTNAME = {};
|
---|
| 325 | var PORT = {};
|
---|
| 326 | var FILE = {};
|
---|
| 327 | var FILE_SLASH = {};
|
---|
| 328 | var FILE_HOST = {};
|
---|
| 329 | var PATH_START = {};
|
---|
| 330 | var PATH = {};
|
---|
| 331 | var CANNOT_BE_A_BASE_URL_PATH = {};
|
---|
| 332 | var QUERY = {};
|
---|
| 333 | var FRAGMENT = {};
|
---|
| 334 |
|
---|
| 335 | // eslint-disable-next-line max-statements -- TODO
|
---|
| 336 | var parseURL = function (url, input, stateOverride, base) {
|
---|
| 337 | var state = stateOverride || SCHEME_START;
|
---|
| 338 | var pointer = 0;
|
---|
| 339 | var buffer = '';
|
---|
| 340 | var seenAt = false;
|
---|
| 341 | var seenBracket = false;
|
---|
| 342 | var seenPasswordToken = false;
|
---|
| 343 | var codePoints, char, bufferCodePoints, failure;
|
---|
| 344 |
|
---|
| 345 | if (!stateOverride) {
|
---|
| 346 | url.scheme = '';
|
---|
| 347 | url.username = '';
|
---|
| 348 | url.password = '';
|
---|
| 349 | url.host = null;
|
---|
| 350 | url.port = null;
|
---|
| 351 | url.path = [];
|
---|
| 352 | url.query = null;
|
---|
| 353 | url.fragment = null;
|
---|
| 354 | url.cannotBeABaseURL = false;
|
---|
| 355 | input = input.replace(LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, '');
|
---|
| 356 | }
|
---|
| 357 |
|
---|
| 358 | input = input.replace(TAB_AND_NEW_LINE, '');
|
---|
| 359 |
|
---|
| 360 | codePoints = arrayFrom(input);
|
---|
| 361 |
|
---|
| 362 | while (pointer <= codePoints.length) {
|
---|
| 363 | char = codePoints[pointer];
|
---|
| 364 | switch (state) {
|
---|
| 365 | case SCHEME_START:
|
---|
| 366 | if (char && ALPHA.test(char)) {
|
---|
| 367 | buffer += char.toLowerCase();
|
---|
| 368 | state = SCHEME;
|
---|
| 369 | } else if (!stateOverride) {
|
---|
| 370 | state = NO_SCHEME;
|
---|
| 371 | continue;
|
---|
| 372 | } else return INVALID_SCHEME;
|
---|
| 373 | break;
|
---|
| 374 |
|
---|
| 375 | case 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)
|
---|
| 383 | )) return;
|
---|
| 384 | url.scheme = buffer;
|
---|
| 385 | if (stateOverride) {
|
---|
| 386 | if (isSpecial(url) && specialSchemes[url.scheme] == url.port) url.port = null;
|
---|
| 387 | return;
|
---|
| 388 | }
|
---|
| 389 | buffer = '';
|
---|
| 390 | if (url.scheme == 'file') {
|
---|
| 391 | state = 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;
|
---|
| 398 | pointer++;
|
---|
| 399 | } else {
|
---|
| 400 | url.cannotBeABaseURL = true;
|
---|
| 401 | url.path.push('');
|
---|
| 402 | state = CANNOT_BE_A_BASE_URL_PATH;
|
---|
| 403 | }
|
---|
| 404 | } else if (!stateOverride) {
|
---|
| 405 | buffer = '';
|
---|
| 406 | state = NO_SCHEME;
|
---|
| 407 | pointer = 0;
|
---|
| 408 | continue;
|
---|
| 409 | } else return INVALID_SCHEME;
|
---|
| 410 | break;
|
---|
| 411 |
|
---|
| 412 | case NO_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;
|
---|
| 418 | url.fragment = '';
|
---|
| 419 | url.cannotBeABaseURL = true;
|
---|
| 420 | state = FRAGMENT;
|
---|
| 421 | break;
|
---|
| 422 | }
|
---|
| 423 | state = base.scheme == 'file' ? FILE : RELATIVE;
|
---|
| 424 | continue;
|
---|
| 425 |
|
---|
| 426 | case SPECIAL_RELATIVE_OR_AUTHORITY:
|
---|
| 427 | if (char == '/' && codePoints[pointer + 1] == '/') {
|
---|
| 428 | state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
|
---|
| 429 | pointer++;
|
---|
| 430 | } else {
|
---|
| 431 | state = RELATIVE;
|
---|
| 432 | continue;
|
---|
| 433 | } break;
|
---|
| 434 |
|
---|
| 435 | case PATH_OR_AUTHORITY:
|
---|
| 436 | if (char == '/') {
|
---|
| 437 | state = AUTHORITY;
|
---|
| 438 | break;
|
---|
| 439 | } else {
|
---|
| 440 | state = PATH;
|
---|
| 441 | continue;
|
---|
| 442 | }
|
---|
| 443 |
|
---|
| 444 | case RELATIVE:
|
---|
| 445 | url.scheme = base.scheme;
|
---|
| 446 | if (char == EOF) {
|
---|
| 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();
|
---|
| 461 | url.query = '';
|
---|
| 462 | state = QUERY;
|
---|
| 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;
|
---|
| 470 | url.fragment = '';
|
---|
| 471 | state = FRAGMENT;
|
---|
| 472 | } else {
|
---|
| 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();
|
---|
| 478 | url.path.pop();
|
---|
| 479 | state = PATH;
|
---|
| 480 | continue;
|
---|
| 481 | } break;
|
---|
| 482 |
|
---|
| 483 | case RELATIVE_SLASH:
|
---|
| 484 | if (isSpecial(url) && (char == '/' || char == '\\')) {
|
---|
| 485 | state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
|
---|
| 486 | } else if (char == '/') {
|
---|
| 487 | state = AUTHORITY;
|
---|
| 488 | } else {
|
---|
| 489 | url.username = base.username;
|
---|
| 490 | url.password = base.password;
|
---|
| 491 | url.host = base.host;
|
---|
| 492 | url.port = base.port;
|
---|
| 493 | state = PATH;
|
---|
| 494 | continue;
|
---|
| 495 | } break;
|
---|
| 496 |
|
---|
| 497 | case SPECIAL_AUTHORITY_SLASHES:
|
---|
| 498 | state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
|
---|
| 499 | if (char != '/' || buffer.charAt(pointer + 1) != '/') continue;
|
---|
| 500 | pointer++;
|
---|
| 501 | break;
|
---|
| 502 |
|
---|
| 503 | case SPECIAL_AUTHORITY_IGNORE_SLASHES:
|
---|
| 504 | if (char != '/' && char != '\\') {
|
---|
| 505 | state = AUTHORITY;
|
---|
| 506 | continue;
|
---|
| 507 | } break;
|
---|
| 508 |
|
---|
| 509 | case AUTHORITY:
|
---|
| 510 | if (char == '@') {
|
---|
| 511 | if (seenAt) buffer = '%40' + buffer;
|
---|
| 512 | seenAt = true;
|
---|
| 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;
|
---|
| 518 | continue;
|
---|
| 519 | }
|
---|
| 520 | var encodedCodePoints = percentEncode(codePoint, userinfoPercentEncodeSet);
|
---|
| 521 | if (seenPasswordToken) url.password += encodedCodePoints;
|
---|
| 522 | else url.username += encodedCodePoints;
|
---|
| 523 | }
|
---|
| 524 | buffer = '';
|
---|
| 525 | } else if (
|
---|
| 526 | char == EOF || char == '/' || char == '?' || char == '#' ||
|
---|
| 527 | (char == '\\' && isSpecial(url))
|
---|
| 528 | ) {
|
---|
| 529 | if (seenAt && buffer == '') return INVALID_AUTHORITY;
|
---|
| 530 | pointer -= arrayFrom(buffer).length + 1;
|
---|
| 531 | buffer = '';
|
---|
| 532 | state = HOST;
|
---|
| 533 | } else buffer += char;
|
---|
| 534 | break;
|
---|
| 535 |
|
---|
| 536 | case HOST:
|
---|
| 537 | case HOSTNAME:
|
---|
| 538 | if (stateOverride && url.scheme == 'file') {
|
---|
| 539 | state = FILE_HOST;
|
---|
| 540 | continue;
|
---|
| 541 | } else if (char == ':' && !seenBracket) {
|
---|
| 542 | if (buffer == '') return INVALID_HOST;
|
---|
| 543 | failure = parseHost(url, buffer);
|
---|
| 544 | if (failure) return failure;
|
---|
| 545 | buffer = '';
|
---|
| 546 | state = PORT;
|
---|
| 547 | if (stateOverride == HOSTNAME) return;
|
---|
| 548 | } else if (
|
---|
| 549 | char == EOF || char == '/' || char == '?' || char == '#' ||
|
---|
| 550 | (char == '\\' && isSpecial(url))
|
---|
| 551 | ) {
|
---|
| 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;
|
---|
| 556 | buffer = '';
|
---|
| 557 | state = PATH_START;
|
---|
| 558 | if (stateOverride) return;
|
---|
| 559 | continue;
|
---|
| 560 | } else {
|
---|
| 561 | if (char == '[') seenBracket = true;
|
---|
| 562 | else if (char == ']') seenBracket = false;
|
---|
| 563 | buffer += char;
|
---|
| 564 | } break;
|
---|
| 565 |
|
---|
| 566 | case PORT:
|
---|
| 567 | if (DIGIT.test(char)) {
|
---|
| 568 | buffer += char;
|
---|
| 569 | } else if (
|
---|
| 570 | char == EOF || char == '/' || char == '?' || char == '#' ||
|
---|
| 571 | (char == '\\' && isSpecial(url)) ||
|
---|
| 572 | stateOverride
|
---|
| 573 | ) {
|
---|
| 574 | if (buffer != '') {
|
---|
| 575 | var port = parseInt(buffer, 10);
|
---|
| 576 | if (port > 0xFFFF) return INVALID_PORT;
|
---|
| 577 | url.port = (isSpecial(url) && port === specialSchemes[url.scheme]) ? null : port;
|
---|
| 578 | buffer = '';
|
---|
| 579 | }
|
---|
| 580 | if (stateOverride) return;
|
---|
| 581 | state = PATH_START;
|
---|
| 582 | continue;
|
---|
| 583 | } else return INVALID_PORT;
|
---|
| 584 | break;
|
---|
| 585 |
|
---|
| 586 | case FILE:
|
---|
| 587 | url.scheme = 'file';
|
---|
| 588 | if (char == '/' || char == '\\') state = FILE_SLASH;
|
---|
| 589 | else if (base && base.scheme == 'file') {
|
---|
| 590 | if (char == EOF) {
|
---|
| 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();
|
---|
| 597 | url.query = '';
|
---|
| 598 | state = QUERY;
|
---|
| 599 | } else if (char == '#') {
|
---|
| 600 | url.host = base.host;
|
---|
| 601 | url.path = base.path.slice();
|
---|
| 602 | url.query = base.query;
|
---|
| 603 | url.fragment = '';
|
---|
| 604 | state = FRAGMENT;
|
---|
| 605 | } else {
|
---|
| 606 | if (!startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {
|
---|
| 607 | url.host = base.host;
|
---|
| 608 | url.path = base.path.slice();
|
---|
| 609 | shortenURLsPath(url);
|
---|
| 610 | }
|
---|
| 611 | state = PATH;
|
---|
| 612 | continue;
|
---|
| 613 | }
|
---|
| 614 | } else {
|
---|
| 615 | state = PATH;
|
---|
| 616 | continue;
|
---|
| 617 | } break;
|
---|
| 618 |
|
---|
| 619 | case FILE_SLASH:
|
---|
| 620 | if (char == '/' || char == '\\') {
|
---|
| 621 | state = FILE_HOST;
|
---|
| 622 | break;
|
---|
| 623 | }
|
---|
| 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;
|
---|
| 627 | }
|
---|
| 628 | state = PATH;
|
---|
| 629 | continue;
|
---|
| 630 |
|
---|
| 631 | case FILE_HOST:
|
---|
| 632 | if (char == EOF || char == '/' || char == '\\' || char == '?' || char == '#') {
|
---|
| 633 | if (!stateOverride && isWindowsDriveLetter(buffer)) {
|
---|
| 634 | state = PATH;
|
---|
| 635 | } else if (buffer == '') {
|
---|
| 636 | url.host = '';
|
---|
| 637 | if (stateOverride) return;
|
---|
| 638 | state = PATH_START;
|
---|
| 639 | } else {
|
---|
| 640 | failure = parseHost(url, buffer);
|
---|
| 641 | if (failure) return failure;
|
---|
| 642 | if (url.host == 'localhost') url.host = '';
|
---|
| 643 | if (stateOverride) return;
|
---|
| 644 | buffer = '';
|
---|
| 645 | state = PATH_START;
|
---|
| 646 | } continue;
|
---|
| 647 | } else buffer += char;
|
---|
| 648 | break;
|
---|
| 649 |
|
---|
| 650 | case PATH_START:
|
---|
| 651 | if (isSpecial(url)) {
|
---|
| 652 | state = PATH;
|
---|
| 653 | if (char != '/' && char != '\\') continue;
|
---|
| 654 | } else if (!stateOverride && char == '?') {
|
---|
| 655 | url.query = '';
|
---|
| 656 | state = QUERY;
|
---|
| 657 | } else if (!stateOverride && char == '#') {
|
---|
| 658 | url.fragment = '';
|
---|
| 659 | state = FRAGMENT;
|
---|
| 660 | } else if (char != EOF) {
|
---|
| 661 | state = PATH;
|
---|
| 662 | if (char != '/') continue;
|
---|
| 663 | } break;
|
---|
| 664 |
|
---|
| 665 | case PATH:
|
---|
| 666 | if (
|
---|
| 667 | char == EOF || char == '/' ||
|
---|
| 668 | (char == '\\' && isSpecial(url)) ||
|
---|
| 669 | (!stateOverride && (char == '?' || char == '#'))
|
---|
| 670 | ) {
|
---|
| 671 | if (isDoubleDot(buffer)) {
|
---|
| 672 | shortenURLsPath(url);
|
---|
| 673 | if (char != '/' && !(char == '\\' && isSpecial(url))) {
|
---|
| 674 | url.path.push('');
|
---|
| 675 | }
|
---|
| 676 | } else if (isSingleDot(buffer)) {
|
---|
| 677 | if (char != '/' && !(char == '\\' && isSpecial(url))) {
|
---|
| 678 | url.path.push('');
|
---|
| 679 | }
|
---|
| 680 | } else {
|
---|
| 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
|
---|
| 684 | }
|
---|
| 685 | url.path.push(buffer);
|
---|
| 686 | }
|
---|
| 687 | buffer = '';
|
---|
| 688 | if (url.scheme == 'file' && (char == EOF || char == '?' || char == '#')) {
|
---|
| 689 | while (url.path.length > 1 && url.path[0] === '') {
|
---|
| 690 | url.path.shift();
|
---|
| 691 | }
|
---|
| 692 | }
|
---|
| 693 | if (char == '?') {
|
---|
| 694 | url.query = '';
|
---|
| 695 | state = QUERY;
|
---|
| 696 | } else if (char == '#') {
|
---|
| 697 | url.fragment = '';
|
---|
| 698 | state = FRAGMENT;
|
---|
| 699 | }
|
---|
| 700 | } else {
|
---|
| 701 | buffer += percentEncode(char, pathPercentEncodeSet);
|
---|
| 702 | } break;
|
---|
| 703 |
|
---|
| 704 | case CANNOT_BE_A_BASE_URL_PATH:
|
---|
| 705 | if (char == '?') {
|
---|
| 706 | url.query = '';
|
---|
| 707 | state = QUERY;
|
---|
| 708 | } else if (char == '#') {
|
---|
| 709 | url.fragment = '';
|
---|
| 710 | state = FRAGMENT;
|
---|
| 711 | } else if (char != EOF) {
|
---|
| 712 | url.path[0] += percentEncode(char, C0ControlPercentEncodeSet);
|
---|
| 713 | } break;
|
---|
| 714 |
|
---|
| 715 | case QUERY:
|
---|
| 716 | if (!stateOverride && char == '#') {
|
---|
| 717 | url.fragment = '';
|
---|
| 718 | state = FRAGMENT;
|
---|
| 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);
|
---|
| 723 | } break;
|
---|
| 724 |
|
---|
| 725 | case FRAGMENT:
|
---|
| 726 | if (char != EOF) url.fragment += percentEncode(char, fragmentPercentEncodeSet);
|
---|
| 727 | break;
|
---|
| 728 | }
|
---|
| 729 |
|
---|
| 730 | pointer++;
|
---|
| 731 | }
|
---|
| 732 | };
|
---|
| 733 |
|
---|
| 734 | // `URL` constructor
|
---|
| 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 = $toString(url);
|
---|
| 740 | var state = setInternalState(that, { type: 'URL' });
|
---|
| 741 | var baseState, failure;
|
---|
| 742 | if (base !== undefined) {
|
---|
| 743 | if (base instanceof URLConstructor) baseState = getInternalURLState(base);
|
---|
| 744 | else {
|
---|
| 745 | failure = parseURL(baseState = {}, $toString(base));
|
---|
| 746 | if (failure) throw TypeError(failure);
|
---|
| 747 | }
|
---|
| 748 | }
|
---|
| 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;
|
---|
| 756 | };
|
---|
| 757 | if (!DESCRIPTORS) {
|
---|
| 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);
|
---|
| 770 | }
|
---|
| 771 | };
|
---|
| 772 |
|
---|
| 773 | var URLPrototype = URLConstructor.prototype;
|
---|
| 774 |
|
---|
| 775 | var serializeURL = function () {
|
---|
| 776 | var url = getInternalURLState(this);
|
---|
| 777 | var scheme = url.scheme;
|
---|
| 778 | var username = url.username;
|
---|
| 779 | var password = url.password;
|
---|
| 780 | var host = url.host;
|
---|
| 781 | var port = url.port;
|
---|
| 782 | var path = url.path;
|
---|
| 783 | var query = url.query;
|
---|
| 784 | var fragment = url.fragment;
|
---|
| 785 | var output = scheme + ':';
|
---|
| 786 | if (host !== null) {
|
---|
| 787 | output += '//';
|
---|
| 788 | if (includesCredentials(url)) {
|
---|
| 789 | output += username + (password ? ':' + password : '') + '@';
|
---|
| 790 | }
|
---|
| 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;
|
---|
| 797 | return output;
|
---|
| 798 | };
|
---|
| 799 |
|
---|
| 800 | var getOrigin = function () {
|
---|
| 801 | var url = getInternalURLState(this);
|
---|
| 802 | var scheme = url.scheme;
|
---|
| 803 | var port = url.port;
|
---|
| 804 | if (scheme == 'blob') try {
|
---|
| 805 | return new URLConstructor(scheme.path[0]).origin;
|
---|
| 806 | } catch (error) {
|
---|
| 807 | return 'null';
|
---|
| 808 | }
|
---|
| 809 | if (scheme == 'file' || !isSpecial(url)) return 'null';
|
---|
| 810 | return scheme + '://' + serializeHost(url.host) + (port !== null ? ':' + port : '');
|
---|
| 811 | };
|
---|
| 812 |
|
---|
| 813 | var getProtocol = function () {
|
---|
| 814 | return getInternalURLState(this).scheme + ':';
|
---|
| 815 | };
|
---|
| 816 |
|
---|
| 817 | var getUsername = function () {
|
---|
| 818 | return getInternalURLState(this).username;
|
---|
| 819 | };
|
---|
| 820 |
|
---|
| 821 | var getPassword = function () {
|
---|
| 822 | return getInternalURLState(this).password;
|
---|
| 823 | };
|
---|
| 824 |
|
---|
| 825 | var getHost = function () {
|
---|
| 826 | var url = getInternalURLState(this);
|
---|
| 827 | var host = url.host;
|
---|
| 828 | var port = url.port;
|
---|
| 829 | return host === null ? ''
|
---|
| 830 | : port === null ? serializeHost(host)
|
---|
| 831 | : serializeHost(host) + ':' + port;
|
---|
| 832 | };
|
---|
| 833 |
|
---|
| 834 | var getHostname = function () {
|
---|
| 835 | var host = getInternalURLState(this).host;
|
---|
| 836 | return host === null ? '' : serializeHost(host);
|
---|
| 837 | };
|
---|
| 838 |
|
---|
| 839 | var getPort = function () {
|
---|
| 840 | var port = getInternalURLState(this).port;
|
---|
| 841 | return port === null ? '' : String(port);
|
---|
| 842 | };
|
---|
| 843 |
|
---|
| 844 | var getPathname = function () {
|
---|
| 845 | var url = getInternalURLState(this);
|
---|
| 846 | var path = url.path;
|
---|
| 847 | return url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';
|
---|
| 848 | };
|
---|
| 849 |
|
---|
| 850 | var getSearch = function () {
|
---|
| 851 | var query = getInternalURLState(this).query;
|
---|
| 852 | return query ? '?' + query : '';
|
---|
| 853 | };
|
---|
| 854 |
|
---|
| 855 | var getSearchParams = function () {
|
---|
| 856 | return getInternalURLState(this).searchParams;
|
---|
| 857 | };
|
---|
| 858 |
|
---|
| 859 | var getHash = function () {
|
---|
| 860 | var fragment = getInternalURLState(this).fragment;
|
---|
| 861 | return fragment ? '#' + fragment : '';
|
---|
| 862 | };
|
---|
| 863 |
|
---|
| 864 | var accessorDescriptor = function (getter, setter) {
|
---|
| 865 | return { get: getter, set: setter, configurable: true, enumerable: true };
|
---|
| 866 | };
|
---|
| 867 |
|
---|
| 868 | if (DESCRIPTORS) {
|
---|
| 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 = $toString(href);
|
---|
| 875 | var failure = parseURL(url, urlString);
|
---|
| 876 | if (failure) throw TypeError(failure);
|
---|
| 877 | getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
|
---|
| 878 | }),
|
---|
| 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, $toString(protocol) + ':', SCHEME_START);
|
---|
| 887 | }),
|
---|
| 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($toString(username));
|
---|
| 893 | if (cannotHaveUsernamePasswordPort(url)) return;
|
---|
| 894 | url.username = '';
|
---|
| 895 | for (var i = 0; i < codePoints.length; i++) {
|
---|
| 896 | url.username += percentEncode(codePoints[i], userinfoPercentEncodeSet);
|
---|
| 897 | }
|
---|
| 898 | }),
|
---|
| 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($toString(password));
|
---|
| 904 | if (cannotHaveUsernamePasswordPort(url)) return;
|
---|
| 905 | url.password = '';
|
---|
| 906 | for (var i = 0; i < codePoints.length; i++) {
|
---|
| 907 | url.password += percentEncode(codePoints[i], userinfoPercentEncodeSet);
|
---|
| 908 | }
|
---|
| 909 | }),
|
---|
| 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, $toString(host), HOST);
|
---|
| 916 | }),
|
---|
| 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, $toString(hostname), HOSTNAME);
|
---|
| 923 | }),
|
---|
| 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;
|
---|
| 929 | port = $toString(port);
|
---|
| 930 | if (port == '') url.port = null;
|
---|
| 931 | else parseURL(url, port, PORT);
|
---|
| 932 | }),
|
---|
| 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;
|
---|
| 938 | url.path = [];
|
---|
| 939 | parseURL(url, $toString(pathname), PATH_START);
|
---|
| 940 | }),
|
---|
| 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 = $toString(search);
|
---|
| 946 | if (search == '') {
|
---|
| 947 | url.query = null;
|
---|
| 948 | } else {
|
---|
| 949 | if ('?' == search.charAt(0)) search = search.slice(1);
|
---|
| 950 | url.query = '';
|
---|
| 951 | parseURL(url, search, QUERY);
|
---|
| 952 | }
|
---|
| 953 | getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
|
---|
| 954 | }),
|
---|
| 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);
|
---|
| 962 | hash = $toString(hash);
|
---|
| 963 | if (hash == '') {
|
---|
| 964 | url.fragment = null;
|
---|
| 965 | return;
|
---|
| 966 | }
|
---|
| 967 | if ('#' == hash.charAt(0)) hash = hash.slice(1);
|
---|
| 968 | url.fragment = '';
|
---|
| 969 | parseURL(url, hash, FRAGMENT);
|
---|
| 970 | })
|
---|
| 971 | });
|
---|
| 972 | }
|
---|
| 973 |
|
---|
| 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 });
|
---|
| 979 |
|
---|
| 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 });
|
---|
| 985 |
|
---|
| 986 | if (NativeURL) {
|
---|
| 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 -- required for `.length`
|
---|
| 992 | if (nativeCreateObjectURL) redefine(URLConstructor, 'createObjectURL', function createObjectURL(blob) {
|
---|
| 993 | return nativeCreateObjectURL.apply(NativeURL, arguments);
|
---|
| 994 | });
|
---|
| 995 | // `URL.revokeObjectURL` method
|
---|
| 996 | // https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
|
---|
| 997 | // eslint-disable-next-line no-unused-vars -- required for `.length`
|
---|
| 998 | if (nativeRevokeObjectURL) redefine(URLConstructor, 'revokeObjectURL', function revokeObjectURL(url) {
|
---|
| 999 | return nativeRevokeObjectURL.apply(NativeURL, arguments);
|
---|
| 1000 | });
|
---|
| 1001 | }
|
---|
| 1002 |
|
---|
| 1003 | setToStringTag(URLConstructor, 'URL');
|
---|
| 1004 |
|
---|
| 1005 | $({ global: true, forced: !USE_NATIVE_URL, sham: !DESCRIPTORS }, {
|
---|
| 1006 | URL: URLConstructor
|
---|
| 1007 | });
|
---|