From f083187b7b04750414d8fda515fe5813648ef5b0 Mon Sep 17 00:00:00 2001 From: Eric Walker Date: Sun, 1 Oct 2023 12:00:13 -0600 Subject: [PATCH 1/2] Add NodeId to wrap usize --- src/bin/parser_test.rs | 8 +-- src/html5_parser/node.rs | 69 ++++++++++++++++++---- src/html5_parser/node_arena.rs | 28 +++++---- src/html5_parser/parser/adoption_agency.rs | 56 ++++++++++-------- src/html5_parser/parser/document.rs | 16 ++--- src/html5_parser/parser/mod.rs | 44 +++++++------- 6 files changed, 140 insertions(+), 81 deletions(-) diff --git a/src/bin/parser_test.rs b/src/bin/parser_test.rs index 9ca277430..057034877 100755 --- a/src/bin/parser_test.rs +++ b/src/bin/parser_test.rs @@ -1,5 +1,5 @@ use gosub_engine::html5_parser::input_stream::InputStream; -use gosub_engine::html5_parser::node::NodeData; +use gosub_engine::html5_parser::node::{NodeData, NodeId}; use gosub_engine::html5_parser::parser::document::Document; use gosub_engine::html5_parser::parser::Html5Parser; use regex::Regex; @@ -271,12 +271,12 @@ pub struct Error { **/ fn match_document_tree(document: &Document, expected: &Vec) -> bool { - match_node(0, -1, -1, document, expected); + match_node(NodeId::root(), -1, -1, document, expected); true } fn match_node( - node_idx: usize, + node_idx: NodeId, expected_id: isize, indent: isize, document: &Document, @@ -284,7 +284,7 @@ fn match_node( ) -> Option { let node = document.get_node_by_id(node_idx).unwrap(); - if node_idx > 0 { + if node_idx.is_positive() { match &node.data { NodeData::Element { name, .. } => { let value = format!("|{}<{}>", " ".repeat((indent as usize * 2) + 1), name); diff --git a/src/html5_parser/node.rs b/src/html5_parser/node.rs index 2051e1886..546eaf393 100644 --- a/src/html5_parser/node.rs +++ b/src/html5_parser/node.rs @@ -32,14 +32,61 @@ pub enum NodeData { }, } +/// Id used to identify a node +#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +pub struct NodeId(usize); + +impl From for usize { + fn from(value: NodeId) -> Self { + value.0 + } +} + +impl Default for &NodeId { + fn default() -> Self { + &NodeId(0) + } +} + +impl NodeId { + // TODO: Drop Default derive and only use 0 for the root, or choose another id for the root + pub const ROOT_NODE: usize = 0; + + pub fn root() -> Self { + Self(Self::ROOT_NODE) + } + + pub fn new(id: usize) -> Self { + Self(id) + } + + pub fn is_positive(&self) -> bool { + self.0 > 0 + } + + pub fn is_root(&self) -> bool { + self.0 == Self::ROOT_NODE + } + + pub fn next(&self) -> Self { + // Might panic + Self(self.0 + 1) + } + + pub fn prev(&self) -> Self { + // Might panic + Self(self.0 - 1) + } +} + /// Node that resembles a DOM node pub struct Node { /// ID of the node, 0 is always the root / document node - pub id: usize, + pub id: NodeId, /// parent of the node, if any - pub parent: Option, + pub parent: Option, /// children of the node - pub children: Vec, + pub children: Vec, /// name of the node, or empty when it's not a tag pub name: String, /// namespace of the node @@ -65,7 +112,7 @@ impl Node { /// Create a new document node pub fn new_document() -> Self { Node { - id: 0, + id: Default::default(), parent: None, children: vec![], data: NodeData::Document {}, @@ -77,7 +124,7 @@ impl Node { /// Create a new element node with the given name and attributes and namespace pub fn new_element(name: &str, attributes: HashMap, namespace: &str) -> Self { Node { - id: 0, + id: Default::default(), parent: None, children: vec![], data: NodeData::Element { @@ -92,7 +139,7 @@ impl Node { /// Create a new comment node pub fn new_comment(value: &str) -> Self { Node { - id: 0, + id: Default::default(), parent: None, children: vec![], data: NodeData::Comment { @@ -106,7 +153,7 @@ impl Node { /// Create a new text node pub fn new_text(value: &str) -> Self { Node { - id: 0, + id: Default::default(), parent: None, children: vec![], data: NodeData::Text { @@ -251,7 +298,7 @@ mod test { #[test] fn test_new_document() { let node = Node::new_document(); - assert_eq!(node.id, 0); + assert_eq!(node.id, NodeId::default()); assert_eq!(node.parent, None); assert!(node.children.is_empty()); assert_eq!(node.name, "".to_string()); @@ -264,7 +311,7 @@ mod test { let mut attributes = HashMap::new(); attributes.insert("id".to_string(), "test".to_string()); let node = Node::new_element("div", attributes.clone(), HTML_NAMESPACE); - assert_eq!(node.id, 0); + assert_eq!(node.id, NodeId::default()); assert_eq!(node.parent, None); assert!(node.children.is_empty()); assert_eq!(node.name, "div".to_string()); @@ -281,7 +328,7 @@ mod test { #[test] fn test_new_comment() { let node = Node::new_comment("test"); - assert_eq!(node.id, 0); + assert_eq!(node.id, NodeId::default()); assert_eq!(node.parent, None); assert!(node.children.is_empty()); assert_eq!(node.name, "".to_string()); @@ -297,7 +344,7 @@ mod test { #[test] fn test_new_text() { let node = Node::new_text("test"); - assert_eq!(node.id, 0); + assert_eq!(node.id, NodeId::default()); assert_eq!(node.parent, None); assert!(node.children.is_empty()); assert_eq!(node.name, "".to_string()); diff --git a/src/html5_parser/node_arena.rs b/src/html5_parser/node_arena.rs index 4428d14d1..f357d46cc 100755 --- a/src/html5_parser/node_arena.rs +++ b/src/html5_parser/node_arena.rs @@ -1,9 +1,11 @@ use crate::html5_parser::node::Node; use std::collections::HashMap; +use super::node::NodeId; + pub struct NodeArena { - nodes: HashMap, // Current nodes - next_id: usize, // next id to use + nodes: HashMap, // Current nodes + next_id: NodeId, // next id to use } impl NodeArena { @@ -11,24 +13,24 @@ impl NodeArena { pub fn new() -> Self { Self { nodes: HashMap::new(), - next_id: 0, + next_id: Default::default(), } } /// Get the node with the given id - pub fn get_node(&self, node_id: usize) -> Option<&Node> { + pub fn get_node(&self, node_id: NodeId) -> Option<&Node> { self.nodes.get(&node_id) } /// Get the node with the given id as a mutable reference - pub fn get_mut_node(&mut self, node_id: usize) -> Option<&mut Node> { + pub fn get_mut_node(&mut self, node_id: NodeId) -> Option<&mut Node> { self.nodes.get_mut(&node_id) } /// Add the node to the arena and return its id - pub fn add_node(&mut self, mut node: Node) -> usize { + pub fn add_node(&mut self, mut node: Node) -> NodeId { let id = self.next_id; - self.next_id += 1; + self.next_id = id.next(); node.id = id; self.nodes.insert(id, node); @@ -36,7 +38,7 @@ impl NodeArena { } /// Add the node as a child the parent node - pub fn attach_node(&mut self, parent_id: usize, node_id: usize) { + pub fn attach_node(&mut self, parent_id: NodeId, node_id: NodeId) { //check if any children of node have parent as child if parent_id == node_id || has_child_recursive(self, node_id, parent_id) { return; @@ -50,7 +52,7 @@ impl NodeArena { } /// Removes the node with the given id from the arena - fn remove_node(&mut self, node_id: usize) { + fn remove_node(&mut self, node_id: NodeId) { // Remove children if let Some(node) = self.nodes.get_mut(&node_id) { for child_id in node.children.clone() { @@ -68,7 +70,7 @@ impl NodeArena { } } -fn has_child_recursive(arena: &mut NodeArena, parent_id: usize, child_id: usize) -> bool { +fn has_child_recursive(arena: &mut NodeArena, parent_id: NodeId, child_id: NodeId) -> bool { let node = arena.get_mut_node(parent_id).cloned(); if node.is_none() { return false; @@ -86,7 +88,7 @@ fn has_child_recursive(arena: &mut NodeArena, parent_id: usize, child_id: usize) false } -fn has_child(arena: &mut NodeArena, parent: Option, child_id: usize) -> bool { +fn has_child(arena: &mut NodeArena, parent: Option, child_id: NodeId) -> bool { let parent_node = if let Some(node) = parent { node } else { @@ -120,8 +122,8 @@ mod tests { let node = Node::new_element("test", HashMap::new(), HTML_NAMESPACE); let id = arena.add_node(node); assert_eq!(arena.nodes.len(), 1); - assert_eq!(arena.next_id, 1); - assert_eq!(id, 0); + assert_eq!(arena.next_id, NodeId::new(1)); + assert_eq!(id, NodeId::default()); } #[test] diff --git a/src/html5_parser/parser/adoption_agency.rs b/src/html5_parser/parser/adoption_agency.rs index a25e32d01..f5a3b074c 100755 --- a/src/html5_parser/parser/adoption_agency.rs +++ b/src/html5_parser/parser/adoption_agency.rs @@ -1,4 +1,4 @@ -use crate::html5_parser::node::{Node, NodeData, HTML_NAMESPACE}; +use crate::html5_parser::node::{Node, NodeData, NodeId, HTML_NAMESPACE}; use crate::html5_parser::parser::{ActiveElement, Html5Parser, Scope}; use crate::html5_parser::tokenizer::token::Token; use std::collections::HashMap; @@ -40,8 +40,8 @@ impl<'a> Html5Parser<'a> { outer_loop_counter += 1; // Step 4.3 - let mut formatting_element_idx: usize = 0; - let mut formatting_element_id: usize = 0; + let mut formatting_element_idx = NodeId::default(); + let mut formatting_element_id = NodeId::default(); let mut formatting_element_name = String::from(""); let mut formatting_element_attributes = HashMap::new(); @@ -57,7 +57,7 @@ impl<'a> Html5Parser<'a> { } = temp_node.data { if name == subject && !attributes.is_empty() { - formatting_element_idx = idx; + formatting_element_idx = NodeId::new(idx); formatting_element_id = node_id; formatting_element_name = String::from(name); formatting_element_attributes = attributes.clone(); @@ -67,7 +67,7 @@ impl<'a> Html5Parser<'a> { } } - if formatting_element_idx == 0 { + if formatting_element_idx.is_root() { // @TODO: process as any other end tag return; } @@ -76,7 +76,7 @@ impl<'a> Html5Parser<'a> { if !open_elements_has!(self, formatting_element_name) { self.parse_error("formatting element not in open elements"); self.active_formatting_elements - .remove(formatting_element_idx); + .remove(formatting_element_idx.into()); return; } @@ -95,17 +95,17 @@ impl<'a> Html5Parser<'a> { } // Step 4.7 - let mut furthest_block_idx = 0; - let mut furthest_block_id = 0; + let mut furthest_block_idx = NodeId::default(); + let mut furthest_block_id = NodeId::default(); let mut furthest_block_children = Vec::new(); - for idx in (0..formatting_element_idx).rev() { + for idx in (0..formatting_element_idx.into()).rev() { match self.active_formatting_elements[idx] { ActiveElement::Marker => {} ActiveElement::Node(node_id) => { let node = self.document.get_node_by_id(node_id).unwrap(); if node.is_special() { - furthest_block_idx = idx; + furthest_block_idx = NodeId::new(idx); furthest_block_id = node_id; furthest_block_children = self .document @@ -119,20 +119,20 @@ impl<'a> Html5Parser<'a> { } // Step 4.8 - if furthest_block_idx == 0 { + if furthest_block_idx.is_root() { while current_node!(self).id != formatting_element_id { self.open_elements.pop(); } self.active_formatting_elements - .remove(formatting_element_idx); + .remove(formatting_element_idx.into()); return; } // Step 4.9 - let common_ancestor_idx = formatting_element_idx - 1; + let common_ancestor_idx = formatting_element_idx.prev(); let common_ancestor = *self .open_elements - .get(common_ancestor_idx) + .get(usize::from(common_ancestor_idx)) .expect("common ancestor not found"); // Step 4.10 @@ -143,7 +143,7 @@ impl<'a> Html5Parser<'a> { let last_node_idx = furthest_block_idx; let mut last_node_id = *self .open_elements - .get(last_node_idx) + .get(usize::from(last_node_idx)) .expect("last node not found"); // Step 4.12 @@ -155,11 +155,14 @@ impl<'a> Html5Parser<'a> { inner_loop_counter += 1; // Step 4.13.2 - let &node_idx = self + let node_idx: NodeId = *self .open_elements - .get(node_idx - 1) + .get(usize::from(node_idx.prev())) + .expect("node not found"); + let node_id = *self + .open_elements + .get(usize::from(node_idx)) .expect("node not found"); - let node_id = *self.open_elements.get(node_idx).expect("node not found"); let node = open_elements_get!(self, node_idx).clone(); // Step 4.13.3 @@ -173,7 +176,7 @@ impl<'a> Html5Parser<'a> { .active_formatting_elements .contains(&ActiveElement::Node(node_id)) { - self.active_formatting_elements.remove(node_idx); + self.active_formatting_elements.remove(node_idx.into()); } // Step 4.13.5 @@ -182,7 +185,7 @@ impl<'a> Html5Parser<'a> { .contains(&ActiveElement::Node(node_id)) { // We have removed the node from the given node_idx - self.open_elements.remove(node_idx); + self.open_elements.remove(node_idx.into()); continue; } @@ -192,7 +195,7 @@ impl<'a> Html5Parser<'a> { // Step 4.13.7 if last_node_idx == furthest_block_idx { - bookmark = node_idx + 1; + bookmark = node_idx.next(); } // Step 4.13.8 @@ -224,16 +227,16 @@ impl<'a> Html5Parser<'a> { // Step 4.18 self.active_formatting_elements - .remove(formatting_element_idx); + .remove(formatting_element_idx.into()); self.active_formatting_elements - .insert(bookmark, ActiveElement::Node(new_element_id)); + .insert(bookmark.into(), ActiveElement::Node(new_element_id)); // Step 4.19 // Remove formatting element from the stack of open elements, and insert the new element into the stack of open elements immediately below the position of furthest block in that stack. } } - fn replace_node(&mut self, node: &Node, node_idx: usize, common_ancestor: usize) -> usize { + fn replace_node(&mut self, node: &Node, node_idx: NodeId, common_ancestor: NodeId) -> NodeId { let node_attributes = match node.data { NodeData::Element { ref attributes, .. } => attributes.clone(), _ => HashMap::new(), @@ -243,8 +246,9 @@ impl<'a> Html5Parser<'a> { Node::new_element(node.name.as_str(), node_attributes, HTML_NAMESPACE); let replacement_node_id = self.document.add_node(replacement_node, common_ancestor); - self.active_formatting_elements[node_idx] = ActiveElement::Node(replacement_node_id); - self.open_elements[node_idx] = replacement_node_id; + self.active_formatting_elements[usize::from(node_idx)] = + ActiveElement::Node(replacement_node_id); + self.open_elements[usize::from(node_idx)] = replacement_node_id; replacement_node_id } diff --git a/src/html5_parser/parser/document.rs b/src/html5_parser/parser/document.rs index 7fb3cd832..783b3cf64 100755 --- a/src/html5_parser/parser/document.rs +++ b/src/html5_parser/parser/document.rs @@ -1,4 +1,4 @@ -use crate::html5_parser::node::{Node, NodeData}; +use crate::html5_parser::node::{Node, NodeData, NodeId}; use crate::html5_parser::node_arena::NodeArena; use crate::html5_parser::parser::quirks::QuirksMode; use std::fmt; @@ -38,33 +38,35 @@ impl Document { } // Fetches a node by id or returns None when no node with this ID is found - pub fn get_node_by_id(&self, node_id: usize) -> Option<&Node> { + pub fn get_node_by_id(&self, node_id: NodeId) -> Option<&Node> { self.arena.get_node(node_id) } - pub fn get_mut_node_by_id(&mut self, node_id: usize) -> Option<&mut Node> { + pub fn get_mut_node_by_id(&mut self, node_id: NodeId) -> Option<&mut Node> { self.arena.get_mut_node(node_id) } // Add to the document - pub fn add_node(&mut self, node: Node, parent_id: usize) -> usize { + pub fn add_node(&mut self, node: Node, parent_id: NodeId) -> NodeId { let node_id = self.arena.add_node(node); self.arena.attach_node(parent_id, node_id); node_id } - pub fn append(&mut self, node_id: usize, parent_id: usize) { + pub fn append(&mut self, node_id: NodeId, parent_id: NodeId) { self.arena.attach_node(parent_id, node_id); } // // append a node to another parent - // pub fn append(&mut self, node_id: usize, parent_id: usize) { + // pub fn append(&mut self, node_id: NodeId, parent_id: NodeId) { // self.arena.attach_node(parent_id, node_id); // } // return the root node pub fn get_root(&self) -> &Node { - self.arena.get_node(0).expect("Root node not found !?") + self.arena + .get_node(NodeId::root()) + .expect("Root node not found !?") } } diff --git a/src/html5_parser/parser/mod.rs b/src/html5_parser/parser/mod.rs index dfde728e0..9e725ec87 100644 --- a/src/html5_parser/parser/mod.rs +++ b/src/html5_parser/parser/mod.rs @@ -19,6 +19,8 @@ use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; +use super::node::NodeId; + // Insertion modes as defined in 13.2.4.1 #[derive(Debug, Copy, Clone, PartialEq)] enum InsertionMode { @@ -57,10 +59,10 @@ trait VecExtensions { F: FnMut(&T) -> bool; } -impl VecExtensions for Vec { +impl VecExtensions for Vec { fn pop_until(&mut self, mut f: F) where - F: FnMut(&usize) -> bool, + F: FnMut(&NodeId) -> bool, { while let Some(top) = self.last() { if f(top) { @@ -72,7 +74,7 @@ impl VecExtensions for Vec { fn pop_check(&mut self, mut f: F) -> bool where - F: FnMut(&usize) -> bool, + F: FnMut(&NodeId) -> bool, { match self.pop() { Some(popped_value) => f(&popped_value), @@ -137,7 +139,7 @@ macro_rules! pop_check { // Checks if the last element on the open elements is $name, and panics if not macro_rules! check_last_element { ($self:expr, $name:expr) => { - let node_id = $self.open_elements.last().unwrap_or(&0); + let node_id = $self.open_elements.last().unwrap_or_default(); if $self .document .get_node_by_id(*node_id) @@ -155,7 +157,7 @@ macro_rules! open_elements_get { ($self:expr, $idx:expr) => { $self .document - .get_node_by_id($self.open_elements[$idx]) + .get_node_by_id($self.open_elements[usize::from($idx)]) .expect("Open element not found") }; } @@ -177,7 +179,7 @@ macro_rules! open_elements_has { // Returns the current node: the last node in the open elements list macro_rules! current_node { ($self:expr) => {{ - let current_node_idx = $self.open_elements.last().unwrap_or(&0); + let current_node_idx = $self.open_elements.last().unwrap_or_default(); $self .document .get_node_by_id(*current_node_idx) @@ -188,7 +190,7 @@ macro_rules! current_node { // Returns the current node as a mutable reference macro_rules! current_node_mut { ($self:expr) => {{ - let current_node_idx = $self.open_elements.last().unwrap_or(&0); + let current_node_idx = $self.open_elements.last().unwrap_or_default(); $self .document .get_mut_node_by_id(*current_node_idx) @@ -202,7 +204,7 @@ mod adoption_agency; // Active formatting elements, which could be a regular node(id), or a marker #[derive(PartialEq)] enum ActiveElement { - Node(usize), + Node(NodeId), Marker, } @@ -215,9 +217,9 @@ pub struct Html5Parser<'a> { parser_cannot_change_mode: bool, // ?? current_token: Token, // Current token from the tokenizer reprocess_token: bool, // If true, the current token should be processed again - open_elements: Vec, // Stack of open elements - head_element: Option, // Current head element - form_element: Option, // Current form element + open_elements: Vec, // Stack of open elements + head_element: Option, // Current head element + form_element: Option, // Current form element scripting_enabled: bool, // If true, scripting is enabled frameset_ok: bool, // if true, we can insert a frameset foster_parenting: bool, // Foster parenting flag @@ -302,7 +304,7 @@ impl<'a> Html5Parser<'a> { Token::CommentToken { .. } => { let node = self.create_node(&self.current_token, HTML_NAMESPACE); // add to end of the document(node) - self.document.add_node(node, 0); + self.document.add_node(node, NodeId::default()); } Token::DocTypeToken { name, @@ -375,7 +377,7 @@ impl<'a> Html5Parser<'a> { } Token::CommentToken { .. } => { let node = self.create_node(&self.current_token, HTML_NAMESPACE); - self.document.add_node(node, 0); + self.document.add_node(node, NodeId::default()); } Token::TextToken { .. } if self.current_token.is_empty_or_white() => { // ignore token @@ -1400,7 +1402,7 @@ impl<'a> Html5Parser<'a> { } Token::CommentToken { .. } => { let node = self.create_node(&self.current_token, HTML_NAMESPACE); - let html_node_id = self.open_elements.first().unwrap_or(&0); + let html_node_id = self.open_elements.first().unwrap_or_default(); self.document.add_node(node, *html_node_id); } Token::DocTypeToken { .. } => { @@ -1530,7 +1532,7 @@ impl<'a> Html5Parser<'a> { InsertionMode::AfterAfterBody => match &self.current_token { Token::CommentToken { .. } => { let node = self.create_node(&self.current_token, HTML_NAMESPACE); - self.document.add_node(node, 0); + self.document.add_node(node, NodeId::default()); } Token::DocTypeToken { .. } => { self.handle_in_body(); @@ -1557,7 +1559,7 @@ impl<'a> Html5Parser<'a> { match &self.current_token { Token::CommentToken { .. } => { let node = self.create_node(&self.current_token, HTML_NAMESPACE); - self.document.add_node(node, 0); + self.document.add_node(node, NodeId::default()); } Token::DocTypeToken { .. } => { self.handle_in_body(); @@ -1962,7 +1964,9 @@ impl<'a> Html5Parser<'a> { Token::StartTagToken { name, .. } if name == "body" => { self.parse_error("body tag not allowed in in body insertion mode"); - if self.open_elements.len() == 1 || open_elements_get!(self, 1).name != "body" { + if self.open_elements.len() == 1 + || open_elements_get!(self, NodeId::new(1)).name != "body" + { // ignore token return; } @@ -3001,11 +3005,11 @@ impl<'a> Html5Parser<'a> { } } - fn insert_html_element(&mut self, token: &Token) -> usize { + fn insert_html_element(&mut self, token: &Token) -> NodeId { self.insert_foreign_element(token, Some(HTML_NAMESPACE)) } - fn insert_foreign_element(&mut self, token: &Token, namespace: Option<&str>) -> usize { + fn insert_foreign_element(&mut self, token: &Token, namespace: Option<&str>) -> NodeId { // adjusted insert location let adjusted_insert_location = self.adjusted_insert_location(None); // let parent_id = current_node!(self).id; @@ -3037,7 +3041,7 @@ impl<'a> Html5Parser<'a> { todo!() } - fn adjusted_insert_location(&self, override_node: Option<&Node>) -> usize { + fn adjusted_insert_location(&self, override_node: Option<&Node>) -> NodeId { let target = match override_node { Some(node) => node, None => current_node!(self), From 77ca0b7d69751bcb6832d04d5ea36f76710cdf03 Mon Sep 17 00:00:00 2001 From: Eric Walker Date: Sun, 1 Oct 2023 12:35:00 -0600 Subject: [PATCH 2/2] NodeId::new -> From for NodeId --- src/html5_parser/node.rs | 10 ++++++---- src/html5_parser/node_arena.rs | 2 +- src/html5_parser/parser/adoption_agency.rs | 4 ++-- src/html5_parser/parser/mod.rs | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/html5_parser/node.rs b/src/html5_parser/node.rs index 546eaf393..dc3c27d07 100644 --- a/src/html5_parser/node.rs +++ b/src/html5_parser/node.rs @@ -42,6 +42,12 @@ impl From for usize { } } +impl From for NodeId { + fn from(value: usize) -> Self { + Self(value) + } +} + impl Default for &NodeId { fn default() -> Self { &NodeId(0) @@ -56,10 +62,6 @@ impl NodeId { Self(Self::ROOT_NODE) } - pub fn new(id: usize) -> Self { - Self(id) - } - pub fn is_positive(&self) -> bool { self.0 > 0 } diff --git a/src/html5_parser/node_arena.rs b/src/html5_parser/node_arena.rs index f357d46cc..ace4f9104 100755 --- a/src/html5_parser/node_arena.rs +++ b/src/html5_parser/node_arena.rs @@ -122,7 +122,7 @@ mod tests { let node = Node::new_element("test", HashMap::new(), HTML_NAMESPACE); let id = arena.add_node(node); assert_eq!(arena.nodes.len(), 1); - assert_eq!(arena.next_id, NodeId::new(1)); + assert_eq!(arena.next_id, 1.into()); assert_eq!(id, NodeId::default()); } diff --git a/src/html5_parser/parser/adoption_agency.rs b/src/html5_parser/parser/adoption_agency.rs index f5a3b074c..c54d986db 100755 --- a/src/html5_parser/parser/adoption_agency.rs +++ b/src/html5_parser/parser/adoption_agency.rs @@ -57,7 +57,7 @@ impl<'a> Html5Parser<'a> { } = temp_node.data { if name == subject && !attributes.is_empty() { - formatting_element_idx = NodeId::new(idx); + formatting_element_idx = idx.into(); formatting_element_id = node_id; formatting_element_name = String::from(name); formatting_element_attributes = attributes.clone(); @@ -105,7 +105,7 @@ impl<'a> Html5Parser<'a> { ActiveElement::Node(node_id) => { let node = self.document.get_node_by_id(node_id).unwrap(); if node.is_special() { - furthest_block_idx = NodeId::new(idx); + furthest_block_idx = idx.into(); furthest_block_id = node_id; furthest_block_children = self .document diff --git a/src/html5_parser/parser/mod.rs b/src/html5_parser/parser/mod.rs index 9e725ec87..af2491cc9 100644 --- a/src/html5_parser/parser/mod.rs +++ b/src/html5_parser/parser/mod.rs @@ -1965,7 +1965,7 @@ impl<'a> Html5Parser<'a> { self.parse_error("body tag not allowed in in body insertion mode"); if self.open_elements.len() == 1 - || open_elements_get!(self, NodeId::new(1)).name != "body" + || open_elements_get!(self, NodeId::root().next()).name != "body" { // ignore token return;