diff options
author | SwagColoredKitteh <kittycake@openmailbox.org> | 2017-01-23 18:59:25 +0100 |
---|---|---|
committer | SwagColoredKitteh <kittycake@openmailbox.org> | 2017-01-24 15:52:01 +0100 |
commit | bb2826e41fe0132eea81c72cc14f85f6f8bf5437 (patch) | |
tree | 86f69b847c173b3cc4e40b0593ccbe01346b2657 /components/script/stylesheet_loader.rs | |
parent | 1b68f7946858ccd25132fe5e04923f23e269c6b0 (diff) | |
download | servo-bb2826e41fe0132eea81c72cc14f85f6f8bf5437.tar.gz servo-bb2826e41fe0132eea81c72cc14f85f6f8bf5437.zip |
fix issue #15101 and make sure out-of-order stylesheet loads work correctly for the same element
Diffstat (limited to 'components/script/stylesheet_loader.rs')
-rw-r--r-- | components/script/stylesheet_loader.rs | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs index 8e5481df8aa..cdc93c9808b 100644 --- a/components/script/stylesheet_loader.rs +++ b/components/script/stylesheet_loader.rs @@ -10,7 +10,7 @@ use dom::document::Document; use dom::element::Element; use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; -use dom::htmllinkelement::HTMLLinkElement; +use dom::htmllinkelement::{RequestGenerationId, HTMLLinkElement}; use dom::node::{document_from_node, window_from_node}; use encoding::EncodingRef; use encoding::all::UTF_8; @@ -85,6 +85,9 @@ pub struct StylesheetContext { /// The node document for elem when the load was initiated. document: Trusted<Document>, origin_clean: bool, + /// A token which must match the generation id of the `HTMLLinkElement` for it to load the stylesheet. + /// This is ignored for `HTMLStyleElement` and imports. + request_generation_id: Option<RequestGenerationId>, } impl PreInvoke for StylesheetContext {} @@ -143,24 +146,30 @@ impl FetchResponseListener for StylesheetContext { let loader = StylesheetLoader::for_element(&elem); match self.source { StylesheetContextSource::LinkElement { ref mut media, .. } => { - let sheet = - Arc::new(Stylesheet::from_bytes(&data, final_url, - protocol_encoding_label, - Some(environment_encoding), - Origin::Author, - media.take().unwrap(), - Some(&loader), - win.css_error_reporter(), - ParserContextExtraData::default())); - if elem.downcast::<HTMLLinkElement>().unwrap().is_alternate() { - sheet.set_disabled(true); + let link = elem.downcast::<HTMLLinkElement>().unwrap(); + // We must first check whether the generations of the context and the element match up, + // else we risk applying the wrong stylesheet when responses come out-of-order. + let is_stylesheet_load_applicable = + self.request_generation_id.map_or(true, |gen| gen == link.get_request_generation_id()); + if is_stylesheet_load_applicable { + let sheet = + Arc::new(Stylesheet::from_bytes(&data, final_url, + protocol_encoding_label, + Some(environment_encoding), + Origin::Author, + media.take().unwrap(), + Some(&loader), + win.css_error_reporter(), + ParserContextExtraData::default())); + + if link.is_alternate() { + sheet.set_disabled(true); + } + + link.set_stylesheet(sheet.clone()); + + win.layout_chan().send(Msg::AddStylesheet(sheet)).unwrap(); } - elem.downcast::<HTMLLinkElement>() - .unwrap() - .set_stylesheet(sheet.clone()); - - let win = window_from_node(&*elem); - win.layout_chan().send(Msg::AddStylesheet(sheet)).unwrap(); } StylesheetContextSource::Import(ref import) => { let import = import.read(); @@ -215,6 +224,8 @@ impl<'a> StylesheetLoader<'a> { integrity_metadata: String) { let url = source.url(); let document = document_from_node(self.elem); + let gen = self.elem.downcast::<HTMLLinkElement>() + .map(HTMLLinkElement::get_request_generation_id); let context = Arc::new(Mutex::new(StylesheetContext { elem: Trusted::new(&*self.elem), source: source, @@ -222,6 +233,7 @@ impl<'a> StylesheetLoader<'a> { data: vec![], document: Trusted::new(&*document), origin_clean: true, + request_generation_id: gen, })); let (action_sender, action_receiver) = ipc::channel().unwrap(); |