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.
217 lines
4.5 KiB
217 lines
4.5 KiB
"use strict"; |
|
const usm = require("./url-state-machine"); |
|
const urlencoded = require("./urlencoded"); |
|
const URLSearchParams = require("./URLSearchParams"); |
|
|
|
exports.implementation = class URLImpl { |
|
constructor(globalObject, constructorArgs) { |
|
const url = constructorArgs[0]; |
|
const base = constructorArgs[1]; |
|
|
|
let parsedBase = null; |
|
if (base !== undefined) { |
|
parsedBase = usm.basicURLParse(base); |
|
if (parsedBase === null) { |
|
throw new TypeError(`Invalid base URL: ${base}`); |
|
} |
|
} |
|
|
|
const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); |
|
if (parsedURL === null) { |
|
throw new TypeError(`Invalid URL: ${url}`); |
|
} |
|
|
|
const query = parsedURL.query !== null ? parsedURL.query : ""; |
|
|
|
this._url = parsedURL; |
|
|
|
// We cannot invoke the "new URLSearchParams object" algorithm without going through the constructor, which strips |
|
// question mark by default. Therefore the doNotStripQMark hack is used. |
|
this._query = URLSearchParams.createImpl(globalObject, [query], { doNotStripQMark: true }); |
|
this._query._url = this; |
|
} |
|
|
|
get href() { |
|
return usm.serializeURL(this._url); |
|
} |
|
|
|
set href(v) { |
|
const parsedURL = usm.basicURLParse(v); |
|
if (parsedURL === null) { |
|
throw new TypeError(`Invalid URL: ${v}`); |
|
} |
|
|
|
this._url = parsedURL; |
|
|
|
this._query._list.splice(0); |
|
const { query } = parsedURL; |
|
if (query !== null) { |
|
this._query._list = urlencoded.parseUrlencodedString(query); |
|
} |
|
} |
|
|
|
get origin() { |
|
return usm.serializeURLOrigin(this._url); |
|
} |
|
|
|
get protocol() { |
|
return `${this._url.scheme}:`; |
|
} |
|
|
|
set protocol(v) { |
|
usm.basicURLParse(`${v}:`, { url: this._url, stateOverride: "scheme start" }); |
|
} |
|
|
|
get username() { |
|
return this._url.username; |
|
} |
|
|
|
set username(v) { |
|
if (usm.cannotHaveAUsernamePasswordPort(this._url)) { |
|
return; |
|
} |
|
|
|
usm.setTheUsername(this._url, v); |
|
} |
|
|
|
get password() { |
|
return this._url.password; |
|
} |
|
|
|
set password(v) { |
|
if (usm.cannotHaveAUsernamePasswordPort(this._url)) { |
|
return; |
|
} |
|
|
|
usm.setThePassword(this._url, v); |
|
} |
|
|
|
get host() { |
|
const url = this._url; |
|
|
|
if (url.host === null) { |
|
return ""; |
|
} |
|
|
|
if (url.port === null) { |
|
return usm.serializeHost(url.host); |
|
} |
|
|
|
return `${usm.serializeHost(url.host)}:${usm.serializeInteger(url.port)}`; |
|
} |
|
|
|
set host(v) { |
|
if (this._url.cannotBeABaseURL) { |
|
return; |
|
} |
|
|
|
usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); |
|
} |
|
|
|
get hostname() { |
|
if (this._url.host === null) { |
|
return ""; |
|
} |
|
|
|
return usm.serializeHost(this._url.host); |
|
} |
|
|
|
set hostname(v) { |
|
if (this._url.cannotBeABaseURL) { |
|
return; |
|
} |
|
|
|
usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); |
|
} |
|
|
|
get port() { |
|
if (this._url.port === null) { |
|
return ""; |
|
} |
|
|
|
return usm.serializeInteger(this._url.port); |
|
} |
|
|
|
set port(v) { |
|
if (usm.cannotHaveAUsernamePasswordPort(this._url)) { |
|
return; |
|
} |
|
|
|
if (v === "") { |
|
this._url.port = null; |
|
} else { |
|
usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); |
|
} |
|
} |
|
|
|
get pathname() { |
|
if (this._url.cannotBeABaseURL) { |
|
return this._url.path[0]; |
|
} |
|
|
|
if (this._url.path.length === 0) { |
|
return ""; |
|
} |
|
|
|
return `/${this._url.path.join("/")}`; |
|
} |
|
|
|
set pathname(v) { |
|
if (this._url.cannotBeABaseURL) { |
|
return; |
|
} |
|
|
|
this._url.path = []; |
|
usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); |
|
} |
|
|
|
get search() { |
|
if (this._url.query === null || this._url.query === "") { |
|
return ""; |
|
} |
|
|
|
return `?${this._url.query}`; |
|
} |
|
|
|
set search(v) { |
|
const url = this._url; |
|
|
|
if (v === "") { |
|
url.query = null; |
|
this._query._list = []; |
|
return; |
|
} |
|
|
|
const input = v[0] === "?" ? v.substring(1) : v; |
|
url.query = ""; |
|
usm.basicURLParse(input, { url, stateOverride: "query" }); |
|
this._query._list = urlencoded.parseUrlencodedString(input); |
|
} |
|
|
|
get searchParams() { |
|
return this._query; |
|
} |
|
|
|
get hash() { |
|
if (this._url.fragment === null || this._url.fragment === "") { |
|
return ""; |
|
} |
|
|
|
return `#${this._url.fragment}`; |
|
} |
|
|
|
set hash(v) { |
|
if (v === "") { |
|
this._url.fragment = null; |
|
return; |
|
} |
|
|
|
const input = v[0] === "#" ? v.substring(1) : v; |
|
this._url.fragment = ""; |
|
usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); |
|
} |
|
|
|
toJSON() { |
|
return this.href; |
|
} |
|
};
|
|
|