+ 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++;
+ }
+ },
+ // 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$1(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;