aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/media_queries.rs4
-rw-r--r--components/style/stylesheets.rs121
2 files changed, 92 insertions, 33 deletions
diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs
index 9bdfcfc748d..a450995c565 100644
--- a/components/style/media_queries.rs
+++ b/components/style/media_queries.rs
@@ -297,4 +297,8 @@ impl MediaList {
}
})
}
+
+ pub fn is_empty(&self) -> bool {
+ self.media_queries.is_empty()
+ }
}
diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs
index 1933d98e583..1689953ba8a 100644
--- a/components/style/stylesheets.rs
+++ b/components/style/stylesheets.rs
@@ -56,6 +56,12 @@ pub struct Namespaces {
#[derive(Debug)]
pub struct CssRules(pub Vec<CssRule>);
+impl CssRules {
+ pub fn is_empty(&self) -> bool {
+ self.0.is_empty()
+ }
+}
+
pub enum RulesMutateError {
Syntax,
IndexSize,
@@ -106,8 +112,9 @@ impl CssRules {
// Step 3, 4
// XXXManishearth should we also store the namespace map?
- let (new_rule, new_state) = try!(CssRule::parse(&rule, parent_stylesheet,
- ParserContextExtraData::default(), state));
+ let (new_rule, new_state) =
+ try!(CssRule::parse(&rule, parent_stylesheet,
+ ParserContextExtraData::default(), state));
// Step 5
// Computes the maximum allowed parser state at a given index.
@@ -464,54 +471,102 @@ impl Stylesheet {
environment_encoding: Option<EncodingRef>,
origin: Origin,
media: MediaList,
+ stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: Box<ParseErrorReporter + Send>,
extra_data: ParserContextExtraData)
-> Stylesheet {
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
- Stylesheet::from_str(&string, base_url, origin, media, error_reporter, extra_data)
+ Stylesheet::from_str(&string,
+ base_url,
+ origin,
+ media,
+ stylesheet_loader,
+ error_reporter,
+ extra_data)
+ }
+
+ pub fn update_from_bytes(existing: &Stylesheet,
+ bytes: &[u8],
+ protocol_encoding_label: Option<&str>,
+ environment_encoding: Option<EncodingRef>,
+ stylesheet_loader: Option<&StylesheetLoader>,
+ error_reporter: Box<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData) {
+ assert!(existing.rules.read().is_empty());
+ let (string, _) = decode_stylesheet_bytes(
+ bytes, protocol_encoding_label, environment_encoding);
+ Self::update_from_str(existing,
+ &string,
+ stylesheet_loader,
+ error_reporter,
+ extra_data)
}
- pub fn from_str(css: &str, base_url: ServoUrl, origin: Origin, media: MediaList,
- error_reporter: Box<ParseErrorReporter + Send>,
- extra_data: ParserContextExtraData) -> Stylesheet {
- let mut namespaces = Namespaces::default();
- let mut rules = vec![];
- let dirty_on_viewport_size_change;
+ pub fn update_from_str(existing: &Stylesheet,
+ css: &str,
+ stylesheet_loader: Option<&StylesheetLoader>,
+ error_reporter: Box<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData) {
+ let mut rules = existing.rules.write();
+ let mut namespaces = existing.namespaces.write();
+
+ assert!(rules.is_empty());
+
+ let mut input = Parser::new(css);
+ let rule_parser = TopLevelRuleParser {
+ stylesheet_origin: existing.origin,
+ namespaces: &mut namespaces,
+ loader: stylesheet_loader,
+ context: ParserContext::new_with_extra_data(existing.origin,
+ &existing.base_url,
+ error_reporter,
+ extra_data),
+ state: Cell::new(State::Start),
+ };
+
+ input.look_for_viewport_percentages();
+
{
- let rule_parser = TopLevelRuleParser {
- stylesheet_origin: origin,
- namespaces: &mut namespaces,
- context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter, extra_data),
- state: Cell::new(State::Start),
- };
- let mut input = Parser::new(css);
- input.look_for_viewport_percentages();
- {
- let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
- while let Some(result) = iter.next() {
- match result {
- Ok(rule) => rules.push(rule),
- Err(range) => {
- let pos = range.start;
- let message = format!("Invalid rule: '{}'", iter.input.slice(range));
- log_css_error(iter.input, pos, &*message, &iter.parser.context);
- }
+ let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
+ while let Some(result) = iter.next() {
+ match result {
+ Ok(rule) => rules.0.push(rule),
+ Err(range) => {
+ let pos = range.start;
+ let message = format!("Invalid rule: '{}'", iter.input.slice(range));
+ log_css_error(iter.input, pos, &*message, &iter.parser.context);
}
}
}
- dirty_on_viewport_size_change = input.seen_viewport_percentages();
}
- Stylesheet {
+ existing.dirty_on_viewport_size_change
+ .store(input.seen_viewport_percentages(), Ordering::Release);
+ }
+
+ pub fn from_str(css: &str, base_url: ServoUrl, origin: Origin,
+ media: MediaList,
+ stylesheet_loader: Option<&StylesheetLoader>,
+ error_reporter: Box<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData) -> Stylesheet {
+ let s = Stylesheet {
origin: origin,
base_url: base_url,
- namespaces: RwLock::new(namespaces),
- rules: CssRules::new(rules),
+ namespaces: RwLock::new(Namespaces::default()),
+ rules: CssRules::new(vec![]),
media: Arc::new(RwLock::new(media)),
- dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change),
+ dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),
- }
+ };
+
+ Self::update_from_str(&s,
+ css,
+ stylesheet_loader,
+ error_reporter,
+ extra_data);
+
+ s
}
pub fn dirty_on_viewport_size_change(&self) -> bool {