diff options
-rw-r--r-- | components/script/document_loader.rs | 7 | ||||
-rw-r--r-- | components/script/dom/window.rs | 75 | ||||
-rw-r--r-- | components/script/layout_image.rs | 81 | ||||
-rw-r--r-- | components/script/lib.rs | 1 |
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; |