summaryrefslogtreecommitdiff
path: root/op_crates/web/12_location.js
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2021-01-17 15:28:54 +0000
committerGitHub <noreply@github.com>2021-01-17 16:28:54 +0100
commit7db0605d456559f1ca9447e6fa778559fe50cc95 (patch)
tree8607446306b6e526dab149a465cac3e3d825b96b /op_crates/web/12_location.js
parentf4dbb267c6672f92605bc204b10ad9a96d160ef4 (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.js188
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;