Skip to content

Commit

Permalink
docs: add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
xusd320 committed Jul 19, 2024
1 parent ee6761c commit 9461dce
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 32 deletions.
5 changes: 2 additions & 3 deletions crates/niddle_napi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ mod serializer;

mod node_repr;

/// Parse string input to a html tree, return the root node.
#[napi]
pub fn parse(html: String) -> NodeRepr {
let parser = parse_html();
let document_node = parser.one(html);
NodeRepr {
node_ref: document_node,
}
NodeRepr(document_node)
}

#[cfg(test)]
Expand Down
17 changes: 8 additions & 9 deletions crates/niddle_napi/src/node_repr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,35 @@ use kuchikiki::{ElementData, NodeDataRef, NodeRef};
mod modify;
mod query;

/// The node object, cann't be instantiated in javascript.
#[napi]
pub struct NodeRepr {
pub(crate) node_ref: NodeRef,
}
pub struct NodeRepr(pub(crate) NodeRef);

impl From<NodeDataRef<ElementData>> for NodeRepr {
fn from(element: NodeDataRef<ElementData>) -> Self {
Self {
node_ref: element.as_node().clone(),
}
Self(element.as_node().clone())
}
}

impl From<NodeRef> for NodeRepr {
fn from(node_ref: NodeRef) -> Self {
Self { node_ref }
Self(node_ref)
}
}

#[napi]
impl NodeRepr {
/// Clone this node to a new instance, not clone its descendants.
#[napi(js_name = "clone")]
pub fn clone_self_only(&self) -> NodeRepr {
let new_node_ref = NodeRef::new(self.node_ref.data().clone());
let new_node_ref = NodeRef::new(self.0.data().clone());
NodeRepr::from(new_node_ref)
}

/// Clone this node to a new instance, including its all descendants.
#[napi]
pub fn clone_recursive(&self) -> NodeRepr {
NodeRepr::from(clone_node_ref_recursive(&self.node_ref))
NodeRepr::from(clone_node_ref_recursive(&self.0))
}
}

Expand Down
51 changes: 40 additions & 11 deletions crates/niddle_napi/src/node_repr/modify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,35 @@ use super::NodeRepr;

#[napi]
impl NodeRepr {
/// Append a child node to this node, after existing children.
///
/// The child node will be remove from its previous position.
#[napi]
pub fn append(&self, new_child: &NodeRepr) {
self.node_ref.append(new_child.node_ref.clone())
self.0.append(new_child.0.clone())
}

/// Append some children nodes to this node by order, after existing children.
///
/// These children nodes will be remove from their previous position.
#[napi]
pub fn append_sequence(&self, new_children: Vec<&NodeRepr>) {
new_children
.into_iter()
.for_each(|new_child| self.append(new_child))
}

/// Prepend a child node to this node, before existing children.
///
/// The child node will be remove from its previous position.
#[napi]
pub fn prepend(&self, new_child: &NodeRepr) {
self.node_ref.prepend(new_child.node_ref.clone())
self.0.prepend(new_child.0.clone())
}

/// Prepend some children nodes to this node by order, before existing children.
///
/// These children nodes will be remove from their previous position.
#[napi]
pub fn prepend_sequence(&self, new_children: Vec<&NodeRepr>) {
if !new_children.is_empty() {
Expand All @@ -34,11 +46,17 @@ impl NodeRepr {
}
}

/// Insert a new sibling after this node.
///
/// The sibling node will be remove from its previous position.
#[napi]
pub fn insert_after(&self, new_sibling: &NodeRepr) {
self.node_ref.insert_after(new_sibling.node_ref.clone())
self.0.insert_after(new_sibling.0.clone())
}

/// Insert some siblings after this node.
///
/// These sibling nodes will be remove from their previous position.
#[napi]
pub fn insert_sequence_after(&self, new_siblings: Vec<&NodeRepr>) {
if !new_siblings.is_empty() {
Expand All @@ -48,48 +66,57 @@ impl NodeRepr {
.skip(1)
.enumerate()
.for_each(|(index, new_sibling)| {
if let Some(sibling) = self.node_ref.following_siblings().nth(index) {
if let Some(sibling) = self.0.following_siblings().nth(index) {
NodeRepr::from(sibling).insert_after(new_sibling)
}
});
}
}

/// Insert a new sibling before this node.
///
/// The sibling node will be remove from its previous position.
#[napi]
pub fn insert_before(&self, new_sibling: &NodeRepr) {
self.node_ref.insert_before(new_sibling.node_ref.clone())
self.0.insert_before(new_sibling.0.clone())
}

/// Insert some siblings before this node.
///
/// These sibling nodes will be remove from their previous position.
#[napi]
pub fn insert_sequence_before(&self, new_siblings: Vec<&NodeRepr>) {
if !new_siblings.is_empty() {
self.insert_before(new_siblings[0]);
new_siblings.iter().skip(1).for_each(|new_sibling| {
if let Some(sibling) = self.node_ref.preceding_siblings().last() {
if let Some(sibling) = self.0.preceding_siblings().last() {
NodeRepr::from(sibling).insert_after(new_sibling)
}
});
}
}

/// Remove a node from its parent and siblings. Children are not affected.
#[napi]
pub fn remove(&self) {
self.node_ref.detach()
self.0.detach()
}

/// Assign an attribute K-V to this node
#[napi]
pub fn set_attribute(&self, name: String, value: String) {
if let Some(ele) = self.node_ref.as_element() {
if let Some(ele) = self.0.as_element() {
ele
.attributes
.borrow_mut()
.insert(LocalName::from(name), StrTendril::from(value));
}
}

/// Assign attributes K-V object to this node
#[napi]
pub fn set_attributes(&self, attrs: IndexMap<String, String>) {
if let Some(ele) = self.node_ref.as_element() {
if let Some(ele) = self.0.as_element() {
attrs.into_iter().for_each(|(name, value)| {
ele
.attributes
Expand All @@ -99,16 +126,18 @@ impl NodeRepr {
}
}

/// Remove an attribute of this node by name
#[napi]
pub fn remove_attribute(&self, name: String) {
if let Some(ele) = self.node_ref.as_element() {
if let Some(ele) = self.0.as_element() {
ele.attributes.borrow_mut().remove(LocalName::from(name));
}
}

/// Remove all attributes of this node
#[napi]
pub fn remove_all_attributes(&self) {
if let Some(ele) = self.node_ref.as_element() {
if let Some(ele) = self.0.as_element() {
ele.attributes.borrow_mut().map.clear();
}
}
Expand Down
20 changes: 14 additions & 6 deletions crates/niddle_napi/src/node_repr/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,40 @@ use super::NodeRepr;

#[napi]
impl NodeRepr {
/// Select the the fist node that match the given selector, like document.querySelector.
#[napi]
pub fn select(&self, selectors: String) -> Option<NodeRepr> {
self.node_ref.select_first(&selectors).ok().map(Into::into)
self.0.select_first(&selectors).ok().map(Into::into)
}

/// Select all nodes that match the given selector, like document.querySelectorAll.
#[napi]
pub fn select_all(&self, selectors: String) -> Vec<NodeRepr> {
self
.node_ref
.0
.select(&selectors)
.map_or(vec![], |els| els.map(Into::into).collect())
}

/// Get all children nodes of this node.
#[napi]
pub fn get_children(&self) -> Vec<NodeRepr> {
self.node_ref.children().map(Into::into).collect()
self.0.children().map(Into::into).collect()
}

/// Get attribute value of this node by given name.
#[napi]
pub fn get_attribute(&self, name: String) -> Option<String> {
self
.node_ref
.0
.as_element()
.and_then(|e| e.attributes.borrow().get(name).map(|v| v.to_string()))
}

/// Get attributes K-V object of this node.
#[napi]
pub fn get_attributes(&self) -> IndexMap<String, String> {
self.node_ref.as_element().map_or_else(IndexMap::new, |e| {
self.0.as_element().map_or_else(IndexMap::new, |e| {
e.attributes
.borrow()
.map
Expand All @@ -49,6 +54,7 @@ impl NodeRepr {
})
}

/// Get the serialized html of this node, including its all descendants and itelf;.
#[napi]
pub fn outer_html(&self) -> String {
let mut u8_vec = Vec::new();
Expand All @@ -65,6 +71,7 @@ impl NodeRepr {
unsafe { String::from_utf8_unchecked(u8_vec) }
}

/// Get the serialized html of this node, only including its all descendants;.
#[napi]
pub fn inner_html(&self) -> String {
let mut buf = Vec::<u8>::new();
Expand All @@ -81,10 +88,11 @@ impl NodeRepr {
unsafe { String::from_utf8_unchecked(buf) }
}

/// Get all text nodes content of this node, including its all descendants and itelf;.
#[napi]
pub fn text(&self) -> String {
let mut buf = Vec::<u8>::new();
serialize_text_only(&self.node_ref, &mut buf).unwrap();
serialize_text_only(&self.0, &mut buf).unwrap();
unsafe { String::from_utf8_unchecked(buf) }
}
}
6 changes: 3 additions & 3 deletions crates/niddle_napi/src/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl Serialize for NodeRepr {
serializer: &mut S,
traversal_scope: TraversalScope,
) -> Result<()> {
match (traversal_scope, self.node_ref.data()) {
match (traversal_scope, self.0.data()) {
(ref scope, NodeData::Element(element)) => {
if *scope == IncludeNode {
let attrs = element.attributes.borrow();
Expand All @@ -38,7 +38,7 @@ impl Serialize for NodeRepr {
)?
}

for child in self.node_ref.children() {
for child in self.0.children() {
Serialize::serialize(&child, serializer, IncludeNode)?
}

Expand All @@ -49,7 +49,7 @@ impl Serialize for NodeRepr {
}

(_, &NodeData::DocumentFragment) | (_, &NodeData::Document(_)) => {
for child in self.node_ref.children() {
for child in self.0.children() {
Serialize::serialize(&child, serializer, IncludeNode)?
}
Ok(())
Expand Down
57 changes: 57 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,86 @@

/* auto-generated by NAPI-RS */

/** Parse string input to a html tree, return the root node. */
function parse(html: string): NodeRepr
/** The node object, cann't be instantiated in javascript. */
export declare class NodeRepr {
/**
* Append a child node to this node, after existing children.
*
* The child node will be remove from its previous position.
*/
append(newChild: NodeRepr): void
/**
* Append some children nodes to this node by order, after existing children.
*
* These children nodes will be remove from their previous position.
*/
appendSequence(newChildren: Array<NodeRepr>): void
/**
* Prepend a child node to this node, before existing children.
*
* The child node will be remove from its previous position.
*/
prepend(newChild: NodeRepr): void
/**
* Prepend some children nodes to this node by order, before existing children.
*
* These children nodes will be remove from their previous position.
*/
prependSequence(newChildren: Array<NodeRepr>): void
/**
* Insert a new sibling after this node.
*
* The sibling node will be remove from its previous position.
*/
insertAfter(newSibling: NodeRepr): void
/**
* Insert some siblings after this node.
*
* These sibling nodes will be remove from their previous position.
*/
insertSequenceAfter(newSiblings: Array<NodeRepr>): void
/**
* Insert a new sibling before this node.
*
* The sibling node will be remove from its previous position.
*/
insertBefore(newSibling: NodeRepr): void
/**
* Insert some siblings before this node.
*
* These sibling nodes will be remove from their previous position.
*/
insertSequenceBefore(newSiblings: Array<NodeRepr>): void
/** Remove a node from its parent and siblings. Children are not affected. */
remove(): void
/** Assign an attribute K-V to this node */
setAttribute(name: string, value: string): void
/** Assign attributes K-V object to this node */
setAttributes(attrs: Record<string, string>): void
/** Remove an attribute of this node by name */
removeAttribute(name: string): void
/** Remove all attributes of this node */
removeAllAttributes(): void
/** Select the the fist node that match the given selector, like document.querySelector. */
select(selectors: string): NodeRepr | null
/** Select all nodes that match the given selector, like document.querySelectorAll. */
selectAll(selectors: string): Array<NodeRepr>
/** Get all children nodes of this node. */
getChildren(): Array<NodeRepr>
/** Get attribute value of this node by given name. */
getAttribute(name: string): string | null
/** Get attributes K-V object of this node. */
getAttributes(): Record<string, string>
/** Get the serialized html of this node, including its all descendants and itelf;. */
outerHtml(): string
/** Get the serialized html of this node, only including its all descendants;. */
innerHtml(): string
/** Get all text nodes content of this node, including its all descendants and itelf;. */
text(): string
/** Clone this node to a new instance, not clone its descendants. */
clone(): NodeRepr
/** Clone this node to a new instance, including its all descendants. */
cloneRecursive(): NodeRepr
}

0 comments on commit 9461dce

Please sign in to comment.