style: Add support for disabled document colors.

This commit is contained in:
Cameron McCormack 2017-05-30 14:33:33 +08:00
parent 9e89b0a229
commit c768169149
15 changed files with 103 additions and 13 deletions

View file

@ -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::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::StartEnd;
use properties::longhands::transition_timing_function::single_value::computed_value::T as TransitionTimingFunction; use properties::longhands::transition_timing_function::single_value::computed_value::T as TransitionTimingFunction;
use rule_tree::CascadeLevel;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use stylearc::Arc; use stylearc::Arc;
use timer::Timer; use timer::Timer;
@ -472,7 +473,8 @@ fn compute_style_for_animation_step(context: &SharedStyleContext,
.all(|&(_, importance)| importance == Importance::Normal)); .all(|&(_, importance)| importance == Importance::Normal));
let iter = || { 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, // This currently ignores visited styles, which seems acceptable,

View file

@ -6,9 +6,10 @@
use app_units::Au; use app_units::Au;
use context::QuirksMode; use context::QuirksMode;
use cssparser::{CssStringWriter, Parser, Token}; use cssparser::{CssStringWriter, Parser, RGBA, Token};
use euclid::Size2D; use euclid::Size2D;
use font_metrics::get_metrics_provider_for_product; use font_metrics::get_metrics_provider_for_product;
use gecko::values::convert_nscolor_to_rgba;
use gecko_bindings::bindings; use gecko_bindings::bindings;
use gecko_bindings::structs::{nsCSSKeyword, nsCSSProps_KTableEntry, nsCSSValue, nsCSSUnit, nsStringBuffer}; use gecko_bindings::structs::{nsCSSKeyword, nsCSSProps_KTableEntry, nsCSSValue, nsCSSUnit, nsStringBuffer};
use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature}; use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature};
@ -134,6 +135,16 @@ impl Device {
Au((*self.pres_context).mVisibleArea.height)) 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 /// A expression for gecko contains a reference to the media feature, the value

View file

@ -150,7 +150,8 @@ class Longhand(object):
need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False, 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', allowed_in_keyframe_block=True, complex_color=False, cast_type='u8',
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False, 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 self.name = name
if not spec: if not spec:
raise TypeError("Spec should be specified for %s" % name) raise TypeError("Spec should be specified for %s" % name)
@ -177,6 +178,7 @@ class Longhand(object):
self.flags = flags.split() if flags else [] self.flags = flags.split() if flags else []
self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule) self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule)
self.allow_quirks = allow_quirks self.allow_quirks = allow_quirks
self.ignored_when_colors_disabled = ignored_when_colors_disabled
self.is_vector = vector self.is_vector = vector
# https://drafts.csswg.org/css-animations/#keyframes # https://drafts.csswg.org/css-animations/#keyframes

View file

@ -12,6 +12,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
spec="https://drafts.csswg.org/css-backgrounds/#background-color", spec="https://drafts.csswg.org/css-backgrounds/#background-color",
animation_value_type="IntermediateColor", animation_value_type="IntermediateColor",
complex_color=True, complex_color=True,
ignored_when_colors_disabled=True,
allow_quirks=True)} allow_quirks=True)}
${helpers.predefined_type("background-image", "ImageLayer", ${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", spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
vector="True", vector="True",
animation_value_type="none", 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")]: % for (axis, direction, initial) in [("x", "Horizontal", "left"), ("y", "Vertical", "top")]:
${helpers.predefined_type("background-position-" + axis, "position::" + direction + "Position", ${helpers.predefined_type("background-position-" + axis, "position::" + direction + "Position",

View file

@ -22,7 +22,8 @@
spec=maybe_logical_spec(side, "color"), spec=maybe_logical_spec(side, "color"),
animation_value_type="IntermediateColor", animation_value_type="IntermediateColor",
logical=side[1], 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", ${helpers.predefined_type("border-%s-style" % side[0], "BorderStyle",
"specified::BorderStyle::none", "specified::BorderStyle::none",
@ -59,7 +60,8 @@ ${helpers.gecko_keyword_conversion(Keyword('border-style',
% for side in PHYSICAL_SIDES: % for side in PHYSICAL_SIDES:
<%helpers:longhand name="-moz-border-${side}-colors" animation_value_type="none" <%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)" 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 std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use values::specified::CSSColor; use values::specified::CSSColor;

View file

@ -10,6 +10,7 @@
<%helpers:longhand name="color" need_clone="True" <%helpers:longhand name="color" need_clone="True"
animation_value_type="IntermediateRGBA" animation_value_type="IntermediateRGBA"
ignored_when_colors_disabled="True"
spec="https://drafts.csswg.org/css-color/#color"> spec="https://drafts.csswg.org/css-color/#color">
use cssparser::RGBA; use cssparser::RGBA;
use std::fmt; use std::fmt;

View file

@ -52,6 +52,7 @@ ${helpers.predefined_type("column-rule-color", "CSSColor",
initial_specified_value="specified::CSSColor::currentcolor()", initial_specified_value="specified::CSSColor::currentcolor()",
products="gecko", animation_value_type="IntermediateColor", extra_prefixes="moz", products="gecko", animation_value_type="IntermediateColor", extra_prefixes="moz",
complex_color=True, need_clone=True, complex_color=True, need_clone=True,
ignored_when_colors_disabled=True,
spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-color")} spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-color")}
${helpers.single_keyword("column-span", "none all", ${helpers.single_keyword("column-span", "none all",

View file

@ -17,6 +17,7 @@ ${helpers.predefined_type("opacity",
<%helpers:vector_longhand name="box-shadow" allow_empty="True" <%helpers:vector_longhand name="box-shadow" allow_empty="True"
animation_value_type="IntermediateBoxShadowList" animation_value_type="IntermediateBoxShadowList"
extra_prefixes="webkit" extra_prefixes="webkit"
ignored_when_colors_disabled="True"
spec="https://drafts.csswg.org/css-backgrounds/#box-shadow"> spec="https://drafts.csswg.org/css-backgrounds/#box-shadow">
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;

View file

@ -680,6 +680,7 @@ ${helpers.single_keyword("text-align-last",
<%helpers:longhand name="text-shadow" <%helpers:longhand name="text-shadow"
animation_value_type="IntermediateTextShadowList", animation_value_type="IntermediateTextShadowList",
ignored_when_colors_disabled="True",
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-shadow"> spec="https://drafts.csswg.org/css-text-decor/#propdef-text-shadow">
use cssparser; use cssparser;
use std::fmt; use std::fmt;
@ -1117,6 +1118,7 @@ ${helpers.predefined_type("text-emphasis-color", "CSSColor",
initial_specified_value="specified::CSSColor::currentcolor()", initial_specified_value="specified::CSSColor::currentcolor()",
products="gecko", animation_value_type="IntermediateColor", products="gecko", animation_value_type="IntermediateColor",
complex_color=True, need_clone=True, complex_color=True, need_clone=True,
ignored_when_colors_disabled=True,
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-color")} spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-color")}
@ -1135,6 +1137,7 @@ ${helpers.predefined_type(
"CSSParserColor::CurrentColor", "CSSParserColor::CurrentColor",
products="gecko", animation_value_type="IntermediateColor", products="gecko", animation_value_type="IntermediateColor",
complex_color=True, need_clone=True, complex_color=True, need_clone=True,
ignored_when_colors_disabled=True,
spec="https://compat.spec.whatwg.org/#the-webkit-text-fill-color")} spec="https://compat.spec.whatwg.org/#the-webkit-text-fill-color")}
${helpers.predefined_type( ${helpers.predefined_type(
@ -1143,6 +1146,7 @@ ${helpers.predefined_type(
initial_specified_value="specified::CSSColor::currentcolor()", initial_specified_value="specified::CSSColor::currentcolor()",
products="gecko", animation_value_type="IntermediateColor", products="gecko", animation_value_type="IntermediateColor",
complex_color=True, need_clone=True, complex_color=True, need_clone=True,
ignored_when_colors_disabled=True,
spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke-color")} spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke-color")}
${helpers.predefined_type("-webkit-text-stroke-width", "BorderWidth", "Au::from_px(0)", ${helpers.predefined_type("-webkit-text-stroke-width", "BorderWidth", "Au::from_px(0)",

View file

@ -13,6 +13,7 @@
${helpers.predefined_type("outline-color", "CSSColor", "computed::CSSColor::CurrentColor", ${helpers.predefined_type("outline-color", "CSSColor", "computed::CSSColor::CurrentColor",
initial_specified_value="specified::CSSColor::currentcolor()", initial_specified_value="specified::CSSColor::currentcolor()",
animation_value_type="IntermediateColor", complex_color=True, need_clone=True, 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")} spec="https://drafts.csswg.org/css-ui/#propdef-outline-color")}
<%helpers:longhand name="outline-style" need_clone="True" animation_value_type="none" <%helpers:longhand name="outline-style" need_clone="True" animation_value_type="none"

View file

@ -184,4 +184,5 @@ ${helpers.predefined_type("caret-color",
spec="https://drafts.csswg.org/css-ui/#caret-color", spec="https://drafts.csswg.org/css-ui/#caret-color",
animation_value_type="Either<IntermediateColor, Auto>", animation_value_type="Either<IntermediateColor, Auto>",
boxed=True, boxed=True,
ignored_when_colors_disabled=True,
products="gecko")} products="gecko")}

View file

@ -284,6 +284,7 @@ ${helpers.predefined_type(
complex_color=True, complex_color=True,
products="gecko", products="gecko",
animation_value_type="IntermediateColor", animation_value_type="IntermediateColor",
ignored_when_colors_disabled=True,
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color")} spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color")}
<%helpers:longhand name="initial-letter" <%helpers:longhand name="initial-letter"

View file

@ -37,9 +37,10 @@ use shared_lock::StylesheetGuards;
use style_traits::{HasViewportPercentage, ToCss}; use style_traits::{HasViewportPercentage, ToCss};
use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData}; use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData};
#[cfg(feature = "servo")] use values::Either; #[cfg(feature = "servo")] use values::Either;
use values::specified::Color;
use values::computed; use values::computed;
use cascade_info::CascadeInfo; use cascade_info::CascadeInfo;
use rule_tree::StrongRuleNode; use rule_tree::{CascadeLevel, StrongRuleNode};
use style_adjuster::StyleAdjuster; use style_adjuster::StyleAdjuster;
#[cfg(feature = "servo")] use values::specified::BorderStyle; #[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 /// The computed value of some properties depends on the (sometimes
/// computed) value of *other* properties. /// computed) value of *other* properties.
/// ///
@ -2499,8 +2509,9 @@ pub fn cascade(device: &Device,
let iter_declarations = || { let iter_declarations = || {
rule_node.self_and_ancestors().flat_map(|node| { rule_node.self_and_ancestors().flat_map(|node| {
let cascade_level = node.cascade_level();
let declarations = match node.style_source() { 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. // The root node has no style source.
None => &[] None => &[]
}; };
@ -2511,7 +2522,7 @@ pub fn cascade(device: &Device,
.rev() .rev()
.filter_map(move |&(ref declaration, declaration_importance)| { .filter_map(move |&(ref declaration, declaration_importance)| {
if declaration_importance == node_importance { if declaration_importance == node_importance {
Some(declaration) Some((declaration, cascade_level))
} else { } else {
None None
} }
@ -2547,13 +2558,13 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
quirks_mode: QuirksMode) quirks_mode: QuirksMode)
-> ComputedValues -> ComputedValues
where F: Fn() -> I, where F: Fn() -> I,
I: Iterator<Item = &'a PropertyDeclaration>, I: Iterator<Item = (&'a PropertyDeclaration, CascadeLevel)>,
{ {
let default_style = device.default_computed_values(); let default_style = device.default_computed_values();
let inherited_custom_properties = inherited_style.custom_properties(); let inherited_custom_properties = inherited_style.custom_properties();
let mut custom_properties = None; let mut custom_properties = None;
let mut seen_custom = HashSet::new(); 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 { if let PropertyDeclaration::Custom(ref name, ref value) = *declaration {
::custom_properties::cascade( ::custom_properties::cascade(
&mut custom_properties, &inherited_custom_properties, &mut custom_properties, &inherited_custom_properties,
@ -2601,6 +2612,14 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
quirks_mode: quirks_mode, 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 // Set computed values, overwriting earlier declarations for the same
// property. // property.
// //
@ -2625,7 +2644,8 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
let mut font_size = None; let mut font_size = None;
let mut font_family = None; let mut font_family = None;
% endif % endif
for declaration in iter_declarations() { for (declaration, cascade_level) in iter_declarations() {
let mut declaration = declaration;
let longhand_id = match declaration.id() { let longhand_id = match declaration.id() {
PropertyDeclarationId::Longhand(id) => id, PropertyDeclarationId::Longhand(id) => id,
PropertyDeclarationId::Custom(..) => continue, PropertyDeclarationId::Custom(..) => continue,
@ -2639,6 +2659,28 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
continue 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
% if category_to_cascade_now == "early": % if category_to_cascade_now == "early":
! !

View file

@ -6,7 +6,7 @@
use app_units::Au; use app_units::Au;
use context::QuirksMode; use context::QuirksMode;
use cssparser::Parser; use cssparser::{Parser, RGBA};
use euclid::{Size2D, TypedSize2D}; use euclid::{Size2D, TypedSize2D};
use font_metrics::ServoMetricsProvider; use font_metrics::ServoMetricsProvider;
use media_queries::MediaType; use media_queries::MediaType;
@ -96,6 +96,16 @@ impl Device {
pub fn media_type(&self) -> MediaType { pub fn media_type(&self) -> MediaType {
self.media_type.clone() 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. /// A expression kind servo understands and parses.

View file

@ -178,6 +178,15 @@ impl CSSColor {
authored: None, 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); no_viewport_percentage!(CSSColor);