diff options
author | Nayeem Rahman <nayeemrmn99@gmail.com> | 2021-01-17 15:28:54 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-17 16:28:54 +0100 |
commit | 7db0605d456559f1ca9447e6fa778559fe50cc95 (patch) | |
tree | 8607446306b6e526dab149a465cac3e3d825b96b /op_crates/web/12_location.js | |
parent | f4dbb267c6672f92605bc204b10ad9a96d160ef4 (diff) |
fix(op_crates/web): Use WorkerLocation for location in workers (#9084)
Diffstat (limited to 'op_crates/web/12_location.js')
-rw-r--r-- | op_crates/web/12_location.js | 188 |
1 files changed, 161 insertions, 27 deletions
diff --git a/op_crates/web/12_location.js b/op_crates/web/12_location.js index 79a9151f1..d6a132413 100644 --- a/op_crates/web/12_location.js +++ b/op_crates/web/12_location.js @@ -4,12 +4,19 @@ const { URL } = window.__bootstrap.url; const locationConstructorKey = Symbol("locationConstuctorKey"); + // The differences between the definitions of `Location` and `WorkerLocation` + // are because of the `LegacyUnforgeable` attribute only specified upon + // `Location`'s properties. See: + // - https://html.spec.whatwg.org/multipage/history.html#the-location-interface + // - https://heycam.github.io/webidl/#LegacyUnforgeable class Location { - constructor(href, key) { + constructor(href = null, key = null) { if (key != locationConstructorKey) { throw new TypeError("Illegal constructor."); } const url = new URL(href); + url.username = ""; + url.password = ""; Object.defineProperties(this, { hash: { get() { @@ -49,7 +56,7 @@ }, href: { get() { - return href; + return url.href; }, set() { throw new DOMException( @@ -65,18 +72,6 @@ }, enumerable: true, }, - password: { - get() { - return url.password; - }, - set() { - throw new DOMException( - `Cannot set "location.password".`, - "NotSupportedError", - ); - }, - enumerable: true, - }, pathname: { get() { return url.pathname; @@ -125,18 +120,6 @@ }, enumerable: true, }, - username: { - get() { - return url.username; - }, - set() { - throw new DOMException( - `Cannot set "location.username".`, - "NotSupportedError", - ); - }, - enumerable: true, - }, ancestorOrigins: { get() { // TODO(nayeemrmn): Replace with a `DOMStringList` instance. @@ -177,7 +160,7 @@ }, toString: { value: function toString() { - return href; + return url.href; }, enumerable: true, }, @@ -192,10 +175,144 @@ }, }); + const workerLocationUrls = new WeakMap(); + + class WorkerLocation { + constructor(href = null, key = null) { + if (key != locationConstructorKey) { + throw new TypeError("Illegal constructor."); + } + const url = new URL(href); + url.username = ""; + url.password = ""; + workerLocationUrls.set(this, url); + } + } + + Object.defineProperties(WorkerLocation.prototype, { + hash: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.hash; + }, + configurable: true, + enumerable: true, + }, + host: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.host; + }, + configurable: true, + enumerable: true, + }, + hostname: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.hostname; + }, + configurable: true, + enumerable: true, + }, + href: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.href; + }, + configurable: true, + enumerable: true, + }, + origin: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.origin; + }, + configurable: true, + enumerable: true, + }, + pathname: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.pathname; + }, + configurable: true, + enumerable: true, + }, + port: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.port; + }, + configurable: true, + enumerable: true, + }, + protocol: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.protocol; + }, + configurable: true, + enumerable: true, + }, + search: { + get() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.search; + }, + configurable: true, + enumerable: true, + }, + toString: { + value: function toString() { + const url = workerLocationUrls.get(this); + if (url == null) { + throw new TypeError("Illegal invocation."); + } + return url.href; + }, + configurable: true, + enumerable: true, + writable: true, + }, + [Symbol.toStringTag]: { + value: "WorkerLocation", + configurable: true, + }, + }); + let location = null; + let workerLocation = null; function setLocationHref(href) { location = new Location(href, locationConstructorKey); + workerLocation = new WorkerLocation(href, locationConstructorKey); } window.__bootstrap = (window.__bootstrap || {}); @@ -205,6 +322,11 @@ configurable: true, writable: true, }, + workerLocationConstructorDescriptor: { + value: WorkerLocation, + configurable: true, + writable: true, + }, locationDescriptor: { get() { if (location == null) { @@ -219,6 +341,18 @@ }, enumerable: true, }, + workerLocationDescriptor: { + get() { + if (workerLocation == null) { + throw new Error( + `Assertion: "globalThis.location" must be defined in a worker.`, + ); + } + return workerLocation; + }, + configurable: true, + enumerable: true, + }, setLocationHref, getLocationHref() { return location?.href; |