+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let p_id = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id, None, HTML_NAMESPACE); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let _ = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + + let query = Query::new().equals_tag("p").find_first(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 1); + assert_eq!(found_ids, [p_id]); + } + + #[test] + fn single_query_equals_tag_find_all() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let p_id = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let p_id_2 = doc.create_element("p", div_id, None, HTML_NAMESPACE); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let p_id_3 = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let p_id_4 = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + + let query = Query::new().equals_tag("p").find_all(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 4); + assert_eq!(found_ids, [p_id, p_id_2, p_id_3, p_id_4]); + } + + #[test] + fn single_query_equals_id() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let p_id_2 = doc.create_element("p", div_id, None, HTML_NAMESPACE); + let res = doc.insert_attribute("id", "myid", p_id_2); + assert!(res.is_ok()); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let _ = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + + let query = Query::new().equals_id("myid").find_first(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 1); + assert_eq!(found_ids, [p_id_2]); + } + + #[test] + fn single_query_contains_class_find_first() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let p_id = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let mut res = doc.insert_attribute("class", "one two", p_id); + assert!(res.is_ok()); + let p_id_2 = doc.create_element("p", div_id, None, HTML_NAMESPACE); + res = doc.insert_attribute("class", "one", p_id_2); + assert!(res.is_ok()); + res = doc.insert_attribute("id", "myid", p_id_2); + assert!(res.is_ok()); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let p_id_3 = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + res = doc.insert_attribute("class", "two three", p_id_3); + assert!(res.is_ok()); + + let p_id_4 = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + res = doc.insert_attribute("class", "three", p_id_4); + assert!(res.is_ok()); + + let query = Query::new().contains_class("two").find_first(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 1); + assert_eq!(found_ids, [p_id]); + } + + #[test] + fn single_query_contains_class_find_all() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let p_id = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let mut res = doc.insert_attribute("class", "one two", p_id); + assert!(res.is_ok()); + let p_id_2 = doc.create_element("p", div_id, None, HTML_NAMESPACE); + res = doc.insert_attribute("class", "one", p_id_2); + assert!(res.is_ok()); + res = doc.insert_attribute("id", "myid", p_id_2); + assert!(res.is_ok()); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let p_id_3 = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + res = doc.insert_attribute("class", "two three", p_id_3); + assert!(res.is_ok()); + + let p_id_4 = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + res = doc.insert_attribute("class", "three", p_id_4); + assert!(res.is_ok()); + + let query = Query::new().contains_class("two").find_all(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 2); + assert_eq!(found_ids, [p_id, p_id_3]); + } + + #[test] + fn single_query_contains_attribute_find_first() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let mut res = doc.insert_attribute("id", "myid", div_id_2); + assert!(res.is_ok()); + res = doc.insert_attribute("style", "somestyle", div_id_2); + assert!(res.is_ok()); + let p_id = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + res = doc.insert_attribute("title", "key", p_id); + assert!(res.is_ok()); + let _ = doc.create_element("p", div_id, None, HTML_NAMESPACE); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + res = doc.insert_attribute("style", "otherstyle", div_id_3); + assert!(res.is_ok()); + res = doc.insert_attribute("id", "otherid", div_id_3); + assert!(res.is_ok()); + let _ = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let p_id_4 = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + res = doc.insert_attribute("title", "yo", p_id_4); + assert!(res.is_ok()); + res = doc.insert_attribute("style", "cat", p_id_4); + assert!(res.is_ok()); + + let query = Query::new().contains_attribute("style").find_first(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 1); + assert_eq!(found_ids, [div_id_2]); + } + + #[test] + fn single_query_contains_attribute_find_all() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let mut res = doc.insert_attribute("id", "myid", div_id_2); + assert!(res.is_ok()); + res = doc.insert_attribute("style", "somestyle", div_id_2); + assert!(res.is_ok()); + let p_id = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + res = doc.insert_attribute("title", "key", p_id); + assert!(res.is_ok()); + let _ = doc.create_element("p", div_id, None, HTML_NAMESPACE); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + res = doc.insert_attribute("style", "otherstyle", div_id_3); + assert!(res.is_ok()); + res = doc.insert_attribute("id", "otherid", div_id_3); + assert!(res.is_ok()); + let _ = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let p_id_4 = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + res = doc.insert_attribute("title", "yo", p_id_4); + assert!(res.is_ok()); + res = doc.insert_attribute("style", "cat", p_id_4); + assert!(res.is_ok()); + + let query = Query::new().contains_attribute("style").find_all(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 3); + assert_eq!(found_ids, [div_id_2, div_id_3, p_id_4]); + } + + #[test] + fn single_query_contains_child_find_first() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id, None, HTML_NAMESPACE); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let _ = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + + let query = Query::new().contains_child_tag("p").find_first(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 1); + assert_eq!(found_ids, [NodeId::root()]); + } + + #[test] + fn single_query_contains_child_find_all() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id, None, HTML_NAMESPACE); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let _ = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + + let query = Query::new().contains_child_tag("p").find_all(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 4); + assert_eq!(found_ids, [NodeId::root(), div_id, div_id_2, div_id_3]); + } + + #[test] + fn single_query_has_parent_find_first() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document(); + + let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_2, None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id, None, HTML_NAMESPACE); + + let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE); + let _ = doc.create_element("p", div_id_3, None, HTML_NAMESPACE); + + let _ = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE); + + let query = Query::new().has_parent_tag("div").find_first(); + let found_ids = doc.query(&query).unwrap(); + assert_eq!(found_ids.len(), 1); + assert_eq!(found_ids, [div_id_2]); + } + + #[test] + fn single_query_has_parent_find_all() { + //
+ //
+ //
+ //
+ let mut doc = DocumentBuilder::new_document();
+
+ let div_id = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE);
+ let div_id_2 = doc.create_element("div", div_id, None, HTML_NAMESPACE);
+ let p_id = doc.create_element("p", div_id_2, None, HTML_NAMESPACE);
+ let p_id_2 = doc.create_element("p", div_id, None, HTML_NAMESPACE);
+
+ let div_id_3 = doc.create_element("div", NodeId::root(), None, HTML_NAMESPACE);
+ let p_id_3 = doc.create_element("p", div_id_3, None, HTML_NAMESPACE);
+
+ let _ = doc.create_element("p", NodeId::root(), None, HTML_NAMESPACE);
+
+ let query = Query::new().has_parent_tag("div").find_all();
+ let found_ids = doc.query(&query).unwrap();
+ assert_eq!(found_ids.len(), 4);
+ assert_eq!(found_ids, [div_id_2, p_id, p_id_2, p_id_3]);
+ }
}
diff --git a/src/html5/parser/query.rs b/src/html5/parser/query.rs
new file mode 100644
index 000000000..3de9a3c28
--- /dev/null
+++ b/src/html5/parser/query.rs
@@ -0,0 +1,130 @@
+#[derive(Debug, PartialEq)]
+pub enum Condition {
+ EqualsTag(String),
+ EqualsId(String),
+ ContainsClass(String),
+ ContainsAttribute(String),
+ ContainsChildTag(String),
+ HasParentTag(String),
+}
+
+#[derive(Debug, PartialEq)]
+pub enum SearchType {
+ Uninitialized,
+ FindFirst,
+ FindAll,
+}
+
+pub struct Query {
+ pub(crate) conditions: Vec