mirror of
https://github.com/servo/servo.git
synced 2025-07-31 11:10:22 +01:00
Add Servo_StyleSet_GetComputedValuesByAddingAnimation FFI.
Add an FFI to create a temporary ServoStyleContext with the animation value. We need this because we calculate the Cumulative change hints to check if we can ignore this animation segment.
This commit is contained in:
parent
4c538b642e
commit
aa72970f0a
3 changed files with 117 additions and 27 deletions
|
@ -3004,6 +3004,19 @@ extern "C" {
|
||||||
CSSPseudoElementType)
|
CSSPseudoElementType)
|
||||||
-> ServoStyleContextStrong;
|
-> ServoStyleContextStrong;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_StyleSet_GetComputedValuesByAddingAnimation(set:
|
||||||
|
RawServoStyleSetBorrowed,
|
||||||
|
element:
|
||||||
|
RawGeckoElementBorrowed,
|
||||||
|
existing_style:
|
||||||
|
ServoStyleContextBorrowed,
|
||||||
|
snapshots:
|
||||||
|
*const ServoElementSnapshotTable,
|
||||||
|
animation:
|
||||||
|
RawServoAnimationValueBorrowed)
|
||||||
|
-> ServoStyleContextStrong;
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_SerializeFontValueForCanvas(declarations:
|
pub fn Servo_SerializeFontValueForCanvas(declarations:
|
||||||
RawServoDeclarationBlockBorrowed,
|
RawServoDeclarationBlockBorrowed,
|
||||||
|
|
|
@ -446,6 +446,25 @@ impl RuleTree {
|
||||||
let rule = self.insert_ordered_rules_from(last.parent().unwrap().clone(), children.drain().rev());
|
let rule = self.insert_ordered_rules_from(last.parent().unwrap().clone(), children.drain().rev());
|
||||||
rule
|
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
|
/// The number of RuleNodes added to the free list before we will consider
|
||||||
|
|
|
@ -123,7 +123,7 @@ use style::properties::animated_properties::AnimationValue;
|
||||||
use style::properties::animated_properties::compare_property_priority;
|
use style::properties::animated_properties::compare_property_priority;
|
||||||
use style::properties::parse_one_declaration_into;
|
use style::properties::parse_one_declaration_into;
|
||||||
use style::rule_cache::RuleCacheConditions;
|
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::selector_parser::{PseudoElementCascadeType, SelectorImpl};
|
||||||
use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
|
use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
|
||||||
use style::string_cache::Atom;
|
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()
|
PropertyDeclarationBlock::with_one(value.uncompute(), Importance::Normal))).into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
// Return the ComputedValues by a base ComputedValues and the rules.
|
||||||
pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawServoStyleSetBorrowed,
|
fn resolve_rules_for_element_with_context<'a>(
|
||||||
element: RawGeckoElementBorrowed,
|
element: GeckoElement<'a>,
|
||||||
computed_values: ServoStyleContextBorrowed,
|
mut context: StyleContext<GeckoElement<'a>>,
|
||||||
snapshots: *const ServoElementSnapshotTable,
|
rules: StrongRuleNode
|
||||||
pseudo_type: CSSPseudoElementType)
|
) -> Arc<ComputedValues> {
|
||||||
-> ServoStyleContextStrong
|
|
||||||
{
|
|
||||||
use style::style_resolver::{PseudoElementResolution, StyleResolverForElement};
|
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());
|
debug_assert!(!snapshots.is_null());
|
||||||
let computed_values = unsafe { ArcBorrow::from_ref(computed_values) };
|
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,
|
Some(ref rules) => rules,
|
||||||
};
|
};
|
||||||
|
|
||||||
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
let doc_data = PerDocumentStyleData::from_ffi(raw_style_set).borrow();
|
||||||
let without_animations =
|
let without_animations_rules = doc_data.stylist.rule_tree().remove_animation_rules(rules);
|
||||||
doc_data.stylist.rule_tree().remove_animation_rules(rules);
|
if without_animations_rules == *rules {
|
||||||
|
|
||||||
if without_animations == *rules {
|
|
||||||
return computed_values.clone_arc().into();
|
return computed_values.clone_arc().into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,9 +736,9 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe
|
||||||
Some(data) => data,
|
Some(data) => data,
|
||||||
None => return computed_values.clone_arc().into(),
|
None => return computed_values.clone_arc().into(),
|
||||||
};
|
};
|
||||||
let styles = &element_data.styles;
|
|
||||||
|
|
||||||
if let Some(pseudo) = PseudoElement::from_pseudo_type(pseudo_type) {
|
if let Some(pseudo) = PseudoElement::from_pseudo_type(pseudo_type) {
|
||||||
|
let styles = &element_data.styles;
|
||||||
// This style already doesn't have animations.
|
// This style already doesn't have animations.
|
||||||
return styles
|
return styles
|
||||||
.pseudos
|
.pseudos
|
||||||
|
@ -735,23 +755,61 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe
|
||||||
TraversalFlags::empty(),
|
TraversalFlags::empty(),
|
||||||
unsafe { &*snapshots });
|
unsafe { &*snapshots });
|
||||||
let mut tlc = ThreadLocalStyleContext::new(&shared);
|
let mut tlc = ThreadLocalStyleContext::new(&shared);
|
||||||
let mut context = StyleContext {
|
let context = StyleContext {
|
||||||
shared: &shared,
|
shared: &shared,
|
||||||
thread_local: &mut tlc,
|
thread_local: &mut tlc,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This currently ignores visited styles, which seems acceptable, as
|
resolve_rules_for_element_with_context(element, context, without_animations_rules).into()
|
||||||
// existing browsers don't appear to animate visited styles.
|
}
|
||||||
let inputs =
|
|
||||||
CascadeInputs {
|
|
||||||
rules: Some(without_animations),
|
|
||||||
visited_rules: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Actually `PseudoElementResolution` doesn't matter.
|
#[no_mangle]
|
||||||
StyleResolverForElement::new(element, &mut context, RuleInclusion::All, PseudoElementResolution::IfApplicable)
|
pub extern "C" fn Servo_StyleSet_GetComputedValuesByAddingAnimation(
|
||||||
.cascade_style_and_visited_with_default_parents(inputs)
|
raw_style_set: RawServoStyleSetBorrowed,
|
||||||
.0.into()
|
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]
|
#[no_mangle]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue