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