diff options
-rw-r--r-- | components/script/parse/html.rs | 96 | ||||
-rw-r--r-- | components/script/script_task.rs | 88 |
2 files changed, 90 insertions, 94 deletions
diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index 1bef0f21c91..5f34c87d3da 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -16,72 +16,26 @@ use dom::node::{Node, NodeHelpers, TrustedNodeAddress}; use dom::servohtmlparser; use dom::servohtmlparser::ServoHTMLParser; use dom::text::Text; -use page::Page; use parse::Parser; use encoding::all::UTF_8; use encoding::types::{Encoding, DecodeReplace}; -use servo_net::resource_task::{Load, LoadData, Payload, Done, ResourceTask}; -use servo_msg::constellation_msg::LoadData as MsgLoadData; +use servo_net::resource_task::{Payload, Done, LoadResponse}; use servo_util::task_state; use servo_util::task_state::IN_HTML_PARSER; use std::ascii::AsciiExt; -use std::comm::channel; -use std::fmt::{mod, Show}; use std::str::MaybeOwned; use url::Url; -use time::{Tm, strptime}; use html5ever::Attribute; use html5ever::tree_builder::{TreeSink, QuirksMode, NodeOrText, AppendNode, AppendText}; use string_cache::QualName; -use hyper::header::{Header, HeaderFormat}; -use hyper::header::common::util as header_util; pub enum HTMLInput { InputString(String), InputUrl(Url), } -//FIXME(seanmonstar): uplift to Hyper -#[deriving(Clone)] -struct LastModified(pub Tm); - -impl Header for LastModified { - #[inline] - fn header_name(_: Option<LastModified>) -> &'static str { - "Last-Modified" - } - - // Parses an RFC 2616 compliant date/time string, - fn parse_header(raw: &[Vec<u8>]) -> Option<LastModified> { - header_util::from_one_raw_str(raw).and_then(|s: String| { - let s = s.as_slice(); - strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| { - strptime(s, "%A, %d-%b-%y %T %Z") - }).or_else(|_| { - strptime(s, "%c") - }).ok().map(|tm| LastModified(tm)) - }) - } -} - -impl HeaderFormat for LastModified { - // a localized date/time string in a format suitable - // for document.lastModified. - fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { - let LastModified(ref tm) = *self; - match tm.tm_gmtoff { - 0 => tm.rfc822().fmt(f), - _ => tm.to_utc().rfc822().fmt(f) - } - } -} - -fn dom_last_modified(tm: &Tm) -> String { - tm.to_local().strftime("%m/%d/%Y %H:%M:%S").unwrap() -} - trait SinkHelpers { fn get_or_create(&self, child: NodeOrText<TrustedNodeAddress>) -> Temporary<Node>; } @@ -207,52 +161,10 @@ impl<'a> TreeSink<TrustedNodeAddress> for servohtmlparser::Sink { } } -// The url from msg_load_data is ignored here -pub fn parse_html(page: &Page, - document: JSRef<Document>, +pub fn parse_html(document: JSRef<Document>, input: HTMLInput, - resource_task: ResourceTask, - msg_load_data: MsgLoadData) { - let (base_url, load_response) = match input { - InputUrl(ref url) => { - // Wait for the LoadResponse so that the parser knows the final URL. - let (input_chan, input_port) = channel(); - resource_task.send(Load(LoadData { - url: url.clone(), - method: msg_load_data.method, - headers: msg_load_data.headers, - data: msg_load_data.data, - cors: None, - consumer: input_chan, - })); - - let load_response = input_port.recv(); - - load_response.metadata.headers.as_ref().map(|headers| { - headers.get().map(|&LastModified(ref tm)| { - document.set_last_modified(dom_last_modified(tm)); - }); - }); - - let base_url = load_response.metadata.final_url.clone(); - - { - // Store the final URL before we start parsing, so that DOM routines - // (e.g. HTMLImageElement::update_image) can resolve relative URLs - // correctly. - *page.mut_url() = Some((base_url.clone(), true)); - } - - (Some(base_url), Some(load_response)) - }, - InputString(_) => { - match *page.url() { - Some((ref page_url, _)) => (Some(page_url.clone()), None), - None => (None, None), - } - }, - }; - + base_url: Option<Url>, + load_response: Option<LoadResponse>) { let parser = ServoHTMLParser::new(base_url.clone(), document).root(); let parser: JSRef<ServoHTMLParser> = *parser; diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 7da46d628ce..688a89757c2 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -51,7 +51,8 @@ use servo_msg::constellation_msg::{KeyModifiers, SUPER, SHIFT, CONTROL, ALT, Rep use servo_msg::constellation_msg::{Released}; use servo_msg::constellation_msg; use servo_net::image_cache_task::ImageCacheTask; -use servo_net::resource_task::ResourceTask; +use servo_net::resource_task::{ResourceTask, Load}; +use servo_net::resource_task::LoadData as NetLoadData; use servo_net::storage_task::StorageTask; use servo_util::geometry::to_frac_px; use servo_util::smallvec::{SmallVec1, SmallVec}; @@ -59,6 +60,8 @@ use servo_util::task::spawn_named_with_send_on_failure; use servo_util::task_state; use geom::point::Point2D; +use hyper::header::{Header, HeaderFormat}; +use hyper::header::common::util as header_util; use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC}; use js::jsapi::{JSContext, JSRuntime, JSTracer}; use js::jsapi::{JS_SetGCParameter, JSGC_MAX_BYTES}; @@ -71,9 +74,11 @@ use libc::size_t; use std::any::{Any, AnyRefExt}; use std::collections::HashSet; use std::comm::{channel, Sender, Receiver, Select}; +use std::fmt::{mod, Show}; use std::mem::replace; use std::rc::Rc; use std::u32; +use time::{Tm, strptime}; local_data_key!(pub StackRoots: *const RootCollection) @@ -748,7 +753,47 @@ impl ScriptTask { InputString(strval.unwrap_or("".to_string())) }; - parse_html(&*page, *document, parser_input, self.resource_task.clone(), load_data); + let (base_url, load_response) = match parser_input { + InputUrl(ref url) => { + // Wait for the LoadResponse so that the parser knows the final URL. + let (input_chan, input_port) = channel(); + self.resource_task.send(Load(NetLoadData { + url: url.clone(), + method: load_data.method, + headers: load_data.headers, + data: load_data.data, + cors: None, + consumer: input_chan, + })); + + let load_response = input_port.recv(); + + load_response.metadata.headers.as_ref().map(|headers| { + headers.get().map(|&LastModified(ref tm)| { + document.set_last_modified(dom_last_modified(tm)); + }); + }); + + let base_url = load_response.metadata.final_url.clone(); + + { + // Store the final URL before we start parsing, so that DOM routines + // (e.g. HTMLImageElement::update_image) can resolve relative URLs + // correctly. + *page.mut_url() = Some((base_url.clone(), true)); + } + + (Some(base_url), Some(load_response)) + }, + InputString(_) => { + match *page.url() { + Some((ref page_url, _)) => (Some(page_url.clone()), None), + None => (None, None), + } + }, + }; + + parse_html(*document, parser_input, base_url, load_response); url = page.get_url().clone(); document.set_ready_state(DocumentReadyStateValues::Interactive); @@ -1159,3 +1204,42 @@ pub fn get_page(page: &Rc<Page>, pipeline_id: PipelineId) -> Rc<Page> { message for a layout channel that is not associated with this script task.\ This is a bug.") } + +//FIXME(seanmonstar): uplift to Hyper +#[deriving(Clone)] +struct LastModified(pub Tm); + +impl Header for LastModified { + #[inline] + fn header_name(_: Option<LastModified>) -> &'static str { + "Last-Modified" + } + + // Parses an RFC 2616 compliant date/time string, + fn parse_header(raw: &[Vec<u8>]) -> Option<LastModified> { + header_util::from_one_raw_str(raw).and_then(|s: String| { + let s = s.as_slice(); + strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| { + strptime(s, "%A, %d-%b-%y %T %Z") + }).or_else(|_| { + strptime(s, "%c") + }).ok().map(|tm| LastModified(tm)) + }) + } +} + +impl HeaderFormat for LastModified { + // a localized date/time string in a format suitable + // for document.lastModified. + fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { + let LastModified(ref tm) = *self; + match tm.tm_gmtoff { + 0 => tm.rfc822().fmt(f), + _ => tm.to_utc().rfc822().fmt(f) + } + } +} + +fn dom_last_modified(tm: &Tm) -> String { + tm.to_local().strftime("%m/%d/%Y %H:%M:%S").unwrap() +} |