diff options
Diffstat (limited to 'op_crates')
-rw-r--r-- | op_crates/fetch/26_fetch.js | 21 | ||||
-rw-r--r-- | op_crates/fetch/lib.rs | 16 | ||||
-rw-r--r-- | op_crates/web/12_location.js | 227 | ||||
-rw-r--r-- | op_crates/web/lib.deno_web.d.ts | 66 | ||||
-rw-r--r-- | op_crates/web/lib.rs | 4 |
5 files changed, 323 insertions, 11 deletions
diff --git a/op_crates/fetch/26_fetch.js b/op_crates/fetch/26_fetch.js index 379c88e2f..0d405d4ec 100644 --- a/op_crates/fetch/26_fetch.js +++ b/op_crates/fetch/26_fetch.js @@ -5,6 +5,7 @@ // provided by "deno_web" const { URLSearchParams } = window.__bootstrap.url; + const { getLocationHref } = window.__bootstrap.location; const { requiredArguments } = window.__bootstrap.fetchUtil; const { ReadableStream, isReadableStreamDisturbed } = @@ -987,8 +988,10 @@ this.credentials = input.credentials; this._stream = input._stream; } else { - // TODO(nayeemrmn): Base from `--location` when implemented and set. - this.url = new URL(String(input)).href; + const baseUrl = getLocationHref(); + this.url = baseUrl != null + ? new URL(String(input), baseUrl).href + : new URL(String(input)).href; } if (init && "method" in init && init.method) { @@ -1175,20 +1178,25 @@ } } + let baseUrl = null; + + function setBaseUrl(href) { + baseUrl = href; + } + function sendFetchReq(url, method, headers, body, clientRid) { let headerArray = []; if (headers) { headerArray = Array.from(headers.entries()); } - const args = { + return opFetch({ method, url, + baseUrl, headers: headerArray, clientRid, - }; - - return opFetch(args, body); + }, body); } async function fetch(input, init) { @@ -1385,6 +1393,7 @@ Blob, DomFile, FormData, + setBaseUrl, fetch, Request, Response, diff --git a/op_crates/fetch/lib.rs b/op_crates/fetch/lib.rs index 91e44f75c..c2e458d89 100644 --- a/op_crates/fetch/lib.rs +++ b/op_crates/fetch/lib.rs @@ -100,12 +100,12 @@ where struct FetchArgs { method: Option<String>, url: String, + base_url: Option<String>, headers: Vec<(String, String)>, client_rid: Option<u32>, } let args: FetchArgs = serde_json::from_value(args)?; - let url = args.url; let client = if let Some(rid) = args.client_rid { let state_ = state.borrow(); @@ -125,10 +125,16 @@ where None => Method::GET, }; - let url_ = Url::parse(&url)?; + let base_url = match args.base_url { + Some(base_url) => Some(Url::parse(&base_url)?), + _ => None, + }; + let url = Url::options() + .base_url(base_url.as_ref()) + .parse(&args.url)?; // Check scheme before asking for net permission - let scheme = url_.scheme(); + let scheme = url.scheme(); if scheme != "http" && scheme != "https" { return Err(type_error(format!("scheme '{}' not supported", scheme))); } @@ -136,10 +142,10 @@ where { let state_ = state.borrow(); let permissions = state_.borrow::<FP>(); - permissions.check_net_url(&url_)?; + permissions.check_net_url(&url)?; } - let mut request = client.request(method, url_); + let mut request = client.request(method, url); match data.len() { 0 => {} diff --git a/op_crates/web/12_location.js b/op_crates/web/12_location.js new file mode 100644 index 000000000..d56ccc1e4 --- /dev/null +++ b/op_crates/web/12_location.js @@ -0,0 +1,227 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +((window) => { + const { URL } = window.__bootstrap.url; + const locationConstructorKey = Symbol("locationConstuctorKey"); + + class Location { + constructor(href, key) { + if (key != locationConstructorKey) { + throw new TypeError("Illegal constructor."); + } + const url = new URL(href); + Object.defineProperties(this, { + hash: { + get() { + return url.hash; + }, + set() { + throw new DOMException( + `Cannot set "location.hash".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + host: { + get() { + return url.host; + }, + set() { + throw new DOMException( + `Cannot set "location.host".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + hostname: { + get() { + return url.hostname; + }, + set() { + throw new DOMException( + `Cannot set "location.hostname".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + href: { + get() { + return href; + }, + set() { + throw new DOMException( + `Cannot set "location.href".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + origin: { + get() { + return url.origin; + }, + enumerable: true, + }, + password: { + get() { + return url.password; + }, + set() { + throw new DOMException( + `Cannot set "location.password".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + pathname: { + get() { + return url.pathname; + }, + set() { + throw new DOMException( + `Cannot set "location.pathname".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + port: { + get() { + return url.port; + }, + set() { + throw new DOMException( + `Cannot set "location.port".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + protocol: { + get() { + return url.protocol; + }, + set() { + throw new DOMException( + `Cannot set "location.protocol".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + search: { + get() { + return url.search; + }, + set() { + throw new DOMException( + `Cannot set "location.search".`, + "NotSupportedError", + ); + }, + 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. + return { + length: 0, + item: () => null, + contains: () => false, + }; + }, + enumerable: true, + }, + assign: { + value: function assign() { + throw new DOMException( + `Cannot call "location.assign()".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + reload: { + value: function reload() { + throw new DOMException( + `Cannot call "location.reload()".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + replace: { + value: function replace() { + throw new DOMException( + `Cannot call "location.replace()".`, + "NotSupportedError", + ); + }, + enumerable: true, + }, + toString: { + value: function toString() { + return href; + }, + enumerable: true, + }, + }); + } + } + + Object.defineProperties(Location.prototype, { + [Symbol.toStringTag]: { + value: "Location", + configurable: true, + }, + }); + + let location = null; + + function setLocationHref(href) { + location = new Location(href, locationConstructorKey); + } + + window.__bootstrap = (window.__bootstrap || {}); + window.__bootstrap.location = { + locationConstructorDescriptor: { + value: Location, + configurable: true, + writable: true, + }, + locationDescriptor: { + get() { + if (location == null) { + throw new ReferenceError( + `Access to "location", run again with --location <href>.`, + ); + } + return location; + }, + set() { + throw new DOMException(`Cannot set "location".`, "NotSupportedError"); + }, + enumerable: true, + }, + setLocationHref, + getLocationHref() { + return location?.href; + }, + }; +})(this); diff --git a/op_crates/web/lib.deno_web.d.ts b/op_crates/web/lib.deno_web.d.ts index 33d867753..491a0ee84 100644 --- a/op_crates/web/lib.deno_web.d.ts +++ b/op_crates/web/lib.deno_web.d.ts @@ -312,3 +312,69 @@ 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; diff --git a/op_crates/web/lib.rs b/op_crates/web/lib.rs index 958d11177..33bb0a33f 100644 --- a/op_crates/web/lib.rs +++ b/op_crates/web/lib.rs @@ -62,6 +62,10 @@ pub fn init(isolate: &mut JsRuntime) { ), ("deno:op_crates/web/11_url.js", include_str!("11_url.js")), ( + "deno:op_crates/web/12_location.js", + include_str!("12_location.js"), + ), + ( "deno:op_crates/web/21_filereader.js", include_str!("21_filereader.js"), ), |