From 86796f8a034cddc1aafd4ea48f7a53abcdc1235b Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 10 Sep 2018 17:51:44 -0700 Subject: [PATCH] guide: Add a user-facing `web-sys` section --- guide/src/SUMMARY.md | 12 +++ guide/src/contributing/web-sys/index.md | 93 ----------------------- guide/src/web-sys/cargo-features.md | 15 ++++ guide/src/web-sys/examples/2d-canvas.md | 29 +++++++ guide/src/web-sys/examples/2d-canvas.png | Bin 0 -> 3799 bytes guide/src/web-sys/examples/fetch.md | 23 ++++++ guide/src/web-sys/examples/index.md | 3 + guide/src/web-sys/examples/web-audio.md | 36 +++++++++ guide/src/web-sys/function-overloads.md | 20 +++++ guide/src/web-sys/index.md | 23 ++++++ guide/src/web-sys/type-translations.md | 22 ++++++ guide/src/web-sys/using-web-sys.md | 61 +++++++++++++++ 12 files changed, 244 insertions(+), 93 deletions(-) create mode 100644 guide/src/web-sys/cargo-features.md create mode 100644 guide/src/web-sys/examples/2d-canvas.md create mode 100644 guide/src/web-sys/examples/2d-canvas.png create mode 100644 guide/src/web-sys/examples/fetch.md create mode 100644 guide/src/web-sys/examples/index.md create mode 100644 guide/src/web-sys/examples/web-audio.md create mode 100644 guide/src/web-sys/function-overloads.md create mode 100644 guide/src/web-sys/index.md create mode 100644 guide/src/web-sys/type-translations.md create mode 100644 guide/src/web-sys/using-web-sys.md diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index c9d6655f9..587cb5476 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -50,6 +50,18 @@ -------------------------------------------------------------------------------- +- [`web-sys`](./web-sys/index.md) + - [Using `web-sys`](./web-sys/using-web-sys.md) + - [Cargo Features](./web-sys/cargo-features.md) + - [Function Overloads](./web-sys/function-overloads.md) + - [Type Translations](./web-sys/type-translations.md) + - [Examples](./web-sys/examples/index.md) + - [The `fetch` API](./web-sys/examples/fetch.md) + - [2D Canvas](./web-sys/examples/2d-canvas.md) + - [WebAudio](./web-sys/examples/web-audio.md) + +-------------------------------------------------------------------------------- + - [Contributing](./contributing/index.md) - [Testing](./contributing/testing.md) - [Internal Design](./contributing/design/index.md) diff --git a/guide/src/contributing/web-sys/index.md b/guide/src/contributing/web-sys/index.md index 574a18b46..1b6d5155e 100644 --- a/guide/src/contributing/web-sys/index.md +++ b/guide/src/contributing/web-sys/index.md @@ -8,96 +8,3 @@ using `wasm-bindgen`'s WebIDL frontend and the WebIDL interface definitions for Web APIs. This means that `web-sys` isn't always the most ergonomic crate to use, but it's intended to provide verified and correct bindings to the web platform, and then better interfaces can be iterated on crates.io! - -### Using `web-sys` - -Let's say you want to use an API defined on the web. Chances are this API is -defined in `web-sys`, so let's go through some steps necessary to use it! - -First up, search the [api documentation][api] for your API. For example if -we're looking for JS's [`fetch`][jsfetch] API we'd start out by [searching for -`fetch`][search-fetch]. The first thing you'll probably notice is that there's -no function called `fetch`! Fear not, though, as the API exists in multiple -forms: - -* [`Window::fetch_with_str`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Window.html#method.fetch_with_str) -* [`Window::fetch_with_request`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Window.html#method.fetch_with_request) -* [`Window::fetch_with_str_and_init`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/str_and_inituct.Window.html#method.fetch_with_str_and_init) -* [`Window::fetch_with_request_and_init`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Window.html#method.fetch_with_request_and_init) - -What's happening here is that the [`fetch` function][fetchfn] actually supports -multiple signatures of arguments, and we've taken the WebIDL definition for this -function and expanded it to unique signatures in Rust (as Rust doesn't have -function name overloading). - -When an API is selected it should have documentation pointing at MDN indicating -what web API its binding. This is often a great way to double check arguments -and such as well, MDN is a great resource! You'll also notice in the -documentation that the API may require some `web-sys` Cargo features to be -activated. For example [`fetch_with_str`] requires the `Window` feature to be -activated. In general an API needs features corresponding to all the types -you'll find in the signature to be activated. - -To load up this API let's depend on `web-sys`: - -```toml -[dependencies] -wasm-bindgen = "0.2" -web-sys = { version = "0.1", features = ['Window'] } - -# Or optionally, -# [target.wasm32-unknown-unknown.dependencies] -# ... -``` - -> **Note**: Currently `web-sys` is not available on crates.io so you'll also -> need to do this in your manifest: -> -> ```toml -> [patch.crates-io] -> web-sys = { git = 'https://github.com/rustwasm/wasm-bindgen' } -> wasm-bindgen = { git = 'https://github.com/rustwasm/wasm-bindgen' } -> ``` - -And next up we can use the API like so: - -```rust -extern crate web_sys; -extern crate wasm_bindgen; - -use wasm_bindgen::prelude::*; -use web_sys::Window; - -#[wasm_bindgen] -pub fn run() { - let promise = Window::fetch_with_str("http://example.com/"); - // ... -} -``` - -and you should be good to go! - -### Type translations in `web-sys` - -Most of the types specified in WebIDL have relatively straightforward -translations into `web-sys`, but it's worth calling out a few in particular: - -* `BufferSource` and `ArrayBufferView` - these two types show up in a number of - APIs that generally deal with a buffer of bytes. We bind them in `web-sys` - with two different types, `Object` and `&mut [u8]`. Using `Object` allows - passing in arbitrary JS values which represent a view of bytes (like any typed - array object), and `&mut [u8]` allows using a raw slice in Rust. Unfortunately - we must pessimistically assume that JS will modify all slices as we don't - currently have information of whether they're modified or not. - -* Callbacks are all represented as `js_sys::Function`. This means that all - callbacks going through `web-sys` are a raw JS value. You can work with this - by either juggling actual `js_sys::Function` instances or you can create a - `Closure`, extract the underlying `JsValue` with `as_ref`, and - then use `JsCast::unchecked_ref` to convert it to a `js_sys::Function`. - -[api]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/ -[jsfetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API -[search-fetch]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/?search=fetch -[fetchfn]: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch -[`fetch_with_str`]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Window.html#method.fetch_with_str diff --git a/guide/src/web-sys/cargo-features.md b/guide/src/web-sys/cargo-features.md new file mode 100644 index 000000000..c31516001 --- /dev/null +++ b/guide/src/web-sys/cargo-features.md @@ -0,0 +1,15 @@ +# Cargo Features in `web-sys` + +To keep `web-sys` building as fast as possible, there is a cargo feature for +every type defined in `web-sys`. To access that type, you must enable its +feature. To access a method, you must enable the feature for its `self` type and +the features for each of its argument types. In the [API documentation][], every +method lists the features that are required to enable it. + +For example, [the `WebGlRenderingContext::compile_shader` function][compile_shader] requires these features: + +* `WebGlRenderingContext`, because that is the method's `self` type +* `WebGlShader`, because it takes an argument of that type + +[API documentation]: https://rustwasm.github.io/wasm-bindgen/api/web_sys +[compile_shader]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.WebGlRenderingContext.html#method.compile_shader diff --git a/guide/src/web-sys/examples/2d-canvas.md b/guide/src/web-sys/examples/2d-canvas.md new file mode 100644 index 000000000..33b2ec948 --- /dev/null +++ b/guide/src/web-sys/examples/2d-canvas.md @@ -0,0 +1,29 @@ +# 2D Canvas + +Drawing a smiley face with the 2D canvas API. This is a port of part of [this +MDN +tutorial](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#Moving_the_pen) +to `web-sys`. + +[See the full source at +`wasm-bindgen/examples/canvas`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/canvas) + +![A smiley face](./2d-canvas.png) + +## `Cargo.toml` + +The `Cargo.toml` enables features necessary to query the DOM and work with 2D +canvas. + +```toml +{{#include ../../../../examples/canvas/Cargo.toml}} +``` + +## `src/lib.rs` + +Gets the `` element, creates a 2D rendering context, and draws the +smiley face. + +```rust +{{#include ../../../../examples/canvas/src/lib.rs}} +``` diff --git a/guide/src/web-sys/examples/2d-canvas.png b/guide/src/web-sys/examples/2d-canvas.png new file mode 100644 index 0000000000000000000000000000000000000000..394081092aee119f31456ea1a3fa846642623b16 GIT binary patch literal 3799 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, extract the underlying `JsValue` with `as_ref`, and + then use `JsCast::unchecked_ref` to convert it to a `js_sys::Function`. + +[webidl]: https://heycam.github.io/webidl/ diff --git a/guide/src/web-sys/using-web-sys.md b/guide/src/web-sys/using-web-sys.md new file mode 100644 index 000000000..2b3950f3e --- /dev/null +++ b/guide/src/web-sys/using-web-sys.md @@ -0,0 +1,61 @@ +# Using `web-sys` + +## Add `web-sys` as a dependency to your `Cargo.toml` + +***Note:** `web-sys` is not available on crates.io yet, so you'll need to depend +on the git version of it, and of `wasm-bindgen`:* + +```toml +[dependencies] +wasm-bindgen = { git = "https://github.com/rustwasm/wasm-bindgen" } +web-sys = { + git = "https://github.com/rustwasm/wasm-bindgen", + features = [ + ] +} +``` + +## Enable the cargo features for the APIs you're using + +To keep build times super speedy, [`web-sys` gates each Web interface behind a +cargo feature](./cargo-features.html). Find the type or method you want to use +in the [API documentation][api]; it will list the features that must be enabled +to access that API. + +For example, if we're looking for [the `window.resizeTo` +function][js-resize-to], we would [search for `resizeTo` in the API +documentation][search-resize-to]. We would find [the +`web_sys::Window::resize_to` function][rust-resize-to], which requires the +`Window` feature. To get access to that function, we enable the `Window` feature +in `Cargo.toml`: + +```toml +web-sys = { + git = "https://github.com/rustwasm/wasm-bindgen", + features = [ + "Window", + ] +} +``` + +## Call the method! + +```rust +extern crate web_sys; +extern crate wasm_bindgen; + +use wasm_bindgen::prelude::*; +use web_sys::Window; + +#[wasm_bindgen] +pub fn make_the_window_small() { + // Resize the window to 500px by 500px. + Window::resize_to(500, 500) + .expect("could not resize the window"); +} +``` + +[api]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/ +[js-resize-to]: https://developer.mozilla.org/en-US/docs/Web/API/window/resizeTo +[search-resize-to]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/?search=resizeTo +[rust-resize-to]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Window.html#method.resize_to