mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #10155 - bholley:generalize_style_structs, r=SimonSapin
Generalize the style structs This allows geckolib to pass gecko style structs and have the style system write to them directly, provided we implement all the traits. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10155) <!-- Reviewable:end -->
This commit is contained in:
commit
605842f193
47 changed files with 995 additions and 433 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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>;
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue