mirror of
https://github.com/servo/servo.git
synced 2025-06-24 17:14:33 +01:00
style: Cleanup duplicated code in the definition of ComputedValues.
This commit is contained in:
parent
5c7632f4c4
commit
1c2fcb16ca
2 changed files with 101 additions and 168 deletions
|
@ -11,7 +11,6 @@
|
|||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
use app_units::Au;
|
||||
use custom_properties::ComputedValuesMap;
|
||||
use gecko_bindings::bindings;
|
||||
% for style_struct in data.style_structs:
|
||||
use gecko_bindings::structs::${style_struct.gecko_ffi_name};
|
||||
|
@ -54,17 +53,14 @@ use gecko::values::round_border_to_device_pixels;
|
|||
use logical_geometry::WritingMode;
|
||||
use media_queries::Device;
|
||||
use properties::animated_properties::TransitionProperty;
|
||||
use properties::computed_value_flags::ComputedValueFlags;
|
||||
use properties::{longhands, FontComputationData, Importance, LonghandId};
|
||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
|
||||
use rule_tree::StrongRuleNode;
|
||||
use properties::{longhands, ComputedValues, LonghandId, PropertyDeclarationId};
|
||||
use std::fmt::{self, Debug};
|
||||
use std::mem::{forget, transmute, zeroed};
|
||||
use std::ptr;
|
||||
use stylearc::Arc;
|
||||
use std::cmp;
|
||||
use values::{Auto, CustomIdent, Either, KeyframesName};
|
||||
use values::computed::{Shadow, ToComputedValue};
|
||||
use values::computed::Shadow;
|
||||
use values::specified::length::Percentage;
|
||||
use computed_values::border_style;
|
||||
|
||||
|
@ -74,157 +70,6 @@ pub mod style_structs {
|
|||
% endfor
|
||||
}
|
||||
|
||||
// FIXME(emilio): Unify both definitions, since they're equal now.
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedValues {
|
||||
% for style_struct in data.style_structs:
|
||||
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
|
||||
% endfor
|
||||
custom_properties: Option<Arc<ComputedValuesMap>>,
|
||||
pub writing_mode: WritingMode,
|
||||
pub font_computation_data: FontComputationData,
|
||||
pub flags: ComputedValueFlags,
|
||||
|
||||
/// The rule node representing the ordered list of rules matched for this
|
||||
/// node. Can be None for default values and text nodes. This is
|
||||
/// essentially an optimization to avoid referencing the root rule node.
|
||||
pub rules: Option<StrongRuleNode>,
|
||||
/// The element's computed values if visited, only computed if there's a
|
||||
/// relevant link for this element. A element's "relevant link" is the
|
||||
/// element being matched if it is a link or the nearest ancestor link.
|
||||
visited_style: Option<Arc<ComputedValues>>,
|
||||
}
|
||||
|
||||
impl ComputedValues {
|
||||
pub fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
|
||||
writing_mode: WritingMode,
|
||||
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
|
||||
flags: ComputedValueFlags,
|
||||
rules: Option<StrongRuleNode>,
|
||||
visited_style: Option<Arc<ComputedValues>>,
|
||||
% for style_struct in data.style_structs:
|
||||
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
|
||||
% endfor
|
||||
) -> Self {
|
||||
ComputedValues {
|
||||
custom_properties,
|
||||
writing_mode,
|
||||
font_computation_data: FontComputationData::new(font_size_keyword),
|
||||
flags,
|
||||
rules,
|
||||
visited_style: visited_style,
|
||||
% for style_struct in data.style_structs:
|
||||
${style_struct.ident},
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
|
||||
Arc::new(ComputedValues {
|
||||
custom_properties: None,
|
||||
writing_mode: WritingMode::empty(), // FIXME(bz): This seems dubious
|
||||
font_computation_data: FontComputationData::default_values(),
|
||||
rules: None,
|
||||
visited_style: None,
|
||||
% for style_struct in data.style_structs:
|
||||
${style_struct.ident}: style_structs::${style_struct.name}::default(pres_context),
|
||||
% endfor
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_display_contents(&self) -> bool {
|
||||
self.get_box().clone_display() == longhands::display::computed_value::T::contents
|
||||
}
|
||||
|
||||
/// Returns true if the value of the `content` property would make a
|
||||
/// pseudo-element not rendered.
|
||||
#[inline]
|
||||
pub fn ineffective_content_property(&self) -> bool {
|
||||
self.get_counters().ineffective_content_property()
|
||||
}
|
||||
|
||||
% for style_struct in data.style_structs:
|
||||
#[inline]
|
||||
pub fn clone_${style_struct.name_lower}(&self) -> Arc<style_structs::${style_struct.name}> {
|
||||
self.${style_struct.ident}.clone()
|
||||
}
|
||||
#[inline]
|
||||
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})
|
||||
}
|
||||
% endfor
|
||||
|
||||
/// Gets a reference to the rule node. Panic if no rule node exists.
|
||||
pub fn rules(&self) -> &StrongRuleNode {
|
||||
self.rules.as_ref().unwrap()
|
||||
}
|
||||
|
||||
/// Gets a reference to the visited style, if any.
|
||||
pub fn get_visited_style(&self) -> Option<<&Arc<ComputedValues>> {
|
||||
self.visited_style.as_ref()
|
||||
}
|
||||
|
||||
/// Gets a reference to the visited style. Panic if no visited style exists.
|
||||
pub fn visited_style(&self) -> &Arc<ComputedValues> {
|
||||
self.get_visited_style().unwrap()
|
||||
}
|
||||
|
||||
/// Clone the visited style. Used for inheriting parent styles in
|
||||
/// StyleBuilder::for_inheritance.
|
||||
pub fn clone_visited_style(&self) -> Option<Arc<ComputedValues>> {
|
||||
self.visited_style.clone()
|
||||
}
|
||||
|
||||
pub fn custom_properties(&self) -> Option<Arc<ComputedValuesMap>> {
|
||||
self.custom_properties.clone()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn has_moz_binding(&self) -> bool {
|
||||
!self.get_box().gecko.mBinding.mPtr.mRawPtr.is_null()
|
||||
}
|
||||
|
||||
// FIXME(bholley): Implement this properly.
|
||||
#[inline]
|
||||
pub fn is_multicol(&self) -> bool { false }
|
||||
|
||||
pub fn to_declaration_block(&self, property: PropertyDeclarationId) -> PropertyDeclarationBlock {
|
||||
match property {
|
||||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
PropertyDeclarationId::Longhand(LonghandId::${prop.camel_case}) => {
|
||||
PropertyDeclarationBlock::with_one(
|
||||
PropertyDeclaration::${prop.camel_case}(
|
||||
% if prop.boxed:
|
||||
Box::new(
|
||||
% endif
|
||||
longhands::${prop.ident}::SpecifiedValue::from_computed_value(
|
||||
&self.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}())
|
||||
% if prop.boxed:
|
||||
)
|
||||
% endif
|
||||
),
|
||||
Importance::Normal
|
||||
)
|
||||
},
|
||||
% endif
|
||||
% endfor
|
||||
PropertyDeclarationId::Custom(_name) => unimplemented!(),
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<%def name="declare_style_struct(style_struct)">
|
||||
pub struct ${style_struct.gecko_struct_name} {
|
||||
gecko: ${style_struct.gecko_ffi_name},
|
||||
|
|
|
@ -1801,9 +1801,6 @@ pub mod style_structs {
|
|||
% endfor
|
||||
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use gecko_properties::ComputedValues;
|
||||
|
||||
/// A legacy alias for a servo-version of ComputedValues. Should go away soon.
|
||||
#[cfg(feature = "servo")]
|
||||
pub type ServoComputedValues = ComputedValues;
|
||||
|
@ -1814,8 +1811,7 @@ pub type ServoComputedValues = ComputedValues;
|
|||
/// every kind of style struct.
|
||||
///
|
||||
/// When needed, the structs may be copied in order to get mutated.
|
||||
#[cfg(feature = "servo")]
|
||||
#[cfg_attr(feature = "servo", derive(Clone))]
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedValues {
|
||||
% for style_struct in data.active_style_structs():
|
||||
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
|
||||
|
@ -1840,7 +1836,6 @@ pub struct ComputedValues {
|
|||
visited_style: Option<Arc<ComputedValues>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
impl ComputedValues {
|
||||
/// Construct a `ComputedValues` instance.
|
||||
pub fn new(
|
||||
|
@ -1868,9 +1863,6 @@ impl ComputedValues {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the initial computed values.
|
||||
pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
|
||||
|
||||
% for style_struct in data.active_style_structs():
|
||||
/// Clone the ${style_struct.name} struct.
|
||||
#[inline]
|
||||
|
@ -1897,6 +1889,30 @@ impl ComputedValues {
|
|||
}
|
||||
% endfor
|
||||
|
||||
/// Get the initial computed values.
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
|
||||
|
||||
/// Get the default computed values for a given document.
|
||||
///
|
||||
/// This takes into account zoom, etc.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn default_values(
|
||||
pres_context: bindings::RawGeckoPresContextBorrowed
|
||||
) -> Arc<Self> {
|
||||
Arc::new(ComputedValues {
|
||||
custom_properties: None,
|
||||
writing_mode: WritingMode::empty(), // FIXME(bz): This seems dubious
|
||||
font_computation_data: FontComputationData::default_values(),
|
||||
flags: ComputedValueFlags::initial(),
|
||||
rules: None,
|
||||
visited_style: None,
|
||||
% for style_struct in data.style_structs:
|
||||
${style_struct.ident}: style_structs::${style_struct.name}::default(pres_context),
|
||||
% endfor
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets a reference to the rule node. Panic if no rule node exists.
|
||||
pub fn rules(&self) -> &StrongRuleNode {
|
||||
self.rules.as_ref().unwrap()
|
||||
|
@ -1929,23 +1945,77 @@ 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>> {
|
||||
pub fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> {
|
||||
self.custom_properties.clone()
|
||||
}
|
||||
|
||||
/// Get a declaration block representing the computed value for a given
|
||||
/// property.
|
||||
///
|
||||
/// Currently only implemented for animated properties.
|
||||
pub fn to_declaration_block(
|
||||
&self,
|
||||
property: PropertyDeclarationId
|
||||
) -> PropertyDeclarationBlock {
|
||||
use values::computed::ToComputedValue;
|
||||
|
||||
match property {
|
||||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
PropertyDeclarationId::Longhand(LonghandId::${prop.camel_case}) => {
|
||||
PropertyDeclarationBlock::with_one(
|
||||
PropertyDeclaration::${prop.camel_case}(
|
||||
% if prop.boxed:
|
||||
Box::new(
|
||||
% endif
|
||||
longhands::${prop.ident}::SpecifiedValue::from_computed_value(
|
||||
&self.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}())
|
||||
% if prop.boxed:
|
||||
)
|
||||
% endif
|
||||
),
|
||||
Importance::Normal
|
||||
)
|
||||
},
|
||||
% endif
|
||||
% endfor
|
||||
PropertyDeclarationId::Custom(_name) => unimplemented!(),
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether this style has a -moz-binding value. This is always false for
|
||||
/// Servo for obvious reasons.
|
||||
#[inline]
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn has_moz_binding(&self) -> bool { false }
|
||||
|
||||
/// Whether this style has a -moz-binding value.
|
||||
#[inline]
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn has_moz_binding(&self) -> bool {
|
||||
!self.get_box().gecko().mBinding.mPtr.mRawPtr.is_null()
|
||||
}
|
||||
|
||||
/// Returns whether this style's display value is equal to contents.
|
||||
///
|
||||
/// Since this isn't supported in Servo, this is always false for Servo.
|
||||
#[inline]
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn is_display_contents(&self) -> bool { false }
|
||||
|
||||
/// Returns whether this style's display value is equal to contents.
|
||||
#[inline]
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_display_contents(&self) -> bool {
|
||||
self.get_box().clone_display() == longhands::display::computed_value::T::contents
|
||||
}
|
||||
|
||||
/// Returns whether the "content" property for the given style is completely
|
||||
/// ineffective, and would yield an empty `::before` or `::after`
|
||||
/// pseudo-element.
|
||||
#[inline]
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn ineffective_content_property(&self) -> bool {
|
||||
use properties::longhands::content::computed_value::T;
|
||||
match self.get_counters().content {
|
||||
|
@ -1954,8 +2024,23 @@ impl ComputedValues {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether the current style is multicolumn.
|
||||
/// Returns true if the value of the `content` property would make a
|
||||
/// pseudo-element not rendered.
|
||||
#[inline]
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn ineffective_content_property(&self) -> bool {
|
||||
self.get_counters().ineffective_content_property()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(feature = "gecko")]
|
||||
/// Whether the current style is multicolumn.
|
||||
/// FIXME(bholley): Implement this properly.
|
||||
pub fn is_multicol(&self) -> bool { false }
|
||||
|
||||
#[inline]
|
||||
#[cfg(feature = "servo")]
|
||||
/// Whether the current style is multicolumn.
|
||||
pub fn is_multicol(&self) -> bool {
|
||||
let style = self.get_column();
|
||||
match style.column_width {
|
||||
|
@ -1966,7 +2051,10 @@ impl ComputedValues {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
impl ComputedValues {
|
||||
/// Resolves the currentColor keyword.
|
||||
///
|
||||
/// Any color value from computed values (except for the 'color' property
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue