style: Add CSSContainerRule.queryContainerFor(Element)

This actually caught a bug in the existing selection logic.

Differential Revision: https://phabricator.services.mozilla.com/D156414
This commit is contained in:
Emilio Cobos Álvarez 2022-09-10 12:25:22 +00:00 committed by Martin Robinson
parent ccad16b560
commit 00c9d9d033

View file

@ -102,6 +102,16 @@ pub struct ContainerCondition {
flags: FeatureFlags, flags: FeatureFlags,
} }
/// The result of a successful container query lookup.
pub struct ContainerLookupResult<E> {
/// The relevant container.
pub element: E,
/// The sizing / writing-mode information of the container.
pub info: ContainerInfo,
/// The style of the element.
pub style: Arc<ComputedValues>,
}
impl ContainerCondition { impl ContainerCondition {
/// Parse a container condition. /// Parse a container condition.
pub fn parse<'a>( pub fn parse<'a>(
@ -120,17 +130,17 @@ impl ContainerCondition {
Ok(Self { name, condition, flags }) Ok(Self { name, condition, flags })
} }
fn valid_container_info<E>(&self, potential_container: E) -> Option<(ContainerInfo, Arc<ComputedValues>)> fn valid_container_info<E>(&self, potential_container: E) -> Option<ContainerLookupResult<E>>
where where
E: TElement, E: TElement,
{ {
use crate::values::computed::ContainerType; use crate::values::computed::ContainerType;
fn container_type_axes(ty_: ContainerType, wm: WritingMode) -> FeatureFlags { fn container_type_axes(ty_: ContainerType, wm: WritingMode) -> FeatureFlags {
if ty_.intersects(ContainerType::SIZE) { if ty_.contains(ContainerType::SIZE) {
return FeatureFlags::all_container_axes() return FeatureFlags::all_container_axes()
} }
if ty_.intersects(ContainerType::INLINE_SIZE) { if ty_.contains(ContainerType::INLINE_SIZE) {
let physical_axis = if wm.is_vertical() { let physical_axis = if wm.is_vertical() {
FeatureFlags::CONTAINER_REQUIRES_HEIGHT_AXIS FeatureFlags::CONTAINER_REQUIRES_HEIGHT_AXIS
} else { } else {
@ -166,16 +176,21 @@ impl ContainerCondition {
let size = potential_container.primary_box_size(); let size = potential_container.primary_box_size();
let style = style.clone(); let style = style.clone();
Some((ContainerInfo { size, wm }, style)) Some(ContainerLookupResult {
element: potential_container,
info: ContainerInfo { size, wm },
style,
})
} }
fn find_container<E>(&self, mut e: E) -> Option<(ContainerInfo, Arc<ComputedValues>)> /// Performs container lookup for a given element.
pub fn find_container<E>(&self, mut e: E) -> Option<ContainerLookupResult<E>>
where where
E: TElement, E: TElement,
{ {
while let Some(element) = e.traversal_parent() { while let Some(element) = e.traversal_parent() {
if let Some(info) = self.valid_container_info(element) { if let Some(result) = self.valid_container_info(element) {
return Some(info); return Some(result);
} }
e = element; e = element;
} }
@ -188,7 +203,8 @@ impl ContainerCondition {
where where
E: TElement, E: TElement,
{ {
let info = self.find_container(element); let result = self.find_container(element);
let info = result.map(|r| (r.info, r.style));
Context::for_container_query_evaluation(device, info, |context| { Context::for_container_query_evaluation(device, info, |context| {
self.condition.matches(context) self.condition.matches(context)
}) })