aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/html/cssparse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/html/cssparse.rs')
-rw-r--r--components/script/html/cssparse.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/components/script/html/cssparse.rs b/components/script/html/cssparse.rs
new file mode 100644
index 00000000000..473b64c7d76
--- /dev/null
+++ b/components/script/html/cssparse.rs
@@ -0,0 +1,72 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+/// Some little helpers for hooking up the HTML parser with the CSS parser.
+
+use std::comm::{channel, Receiver};
+use encoding::EncodingRef;
+use encoding::all::UTF_8;
+use style::Stylesheet;
+use servo_net::resource_task::{Load, LoadData, LoadResponse, ProgressMsg, Payload, Done, ResourceTask};
+use servo_util::task::spawn_named;
+use url::Url;
+
+/// Where a style sheet comes from.
+pub enum StylesheetProvenance {
+ UrlProvenance(Url, ResourceTask),
+ InlineProvenance(Url, String),
+}
+
+// Parses the style data and returns the stylesheet
+pub fn parse_inline_css(url: Url, data: String) -> Stylesheet {
+ parse_css(InlineProvenance(url, data))
+}
+
+fn parse_css(provenance: StylesheetProvenance) -> Stylesheet {
+ // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
+ let environment_encoding = UTF_8 as EncodingRef;
+
+ match provenance {
+ UrlProvenance(url, resource_task) => {
+ debug!("cssparse: loading style sheet at {:s}", url.serialize());
+ let (input_chan, input_port) = channel();
+ resource_task.send(Load(LoadData::new(url), input_chan));
+ let LoadResponse { metadata: metadata, progress_port: progress_port , ..}
+ = input_port.recv();
+ let final_url = &metadata.final_url;
+ 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, final_url.clone(),
+ protocol_encoding_label, Some(environment_encoding))
+ }
+ InlineProvenance(base_url, data) => {
+ debug!("cssparse: loading inline stylesheet {:s}", data);
+ Stylesheet::from_str(data.as_slice(), base_url)
+ }
+ }
+}
+
+pub fn spawn_css_parser(provenance: StylesheetProvenance) -> Receiver<Stylesheet> {
+ let (result_chan, result_port) = channel();
+
+ spawn_named("cssparser", proc() {
+ result_chan.send(parse_css(provenance));
+ });
+
+ return result_port;
+}
+
+struct ProgressMsgPortIterator {
+ progress_port: Receiver<ProgressMsg>
+}
+
+impl Iterator<Vec<u8>> for ProgressMsgPortIterator {
+ fn next(&mut self) -> Option<Vec<u8>> {
+ match self.progress_port.recv() {
+ Payload(data) => Some(data),
+ Done(..) => None
+ }
+ }
+}