diff --git a/Cargo.lock b/Cargo.lock index 877f67e4dc4..2d358b2cb70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2393,6 +2393,7 @@ dependencies = [ "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/components/selectors/Cargo.toml b/components/selectors/Cargo.toml index a7145130342..4410ea922a8 100644 --- a/components/selectors/Cargo.toml +++ b/components/selectors/Cargo.toml @@ -21,3 +21,4 @@ matches = "0.1" cssparser = "0.12.1" fnv = "1.0" precomputed-hash = "0.1" +smallvec = "0.3" diff --git a/components/selectors/lib.rs b/components/selectors/lib.rs index fd8ccc6e52d..49fce51a4fe 100644 --- a/components/selectors/lib.rs +++ b/components/selectors/lib.rs @@ -7,6 +7,7 @@ #[macro_use] extern crate matches; extern crate fnv; extern crate precomputed_hash; +extern crate smallvec; pub mod bloom; pub mod matching; diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index fe0b5079988..c84c421a2a4 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -360,12 +360,29 @@ impl ToCss for Selector { impl ToCss for ComplexSelector { fn to_css(&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)?; - } - for simple in &self.compound_selector { - simple.to_css(dest)?; + use smallvec::SmallVec; + let mut current = self; + let mut nodes = SmallVec::<[&Self;8]>::new(); + nodes.push(current); + + loop { + match current.next { + None => break, + Some((ref next, _)) => { + current = &**next; + nodes.push(next); + } + } + } + + for selector in nodes.iter().rev() { + if let Some((_, ref combinator)) = selector.next { + combinator.to_css(dest)?; + } + + for simple in &selector.compound_selector { + simple.to_css(dest)?; + } } Ok(()) }