servo: Merge #14841 - Track stylesheet load's document instead of using element's current document (from jdm:stylesheet_document); r=emilio
authorJosh Matthews <josh@joshmatthews.net>
Wed, 04 Jan 2017 07:26:04 -0800
changeset 340474 7f309d03fd4baedaba5206e7ab537a11b33a450f
parent 340473 b2a4b1399cd6402faae03468bfc64a56b333071f
child 340475 1b1e46d4caf041497cb905cc3bf5e72b7fab6317
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
servo: Merge #14841 - Track stylesheet load's document instead of using element's current document (from jdm:stylesheet_document); r=emilio For cases where a stylesheet load finishes in a different document than it started, we need to be more careful about which document we report the completion to. In this case we actually have separate requests for each document involved, but they previously used the same element to determine which document to interact with. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14641 - [X] There are tests for these changes OR Source-Repo: https://github.com/servo/servo Source-Revision: 384e905be23cd10e7bc352da1171b9af9e6eaddc
servo/components/script/stylesheet_loader.rs
--- a/servo/components/script/stylesheet_loader.rs
+++ b/servo/components/script/stylesheet_loader.rs
@@ -1,16 +1,17 @@
 /* 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/. */
 
 use document_loader::LoadType;
 use dom::bindings::inheritance::Castable;
 use dom::bindings::refcounted::Trusted;
 use dom::bindings::reflector::DomObject;
+use dom::document::Document;
 use dom::element::Element;
 use dom::eventtarget::EventTarget;
 use dom::htmlelement::HTMLElement;
 use dom::htmllinkelement::HTMLLinkElement;
 use dom::node::{document_from_node, window_from_node};
 use encoding::EncodingRef;
 use encoding::all::UTF_8;
 use hyper::header::ContentType;
@@ -73,16 +74,18 @@ impl StylesheetContextSource {
 /// The context required for asynchronously loading an external stylesheet.
 pub struct StylesheetContext {
     /// The element that initiated the request.
     elem: Trusted<HTMLElement>,
     source: StylesheetContextSource,
     metadata: Option<Metadata>,
     /// The response body received to date.
     data: Vec<u8>,
+    /// The node document for elem when the load was initiated.
+    document: Trusted<Document>,
 }
 
 impl PreInvoke for StylesheetContext {}
 
 impl FetchResponseListener for StylesheetContext {
     fn process_request_body(&mut self) {}
 
     fn process_request_eof(&mut self) {}
@@ -98,17 +101,17 @@ impl FetchResponseListener for Styleshee
     }
 
     fn process_response_chunk(&mut self, mut payload: Vec<u8>) {
         self.data.append(&mut payload);
     }
 
     fn process_response_eof(&mut self, status: Result<(), NetworkError>) {
         let elem = self.elem.root();
-        let document = document_from_node(&*elem);
+        let document = self.document.root();
         let mut successful = false;
 
         if status.is_ok() {
             let metadata = match self.metadata.take() {
                 Some(meta) => meta,
                 None => return,
             };
             let is_css = metadata.content_type.map_or(false, |Serde(ContentType(Mime(top, sub, _)))|
@@ -187,25 +190,25 @@ impl<'a> StylesheetLoader<'a> {
             elem: element,
         }
     }
 }
 
 impl<'a> StylesheetLoader<'a> {
     pub fn load(&self, source: StylesheetContextSource) {
         let url = source.url();
+        let document = document_from_node(self.elem);
         let context = Arc::new(Mutex::new(StylesheetContext {
             elem: Trusted::new(&*self.elem),
             source: source,
             metadata: None,
             data: vec![],
+            document: Trusted::new(&*document),
         }));
 
-        let document = document_from_node(self.elem);
-
         let (action_sender, action_receiver) = ipc::channel().unwrap();
         let listener = NetworkListener {
             context: context,
             task_source: document.window().networking_task_source(),
             wrapper: Some(document.window().get_runnable_wrapper())
         };
         ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
             listener.notify_fetch(message.to().unwrap());