Spaces:
Paused
Paused
| ; | |
| const usm = require("./url-state-machine"); | |
| const urlencoded = require("./urlencoded"); | |
| const URLSearchParams = require("./URLSearchParams"); | |
| const URL = require("./URL"); | |
| exports.implementation = class URLImpl { | |
| // Unlike the spec, we duplicate some code between the constructor and canParse, because we want to give useful error | |
| // messages in the constructor that distinguish between the different causes of failure. | |
| constructor(globalObject, [url, base]) { | |
| 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; | |
| } | |
| static parse(globalObject, input, base) { | |
| try { | |
| return URL.createImpl(globalObject, [input, base]); | |
| } catch { | |
| return null; | |
| } | |
| } | |
| static canParse(url, base) { | |
| let parsedBase = null; | |
| if (base !== undefined) { | |
| parsedBase = usm.basicURLParse(base); | |
| if (parsedBase === null) { | |
| return false; | |
| } | |
| } | |
| const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); | |
| if (parsedURL === null) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| 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 (usm.hasAnOpaquePath(this._url)) { | |
| 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 (usm.hasAnOpaquePath(this._url)) { | |
| 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() { | |
| return usm.serializePath(this._url); | |
| } | |
| set pathname(v) { | |
| if (usm.hasAnOpaquePath(this._url)) { | |
| 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; | |
| } | |
| }; | |