зеркало из 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
|
// Note: we can parse the next document in parallel
|
||||||
// with any previous documents.
|
// with any previous documents.
|
||||||
let stream = spawn_html_lexer_task(copy url, self.resource_task);
|
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 css_rules = style_port.recv();
|
||||||
let js_scripts = js_port.recv();
|
let js_scripts = js_port.recv();
|
||||||
|
|
||||||
|
|
|
@ -184,12 +184,16 @@ impl parser_methods of parser_methods for TokenReader {
|
||||||
some(list){ copy list }
|
some(list){ copy list }
|
||||||
none { ret none; }
|
none { ret none; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#debug("sel_list: %?", sel_list);
|
||||||
|
|
||||||
// Get the description to be applied to the selector
|
// Get the description to be applied to the selector
|
||||||
let desc_list = alt self.parse_description() {
|
let desc_list = alt self.parse_description() {
|
||||||
some(list) { copy list }
|
some(list) { copy list }
|
||||||
none { ret none; }
|
none { ret none; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#debug("desc_list: %?", desc_list);
|
||||||
|
|
||||||
ret some(~(sel_list, desc_list));
|
ret some(~(sel_list, desc_list));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import pipes::{port, chan};
|
||||||
import lexer_util::*;
|
import lexer_util::*;
|
||||||
|
|
||||||
import std::net::url::url;
|
import std::net::url::url;
|
||||||
|
import resource::resource_task::{ResourceTask, ProgressMsg, Load};
|
||||||
|
import result::ok;
|
||||||
|
|
||||||
enum ParserState {
|
enum ParserState {
|
||||||
CssElement,
|
CssElement,
|
||||||
|
@ -225,13 +227,20 @@ impl css_methods of css_methods for CssLexer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parser(reader: io::reader, state : ParserState) -> CssLexer {
|
fn parser(input_port: comm::port<ProgressMsg>, state : ParserState) -> CssLexer {
|
||||||
ret { input_state: {mut lookahead: none, reader: reader}, mut parser_state: state };
|
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>) {
|
fn lex_css_from_bytes(+input_port: comm::port<ProgressMsg>, result_chan : chan<Token>) {
|
||||||
let reader = io::bytes_reader(content);
|
let lexer = parser(input_port, CssElement);
|
||||||
let lexer = parser(reader, CssElement);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let token = lexer.parse_css();
|
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();
|
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;
|
ret result_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(no_non_implicitly_copyable_typarams)]
|
#[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();
|
let (result_chan, result_port) = pipes::stream();
|
||||||
|
|
||||||
task::spawn(|| {
|
task::spawn(|| {
|
||||||
assert url.path.ends_with(".css");
|
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,
|
lex_css_from_bytes(input_port, result_chan);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ret result_port;
|
ret result_port;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import parser::Token;
|
||||||
import dom::style::Stylesheet;
|
import dom::style::Stylesheet;
|
||||||
import vec::{push, push_all_move, flat_map};
|
import vec::{push, push_all_move, flat_map};
|
||||||
import std::net::url::url;
|
import std::net::url::url;
|
||||||
|
import resource::resource_task::ResourceTask;
|
||||||
import dvec::extensions;
|
import dvec::extensions;
|
||||||
|
|
||||||
enum CSSMessage {
|
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.
|
* `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 = ~[];
|
let mut result_vec = ~[];
|
||||||
|
|
||||||
loop {
|
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_port = comm::port();
|
||||||
let result_chan = comm::chan(result_port);
|
let result_chan = comm::chan(result_port);
|
||||||
task::spawn(|| {
|
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);
|
let mut css_rules = css_builder::build_stylesheet(css_stream);
|
||||||
result_chan.send(css_rules);
|
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)]
|
#[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.
|
// The current reference node.
|
||||||
let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
|
let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
|
||||||
// We will spawn a separate task to parse any css that is
|
// 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 style_port = comm::port();
|
||||||
let child_chan = comm::chan(style_port);
|
let child_chan = comm::chan(style_port);
|
||||||
let style_chan = task::spawn_listener(|child_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();
|
let js_port = comm::port();
|
||||||
|
|
|
@ -5,7 +5,7 @@ import str::from_bytes;
|
||||||
import vec::push;
|
import vec::push;
|
||||||
import lexer_util::*;
|
import lexer_util::*;
|
||||||
import resource::resource_task;
|
import resource::resource_task;
|
||||||
import resource_task::{ResourceTask};
|
import resource_task::{ResourceTask, ProgressMsg, Load};
|
||||||
import std::net::url::url;
|
import std::net::url::url;
|
||||||
|
|
||||||
enum Token {
|
enum Token {
|
||||||
|
@ -166,8 +166,16 @@ impl html_methods of html_methods for HtmlLexer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lexer(reader: io::reader, state : ParseState) -> HtmlLexer {
|
fn lexer(+input_port: port<resource_task::ProgressMsg>, state : ParseState) -> HtmlLexer {
|
||||||
ret { input_state: {mut lookahead: none, reader: reader}, mut parser_state: state };
|
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)]
|
#[warn(no_non_implicitly_copyable_typarams)]
|
||||||
|
@ -177,10 +185,10 @@ fn spawn_html_lexer_task(-url: url, resource_task: ResourceTask) -> port<Token>
|
||||||
|
|
||||||
task::spawn(|| {
|
task::spawn(|| {
|
||||||
assert url.path.ends_with(~".html");
|
assert url.path.ends_with(~".html");
|
||||||
let file_data = io::read_whole_file(url.path).get();
|
let input_port = port();
|
||||||
let reader = io::bytes_reader(file_data);
|
resource_task.send(Load(url, input_port.chan()));
|
||||||
|
|
||||||
let lexer = lexer(reader, NormalHtml);
|
let lexer = lexer(input_port, NormalHtml);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let token = lexer.parse_html();
|
let token = lexer.parse_html();
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
import option::is_none;
|
import option::is_none;
|
||||||
import str::from_bytes;
|
import str::from_bytes;
|
||||||
import vec::push;
|
import vec::push;
|
||||||
|
import comm::{port, methods};
|
||||||
|
import resource::resource_task::{ProgressMsg, Payload, Done};
|
||||||
|
|
||||||
enum CharOrEof {
|
enum CharOrEof {
|
||||||
CoeChar(u8),
|
CoeChar(u8),
|
||||||
|
@ -11,7 +13,9 @@ enum CharOrEof {
|
||||||
|
|
||||||
type InputState = {
|
type InputState = {
|
||||||
mut lookahead: option<CharOrEof>,
|
mut lookahead: option<CharOrEof>,
|
||||||
reader: io::reader
|
mut buffer: ~[u8],
|
||||||
|
input_port: port<ProgressMsg>,
|
||||||
|
mut eof: bool
|
||||||
};
|
};
|
||||||
|
|
||||||
trait u8_methods {
|
trait u8_methods {
|
||||||
|
@ -43,18 +47,36 @@ trait util_methods {
|
||||||
impl util_methods of util_methods for InputState {
|
impl util_methods of util_methods for InputState {
|
||||||
fn get() -> CharOrEof {
|
fn get() -> CharOrEof {
|
||||||
alt copy self.lookahead {
|
alt copy self.lookahead {
|
||||||
some(coe) {
|
some(coe) {
|
||||||
let rv = coe;
|
let rv = coe;
|
||||||
self.lookahead = none;
|
self.lookahead = none;
|
||||||
ret rv;
|
ret rv;
|
||||||
}
|
}
|
||||||
none {
|
none {
|
||||||
/* fall through */
|
/* fall through */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.reader.eof() { ret CoeEof; }
|
// FIXME: Lots of copies here
|
||||||
ret CoeChar(self.reader.read_byte() as u8);
|
|
||||||
|
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) {
|
fn unget(ch: u8) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче