Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/lomirus/html-editor
Browse files Browse the repository at this point in the history
  • Loading branch information
lomirus committed Apr 22, 2023
2 parents 2c90f65 + f9c5d7f commit 46cb8bf
Show file tree
Hide file tree
Showing 7 changed files with 306 additions and 98 deletions.
74 changes: 51 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@ pub enum Doctype {
/// Node of DOM
#[derive(Debug, Clone)]
pub enum Node {
Element {
name: String,
attrs: Vec<(String, String)>,
children: Vec<Node>,
},
Element(Element),
Text(String),
Comment(String),
Doctype(Doctype),
Expand All @@ -74,34 +70,53 @@ impl Node {
matches!(self, Node::Element { .. })
}

#[deprecated(note = "Please use `is_element` instead")]
pub fn into_element(self) -> Element {
match self {
Node::Element(element) => element,
_ => panic!("{:?} is not an element", self),
}
}

/// Convert the node into an element.
///
/// Warning: The program will panic if it fails to convert.
/// So take care to use this method unless you are sure.
/// Returns `None` if the node is not an element.
///
/// Example:
/// ```
/// use html_editor::{Node, Element};
///
/// let a: Node = Node::new_element("div", vec![("id", "app")], vec![]);
/// let a: Element = a.into_element();
/// assert!(a.as_element().is_some());
///
/// let b: Node = Node::Text("hello".to_string());
/// // The next line will panic at 'Text("hello") is not an element'
/// // let b: Element = a.into_element();
/// assert!(b.as_element().is_none());
/// ```
pub fn into_element(self) -> Element {
pub fn as_element(&self) -> Option<&Element> {
match self {
Node::Element {
name,
attrs,
children,
} => Element {
name,
attrs,
children,
},
_ => panic!("{:?} is not an element", self),
Node::Element(element) => Some(element),
_ => None,
}
}

/// Convert the node into a mutable element.
///
/// Returns `None` if the node is not an element.
///
/// Example:
/// ```
/// use html_editor::{Node, Element};
///
/// let mut a: Node = Node::new_element("div", vec![("id", "app")], vec![]);
/// assert!(a.as_element_mut().is_some());
///
/// let mut b: Node = Node::Text("hello".to_string());
/// assert!(b.as_element_mut().is_none());
/// ```
pub fn as_element_mut(&mut self) -> Option<&mut Element> {
match self {
Node::Element(element) => Some(element),
_ => None,
}
}

Expand All @@ -119,19 +134,20 @@ impl Node {
/// );
/// ```
pub fn new_element(name: &str, attrs: Vec<(&str, &str)>, children: Vec<Node>) -> Node {
Node::Element {
Element {
name: name.to_string(),
attrs: attrs
.into_iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect(),
children,
}
.into_node()
}
}

/// HTML Element
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Element {
pub name: String,
pub attrs: Vec<(String, String)>,
Expand All @@ -151,3 +167,15 @@ impl Element {
}
}
}

impl Element {
pub fn into_node(self) -> Node {
Node::Element(self)
}
}

impl From<Element> for Node {
fn from(element: Element) -> Self {
Node::Element(element)
}
}
29 changes: 12 additions & 17 deletions src/operation/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,23 @@ impl Editable for Vec<Node> {
Node::Element { .. } => true,
});
for node in self.iter_mut() {
if let Node::Element { children, .. } = node {
children.trim();
if let Node::Element(el) = node {
el.children.trim();
}
}
self
}

fn insert_to(&mut self, selector: &Selector, target: Node) -> &mut Self {
for node in self.iter_mut() {
if let Node::Element {
name,
attrs,
children,
} = node
{
children.insert_to(selector, target.clone());
if let Node::Element(el) = node {
el.children.insert_to(selector, target.clone());
if selector.matches(&Element {
name: name.clone(),
attrs: attrs.clone(),
name: el.name.clone(),
attrs: el.attrs.clone(),
children: vec![],
}) {
children.push(target.clone());
el.children.push(target.clone());
}
}
}
Expand All @@ -106,19 +101,19 @@ impl Editable for Vec<Node> {

fn remove_by(&mut self, selector: &Selector) -> &mut Self {
self.retain(|node| {
if let Node::Element { name, attrs, .. } = node {
if let Node::Element(el) = node {
let element = Element {
name: name.clone(),
attrs: attrs.clone(),
name: el.name.clone(),
attrs: el.attrs.clone(),
children: vec![],
};
return !selector.matches(&element);
}
true
});
for node in self.iter_mut() {
if let Node::Element { children, .. } = node {
children.remove_by(selector);
if let Node::Element(el) = node {
el.remove_by(selector);
}
}
self
Expand Down
2 changes: 1 addition & 1 deletion src/operation/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl Htmlifiable for Element {
impl Htmlifiable for Node {
fn html(&self) -> String {
match self {
Node::Element { .. } => self.clone().into_element().html(),
Node::Element(element) => element.html(),
Node::Text(text) => text.to_string(),
Node::Comment(comment) => format!("<!--{}-->", comment),
Node::Doctype(doctype) => match &doctype {
Expand Down

0 comments on commit 46cb8bf

Please sign in to comment.