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

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

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