source: frontend/node_modules/core-js-pure/modules/web.url.constructor.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 36.1 KB
Line 
1'use strict';
2// TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env`
3require('../modules/es.string.iterator');
4var $ = require('../internals/export');
5var DESCRIPTORS = require('../internals/descriptors');
6var USE_NATIVE_URL = require('../internals/url-constructor-detection');
7var globalThis = require('../internals/global-this');
8var bind = require('../internals/function-bind-context');
9var uncurryThis = require('../internals/function-uncurry-this');
10var defineBuiltIn = require('../internals/define-built-in');
11var defineBuiltInAccessor = require('../internals/define-built-in-accessor');
12var anInstance = require('../internals/an-instance');
13var hasOwn = require('../internals/has-own-property');
14var assign = require('../internals/object-assign');
15var arrayFrom = require('../internals/array-from');
16var arraySlice = require('../internals/array-slice');
17var codeAt = require('../internals/string-multibyte').codeAt;
18var toASCII = require('../internals/string-punycode-to-ascii');
19var $toString = require('../internals/to-string');
20var setToStringTag = require('../internals/set-to-string-tag');
21var validateArgumentsLength = require('../internals/validate-arguments-length');
22var URLSearchParamsModule = require('../modules/web.url-search-params.constructor');
23var InternalStateModule = require('../internals/internal-state');
24
25var setInternalState = InternalStateModule.set;
26var getInternalURLState = InternalStateModule.getterFor('URL');
27var URLSearchParams = URLSearchParamsModule.URLSearchParams;
28var getInternalSearchParamsState = URLSearchParamsModule.getState;
29
30var NativeURL = globalThis.URL;
31var TypeError = globalThis.TypeError;
32var encodeURIComponent = globalThis.encodeURIComponent;
33var parseInt = globalThis.parseInt;
34var floor = Math.floor;
35var pow = Math.pow;
36var charAt = uncurryThis(''.charAt);
37var exec = uncurryThis(/./.exec);
38var join = uncurryThis([].join);
39var numberToString = uncurryThis(1.1.toString);
40var pop = uncurryThis([].pop);
41var push = uncurryThis([].push);
42var replace = uncurryThis(''.replace);
43var shift = uncurryThis([].shift);
44var split = uncurryThis(''.split);
45var stringSlice = uncurryThis(''.slice);
46var toLowerCase = uncurryThis(''.toLowerCase);
47var unshift = uncurryThis([].unshift);
48
49var INVALID_AUTHORITY = 'Invalid authority';
50var INVALID_SCHEME = 'Invalid scheme';
51var INVALID_HOST = 'Invalid host';
52var INVALID_PORT = 'Invalid port';
53
54var ALPHA = /[a-z]/i;
55var ALPHANUMERIC_PLUS_MINUS_DOT = /[\d+\-.a-z]/i;
56var DIGIT = /\d/;
57var HEX_START = /^0x/i;
58var OCT = /^[0-7]+$/;
59var DEC = /^\d+$/;
60var HEX = /^[\da-f]+$/i;
61/* eslint-disable regexp/no-control-character -- safe */
62var FORBIDDEN_HOST_CODE_POINT = /[\0\t\n\r #%/:<>?@[\\\]^|]/;
63var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\0\t\n\r #/:<>?@[\\\]^|]/;
64var LEADING_C0_CONTROL_OR_SPACE = /^[\u0000-\u0020]+/;
65var TRAILING_C0_CONTROL_OR_SPACE = /(^|[^\u0000-\u0020])[\u0000-\u0020]+$/;
66var TAB_AND_NEW_LINE = /[\t\n\r]/g;
67/* eslint-enable regexp/no-control-character -- safe */
68// eslint-disable-next-line no-unassigned-vars -- expected `undefined` value
69var EOF;
70
71// https://url.spec.whatwg.org/#ends-in-a-number-checker
72var endsInNumber = function (input) {
73 var parts = split(input, '.');
74 var last, hexPart;
75 if (parts[parts.length - 1] === '') {
76 if (parts.length === 1) return false;
77 parts.length--;
78 }
79 last = parts[parts.length - 1];
80 if (exec(DEC, last)) return true;
81 if (exec(HEX_START, last)) {
82 hexPart = stringSlice(last, 2);
83 return hexPart === '' || !!exec(HEX, hexPart);
84 }
85 return false;
86};
87
88// https://url.spec.whatwg.org/#concept-ipv4-parser
89var parseIPv4 = function (input) {
90 var parts = split(input, '.');
91 var partsLength, numbers, index, part, radix, number, ipv4;
92 if (parts.length && parts[parts.length - 1] === '') {
93 parts.length--;
94 }
95 partsLength = parts.length;
96 if (partsLength > 4) return null;
97 numbers = [];
98 for (index = 0; index < partsLength; index++) {
99 part = parts[index];
100 if (part === '') return null;
101 radix = 10;
102 if (part.length > 1 && charAt(part, 0) === '0') {
103 radix = exec(HEX_START, part) ? 16 : 8;
104 part = stringSlice(part, radix === 8 ? 1 : 2);
105 }
106 if (part === '') {
107 number = 0;
108 } else {
109 if (!exec(radix === 10 ? DEC : radix === 8 ? OCT : HEX, part)) return null;
110 number = parseInt(part, radix);
111 }
112 push(numbers, number);
113 }
114 for (index = 0; index < partsLength; index++) {
115 number = numbers[index];
116 if (index === partsLength - 1) {
117 if (number >= pow(256, 5 - partsLength)) return null;
118 } else if (number > 255) return null;
119 }
120 ipv4 = pop(numbers);
121 for (index = 0; index < numbers.length; index++) {
122 ipv4 += numbers[index] * pow(256, 3 - index);
123 }
124 return ipv4;
125};
126
127// https://url.spec.whatwg.org/#concept-ipv6-parser
128// eslint-disable-next-line max-statements -- TODO
129var parseIPv6 = function (input) {
130 var address = [0, 0, 0, 0, 0, 0, 0, 0];
131 var pieceIndex = 0;
132 var compress = null;
133 var pointer = 0;
134 var value, length, numbersSeen, ipv4Piece, number, swaps, swap;
135
136 var chr = function () {
137 return charAt(input, pointer);
138 };
139
140 if (chr() === ':') {
141 if (charAt(input, 1) !== ':') return;
142 pointer += 2;
143 pieceIndex++;
144 compress = pieceIndex;
145 }
146 while (chr()) {
147 if (pieceIndex === 8) return;
148 if (chr() === ':') {
149 if (compress !== null) return;
150 pointer++;
151 pieceIndex++;
152 compress = pieceIndex;
153 continue;
154 }
155 value = length = 0;
156 while (length < 4 && exec(HEX, chr())) {
157 value = value * 16 + parseInt(chr(), 16);
158 pointer++;
159 length++;
160 }
161 if (chr() === '.') {
162 if (length === 0) return;
163 pointer -= length;
164 if (pieceIndex > 6) return;
165 numbersSeen = 0;
166 while (chr()) {
167 ipv4Piece = null;
168 if (numbersSeen > 0) {
169 if (chr() === '.' && numbersSeen < 4) pointer++;
170 else return;
171 }
172 if (!exec(DIGIT, chr())) return;
173 while (exec(DIGIT, chr())) {
174 number = parseInt(chr(), 10);
175 if (ipv4Piece === null) ipv4Piece = number;
176 else if (ipv4Piece === 0) return;
177 else ipv4Piece = ipv4Piece * 10 + number;
178 if (ipv4Piece > 255) return;
179 pointer++;
180 }
181 address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece;
182 numbersSeen++;
183 if (numbersSeen === 2 || numbersSeen === 4) pieceIndex++;
184 }
185 if (numbersSeen !== 4) return;
186 break;
187 } else if (chr() === ':') {
188 pointer++;
189 if (!chr()) return;
190 } else if (chr()) return;
191 address[pieceIndex++] = value;
192 }
193 if (compress !== null) {
194 swaps = pieceIndex - compress;
195 pieceIndex = 7;
196 while (pieceIndex !== 0 && swaps > 0) {
197 swap = address[pieceIndex];
198 address[pieceIndex--] = address[compress + swaps - 1];
199 address[compress + --swaps] = swap;
200 }
201 } else if (pieceIndex !== 8) return;
202 return address;
203};
204
205var findLongestZeroSequence = function (ipv6) {
206 var maxIndex = null;
207 var maxLength = 1;
208 var currStart = null;
209 var currLength = 0;
210 var index = 0;
211 for (; index < 8; index++) {
212 if (ipv6[index] !== 0) {
213 if (currLength > maxLength) {
214 maxIndex = currStart;
215 maxLength = currLength;
216 }
217 currStart = null;
218 currLength = 0;
219 } else {
220 if (currStart === null) currStart = index;
221 ++currLength;
222 }
223 }
224 return currLength > maxLength ? currStart : maxIndex;
225};
226
227// https://url.spec.whatwg.org/#host-serializing
228var serializeHost = function (host) {
229 var result, index, compress, ignore0;
230
231 // ipv4
232 if (typeof host == 'number') {
233 result = [];
234 for (index = 0; index < 4; index++) {
235 unshift(result, host % 256);
236 host = floor(host / 256);
237 }
238 return join(result, '.');
239 }
240
241 // ipv6
242 if (typeof host == 'object') {
243 result = '';
244 compress = findLongestZeroSequence(host);
245 for (index = 0; index < 8; index++) {
246 if (ignore0 && host[index] === 0) continue;
247 if (ignore0) ignore0 = false;
248 if (compress === index) {
249 result += index ? ':' : '::';
250 ignore0 = true;
251 } else {
252 result += numberToString(host[index], 16);
253 if (index < 7) result += ':';
254 }
255 }
256 return '[' + result + ']';
257 }
258
259 return host;
260};
261
262var C0ControlPercentEncodeSet = {};
263var queryPercentEncodeSet = assign({}, C0ControlPercentEncodeSet, {
264 ' ': 1, '"': 1, '#': 1, '<': 1, '>': 1
265});
266var specialQueryPercentEncodeSet = assign({}, queryPercentEncodeSet, {
267 "'": 1
268});
269var fragmentPercentEncodeSet = assign({}, C0ControlPercentEncodeSet, {
270 ' ': 1, '"': 1, '<': 1, '>': 1, '`': 1
271});
272var pathPercentEncodeSet = assign({}, fragmentPercentEncodeSet, {
273 '#': 1, '?': 1, '{': 1, '}': 1, '^': 1
274});
275var userinfoPercentEncodeSet = assign({}, pathPercentEncodeSet, {
276 '/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\': 1, ']': 1, '^': 1, '|': 1
277});
278
279var percentEncode = function (chr, set) {
280 var code = codeAt(chr, 0);
281 // encodeURIComponent does not encode ', which is in the special-query percent-encode set
282 return code >= 0x20 && code < 0x7F && !hasOwn(set, chr) ? chr : chr === "'" && hasOwn(set, chr) ? '%27' : encodeURIComponent(chr);
283};
284
285// https://url.spec.whatwg.org/#special-scheme
286var specialSchemes = {
287 ftp: 21,
288 file: null,
289 http: 80,
290 https: 443,
291 ws: 80,
292 wss: 443
293};
294
295// https://url.spec.whatwg.org/#windows-drive-letter
296var isWindowsDriveLetter = function (string, normalized) {
297 var second;
298 return string.length === 2 && exec(ALPHA, charAt(string, 0))
299 && ((second = charAt(string, 1)) === ':' || (!normalized && second === '|'));
300};
301
302// https://url.spec.whatwg.org/#start-with-a-windows-drive-letter
303var startsWithWindowsDriveLetter = function (string) {
304 var third;
305 return string.length > 1 && isWindowsDriveLetter(stringSlice(string, 0, 2)) && (
306 string.length === 2 ||
307 ((third = charAt(string, 2)) === '/' || third === '\\' || third === '?' || third === '#')
308 );
309};
310
311// https://url.spec.whatwg.org/#single-dot-path-segment
312var isSingleDot = function (segment) {
313 return segment === '.' || toLowerCase(segment) === '%2e';
314};
315
316// https://url.spec.whatwg.org/#double-dot-path-segment
317var isDoubleDot = function (segment) {
318 segment = toLowerCase(segment);
319 return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e';
320};
321
322// States:
323var SCHEME_START = {};
324var SCHEME = {};
325var NO_SCHEME = {};
326var SPECIAL_RELATIVE_OR_AUTHORITY = {};
327var PATH_OR_AUTHORITY = {};
328var RELATIVE = {};
329var RELATIVE_SLASH = {};
330var SPECIAL_AUTHORITY_SLASHES = {};
331var SPECIAL_AUTHORITY_IGNORE_SLASHES = {};
332var AUTHORITY = {};
333var HOST = {};
334var HOSTNAME = {};
335var PORT = {};
336var FILE = {};
337var FILE_SLASH = {};
338var FILE_HOST = {};
339var PATH_START = {};
340var PATH = {};
341var CANNOT_BE_A_BASE_URL_PATH = {};
342var QUERY = {};
343var FRAGMENT = {};
344
345var URLState = function (url, isBase, base) {
346 var urlString = $toString(url);
347 var baseState, failure, searchParams;
348 if (isBase) {
349 failure = this.parse(urlString);
350 if (failure) throw new TypeError(failure);
351 this.searchParams = null;
352 } else {
353 if (base !== undefined) baseState = new URLState(base, true);
354 failure = this.parse(urlString, null, baseState);
355 if (failure) throw new TypeError(failure);
356 searchParams = getInternalSearchParamsState(new URLSearchParams());
357 searchParams.bindURL(this);
358 this.searchParams = searchParams;
359 }
360};
361
362URLState.prototype = {
363 type: 'URL',
364 // https://url.spec.whatwg.org/#url-parsing
365 // eslint-disable-next-line max-statements -- TODO
366 parse: function (input, stateOverride, base) {
367 var url = this;
368 var state = stateOverride || SCHEME_START;
369 var pointer = 0;
370 var buffer = '';
371 var seenAt = false;
372 var seenBracket = false;
373 var seenPasswordToken = false;
374 var codePoints, chr, bufferCodePoints, failure;
375
376 input = $toString(input);
377
378 if (!stateOverride) {
379 url.scheme = '';
380 url.username = '';
381 url.password = '';
382 url.host = null;
383 url.port = null;
384 url.path = [];
385 url.query = null;
386 url.fragment = null;
387 url.cannotBeABaseURL = false;
388 input = replace(input, LEADING_C0_CONTROL_OR_SPACE, '');
389 input = replace(input, TRAILING_C0_CONTROL_OR_SPACE, '$1');
390 }
391
392 input = replace(input, TAB_AND_NEW_LINE, '');
393
394 codePoints = arrayFrom(input);
395
396 while (pointer <= codePoints.length) {
397 chr = codePoints[pointer];
398 switch (state) {
399 case SCHEME_START:
400 if (chr && exec(ALPHA, chr)) {
401 buffer += toLowerCase(chr);
402 state = SCHEME;
403 } else if (!stateOverride) {
404 state = NO_SCHEME;
405 continue;
406 } else return INVALID_SCHEME;
407 break;
408
409 case SCHEME:
410 if (chr && exec(ALPHANUMERIC_PLUS_MINUS_DOT, chr)) {
411 buffer += toLowerCase(chr);
412 } else if (chr === ':') {
413 if (stateOverride && (
414 (url.isSpecial() !== hasOwn(specialSchemes, buffer)) ||
415 (buffer === 'file' && (url.includesCredentials() || url.port !== null)) ||
416 (url.scheme === 'file' && url.host === '')
417 )) return;
418 url.scheme = buffer;
419 if (stateOverride) {
420 if (url.isSpecial() && specialSchemes[url.scheme] === url.port) url.port = null;
421 return;
422 }
423 buffer = '';
424 if (url.scheme === 'file') {
425 state = FILE;
426 } else if (url.isSpecial() && base && base.scheme === url.scheme) {
427 state = SPECIAL_RELATIVE_OR_AUTHORITY;
428 } else if (url.isSpecial()) {
429 state = SPECIAL_AUTHORITY_SLASHES;
430 } else if (codePoints[pointer + 1] === '/') {
431 state = PATH_OR_AUTHORITY;
432 pointer++;
433 } else {
434 url.cannotBeABaseURL = true;
435 push(url.path, '');
436 state = CANNOT_BE_A_BASE_URL_PATH;
437 }
438 } else if (!stateOverride) {
439 buffer = '';
440 state = NO_SCHEME;
441 pointer = 0;
442 continue;
443 } else return INVALID_SCHEME;
444 break;
445
446 case NO_SCHEME:
447 if (!base || (base.cannotBeABaseURL && chr !== '#')) return INVALID_SCHEME;
448 if (base.cannotBeABaseURL && chr === '#') {
449 url.scheme = base.scheme;
450 url.path = arraySlice(base.path);
451 url.query = base.query;
452 url.fragment = '';
453 url.cannotBeABaseURL = true;
454 state = FRAGMENT;
455 break;
456 }
457 state = base.scheme === 'file' ? FILE : RELATIVE;
458 continue;
459
460 case SPECIAL_RELATIVE_OR_AUTHORITY:
461 if (chr === '/' && codePoints[pointer + 1] === '/') {
462 state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
463 pointer++;
464 } else {
465 state = RELATIVE;
466 continue;
467 } break;
468
469 case PATH_OR_AUTHORITY:
470 if (chr === '/') {
471 state = AUTHORITY;
472 break;
473 } else {
474 state = PATH;
475 continue;
476 }
477
478 case RELATIVE:
479 url.scheme = base.scheme;
480 if (chr === EOF) {
481 url.username = base.username;
482 url.password = base.password;
483 url.host = base.host;
484 url.port = base.port;
485 url.path = arraySlice(base.path);
486 url.query = base.query;
487 } else if (chr === '/' || (chr === '\\' && url.isSpecial())) {
488 state = RELATIVE_SLASH;
489 } else if (chr === '?') {
490 url.username = base.username;
491 url.password = base.password;
492 url.host = base.host;
493 url.port = base.port;
494 url.path = arraySlice(base.path);
495 url.query = '';
496 state = QUERY;
497 } else if (chr === '#') {
498 url.username = base.username;
499 url.password = base.password;
500 url.host = base.host;
501 url.port = base.port;
502 url.path = arraySlice(base.path);
503 url.query = base.query;
504 url.fragment = '';
505 state = FRAGMENT;
506 } else {
507 url.username = base.username;
508 url.password = base.password;
509 url.host = base.host;
510 url.port = base.port;
511 url.path = arraySlice(base.path);
512 if (url.path.length) url.path.length--;
513 state = PATH;
514 continue;
515 } break;
516
517 case RELATIVE_SLASH:
518 if (url.isSpecial() && (chr === '/' || chr === '\\')) {
519 state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
520 } else if (chr === '/') {
521 state = AUTHORITY;
522 } else {
523 url.username = base.username;
524 url.password = base.password;
525 url.host = base.host;
526 url.port = base.port;
527 state = PATH;
528 continue;
529 } break;
530
531 case SPECIAL_AUTHORITY_SLASHES:
532 state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
533 if (chr !== '/' || codePoints[pointer + 1] !== '/') continue;
534 pointer++;
535 break;
536
537 case SPECIAL_AUTHORITY_IGNORE_SLASHES:
538 if (chr !== '/' && chr !== '\\') {
539 state = AUTHORITY;
540 continue;
541 } break;
542
543 case AUTHORITY:
544 if (chr === '@') {
545 if (seenAt) buffer = '%40' + buffer;
546 seenAt = true;
547 bufferCodePoints = arrayFrom(buffer);
548 for (var i = 0; i < bufferCodePoints.length; i++) {
549 var codePoint = bufferCodePoints[i];
550 if (codePoint === ':' && !seenPasswordToken) {
551 seenPasswordToken = true;
552 continue;
553 }
554 var encodedCodePoints = percentEncode(codePoint, userinfoPercentEncodeSet);
555 if (seenPasswordToken) url.password += encodedCodePoints;
556 else url.username += encodedCodePoints;
557 }
558 buffer = '';
559 } else if (
560 chr === EOF || chr === '/' || chr === '?' || chr === '#' ||
561 (chr === '\\' && url.isSpecial())
562 ) {
563 if (seenAt && buffer === '') return INVALID_AUTHORITY;
564 pointer -= arrayFrom(buffer).length + 1;
565 buffer = '';
566 state = HOST;
567 } else buffer += chr;
568 break;
569
570 case HOST:
571 case HOSTNAME:
572 if (stateOverride && url.scheme === 'file') {
573 state = FILE_HOST;
574 continue;
575 } else if (chr === ':' && !seenBracket) {
576 if (buffer === '') return INVALID_HOST;
577 if (stateOverride === HOSTNAME) return;
578 failure = url.parseHost(buffer);
579 if (failure) return failure;
580 buffer = '';
581 state = PORT;
582 } else if (
583 chr === EOF || chr === '/' || chr === '?' || chr === '#' ||
584 (chr === '\\' && url.isSpecial())
585 ) {
586 if (url.isSpecial() && buffer === '') return INVALID_HOST;
587 if (stateOverride && buffer === '' && (url.includesCredentials() || url.port !== null)) return;
588 failure = url.parseHost(buffer);
589 if (failure) return failure;
590 buffer = '';
591 state = PATH_START;
592 if (stateOverride) return;
593 continue;
594 } else {
595 if (chr === '[') seenBracket = true;
596 else if (chr === ']') seenBracket = false;
597 buffer += chr;
598 } break;
599
600 case PORT:
601 if (exec(DIGIT, chr)) {
602 buffer += chr;
603 } else if (
604 chr === EOF || chr === '/' || chr === '?' || chr === '#' ||
605 (chr === '\\' && url.isSpecial()) ||
606 stateOverride
607 ) {
608 if (buffer !== '') {
609 var port = parseInt(buffer, 10);
610 if (port > 0xFFFF) return INVALID_PORT;
611 url.port = (url.isSpecial() && port === specialSchemes[url.scheme]) ? null : port;
612 buffer = '';
613 }
614 if (stateOverride) return;
615 state = PATH_START;
616 continue;
617 } else return INVALID_PORT;
618 break;
619
620 case FILE:
621 url.scheme = 'file';
622 url.host = '';
623 if (chr === '/' || chr === '\\') state = FILE_SLASH;
624 else if (base && base.scheme === 'file') {
625 switch (chr) {
626 case EOF:
627 url.host = base.host;
628 url.path = arraySlice(base.path);
629 url.query = base.query;
630 break;
631 case '?':
632 url.host = base.host;
633 url.path = arraySlice(base.path);
634 url.query = '';
635 state = QUERY;
636 break;
637 case '#':
638 url.host = base.host;
639 url.path = arraySlice(base.path);
640 url.query = base.query;
641 url.fragment = '';
642 state = FRAGMENT;
643 break;
644 default:
645 url.host = base.host;
646 if (!startsWithWindowsDriveLetter(join(arraySlice(codePoints, pointer), ''))) {
647 url.path = arraySlice(base.path);
648 url.shortenPath();
649 }
650 state = PATH;
651 continue;
652 }
653 } else {
654 state = PATH;
655 continue;
656 } break;
657
658 case FILE_SLASH:
659 if (chr === '/' || chr === '\\') {
660 state = FILE_HOST;
661 break;
662 }
663 if (base && base.scheme === 'file') {
664 url.host = base.host;
665 if (!startsWithWindowsDriveLetter(join(arraySlice(codePoints, pointer), ''))
666 && isWindowsDriveLetter(base.path[0], true)) push(url.path, base.path[0]);
667 }
668 state = PATH;
669 continue;
670
671 case FILE_HOST:
672 if (chr === EOF || chr === '/' || chr === '\\' || chr === '?' || chr === '#') {
673 if (!stateOverride && isWindowsDriveLetter(buffer)) {
674 state = PATH;
675 } else if (buffer === '') {
676 url.host = '';
677 if (stateOverride) return;
678 state = PATH_START;
679 } else {
680 failure = url.parseHost(buffer);
681 if (failure) return failure;
682 if (url.host === 'localhost') url.host = '';
683 if (stateOverride) return;
684 buffer = '';
685 state = PATH_START;
686 } continue;
687 } else buffer += chr;
688 break;
689
690 case PATH_START:
691 if (url.isSpecial()) {
692 state = PATH;
693 if (chr !== '/' && chr !== '\\') continue;
694 } else if (!stateOverride && chr === '?') {
695 url.query = '';
696 state = QUERY;
697 } else if (!stateOverride && chr === '#') {
698 url.fragment = '';
699 state = FRAGMENT;
700 } else if (chr !== EOF) {
701 state = PATH;
702 if (chr !== '/') continue;
703 } break;
704
705 case PATH:
706 if (
707 chr === EOF || chr === '/' ||
708 (chr === '\\' && url.isSpecial()) ||
709 (!stateOverride && (chr === '?' || chr === '#'))
710 ) {
711 if (isDoubleDot(buffer)) {
712 url.shortenPath();
713 if (chr !== '/' && !(chr === '\\' && url.isSpecial())) {
714 push(url.path, '');
715 }
716 } else if (isSingleDot(buffer)) {
717 if (chr !== '/' && !(chr === '\\' && url.isSpecial())) {
718 push(url.path, '');
719 }
720 } else {
721 if (url.scheme === 'file' && !url.path.length && isWindowsDriveLetter(buffer)) {
722 if (url.host !== null && url.host !== '') url.host = '';
723 buffer = charAt(buffer, 0) + ':'; // normalize windows drive letter
724 }
725 push(url.path, buffer);
726 }
727 buffer = '';
728 if (url.scheme === 'file' && (chr === EOF || chr === '?' || chr === '#')) {
729 while (url.path.length > 1 && url.path[0] === '') {
730 shift(url.path);
731 }
732 }
733 if (chr === '?') {
734 url.query = '';
735 state = QUERY;
736 } else if (chr === '#') {
737 url.fragment = '';
738 state = FRAGMENT;
739 }
740 } else {
741 buffer += percentEncode(chr, pathPercentEncodeSet);
742 } break;
743
744 case CANNOT_BE_A_BASE_URL_PATH:
745 if (chr === '?') {
746 url.query = '';
747 state = QUERY;
748 } else if (chr === '#') {
749 url.fragment = '';
750 state = FRAGMENT;
751 } else if (chr !== EOF) {
752 url.path[0] += percentEncode(chr, C0ControlPercentEncodeSet);
753 } break;
754
755 case QUERY:
756 if (!stateOverride && chr === '#') {
757 url.fragment = '';
758 state = FRAGMENT;
759 } else if (chr !== EOF) {
760 url.query += percentEncode(chr, url.isSpecial() ? specialQueryPercentEncodeSet : queryPercentEncodeSet);
761 } break;
762
763 case FRAGMENT:
764 if (chr !== EOF) url.fragment += percentEncode(chr, fragmentPercentEncodeSet);
765 break;
766 }
767
768 pointer++;
769 }
770 },
771 // https://url.spec.whatwg.org/#host-parsing
772 parseHost: function (input) {
773 var result, codePoints, index;
774 if (charAt(input, 0) === '[') {
775 if (charAt(input, input.length - 1) !== ']') return INVALID_HOST;
776 result = parseIPv6(stringSlice(input, 1, -1));
777 if (!result) return INVALID_HOST;
778 this.host = result;
779 // opaque host
780 } else if (!this.isSpecial()) {
781 if (exec(FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT, input)) return INVALID_HOST;
782 result = '';
783 codePoints = arrayFrom(input);
784 for (index = 0; index < codePoints.length; index++) {
785 result += percentEncode(codePoints[index], C0ControlPercentEncodeSet);
786 }
787 this.host = result;
788 } else {
789 input = toASCII(input);
790 if (exec(FORBIDDEN_HOST_CODE_POINT, input)) return INVALID_HOST;
791 if (endsInNumber(input)) {
792 result = parseIPv4(input);
793 if (result === null) return INVALID_HOST;
794 this.host = result;
795 } else {
796 this.host = input;
797 }
798 }
799 },
800 // https://url.spec.whatwg.org/#cannot-have-a-username-password-port
801 cannotHaveUsernamePasswordPort: function () {
802 return this.host === null || this.host === '' || this.cannotBeABaseURL || this.scheme === 'file';
803 },
804 // https://url.spec.whatwg.org/#include-credentials
805 includesCredentials: function () {
806 return this.username !== '' || this.password !== '';
807 },
808 // https://url.spec.whatwg.org/#is-special
809 isSpecial: function () {
810 return hasOwn(specialSchemes, this.scheme);
811 },
812 // https://url.spec.whatwg.org/#shorten-a-urls-path
813 shortenPath: function () {
814 var path = this.path;
815 var pathSize = path.length;
816 if (pathSize && (this.scheme !== 'file' || pathSize !== 1 || !isWindowsDriveLetter(path[0], true))) {
817 path.length--;
818 }
819 },
820 // https://url.spec.whatwg.org/#concept-url-serializer
821 serialize: function () {
822 var url = this;
823 var scheme = url.scheme;
824 var username = url.username;
825 var password = url.password;
826 var host = url.host;
827 var port = url.port;
828 var path = url.path;
829 var query = url.query;
830 var fragment = url.fragment;
831 var output = scheme + ':';
832 if (host !== null) {
833 output += '//';
834 if (url.includesCredentials()) {
835 output += username + (password ? ':' + password : '') + '@';
836 }
837 output += serializeHost(host);
838 if (port !== null) output += ':' + port;
839 } else if (scheme === 'file') output += '//';
840 if (host === null && !url.cannotBeABaseURL && path.length > 1 && path[0] === '') output += '/.';
841 output += url.cannotBeABaseURL ? path[0] : path.length ? '/' + join(path, '/') : '';
842 if (query !== null) output += '?' + query;
843 if (fragment !== null) output += '#' + fragment;
844 return output;
845 },
846 // https://url.spec.whatwg.org/#dom-url-href
847 setHref: function (href) {
848 var failure = this.parse(href);
849 if (failure) throw new TypeError(failure);
850 this.searchParams.update();
851 },
852 // https://url.spec.whatwg.org/#dom-url-origin
853 getOrigin: function () {
854 var scheme = this.scheme;
855 var port = this.port;
856 if (scheme === 'blob') try {
857 return new URLConstructor(this.path[0]).origin;
858 } catch (error) {
859 return 'null';
860 }
861 if (scheme === 'file' || !this.isSpecial()) return 'null';
862 return scheme + '://' + serializeHost(this.host) + (port !== null ? ':' + port : '');
863 },
864 // https://url.spec.whatwg.org/#dom-url-protocol
865 getProtocol: function () {
866 return this.scheme + ':';
867 },
868 setProtocol: function (protocol) {
869 this.parse($toString(protocol) + ':', SCHEME_START);
870 },
871 // https://url.spec.whatwg.org/#dom-url-username
872 getUsername: function () {
873 return this.username;
874 },
875 setUsername: function (username) {
876 var codePoints = arrayFrom($toString(username));
877 if (this.cannotHaveUsernamePasswordPort()) return;
878 this.username = '';
879 for (var i = 0; i < codePoints.length; i++) {
880 this.username += percentEncode(codePoints[i], userinfoPercentEncodeSet);
881 }
882 },
883 // https://url.spec.whatwg.org/#dom-url-password
884 getPassword: function () {
885 return this.password;
886 },
887 setPassword: function (password) {
888 var codePoints = arrayFrom($toString(password));
889 if (this.cannotHaveUsernamePasswordPort()) return;
890 this.password = '';
891 for (var i = 0; i < codePoints.length; i++) {
892 this.password += percentEncode(codePoints[i], userinfoPercentEncodeSet);
893 }
894 },
895 // https://url.spec.whatwg.org/#dom-url-host
896 getHost: function () {
897 var host = this.host;
898 var port = this.port;
899 return host === null ? ''
900 : port === null ? serializeHost(host)
901 : serializeHost(host) + ':' + port;
902 },
903 setHost: function (host) {
904 if (this.cannotBeABaseURL) return;
905 this.parse(host, HOST);
906 },
907 // https://url.spec.whatwg.org/#dom-url-hostname
908 getHostname: function () {
909 var host = this.host;
910 return host === null ? '' : serializeHost(host);
911 },
912 setHostname: function (hostname) {
913 if (this.cannotBeABaseURL) return;
914 this.parse(hostname, HOSTNAME);
915 },
916 // https://url.spec.whatwg.org/#dom-url-port
917 getPort: function () {
918 var port = this.port;
919 return port === null ? '' : $toString(port);
920 },
921 setPort: function (port) {
922 if (this.cannotHaveUsernamePasswordPort()) return;
923 port = $toString(port);
924 if (port === '') this.port = null;
925 else this.parse(port, PORT);
926 },
927 // https://url.spec.whatwg.org/#dom-url-pathname
928 getPathname: function () {
929 var path = this.path;
930 return this.cannotBeABaseURL ? path[0] : path.length ? '/' + join(path, '/') : '';
931 },
932 setPathname: function (pathname) {
933 if (this.cannotBeABaseURL) return;
934 this.path = [];
935 this.parse(pathname, PATH_START);
936 },
937 // https://url.spec.whatwg.org/#dom-url-search
938 getSearch: function () {
939 var query = this.query;
940 return query ? '?' + query : '';
941 },
942 setSearch: function (search) {
943 search = $toString(search);
944 if (search === '') {
945 this.query = null;
946 } else {
947 if (charAt(search, 0) === '?') search = stringSlice(search, 1);
948 this.query = '';
949 this.parse(search, QUERY);
950 }
951 this.searchParams.update();
952 },
953 // https://url.spec.whatwg.org/#dom-url-searchparams
954 getSearchParams: function () {
955 return this.searchParams.facade;
956 },
957 // https://url.spec.whatwg.org/#dom-url-hash
958 getHash: function () {
959 var fragment = this.fragment;
960 return fragment ? '#' + fragment : '';
961 },
962 setHash: function (hash) {
963 hash = $toString(hash);
964 if (hash === '') {
965 this.fragment = null;
966 return;
967 }
968 if (charAt(hash, 0) === '#') hash = stringSlice(hash, 1);
969 this.fragment = '';
970 this.parse(hash, FRAGMENT);
971 },
972 update: function () {
973 this.query = this.searchParams.serialize() || null;
974 }
975};
976
977// `URL` constructor
978// https://url.spec.whatwg.org/#url-class
979var URLConstructor = function URL(url /* , base */) {
980 var that = anInstance(this, URLPrototype);
981 var base = validateArgumentsLength(arguments.length, 1) > 1 ? arguments[1] : undefined;
982 var state = setInternalState(that, new URLState(url, false, base));
983 if (!DESCRIPTORS) {
984 that.href = state.serialize();
985 that.origin = state.getOrigin();
986 that.protocol = state.getProtocol();
987 that.username = state.getUsername();
988 that.password = state.getPassword();
989 that.host = state.getHost();
990 that.hostname = state.getHostname();
991 that.port = state.getPort();
992 that.pathname = state.getPathname();
993 that.search = state.getSearch();
994 that.searchParams = state.getSearchParams();
995 that.hash = state.getHash();
996 }
997};
998
999var URLPrototype = URLConstructor.prototype;
1000
1001var accessorDescriptor = function (getter, setter) {
1002 return {
1003 get: function () {
1004 return getInternalURLState(this)[getter]();
1005 },
1006 set: setter && function (value) {
1007 return getInternalURLState(this)[setter](value);
1008 },
1009 configurable: true,
1010 enumerable: true
1011 };
1012};
1013
1014if (DESCRIPTORS) {
1015 // `URL.prototype.href` accessors pair
1016 // https://url.spec.whatwg.org/#dom-url-href
1017 defineBuiltInAccessor(URLPrototype, 'href', accessorDescriptor('serialize', 'setHref'));
1018 // `URL.prototype.origin` getter
1019 // https://url.spec.whatwg.org/#dom-url-origin
1020 defineBuiltInAccessor(URLPrototype, 'origin', accessorDescriptor('getOrigin'));
1021 // `URL.prototype.protocol` accessors pair
1022 // https://url.spec.whatwg.org/#dom-url-protocol
1023 defineBuiltInAccessor(URLPrototype, 'protocol', accessorDescriptor('getProtocol', 'setProtocol'));
1024 // `URL.prototype.username` accessors pair
1025 // https://url.spec.whatwg.org/#dom-url-username
1026 defineBuiltInAccessor(URLPrototype, 'username', accessorDescriptor('getUsername', 'setUsername'));
1027 // `URL.prototype.password` accessors pair
1028 // https://url.spec.whatwg.org/#dom-url-password
1029 defineBuiltInAccessor(URLPrototype, 'password', accessorDescriptor('getPassword', 'setPassword'));
1030 // `URL.prototype.host` accessors pair
1031 // https://url.spec.whatwg.org/#dom-url-host
1032 defineBuiltInAccessor(URLPrototype, 'host', accessorDescriptor('getHost', 'setHost'));
1033 // `URL.prototype.hostname` accessors pair
1034 // https://url.spec.whatwg.org/#dom-url-hostname
1035 defineBuiltInAccessor(URLPrototype, 'hostname', accessorDescriptor('getHostname', 'setHostname'));
1036 // `URL.prototype.port` accessors pair
1037 // https://url.spec.whatwg.org/#dom-url-port
1038 defineBuiltInAccessor(URLPrototype, 'port', accessorDescriptor('getPort', 'setPort'));
1039 // `URL.prototype.pathname` accessors pair
1040 // https://url.spec.whatwg.org/#dom-url-pathname
1041 defineBuiltInAccessor(URLPrototype, 'pathname', accessorDescriptor('getPathname', 'setPathname'));
1042 // `URL.prototype.search` accessors pair
1043 // https://url.spec.whatwg.org/#dom-url-search
1044 defineBuiltInAccessor(URLPrototype, 'search', accessorDescriptor('getSearch', 'setSearch'));
1045 // `URL.prototype.searchParams` getter
1046 // https://url.spec.whatwg.org/#dom-url-searchparams
1047 defineBuiltInAccessor(URLPrototype, 'searchParams', accessorDescriptor('getSearchParams'));
1048 // `URL.prototype.hash` accessors pair
1049 // https://url.spec.whatwg.org/#dom-url-hash
1050 defineBuiltInAccessor(URLPrototype, 'hash', accessorDescriptor('getHash', 'setHash'));
1051}
1052
1053// `URL.prototype.toJSON` method
1054// https://url.spec.whatwg.org/#dom-url-tojson
1055defineBuiltIn(URLPrototype, 'toJSON', function toJSON() {
1056 return getInternalURLState(this).serialize();
1057}, { enumerable: true });
1058
1059// `URL.prototype.toString` method
1060// https://url.spec.whatwg.org/#URL-stringification-behavior
1061defineBuiltIn(URLPrototype, 'toString', function toString() {
1062 return getInternalURLState(this).serialize();
1063}, { enumerable: true });
1064
1065if (NativeURL) {
1066 var nativeCreateObjectURL = NativeURL.createObjectURL;
1067 var nativeRevokeObjectURL = NativeURL.revokeObjectURL;
1068 // `URL.createObjectURL` method
1069 // https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
1070 if (nativeCreateObjectURL) defineBuiltIn(URLConstructor, 'createObjectURL', bind(nativeCreateObjectURL, NativeURL));
1071 // `URL.revokeObjectURL` method
1072 // https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
1073 if (nativeRevokeObjectURL) defineBuiltIn(URLConstructor, 'revokeObjectURL', bind(nativeRevokeObjectURL, NativeURL));
1074}
1075
1076setToStringTag(URLConstructor, 'URL');
1077
1078$({ global: true, constructor: true, forced: !USE_NATIVE_URL, sham: !DESCRIPTORS }, {
1079 URL: URLConstructor
1080});
Note: See TracBrowser for help on using the repository browser.