aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/html
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script/html')
-rw-r--r--src/components/script/html/cssparse.rs17
-rw-r--r--src/components/script/html/hubbub_html_parser.rs81
2 files changed, 62 insertions, 36 deletions
diff --git a/src/components/script/html/cssparse.rs b/src/components/script/html/cssparse.rs
index 6d9d0d18a5a..9111f517c12 100644
--- a/src/components/script/html/cssparse.rs
+++ b/src/components/script/html/cssparse.rs
@@ -10,7 +10,7 @@ use std::comm::Port;
use std::task;
use newcss::stylesheet::Stylesheet;
use newcss::util::DataStream;
-use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
+use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done, UrlChange};
use extra::url::Url;
/// Where a style sheet comes from.
@@ -57,10 +57,19 @@ fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) ->
fn resource_port_to_data_stream(input_port: Port<ProgressMsg>) -> DataStream {
return || {
- match input_port.recv() {
- Payload(data) => Some(data),
- Done(*) => None
+ // Can't just 'return' the value since we're inside a lambda
+ let mut result = None;
+ loop {
+ match input_port.recv() {
+ UrlChange(*) => (), // don't care that URL changed
+ Payload(data) => {
+ result = Some(data);
+ break;
+ }
+ Done(*) => break
+ }
}
+ result
}
}
diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs
index 0be9fa9c0e3..523e7dabe3c 100644
--- a/src/components/script/html/hubbub_html_parser.rs
+++ b/src/components/script/html/hubbub_html_parser.rs
@@ -24,7 +24,7 @@ use std::from_str::FromStr;
use hubbub::hubbub;
use servo_msg::constellation_msg::{ConstellationChan, SubpageId};
use servo_net::image_cache_task::ImageCacheTask;
-use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
+use servo_net::resource_task::{ProgressMsg, Done, Load, Payload, UrlChange, ResourceTask};
use servo_util::tree::TreeNodeRef;
use servo_util::url::make_url;
use extra::url::Url;
@@ -98,6 +98,7 @@ pub enum HtmlDiscoveryMessage {
pub struct HtmlParserResult {
root: AbstractNode<ScriptView>,
discovery_port: Port<HtmlDiscoveryMessage>,
+ url: Url,
}
trait NodeWrapping {
@@ -171,6 +172,7 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
let mut buf = ~[];
loop {
match input_port.recv() {
+ UrlChange(*) => (), // don't care that URL changed
Payload(data) => {
buf.push_all(data);
}
@@ -329,8 +331,25 @@ pub fn parse_html(cx: *JSContext,
}
let js_chan = SharedChan::new(js_msg_chan);
- let url2 = url.clone();
- let url3 = url.clone();
+ // Process any UrlChange messages before we build the parser, because the
+ // tree handler functions need to know the final URL.
+ let mut final_url = url.clone();
+ let (input_port, input_chan) = comm::stream();
+ resource_task.send(Load(url.clone(), input_chan));
+ let mut progress_msg: ProgressMsg;
+ loop {
+ progress_msg = input_port.recv();
+ match progress_msg {
+ UrlChange(url) => {
+ debug!("page URL changed to %s", url.to_str());
+ final_url = url;
+ }
+ _ => break
+ }
+ }
+
+ let url2 = final_url.clone();
+ let url3 = final_url.clone();
// Build the root node.
let root = @HTMLHtmlElement { htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html") };
@@ -500,37 +519,31 @@ pub fn parse_html(cx: *JSContext,
debug!("encoding change");
},
complete_script: |script| {
- // A little function for holding this lint attr
- fn complete_script(script: hubbub::NodeDataPtr,
- url: Url,
- js_chan: SharedChan<JSMessage>) {
- unsafe {
- let scriptnode: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(script);
- do scriptnode.with_imm_element |script| {
- match script.get_attr("src") {
- Some(src) => {
- debug!("found script: %s", src);
- let new_url = make_url(src.to_str(), Some(url.clone()));
- js_chan.send(JSTaskNewFile(new_url));
- }
- None => {
- let mut data = ~[];
- debug!("iterating over children %?", scriptnode.first_child());
- for child in scriptnode.children() {
- debug!("child = %?", child);
- do child.with_imm_text() |text| {
- data.push(text.element.data.to_str()); // FIXME: Bad copy.
- }
+ unsafe {
+ let scriptnode: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(script);
+ do scriptnode.with_imm_element |script| {
+ match script.get_attr("src") {
+ Some(src) => {
+ debug!("found script: %s", src);
+ let new_url = make_url(src.to_str(), Some(url3.clone()));
+ js_chan2.send(JSTaskNewFile(new_url));
+ }
+ None => {
+ let mut data = ~[];
+ debug!("iterating over children %?", scriptnode.first_child());
+ for child in scriptnode.children() {
+ debug!("child = %?", child);
+ do child.with_imm_text() |text| {
+ data.push(text.element.data.to_str()); // FIXME: Bad copy.
}
-
- debug!("data = %?", data);
- js_chan.send(JSTaskNewInlineScript(data.concat(), url.clone()));
}
+
+ debug!("script data = %?", data);
+ js_chan2.send(JSTaskNewInlineScript(data.concat(), url3.clone()));
}
}
}
}
- complete_script(script, url3.clone(), js_chan2.clone());
debug!("complete script");
},
complete_style: |style| {
@@ -549,7 +562,7 @@ pub fn parse_html(cx: *JSContext,
}
}
- debug!("data = %?", data);
+ debug!("style data = %?", data);
let provenance = InlineProvenance(url_cell.take().unwrap(), data.concat());
css_chan3.send(CSSTaskNewFile(provenance));
}
@@ -557,11 +570,13 @@ pub fn parse_html(cx: *JSContext,
});
debug!("set tree handler");
- let (input_port, input_chan) = comm::stream();
- resource_task.send(Load(url.clone(), input_chan));
debug!("loaded page");
loop {
- match input_port.recv() {
+ // We already have a message from the earlier UrlChange processing.
+ match progress_msg {
+ UrlChange(*) => {
+ fail!("got UrlChange message after others");
+ }
Payload(data) => {
debug!("received data");
parser.parse_chunk(data);
@@ -573,6 +588,7 @@ pub fn parse_html(cx: *JSContext,
break;
}
}
+ progress_msg = input_port.recv();
}
css_chan.send(CSSTaskExit);
@@ -581,6 +597,7 @@ pub fn parse_html(cx: *JSContext,
HtmlParserResult {
root: root,
discovery_port: discovery_port,
+ url: final_url,
}
}