diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2013-12-11 16:40:30 +0000 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2013-12-11 16:40:30 +0000 |
commit | 2d6ac336568cdc55ecf974e20706d431c932e4fc (patch) | |
tree | 0786891b44a7a55673f55248dd7f19d5da0dab11 | |
parent | b98acc2f752aaa783f68483a81b79984a2dc7b16 (diff) | |
download | servo-2d6ac336568cdc55ecf974e20706d431c932e4fc.tar.gz servo-2d6ac336568cdc55ecf974e20706d431c932e4fc.zip |
Add support for non-UTF8 CSS stylesheets, with rust-encoding.
-rw-r--r-- | src/components/main/css/select.rs | 2 | ||||
-rw-r--r-- | src/components/script/html/cssparse.rs | 18 | ||||
-rw-r--r-- | src/components/script/script.rc | 1 | ||||
-rw-r--r-- | src/components/style/selector_matching.rs | 35 | ||||
-rw-r--r-- | src/components/style/style.rc | 1 | ||||
-rw-r--r-- | src/components/style/stylesheets.rs | 34 | ||||
m--------- | src/support/css/rust-cssparser | 0 | ||||
m--------- | src/support/encoding/rust-encoding | 0 |
8 files changed, 55 insertions, 36 deletions
diff --git a/src/components/main/css/select.rs b/src/components/main/css/select.rs index aad62f6860f..e65c76c6e25 100644 --- a/src/components/main/css/select.rs +++ b/src/components/main/css/select.rs @@ -8,7 +8,7 @@ use style::{Stylesheet, Stylist, UserAgentOrigin, with_errors_silenced}; pub fn new_stylist() -> Stylist { let mut stylist = Stylist::new(); let ua_stylesheet = with_errors_silenced( - || Stylesheet::from_str(include_str!("user-agent.css"))); + || Stylesheet::from_bytes(include_bin!("user-agent.css"), None, None)); stylist.add_stylesheet(ua_stylesheet, UserAgentOrigin); stylist } diff --git a/src/components/script/html/cssparse.rs b/src/components/script/html/cssparse.rs index ade3b58ed69..15532d76ab8 100644 --- a/src/components/script/html/cssparse.rs +++ b/src/components/script/html/cssparse.rs @@ -8,8 +8,10 @@ use std::cell::Cell; use std::comm; use std::comm::Port; use std::task; +use encoding::EncodingObj; +use encoding::all::UTF_8; use style::Stylesheet; -use servo_net::resource_task::{Load, ProgressMsg, Payload, Done, ResourceTask}; +use servo_net::resource_task::{Load, LoadResponse, ProgressMsg, Payload, Done, ResourceTask}; use extra::url::Url; /// Where a style sheet comes from. @@ -23,6 +25,9 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance, -> Port<Stylesheet> { let (result_port, result_chan) = comm::stream(); + // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding + let environment_encoding = UTF_8 as EncodingObj; + let provenance_cell = Cell::new(provenance); do task::spawn { // TODO: CSS parsing should take a base URL. @@ -38,12 +43,15 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance, debug!("cssparse: loading style sheet at {:s}", url.to_str()); let (input_port, input_chan) = comm::stream(); resource_task.send(Load(url, input_chan)); - Stylesheet::from_iter(ProgressMsgPortIterator { - progress_port: input_port.recv().progress_port - }) + let LoadResponse { metadata: metadata, progress_port: progress_port } + = input_port.recv(); + let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice()); + let iter = ProgressMsgPortIterator { progress_port: progress_port }; + Stylesheet::from_bytes_iter( + iter, protocol_encoding_label, Some(environment_encoding)) } InlineProvenance(_, data) => { - Stylesheet::from_str(data) + Stylesheet::from_str(data, environment_encoding) } }; result_chan.send(sheet); diff --git a/src/components/script/script.rc b/src/components/script/script.rc index 5556da368c1..63e23211a01 100644 --- a/src/components/script/script.rc +++ b/src/components/script/script.rc @@ -15,6 +15,7 @@ extern mod geom = "rust-geom"; extern mod hubbub; +extern mod encoding; extern mod js; extern mod servo_net (name = "net"); extern mod servo_util (name = "util"); diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs index 079e1babf83..6f52e1ecff1 100644 --- a/src/components/style/selector_matching.rs +++ b/src/components/style/selector_matching.rs @@ -651,28 +651,27 @@ fn match_attribute<N: TreeNode<T>, T: TreeNodeRefAsElement<N, E>, E: ElementLike } } } -fn get_rules(css_string: &str) -> ~[~[Rule]] { - let device = &Device { media_type: Screen }; - let sheet = Stylesheet::from_str(css_string); - let mut index = 0u; - let mut results = ~[]; - do iter_style_rules(sheet.rules.as_slice(), device) |style_rule| { - results.push(style_rule.selectors.iter().map(|s| Rule { - selector: Arc::new(s.clone()), - declarations: style_rule.declarations.normal.clone(), - index: index, - stylesheet_index: 0u, - }).collect()); - index += 1u; - } - results -} + /// Helper method to get some Rules from selector strings. /// Each sublist of the result contains the Rules for one StyleRule. fn get_mock_rules(css_selectors: &[&str]) -> ~[~[Rule]] { - let css_string = css_selectors.map(|s| s + " { color: red; } ").concat(); - get_rules(css_string) + use namespaces::NamespaceMap; + use selectors::parse_selector_list; + use cssparser::tokenize; + + let namespaces = NamespaceMap::new(); + css_selectors.iter().enumerate().map(|(i, selectors)| { + parse_selector_list(tokenize(*selectors).map(|(c, _)| c).to_owned_vec(), &namespaces) + .unwrap().move_iter().map(|s| { + Rule { + selector: Arc::new(s), + declarations: Arc::new(~[]), + index: i, + stylesheet_index: 0u, + } + }).to_owned_vec() + }).to_owned_vec() } #[test] diff --git a/src/components/style/style.rc b/src/components/style/style.rc index a5c05652011..59f948f5961 100644 --- a/src/components/style/style.rc +++ b/src/components/style/style.rc @@ -15,6 +15,7 @@ extern mod extra; extern mod cssparser; +extern mod encoding; extern mod servo_util (name = "util"); diff --git a/src/components/style/stylesheets.rs b/src/components/style/stylesheets.rs index 81830e38686..ab4ebb30a53 100644 --- a/src/components/style/stylesheets.rs +++ b/src/components/style/stylesheets.rs @@ -2,10 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::str; use std::iter::Iterator; use std::ascii::StrAsciiExt; -use cssparser::{tokenize, parse_stylesheet_rules, ToCss}; + +use encoding::EncodingObj; + +use cssparser::{decode_stylesheet_bytes, tokenize, parse_stylesheet_rules, ToCss}; use cssparser::ast::*; use selectors; use properties; @@ -20,6 +22,7 @@ pub struct Stylesheet { /// cascading order) rules: ~[CSSRule], namespaces: NamespaceMap, + encoding: EncodingObj, } @@ -36,19 +39,26 @@ pub struct StyleRule { impl Stylesheet { - pub fn from_iter<I: Iterator<~[u8]>>(input: I) -> Stylesheet { - let mut string = ~""; - let mut input = input; - // TODO: incremental tokinization/parsing + pub fn from_bytes_iter<I: Iterator<~[u8]>>( + mut input: I, protocol_encoding_label: Option<&str>, + environment_encoding: Option<EncodingObj>) -> Stylesheet { + let mut bytes = ~[]; + // TODO: incremental decoding and tokinization/parsing for chunk in input { - // Assume UTF-8. This fails on invalid UTF-8 - // TODO: support character encodings (use rust-encodings in rust-cssparser) - string.push_str(str::from_utf8_owned(chunk)) + bytes.push_all(chunk) } - Stylesheet::from_str(string) + Stylesheet::from_bytes(bytes, protocol_encoding_label, environment_encoding) + } + + pub fn from_bytes( + bytes: &[u8], protocol_encoding_label: Option<&str>, + environment_encoding: Option<EncodingObj>) -> Stylesheet { + let (string, used_encoding) = decode_stylesheet_bytes( + bytes, protocol_encoding_label, environment_encoding); + Stylesheet::from_str(string, used_encoding) } - pub fn from_str(css: &str) -> Stylesheet { + pub fn from_str(css: &str, encoding: EncodingObj) -> Stylesheet { static STATE_CHARSET: uint = 1; static STATE_IMPORTS: uint = 2; static STATE_NAMESPACES: uint = 3; @@ -107,7 +117,7 @@ impl Stylesheet { } state = next_state; } - Stylesheet{ rules: rules, namespaces: namespaces } + Stylesheet{ rules: rules, namespaces: namespaces, encoding: encoding } } } diff --git a/src/support/css/rust-cssparser b/src/support/css/rust-cssparser -Subproject 1a7b4ca6d368f6035a4135504f89d66c5e225d0 +Subproject 4eb52d5cb22e39c9edff848420c910b0b7ecafa diff --git a/src/support/encoding/rust-encoding b/src/support/encoding/rust-encoding -Subproject 2c486a34dedba1faace3de641e0ace103c7f314 +Subproject 47bef0fe76e094e7886f3eaabb652d0f43af191 |