aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/document_loader.rs7
-rw-r--r--components/script/dom/window.rs75
-rw-r--r--components/script/layout_image.rs81
-rw-r--r--components/script/lib.rs1
4 files changed, 92 insertions, 72 deletions
diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs
index 30d83019c5f..a4ce36a2f57 100644
--- a/components/script/document_loader.rs
+++ b/components/script/document_loader.rs
@@ -116,6 +116,13 @@ impl DocumentLoader {
request: RequestInit,
fetch_target: IpcSender<FetchResponseMsg>) {
self.add_blocking_load(load);
+ self.fetch_async_background(request, fetch_target);
+ }
+
+ /// Initiate a new fetch that does not block the document load event.
+ pub fn fetch_async_background(&mut self,
+ request: RequestInit,
+ fetch_target: IpcSender<FetchResponseMsg>) {
self.resource_threads.sender().send(CoreResourceMsg::Fetch(request, fetch_target)).unwrap();
}
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 71dbdc8e8d4..93cdd1c31d0 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -6,7 +6,6 @@ use app_units::Au;
use bluetooth_traits::BluetoothRequest;
use cssparser::Parser;
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
-use document_loader::LoadType;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
@@ -43,7 +42,7 @@ use dom::location::Location;
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
use dom::messageevent::MessageEvent;
use dom::navigator::Navigator;
-use dom::node::{Node, from_untrusted_node_address, window_from_node, document_from_node, NodeDamage};
+use dom::node::{Node, from_untrusted_node_address, window_from_node, NodeDamage};
use dom::performance::Performance;
use dom::promise::Promise;
use dom::screen::Screen;
@@ -58,14 +57,12 @@ use js::jsapi::{HandleObject, HandleValue, JSAutoCompartment, JSContext};
use js::jsapi::{JS_GC, JS_GetRuntime};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
+use layout_image::fetch_image_for_layout;
use msg::constellation_msg::{FrameType, PipelineId};
-use net_traits::{FetchResponseMsg, NetworkError};
-use net_traits::{ResourceThreads, ReferrerPolicy, FetchResponseListener, FetchMetadata};
+use net_traits::{ResourceThreads, ReferrerPolicy};
use net_traits::image_cache_thread::{ImageResponder, ImageResponse};
use net_traits::image_cache_thread::{PendingImageResponse, ImageCacheThread, PendingImageId};
-use net_traits::request::{Type as RequestType, RequestInit as FetchRequestInit};
use net_traits::storage_thread::StorageType;
-use network_listener::{NetworkListener, PreInvoke};
use num_traits::ToPrimitive;
use open;
use profile_traits::mem::ProfilerChan as MemProfilerChan;
@@ -1894,69 +1891,3 @@ impl Runnable for PostMessageHandler {
message.handle());
}
}
-
-struct LayoutImageContext {
- node: Trusted<Node>,
- id: PendingImageId,
- url: ServoUrl,
- cache: ImageCacheThread,
-}
-
-impl FetchResponseListener for LayoutImageContext {
- fn process_request_body(&mut self) {}
- fn process_request_eof(&mut self) {}
- fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
- self.cache.notify_pending_response(
- self.id,
- FetchResponseMsg::ProcessResponse(metadata));
- }
-
- fn process_response_chunk(&mut self, payload: Vec<u8>) {
- self.cache.notify_pending_response(
- self.id,
- FetchResponseMsg::ProcessResponseChunk(payload));
- }
-
- fn process_response_eof(&mut self, response: Result<(), NetworkError>) {
- let node = self.node.root();
- let document = document_from_node(&*node);
- self.cache.notify_pending_response(self.id,
- FetchResponseMsg::ProcessResponseEOF(response));
- document.finish_load(LoadType::Image(self.url.clone()));
- }
-}
-
-impl PreInvoke for LayoutImageContext {}
-
-fn fetch_image_for_layout(url: ServoUrl, node: &Node, id: PendingImageId, cache: ImageCacheThread) {
- let context = Arc::new(Mutex::new(LayoutImageContext {
- node: Trusted::new(node),
- id: id,
- url: url.clone(),
- cache: cache,
- }));
-
- let document = document_from_node(node);
- let window = window_from_node(node);
-
- let (action_sender, action_receiver) = ipc::channel().unwrap();
- let listener = NetworkListener {
- context: context,
- task_source: window.networking_task_source(),
- wrapper: Some(window.get_runnable_wrapper()),
- };
- ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
- listener.notify_fetch(message.to().unwrap());
- });
-
- let request = FetchRequestInit {
- url: url.clone(),
- origin: document.url().clone(),
- type_: RequestType::Image,
- pipeline_id: Some(document.global().pipeline_id()),
- .. FetchRequestInit::default()
- };
-
- //XXXjdm should not block load event
- document.fetch_async(LoadType::Image(url), request, action_sender);
-}
diff --git a/components/script/layout_image.rs b/components/script/layout_image.rs
new file mode 100644
index 00000000000..d903b435c26
--- /dev/null
+++ b/components/script/layout_image.rs
@@ -0,0 +1,81 @@
+/* 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/. */
+
+//! Infrastructure to initiate network requests for images needed by the layout
+//! thread. The script thread needs to be responsible for them because there's
+//! no guarantee that the responsible nodes will still exist in the future if the
+//! layout thread holds on to them during asynchronous operations.
+
+use dom::bindings::reflector::DomObject;
+use dom::node::{Node, document_from_node};
+use ipc_channel::ipc;
+use ipc_channel::router::ROUTER;
+use net_traits::{FetchResponseMsg, FetchResponseListener, FetchMetadata, NetworkError};
+use net_traits::image_cache_thread::{ImageCacheThread, PendingImageId};
+use net_traits::request::{Type as RequestType, RequestInit as FetchRequestInit};
+use network_listener::{NetworkListener, PreInvoke};
+use servo_url::ServoUrl;
+use std::sync::{Arc, Mutex};
+
+struct LayoutImageContext {
+ id: PendingImageId,
+ cache: ImageCacheThread,
+}
+
+impl FetchResponseListener for LayoutImageContext {
+ fn process_request_body(&mut self) {}
+ fn process_request_eof(&mut self) {}
+ fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
+ self.cache.notify_pending_response(
+ self.id,
+ FetchResponseMsg::ProcessResponse(metadata));
+ }
+
+ fn process_response_chunk(&mut self, payload: Vec<u8>) {
+ self.cache.notify_pending_response(
+ self.id,
+ FetchResponseMsg::ProcessResponseChunk(payload));
+ }
+
+ fn process_response_eof(&mut self, response: Result<(), NetworkError>) {
+ self.cache.notify_pending_response(self.id,
+ FetchResponseMsg::ProcessResponseEOF(response));
+ }
+}
+
+impl PreInvoke for LayoutImageContext {}
+
+pub fn fetch_image_for_layout(url: ServoUrl,
+ node: &Node,
+ id: PendingImageId,
+ cache: ImageCacheThread) {
+ let context = Arc::new(Mutex::new(LayoutImageContext {
+ id: id,
+ cache: cache,
+ }));
+
+ let document = document_from_node(node);
+ let window = document.window();
+
+ let (action_sender, action_receiver) = ipc::channel().unwrap();
+ let listener = NetworkListener {
+ context: context,
+ task_source: window.networking_task_source(),
+ wrapper: Some(window.get_runnable_wrapper()),
+ };
+ ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
+ listener.notify_fetch(message.to().unwrap());
+ });
+
+ let request = FetchRequestInit {
+ url: url,
+ origin: document.url().clone(),
+ type_: RequestType::Image,
+ pipeline_id: Some(document.global().pipeline_id()),
+ .. FetchRequestInit::default()
+ };
+
+ // Layout image loads do not delay the document load event.
+ document.mut_loader().fetch_async_background(request, action_sender);
+}
diff --git a/components/script/lib.rs b/components/script/lib.rs
index e5c93357bd2..81c7eb0901f 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -110,6 +110,7 @@ pub mod document_loader;
#[macro_use]
mod dom;
pub mod fetch;
+mod layout_image;
pub mod layout_wrapper;
mod mem;
mod microtask;