Fix the out-of-bound failure in stylesheet iterator.

Rewrite the iterator as internal instead of external.
This is much easier for recursive tree traversal.
This commit is contained in:
Simon Sapin 2013-10-26 00:17:06 +02:00
parent 4eb1e88e8f
commit eab2f06c5d
2 changed files with 9 additions and 33 deletions

View file

@ -7,7 +7,7 @@ use std::ascii::StrAsciiExt;
use extra::sort::tim_sort; use extra::sort::tim_sort;
use selectors::*; use selectors::*;
use stylesheets::Stylesheet; use stylesheets::{Stylesheet, iter_style_rules};
use media_queries::{Device, Screen}; use media_queries::{Device, Screen};
use properties::{PropertyDeclaration, PropertyDeclarationBlock}; use properties::{PropertyDeclaration, PropertyDeclarationBlock};
use servo_util::tree::{TreeNodeRefAsElement, TreeNode, ElementLike}; use servo_util::tree::{TreeNodeRefAsElement, TreeNode, ElementLike};
@ -62,7 +62,7 @@ impl Stylist {
) )
let device = &Device { media_type: Screen }; // TODO, use Print when printing let device = &Device { media_type: Screen }; // TODO, use Print when printing
for style_rule in stylesheet.iter_style_rules(device) { do iter_style_rules(stylesheet.rules.as_slice(), device) |style_rule| {
append!(normal, added_normal_declarations); append!(normal, added_normal_declarations);
append!(important, added_important_declarations); append!(important, added_important_declarations);
} }

View file

@ -132,37 +132,13 @@ pub fn parse_nested_at_rule(lower_name: &str, rule: AtRule,
} }
impl Stylesheet { pub fn iter_style_rules<'a>(rules: &[CSSRule], device: &media_queries::Device,
pub fn iter_style_rules<'a>(&'a self, device: &'a media_queries::Device) callback: &fn(&StyleRule)) {
-> StyleRuleIterator<'a> { for rule in rules.iter() {
StyleRuleIterator { device: device, stack: ~[(self.rules.as_slice(), 0)] } match *rule {
} CSSStyleRule(ref rule) => callback(rule),
} CSSMediaRule(ref rule) => if rule.media_queries.evaluate(device) {
iter_style_rules(rule.rules.as_slice(), device, |s| callback(s))
struct StyleRuleIterator<'self> {
device: &'self media_queries::Device,
// FIXME: I couldn't get this to borrow-check with a stack of VecIterator
stack: ~[(&'self [CSSRule], uint)],
}
impl<'self> Iterator<&'self StyleRule> for StyleRuleIterator<'self> {
fn next(&mut self) -> Option<&'self StyleRule> {
loop {
match self.stack.pop_opt() {
None => return None,
Some((rule_list, i)) => {
if i + 1 < rule_list.len() {
self.stack.push((rule_list, i + 1))
}
match rule_list[i] {
CSSStyleRule(ref rule) => return Some(rule),
CSSMediaRule(ref rule) => {
if rule.media_queries.evaluate(self.device) {
self.stack.push((rule.rules.as_slice(), 0))
}
}
}
}
} }
} }
} }