Skip to content

Commit

Permalink
Merge branch 'master' of github.com:yewstack/yew
Browse files Browse the repository at this point in the history
  • Loading branch information
mrh0057 committed Apr 4, 2020
2 parents ae23594 + 8edf136 commit 7bd7305
Show file tree
Hide file tree
Showing 62 changed files with 774 additions and 217 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ If applicable, add screenshots to help explain your problem.

**Environment:**
- Yew version [e.g. v0.10, `master`]
- Rust version [e.g. 1.41.0]
- Rust version [e.g. 1.42.0]
- Target if relevant [e.g. `wasm32-unknown-emscripten`]
- `stdweb` / `web-sys` version [e.g. web-sys v0.3.33]
- OS: [e.g. macos]
Expand Down
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ install:
- nvm install 9
- rustup component add rustfmt
- rustup component add clippy
- rustup install stable
- rustup target add wasm32-unknown-unknown
- cargo install cargo-update || true
- cargo install-update-config --version =0.2.59 wasm-bindgen-cli
- cargo install-update --allow-no-update wasm-bindgen-cli
- cargo +stable install wasm-bindgen-cli
- curl --retry 5 -LO https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz
- tar -xzf geckodriver-v0.26.0-linux64.tar.gz
- ./ci/install_cargo_web.sh
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## **0.14.3** *(2020-04-04)*

- #### 🛠 Fixes

- Remove `html!` component validation to allow generic components. [[@mankinskin], [#1065](https://github.com/yewstack/yew/pull/1065)]
- Improve `Debug` formatting for `VTag` and `VText`. [[@dancespiele], [#1059](https://github.com/yewstack/yew/pull/1059)]
- Implement `Default` for `Callback`. [[@TheNeikos], [#1043](https://github.com/yewstack/yew/pull/1043)]

## **0.14.2** *(2020-03-23)*

- #### 🛠 Fixes
Expand Down Expand Up @@ -761,6 +769,7 @@ This release introduces the concept of an `Agent`. Agents are separate activitie
[@charvp]: https://github.com/charvp
[@ctaggart]: https://github.com/ctaggart
[@ctm]: https://github.com/ctm
[@dancespiele]: https://github.com/dancespiele
[@daxpedda]: https://github.com/daxpedda
[@davidkna]: https://github.com/davidkna
[@DenisKolodin]: https://github.com/DenisKolodin
Expand All @@ -776,6 +785,7 @@ This release introduces the concept of an `Agent`. Agents are separate activitie
[@kuy]: https://github.com/kuy
[@leo-lb]: https://github.com/leo-lb
[@lizhaoxian]: https://github.com/lizhaoxian
[@mankinskin]: https://github.com/mankinskin
[@mdtusz]: https://github.com/mdtusz
[@mrh0057]: https://github.com/mrh0057
[@nicklaswj]: https://github.com/nicklaswj
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ although more driver support may be added! You can download these at:
* safaridriver - should be preinstalled on OSX

##### Macro Tests
When adding or updating tests, please make sure you have updated the appropriate `stderr` file, which you can find [here](https://github.com/yewstack/yew/tree/master/tests/macro) for the `html!` macro. These files ensure that macro compilation errors are correct and easy to understand.
When adding or updating tests, please make sure you have updated the appropriate `stderr` file, which you can find [here](https://github.com/yewstack/yew/tree/master/crates/macro/tests/macro) for the `html!` macro. These files ensure that macro compilation errors are correct and easy to understand.

To update or generate a new `stderr` file you can run `TRYBUILD=overwrite cargo test --test macro_test` or `TRYBUILD=overwrite cargo test --test derive_props_test`.
To update or generate a new `stderr` file you can run `TRYBUILD=overwrite cargo test --test macro_test` or `TRYBUILD=overwrite cargo test --test derive_props_test` from the `crates/macro` directory.

##### Running Tests

Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "yew"
version = "0.14.2"
version = "0.14.3"
edition = "2018"
authors = [
"Denis Kolodin <deniskolodin@gmail.com>",
Expand Down Expand Up @@ -42,9 +42,9 @@ slab = "0.4"
stdweb = { version = "0.4.20", optional = true }
thiserror = "1"
toml = { version = "0.5", optional = true }
wasm-bindgen = { version = "0.2.59", optional = true }
wasm-bindgen = { version = "0.2.60", optional = true }
wasm-bindgen-futures = { version = "0.4", optional = true }
yew-macro = { version = "0.14.0", path = "crates/macro" }
yew-macro = { version = "0.14.1", path = "crates/macro" }

[dependencies.web-sys]
version = "0.3"
Expand Down Expand Up @@ -102,7 +102,7 @@ features = [

# Changes here must be reflected in `build.rs`
[target.'cfg(all(target_arch = "wasm32", not(target_os="wasi"), not(cargo_web)))'.dependencies]
wasm-bindgen = "0.2.59"
wasm-bindgen = "0.2.60"

# Changes here must be reflected in `build.rs`
[target.'cfg(all(target_arch = "wasm32", not(target_os="wasi"), not(cargo_web)))'.dev-dependencies]
Expand Down
1 change: 0 additions & 1 deletion ci/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ cargo test --doc --features doc_test,wasm_test,yaml,msgpack,cbor,web_sys

(cd crates/functional \
&& cargo test --features wasm_test --target wasm32-unknown-unknown)

4 changes: 3 additions & 1 deletion crates/functional/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ yew = { path = "../..", features = ["web_sys"] }
yew = { path = "../.." }

[target.'cfg(all(target_arch = "wasm32", not(target_os="wasi"), not(cargo_web)))'.dependencies]
wasm-bindgen = "0.2.59"
wasm-bindgen = "0.2.60"

[target.'cfg(all(target_arch = "wasm32", not(target_os="wasi"), not(cargo_web)))'.dev-dependencies]
wasm-bindgen-test = "0.3.4"

[features]
wasm_test = []
web_sys = ["yew/web_sys"]
std_web = ["yew/std_web"]
121 changes: 113 additions & 8 deletions crates/functional/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Borrow;
use std::cell::RefCell;
use std::ops::DerefMut;
use std::rc::Rc;
Expand All @@ -7,10 +8,15 @@ thread_local! {
static CURRENT_HOOK: RefCell<Option<HookState>> = RefCell::new(None);
}

pub trait Hook {
fn tear_down(&mut self) {}
}

struct HookState {
counter: usize,
process_message: Rc<dyn Fn(Box<dyn FnOnce() -> bool>)>,
hooks: Vec<Rc<RefCell<dyn std::any::Any>>>,
destroy_listeners: Vec<Box<dyn FnOnce()>>,
}

pub trait FunctionProvider {
Expand Down Expand Up @@ -39,6 +45,7 @@ where
counter: 0,
process_message: Rc::new(move |msg| link.send_message(msg)),
hooks: vec![],
destroy_listeners: vec![],
})),
}
}
Expand Down Expand Up @@ -88,27 +95,37 @@ where

return ret;
}

fn destroy(&mut self) {
if let Some(hook_state) = self.hook_state.borrow_mut().deref_mut() {
for hook in hook_state.destroy_listeners.drain(..) {
hook()
}
}
}
}

pub fn use_ref<T: 'static, InitialProvider>(initial_value: InitialProvider) -> Rc<RefCell<T>>
where
InitialProvider: FnOnce() -> T,
{
type UseRefState<T> = Rc<RefCell<T>>;
#[derive(Clone)]
struct UseRefState<T>(Rc<RefCell<T>>);
impl<T> Hook for UseRefState<T> {}

use_hook(
|state: &mut UseRefState<T>, pretrigger_change_acceptor| {
let _ignored = || pretrigger_change_acceptor(|_| false); // we need it to be a specific closure type, even if we never use it
return state.clone();
return state.0.clone();
},
move || Rc::new(RefCell::new(initial_value())),
move || UseRefState(Rc::new(RefCell::new(initial_value()))),
)
}

pub fn use_reducer<Action: 'static, Reducer, State: 'static>(
reducer: Reducer,
initial_state: State,
) -> (Rc<State>, Box<impl Fn(Action)>)
) -> (Rc<State>, Rc<impl Fn(Action)>)
where
Reducer: Fn(Rc<State>, Action) -> State + 'static,
{
Expand All @@ -119,21 +136,22 @@ pub fn use_reducer_with_init<Action: 'static, Reducer, State: 'static, InitialSt
reducer: Reducer,
initial_state: InitialState,
init: InitFn,
) -> (Rc<State>, Box<impl Fn(Action)>)
) -> (Rc<State>, Rc<impl Fn(Action)>)
where
Reducer: Fn(Rc<State>, Action) -> State + 'static,
InitFn: Fn(InitialState) -> State,
{
struct UseReducerState<State> {
current_state: Rc<State>,
}
impl<T> Hook for UseReducerState<T> {};
let init = Box::new(init);
let reducer = Rc::new(reducer);
let ret = use_hook(
|internal_hook_change: &mut UseReducerState<State>, pretrigger_change_runner| {
return (
internal_hook_change.current_state.clone(),
Box::new(move |action: Action| {
Rc::new(move |action: Action| {
let reducer = reducer.clone();
pretrigger_change_runner(
move |internal_hook_change: &mut UseReducerState<State>| {
Expand Down Expand Up @@ -162,6 +180,7 @@ where
struct UseStateState<T2> {
current: Rc<T2>,
}
impl<T> Hook for UseStateState<T> {}
return use_hook(
|prev: &mut UseStateState<T>, hook_update| {
let current = prev.current.clone();
Expand All @@ -181,13 +200,96 @@ where
);
}

pub fn use_effect<F, Destructor>(callback: F)
where
F: FnOnce() -> Destructor + 'static,
Destructor: FnOnce() + 'static,
{
let callback = Box::new(callback);
struct UseEffectState<Destructor> {
destructor: Option<Box<Destructor>>,
}
impl<T: FnOnce() + 'static> Hook for UseEffectState<T> {
fn tear_down(&mut self) {
if let Some(destructor) = self.destructor.take() {
destructor()
}
}
}
use_hook(
|_: &mut UseEffectState<Destructor>, hook_update| {
return move || {
hook_update(move |state: &mut UseEffectState<Destructor>| {
if let Some(de) = state.destructor.take() {
de();
}
let new_destructor = callback();
state.destructor.replace(Box::new(new_destructor));
false
});
};
},
|| UseEffectState { destructor: None },
)();
}

pub fn use_effect_with_deps<F, Destructor, Dependents>(callback: F, deps: Dependents)
where
F: FnOnce(&Dependents) -> Destructor + 'static,
Destructor: FnOnce() + 'static,
Dependents: PartialEq + 'static,
{
struct UseEffectState<Dependents, Destructor> {
deps: Rc<Dependents>,
destructor: Option<Box<Destructor>>,
}
let deps = Rc::new(deps);
let deps_c = deps.clone();

impl<Dependents, Destructor: FnOnce() + 'static> Hook for UseEffectState<Dependents, Destructor> {
fn tear_down(&mut self) {
if let Some(destructor) = self.destructor.take() {
destructor()
}
}
}
use_hook(
move |state: &mut UseEffectState<Dependents, Destructor>, hook_update| {
let mut should_update = !(*state.deps == *deps);

return move || {
hook_update(move |state: &mut UseEffectState<Dependents, Destructor>| {
if should_update {
if let Some(de) = state.destructor.take() {
de();
}
let new_destructor = callback(deps.borrow());
state.deps = deps.clone();
state.destructor.replace(Box::new(new_destructor));
} else if state.destructor.is_none() {
should_update = true;
state
.destructor
.replace(Box::new(callback(state.deps.borrow())));
}
false
})
};
},
|| UseEffectState {
deps: deps_c,
destructor: None,
},
)();
}

pub fn use_hook<InternalHookState, HookRunner, R, InitialStateProvider, PretriggerChange: 'static>(
hook_runner: HookRunner,
initial_state_producer: InitialStateProvider,
) -> R
where
HookRunner: FnOnce(&mut InternalHookState, Box<dyn Fn(PretriggerChange)>) -> R,
InternalHookState: 'static,
InternalHookState: Hook + 'static,
InitialStateProvider: FnOnce() -> InternalHookState,
PretriggerChange: FnOnce(&mut InternalHookState) -> bool,
{
Expand All @@ -206,7 +308,10 @@ where
// Initialize hook if this is the first call
if hook_pos >= hook_state.hooks.len() {
let initial_state = Rc::new(RefCell::new(initial_state_producer()));
hook_state.hooks.push(initial_state);
hook_state.hooks.push(initial_state.clone());
hook_state.destroy_listeners.push(Box::new(move || {
initial_state.borrow_mut().deref_mut().tear_down();
}));
}

let hook = hook_state.hooks[hook_pos].clone();
Expand Down

0 comments on commit 7bd7305

Please sign in to comment.