From a0c2bdf775fd4286e82a209d892518f7fb9fefdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 12 Apr 2017 22:12:12 +0800 Subject: [PATCH] style: Smoke-test the dependency tracking logic. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MozReview-Commit-ID: J5HWdS1H49s Signed-off-by: Emilio Cobos Álvarez --- .travis.yml | 1 + components/selectors/parser.rs | 24 ++++++++++++++- components/selectors/visitor.rs | 1 - components/style/restyle_hints.rs | 49 +++++++++++++++++++++++++------ 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 52c6dc6a7194..c9652e696a2c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ matrix: - bash etc/ci/lockfile_changed.sh - bash etc/ci/manifest_changed.sh - ./mach cargo test -p selectors + - ./mach cargo test -p style cache: directories: - .cargo diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 25eb0fff8773..367220b27e86 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -1164,7 +1164,7 @@ pub mod tests { impl SelectorMethods for PseudoClass { type Impl = DummySelectorImpl; - fn visit(&self, visitor: &mut V) -> bool + fn visit(&self, _visitor: &mut V) -> bool where V: SelectorVisitor { true } } @@ -1501,4 +1501,26 @@ pub mod tests { specificity: specificity(1, 1, 0), })))); } + + struct TestVisitor { + seen: Vec, + } + + impl SelectorVisitor for TestVisitor { + type Impl = DummySelectorImpl; + + fn visit_simple_selector(&mut self, s: &SimpleSelector) -> bool { + let mut dest = String::new(); + s.to_css(&mut dest).unwrap(); + self.seen.push(dest); + true + } + } + + #[test] + fn visitor() { + let mut test_visitor = TestVisitor { seen: vec![], }; + parse(":not(:hover) ~ label").unwrap().0[0].visit(&mut test_visitor); + assert!(test_visitor.seen.contains(&":hover".into())); + } } diff --git a/components/selectors/visitor.rs b/components/selectors/visitor.rs index 3d63db404b97..2e0b52987f80 100644 --- a/components/selectors/visitor.rs +++ b/components/selectors/visitor.rs @@ -7,7 +7,6 @@ #![deny(missing_docs)] use parser::{AttrSelector, Combinator, ComplexSelector, SelectorImpl, SimpleSelector}; -use std::sync::Arc; /// A trait to visit selector properties. /// diff --git a/components/style/restyle_hints.rs b/components/style/restyle_hints.rs index 7d1c8d24f8be..e1ec77360343 100644 --- a/components/style/restyle_hints.rs +++ b/components/style/restyle_hints.rs @@ -279,7 +279,7 @@ impl<'a, E> Element for ElementWrapper<'a, E> fn match_non_ts_pseudo_class(&self, pseudo_class: &NonTSPseudoClass, relations: &mut StyleRelations, - _: &mut F) + _setter: &mut F) -> bool where F: FnMut(&Self, ElementSelectorFlags), { @@ -293,12 +293,12 @@ impl<'a, E> Element for ElementWrapper<'a, E> self, None, relations, - setter) + _setter) }) } } - let flag = SelectorImpl::pseudo_class_state_flag(pseudo_class); + let flag = pseudo_class.state_flag(); if flag.is_empty() { return self.element.match_non_ts_pseudo_class(pseudo_class, relations, @@ -382,7 +382,7 @@ impl<'a, E> Element for ElementWrapper<'a, E> fn selector_to_state(sel: &SimpleSelector) -> ElementState { match *sel { - SimpleSelector::NonTSPseudoClass(ref pc) => SelectorImpl::pseudo_class_state_flag(pc), + SimpleSelector::NonTSPseudoClass(ref pc) => pc.state_flag(), _ => ElementState::empty(), } } @@ -505,6 +505,7 @@ impl SelectorVisitor for SensitivitiesVisitor { combinator: Option) -> bool { self.hint |= combinator_to_restyle_hint(combinator); self.needs_revalidation |= self.hint.contains(RESTYLE_LATER_SIBLINGS); + true } @@ -577,21 +578,28 @@ impl DependencySet { ss.visit(&mut sensitivities_visitor); } - sensitivities_visitor.hint |= combinator_to_restyle_hint(combinator); needs_revalidation |= sensitivities_visitor.needs_revalidation; - if !sensitivities_visitor.sensitivities.is_empty() { + let SensitivitiesVisitor { + sensitivities, + mut hint, + .. + } = sensitivities_visitor; + + hint |= combinator_to_restyle_hint(combinator); + + if !sensitivities.is_empty() { self.add_dependency(Dependency { - sensitivities: sensitivities_visitor.sensitivities, - hint: sensitivities_visitor.hint, + sensitivities: sensitivities, + hint: hint, selector: current.clone(), }) } match current.next { Some((ref next, next_combinator)) => { - combinator = Some(next_combinator); current = next; + combinator = Some(next_combinator); } None => break, } @@ -697,3 +705,26 @@ impl DependencySet { } } } + +#[test] +#[cfg(all(test, feature = "servo"))] +fn smoke_restyle_hints() { + use cssparser::Parser; + use selector_parser::SelectorParser; + use stylesheets::{Origin, Namespaces}; + let namespaces = Namespaces::default(); + let parser = SelectorParser { + stylesheet_origin: Origin::Author, + namespaces: &namespaces, + }; + + let mut dependencies = DependencySet::new(); + + let mut p = Parser::new(":not(:active) ~ label"); + let selector = Arc::new(ComplexSelector::parse(&parser, &mut p).unwrap()); + dependencies.note_selector(&selector); + assert_eq!(dependencies.len(), 1); + assert_eq!(dependencies.state_deps.len(), 1); + assert!(!dependencies.state_deps[0].sensitivities.states.is_empty()); + assert!(dependencies.state_deps[0].hint.contains(RESTYLE_LATER_SIBLINGS)); +}