From 7091c76144f58215e138f340bd2787ba22c5cc95 Mon Sep 17 00:00:00 2001 From: Joshua Thijssen Date: Sat, 14 Sep 2024 11:54:33 +0200 Subject: [PATCH] error: could not compile (lib) due to 22 previous errors; 1 warning emitted --- crates/gosub_html5/src/document/document.rs | 20 +- crates/gosub_html5/src/document/task_queue.rs | 2 +- crates/gosub_html5/src/node/node.rs | 185 +++++++++++------- crates/gosub_html5/src/parser.rs | 23 +-- crates/gosub_html5/src/parser/helper.rs | 21 +- crates/gosub_html5/src/writer.rs | 26 +-- crates/gosub_shared/src/traits/node.rs | 32 +-- 7 files changed, 175 insertions(+), 134 deletions(-) diff --git a/crates/gosub_html5/src/document/document.rs b/crates/gosub_html5/src/document/document.rs index 0dbb9a9b9..f4ed22593 100755 --- a/crates/gosub_html5/src/document/document.rs +++ b/crates/gosub_html5/src/document/document.rs @@ -691,19 +691,19 @@ mod tests { // div child let div_child = doc_read.get_node_by_id(root_children[0]).unwrap(); - assert_eq!(div_child.type_of(), NodeType::Element); + assert_eq!(div_child.type_of(), NodeType::ElementNode); assert_eq!(div_child.name, "div"); let div_children = &div_child.children; // p child let p_child = doc_read.get_node_by_id(div_children[0]).unwrap(); - assert_eq!(p_child.type_of(), NodeType::Element); + assert_eq!(p_child.type_of(), NodeType::ElementNode); assert_eq!(p_child.name, "p"); let p_children = &p_child.children; // comment inside p let p_comment = doc_read.get_node_by_id(p_children[0]).unwrap(); - assert_eq!(p_comment.type_of(), NodeType::Comment); + assert_eq!(p_comment.type_of(), NodeType::CommentNode); let NodeData::Comment(p_comment_data) = &p_comment.data else { panic!() }; @@ -711,7 +711,7 @@ mod tests { // body inside p let p_body = doc_read.get_node_by_id(p_children[1]).unwrap(); - assert_eq!(p_body.type_of(), NodeType::Text); + assert_eq!(p_body.type_of(), NodeType::TextNode); let NodeData::Text(p_body_data) = &p_body.data else { panic!() }; @@ -719,7 +719,7 @@ mod tests { // comment inside div let div_comment = doc_read.get_node_by_id(div_children[1]).unwrap(); - assert_eq!(div_comment.type_of(), NodeType::Comment); + assert_eq!(div_comment.type_of(), NodeType::CommentNode); let NodeData::Comment(div_comment_data) = &div_comment.data else { panic!() }; @@ -852,19 +852,19 @@ mod tests { // div child let div_child = doc_read.get_node_by_id(root_children[0]).unwrap(); - assert_eq!(div_child.type_of(), NodeType::Element); + assert_eq!(div_child.type_of(), NodeType::ElementNode); assert_eq!(div_child.name, "div"); let div_children = &div_child.children; // p child let p_child = doc_read.get_node_by_id(div_children[0]).unwrap(); - assert_eq!(p_child.type_of(), NodeType::Element); + assert_eq!(p_child.type_of(), NodeType::ElementNode); assert_eq!(p_child.name, "p"); let p_children = &p_child.children; // comment inside p let p_comment = doc_read.get_node_by_id(p_children[0]).unwrap(); - assert_eq!(p_comment.type_of(), NodeType::Comment); + assert_eq!(p_comment.type_of(), NodeType::CommentNode); let NodeData::Comment(p_comment_data) = &p_comment.data else { panic!() }; @@ -872,7 +872,7 @@ mod tests { // body inside p let p_body = doc_read.get_node_by_id(p_children[1]).unwrap(); - assert_eq!(p_body.type_of(), NodeType::Text); + assert_eq!(p_body.type_of(), NodeType::TextNode); let NodeData::Text(p_body_data) = &p_body.data else { panic!() }; @@ -880,7 +880,7 @@ mod tests { // comment inside div let div_comment = doc_read.get_node_by_id(div_children[1]).unwrap(); - assert_eq!(div_comment.type_of(), NodeType::Comment); + assert_eq!(div_comment.type_of(), NodeType::CommentNode); let NodeData::Comment(div_comment_data) = &div_comment.data else { panic!() }; diff --git a/crates/gosub_html5/src/document/task_queue.rs b/crates/gosub_html5/src/document/task_queue.rs index 0e1432937..c4752ae21 100644 --- a/crates/gosub_html5/src/document/task_queue.rs +++ b/crates/gosub_html5/src/document/task_queue.rs @@ -113,7 +113,7 @@ impl DocumentTaskQueue { element_id, } => { if let Some(node) = self.document.get_mut().get_node_by_id_mut(*element_id) { - if let Some(data) = node.get_element_data_mut() { + if let Some(mut data) = node.get_element_data_mut() { data.attributes_mut().insert(key.clone(), value.clone()); // let mut attributes = node.get_element_data().unwrap().attributes().clone(); // attributes.insert(key.clone(), value.clone()); diff --git a/crates/gosub_html5/src/node/node.rs b/crates/gosub_html5/src/node/node.rs index cdfa3e6a1..69d0957dc 100644 --- a/crates/gosub_html5/src/node/node.rs +++ b/crates/gosub_html5/src/node/node.rs @@ -1,9 +1,10 @@ -use gosub_shared::traits::node::{Node, NodeDataType}; +use gosub_shared::traits::node::{Node, NodeType}; use crate::node::data::comment::CommentData; use crate::node::data::doctype::DocTypeData; use crate::node::data::document::DocumentData; use crate::node::data::text::TextData; use core::fmt::Debug; +use std::cell::{Ref, RefCell, RefMut}; use gosub_shared::byte_stream::Location; use gosub_shared::document::DocumentHandle; use gosub_shared::node::NodeId; @@ -31,18 +32,13 @@ pub struct NodeImpl { pub id: NodeId, /// parent of the node, if any pub parent: Option, - /// children of the node + /// any children of the node pub children: Vec, - // /// name of the node, or empty when it's not a tag - // pub name: String, - // /// namespace of the node - // pub namespace: Option, /// actual data of the node - pub data: NodeDataTypeInternal, - /// weak pointer to document this node is attached to - // pub document: Weak>, + pub data: RefCell, + /// Handle to the document in which this node resides pub document: DocumentHandle, - // Returns true when the given node is registered into an arena + // Returns true when the given node is registered into the document arena pub is_registered: bool, // Location of the node in the source code pub location: Location, @@ -80,77 +76,118 @@ impl Node for NodeImpl { self.parent_id().is_none() } - // fn type_of_mut(&mut self) -> &mut NodeDataType - // where - // Self: Sized - // { - // match &mut self.data { - // NodeDataTypeInternal::Document(data) => &mut NodeDataType::Document(data), - // NodeDataTypeInternal::DocType(data) => &mut NodeDataType::DocType(data), - // NodeDataTypeInternal::Text(data) => &mut NodeDataType::Text(data), - // NodeDataTypeInternal::Comment(data) => &mut NodeDataType::Comment(data), - // NodeDataTypeInternal::Element(data) => &mut NodeDataType::Element(data), - // } - // } - fn children(&self) -> &[NodeId] { self.children.as_slice() } - /// Returns the token type of the given token - fn type_of(&self) -> NodeDataType { - match &self.data { - NodeDataTypeInternal::Document(data) => NodeDataType::Document(data), - NodeDataTypeInternal::DocType(data) => NodeDataType::DocType(data), - NodeDataTypeInternal::Text(data) => NodeDataType::Text(data), - NodeDataTypeInternal::Comment(data) => NodeDataType::Comment(data), - NodeDataTypeInternal::Element(data) => NodeDataType::Element(data), + fn type_of(&self) -> NodeType { + match *self.data.borrow() { + NodeDataTypeInternal::Document(_) => NodeType::DocumentNode, + NodeDataTypeInternal::DocType(_) => NodeType::DocTypeNode, + NodeDataTypeInternal::Text(_) => NodeType::TextNode, + NodeDataTypeInternal::Comment(_) => NodeType::CommentNode, + NodeDataTypeInternal::Element(_) => NodeType::ElementNode, } } fn is_element_node(&self) -> bool { - match &self.data { - NodeDataTypeInternal::Element(_) => true, - _ => false, - } + self.type_of() == NodeType::ElementNode } - fn get_element_data(&self) -> Option<&Self::ElementData> { - if let NodeDataTypeInternal::Element(data) = &self.data { - return Some(data); - } + fn get_element_data(&self) -> Option> { + let borrowed_data = self.data.borrow(); + if let NodeDataTypeInternal::Element(_) = *borrowed_data { + return Some(Ref::map(borrowed_data, |d| + if let NodeDataTypeInternal::Element(ref element_data) = d { + element_data + } else { + unreachable!() + } + )); + } None } - fn get_element_data_mut(&mut self) -> Option<&mut Self::ElementData> { - if let NodeDataTypeInternal::Element(data) = &mut self.data { - return Some(data); - } + fn get_element_data_mut(&self) -> Option> { + let borrowed_data = self.data.borrow_mut(); + if let NodeDataTypeInternal::Element(_) = *borrowed_data { + return Some(RefMut::map(borrowed_data, |d| { + if let NodeDataTypeInternal::Element(ref mut element_data) = d { + element_data + } else { + unreachable!() + } + })); + } None } fn is_text_node(&self) -> bool { - match &self.data { + match *self.data.borrow() { NodeDataTypeInternal::Text(_) => true, _ => false, } } - fn get_text_data(&self) -> Option<&Self::TextData> { - if let NodeDataTypeInternal::Text(data) = &self.data { - return Some(data); + fn get_text_data(&self) -> Option> { + let borrowed_data = self.data.borrow(); + + if let NodeDataTypeInternal::Text(_) = *borrowed_data { + return Some(Ref::map(borrowed_data, |d| + if let NodeDataTypeInternal::Text(ref text_data) = d { + text_data + } else { + unreachable!() + } + )); } + None + } + + fn get_text_data_mut(&self) -> Option> { + let borrowed_data = self.data.borrow_mut(); + if let NodeDataTypeInternal::Text(_) = *borrowed_data { + return Some(RefMut::map(borrowed_data, |d| { + if let NodeDataTypeInternal::Text(ref mut text_data) = d { + text_data + } else { + unreachable!() + } + })); + } None } - fn get_text_data_mut(&mut self) -> Option<&mut Self::TextData> { - if let NodeDataTypeInternal::Text(data) = &mut self.data { - return Some(data); + fn get_comment_data(&self) -> Option> { + let borrowed_data = self.data.borrow(); + + if let NodeDataTypeInternal::Comment(_) = *borrowed_data { + return Some(Ref::map(borrowed_data, |d| + if let NodeDataTypeInternal::Comment(ref text_data) = d { + text_data + } else { + unreachable!() + } + )); } + None + } + fn get_doctype_data(&self) -> Option> { + let borrowed_data = self.data.borrow(); + + if let NodeDataTypeInternal::DocType(_) = *borrowed_data { + return Some(Ref::map(borrowed_data, |d| + if let NodeDataTypeInternal::DocType(ref text_data) = d { + text_data + } else { + unreachable!() + } + )); + } None } @@ -211,7 +248,7 @@ impl NodeImpl { id, parent, children, - data: data.clone(), + data: data.clone().into(), document: document.clone(), is_registered, location, @@ -286,21 +323,21 @@ impl NodeImpl { self.is_registered } - pub fn is_text(&self) -> bool { - if let NodeDataTypeInternal::Text(_) = &self.data { - return true; - } - - false - } - - pub fn as_text(&self) -> &TextData { - if let NodeDataTypeInternal::Text(text) = &self.data { - return text; - } - - panic!("Node is not a text"); - } + // pub fn is_text(&self) -> bool { + // if let NodeDataTypeInternal::Text(_) = *self.data.borrow() { + // return true; + // } + // + // false + // } + // + // pub fn as_text(&self) -> &TextData { + // if let NodeDataTypeInternal::Text(text) = &self.data { + // return text; + // } + // + // panic!("Node is not a text"); + // } } #[cfg(test)] @@ -397,11 +434,11 @@ mod tests { fn type_of() { let document = Document::shared(None); let node = Node::new_document(&document, Location::default()); - assert_eq!(node.type_of(), NodeType::Document); + assert_eq!(node.type_of(), NodeType::DocumentNode); let node = Node::new_text(&document, Location::default(), "test"); - assert_eq!(node.type_of(), NodeType::Text); + assert_eq!(node.type_of(), NodeType::TextNode); let node = Node::new_comment(&document, Location::default(), "test"); - assert_eq!(node.type_of(), NodeType::Comment); + assert_eq!(node.type_of(), NodeType::CommentNode); let mut attributes = HashMap::new(); attributes.insert("id".to_string(), "test".to_string()); let node = Node::new_element( @@ -411,7 +448,7 @@ mod tests { HTML_NAMESPACE, Location::default(), ); - assert_eq!(node.type_of(), NodeType::Element); + assert_eq!(node.type_of(), NodeType::ElementNode); } #[test] @@ -470,11 +507,11 @@ mod tests { fn type_of_node() { let document = Document::shared(None); let node = Node::new_document(&document, Location::default()); - assert_eq!(node.type_of(), NodeType::Document); + assert_eq!(node.type_of(), NodeType::DocumentNode); let node = Node::new_text(&document, Location::default(), "test"); - assert_eq!(node.type_of(), NodeType::Text); + assert_eq!(node.type_of(), NodeType::TextNode); let node = Node::new_comment(&document, Location::default(), "test"); - assert_eq!(node.type_of(), NodeType::Comment); + assert_eq!(node.type_of(), NodeType::CommentNode); let mut attributes = HashMap::new(); attributes.insert("id".to_string(), "test".to_string()); let node = Node::new_element( @@ -484,6 +521,6 @@ mod tests { HTML_NAMESPACE, Location::default(), ); - assert_eq!(node.type_of(), NodeType::Element); + assert_eq!(node.type_of(), NodeType::ElementNode); } } diff --git a/crates/gosub_html5/src/parser.rs b/crates/gosub_html5/src/parser.rs index db52486d9..07d66cd43 100644 --- a/crates/gosub_html5/src/parser.rs +++ b/crates/gosub_html5/src/parser.rs @@ -24,7 +24,6 @@ use crate::document::builder::DocumentBuilder; use crate::document::document::DocumentImpl; use crate::document::fragment::DocumentFragmentImpl; use crate::node::{HTML_NAMESPACE, MATHML_NAMESPACE, SVG_NAMESPACE}; -use crate::node::node::NodeDataTypeInternal; use crate::parser::attr_replacements::{ MATHML_ADJUSTMENTS, SVG_ADJUSTMENTS_ATTRIBUTES, SVG_ADJUSTMENTS_TAGS, XML_ADJUSTMENTS, }; @@ -2272,13 +2271,15 @@ impl<'chars, D: Document> Html5Parser<'chars, D> let first_node = doc .get_node_by_id_mut(first_node_id) .expect("node not found"); - if let NodeDataTypeInternal::Element(element) = &mut first_node.data() { + + if first_node.is_element_node() { + let element_data = get_element_data_mut!(first_node); for (key, value) in attributes { - if !element.attributes().contains_key(key) { - element.attributes().insert(key.to_owned(), value.to_owned()); + if !element_data.attributes().contains_key(key) { + element_data.attributes().insert(key.to_owned(), value.to_owned()); } } - }; + } } Token::StartTag { name, .. } if name == "base" @@ -2353,7 +2354,7 @@ impl<'chars, D: Document> Html5Parser<'chars, D> if second_node.parent_id().is_some() { self.document .get_mut() - .remove_from_parent(second_node_id) + .detach_node(second_node_id) } } @@ -3149,7 +3150,7 @@ impl<'chars, D: Document> Html5Parser<'chars, D> Token::StartTag { name, .. } if name == "script" => { let insert_position = self.appropriate_place_insert(None); let node = self.create_node(&self.current_token.clone(), HTML_NAMESPACE); - let node_id = self.document.get_mut().register_node(node); + let node_id = self.document.get_mut().register_node(&node); self.insert_element_helper(node_id, insert_position); // TODO Set the element's parser document to the Document, and set the element's force async to false. @@ -4054,8 +4055,8 @@ impl<'chars, D: Document> Html5Parser<'chars, D> fn process_unexpected_html_tag(&mut self) { self.parse_error("process_unexpected_html_tag"); - let mut current_node = current_node!(self); - let mut current_node_element_data = get_element_data!(current_node); + let mut tmp_node = current_node!(self); + let mut current_node_element_data = get_element_data!(tmp_node); while !current_node_element_data.is_mathml_integration_point() && !current_node_element_data.is_html_integration_point() @@ -4066,8 +4067,8 @@ impl<'chars, D: Document> Html5Parser<'chars, D> return; } - current_node = current_node!(self); - current_node_element_data = get_element_data!(current_node); + tmp_node = current_node!(self); + current_node_element_data = get_element_data!(tmp_node); } // Process as HTML content diff --git a/crates/gosub_html5/src/parser/helper.rs b/crates/gosub_html5/src/parser/helper.rs index fe57e6e85..ea230e308 100644 --- a/crates/gosub_html5/src/parser/helper.rs +++ b/crates/gosub_html5/src/parser/helper.rs @@ -115,10 +115,10 @@ where Some(index) => { let last_node_id = parent_node.children()[index - 1]; let mut_handle = &mut handle.clone(); - let mut last_node = self.get_node_by_id_mut(mut_handle, last_node_id); + let mut last_node = get_node_by_id!(mut_handle, last_node_id); if last_node.is_text_node() { - let data = get_text_data_mut!(&mut last_node); + let mut data = get_text_data_mut!(&mut last_node); data.value_mut().push_str(&token.to_string()); return; } @@ -132,10 +132,10 @@ where let parent_node = get_node_by_id!(handle, parent); if let Some(&last_node_id) = parent_node.children().last() { let mut_handle = &mut handle.clone(); - let mut last_node = self.get_node_by_id_mut(mut_handle, last_node_id); + let mut last_node = get_node_by_id!(mut_handle, last_node_id); if last_node.is_text_node() { - let data = get_text_data_mut!(&mut last_node); + let mut data = get_text_data_mut!(&mut last_node); data.value_mut().push_str(&token.to_string()); return; }; @@ -174,9 +174,9 @@ where if node.is_element_node() { let mut_handle = &mut self.document.clone(); - let mut node = self.get_node_by_id_mut(mut_handle, node.id()); + let mut node = get_node_by_id!(mut_handle, node.id()); - let data = get_element_data_mut!(&mut node); + let mut data = get_element_data_mut!(&mut node); if let Some(class_string) = data.attributes().get("class") { data.add_class(class_string.clone().as_str()); } @@ -195,9 +195,9 @@ where if new_node.is_element_node() { let mut_handle = &mut self.document.clone(); - let mut new_node = self.get_node_by_id_mut(mut_handle, new_node.id()); + let mut new_node = get_node_by_id!(mut_handle, new_node.id()); - let data = get_element_data_mut!(&mut new_node); + let mut data = get_element_data_mut!(&mut new_node); if let Some(class_string) = data.attributes().get("class") { data.add_class(class_string.clone().as_str()); } @@ -529,9 +529,4 @@ where self.open_elements.insert(position + 1, new_node_id); } } - - fn get_node_by_id_mut<'a>(&self, handle: &'a mut DocumentHandle, node_id: NodeId) -> &'a mut D::Node { - let mut doc = handle.get_mut(); - doc.get_node_by_id_mut(node_id).expect("node not found") - } } diff --git a/crates/gosub_html5/src/writer.rs b/crates/gosub_html5/src/writer.rs index 9cc301f9e..70131431d 100644 --- a/crates/gosub_html5/src/writer.rs +++ b/crates/gosub_html5/src/writer.rs @@ -1,7 +1,7 @@ use gosub_shared::document::DocumentHandle; use gosub_shared::node::NodeId; use gosub_shared::traits::document::Document; -use gosub_shared::traits::node::{CommentDataType, DocTypeDataType, Node, NodeDataType, TextDataType}; +use gosub_shared::traits::node::{CommentDataType, DocTypeDataType, Node, NodeType, TextDataType}; use crate::node::visitor::Visitor; use gosub_shared::traits::node::ElementDataType; @@ -32,27 +32,27 @@ impl DocumentWriter { }; match node.type_of() { - NodeDataType::Document(_) => { + NodeType::DocumentNode => { self.document_enter(node); self.visit_children(node.children(), handle.clone()); self.document_leave(node); } - NodeDataType::DocType(_) => { + NodeType::DocTypeNode => { self.doctype_enter(node); self.visit_children(node.children(), handle.clone()); self.doctype_leave(node); } - NodeDataType::Text(_) => { + NodeType::TextNode => { self.text_enter(node); self.visit_children(node.children(), handle.clone()); self.text_leave(node); } - NodeDataType::Comment(_) => { + NodeType::CommentNode => { self.comment_enter(node); self.visit_children(node.children(), handle.clone()); self.comment_leave(node); } - NodeDataType::Element(_) => { + NodeType::ElementNode => { self.element_enter(node); self.visit_children(node.children(), handle.clone()); self.element_leave(node); @@ -73,7 +73,7 @@ impl Visitor for DocumentWriter { fn document_leave(&mut self, _node: &N) {} fn doctype_enter(&mut self, node: &N) { - if let NodeDataType::DocType(data) = node.type_of() { + if let Some(data) = node.get_doctype_data() { self.buffer.push_str("'); @@ -83,7 +83,7 @@ impl Visitor for DocumentWriter { fn doctype_leave(&mut self, _node: &N) {} fn text_enter(&mut self, node: &N) { - if let NodeDataType::Text(data) = node.type_of() { + if let Some(data) = node.get_text_data() { self.buffer.push_str(&data.value()); } } @@ -91,7 +91,7 @@ impl Visitor for DocumentWriter { fn text_leave(&mut self, _node: &N) {} fn comment_enter(&mut self, node: &N) { - if let NodeDataType::Comment(data) = node.type_of() { + if let Some(data) = node.get_comment_data() { self.buffer.push_str(""); @@ -101,11 +101,11 @@ impl Visitor for DocumentWriter { fn comment_leave(&mut self, _node: &N) {} fn element_enter(&mut self, node: &N) { - if let Some(element_data) = node.get_element_data() { + if let Some(data) = node.get_element_data() { self.buffer.push_str("<"); - self.buffer.push_str(element_data.name()); + self.buffer.push_str(data.name()); - for (name, value) in element_data.attributes() { + for (name, value) in data.attributes() { self.buffer.push(' '); self.buffer.push_str(name); self.buffer.push_str("=\""); @@ -118,7 +118,7 @@ impl Visitor for DocumentWriter { } fn element_leave(&mut self, node: &N) { - if let NodeDataType::Element(data) = node.type_of() { + if let Some(data) = node.get_element_data() { self.buffer.push_str("'); diff --git a/crates/gosub_shared/src/traits/node.rs b/crates/gosub_shared/src/traits/node.rs index 0472c4786..498d754bc 100644 --- a/crates/gosub_shared/src/traits/node.rs +++ b/crates/gosub_shared/src/traits/node.rs @@ -1,3 +1,4 @@ +use std::cell::{Ref, RefMut}; use crate::traits::document::DocumentFragment; use std::collections::HashMap; use crate::byte_stream::Location; @@ -12,9 +13,19 @@ pub enum QuirksMode { NoQuirks, } +/// Different types of nodes that all have their own data structures (NodeData) +#[derive(Debug, PartialEq)] +pub enum NodeType { + DocumentNode, + DocTypeNode, + TextNode, + CommentNode, + ElementNode, +} + /// Different types of nodes #[derive(Debug, PartialEq)] -pub enum NodeDataType<'a, N: Node> { +pub enum NodeData<'a, N: Node> { Document(&'a N::DocumentData), DocType(&'a N::DocTypeData), Text(&'a N::TextData), @@ -102,22 +113,19 @@ pub trait Node: Clone { fn children(&self) -> &[NodeId]; /// Returns the type of the node - fn type_of(&self) -> NodeDataType where Self: Sized; + fn type_of(&self) -> NodeType; - // Returns true if the node is an element node fn is_element_node(&self) -> bool; - /// Returns element data - fn get_element_data(&self) -> Option<&Self::ElementData>; - /// Returns mutable element data - fn get_element_data_mut(&mut self) -> Option<&mut Self::ElementData>; + fn get_element_data(&self) -> Option>; + fn get_element_data_mut(&self) -> Option>; - // Returns true if the node is a text node fn is_text_node(&self) -> bool; - /// Returns text data - fn get_text_data(&self) -> Option<&Self::TextData>; - /// Returns mutable text data - fn get_text_data_mut(&mut self) -> Option<&mut Self::TextData>; + fn get_text_data(&self) -> Option>; + fn get_text_data_mut(&self) -> Option>; + fn get_comment_data(&self) -> Option>; + fn get_doctype_data(&self) -> Option>; + /// Returns the document handle of the node fn handle(&self) -> DocumentHandle; /// Removes a child node from the node