diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 66 | ||||
-rw-r--r-- | components/script/dom/htmlstyleelement.rs | 4 | ||||
-rw-r--r-- | components/script/html/cssparse.rs | 72 | ||||
-rw-r--r-- | components/script/html/hubbub_html_parser.rs | 111 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 3 | ||||
-rw-r--r-- | components/script/lib.rs | 1 | ||||
-rw-r--r-- | components/script/script_task.rs | 8 |
7 files changed, 71 insertions, 194 deletions
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index fae89c1c520..20833d89326 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -2,20 +2,25 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::HTMLLinkElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLinkElementDerived; -use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast}; +use dom::bindings::js::{JSRef, Temporary, OptionalRootable}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::Document; -use dom::element::HTMLLinkElementTypeId; +use dom::element::{AttributeHandlers, Element, HTMLLinkElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{Node, NodeHelpers, ElementNodeTypeId}; +use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; - +use layout_interface::{LayoutChan, LoadStylesheetMsg}; use servo_util::atom::Atom; -use servo_util::str::DOMString; +use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS}; +use servo_util::namespace::Null; + +use std::ascii::StrAsciiExt; +use url::UrlParser; #[deriving(Encodable)] pub struct HTMLLinkElement { @@ -72,6 +77,55 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> { _ => () } } + + fn bind_to_tree(&self, tree_in_doc: bool) { + match self.super_type() { + Some(ref s) => s.bind_to_tree(tree_in_doc), + _ => () + } + + if tree_in_doc { + let element: &JSRef<Element> = ElementCast::from_ref(self); + + // FIXME: workaround for https://github.com/mozilla/rust/issues/13246; + // we get unrooting order failures if these are inside the match. + let rel = { + let rel = element.get_attribute(Null, "rel").root(); + rel.map(|rel| rel.deref().value().as_slice().to_string()) + }; + let href = { + let href = element.get_attribute(Null, "href").root(); + href.map(|href| href.deref().value().as_slice().to_string()) + }; + + match (rel, href) { + (Some(ref rel), Some(ref href)) => { + if rel.as_slice().split(HTML_SPACE_CHARACTERS.as_slice()) + .any(|s| s.as_slice().eq_ignore_ascii_case("stylesheet")) { + self.handle_stylesheet_url(href.as_slice()); + } + } + _ => {} + } + } + } +} + +trait PrivateHTMLLinkElementHelpers { + fn handle_stylesheet_url(&self, href: &str); +} + +impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> { + fn handle_stylesheet_url(&self, href: &str) { + let window = window_from_node(self).root(); + match UrlParser::new().base_url(&window.deref().page().get_url()).parse(href) { + Ok(url) => { + let LayoutChan(ref layout_chan) = *window.deref().page().layout_chan; + layout_chan.send(LoadStylesheetMsg(url)); + } + Err(e) => debug!("Parsing url {:s} failed: {:?}", href, e) + } + } } impl Reflectable for HTMLLinkElement { diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index d32219ea8f9..3327bc48896 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -13,9 +13,9 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; -use html::cssparse::parse_inline_css; use layout_interface::{AddStylesheetMsg, LayoutChan}; use servo_util::str::DOMString; +use style::Stylesheet; #[deriving(Encodable)] pub struct HTMLStyleElement { @@ -54,7 +54,7 @@ impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> { let url = win.deref().page().get_url(); let data = node.GetTextContent().expect("Element.textContent must be a string"); - let sheet = parse_inline_css(url, data); + let sheet = Stylesheet::from_str(data.as_slice(), url); let LayoutChan(ref layout_chan) = *win.deref().page().layout_chan; layout_chan.send(AddStylesheetMsg(sheet)); } diff --git a/components/script/html/cssparse.rs b/components/script/html/cssparse.rs deleted file mode 100644 index 473b64c7d76..00000000000 --- a/components/script/html/cssparse.rs +++ /dev/null @@ -1,72 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/// Some little helpers for hooking up the HTML parser with the CSS parser. - -use std::comm::{channel, Receiver}; -use encoding::EncodingRef; -use encoding::all::UTF_8; -use style::Stylesheet; -use servo_net::resource_task::{Load, LoadData, LoadResponse, ProgressMsg, Payload, Done, ResourceTask}; -use servo_util::task::spawn_named; -use url::Url; - -/// Where a style sheet comes from. -pub enum StylesheetProvenance { - UrlProvenance(Url, ResourceTask), - InlineProvenance(Url, String), -} - -// Parses the style data and returns the stylesheet -pub fn parse_inline_css(url: Url, data: String) -> Stylesheet { - parse_css(InlineProvenance(url, data)) -} - -fn parse_css(provenance: StylesheetProvenance) -> Stylesheet { - // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding - let environment_encoding = UTF_8 as EncodingRef; - - match provenance { - UrlProvenance(url, resource_task) => { - debug!("cssparse: loading style sheet at {:s}", url.serialize()); - let (input_chan, input_port) = channel(); - resource_task.send(Load(LoadData::new(url), input_chan)); - let LoadResponse { metadata: metadata, progress_port: progress_port , ..} - = input_port.recv(); - let final_url = &metadata.final_url; - let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice()); - let iter = ProgressMsgPortIterator { progress_port: progress_port }; - Stylesheet::from_bytes_iter( - iter, final_url.clone(), - protocol_encoding_label, Some(environment_encoding)) - } - InlineProvenance(base_url, data) => { - debug!("cssparse: loading inline stylesheet {:s}", data); - Stylesheet::from_str(data.as_slice(), base_url) - } - } -} - -pub fn spawn_css_parser(provenance: StylesheetProvenance) -> Receiver<Stylesheet> { - let (result_chan, result_port) = channel(); - - spawn_named("cssparser", proc() { - result_chan.send(parse_css(provenance)); - }); - - return result_port; -} - -struct ProgressMsgPortIterator { - progress_port: Receiver<ProgressMsg> -} - -impl Iterator<Vec<u8>> for ProgressMsgPortIterator { - fn next(&mut self) -> Option<Vec<u8>> { - match self.progress_port.recv() { - Payload(data) => Some(data), - Done(..) => None - } - } -} diff --git a/components/script/html/hubbub_html_parser.rs b/components/script/html/hubbub_html_parser.rs index 4f9bd3cfb96..74dd6ca933b 100644 --- a/components/script/html/hubbub_html_parser.rs +++ b/components/script/html/hubbub_html_parser.rs @@ -10,14 +10,13 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLScriptElementCast}; use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, Root}; use dom::bindings::utils::Reflectable; use dom::document::{Document, DocumentHelpers}; -use dom::element::{AttributeHandlers, HTMLLinkElementTypeId}; +use dom::element::AttributeHandlers; use dom::htmlelement::HTMLElement; use dom::htmlheadingelement::{Heading1, Heading2, Heading3, Heading4, Heading5, Heading6}; use dom::htmlformelement::HTMLFormElement; use dom::htmlscriptelement::HTMLScriptElementHelpers; -use dom::node::{ElementNodeTypeId, NodeHelpers}; +use dom::node::NodeHelpers; use dom::types::*; -use html::cssparse::{StylesheetProvenance, UrlProvenance, spawn_css_parser}; use page::Page; use encoding::all::UTF_8; @@ -29,13 +28,12 @@ use servo_net::resource_task::{Load, LoadData, Payload, Done, ResourceTask, load use servo_util::atom::Atom; use servo_util::namespace; use servo_util::namespace::{Namespace, Null}; -use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS}; +use servo_util::str::DOMString; use servo_util::task::spawn_named; use std::ascii::StrAsciiExt; use std::mem; use std::cell::RefCell; use std::comm::{channel, Sender, Receiver}; -use style::Stylesheet; use url::{Url, UrlParser}; use http::headers::HeaderEnum; use time; @@ -65,11 +63,6 @@ pub enum HTMLInput { InputUrl(Url), } -enum CSSMessage { - CSSTaskNewFile(StylesheetProvenance), - CSSTaskExit -} - enum JSMessage { JSTaskNewFile(Url), JSTaskNewInlineScript(String, Option<Url>), @@ -78,7 +71,6 @@ enum JSMessage { /// Messages generated by the HTML parser upon discovery of additional resources pub enum HtmlDiscoveryMessage { - HtmlDiscoveredStyle(Stylesheet), HtmlDiscoveredScript(JSResult) } @@ -100,43 +92,6 @@ unsafe fn from_hubbub_node<T: Reflectable>(n: hubbub::NodeDataPtr) -> Temporary< Temporary::new(JS::from_raw(mem::transmute(n))) } -/** -Runs a task that coordinates parsing links to css stylesheets. - -This function should be spawned in a separate task and spins waiting -for the html builder to find links to css stylesheets and sends off -tasks to parse each link. When the html process finishes, it notifies -the listener, who then collects the css rules from each task it -spawned, collates them, and sends them to the given result channel. - -# Arguments - -* `to_parent` - A channel on which to send back the full set of rules. -* `from_parent` - A port on which to receive new links. - -*/ -fn css_link_listener(to_parent: Sender<HtmlDiscoveryMessage>, - from_parent: Receiver<CSSMessage>) { - let mut result_vec = vec!(); - - loop { - match from_parent.recv_opt() { - Ok(CSSTaskNewFile(provenance)) => { - result_vec.push(spawn_css_parser(provenance)); - } - Ok(CSSTaskExit) | Err(()) => { - break; - } - } - } - - // Send the sheets back in order - // FIXME: Shouldn't wait until after we've recieved CSSTaskExit to start sending these - for port in result_vec.iter() { - assert!(to_parent.send_opt(HtmlDiscoveredStyle(port.recv())).is_ok()); - } -} - fn js_script_listener(to_parent: Sender<HtmlDiscoveryMessage>, from_parent: Receiver<JSMessage>, resource_task: ResourceTask) { @@ -335,16 +290,9 @@ pub fn parse_html(page: &Page, resource_task: ResourceTask) -> HtmlParserResult { debug!("Hubbub: parsing {:?}", input); - // Spawn a CSS parser to receive links to CSS style sheets. - - let (discovery_chan, discovery_port) = channel(); - let stylesheet_chan = discovery_chan.clone(); - let (css_chan, css_msg_port) = channel(); - spawn_named("parse_html:css", proc() { - css_link_listener(stylesheet_chan, css_msg_port); - }); // Spawn a JS parser to receive JavaScript. + let (discovery_chan, discovery_port) = channel(); let resource_task2 = resource_task.clone(); let js_result_chan = discovery_chan.clone(); let (js_chan, js_msg_port) = channel(); @@ -395,7 +343,7 @@ pub fn parse_html(page: &Page, let mut parser = build_parser(unsafe { document.to_hubbub_node() }); debug!("created parser"); - let (css_chan2, js_chan2) = (css_chan.clone(), js_chan.clone()); + let js_chan2 = js_chan.clone(); let doc_cell = RefCell::new(document); @@ -447,54 +395,6 @@ pub fn parse_html(page: &Page, prefix.map(|p| p.to_string())); } - //FIXME: workaround for https://github.com/mozilla/rust/issues/13246; - // we get unrooting order failures if these are inside the match. - let rel = { - let rel = element.deref().get_attribute(Null, "rel").root(); - rel.map(|a| a.deref().Value()) - }; - let href = { - let href= element.deref().get_attribute(Null, "href").root(); - href.map(|a| a.deref().Value()) - }; - - // Spawn additional parsing, network loads, etc. from tag and attrs - let type_id = { - let node: &JSRef<Node> = NodeCast::from_ref(&*element); - node.type_id() - }; - match type_id { - // Handle CSS style sheets from <link> elements - ElementNodeTypeId(HTMLLinkElementTypeId) => { - match (rel, href) { - (Some(ref rel), Some(ref href)) => { - if rel.as_slice() - .split(HTML_SPACE_CHARACTERS.as_slice()) - .any(|s| { - s.as_slice().eq_ignore_ascii_case("stylesheet") - }) { - debug!("found CSS stylesheet: {:s}", *href); - let mut url_parser = UrlParser::new(); - match base_url { - None => (), - Some(ref base_url) => { - url_parser.base_url(base_url); - } - } - - match url_parser.parse(href.as_slice()) { - Ok(url) => css_chan2.send(CSSTaskNewFile( - UrlProvenance(url, resource_task.clone()))), - Err(e) => debug!("Parsing url {:s} failed: {:?}", *href, e) - }; - } - } - _ => {} - } - } - _ => {} - } - unsafe { element.deref().to_hubbub_node() } }, create_text: |data: String| { @@ -641,7 +541,6 @@ pub fn parse_html(page: &Page, } debug!("finished parsing"); - css_chan.send(CSSTaskExit); js_chan.send(JSTaskExit); HtmlParserResult { diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 1e5e23f9c9a..0c82c61447d 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -29,6 +29,9 @@ pub enum Msg { /// Adds the given stylesheet to the document. AddStylesheetMsg(Stylesheet), + /// Adds the given stylesheet to the document. + LoadStylesheetMsg(Url), + /// Requests a reflow. ReflowMsg(Box<Reflow>), diff --git a/components/script/lib.rs b/components/script/lib.rs index 275051435bd..c153e90bebb 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -199,7 +199,6 @@ pub mod dom { /// Parsers for HTML and CSS. pub mod html { - pub mod cssparse; pub mod hubbub_html_parser; } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index a705398d4c1..8dc4578abb8 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -23,10 +23,8 @@ use dom::node::{ElementNodeTypeId, Node, NodeHelpers}; use dom::window::{TimerId, Window, WindowHelpers}; use dom::worker::{Worker, TrustedWorkerAddress}; use dom::xmlhttprequest::{TrustedXHRAddress, XMLHttpRequest, XHRProgress}; -use html::hubbub_html_parser::{InputString, InputUrl, HtmlParserResult}; -use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredScript}; +use html::hubbub_html_parser::{InputString, InputUrl, HtmlParserResult, HtmlDiscoveredScript}; use html::hubbub_html_parser; -use layout_interface::AddStylesheetMsg; use layout_interface::{ScriptLayoutChan, LayoutChan, MatchSelectorsDocumentDamage}; use layout_interface::{ReflowDocumentDamage, ReflowForDisplay}; use layout_interface::ContentChangedDocumentDamage; @@ -682,10 +680,6 @@ impl ScriptTask { assert!(js_scripts.is_none()); js_scripts = Some(scripts); } - Ok(HtmlDiscoveredStyle(sheet)) => { - let LayoutChan(ref chan) = *page.layout_chan; - chan.send(AddStylesheetMsg(sheet)); - } Err(()) => break } } |