aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/html/cssparse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script/html/cssparse.rs')
-rw-r--r--src/components/script/html/cssparse.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/components/script/html/cssparse.rs b/src/components/script/html/cssparse.rs
new file mode 100644
index 00000000000..9ee789d6e3e
--- /dev/null
+++ b/src/components/script/html/cssparse.rs
@@ -0,0 +1,76 @@
+/* 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 core::cell::Cell;
+use core::comm::Port;
+use core::str;
+use newcss::stylesheet::Stylesheet;
+use newcss::util::DataStream;
+use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
+use std::net::url::Url;
+
+/// Where a style sheet comes from.
+pub enum StylesheetProvenance {
+ UrlProvenance(Url),
+ InlineProvenance(Url, ~str),
+}
+
+pub fn spawn_css_parser(provenance: StylesheetProvenance,
+ resource_task: ResourceTask)
+ -> Port<Stylesheet> {
+ let (result_port, result_chan) = comm::stream();
+
+ let provenance_cell = Cell(provenance);
+ do task::spawn {
+ let url = do provenance_cell.with_ref |p| {
+ match *p {
+ UrlProvenance(copy the_url) => the_url,
+ InlineProvenance(copy the_url, _) => the_url
+ }
+ };
+
+ let sheet = Stylesheet::new(url, data_stream(provenance_cell.take(),
+ resource_task.clone()));
+ result_chan.send(sheet);
+ }
+
+ return result_port;
+}
+
+fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) -> DataStream {
+ match provenance {
+ UrlProvenance(url) => {
+ let (input_port, input_chan) = comm::stream();
+ resource_task.send(Load(url, input_chan));
+ resource_port_to_data_stream(input_port)
+ }
+ InlineProvenance(_, data) => {
+ data_to_data_stream(data)
+ }
+ }
+}
+
+fn resource_port_to_data_stream(input_port: Port<ProgressMsg>) -> DataStream {
+ return || {
+ match input_port.recv() {
+ Payload(data) => Some(data),
+ Done(*) => None
+ }
+ }
+}
+
+fn data_to_data_stream(data: ~str) -> DataStream {
+ let data_cell = Cell(data);
+ return || {
+ if data_cell.is_empty() {
+ None
+ } else {
+ // FIXME: Blech, a copy.
+ Some(str::to_bytes(data_cell.take()))
+ }
+ }
+}
+