mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
html: Handle inline stylesheets. purple.com works now.
This commit is contained in:
parent
f249396712
commit
7917da2f8c
2 changed files with 86 additions and 22 deletions
|
@ -2,28 +2,53 @@
|
|||
Some little helpers for hooking up the HTML parser with the CSS parser
|
||||
*/
|
||||
|
||||
use std::net::url::Url;
|
||||
use std::cell::Cell;
|
||||
use resource::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
|
||||
|
||||
use core::str;
|
||||
use newcss::stylesheet::Stylesheet;
|
||||
use newcss::util::DataStream;
|
||||
use std::cell::Cell;
|
||||
use std::net::url::Url;
|
||||
use std::net::url;
|
||||
|
||||
pub fn spawn_css_parser(url: Url, resource_task: ResourceTask) -> comm::Port<Stylesheet> {
|
||||
/// Where a style sheet comes from.
|
||||
enum StylesheetProvenance {
|
||||
UrlProvenance(Url),
|
||||
InlineProvenance(Url, ~str),
|
||||
}
|
||||
|
||||
pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
||||
resource_task: ResourceTask) -> comm::Port<Stylesheet> {
|
||||
let result_port = comm::Port();
|
||||
let result_chan = comm::Chan(&result_port);
|
||||
do task::spawn |move url, copy resource_task| {
|
||||
|
||||
let sheet = Stylesheet::new(copy url, data_stream(copy url, resource_task));
|
||||
|
||||
let provenance_cell = Cell(move provenance);
|
||||
do task::spawn |move provenance_cell, copy resource_task| {
|
||||
let url = do provenance_cell.with_ref |p| {
|
||||
match *p {
|
||||
UrlProvenance(copy the_url) => move the_url,
|
||||
InlineProvenance(copy the_url, _) => move the_url
|
||||
}
|
||||
};
|
||||
|
||||
let sheet = Stylesheet::new(move url, data_stream(provenance_cell.take(), resource_task));
|
||||
result_chan.send(move sheet);
|
||||
}
|
||||
|
||||
return result_port;
|
||||
}
|
||||
|
||||
fn data_stream(url: Url, resource_task: ResourceTask) -> DataStream {
|
||||
let input_port = Port();
|
||||
resource_task.send(Load(move url, input_port.chan()));
|
||||
resource_port_to_data_stream(input_port)
|
||||
fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) -> DataStream {
|
||||
match move provenance {
|
||||
UrlProvenance(move url) => {
|
||||
let input_port = Port();
|
||||
resource_task.send(Load(move url, input_port.chan()));
|
||||
resource_port_to_data_stream(input_port)
|
||||
}
|
||||
InlineProvenance(_, move data) => {
|
||||
data_to_data_stream(move data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resource_port_to_data_stream(input_port: comm::Port<ProgressMsg>) -> DataStream {
|
||||
|
@ -34,3 +59,16 @@ fn resource_port_to_data_stream(input_port: comm::Port<ProgressMsg>) -> DataStre
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn data_to_data_stream(data: ~str) -> DataStream {
|
||||
let data_cell = Cell(move data);
|
||||
return |move data_cell| {
|
||||
if data_cell.is_empty() {
|
||||
None
|
||||
} else {
|
||||
// FIXME: Blech, a copy.
|
||||
Some(str::to_bytes(data_cell.take()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
use au = gfx::geometry;
|
||||
use content::content_task::ContentTask;
|
||||
use newcss::stylesheet::Stylesheet;
|
||||
use dom::cow;
|
||||
use dom::element::*;
|
||||
use dom::event::{Event, ReflowEvent};
|
||||
use dom::node::{Comment, Doctype, DoctypeData, Text,
|
||||
Element, Node, NodeScope};
|
||||
use dom::node::{Comment, Doctype, DoctypeData, Element, Node, NodeScope, Text};
|
||||
use resource::image_cache_task::ImageCacheTask;
|
||||
use resource::image_cache_task;
|
||||
use resource::resource_task::{Done, Load, Payload, ResourceTask};
|
||||
|
||||
use core::comm::{Chan, Port};
|
||||
use cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
||||
use hubbub::Attribute;
|
||||
|
||||
use comm::{Chan, Port};
|
||||
use newcss::stylesheet::Stylesheet;
|
||||
use std::net::url::Url;
|
||||
use cssparse::spawn_css_parser;
|
||||
use std::net::url;
|
||||
|
||||
type JSResult = ~[~[u8]];
|
||||
|
||||
enum CSSMessage {
|
||||
CSSTaskNewFile(Url),
|
||||
CSSTaskNewFile(StylesheetProvenance),
|
||||
CSSTaskExit
|
||||
}
|
||||
|
||||
|
@ -49,14 +48,15 @@ spawned, collates them, and sends them to the given result channel.
|
|||
* `from_parent` - A port on which to receive new links.
|
||||
|
||||
*/
|
||||
fn css_link_listener(to_parent : comm::Chan<Option<Stylesheet>>, from_parent : comm::Port<CSSMessage>,
|
||||
fn css_link_listener(to_parent : comm::Chan<Option<Stylesheet>>,
|
||||
from_parent : comm::Port<CSSMessage>,
|
||||
resource_task: ResourceTask) {
|
||||
let mut result_vec = ~[];
|
||||
|
||||
loop {
|
||||
match from_parent.recv() {
|
||||
CSSTaskNewFile(move url) => {
|
||||
result_vec.push(spawn_css_parser(move url, copy resource_task));
|
||||
CSSTaskNewFile(move provenance) => {
|
||||
result_vec.push(spawn_css_parser(move provenance, copy resource_task));
|
||||
}
|
||||
CSSTaskExit => {
|
||||
break;
|
||||
|
@ -184,6 +184,31 @@ pub fn parse_html(scope: NodeScope,
|
|||
debug!("created parser");
|
||||
parser.set_document_node(cast::transmute(cow::unwrap(root)));
|
||||
parser.enable_scripting(true);
|
||||
|
||||
// Performs various actions necessary after appending has taken place. Currently, this consists
|
||||
// of processing inline stylesheets, but in the future it might perform prefetching, etc.
|
||||
let append_hook: @fn(Node, Node) = |parent_node, child_node| {
|
||||
do scope.read(&parent_node) |parent_node_contents| {
|
||||
do scope.read(&child_node) |child_node_contents| {
|
||||
match (parent_node_contents.kind, child_node_contents.kind) {
|
||||
(~Element(ref element), ~Text(ref data)) => {
|
||||
match element.kind {
|
||||
~HTMLStyleElement => {
|
||||
debug!("found inline CSS stylesheet");
|
||||
let url = url::from_str("http://example.com/"); // FIXME
|
||||
let provenance = InlineProvenance(result::unwrap(move url),
|
||||
copy *data);
|
||||
css_chan.send(CSSTaskNewFile(provenance));
|
||||
}
|
||||
_ => {} // Nothing to do.
|
||||
}
|
||||
}
|
||||
_ => {} // Nothing to do.
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
parser.set_tree_handler(@hubbub::TreeHandler {
|
||||
create_comment: |data: ~str| {
|
||||
debug!("create comment");
|
||||
|
@ -227,8 +252,8 @@ pub fn parse_html(scope: NodeScope,
|
|||
(Some(move rel), Some(move href)) => {
|
||||
if rel == ~"stylesheet" {
|
||||
debug!("found CSS stylesheet: %s", href);
|
||||
css_chan.send(CSSTaskNewFile(make_url(move href,
|
||||
Some(copy *url))));
|
||||
css_chan.send(CSSTaskNewFile(UrlProvenance(make_url(move href,
|
||||
Some(copy *url)))));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -262,6 +287,7 @@ pub fn parse_html(scope: NodeScope,
|
|||
let p: Node = cow::wrap(cast::transmute(parent));
|
||||
let c: Node = cow::wrap(cast::transmute(child));
|
||||
scope.add_child(p, c);
|
||||
append_hook(p, c);
|
||||
}
|
||||
child
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue