Skip to content

Commit

Permalink
web-sys general conversion (#826)
Browse files Browse the repository at this point in the history
* Moved patches from different PRs.

* Add bits & pieces and some services.

* Rename `stdweb` feature to `std_web`.

* Move tests and examples to different PR.

* Revert some `cargo_web` handling removal.

* Missed something.

* Implement `console_error_panic_hook`.

* Update Cargo.toml

Co-authored-by: Justin Starry <justin.m.starry@gmail.com>
  • Loading branch information
daxpedda and jstarry committed Jan 8, 2020
1 parent 6357834 commit 0d29a28
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 10 deletions.
58 changes: 57 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ travis-ci = { repository = "yewstack/yew" }
[dependencies]
anymap = "0.12"
bincode = { version = "~1.2.1", optional = true }
console_error_panic_hook = { version = "0.1", optional = true }
failure = "0.1"
gloo = { version = "0.2", optional = true }
http = "0.2"
indexmap = "1.0.2"
js-sys = { version = "0.3", optional = true }
log = "0.4"
proc-macro-hack = "0.5"
proc-macro-nested = "0.1"
Expand All @@ -33,10 +36,61 @@ serde_cbor = { version = "0.10.2", optional = true }
serde_json = "1.0"
serde_yaml = { version = "0.8.3", optional = true }
slab = "0.4"
stdweb = "0.4.20"
stdweb = { version = "0.4.20", optional = true }
toml = { version = "0.5", optional = true }
yew-macro = { version = "0.10.1", path = "crates/macro" }

[dependencies.web-sys]
version = "0.3"
optional = true
features = [
"AbortController",
"AbortSignal",
"BinaryType",
"Blob",
"console",
"DedicatedWorkerGlobalScope",
"Document",
"DomTokenList",
"DragEvent",
"Element",
"Event",
"EventTarget",
"File",
"FileList",
"FileReader",
"FocusEvent",
"Headers",
"HtmlElement",
"HtmlInputElement",
"HtmlSelectElement",
"HtmlTextAreaElement",
"KeyboardEvent",
"Location",
"MessageEvent",
"MouseEvent",
"Node",
"ObserverCallback",
"PointerEvent",
"ReferrerPolicy",
"Request",
"RequestCache",
"RequestCredentials",
"RequestInit",
"RequestMode",
"RequestRedirect",
"Response",
"Storage",
"Text",
"TouchEvent",
"UiEvent",
"WebSocket",
"WheelEvent",
"Window",
"Worker",
"WorkerOptions",
]

[target.'cfg(all(target_arch = "wasm32", not(target_os="wasi"), not(cargo_web)))'.dependencies]
wasm-bindgen = "0.2.56"
wasm-bindgen-futures = "0.4.4"
Expand All @@ -54,6 +108,8 @@ rustversion = "1.0"

[features]
default = ["services", "agent"]
std_web = ["stdweb"]
web_sys = ["console_error_panic_hook", "gloo", "js-sys", "web-sys"]
doc_test = []
web_test = []
wasm_test = []
Expand Down
6 changes: 6 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use std::env;

pub fn main() {
if cfg!(all(feature = "web_sys", feature = "std_web")) {
panic!("don't use `web_sys` and `std_web` simultaneously")
} else if cfg!(not(any(feature = "web_sys", feature = "std_web"))) {
panic!("please select either `web_sys` or `std_web`")
}

let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
let cargo_web = env::var("COMPILING_UNDER_CARGO_WEB").unwrap_or_default();
if target_arch == "wasm32" && cargo_web != "1" {
Expand Down
35 changes: 29 additions & 6 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
//! a component in an isolated scope.

use crate::html::{Component, NodeRef, Scope};
#[cfg(feature = "std_web")]
use stdweb::web::{document, Element, INode, IParentNode};
#[cfg(feature = "web_sys")]
use web_sys::Element;

/// An application instance.
#[derive(Debug)]
Expand Down Expand Up @@ -42,8 +45,13 @@ where

/// Alias to `mount("body", ...)`.
pub fn mount_to_body(self) -> Scope<COMP> {
#[cfg(feature = "std_web")]
let document = document();
#[cfg(feature = "web_sys")]
let document = web_sys::window().unwrap().document().unwrap();

// Bootstrap the component for `Window` environment only (not for `Worker`)
let element = document()
let element = document
.query_selector("body")
.expect("can't get body node for rendering")
.expect("can't unwrap body node");
Expand All @@ -55,11 +63,16 @@ where
/// need to manipulate the body element. For example, adding/removing app-wide
/// CSS classes of the body element.
pub fn mount_as_body(self) -> Scope<COMP> {
let html_element = document()
#[cfg(feature = "std_web")]
let document = document();
#[cfg(feature = "web_sys")]
let document = web_sys::window().unwrap().document().unwrap();

let html_element = document
.query_selector("html")
.expect("can't get html node for rendering")
.expect("can't unwrap html node");
let body_element = document()
let body_element = document
.query_selector("body")
.expect("can't get body node for rendering")
.expect("can't unwrap body node");
Expand Down Expand Up @@ -97,8 +110,13 @@ where

/// Alias to `mount_with_props("body", ...)`.
pub fn mount_to_body_with_props(self, props: COMP::Properties) -> Scope<COMP> {
#[cfg(feature = "std_web")]
let document = document();
#[cfg(feature = "web_sys")]
let document = web_sys::window().unwrap().document().unwrap();

// Bootstrap the component for `Window` environment only (not for `Worker`)
let element = document()
let element = document
.query_selector("body")
.expect("can't get body node for rendering")
.expect("can't unwrap body node");
Expand All @@ -110,11 +128,16 @@ where
/// when you need to manipulate the body element. For example, adding/removing app-wide
/// CSS classes of the body element.
pub fn mount_as_body_with_props(self, props: COMP::Properties) -> Scope<COMP> {
let html_element = document()
#[cfg(feature = "std_web")]
let document = document();
#[cfg(feature = "web_sys")]
let document = web_sys::window().unwrap().document().unwrap();

let html_element = document
.query_selector("html")
.expect("can't get html node for rendering")
.expect("can't unwrap html node");
let body_element = document()
let body_element = document
.query_selector("body")
.expect("can't get body node for rendering")
.expect("can't unwrap body node");
Expand Down
6 changes: 5 additions & 1 deletion src/components/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,11 @@ where
fn onchange(&self) -> Callback<ChangeData> {
self.link.callback(|event| match event {
ChangeData::Select(elem) => {
let value = elem.selected_index().map(|x| x as usize);
let value = elem.selected_index();
#[cfg(feature = "std_web")]
let value = value.map(|x| x as usize);
#[cfg(feature = "web_sys")]
let value = Some(value as usize);
Msg::Selected(value)
}
_ => {
Expand Down
10 changes: 10 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub mod services;
pub mod events {
pub use crate::html::{ChangeData, InputData};

#[cfg(feature = "std_web")]
pub use stdweb::web::event::{
BlurEvent, ClickEvent, ContextMenuEvent, DoubleClickEvent, DragDropEvent, DragEndEvent,
DragEnterEvent, DragEvent, DragExitEvent, DragLeaveEvent, DragOverEvent, DragStartEvent,
Expand All @@ -106,15 +107,24 @@ pub mod events {
PointerLeaveEvent, PointerMoveEvent, PointerOutEvent, PointerOverEvent, PointerUpEvent,
ScrollEvent, SubmitEvent, TouchCancel, TouchEnd, TouchEnter, TouchMove, TouchStart,
};
#[cfg(feature = "web_sys")]
pub use web_sys::{
DragEvent, Event, FocusEvent, KeyboardEvent, MouseEvent, PointerEvent, TouchEvent, UiEvent,
WheelEvent,
};
}

/// Initializes yew framework. It should be called first.
pub fn initialize() {
#[cfg(feature = "std_web")]
stdweb::initialize();
#[cfg(feature = "web_sys")]
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
}

/// Starts event loop.
pub fn run_loop() {
#[cfg(feature = "std_web")]
stdweb::event_loop();
}

Expand Down
23 changes: 21 additions & 2 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
//! This module contains useful utils to get information about the current document.

use failure::{err_msg, Error};
#[cfg(feature = "std_web")]
use stdweb::web::document;

/// Returns `host` for the current document. Useful to connect to a server that server the app.
pub fn host() -> Result<String, Error> {
document()
#[cfg(feature = "std_web")]
{
document()
.location()
.ok_or_else(|| err_msg("can't get location"))
.and_then(|l| l.host().map_err(Error::from))
}
#[cfg(feature = "web_sys")]
web_sys::window()
.unwrap()
.document()
.unwrap()
.location()
.ok_or_else(|| err_msg("can't get location"))
.and_then(|l| l.host().map_err(Error::from))
.and_then(|l| {
l.host().map_err(|e| {
err_msg(
e.as_string()
.unwrap_or_else(|| String::from("error not recoverable")),
)
})
})
}

0 comments on commit 0d29a28

Please sign in to comment.