about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--]src/lib.rs29
-rwxr-xr-x[-rw-r--r--]src/query.rs0
-rwxr-xr-x[-rw-r--r--]src/tag.rs53
3 files changed, 78 insertions, 4 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 8b5c47d..bc8b629 100644..100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -87,6 +87,31 @@ impl Html {
 		None
 	}
 
+	pub fn get_by_id(&self, id: &str) -> Option<&Tag> {
+		// depth first
+		fn find_node<'a>(tag: &'a Tag, id: &str) -> Option<&'a Tag> {
+			if tag.id().unwrap_or_default() == id {
+				return Some(tag);
+			}
+
+			for child in tag.child_tags() {
+				if let Some(tag) = find_node(child, id) {
+					return Some(tag);
+				}
+			}
+
+			None
+		}
+
+		for child in self.child_tags() {
+			if let Some(tag) = find_node(child, id) {
+				return Some(tag);
+			}
+		}
+
+		None
+	}
+
 	fn parse_node(raw: &str) -> Consumed {
 		match Self::is_tag(raw) {
 			Some(_) => {
@@ -133,14 +158,11 @@ impl Html {
 			};
 		}
 
-		println!("Looking for {}", root_tag.name);
-
 		loop {
 			// Special case <script> and <style>
 			if root_tag.name == "script" && tag.get_attribute("src").is_none()
 				|| root_tag.name == "style"
 			{
-				println!("\tparse special");
 				let special = Self::special_parse(rest.unwrap(), root_tag.name);
 
 				match special {
@@ -166,7 +188,6 @@ impl Html {
 			// Find the closing end of out root_tag
 			if let Some((parsed, remaining)) = Self::is_tag(rest.unwrap()) {
 				if parsed.closing && parsed.name == root_tag.name {
-					println!("\tclosed {}", parsed.name);
 					break Consumed {
 						node: Node::Tag(tag),
 						remaining,
diff --git a/src/query.rs b/src/query.rs
index 26b02aa..26b02aa 100644..100755
--- a/src/query.rs
+++ b/src/query.rs
diff --git a/src/tag.rs b/src/tag.rs
index 0a97061..43c4e0c 100644..100755
--- a/src/tag.rs
+++ b/src/tag.rs
@@ -1,4 +1,5 @@
 use core::fmt;
+use std::{iter::Peekable, str::CharIndices};
 
 use crate::Node;
 
@@ -208,6 +209,8 @@ impl<'a> Iterator for TagIteratorMut<'a> {
 mod test {
 	use crate::Tag;
 
+	use super::peek_skip_while;
+
 	#[test]
 	fn tag_finds_boolen_attribute() {
 		let tag = Tag {
@@ -240,4 +243,54 @@ mod test {
 		};
 		assert!(tag.get_attribute("contenteditable").is_some());
 	}
+
+	// yes, this is a bad name.
+	#[test]
+	fn peek_skip_while_works() {
+		let str = "\t    no whitespace";
+		let mut chari = str.char_indices().peekable();
+
+		peek_skip_while(&mut chari, |c| c.is_whitespace());
+
+		let next_idx = chari.next().unwrap().0;
+		assert_eq!(&str[next_idx..], "no whitespace");
+	}
+}
+
+struct Attribute<'body> {
+	name: &'body str,
+	content: Option<&'body str>,
+	start: usize,
+	len: usize,
+}
+
+fn find_attribute<'body>(body: &'body str, attribute: &str) -> Option<Attribute<'body>> {
+	let mut chari = body.char_indices().peekable();
+
+	'big: loop {
+		// skip whitespace
+		peek_skip_while(&mut chari, |c| c.is_whitespace());
+
+		let key_start = chari.next().unwrap();
+		// find end of key
+		peek_skip_while(&mut chari, |c| c.is_alphanumeric());
+
+		let key_after = chari.next().unwrap();
+	}
+
+	todo!()
+}
+
+fn peek_skip_while<P>(iter: &mut Peekable<CharIndices>, mut predicate: P)
+where
+	P: FnMut(&char) -> bool,
+{
+	loop {
+		match iter.peek() {
+			Some((_, c)) if predicate(c) => {
+				iter.next();
+			}
+			_ => break,
+		}
+	}
 }