1 #![allow(clippy::similar_names)]
2
3 use std::collections::VecDeque;
4
5 use super::super::{
6 Combinator, ComplexSelector, ComplexSelectorComponent, CompoundSelector, Pseudo, SimpleSelector,
7 };
8
9 /// Returns the contents of a `SelectorList` that matches only elements that are
10 /// matched by both `complex_one` and `complex_two`.
11 ///
12 /// If no such list can be produced, returns `None`.
unify_complex( complexes: Vec<Vec<ComplexSelectorComponent>>, ) -> Option<Vec<Vec<ComplexSelectorComponent>>>13 pub(crate) fn unify_complex(
14 complexes: Vec<Vec<ComplexSelectorComponent>>,
15 ) -> Option<Vec<Vec<ComplexSelectorComponent>>> {
16 debug_assert!(!complexes.is_empty());
17
18 if complexes.len() == 1 {
19 return Some(complexes);
20 }
21
22 let mut unified_base: Option<Vec<SimpleSelector>> = None;
23
24 for complex in &complexes {
25 let base = complex.last()?;
26
27 if let ComplexSelectorComponent::Compound(base) = base {
28 if let Some(mut some_unified_base) = unified_base.clone() {
29 for simple in base.components.clone() {
30 some_unified_base = simple.unify(some_unified_base.clone())?;
31 }
32 unified_base = Some(some_unified_base);
33 } else {
34 unified_base = Some(base.components.clone());
35 }
36 } else {
37 return None;
38 }
39 }
40
41 let mut complexes_without_bases: Vec<Vec<ComplexSelectorComponent>> = complexes
42 .into_iter()
43 .map(|mut complex| {
44 complex.pop();
45 complex
46 })
47 .collect();
48
49 complexes_without_bases
50 .last_mut()
51 .unwrap()
52 .push(ComplexSelectorComponent::Compound(CompoundSelector {
53 components: unified_base?,
54 }));
55
56 Some(weave(complexes_without_bases))
57 }
58
59 /// Expands "parenthesized selectors" in `complexes`.
60 ///
61 /// That is, if we have `.A .B {@extend .C}` and `.D .C {...}`, this
62 /// conceptually expands into `.D .C, .D (.A .B)`, and this function translates
63 /// `.D (.A .B)` into `.D .A .B, .A .D .B`. For thoroughness, `.A.D .B` would
64 /// also be required, but including merged selectors results in exponential
65 /// output for very little gain.
66 ///
67 /// The selector `.D (.A .B)` is represented as the list `[[.D], [.A, .B]]`.
weave( mut complexes: Vec<Vec<ComplexSelectorComponent>>, ) -> Vec<Vec<ComplexSelectorComponent>>68 pub(crate) fn weave(
69 mut complexes: Vec<Vec<ComplexSelectorComponent>>,
70 ) -> Vec<Vec<ComplexSelectorComponent>> {
71 let mut prefixes: Vec<Vec<ComplexSelectorComponent>> = vec![complexes.remove(0)];
72
73 for mut complex in complexes {
74 let target = match complex.pop() {
75 Some(c) => c,
76 None => continue,
77 };
78
79 if complex.is_empty() {
80 for prefix in &mut prefixes {
81 prefix.push(target.clone());
82 }
83 continue;
84 }
85
86 let parents: Vec<ComplexSelectorComponent> = complex;
87 let mut new_prefixes: Vec<Vec<ComplexSelectorComponent>> = Vec::new();
88
89 for prefix in prefixes {
90 if let Some(parent_prefixes) = weave_parents(prefix, parents.clone()) {
91 for mut parent_prefix in parent_prefixes {
92 parent_prefix.push(target.clone());
93 new_prefixes.push(parent_prefix);
94 }
95 }
96 }
97 prefixes = new_prefixes;
98 }
99
100 prefixes
101 }
102
103 /// Interweaves `parents_one` and `parents_two` as parents of the same target selector.
104 ///
105 /// Returns all possible orderings of the selectors in the inputs (including
106 /// using unification) that maintain the relative ordering of the input. For
107 /// example, given `.foo .bar` and `.baz .bang`, this would return `.foo .bar
108 /// .baz .bang`, `.foo .bar.baz .bang`, `.foo .baz .bar .bang`, `.foo .baz
109 /// .bar.bang`, `.foo .baz .bang .bar`, and so on until `.baz .bang .foo .bar`.
110 ///
111 /// Semantically, for selectors A and B, this returns all selectors `AB_i`
112 /// such that the union over all i of elements matched by `AB_i X` is
113 /// identical to the intersection of all elements matched by `A X` and all
114 /// elements matched by `B X`. Some `AB_i` are elided to reduce the size of
115 /// the output.
weave_parents( parents_one: Vec<ComplexSelectorComponent>, parents_two: Vec<ComplexSelectorComponent>, ) -> Option<Vec<Vec<ComplexSelectorComponent>>>116 fn weave_parents(
117 parents_one: Vec<ComplexSelectorComponent>,
118 parents_two: Vec<ComplexSelectorComponent>,
119 ) -> Option<Vec<Vec<ComplexSelectorComponent>>> {
120 let mut queue_one = VecDeque::from(parents_one);
121 let mut queue_two = VecDeque::from(parents_two);
122
123 let initial_combinators = merge_initial_combinators(&mut queue_one, &mut queue_two)?;
124
125 let mut final_combinators = merge_final_combinators(&mut queue_one, &mut queue_two, None)?;
126
127 match (first_if_root(&mut queue_one), first_if_root(&mut queue_two)) {
128 (Some(root_one), Some(root_two)) => {
129 let root = ComplexSelectorComponent::Compound(root_one.unify(root_two)?);
130 queue_one.push_front(root.clone());
131 queue_two.push_front(root);
132 }
133 (Some(root_one), None) => {
134 queue_two.push_front(ComplexSelectorComponent::Compound(root_one));
135 }
136 (None, Some(root_two)) => {
137 queue_one.push_front(ComplexSelectorComponent::Compound(root_two));
138 }
139 (None, None) => {}
140 }
141
142 let mut groups_one = group_selectors(Vec::from(queue_one));
143 let mut groups_two = group_selectors(Vec::from(queue_two));
144
145 let lcs = longest_common_subsequence(
146 groups_two.as_slices().0,
147 groups_one.as_slices().0,
148 Some(&|group_one, group_two| {
149 if group_one == group_two {
150 return Some(group_one);
151 }
152
153 if let ComplexSelectorComponent::Combinator(..) = group_one.first()? {
154 return None;
155 }
156 if let ComplexSelectorComponent::Combinator(..) = group_two.first()? {
157 return None;
158 }
159
160 if complex_is_parent_superselector(group_one.clone(), group_two.clone()) {
161 return Some(group_two);
162 }
163 if complex_is_parent_superselector(group_two.clone(), group_one.clone()) {
164 return Some(group_one);
165 }
166
167 if !must_unify(&group_one, &group_two) {
168 return None;
169 }
170
171 let unified = unify_complex(vec![group_one, group_two])?;
172 if unified.len() > 1 {
173 return None;
174 }
175
176 unified.first().cloned()
177 }),
178 );
179
180 let mut choices = vec![vec![initial_combinators
181 .into_iter()
182 .map(ComplexSelectorComponent::Combinator)
183 .collect::<Vec<ComplexSelectorComponent>>()]];
184
185 for group in lcs {
186 choices.push(
187 chunks(&mut groups_one, &mut groups_two, |sequence| {
188 complex_is_parent_superselector(
189 match sequence.get(0) {
190 Some(v) => v.clone(),
191 None => return true,
192 },
193 group.clone(),
194 )
195 })
196 .into_iter()
197 .map(|chunk| chunk.into_iter().flatten().collect())
198 .collect(),
199 );
200 choices.push(vec![group]);
201 groups_one.pop_front();
202 groups_two.pop_front();
203 }
204
205 choices.push(
206 chunks(&mut groups_one, &mut groups_two, VecDeque::is_empty)
207 .into_iter()
208 .map(|chunk| chunk.into_iter().flatten().collect())
209 .collect(),
210 );
211
212 choices.append(&mut final_combinators);
213
214 Some(
215 paths(
216 choices
217 .into_iter()
218 .filter(|choice| !choice.is_empty())
219 .collect(),
220 )
221 .into_iter()
222 .map(|chunk| chunk.into_iter().flatten().collect())
223 .collect(),
224 )
225 }
226
227 /// Extracts leading `Combinator`s from `components_one` and `components_two` and
228 /// merges them together into a single list of combinators.
229 ///
230 /// If there are no combinators to be merged, returns an empty list. If the
231 /// combinators can't be merged, returns `None`.
merge_initial_combinators( components_one: &mut VecDeque<ComplexSelectorComponent>, components_two: &mut VecDeque<ComplexSelectorComponent>, ) -> Option<Vec<Combinator>>232 fn merge_initial_combinators(
233 components_one: &mut VecDeque<ComplexSelectorComponent>,
234 components_two: &mut VecDeque<ComplexSelectorComponent>,
235 ) -> Option<Vec<Combinator>> {
236 let mut combinators_one: Vec<Combinator> = Vec::new();
237
238 while let Some(ComplexSelectorComponent::Combinator(c)) = components_one.get(0) {
239 combinators_one.push(*c);
240 components_one.pop_front();
241 }
242
243 let mut combinators_two = Vec::new();
244
245 while let Some(ComplexSelectorComponent::Combinator(c)) = components_two.get(0) {
246 combinators_two.push(*c);
247 components_two.pop_front();
248 }
249
250 let lcs = longest_common_subsequence(&combinators_one, &combinators_two, None);
251
252 if lcs == combinators_one {
253 Some(combinators_two)
254 } else if lcs == combinators_two {
255 Some(combinators_one)
256 } else {
257 // If neither sequence of combinators is a subsequence of the other, they
258 // cannot be merged successfully.
259 None
260 }
261 }
262
263 /// Returns the longest common subsequence between `list_one` and `list_two`.
264 ///
265 /// If there are more than one equally long common subsequence, returns the one
266 /// which starts first in `list_one`.
267 ///
268 /// If `select` is passed, it's used to check equality between elements in each
269 /// list. If it returns `None`, the elements are considered unequal; otherwise,
270 /// it should return the element to include in the return value.
271 #[allow(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
longest_common_subsequence<T: PartialEq + Clone>( list_one: &[T], list_two: &[T], select: Option<&dyn Fn(T, T) -> Option<T>>, ) -> Vec<T>272 fn longest_common_subsequence<T: PartialEq + Clone>(
273 list_one: &[T],
274 list_two: &[T],
275 select: Option<&dyn Fn(T, T) -> Option<T>>,
276 ) -> Vec<T> {
277 let select = select.unwrap_or(&|element_one, element_two| {
278 if element_one == element_two {
279 Some(element_one)
280 } else {
281 None
282 }
283 });
284
285 let mut lengths = vec![vec![0; list_two.len() + 1]; list_one.len() + 1];
286
287 let mut selections: Vec<Vec<Option<T>>> = vec![vec![None; list_two.len()]; list_one.len()];
288
289 for i in 0..list_one.len() {
290 for j in 0..list_two.len() {
291 let selection = select(
292 list_one.get(i).unwrap().clone(),
293 list_two.get(j).unwrap().clone(),
294 );
295 selections[i][j] = selection.clone();
296 lengths[i + 1][j + 1] = if selection.is_none() {
297 std::cmp::max(lengths[i + 1][j], lengths[i][j + 1])
298 } else {
299 lengths[i][j] + 1
300 };
301 }
302 }
303
304 fn backtrack<T: Clone>(
305 i: isize,
306 j: isize,
307 lengths: Vec<Vec<i32>>,
308 selections: &mut Vec<Vec<Option<T>>>,
309 ) -> Vec<T> {
310 if i == -1 || j == -1 {
311 return Vec::new();
312 }
313
314 let selection = selections.get(i as usize).cloned().unwrap_or_default();
315
316 if let Some(Some(selection)) = selection.get(j as usize) {
317 let mut tmp = backtrack(i - 1, j - 1, lengths, selections);
318 tmp.push(selection.clone());
319 return tmp;
320 }
321
322 if lengths[(i + 1) as usize][j as usize] > lengths[i as usize][(j + 1) as usize] {
323 backtrack(i, j - 1, lengths, selections)
324 } else {
325 backtrack(i - 1, j, lengths, selections)
326 }
327 }
328 backtrack(
329 (list_one.len() as isize).saturating_sub(1),
330 (list_two.len() as isize).saturating_sub(1),
331 lengths,
332 &mut selections,
333 )
334 }
335
336 /// Extracts trailing `Combinator`s, and the selectors to which they apply, from
337 /// `components_one` and `components_two` and merges them together into a single list.
338 ///
339 /// If there are no combinators to be merged, returns an empty list. If the
340 /// sequences can't be merged, returns `None`.
341 #[allow(clippy::cognitive_complexity)]
merge_final_combinators( components_one: &mut VecDeque<ComplexSelectorComponent>, components_two: &mut VecDeque<ComplexSelectorComponent>, result: Option<VecDeque<Vec<Vec<ComplexSelectorComponent>>>>, ) -> Option<Vec<Vec<Vec<ComplexSelectorComponent>>>>342 fn merge_final_combinators(
343 components_one: &mut VecDeque<ComplexSelectorComponent>,
344 components_two: &mut VecDeque<ComplexSelectorComponent>,
345 result: Option<VecDeque<Vec<Vec<ComplexSelectorComponent>>>>,
346 ) -> Option<Vec<Vec<Vec<ComplexSelectorComponent>>>> {
347 let mut result = result.unwrap_or_default();
348
349 if (components_one.is_empty() || !components_one.back().unwrap().is_combinator())
350 && (components_two.is_empty() || !components_two.back().unwrap().is_combinator())
351 {
352 return Some(Vec::from(result));
353 }
354
355 let mut combinators_one = Vec::new();
356
357 while let Some(ComplexSelectorComponent::Combinator(combinator)) =
358 components_one.get(components_one.len().saturating_sub(1))
359 {
360 combinators_one.push(*combinator);
361 components_one.pop_back();
362 }
363
364 let mut combinators_two = Vec::new();
365
366 while let Some(ComplexSelectorComponent::Combinator(combinator)) =
367 components_two.get(components_two.len().saturating_sub(1))
368 {
369 combinators_two.push(*combinator);
370 components_two.pop_back();
371 }
372
373 if combinators_one.len() > 1 || combinators_two.len() > 1 {
374 // If there are multiple combinators, something hacky's going on. If one
375 // is a supersequence of the other, use that, otherwise give up.
376 let lcs = longest_common_subsequence(&combinators_one, &combinators_two, None);
377 if lcs == combinators_one {
378 result.push_front(vec![combinators_two
379 .into_iter()
380 .map(ComplexSelectorComponent::Combinator)
381 .rev()
382 .collect()]);
383 } else if lcs == combinators_two {
384 result.push_front(vec![combinators_one
385 .into_iter()
386 .map(ComplexSelectorComponent::Combinator)
387 .rev()
388 .collect()]);
389 } else {
390 return None;
391 }
392
393 return Some(Vec::from(result));
394 }
395
396 let combinator_one = combinators_one.first();
397
398 let combinator_two = combinators_two.first();
399
400 // This code looks complicated, but it's actually just a bunch of special
401 // cases for interactions between different combinators.
402 match (combinator_one, combinator_two) {
403 (Some(combinator_one), Some(combinator_two)) => {
404 let compound_one = match components_one.pop_back() {
405 Some(ComplexSelectorComponent::Compound(c)) => c,
406 Some(..) | None => unreachable!(),
407 };
408 let compound_two = match components_two.pop_back() {
409 Some(ComplexSelectorComponent::Compound(c)) => c,
410 Some(..) | None => unreachable!(),
411 };
412
413 match (combinator_one, combinator_two) {
414 (Combinator::FollowingSibling, Combinator::FollowingSibling) => {
415 if compound_one.is_super_selector(&compound_two, &None) {
416 result.push_front(vec![vec![
417 ComplexSelectorComponent::Compound(compound_two),
418 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
419 ]]);
420 } else if compound_two.is_super_selector(&compound_one, &None) {
421 result.push_front(vec![vec![
422 ComplexSelectorComponent::Compound(compound_one),
423 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
424 ]]);
425 } else {
426 let mut choices = vec![
427 vec![
428 ComplexSelectorComponent::Compound(compound_one.clone()),
429 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
430 ComplexSelectorComponent::Compound(compound_two.clone()),
431 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
432 ],
433 vec![
434 ComplexSelectorComponent::Compound(compound_two.clone()),
435 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
436 ComplexSelectorComponent::Compound(compound_one.clone()),
437 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
438 ],
439 ];
440
441 if let Some(unified) = compound_one.unify(compound_two) {
442 choices.push(vec![
443 ComplexSelectorComponent::Compound(unified),
444 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
445 ]);
446 }
447
448 result.push_front(choices);
449 }
450 }
451 (Combinator::FollowingSibling, Combinator::NextSibling)
452 | (Combinator::NextSibling, Combinator::FollowingSibling) => {
453 let following_sibling_selector =
454 if combinator_one == &Combinator::FollowingSibling {
455 compound_one.clone()
456 } else {
457 compound_two.clone()
458 };
459
460 let next_sibling_selector = if combinator_one == &Combinator::FollowingSibling {
461 compound_two.clone()
462 } else {
463 compound_one.clone()
464 };
465
466 if following_sibling_selector.is_super_selector(&next_sibling_selector, &None) {
467 result.push_front(vec![vec![
468 ComplexSelectorComponent::Compound(next_sibling_selector),
469 ComplexSelectorComponent::Combinator(Combinator::NextSibling),
470 ]]);
471 } else {
472 let mut v = vec![vec![
473 ComplexSelectorComponent::Compound(following_sibling_selector),
474 ComplexSelectorComponent::Combinator(Combinator::FollowingSibling),
475 ComplexSelectorComponent::Compound(next_sibling_selector),
476 ComplexSelectorComponent::Combinator(Combinator::NextSibling),
477 ]];
478
479 if let Some(unified) = compound_one.unify(compound_two) {
480 v.push(vec![
481 ComplexSelectorComponent::Compound(unified),
482 ComplexSelectorComponent::Combinator(Combinator::NextSibling),
483 ]);
484 }
485 result.push_front(v);
486 }
487 }
488 (Combinator::Child, Combinator::NextSibling)
489 | (Combinator::Child, Combinator::FollowingSibling) => {
490 result.push_front(vec![vec![
491 ComplexSelectorComponent::Compound(compound_two),
492 ComplexSelectorComponent::Combinator(*combinator_two),
493 ]]);
494 components_one.push_back(ComplexSelectorComponent::Compound(compound_one));
495 components_one
496 .push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
497 }
498 (Combinator::NextSibling, Combinator::Child)
499 | (Combinator::FollowingSibling, Combinator::Child) => {
500 result.push_front(vec![vec![
501 ComplexSelectorComponent::Compound(compound_one),
502 ComplexSelectorComponent::Combinator(*combinator_one),
503 ]]);
504 components_two.push_back(ComplexSelectorComponent::Compound(compound_two));
505 components_two
506 .push_back(ComplexSelectorComponent::Combinator(Combinator::Child));
507 }
508 (..) => {
509 if combinator_one != combinator_two {
510 return None;
511 }
512
513 let unified = compound_one.unify(compound_two)?;
514
515 result.push_front(vec![vec![
516 ComplexSelectorComponent::Compound(unified),
517 ComplexSelectorComponent::Combinator(*combinator_one),
518 ]]);
519 }
520 }
521
522 merge_final_combinators(components_one, components_two, Some(result))
523 }
524 (Some(combinator_one), None) => {
525 if *combinator_one == Combinator::Child && !components_two.is_empty() {
526 if let Some(ComplexSelectorComponent::Compound(c1)) = components_one.back() {
527 if let Some(ComplexSelectorComponent::Compound(c2)) = components_two.back() {
528 if c2.is_super_selector(c1, &None) {
529 components_two.pop_back();
530 }
531 }
532 }
533 }
534
535 result.push_front(vec![vec![
536 components_one.pop_back().unwrap(),
537 ComplexSelectorComponent::Combinator(*combinator_one),
538 ]]);
539
540 merge_final_combinators(components_one, components_two, Some(result))
541 }
542 (None, Some(combinator_two)) => {
543 if *combinator_two == Combinator::Child && !components_one.is_empty() {
544 if let Some(ComplexSelectorComponent::Compound(c1)) = components_one.back() {
545 if let Some(ComplexSelectorComponent::Compound(c2)) = components_two.back() {
546 if c1.is_super_selector(c2, &None) {
547 components_one.pop_back();
548 }
549 }
550 }
551 }
552
553 result.push_front(vec![vec![
554 components_two.pop_back().unwrap(),
555 ComplexSelectorComponent::Combinator(*combinator_two),
556 ]]);
557 merge_final_combinators(components_one, components_two, Some(result))
558 }
559 (None, None) => unreachable!(),
560 }
561 }
562
563 /// If the first element of `queue` has a `::root` selector, removes and returns
564 /// that element.
first_if_root(queue: &mut VecDeque<ComplexSelectorComponent>) -> Option<CompoundSelector>565 fn first_if_root(queue: &mut VecDeque<ComplexSelectorComponent>) -> Option<CompoundSelector> {
566 if queue.is_empty() {
567 return None;
568 }
569 if let Some(ComplexSelectorComponent::Compound(c)) = queue.get(0) {
570 if !has_root(c) {
571 return None;
572 }
573 let compound = c.clone();
574 queue.pop_front();
575 Some(compound)
576 } else {
577 None
578 }
579 }
580
581 /// Returns whether or not `compound` contains a `::root` selector.
has_root(compound: &CompoundSelector) -> bool582 fn has_root(compound: &CompoundSelector) -> bool {
583 compound.components.iter().any(|simple| {
584 if let SimpleSelector::Pseudo(pseudo) = simple {
585 pseudo.is_class && pseudo.normalized_name() == "root"
586 } else {
587 false
588 }
589 })
590 }
591
592 /// Returns `complex`, grouped into sub-lists such that no sub-list contains two
593 /// adjacent `ComplexSelector`s.
594 ///
595 /// For example, `(A B > C D + E ~ > G)` is grouped into
596 /// `[(A) (B > C) (D + E ~ > G)]`.
group_selectors( complex: Vec<ComplexSelectorComponent>, ) -> VecDeque<Vec<ComplexSelectorComponent>>597 fn group_selectors(
598 complex: Vec<ComplexSelectorComponent>,
599 ) -> VecDeque<Vec<ComplexSelectorComponent>> {
600 let mut groups = VecDeque::new();
601
602 let mut iter = complex.into_iter();
603
604 groups.push_back(if let Some(c) = iter.next() {
605 vec![c]
606 } else {
607 return groups;
608 });
609
610 for c in iter {
611 let mut last_group = groups.pop_back().unwrap();
612 if last_group
613 .last()
614 .map_or(false, ComplexSelectorComponent::is_combinator)
615 || c.is_combinator()
616 {
617 last_group.push(c);
618 groups.push_back(last_group);
619 } else {
620 groups.push_back(last_group);
621 groups.push_back(vec![c]);
622 }
623 }
624
625 groups
626 }
627
628 /// Returns all orderings of initial subseqeuences of `queue_one` and `queue_two`.
629 ///
630 /// The `done` callback is used to determine the extent of the initial
631 /// subsequences. It's called with each queue until it returns `true`.
632 ///
633 /// This destructively removes the initial subsequences of `queue_one` and
634 /// `queue_two`.
635 ///
636 /// For example, given `(A B C | D E)` and `(1 2 | 3 4 5)` (with `|` denoting
637 /// the boundary of the initial subsequence), this would return `[(A B C 1 2),
638 /// (1 2 A B C)]`. The queues would then contain `(D E)` and `(3 4 5)`.
chunks<T: Clone>( queue_one: &mut VecDeque<T>, queue_two: &mut VecDeque<T>, done: impl Fn(&VecDeque<T>) -> bool, ) -> Vec<Vec<T>>639 fn chunks<T: Clone>(
640 queue_one: &mut VecDeque<T>,
641 queue_two: &mut VecDeque<T>,
642 done: impl Fn(&VecDeque<T>) -> bool,
643 ) -> Vec<Vec<T>> {
644 let mut chunk_one = Vec::new();
645 while !done(queue_one) {
646 chunk_one.push(queue_one.pop_front().unwrap());
647 }
648
649 let mut chunk_two = Vec::new();
650 while !done(queue_two) {
651 chunk_two.push(queue_two.pop_front().unwrap());
652 }
653
654 match (chunk_one.is_empty(), chunk_two.is_empty()) {
655 (true, true) => Vec::new(),
656 (true, false) => vec![chunk_two],
657 (false, true) => vec![chunk_one],
658 (false, false) => {
659 let mut l1 = chunk_one.clone();
660 l1.append(&mut chunk_two.clone());
661
662 let mut l2 = chunk_two;
663 l2.append(&mut chunk_one);
664
665 vec![l1, l2]
666 }
667 }
668 }
669
670 /// Like `complex_is_superselector`, but compares `complex_one` and `complex_two` as
671 /// though they shared an implicit base `SimpleSelector`.
672 ///
673 /// For example, `B` is not normally a superselector of `B A`, since it doesn't
674 /// match elements that match `A`. However, it *is* a parent superselector,
675 /// since `B X` is a superselector of `B A X`.
complex_is_parent_superselector( mut complex_one: Vec<ComplexSelectorComponent>, mut complex_two: Vec<ComplexSelectorComponent>, ) -> bool676 fn complex_is_parent_superselector(
677 mut complex_one: Vec<ComplexSelectorComponent>,
678 mut complex_two: Vec<ComplexSelectorComponent>,
679 ) -> bool {
680 if let Some(ComplexSelectorComponent::Combinator(..)) = complex_one.first() {
681 return false;
682 }
683 if let Some(ComplexSelectorComponent::Combinator(..)) = complex_two.first() {
684 return false;
685 }
686 if complex_one.len() > complex_two.len() {
687 return false;
688 }
689 let base = CompoundSelector {
690 components: vec![SimpleSelector::Placeholder(String::new())],
691 };
692 complex_one.push(ComplexSelectorComponent::Compound(base.clone()));
693 complex_two.push(ComplexSelectorComponent::Compound(base));
694
695 ComplexSelector::new(complex_one, false)
696 .is_super_selector(&ComplexSelector::new(complex_two, false))
697 }
698
699 /// Returns a list of all possible paths through the given lists.
700 ///
701 /// For example, given `[[1, 2], [3, 4], [5]]`, this returns:
702 ///
703 /// ```no_run
704 /// [[1, 3, 5],
705 /// [2, 3, 5],
706 /// [1, 4, 5],
707 /// [2, 4, 5]];
708 /// ```
paths<T: Clone>(choices: Vec<Vec<T>>) -> Vec<Vec<T>>709 pub(crate) fn paths<T: Clone>(choices: Vec<Vec<T>>) -> Vec<Vec<T>> {
710 choices.into_iter().fold(vec![vec![]], |paths, choice| {
711 choice
712 .into_iter()
713 .flat_map(move |option| {
714 paths.clone().into_iter().map(move |mut path| {
715 path.push(option.clone());
716 path
717 })
718 })
719 .collect()
720 })
721 }
722
723 /// Returns whether `complex_one` and `complex_two` need to be unified to produce a
724 /// valid combined selector.
725 ///
726 /// This is necessary when both selectors contain the same unique simple
727 /// selector, such as an ID.
must_unify( complex_one: &[ComplexSelectorComponent], complex_two: &[ComplexSelectorComponent], ) -> bool728 fn must_unify(
729 complex_one: &[ComplexSelectorComponent],
730 complex_two: &[ComplexSelectorComponent],
731 ) -> bool {
732 let mut unique_selectors = Vec::new();
733 for component in complex_one {
734 if let ComplexSelectorComponent::Compound(c) = component {
735 unique_selectors.extend(c.components.iter().filter(|f| is_unique(f)));
736 }
737 }
738
739 if unique_selectors.is_empty() {
740 return false;
741 }
742
743 complex_two.iter().any(|component| {
744 if let ComplexSelectorComponent::Compound(compound) = component {
745 compound
746 .components
747 .iter()
748 .any(|simple| is_unique(simple) && unique_selectors.contains(&simple))
749 } else {
750 false
751 }
752 })
753 }
754
755 /// Returns whether a `CompoundSelector` may contain only one simple selector of
756 /// the same type as `simple`.
is_unique(simple: &SimpleSelector) -> bool757 fn is_unique(simple: &SimpleSelector) -> bool {
758 matches!(
759 simple,
760 SimpleSelector::Id(..)
761 | SimpleSelector::Pseudo(Pseudo {
762 is_class: false,
763 ..
764 })
765 )
766 }
767