diff options
Diffstat (limited to 'components/script/dom/htmlimageelement.rs')
-rw-r--r-- | components/script/dom/htmlimageelement.rs | 152 |
1 files changed, 67 insertions, 85 deletions
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index b5f20784c8e..052b622bb9f 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -43,7 +43,7 @@ use crate::dom::values::UNSIGNED_LONG_MAX; use crate::dom::virtualmethods::VirtualMethods; use crate::dom::window::Window; use crate::fetch::create_a_potential_cors_request; -use crate::image_listener::{add_cache_listener_for_element, ImageCacheListener}; +use crate::image_listener::{generate_cache_listener_for_element, ImageCacheListener}; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; use crate::script_thread::ScriptThread; @@ -54,13 +54,15 @@ use dom_struct::dom_struct; use euclid::Point2D; use html5ever::{LocalName, Prefix, QualName}; use ipc_channel::ipc; +use ipc_channel::ipc::IpcSender; use ipc_channel::router::ROUTER; use mime::{self, Mime}; use msg::constellation_msg::PipelineId; use net_traits::image::base::{Image, ImageMetadata}; -use net_traits::image_cache::UsePlaceholder; -use net_traits::image_cache::{CanRequestImages, CorsStatus, ImageCache, ImageOrMetadataAvailable}; -use net_traits::image_cache::{ImageResponder, ImageResponse, ImageState, PendingImageId}; +use net_traits::image_cache::{ + CanRequestImages, CorsStatus, ImageCache, ImageCacheResult, ImageOrMetadataAvailable, + ImageResponse, PendingImageId, PendingImageResponse, UsePlaceholder, +}; use net_traits::request::{CorsSettings, Destination, Initiator, RequestBuilder}; use net_traits::{FetchMetadata, FetchResponseListener, FetchResponseMsg, NetworkError}; use net_traits::{ReferrerPolicy, ResourceFetchTiming, ResourceTimingType}; @@ -317,35 +319,27 @@ impl HTMLImageElement { fn fetch_image(&self, img_url: &ServoUrl) { let window = window_from_node(self); let image_cache = window.image_cache(); - let response = image_cache.find_image_or_metadata( - img_url.clone().into(), + let sender = generate_cache_listener_for_element(self); + let cache_result = image_cache.track_image( + img_url.clone(), window.origin().immutable().clone(), cors_setting_for_element(self.upcast()), + sender, UsePlaceholder::Yes, CanRequestImages::Yes, ); - match response { - Ok(ImageOrMetadataAvailable::ImageAvailable(image, url)) => { - self.process_image_response(ImageResponse::Loaded(image, url)); - }, - Ok(ImageOrMetadataAvailable::MetadataAvailable(m)) => { - self.process_image_response(ImageResponse::MetadataLoaded(m)); + match cache_result { + ImageCacheResult::Available(ImageOrMetadataAvailable::ImageAvailable(image, url)) => { + self.process_image_response(ImageResponse::Loaded(image, url)) }, - - Err(ImageState::Pending(id)) => { - add_cache_listener_for_element(image_cache, id, self); + ImageCacheResult::Available(ImageOrMetadataAvailable::MetadataAvailable(m)) => { + self.process_image_response(ImageResponse::MetadataLoaded(m)) }, - - Err(ImageState::LoadError) => { - self.process_image_response(ImageResponse::None); - }, - - Err(ImageState::NotRequested(id)) => { - add_cache_listener_for_element(image_cache, id, self); - self.fetch_request(img_url, id); - }, - } + ImageCacheResult::Pending(_) => (), + ImageCacheResult::ReadyForRequest(id) => self.fetch_request(img_url, id), + ImageCacheResult::LoadError => self.process_image_response(ImageResponse::None), + }; } fn fetch_request(&self, img_url: &ServoUrl, id: PendingImageId) { @@ -943,14 +937,13 @@ impl HTMLImageElement { if let Some(src) = selected_source { if let Ok(img_url) = base_url.join(&src) { let image_cache = window.image_cache(); - let response = image_cache.find_image_or_metadata( - img_url.clone().into(), + let response = image_cache.get_image( + img_url.clone(), window.origin().immutable().clone(), cors_setting_for_element(self.upcast()), - UsePlaceholder::No, - CanRequestImages::No, ); - if let Ok(ImageOrMetadataAvailable::ImageAvailable(image, url)) = response { + + if let Some(image) = response { // Cancel any outstanding tasks that were queued before the src was // set on this element. self.generation.set(self.generation.get() + 1); @@ -963,7 +956,7 @@ impl HTMLImageElement { self.abort_request(State::CompletelyAvailable, ImageRequestPhase::Current); self.abort_request(State::Unavailable, ImageRequestPhase::Pending); let mut current_request = self.current_request.borrow_mut(); - current_request.final_url = Some(url); + current_request.final_url = Some(img_url.clone()); current_request.image = Some(image.clone()); current_request.metadata = Some(metadata); // Step 6.3.6 @@ -1010,13 +1003,12 @@ impl HTMLImageElement { /// Step 2-12 of https://html.spec.whatwg.org/multipage/#img-environment-changes fn react_to_environment_changes_sync_steps(&self, generation: u32) { // TODO reduce duplicacy of this code - fn add_cache_listener_for_element( - image_cache: Arc<dyn ImageCache>, - id: PendingImageId, + + fn generate_cache_listener_for_element( elem: &HTMLImageElement, selected_source: String, selected_pixel_density: f64, - ) { + ) -> IpcSender<PendingImageResponse> { let trusted_node = Trusted::new(elem); let (responder_sender, responder_receiver) = ipc::channel().unwrap(); @@ -1025,27 +1017,30 @@ impl HTMLImageElement { .task_manager() .networking_task_source_with_canceller(); let generation = elem.generation.get(); - ROUTER.add_route(responder_receiver.to_opaque(), Box::new(move |message| { - debug!("Got image {:?}", message); - // Return the image via a message to the script thread, which marks - // the element as dirty and triggers a reflow. - let element = trusted_node.clone(); - let image = message.to().unwrap(); - let selected_source_clone = selected_source.clone(); - let _ = task_source.queue_with_canceller( - task!(process_image_response_for_environment_change: move || { - let element = element.root(); - // Ignore any image response for a previous request that has been discarded. - if generation == element.generation.get() { - element.process_image_response_for_environment_change(image, - USVString::from(selected_source_clone), generation, selected_pixel_density); - } - }), - &canceller, - ); - })); + ROUTER.add_route( + responder_receiver.to_opaque(), + Box::new(move |message| { + debug!("Got image {:?}", message); + // Return the image via a message to the script thread, which marks + // the element as dirty and triggers a reflow. + let element = trusted_node.clone(); + let image = message.to().unwrap(); + let selected_source_clone = selected_source.clone(); + let _ = task_source.queue_with_canceller( + task!(process_image_response_for_environment_change: move || { + let element = element.root(); + // Ignore any image response for a previous request that has been discarded. + if generation == element.generation.get() { + element.process_image_response_for_environment_change(image, + USVString::from(selected_source_clone), generation, selected_pixel_density); + } + }), + &canceller, + ); + }), + ); - image_cache.add_listener(id, ImageResponder::new(responder_sender, id)); + responder_sender } let elem = self.upcast::<Element>(); @@ -1099,25 +1094,32 @@ impl HTMLImageElement { let window = window_from_node(self); let image_cache = window.image_cache(); + // Step 14 - let response = image_cache.find_image_or_metadata( - img_url.clone().into(), + let sender = generate_cache_listener_for_element( + self, + selected_source.0.clone(), + selected_pixel_density, + ); + let cache_result = image_cache.track_image( + img_url.clone(), window.origin().immutable().clone(), cors_setting_for_element(self.upcast()), + sender, UsePlaceholder::No, CanRequestImages::Yes, ); - match response { - Ok(ImageOrMetadataAvailable::ImageAvailable(_image, _url)) => { + + match cache_result { + ImageCacheResult::Available(ImageOrMetadataAvailable::ImageAvailable(_image, _url)) => { // Step 15 self.finish_reacting_to_environment_change( selected_source, generation, selected_pixel_density, - ); + ) }, - - Ok(ImageOrMetadataAvailable::MetadataAvailable(m)) => { + ImageCacheResult::Available(ImageOrMetadataAvailable::MetadataAvailable(m)) => { self.process_image_response_for_environment_change( ImageResponse::MetadataLoaded(m), selected_source, @@ -1125,18 +1127,7 @@ impl HTMLImageElement { selected_pixel_density, ); }, - - Err(ImageState::Pending(id)) => { - add_cache_listener_for_element( - image_cache.clone(), - id, - self, - selected_source.0, - selected_pixel_density, - ); - }, - - Err(ImageState::LoadError) => { + ImageCacheResult::LoadError => { self.process_image_response_for_environment_change( ImageResponse::None, selected_source, @@ -1144,17 +1135,8 @@ impl HTMLImageElement { selected_pixel_density, ); }, - - Err(ImageState::NotRequested(id)) => { - add_cache_listener_for_element( - image_cache, - id, - self, - selected_source.0, - selected_pixel_density, - ); - self.fetch_request(&img_url, id); - }, + ImageCacheResult::ReadyForRequest(id) => self.fetch_request(&img_url, id), + ImageCacheResult::Pending(_) => (), } } |