mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
fix(op_crates/web): Use WorkerLocation for location in workers (#9084)
This commit is contained in:
parent
f4dbb267c6
commit
7db0605d45
12 changed files with 277 additions and 100 deletions
72
cli/dts/lib.deno.window.d.ts
vendored
72
cli/dts/lib.deno.window.d.ts
vendored
|
@ -49,3 +49,75 @@ declare function confirm(message?: string): boolean;
|
|||
* @param defaultValue
|
||||
*/
|
||||
declare function prompt(message?: string, defaultValue?: string): string | null;
|
||||
|
||||
// TODO(nayeemrmn): Move this to `op_crates/web` where its implementation is.
|
||||
// The types there must first be split into window, worker and global types.
|
||||
/** The location (URL) of the object it is linked to. Changes done on it are
|
||||
* reflected on the object it relates to. Accessible via
|
||||
* `globalThis.location`. */
|
||||
declare class Location {
|
||||
constructor();
|
||||
/** Returns a DOMStringList object listing the origins of the ancestor
|
||||
* browsing contexts, from the parent browsing context to the top-level
|
||||
* browsing context.
|
||||
*
|
||||
* Always empty in Deno. */
|
||||
readonly ancestorOrigins: DOMStringList;
|
||||
/** Returns the Location object's URL's fragment (includes leading "#" if
|
||||
* non-empty).
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
hash: string;
|
||||
/** Returns the Location object's URL's host and port (if different from the
|
||||
* default port for the scheme).
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
host: string;
|
||||
/** Returns the Location object's URL's host.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
hostname: string;
|
||||
/** Returns the Location object's URL.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
href: string;
|
||||
toString(): string;
|
||||
/** Returns the Location object's URL's origin. */
|
||||
readonly origin: string;
|
||||
/** Returns the Location object's URL's path.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
pathname: string;
|
||||
/** Returns the Location object's URL's port.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
port: string;
|
||||
/** Returns the Location object's URL's scheme.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
protocol: string;
|
||||
/** Returns the Location object's URL's query (includes leading "?" if
|
||||
* non-empty).
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
search: string;
|
||||
/** Navigates to the given URL.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
assign(url: string): void;
|
||||
/** Reloads the current page.
|
||||
*
|
||||
* Disabled in Deno. */
|
||||
reload(): void;
|
||||
/** @deprecated */
|
||||
reload(forcedReload: boolean): void;
|
||||
/** Removes the current page from the session history and navigates to the
|
||||
* given URL.
|
||||
*
|
||||
* Disabled in Deno. */
|
||||
replace(url: string): void;
|
||||
}
|
||||
|
||||
// TODO(nayeemrmn): Move this to `op_crates/web` where its implementation is.
|
||||
// The types there must first be split into window, worker and global types.
|
||||
declare var location: Location;
|
||||
|
|
23
cli/dts/lib.deno.worker.d.ts
vendored
23
cli/dts/lib.deno.worker.d.ts
vendored
|
@ -58,3 +58,26 @@ declare var onerror:
|
|||
declare var close: () => void;
|
||||
declare var name: string;
|
||||
declare var postMessage: (message: any) => void;
|
||||
|
||||
// TODO(nayeemrmn): Move this to `op_crates/web` where its implementation is.
|
||||
// The types there must first be split into window, worker and global types.
|
||||
/** The absolute location of the script executed by the Worker. Such an object
|
||||
* is initialized for each worker and is available via the
|
||||
* WorkerGlobalScope.location property obtained by calling self.location. */
|
||||
declare class WorkerLocation {
|
||||
constructor();
|
||||
readonly hash: string;
|
||||
readonly host: string;
|
||||
readonly hostname: string;
|
||||
readonly href: string;
|
||||
toString(): string;
|
||||
readonly origin: string;
|
||||
readonly pathname: string;
|
||||
readonly port: string;
|
||||
readonly protocol: string;
|
||||
readonly search: string;
|
||||
}
|
||||
|
||||
// TODO(nayeemrmn): Move this to `op_crates/web` where its implementation is.
|
||||
// The types there must first be split into window, worker and global types.
|
||||
declare var location: WorkerLocation;
|
||||
|
|
|
@ -1437,7 +1437,10 @@ fn location_arg<'a, 'b>() -> Arg<'a, 'b> {
|
|||
if url.is_err() {
|
||||
return Err("Failed to parse URL".to_string());
|
||||
}
|
||||
if !["http", "https"].contains(&url.unwrap().scheme()) {
|
||||
let mut url = url.unwrap();
|
||||
url.set_username("").unwrap();
|
||||
url.set_password(None).unwrap();
|
||||
if !["http", "https"].contains(&url.scheme()) {
|
||||
return Err("Expected protocol \"http\" or \"https\"".to_string());
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -6,12 +6,10 @@ Location {
|
|||
hostname: [Getter/Setter],
|
||||
href: [Getter/Setter],
|
||||
origin: [Getter],
|
||||
password: [Getter/Setter],
|
||||
pathname: [Getter/Setter],
|
||||
port: [Getter/Setter],
|
||||
protocol: [Getter/Setter],
|
||||
search: [Getter/Setter],
|
||||
username: [Getter/Setter],
|
||||
ancestorOrigins: [Getter],
|
||||
assign: [Function: assign],
|
||||
reload: [Function: reload],
|
||||
|
|
1
cli/tests/079_location_authentication.ts
Normal file
1
cli/tests/079_location_authentication.ts
Normal file
|
@ -0,0 +1 @@
|
|||
console.log(location.href);
|
3
cli/tests/079_location_authentication.ts.out
Normal file
3
cli/tests/079_location_authentication.ts.out
Normal file
|
@ -0,0 +1,3 @@
|
|||
[WILDCARD]
|
||||
https://baz/qux
|
||||
[WILDCARD]
|
|
@ -2651,6 +2651,11 @@ itest!(_078_unload_on_exit {
|
|||
output: "078_unload_on_exit.ts.out",
|
||||
});
|
||||
|
||||
itest!(_079_location_authentication {
|
||||
args: "run --location https://foo:bar@baz/qux 079_location_authentication.ts",
|
||||
output: "079_location_authentication.ts.out",
|
||||
});
|
||||
|
||||
itest!(js_import_detect {
|
||||
args: "run --quiet --reload js_import_detect.ts",
|
||||
output: "js_import_detect.ts.out",
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
onmessage = function (): void {
|
||||
postMessage(self.location.href);
|
||||
postMessage(
|
||||
`${location.href}, ${location instanceof WorkerLocation}`,
|
||||
);
|
||||
close();
|
||||
};
|
||||
|
|
|
@ -648,7 +648,7 @@ Deno.test({
|
|||
new URL("subdir/worker_location.ts", import.meta.url).href;
|
||||
const w = new Worker(workerModuleHref, { type: "module" });
|
||||
w.onmessage = (e): void => {
|
||||
assertEquals(e.data, workerModuleHref);
|
||||
assertEquals(e.data, `${workerModuleHref}, true`);
|
||||
promise.resolve();
|
||||
};
|
||||
w.postMessage("Hello, world!");
|
||||
|
|
|
@ -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;
|
||||
|
|
66
op_crates/web/lib.deno_web.d.ts
vendored
66
op_crates/web/lib.deno_web.d.ts
vendored
|
@ -313,69 +313,3 @@ declare var FileReader: {
|
|||
readonly EMPTY: number;
|
||||
readonly LOADING: number;
|
||||
};
|
||||
|
||||
/** The location (URL) of the object it is linked to. Changes done on it are
|
||||
* reflected on the object it relates to. Accessible via
|
||||
* `globalThis.location`. */
|
||||
declare class Location {
|
||||
constructor();
|
||||
/** Returns a DOMStringList object listing the origins of the ancestor
|
||||
* browsing contexts, from the parent browsing context to the top-level
|
||||
* browsing context.
|
||||
*
|
||||
* Always empty in Deno. */
|
||||
readonly ancestorOrigins: DOMStringList;
|
||||
/** Returns the Location object's URL's fragment (includes leading "#" if non-empty).
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
hash: string;
|
||||
/** Returns the Location object's URL's host and port (if different from the default port for the scheme).
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
host: string;
|
||||
/** Returns the Location object's URL's host.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
hostname: string;
|
||||
/** Returns the Location object's URL.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
href: string;
|
||||
toString(): string;
|
||||
/** Returns the Location object's URL's origin. */
|
||||
readonly origin: string;
|
||||
/** Returns the Location object's URL's path.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
pathname: string;
|
||||
/** Returns the Location object's URL's port.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
port: string;
|
||||
/** Returns the Location object's URL's scheme.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
protocol: string;
|
||||
/** Returns the Location object's URL's query (includes leading "?" if
|
||||
* non-empty).
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
search: string;
|
||||
/** Navigates to the given URL.
|
||||
*
|
||||
* Cannot be set in Deno. */
|
||||
assign(url: string): void;
|
||||
/** Reloads the current page.
|
||||
*
|
||||
* Disabled in Deno. */
|
||||
reload(): void;
|
||||
/** @deprecated */
|
||||
reload(forcedReload: boolean): void;
|
||||
/** Removes the current page from the session history and navigates to the
|
||||
* given URL.
|
||||
*
|
||||
* Disabled in Deno. */
|
||||
replace(url: string): void;
|
||||
}
|
||||
|
||||
declare var location: Location;
|
||||
|
|
|
@ -197,8 +197,6 @@ delete Object.prototype.__proto__;
|
|||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
|
||||
const windowOrWorkerGlobalScope = {
|
||||
Location: location.locationConstructorDescriptor,
|
||||
location: location.locationDescriptor,
|
||||
Blob: util.nonEnumerable(fetch.Blob),
|
||||
ByteLengthQueuingStrategy: util.nonEnumerable(
|
||||
streams.ByteLengthQueuingStrategy,
|
||||
|
@ -257,6 +255,8 @@ delete Object.prototype.__proto__;
|
|||
windowOrWorkerGlobalScope.console.enumerable = false;
|
||||
|
||||
const mainRuntimeGlobalProperties = {
|
||||
Location: location.locationConstructorDescriptor,
|
||||
location: location.locationDescriptor,
|
||||
Window: globalInterfaces.windowConstructorDescriptor,
|
||||
window: util.readOnly(globalThis),
|
||||
self: util.readOnly(globalThis),
|
||||
|
@ -272,6 +272,8 @@ delete Object.prototype.__proto__;
|
|||
};
|
||||
|
||||
const workerRuntimeGlobalProperties = {
|
||||
WorkerLocation: location.workerLocationConstructorDescriptor,
|
||||
location: location.workerLocationDescriptor,
|
||||
WorkerGlobalScope: globalInterfaces.workerGlobalScopeConstructorDescriptor,
|
||||
DedicatedWorkerGlobalScope:
|
||||
globalInterfaces.dedicatedWorkerGlobalScopeConstructorDescriptor,
|
||||
|
|
Loading…
Add table
Reference in a new issue