diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2016-12-16 12:16:41 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2016-12-16 16:57:20 +0100 |
commit | 21bf91c38676900fa2f1ef5a67ac05507466abfb (patch) | |
tree | 1cf92344611f5cca2f6622f62c85ef83220b7d86 | |
parent | b86aa41568463ed8454037dbd4247dd939c3f114 (diff) | |
download | servo-21bf91c38676900fa2f1ef5a67ac05507466abfb.tar.gz servo-21bf91c38676900fa2f1ef5a67ac05507466abfb.zip |
script: Add infrastructure to track subresource loads in <link> and <style> elements.
-rw-r--r-- | components/script/dom/create.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 44 | ||||
-rw-r--r-- | components/script/dom/htmlstyleelement.rs | 46 |
3 files changed, 86 insertions, 6 deletions
diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index cb591e74c55..7c9a9eeea9c 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -244,7 +244,7 @@ fn create_html_element(name: QualName, local_name!("span") => make!(HTMLSpanElement), local_name!("strike") => make!(HTMLElement), local_name!("strong") => make!(HTMLElement), - local_name!("style") => make!(HTMLStyleElement), + local_name!("style") => make!(HTMLStyleElement, creator), local_name!("sub") => make!(HTMLElement), local_name!("summary") => make!(HTMLElement), local_name!("sup") => make!(HTMLElement), diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 145b53b3ec7..54483e481db 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -62,6 +62,11 @@ pub struct HTMLLinkElement { /// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts parser_inserted: Cell<bool>, + /// The number of loads that this link element has triggered (could be more + /// than one because of imports), and how many of them have finished. + pending_loads: Cell<u32>, + /// Whether any of the loads have failed. + any_failed_load: Cell<bool>, } impl HTMLLinkElement { @@ -73,6 +78,8 @@ impl HTMLLinkElement { parser_inserted: Cell::new(creator == ElementCreator::ParserCreated), stylesheet: DOMRefCell::new(None), cssom_stylesheet: MutNullableJS::new(None), + pending_loads: Cell::new(0), + any_failed_load: Cell::new(false), } } @@ -86,6 +93,16 @@ impl HTMLLinkElement { HTMLLinkElementBinding::Wrap) } + pub fn parser_inserted(&self) -> bool { + self.parser_inserted.get() + } + + pub fn set_stylesheet(&self, s: Arc<Stylesheet>) { + assert!(self.stylesheet.borrow().is_none()); + *self.stylesheet.borrow_mut() = Some(s); + } + + pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> { self.stylesheet.borrow().clone() } @@ -217,6 +234,28 @@ impl VirtualMethods for HTMLLinkElement { impl HTMLLinkElement { + pub fn increment_pending_loads_count(&self) { + self.pending_loads.set(self.pending_loads.get() + 1) + } + + /// Returns None if there are still pending loads, or whether any load has + /// failed since the loads started. + pub fn load_finished(&self, succeeded: bool) -> Option<bool> { + assert!(self.pending_loads.get() > 0, "What finished?"); + if !succeeded { + self.any_failed_load.set(true); + } + + self.pending_loads.set(self.pending_loads.get() - 1); + if self.pending_loads.get() != 0 { + return None; + } + + let any_failed = self.any_failed_load.get(); + self.any_failed_load.set(false); + Some(any_failed) + } + /// https://html.spec.whatwg.org/multipage/#concept-link-obtain fn handle_stylesheet_url(&self, href: &str) { let document = document_from_node(self); @@ -231,8 +270,11 @@ impl HTMLLinkElement { // Step 2. let url = match document.base_url().join(href) { - Err(e) => return debug!("Parsing url {} failed: {}", href, e), Ok(url) => url, + Err(e) => { + debug!("Parsing url {} failed: {}", href, e); + return; + } }; let element = self.upcast::<Element>(); diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 8576a282052..5dbbd338199 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -12,17 +12,20 @@ use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::str::DOMString; use dom::cssstylesheet::CSSStyleSheet; use dom::document::Document; -use dom::element::Element; +use dom::element::{Element, ElementCreator}; +use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; use dom::node::{ChildrenMutation, Node, document_from_node, window_from_node}; use dom::stylesheet::StyleSheet as DOMStyleSheet; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; use script_layout_interface::message::Msg; +use std::cell::Cell; use std::sync::Arc; use style::media_queries::parse_media_query_list; use style::parser::ParserContextExtraData; use style::stylesheets::{Stylesheet, Origin}; +use stylesheet_loader::StylesheetLoader; #[dom_struct] pub struct HTMLStyleElement { @@ -30,28 +33,59 @@ pub struct HTMLStyleElement { #[ignore_heap_size_of = "Arc"] stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>, cssom_stylesheet: MutNullableJS<CSSStyleSheet>, + /// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts + parser_inserted: Cell<bool>, + pending_loads: Cell<u32>, + any_failed_load: Cell<bool>, } impl HTMLStyleElement { fn new_inherited(local_name: LocalName, prefix: Option<DOMString>, - document: &Document) -> HTMLStyleElement { + document: &Document, + creator: ElementCreator) -> HTMLStyleElement { HTMLStyleElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), stylesheet: DOMRefCell::new(None), cssom_stylesheet: MutNullableJS::new(None), + parser_inserted: Cell::new(creator == ElementCreator::ParserCreated), + pending_loads: Cell::new(0), + any_failed_load: Cell::new(false), } } #[allow(unrooted_must_root)] pub fn new(local_name: LocalName, prefix: Option<DOMString>, - document: &Document) -> Root<HTMLStyleElement> { - Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document), + document: &Document, + creator: ElementCreator) -> Root<HTMLStyleElement> { + Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document, creator), document, HTMLStyleElementBinding::Wrap) } + pub fn increment_pending_loads_count(&self) { + self.pending_loads.set(self.pending_loads.get() + 1) + } + + /// Returns None if there are still pending loads, or whether any load has + /// failed since the loads started. + pub fn load_finished(&self, succeeded: bool) -> Option<bool> { + assert!(self.pending_loads.get() > 0, "What finished?"); + if !succeeded { + self.any_failed_load.set(true); + } + + self.pending_loads.set(self.pending_loads.get() - 1); + if self.pending_loads.get() != 0 { + return None; + } + + let any_failed = self.any_failed_load.get(); + self.any_failed_load.set(false); + Some(any_failed) + } + pub fn parse_own_css(&self) { let node = self.upcast::<Node>(); let element = self.upcast::<Element>(); @@ -94,6 +128,10 @@ impl HTMLStyleElement { }) }) } + + pub fn parser_inserted(&self) -> bool { + self.parser_inserted.get() + } } impl VirtualMethods for HTMLStyleElement { |