Skip to content

insert_id_before doesn't detach the inserted node #24

@newsch

Description

@newsch

Calling insert_id_before or insert_id_after with a node that is already a child doesn't remove it from the parent's list of children.

I came across this while trying to replace a node with its children.

If this is unexpected behavior, I'd be happy to make a PR.

Reproducible example:

//! ```cargo
//! [dependencies]
//! ego-tree = "=0.6.2"
//! scraper = "=0.16.0"
//! ```
use scraper::{ElementRef, Html, Selector};

fn main() {
    let html = r#"
    <p> Some text that includes
        <a href="Some_Page">several</a>
        <a href="./Another_Page">relative links</a>
    and
        <a href="https://example.com/page">an absolute link</a>
    .
    </p>
    "#;

    let anchors = Selector::parse("a").unwrap();

    let mut document = Html::parse_fragment(html);

    let links: Vec<_> = document
        .select(&anchors)
        .map(|el| el.id())
        .collect();

    for id in links {
        let Some(mut node) = document.tree.get_mut(id) else { continue };

        while let Some(mut child) = node.first_child() {
            let child_id = child.id();
            eprintln!("Reparenting node {:?}", child_id);
            child.detach(); // <---- comment this for infinite loop
            node.insert_id_before(child_id);
            // node.insert_id_after(child_id);
        }

        node.detach();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions