mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
parent
35028f8f60
commit
16e318d055
20 changed files with 188 additions and 58 deletions
|
@ -426,7 +426,7 @@ fn compute_style_for_animation_step(context: &SharedStyleContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
let computed =
|
let computed =
|
||||||
properties::apply_declarations(context.viewport_size(),
|
properties::apply_declarations(&context.stylist.device,
|
||||||
/* is_root = */ false,
|
/* is_root = */ false,
|
||||||
iter,
|
iter,
|
||||||
previous_style,
|
previous_style,
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub struct Device {
|
||||||
/// NB: The pres context lifetime is tied to the styleset, who owns the
|
/// NB: The pres context lifetime is tied to the styleset, who owns the
|
||||||
/// stylist, and thus the `Device`, so having a raw pres context pointer
|
/// stylist, and thus the `Device`, so having a raw pres context pointer
|
||||||
/// here is fine.
|
/// here is fine.
|
||||||
pres_context: RawGeckoPresContextOwned,
|
pub pres_context: RawGeckoPresContextOwned,
|
||||||
default_values: Arc<ComputedValues>,
|
default_values: Arc<ComputedValues>,
|
||||||
viewport_override: Option<ViewportConstraints>,
|
viewport_override: Option<ViewportConstraints>,
|
||||||
}
|
}
|
||||||
|
@ -497,13 +497,13 @@ impl Expression {
|
||||||
// em units are relative to the initial font-size.
|
// em units are relative to the initial font-size.
|
||||||
let context = computed::Context {
|
let context = computed::Context {
|
||||||
is_root_element: false,
|
is_root_element: false,
|
||||||
viewport_size: device.au_viewport_size(),
|
device: device,
|
||||||
inherited_style: default_values,
|
inherited_style: default_values,
|
||||||
layout_parent_style: default_values,
|
layout_parent_style: default_values,
|
||||||
// This cloning business is kind of dumb.... It's because Context
|
// This cloning business is kind of dumb.... It's because Context
|
||||||
// insists on having an actual ComputedValues inside itself.
|
// insists on having an actual ComputedValues inside itself.
|
||||||
style: default_values.clone(),
|
style: default_values.clone(),
|
||||||
font_metrics_provider: None
|
font_metrics_provider: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let required_value = match self.value {
|
let required_value = match self.value {
|
||||||
|
|
|
@ -539,7 +539,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
|
|
||||||
// Invoke the cascade algorithm.
|
// Invoke the cascade algorithm.
|
||||||
let values =
|
let values =
|
||||||
Arc::new(cascade(shared_context.viewport_size(),
|
Arc::new(cascade(&shared_context.stylist.device,
|
||||||
rule_node,
|
rule_node,
|
||||||
inherited_values,
|
inherited_values,
|
||||||
layout_parent_style,
|
layout_parent_style,
|
||||||
|
|
|
@ -8,28 +8,24 @@
|
||||||
|
|
||||||
<%helpers:longhand name="color" need_clone="True" animatable="True"
|
<%helpers:longhand name="color" need_clone="True" animatable="True"
|
||||||
spec="https://drafts.csswg.org/css-color/#color">
|
spec="https://drafts.csswg.org/css-color/#color">
|
||||||
use cssparser::Color as CSSParserColor;
|
|
||||||
use cssparser::RGBA;
|
use cssparser::RGBA;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
use values::specified::{CSSColor, CSSRGBA};
|
use values::specified::{Color, CSSColor, CSSRGBA};
|
||||||
|
|
||||||
impl ToComputedValue for SpecifiedValue {
|
impl ToComputedValue for SpecifiedValue {
|
||||||
type ComputedValue = computed_value::T;
|
type ComputedValue = computed_value::T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
||||||
match self.0.parsed {
|
self.0.parsed.to_computed_value(context)
|
||||||
CSSParserColor::RGBA(rgba) => rgba,
|
|
||||||
CSSParserColor::CurrentColor => context.inherited_style.get_color().clone_color(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
fn from_computed_value(computed: &computed_value::T) -> Self {
|
||||||
SpecifiedValue(CSSColor {
|
SpecifiedValue(CSSColor {
|
||||||
parsed: CSSParserColor::RGBA(*computed),
|
parsed: Color::RGBA(*computed),
|
||||||
authored: None,
|
authored: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -792,7 +792,7 @@ ${helpers.single_keyword("text-align-last",
|
||||||
blur_radius: value.blur_radius.to_computed_value(context),
|
blur_radius: value.blur_radius.to_computed_value(context),
|
||||||
color: value.color
|
color: value.color
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|color| color.parsed)
|
.map(|color| color.to_computed_value(context))
|
||||||
.unwrap_or(cssparser::Color::CurrentColor),
|
.unwrap_or(cssparser::Color::CurrentColor),
|
||||||
}
|
}
|
||||||
}).collect())
|
}).collect())
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
additional_methods=[Method("outline_has_nonzero_width", "bool")]) %>
|
additional_methods=[Method("outline_has_nonzero_width", "bool")]) %>
|
||||||
|
|
||||||
// TODO(pcwalton): `invert`
|
// TODO(pcwalton): `invert`
|
||||||
${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor",
|
${helpers.predefined_type("outline-color", "CSSColor", "computed::CSSColor::CurrentColor",
|
||||||
initial_specified_value="specified::CSSColor::currentcolor()",
|
initial_specified_value="specified::CSSColor::currentcolor()",
|
||||||
animatable=True, complex_color=True, need_clone=True,
|
animatable=True, complex_color=True, need_clone=True,
|
||||||
spec="https://drafts.csswg.org/css-ui/#propdef-outline-color")}
|
spec="https://drafts.csswg.org/css-ui/#propdef-outline-color")}
|
||||||
|
|
|
@ -224,7 +224,7 @@ ${helpers.single_keyword("text-decoration-style",
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"text-decoration-color", "CSSColor",
|
"text-decoration-color", "CSSColor",
|
||||||
"::cssparser::Color::CurrentColor",
|
"computed::CSSColor::CurrentColor",
|
||||||
initial_specified_value="specified::CSSColor::currentcolor()",
|
initial_specified_value="specified::CSSColor::currentcolor()",
|
||||||
complex_color=True,
|
complex_color=True,
|
||||||
products="gecko",
|
products="gecko",
|
||||||
|
|
|
@ -21,13 +21,13 @@ use app_units::Au;
|
||||||
use cssparser::{Parser, TokenSerializationType};
|
use cssparser::{Parser, TokenSerializationType};
|
||||||
use error_reporting::ParseErrorReporter;
|
use error_reporting::ParseErrorReporter;
|
||||||
#[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
|
#[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
|
||||||
use euclid::size::Size2D;
|
|
||||||
use computed_values;
|
use computed_values;
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::bindings;
|
#[cfg(feature = "gecko")] use gecko_bindings::bindings;
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID};
|
#[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID};
|
||||||
#[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
|
#[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
|
||||||
use logical_geometry::WritingMode;
|
use logical_geometry::WritingMode;
|
||||||
|
use media_queries::Device;
|
||||||
use parser::{Parse, ParserContext, ParserContextExtraData};
|
use parser::{Parse, ParserContext, ParserContextExtraData};
|
||||||
use properties::animated_properties::TransitionProperty;
|
use properties::animated_properties::TransitionProperty;
|
||||||
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
||||||
|
@ -1793,7 +1793,7 @@ bitflags! {
|
||||||
///
|
///
|
||||||
/// The arguments are:
|
/// The arguments are:
|
||||||
///
|
///
|
||||||
/// * `viewport_size`: The size of the initial viewport.
|
/// * `device`: Used to get the initial viewport and other external state.
|
||||||
///
|
///
|
||||||
/// * `rule_node`: The rule node in the tree that represent the CSS rules that
|
/// * `rule_node`: The rule node in the tree that represent the CSS rules that
|
||||||
/// matched.
|
/// matched.
|
||||||
|
@ -1803,7 +1803,7 @@ bitflags! {
|
||||||
/// Returns the computed values.
|
/// Returns the computed values.
|
||||||
/// * `flags`: Various flags.
|
/// * `flags`: Various flags.
|
||||||
///
|
///
|
||||||
pub fn cascade(viewport_size: Size2D<Au>,
|
pub fn cascade(device: &Device,
|
||||||
rule_node: &StrongRuleNode,
|
rule_node: &StrongRuleNode,
|
||||||
parent_style: Option<<&ComputedValues>,
|
parent_style: Option<<&ComputedValues>,
|
||||||
layout_parent_style: Option<<&ComputedValues>,
|
layout_parent_style: Option<<&ComputedValues>,
|
||||||
|
@ -1836,7 +1836,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
apply_declarations(viewport_size,
|
apply_declarations(device,
|
||||||
is_root_element,
|
is_root_element,
|
||||||
iter_declarations,
|
iter_declarations,
|
||||||
inherited_style,
|
inherited_style,
|
||||||
|
@ -1850,7 +1850,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
|
||||||
|
|
||||||
/// NOTE: This function expects the declaration with more priority to appear
|
/// NOTE: This function expects the declaration with more priority to appear
|
||||||
/// first.
|
/// first.
|
||||||
pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
pub fn apply_declarations<'a, F, I>(device: &Device,
|
||||||
is_root_element: bool,
|
is_root_element: bool,
|
||||||
iter_declarations: F,
|
iter_declarations: F,
|
||||||
inherited_style: &ComputedValues,
|
inherited_style: &ComputedValues,
|
||||||
|
@ -1905,7 +1905,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
||||||
|
|
||||||
let mut context = computed::Context {
|
let mut context = computed::Context {
|
||||||
is_root_element: is_root_element,
|
is_root_element: is_root_element,
|
||||||
viewport_size: viewport_size,
|
device: device,
|
||||||
inherited_style: inherited_style,
|
inherited_style: inherited_style,
|
||||||
layout_parent_style: layout_parent_style,
|
layout_parent_style: layout_parent_style,
|
||||||
style: starting_style,
|
style: starting_style,
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use cssparser::Color;
|
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use values::specified::{BorderStyle, CSSColor};
|
use values::specified::{BorderStyle, Color, CSSColor};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
|
|
@ -10,13 +10,12 @@
|
||||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration">
|
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration">
|
||||||
|
|
||||||
% if product == "gecko" or data.testing:
|
% if product == "gecko" or data.testing:
|
||||||
use cssparser::Color as CSSParserColor;
|
use values::specified;
|
||||||
use properties::longhands::{text_decoration_line, text_decoration_style, text_decoration_color};
|
use properties::longhands::{text_decoration_line, text_decoration_style, text_decoration_color};
|
||||||
% else:
|
% else:
|
||||||
use properties::longhands::text_decoration_line;
|
use properties::longhands::text_decoration_line;
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||||
% if product == "gecko" or data.testing:
|
% if product == "gecko" or data.testing:
|
||||||
let (mut line, mut style, mut color, mut any) = (None, None, None, false);
|
let (mut line, mut style, mut color, mut any) = (None, None, None, false);
|
||||||
|
@ -71,7 +70,7 @@
|
||||||
self.text_decoration_style.to_css(dest)?;
|
self.text_decoration_style.to_css(dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.text_decoration_color.parsed != CSSParserColor::CurrentColor {
|
if self.text_decoration_color.parsed != specified::Color::CurrentColor {
|
||||||
dest.write_str(" ")?;
|
dest.write_str(" ")?;
|
||||||
self.text_decoration_color.to_css(dest)?;
|
self.text_decoration_color.to_css(dest)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl Expression {
|
||||||
let value = viewport_size.width;
|
let value = viewport_size.width;
|
||||||
match self.0 {
|
match self.0 {
|
||||||
ExpressionKind::Width(ref range) => {
|
ExpressionKind::Width(ref range) => {
|
||||||
match range.to_computed_range(viewport_size, device.default_values()) {
|
match range.to_computed_range(device) {
|
||||||
Range::Min(ref width) => { value >= *width },
|
Range::Min(ref width) => { value >= *width },
|
||||||
Range::Max(ref width) => { value <= *width },
|
Range::Max(ref width) => { value <= *width },
|
||||||
Range::Eq(ref width) => { value == *width },
|
Range::Eq(ref width) => { value == *width },
|
||||||
|
@ -170,15 +170,13 @@ pub enum Range<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Range<specified::Length> {
|
impl Range<specified::Length> {
|
||||||
fn to_computed_range(&self,
|
fn to_computed_range(&self, device: &Device) -> Range<Au> {
|
||||||
viewport_size: Size2D<Au>,
|
let default_values = device.default_values();
|
||||||
default_values: &ComputedValues)
|
|
||||||
-> Range<Au> {
|
|
||||||
// http://dev.w3.org/csswg/mediaqueries3/#units
|
// http://dev.w3.org/csswg/mediaqueries3/#units
|
||||||
// em units are relative to the initial font-size.
|
// em units are relative to the initial font-size.
|
||||||
let context = computed::Context {
|
let context = computed::Context {
|
||||||
is_root_element: false,
|
is_root_element: false,
|
||||||
viewport_size: viewport_size,
|
device: device,
|
||||||
inherited_style: default_values,
|
inherited_style: default_values,
|
||||||
layout_parent_style: default_values,
|
layout_parent_style: default_values,
|
||||||
// This cloning business is kind of dumb.... It's because Context
|
// This cloning business is kind of dumb.... It's because Context
|
||||||
|
|
|
@ -325,7 +325,7 @@ impl Stylist {
|
||||||
// the actual used value, and the computed value of it would need
|
// the actual used value, and the computed value of it would need
|
||||||
// blockification.
|
// blockification.
|
||||||
let computed =
|
let computed =
|
||||||
properties::cascade(self.device.au_viewport_size(),
|
properties::cascade(&self.device,
|
||||||
&rule_node,
|
&rule_node,
|
||||||
parent.map(|p| &**p),
|
parent.map(|p| &**p),
|
||||||
parent.map(|p| &**p),
|
parent.map(|p| &**p),
|
||||||
|
@ -410,7 +410,7 @@ impl Stylist {
|
||||||
// (tl;dr: It doesn't apply for replaced elements and such, but the
|
// (tl;dr: It doesn't apply for replaced elements and such, but the
|
||||||
// computed value is still "contents").
|
// computed value is still "contents").
|
||||||
let computed =
|
let computed =
|
||||||
properties::cascade(self.device.au_viewport_size(),
|
properties::cascade(&self.device,
|
||||||
&rule_node,
|
&rule_node,
|
||||||
Some(&**parent),
|
Some(&**parent),
|
||||||
Some(&**parent),
|
Some(&**parent),
|
||||||
|
|
|
@ -250,7 +250,7 @@ impl ToComputedValue for specified::ColorStop {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, context: &Context) -> ColorStop {
|
fn to_computed_value(&self, context: &Context) -> ColorStop {
|
||||||
ColorStop {
|
ColorStop {
|
||||||
color: self.color.parsed,
|
color: self.color.to_computed_value(context),
|
||||||
position: match self.position {
|
position: match self.position {
|
||||||
None => None,
|
None => None,
|
||||||
Some(ref value) => Some(value.to_computed_value(context)),
|
Some(ref value) => Some(value.to_computed_value(context)),
|
||||||
|
|
|
@ -12,7 +12,6 @@ use super::{Number, ToComputedValue, Context};
|
||||||
use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified};
|
use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified};
|
||||||
use values::specified::length::{FontRelativeLength, ViewportPercentageLength};
|
use values::specified::length::{FontRelativeLength, ViewportPercentageLength};
|
||||||
|
|
||||||
pub use cssparser::Color as CSSColor;
|
|
||||||
pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
|
pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image};
|
||||||
pub use super::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
|
pub use super::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
|
||||||
pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone};
|
pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
|
use media_queries::Device;
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
@ -37,8 +38,8 @@ pub struct Context<'a> {
|
||||||
/// Whether the current element is the root element.
|
/// Whether the current element is the root element.
|
||||||
pub is_root_element: bool,
|
pub is_root_element: bool,
|
||||||
|
|
||||||
/// The current viewport size.
|
/// The Device holds the viewport and other external state.
|
||||||
pub viewport_size: Size2D<Au>,
|
pub device: &'a Device,
|
||||||
|
|
||||||
/// The style we're inheriting from.
|
/// The style we're inheriting from.
|
||||||
pub inherited_style: &'a ComputedValues,
|
pub inherited_style: &'a ComputedValues,
|
||||||
|
@ -65,7 +66,7 @@ impl<'a> Context<'a> {
|
||||||
/// Whether the current element is the root element.
|
/// Whether the current element is the root element.
|
||||||
pub fn is_root_element(&self) -> bool { self.is_root_element }
|
pub fn is_root_element(&self) -> bool { self.is_root_element }
|
||||||
/// The current viewport size.
|
/// The current viewport size.
|
||||||
pub fn viewport_size(&self) -> Size2D<Au> { self.viewport_size }
|
pub fn viewport_size(&self) -> Size2D<Au> { self.device.au_viewport_size() }
|
||||||
/// The style we're inheriting from.
|
/// The style we're inheriting from.
|
||||||
pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style }
|
pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style }
|
||||||
/// The current style. Note that only "eager" properties should be accessed
|
/// The current style. Note that only "eager" properties should be accessed
|
||||||
|
@ -113,18 +114,65 @@ impl<T> ToComputedValue for T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for specified::Color {
|
||||||
|
type ComputedValue = RGBA;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gecko"))]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> RGBA {
|
||||||
|
match *self {
|
||||||
|
specified::Color::RGBA(rgba) => rgba,
|
||||||
|
specified::Color::CurrentColor => context.inherited_style.get_color().clone_color(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> RGBA {
|
||||||
|
use gecko::values::convert_nscolor_to_rgba as to_rgba;
|
||||||
|
// It's safe to access the nsPresContext immutably during style computation.
|
||||||
|
let pres_context = unsafe { &*context.device.pres_context };
|
||||||
|
match *self {
|
||||||
|
specified::Color::RGBA(rgba) => rgba,
|
||||||
|
specified::Color::CurrentColor => context.inherited_style.get_color().clone_color(),
|
||||||
|
specified::Color::MozDefaultColor => to_rgba(pres_context.mDefaultColor),
|
||||||
|
specified::Color::MozDefaultBackgroundColor => to_rgba(pres_context.mBackgroundColor),
|
||||||
|
specified::Color::MozHyperlinktext => to_rgba(pres_context.mLinkColor),
|
||||||
|
specified::Color::MozActiveHyperlinktext => to_rgba(pres_context.mActiveLinkColor),
|
||||||
|
specified::Color::MozVisitedHyperlinktext => to_rgba(pres_context.mVisitedLinkColor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_computed_value(computed: &RGBA) -> Self {
|
||||||
|
specified::Color::RGBA(*computed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToComputedValue for specified::CSSColor {
|
impl ToComputedValue for specified::CSSColor {
|
||||||
type ComputedValue = CSSColor;
|
type ComputedValue = CSSColor;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gecko"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_computed_value(&self, _context: &Context) -> CSSColor {
|
fn to_computed_value(&self, _context: &Context) -> CSSColor {
|
||||||
self.parsed
|
self.parsed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> CSSColor {
|
||||||
|
match self.parsed {
|
||||||
|
specified::Color::RGBA(rgba) => CSSColor::RGBA(rgba),
|
||||||
|
specified::Color::CurrentColor => CSSColor::CurrentColor,
|
||||||
|
// Resolve non-standard -moz keywords to RGBA:
|
||||||
|
non_standard => CSSColor::RGBA(non_standard.to_computed_value(context)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &CSSColor) -> Self {
|
fn from_computed_value(computed: &CSSColor) -> Self {
|
||||||
specified::CSSColor {
|
specified::CSSColor {
|
||||||
parsed: *computed,
|
parsed: match *computed {
|
||||||
|
CSSColor::RGBA(rgba) => specified::Color::RGBA(rgba),
|
||||||
|
CSSColor::CurrentColor => specified::Color::CurrentColor,
|
||||||
|
},
|
||||||
authored: None,
|
authored: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
90
components/style/values/specified/color.rs
Normal file
90
components/style/values/specified/color.rs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Non-standard CSS color values
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gecko"))] pub use self::servo::Color;
|
||||||
|
#[cfg(feature = "gecko")] pub use self::gecko::Color;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gecko"))]
|
||||||
|
mod servo {
|
||||||
|
pub use cssparser::Color;
|
||||||
|
use cssparser::Parser;
|
||||||
|
use parser::{Parse, ParserContext};
|
||||||
|
|
||||||
|
impl Parse for Color {
|
||||||
|
fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
Color::parse(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
mod gecko {
|
||||||
|
use cssparser::{Color as CSSParserColor, Parser, RGBA};
|
||||||
|
use parser::{Parse, ParserContext};
|
||||||
|
use std::fmt;
|
||||||
|
use style_traits::ToCss;
|
||||||
|
use values::HasViewportPercentage;
|
||||||
|
|
||||||
|
/// Color value including non-standard -moz prefixed values.
|
||||||
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
|
pub enum Color {
|
||||||
|
/// The 'currentColor' keyword
|
||||||
|
CurrentColor,
|
||||||
|
/// A specific RGBA color
|
||||||
|
RGBA(RGBA),
|
||||||
|
|
||||||
|
/// -moz-default-color
|
||||||
|
MozDefaultColor,
|
||||||
|
/// -moz-default-background-color
|
||||||
|
MozDefaultBackgroundColor,
|
||||||
|
/// -moz-hyperlinktext
|
||||||
|
MozHyperlinktext,
|
||||||
|
/// -moz-activehyperlinktext
|
||||||
|
MozActiveHyperlinktext,
|
||||||
|
/// -moz-visitedhyperlinktext
|
||||||
|
MozVisitedHyperlinktext,
|
||||||
|
}
|
||||||
|
|
||||||
|
no_viewport_percentage!(Color);
|
||||||
|
|
||||||
|
impl Parse for Color {
|
||||||
|
fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
if let Ok(value) = input.try(CSSParserColor::parse) {
|
||||||
|
match value {
|
||||||
|
CSSParserColor::CurrentColor => Ok(Color::CurrentColor),
|
||||||
|
CSSParserColor::RGBA(x) => Ok(Color::RGBA(x)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let ident = input.expect_ident()?;
|
||||||
|
match_ignore_ascii_case! { &ident,
|
||||||
|
"-moz-default-color" => Ok(Color::MozDefaultColor),
|
||||||
|
"-moz-default-background-color" => Ok(Color::MozDefaultBackgroundColor),
|
||||||
|
"-moz-hyperlinktext" => Ok(Color::MozHyperlinktext),
|
||||||
|
"-moz-activehyperlinktext" => Ok(Color::MozActiveHyperlinktext),
|
||||||
|
"-moz-visitedhyperlinktext" => Ok(Color::MozVisitedHyperlinktext),
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for Color {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
match *self {
|
||||||
|
// Standard values:
|
||||||
|
Color::CurrentColor => CSSParserColor::CurrentColor.to_css(dest),
|
||||||
|
Color::RGBA(rgba) => rgba.to_css(dest),
|
||||||
|
|
||||||
|
// Non-standard values:
|
||||||
|
Color::MozDefaultColor => dest.write_str("-moz-default-color"),
|
||||||
|
Color::MozDefaultBackgroundColor => dest.write_str("-moz-default-background-color"),
|
||||||
|
Color::MozHyperlinktext => dest.write_str("-moz-hyperlinktext"),
|
||||||
|
Color::MozActiveHyperlinktext => dest.write_str("-moz-activehyperlinktext"),
|
||||||
|
Color::MozVisitedHyperlinktext => dest.write_str("-moz-visitedhyperlinktext"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,11 +18,12 @@ use std::fmt;
|
||||||
use std::ops::Mul;
|
use std::ops::Mul;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use super::{Auto, CSSFloat, HasViewportPercentage, Either, None_};
|
use super::{Auto, CSSFloat, HasViewportPercentage, Either, None_};
|
||||||
use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
use super::computed::{ComputedValueAsSpecified, Context};
|
||||||
use super::computed::Shadow as ComputedShadow;
|
use super::computed::{Shadow as ComputedShadow, ToComputedValue};
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
|
pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
|
||||||
|
pub use self::color::Color;
|
||||||
pub use self::grid::{GridLine, TrackKeyword};
|
pub use self::grid::{GridLine, TrackKeyword};
|
||||||
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
||||||
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};
|
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};
|
||||||
|
@ -36,6 +37,7 @@ pub use self::position::{HorizontalPosition, Position, VerticalPosition};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub mod align;
|
pub mod align;
|
||||||
pub mod basic_shape;
|
pub mod basic_shape;
|
||||||
|
pub mod color;
|
||||||
pub mod grid;
|
pub mod grid;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
|
@ -48,12 +50,12 @@ no_viewport_percentage!(i32); // For PropertyDeclaration::Order
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub struct CSSColor {
|
pub struct CSSColor {
|
||||||
pub parsed: cssparser::Color,
|
pub parsed: Color,
|
||||||
pub authored: Option<Box<str>>,
|
pub authored: Option<Box<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for CSSColor {
|
impl Parse for CSSColor {
|
||||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
let start_position = input.position();
|
let start_position = input.position();
|
||||||
let authored = match input.next() {
|
let authored = match input.next() {
|
||||||
Ok(Token::Ident(s)) => Some(s.into_owned().into_boxed_str()),
|
Ok(Token::Ident(s)) => Some(s.into_owned().into_boxed_str()),
|
||||||
|
@ -61,7 +63,7 @@ impl Parse for CSSColor {
|
||||||
};
|
};
|
||||||
input.reset(start_position);
|
input.reset(start_position);
|
||||||
Ok(CSSColor {
|
Ok(CSSColor {
|
||||||
parsed: try!(cssparser::Color::parse(input)),
|
parsed: try!(Parse::parse(context, input)),
|
||||||
authored: authored,
|
authored: authored,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -83,7 +85,7 @@ impl CSSColor {
|
||||||
/// Returns currentcolor value.
|
/// Returns currentcolor value.
|
||||||
pub fn currentcolor() -> CSSColor {
|
pub fn currentcolor() -> CSSColor {
|
||||||
CSSColor {
|
CSSColor {
|
||||||
parsed: cssparser::Color::CurrentColor,
|
parsed: Color::CurrentColor,
|
||||||
authored: None,
|
authored: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +94,7 @@ impl CSSColor {
|
||||||
/// Returns transparent value.
|
/// Returns transparent value.
|
||||||
pub fn transparent() -> CSSColor {
|
pub fn transparent() -> CSSColor {
|
||||||
CSSColor {
|
CSSColor {
|
||||||
parsed: cssparser::Color::RGBA(cssparser::RGBA::transparent()),
|
parsed: Color::RGBA(cssparser::RGBA::transparent()),
|
||||||
// This should probably be "transparent", but maybe it doesn't matter.
|
// This should probably be "transparent", but maybe it doesn't matter.
|
||||||
authored: None,
|
authored: None,
|
||||||
}
|
}
|
||||||
|
@ -616,7 +618,7 @@ impl ToComputedValue for Shadow {
|
||||||
spread_radius: self.spread_radius.to_computed_value(context),
|
spread_radius: self.spread_radius.to_computed_value(context),
|
||||||
color: self.color
|
color: self.color
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|color| color.parsed)
|
.map(|color| color.to_computed_value(context))
|
||||||
.unwrap_or(cssparser::Color::CurrentColor),
|
.unwrap_or(cssparser::Color::CurrentColor),
|
||||||
inset: self.inset,
|
inset: self.inset,
|
||||||
}
|
}
|
||||||
|
|
|
@ -687,7 +687,7 @@ impl MaybeNew for ViewportConstraints {
|
||||||
// TODO(emilio): Stop cloning `ComputedValues` around!
|
// TODO(emilio): Stop cloning `ComputedValues` around!
|
||||||
let context = Context {
|
let context = Context {
|
||||||
is_root_element: false,
|
is_root_element: false,
|
||||||
viewport_size: initial_viewport,
|
device: device,
|
||||||
inherited_style: device.default_values(),
|
inherited_style: device.default_values(),
|
||||||
layout_parent_style: device.default_values(),
|
layout_parent_style: device.default_values(),
|
||||||
style: device.default_values().clone(),
|
style: device.default_values().clone(),
|
||||||
|
|
|
@ -1173,9 +1173,8 @@ pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(declarations:
|
||||||
pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations:
|
pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations:
|
||||||
RawServoDeclarationBlockBorrowed,
|
RawServoDeclarationBlockBorrowed,
|
||||||
property: nsCSSPropertyID) {
|
property: nsCSSPropertyID) {
|
||||||
use cssparser::Color;
|
|
||||||
use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId};
|
use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId};
|
||||||
use style::values::specified::CSSColor;
|
use style::values::specified::{Color, CSSColor};
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
|
@ -1195,11 +1194,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations:
|
||||||
RawServoDeclarationBlockBorrowed,
|
RawServoDeclarationBlockBorrowed,
|
||||||
property: nsCSSPropertyID,
|
property: nsCSSPropertyID,
|
||||||
value: structs::nscolor) {
|
value: structs::nscolor) {
|
||||||
use cssparser::Color;
|
|
||||||
use style::gecko::values::convert_nscolor_to_rgba;
|
use style::gecko::values::convert_nscolor_to_rgba;
|
||||||
use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId};
|
use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId};
|
||||||
use style::properties::longhands;
|
use style::properties::longhands;
|
||||||
use style::values::specified::CSSColor;
|
use style::values::specified::{Color, CSSColor};
|
||||||
|
|
||||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let long = get_longhand_from_id!(property);
|
let long = get_longhand_from_id!(property);
|
||||||
|
@ -1444,7 +1442,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
||||||
|
|
||||||
let context = Context {
|
let context = Context {
|
||||||
is_root_element: false,
|
is_root_element: false,
|
||||||
viewport_size: data.stylist.device.au_viewport_size(),
|
device: &data.stylist.device,
|
||||||
inherited_style: parent_style.unwrap_or(default_values),
|
inherited_style: parent_style.unwrap_or(default_values),
|
||||||
layout_parent_style: parent_style.unwrap_or(default_values),
|
layout_parent_style: parent_style.unwrap_or(default_values),
|
||||||
style: (**style).clone(),
|
style: (**style).clone(),
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use app_units::Au;
|
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use euclid::size::Size2D;
|
use euclid::size::TypedSize2D;
|
||||||
use media_queries::CSSErrorReporterTest;
|
use media_queries::CSSErrorReporterTest;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
use style::media_queries::{Device, MediaType};
|
||||||
use style::parser::ParserContext;
|
use style::parser::ParserContext;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::stylesheets::Origin;
|
use style::stylesheets::Origin;
|
||||||
|
@ -43,11 +43,12 @@ fn test_linear_gradient() {
|
||||||
// AngleOrCorner::None should become AngleOrCorner::Angle(Angle(PI)) when parsed
|
// AngleOrCorner::None should become AngleOrCorner::Angle(Angle(PI)) when parsed
|
||||||
// Note that Angle(PI) is correct for top-to-bottom rendering, whereas Angle(0) would render bottom-to-top.
|
// Note that Angle(PI) is correct for top-to-bottom rendering, whereas Angle(0) would render bottom-to-top.
|
||||||
// ref: https://developer.mozilla.org/en-US/docs/Web/CSS/angle
|
// ref: https://developer.mozilla.org/en-US/docs/Web/CSS/angle
|
||||||
let container = Size2D::new(Au::default(), Au::default());
|
let viewport_size = TypedSize2D::new(0., 0.);
|
||||||
let initial_style = ComputedValues::initial_values();
|
let initial_style = ComputedValues::initial_values();
|
||||||
|
let device = Device::new(MediaType::Screen, viewport_size);
|
||||||
let specified_context = Context {
|
let specified_context = Context {
|
||||||
is_root_element: true,
|
is_root_element: true,
|
||||||
viewport_size: container,
|
device: &device,
|
||||||
inherited_style: initial_style,
|
inherited_style: initial_style,
|
||||||
layout_parent_style: initial_style,
|
layout_parent_style: initial_style,
|
||||||
style: initial_style.clone(),
|
style: initial_style.clone(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue