aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Brubeck <mbrubeck@limpet.net>2014-09-15 12:39:18 -0700
committerMatt Brubeck <mbrubeck@limpet.net>2014-09-16 07:12:01 -0700
commit1ae3bda172939a3f142f89e63eaa5758ba563935 (patch)
tree03f1f962c6a64d4e1c125f9536ea09cd8a8a418b
parent7a5f15f13723a6c510ed05ad7875eb10b290dea2 (diff)
downloadservo-1ae3bda172939a3f142f89e63eaa5758ba563935.tar.gz
servo-1ae3bda172939a3f142f89e63eaa5758ba563935.zip
Move link rel=stylesheet fetching to layout task
Fixes #3346.
-rw-r--r--Cargo.lock1
-rw-r--r--components/compositing/pipeline.rs3
-rw-r--r--components/layout/Cargo.toml3
-rw-r--r--components/layout/layout_task.rs25
-rw-r--r--components/layout/lib.rs1
-rw-r--r--components/layout_traits/lib.rs2
-rw-r--r--components/net/resource_task.rs28
-rw-r--r--components/script/dom/htmllinkelement.rs66
-rw-r--r--components/script/dom/htmlstyleelement.rs4
-rw-r--r--components/script/html/cssparse.rs72
-rw-r--r--components/script/html/hubbub_html_parser.rs111
-rw-r--r--components/script/layout_interface.rs3
-rw-r--r--components/script/lib.rs1
-rw-r--r--components/script/script_task.rs8
-rw-r--r--tests/ref/basic.list1
-rw-r--r--tests/ref/link_style_order.html11
-rw-r--r--tests/ref/link_style_order_ref.html10
17 files changed, 154 insertions, 196 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 57f5b658e50..8220a58ce77 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -256,6 +256,7 @@ dependencies = [
name = "layout"
version = "0.0.1"
dependencies = [
+ "encoding 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding#12b6610adff6eddc060691888c36017cd3ad57f7)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)",
"gfx 0.0.1",
"layout_traits 0.0.1",
diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs
index 8ccc0fe48a5..8dd8c1f0de7 100644
--- a/components/compositing/pipeline.rs
+++ b/components/compositing/pipeline.rs
@@ -80,7 +80,7 @@ impl Pipeline {
script_port,
constellation_chan.clone(),
failure.clone(),
- resource_task,
+ resource_task.clone(),
image_cache_task.clone(),
window_size);
ScriptControlChan(script_chan)
@@ -117,6 +117,7 @@ impl Pipeline {
failure,
script_chan.clone(),
render_chan.clone(),
+ resource_task,
image_cache_task,
font_cache_task,
opts.clone(),
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml
index 9d8e8abbdaa..ed1ba4a5740 100644
--- a/components/layout/Cargo.toml
+++ b/components/layout/Cargo.toml
@@ -31,6 +31,9 @@ path = "../net"
[dependencies.util]
path = "../util"
+[dependencies.encoding]
+git = "https://github.com/lifthrasiir/rust-encoding"
+
[dependencies.geom]
git = "https://github.com/servo/rust-geom"
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 36db0d8c44e..bed96555e4b 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -21,6 +21,8 @@ use util::{LayoutDataAccess, LayoutDataWrapper, OpaqueNodeMethods, ToGfxColor};
use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
use collections::dlist::DList;
+use encoding::EncodingRef;
+use encoding::all::UTF_8;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
@@ -33,7 +35,7 @@ use layout_traits::{LayoutControlMsg, LayoutTaskFactory};
use script::dom::bindings::js::JS;
use script::dom::node::{ElementNodeTypeId, LayoutDataRef, Node};
use script::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId};
-use script::layout_interface::{AddStylesheetMsg, ScriptLayoutChan};
+use script::layout_interface::{AddStylesheetMsg, LoadStylesheetMsg, ScriptLayoutChan};
use script::layout_interface::{TrustedNodeAddress, ContentBoxesResponse, ExitNowMsg};
use script::layout_interface::{ContentBoxResponse, HitTestResponse, MouseOverResponse};
use script::layout_interface::{ContentChangedDocumentDamage, LayoutChan, Msg, PrepareToExitMsg};
@@ -46,6 +48,7 @@ use servo_net::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use gfx::font_cache_task::{FontCacheTask};
use servo_net::local_image_cache::{ImageResponder, LocalImageCache};
use servo_util::bloom::BloomFilter;
+use servo_net::resource_task::{ResourceTask, load_bytes_iter};
use servo_util::geometry::Au;
use servo_util::geometry;
use servo_util::logical_geometry::LogicalPoint;
@@ -112,6 +115,9 @@ pub struct LayoutTask {
/// The channel on which messages can be sent to the time profiler.
pub time_profiler_chan: TimeProfilerChan,
+ /// The channel on which messages can be sent to the resource task.
+ pub resource_task: ResourceTask,
+
/// The channel on which messages can be sent to the image cache.
pub image_cache_task: ImageCacheTask,
@@ -298,6 +304,7 @@ impl LayoutTaskFactory for LayoutTask {
failure_msg: Failure,
script_chan: ScriptControlChan,
render_chan: RenderChan,
+ resource_task: ResourceTask,
img_cache_task: ImageCacheTask,
font_cache_task: FontCacheTask,
opts: Opts,
@@ -316,6 +323,7 @@ impl LayoutTaskFactory for LayoutTask {
constellation_chan,
script_chan,
render_chan,
+ resource_task,
img_cache_task,
font_cache_task,
&opts,
@@ -365,6 +373,7 @@ impl LayoutTask {
constellation_chan: ConstellationChan,
script_chan: ScriptControlChan,
render_chan: RenderChan,
+ resource_task: ResourceTask,
image_cache_task: ImageCacheTask,
font_cache_task: FontCacheTask,
opts: &Opts,
@@ -387,6 +396,7 @@ impl LayoutTask {
script_chan: script_chan,
render_chan: render_chan,
time_profiler_chan: time_profiler_chan,
+ resource_task: resource_task,
image_cache_task: image_cache_task.clone(),
font_cache_task: font_cache_task,
opts: opts.clone(),
@@ -494,6 +504,7 @@ impl LayoutTask {
fn handle_script_request<'a>(&'a self, request: Msg, possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) -> bool {
match request {
AddStylesheetMsg(sheet) => self.handle_add_stylesheet(sheet, possibly_locked_rw_data),
+ LoadStylesheetMsg(url) => self.handle_load_stylesheet(url, possibly_locked_rw_data),
GetRPCMsg(response_chan) => {
response_chan.send(
box LayoutRPCImpl(
@@ -567,6 +578,18 @@ impl LayoutTask {
response_port.recv()
}
+ fn handle_load_stylesheet<'a>(&'a self, url: Url, possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
+ // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
+ let environment_encoding = UTF_8 as EncodingRef;
+
+ let (metadata, iter) = load_bytes_iter(&self.resource_task, url);
+ let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice());
+ let final_url = metadata.final_url;
+
+ let sheet = Stylesheet::from_bytes_iter(iter, final_url, protocol_encoding_label, Some(environment_encoding));
+ self.handle_add_stylesheet(sheet, possibly_locked_rw_data);
+ }
+
fn handle_add_stylesheet<'a>(&'a self, sheet: Stylesheet, possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
// Find all font-face rules and notify the font cache of them.
// GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!)
diff --git a/components/layout/lib.rs b/components/layout/lib.rs
index 8cd1b44b4e2..768cfa9992a 100644
--- a/components/layout/lib.rs
+++ b/components/layout/lib.rs
@@ -29,6 +29,7 @@ extern crate servo_msg = "msg";
extern crate servo_util = "util";
extern crate collections;
+extern crate encoding;
extern crate green;
extern crate libc;
extern crate sync;
diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs
index 438afed3225..61cd57fedfe 100644
--- a/components/layout_traits/lib.rs
+++ b/components/layout_traits/lib.rs
@@ -23,6 +23,7 @@ use gfx::render_task::RenderChan;
use servo_msg::constellation_msg::{ConstellationChan, PipelineId};
use servo_msg::constellation_msg::Failure;
use servo_net::image_cache_task::ImageCacheTask;
+use servo_net::resource_task::ResourceTask;
use servo_util::opts::Opts;
use servo_util::time::TimeProfilerChan;
use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel};
@@ -48,6 +49,7 @@ pub trait LayoutTaskFactory {
failure_msg: Failure,
script_chan: ScriptControlChan,
render_chan: RenderChan,
+ resource_task: ResourceTask,
img_cache_task: ImageCacheTask,
font_cache_task: FontCacheTask,
opts: Opts,
diff --git a/components/net/resource_task.rs b/components/net/resource_task.rs
index cdc44fe2cec..f25c1efa258 100644
--- a/components/net/resource_task.rs
+++ b/components/net/resource_task.rs
@@ -219,6 +219,34 @@ impl ResourceManager {
}
}
+/// Load a URL asynchronously and iterate over chunks of bytes from the response.
+pub fn load_bytes_iter(resource_task: &ResourceTask, url: Url) -> (Metadata, ProgressMsgPortIterator) {
+ let (input_chan, input_port) = channel();
+ resource_task.send(Load(LoadData::new(url), input_chan));
+
+ let response = input_port.recv();
+ let iter = ProgressMsgPortIterator { progress_port: response.progress_port };
+ (response.metadata, iter)
+}
+
+/// Iterator that reads chunks of bytes from a ProgressMsg port
+pub 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(Ok(())) => None,
+ Done(Err(e)) => {
+ error!("error receiving bytes: {}", e);
+ None
+ }
+ }
+ }
+}
+
#[test]
fn test_exit() {
let resource_task = new_resource_task();
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
}
}
diff --git a/tests/ref/basic.list b/tests/ref/basic.list
index 9cdcdb108fb..b5131f20389 100644
--- a/tests/ref/basic.list
+++ b/tests/ref/basic.list
@@ -124,3 +124,4 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html
== inline_block_baseline_a.html inline_block_baseline_ref.html
== float_table_a.html float_table_ref.html
== table_containing_block_a.html table_containing_block_ref.html
+== link_style_order.html link_style_order_ref.html
diff --git a/tests/ref/link_style_order.html b/tests/ref/link_style_order.html
new file mode 100644
index 00000000000..0cac3321ae9
--- /dev/null
+++ b/tests/ref/link_style_order.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>link/style order test</title>
+ <link rel="stylesheet" href="data:text/css,body{background:red;}">
+ <style>body { background: green; }</style>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/ref/link_style_order_ref.html b/tests/ref/link_style_order_ref.html
new file mode 100644
index 00000000000..f3ec1128afd
--- /dev/null
+++ b/tests/ref/link_style_order_ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>link/style order test</title>
+ <style>body { background: green; }</style>
+ </head>
+ <body>
+ </body>
+</html>