mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
style: Respect the cascade properly when in high-contrast mode.
Differential Revision: https://phabricator.services.mozilla.com/D65345
This commit is contained in:
parent
c5b74bf001
commit
a73e4353fe
2 changed files with 49 additions and 84 deletions
|
@ -337,94 +337,74 @@ where
|
||||||
context.builder.build()
|
context.builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How should a declaration behave when ignoring document colors?
|
/// For ignored colors mode, we sometimes want to do something equivalent to
|
||||||
enum DeclarationApplication {
|
/// "revert-or-initial", where we `revert` for a given origin, but then apply a
|
||||||
/// We should apply the declaration.
|
/// given initial value if nothing in other origins did override it.
|
||||||
Apply,
|
///
|
||||||
/// We should ignore the declaration.
|
/// This is a bit of a clunky way of achieving this.
|
||||||
Ignore,
|
type DeclarationsToApplyUnlessOverriden = SmallVec::<[PropertyDeclaration; 2]>;
|
||||||
/// We should apply the following declaration, only if any other declaration
|
|
||||||
/// hasn't set it before.
|
|
||||||
ApplyUnlessOverriden(PropertyDeclaration),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn application_when_ignoring_colors(
|
fn tweak_when_ignoring_colors(
|
||||||
builder: &StyleBuilder,
|
builder: &StyleBuilder,
|
||||||
longhand_id: LonghandId,
|
longhand_id: LonghandId,
|
||||||
origin: Origin,
|
origin: Origin,
|
||||||
declaration: &PropertyDeclaration,
|
declaration: &mut Cow<PropertyDeclaration>,
|
||||||
) -> DeclarationApplication {
|
declarations_to_apply_unless_overriden: &mut DeclarationsToApplyUnlessOverriden,
|
||||||
|
) {
|
||||||
if !longhand_id.ignored_when_document_colors_disabled() {
|
if !longhand_id.ignored_when_document_colors_disabled() {
|
||||||
return DeclarationApplication::Apply;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_ua_or_user_rule = matches!(origin, Origin::User | Origin::UserAgent);
|
let is_ua_or_user_rule = matches!(origin, Origin::User | Origin::UserAgent);
|
||||||
if is_ua_or_user_rule {
|
if is_ua_or_user_rule {
|
||||||
return DeclarationApplication::Apply;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't override background-color on ::-moz-color-swatch. It is set as an
|
// 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
|
// author style (via the style attribute), but it's pretty important for it
|
||||||
// to show up for obvious reasons :)
|
// to show up for obvious reasons :)
|
||||||
if builder.pseudo.map_or(false, |p| p.is_color_swatch()) && longhand_id == LonghandId::BackgroundColor {
|
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
|
// A few special-cases ahead.
|
||||||
// anything other than a fully transparent color, convert it into the
|
match **declaration {
|
||||||
// Device's default background color.
|
// We honor color and background-color: transparent, and
|
||||||
// Also: for now, we treat background-image a bit differently, too.
|
// "revert-or-initial" otherwise.
|
||||||
// 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
|
|
||||||
PropertyDeclaration::BackgroundColor(ref color) => {
|
PropertyDeclaration::BackgroundColor(ref color) => {
|
||||||
if color.is_transparent() {
|
if color.is_transparent() {
|
||||||
return DeclarationApplication::Apply;
|
return;
|
||||||
}
|
}
|
||||||
let color = builder.device.default_background_color();
|
let color = builder.device.default_background_color();
|
||||||
DeclarationApplication::ApplyUnlessOverriden(
|
declarations_to_apply_unless_overriden.push(
|
||||||
PropertyDeclaration::BackgroundColor(color.into())
|
PropertyDeclaration::BackgroundColor(color.into())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
PropertyDeclaration::Color(ref color) => {
|
PropertyDeclaration::Color(ref color) => {
|
||||||
|
// otherwise.
|
||||||
if color.0.is_transparent() {
|
if color.0.is_transparent() {
|
||||||
return DeclarationApplication::Apply;
|
return;
|
||||||
}
|
|
||||||
if builder.get_parent_inherited_text().clone_color().alpha != 0 {
|
|
||||||
return DeclarationApplication::Ignore;
|
|
||||||
}
|
}
|
||||||
let color = builder.device.default_color();
|
let color = builder.device.default_color();
|
||||||
DeclarationApplication::ApplyUnlessOverriden(
|
declarations_to_apply_unless_overriden.push(
|
||||||
PropertyDeclaration::Color(specified::ColorPropertyValue(color.into()))
|
PropertyDeclaration::Color(specified::ColorPropertyValue(color.into()))
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
// In the future, if/when we remove the backplate pref, we can remove this
|
// We honor url background-images if backplating.
|
||||||
// special case along with the 'ignored_when_colors_disabled=True' mako line
|
|
||||||
// for the "background-image" property.
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
PropertyDeclaration::BackgroundImage(ref bkg) => {
|
PropertyDeclaration::BackgroundImage(ref bkg) => {
|
||||||
use crate::values::generics::image::Image;
|
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 static_prefs::pref!("browser.display.permit_backplate") {
|
||||||
if bkg.0.iter().all(|image| matches!(*image, Image::Url(..))) {
|
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> {
|
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 ignore_colors = !self.context.builder.device.use_document_colors();
|
||||||
let mut declarations_to_apply_unless_overriden =
|
let mut declarations_to_apply_unless_overriden =
|
||||||
SmallVec::<[PropertyDeclaration; 2]>::new();
|
DeclarationsToApplyUnlessOverriden::new();
|
||||||
|
|
||||||
for (declaration, origin) in declarations {
|
for (declaration, origin) in declarations {
|
||||||
let declaration_id = declaration.id();
|
let declaration_id = declaration.id();
|
||||||
|
@ -544,26 +524,23 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
continue;
|
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
|
// When document colors are disabled, do special handling of
|
||||||
// properties that are marked as ignored in that mode.
|
// properties that are marked as ignored in that mode.
|
||||||
if ignore_colors {
|
if ignore_colors {
|
||||||
let application = application_when_ignoring_colors(
|
tweak_when_ignoring_colors(
|
||||||
&self.context.builder,
|
&self.context.builder,
|
||||||
longhand_id,
|
longhand_id,
|
||||||
origin,
|
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();
|
let css_wide_keyword = declaration.get_css_wide_keyword();
|
||||||
|
|
|
@ -1590,10 +1590,7 @@ impl UnparsedValue {
|
||||||
} else {
|
} else {
|
||||||
CSSWideKeyword::Initial
|
CSSWideKeyword::Initial
|
||||||
};
|
};
|
||||||
PropertyDeclaration::CSSWideKeyword(WideKeywordDeclaration {
|
PropertyDeclaration::css_wide_keyword(longhand_id, keyword)
|
||||||
id: longhand_id,
|
|
||||||
keyword,
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let css = match crate::custom_properties::substitute(
|
let css = match crate::custom_properties::substitute(
|
||||||
|
@ -1630,10 +1627,7 @@ impl UnparsedValue {
|
||||||
let mut input = Parser::new(&mut input);
|
let mut input = Parser::new(&mut input);
|
||||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||||
if let Ok(keyword) = input.try(CSSWideKeyword::parse) {
|
if let Ok(keyword) = input.try(CSSWideKeyword::parse) {
|
||||||
return PropertyDeclaration::CSSWideKeyword(WideKeywordDeclaration {
|
return PropertyDeclaration::css_wide_keyword(longhand_id, keyword);
|
||||||
id: longhand_id,
|
|
||||||
keyword,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let declaration = input.parse_entirely(|input| {
|
let declaration = input.parse_entirely(|input| {
|
||||||
|
@ -2239,6 +2233,12 @@ impl PropertyDeclaration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a CSS-wide keyword declaration for a given property.
|
||||||
|
#[inline]
|
||||||
|
pub fn css_wide_keyword(id: LonghandId, keyword: CSSWideKeyword) -> Self {
|
||||||
|
Self::CSSWideKeyword(WideKeywordDeclaration { id, keyword })
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a CSS-wide keyword if the declaration's value is one.
|
/// Returns a CSS-wide keyword if the declaration's value is one.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_css_wide_keyword(&self) -> Option<CSSWideKeyword> {
|
pub fn get_css_wide_keyword(&self) -> Option<CSSWideKeyword> {
|
||||||
|
@ -2367,9 +2367,7 @@ impl PropertyDeclaration {
|
||||||
PropertyId::Longhand(id) => {
|
PropertyId::Longhand(id) => {
|
||||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||||
input.try(CSSWideKeyword::parse).map(|keyword| {
|
input.try(CSSWideKeyword::parse).map(|keyword| {
|
||||||
PropertyDeclaration::CSSWideKeyword(
|
PropertyDeclaration::css_wide_keyword(id, keyword)
|
||||||
WideKeywordDeclaration { id, keyword },
|
|
||||||
)
|
|
||||||
}).or_else(|()| {
|
}).or_else(|()| {
|
||||||
input.look_for_var_or_env_functions();
|
input.look_for_var_or_env_functions();
|
||||||
input.parse_entirely(|input| id.parse_value(context, input))
|
input.parse_entirely(|input| id.parse_value(context, input))
|
||||||
|
@ -2403,12 +2401,7 @@ impl PropertyDeclaration {
|
||||||
declarations.all_shorthand = AllShorthand::CSSWideKeyword(keyword)
|
declarations.all_shorthand = AllShorthand::CSSWideKeyword(keyword)
|
||||||
} else {
|
} else {
|
||||||
for longhand in id.longhands() {
|
for longhand in id.longhands() {
|
||||||
declarations.push(PropertyDeclaration::CSSWideKeyword(
|
declarations.push(PropertyDeclaration::css_wide_keyword(longhand, keyword));
|
||||||
WideKeywordDeclaration {
|
|
||||||
id: longhand,
|
|
||||||
keyword,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2550,12 +2543,7 @@ impl<'a> Iterator for AllShorthandDeclarationIterator<'a> {
|
||||||
match *self.all_shorthand {
|
match *self.all_shorthand {
|
||||||
AllShorthand::NotSet => None,
|
AllShorthand::NotSet => None,
|
||||||
AllShorthand::CSSWideKeyword(ref keyword) => {
|
AllShorthand::CSSWideKeyword(ref keyword) => {
|
||||||
Some(PropertyDeclaration::CSSWideKeyword(
|
Some(PropertyDeclaration::css_wide_keyword(self.longhands.next()?, *keyword))
|
||||||
WideKeywordDeclaration {
|
|
||||||
id: self.longhands.next()?,
|
|
||||||
keyword: *keyword
|
|
||||||
}
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
AllShorthand::WithVariables(ref unparsed) => {
|
AllShorthand::WithVariables(ref unparsed) => {
|
||||||
Some(PropertyDeclaration::WithVariables(
|
Some(PropertyDeclaration::WithVariables(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue