diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index 5526c449247..5ea15926f97 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -265,9 +265,10 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { .current_styles().pseudos.contains_key(&style_pseudo) { let mut data = self.get_style_data().unwrap().borrow_mut(); let new_style = - context.stylist - .precomputed_values_for_pseudo(&style_pseudo, - Some(&data.current_styles().primary)); + context.stylist.precomputed_values_for_pseudo( + &style_pseudo, + Some(&data.current_styles().primary), + false); data.current_pseudos_mut() .insert(style_pseudo.clone(), new_style.unwrap()); } diff --git a/components/style/animation.rs b/components/style/animation.rs index bf74fa643f2..3cdc057d532 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -9,7 +9,7 @@ use context::SharedStyleContext; use dom::{OpaqueNode, UnsafeNode}; use euclid::point::Point2D; use keyframes::{KeyframesStep, KeyframesStepValue}; -use properties::{self, ComputedValues, Importance}; +use properties::{self, CascadeFlags, ComputedValues, Importance}; use properties::animated_properties::{AnimatedProperty, TransitionProperty}; use properties::longhands::animation_direction::computed_value::AnimationDirection; use properties::longhands::animation_iteration_count::computed_value::AnimationIterationCount; @@ -397,11 +397,11 @@ fn compute_style_for_animation_step(context: &SharedStyleContext, }; let (computed, _) = properties::cascade(context.viewport_size, &[declaration_block], - false, Some(previous_style), None, None, - context.error_reporter.clone()); + context.error_reporter.clone(), + CascadeFlags::empty()); computed } } diff --git a/components/style/matching.rs b/components/style/matching.rs index 6f92e3e9144..a7c7769788d 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -13,7 +13,7 @@ use cascade_info::CascadeInfo; use context::{SharedStyleContext, StyleContext}; use data::{NodeStyles, PseudoStyles}; use dom::{NodeInfo, TElement, TNode, TRestyleDamage, UnsafeNode}; -use properties::{ComputedValues, cascade}; +use properties::{CascadeFlags, ComputedValues, SHAREABLE, cascade}; use properties::longhands::display::computed_value as display; use selector_impl::{PseudoElement, TheSelectorImpl}; use selector_matching::{ApplicableDeclarationBlock, Stylist}; @@ -489,6 +489,8 @@ pub enum StyleSharingResult { // Callers need to pass several boolean flags to cascade_node_pseudo_element. // We encapsulate them in this struct to avoid mixing them up. +// +// FIXME(pcwalton): Unify with `CascadeFlags`, perhaps? struct CascadeBooleans { shareable: bool, cacheable: bool, @@ -523,6 +525,11 @@ trait PrivateMatchMethods: TNode { cacheable = cacheable && !has_style_attribute; let mut cascade_info = CascadeInfo::new(); + let mut cascade_flags = CascadeFlags::empty(); + if booleans.shareable { + cascade_flags.insert(SHAREABLE) + } + let (this_style, is_cacheable) = match parent_style { Some(ref parent_style) => { let cache_entry = applicable_declarations_cache.find(applicable_declarations); @@ -533,20 +540,20 @@ trait PrivateMatchMethods: TNode { cascade(shared_context.viewport_size, applicable_declarations, - booleans.shareable, Some(&***parent_style), cached_computed_values, Some(&mut cascade_info), - shared_context.error_reporter.clone()) + shared_context.error_reporter.clone(), + cascade_flags) } None => { cascade(shared_context.viewport_size, applicable_declarations, - booleans.shareable, None, None, Some(&mut cascade_info), - shared_context.error_reporter.clone()) + shared_context.error_reporter.clone(), + cascade_flags) } }; cascade_info.finish(self); diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index bfa7c7e9edf..d5a42102a7c 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1524,6 +1524,17 @@ static CASCADE_PROPERTY: [CascadePropertyFn; ${len(data.longhands)}] = [ % endfor ]; +bitflags! { + pub flags CascadeFlags: u8 { + /// Whether the `ComputedValues` structure to be constructed should be considered + /// shareable. + const SHAREABLE = 0x01, + /// Whether to inherit all styles from the parent. If this flag is not present, + /// non-inherited styles are reset to their initial values. + const INHERIT_ALL = 0x02, + } +} + /// Performs the CSS cascade, computing new styles for an element from its parent style and /// optionally a cached related style. The arguments are: /// @@ -1531,9 +1542,6 @@ static CASCADE_PROPERTY: [CascadePropertyFn; ${len(data.longhands)}] = [ /// /// * `applicable_declarations`: The list of CSS rules that matched. /// -/// * `shareable`: Whether the `ComputedValues` structure to be constructed should be considered -/// shareable. -/// /// * `parent_style`: The parent style, if applicable; if `None`, this is the root node. /// /// * `cached_style`: If present, cascading is short-circuited for everything but inherited @@ -1541,14 +1549,16 @@ static CASCADE_PROPERTY: [CascadePropertyFn; ${len(data.longhands)}] = [ /// this that it is safe to only provide inherited declarations. If `parent_style` is `None`, /// this is ignored. /// +/// * `flags`: Various flags. +/// /// Returns the computed values and a boolean indicating whether the result is cacheable. pub fn cascade(viewport_size: Size2D, applicable_declarations: &[ApplicableDeclarationBlock], - shareable: bool, parent_style: Option<<&ComputedValues>, cached_style: Option<<&ComputedValues>, mut cascade_info: Option<<&mut CascadeInfo>, - mut error_reporter: StdBox) + mut error_reporter: StdBox, + flags: CascadeFlags) -> (ComputedValues, bool) { let initial_values = ComputedValues::initial_values(); let (is_root_element, inherited_style) = match parent_style { @@ -1582,7 +1592,7 @@ pub fn cascade(viewport_size: Size2D, if let (Some(cached_style), Some(parent_style)) = (cached_style, parent_style) { let style = cascade_with_cached_declarations(viewport_size, &applicable_declarations, - shareable, + flags.contains(SHAREABLE), parent_style, cached_style, custom_properties, @@ -1591,24 +1601,35 @@ pub fn cascade(viewport_size: Size2D, return (style, false) } + let starting_style = if !flags.contains(INHERIT_ALL) { + ComputedValues::new(custom_properties, + flags.contains(SHAREABLE), + WritingMode::empty(), + inherited_style.root_font_size(), + % for style_struct in data.active_style_structs(): + % if style_struct.inherited: + inherited_style.clone_${style_struct.name_lower}(), + % else: + initial_values.clone_${style_struct.name_lower}(), + % endif + % endfor + ) + } else { + ComputedValues::new(custom_properties, + flags.contains(SHAREABLE), + WritingMode::empty(), + inherited_style.root_font_size(), + % for style_struct in data.active_style_structs(): + inherited_style.clone_${style_struct.name_lower}(), + % endfor + ) + }; + let mut context = computed::Context { is_root_element: is_root_element, viewport_size: viewport_size, inherited_style: inherited_style, - style: ComputedValues::new( - custom_properties, - shareable, - WritingMode::empty(), - inherited_style.root_font_size(), - % for style_struct in data.active_style_structs(): - % if style_struct.inherited: - inherited_style - % else: - initial_values - % endif - .clone_${style_struct.name_lower}(), - % endfor - ), + style: starting_style, }; // Set computed values, overwriting earlier declarations for the same property. diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index 1b3ee9c3432..ebd5e9b29eb 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -10,7 +10,8 @@ use error_reporting::StdoutErrorReporter; use keyframes::KeyframesAnimation; use media_queries::{Device, MediaType}; use parking_lot::{RwLock, RwLockReadGuard}; -use properties::{self, PropertyDeclaration, PropertyDeclarationBlock, ComputedValues, Importance}; +use properties::{self, CascadeFlags, ComputedValues, INHERIT_ALL, Importance}; +use properties::{PropertyDeclaration, PropertyDeclarationBlock}; use quickersort::sort_by; use restyle_hints::{RestyleHint, DependencySet}; use selector_impl::{ElementExt, TheSelectorImpl, PseudoElement}; @@ -252,19 +253,30 @@ impl Stylist { /// Computes the style for a given "precomputed" pseudo-element, taking the /// universal rules and applying them. + /// + /// If `inherit_all` is true, then all properties are inherited from the parent; otherwise, + /// non-inherited properties are reset to their initial values. The flow constructor uses this + /// flag when constructing anonymous flows. pub fn precomputed_values_for_pseudo(&self, pseudo: &PseudoElement, - parent: Option<&Arc>) + parent: Option<&Arc>, + inherit_all: bool) -> Option> { debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_precomputed()); if let Some(declarations) = self.precomputed_pseudo_element_decls.get(pseudo) { + let mut flags = CascadeFlags::empty(); + if inherit_all { + flags.insert(INHERIT_ALL) + } + let (computed, _) = properties::cascade(self.device.au_viewport_size(), - &declarations, false, + &declarations, parent.map(|p| &**p), None, None, - Box::new(StdoutErrorReporter)); + Box::new(StdoutErrorReporter), + flags); Some(Arc::new(computed)) } else { parent.map(|p| p.clone()) @@ -325,10 +337,12 @@ impl Stylist { let (computed, _) = properties::cascade(self.device.au_viewport_size(), - &declarations, false, - Some(&**parent), None, None, - Box::new(StdoutErrorReporter)); - + &declarations, + Some(&**parent), + None, + None, + Box::new(StdoutErrorReporter), + CascadeFlags::empty()); Some(Arc::new(computed)) } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 49f62c0d726..07ea507b533 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -37,7 +37,7 @@ use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong}; use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI}; use style::parallel; use style::parser::{ParserContext, ParserContextExtraData}; -use style::properties::{ComputedValues, Importance, PropertyDeclaration}; +use style::properties::{CascadeFlags, ComputedValues, Importance, PropertyDeclaration}; use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock}; use style::properties::{cascade, parse_one_declaration}; use style::selector_impl::PseudoElementCascadeType; @@ -143,11 +143,11 @@ pub extern "C" fn Servo_RestyleWithAddedDeclaration(declarations: RawServoDeclar // FIXME (bug 1303229): Use the actual viewport size here let (computed, _) = cascade(Size2D::new(Au(0), Au(0)), &[declaration_block], - false, Some(previous_style), None, None, - Box::new(StdoutErrorReporter)); + Box::new(StdoutErrorReporter), + CascadeFlags::empty()); Arc::new(computed).into_strong() } @@ -282,7 +282,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null); - let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent); + let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent, false); new_computed.map_or(Strong::null(), |c| c.into_strong()) }