Bug 1362914 - Factor out PropertyDeclaration only iterator. r?manishearth
MozReview-Commit-ID: LcyVsynftT2
--- a/servo/components/style/properties/declaration_block.rs
+++ b/servo/components/style/properties/declaration_block.rs
@@ -7,16 +7,17 @@
#![deny(missing_docs)]
use context::QuirksMode;
use cssparser::{DeclarationListParser, parse_important};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
use error_reporting::ParseErrorReporter;
use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
use std::fmt;
+use std::slice::Iter;
use style_traits::ToCss;
use stylesheets::{CssRuleType, Origin, UrlExtraData};
use super::*;
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
/// A declaration [importance][importance].
///
/// [importance]: https://drafts.csswg.org/css-cascade/#importance
@@ -49,16 +50,34 @@ pub struct PropertyDeclarationBlock {
declarations: Vec<(PropertyDeclaration, Importance)>,
/// The number of entries in `self.declaration` with `Importance::Important`
important_count: usize,
longhands: LonghandIdSet,
}
+/// Iterator for PropertyDeclaration to be generated from PropertyDeclarationBlock.
+#[derive(Clone)]
+pub struct PropertyDeclarationIterator<'a> {
+ iter: Iter<'a, (PropertyDeclaration, Importance)>,
+}
+
+impl<'a> Iterator for PropertyDeclarationIterator<'a> {
+ type Item = &'a PropertyDeclaration;
+ fn next(&mut self) -> Option<&'a PropertyDeclaration> {
+ // we use this function because a closure won't be `Clone`
+ fn get_declaration(dec: &(PropertyDeclaration, Importance))
+ -> &PropertyDeclaration {
+ &dec.0
+ }
+ self.iter.next().map(get_declaration as fn(_) -> _)
+ }
+}
+
impl fmt::Debug for PropertyDeclarationBlock {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.declarations.fmt(f)
}
}
impl PropertyDeclarationBlock {
/// Returns the number of declarations in the block.
@@ -88,16 +107,23 @@ impl PropertyDeclarationBlock {
}
}
/// The declarations in this block
pub fn declarations(&self) -> &[(PropertyDeclaration, Importance)] {
&self.declarations
}
+ /// Iterate over only PropertyDeclaration.
+ pub fn declarations_iter(&self) -> PropertyDeclarationIterator {
+ PropertyDeclarationIterator {
+ iter: self.declarations.iter(),
+ }
+ }
+
/// Returns whether this block contains any declaration with `!important`.
///
/// This is based on the `important_count` counter,
/// which should be maintained whenever `declarations` is changed.
// FIXME: make fields private and maintain it here in methods?
pub fn any_important(&self) -> bool {
self.important_count > 0
}
@@ -316,25 +342,20 @@ impl PropertyDeclarationBlock {
Err(_longhand_or_custom) => {
if self.declarations.len() == 1 {
self.declarations[0].0.to_css(dest)
} else {
Err(fmt::Error)
}
}
Ok(shorthand) => {
- // we use this function because a closure won't be `Clone`
- fn get_declaration(dec: &(PropertyDeclaration, Importance))
- -> &PropertyDeclaration {
- &dec.0
- }
if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) {
return Err(fmt::Error)
}
- let iter = self.declarations.iter().map(get_declaration as fn(_) -> _);
+ let iter = self.declarations_iter();
match shorthand.get_shorthand_appendable_value(iter) {
Some(AppendableValue::Css { css, .. }) => {
dest.write_str(css)
},
Some(AppendableValue::DeclarationsForShorthand(_, decls)) => {
shorthand.longhands_to_css(decls, dest)
}
_ => Ok(())