Skip to content

Commit

Permalink
Merge branch 'feature/addCloneMethod' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
fefit committed Apr 17, 2024
2 parents 2d97ed0 + f0f50ec commit 90c1d83
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 11 deletions.
16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ repository = "https://github.com/fefit/visdom"
documentation = "https://docs.rs/visdom/"
categories = ["web-programming"]
license = "MIT"
exclude = [".vscode/*.*", ".github/*.*", ".editorconfig", "src/main.rs", "performance/*.*"]
exclude = [
".vscode/*.*",
".github/*.*",
".editorconfig",
"src/main.rs",
"performance/*.*",
]

[dependencies]
rphtml = "0.5.9"
rphtml = { version = "0.5.10" }
lazy_static = "1.4.0"
thiserror = "1.0.24"
regex = "1.7.0"
Expand All @@ -24,11 +30,7 @@ criterion = "0.4.0"

[features]
default = []
full = [
"text",
"insertion",
"destroy"
]
full = ["text", "insertion", "destory"]
text = []
insertion = []
destroy = []
Expand Down
10 changes: 9 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,19 @@ impl INodeTrait for Rc<RefCell<Node>> {
self.borrow().index
}

/// impl `clone_node`
/// The current version of this method only implements the clone of `Rc` pointers.
/// This is different from the standard `clone_node` method.
/// If you want to use `clone_node` method with the standard semantics, now you can use `copy_node` instead.
/// This method may be changed in future versions to be consist with the standard `clone_node` semantics.
fn clone_node<'b>(&self) -> BoxDynNode<'b> {
Box::new(self.clone())
}

/// impl standard semantics `clone_node` method
fn copy_node<'b>(&self) -> BoxDynNode<'b> {
Box::new(self.borrow().clone_node())
}

/// impl `typed`
fn typed<'b>(self: Box<Self>) -> IEnumTyped<'b> {
match self.node_type() {
Expand Down
14 changes: 14 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ fn main() -> Result<(), BoxDynError> {
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<text x="0" y="15" fill="red" transform="rotate(30 20,40)">I love SVG</text>
</svg>
<div id="test_clone">
<div class="abc">hello</div>
great!
<p class="def">world!</div>
</div>
</div>
</body>
</html>
Expand Down Expand Up @@ -322,5 +327,14 @@ fn main() -> Result<(), BoxDynError> {
let child_nodes = root.get(0).unwrap().child_nodes();
println!("{}", child_nodes[1].text_content());
println!("{}", content.html());
let mut test_clone = root.find("#test_clone");
println!("test_clone:{:?}", test_clone.html());
let test_clone_new = test_clone.clone();
test_clone_new.find(".abc").set_text("哈哈哈");
println!("test_clone:{:?}", test_clone.html());
println!("test_clone_new:{:?}", test_clone_new.html());
test_clone_new.find(".abc").append_to(&mut test_clone);
println!("test_clone:{:?}", test_clone.html());
println!("test_clone_new:{:?}", test_clone_new.html());
Ok(())
}
9 changes: 8 additions & 1 deletion src/mesdoc/interface/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,18 @@ cfg_feat_insertion! {
pub trait IElementTrait: INodeTrait {
fn is(&self, ele: &BoxDynElement) -> bool;
fn is_root_element(&self) -> bool;
// cloned
/// The current version is an implementation of `Rc` pointers with non-copy semantics.
/// If you want to achieve complete copying of nodes in the current version, please use the `copied` method instead.
/// The semantics of this method may be changed in future versions to be consist with the `copied` method.
fn cloned<'b>(&self) -> BoxDynElement<'b> {
let ele = self.clone_node();
ele.typed().into_element().unwrap()
}
/// Copy a element
fn copied<'b>(&self) -> BoxDynElement<'b> {
let ele = self.copy_node();
ele.typed().into_element().unwrap()
}
// next sibling
fn next_element_sibling<'b>(&self) -> MaybeElement<'b> {
// use child_nodes instead of chilren, reduce one loop
Expand Down
50 changes: 49 additions & 1 deletion src/mesdoc/interface/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1854,7 +1854,11 @@ impl<'a> Elements<'a> {
}
elements
}
// cloned

/// This method will be removed in future versions.
/// If you want to clone an elements set, please use the `clone()` method instead.
/// This method only clone the element's `Rc` pointer in the elements set.
/// Any modifications to the cloned elements set will be reflected on the original elements set.
pub fn cloned(&self) -> Elements<'a> {
let mut result = Elements::with_capacity(self.length());
for ele in &self.nodes {
Expand Down Expand Up @@ -3529,6 +3533,49 @@ impl<'a> Elements<'a> {
** before, insert_before, after, insert_after
*/

cfg_feat_mutation! {
/// Clone the Elements set.
///
/// ```
/// use visdom::Vis;
/// use visdom::types::BoxDynError;
/// fn main()-> Result<(), BoxDynError>{
/// let html = r##"
/// <html>
/// <head>
/// <title>document</title>
/// </head>
/// <body>
/// <dl>
/// <dt>Title</dt>
/// <dd><span class="span">item1</span></dd>
/// <dd class="item2"><span>item2</span></dd>
/// <dd class="item3"><!--comment-->item3</dd>
/// </dl>
/// </body>
/// </html>
/// "##;
/// let doc = Vis::load(html)?;
/// let dl = doc.find("dl");
/// let span = dl.find("span.span");
/// assert_eq!(span.text(), "item1");
/// // clone the "dl" Elements
/// let clone_dl = dl.clone();
/// let mut clone_span = clone_dl.find("span.span");
/// clone_span.set_text("span");
/// assert_eq!(span.text(), "item1");
/// assert_eq!(clone_dl.find("span.span").text(), "span");
/// Ok(())
/// }
/// ```
impl<'a> std::clone::Clone for Elements<'a>{
fn clone(&self) -> Self {
let nodes: Vec<BoxDynElement> = self.get_ref().iter().map(|ele|ele.copied()).collect();
Elements::with_nodes(nodes)
}
}
}

impl<'a> Elements<'a> {
// when feature 'destory' or 'insertion' is open
cfg_feat_mutation! {
Expand Down Expand Up @@ -3608,6 +3655,7 @@ impl<'a> Elements<'a> {
self.set_text("");
self
}

}
// when feature 'insertion' is open
cfg_feat_insertion! {
Expand Down
4 changes: 3 additions & 1 deletion src/mesdoc/interface/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ impl<'a> IEnumTyped<'a> {

pub trait INodeTrait {
fn to_node(self: Box<Self>) -> Box<dyn Any>;
// clone a ele
// clone a node
fn clone_node<'b>(&self) -> BoxDynNode<'b>;
// copy a node
fn copy_node<'b>(&self) -> BoxDynNode<'b>;
// typed, whether element or text
fn typed<'b>(self: Box<Self>) -> IEnumTyped<'b>;
// get ele type
Expand Down
36 changes: 36 additions & 0 deletions tests/mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,39 @@ fn test_replace_with() -> Result {
assert_eq!(now_svg.length(), 1);
Ok(())
}

#[test]
fn test_clone() -> Result {
let menu_html = r#"<menu class="menu">
<h3>Title</h3>
<ul class="list">
<li class="item-1">item1</li>
<li class="item-2">item2</li>
</ul>
</menu>"#;
let html = format!(
r#"
<h2>logo</h2>
{}
"#,
menu_html
);
let fragement = Vis::load(html)?;
let menu = fragement.find(">.menu");
let clone_menu = menu.clone();
let mut clone_h3 = clone_menu.find(">h3");
clone_h3.set_text("h3");
assert_eq!(menu.outer_html(), menu_html);
assert_eq!(clone_h3.text(), "h3");
let mut clone_item_1 = clone_menu.find(".item-1");
clone_item_1.add_class("item");
assert_eq!(menu.outer_html(), menu_html);
assert!(clone_item_1.has_class("item"));
clone_item_1.remove_class("item-1").add_class("item-3");
clone_item_1.append_to(&mut menu.find("ul.list"));
assert_eq!(menu.find(".list > li").length(), 3);
assert!(menu.find(".list > li").eq(2).has_class("item-3"));
assert_eq!(clone_menu.find(".list > li").length(), 1);
assert_eq!(clone_menu.find(".list > li").first().text(), "item2");
Ok(())
}

0 comments on commit 90c1d83

Please sign in to comment.