diff --git a/components/style/animation.rs b/components/style/animation.rs index 8d670964ec8..d7eab3f314e 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -19,6 +19,7 @@ use properties::longhands::animation_iteration_count::single_value::computed_val use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState; use properties::longhands::transition_timing_function::single_value::computed_value::StartEnd; use properties::longhands::transition_timing_function::single_value::computed_value::T as TransitionTimingFunction; +use rule_tree::CascadeLevel; use std::sync::mpsc::Sender; use stylearc::Arc; use timer::Timer; @@ -472,7 +473,8 @@ fn compute_style_for_animation_step(context: &SharedStyleContext, .all(|&(_, importance)| importance == Importance::Normal)); let iter = || { - guard.declarations().iter().rev().map(|&(ref decl, _importance)| decl) + guard.declarations().iter().rev() + .map(|&(ref decl, _importance)| (decl, CascadeLevel::Animations)) }; // This currently ignores visited styles, which seems acceptable, diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 7ba4959eeb5..3cfdc7a798c 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -6,9 +6,10 @@ use app_units::Au; use context::QuirksMode; -use cssparser::{CssStringWriter, Parser, Token}; +use cssparser::{CssStringWriter, Parser, RGBA, Token}; use euclid::Size2D; use font_metrics::get_metrics_provider_for_product; +use gecko::values::convert_nscolor_to_rgba; use gecko_bindings::bindings; use gecko_bindings::structs::{nsCSSKeyword, nsCSSProps_KTableEntry, nsCSSValue, nsCSSUnit, nsStringBuffer}; use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature}; @@ -134,6 +135,16 @@ impl Device { Au((*self.pres_context).mVisibleArea.height)) }) } + + /// Returns whether document colors are enabled. + pub fn use_document_colors(&self) -> bool { + unsafe { (*self.pres_context).mUseDocumentColors() != 0 } + } + + /// Returns the default background color. + pub fn default_background_color(&self) -> RGBA { + convert_nscolor_to_rgba(unsafe { (*self.pres_context).mBackgroundColor }) + } } /// A expression for gecko contains a reference to the media feature, the value diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 5b18424ebee..06735ef888b 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -150,7 +150,8 @@ class Longhand(object): need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False, allowed_in_keyframe_block=True, complex_color=False, cast_type='u8', has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False, - flags=None, allowed_in_page_rule=False, allow_quirks=False, vector=False): + flags=None, allowed_in_page_rule=False, allow_quirks=False, ignored_when_colors_disabled=False, + vector=False): self.name = name if not spec: raise TypeError("Spec should be specified for %s" % name) @@ -177,6 +178,7 @@ class Longhand(object): self.flags = flags.split() if flags else [] self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule) self.allow_quirks = allow_quirks + self.ignored_when_colors_disabled = ignored_when_colors_disabled self.is_vector = vector # https://drafts.csswg.org/css-animations/#keyframes diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 7a3c1d41cb6..4937a2569b0 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -12,6 +12,7 @@ ${helpers.predefined_type("background-color", "CSSColor", spec="https://drafts.csswg.org/css-backgrounds/#background-color", animation_value_type="IntermediateColor", complex_color=True, + ignored_when_colors_disabled=True, allow_quirks=True)} ${helpers.predefined_type("background-image", "ImageLayer", @@ -20,7 +21,8 @@ ${helpers.predefined_type("background-image", "ImageLayer", spec="https://drafts.csswg.org/css-backgrounds/#the-background-image", vector="True", animation_value_type="none", - has_uncacheable_values="True" if product == "gecko" else "False")} + has_uncacheable_values="True" if product == "gecko" else "False", + ignored_when_colors_disabled="True")} % for (axis, direction, initial) in [("x", "Horizontal", "left"), ("y", "Vertical", "top")]: ${helpers.predefined_type("background-position-" + axis, "position::" + direction + "Position", diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index eb876c40d97..9026b3fe32e 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -22,7 +22,8 @@ spec=maybe_logical_spec(side, "color"), animation_value_type="IntermediateColor", logical=side[1], - allow_quirks=not side[1])} + allow_quirks=not side[1], + ignored_when_colors_disabled=True)} ${helpers.predefined_type("border-%s-style" % side[0], "BorderStyle", "specified::BorderStyle::none", @@ -59,7 +60,8 @@ ${helpers.gecko_keyword_conversion(Keyword('border-style', % for side in PHYSICAL_SIDES: <%helpers:longhand name="-moz-border-${side}-colors" animation_value_type="none" spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-border-*-colors)" - products="gecko"> + products="gecko" + ignored_when_colors_disabled="True"> use std::fmt; use style_traits::ToCss; use values::specified::CSSColor; diff --git a/components/style/properties/longhand/color.mako.rs b/components/style/properties/longhand/color.mako.rs index 20faeec8485..238b8689e26 100644 --- a/components/style/properties/longhand/color.mako.rs +++ b/components/style/properties/longhand/color.mako.rs @@ -10,6 +10,7 @@ <%helpers:longhand name="color" need_clone="True" animation_value_type="IntermediateRGBA" + ignored_when_colors_disabled="True" spec="https://drafts.csswg.org/css-color/#color"> use cssparser::RGBA; use std::fmt; diff --git a/components/style/properties/longhand/column.mako.rs b/components/style/properties/longhand/column.mako.rs index 3d01d20b895..dee3bbef627 100644 --- a/components/style/properties/longhand/column.mako.rs +++ b/components/style/properties/longhand/column.mako.rs @@ -52,6 +52,7 @@ ${helpers.predefined_type("column-rule-color", "CSSColor", initial_specified_value="specified::CSSColor::currentcolor()", products="gecko", animation_value_type="IntermediateColor", extra_prefixes="moz", complex_color=True, need_clone=True, + ignored_when_colors_disabled=True, spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-color")} ${helpers.single_keyword("column-span", "none all", diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 6c01cb8e3e2..32c96bd39ac 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -17,6 +17,7 @@ ${helpers.predefined_type("opacity", <%helpers:vector_longhand name="box-shadow" allow_empty="True" animation_value_type="IntermediateBoxShadowList" extra_prefixes="webkit" + ignored_when_colors_disabled="True" spec="https://drafts.csswg.org/css-backgrounds/#box-shadow"> use std::fmt; use style_traits::ToCss; diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 3884e001282..6b106016634 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -680,6 +680,7 @@ ${helpers.single_keyword("text-align-last", <%helpers:longhand name="text-shadow" animation_value_type="IntermediateTextShadowList", + ignored_when_colors_disabled="True", spec="https://drafts.csswg.org/css-text-decor/#propdef-text-shadow"> use cssparser; use std::fmt; @@ -1117,6 +1118,7 @@ ${helpers.predefined_type("text-emphasis-color", "CSSColor", initial_specified_value="specified::CSSColor::currentcolor()", products="gecko", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, + ignored_when_colors_disabled=True, spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-color")} @@ -1135,6 +1137,7 @@ ${helpers.predefined_type( "CSSParserColor::CurrentColor", products="gecko", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, + ignored_when_colors_disabled=True, spec="https://compat.spec.whatwg.org/#the-webkit-text-fill-color")} ${helpers.predefined_type( @@ -1143,6 +1146,7 @@ ${helpers.predefined_type( initial_specified_value="specified::CSSColor::currentcolor()", products="gecko", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, + ignored_when_colors_disabled=True, spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke-color")} ${helpers.predefined_type("-webkit-text-stroke-width", "BorderWidth", "Au::from_px(0)", diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs index 3d0a22f08d4..0bd0f6a95da 100644 --- a/components/style/properties/longhand/outline.mako.rs +++ b/components/style/properties/longhand/outline.mako.rs @@ -13,6 +13,7 @@ ${helpers.predefined_type("outline-color", "CSSColor", "computed::CSSColor::CurrentColor", initial_specified_value="specified::CSSColor::currentcolor()", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, + ignored_when_colors_disabled=True, spec="https://drafts.csswg.org/css-ui/#propdef-outline-color")} <%helpers:longhand name="outline-style" need_clone="True" animation_value_type="none" diff --git a/components/style/properties/longhand/pointing.mako.rs b/components/style/properties/longhand/pointing.mako.rs index 5c1f929efe6..bba9b160638 100644 --- a/components/style/properties/longhand/pointing.mako.rs +++ b/components/style/properties/longhand/pointing.mako.rs @@ -184,4 +184,5 @@ ${helpers.predefined_type("caret-color", spec="https://drafts.csswg.org/css-ui/#caret-color", animation_value_type="Either", boxed=True, + ignored_when_colors_disabled=True, products="gecko")} diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index 9cfc5dece4d..0b4257b67f6 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -284,6 +284,7 @@ ${helpers.predefined_type( complex_color=True, products="gecko", animation_value_type="IntermediateColor", + ignored_when_colors_disabled=True, spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color")} <%helpers:longhand name="initial-letter" diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 9865ad963ab..1e96ffa01a8 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -37,9 +37,10 @@ use shared_lock::StylesheetGuards; use style_traits::{HasViewportPercentage, ToCss}; use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData}; #[cfg(feature = "servo")] use values::Either; +use values::specified::Color; use values::computed; use cascade_info::CascadeInfo; -use rule_tree::StrongRuleNode; +use rule_tree::{CascadeLevel, StrongRuleNode}; use style_adjuster::StyleAdjuster; #[cfg(feature = "servo")] use values::specified::BorderStyle; @@ -591,6 +592,15 @@ impl LonghandId { ) } + /// Returns true if the property is one that is ignored when document + /// colors are disabled. + fn is_ignored_when_document_colors_disabled(&self) -> bool { + matches!(*self, + ${" | ".join([("LonghandId::" + p.camel_case) + for p in data.longhands if p.ignored_when_colors_disabled])} + ) + } + /// The computed value of some properties depends on the (sometimes /// computed) value of *other* properties. /// @@ -2499,8 +2509,9 @@ pub fn cascade(device: &Device, let iter_declarations = || { rule_node.self_and_ancestors().flat_map(|node| { + let cascade_level = node.cascade_level(); let declarations = match node.style_source() { - Some(source) => source.read(node.cascade_level().guard(guards)).declarations(), + Some(source) => source.read(cascade_level.guard(guards)).declarations(), // The root node has no style source. None => &[] }; @@ -2511,7 +2522,7 @@ pub fn cascade(device: &Device, .rev() .filter_map(move |&(ref declaration, declaration_importance)| { if declaration_importance == node_importance { - Some(declaration) + Some((declaration, cascade_level)) } else { None } @@ -2547,13 +2558,13 @@ pub fn apply_declarations<'a, F, I>(device: &Device, quirks_mode: QuirksMode) -> ComputedValues where F: Fn() -> I, - I: Iterator, + I: Iterator, { let default_style = device.default_computed_values(); let inherited_custom_properties = inherited_style.custom_properties(); let mut custom_properties = None; let mut seen_custom = HashSet::new(); - for declaration in iter_declarations() { + for (declaration, _cascade_level) in iter_declarations() { if let PropertyDeclaration::Custom(ref name, ref value) = *declaration { ::custom_properties::cascade( &mut custom_properties, &inherited_custom_properties, @@ -2601,6 +2612,14 @@ pub fn apply_declarations<'a, F, I>(device: &Device, quirks_mode: quirks_mode, }; + let ignore_colors = !device.use_document_colors(); + let default_background_color_decl = if ignore_colors { + let color = device.default_background_color(); + Some(PropertyDeclaration::BackgroundColor(Color::RGBA(color).into())) + } else { + None + }; + // Set computed values, overwriting earlier declarations for the same // property. // @@ -2625,7 +2644,8 @@ pub fn apply_declarations<'a, F, I>(device: &Device, let mut font_size = None; let mut font_family = None; % endif - for declaration in iter_declarations() { + for (declaration, cascade_level) in iter_declarations() { + let mut declaration = declaration; let longhand_id = match declaration.id() { PropertyDeclarationId::Longhand(id) => id, PropertyDeclarationId::Custom(..) => continue, @@ -2639,6 +2659,28 @@ pub fn apply_declarations<'a, F, I>(device: &Device, continue } + // When document colors are disabled, skip properties that are + // marked as ignored in that mode, if they come from a UA or + // user style sheet. + if ignore_colors && + longhand_id.is_ignored_when_document_colors_disabled() && + !matches!(cascade_level, + CascadeLevel::UANormal | + CascadeLevel::UserNormal | + CascadeLevel::UserImportant | + CascadeLevel::UAImportant) { + if let PropertyDeclaration::BackgroundColor(ref color) = *declaration { + // 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. + if color.is_non_transparent() { + declaration = default_background_color_decl.as_ref().unwrap(); + } + } else { + continue + } + } + if % if category_to_cascade_now == "early": ! diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs index 2aaadfcd32b..8e1f12b6b94 100644 --- a/components/style/servo/media_queries.rs +++ b/components/style/servo/media_queries.rs @@ -6,7 +6,7 @@ use app_units::Au; use context::QuirksMode; -use cssparser::Parser; +use cssparser::{Parser, RGBA}; use euclid::{Size2D, TypedSize2D}; use font_metrics::ServoMetricsProvider; use media_queries::MediaType; @@ -96,6 +96,16 @@ impl Device { pub fn media_type(&self) -> MediaType { self.media_type.clone() } + + /// Returns whether document colors are enabled. + pub fn use_document_colors(&self) -> bool { + true + } + + /// Returns the default background color. + pub fn default_background_color(&self) -> RGBA { + RGBA::new(255, 255, 255, 255) + } } /// A expression kind servo understands and parses. diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index bf8033ed79a..22a96650342 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -178,6 +178,15 @@ impl CSSColor { authored: None, }) } + + /// Returns false if the color is completely transparent, and + /// true otherwise. + pub fn is_non_transparent(&self) -> bool { + match self.parsed { + Color::RGBA(rgba) if rgba.alpha == 0 => false, + _ => true, + } + } } no_viewport_percentage!(CSSColor);