Auto merge of #16111 - hiikezoe:after-change-style, r=emilio

Add functions for after-change style of CSS Transition

<!-- Please describe your changes on the following line: -->
This is a PR of https://bugzilla.mozilla.org/show_bug.cgi?id=1346663

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [X] These changes do not require tests because it's for stylo

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16111)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-03-23 19:05:03 -07:00 committed by GitHub
commit 089c71b587
2 changed files with 92 additions and 17 deletions

View file

@ -469,24 +469,15 @@ trait PrivateMatchMethods: TElement {
}
}
fn cascade_internal(&self,
fn cascade_with_rules(&self,
context: &StyleContext<Self>,
rule_node: &StrongRuleNode,
primary_style: &ComputedStyle,
pseudo_style: &mut Option<(&PseudoElement, &mut ComputedStyle)>,
booleans: &CascadeBooleans)
pseudo_style: &Option<(&PseudoElement, &mut ComputedStyle)>,
cascade_flags: CascadeFlags)
-> Arc<ComputedValues> {
let shared_context = context.shared;
let mut cascade_info = CascadeInfo::new();
let mut cascade_flags = CascadeFlags::empty();
if booleans.shareable {
cascade_flags.insert(SHAREABLE)
}
if self.skip_root_and_item_based_display_fixup() {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)
}
// Grab the rule node.
let rule_node = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1).rules;
// Grab the inherited values.
let parent_el;
@ -552,6 +543,25 @@ trait PrivateMatchMethods: TElement {
values
}
fn cascade_internal(&self,
context: &StyleContext<Self>,
primary_style: &ComputedStyle,
pseudo_style: &Option<(&PseudoElement, &mut ComputedStyle)>,
booleans: &CascadeBooleans)
-> Arc<ComputedValues> {
let mut cascade_flags = CascadeFlags::empty();
if booleans.shareable {
cascade_flags.insert(SHAREABLE)
}
if self.skip_root_and_item_based_display_fixup() {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)
}
// Grab the rule node.
let rule_node = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1).rules;
self.cascade_with_rules(context, rule_node, primary_style, pseudo_style, cascade_flags)
}
/// Computes values and damage for the primary or pseudo style of an element,
/// setting them on the ElementData.
fn cascade_primary_or_pseudo<'a>(&self,
@ -570,7 +580,7 @@ trait PrivateMatchMethods: TElement {
// Compute the new values.
let mut new_values = self.cascade_internal(context, primary_style,
&mut pseudo_style, &booleans);
&pseudo_style, &booleans);
// Handle animations.
if booleans.animate {
@ -594,6 +604,33 @@ trait PrivateMatchMethods: TElement {
}
}
#[cfg(feature = "gecko")]
fn get_after_change_style(&self,
context: &mut StyleContext<Self>,
primary_style: &ComputedStyle,
pseudo_style: &Option<(&PseudoElement, &mut ComputedStyle)>)
-> Arc<ComputedValues> {
let style = &pseudo_style.as_ref().map_or(primary_style, |p| &*p.1);
let rule_node = &style.rules;
let without_transition_rules =
context.shared.stylist.rule_tree.remove_transition_rule_if_applicable(rule_node);
if without_transition_rules == *rule_node {
// Note that unwrapping here is fine, because the style is
// only incomplete during the styling process.
return style.values.as_ref().unwrap().clone();
}
let mut cascade_flags = CascadeFlags::empty();
if self.skip_root_and_item_based_display_fixup() {
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP)
}
self.cascade_with_rules(context,
&without_transition_rules,
primary_style,
&pseudo_style,
cascade_flags)
}
#[cfg(feature = "gecko")]
fn process_animations(&self,
context: &mut StyleContext<Self>,

View file

@ -239,6 +239,37 @@ impl RuleTree {
// necessary.
Some(self.insert_ordered_rules_from(current, children.into_iter().rev()))
}
/// Returns new rule nodes without Transitions level rule.
pub fn remove_transition_rule_if_applicable(&self, path: &StrongRuleNode) -> StrongRuleNode {
// Return a clone if there is no transition level.
if path.cascade_level() != CascadeLevel::Transitions {
return path.clone();
}
path.parent().unwrap().clone()
}
/// Returns new rule node without Animations and Transitions level rules.
pub fn remove_animation_and_transition_rules(&self, path: &StrongRuleNode) -> StrongRuleNode {
// Return a clone if there is neither animation nor transition level.
if !path.has_animation_or_transition_rules() {
return path.clone();
}
let iter = path.self_and_ancestors().take_while(|node| node.cascade_level() >= CascadeLevel::Animations);
let mut last = path;
let mut children = vec![];
for node in iter {
if node.cascade_level() != CascadeLevel::Animations &&
node.cascade_level() != CascadeLevel::Transitions {
children.push((node.get().source.clone().unwrap(), node.cascade_level()));
}
last = node;
}
self.insert_ordered_rules_from(last.parent().unwrap().clone(), children.into_iter().rev())
}
}
/// The number of RuleNodes added to the free list before we will consider
@ -728,6 +759,13 @@ impl StrongRuleNode {
self.gc();
}
}
/// Returns true if there is either animation or transition level rule.
pub fn has_animation_or_transition_rules(&self) -> bool {
self.self_and_ancestors()
.take_while(|node| node.cascade_level() >= CascadeLevel::Animations)
.any(|node| matches!(node.cascade_level(), CascadeLevel::Animations | CascadeLevel::Transitions))
}
}
/// An iterator over a rule node and its ancestors.