servo: Feed the HTML/CSS parsers with the ResourceTask

Source-Repo: https://github.com/servo/servo
Source-Revision: 6430d74ecea417ea3c65a62881792192e56482dc
This commit is contained in:
Brian Anderson 2012-07-27 19:16:04 -07:00
Родитель d42a90907a
Коммит a16038af5d
6 изменённых файлов: 86 добавлений и 42 удалений

Просмотреть файл

@ -131,7 +131,7 @@ class Content<S:Sink send copy> {
// Note: we can parse the next document in parallel
// with any previous documents.
let stream = spawn_html_lexer_task(copy url, self.resource_task);
let (root, style_port, js_port) = build_dom(self.scope, stream, url);
let (root, style_port, js_port) = build_dom(self.scope, stream, url, self.resource_task);
let css_rules = style_port.recv();
let js_scripts = js_port.recv();

Просмотреть файл

@ -185,12 +185,16 @@ impl parser_methods of parser_methods for TokenReader {
none { ret none; }
};
#debug("sel_list: %?", sel_list);
// Get the description to be applied to the selector
let desc_list = alt self.parse_description() {
some(list) { copy list }
none { ret none; }
};
#debug("desc_list: %?", desc_list);
ret some(~(sel_list, desc_list));
}
}

Просмотреть файл

@ -10,6 +10,8 @@ import pipes::{port, chan};
import lexer_util::*;
import std::net::url::url;
import resource::resource_task::{ResourceTask, ProgressMsg, Load};
import result::ok;
enum ParserState {
CssElement,
@ -225,13 +227,20 @@ impl css_methods of css_methods for CssLexer {
}
}
fn parser(reader: io::reader, state : ParserState) -> CssLexer {
ret { input_state: {mut lookahead: none, reader: reader}, mut parser_state: state };
fn parser(input_port: comm::port<ProgressMsg>, state : ParserState) -> CssLexer {
ret {
input_state: {
mut lookahead: none,
mut buffer: ~[],
input_port: input_port,
mut eof: false
},
mut parser_state: state
};
}
fn lex_css_from_bytes(-content : ~[u8], result_chan : chan<Token>) {
let reader = io::bytes_reader(content);
let lexer = parser(reader, CssElement);
fn lex_css_from_bytes(+input_port: comm::port<ProgressMsg>, result_chan : chan<Token>) {
let lexer = parser(input_port, CssElement);
loop {
let token = lexer.parse_css();
@ -245,32 +254,31 @@ fn lex_css_from_bytes(-content : ~[u8], result_chan : chan<Token>) {
}
}
fn spawn_css_lexer_from_string(-content : ~str) -> port<Token> {
fn spawn_css_lexer_from_string(-content : ~str) -> pipes::port<Token> {
let (result_chan, result_port) = pipes::stream();
task::spawn(|| lex_css_from_bytes(str::bytes(content), result_chan));
do task::spawn {
let input_port = comm::port();
let chan = input_port.chan();
input_port.send(Payload(str::bytes(content)));
input_port.send(Done(ok(())));
lex_css_from_bytes(input_port, result_chan);
}
ret result_port;
}
#[warn(no_non_implicitly_copyable_typarams)]
fn spawn_css_lexer_task(-url: url) -> pipes::port<Token> {
fn spawn_css_lexer_task(-url: url, resource_task: ResourceTask) -> pipes::port<Token> {
let (result_chan, result_port) = pipes::stream();
task::spawn(|| {
assert url.path.ends_with(".css");
let file_try = io::read_whole_file(url.path);
let input_port = port();
resource_task.send(Load(url, input_port.chan()));
// Check if the given css file existed, if it does, parse it,
// otherwise just send an eof.
if file_try.is_ok() {
#debug["Lexing css sheet %?", url.path];
let file_data = file_try.get();
lex_css_from_bytes(file_data, result_chan);
} else {
#debug["Failed to open css sheet %?", url.path];
result_chan.send(Eof);
}
lex_css_from_bytes(input_port, result_chan);
});
ret result_port;

Просмотреть файл

@ -13,7 +13,7 @@ import parser::Token;
import dom::style::Stylesheet;
import vec::{push, push_all_move, flat_map};
import std::net::url::url;
import resource::resource_task::ResourceTask;
import dvec::extensions;
enum CSSMessage {
@ -95,7 +95,8 @@ 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<Stylesheet>, from_parent : comm::port<CSSMessage>) {
fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::port<CSSMessage>,
resource_task: ResourceTask) {
let mut result_vec = ~[];
loop {
@ -104,7 +105,7 @@ fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::por
let result_port = comm::port();
let result_chan = comm::chan(result_port);
task::spawn(|| {
let css_stream = css_lexer::spawn_css_lexer_task(copy url);
let css_stream = css_lexer::spawn_css_lexer_task(copy url, resource_task);
let mut css_rules = css_builder::build_stylesheet(css_stream);
result_chan.send(css_rules);
});
@ -153,7 +154,8 @@ fn js_script_listener(to_parent : comm::chan<~[~[u8]]>, from_parent : comm::port
}
#[warn(no_non_implicitly_copyable_typarams)]
fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) {
fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url,
resource_task: ResourceTask) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) {
// The current reference node.
let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
// We will spawn a separate task to parse any css that is
@ -164,7 +166,7 @@ fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url) -> (Node, co
let style_port = comm::port();
let child_chan = comm::chan(style_port);
let style_chan = task::spawn_listener(|child_port| {
css_link_listener(child_chan, child_port);
css_link_listener(child_chan, child_port, resource_task);
});
let js_port = comm::port();

Просмотреть файл

@ -5,7 +5,7 @@ import str::from_bytes;
import vec::push;
import lexer_util::*;
import resource::resource_task;
import resource_task::{ResourceTask};
import resource_task::{ResourceTask, ProgressMsg, Load};
import std::net::url::url;
enum Token {
@ -166,8 +166,16 @@ impl html_methods of html_methods for HtmlLexer {
}
}
fn lexer(reader: io::reader, state : ParseState) -> HtmlLexer {
ret { input_state: {mut lookahead: none, reader: reader}, mut parser_state: state };
fn lexer(+input_port: port<resource_task::ProgressMsg>, state : ParseState) -> HtmlLexer {
ret {
input_state: {
mut lookahead: none,
mut buffer: ~[],
input_port: input_port,
mut eof: false
},
mut parser_state: state
};
}
#[warn(no_non_implicitly_copyable_typarams)]
@ -177,10 +185,10 @@ fn spawn_html_lexer_task(-url: url, resource_task: ResourceTask) -> port<Token>
task::spawn(|| {
assert url.path.ends_with(~".html");
let file_data = io::read_whole_file(url.path).get();
let reader = io::bytes_reader(file_data);
let input_port = port();
resource_task.send(Load(url, input_port.chan()));
let lexer = lexer(reader, NormalHtml);
let lexer = lexer(input_port, NormalHtml);
loop {
let token = lexer.parse_html();

Просмотреть файл

@ -3,6 +3,8 @@
import option::is_none;
import str::from_bytes;
import vec::push;
import comm::{port, methods};
import resource::resource_task::{ProgressMsg, Payload, Done};
enum CharOrEof {
CoeChar(u8),
@ -11,7 +13,9 @@ enum CharOrEof {
type InputState = {
mut lookahead: option<CharOrEof>,
reader: io::reader
mut buffer: ~[u8],
input_port: port<ProgressMsg>,
mut eof: bool
};
trait u8_methods {
@ -53,8 +57,26 @@ impl util_methods of util_methods for InputState {
}
}
if self.reader.eof() { ret CoeEof; }
ret CoeChar(self.reader.read_byte() as u8);
// FIXME: Lots of copies here
if self.buffer.len() > 0 {
ret CoeChar(vec::shift(self.buffer));
}
if self.eof {
ret CoeEof;
}
alt self.input_port.recv() {
Payload(data) {
self.buffer = data;
ret CoeChar(vec::shift(self.buffer));
}
Done(*) {
self.eof = true;
ret CoeEof;
}
}
}
fn unget(ch: u8) {