style: Respect the cascade properly when in high-contrast mode.

Differential Revision: https://phabricator.services.mozilla.com/D65345
This commit is contained in:
Emilio Cobos Álvarez 2020-03-04 21:25:24 +00:00
parent c5b74bf001
commit a73e4353fe
2 changed files with 49 additions and 84 deletions

View file

@ -337,94 +337,74 @@ where
context.builder.build()
}
/// How should a declaration behave when ignoring document colors?
enum DeclarationApplication {
/// We should apply the declaration.
Apply,
/// We should ignore the declaration.
Ignore,
/// We should apply the following declaration, only if any other declaration
/// hasn't set it before.
ApplyUnlessOverriden(PropertyDeclaration),
}
/// For ignored colors mode, we sometimes want to do something equivalent to
/// "revert-or-initial", where we `revert` for a given origin, but then apply a
/// given initial value if nothing in other origins did override it.
///
/// This is a bit of a clunky way of achieving this.
type DeclarationsToApplyUnlessOverriden = SmallVec::<[PropertyDeclaration; 2]>;
fn application_when_ignoring_colors(
fn tweak_when_ignoring_colors(
builder: &StyleBuilder,
longhand_id: LonghandId,
origin: Origin,
declaration: &PropertyDeclaration,
) -> DeclarationApplication {
declaration: &mut Cow<PropertyDeclaration>,
declarations_to_apply_unless_overriden: &mut DeclarationsToApplyUnlessOverriden,
) {
if !longhand_id.ignored_when_document_colors_disabled() {
return DeclarationApplication::Apply;
return;
}
let is_ua_or_user_rule = matches!(origin, Origin::User | Origin::UserAgent);
if is_ua_or_user_rule {
return DeclarationApplication::Apply;
return;
}
// Don't override background-color on ::-moz-color-swatch. It is set as an
// author style (via the style attribute), but it's pretty important for it
// to show up for obvious reasons :)
if builder.pseudo.map_or(false, |p| p.is_color_swatch()) && longhand_id == LonghandId::BackgroundColor {
return DeclarationApplication::Apply;
return;
}
// Treat background-color a bit differently. If the specified color is
// anything other than a fully transparent color, convert it into the
// Device's default background color.
// Also: for now, we treat background-image a bit differently, too.
// background-image is marked as ignored, but really, we only ignore
// it when backplates are disabled (since then text may be unreadable over
// a background image, if we're ignoring document colors).
// Here we check backplate status to decide if ignoring background-image
// is the right decision.
match *declaration {
// If we've got multiple declarations in the same block, they'll
// get overridden at parse time. We should probably adjust this
// to turn Ignored decls into `none`. See 1619701
// A few special-cases ahead.
match **declaration {
// We honor color and background-color: transparent, and
// "revert-or-initial" otherwise.
PropertyDeclaration::BackgroundColor(ref color) => {
if color.is_transparent() {
return DeclarationApplication::Apply;
return;
}
let color = builder.device.default_background_color();
DeclarationApplication::ApplyUnlessOverriden(
declarations_to_apply_unless_overriden.push(
PropertyDeclaration::BackgroundColor(color.into())
)
}
PropertyDeclaration::Color(ref color) => {
// otherwise.
if color.0.is_transparent() {
return DeclarationApplication::Apply;
}
if builder.get_parent_inherited_text().clone_color().alpha != 0 {
return DeclarationApplication::Ignore;
return;
}
let color = builder.device.default_color();
DeclarationApplication::ApplyUnlessOverriden(
declarations_to_apply_unless_overriden.push(
PropertyDeclaration::Color(specified::ColorPropertyValue(color.into()))
)
},
// In the future, if/when we remove the backplate pref, we can remove this
// special case along with the 'ignored_when_colors_disabled=True' mako line
// for the "background-image" property.
// We honor url background-images if backplating.
#[cfg(feature = "gecko")]
PropertyDeclaration::BackgroundImage(ref bkg) => {
use crate::values::generics::image::Image;
// We should only allow images to be rendered in HCM if the backplate pref
// is enabled, and if all the images applied to the background are from URLs.
// If one or more background images aren't from URL's (ie. gradients)
// we should ignore all background-image styling.
if static_prefs::pref!("browser.display.permit_backplate") {
if bkg.0.iter().all(|image| matches!(*image, Image::Url(..))) {
return DeclarationApplication::Apply;
return;
}
return DeclarationApplication::Ignore;
} else {
return DeclarationApplication::Ignore;
}
},
_ => DeclarationApplication::Ignore,
_ => {},
}
*declaration.to_mut() = PropertyDeclaration::css_wide_keyword(longhand_id, CSSWideKeyword::Revert);
}
struct Cascade<'a, 'b: 'a> {
@ -502,7 +482,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
let ignore_colors = !self.context.builder.device.use_document_colors();
let mut declarations_to_apply_unless_overriden =
SmallVec::<[PropertyDeclaration; 2]>::new();
DeclarationsToApplyUnlessOverriden::new();
for (declaration, origin) in declarations {
let declaration_id = declaration.id();
@ -544,26 +524,23 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
continue;
}
let declaration = self.substitute_variables_if_needed(declaration);
let mut declaration = self.substitute_variables_if_needed(declaration);
// When document colors are disabled, do special handling of
// properties that are marked as ignored in that mode.
if ignore_colors {
let application = application_when_ignoring_colors(
tweak_when_ignoring_colors(
&self.context.builder,
longhand_id,
origin,
&declaration,
&mut declaration,
&mut declarations_to_apply_unless_overriden,
);
debug_assert_eq!(
declaration.id(),
PropertyDeclarationId::Longhand(longhand_id),
"Shouldn't change the declaration id!",
);
match application {
DeclarationApplication::Ignore => continue,
DeclarationApplication::Apply => {},
DeclarationApplication::ApplyUnlessOverriden(decl) => {
declarations_to_apply_unless_overriden.push(decl);
continue;
}
}
}
let css_wide_keyword = declaration.get_css_wide_keyword();