diff options
-rw-r--r-- | components/style/gecko/generated/bindings.rs | 13 | ||||
-rw-r--r-- | components/style/rule_tree/mod.rs | 19 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 112 |
3 files changed, 117 insertions, 27 deletions
diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 404e072b04e..3ffab7ccf56 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -3005,6 +3005,19 @@ extern "C" { -> ServoStyleContextStrong; } extern "C" { + pub fn Servo_StyleSet_GetComputedValuesByAddingAnimation(set: + RawServoStyleSetBorrowed, + element: + RawGeckoElementBorrowed, + existing_style: + ServoStyleContextBorrowed, + snapshots: + *const ServoElementSnapshotTable, + animation: + RawServoAnimationValueBorrowed) + -> ServoStyleContextStrong; +} +extern "C" { pub fn Servo_SerializeFontValueForCanvas(declarations: RawServoDeclarationBlockBorrowed, buffer: *mut nsAString); diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index 49c42a7f223..02c329257ac 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -446,6 +446,25 @@ impl RuleTree { let rule = self.insert_ordered_rules_from(last.parent().unwrap().clone(), children.drain().rev()); rule } + + /// Returns new rule node by adding animation rules at transition level. + /// The additional rules must be appropriate for the transition + /// level of the cascade, which is the highest level of the cascade. + /// (This is the case for one current caller, the cover rule used + /// for CSS transitions.) + pub fn add_animation_rules_at_transition_level( + &self, + path: &StrongRuleNode, + pdb: Arc<Locked<PropertyDeclarationBlock>>, + guards: &StylesheetGuards, + ) -> StrongRuleNode { + let mut dummy = false; + self.update_rule_at_level(CascadeLevel::Transitions, + Some(pdb.borrow_arc()), + path, + guards, + &mut dummy).expect("Should return a valid rule node") + } } /// The number of RuleNodes added to the free list before we will consider diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 8ee26bd398a..98b7cde6866 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -123,7 +123,7 @@ use style::properties::animated_properties::AnimationValue; use style::properties::animated_properties::compare_property_priority; use style::properties::parse_one_declaration_into; use style::rule_cache::RuleCacheConditions; -use style::rule_tree::{CascadeLevel, StyleSource}; +use style::rule_tree::{CascadeLevel, StrongRuleNode, StyleSource}; use style::selector_parser::{PseudoElementCascadeType, SelectorImpl}; use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked}; use style::string_cache::Atom; @@ -684,16 +684,38 @@ pub extern "C" fn Servo_AnimationValue_Uncompute( PropertyDeclarationBlock::with_one(value.uncompute(), Importance::Normal))).into_strong() } -#[no_mangle] -pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawServoStyleSetBorrowed, - element: RawGeckoElementBorrowed, - computed_values: ServoStyleContextBorrowed, - snapshots: *const ServoElementSnapshotTable, - pseudo_type: CSSPseudoElementType) - -> ServoStyleContextStrong -{ +// Return the ComputedValues by a base ComputedValues and the rules. +fn resolve_rules_for_element_with_context<'a>( + element: GeckoElement<'a>, + mut context: StyleContext<GeckoElement<'a>>, + rules: StrongRuleNode +) -> Arc<ComputedValues> { use style::style_resolver::{PseudoElementResolution, StyleResolverForElement}; + // This currently ignores visited styles, which seems acceptable, as + // existing browsers don't appear to animate visited styles. + let inputs = + CascadeInputs { + rules: Some(rules), + visited_rules: None, + }; + + // Actually `PseudoElementResolution` doesn't matter. + StyleResolverForElement::new(element, + &mut context, + RuleInclusion::All, + PseudoElementResolution::IfApplicable) + .cascade_style_and_visited_with_default_parents(inputs).0 +} + +#[no_mangle] +pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement( + raw_style_set: RawServoStyleSetBorrowed, + element: RawGeckoElementBorrowed, + computed_values: ServoStyleContextBorrowed, + snapshots: *const ServoElementSnapshotTable, + pseudo_type: CSSPseudoElementType +) -> ServoStyleContextStrong { debug_assert!(!snapshots.is_null()); let computed_values = unsafe { ArcBorrow::from_ref(computed_values) }; @@ -702,11 +724,9 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe Some(ref rules) => rules, }; - let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); - let without_animations = - doc_data.stylist.rule_tree().remove_animation_rules(rules); - - if without_animations == *rules { + let doc_data = PerDocumentStyleData::from_ffi(raw_style_set).borrow(); + let without_animations_rules = doc_data.stylist.rule_tree().remove_animation_rules(rules); + if without_animations_rules == *rules { return computed_values.clone_arc().into(); } @@ -716,9 +736,9 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe Some(data) => data, None => return computed_values.clone_arc().into(), }; - let styles = &element_data.styles; if let Some(pseudo) = PseudoElement::from_pseudo_type(pseudo_type) { + let styles = &element_data.styles; // This style already doesn't have animations. return styles .pseudos @@ -735,23 +755,61 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe TraversalFlags::empty(), unsafe { &*snapshots }); let mut tlc = ThreadLocalStyleContext::new(&shared); - let mut context = StyleContext { + let context = StyleContext { shared: &shared, thread_local: &mut tlc, }; - // This currently ignores visited styles, which seems acceptable, as - // existing browsers don't appear to animate visited styles. - let inputs = - CascadeInputs { - rules: Some(without_animations), - visited_rules: None, - }; + resolve_rules_for_element_with_context(element, context, without_animations_rules).into() +} - // Actually `PseudoElementResolution` doesn't matter. - StyleResolverForElement::new(element, &mut context, RuleInclusion::All, PseudoElementResolution::IfApplicable) - .cascade_style_and_visited_with_default_parents(inputs) - .0.into() +#[no_mangle] +pub extern "C" fn Servo_StyleSet_GetComputedValuesByAddingAnimation( + raw_style_set: RawServoStyleSetBorrowed, + element: RawGeckoElementBorrowed, + computed_values: ServoStyleContextBorrowed, + snapshots: *const ServoElementSnapshotTable, + animation_value: RawServoAnimationValueBorrowed, +) -> ServoStyleContextStrong { + debug_assert!(!snapshots.is_null()); + let computed_values = unsafe { ArcBorrow::from_ref(computed_values) }; + let rules = match computed_values.rules { + None => return ServoStyleContextStrong::null(), + Some(ref rules) => rules, + }; + + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let uncomputed_value = AnimationValue::as_arc(&animation_value).uncompute(); + let doc_data = PerDocumentStyleData::from_ffi(raw_style_set).borrow(); + + let with_animations_rules = { + let guards = StylesheetGuards::same(&guard); + let declarations = + Arc::new(global_style_data.shared_lock.wrap( + PropertyDeclarationBlock::with_one(uncomputed_value, Importance::Normal))); + doc_data.stylist + .rule_tree() + .add_animation_rules_at_transition_level(rules, declarations, &guards) + }; + + let element = GeckoElement(element); + if element.borrow_data().is_none() { + return ServoStyleContextStrong::null(); + } + + let shared = create_shared_context(&global_style_data, + &guard, + &doc_data, + TraversalFlags::empty(), + unsafe { &*snapshots }); + let mut tlc: ThreadLocalStyleContext<GeckoElement> = ThreadLocalStyleContext::new(&shared); + let context = StyleContext { + shared: &shared, + thread_local: &mut tlc, + }; + + resolve_rules_for_element_with_context(element, context, with_animations_rules).into() } #[no_mangle] |