diff options
Diffstat (limited to 'node_modules/jsdom/lib/jsdom/living/window/Location-impl.js')
-rw-r--r-- | node_modules/jsdom/lib/jsdom/living/window/Location-impl.js | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/node_modules/jsdom/lib/jsdom/living/window/Location-impl.js b/node_modules/jsdom/lib/jsdom/living/window/Location-impl.js new file mode 100644 index 0000000..c8a330c --- /dev/null +++ b/node_modules/jsdom/lib/jsdom/living/window/Location-impl.js @@ -0,0 +1,238 @@ +"use strict"; +const whatwgURL = require("whatwg-url"); +const DOMException = require("domexception/webidl2js-wrapper"); +const { documentBaseURL, parseURLToResultingURLRecord } = require("../helpers/document-base-url"); +const { navigate } = require("./navigation"); + +// Not implemented: use of entry settings object's API base URL in href setter, assign, and replace. Instead we just +// use the document base URL. The difference matters in the case of cross-frame calls. + +exports.implementation = class LocationImpl { + constructor(globalObject, args, privateData) { + this._relevantDocument = privateData.relevantDocument; + this.url = null; + + this._globalObject = globalObject; + } + + get _url() { + return this._relevantDocument._URL; + } + + _locationObjectSetterNavigate(url) { + // Not implemented: extra steps here to determine replacement flag. + + return this._locationObjectNavigate(url); + } + + _locationObjectNavigate(url, { replacement = false } = {}) { + // Not implemented: the setup for calling navigate, which doesn't apply to our stub navigate anyway. + + navigate(this._relevantDocument._defaultView, url, { replacement, exceptionsEnabled: true }); + } + + toString() { + return this.href; + } + + get href() { + return whatwgURL.serializeURL(this._url); + } + set href(v) { + const newURL = whatwgURL.parseURL(v, { baseURL: documentBaseURL(this._relevantDocument) }); + if (newURL === null) { + throw new TypeError(`Could not parse "${v}" as a URL`); + } + + this._locationObjectSetterNavigate(newURL); + } + + get origin() { + return whatwgURL.serializeURLOrigin(this._url); + } + + get protocol() { + return this._url.scheme + ":"; + } + set protocol(v) { + const copyURL = { ...this._url }; + + const possibleFailure = whatwgURL.basicURLParse(v + ":", { url: copyURL, stateOverride: "scheme start" }); + if (possibleFailure === null) { + throw new TypeError(`Could not parse the URL after setting the procol to "${v}"`); + } + + if (copyURL.scheme !== "http" && copyURL.scheme !== "https") { + return; + } + + this._locationObjectSetterNavigate(copyURL); + } + + get host() { + const url = this._url; + + if (url.host === null) { + return ""; + } + if (url.port === null) { + return whatwgURL.serializeHost(url.host); + } + + return whatwgURL.serializeHost(url.host) + ":" + whatwgURL.serializeInteger(url.port); + } + set host(v) { + const copyURL = { ...this._url }; + + if (copyURL.cannotBeABaseURL) { + return; + } + + whatwgURL.basicURLParse(v, { url: copyURL, stateOverride: "host" }); + + this._locationObjectSetterNavigate(copyURL); + } + + get hostname() { + if (this._url.host === null) { + return ""; + } + + return whatwgURL.serializeHost(this._url.host); + } + set hostname(v) { + const copyURL = { ...this._url }; + + if (copyURL.cannotBeABaseURL) { + return; + } + + whatwgURL.basicURLParse(v, { url: copyURL, stateOverride: "hostname" }); + + this._locationObjectSetterNavigate(copyURL); + } + + get port() { + if (this._url.port === null) { + return ""; + } + + return whatwgURL.serializeInteger(this._url.port); + } + set port(v) { + const copyURL = { ...this._url }; + + if (copyURL.host === null || copyURL.cannotBeABaseURL || copyURL.scheme === "file") { + return; + } + + whatwgURL.basicURLParse(v, { url: copyURL, stateOverride: "port" }); + + this._locationObjectSetterNavigate(copyURL); + } + + get pathname() { + const url = this._url; + + if (url.cannotBeABaseURL) { + return url.path[0]; + } + + return "/" + url.path.join("/"); + } + set pathname(v) { + const copyURL = { ...this._url }; + + if (copyURL.cannotBeABaseURL) { + return; + } + + copyURL.path = []; + whatwgURL.basicURLParse(v, { url: copyURL, stateOverride: "path start" }); + + this._locationObjectSetterNavigate(copyURL); + } + + get search() { + if (this._url.query === null || this._url.query === "") { + return ""; + } + + return "?" + this._url.query; + } + set search(v) { + const copyURL = { ...this._url }; + + if (v === "") { + copyURL.query = null; + } else { + const input = v[0] === "?" ? v.substring(1) : v; + copyURL.query = ""; + whatwgURL.basicURLParse(input, { + url: copyURL, + stateOverride: "query", + encodingOverride: this._relevantDocument.charset + }); + } + + this._locationObjectSetterNavigate(copyURL); + } + + get hash() { + if (this._url.fragment === null || this._url.fragment === "") { + return ""; + } + + return "#" + this._url.fragment; + } + set hash(v) { + const copyURL = { ...this._url }; + + if (copyURL.scheme === "javascript") { + return; + } + + if (v === "") { + copyURL.fragment = null; + } else { + const input = v[0] === "#" ? v.substring(1) : v; + copyURL.fragment = ""; + whatwgURL.basicURLParse(input, { url: copyURL, stateOverride: "fragment" }); + } + + this._locationObjectSetterNavigate(copyURL); + } + + assign(url) { + // Should be entry settings object; oh well + const parsedURL = parseURLToResultingURLRecord(url, this._relevantDocument); + + if (parsedURL === null) { + throw DOMException.create(this._globalObject, [ + `Could not resolve the given string "${url}" relative to the base URL "${this._relevantDocument.URL}"`, + "SyntaxError" + ]); + } + + this._locationObjectNavigate(parsedURL); + } + + replace(url) { + // Should be entry settings object; oh well + const parsedURL = parseURLToResultingURLRecord(url, this._relevantDocument); + + if (parsedURL === null) { + throw DOMException.create(this._globalObject, [ + `Could not resolve the given string "${url}" relative to the base URL "${this._relevantDocument.URL}"`, + "SyntaxError" + ]); + } + + this._locationObjectNavigate(parsedURL, { replacement: true }); + } + + reload() { + const flags = { replace: true, reloadTriggered: true, exceptionsEnabled: true }; + navigate(this._relevantDocument._defaultView, this._url, flags); + } +}; |