Skip to content

Commit 2f7db33

Browse files
committed
fix(forest): remove child nodes from their parent before manipulation
1 parent 8cd5b68 commit 2f7db33

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

float-pigment-forest/src/node.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ impl Node {
226226
let self_node = Box::new(Self::new());
227227
Box::into_raw(self_node)
228228
}
229-
pub unsafe fn parent(&self) -> Option<&Node> {
229+
pub unsafe fn parent<'a>(&self) -> Option<&'a Node> {
230230
if self.parent.get().is_null() {
231231
None
232232
} else {
@@ -267,7 +267,12 @@ impl Node {
267267
self.layout_node.computed_style()
268268
}
269269
pub unsafe fn set_node_type(&self, node_type: NodeType) {
270-
if self.node_type.get() != node_type {
270+
let prev_type = self.node_type.get();
271+
if prev_type != node_type {
272+
if prev_type == NodeType::Text {
273+
*self.measure_cache.get() = None;
274+
*self.baseline_cache.get() = None;
275+
}
271276
self.node_type.replace(node_type);
272277
}
273278
if node_type == NodeType::Text {
@@ -278,8 +283,10 @@ impl Node {
278283

279284
#[inline(always)]
280285
pub(crate) unsafe fn measure_cache(&self) -> Option<&mut MeasureCache> {
281-
let ret: *mut _ = self.measure_cache.get();
282-
(*ret).as_deref_mut()
286+
if self.node_type() != NodeType::Text {
287+
return None;
288+
}
289+
(*self.measure_cache.get()).as_deref_mut()
283290
}
284291

285292
pub(crate) unsafe fn clear_measure_cache(&self) {
@@ -290,8 +297,10 @@ impl Node {
290297

291298
#[inline(always)]
292299
pub(crate) unsafe fn baseline_cache(&self) -> Option<&mut BaselineCache> {
293-
let ret: *mut _ = self.baseline_cache.get();
294-
(*ret).as_deref_mut()
300+
if self.node_type() != NodeType::Text {
301+
return None;
302+
}
303+
(*self.baseline_cache.get()).as_deref_mut()
295304
}
296305

297306
pub(crate) unsafe fn clear_baseline_cache(&self) {
@@ -503,18 +512,27 @@ impl ChildOperation for Node {
503512
}
504513
#[allow(clippy::not_unsafe_ptr_arg_deref)]
505514
unsafe fn append_child(&self, child: NodePtr) {
515+
if let Some(prev_parent) = (*child).parent() {
516+
prev_parent.remove_child(child);
517+
}
506518
(*child).set_parent(Some(convert_node_ref_to_ptr(self)));
507519
self.children.borrow_mut().push(child);
508520
self.mark_dirty_propagate()
509521
}
510522
#[allow(clippy::not_unsafe_ptr_arg_deref)]
511523
unsafe fn insert_child_at(&self, child: NodePtr, idx: usize) {
524+
if let Some(prev_parent) = (*child).parent() {
525+
prev_parent.remove_child(child);
526+
}
512527
(*child).set_parent(Some(convert_node_ref_to_ptr(self)));
513528
self.children.borrow_mut().insert(idx, child);
514529
self.mark_dirty_propagate()
515530
}
516531
#[allow(clippy::not_unsafe_ptr_arg_deref)]
517532
unsafe fn insert_child_before(&self, child: NodePtr, pivot: NodePtr) {
533+
if let Some(prev_parent) = (*child).parent() {
534+
prev_parent.remove_child(child);
535+
}
518536
(*child).set_parent(Some(convert_node_ref_to_ptr(self)));
519537
let idx = self
520538
.children

0 commit comments

Comments
 (0)