• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

ci/H03-May-2022-178128

info/H03-May-2022-

src/H03-May-2022-23,01615,192

.cargo-checksum.jsonH A D03-May-202289 11

.cargo_vcs_info.jsonH A D01-Jan-197074 65

.gitignoreH A D01-Jul-201877 97

.travis.ymlH A D19-May-2019650 3733

CONTRIBUTING.mdH A D01-Jul-20182.2 KiB5635

Cargo.tomlH A D01-Jan-19702.6 KiB8773

Cargo.toml.orig-cargoH A D07-Oct-20192 KiB5545

LICENSE-APACHEH A D23-Apr-201710.6 KiB202169

LICENSE-MITH A D23-Apr-20171 KiB2622

README.mdH A D10-Oct-201920.6 KiB574509

Web.tomlH A D19-May-201939 32

build.rsH A D19-May-2019288 129

README.md

1<p align="center">
2    <img src="info/logo.png">
3</p>
4
5[![Build Status](https://api.travis-ci.org/koute/stdweb.svg)](https://travis-ci.org/koute/stdweb)
6[![Join the chat at https://gitter.im/stdweb-rs/stdweb](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/stdweb-rs/stdweb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7
8# A standard library for the client-side Web
9
10[![Documentation](https://docs.rs/stdweb/badge.svg)](https://docs.rs/stdweb/*/stdweb/)
11
12The goal of this crate is to provide Rust bindings to the Web APIs and to allow
13a high degree of interoperability between Rust and JavaScript.
14
15## Donate
16
17[![Become a patron](https://koute.github.io/img/become_a_patron_button.png)](https://www.patreon.com/koute)
18
19## Patrons
20
21This software was brought to you thanks to these wonderful people:
22  * Embark Studios
23  * Joe Narvaez
24  * Eduard Knyshov
25  * Anselm Eickhoff
26  * Johan Andersson
27  * Stephen Sugden
28  * is8ac
29
30Thank you!
31
32## Examples
33
34You can directly embed JavaScript code into Rust:
35
36```rust
37let message = "Hello, 世界!";
38let result = js! {
39    alert( @{message} );
40    return 2 + 2 * 2;
41};
42
43println!( "2 + 2 * 2 = {:?}", result );
44```
45
46Closures are also supported:
47
48```rust
49let print_hello = |name: String| {
50    println!( "Hello, {}!", name );
51};
52
53js! {
54    var print_hello = @{print_hello};
55    print_hello( "Bob" );
56    print_hello.drop(); // Necessary to clean up the closure on Rust's side.
57}
58```
59
60You can also pass arbitrary structures thanks to [serde]:
61
62```rust
63#[derive(Serialize)]
64struct Person {
65    name: String,
66    age: i32
67}
68
69js_serializable!( Person );
70
71js! {
72    var person = @{person};
73    console.log( person.name + " is " + person.age + " years old." );
74};
75```
76
77[serde]: https://serde.rs/
78
79This crate also exposes a number of Web APIs, for example:
80
81```rust
82let button = document().query_selector( "#hide-button" ).unwrap().unwrap();
83button.add_event_listener( move |_: ClickEvent| {
84    for anchor in document().query_selector_all( "#main a" ) {
85        js!( @{anchor}.style = "display: none;"; );
86    }
87});
88```
89
90Exposing Rust functions to JavaScript is supported too:
91
92```rust
93#[js_export]
94fn hash( string: String ) -> String {
95    let mut hasher = Sha1::new();
96    hasher.update( string.as_bytes() );
97    hasher.digest().to_string()
98}
99```
100
101Then you can do this from Node.js:
102
103```js
104var hasher = require( "hasher.js" ); // Where `hasher.js` is generated from Rust code.
105console.log( hasher.hash( "Hello world!" ) );
106```
107
108Or you can take the same `.js` file and use it in a web browser:
109
110```html
111<script src="hasher.js"></script>
112<script>
113    Rust.hasher.then( function( hasher ) {
114        console.log( hasher.hash( "Hello world!" ) );
115    });
116</script>
117```
118
119If you're using [Parcel] you can also use our [experimental Parcel plugin];
120first do this in your existing Parcel project:
121
122    $ npm install --save parcel-plugin-cargo-web
123
124And then simply:
125
126```js
127import hasher from "./hasher/Cargo.toml";
128console.log( hasher.hash( "Hello world!" ) );
129```
130
131[Parcel]: https://parceljs.org/
132[experimental Parcel plugin]: https://github.com/koute/parcel-plugin-cargo-web
133
134## Design goals
135
136  * Expose a full suite of Web APIs as exposed by web browsers.
137  * Try to follow the original JavaScript conventions and structure as much as possible,
138    except in cases where doing otherwise results in a clearly superior design.
139  * Be a building block from which higher level frameworks and libraries
140    can be built.
141  * Make it convenient and easy to embed JavaScript code directly into Rust
142    and to marshal data between the two.
143  * Integrate with the wider Rust ecosystem, e.g. support marshaling of structs
144    which implement serde's Serializable.
145  * Put Rust in the driver's seat where a non-trivial Web application can be
146    written without touching JavaScript at all.
147  * Allow Rust to take part in the upcoming WebAssembly (re)volution.
148  * Make it possible to trivially create standalone libraries which are
149    easily callable from JavaScript.
150
151## Getting started
152
153Take a look at some of the examples:
154
155  * `examples/minimal` - a totally minimal example which calls [alert]
156  * `examples/todomvc` - a naively implemented [TodoMVC] application; shows how to call into the DOM
157  * `examples/hasher` - shows how to export Rust functions to JavaScript and how to call them from
158                        a vanilla web browser environment or from Nodejs
159  * `examples/hasher-parcel` - shows how to import and call exported Rust functions in a [Parcel] project
160  * [`pinky-web`] - an NES emulator; you can play with the [precompiled version here](http://koute.github.io/pinky-web/)
161
162[The API documentation](https://docs.rs/stdweb/*/stdweb/) is also available for you to look at.
163
164[alert]: https://developer.mozilla.org/en-US/docs/Web/API/Window/alert
165[TodoMVC]: http://todomvc.com/
166[`pinky-web`]: https://github.com/koute/pinky/tree/master/pinky-web
167
168## Running the examples
169
1701. Install [cargo-web]:
171
172       $ cargo install -f cargo-web
173
1743. Go into `examples/todomvc` and start the example using one of these commands:
175
176    * Compile to [WebAssembly] using Rust's native WebAssembly backend:
177
178          $ cargo web start --target=wasm32-unknown-unknown
179
180    * Compile to [asm.js] using Emscripten:
181
182          $ cargo web start --target=asmjs-unknown-emscripten
183
184    * Compile to [WebAssembly] using Emscripten:
185
186          $ cargo web start --target=wasm32-unknown-emscripten
187
1884. Visit `http://localhost:8000` with your browser.
189
190For the `*-emscripten` targets `cargo-web` is not necessary, however
191the native `wasm32-unknown-unknown` which doesn't need Emscripten
192**requires** `cargo-web` to work!
193
194[cargo-web]: https://github.com/koute/cargo-web
195[asm.js]: https://en.wikipedia.org/wiki/Asm.js
196[WebAssembly]: https://en.wikipedia.org/wiki/WebAssembly
197
198## Changelog
199   * `stdweb 0.4.20`
200      * Compatibility with the newest `wasm-bindgen`
201      * New events:
202         * `FullscreenChangeEvent`
203   * `stdweb 0.4.19`
204      * New methods:
205         * `Document::fullscreen_enabled`
206         * `Document::fullscreen_element`
207         * `InputElement::selection_start`
208         * `InputElement::selection_end`
209         * `InputElement::set_selection_start`
210         * `InputElement::set_selection_end`
211         * `Object::to_iter`
212         * `Window::confirm`
213      * `&Array`s can now be converted to `Vec`s through `TryFrom`
214      * The runtime should now be compatible with newer versions of Emscripten
215      * The unstable `futures`-related APIs were updated to work with the latest nightlies
216      * The `syn` dependency was updated to version 1
217   * `stdweb 0.4.18`
218      * The `js!` macro can now be imported with an `use`
219      * New events:
220         * `BeforeUnloadEvent`
221         * `UnloadEvent`
222      * New methods:
223         * `IBlob::slice`
224         * `IBlob::slice_with_content_type`
225         * `IWindowOrWorker::set_clearable_timeout`
226   * `stdweb 0.4.17`
227      * The unstable `futures`-related APIs were updated to work with the latest nightlies
228   * `stdweb 0.4.16`
229      * Initial `wasm-bindgen` compatibility; you can now use `stdweb` in projects
230        using `wasm-bindgen`
231      * Minimum supported Rust version is now 1.33.0
232      * Minimum required `cargo-web` version is now 0.6.24
233   * `stdweb 0.4.15`
234      * The unstable `futures`-related APIs were updated to work with the latest nightlies
235      * New types:
236         * `FormData`
237         * `FormDataEntry`
238         * `MouseButtonsState`
239      * New methods:
240         * `Blob::new`
241   * `stdweb 0.4.14`
242      * The `js!` macro now generates slightly more efficient code
243        if you're not returning anything from your JS snippet. This makes
244        it unnecessary to add the `@(no_return)` annotation in the vast
245        majority of cases.
246      * New types:
247         * `File`
248   * `stdweb 0.4.13`
249      * Fixed the procedural `js!` macro's whitespace handling
250      * New types:
251         * `ITouchEvent`
252         * `Touch`
253         * `TouchType`
254      * New events:
255         * `TouchEvent`
256         * `TouchMove`
257         * `TouchLeave`
258         * `TouchEnter`
259         * `TouchEnd`
260         * `TouchCancel`
261         * `TouchStart`
262      * New methods:
263         * `XmlHttpRequest::set_response_type`
264   * `stdweb 0.4.12`
265      * Improved diagnostics when trying to compile for the `wasm32-unknown-unknown` target without `cargo-web`
266   * `stdweb 0.4.11`
267      * The minimum required Rust version is now 1.30.1
268      * The minimum required `cargo-web` version is now 0.6.22
269      * `wasm32-unknown-unknown` is now officially supported on stable Rust
270      * Debug builds on `wasm32-unknown-unknown` are now supported
271      * The `js!` macro is now partially implemented using a procedural macro
272      * String decoding/encoding is now a lot faster due to the use of native codec APIs
273      * New methods:
274        * `Document::import_node`
275        * `IElement::slot`
276        * `IElement::attach_shadow`
277        * `IElement::shadow_root`
278      * New types:
279        * `ISlotable`
280        * `ShadowRoot`
281        * `ShadowRootMode`
282        * `TemplateElement`
283        * `SlotElement`
284      * New events:
285        * `SlotChangeEvent`
286      * `IParentNode::query_selector` and `IParentNode::query_selector_all` now return a proper error type
287   * `stdweb 0.4.10`, `stdweb-derive 0.5.1`
288      * New methods:
289        * `IElement::insert_adjacent_html`
290        * `IElement::insert_html_before`
291        * `IElement::insert_html_after`
292        * `IElement::prepend_html`
293        * `IElement::append_html`
294        * `IElement::namespace_uri`
295        * `IElement::closest`
296        * `Document::create_element_ns`
297        * `Window::get_selection`
298      * New types:
299        * `AbortError`
300        * `SelectionType`
301        * `Selection`
302        * `Range`
303      * The error messages for failed type conversions are now improved
304      * The error type of failed conversions (when using `.try_into()`/`.try_from()`) is now convertible into a `TypeError`
305      * Aggregate error types (like, e.g. `DrawImageError`) are now serializable through the `js!` macro
306      * `TypeError` is now fixed (it was incorrectly treated as a `DOMException`)
307      * `Number` can now be converted into `f64` with `.into()`/`.from()`
308      * Added `Mut`, which is a new wrapper type for safely passing `FnMut` closures into the `js!` macro;
309        it is optional for now, however the usage of this wrapper type **will be mandatory** in the future!
310      * `FnMut` closures cannot be called recursively anymore
311      * `#[derive(ReferenceType)]` now supports a limited subset of generic types
312      * Asynchronous unit tests are now supported with a new `#[async_test]` attribute macro (nightly only)
313      * Updated to `futures 0.3` (nightly only)
314   * `stdweb 0.4.9`, `stdweb-derive 0.5.0`
315      * Performance improvements; serialization through serde is now twice as fast
316      * New events:
317        * `ScrollEvent`
318        * `DragRelatedEvent`
319        * `DragEvent`
320        * `DragStartEvent`
321        * `DragEndEvent`
322        * `DragEnterEvent`
323        * `DragLeaveEvent`
324        * `DragOverEvent`
325        * `DragExitEvent`
326        * `DragDropEvent`
327      * New types:
328        * `DataTransfer`
329        * `EffectAllowed`
330        * `DropEffect`
331        * `DataTransferItemList`
332        * `DataTransferItem`
333        * `DataTransferItemKind`
334        * `IDragEvent`
335      * `Value`s can now be converted to `Option< Serde< T > >` with `try_into`
336      * Deserialization of numbers through serde now works in the majority of cases
337        allowing types other than `i32` and `f64` to be used
338      * All of the events are now more strongly-typed
339          * Previously in was possible to deserialize e.g. a `keyup` event
340            as a `KeyDownEvent` since only the event's JS type was checked
341            and both `keyup` and `keydown` share the same JS type (`KeyboardEvent`).
342            From now on the `type` field of the event is also checked, so
343            such conversions are not allowed anymore.
344   * `0.4.8`
345      * Fixed compilation on the newest nightly when targeting `wasm32-unknown-unknown`
346      * New events:
347        * `PointerLockChangeEvent`
348        * `PointerLockErrorEvent`
349        * `MouseWheelEvent`
350      * New types:
351        * `MouseWheelDeltaMode`
352        * `XhrResponseType`
353      * New methods:
354        * `XmlHttpRequest::raw_response`
355        * `Window::device_pixel_ratio`
356        * `Document::pointer_lock_element`
357        * `Document::exit_pointer_lock`
358   * `0.4.7`
359      * New events:
360         * `AuxClickEvent`
361         * `MouseEnterEvent`
362         * `MouseLeaveEvent`
363         * `ContextMenuEvent`
364         * `SelectionChangeEvent`
365      * New types:
366        * `FileList`
367        * `FileReaderReadyState`
368      * Implement gamepad APIs:
369         * `Gamepad`
370         * `GamepadButton`
371         * `GamepadButtonMapping`
372         * `GamepadEvent`
373      * Fixed `CanvasRenderingContext2d::clear_rect`
374      * Fixed a leak when creating `TypedArray`s from
375        `Vec`s and `ArrayBuffer`s.
376   * `0.4.6`
377      * Fix `docs.rs` again
378      * New types:
379         * `SubmitEvent`
380         * `IChildNode`
381      * Fix `CanvasElement::to_data_url`
382   * `0.4.5`
383      * New types:
384         * `DocumentFragment`
385         * `SelectElement`
386         * `OptionElement`
387         * `HtmlCollection`
388      * New methods:
389         * `Node::from_html`
390         * `Value::is_null`
391      * Expose enums:
392         * `SocketMessageData`
393         * `NodeType`
394      * Update to `futures` 0.2
395   * `0.4.4`
396      * Fix `docs.rs` (hopefully).
397      * New methods:
398         * `Location::origin`
399         * `Location::protocol`
400         * `Location::host`
401         * `Location::hostname`
402         * `Location::port`
403         * `Location::pathname`
404         * `Location::search`
405      * These now return `SecurityError` in the error case:
406         * `Location::hash`
407         * `Location::href`
408   * `0.4.3`
409      * Objects which cannot be used as keys in a `WeakMap`
410        should be supported now (e.g. some of the WebGL-related objects under Firefox)
411      * New methods:
412         * `Element::get_bounding_client_rect`
413         * `Element::scroll_top`
414         * `Element::scroll_left`
415         * `Window::page_x_offset`
416         * `Window::page_y_offset`
417         * `NodeList::item`
418         * `Document::body`
419         * `Document::head`
420         * `Document::title`
421         * `Document::set_title`
422         * `IMouseEvent::offset_x`
423         * `IMouseEvent::offset_y`
424      * Expose more canvas related types:
425         * `CompositeOperation`
426         * `LineCap`
427         * `LineJoin`
428         * `Repetition`
429         * `TextAlign`
430         * `TextBaseline`
431      * Expose canvas related error types: `AddColorStopError`, `DrawImageError`, `GetImageDataError`
432      * New events:
433         * `MouseOverEvent`
434         * `MouseOutEvent`
435         * `PointerOverEvent`
436         * `PointerEnterEvent`
437         * `PointerDownEvent`
438         * `PointerMoveEvent`
439         * `PointerUpEvent`
440         * `PointerCancelEvent`
441         * `PointerOutEvent`
442         * `PointerLeaveEvent`
443         * `GotPointerCaptureEvent`
444         * `LostPointerCaptureEvent`
445      * New interface for pointer events: `IPointerEvent`
446   * `0.4.2`
447      * Fixed a leak when deserializing references
448      * Fixed `CanvasRenderingContext2d::get_canvas`
449      * Exposed `FillRule` and `SocketReadyState`
450      * New attribute related methods added to `IElement`
451      * New `Date` bindings
452   * `0.4.1`
453      * Support for newest nightly Rust on `wasm32-unknown-unknown`
454      * Exposed `SocketBinaryType` enum
455      * New canvas APIs:
456         * Numerous new methods for `CanvasRenderingContext2d`
457         * New types: `CanvasGradient`, `CanvasPattern`, `CanvasStyle`, `ImageData`, `TextMetrics`
458      * New error types: `IndexSizeError`, `NotSupportedError`, `TypeError`
459   * `0.4`
460      * (breaking change) Removed `Array` and `Object` variants from `Value`; these are now treated as `Reference`s
461      * (breaking change) The `Value` has an extra variant: `Symbol`
462      * (breaking change) Removed:
463         * `InputElement::set_kind`
464         * `InputElement::files`
465      * (breaking change) Renamed:
466         * `KeydownEvent` -> `KeyDownEvent`
467         * `KeyupEvent` -> `KeyUpEvent`
468         * `KeypressEvent` -> `KeyPressEvent`
469         * `ReadyState` -> `FileReaderReadyState`
470         * `InputElement::value` -> `InputElement::raw_value`
471         * `InputElement::set_value` -> `InputElement::set_raw_value`
472      * (breaking change) `ArrayBuffer::new` now takes an `u64` argument
473      * (breaking change) `InputElement::set_raw_value` now takes `&str` instead of `Into< Value >`
474      * (breaking change) Changed return types:
475         * Every method which returned `usize` now returns `u32`
476         * `INode::remove_child` now returns `Node` in the `Ok` case
477         * The following now return an `u64`:
478            * `ArrayBuffer::len`
479         * The following now return an `i32` instead of `f64`:
480            * `IMouseEvent::client_x`
481            * `IMouseEvent::client_y`
482            * `IMouseEvent::movement_x`
483            * `IMouseEvent::movement_y`
484            * `IMouseEvent::screen_x`
485            * `IMouseEvent::screen_y`
486         * The following now return a `Result`:
487            * `INode::insert_before`
488            * `INode::replace_child`
489            * `INode::clone_node`
490            * `StringMap::insert`
491            * `TokenList::add`
492            * `TokenList::remove`
493            * `Document::create_element`
494            * `IEventTarget::dispatch_event`
495            * `FileReader::read_as_text`
496            * `FileReader::read_as_array_buffer`
497            * `FileReader::read_as_text`
498            * `History::replace_state`
499            * `History::go`
500            * `History::back`
501            * `History::forward`
502            * `Location::href`
503            * `Location::hash`
504            * `CanvasElement::to_data_url`
505            * `CanvasElement::to_blob`
506            * `ArrayBuffer::new`
507        * `INode::base_uri` now returns a `String` instead of `Option< String >`
508        * `InputElement::raw_value` now returns a `String` instead of `Value`
509      * (breaking change) `INode::inner_text` was moved to `IHtmlElement::inner_text`
510      * (breaking change) `Document::query_selector` and `Document::query_selector_all` were moved to `IParentNode`
511      * (breaking change) `IElement::query_selector` and `IElement::query_selector_all` were moved to `IParentNode`
512      * (breaking change) `Document::get_element_by_id` was moved to `INonElementParentNode`
513      * (breaking change) A blanket impl for converting between arbitrary reference-like objects using
514        `TryFrom`/`TryInto` has been removed
515      * When building using a recent `cargo-web` it's not necessary to call
516        `stdweb::initialize` nor `stdweb::event_loop` anymore
517      * Support for `cdylib` crates on `wasm32-unknown-unknown`
518      * New bindings:
519         * `XmlHttpRequest`
520         * `WebSocket`
521         * `MutationObserver`
522         * `History`
523         * `TextAreaElement`
524         * `CanvasElement`
525      * New event types:
526         * `MouseDownEvent`
527         * `MouseUpEvent`
528         * `MouseMoveEvent`
529         * `PopStateEvent`
530         * `ResizeEvent`
531         * `ReadyStateChange`
532         * `SocketCloseEvent`
533         * `SocketErrorEvent`
534         * `SocketOpenEvent`
535         * `SocketMessageEvent`
536      * Initial support for the Canvas APIs
537      * New traits: `ReferenceType` and `InstanceOf`
538      * Add `#[derive(ReferenceType)]` in `stdweb-derive` crate; it's now possible
539        to define custom API bindings outside of `stdweb`
540      * Add `#[js_export]` procedural attribute (`wasm32-unknown-unknown` only)
541      * Add `DomException` and subtypes for passing around JavaScript exceptions
542      * `IElement` now inherits from `INode`
543      * Every interface now inherits from `ReferenceType`
544      * Add `stdweb::traits` module to act as a prelude for `use`-ing all of our interface traits
545      * Add `console!` macro
546      * Most types now implement `PartialEq` and `Eq`
547
548   * `0.3`
549      * (breaking change) Deleted `ErrorEvent` methods
550      * (breaking change) Renamed:
551         * `LoadEvent` -> `ResourceLoadEvent`
552         * `AbortEvent` -> `ResourceAbortEvent`
553         * `ErrorEvent` -> `ResourceErrorEvent`
554      * Add `UnsafeTypedArray` for zero cost slice passing to `js!`
555      * Add `Once` for passing `FnOnce` closures to `js!`
556
557## License
558
559Licensed under either of
560
561  * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
562  * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
563
564at your option.
565
566Snippets of documentation which come from [Mozilla Developer Network] are covered under the [CC-BY-SA, version 2.5] or later.
567
568[Mozilla Developer Network]: https://developer.mozilla.org/en-US/
569[CC-BY-SA, version 2.5]: https://developer.mozilla.org/en-US/docs/MDN/About#Copyrights_and_licenses
570
571### Contributing
572
573See [CONTRIBUTING.md](https://github.com/koute/stdweb/blob/master/CONTRIBUTING.md)
574