mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-28 12:32:37 +03:00
guide: Add a user-facing web-sys
section
This commit is contained in:
parent
723ed6e856
commit
86796f8a03
@ -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)
|
||||
|
@ -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<FnMut(...)>`, 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
|
||||
|
15
guide/src/web-sys/cargo-features.md
Normal file
15
guide/src/web-sys/cargo-features.md
Normal file
@ -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
|
29
guide/src/web-sys/examples/2d-canvas.md
Normal file
29
guide/src/web-sys/examples/2d-canvas.md
Normal file
@ -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 `<canvas>` element, creates a 2D rendering context, and draws the
|
||||
smiley face.
|
||||
|
||||
```rust
|
||||
{{#include ../../../../examples/canvas/src/lib.rs}}
|
||||
```
|
BIN
guide/src/web-sys/examples/2d-canvas.png
Normal file
BIN
guide/src/web-sys/examples/2d-canvas.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
23
guide/src/web-sys/examples/fetch.md
Normal file
23
guide/src/web-sys/examples/fetch.md
Normal file
@ -0,0 +1,23 @@
|
||||
# The `fetch` API
|
||||
|
||||
This example uses the `fetch` API to make an HTTP request to the GitHub API and
|
||||
then parses the resulting JSON.
|
||||
|
||||
[See the full source at
|
||||
`wasm-bindgen/examples/fetch`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/fetch)
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables a number of features related to the `fetch` API and
|
||||
types used: `Headers`, `Request`, etc. It also enables `wasm-bindgen`'s `serde`
|
||||
support.
|
||||
|
||||
```toml
|
||||
{{#include ../../../../examples/fetch/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../../examples/fetch/src/lib.rs}}
|
||||
```
|
3
guide/src/web-sys/examples/index.md
Normal file
3
guide/src/web-sys/examples/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Examples of using `web-sys`
|
||||
|
||||
This subsection contains examples of using the `web-sys` crate.
|
36
guide/src/web-sys/examples/web-audio.md
Normal file
36
guide/src/web-sys/examples/web-audio.md
Normal file
@ -0,0 +1,36 @@
|
||||
# WebAudio
|
||||
|
||||
This example creates an [FM
|
||||
oscillator](https://en.wikipedia.org/wiki/Frequency_modulation_synthesis) using
|
||||
the [WebAudio
|
||||
API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) and
|
||||
`web-sys`.
|
||||
|
||||
[See the full source at
|
||||
`wasm-bindgen/examples/webaudio`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webaudio)
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables the types needed to use the relevant bits of the
|
||||
WebAudio API.
|
||||
|
||||
```toml
|
||||
{{#include ../../../../examples/webaudio/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
The Rust code implements the FM oscillator.
|
||||
|
||||
```rust
|
||||
{{#include ../../../../examples/webaudio/src/lib.rs}}
|
||||
```
|
||||
|
||||
## `index.js`
|
||||
|
||||
A small bit of JavaScript glues the rust module to input widgets and translates
|
||||
events into calls into wasm code.
|
||||
|
||||
```js
|
||||
{{#include ../../../../examples/webaudio/index.js}}
|
||||
```
|
20
guide/src/web-sys/function-overloads.md
Normal file
20
guide/src/web-sys/function-overloads.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Function Overloads
|
||||
|
||||
Many Web APIs are overloaded to take different types of arguments or to skip
|
||||
arguments completely. `web-sys` contains multiple bindings for these functions
|
||||
that each specialize to a particular overload and set of argument types.
|
||||
|
||||
For example, [the `fetch` API][mdn-fetch] can be given a URL string, or a
|
||||
`Request` object, and it might also optionally be given a `RequestInit` options
|
||||
object. Therefore, we end up with these `web-sys` functions that all bind to the
|
||||
`window.fetch` function:
|
||||
|
||||
* [`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)
|
||||
|
||||
Note that different overloads can use different interfaces, and therefore can
|
||||
require different sets of cargo features to be enabled.
|
||||
|
||||
[mdn-fetch]: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
|
23
guide/src/web-sys/index.md
Normal file
23
guide/src/web-sys/index.md
Normal file
@ -0,0 +1,23 @@
|
||||
# The `web-sys` Crate
|
||||
|
||||
The `web-sys` crate provides raw `wasm-bindgen` imports for all of the Web's
|
||||
APIs. This includes:
|
||||
|
||||
* `window.fetch`
|
||||
* `Node.prototype.appendChild`
|
||||
* WebGL
|
||||
* WebAudio
|
||||
* and many more!
|
||||
|
||||
It's sort of like the `libc` crate, but for the Web.
|
||||
|
||||
It does *not* include the JavaScript APIs that are guaranteed to exist in all
|
||||
standards-compliant ECMAScript environments, such as `Array`, `Date`, and
|
||||
`eval`. Bindings for these APIs can be found in [the `js-sys` crate][js-sys].
|
||||
|
||||
## API Documentation
|
||||
|
||||
[**Read the `web-sys` API documentation here!**][api]
|
||||
|
||||
[api]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/
|
||||
[js-sys]: https://crates.io/crates/js-sys
|
22
guide/src/web-sys/type-translations.md
Normal file
22
guide/src/web-sys/type-translations.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Type Translations in `web-sys`
|
||||
|
||||
Most of the types specified in [WebIDL (the interface definition language for
|
||||
all Web APIs)][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, `js_sys::Object` and `&mut [u8]`. Using
|
||||
`js_sys::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<FnMut(...)>`, 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/
|
61
guide/src/web-sys/using-web-sys.md
Normal file
61
guide/src/web-sys/using-web-sys.md
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user