diff --git a/crates/web-sys/Cargo.toml b/crates/web-sys/Cargo.toml index 51165e0b..d2c57969 100644 --- a/crates/web-sys/Cargo.toml +++ b/crates/web-sys/Cargo.toml @@ -3,6 +3,8 @@ name = "web-sys" version = "0.1.0" authors = ["The wasm-bindgen Developers"] readme = "./README.md" +homepage = "https://rustwasm.github.io/wasm-bindgen/web-sys/index.html" +documentation = "https://rustwasm.github.io/wasm-bindgen/api/web_sys/" [package.metadata.docs.rs] all-features = true diff --git a/crates/web-sys/README.md b/crates/web-sys/README.md index 15b763dd..a5fe2033 100644 --- a/crates/web-sys/README.md +++ b/crates/web-sys/README.md @@ -1,10 +1,10 @@ # `web-sys` -[Documentation](https://rustwasm.github.io/wasm-bindgen/api/web_sys/) - Raw bindings to Web APIs for projects using `wasm-bindgen`. -The book: https://rustwasm.github.io/wasm-bindgen/web-sys.html +* [The `web-sys` section of the `wasm-bindgen` + guide](https://rustwasm.github.io/wasm-bindgen/web-sys/index.html) +* [API Documentation](https://rustwasm.github.io/wasm-bindgen/api/web_sys/) ## Crate features diff --git a/examples/fetch/Cargo.toml b/examples/fetch/Cargo.toml index 62032710..5992a153 100644 --- a/examples/fetch/Cargo.toml +++ b/examples/fetch/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "fetch" version = "0.1.0" -authors = ["Andrew Chin "] +authors = ["The wasm-bindgen Developers"] [lib] crate-type = ["cdylib"] diff --git a/examples/fetch/src/lib.rs b/examples/fetch/src/lib.rs index 20bfbc73..523d4cf8 100644 --- a/examples/fetch/src/lib.rs +++ b/examples/fetch/src/lib.rs @@ -1,21 +1,23 @@ -extern crate wasm_bindgen; -extern crate js_sys; -extern crate web_sys; -extern crate wasm_bindgen_futures; extern crate futures; +extern crate js_sys; +extern crate wasm_bindgen; +extern crate wasm_bindgen_futures; +extern crate web_sys; #[macro_use] extern crate serde_derive; +use futures::{future, Future}; +use js_sys::Promise; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; -use js_sys::Promise; -use web_sys::{Request, RequestInit, RequestMode, Response, Window}; -use wasm_bindgen_futures::JsFuture; -use futures::{future, Future}; use wasm_bindgen_futures::future_to_promise; +use wasm_bindgen_futures::JsFuture; +use web_sys::{Request, RequestInit, RequestMode, Response, Window}; -// A struct to hold some data from the github Branch API. -// Note how we don't have to define every member -- serde will ignore extra data when deserializing +/// A struct to hold some data from the github Branch API. +/// +/// Note how we don't have to define every member -- serde will ignore extra +/// data when deserializing #[derive(Debug, Serialize, Deserialize)] pub struct Branch { pub name: String, @@ -42,37 +44,38 @@ pub struct Signature { #[wasm_bindgen] pub fn run() -> Promise { - let mut request_options = RequestInit::new(); - request_options.method("GET"); - request_options.mode(RequestMode::Cors); + let mut opts = RequestInit::new(); + opts.method("GET"); + opts.mode(RequestMode::Cors); - let req = Request::new_with_str_and_init("https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master", &request_options).unwrap(); + let request = Request::new_with_str_and_init( + "https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master", + &opts, + ).unwrap(); - // the RequestInit struct will eventually support setting headers, but that's missing right now - req.headers().set("Accept", "application/vnd.github.v3+json").unwrap(); + request.headers() + .set("Accept", "application/vnd.github.v3+json") + .unwrap(); - let req_promise = Window::fetch_with_request(&req); + let request_promise = Window::fetch_with_request(&request); - let to_return = JsFuture::from(req_promise).and_then(|resp_value| { - // resp_value is a Response object - assert!(resp_value.is_instance_of::()); - let resp: Response = resp_value.dyn_into().unwrap(); + let future = JsFuture::from(request_promise) + .and_then(|resp_value| { + // `resp_value` is a `Response` object. + assert!(resp_value.is_instance_of::()); + let resp: Response = resp_value.dyn_into().unwrap(); + resp.json() + }).and_then(|json_value: Promise| { + // Convert this other `Promise` into a rust `Future`. + JsFuture::from(json_value) + }).and_then(|json| { + // Use serde to parse the JSON into a struct. + let branch_info: Branch = json.into_serde().unwrap(); - resp.json() + // Send the `Branch` struct back to JS as an `Object`. + future::ok(JsValue::from_serde(&branch_info).unwrap()) + }); - - }).and_then(|json_value: Promise| { - // convert this other promise into a rust Future - JsFuture::from(json_value) - }).and_then(|json| { - // Use serde to parse this into a struct - let branch_info: Branch = json.into_serde().unwrap(); - - // Send the Branch struct back to javascript as an object - future::ok(JsValue::from_serde(&branch_info).unwrap()) - }); - - // Convert this rust future back into a javascript promise. - // Return it to javascript so that it can be driven to completion. - future_to_promise(to_return) + // Convert this Rust `Future` back into a JS `Promise`. + future_to_promise(future) } diff --git a/examples/webaudio/Cargo.toml b/examples/webaudio/Cargo.toml index 9f1f07f0..1db5cc9f 100644 --- a/examples/webaudio/Cargo.toml +++ b/examples/webaudio/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "webaudio" version = "0.1.0" -authors = ["Andrew Chin "] +authors = ["The wasm-bindgen Developers"] [lib] crate-type = ["cdylib"] diff --git a/examples/webaudio/index.html b/examples/webaudio/index.html index d091f797..108ea885 100644 --- a/examples/webaudio/index.html +++ b/examples/webaudio/index.html @@ -3,16 +3,9 @@ - - + (headphone users, please make sure your volume is not too loud!)
diff --git a/examples/webaudio/index.js b/examples/webaudio/index.js index 6488f5de..98be8c0c 100644 --- a/examples/webaudio/index.js +++ b/examples/webaudio/index.js @@ -1,40 +1,35 @@ -const rust = import('./webaudio'); +import('./webaudio').then(rust_module => { + let fm = null; + const play_button = document.getElementById("play"); + play_button.addEventListener("click", event => { + if (fm === null) { + fm = new rust_module.FmOsc(); + fm.set_note(50); + fm.set_fm_frequency(0); + fm.set_fm_amount(0); + fm.set_gain(0.8); + } + }); -// Most browsers don't let WebAudio autoplay without some interaction from the user. So once the module is loaded, -// it's passed to this function which will set up the UI elements for the user to interact with -function setup(rust_module) { - play = function() { - console.log("About to create some music!"); - fm = new rust_module.FmOsc(); + const primary_slider = document.getElementById("primary_input"); + primary_slider.addEventListener("input", event => { + if (fm) { + fm.set_note(event.target.value); + } + }); - fm.set_note(50); - fm.set_fm_frequency(0); - fm.set_fm_amount(0); - fm.set_gain(0.8); + const fm_freq = document.getElementById("fm_freq"); + fm_freq.addEventListener("input", event => { + if (fm) { + fm.set_fm_frequency(event.target.value); + } + }); - }; - - // create some UI elements - const primary_slider = document.getElementById("primary_input"); - primary_slider.oninput = (e) => { - fm.set_note(e.target.value); - }; - - const fm_freq = document.getElementById("fm_freq"); - fm_freq.oninput = (e) => { - fm.set_fm_frequency(e.target.value); - }; - - const fm_amount = document.getElementById("fm_amount"); - fm_amount.oninput = (e) => { - fm.set_fm_amount(e.target.value); - }; - - console.log("Ready! Press the play button!"); -} - - -rust.then(m => { - setup(m); + const fm_amount = document.getElementById("fm_amount"); + fm_amount.addEventListener("input", event => { + if (fm) { + fm.set_fm_amount(event.target.value); + } + }); }); diff --git a/examples/webaudio/package.json b/examples/webaudio/package.json index 3759f517..5cac0844 100644 --- a/examples/webaudio/package.json +++ b/examples/webaudio/package.json @@ -4,6 +4,7 @@ }, "devDependencies": { "webpack": "^4.16.5", - "webpack-serve": "^2.0.2" + "webpack-cli": "^2.0.10", + "webpack-dev-server": "^3.1.0" } } diff --git a/examples/webaudio/src/lib.rs b/examples/webaudio/src/lib.rs index dce8b554..73d17c6a 100644 --- a/examples/webaudio/src/lib.rs +++ b/examples/webaudio/src/lib.rs @@ -2,7 +2,9 @@ extern crate wasm_bindgen; extern crate web_sys; use wasm_bindgen::prelude::*; -use web_sys::{AudioContext, BaseAudioContext, AudioNode, AudioScheduledSourceNode, OscillatorType}; +use web_sys::{ + AudioContext, AudioNode, AudioScheduledSourceNode, BaseAudioContext, OscillatorType, +}; /// Converts a midi note to frequency /// @@ -32,16 +34,12 @@ pub struct FmOsc { fm_freq_ratio: f32, fm_gain_ratio: f32, - - } #[wasm_bindgen] impl FmOsc { #[wasm_bindgen(constructor)] pub fn new() -> FmOsc { - // TODO, how to throw from a constructor? - let ctx = web_sys::AudioContext::new().unwrap(); let primary; let fm_osc; @@ -51,14 +49,14 @@ impl FmOsc { { let base: &BaseAudioContext = ctx.as_ref(); - // create our web audio objects + // Create our web audio objects. primary = base.create_oscillator().unwrap(); fm_osc = base.create_oscillator().unwrap(); gain = base.create_gain().unwrap(); fm_gain = base.create_gain().unwrap(); } - // some initial settings: + // Some initial settings: primary.set_type(OscillatorType::Sine); primary.frequency().set_value(440.0); // A4 note gain.gain().set_value(0.0); // starts muted @@ -66,7 +64,6 @@ impl FmOsc { fm_osc.set_type(OscillatorType::Sine); fm_osc.frequency().set_value(0.0); - // Create base class references: { let primary_node: &AudioNode = primary.as_ref(); @@ -77,26 +74,36 @@ impl FmOsc { let destination = base.destination(); let destination_node: &AudioNode = destination.as_ref(); + // Connect the nodes up! - // connect them up: - - // The primary oscillator is routed through the gain node, so that it can control the overall output volume + // The primary oscillator is routed through the gain node, so that + // it can control the overall output volume. primary_node.connect_with_audio_node(gain.as_ref()).unwrap(); - // Then connect the gain node to the AudioContext destination (aka your speakers) + + // Then connect the gain node to the AudioContext destination (aka + // your speakers). gain_node.connect_with_audio_node(destination_node).unwrap(); - // the FM oscillator is connected to its own gain node, so it can control the amount of modulation - fm_osc_node.connect_with_audio_node(fm_gain.as_ref()).unwrap(); + // The FM oscillator is connected to its own gain node, so it can + // control the amount of modulation. + fm_osc_node + .connect_with_audio_node(fm_gain.as_ref()) + .unwrap(); - // Connect the FM oscillator to the frequency parameter of the main oscillator, so that the - // FM node can modulate its frequency - fm_gain_node.connect_with_audio_param(&primary.frequency()).unwrap(); + // Connect the FM oscillator to the frequency parameter of the main + // oscillator, so that the FM node can modulate its frequency. + fm_gain_node + .connect_with_audio_param(&primary.frequency()) + .unwrap(); } - - // start the oscillators! - AsRef::::as_ref(&primary).start().unwrap(); - AsRef::::as_ref(&fm_osc).start().unwrap(); + // Start the oscillators! + AsRef::::as_ref(&primary) + .start() + .unwrap(); + AsRef::::as_ref(&fm_osc) + .start() + .unwrap(); FmOsc { ctx, @@ -107,14 +114,17 @@ impl FmOsc { fm_freq_ratio: 0.0, fm_gain_ratio: 0.0, } - } - /// Sets the gain for this oscillator, between 0.0 and 1.0 + /// Sets the gain for this oscillator, between 0.0 and 1.0. #[wasm_bindgen] pub fn set_gain(&self, mut gain: f32) { - if gain > 1.0 { gain = 1.0; } - if gain < 0.0 { gain = 0.0; } + if gain > 1.0 { + gain = 1.0; + } + if gain < 0.0 { + gain = 0.0; + } self.gain.gain().set_value(gain); } @@ -122,11 +132,10 @@ impl FmOsc { pub fn set_primary_frequency(&self, freq: f32) { self.primary.frequency().set_value(freq); - // The frequency of the FM oscillator depends on the frequency of the primary oscillator, so - // we update the frequency of both in this method + // The frequency of the FM oscillator depends on the frequency of the + // primary oscillator, so we update the frequency of both in this method. self.fm_osc.frequency().set_value(self.fm_freq_ratio * freq); self.fm_gain.gain().set_value(self.fm_gain_ratio * freq); - } #[wasm_bindgen] @@ -135,21 +144,22 @@ impl FmOsc { self.set_primary_frequency(freq); } - /// This should be between 0 and 1, though higher values are accepted + /// This should be between 0 and 1, though higher values are accepted. #[wasm_bindgen] pub fn set_fm_amount(&mut self, amt: f32) { self.fm_gain_ratio = amt; - self.fm_gain.gain().set_value(self.fm_gain_ratio * self.primary.frequency().value()); - + self.fm_gain + .gain() + .set_value(self.fm_gain_ratio * self.primary.frequency().value()); } - /// This should be between 0 and 1, though higher values are accepted + /// This should be between 0 and 1, though higher values are accepted. #[wasm_bindgen] pub fn set_fm_frequency(&mut self, amt: f32) { self.fm_freq_ratio = amt; - self.fm_osc.frequency().set_value(self.fm_freq_ratio * self.primary.frequency().value()); + self.fm_osc + .frequency() + .set_value(self.fm_freq_ratio * self.primary.frequency().value()); } - - } diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index 89dfa890..587cb547 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -50,23 +50,35 @@ -------------------------------------------------------------------------------- -- [Contributing](./contributing.md) - - [Testing](./testing.md) - - [Internal Design](./design.md) - - [JS Objects in Rust](./design/js-objects-in-rust.md) - - [Exporting a function to JS](./design/exporting-rust.md) - - [Exporting a struct to JS](./design/exporting-rust-struct.md) - - [Importing a function from JS](./design/importing-js.md) - - [Importing a class from JS](./design/importing-js-struct.md) - - [Rust Type conversions](./design/rust-type-conversions.md) - - [Types in `wasm-bindgen`](./design/describe.md) - - [`js-sys`](./js-sys.md) - - [Testing](./js-sys/testing.md) - - [Adding More APIs](./js-sys/adding-more-apis.md) - - [`web-sys`](./web-sys.md) - - [Overview](./web-sys/overview.md) - - [Testing](./web-sys/testing.md) - - [Logging](./web-sys/logging.md) - - [Supporting More Web APIs](./web-sys/supporting-more-web-apis.md) - - [Publishing](./publishing.md) - - [Team](./team.md) +- [`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) + - [JS Objects in Rust](./contributing/design/js-objects-in-rust.md) + - [Exporting a function to JS](./contributing/design/exporting-rust.md) + - [Exporting a struct to JS](./contributing/design/exporting-rust-struct.md) + - [Importing a function from JS](./contributing/design/importing-js.md) + - [Importing a class from JS](./contributing/design/importing-js-struct.md) + - [Rust Type conversions](./contributing/design/rust-type-conversions.md) + - [Types in `wasm-bindgen`](./contributing/design/describe.md) + - [`js-sys`](./contributing/js-sys/index.md) + - [Testing](./contributing/js-sys/testing.md) + - [Adding More APIs](./contributing/js-sys/adding-more-apis.md) + - [`web-sys`](./contributing/web-sys/index.md) + - [Overview](./contributing/web-sys/overview.md) + - [Testing](./contributing/web-sys/testing.md) + - [Logging](./contributing/web-sys/logging.md) + - [Supporting More Web APIs](./contributing/web-sys/supporting-more-web-apis.md) + - [Publishing](./contributing/publishing.md) + - [Team](./contributing/team.md) diff --git a/guide/src/design/describe.md b/guide/src/contributing/design/describe.md similarity index 100% rename from guide/src/design/describe.md rename to guide/src/contributing/design/describe.md diff --git a/guide/src/design/exporting-rust-struct.md b/guide/src/contributing/design/exporting-rust-struct.md similarity index 100% rename from guide/src/design/exporting-rust-struct.md rename to guide/src/contributing/design/exporting-rust-struct.md diff --git a/guide/src/design/exporting-rust.md b/guide/src/contributing/design/exporting-rust.md similarity index 100% rename from guide/src/design/exporting-rust.md rename to guide/src/contributing/design/exporting-rust.md diff --git a/guide/src/design/importing-js-struct.md b/guide/src/contributing/design/importing-js-struct.md similarity index 100% rename from guide/src/design/importing-js-struct.md rename to guide/src/contributing/design/importing-js-struct.md diff --git a/guide/src/design/importing-js.md b/guide/src/contributing/design/importing-js.md similarity index 100% rename from guide/src/design/importing-js.md rename to guide/src/contributing/design/importing-js.md diff --git a/guide/src/design.md b/guide/src/contributing/design/index.md similarity index 100% rename from guide/src/design.md rename to guide/src/contributing/design/index.md diff --git a/guide/src/design/js-objects-in-rust.md b/guide/src/contributing/design/js-objects-in-rust.md similarity index 100% rename from guide/src/design/js-objects-in-rust.md rename to guide/src/contributing/design/js-objects-in-rust.md diff --git a/guide/src/design/rust-type-conversions.md b/guide/src/contributing/design/rust-type-conversions.md similarity index 100% rename from guide/src/design/rust-type-conversions.md rename to guide/src/contributing/design/rust-type-conversions.md diff --git a/guide/src/contributing.md b/guide/src/contributing/index.md similarity index 100% rename from guide/src/contributing.md rename to guide/src/contributing/index.md diff --git a/guide/src/js-sys/adding-more-apis.md b/guide/src/contributing/js-sys/adding-more-apis.md similarity index 100% rename from guide/src/js-sys/adding-more-apis.md rename to guide/src/contributing/js-sys/adding-more-apis.md diff --git a/guide/src/js-sys.md b/guide/src/contributing/js-sys/index.md similarity index 100% rename from guide/src/js-sys.md rename to guide/src/contributing/js-sys/index.md diff --git a/guide/src/js-sys/testing.md b/guide/src/contributing/js-sys/testing.md similarity index 100% rename from guide/src/js-sys/testing.md rename to guide/src/contributing/js-sys/testing.md diff --git a/guide/src/contributing/publishing.md b/guide/src/contributing/publishing.md new file mode 100644 index 00000000..0eedb7d8 --- /dev/null +++ b/guide/src/contributing/publishing.md @@ -0,0 +1,24 @@ +# Publishing New `wasm-bindgen` Releases + +1. Compile the `publish.rs` script: + + ``` + rustc publish.rs + ``` + +2. Bump every crate's minor version: + + ``` + # Make sure you are in the root of the wasm-bindgen repo! + ./publish bump + ``` + +3. Send a pull request for the version bump. + +4. After the pull request's CI is green and it has been + merged, publish to cargo: + + ``` + # Make sure you are in the root of the wasm-bindgen repo! + ./publish publish + ``` diff --git a/guide/src/team.md b/guide/src/contributing/team.md similarity index 100% rename from guide/src/team.md rename to guide/src/contributing/team.md diff --git a/guide/src/testing.md b/guide/src/contributing/testing.md similarity index 100% rename from guide/src/testing.md rename to guide/src/contributing/testing.md diff --git a/guide/src/contributing/web-sys/index.md b/guide/src/contributing/web-sys/index.md new file mode 100644 index 00000000..1b6d5155 --- /dev/null +++ b/guide/src/contributing/web-sys/index.md @@ -0,0 +1,10 @@ +# `web-sys` + +The `web-sys` crate provides raw bindings to all of the Web's APIs, and its +source lives at `wasm-bindgen/crates/web-sys`. + +The `web-sys` crate is **entirely** mechanically generated inside `build.rs` +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! diff --git a/guide/src/web-sys/logging.md b/guide/src/contributing/web-sys/logging.md similarity index 100% rename from guide/src/web-sys/logging.md rename to guide/src/contributing/web-sys/logging.md diff --git a/guide/src/web-sys/overview.md b/guide/src/contributing/web-sys/overview.md similarity index 100% rename from guide/src/web-sys/overview.md rename to guide/src/contributing/web-sys/overview.md diff --git a/guide/src/web-sys/supporting-more-web-apis.md b/guide/src/contributing/web-sys/supporting-more-web-apis.md similarity index 100% rename from guide/src/web-sys/supporting-more-web-apis.md rename to guide/src/contributing/web-sys/supporting-more-web-apis.md diff --git a/guide/src/web-sys/testing.md b/guide/src/contributing/web-sys/testing.md similarity index 100% rename from guide/src/web-sys/testing.md rename to guide/src/contributing/web-sys/testing.md diff --git a/guide/src/publishing.md b/guide/src/publishing.md deleted file mode 100644 index fa916332..00000000 --- a/guide/src/publishing.md +++ /dev/null @@ -1,40 +0,0 @@ -# Publishing New `wasm-bindgen` Releases - -* [ ] Make sure that your git working copy is clean. - -* [ ] Make sure that you are on the latest `master`: - - ``` - git pull origin master - ``` - -* [ ] Run `rustc ./publish.rs` - -* [ ] Run `./publish bump` - this will update all version numbers - -* [ ] Write a "0.X.Z" entry in the CHANGELOG.md - -* [ ] Commit the version bump: - - ``` - git commit -m "Bump to version 0.X.Z" - ``` - -* [ ] Send a PR to the `wasm-bindgen` repository, get it merged - -* [ ] Check out the merge commit of `wasm-bindgen` - -* [ ] Comment out the `[patch]` section in the root `Cargo.toml` that only - exists to make sure that `console_error_panic_hook` in tests is using - *this* `wasm-bindgen` rather than one from crates.io. - -* [ ] Run `rustc ./publish.rs` - -* [ ] Run `./publish publish` - -* [ ] Tag the release and push it: - - ``` - git tag 0.X.Z - git push origin --tags - ``` diff --git a/guide/src/web-sys.md b/guide/src/web-sys.md deleted file mode 100644 index 574a18b4..00000000 --- a/guide/src/web-sys.md +++ /dev/null @@ -1,103 +0,0 @@ -# `web-sys` - -The `web-sys` crate provides raw bindings to all of the Web's APIs, and its -source lives at `wasm-bindgen/crates/web-sys`. - -The `web-sys` crate is **entirely** mechanically generated inside `build.rs` -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 00000000..c3151600 --- /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 00000000..33b2ec94 --- /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 00000000..39408109 Binary files /dev/null and b/guide/src/web-sys/examples/2d-canvas.png differ diff --git a/guide/src/web-sys/examples/fetch.md b/guide/src/web-sys/examples/fetch.md new file mode 100644 index 00000000..79e1f810 --- /dev/null +++ b/guide/src/web-sys/examples/fetch.md @@ -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}} +``` diff --git a/guide/src/web-sys/examples/index.md b/guide/src/web-sys/examples/index.md new file mode 100644 index 00000000..6136b476 --- /dev/null +++ b/guide/src/web-sys/examples/index.md @@ -0,0 +1,3 @@ +# Examples of using `web-sys` + +This subsection contains examples of using the `web-sys` crate. diff --git a/guide/src/web-sys/examples/web-audio.md b/guide/src/web-sys/examples/web-audio.md new file mode 100644 index 00000000..6202a9aa --- /dev/null +++ b/guide/src/web-sys/examples/web-audio.md @@ -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}} +``` diff --git a/guide/src/web-sys/function-overloads.md b/guide/src/web-sys/function-overloads.md new file mode 100644 index 00000000..02c93af8 --- /dev/null +++ b/guide/src/web-sys/function-overloads.md @@ -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 diff --git a/guide/src/web-sys/index.md b/guide/src/web-sys/index.md new file mode 100644 index 00000000..68ac1e95 --- /dev/null +++ b/guide/src/web-sys/index.md @@ -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 diff --git a/guide/src/web-sys/type-translations.md b/guide/src/web-sys/type-translations.md new file mode 100644 index 00000000..77a8dab1 --- /dev/null +++ b/guide/src/web-sys/type-translations.md @@ -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`, 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 00000000..2b3950f3 --- /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