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 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 has = require('../internals/has');
+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-simple');
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 NativeURL = global.URL;
-var URLSearchParams = URLSearchParamsModule.URLSearchParams;
-var getInternalSearchParamsState = URLSearchParamsModule.getState;
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-Za-z]/;
-var ALPHANUMERIC = /[\d+-.A-Za-z]/;
+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|0X)/;
+var HEX_START = /^0x/i;
var OCT = /^[0-7]+$/;
var DEC = /^\d+$/;
-var HEX = /^[\dA-Fa-f]+$/;
-/* eslint-disable no-control-regex -- safe */
-var FORBIDDEN_HOST_CODE_POINT = /[\u0000\t\u000A\u000D #%/:?@[\\]]/;
-var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\u0000\t\u000A\u000D #/:?@[\\]]/;
-var LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\u0000-\u001F ]+|[\u0000-\u001F ]+$/g;
-var TAB_AND_NEW_LINE = /[\t\u000A\u000D]/g;
-/* eslint-enable no-control-regex -- safe */
+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 (input.charAt(0) == '[') {
- if (input.charAt(input.length - 1) != ']') return INVALID_HOST;
- result = parseIPv6(input.slice(1, -1));
- if (!result) return INVALID_HOST;
- url.host = result;
- // opaque host
- } else if (!isSpecial(url)) {
- if (FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT.test(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 (FORBIDDEN_HOST_CODE_POINT.test(input)) return INVALID_HOST;
- result = parseIPv4(input);
- if (result === null) return INVALID_HOST;
- url.host = result;
- }
-};
-
+// https://url.spec.whatwg.org/#ipv4-number-parser
var parseIPv4 = function (input) {
- var parts = input.split('.');
+ var parts = split(input, '.');
var partsLength, numbers, index, part, radix, number, ipv4;
if (parts.length && parts[parts.length - 1] == '') {
- parts.pop();
+ parts.length--;
}
partsLength = parts.length;
if (partsLength > 4) return input;
part = parts[index];
if (part == '') return input;
radix = 10;
- if (part.length > 1 && part.charAt(0) == '0') {
- radix = HEX_START.test(part) ? 16 : 8;
- part = part.slice(radix == 8 ? 1 : 2);
+ 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 (!(radix == 10 ? DEC : radix == 8 ? OCT : HEX).test(part)) return input;
+ if (!exec(radix == 10 ? DEC : radix == 8 ? OCT : HEX, part)) return input;
number = parseInt(part, radix);
}
- numbers.push(number);
+ push(numbers, number);
}
for (index = 0; index < partsLength; index++) {
number = numbers[index];
if (number >= pow(256, 5 - partsLength)) return null;
} else if (number > 255) return null;
}
- ipv4 = numbers.pop();
+ ipv4 = pop(numbers);
for (index = 0; index < numbers.length; index++) {
ipv4 += numbers[index] * pow(256, 3 - index);
}
return ipv4;
};
+// https://url.spec.whatwg.org/#concept-ipv6-parser
// eslint-disable-next-line max-statements -- TODO
var parseIPv6 = function (input) {
var address = [0, 0, 0, 0, 0, 0, 0, 0];
var pointer = 0;
var value, length, numbersSeen, ipv4Piece, number, swaps, swap;
- var char = function () {
- return input.charAt(pointer);
+ var chr = function () {
+ return charAt(input, pointer);
};
- if (char() == ':') {
- if (input.charAt(1) != ':') return;
+ if (chr() == ':') {
+ if (charAt(input, 1) != ':') return;
pointer += 2;
pieceIndex++;
compress = pieceIndex;
}
- while (char()) {
+ while (chr()) {
if (pieceIndex == 8) return;
- if (char() == ':') {
+ if (chr() == ':') {
if (compress !== null) return;
pointer++;
pieceIndex++;
continue;
}
value = length = 0;
- while (length < 4 && HEX.test(char())) {
- value = value * 16 + parseInt(char(), 16);
+ while (length < 4 && exec(HEX, chr())) {
+ value = value * 16 + parseInt(chr(), 16);
pointer++;
length++;
}
- if (char() == '.') {
+ if (chr() == '.') {
if (length == 0) return;
pointer -= length;
if (pieceIndex > 6) return;
numbersSeen = 0;
- while (char()) {
+ while (chr()) {
ipv4Piece = null;
if (numbersSeen > 0) {
- if (char() == '.' && numbersSeen < 4) pointer++;
+ if (chr() == '.' && numbersSeen < 4) pointer++;
else return;
}
- if (!DIGIT.test(char())) return;
- while (DIGIT.test(char())) {
- number = parseInt(char(), 10);
+ 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 (numbersSeen != 4) return;
break;
- } else if (char() == ':') {
+ } else if (chr() == ':') {
pointer++;
- if (!char()) return;
- } else if (char()) return;
+ if (!chr()) return;
+ } else if (chr()) return;
address[pieceIndex++] = value;
}
if (compress !== null) {
return maxIndex;
};
+// https://url.spec.whatwg.org/#host-serializing
var serializeHost = function (host) {
var result, index, compress, ignore0;
// ipv4
if (typeof host == 'number') {
result = [];
for (index = 0; index < 4; index++) {
- result.unshift(host % 256);
+ unshift(result, host % 256);
host = floor(host / 256);
- } return result.join('.');
+ } return join(result, '.');
// ipv6
} else if (typeof host == 'object') {
result = '';
result += index ? ':' : '::';
ignore0 = true;
} else {
- result += host[index].toString(16);
+ result += numberToString(host[index], 16);
if (index < 7) result += ':';
}
}
'/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\': 1, ']': 1, '^': 1, '|': 1
});
-var percentEncode = function (char, set) {
- var code = codeAt(char, 0);
- return code > 0x20 && code < 0x7F && !has(set, char) ? char : encodeURIComponent(char);
+var percentEncode = function (chr, set) {
+ var code = codeAt(chr, 0);
+ return code > 0x20 && code < 0x7F && !hasOwn(set, chr) ? chr : encodeURIComponent(chr);
};
+// https://url.spec.whatwg.org/#special-scheme
var specialSchemes = {
ftp: 21,
file: null,
wss: 443
};
-var isSpecial = function (url) {
- return has(specialSchemes, url.scheme);
-};
-
-var includesCredentials = function (url) {
- return url.username != '' || url.password != '';
-};
-
-var cannotHaveUsernamePasswordPort = function (url) {
- return !url.host || url.cannotBeABaseURL || url.scheme == 'file';
-};
-
+// https://url.spec.whatwg.org/#windows-drive-letter
var isWindowsDriveLetter = function (string, normalized) {
var second;
- return string.length == 2 && ALPHA.test(string.charAt(0))
- && ((second = string.charAt(1)) == ':' || (!normalized && second == '|'));
+ return string.length == 2 && exec(ALPHA, charAt(string, 0))
+ && ((second = charAt(string, 1)) == ':' || (!normalized && second == '|'));
};
+// https://url.spec.whatwg.org/#start-with-a-windows-drive-letter
var startsWithWindowsDriveLetter = function (string) {
var third;
- return string.length > 1 && isWindowsDriveLetter(string.slice(0, 2)) && (
+ return string.length > 1 && isWindowsDriveLetter(stringSlice(string, 0, 2)) && (
string.length == 2 ||
- ((third = string.charAt(2)) === '/' || third === '\\' || third === '?' || third === '#')
+ ((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.pop();
- }
-};
-
+// https://url.spec.whatwg.org/#single-dot-path-segment
var isSingleDot = function (segment) {
- return segment === '.' || segment.toLowerCase() === '%2e';
+ return segment === '.' || toLowerCase(segment) === '%2e';
};
+// https://url.spec.whatwg.org/#double-dot-path-segment
var isDoubleDot = function (segment) {
- segment = segment.toLowerCase();
+ segment = toLowerCase(segment);
return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e';
};
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, char, 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 = input.replace(LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, '');
+var URLState = function (url, isBase, base) {
+ var urlString = $toString(url);
+ var baseState, failure, searchParams;
+ if (isBase) {
+ failure = this.parse(urlString);
+ if (failure) throw TypeError(failure);
+ this.searchParams = null;
+ } else {
+ if (base !== undefined) baseState = new URLState(base, true);
+ failure = this.parse(urlString, null, baseState);
+ if (failure) throw TypeError(failure);
+ searchParams = getInternalSearchParamsState(new URLSearchParams());
+ searchParams.bindURL(this);
+ this.searchParams = searchParams;
}
+};
- input = input.replace(TAB_AND_NEW_LINE, '');
+URLState.prototype = {
+ type: 'URL',
+ // https://url.spec.whatwg.org/#url-parsing
+ // eslint-disable-next-line max-statements -- TODO
+ parse: function (input, stateOverride, base) {
+ var url = this;
+ var state = stateOverride || SCHEME_START;
+ var pointer = 0;
+ var buffer = '';
+ var seenAt = false;
+ var seenBracket = false;
+ var seenPasswordToken = false;
+ var codePoints, chr, bufferCodePoints, failure;
+
+ input = $toString(input);
+
+ 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, '');
+ }
- codePoints = arrayFrom(input);
+ input = replace(input, TAB_AND_NEW_LINE, '');
- while (pointer <= codePoints.length) {
- char = codePoints[pointer];
- switch (state) {
- case SCHEME_START:
- if (char && ALPHA.test(char)) {
- buffer += char.toLowerCase();
- state = SCHEME;
- } else if (!stateOverride) {
- state = NO_SCHEME;
- continue;
- } else return INVALID_SCHEME;
- break;
-
- case SCHEME:
- if (char && (ALPHANUMERIC.test(char) || char == '+' || char == '-' || char == '.')) {
- buffer += char.toLowerCase();
- } else if (char == ':') {
- if (stateOverride && (
- (isSpecial(url) != has(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;
- url.path.push('');
- state = CANNOT_BE_A_BASE_URL_PATH;
- }
- } else if (!stateOverride) {
- buffer = '';
- state = NO_SCHEME;
- pointer = 0;
- continue;
- } else return INVALID_SCHEME;
- break;
+ codePoints = arrayFrom(input);
- case NO_SCHEME:
- if (!base || (base.cannotBeABaseURL && char != '#')) return INVALID_SCHEME;
- if (base.cannotBeABaseURL && char == '#') {
- url.scheme = base.scheme;
- url.path = base.path.slice();
- url.query = base.query;
- url.fragment = '';
- url.cannotBeABaseURL = true;
- state = FRAGMENT;
+ 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;
- }
- state = base.scheme == 'file' ? FILE : RELATIVE;
- continue;
-
- case SPECIAL_RELATIVE_OR_AUTHORITY:
- if (char == '/' && codePoints[pointer + 1] == '/') {
- state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
- pointer++;
- } else {
- state = RELATIVE;
- continue;
- } break;
- case PATH_OR_AUTHORITY:
- if (char == '/') {
- state = AUTHORITY;
+ case SCHEME:
+ if (chr && (exec(ALPHANUMERIC, chr) || chr == '+' || chr == '-' || chr == '.')) {
+ buffer += toLowerCase(chr);
+ } else if (chr == ':') {
+ if (stateOverride && (
+ (url.isSpecial() != hasOwn(specialSchemes, buffer)) ||
+ (buffer == 'file' && (url.includesCredentials() || url.port !== null)) ||
+ (url.scheme == 'file' && !url.host)
+ )) return;
+ url.scheme = buffer;
+ if (stateOverride) {
+ if (url.isSpecial() && specialSchemes[url.scheme] == url.port) url.port = null;
+ return;
+ }
+ buffer = '';
+ if (url.scheme == 'file') {
+ state = FILE;
+ } else if (url.isSpecial() && base && base.scheme == url.scheme) {
+ state = SPECIAL_RELATIVE_OR_AUTHORITY;
+ } else if (url.isSpecial()) {
+ 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;
- } else {
- state = PATH;
- continue;
- }
- case RELATIVE:
- url.scheme = base.scheme;
- if (char == EOF) {
- url.username = base.username;
- url.password = base.password;
- url.host = base.host;
- url.port = base.port;
- url.path = base.path.slice();
- url.query = base.query;
- } else if (char == '/' || (char == '\\' && isSpecial(url))) {
- state = RELATIVE_SLASH;
- } else if (char == '?') {
- url.username = base.username;
- url.password = base.password;
- url.host = base.host;
- url.port = base.port;
- url.path = base.path.slice();
- url.query = '';
- state = QUERY;
- } else if (char == '#') {
- url.username = base.username;
- url.password = base.password;
- url.host = base.host;
- url.port = base.port;
- url.path = base.path.slice();
- 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 = base.path.slice();
- url.path.pop();
- state = PATH;
- continue;
- } break;
-
- case RELATIVE_SLASH:
- if (isSpecial(url) && (char == '/' || char == '\\')) {
- state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
- } else if (char == '/') {
- state = AUTHORITY;
- } else {
- url.username = base.username;
- url.password = base.password;
- url.host = base.host;
- url.port = base.port;
- state = PATH;
+ 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;
- } break;
- case SPECIAL_AUTHORITY_SLASHES:
- state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
- if (char != '/' || buffer.charAt(pointer + 1) != '/') continue;
- pointer++;
- break;
+ case SPECIAL_RELATIVE_OR_AUTHORITY:
+ if (chr == '/' && codePoints[pointer + 1] == '/') {
+ state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
+ pointer++;
+ } else {
+ state = RELATIVE;
+ continue;
+ } break;
- case SPECIAL_AUTHORITY_IGNORE_SLASHES:
- if (char != '/' && char != '\\') {
- state = AUTHORITY;
- continue;
- } break;
-
- case AUTHORITY:
- if (char == '@') {
- 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 (
- char == EOF || char == '/' || char == '?' || char == '#' ||
- (char == '\\' && isSpecial(url))
- ) {
- if (seenAt && buffer == '') return INVALID_AUTHORITY;
- pointer -= arrayFrom(buffer).length + 1;
- buffer = '';
- state = HOST;
- } else buffer += char;
- break;
-
- case HOST:
- case HOSTNAME:
- if (stateOverride && url.scheme == 'file') {
- state = FILE_HOST;
- continue;
- } else if (char == ':' && !seenBracket) {
- if (buffer == '') return INVALID_HOST;
- failure = parseHost(url, buffer);
- if (failure) return failure;
- buffer = '';
- state = PORT;
- if (stateOverride == HOSTNAME) return;
- } else if (
- char == EOF || char == '/' || char == '?' || char == '#' ||
- (char == '\\' && 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 (char == '[') seenBracket = true;
- else if (char == ']') seenBracket = false;
- buffer += char;
- } break;
-
- case PORT:
- if (DIGIT.test(char)) {
- buffer += char;
- } else if (
- char == EOF || char == '/' || char == '?' || char == '#' ||
- (char == '\\' && 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 = '';
+ case PATH_OR_AUTHORITY:
+ if (chr == '/') {
+ state = AUTHORITY;
+ break;
+ } else {
+ state = PATH;
+ continue;
}
- if (stateOverride) return;
- state = PATH_START;
- continue;
- } else return INVALID_PORT;
- break;
-
- case FILE:
- url.scheme = 'file';
- if (char == '/' || char == '\\') state = FILE_SLASH;
- else if (base && base.scheme == 'file') {
- if (char == EOF) {
+
+ case RELATIVE:
+ url.scheme = base.scheme;
+ if (chr == EOF) {
+ url.username = base.username;
+ url.password = base.password;
url.host = base.host;
- url.path = base.path.slice();
+ url.port = base.port;
+ url.path = arraySlice(base.path);
url.query = base.query;
- } else if (char == '?') {
+ } else if (chr == '/' || (chr == '\\' && url.isSpecial())) {
+ state = RELATIVE_SLASH;
+ } else if (chr == '?') {
+ url.username = base.username;
+ url.password = base.password;
url.host = base.host;
- url.path = base.path.slice();
+ url.port = base.port;
+ url.path = arraySlice(base.path);
url.query = '';
state = QUERY;
- } else if (char == '#') {
+ } else if (chr == '#') {
+ url.username = base.username;
+ url.password = base.password;
url.host = base.host;
- url.path = base.path.slice();
+ url.port = base.port;
+ url.path = arraySlice(base.path);
url.query = base.query;
url.fragment = '';
state = FRAGMENT;
} else {
- if (!startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {
+ 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 (url.isSpecial() && (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 == '\\' && url.isSpecial())
+ ) {
+ 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 = url.parseHost(buffer);
+ if (failure) return failure;
+ buffer = '';
+ state = PORT;
+ if (stateOverride == HOSTNAME) return;
+ } else if (
+ chr == EOF || chr == '/' || chr == '?' || chr == '#' ||
+ (chr == '\\' && url.isSpecial())
+ ) {
+ if (url.isSpecial() && buffer == '') return INVALID_HOST;
+ if (stateOverride && buffer == '' && (url.includesCredentials() || url.port !== null)) return;
+ failure = url.parseHost(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 == '\\' && url.isSpecial()) ||
+ stateOverride
+ ) {
+ if (buffer != '') {
+ var port = parseInt(buffer, 10);
+ if (port > 0xFFFF) return INVALID_PORT;
+ url.port = (url.isSpecial() && 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 = base.path.slice();
- shortenURLsPath(url);
+ 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);
+ url.shortenPath();
+ }
+ 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;
}
- } else {
state = PATH;
continue;
- } break;
- case FILE_SLASH:
- if (char == '/' || char == '\\') {
- state = FILE_HOST;
+ 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 = url.parseHost(buffer);
+ if (failure) return failure;
+ if (url.host == 'localhost') url.host = '';
+ if (stateOverride) return;
+ buffer = '';
+ state = PATH_START;
+ } continue;
+ } else buffer += chr;
break;
- }
- if (base && base.scheme == 'file' && !startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {
- if (isWindowsDriveLetter(base.path[0], true)) url.path.push(base.path[0]);
- else url.host = base.host;
- }
- state = PATH;
- continue;
- case FILE_HOST:
- if (char == EOF || char == '/' || char == '\\' || char == '?' || char == '#') {
- if (!stateOverride && isWindowsDriveLetter(buffer)) {
+ case PATH_START:
+ if (url.isSpecial()) {
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;
+ 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 == '\\' && url.isSpecial()) ||
+ (!stateOverride && (chr == '?' || chr == '#'))
+ ) {
+ if (isDoubleDot(buffer)) {
+ url.shortenPath();
+ if (chr != '/' && !(chr == '\\' && url.isSpecial())) {
+ push(url.path, '');
+ }
+ } else if (isSingleDot(buffer)) {
+ if (chr != '/' && !(chr == '\\' && url.isSpecial())) {
+ 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 = '';
- state = PATH_START;
- } continue;
- } else buffer += char;
- break;
-
- case PATH_START:
- if (isSpecial(url)) {
- state = PATH;
- if (char != '/' && char != '\\') continue;
- } else if (!stateOverride && char == '?') {
- url.query = '';
- state = QUERY;
- } else if (!stateOverride && char == '#') {
- url.fragment = '';
- state = FRAGMENT;
- } else if (char != EOF) {
- state = PATH;
- if (char != '/') continue;
- } break;
-
- case PATH:
- if (
- char == EOF || char == '/' ||
- (char == '\\' && isSpecial(url)) ||
- (!stateOverride && (char == '?' || char == '#'))
- ) {
- if (isDoubleDot(buffer)) {
- shortenURLsPath(url);
- if (char != '/' && !(char == '\\' && isSpecial(url))) {
- url.path.push('');
+ if (url.scheme == 'file' && (chr == EOF || chr == '?' || chr == '#')) {
+ while (url.path.length > 1 && url.path[0] === '') {
+ shift(url.path);
+ }
}
- } else if (isSingleDot(buffer)) {
- if (char != '/' && !(char == '\\' && isSpecial(url))) {
- url.path.push('');
+ if (chr == '?') {
+ url.query = '';
+ state = QUERY;
+ } else if (chr == '#') {
+ url.fragment = '';
+ state = FRAGMENT;
}
} else {
- if (url.scheme == 'file' && !url.path.length && isWindowsDriveLetter(buffer)) {
- if (url.host) url.host = '';
- buffer = buffer.charAt(0) + ':'; // normalize windows drive letter
- }
- url.path.push(buffer);
- }
- buffer = '';
- if (url.scheme == 'file' && (char == EOF || char == '?' || char == '#')) {
- while (url.path.length > 1 && url.path[0] === '') {
- url.path.shift();
- }
- }
- if (char == '?') {
+ buffer += percentEncode(chr, pathPercentEncodeSet);
+ } break;
+
+ case CANNOT_BE_A_BASE_URL_PATH:
+ if (chr == '?') {
url.query = '';
state = QUERY;
- } else if (char == '#') {
+ } else if (chr == '#') {
url.fragment = '';
state = FRAGMENT;
- }
- } else {
- buffer += percentEncode(char, pathPercentEncodeSet);
- } break;
-
- case CANNOT_BE_A_BASE_URL_PATH:
- if (char == '?') {
- url.query = '';
- state = QUERY;
- } else if (char == '#') {
- url.fragment = '';
- state = FRAGMENT;
- } else if (char != EOF) {
- url.path[0] += percentEncode(char, C0ControlPercentEncodeSet);
- } break;
-
- case QUERY:
- if (!stateOverride && char == '#') {
- url.fragment = '';
- state = FRAGMENT;
- } else if (char != EOF) {
- if (char == "'" && isSpecial(url)) url.query += '%27';
- else if (char == '#') url.query += '%23';
- else url.query += percentEncode(char, C0ControlPercentEncodeSet);
- } break;
-
- case FRAGMENT:
- if (char != EOF) url.fragment += percentEncode(char, fragmentPercentEncodeSet);
- break;
- }
+ } 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 == "'" && url.isSpecial()) 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++;
+ pointer++;
+ }
+ },
+ // https://url.spec.whatwg.org/#host-parsing
+ parseHost: function (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;
+ this.host = result;
+ // opaque host
+ } else if (!this.isSpecial()) {
+ 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);
+ }
+ this.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;
+ this.host = result;
+ }
+ },
+ // https://url.spec.whatwg.org/#cannot-have-a-username-password-port
+ cannotHaveUsernamePasswordPort: function () {
+ return !this.host || this.cannotBeABaseURL || this.scheme == 'file';
+ },
+ // https://url.spec.whatwg.org/#include-credentials
+ includesCredentials: function () {
+ return this.username != '' || this.password != '';
+ },
+ // https://url.spec.whatwg.org/#is-special
+ isSpecial: function () {
+ return hasOwn(specialSchemes, this.scheme);
+ },
+ // https://url.spec.whatwg.org/#shorten-a-urls-path
+ shortenPath: function () {
+ var path = this.path;
+ var pathSize = path.length;
+ if (pathSize && (this.scheme != 'file' || pathSize != 1 || !isWindowsDriveLetter(path[0], true))) {
+ path.length--;
+ }
+ },
+ // https://url.spec.whatwg.org/#concept-url-serializer
+ serialize: function () {
+ var url = 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 (url.includesCredentials()) {
+ 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;
+ },
+ // https://url.spec.whatwg.org/#dom-url-href
+ setHref: function (href) {
+ var failure = this.parse(href);
+ if (failure) throw TypeError(failure);
+ this.searchParams.update();
+ },
+ // https://url.spec.whatwg.org/#dom-url-origin
+ getOrigin: function () {
+ var scheme = this.scheme;
+ var port = this.port;
+ if (scheme == 'blob') try {
+ return new URLConstructor(scheme.path[0]).origin;
+ } catch (error) {
+ return 'null';
+ }
+ if (scheme == 'file' || !this.isSpecial()) return 'null';
+ return scheme + '://' + serializeHost(this.host) + (port !== null ? ':' + port : '');
+ },
+ // https://url.spec.whatwg.org/#dom-url-protocol
+ getProtocol: function () {
+ return this.scheme + ':';
+ },
+ setProtocol: function (protocol) {
+ this.parse($toString(protocol) + ':', SCHEME_START);
+ },
+ // https://url.spec.whatwg.org/#dom-url-username
+ getUsername: function () {
+ return this.username;
+ },
+ setUsername: function (username) {
+ var codePoints = arrayFrom($toString(username));
+ if (this.cannotHaveUsernamePasswordPort()) return;
+ this.username = '';
+ for (var i = 0; i < codePoints.length; i++) {
+ this.username += percentEncode(codePoints[i], userinfoPercentEncodeSet);
+ }
+ },
+ // https://url.spec.whatwg.org/#dom-url-password
+ getPassword: function () {
+ return this.password;
+ },
+ setPassword: function (password) {
+ var codePoints = arrayFrom($toString(password));
+ if (this.cannotHaveUsernamePasswordPort()) return;
+ this.password = '';
+ for (var i = 0; i < codePoints.length; i++) {
+ this.password += percentEncode(codePoints[i], userinfoPercentEncodeSet);
+ }
+ },
+ // https://url.spec.whatwg.org/#dom-url-host
+ getHost: function () {
+ var host = this.host;
+ var port = this.port;
+ return host === null ? ''
+ : port === null ? serializeHost(host)
+ : serializeHost(host) + ':' + port;
+ },
+ setHost: function (host) {
+ if (this.cannotBeABaseURL) return;
+ this.parse(host, HOST);
+ },
+ // https://url.spec.whatwg.org/#dom-url-hostname
+ getHostname: function () {
+ var host = this.host;
+ return host === null ? '' : serializeHost(host);
+ },
+ setHostname: function (hostname) {
+ if (this.cannotBeABaseURL) return;
+ this.parse(hostname, HOSTNAME);
+ },
+ // https://url.spec.whatwg.org/#dom-url-port
+ getPort: function () {
+ var port = this.port;
+ return port === null ? '' : $toString(port);
+ },
+ setPort: function (port) {
+ if (this.cannotHaveUsernamePasswordPort()) return;
+ port = $toString(port);
+ if (port == '') this.port = null;
+ else this.parse(port, PORT);
+ },
+ // https://url.spec.whatwg.org/#dom-url-pathname
+ getPathname: function () {
+ var path = this.path;
+ return this.cannotBeABaseURL ? path[0] : path.length ? '/' + join(path, '/') : '';
+ },
+ setPathname: function (pathname) {
+ if (this.cannotBeABaseURL) return;
+ this.path = [];
+ this.parse(pathname, PATH_START);
+ },
+ // https://url.spec.whatwg.org/#dom-url-search
+ getSearch: function () {
+ var query = this.query;
+ return query ? '?' + query : '';
+ },
+ setSearch: function (search) {
+ search = $toString(search);
+ if (search == '') {
+ this.query = null;
+ } else {
+ if ('?' == charAt(search, 0)) search = stringSlice(search, 1);
+ this.query = '';
+ this.parse(search, QUERY);
+ }
+ this.searchParams.update();
+ },
+ // https://url.spec.whatwg.org/#dom-url-searchparams
+ getSearchParams: function () {
+ return this.searchParams.facade;
+ },
+ // https://url.spec.whatwg.org/#dom-url-hash
+ getHash: function () {
+ var fragment = this.fragment;
+ return fragment ? '#' + fragment : '';
+ },
+ setHash: function (hash) {
+ hash = $toString(hash);
+ if (hash == '') {
+ this.fragment = null;
+ return;
+ }
+ if ('#' == charAt(hash, 0)) hash = stringSlice(hash, 1);
+ this.fragment = '';
+ this.parse(hash, FRAGMENT);
+ },
+ update: function () {
+ this.query = this.searchParams.serialize() || null;
}
};
// `URL` constructor
// https://url.spec.whatwg.org/#url-class
var URLConstructor = function URL(url /* , base */) {
- var that = anInstance(this, URLConstructor, 'URL');
+ var that = anInstance(this, URLPrototype);
var base = arguments.length > 1 ? arguments[1] : undefined;
- var urlString = String(url);
- var state = setInternalState(that, { type: 'URL' });
- var baseState, failure;
- if (base !== undefined) {
- if (base instanceof URLConstructor) baseState = getInternalURLState(base);
- else {
- failure = parseURL(baseState = {}, String(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 = String(searchParams) || null;
- };
+ var state = setInternalState(that, new URLState(url, false, base));
if (!DESCRIPTORS) {
- that.href = serializeURL.call(that);
- that.origin = getOrigin.call(that);
- that.protocol = getProtocol.call(that);
- that.username = getUsername.call(that);
- that.password = getPassword.call(that);
- that.host = getHost.call(that);
- that.hostname = getHostname.call(that);
- that.port = getPort.call(that);
- that.pathname = getPathname.call(that);
- that.search = getSearch.call(that);
- that.searchParams = getSearchParams.call(that);
- that.hash = getHash.call(that);
+ that.href = state.serialize();
+ that.origin = state.getOrigin();
+ that.protocol = state.getProtocol();
+ that.username = state.getUsername();
+ that.password = state.getPassword();
+ that.host = state.getHost();
+ that.hostname = state.getHostname();
+ that.port = state.getPort();
+ that.pathname = state.getPathname();
+ that.search = state.getSearch();
+ that.searchParams = state.getSearchParams();
+ that.hash = state.getHash();
}
};
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 ? '/' + path.join('/') : '';
- 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 URL(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 ? '' : String(port);
-};
-
-var getPathname = function () {
- var url = getInternalURLState(this);
- var path = url.path;
- return url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';
-};
-
-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 };
+ return {
+ get: function () {
+ return getInternalURLState(this)[getter]();
+ },
+ set: setter && function (value) {
+ return getInternalURLState(this)[setter](value);
+ },
+ 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 = String(href);
- var failure = parseURL(url, urlString);
- if (failure) throw TypeError(failure);
- getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
- }),
+ href: accessorDescriptor('serialize', 'setHref'),
// `URL.prototype.origin` getter
// https://url.spec.whatwg.org/#dom-url-origin
- origin: accessorDescriptor(getOrigin),
+ 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, String(protocol) + ':', SCHEME_START);
- }),
+ protocol: accessorDescriptor('getProtocol', 'setProtocol'),
// `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(String(username));
- if (cannotHaveUsernamePasswordPort(url)) return;
- url.username = '';
- for (var i = 0; i < codePoints.length; i++) {
- url.username += percentEncode(codePoints[i], userinfoPercentEncodeSet);
- }
- }),
+ username: accessorDescriptor('getUsername', 'setUsername'),
// `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(String(password));
- if (cannotHaveUsernamePasswordPort(url)) return;
- url.password = '';
- for (var i = 0; i < codePoints.length; i++) {
- url.password += percentEncode(codePoints[i], userinfoPercentEncodeSet);
- }
- }),
+ password: accessorDescriptor('getPassword', 'setPassword'),
// `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, String(host), HOST);
- }),
+ host: accessorDescriptor('getHost', 'setHost'),
// `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, String(hostname), HOSTNAME);
- }),
+ hostname: accessorDescriptor('getHostname', 'setHostname'),
// `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 = String(port);
- if (port == '') url.port = null;
- else parseURL(url, port, PORT);
- }),
+ port: accessorDescriptor('getPort', 'setPort'),
// `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, pathname + '', PATH_START);
- }),
+ pathname: accessorDescriptor('getPathname', 'setPathname'),
// `URL.prototype.search` accessors pair
// https://url.spec.whatwg.org/#dom-url-search
- search: accessorDescriptor(getSearch, function (search) {
- var url = getInternalURLState(this);
- search = String(search);
- if (search == '') {
- url.query = null;
- } else {
- if ('?' == search.charAt(0)) search = search.slice(1);
- url.query = '';
- parseURL(url, search, QUERY);
- }
- getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
- }),
+ search: accessorDescriptor('getSearch', 'setSearch'),
// `URL.prototype.searchParams` getter
// https://url.spec.whatwg.org/#dom-url-searchparams
- searchParams: accessorDescriptor(getSearchParams),
+ 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 = String(hash);
- if (hash == '') {
- url.fragment = null;
- return;
- }
- if ('#' == hash.charAt(0)) hash = hash.slice(1);
- url.fragment = '';
- parseURL(url, hash, FRAGMENT);
- })
+ hash: accessorDescriptor('getHash', 'setHash')
});
}
// `URL.prototype.toJSON` method
// https://url.spec.whatwg.org/#dom-url-tojson
redefine(URLPrototype, 'toJSON', function toJSON() {
- return serializeURL.call(this);
+ return getInternalURLState(this).serialize();
}, { enumerable: true });
// `URL.prototype.toString` method
// https://url.spec.whatwg.org/#URL-stringification-behavior
redefine(URLPrototype, 'toString', function toString() {
- return serializeURL.call(this);
+ return getInternalURLState(this).serialize();
}, { enumerable: true });
if (NativeURL) {
var nativeRevokeObjectURL = NativeURL.revokeObjectURL;
// `URL.createObjectURL` method
// https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
- // eslint-disable-next-line no-unused-vars -- required for `.length`
- if (nativeCreateObjectURL) redefine(URLConstructor, 'createObjectURL', function createObjectURL(blob) {
- return nativeCreateObjectURL.apply(NativeURL, arguments);
- });
+ if (nativeCreateObjectURL) redefine(URLConstructor, 'createObjectURL', bind(nativeCreateObjectURL, NativeURL));
// `URL.revokeObjectURL` method
// https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
- // eslint-disable-next-line no-unused-vars -- required for `.length`
- if (nativeRevokeObjectURL) redefine(URLConstructor, 'revokeObjectURL', function revokeObjectURL(url) {
- return nativeRevokeObjectURL.apply(NativeURL, arguments);
- });
+ if (nativeRevokeObjectURL) redefine(URLConstructor, 'revokeObjectURL', bind(nativeRevokeObjectURL, NativeURL));
}
setToStringTag(URLConstructor, 'URL');