mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
script: Add infrastructure to track subresource loads in <link> and <style> elements.
This commit is contained in:
parent
b86aa41568
commit
21bf91c386
3 changed files with 86 additions and 6 deletions
|
@ -244,7 +244,7 @@ fn create_html_element(name: QualName,
|
||||||
local_name!("span") => make!(HTMLSpanElement),
|
local_name!("span") => make!(HTMLSpanElement),
|
||||||
local_name!("strike") => make!(HTMLElement),
|
local_name!("strike") => make!(HTMLElement),
|
||||||
local_name!("strong") => 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!("sub") => make!(HTMLElement),
|
||||||
local_name!("summary") => make!(HTMLElement),
|
local_name!("summary") => make!(HTMLElement),
|
||||||
local_name!("sup") => make!(HTMLElement),
|
local_name!("sup") => make!(HTMLElement),
|
||||||
|
|
|
@ -62,6 +62,11 @@ pub struct HTMLLinkElement {
|
||||||
|
|
||||||
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
|
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
|
||||||
parser_inserted: Cell<bool>,
|
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 {
|
impl HTMLLinkElement {
|
||||||
|
@ -73,6 +78,8 @@ impl HTMLLinkElement {
|
||||||
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
|
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
|
||||||
stylesheet: DOMRefCell::new(None),
|
stylesheet: DOMRefCell::new(None),
|
||||||
cssom_stylesheet: MutNullableJS::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)
|
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>> {
|
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
|
||||||
self.stylesheet.borrow().clone()
|
self.stylesheet.borrow().clone()
|
||||||
}
|
}
|
||||||
|
@ -217,6 +234,28 @@ impl VirtualMethods for HTMLLinkElement {
|
||||||
|
|
||||||
|
|
||||||
impl 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
|
/// https://html.spec.whatwg.org/multipage/#concept-link-obtain
|
||||||
fn handle_stylesheet_url(&self, href: &str) {
|
fn handle_stylesheet_url(&self, href: &str) {
|
||||||
let document = document_from_node(self);
|
let document = document_from_node(self);
|
||||||
|
@ -231,8 +270,11 @@ impl HTMLLinkElement {
|
||||||
|
|
||||||
// Step 2.
|
// Step 2.
|
||||||
let url = match document.base_url().join(href) {
|
let url = match document.base_url().join(href) {
|
||||||
Err(e) => return debug!("Parsing url {} failed: {}", href, e),
|
|
||||||
Ok(url) => url,
|
Ok(url) => url,
|
||||||
|
Err(e) => {
|
||||||
|
debug!("Parsing url {} failed: {}", href, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let element = self.upcast::<Element>();
|
let element = self.upcast::<Element>();
|
||||||
|
|
|
@ -12,17 +12,20 @@ use dom::bindings::js::{MutNullableJS, Root};
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
use dom::cssstylesheet::CSSStyleSheet;
|
use dom::cssstylesheet::CSSStyleSheet;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::{Element, ElementCreator};
|
||||||
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{ChildrenMutation, Node, document_from_node, window_from_node};
|
use dom::node::{ChildrenMutation, Node, document_from_node, window_from_node};
|
||||||
use dom::stylesheet::StyleSheet as DOMStyleSheet;
|
use dom::stylesheet::StyleSheet as DOMStyleSheet;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use html5ever_atoms::LocalName;
|
use html5ever_atoms::LocalName;
|
||||||
use script_layout_interface::message::Msg;
|
use script_layout_interface::message::Msg;
|
||||||
|
use std::cell::Cell;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::media_queries::parse_media_query_list;
|
use style::media_queries::parse_media_query_list;
|
||||||
use style::parser::ParserContextExtraData;
|
use style::parser::ParserContextExtraData;
|
||||||
use style::stylesheets::{Stylesheet, Origin};
|
use style::stylesheets::{Stylesheet, Origin};
|
||||||
|
use stylesheet_loader::StylesheetLoader;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct HTMLStyleElement {
|
pub struct HTMLStyleElement {
|
||||||
|
@ -30,28 +33,59 @@ pub struct HTMLStyleElement {
|
||||||
#[ignore_heap_size_of = "Arc"]
|
#[ignore_heap_size_of = "Arc"]
|
||||||
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
||||||
cssom_stylesheet: MutNullableJS<CSSStyleSheet>,
|
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 {
|
impl HTMLStyleElement {
|
||||||
fn new_inherited(local_name: LocalName,
|
fn new_inherited(local_name: LocalName,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: &Document) -> HTMLStyleElement {
|
document: &Document,
|
||||||
|
creator: ElementCreator) -> HTMLStyleElement {
|
||||||
HTMLStyleElement {
|
HTMLStyleElement {
|
||||||
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
||||||
stylesheet: DOMRefCell::new(None),
|
stylesheet: DOMRefCell::new(None),
|
||||||
cssom_stylesheet: MutNullableJS::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)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(local_name: LocalName,
|
pub fn new(local_name: LocalName,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: &Document) -> Root<HTMLStyleElement> {
|
document: &Document,
|
||||||
Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document),
|
creator: ElementCreator) -> Root<HTMLStyleElement> {
|
||||||
|
Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document, creator),
|
||||||
document,
|
document,
|
||||||
HTMLStyleElementBinding::Wrap)
|
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) {
|
pub fn parse_own_css(&self) {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let element = self.upcast::<Element>();
|
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 {
|
impl VirtualMethods for HTMLStyleElement {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue