fix(css): use Stylo for content visibility

This commit is contained in:
ldm0
2026-09-14 13:33:58 +08:00
parent f8f397b5dc
commit 1a4fbe46fb
3 changed files with 43 additions and 33 deletions
@@ -1802,12 +1802,6 @@ fn style_entries_affecting_property(entries: &[StyleEntry], property: &str) -> V
fn cssom_style_property_write_uses_pdb(name: &str, value: &str) -> bool {
let name = canonical_style_property_name(name);
// This Stylo build parses `content-visibility` but does not expose it
// through the declaration-block mutation/query surface. Keep the value in
// the validated side-entry path so CSSOM writes remain observable.
if name == "content-visibility" {
return false;
}
if moli_css_parse::is_cssom_custom_property_name(&name) {
return !value.is_empty() && stylo_pdb_entries_for_property(&name, value, false).is_some();
}
@@ -2678,21 +2672,6 @@ pub(crate) fn parse_style_property_entries_with_base(
});
}
if name == "content-visibility" {
let value = css_wide_keyword(value).or_else(|| {
let value = value.trim().to_ascii_lowercase();
matches!(value.as_str(), "visible" | "auto" | "hidden").then_some(value)
})?;
return Some(ParsedStylePropertyEntries {
entries: vec![StyleEntry {
name: name.clone(),
value,
priority,
}],
affected_names: vec![name],
});
}
if name == "width"
&& value
.trim_start()
@@ -3989,6 +3968,42 @@ mod tests {
}
}
#[test]
fn content_visibility_cssom_writes_use_stylo_pdb() {
for (value, expected) in [
("hidden", "hidden"),
("AUTO", "auto"),
("inherit", "inherit"),
] {
assert!(cssom_style_property_write_uses_pdb(
"content-visibility",
value
));
let parsed = parse_style_property_entries_for_cssom_write(
"content-visibility",
value,
true,
None,
)
.expect("content-visibility should parse through Stylo PDB");
assert_eq!(parsed.entries.len(), 1);
assert_eq!(parsed.entries[0].name, "content-visibility");
assert_eq!(parsed.entries[0].value, expected);
assert!(parsed.entries[0].priority);
assert!(style_entry_is_pdb_safe(&parsed.entries[0]));
}
assert!(
parse_style_property_entries_for_cssom_write(
"content-visibility",
"bogus",
false,
None,
)
.is_none()
);
}
#[test]
fn transition_pdb_parser_accepts_dynamic_numeric_longhands() {
let shorthand = parse_style_property_entries_with_base(
@@ -1383,10 +1383,7 @@ pub(super) fn computed_style_default_value(
"line-height" => "normal".to_owned(),
"link-parameters" => "none".to_owned(),
"content" => "normal".to_owned(),
"content-visibility" => match element_hidden_attribute_state(runtime, handle) {
HiddenAttributeState::UntilFound => "hidden".to_owned(),
HiddenAttributeState::Missing | HiddenAttributeState::Hidden => "visible".to_owned(),
},
"content-visibility" => "visible".to_owned(),
"background-color" => "rgba(0, 0, 0, 0)".to_owned(),
"background-attachment" => "scroll".to_owned(),
"background-blend-mode" | "mix-blend-mode" => "normal".to_owned(),
@@ -2568,13 +2565,6 @@ fn computed_style_property_value_from_moli(
"link-parameters" => Some(computed_non_inherited_css_keyword_property_value(
runtime, handle, property, "none",
)),
"content-visibility" => {
inline_style_entry_for_inline_style(runtime, handle, property).map(|_| {
computed_non_inherited_css_keyword_property_value(
runtime, handle, property, "visible",
)
})
}
"text-size-adjust" => Some(computed_text_size_adjust_value(runtime, handle)),
"transition-property" | "transition-behavior" => {
inline_style_entry_for_inline_style(runtime, handle, property).map(|entry| entry.value)
@@ -6822,6 +6822,11 @@ fn computed_style_distinguishes_hidden_and_until_found_states() {
target.setAttribute('hidden', value);
values.push(read());
}
target.setAttribute('hidden', 'until-found');
target.style.contentVisibility = 'visible';
values.push(`${target.style.contentVisibility}/${read()}`);
target.style.removeProperty('content-visibility');
values.push(read());
target.removeAttribute('hidden');
target.style.contentVisibility = 'hidden';
values.push(`${target.style.contentVisibility}/${read()}`);
@@ -6835,7 +6840,7 @@ fn computed_style_distinguishes_hidden_and_until_found_states() {
assert_eq!(
result,
"block:visible|none:visible|none:visible|block:hidden|block:hidden|block:hidden|none:visible|hidden/block:hidden|hidden/block:hidden"
"block:visible|none:visible|none:visible|block:hidden|block:hidden|block:hidden|none:visible|visible/block:visible|block:hidden|hidden/block:hidden|hidden/block:hidden"
);
}