Implement basic .contains ancestry selector

This commit is contained in:
Schrottkatze 2025-02-15 08:05:10 +01:00
parent e4f8e57c53
commit ba4d1dacaf
No known key found for this signature in database
3 changed files with 23 additions and 4 deletions

View File

@ -412,7 +412,7 @@ impl Content {
/// Queries the content tree for all elements that match the given selector.
///
/// Elements produced in `show` rules will not be included in the results.
pub fn query(&self, selector: Selector) -> Vec<Content> {
pub fn query(&self, selector: &Selector) -> Vec<Content> {
let mut results = Vec::new();
self.traverse(&mut |element| {
if selector.matches(&element, None) {

View File

@ -93,6 +93,9 @@ pub enum Selector {
Before { selector: Arc<Self>, end: Arc<Self>, inclusive: bool },
/// Matches all matches of `selector` after `start`.
After { selector: Arc<Self>, start: Arc<Self>, inclusive: bool },
/// Matches all children of `selector` matchin `c`
/// TODO: Better name
Contains { selector: Arc<Self>, c: Arc<Self> },
}
impl Selector {
@ -139,7 +142,10 @@ impl Selector {
}
Self::Location(location) => target.location() == Some(*location),
// Not supported here.
Self::Regex(_) | Self::Before { .. } | Self::After { .. } => false,
Self::Regex(_)
| Self::Before { .. }
| Self::After { .. }
| Self::Contains { .. } => false,
}
}
}
@ -221,6 +227,11 @@ impl Selector {
inclusive,
}
}
#[func]
pub fn contains(self, c: LocatableSelector) -> Selector {
Self::Contains { selector: Arc::new(self), c: Arc::new(c.0) }
}
}
impl From<Location> for Selector {
@ -266,6 +277,7 @@ impl Repr for Selector {
inclusive_arg
)
}
Self::Contains { .. } => todo!(),
}
}
}
@ -352,7 +364,8 @@ impl FromValue for LocatableSelector {
}
}
Selector::Before { selector, end: split, .. }
| Selector::After { selector, start: split, .. } => {
| Selector::After { selector, start: split, .. }
| Selector::Contains { selector, c: split } => {
for selector in [selector, split] {
validate(selector)?;
}
@ -431,7 +444,8 @@ impl FromValue for ShowableSelector {
| Selector::Location(_)
| Selector::Can(_)
| Selector::Before { .. }
| Selector::After { .. } => {
| Selector::After { .. }
| Selector::Contains { .. } => {
bail!("this selector cannot be used with show")
}
}

View File

@ -185,6 +185,11 @@ impl Introspector {
}
list
}
Selector::Contains { selector, c } => self
.query(selector)
.iter()
.flat_map(|children| children.query(c))
.collect(),
// Not supported here.
Selector::Can(_) | Selector::Regex(_) => EcoVec::new(),
};