nipper_trunk/
traversal.rs1use crate::matcher::{MatchScope, Matcher, Matches};
2use crate::Document;
3use crate::Node;
4use crate::Selection;
5use std::collections::HashSet;
6use std::vec::IntoIter;
7
8impl Document {
9 pub fn select(&self, sel: &str) -> Selection {
16 let matcher = Matcher::new(sel).expect("Invalid CSS selector");
17 let root = self.tree.root();
18 Selection {
19 nodes: Matches::from_one(root, matcher.clone(), MatchScope::IncludeNode).collect(),
20 }
21 }
22
23 pub fn nip(&self, sel: &str) -> Selection {
30 self.select(sel)
31 }
32
33 pub fn try_select(&self, sel: &str) -> Option<Selection> {
36 match Matcher::new(sel) {
37 Ok(matcher) => {
38 let root = self.tree.root();
39 let nodes: Vec<Node> =
40 Matches::from_one(root, matcher.clone(), MatchScope::ChildrenOnly).collect();
41 if nodes.len() > 0 {
42 Some(Selection { nodes })
43 } else {
44 None
45 }
46 }
47 Err(_) => None,
48 }
49 }
50
51 pub fn select_matcher<'a, 'b>(&'a self, matcher: &'b Matcher) -> Selection<'a> {
54 let root = self.tree.root();
55 let nodes = Matches::from_one(root, matcher.clone(), MatchScope::IncludeNode).collect();
56
57 Selection { nodes }
58 }
59}
60
61impl<'a> Selection<'a> {
62 pub fn select(&self, sel: &str) -> Selection<'a> {
70 let matcher = Matcher::new(sel).expect("Invalid CSS seletor");
71 Selection {
72 nodes: Matches::from_list(
73 self.nodes.clone().into_iter(),
74 matcher,
75 MatchScope::ChildrenOnly,
76 )
77 .collect(),
78 }
79 }
80
81 pub fn nip(&self, sel: &str) -> Selection<'a> {
89 self.select(sel)
90 }
91
92 pub fn try_select(&self, sel: &str) -> Option<Selection<'a>> {
96 match Matcher::new(sel) {
97 Ok(matcher) => {
98 let nodes: Vec<Node> = Matches::from_list(
99 self.nodes.clone().into_iter(),
100 matcher,
101 MatchScope::ChildrenOnly,
102 )
103 .collect();
104 if nodes.len() > 0 {
105 Some(Selection { nodes })
106 } else {
107 None
108 }
109 }
110 Err(_) => None,
111 }
112 }
113
114 pub fn select_matcher(&self, matcher: &Matcher) -> Selection<'a> {
118 Selection {
119 nodes: Matches::from_list(
120 self.nodes.clone().into_iter(),
121 matcher.clone(),
122 MatchScope::ChildrenOnly,
123 )
124 .collect(),
125 }
126 }
127
128 pub fn nodes(&self) -> &[Node<'a>] {
130 &self.nodes
131 }
132
133 pub fn iter(&self) -> Selections<Node<'a>> {
135 Selections::new(self.nodes.clone().into_iter())
136 }
137
138 pub fn parent(&self) -> Selection<'a> {
141 let mut result = Vec::with_capacity(self.length());
142 let mut set = HashSet::with_capacity(self.length());
143
144 for node in self.nodes() {
145 if let Some(parent) = node.parent() {
146 if !set.contains(&parent.id) {
147 set.insert(parent.id);
148 result.push(parent);
149 }
150 }
151 }
152
153 Self { nodes: result }
154 }
155
156 pub fn children(&self) -> Selection<'a> {
159 let mut result = Vec::with_capacity(self.length());
160 let mut set = HashSet::with_capacity(self.length());
161
162 for node in self.nodes() {
163 for child in node.children() {
164 if !set.contains(&child.id) && child.is_element() {
165 set.insert(child.id);
166 result.push(child);
167 }
168 }
169 }
170
171 Self { nodes: result }
172 }
173
174 #[deprecated(since = "0.1.6", note = "Please use `next_sibling`")]
175 pub fn next(&self) -> Selection<'a> {
178 self.next_sibling()
179 }
180
181 pub fn next_sibling(&self) -> Selection<'a> {
184 let mut result = Vec::with_capacity(self.length());
185 let mut set = HashSet::with_capacity(self.length());
186
187 for node in self.nodes() {
188 if let Some(sibling) = node.next_element_sibling() {
189 if !set.contains(&sibling.id) {
190 set.insert(sibling.id);
191 result.push(sibling);
192 }
193 }
194 }
195
196 Self { nodes: result }
197 }
198
199 pub fn prev_sibling(&self) -> Selection<'a> {
202 let mut result = Vec::with_capacity(self.length());
203 let mut set = HashSet::with_capacity(self.length());
204
205 for node in self.nodes() {
206 if let Some(sibling) = node.prev_element_sibling() {
207 if !set.contains(&sibling.id) {
208 set.insert(sibling.id);
209 result.push(sibling);
210 }
211 }
212 }
213
214 Self { nodes: result }
215 }
216
217 pub fn first(&self) -> Selection<'a> {
221 if self.length() > 0 {
222 Selection::from(self.nodes[0].clone())
223 } else {
224 Default::default()
225 }
226 }
227
228 pub fn last(&self) -> Selection<'a> {
232 if self.length() > 0 {
233 Selection::from(self.nodes[self.length() - 1].clone())
234 } else {
235 Default::default()
236 }
237 }
238
239 pub fn get(&self, index: usize) -> Option<&Node<'a>> {
241 self.nodes.get(index)
242 }
243}
244
245pub struct Selections<I> {
247 iter: IntoIter<I>,
248}
249
250impl<I> Selections<I> {
251 fn new(iter: IntoIter<I>) -> Self {
252 Self { iter }
253 }
254}
255
256impl<'a> Iterator for Selections<Node<'a>> {
257 type Item = Selection<'a>;
258
259 fn next(&mut self) -> Option<Self::Item> {
260 self.iter.next().map(Selection::from)
261 }
262}
263
264impl<'a> DoubleEndedIterator for Selections<Node<'a>> {
265 fn next_back(&mut self) -> Option<Self::Item> {
266 self.iter.next_back().map(Selection::from)
267 }
268}