aboutsummaryrefslogtreecommitdiffstats
path: root/components/style
diff options
context:
space:
mode:
Diffstat (limited to 'components/style')
-rw-r--r--components/style/animation.rs34
-rw-r--r--components/style/context.rs11
-rw-r--r--components/style/data.rs14
-rw-r--r--components/style/dom.rs19
-rw-r--r--components/style/lib.rs2
-rw-r--r--components/style/matching.rs83
-rw-r--r--components/style/properties.mako.rs719
-rw-r--r--components/style/servo.rs3
-rw-r--r--components/style/traversal.rs4
-rw-r--r--components/style/values.rs68
-rw-r--r--components/style/viewport.rs6
11 files changed, 598 insertions, 365 deletions
diff --git a/components/style/animation.rs b/components/style/animation.rs
index b152be5fcc3..e7663093cd5 100644
--- a/components/style/animation.rs
+++ b/components/style/animation.rs
@@ -7,7 +7,6 @@ use bezier::Bezier;
use cssparser::{Color, RGBA};
use dom::{OpaqueNode, TRestyleDamage};
use euclid::point::Point2D;
-use properties::ComputedValues;
use properties::longhands::background_position::computed_value::T as BackgroundPosition;
use properties::longhands::border_spacing::computed_value::T as BorderSpacing;
use properties::longhands::clip::computed_value::ClipRect;
@@ -25,6 +24,8 @@ use properties::longhands::transition_timing_function::computed_value::{Transiti
use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex;
+use properties::style_struct_traits::TAnimation;
+use properties::{ComputedValues, TComputedValues};
use std::cmp::Ordering;
use std::iter::repeat;
use std::sync::mpsc::Sender;
@@ -73,7 +74,7 @@ impl PropertyAnimation {
-> Vec<PropertyAnimation> {
let mut result = Vec::new();
let transition_property =
- new_style.get_animation().transition_property.0[transition_index];
+ new_style.as_servo().get_animation().transition_property.0[transition_index];
if transition_property != TransitionProperty::All {
if let Some(property_animation) =
PropertyAnimation::from_transition_property(transition_property,
@@ -929,22 +930,22 @@ impl<T> GetMod for Vec<T> {
/// Inserts transitions into the queue of running animations as applicable for the given style
/// difference. This is called from the layout worker threads. Returns true if any animations were
/// kicked off and false otherwise.
-pub fn start_transitions_if_applicable(new_animations_sender: &Mutex<Sender<Animation>>,
- node: OpaqueNode,
- old_style: &ComputedValues,
- new_style: &mut ComputedValues)
- -> bool {
+pub fn start_transitions_if_applicable<C: TComputedValues>(new_animations_sender: &Mutex<Sender<Animation>>,
+ node: OpaqueNode,
+ old_style: &C,
+ new_style: &mut C)
+ -> bool {
let mut had_animations = false;
- for i in 0..new_style.get_animation().transition_property.0.len() {
+ for i in 0..new_style.get_animation().transition_count() {
// Create any property animations, if applicable.
- let property_animations = PropertyAnimation::from_transition(i, old_style, new_style);
+ let property_animations = PropertyAnimation::from_transition(i, old_style.as_servo(), new_style.as_servo_mut());
for property_animation in property_animations {
// Set the property to the initial value.
- property_animation.update(new_style, 0.0);
+ property_animation.update(new_style.as_servo_mut(), 0.0);
// Kick off the animation.
let now = time::precise_time_s();
- let animation_style = new_style.get_animation();
+ let animation_style = new_style.as_servo().get_animation();
let start_time =
now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64);
new_animations_sender.lock().unwrap().send(Animation {
@@ -964,9 +965,10 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Mutex<Sender<Anim
/// Updates a single animation and associated style based on the current time. If `damage` is
/// provided, inserts the appropriate restyle damage.
-pub fn update_style_for_animation<ConcreteRestyleDamage: TRestyleDamage>(animation: &Animation,
- style: &mut Arc<ComputedValues>,
- damage: Option<&mut ConcreteRestyleDamage>) {
+pub fn update_style_for_animation<C: TComputedValues,
+ Damage: TRestyleDamage<ConcreteComputedValues=C>>(animation: &Animation,
+ style: &mut Arc<C>,
+ damage: Option<&mut Damage>) {
let now = time::precise_time_s();
let mut progress = (now - animation.start_time) / animation.duration();
if progress > 1.0 {
@@ -977,9 +979,9 @@ pub fn update_style_for_animation<ConcreteRestyleDamage: TRestyleDamage>(animati
}
let mut new_style = (*style).clone();
- animation.property_animation.update(&mut *Arc::make_mut(&mut new_style), progress);
+ animation.property_animation.update(Arc::make_mut(&mut new_style).as_servo_mut(), progress);
if let Some(damage) = damage {
- *damage = *damage | ConcreteRestyleDamage::compute(Some(style), &new_style);
+ *damage = *damage | Damage::compute(Some(style), &new_style);
}
*style = new_style
diff --git a/components/style/context.rs b/components/style/context.rs
index 6e4edfd1b52..ef19bc2561e 100644
--- a/components/style/context.rs
+++ b/components/style/context.rs
@@ -8,6 +8,7 @@ use dom::OpaqueNode;
use error_reporting::ParseErrorReporter;
use euclid::Size2D;
use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
+use properties::TComputedValues;
use selector_impl::SelectorImplExt;
use selector_matching::Stylist;
use std::cell::RefCell;
@@ -54,15 +55,15 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub error_reporter: Box<ParseErrorReporter + Sync>,
}
-pub struct LocalStyleContext {
- pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache>,
- pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>,
+pub struct LocalStyleContext<C: TComputedValues> {
+ pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache<C>>,
+ pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache<C>>,
}
-pub trait StyleContext<'a, Impl: SelectorImplExt> {
+pub trait StyleContext<'a, Impl: SelectorImplExt, C: TComputedValues> {
fn shared_context(&self) -> &'a SharedStyleContext<Impl>;
- fn local_context(&self) -> &LocalStyleContext;
+ fn local_context(&self) -> &LocalStyleContext<C>;
}
/// Why we're doing reflow.
diff --git a/components/style/data.rs b/components/style/data.rs
index ffe12908cba..6bc6916a564 100644
--- a/components/style/data.rs
+++ b/components/style/data.rs
@@ -2,26 +2,28 @@
* 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/. */
-use properties::ComputedValues;
+use properties::TComputedValues;
use selectors::parser::SelectorImpl;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::sync::Arc;
use std::sync::atomic::AtomicIsize;
-pub struct PrivateStyleData<Impl: SelectorImpl> {
+pub struct PrivateStyleData<Impl: SelectorImpl, ConcreteComputedValues: TComputedValues> {
/// The results of CSS styling for this node.
- pub style: Option<Arc<ComputedValues>>,
+ pub style: Option<Arc<ConcreteComputedValues>>,
/// The results of CSS styling for each pseudo-element (if any).
- pub per_pseudo: HashMap<Impl::PseudoElement, Arc<ComputedValues>, BuildHasherDefault<::fnv::FnvHasher>>,
+ pub per_pseudo: HashMap<Impl::PseudoElement, Arc<ConcreteComputedValues>,
+ BuildHasherDefault<::fnv::FnvHasher>>,
/// Information needed during parallel traversals.
pub parallel: DomParallelInfo,
}
-impl<Impl: SelectorImpl> PrivateStyleData<Impl> {
- pub fn new() -> PrivateStyleData<Impl> {
+impl<Impl, ConcreteComputedValues> PrivateStyleData<Impl, ConcreteComputedValues>
+ where Impl: SelectorImpl, ConcreteComputedValues: TComputedValues {
+ pub fn new() -> PrivateStyleData<Impl, ConcreteComputedValues> {
PrivateStyleData {
style: None,
per_pseudo: HashMap::with_hasher(Default::default()),
diff --git a/components/style/dom.rs b/components/style/dom.rs
index 37859736dbe..861cec599a2 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -6,7 +6,7 @@
use data::PrivateStyleData;
use element_state::ElementState;
-use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
+use properties::{PropertyDeclaration, PropertyDeclarationBlock, TComputedValues};
use restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
use selector_impl::ElementExt;
use selectors::Element;
@@ -43,14 +43,16 @@ impl OpaqueNode {
}
pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
- fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> Self;
+ type ConcreteComputedValues: TComputedValues;
+ fn compute(old: Option<&Arc<Self::ConcreteComputedValues>>, new: &Self::ConcreteComputedValues) -> Self;
fn rebuild_and_reflow() -> Self;
}
pub trait TNode : Sized + Copy + Clone {
type ConcreteElement: TElement<ConcreteNode = Self, ConcreteDocument = Self::ConcreteDocument>;
type ConcreteDocument: TDocument<ConcreteNode = Self, ConcreteElement = Self::ConcreteElement>;
- type ConcreteRestyleDamage: TRestyleDamage;
+ type ConcreteRestyleDamage: TRestyleDamage<ConcreteComputedValues = Self::ConcreteComputedValues>;
+ type ConcreteComputedValues: TComputedValues;
fn to_unsafe(&self) -> UnsafeNode;
unsafe fn from_unsafe(n: &UnsafeNode) -> Self;
@@ -135,17 +137,20 @@ pub trait TNode : Sized + Copy + Clone {
/// Borrows the PrivateStyleData without checks.
#[inline(always)]
unsafe fn borrow_data_unchecked(&self)
- -> Option<*const PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>;
+ -> Option<*const PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
+ Self::ConcreteComputedValues>>;
/// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow.
#[inline(always)]
fn borrow_data(&self)
- -> Option<Ref<PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>>;
+ -> Option<Ref<PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
+ Self::ConcreteComputedValues>>>;
/// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow.
#[inline(always)]
fn mutate_data(&self)
- -> Option<RefMut<PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>>;
+ -> Option<RefMut<PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
+ Self::ConcreteComputedValues>>>;
/// Get the description of how to account for recent style changes.
fn restyle_damage(self) -> Self::ConcreteRestyleDamage;
@@ -166,7 +171,7 @@ pub trait TNode : Sized + Copy + Clone {
/// Returns the style results for the given node. If CSS selector matching
/// has not yet been performed, fails.
- fn style(&self) -> Ref<Arc<ComputedValues>> {
+ fn style(&self) -> Ref<Arc<Self::ConcreteComputedValues>> {
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
}
diff --git a/components/style/lib.rs b/components/style/lib.rs
index a696b882d43..951a32cd3ce 100644
--- a/components/style/lib.rs
+++ b/components/style/lib.rs
@@ -50,7 +50,7 @@ pub mod animation;
pub mod attr;
pub mod bezier;
pub mod context;
-mod custom_properties;
+pub mod custom_properties;
pub mod data;
pub mod dom;
pub mod element_state;
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 1c158505e97..025e229e57c 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -8,8 +8,8 @@ use animation::{self, Animation};
use context::SharedStyleContext;
use data::PrivateStyleData;
use dom::{TElement, TNode, TRestyleDamage};
-use properties::{ComputedValues, PropertyDeclaration, cascade};
-use selector_impl::SelectorImplExt;
+use properties::{PropertyDeclaration, TComputedValues, cascade};
+use selector_impl::{ElementExt, SelectorImplExt};
use selector_matching::{DeclarationBlock, Stylist};
use selectors::Element;
use selectors::bloom::BloomFilter;
@@ -151,25 +151,25 @@ impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
static APPLICABLE_DECLARATIONS_CACHE_SIZE: usize = 32;
-pub struct ApplicableDeclarationsCache {
- cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<ComputedValues>>,
+pub struct ApplicableDeclarationsCache<C: TComputedValues> {
+ cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<C>>,
}
-impl ApplicableDeclarationsCache {
- pub fn new() -> ApplicableDeclarationsCache {
+impl<C: TComputedValues> ApplicableDeclarationsCache<C> {
+ pub fn new() -> Self {
ApplicableDeclarationsCache {
cache: SimpleHashCache::new(APPLICABLE_DECLARATIONS_CACHE_SIZE),
}
}
- pub fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<ComputedValues>> {
+ pub fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<C>> {
match self.cache.find(&ApplicableDeclarationsCacheQuery::new(declarations)) {
None => None,
Some(ref values) => Some((*values).clone()),
}
}
- pub fn insert(&mut self, declarations: Vec<DeclarationBlock>, style: Arc<ComputedValues>) {
+ pub fn insert(&mut self, declarations: Vec<DeclarationBlock>, style: Arc<C>) {
self.cache.insert(ApplicableDeclarationsCacheEntry::new(declarations), style)
}
@@ -179,14 +179,14 @@ impl ApplicableDeclarationsCache {
}
/// An LRU cache of the last few nodes seen, so that we can aggressively try to reuse their styles.
-pub struct StyleSharingCandidateCache {
- cache: LRUCache<StyleSharingCandidate, ()>,
+pub struct StyleSharingCandidateCache<C: TComputedValues> {
+ cache: LRUCache<StyleSharingCandidate<C>, ()>,
}
#[derive(Clone)]
-pub struct StyleSharingCandidate {
- pub style: Arc<ComputedValues>,
- pub parent_style: Arc<ComputedValues>,
+pub struct StyleSharingCandidate<C: TComputedValues> {
+ pub style: Arc<C>,
+ pub parent_style: Arc<C>,
pub local_name: Atom,
// FIXME(pcwalton): Should be a list of atoms instead.
pub class: Option<String>,
@@ -195,8 +195,8 @@ pub struct StyleSharingCandidate {
pub link: bool,
}
-impl PartialEq for StyleSharingCandidate {
- fn eq(&self, other: &StyleSharingCandidate) -> bool {
+impl<C: TComputedValues> PartialEq for StyleSharingCandidate<C> {
+ fn eq(&self, other: &Self) -> bool {
arc_ptr_eq(&self.style, &other.style) &&
arc_ptr_eq(&self.parent_style, &other.parent_style) &&
self.local_name == other.local_name &&
@@ -207,12 +207,12 @@ impl PartialEq for StyleSharingCandidate {
}
}
-impl StyleSharingCandidate {
+impl<C: TComputedValues> StyleSharingCandidate<C> {
/// Attempts to create a style sharing candidate from this node. Returns
/// the style sharing candidate or `None` if this node is ineligible for
/// style sharing.
#[allow(unsafe_code)]
- fn new<E: TElement>(element: &E) -> Option<StyleSharingCandidate> {
+ fn new<N: TNode<ConcreteComputedValues=C>>(element: &N::ConcreteElement) -> Option<Self> {
let parent_element = match element.parent_element() {
None => return None,
Some(parent_element) => parent_element,
@@ -254,7 +254,7 @@ impl StyleSharingCandidate {
link: element.is_link(),
namespace: (*element.get_namespace()).clone(),
common_style_affecting_attributes:
- create_common_style_affecting_attributes_from_element::<E>(&element)
+ create_common_style_affecting_attributes_from_element::<N::ConcreteElement>(&element)
})
}
@@ -332,19 +332,19 @@ impl StyleSharingCandidate {
static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 40;
-impl StyleSharingCandidateCache {
- pub fn new() -> StyleSharingCandidateCache {
+impl<C: TComputedValues> StyleSharingCandidateCache<C> {
+ pub fn new() -> Self {
StyleSharingCandidateCache {
cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE),
}
}
- pub fn iter(&self) -> Iter<(StyleSharingCandidate, ())> {
+ pub fn iter(&self) -> Iter<(StyleSharingCandidate<C>, ())> {
self.cache.iter()
}
- pub fn insert_if_possible<E: TElement>(&mut self, element: &E) {
- match StyleSharingCandidate::new(element) {
+ pub fn insert_if_possible<N: TNode<ConcreteComputedValues=C>>(&mut self, element: &N::ConcreteElement) {
+ match StyleSharingCandidate::new::<N>(element) {
None => {}
Some(candidate) => self.cache.insert(candidate, ())
}
@@ -368,15 +368,15 @@ trait PrivateMatchMethods: TNode
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
fn cascade_node_pseudo_element(&self,
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
- parent_style: Option<&Arc<ComputedValues>>,
+ parent_style: Option<&Arc<Self::ConcreteComputedValues>>,
applicable_declarations: &[DeclarationBlock],
- mut style: Option<&mut Arc<ComputedValues>>,
+ mut style: Option<&mut Arc<Self::ConcreteComputedValues>>,
applicable_declarations_cache:
- &mut ApplicableDeclarationsCache,
+ &mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>,
new_animations_sender: &Mutex<Sender<Animation>>,
shareable: bool,
animate_properties: bool)
- -> (Self::ConcreteRestyleDamage, Arc<ComputedValues>) {
+ -> (Self::ConcreteRestyleDamage, Arc<Self::ConcreteComputedValues>) {
let mut cacheable = true;
if animate_properties {
cacheable = !self.update_animations_for_cascade(context, &mut style) && cacheable;
@@ -416,10 +416,11 @@ trait PrivateMatchMethods: TNode
if animate_properties {
if let Some(ref style) = style {
let animations_started =
- animation::start_transitions_if_applicable(new_animations_sender,
- self.opaque(),
- &**style,
- &mut this_style);
+ animation::start_transitions_if_applicable::<Self::ConcreteComputedValues>(
+ new_animations_sender,
+ self.opaque(),
+ &**style,
+ &mut this_style);
cacheable = cacheable && !animations_started
}
}
@@ -440,7 +441,7 @@ trait PrivateMatchMethods: TNode
fn update_animations_for_cascade(&self,
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
- style: &mut Option<&mut Arc<ComputedValues>>)
+ style: &mut Option<&mut Arc<Self::ConcreteComputedValues>>)
-> bool {
let style = match *style {
None => return false,
@@ -456,7 +457,7 @@ trait PrivateMatchMethods: TNode
had_animations_to_expire = animations_to_expire.is_some();
if let Some(ref animations) = animations_to_expire {
for animation in *animations {
- animation.property_animation.update(&mut *Arc::make_mut(style), 1.0);
+ animation.property_animation.update(Arc::make_mut(style).as_servo_mut(), 1.0);
}
}
}
@@ -474,7 +475,8 @@ trait PrivateMatchMethods: TNode
if had_running_animations {
let mut all_running_animations = context.running_animations.write().unwrap();
for running_animation in all_running_animations.get(&this_opaque).unwrap() {
- animation::update_style_for_animation::<Self::ConcreteRestyleDamage>(running_animation, style, None);
+ animation::update_style_for_animation::<Self::ConcreteComputedValues,
+ Self::ConcreteRestyleDamage>(running_animation, style, None);
}
all_running_animations.remove(&this_opaque);
}
@@ -489,14 +491,15 @@ impl<N: TNode> PrivateMatchMethods for N
trait PrivateElementMatchMethods: TElement {
fn share_style_with_candidate_if_possible(&self,
parent_node: Option<Self::ConcreteNode>,
- candidate: &StyleSharingCandidate)
- -> Option<Arc<ComputedValues>> {
+ candidate: &StyleSharingCandidate<<Self::ConcreteNode as
+ TNode>::ConcreteComputedValues>)
+ -> Option<Arc<<Self::ConcreteNode as TNode>::ConcreteComputedValues>> {
let parent_node = match parent_node {
Some(ref parent_node) if parent_node.as_element().is_some() => parent_node,
Some(_) | None => return None,
};
- let parent_data: Option<&PrivateStyleData<_>> = unsafe {
+ let parent_data: Option<&PrivateStyleData<_, _>> = unsafe {
parent_node.borrow_data_unchecked().map(|d| &*d)
};
@@ -550,7 +553,8 @@ pub trait ElementMatchMethods : TElement
/// guarantee that at the type system level yet.
unsafe fn share_style_if_possible(&self,
style_sharing_candidate_cache:
- &mut StyleSharingCandidateCache,
+ &mut StyleSharingCandidateCache<<Self::ConcreteNode as
+ TNode>::ConcreteComputedValues>,
parent: Option<Self::ConcreteNode>)
-> StyleSharingResult<<Self::ConcreteNode as TNode>::ConcreteRestyleDamage> {
if opts::get().disable_share_style_cache {
@@ -639,7 +643,8 @@ pub trait MatchMethods : TNode {
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
parent: Option<Self>,
applicable_declarations: &ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>,
- applicable_declarations_cache: &mut ApplicableDeclarationsCache,
+ applicable_declarations_cache:
+ &mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>,
new_animations_sender: &Mutex<Sender<Animation>>)
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
// Get our parent's style. This must be unsafe so that we don't touch the parent's
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index a7cd97743cc..7c0189f599e 100644
--- a/components/style/properties.mako.rs
+++ b/components/style/properties.mako.rs
@@ -10,9 +10,7 @@
use std::ascii::AsciiExt;
use std::collections::HashSet;
-use std::default::Default;
use std::fmt;
-use std::hash::{Hash, Hasher};
use std::intrinsics;
use std::mem;
use std::sync::Arc;
@@ -24,7 +22,6 @@ use error_reporting::ParseErrorReporter;
use url::Url;
use euclid::SideOffsets2D;
use euclid::size::Size2D;
-use fnv::FnvHasher;
use string_cache::Atom;
use computed_values;
use logical_geometry::{LogicalMargin, PhysicalSide, WritingMode};
@@ -32,7 +29,7 @@ use parser::{ParserContext, log_css_error};
use selectors::matching::DeclarationBlock;
use stylesheets::Origin;
use values::AuExtensionMethods;
-use values::computed::{self, ToComputedValue};
+use values::computed::{self, TContext, ToComputedValue};
use values::specified::BorderStyle;
use self::property_bit_field::PropertyBitField;
@@ -142,17 +139,20 @@ pub mod longhands {
use error_reporting::ParseErrorReporter;
use properties::longhands;
use properties::property_bit_field::PropertyBitField;
- use properties::{ComputedValues, PropertyDeclaration};
+ use properties::{ComputedValues, PropertyDeclaration, TComputedValues};
+ use properties::style_struct_traits::T${THIS_STYLE_STRUCT.name};
+ use properties::style_structs;
use std::collections::HashMap;
use std::sync::Arc;
- use values::computed::ToComputedValue;
+ use values::computed::{TContext, ToComputedValue};
use values::{computed, specified};
use string_cache::Atom;
${caller.body()}
#[allow(unused_variables)]
- pub fn cascade_property(declaration: &PropertyDeclaration,
- inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ pub fn cascade_property<C: TComputedValues>(
+ declaration: &PropertyDeclaration,
+ inherited_style: &C,
+ context: &mut computed::Context<C>,
seen: &mut PropertyBitField,
cacheable: &mut bool,
error_reporter: &mut Box<ParseErrorReporter + Send>) {
@@ -167,31 +167,39 @@ pub mod longhands {
return
}
seen.set_${property.ident}();
- let computed_value = ::properties::substitute_variables_${property.ident}(
- declared_value, &context.style.custom_properties, |value| match *value {
- DeclaredValue::Value(ref specified_value) => {
- specified_value.to_computed_value(&context)
- }
- DeclaredValue::WithVariables { .. } => unreachable!(),
- DeclaredValue::Initial => get_initial_value(),
- DeclaredValue::Inherit => {
- // This is a bit slow, but this is rare so it shouldn't
- // matter.
- //
- // FIXME: is it still?
- *cacheable = false;
- inherited_style.${THIS_STYLE_STRUCT.ident}
- .${property.ident}
- .clone()
- }
- }, error_reporter
- );
- Arc::make_mut(&mut context.style.${THIS_STYLE_STRUCT.ident}).${property.ident} =
- computed_value;
+ {
+ let custom_props = context.style().custom_properties();
+ ::properties::substitute_variables_${property.ident}(
+ declared_value, &custom_props, |value| match *value {
+ DeclaredValue::Value(ref specified_value) => {
+ let computed = specified_value.to_computed_value(context);
+ context.mutate_style().mutate_${THIS_STYLE_STRUCT.name.lower()}()
+ .set_${property.ident}(computed);
+ }
+ DeclaredValue::WithVariables { .. } => unreachable!(),
+ DeclaredValue::Initial => {
+ // We assume that it's faster to use copy_*_from rather than
+ // set_*(get_initial_value());
+ let initial_struct = C::initial_values().get_${THIS_STYLE_STRUCT.name.lower()}();
+ context.mutate_style().mutate_${THIS_STYLE_STRUCT.name.lower()}()
+ .copy_${property.ident}_from(initial_struct);
+ },
+ DeclaredValue::Inherit => {
+ // This is a bit slow, but this is rare so it shouldn't
+ // matter.
+ //
+ // FIXME: is it still?
+ *cacheable = false;
+ let inherited_struct = inherited_style.get_${THIS_STYLE_STRUCT.name.lower()}();
+ context.mutate_style().mutate_${THIS_STYLE_STRUCT.name.lower()}()
+ .copy_${property.ident}_from(inherited_struct);
+ }
+ }, error_reporter
+ );
+ }
% if custom_cascade:
- cascade_property_custom(&computed_value,
- declaration,
+ cascade_property_custom(declaration,
inherited_style,
context,
seen,
@@ -334,7 +342,6 @@ pub mod longhands {
use app_units::Au;
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -361,7 +368,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
self.0.to_computed_value(context)
}
}
@@ -399,7 +406,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -421,7 +427,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
self.0.to_computed_value(context)
}
}
@@ -453,6 +459,7 @@ pub mod longhands {
%>
pub use self::computed_value::T as SpecifiedValue;
use values::computed::{Context, ComputedValueAsSpecified};
+ use properties::style_struct_traits::TInheritedText;
pub mod computed_value {
#[allow(non_camel_case_types)]
@@ -498,31 +505,27 @@ pub mod longhands {
impl ComputedValueAsSpecified for SpecifiedValue {}
- fn cascade_property_custom(_computed_value: &computed_value::T,
+ fn cascade_property_custom<C: TComputedValues>(
_declaration: &PropertyDeclaration,
- _inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ _inherited_style: &C,
+ context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
_error_reporter: &mut Box<ParseErrorReporter + Send>) {
- Arc::make_mut(&mut context.style.box_)._servo_display_for_hypothetical_box =
- longhands::_servo_display_for_hypothetical_box::derive_from_display(&context);
- Arc::make_mut(&mut context.style.inheritedtext)._servo_text_decorations_in_effect =
- longhands::_servo_text_decorations_in_effect::derive_from_display(&context);
+ longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
+ longhands::_servo_text_decorations_in_effect::derive_from_display(context);
}
</%self:longhand>
${single_keyword("position", "static absolute relative fixed")}
<%self:single_keyword_computed name="float" values="none left right">
- use values::computed::Context;
-
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
- let positioned = matches!(context.style.box_.position,
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
+ let positioned = matches!(context.style().get_box().clone_position(),
longhands::position::SpecifiedValue::absolute |
longhands::position::SpecifiedValue::fixed);
if positioned {
@@ -546,9 +549,9 @@ pub mod longhands {
}
#[inline]
- pub fn derive_from_display(context: &computed::Context)
- -> computed_value::T {
- context.style.box_.display
+ pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
+ let d = context.style().get_box().clone_display();
+ context.mutate_style().mutate_box().set__servo_display_for_hypothetical_box(d);
}
</%self:longhand>
@@ -636,7 +639,6 @@ pub mod longhands {
use std::fmt;
use values::AuExtensionMethods;
use values::CSSFloat;
- use values::computed::Context;
#[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -699,7 +701,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T::Normal,
SpecifiedValue::Number(value) => computed_value::T::Number(value),
@@ -729,7 +731,6 @@ pub mod longhands {
<%self:longhand name="vertical-align">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
<% vertical_align_keywords = (
"baseline sub super top text-top middle bottom text-bottom".split()) %>
@@ -797,7 +798,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
% for keyword in vertical_align_keywords:
SpecifiedValue::${to_rust_ident(keyword)} => {
@@ -823,7 +824,6 @@ pub mod longhands {
// FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
<%self:longhand name="overflow-y">
use super::overflow_x;
- use values::computed::Context;
use cssparser::ToCss;
use std::fmt;
@@ -845,7 +845,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.to_computed_value(context))
}
}
@@ -1052,7 +1052,6 @@ pub mod longhands {
use cssparser::{ToCss, Token};
use std::fmt;
use url::Url;
- use values::computed::Context;
use values::LocalToCss;
#[derive(Debug, Clone, PartialEq, Eq, HeapSizeOf)]
@@ -1093,7 +1092,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::None => computed_value::T(None),
SpecifiedValue::Url(ref url) => computed_value::T(Some(url.clone())),
@@ -1272,7 +1271,6 @@ pub mod longhands {
<%self:longhand name="background-image">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
use values::specified::Image;
use values::LocalToCss;
@@ -1320,7 +1318,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue(None) => computed_value::T(None),
SpecifiedValue(Some(ref image)) =>
@@ -1334,7 +1332,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
pub mod computed_value {
use values::computed::LengthOrPercentage;
@@ -1419,7 +1416,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -1456,7 +1453,6 @@ pub mod longhands {
use cssparser::{ToCss, Token};
use std::ascii::AsciiExt;
use std::fmt;
- use values::computed::Context;
pub mod computed_value {
use values::computed::LengthOrPercentageOrAuto;
@@ -1529,7 +1525,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &computed::Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Explicit(ref size) => {
computed_value::T::Explicit(computed_value::ExplicitSize {
@@ -1593,14 +1589,13 @@ pub mod longhands {
<%self:raw_longhand name="color">
use cssparser::{Color, RGBA};
- use values::computed::Context;
use values::specified::{CSSColor, CSSRGBA};
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
self.parsed
}
}
@@ -1747,7 +1742,6 @@ pub mod longhands {
<%self:longhand name="font-weight">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
#[derive(Debug, Clone, PartialEq, Eq, Copy, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -1831,12 +1825,12 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
% for weight in range(100, 901, 100):
SpecifiedValue::Weight${weight} => computed_value::T::Weight${weight},
% endfor
- SpecifiedValue::Bolder => match context.inherited_style.font.font_weight {
+ SpecifiedValue::Bolder => match context.inherited_style().get_font().clone_font_weight() {
computed_value::T::Weight100 => computed_value::T::Weight400,
computed_value::T::Weight200 => computed_value::T::Weight400,
computed_value::T::Weight300 => computed_value::T::Weight400,
@@ -1847,7 +1841,7 @@ pub mod longhands {
computed_value::T::Weight800 => computed_value::T::Weight900,
computed_value::T::Weight900 => computed_value::T::Weight900,
},
- SpecifiedValue::Lighter => match context.inherited_style.font.font_weight {
+ SpecifiedValue::Lighter => match context.inherited_style().get_font().clone_font_weight() {
computed_value::T::Weight100 => computed_value::T::Weight100,
computed_value::T::Weight200 => computed_value::T::Weight100,
computed_value::T::Weight300 => computed_value::T::Weight100,
@@ -1868,7 +1862,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::FONT_MEDIUM_PX;
- use values::computed::Context;
use values::specified::{LengthOrPercentage, Length, Percentage};
impl ToCss for SpecifiedValue {
@@ -1891,24 +1884,25 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match self.0 {
LengthOrPercentage::Length(Length::FontRelative(value)) => {
- value.to_computed_value(context.inherited_style.font.font_size,
- context.style.root_font_size)
+ value.to_computed_value(context.inherited_style().get_font().clone_font_size(),
+ context.style().root_font_size())
}
LengthOrPercentage::Length(Length::ServoCharacterWidth(value)) => {
- value.to_computed_value(context.inherited_style.font.font_size)
+ value.to_computed_value(context.inherited_style().get_font().clone_font_size())
}
LengthOrPercentage::Length(l) => {
- l.to_computed_value(&context)
+ l.to_computed_value(context)
}
LengthOrPercentage::Percentage(Percentage(value)) => {
- context.inherited_style.font.font_size.scale_by(value)
+ context.inherited_style().get_font().clone_font_size().scale_by(value)
}
LengthOrPercentage::Calc(calc) => {
- let calc = calc.to_computed_value(&context);
- calc.length() + context.inherited_style.font.font_size.scale_by(calc.percentage())
+ let calc = calc.to_computed_value(context);
+ calc.length() + context.inherited_style().get_font().clone_font_size()
+ .scale_by(calc.percentage())
}
}
}
@@ -1992,7 +1986,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2033,7 +2026,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2055,7 +2048,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2096,7 +2088,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2136,6 +2128,7 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::computed::ComputedValueAsSpecified;
+ use properties::style_struct_traits::TInheritedText;
impl ComputedValueAsSpecified for SpecifiedValue {}
@@ -2207,16 +2200,14 @@ pub mod longhands {
if !empty { Ok(result) } else { Err(()) }
}
- fn cascade_property_custom(_computed_value: &computed_value::T,
+ fn cascade_property_custom<C: TComputedValues>(
_declaration: &PropertyDeclaration,
- _inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ _inherited_style: &C,
+ context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
_error_reporter: &mut Box<ParseErrorReporter + Send>) {
- Arc::make_mut(&mut context.style.inheritedtext)._servo_text_decorations_in_effect =
- longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(
- &context);
+ longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context);
}
</%self:longhand>
@@ -2228,6 +2219,7 @@ pub mod longhands {
use std::fmt;
use values::computed::ComputedValueAsSpecified;
+ use properties::style_struct_traits::{TBox, TColor, TText};
impl ComputedValueAsSpecified for SpecifiedValue {}
@@ -2258,20 +2250,20 @@ pub mod longhands {
}
}
- fn maybe(flag: bool, context: &computed::Context) -> Option<RGBA> {
+ fn maybe<Cx: TContext>(flag: bool, context: &Cx) -> Option<RGBA> {
if flag {
- Some(context.style.color.color)
+ Some(context.style().get_color().clone_color())
} else {
None
}
}
- fn derive(context: &computed::Context) -> computed_value::T {
+ fn derive<Cx: TContext>(context: &Cx) -> computed_value::T {
// Start with no declarations if this is a block; otherwise, start with the
// declarations in effect and add in the text decorations that this inline specifies.
- let mut result = match context.style.box_.display {
+ let mut result = match context.style().get_box().clone_display() {
super::display::computed_value::T::inline => {
- context.inherited_style.inheritedtext._servo_text_decorations_in_effect
+ context.inherited_style().get_inheritedtext().clone__servo_text_decorations_in_effect()
}
_ => {
SpecifiedValue {
@@ -2283,27 +2275,28 @@ pub mod longhands {
};
if result.underline.is_none() {
- result.underline = maybe(context.style.text.text_decoration.underline, context)
+ result.underline = maybe(context.style().get_text().has_underline(), context)
}
if result.overline.is_none() {
- result.overline = maybe(context.style.text.text_decoration.overline, context)
+ result.overline = maybe(context.style().get_text().has_overline(), context)
}
if result.line_through.is_none() {
- result.line_through = maybe(context.style.text.text_decoration.line_through, context)
+ result.line_through = maybe(context.style().get_text().has_line_through(), context)
}
+
result
}
#[inline]
- pub fn derive_from_text_decoration(context: &computed::Context)
- -> computed_value::T {
- derive(context)
+ pub fn derive_from_text_decoration<Cx: TContext>(context: &mut Cx) {
+ let derived = derive(context);
+ context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived);
}
#[inline]
- pub fn derive_from_display(context: &computed::Context)
- -> computed_value::T {
- derive(context)
+ pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
+ let derived = derive(context);
+ context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived);
}
</%self:longhand>
@@ -2365,7 +2358,6 @@ pub mod longhands {
<%self:longhand name="border-spacing">
use app_units::Au;
use values::AuExtensionMethods;
- use values::computed::Context;
use cssparser::ToCss;
use std::fmt;
@@ -2414,7 +2406,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -2529,7 +2521,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2570,7 +2561,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2591,7 +2582,6 @@ pub mod longhands {
<%self:longhand name="column-count" experimental="True">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2631,7 +2621,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(count) =>
@@ -2658,7 +2648,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2699,7 +2688,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2724,7 +2713,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::CSSFloat;
- use values::computed::Context;
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -2747,7 +2735,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
if self.0 < 0.0 {
0.0
} else if self.0 > 1.0 {
@@ -2766,7 +2754,6 @@ pub mod longhands {
use cssparser::{self, ToCss};
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, PartialEq, HeapSizeOf)]
pub struct SpecifiedValue(Vec<SpecifiedBoxShadow>);
@@ -2890,12 +2877,12 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.iter().map(|value| compute_one_box_shadow(value, context)).collect())
}
}
- pub fn compute_one_box_shadow(value: &SpecifiedBoxShadow, context: &computed::Context)
+ pub fn compute_one_box_shadow<Cx: TContext>(value: &SpecifiedBoxShadow, context: &Cx)
-> computed_value::BoxShadow {
computed_value::BoxShadow {
offset_x: value.offset_x.to_computed_value(context),
@@ -2978,8 +2965,6 @@ pub mod longhands {
// NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
- use values::computed::Context;
-
pub mod computed_value {
use app_units::Au;
@@ -3083,7 +3068,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.map(|value| computed_value::ClipRect {
top: value.top.to_computed_value(context),
right: value.right.map(|right| right.to_computed_value(context)),
@@ -3130,7 +3115,6 @@ pub mod longhands {
use cssparser::{self, ToCss};
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Clone, PartialEq, Debug, HeapSizeOf)]
pub struct SpecifiedValue(Vec<SpecifiedTextShadow>);
@@ -3289,7 +3273,7 @@ pub mod longhands {
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
- fn to_computed_value(&self, context: &computed::Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.iter().map(|value| {
computed_value::TextShadow {
offset_x: value.offset_x.to_computed_value(context),
@@ -3518,7 +3502,7 @@ pub mod longhands {
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
- fn to_computed_value(&self, context: &computed::Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T{ filters: self.0.iter().map(|value| {
match *value {
SpecifiedFilter::Blur(factor) =>
@@ -3540,7 +3524,6 @@ pub mod longhands {
<%self:longhand name="transform">
use app_units::Au;
use values::CSSFloat;
- use values::computed::Context;
use cssparser::ToCss;
use std::fmt;
@@ -3957,7 +3940,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
if self.0.is_empty() {
return computed_value::T(None)
}
@@ -4083,7 +4066,6 @@ pub mod longhands {
<%self:longhand name="transform-origin">
use app_units::Au;
use values::AuExtensionMethods;
- use values::computed::Context;
use values::specified::{Length, LengthOrPercentage, Percentage};
use cssparser::ToCss;
@@ -4149,7 +4131,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -4164,7 +4146,6 @@ pub mod longhands {
"computed::LengthOrNone::None")}
<%self:longhand name="perspective-origin">
- use values::computed::Context;
use values::specified::{LengthOrPercentage, Percentage};
use cssparser::ToCss;
@@ -4225,7 +4206,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -4240,7 +4221,6 @@ pub mod longhands {
saturation color luminosity""")}
<%self:longhand name="image-rendering">
- use values::computed::Context;
pub mod computed_value {
use cssparser::ToCss;
@@ -4289,7 +4269,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
*self
}
}
@@ -4307,7 +4287,7 @@ pub mod longhands {
pub mod computed_value {
use cssparser::ToCss;
use std::fmt;
- use values::computed::{Context, ToComputedValue};
+ use values::computed::{TContext, ToComputedValue};
pub use values::computed::Time as SingleComputedValue;
@@ -4318,7 +4298,7 @@ pub mod longhands {
type ComputedValue = T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> T {
(*self).clone()
}
}
@@ -4363,7 +4343,6 @@ pub mod longhands {
// TODO(pcwalton): Multiple transitions.
<%self:longhand name="transition-timing-function">
use self::computed_value::{StartEnd, TransitionTimingFunction};
- use values::computed::Context;
use euclid::point::Point2D;
@@ -4487,7 +4466,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
(*self).clone()
}
}
@@ -4560,7 +4539,6 @@ pub mod longhands {
// TODO(pcwalton): Lots more properties.
<%self:longhand name="transition-property">
use self::computed_value::TransitionProperty;
- use values::computed::Context;
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
pub use self::computed_value::T as SpecifiedValue;
@@ -4807,7 +4785,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
(*self).clone()
}
}
@@ -5587,13 +5565,12 @@ mod property_bit_field {
% for property in LONGHANDS:
% if property.derived_from is None:
#[allow(non_snake_case)]
- fn substitute_variables_${property.ident}<F, R>(
+ fn substitute_variables_${property.ident}<F>(
value: &DeclaredValue<longhands::${property.ident}::SpecifiedValue>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
error_reporter: &mut Box<ParseErrorReporter + Send>)
- -> R
- where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) -> R
+ where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>)
{
if let DeclaredValue::WithVariables {
ref css, first_token_type, ref base_url, from_shorthand
@@ -5604,15 +5581,15 @@ mod property_bit_field {
from_shorthand,
custom_properties,
f,
- error_reporter)
+ error_reporter);
} else {
- f(value)
+ f(value);
}
}
#[allow(non_snake_case)]
#[inline(never)]
- fn substitute_variables_${property.ident}_slow<F, R>(
+ fn substitute_variables_${property.ident}_slow<F>(
css: &String,
first_token_type: TokenSerializationType,
base_url: &Url,
@@ -5620,9 +5597,7 @@ mod property_bit_field {
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
error_reporter: &mut Box<ParseErrorReporter + Send>)
- -> R
- where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>)
- -> R {
+ where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) {
f(&
::custom_properties::substitute(css, first_token_type, custom_properties)
.and_then(|css| {
@@ -5656,7 +5631,7 @@ mod property_bit_field {
// Invalid at computed-value time.
DeclaredValue::${"Inherit" if property.style_struct.inherited else "Initial"}
)
- )
+ );
}
% endif
% endfor
@@ -6087,8 +6062,58 @@ impl PropertyDeclaration {
}
}
+pub mod style_struct_traits {
+ use super::longhands;
+
+ % for style_struct in STYLE_STRUCTS:
+ pub trait T${style_struct.name}: Clone + PartialEq {
+ % for longhand in style_struct.longhands:
+ #[allow(non_snake_case)]
+ fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T);
+ #[allow(non_snake_case)]
+ fn copy_${longhand.ident}_from(&mut self, other: &Self);
+ % endfor
+ % if style_struct.name == "Animation":
+ fn transition_count(&self) -> usize;
+ % elif style_struct.name == "Border":
+ % for side in ["top", "right", "bottom", "left"]:
+ fn border_${side}_is_none_or_hidden_and_has_nonzero_width(&self) -> bool;
+ % endfor
+ % elif style_struct.name == "Box":
+ fn clone_display(&self) -> longhands::display::computed_value::T;
+ fn clone_position(&self) -> longhands::position::computed_value::T;
+ fn is_floated(&self) -> bool;
+ fn overflow_x_is_visible(&self) -> bool;
+ fn overflow_y_is_visible(&self) -> bool;
+ % elif style_struct.name == "Color":
+ fn clone_color(&self) -> longhands::color::computed_value::T;
+ % elif style_struct.name == "Font":
+ fn clone_font_size(&self) -> longhands::font_size::computed_value::T;
+ fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T;
+ fn compute_font_hash(&mut self);
+ % elif style_struct.name == "InheritedBox":
+ fn clone_direction(&self) -> longhands::direction::computed_value::T;
+ fn clone_writing_mode(&self) -> longhands::writing_mode::computed_value::T;
+ fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T;
+ % elif style_struct.name == "InheritedText":
+ #[allow(non_snake_case)]
+ fn clone__servo_text_decorations_in_effect(&self) ->
+ longhands::_servo_text_decorations_in_effect::computed_value::T;
+ % elif style_struct.name == "Outline":
+ fn outline_is_none_or_hidden_and_has_nonzero_width(&self) -> bool;
+ % elif style_struct.name == "Text":
+ fn has_underline(&self) -> bool;
+ fn has_overline(&self) -> bool;
+ fn has_line_through(&self) -> bool;
+ % endif
+ }
+ % endfor
+}
+
pub mod style_structs {
+ use fnv::FnvHasher;
use super::longhands;
+ use std::hash::{Hash, Hasher};
% for style_struct in STYLE_STRUCTS:
% if style_struct.name == "Font":
@@ -6116,7 +6141,132 @@ pub mod style_structs {
}
% endif
+ impl super::style_struct_traits::T${style_struct.name} for ${style_struct.name} {
+ % for longhand in style_struct.longhands:
+ fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
+ self.${longhand.ident} = v;
+ }
+ fn copy_${longhand.ident}_from(&mut self, other: &Self) {
+ self.${longhand.ident} = other.${longhand.ident}.clone();
+ }
+ % endfor
+ % if style_struct.name == "Animation":
+ fn transition_count(&self) -> usize {
+ self.transition_property.0.len()
+ }
+ % elif style_struct.name == "Border":
+ % for side in ["top", "right", "bottom", "left"]:
+ fn border_${side}_is_none_or_hidden_and_has_nonzero_width(&self) -> bool {
+ self.border_${side}_style.none_or_hidden() &&
+ self.border_${side}_width != ::app_units::Au(0)
+ }
+ % endfor
+ % elif style_struct.name == "Box":
+ fn clone_display(&self) -> longhands::display::computed_value::T {
+ self.display.clone()
+ }
+ fn clone_position(&self) -> longhands::position::computed_value::T {
+ self.position.clone()
+ }
+ fn is_floated(&self) -> bool {
+ self.float != longhands::float::SpecifiedValue::none
+ }
+ fn overflow_x_is_visible(&self) -> bool {
+ self.overflow_x == longhands::overflow_x::computed_value::T::visible
+ }
+ fn overflow_y_is_visible(&self) -> bool {
+ self.overflow_y.0 == longhands::overflow_x::computed_value::T::visible
+ }
+ % elif style_struct.name == "Color":
+ fn clone_color(&self) -> longhands::color::computed_value::T {
+ self.color.clone()
+ }
+ % elif style_struct.name == "Font":
+ fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
+ self.font_size.clone()
+ }
+ fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
+ self.font_weight.clone()
+ }
+ fn compute_font_hash(&mut self) {
+ // Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`.
+ let mut hasher: FnvHasher = Default::default();
+ hasher.write_u16(self.font_weight as u16);
+ self.font_stretch.hash(&mut hasher);
+ self.font_family.hash(&mut hasher);
+ self.hash = hasher.finish()
+ }
+ % elif style_struct.name == "InheritedBox":
+ fn clone_direction(&self) -> longhands::direction::computed_value::T {
+ self.direction.clone()
+ }
+ fn clone_writing_mode(&self) -> longhands::writing_mode::computed_value::T {
+ self.writing_mode.clone()
+ }
+ fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T {
+ self.text_orientation.clone()
+ }
+ % elif style_struct.name == "InheritedText":
+ fn clone__servo_text_decorations_in_effect(&self) ->
+ longhands::_servo_text_decorations_in_effect::computed_value::T {
+ self._servo_text_decorations_in_effect.clone()
+ }
+ % elif style_struct.name == "Outline":
+ fn outline_is_none_or_hidden_and_has_nonzero_width(&self) -> bool {
+ self.outline_style.none_or_hidden() && self.outline_width != ::app_units::Au(0)
+ }
+ % elif style_struct.name == "Text":
+ fn has_underline(&self) -> bool {
+ self.text_decoration.underline
+ }
+ fn has_overline(&self) -> bool {
+ self.text_decoration.overline
+ }
+ fn has_line_through(&self) -> bool {
+ self.text_decoration.line_through
+ }
+ % endif
+ }
+
+ % endfor
+}
+
+pub trait TComputedValues : Clone + Send + Sync + 'static {
+ % for style_struct in STYLE_STRUCTS:
+ type Concrete${style_struct.name}: style_struct_traits::T${style_struct.name};
+ % endfor
+
+ // Temporary bailout case for stuff we haven't made work with the trait
+ // yet - panics for non-Servo implementations.
+ //
+ // Used only for animations. Don't use it in other places.
+ fn as_servo<'a>(&'a self) -> &'a ComputedValues;
+ fn as_servo_mut<'a>(&'a mut self) -> &'a mut ComputedValues;
+
+ fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
+ shareable: bool,
+ writing_mode: WritingMode,
+ root_font_size: Au,
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: Arc<Self::Concrete${style_struct.name}>,
+ % endfor
+ ) -> Self;
+
+ fn initial_values() -> &'static Self;
+
+ fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(f: F);
+
+ % for style_struct in STYLE_STRUCTS:
+ fn clone_${style_struct.name.lower()}(&self) -> Arc<Self::Concrete${style_struct.name}>;
+ fn get_${style_struct.name.lower()}<'a>(&'a self) -> &'a Self::Concrete${style_struct.name};
+ fn mutate_${style_struct.name.lower()}<'a>(&'a mut self) -> &'a mut Self::Concrete${style_struct.name};
% endfor
+
+ fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>>;
+ fn root_font_size(&self) -> Au;
+ fn set_root_font_size(&mut self, size: Au);
+ fn set_writing_mode(&mut self, mode: WritingMode);
+ fn is_multicol(&self) -> bool;
}
#[derive(Clone, HeapSizeOf)]
@@ -6130,6 +6280,71 @@ pub struct ComputedValues {
pub root_font_size: Au,
}
+impl TComputedValues for ComputedValues {
+ % for style_struct in STYLE_STRUCTS:
+ type Concrete${style_struct.name} = style_structs::${style_struct.name};
+ % endfor
+
+ fn as_servo<'a>(&'a self) -> &'a ComputedValues { self }
+ fn as_servo_mut<'a>(&'a mut self) -> &'a mut ComputedValues { self }
+
+ fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
+ shareable: bool,
+ writing_mode: WritingMode,
+ root_font_size: Au,
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
+ % endfor
+ ) -> Self {
+ ComputedValues {
+ custom_properties: custom_properties,
+ shareable: shareable,
+ writing_mode: writing_mode,
+ root_font_size: root_font_size,
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: ${style_struct.ident},
+ % endfor
+ }
+ }
+
+ fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
+
+ fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(f: F) {
+ CASCADE_PROPERTY.with(|x| f(x));
+ }
+
+ % for style_struct in STYLE_STRUCTS:
+ #[inline]
+ fn clone_${style_struct.name.lower()}(&self) -> Arc<Self::Concrete${style_struct.name}> {
+ self.${style_struct.ident}.clone()
+ }
+ #[inline]
+ fn get_${style_struct.name.lower()}<'a>(&'a self) -> &'a Self::Concrete${style_struct.name} {
+ &self.${style_struct.ident}
+ }
+ #[inline]
+ fn mutate_${style_struct.name.lower()}<'a>(&'a mut self) -> &'a mut Self::Concrete${style_struct.name} {
+ Arc::make_mut(&mut self.${style_struct.ident})
+ }
+ % endfor
+
+ // 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())
+ }
+
+ fn root_font_size(&self) -> Au { self.root_font_size }
+ fn set_root_font_size(&mut self, size: Au) { self.root_font_size = size }
+ fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
+
+ #[inline]
+ fn is_multicol(&self) -> bool {
+ let style = self.get_column();
+ style.column_count.0.is_some() || style.column_width.0.is_some()
+ }
+}
+
impl ComputedValues {
/// Resolves the currentColor keyword.
/// Any color value form computed values (except for the 'color' property itself)
@@ -6231,12 +6446,6 @@ impl ComputedValues {
}
#[inline]
- pub fn is_multicol(&self) -> bool {
- let style = self.get_column();
- style.column_count.0.is_some() || style.column_width.0.is_some()
- }
-
- #[inline]
pub fn get_font_arc(&self) -> Arc<style_structs::Font> {
self.font.clone()
}
@@ -6301,19 +6510,6 @@ impl ComputedValues {
false
}
- % for style_struct in STYLE_STRUCTS:
- #[inline]
- pub fn get_${style_struct.name.lower()}
- <'a>(&'a self) -> &'a style_structs::${style_struct.name} {
- &*self.${style_struct.ident}
- }
- #[inline]
- pub fn mutate_${style_struct.name.lower()}
- <'a>(&'a mut self) -> &'a mut style_structs::${style_struct.name} {
- &mut *Arc::make_mut(&mut self.${style_struct.ident})
- }
- % endfor
-
pub fn computed_value_to_string(&self, name: &str) -> Result<String, ()> {
match name {
% for style_struct in STYLE_STRUCTS:
@@ -6333,16 +6529,16 @@ impl ComputedValues {
/// Return a WritingMode bitflags from the relevant CSS properties.
-pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> WritingMode {
+pub fn get_writing_mode<S: style_struct_traits::TInheritedBox>(inheritedbox_style: &S) -> WritingMode {
use logical_geometry;
let mut flags = WritingMode::empty();
- match inheritedbox_style.direction {
+ match inheritedbox_style.clone_direction() {
computed_values::direction::T::ltr => {},
computed_values::direction::T::rtl => {
flags.insert(logical_geometry::FLAG_RTL);
},
}
- match inheritedbox_style.writing_mode {
+ match inheritedbox_style.clone_writing_mode() {
computed_values::writing_mode::T::horizontal_tb => {},
computed_values::writing_mode::T::vertical_rl => {
flags.insert(logical_geometry::FLAG_VERTICAL);
@@ -6352,7 +6548,7 @@ pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> Wri
flags.insert(logical_geometry::FLAG_VERTICAL_LR);
},
}
- match inheritedbox_style.text_orientation {
+ match inheritedbox_style.clone_text_orientation() {
computed_values::text_orientation::T::sideways_right => {},
computed_values::text_orientation::T::sideways_left => {
flags.insert(logical_geometry::FLAG_VERTICAL_LR);
@@ -6369,7 +6565,7 @@ pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> Wri
/// The initial values for all style structs as defined by the specification.
lazy_static! {
- pub static ref INITIAL_VALUES: ComputedValues = ComputedValues {
+ pub static ref INITIAL_SERVO_VALUES: ComputedValues = ComputedValues {
% for style_struct in STYLE_STRUCTS:
${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
% for longhand in style_struct.longhands:
@@ -6389,35 +6585,34 @@ lazy_static! {
/// Fast path for the function below. Only computes new inherited styles.
-#[allow(unused_mut)]
-fn cascade_with_cached_declarations(
+#[allow(unused_mut, unused_imports)]
+fn cascade_with_cached_declarations<C: TComputedValues>(
viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool,
- parent_style: &ComputedValues,
- cached_style: &ComputedValues,
+ parent_style: &C,
+ cached_style: &C,
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
mut error_reporter: Box<ParseErrorReporter + Send>)
- -> ComputedValues {
+ -> C {
let mut context = computed::Context {
is_root_element: false,
viewport_size: viewport_size,
inherited_style: parent_style,
- style: ComputedValues {
+ style: C::new(
+ custom_properties,
+ shareable,
+ WritingMode::empty(),
+ parent_style.root_font_size(),
% for style_struct in STYLE_STRUCTS:
- ${style_struct.ident}:
- % if style_struct.inherited:
- parent_style
- % else:
- cached_style
- % endif
- .${style_struct.ident}.clone(),
+ % if style_struct.inherited:
+ parent_style
+ % else:
+ cached_style
+ % endif
+ .clone_${style_struct.name.lower()}(),
% endfor
- custom_properties: custom_properties,
- shareable: shareable,
- writing_mode: WritingMode::empty(),
- root_font_size: parent_style.root_font_size,
- },
+ ),
};
let mut seen = PropertyBitField::new();
// Declaration blocks are stored in increasing precedence order,
@@ -6432,42 +6627,47 @@ fn cascade_with_cached_declarations(
PropertyDeclaration::${property.camel_case}(ref
${'_' if not style_struct.inherited else ''}declared_value)
=> {
+ use properties::style_struct_traits::T${style_struct.name};
% if style_struct.inherited:
if seen.get_${property.ident}() {
continue
}
seen.set_${property.ident}();
- let computed_value =
+ let custom_props = context.style().custom_properties();
substitute_variables_${property.ident}(
- declared_value, &context.style.custom_properties,
+ declared_value, &custom_props,
|value| match *value {
DeclaredValue::Value(ref specified_value)
- => specified_value.to_computed_value(&context),
+ => {
+ let computed = specified_value.to_computed_value(&context);
+ context.mutate_style().mutate_${style_struct.name.lower()}()
+ .set_${property.ident}(computed);
+ },
DeclaredValue::Initial
- => longhands::${property.ident}::get_initial_value(),
+ => {
+ // FIXME(bholley): We may want set_X_to_initial_value() here.
+ let initial = longhands::${property.ident}::get_initial_value();
+ context.mutate_style().mutate_${style_struct.name.lower()}()
+ .set_${property.ident}(initial);
+ },
DeclaredValue::Inherit => {
// This is a bit slow, but this is rare so it shouldn't
// matter.
//
// FIXME: is it still?
- parent_style.${style_struct.ident}
- .${property.ident}
- .clone()
+ let inherited_struct = parent_style.get_${style_struct.ident}();
+ context.mutate_style().mutate_${style_struct.name.lower()}()
+ .copy_${property.ident}_from(inherited_struct);
}
DeclaredValue::WithVariables { .. } => unreachable!()
}, &mut error_reporter
);
- Arc::make_mut(&mut context.style.${style_struct.ident})
- .${property.ident} = computed_value;
% endif
% if property.name in DERIVED_LONGHANDS:
% for derived in DERIVED_LONGHANDS[property.name]:
- Arc::make_mut(&mut context.style.${derived.style_struct.ident})
- .${derived.ident} =
longhands::${derived.ident}
- ::derive_from_${property.ident}(
- &context);
+ ::derive_from_${property.ident}(&mut context);
% endfor
% endif
}
@@ -6485,23 +6685,25 @@ fn cascade_with_cached_declarations(
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() {
- compute_font_hash(&mut *Arc::make_mut(&mut context.style.font))
+ use properties::style_struct_traits::TFont;
+ context.mutate_style().mutate_font().compute_font_hash();
}
context.style
}
-type CascadePropertyFn = extern "Rust" fn(declaration: &PropertyDeclaration,
- inherited_style: &ComputedValues,
- context: &mut computed::Context,
- seen: &mut PropertyBitField,
- cacheable: &mut bool,
- error_reporter: &mut Box<ParseErrorReporter + Send>);
+pub type CascadePropertyFn<C: TComputedValues> =
+ extern "Rust" fn(declaration: &PropertyDeclaration,
+ inherited_style: &C,
+ context: &mut computed::Context<C>,
+ seen: &mut PropertyBitField,
+ cacheable: &mut bool,
+ error_reporter: &mut Box<ParseErrorReporter + Send>);
// This is a thread-local rather than a lazy static to avoid atomic operations when cascading
// properties.
-thread_local!(static CASCADE_PROPERTY: Vec<Option<CascadePropertyFn>> = {
- let mut result: Vec<Option<CascadePropertyFn>> = Vec::new();
+thread_local!(static CASCADE_PROPERTY: Vec<Option<CascadePropertyFn<ComputedValues>>> = {
+ let mut result: Vec<Option<CascadePropertyFn<ComputedValues>>> = Vec::new();
% for style_struct in STYLE_STRUCTS:
% for property in style_struct.longhands:
let discriminant;
@@ -6537,19 +6739,22 @@ thread_local!(static CASCADE_PROPERTY: Vec<Option<CascadePropertyFn>> = {
/// this is ignored.
///
/// Returns the computed values and a boolean indicating whether the result is cacheable.
-pub fn cascade(viewport_size: Size2D<Au>,
+pub fn cascade<C: TComputedValues>(
+ viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool,
- parent_style: Option< &ComputedValues >,
- cached_style: Option< &ComputedValues >,
+ parent_style: Option< &C >,
+ cached_style: Option< &C >,
mut error_reporter: Box<ParseErrorReporter + Send>)
- -> (ComputedValues, bool) {
- let initial_values = &*INITIAL_VALUES;
+ -> (C, bool) {
+ use properties::style_struct_traits::{TBorder, TBox, TColor, TFont, TOutline};
+ let initial_values = C::initial_values();
let (is_root_element, inherited_style) = match parent_style {
Some(parent_style) => (false, parent_style),
None => (true, initial_values),
};
+ let inherited_custom_properties = inherited_style.custom_properties();
let mut custom_properties = None;
let mut seen_custom = HashSet::new();
for sub_list in applicable_declarations.iter().rev() {
@@ -6558,7 +6763,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
match *declaration {
PropertyDeclaration::Custom(ref name, ref value) => {
::custom_properties::cascade(
- &mut custom_properties, &inherited_style.custom_properties,
+ &mut custom_properties, &inherited_custom_properties,
&mut seen_custom, name, value)
}
_ => {}
@@ -6566,7 +6771,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
}
}
let custom_properties = ::custom_properties::finish_cascade(
- custom_properties, &inherited_style.custom_properties);
+ custom_properties, &inherited_custom_properties);
if let (Some(cached_style), Some(parent_style)) = (cached_style, parent_style) {
let style = cascade_with_cached_declarations(viewport_size,
@@ -6583,21 +6788,20 @@ pub fn cascade(viewport_size: Size2D<Au>,
is_root_element: is_root_element,
viewport_size: viewport_size,
inherited_style: inherited_style,
- style: ComputedValues {
+ style: C::new(
+ custom_properties,
+ shareable,
+ WritingMode::empty(),
+ inherited_style.root_font_size(),
% for style_struct in STYLE_STRUCTS:
- ${style_struct.ident}:
- % if style_struct.inherited:
- inherited_style
- % else:
- initial_values
- % endif
- .${style_struct.ident}.clone(),
+ % if style_struct.inherited:
+ inherited_style
+ % else:
+ initial_values
+ % endif
+ .clone_${style_struct.name.lower()}(),
% endfor
- custom_properties: custom_properties,
- shareable: shareable,
- writing_mode: WritingMode::empty(),
- root_font_size: inherited_style.root_font_size,
- },
+ ),
};
// Set computed values, overwriting earlier declarations for the same property.
@@ -6609,7 +6813,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
// We could (and used to) use a pattern match here, but that bloats this function to over 100K
// of compiled code! To improve i-cache behavior, we outline the individual functions and use
// virtual dispatch instead.
- CASCADE_PROPERTY.with(|cascade_property| {
+ C::do_cascade_property(|cascade_property| {
% for category_to_cascade_now in ["early", "other"]:
for sub_list in applicable_declarations.iter().rev() {
// Declarations are already stored in reverse order.
@@ -6655,14 +6859,14 @@ pub fn cascade(viewport_size: Size2D<Au>,
let mut style = context.style;
- let positioned = matches!(style.box_.position,
+ let positioned = matches!(style.get_box().clone_position(),
longhands::position::SpecifiedValue::absolute |
longhands::position::SpecifiedValue::fixed);
- let floated = style.box_.float != longhands::float::SpecifiedValue::none;
+ let floated = style.get_box().is_floated();
if positioned || floated || is_root_element {
use computed_values::display::T;
- let specified_display = style.box_.display;
+ let specified_display = style.get_box().clone_display();
let computed_display = match specified_display {
T::inline_table => {
Some(T::table)
@@ -6677,26 +6881,26 @@ pub fn cascade(viewport_size: Size2D<Au>,
_ => None
};
if let Some(computed_display) = computed_display {
- let box_ = Arc::make_mut(&mut style.box_);
- box_.display = computed_display;
- box_._servo_display_for_hypothetical_box = if is_root_element {
+ let box_ = style.mutate_box();
+ box_.set_display(computed_display);
+ box_.set__servo_display_for_hypothetical_box(if is_root_element {
computed_display
} else {
specified_display
- };
+ });
}
}
{
use computed_values::overflow_x::T as overflow;
use computed_values::overflow_y;
- match (style.box_.overflow_x, style.box_.overflow_y.0) {
- (overflow::visible, overflow::visible) => {}
- (overflow::visible, _) => {
- Arc::make_mut(&mut style.box_).overflow_x = overflow::auto
+ match (style.get_box().overflow_x_is_visible(), style.get_box().overflow_y_is_visible()) {
+ (true, true) => {}
+ (true, _) => {
+ style.mutate_box().set_overflow_x(overflow::auto);
}
- (_, overflow::visible) => {
- Arc::make_mut(&mut style.box_).overflow_y = overflow_y::T(overflow::auto)
+ (_, true) => {
+ style.mutate_box().set_overflow_y(overflow_y::T(overflow::auto));
}
_ => {}
}
@@ -6705,27 +6909,29 @@ pub fn cascade(viewport_size: Size2D<Au>,
// The initial value of border-*-width may be changed at computed value time.
% for side in ["top", "right", "bottom", "left"]:
// Like calling to_computed_value, which wouldn't type check.
- if style.border.border_${side}_style.none_or_hidden() &&
- style.border.border_${side}_width != Au(0) {
- Arc::make_mut(&mut style.border).border_${side}_width = Au(0);
+ if style.get_border().border_${side}_is_none_or_hidden_and_has_nonzero_width() {
+ style.mutate_border().set_border_${side}_width(Au(0));
}
% endfor
// The initial value of outline width may be changed at computed value time.
- if style.outline.outline_style.none_or_hidden() && style.outline.outline_width != Au(0) {
- Arc::make_mut(&mut style.outline).outline_width = Au(0);
+ if style.get_outline().outline_is_none_or_hidden_and_has_nonzero_width() {
+ style.mutate_outline().set_outline_width(Au(0));
}
if is_root_element {
- style.root_font_size = style.font.font_size;
+ let s = style.get_font().clone_font_size();
+ style.set_root_font_size(s);
}
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() {
- compute_font_hash(&mut *Arc::make_mut(&mut style.font))
+ use properties::style_struct_traits::TFont;
+ style.mutate_font().compute_font_hash();
}
- style.writing_mode = get_writing_mode(&*style.inheritedbox);
+ let mode = get_writing_mode(style.get_inheritedbox());
+ style.set_writing_mode(mode);
(style, cacheable)
}
@@ -6930,12 +7136,3 @@ macro_rules! longhand_properties_idents {
}
}
}
-
-/// Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`.
-fn compute_font_hash(font: &mut style_structs::Font) {
- let mut hasher: FnvHasher = Default::default();
- hasher.write_u16(font.font_weight as u16);
- font.font_stretch.hash(&mut hasher);
- font.font_family.hash(&mut hasher);
- font.hash = hasher.finish()
-}
diff --git a/components/style/servo.rs b/components/style/servo.rs
index 56aef8f6210..10867d4eaf8 100644
--- a/components/style/servo.rs
+++ b/components/style/servo.rs
@@ -3,13 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use context;
use data;
+use properties::ComputedValues;
use selector_impl::ServoSelectorImpl;
use selector_matching;
use stylesheets;
/// Concrete types for servo Style implementation
pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>;
-pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl>;
+pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl, ComputedValues>;
pub type Stylist = selector_matching::Stylist<ServoSelectorImpl>;
pub type StylistWrapper = context::StylistWrapper<ServoSelectorImpl>;
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index 79759cf26b9..f39347e83ab 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -123,7 +123,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
root: OpaqueNode,
node: N)
where N: TNode,
- C: StyleContext<'a, <N::ConcreteElement as Element>::Impl>,
+ C: StyleContext<'a, <N::ConcreteElement as Element>::Impl, N::ConcreteComputedValues>,
<N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
// Initialize layout data.
//
@@ -195,7 +195,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
// Add ourselves to the LRU cache.
if let Some(element) = shareable_element {
- style_sharing_candidate_cache.insert_if_possible(&element);
+ style_sharing_candidate_cache.insert_if_possible::<'ln, N>(&element);
}
}
StyleSharingResult::StyleWasShared(index, damage) => {
diff --git a/components/style/values.rs b/components/style/values.rs
index b35a2ca0766..69cd83309fc 100644
--- a/components/style/values.rs
+++ b/components/style/values.rs
@@ -100,6 +100,7 @@ pub mod specified {
use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType;
use super::AuExtensionMethods;
+ use super::computed::{TContext, ToComputedValue};
use super::{CSSFloat, FONT_MEDIUM_PX};
use url::Url;
@@ -1418,11 +1419,11 @@ pub mod specified {
}
}
- impl super::computed::ToComputedValue for Time {
+ impl ToComputedValue for Time {
type ComputedValue = Time;
#[inline]
- fn to_computed_value(&self, _: &super::computed::Context) -> Time {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> Time {
*self
}
}
@@ -1437,7 +1438,8 @@ pub mod specified {
pub mod computed {
use app_units::Au;
use euclid::size::Size2D;
- use properties::ComputedValues;
+ use properties::TComputedValues;
+ use properties::style_struct_traits::TFont;
use std::fmt;
use super::AuExtensionMethods;
use super::specified::AngleOrCorner;
@@ -1446,21 +1448,39 @@ pub mod computed {
pub use cssparser::Color as CSSColor;
pub use super::specified::{Angle, BorderStyle, Time};
- pub struct Context<'a> {
+ pub trait TContext {
+ type ConcreteComputedValues: TComputedValues;
+ fn is_root_element(&self) -> bool;
+ fn viewport_size(&self) -> Size2D<Au>;
+ fn inherited_style(&self) -> &Self::ConcreteComputedValues;
+ fn style(&self) -> &Self::ConcreteComputedValues;
+ fn mutate_style(&mut self) -> &mut Self::ConcreteComputedValues;
+ }
+
+ pub struct Context<'a, C: TComputedValues> {
pub is_root_element: bool,
pub viewport_size: Size2D<Au>,
- pub inherited_style: &'a ComputedValues,
+ pub inherited_style: &'a C,
/// Values access through this need to be in the properties "computed early":
/// color, text-decoration, font-size, display, position, float, border-*-style, outline-style
- pub style: ComputedValues,
+ pub style: C,
+ }
+
+ impl<'a, C: TComputedValues> TContext for Context<'a, C> {
+ type ConcreteComputedValues = C;
+ fn is_root_element(&self) -> bool { self.is_root_element }
+ fn viewport_size(&self) -> Size2D<Au> { self.viewport_size }
+ fn inherited_style(&self) -> &C { &self.inherited_style }
+ fn style(&self) -> &C { &self.style }
+ fn mutate_style(&mut self) -> &mut C { &mut self.style }
}
pub trait ToComputedValue {
type ComputedValue;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue;
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> Self::ComputedValue;
}
pub trait ComputedValueAsSpecified {}
@@ -1469,7 +1489,7 @@ pub mod computed {
type ComputedValue = T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> T {
self.clone()
}
}
@@ -1478,7 +1498,7 @@ pub mod computed {
type ComputedValue = CSSColor;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> CSSColor {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> CSSColor {
self.parsed
}
}
@@ -1489,17 +1509,17 @@ pub mod computed {
type ComputedValue = Au;
#[inline]
- fn to_computed_value(&self, context: &Context) -> Au {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Au {
match *self {
specified::Length::Absolute(length) => length,
specified::Length::Calc(calc) => calc.to_computed_value(context).length(),
specified::Length::FontRelative(length) =>
- length.to_computed_value(context.style.get_font().font_size,
- context.style.root_font_size),
+ length.to_computed_value(context.style().get_font().clone_font_size(),
+ context.style().root_font_size()),
specified::Length::ViewportPercentage(length) =>
- length.to_computed_value(context.viewport_size),
+ length.to_computed_value(context.viewport_size()),
specified::Length::ServoCharacterWidth(length) =>
- length.to_computed_value(context.style.get_font().font_size)
+ length.to_computed_value(context.style().get_font().clone_font_size())
}
}
}
@@ -1583,7 +1603,7 @@ pub mod computed {
impl ToComputedValue for specified::CalcLengthOrPercentage {
type ComputedValue = CalcLengthOrPercentage;
- fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> CalcLengthOrPercentage {
let mut length = None;
if let Some(absolute) = self.absolute {
@@ -1593,13 +1613,13 @@ pub mod computed {
for val in &[self.vw, self.vh, self.vmin, self.vmax] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) +
- val.to_computed_value(context.viewport_size));
+ val.to_computed_value(context.viewport_size()));
}
}
for val in &[self.ch, self.em, self.ex, self.rem] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) + val.to_computed_value(
- context.style.get_font().font_size, context.style.root_font_size));
+ context.style().get_font().clone_font_size(), context.style().root_font_size()));
}
}
@@ -1621,7 +1641,7 @@ pub mod computed {
type ComputedValue = BorderRadiusSize;
#[inline]
- fn to_computed_value(&self, context: &Context) -> BorderRadiusSize {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> BorderRadiusSize {
let specified::BorderRadiusSize(s) = *self;
let w = s.width.to_computed_value(context);
let h = s.height.to_computed_value(context);
@@ -1664,7 +1684,7 @@ pub mod computed {
impl ToComputedValue for specified::LengthOrPercentage {
type ComputedValue = LengthOrPercentage;
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentage {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentage {
match *self {
specified::LengthOrPercentage::Length(value) => {
LengthOrPercentage::Length(value.to_computed_value(context))
@@ -1712,7 +1732,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrAuto;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrAuto {
match *self {
specified::LengthOrPercentageOrAuto::Length(value) => {
LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
@@ -1764,7 +1784,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrNone;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrNone {
match *self {
specified::LengthOrPercentageOrNone::Length(value) => {
LengthOrPercentageOrNone::Length(value.to_computed_value(context))
@@ -1812,7 +1832,7 @@ pub mod computed {
type ComputedValue = LengthOrNone;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrNone {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrNone {
match *self {
specified::LengthOrNone::Length(specified::Length::Calc(calc)) => {
LengthOrNone::Length(calc.to_computed_value(context).length())
@@ -1840,7 +1860,7 @@ pub mod computed {
type ComputedValue = Image;
#[inline]
- fn to_computed_value(&self, context: &Context) -> Image {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Image {
match *self {
specified::Image::Url(ref url) => Image::Url(url.clone()),
specified::Image::LinearGradient(ref linear_gradient) => {
@@ -1936,7 +1956,7 @@ pub mod computed {
type ComputedValue = LinearGradient;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LinearGradient {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LinearGradient {
let specified::LinearGradient {
angle_or_corner,
ref stops
diff --git a/components/style/viewport.rs b/components/style/viewport.rs
index 53c6d5bcbc2..f2da78088e4 100644
--- a/components/style/viewport.rs
+++ b/components/style/viewport.rs
@@ -8,7 +8,7 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser,
use euclid::scale_factor::ScaleFactor;
use euclid::size::{Size2D, TypedSize2D};
use parser::{ParserContext, log_css_error};
-use properties::INITIAL_VALUES;
+use properties::{ComputedValues, TComputedValues};
use std::ascii::AsciiExt;
use std::collections::hash_map::{Entry, HashMap};
use std::fmt;
@@ -594,8 +594,8 @@ impl MaybeNew for ViewportConstraints {
let context = Context {
is_root_element: false,
viewport_size: initial_viewport,
- inherited_style: &*INITIAL_VALUES,
- style: INITIAL_VALUES.clone(),
+ inherited_style: ComputedValues::initial_values(),
+ style: ComputedValues::initial_values().clone(),
};
// DEVICE-ADAPT § 9.3 Resolving 'extend-to-zoom'