mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #16663 - emilio:style-builder, r=bholley
style: Add a StyleBuilder struct to avoid refcount and atomic CAS during the cascade. This should fix most of the complaints that caused https://bugzilla.mozilla.org/show_bug.cgi?id=1360889 to be open, and also fix a bunch of other FIXMEs across the style system. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16663) <!-- Reviewable:end -->
This commit is contained in:
commit
bf0bf4f4b4
11 changed files with 279 additions and 120 deletions
|
@ -16,7 +16,7 @@ use gecko_bindings::structs::{nsMediaFeature_ValueType, nsMediaFeature_RangeType
|
|||
use gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use media_queries::MediaType;
|
||||
use parser::ParserContext;
|
||||
use properties::ComputedValues;
|
||||
use properties::{ComputedValues, StyleBuilder};
|
||||
use std::fmt::{self, Write};
|
||||
use std::sync::Arc;
|
||||
use str::starts_with_ignore_ascii_case;
|
||||
|
@ -552,6 +552,7 @@ impl Expression {
|
|||
|
||||
let default_values = device.default_computed_values();
|
||||
|
||||
|
||||
let provider = get_metrics_provider_for_product();
|
||||
|
||||
// http://dev.w3.org/csswg/mediaqueries3/#units
|
||||
|
@ -561,10 +562,9 @@ impl Expression {
|
|||
device: device,
|
||||
inherited_style: default_values,
|
||||
layout_parent_style: default_values,
|
||||
// This cloning business is kind of dumb.... It's because Context
|
||||
// insists on having an actual ComputedValues inside itself.
|
||||
style: default_values.clone(),
|
||||
style: StyleBuilder::for_derived_style(default_values),
|
||||
font_metrics_provider: &provider,
|
||||
cached_system_font: None,
|
||||
in_media_query: true,
|
||||
// TODO: pass the correct value here.
|
||||
quirks_mode: quirks_mode,
|
||||
|
|
|
@ -102,32 +102,13 @@ pub struct ComputedValues {
|
|||
}
|
||||
|
||||
impl ComputedValues {
|
||||
/// Inherits style from the parent element, accounting for the default
|
||||
/// computed values that need to be provided as well.
|
||||
pub fn inherit_from(parent: &Self, default: &Self) -> Self {
|
||||
ComputedValues {
|
||||
custom_properties: parent.custom_properties.clone(),
|
||||
writing_mode: parent.writing_mode,
|
||||
root_font_size: parent.root_font_size,
|
||||
font_size_keyword: parent.font_size_keyword,
|
||||
cached_system_font: None,
|
||||
% for style_struct in data.style_structs:
|
||||
% if style_struct.inherited:
|
||||
${style_struct.ident}: parent.${style_struct.ident}.clone(),
|
||||
% else:
|
||||
${style_struct.ident}: default.${style_struct.ident}.clone(),
|
||||
% endif
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
|
||||
writing_mode: WritingMode,
|
||||
root_font_size: Au,
|
||||
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
||||
% for style_struct in data.style_structs:
|
||||
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
|
||||
% endfor
|
||||
writing_mode: WritingMode,
|
||||
root_font_size: Au,
|
||||
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
||||
% for style_struct in data.style_structs:
|
||||
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
|
||||
% endfor
|
||||
) -> Self {
|
||||
ComputedValues {
|
||||
custom_properties: custom_properties,
|
||||
|
@ -168,6 +149,11 @@ impl ComputedValues {
|
|||
pub fn get_${style_struct.name_lower}(&self) -> &style_structs::${style_struct.name} {
|
||||
&self.${style_struct.ident}
|
||||
}
|
||||
|
||||
pub fn ${style_struct.name_lower}_arc(&self) -> &Arc<style_structs::${style_struct.name}> {
|
||||
&self.${style_struct.ident}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
|
||||
Arc::make_mut(&mut self.${style_struct.ident})
|
||||
|
@ -175,7 +161,7 @@ impl ComputedValues {
|
|||
% endfor
|
||||
|
||||
pub fn custom_properties(&self) -> Option<Arc<ComputedValuesMap>> {
|
||||
self.custom_properties.as_ref().map(|x| x.clone())
|
||||
self.custom_properties.clone()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -183,12 +169,6 @@ impl ComputedValues {
|
|||
!self.get_box().gecko.mBinding.mPtr.mRawPtr.is_null()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn in_top_layer(&self) -> bool {
|
||||
matches!(self.get_box().clone__moz_top_layer(),
|
||||
longhands::_moz_top_layer::SpecifiedValue::top)
|
||||
}
|
||||
|
||||
// FIXME(bholley): Implement this properly.
|
||||
#[inline]
|
||||
pub fn is_multicol(&self) -> bool { false }
|
||||
|
|
|
@ -478,7 +478,7 @@
|
|||
SpecifiedValue::Keyword(v) => v,
|
||||
SpecifiedValue::System(_) => {
|
||||
% if product == "gecko":
|
||||
_cx.style.cached_system_font.as_ref().unwrap().${to_rust_ident(name)}
|
||||
_cx.cached_system_font.as_ref().unwrap().${to_rust_ident(name)}
|
||||
% else:
|
||||
unreachable!()
|
||||
% endif
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
SpecifiedValue::Value(v) => v,
|
||||
SpecifiedValue::System(_) => {
|
||||
<%self:nongecko_unreachable>
|
||||
_context.style.cached_system_font.as_ref().unwrap().${name}
|
||||
_context.cached_system_font.as_ref().unwrap().${name}
|
||||
</%self:nongecko_unreachable>
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +270,7 @@
|
|||
SpecifiedValue::Values(ref v) => computed_value::T(v.clone()),
|
||||
SpecifiedValue::System(_) => {
|
||||
<%self:nongecko_unreachable>
|
||||
_cx.style.cached_system_font.as_ref().unwrap().font_family.clone()
|
||||
_cx.cached_system_font.as_ref().unwrap().font_family.clone()
|
||||
</%self:nongecko_unreachable>
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
},
|
||||
SpecifiedValue::System(_) => {
|
||||
<%self:nongecko_unreachable>
|
||||
context.style.cached_system_font.as_ref().unwrap().font_weight.clone()
|
||||
context.cached_system_font.as_ref().unwrap().font_weight.clone()
|
||||
</%self:nongecko_unreachable>
|
||||
}
|
||||
}
|
||||
|
@ -809,7 +809,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
|
||||
SpecifiedValue::System(_) => {
|
||||
<%self:nongecko_unreachable>
|
||||
context.style.cached_system_font.as_ref().unwrap().font_size
|
||||
context.cached_system_font.as_ref().unwrap().font_size
|
||||
</%self:nongecko_unreachable>
|
||||
}
|
||||
}
|
||||
|
@ -982,7 +982,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
SpecifiedValue::Number(ref n) => computed_value::T::Number(n.to_computed_value(context)),
|
||||
SpecifiedValue::System(_) => {
|
||||
<%self:nongecko_unreachable>
|
||||
context.style.cached_system_font.as_ref().unwrap().font_size_adjust
|
||||
context.cached_system_font.as_ref().unwrap().font_size_adjust
|
||||
</%self:nongecko_unreachable>
|
||||
}
|
||||
}
|
||||
|
@ -1966,7 +1966,7 @@ ${helpers.single_keyword_system("font-variant-position",
|
|||
}
|
||||
SpecifiedValue::System(_) => {
|
||||
<%self:nongecko_unreachable>
|
||||
_context.style.cached_system_font.as_ref().unwrap().font_language_override
|
||||
_context.cached_system_font.as_ref().unwrap().font_language_override
|
||||
</%self:nongecko_unreachable>
|
||||
}
|
||||
}
|
||||
|
@ -2365,11 +2365,11 @@ ${helpers.single_keyword("-moz-math-variant",
|
|||
/// Must be called before attempting to compute a system font
|
||||
/// specified value
|
||||
pub fn resolve_system_font(system: SystemFont, context: &mut Context) {
|
||||
if context.style.cached_system_font.is_none() {
|
||||
if context.cached_system_font.is_none() {
|
||||
let computed = system.to_computed_value(context);
|
||||
context.style.cached_system_font = Some(computed);
|
||||
context.cached_system_font = Some(computed);
|
||||
}
|
||||
debug_assert!(system == context.style.cached_system_font.as_ref().unwrap().system_font)
|
||||
debug_assert!(system == context.cached_system_font.as_ref().unwrap().system_font)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
use app_units::Au;
|
||||
|
@ -1725,6 +1726,12 @@ impl ComputedValues {
|
|||
&self.${style_struct.ident}
|
||||
}
|
||||
|
||||
/// Gets an immutable reference to the refcounted value that wraps
|
||||
/// `${style_struct.name}`.
|
||||
pub fn ${style_struct.name_lower}_arc(&self) -> &Arc<style_structs::${style_struct.name}> {
|
||||
&self.${style_struct.ident}
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the ${style_struct.name} struct.
|
||||
#[inline]
|
||||
pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
|
||||
|
@ -1737,18 +1744,13 @@ impl ComputedValues {
|
|||
/// Cloning the Arc here is fine because it only happens in the case where
|
||||
/// we have custom properties, and those are both rare and expensive.
|
||||
fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> {
|
||||
self.custom_properties.as_ref().map(|x| x.clone())
|
||||
self.custom_properties.clone()
|
||||
}
|
||||
|
||||
/// Whether this style has a -moz-binding value. This is always false for
|
||||
/// Servo for obvious reasons.
|
||||
pub fn has_moz_binding(&self) -> bool { false }
|
||||
|
||||
/// Whether this style has a top-layer style. That's implemented in Gecko
|
||||
/// via the -moz-top-layer property, but servo doesn't have any concept of a
|
||||
/// top layer (yet, it's needed for fullscreen).
|
||||
pub fn in_top_layer(&self) -> bool { false }
|
||||
|
||||
/// Returns whether this style's display value is equal to contents.
|
||||
///
|
||||
/// Since this isn't supported in Servo, this is always false for Servo.
|
||||
|
@ -1967,22 +1969,6 @@ impl ComputedValues {
|
|||
}
|
||||
}
|
||||
|
||||
impl ComputedValues {
|
||||
/// Returns whether this computed style represents a floated object.
|
||||
pub fn floated(&self) -> bool {
|
||||
self.get_box().clone_float() != longhands::float::computed_value::T::none
|
||||
}
|
||||
|
||||
/// Returns whether this computed style represents an out of flow-positioned
|
||||
/// object.
|
||||
pub fn out_of_flow_positioned(&self) -> bool {
|
||||
use properties::longhands::position::computed_value::T as position;
|
||||
matches!(self.get_box().clone_position(),
|
||||
position::absolute | position::fixed)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Return a WritingMode bitflags from the relevant CSS properties.
|
||||
pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> WritingMode {
|
||||
use logical_geometry;
|
||||
|
@ -2034,6 +2020,176 @@ pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> Wri
|
|||
flags
|
||||
}
|
||||
|
||||
/// A reference to a style struct of the parent, or our own style struct.
|
||||
pub enum StyleStructRef<'a, T: 'a> {
|
||||
/// A borrowed struct from the parent, for example, for inheriting style.
|
||||
Borrowed(&'a Arc<T>),
|
||||
/// An owned struct, that we've already mutated.
|
||||
Owned(T),
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> StyleStructRef<'a, T>
|
||||
where T: Clone,
|
||||
{
|
||||
/// Ensure a mutable reference of this value exists, either cloning the
|
||||
/// borrowed value, or returning the owned one.
|
||||
pub fn mutate(&mut self) -> &mut T {
|
||||
if let StyleStructRef::Borrowed(v) = *self {
|
||||
*self = StyleStructRef::Owned((**v).clone());
|
||||
}
|
||||
|
||||
match *self {
|
||||
StyleStructRef::Owned(ref mut v) => v,
|
||||
StyleStructRef::Borrowed(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an `Arc` to the internal struct, constructing one if
|
||||
/// appropriate.
|
||||
pub fn build(self) -> Arc<T> {
|
||||
match self {
|
||||
StyleStructRef::Owned(v) => Arc::new(v),
|
||||
StyleStructRef::Borrowed(v) => v.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> Deref for StyleStructRef<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
match *self {
|
||||
StyleStructRef::Owned(ref v) => v,
|
||||
StyleStructRef::Borrowed(v) => &**v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A type used to compute a struct with minimal overhead.
|
||||
///
|
||||
/// This allows holding references to the parent/default computed values without
|
||||
/// actually cloning them, until we either build the style, or mutate the
|
||||
/// inherited value.
|
||||
pub struct StyleBuilder<'a> {
|
||||
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
|
||||
/// The writing mode flags.
|
||||
///
|
||||
/// TODO(emilio): Make private.
|
||||
pub writing_mode: WritingMode,
|
||||
/// The font size of the root element.
|
||||
pub root_font_size: Au,
|
||||
/// The keyword behind the current font-size property, if any.
|
||||
pub font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
||||
% for style_struct in data.active_style_structs():
|
||||
${style_struct.ident}: StyleStructRef<'a, style_structs::${style_struct.name}>,
|
||||
% endfor
|
||||
}
|
||||
|
||||
impl<'a> StyleBuilder<'a> {
|
||||
/// Trivially construct a `StyleBuilder`.
|
||||
pub fn new(
|
||||
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
|
||||
writing_mode: WritingMode,
|
||||
root_font_size: Au,
|
||||
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
||||
% for style_struct in data.active_style_structs():
|
||||
${style_struct.ident}: &'a Arc<style_structs::${style_struct.name}>,
|
||||
% endfor
|
||||
) -> Self {
|
||||
StyleBuilder {
|
||||
custom_properties: custom_properties,
|
||||
writing_mode: writing_mode,
|
||||
root_font_size: root_font_size,
|
||||
font_size_keyword: font_size_keyword,
|
||||
% for style_struct in data.active_style_structs():
|
||||
${style_struct.ident}: StyleStructRef::Borrowed(${style_struct.ident}),
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a StyleBuilder holding only references to the structs of `s`, in
|
||||
/// order to create a derived style.
|
||||
pub fn for_derived_style(s: &'a ComputedValues) -> Self {
|
||||
Self::for_inheritance(s, s)
|
||||
}
|
||||
|
||||
/// Inherits style from the parent element, accounting for the default
|
||||
/// computed values that need to be provided as well.
|
||||
pub fn for_inheritance(parent: &'a ComputedValues, default: &'a ComputedValues) -> Self {
|
||||
Self::new(parent.custom_properties(),
|
||||
parent.writing_mode,
|
||||
parent.root_font_size,
|
||||
parent.font_size_keyword,
|
||||
% for style_struct in data.active_style_structs():
|
||||
% if style_struct.inherited:
|
||||
parent.${style_struct.name_lower}_arc(),
|
||||
% else:
|
||||
default.${style_struct.name_lower}_arc(),
|
||||
% endif
|
||||
% endfor
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
% for style_struct in data.active_style_structs():
|
||||
/// Gets an immutable view of the current `${style_struct.name}` style.
|
||||
pub fn get_${style_struct.name_lower}(&self) -> &style_structs::${style_struct.name} {
|
||||
&self.${style_struct.ident}
|
||||
}
|
||||
|
||||
/// Gets a mutable view of the current `${style_struct.name}` style.
|
||||
pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
|
||||
self.${style_struct.ident}.mutate()
|
||||
}
|
||||
% endfor
|
||||
|
||||
/// Returns whether this computed style represents a floated object.
|
||||
pub fn floated(&self) -> bool {
|
||||
self.get_box().clone_float() != longhands::float::computed_value::T::none
|
||||
}
|
||||
|
||||
/// Returns whether this computed style represents an out of flow-positioned
|
||||
/// object.
|
||||
pub fn out_of_flow_positioned(&self) -> bool {
|
||||
use properties::longhands::position::computed_value::T as position;
|
||||
matches!(self.get_box().clone_position(),
|
||||
position::absolute | position::fixed)
|
||||
}
|
||||
|
||||
/// Whether this style has a top-layer style. That's implemented in Gecko
|
||||
/// via the -moz-top-layer property, but servo doesn't have any concept of a
|
||||
/// top layer (yet, it's needed for fullscreen).
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn in_top_layer(&self) -> bool { false }
|
||||
|
||||
/// Whether this style has a top-layer style.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn in_top_layer(&self) -> bool {
|
||||
matches!(self.get_box().clone__moz_top_layer(),
|
||||
longhands::_moz_top_layer::computed_value::T::top)
|
||||
}
|
||||
|
||||
|
||||
/// Turns this `StyleBuilder` into a proper `ComputedValues` instance.
|
||||
pub fn build(self) -> ComputedValues {
|
||||
ComputedValues::new(self.custom_properties,
|
||||
self.writing_mode,
|
||||
self.root_font_size,
|
||||
self.font_size_keyword,
|
||||
% for style_struct in data.active_style_structs():
|
||||
self.${style_struct.ident}.build(),
|
||||
% endfor
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the custom properties map if necessary.
|
||||
///
|
||||
/// Cloning the Arc here is fine because it only happens in the case where
|
||||
/// we have custom properties, and those are both rare and expensive.
|
||||
fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> {
|
||||
self.custom_properties.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
pub use self::lazy_static_module::INITIAL_SERVO_VALUES;
|
||||
|
@ -2202,28 +2358,28 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
|||
::custom_properties::finish_cascade(
|
||||
custom_properties, &inherited_custom_properties);
|
||||
|
||||
let starting_style = if !flags.contains(INHERIT_ALL) {
|
||||
ComputedValues::new(custom_properties,
|
||||
WritingMode::empty(),
|
||||
inherited_style.root_font_size,
|
||||
inherited_style.font_size_keyword,
|
||||
% for style_struct in data.active_style_structs():
|
||||
% if style_struct.inherited:
|
||||
inherited_style.clone_${style_struct.name_lower}(),
|
||||
% else:
|
||||
default_style.clone_${style_struct.name_lower}(),
|
||||
% endif
|
||||
% endfor
|
||||
)
|
||||
let builder = if !flags.contains(INHERIT_ALL) {
|
||||
StyleBuilder::new(custom_properties,
|
||||
WritingMode::empty(),
|
||||
inherited_style.root_font_size,
|
||||
inherited_style.font_size_keyword,
|
||||
% for style_struct in data.active_style_structs():
|
||||
% if style_struct.inherited:
|
||||
inherited_style.${style_struct.name_lower}_arc(),
|
||||
% else:
|
||||
default_style.${style_struct.name_lower}_arc(),
|
||||
% endif
|
||||
% endfor
|
||||
)
|
||||
} else {
|
||||
ComputedValues::new(custom_properties,
|
||||
WritingMode::empty(),
|
||||
inherited_style.root_font_size,
|
||||
inherited_style.font_size_keyword,
|
||||
% for style_struct in data.active_style_structs():
|
||||
inherited_style.clone_${style_struct.name_lower}(),
|
||||
% endfor
|
||||
)
|
||||
StyleBuilder::new(custom_properties,
|
||||
WritingMode::empty(),
|
||||
inherited_style.root_font_size,
|
||||
inherited_style.font_size_keyword,
|
||||
% for style_struct in data.active_style_structs():
|
||||
inherited_style.${style_struct.name_lower}_arc(),
|
||||
% endfor
|
||||
)
|
||||
};
|
||||
|
||||
let mut context = computed::Context {
|
||||
|
@ -2231,8 +2387,9 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
|||
device: device,
|
||||
inherited_style: inherited_style,
|
||||
layout_parent_style: layout_parent_style,
|
||||
style: starting_style,
|
||||
style: builder,
|
||||
font_metrics_provider: font_metrics_provider,
|
||||
cached_system_font: None,
|
||||
in_media_query: false,
|
||||
quirks_mode: quirks_mode,
|
||||
};
|
||||
|
@ -2382,9 +2539,11 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
|||
|
||||
let mut style = context.style;
|
||||
|
||||
StyleAdjuster::new(&mut style, is_root_element)
|
||||
.adjust(context.layout_parent_style,
|
||||
flags.contains(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP));
|
||||
{
|
||||
StyleAdjuster::new(&mut style, is_root_element)
|
||||
.adjust(context.layout_parent_style,
|
||||
flags.contains(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP));
|
||||
}
|
||||
|
||||
% if product == "gecko":
|
||||
// FIXME(emilio): This is effectively creating a new nsStyleBackground
|
||||
|
@ -2408,12 +2567,12 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
|||
}
|
||||
% endif
|
||||
|
||||
style
|
||||
style.build()
|
||||
}
|
||||
|
||||
|
||||
/// See StyleAdjuster::adjust_for_border_width.
|
||||
pub fn adjust_border_width(style: &mut ComputedValues) {
|
||||
pub fn adjust_border_width(style: &mut StyleBuilder) {
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
// Like calling to_computed_value, which wouldn't type check.
|
||||
if style.get_border().clone_border_${side}_style().none_or_hidden() &&
|
||||
|
|
|
@ -11,7 +11,7 @@ use euclid::{Size2D, TypedSize2D};
|
|||
use font_metrics::ServoMetricsProvider;
|
||||
use media_queries::MediaType;
|
||||
use parser::ParserContext;
|
||||
use properties::ComputedValues;
|
||||
use properties::{ComputedValues, StyleBuilder};
|
||||
use std::fmt;
|
||||
use style_traits::{CSSPixel, ToCss};
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
|
@ -185,14 +185,13 @@ impl Range<specified::Length> {
|
|||
device: device,
|
||||
inherited_style: default_values,
|
||||
layout_parent_style: default_values,
|
||||
// This cloning business is kind of dumb.... It's because Context
|
||||
// insists on having an actual ComputedValues inside itself.
|
||||
style: default_values.clone(),
|
||||
style: StyleBuilder::for_derived_style(default_values),
|
||||
// Servo doesn't support font metrics
|
||||
// A real provider will be needed here once we do; since
|
||||
// ch units can exist in media queries.
|
||||
font_metrics_provider: &ServoMetricsProvider,
|
||||
in_media_query: true,
|
||||
cached_system_font: None,
|
||||
quirks_mode: quirks_mode,
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
//! for it to adhere to the CSS spec.
|
||||
|
||||
use app_units::Au;
|
||||
use properties::{self, ComputedValues};
|
||||
use properties::{self, ComputedValues, StyleBuilder};
|
||||
use properties::longhands::display::computed_value::T as display;
|
||||
use properties::longhands::float::computed_value::T as float;
|
||||
use properties::longhands::overflow_x::computed_value::T as overflow;
|
||||
|
@ -14,14 +14,14 @@ use properties::longhands::position::computed_value::T as position;
|
|||
|
||||
|
||||
/// An unsized struct that implements all the adjustment methods.
|
||||
pub struct StyleAdjuster<'a> {
|
||||
style: &'a mut ComputedValues,
|
||||
pub struct StyleAdjuster<'a, 'b: 'a> {
|
||||
style: &'a mut StyleBuilder<'b>,
|
||||
is_root_element: bool,
|
||||
}
|
||||
|
||||
impl<'a> StyleAdjuster<'a> {
|
||||
impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||
/// Trivially constructs a new StyleAdjuster.
|
||||
pub fn new(style: &'a mut ComputedValues, is_root_element: bool) -> Self {
|
||||
pub fn new(style: &'a mut StyleBuilder<'b>, is_root_element: bool) -> Self {
|
||||
StyleAdjuster {
|
||||
style: style,
|
||||
is_root_element: is_root_element,
|
||||
|
@ -264,7 +264,7 @@ impl<'a> StyleAdjuster<'a> {
|
|||
///
|
||||
/// When comparing to Gecko, this is similar to the work done by
|
||||
/// `nsStyleContext::ApplyStyleFixups`.
|
||||
pub fn adjust(mut self,
|
||||
pub fn adjust(&mut self,
|
||||
layout_parent_style: &ComputedValues,
|
||||
skip_root_and_element_display_fixup: bool) {
|
||||
self.adjust_for_top_layer();
|
||||
|
|
|
@ -8,7 +8,9 @@ use context::QuirksMode;
|
|||
use euclid::size::Size2D;
|
||||
use font_metrics::FontMetricsProvider;
|
||||
use media_queries::Device;
|
||||
use properties::ComputedValues;
|
||||
#[cfg(feature = "gecko")]
|
||||
use properties;
|
||||
use properties::{ComputedValues, StyleBuilder};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use super::{CSSFloat, CSSInteger, RGBA};
|
||||
|
@ -53,10 +55,23 @@ pub struct Context<'a> {
|
|||
/// isn't `contents`.
|
||||
pub layout_parent_style: &'a ComputedValues,
|
||||
|
||||
/// Values access through this need to be in the properties "computed
|
||||
/// Values accessed through this need to be in the properties "computed
|
||||
/// early": color, text-decoration, font-size, display, position, float,
|
||||
/// border-*-style, outline-style, font-family, writing-mode...
|
||||
pub style: ComputedValues,
|
||||
pub style: StyleBuilder<'a>,
|
||||
|
||||
/// A cached computed system font value, for use by gecko.
|
||||
///
|
||||
/// See properties/longhands/font.mako.rs
|
||||
#[cfg(feature = "gecko")]
|
||||
pub cached_system_font: Option<properties::longhands::system_font::ComputedSystemFont>,
|
||||
|
||||
/// A dummy option for servo so initializing a computed::Context isn't
|
||||
/// painful.
|
||||
///
|
||||
/// TODO(emilio): Make constructors for Context, and drop this.
|
||||
#[cfg(feature = "servo")]
|
||||
pub cached_system_font: Option<()>,
|
||||
|
||||
/// A font metrics provider, used to access font metrics to implement
|
||||
/// font-relative units.
|
||||
|
@ -78,9 +93,9 @@ impl<'a> Context<'a> {
|
|||
pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style }
|
||||
/// The current style. Note that only "eager" properties should be accessed
|
||||
/// from here, see the comment in the member.
|
||||
pub fn style(&self) -> &ComputedValues { &self.style }
|
||||
pub fn style(&self) -> &StyleBuilder { &self.style }
|
||||
/// A mutable reference to the current style.
|
||||
pub fn mutate_style(&mut self) -> &mut ComputedValues { &mut self.style }
|
||||
pub fn mutate_style(&mut self) -> &mut StyleBuilder<'a> { &mut self.style }
|
||||
}
|
||||
|
||||
/// A trait to represent the conversion between computed and specified values.
|
||||
|
|
|
@ -17,6 +17,7 @@ use euclid::size::TypedSize2D;
|
|||
use font_metrics::get_metrics_provider_for_product;
|
||||
use media_queries::Device;
|
||||
use parser::{Parse, ParserContext, log_css_error};
|
||||
use properties::StyleBuilder;
|
||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::Cow;
|
||||
|
@ -678,14 +679,17 @@ impl MaybeNew for ViewportConstraints {
|
|||
|
||||
let provider = get_metrics_provider_for_product();
|
||||
|
||||
let default_values = device.default_computed_values();
|
||||
|
||||
// TODO(emilio): Stop cloning `ComputedValues` around!
|
||||
let context = Context {
|
||||
is_root_element: false,
|
||||
device: device,
|
||||
inherited_style: device.default_computed_values(),
|
||||
layout_parent_style: device.default_computed_values(),
|
||||
style: device.default_computed_values().clone(),
|
||||
inherited_style: default_values,
|
||||
layout_parent_style: default_values,
|
||||
style: StyleBuilder::for_derived_style(default_values),
|
||||
font_metrics_provider: &provider,
|
||||
cached_system_font: None,
|
||||
in_media_query: false,
|
||||
quirks_mode: quirks_mode,
|
||||
};
|
||||
|
|
|
@ -72,7 +72,7 @@ use style::keyframes::KeyframesStepValue;
|
|||
use style::media_queries::{MediaList, parse_media_query_list};
|
||||
use style::parallel;
|
||||
use style::parser::{LengthParsingMode, ParserContext};
|
||||
use style::properties::{CascadeFlags, ComputedValues, Importance, ParsedDeclaration};
|
||||
use style::properties::{CascadeFlags, ComputedValues, Importance, ParsedDeclaration, StyleBuilder};
|
||||
use style::properties::{PropertyDeclarationBlock, PropertyId};
|
||||
use style::properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
|
||||
use style::properties::animated_properties::{AnimationValue, ComputeDistance, Interpolate, TransitionProperty};
|
||||
|
@ -1002,14 +1002,14 @@ pub extern "C" fn Servo_ComputedValues_Inherit(
|
|||
let for_text = target == structs::InheritTarget::Text;
|
||||
let style = if let Some(reference) = maybe_arc.as_ref() {
|
||||
let mut style =
|
||||
ComputedValues::inherit_from(reference,
|
||||
&data.default_computed_values());
|
||||
StyleBuilder::for_inheritance(reference,
|
||||
&data.default_computed_values());
|
||||
if for_text {
|
||||
StyleAdjuster::new(&mut style, /* is_root = */ false)
|
||||
.adjust_for_text();
|
||||
}
|
||||
|
||||
Arc::new(style)
|
||||
Arc::new(style.build())
|
||||
} else {
|
||||
debug_assert!(!for_text);
|
||||
data.default_computed_values().clone()
|
||||
|
@ -2002,8 +2002,9 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
|||
device: &data.stylist.device,
|
||||
inherited_style: parent_style.unwrap_or(default_values),
|
||||
layout_parent_style: parent_style.unwrap_or(default_values),
|
||||
style: (**style).clone(),
|
||||
style: StyleBuilder::for_derived_style(&style),
|
||||
font_metrics_provider: &metrics,
|
||||
cached_system_font: None,
|
||||
in_media_query: false,
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::f32::consts::PI;
|
|||
use style::context::QuirksMode;
|
||||
use style::font_metrics::ServoMetricsProvider;
|
||||
use style::media_queries::{Device, MediaType};
|
||||
use style::properties::ComputedValues;
|
||||
use style::properties::{ComputedValues, StyleBuilder};
|
||||
use style::values::computed;
|
||||
use style::values::computed::{Angle, Context, ToComputedValue};
|
||||
use style::values::specified;
|
||||
|
@ -49,7 +49,8 @@ fn test_linear_gradient() {
|
|||
device: &device,
|
||||
inherited_style: initial_style,
|
||||
layout_parent_style: initial_style,
|
||||
style: initial_style.clone(),
|
||||
style: StyleBuilder::for_derived_style(&initial_style),
|
||||
cached_system_font: None,
|
||||
font_metrics_provider: &ServoMetricsProvider,
|
||||
in_media_query: false,
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue