mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Don't use 'select'
The new runtime isn't quite mature enough to deal with it, and this is faster anyway.
This commit is contained in:
parent
034536e531
commit
a875b12c22
2 changed files with 33 additions and 49 deletions
|
@ -107,11 +107,16 @@ enum JSMessage {
|
||||||
JSTaskExit
|
JSTaskExit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Messages generated by the HTML parser upon discovery of additional resources
|
||||||
|
pub enum HtmlDiscoveryMessage {
|
||||||
|
HtmlDiscoveredStyle(Stylesheet),
|
||||||
|
HtmlDiscoveredIFrame((Url, SubpageId, Future<Size2D<uint>>)),
|
||||||
|
HtmlDiscoveredScript(JSResult)
|
||||||
|
}
|
||||||
|
|
||||||
pub struct HtmlParserResult {
|
pub struct HtmlParserResult {
|
||||||
root: AbstractNode<ScriptView>,
|
root: AbstractNode<ScriptView>,
|
||||||
style_port: Port<Stylesheet>,
|
discovery_port: Port<HtmlDiscoveryMessage>,
|
||||||
iframe_port: Port<(Url, SubpageId, Future<Size2D<uint>>)>,
|
|
||||||
js_port: Port<JSResult>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait NodeWrapping {
|
trait NodeWrapping {
|
||||||
|
@ -143,7 +148,7 @@ 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: Chan<Stylesheet>,
|
fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
|
||||||
from_parent: Port<CSSMessage>,
|
from_parent: Port<CSSMessage>,
|
||||||
resource_task: ResourceTask) {
|
resource_task: ResourceTask) {
|
||||||
let mut result_vec = ~[];
|
let mut result_vec = ~[];
|
||||||
|
@ -162,11 +167,11 @@ fn css_link_listener(to_parent: Chan<Stylesheet>,
|
||||||
// Send the sheets back in order
|
// Send the sheets back in order
|
||||||
// FIXME: Shouldn't wait until after we've recieved CSSTaskExit to start sending these
|
// FIXME: Shouldn't wait until after we've recieved CSSTaskExit to start sending these
|
||||||
for result_vec.iter().advance |port| {
|
for result_vec.iter().advance |port| {
|
||||||
to_parent.send(port.recv());
|
to_parent.send(HtmlDiscoveredStyle(port.recv()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn js_script_listener(to_parent: Chan<~[~[u8]]>,
|
fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
|
||||||
from_parent: Port<JSMessage>,
|
from_parent: Port<JSMessage>,
|
||||||
resource_task: ResourceTask) {
|
resource_task: ResourceTask) {
|
||||||
let mut result_vec = ~[];
|
let mut result_vec = ~[];
|
||||||
|
@ -208,7 +213,7 @@ fn js_script_listener(to_parent: Chan<~[~[u8]]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let js_scripts = result_vec.iter().filter_map(|result_port| result_port.recv()).collect();
|
let js_scripts = result_vec.iter().filter_map(|result_port| result_port.recv()).collect();
|
||||||
to_parent.send(js_scripts);
|
to_parent.send(HtmlDiscoveredScript(js_scripts));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Silly macros to handle constructing DOM nodes. This produces bad code and should be optimized
|
// Silly macros to handle constructing DOM nodes. This produces bad code and should be optimized
|
||||||
|
@ -277,8 +282,10 @@ pub fn parse_html(cx: *JSContext,
|
||||||
// Spawn a CSS parser to receive links to CSS style sheets.
|
// Spawn a CSS parser to receive links to CSS style sheets.
|
||||||
let resource_task2 = resource_task.clone();
|
let resource_task2 = resource_task.clone();
|
||||||
|
|
||||||
let (stylesheet_port, stylesheet_chan) = comm::stream();
|
let (discovery_port, discovery_chan) = comm::stream();
|
||||||
let stylesheet_chan = Cell::new(stylesheet_chan);
|
let discovery_chan = SharedChan::new(discovery_chan);
|
||||||
|
|
||||||
|
let stylesheet_chan = Cell::new(discovery_chan.clone());
|
||||||
let (css_msg_port, css_msg_chan) = comm::stream();
|
let (css_msg_port, css_msg_chan) = comm::stream();
|
||||||
let css_msg_port = Cell::new(css_msg_port);
|
let css_msg_port = Cell::new(css_msg_port);
|
||||||
do spawn {
|
do spawn {
|
||||||
|
@ -289,8 +296,7 @@ pub fn parse_html(cx: *JSContext,
|
||||||
|
|
||||||
// Spawn a JS parser to receive JavaScript.
|
// Spawn a JS parser to receive JavaScript.
|
||||||
let resource_task2 = resource_task.clone();
|
let resource_task2 = resource_task.clone();
|
||||||
let (js_result_port, js_result_chan) = comm::stream();
|
let js_result_chan = Cell::new(discovery_chan.clone());
|
||||||
let js_result_chan = Cell::new(js_result_chan);
|
|
||||||
let (js_msg_port, js_msg_chan) = comm::stream();
|
let (js_msg_port, js_msg_chan) = comm::stream();
|
||||||
let js_msg_port = Cell::new(js_msg_port);
|
let js_msg_port = Cell::new(js_msg_port);
|
||||||
do spawn {
|
do spawn {
|
||||||
|
@ -312,7 +318,6 @@ pub fn parse_html(cx: *JSContext,
|
||||||
parser.enable_styling(true);
|
parser.enable_styling(true);
|
||||||
|
|
||||||
let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone());
|
let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone());
|
||||||
let (iframe_port, iframe_chan) = comm::stream();
|
|
||||||
let next_subpage_id = Cell::new(next_subpage_id);
|
let next_subpage_id = Cell::new(next_subpage_id);
|
||||||
|
|
||||||
parser.set_tree_handler(~hubbub::TreeHandler {
|
parser.set_tree_handler(~hubbub::TreeHandler {
|
||||||
|
@ -373,7 +378,9 @@ pub fn parse_html(cx: *JSContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementNodeTypeId(HTMLIframeElementTypeId) => {
|
ElementNodeTypeId(HTMLIframeElementTypeId) => {
|
||||||
|
let iframe_chan = Cell::new(discovery_chan.clone());
|
||||||
do node.with_mut_iframe_element |iframe_element| {
|
do node.with_mut_iframe_element |iframe_element| {
|
||||||
|
let iframe_chan = iframe_chan.take();
|
||||||
let elem = &mut iframe_element.parent.parent;
|
let elem = &mut iframe_element.parent.parent;
|
||||||
let src_opt = elem.get_attr("src").map(|x| x.to_str());
|
let src_opt = elem.get_attr("src").map(|x| x.to_str());
|
||||||
for src_opt.iter().advance |src| {
|
for src_opt.iter().advance |src| {
|
||||||
|
@ -390,7 +397,7 @@ pub fn parse_html(cx: *JSContext,
|
||||||
iframe_element.subpage_id = Some(subpage_id);
|
iframe_element.subpage_id = Some(subpage_id);
|
||||||
next_subpage_id.put_back(SubpageId(*subpage_id + 1));
|
next_subpage_id.put_back(SubpageId(*subpage_id + 1));
|
||||||
|
|
||||||
iframe_chan.send((iframe_url, subpage_id, size_future));
|
iframe_chan.send(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,9 +549,7 @@ pub fn parse_html(cx: *JSContext,
|
||||||
|
|
||||||
HtmlParserResult {
|
HtmlParserResult {
|
||||||
root: root,
|
root: root,
|
||||||
style_port: stylesheet_port,
|
discovery_port: discovery_port,
|
||||||
iframe_port: iframe_port,
|
|
||||||
js_port: js_result_port,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ use std::util::replace;
|
||||||
use dom::window::TimerData;
|
use dom::window::TimerData;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use html::hubbub_html_parser::HtmlParserResult;
|
use html::hubbub_html_parser::HtmlParserResult;
|
||||||
|
use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredIFrame, HtmlDiscoveredScript};
|
||||||
use html::hubbub_html_parser;
|
use html::hubbub_html_parser;
|
||||||
use js::JSVAL_NULL;
|
use js::JSVAL_NULL;
|
||||||
use js::global::{global_class, debug_fns};
|
use js::global::{global_class, debug_fns};
|
||||||
|
@ -605,7 +606,7 @@ impl ScriptTask {
|
||||||
self.image_cache_task.clone(),
|
self.image_cache_task.clone(),
|
||||||
page.next_subpage_id.clone());
|
page.next_subpage_id.clone());
|
||||||
|
|
||||||
let HtmlParserResult {root, js_port, style_port, iframe_port} = html_parsing_result;
|
let HtmlParserResult {root, discovery_port} = html_parsing_result;
|
||||||
|
|
||||||
// Create the window and document objects.
|
// Create the window and document objects.
|
||||||
let window = {
|
let window = {
|
||||||
|
@ -637,52 +638,30 @@ impl ScriptTask {
|
||||||
// FIXME: These should be streamed to layout as they're parsed. We don't need to stop here
|
// FIXME: These should be streamed to layout as they're parsed. We don't need to stop here
|
||||||
// in the script task.
|
// in the script task.
|
||||||
|
|
||||||
let get_iframes = |iframe_port: &Port<(Url, SubpageId, Future<Size2D<uint>>)>| loop {
|
let mut js_scripts = None;
|
||||||
match iframe_port.try_recv() {
|
|
||||||
None => break,
|
|
||||||
Some((iframe_url, subpage_id, size_future)) => {
|
|
||||||
page.next_subpage_id = SubpageId(*subpage_id + 1);
|
|
||||||
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
|
|
||||||
pipeline_id,
|
|
||||||
subpage_id,
|
|
||||||
size_future));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let get_stylesheets = |style_port: &Port<Stylesheet>| loop {
|
|
||||||
match style_port.try_recv() {
|
|
||||||
None => break,
|
|
||||||
Some(sheet) => page.layout_chan.send(AddStylesheetMsg(sheet)),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut select_ports = (style_port, iframe_port);
|
|
||||||
loop {
|
loop {
|
||||||
match select_ports.try_select() {
|
match discovery_port.try_recv() {
|
||||||
Left(None) => {
|
Some(HtmlDiscoveredScript(scripts)) => {
|
||||||
get_iframes(select_ports.second_ref());
|
assert!(js_scripts.is_none());
|
||||||
break;
|
js_scripts = Some(scripts);
|
||||||
}
|
}
|
||||||
Left(Some(sheet)) => {
|
Some(HtmlDiscoveredStyle(sheet)) => {
|
||||||
page.layout_chan.send(AddStylesheetMsg(sheet));
|
page.layout_chan.send(AddStylesheetMsg(sheet));
|
||||||
}
|
}
|
||||||
Right(Some((iframe_url, subpage_id, size_future))) => {
|
Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future))) => {
|
||||||
page.next_subpage_id = SubpageId(*subpage_id + 1);
|
page.next_subpage_id = SubpageId(*subpage_id + 1);
|
||||||
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
|
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
size_future));
|
size_future));
|
||||||
}
|
}
|
||||||
Right(None) => {
|
None => break
|
||||||
get_stylesheets(select_ports.first_ref());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive the JavaScript scripts.
|
// Receive the JavaScript scripts.
|
||||||
let js_scripts = js_port.recv();
|
assert!(js_scripts.is_some());
|
||||||
|
let js_scripts = js_scripts.swap_unwrap();
|
||||||
debug!("js_scripts: %?", js_scripts);
|
debug!("js_scripts: %?", js_scripts);
|
||||||
|
|
||||||
// Perform the initial reflow.
|
// Perform the initial reflow.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue