зеркало из https://github.com/mozilla/gecko-dev.git
servo: Feed the HTML/CSS parsers with the ResourceTask
Source-Repo: https://github.com/servo/servo Source-Revision: 6430d74ecea417ea3c65a62881792192e56482dc
This commit is contained in:
Родитель
d42a90907a
Коммит
a16038af5d
|
@ -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();
|
||||
|
||||
|
|
|
@ -184,12 +184,16 @@ impl parser_methods of parser_methods for TokenReader {
|
|||
some(list){ copy list }
|
||||
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 {
|
||||
|
@ -43,18 +47,36 @@ trait util_methods {
|
|||
impl util_methods of util_methods for InputState {
|
||||
fn get() -> CharOrEof {
|
||||
alt copy self.lookahead {
|
||||
some(coe) {
|
||||
let rv = coe;
|
||||
self.lookahead = none;
|
||||
ret rv;
|
||||
}
|
||||
none {
|
||||
/* fall through */
|
||||
}
|
||||
some(coe) {
|
||||
let rv = coe;
|
||||
self.lookahead = none;
|
||||
ret rv;
|
||||
}
|
||||
none {
|
||||
/* fall through */
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче