Compare commits
1 Commits
main
...
revert-538
Author | SHA1 | Date |
---|---|---|
Greg Johnston | f0f7d900a1 |
|
@ -4,55 +4,55 @@ use leptos::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn App(cx: Scope) -> impl IntoView {
|
pub fn App(cx: Scope) -> impl IntoView {
|
||||||
let pending_thing = create_resource(
|
let pending_thing = create_resource(
|
||||||
cx,
|
cx,
|
||||||
|| false,
|
|| false,
|
||||||
|_| async {
|
|_| async {
|
||||||
if cfg!(feature = "ssr") {
|
if cfg!(feature = "ssr") {
|
||||||
let (tx, rx) = futures::channel::oneshot::channel();
|
let (tx, rx) = futures::channel::oneshot::channel();
|
||||||
spawn_local(async {
|
spawn_local(async {
|
||||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||||
tx.send(());
|
tx.send(());
|
||||||
});
|
});
|
||||||
rx.await;
|
rx.await;
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
view! { cx,
|
view! { cx,
|
||||||
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
"This is some text"
|
||||||
"This is some text"
|
|
||||||
</div>
|
|
||||||
// <Suspense fallback=move || view! { cx, <p>"Loading..."</p> }>
|
|
||||||
{move || pending_thing.read().map(|n| view! { cx, <ComponentA/> })}
|
|
||||||
// </Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
// <Suspense fallback=move || view! { cx, <p>"Loading..."</p> }>
|
||||||
|
{move || pending_thing.read().map(|n| view! { cx, <ComponentA/> })}
|
||||||
|
// </Suspense>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn ComponentA(cx: Scope) -> impl IntoView {
|
pub fn ComponentA(cx: Scope) -> impl IntoView {
|
||||||
let (value, set_value) = create_signal(cx, "Hello?".to_string());
|
let (value, set_value) = create_signal(cx, "Hello?".to_string());
|
||||||
let (counter, set_counter) = create_signal(cx, 0);
|
let (counter, set_counter) = create_signal(cx, 0);
|
||||||
|
|
||||||
// Test to make sure hydration isn't broken by
|
// Test to make sure hydration isn't broken by
|
||||||
// something like this
|
// something like this
|
||||||
//let _ = [div(cx)].into_view(cx);
|
//let _ = [div(cx)].into_view(cx);
|
||||||
|
|
||||||
div(cx)
|
div(cx)
|
||||||
.id("the-div")
|
.id("the-div")
|
||||||
.child(
|
.child(
|
||||||
input(cx)
|
input(cx)
|
||||||
.attr("type", "text")
|
.attr("type", "text")
|
||||||
.prop("value", (cx, value))
|
.prop("value", (cx, value))
|
||||||
.on(ev::input, move |e| set_value(event_target_value(&e))),
|
.on(ev::input, move |e| set_value(event_target_value(&e))),
|
||||||
)
|
)
|
||||||
.child(input(cx).attr("type", "text").prop("value", value))
|
.child(input(cx).attr("type", "text").prop("value", value))
|
||||||
.child(p(cx).child("Value: ").child(value))
|
.child(p(cx).child("Value: ").child(value))
|
||||||
.into_view(cx)
|
.into_view(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "hydrate")]
|
#[cfg(feature = "hydrate")]
|
||||||
|
@ -61,11 +61,11 @@ use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
#[cfg(feature = "hydrate")]
|
#[cfg(feature = "hydrate")]
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn hydrate() {
|
pub fn hydrate() {
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
gloo::console::debug!("starting WASM");
|
gloo::console::debug!("starting WASM");
|
||||||
|
|
||||||
leptos::mount_to_body(move |cx| {
|
leptos::mount_to_body(move |cx| {
|
||||||
view! { cx, <App/> }
|
view! { cx, <App/> }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ gloo = { version = "0.8", features = ["futures"] }
|
||||||
leptos = { path = "../../../leptos", features = ["tracing"] }
|
leptos = { path = "../../../leptos", features = ["tracing"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = "0.3"
|
tracing-subscriber = "0.3"
|
||||||
tracing-subscriber-wasm = "0.1"
|
|
||||||
wasm-bindgen-futures = "0.4"
|
wasm-bindgen-futures = "0.4"
|
||||||
web-sys = "0.3"
|
web-sys = "0.3"
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,102 @@
|
||||||
|
#![allow(warnings)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate tracing;
|
extern crate tracing;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use tracing_subscriber::prelude::*;
|
use tracing::field::debug;
|
||||||
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tracing_subscriber::fmt()
|
console_error_panic_hook::set_once();
|
||||||
.with_writer(tracing_subscriber_wasm::MakeConsoleWriter::default())
|
|
||||||
.without_time()
|
|
||||||
.with_max_level(tracing::Level::TRACE)
|
|
||||||
.pretty()
|
|
||||||
.with_target(false)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
mount_to_body(app);
|
tracing_subscriber::fmt()
|
||||||
|
.with_max_level(tracing::Level::TRACE)
|
||||||
|
.without_time()
|
||||||
|
.with_file(true)
|
||||||
|
.with_line_number(true)
|
||||||
|
.with_target(false)
|
||||||
|
.with_writer(utils::MakeConsoleWriter)
|
||||||
|
.with_ansi(false)
|
||||||
|
.pretty()
|
||||||
|
.finish()
|
||||||
|
.init();
|
||||||
|
|
||||||
|
mount_to_body(view_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
fn view_fn(cx: Scope) -> impl IntoView {
|
||||||
fn app(cx: Scope) -> impl IntoView {
|
let view = view! { cx,
|
||||||
let (data, set_data) = create_signal(cx, vec![1, 3, 5]);
|
<For
|
||||||
|
each=|| vec![0, 1, 2, 3, 4, 5, 6, 7]
|
||||||
|
key=|i| *i
|
||||||
|
view=|cx, i| view! { cx, {i} }
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
.into_view(cx);
|
||||||
|
|
||||||
let handle_change = move |_| {
|
let (a, set_a) = create_signal(cx, view.clone());
|
||||||
set_data.update(|data| {
|
let (b, set_b) = create_signal(cx, view);
|
||||||
if [1, 3, 5] == data[..] {
|
|
||||||
*data = vec![0, 1, 2, 3, 4, 5, 6];
|
|
||||||
} else {
|
|
||||||
*data = vec![1, 3, 5];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
view! { cx,
|
let (is_a, set_is_a) = create_signal(cx, true);
|
||||||
<button on:click=handle_change>"Reverse"</button>
|
|
||||||
|
|
||||||
<For
|
let handle_toggle = move |_| {
|
||||||
each=data
|
trace!("toggling");
|
||||||
key=|item| *item
|
if is_a() {
|
||||||
view=|cx, i| view! { cx, <h3>{i}</h3> }
|
set_b(a());
|
||||||
/>
|
|
||||||
|
set_is_a(false);
|
||||||
|
} else {
|
||||||
|
set_a(a());
|
||||||
|
|
||||||
|
set_is_a(true);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let a_tag = view! { cx, <svg::a/> };
|
||||||
|
|
||||||
|
view! { cx,
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<button on:click=handle_toggle>"Toggle"</button>
|
||||||
|
</div>
|
||||||
|
<svg>{a_tag}</svg>
|
||||||
|
<Example/>
|
||||||
|
<A child=Signal::from(a) />
|
||||||
|
<A child=Signal::from(b) />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn A(cx: Scope, child: Signal<View>) -> impl IntoView {
|
||||||
|
move || child()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Example(cx: Scope) -> impl IntoView {
|
||||||
|
trace!("rendering <Example/>");
|
||||||
|
|
||||||
|
let (value, set_value) = create_signal(cx, 10);
|
||||||
|
|
||||||
|
let memo = create_memo(cx, move |_| value() * 2);
|
||||||
|
let derived = Signal::derive(cx, move || value() * 3);
|
||||||
|
|
||||||
|
create_effect(cx, move |_| {
|
||||||
|
trace!("logging value of derived..., {}", derived.get());
|
||||||
|
});
|
||||||
|
|
||||||
|
set_timeout(
|
||||||
|
move || set_value.update(|v| *v += 1),
|
||||||
|
std::time::Duration::from_millis(50),
|
||||||
|
);
|
||||||
|
|
||||||
|
view! { cx,
|
||||||
|
<h1>"Example"</h1>
|
||||||
|
<button on:click=move |_| set_value.update(|value| *value += 1)>
|
||||||
|
"Click me"
|
||||||
|
</button>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
pub struct MakeConsoleWriter;
|
||||||
|
use std::io::{self, Write};
|
||||||
|
use tracing_subscriber::fmt::MakeWriter;
|
||||||
|
|
||||||
|
impl<'a> MakeWriter<'a> for MakeConsoleWriter {
|
||||||
|
type Writer = ConsoleWriter;
|
||||||
|
|
||||||
|
fn make_writer(&'a self) -> Self::Writer {
|
||||||
|
unimplemented!("use make_writer_for instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_writer_for(&'a self, meta: &tracing::Metadata<'_>) -> Self::Writer {
|
||||||
|
ConsoleWriter(*meta.level(), Vec::with_capacity(256))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ConsoleWriter(tracing::Level, Vec<u8>);
|
||||||
|
|
||||||
|
impl io::Write for ConsoleWriter {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
|
self.1.write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
|
use gloo::console;
|
||||||
|
use tracing::Level;
|
||||||
|
|
||||||
|
let data = String::from_utf8(self.1.to_owned())
|
||||||
|
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "data not UTF-8"))?;
|
||||||
|
|
||||||
|
match self.0 {
|
||||||
|
Level::TRACE => console::debug!(&data),
|
||||||
|
Level::DEBUG => console::debug!(&data),
|
||||||
|
Level::INFO => console::log!(&data),
|
||||||
|
Level::WARN => console::warn!(&data),
|
||||||
|
Level::ERROR => console::error!(&data),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for ConsoleWriter {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.flush();
|
||||||
|
}
|
||||||
|
}
|
|
@ -347,72 +347,60 @@ where
|
||||||
let (children, closing) =
|
let (children, closing) =
|
||||||
(component.children.clone(), component.closing.node.clone());
|
(component.children.clone(), component.closing.node.clone());
|
||||||
|
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
cfg_if::cfg_if! {
|
||||||
{
|
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
|
||||||
create_effect(cx, move |prev_hash_run| {
|
create_effect(cx, move |prev_hash_run| {
|
||||||
let mut children_borrow = children.borrow_mut();
|
let mut children_borrow = children.borrow_mut();
|
||||||
|
|
||||||
let opening = if let Some(Some(child)) = children_borrow.get(0)
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
{
|
let opening = if let Some(Some(child)) = children_borrow.get(0) {
|
||||||
child.get_opening_node()
|
child.get_opening_node()
|
||||||
} else {
|
} else {
|
||||||
closing.clone()
|
closing.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let items = items_fn();
|
let items = items_fn();
|
||||||
|
|
||||||
let items = items.into_iter().collect::<SmallVec<[_; 128]>>();
|
let items = items.into_iter().collect::<SmallVec<[_; 128]>>();
|
||||||
|
|
||||||
let hashed_items =
|
let hashed_items =
|
||||||
items.iter().map(&key_fn).collect::<FxIndexSet<_>>();
|
items.iter().map(&key_fn).collect::<FxIndexSet<_>>();
|
||||||
|
|
||||||
if let Some(HashRun(prev_hash_run)) = prev_hash_run {
|
if let Some(HashRun(prev_hash_run)) = prev_hash_run {
|
||||||
let cmds = diff(&prev_hash_run, &hashed_items);
|
let cmds = diff(&prev_hash_run, &hashed_items);
|
||||||
|
|
||||||
tracing::debug!("cmds:\n{cmds:#?}");
|
apply_cmds(
|
||||||
|
cx,
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
&opening,
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
&closing,
|
||||||
|
cmds,
|
||||||
|
&mut children_borrow,
|
||||||
|
items.into_iter().map(|t| Some(t)).collect(),
|
||||||
|
&each_fn
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
*children_borrow = Vec::with_capacity(items.len());
|
||||||
|
|
||||||
apply_cmds(
|
for item in items {
|
||||||
cx,
|
let (each_item, _) = cx.run_child_scope(|cx| EachItem::new(cx, each_fn(cx, item).into_view(cx)));
|
||||||
&opening,
|
|
||||||
&closing,
|
|
||||||
cmds,
|
|
||||||
&mut children_borrow,
|
|
||||||
items.into_iter().map(|t| Some(t)).collect(),
|
|
||||||
&each_fn,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
children_borrow.clear();
|
|
||||||
children_borrow.reserve(items.len());
|
|
||||||
|
|
||||||
for item in items {
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
let (each_item, disposer) = cx.run_child_scope(|cx| {
|
mount_child(MountKind::Before(&closing), &each_item);
|
||||||
EachItem::new(cx, each_fn(cx, item).into_view(cx))
|
|
||||||
});
|
|
||||||
|
|
||||||
mount_child(MountKind::Before(&closing), &each_item);
|
children_borrow.push(Some(each_item));
|
||||||
|
|
||||||
children_borrow.push(Some(each_item));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HashRun(hashed_items)
|
HashRun(hashed_items)
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
|
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
|
||||||
{
|
|
||||||
*component.children.borrow_mut() = (items_fn)()
|
*component.children.borrow_mut() = (items_fn)()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|child| {
|
.map(|child| cx.run_child_scope(|cx| Some(EachItem::new(cx, (each_fn)(cx, child).into_view(cx)))).0)
|
||||||
cx.run_child_scope(|cx| {
|
.collect();
|
||||||
Some(EachItem::new(
|
}
|
||||||
cx,
|
|
||||||
(each_fn)(cx, child).into_view(cx),
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.0
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
View::CoreComponent(CoreComponent::Each(component))
|
View::CoreComponent(CoreComponent::Each(component))
|
||||||
|
@ -423,7 +411,7 @@ where
|
||||||
#[educe(Debug)]
|
#[educe(Debug)]
|
||||||
struct HashRun<T>(#[educe(Debug(ignore))] T);
|
struct HashRun<T>(#[educe(Debug(ignore))] T);
|
||||||
|
|
||||||
/// Calculates the operations needed to get from `a` to `b`.
|
/// Calculates the operations need to get from `a` to `b`.
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
fn diff<K: Eq + Hash>(from: &FxIndexSet<K>, to: &FxIndexSet<K>) -> Diff {
|
fn diff<K: Eq + Hash>(from: &FxIndexSet<K>, to: &FxIndexSet<K>) -> Diff {
|
||||||
if from.is_empty() && to.is_empty() {
|
if from.is_empty() && to.is_empty() {
|
||||||
|
@ -436,73 +424,72 @@ fn diff<K: Eq + Hash>(from: &FxIndexSet<K>, to: &FxIndexSet<K>) -> Diff {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get removed items
|
// Get removed items
|
||||||
let mut removed =
|
let mut removed = from.difference(to);
|
||||||
from.difference(to).map(|k| from.get_index_of(k).unwrap());
|
|
||||||
|
|
||||||
let removed_cmds = removed.clone().map(|idx| DiffOpRemove { at: idx });
|
let removed_cmds = removed
|
||||||
|
.clone()
|
||||||
|
.map(|k| from.get_full(k).unwrap().0)
|
||||||
|
.map(|idx| DiffOpRemove { at: idx });
|
||||||
|
|
||||||
// Get added items
|
// Get added items
|
||||||
let mut added = to.difference(from).map(|k| to.get_index_of(k).unwrap());
|
let mut added = to.difference(from);
|
||||||
|
|
||||||
let added_cmds = added.clone().map(|idx| DiffOpAdd {
|
let added_cmds =
|
||||||
at: idx,
|
added
|
||||||
mode: Default::default(),
|
.clone()
|
||||||
});
|
.map(|k| to.get_full(k).unwrap().0)
|
||||||
|
.map(|idx| DiffOpAdd {
|
||||||
|
at: idx,
|
||||||
|
mode: Default::default(),
|
||||||
|
});
|
||||||
|
|
||||||
let mut normalized_idx = 0i64;
|
// Get moved items
|
||||||
let mut next_added_idx = added.next();
|
let mut normalized_idx = 0;
|
||||||
let mut next_removed_idx = removed.next();
|
let mut move_cmds = SmallVec::<[_; 8]>::with_capacity(to.len());
|
||||||
|
let mut added_idx = added.next().map(|k| to.get_full(k).unwrap().0);
|
||||||
|
let mut removed_idx = removed.next().map(|k| from.get_full(k).unwrap().0);
|
||||||
|
|
||||||
let move_cmds = to
|
for (idx, k) in to.iter().enumerate() {
|
||||||
.iter()
|
if let Some(added_idx) = added_idx.as_mut().filter(|r_i| **r_i == idx) {
|
||||||
.enumerate()
|
if let Some(next_added) =
|
||||||
.filter_map(|(i, k)| {
|
added.next().map(|k| to.get_full(k).unwrap().0)
|
||||||
let is_added = if let Some(idx) = next_added_idx {
|
{
|
||||||
if i == idx {
|
*added_idx = next_added;
|
||||||
next_added_idx = added.next();
|
|
||||||
normalized_idx -= 1;
|
|
||||||
|
|
||||||
true
|
normalized_idx = usize::wrapping_sub(normalized_idx, 1);
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
let is_removed = if let Some(idx) = next_removed_idx {
|
|
||||||
if i == idx {
|
|
||||||
next_removed_idx = removed.next();
|
|
||||||
normalized_idx += 1;
|
|
||||||
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
normalized_idx += 1;
|
|
||||||
|
|
||||||
if !is_added && !is_removed {
|
|
||||||
Some((
|
|
||||||
from.get_index_of(k).unwrap(),
|
|
||||||
i,
|
|
||||||
// We need to `-1` because otherwise, we'd be accounting for
|
|
||||||
// the NEXT iteration, not this current one
|
|
||||||
normalized_idx - 1,
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.map(|(from, to, normalized_idx)| DiffOpMove {
|
|
||||||
from,
|
if let Some(removed_idx) =
|
||||||
to,
|
removed_idx.as_mut().filter(|r_i| **r_i == idx)
|
||||||
move_in_dom: to != normalized_idx as usize,
|
{
|
||||||
})
|
normalized_idx = normalized_idx.wrapping_add(1);
|
||||||
.collect();
|
|
||||||
|
if let Some(next_removed) =
|
||||||
|
removed.next().map(|k| from.get_full(k).unwrap().0)
|
||||||
|
{
|
||||||
|
*removed_idx = next_removed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((from_idx, _)) = from.get_full(k) {
|
||||||
|
if from_idx != normalized_idx {
|
||||||
|
move_cmds.push(DiffOpMove {
|
||||||
|
from: from_idx,
|
||||||
|
to: idx,
|
||||||
|
move_in_dom: true,
|
||||||
|
});
|
||||||
|
} else if from_idx != idx {
|
||||||
|
move_cmds.push(DiffOpMove {
|
||||||
|
from: from_idx,
|
||||||
|
to: idx,
|
||||||
|
move_in_dom: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
normalized_idx = normalized_idx.wrapping_add(1);
|
||||||
|
}
|
||||||
|
|
||||||
let mut diffs = Diff {
|
let mut diffs = Diff {
|
||||||
removed: removed_cmds.collect(),
|
removed: removed_cmds.collect(),
|
||||||
|
@ -634,16 +621,17 @@ fn apply_cmds<T, EF, N>(
|
||||||
if opening.previous_sibling().is_none()
|
if opening.previous_sibling().is_none()
|
||||||
&& closing.next_sibling().is_none()
|
&& closing.next_sibling().is_none()
|
||||||
{
|
{
|
||||||
if let Some(parent) = closing
|
let parent = closing
|
||||||
.parent_node()
|
.parent_node()
|
||||||
.map(JsCast::unchecked_into::<web_sys::Element>)
|
.expect("could not get closing node")
|
||||||
{
|
.unchecked_into::<web_sys::Element>();
|
||||||
#[cfg(debug_assertions)]
|
parent.set_text_content(Some(""));
|
||||||
parent.append_with_node_2(opening, closing).unwrap();
|
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(debug_assertions)]
|
||||||
parent.append_with_node_1(closing).unwrap();
|
parent.append_with_node_2(opening, closing).unwrap();
|
||||||
}
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
parent.append_with_node_1(closing).unwrap();
|
||||||
} else {
|
} else {
|
||||||
range.set_start_before(opening).unwrap();
|
range.set_start_before(opening).unwrap();
|
||||||
range.set_end_before(closing).unwrap();
|
range.set_end_before(closing).unwrap();
|
||||||
|
@ -676,7 +664,7 @@ fn apply_cmds<T, EF, N>(
|
||||||
for DiffOpAdd { at, mode } in cmds.added {
|
for DiffOpAdd { at, mode } in cmds.added {
|
||||||
let item = items[at].take().unwrap();
|
let item = items[at].take().unwrap();
|
||||||
|
|
||||||
let (each_item, disposer) = cx.run_child_scope(|cx| {
|
let (each_item, _) = cx.run_child_scope(|cx| {
|
||||||
let child = each_fn(cx, item).into_view(cx);
|
let child = each_fn(cx, item).into_view(cx);
|
||||||
EachItem::new(cx, child)
|
EachItem::new(cx, child)
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue