diff options
Diffstat (limited to 'components/script/layout_image.rs')
-rw-r--r-- | components/script/layout_image.rs | 81 |
1 files changed, 81 insertions, 0 deletions
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); +} |