Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing recursion from ComplexSelector WIP #16227

Closed
wants to merge 6 commits into from

style: Cleanup a bit the restyle hint propagation code.

Update parser.rs
  • Loading branch information
emilio authored and Matthew committed Apr 6, 2017
commit bda19168e53fa61fd2314c69fbcf54a23a0d5f6d
@@ -376,13 +376,30 @@ impl<Impl: SelectorImpl> ToCss for Selector<Impl> {

impl<Impl: SelectorImpl> ToCss for ComplexSelector<Impl> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if let Some((ref next, ref combinator)) = self.next {
next.to_css(dest)?;
combinator.to_css(dest)?;
use smallvec::SmallVec;
let mut current = self;
let mut nodes = SmallVec::<[Arc<ComplexSelector<Impl>>; 8]>::new();
loop{
match current.next{
None => break,
Some((ref next, ref combinator)) => {
current = &**next;
combinator.to_css(dest)?;
nodes.push((*next).clone());
}
}
}
for simple in &self.compound_selector {
simple.to_css(dest)?;

for simp in &self.compound_selector{
simp.to_css(dest)?;
}

for node in nodes {
for simple in &node.compound_selector {
simple.to_css(dest)?;
}
}

Ok(())
}
}
@@ -1133,6 +1150,9 @@ fn parse_simple_pseudo_class<P, Impl>(parser: &P, name: Cow<str>) -> Result<Simp
// NB: pub module in order to access the DummyParser
#[cfg(test)]
pub mod tests {



use cssparser::{Parser as CssParser, ToCss, serialize_identifier};
use std::borrow::Cow;
use std::collections::HashMap;
@@ -135,13 +135,20 @@ pub struct StoredRestyleHint(RestyleHint);

impl StoredRestyleHint {
/// Propagates this restyle hint to a child element.
pub fn propagate(&self) -> Self {
// If we have RESTYLE_CSS_ANIMATIONS restyle hint, it means we are in the
// middle of an animation only restyle. In that case, we don't need to
// propagate any restyle hints.
StoredRestyleHint(if self.0.contains(RESTYLE_CSS_ANIMATIONS) {
RestyleHint::empty()
} else if self.0.contains(RESTYLE_DESCENDANTS) {
pub fn propagate(&mut self) -> Self {
use std::mem;

// If we have RESTYLE_CSS_ANIMATIONS restyle hint, it means we are in
// the middle of an animation only restyle. In that case, we don't need
// to propagate any restyle hints, and we need to remove ourselves.
if self.0.contains(RESTYLE_CSS_ANIMATIONS) {
self.0.remove(RESTYLE_CSS_ANIMATIONS);
return Self::empty();
}

// Else we should clear ourselves, and return the propagated hint.
let hint = mem::replace(&mut self.0, RestyleHint::empty());
StoredRestyleHint(if hint.contains(RESTYLE_DESCENDANTS) {
RESTYLE_SELF | RESTYLE_DESCENDANTS
} else {
RestyleHint::empty()
@@ -180,11 +187,6 @@ impl StoredRestyleHint {
self.0 |= other.0
}

/// Remove animation restyle hint.
pub fn remove_animation_hint(&mut self) {
self.0.remove(RESTYLE_CSS_ANIMATIONS)
}

/// Returns true if the hint has animation-only restyle.
pub fn has_animation_hint(&self) -> bool {
self.0.contains(RESTYLE_CSS_ANIMATIONS)
@@ -15,7 +15,6 @@ use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF};
use selector_parser::RestyleDamage;
use servo_config::opts;
use std::borrow::BorrowMut;
use std::mem;
use stylist::Stylist;

/// A per-traversal-level chunk of data. This is sent down by the traversal, and
@@ -484,37 +483,46 @@ pub fn recalc_style_at<E, D>(traversal: &D,

// Now that matching and cascading is done, clear the bits corresponding to
// those operations and compute the propagated restyle hint.
let empty_hint = StoredRestyleHint::empty();
let propagated_hint = match data.get_restyle_mut() {
None => empty_hint,
None => StoredRestyleHint::empty(),
Some(r) => {
debug_assert!(context.shared.animation_only_restyle ||
!r.hint.has_animation_hint(),
"animation restyle hint should be handled during \
animation-only restyles");
r.recascade = false;
if r.hint.has_animation_hint() {
debug_assert!(context.shared.animation_only_restyle,
"animation restyle hint should be handled during animation-only restyles");
// Drop animation restyle hint.
let propagated_hint = r.hint.propagate();
r.hint.remove_animation_hint();
propagated_hint
} else {
mem::replace(&mut r.hint, empty_hint).propagate()
}
r.hint.propagate()
},
};
debug_assert!(data.has_current_styles() || context.shared.animation_only_restyle,
"Should have computed style or haven't yet valid computed style in case of animation-only restyle");
trace!("propagated_hint={:?}, inherited_style_changed={:?}", propagated_hint, inherited_style_changed);
trace!("propagated_hint={:?}, inherited_style_changed={:?}",
propagated_hint, inherited_style_changed);

let has_dirty_descendants_for_this_restyle =
if context.shared.animation_only_restyle {
element.has_animation_only_dirty_descendants()
} else {
element.has_dirty_descendants()
};

// Preprocess children, propagating restyle hints and handling sibling relationships.
if traversal.should_traverse_children(&mut context.thread_local, element, &data, DontLog) &&
((!context.shared.animation_only_restyle && element.has_dirty_descendants()) ||
(context.shared.animation_only_restyle && element.has_animation_only_dirty_descendants()) ||
!propagated_hint.is_empty() ||
inherited_style_changed) {
if traversal.should_traverse_children(&mut context.thread_local,
element,
&data,
DontLog) &&
(has_dirty_descendants_for_this_restyle ||
!propagated_hint.is_empty() ||
inherited_style_changed) {
let damage_handled = data.get_restyle().map_or(RestyleDamage::empty(), |r| {
r.damage_handled() | r.damage.handled_for_descendants()
});
preprocess_children(traversal, element, propagated_hint, damage_handled, inherited_style_changed);

preprocess_children(traversal,
element,
propagated_hint,
damage_handled,
inherited_style_changed);
}

if context.shared.animation_only_restyle {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.