Skip to content

Commit

Permalink
Merge pull request #303 from koopa1338/refactor/node-initialization
Browse files Browse the repository at this point in the history
simplify `Node` constructor and merge impl blocks
  • Loading branch information
Kiyoshika authored Dec 2, 2023
2 parents 495a1d7 + edc1c93 commit 798e217
Showing 1 changed file with 88 additions and 117 deletions.
205 changes: 88 additions & 117 deletions src/html5/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,44 +136,6 @@ impl PartialEq for Node {
}
}

impl Node {
/// Returns true when the given node is of the given namespace
pub(crate) fn is_namespace(&self, namespace: &str) -> bool {
self.namespace == Some(namespace.into())
}

/// Returns true if the given node is a html integration point
/// See: https://html.spec.whatwg.org/multipage/parsing.html#html-integration-point
pub(crate) fn is_html_integration_point(&self) -> bool {
let namespace = self.namespace.clone().unwrap_or_default();

if namespace == MATHML_NAMESPACE && self.name == "annotation-xml" {
if let NodeData::Element(element) = &self.data {
if let Some(value) = element.attributes.get("encoding") {
if value.eq_ignore_ascii_case("text/html") {
return true;
}
if value.eq_ignore_ascii_case("application/xhtml+xml") {
return true;
}
}
}
}

namespace == SVG_NAMESPACE
&& ["foreignObject", "desc", "title"].contains(&self.name.as_str())
}

/// Returns true if the given node is a mathml integration point
/// See: https://html.spec.whatwg.org/multipage/parsing.html#mathml-text-integration-point
pub(crate) fn is_mathml_integration_point(&self) -> bool {
let namespace = self.namespace.clone().unwrap_or_default();

namespace == MATHML_NAMESPACE
&& ["mi", "mo", "mn", "ms", "mtext"].contains(&self.name.as_str())
}
}

impl Debug for Node {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut debug = f.debug_struct("Node");
Expand All @@ -196,36 +158,6 @@ impl Debug for Node {
}
}

impl Node {
/// This will only compare against the tag, namespace and data same except element data.
/// for element data compaare against the tag, namespace and attributes without order.
/// Both nodes could still have other parents and children.
pub fn matches_tag_and_attrs_without_order(&self, other: &Self) -> bool {
if self.name != other.name || self.namespace != other.namespace {
return false;
}

if self.type_of() != other.type_of() {
return false;
}

match self.type_of() {
NodeType::Element => {
let mut self_attributes = None;
let mut other_attributes = None;
if let NodeData::Element(element) = &self.data {
self_attributes = Some(element.attributes.clone());
}
if let NodeData::Element(element) = &other.data {
other_attributes = Some(element.attributes.clone());
}
self_attributes.eq(&other_attributes)
}
_ => self.data == other.data,
}
}
}

impl Clone for Node {
fn clone(&self) -> Self {
Node {
Expand All @@ -242,21 +174,26 @@ impl Clone for Node {
}

impl Node {
/// Create a new document node
/// create a new `Node`
#[must_use]
pub fn new_document(document: &DocumentHandle) -> Self {
pub fn new(data: NodeData, document: &DocumentHandle) -> Self {
let (id, parent, children, name, namespace, is_registered) = <_>::default();
Node {
Self {
id,
parent,
children,
data: NodeData::Document(DocumentData::new()),
data,
name,
namespace,
document: document.to_weak(),
is_registered,
}
}
/// Create a new document node
#[must_use]
pub fn new_document(document: &DocumentHandle) -> Self {
Self::new(NodeData::Document(DocumentData::new()), document)
}

#[must_use]
pub fn new_doctype(
Expand All @@ -265,17 +202,10 @@ impl Node {
pub_identifier: &str,
sys_identifier: &str,
) -> Self {
let (id, parent, children, namespace, is_registered) = <_>::default();
Node {
id,
parent,
children,
data: NodeData::DocType(DocTypeData::new(name, pub_identifier, sys_identifier)),
name: "".to_owned(),
namespace,
document: document.to_weak(),
is_registered,
}
Self::new(
NodeData::DocType(DocTypeData::new(name, pub_identifier, sys_identifier)),
document,
)
}

/// Create a new element node with the given name and attributes and namespace
Expand All @@ -286,53 +216,30 @@ impl Node {
attributes: HashMap<String, String>,
namespace: &str,
) -> Self {
let (id, parent, children, is_registered) = <_>::default();
Node {
id,
parent,
children,
data: NodeData::Element(Box::new(ElementData::with_name_and_attributes(
NodeId::default(),
name,
attributes,
))),
Self {
name: name.to_owned(),
namespace: Some(namespace.into()),
document: document.to_weak(),
is_registered,
..Self::new(
NodeData::Element(Box::new(ElementData::with_name_and_attributes(
NodeId::default(),
name,
attributes,
))),
document,
)
}
}

/// Creates a new comment node
#[must_use]
pub fn new_comment(document: &DocumentHandle, value: &str) -> Self {
let (id, parent, children, name, namespace, is_registered) = <_>::default();
Node {
id,
parent,
children,
data: NodeData::Comment(CommentData::with_value(value)),
name,
namespace,
document: document.to_weak(),
is_registered,
}
Self::new(NodeData::Comment(CommentData::with_value(value)), document)
}

/// Creates a new text node
#[must_use]
pub fn new_text(document: &DocumentHandle, value: &str) -> Self {
let (id, parent, children, name, namespace, is_registered) = <_>::default();
Node {
id,
parent,
children,
data: NodeData::Text(TextData::with_value(value)),
name,
namespace,
document: document.to_weak(),
is_registered,
}
Self::new(NodeData::Text(TextData::with_value(value)), document)
}

/// Returns true if the given node is a "formatting" node
Expand Down Expand Up @@ -366,6 +273,70 @@ impl Node {
pub fn is_registered(&self) -> bool {
self.is_registered
}

/// This will only compare against the tag, namespace and data same except element data.
/// for element data compaare against the tag, namespace and attributes without order.
/// Both nodes could still have other parents and children.
pub fn matches_tag_and_attrs_without_order(&self, other: &Self) -> bool {
if self.name != other.name || self.namespace != other.namespace {
return false;
}

if self.type_of() != other.type_of() {
return false;
}

match self.type_of() {
NodeType::Element => {
let mut self_attributes = None;
let mut other_attributes = None;
if let NodeData::Element(element) = &self.data {
self_attributes = Some(element.attributes.clone());
}
if let NodeData::Element(element) = &other.data {
other_attributes = Some(element.attributes.clone());
}
self_attributes.eq(&other_attributes)
}
_ => self.data == other.data,
}
}

/// Returns true when the given node is of the given namespace
pub(crate) fn is_namespace(&self, namespace: &str) -> bool {
self.namespace == Some(namespace.into())
}

/// Returns true if the given node is a html integration point
/// See: https://html.spec.whatwg.org/multipage/parsing.html#html-integration-point
pub(crate) fn is_html_integration_point(&self) -> bool {
let namespace = self.namespace.clone().unwrap_or_default();

if namespace == MATHML_NAMESPACE && self.name == "annotation-xml" {
if let NodeData::Element(element) = &self.data {
if let Some(value) = element.attributes.get("encoding") {
if value.eq_ignore_ascii_case("text/html") {
return true;
}
if value.eq_ignore_ascii_case("application/xhtml+xml") {
return true;
}
}
}
}

namespace == SVG_NAMESPACE
&& ["foreignObject", "desc", "title"].contains(&self.name.as_str())
}

/// Returns true if the given node is a mathml integration point
/// See: https://html.spec.whatwg.org/multipage/parsing.html#mathml-text-integration-point
pub(crate) fn is_mathml_integration_point(&self) -> bool {
let namespace = self.namespace.clone().unwrap_or_default();

namespace == MATHML_NAMESPACE
&& ["mi", "mo", "mn", "ms", "mtext"].contains(&self.name.as_str())
}
}

pub trait NodeTrait {
Expand Down

0 comments on commit 798e217

Please sign in to comment.