mirror of
https://github.com/servo/servo.git
synced 2025-06-17 04:44:28 +00:00
Auto merge of #23661 - julientregoat:i-21289, r=jdm
Refactor ImageCache::find_image_or_metadata -> ImageCache::{get_image, track_image} <!-- Please describe your changes on the following line: --> Updated the `ImageCache` trait to replace `find_image_or_metadata` with two new functions `track_image` and `get_image`, as well as a new enum (`ImageCacheResult`). As a result, I was able to refactor the functions that previously called `find_image_or_metadata` pretty cleanly. For a list of these functions, please see the commit information. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #21289 (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require tests because tests already exist for these components. I ran `cargo test` in `net`, `net_traits`, `layout`, and `script` successfully. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23661) <!-- Reviewable:end -->
This commit is contained in:
commit
c9480c8e07
9 changed files with 282 additions and 242 deletions
|
@ -432,8 +432,7 @@ impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
|||
|
||||
pub mod utils {
|
||||
use crate::dom::window::Window;
|
||||
use net_traits::image_cache::CanRequestImages;
|
||||
use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
|
||||
use net_traits::image_cache::ImageResponse;
|
||||
use net_traits::request::CorsSettings;
|
||||
use servo_url::ServoUrl;
|
||||
|
||||
|
@ -443,18 +442,15 @@ pub mod utils {
|
|||
cors_setting: Option<CorsSettings>,
|
||||
) -> ImageResponse {
|
||||
let image_cache = window.image_cache();
|
||||
let response = image_cache.find_image_or_metadata(
|
||||
url.into(),
|
||||
let result = image_cache.get_image(
|
||||
url.clone(),
|
||||
window.origin().immutable().clone(),
|
||||
cors_setting,
|
||||
UsePlaceholder::No,
|
||||
CanRequestImages::No,
|
||||
);
|
||||
match response {
|
||||
Ok(ImageOrMetadataAvailable::ImageAvailable(image, url)) => {
|
||||
ImageResponse::Loaded(image, url)
|
||||
},
|
||||
_ => ImageResponse::None,
|
||||
|
||||
match result {
|
||||
Some(image) => ImageResponse::Loaded(image, url),
|
||||
None => ImageResponse::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(_) => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,16 +19,17 @@ use crate::dom::node::{document_from_node, window_from_node, Node};
|
|||
use crate::dom::performanceresourcetiming::InitiatorType;
|
||||
use crate::dom::virtualmethods::VirtualMethods;
|
||||
use crate::fetch::FetchCanceller;
|
||||
use crate::image_listener::{add_cache_listener_for_element, ImageCacheListener};
|
||||
use crate::image_listener::{generate_cache_listener_for_element, ImageCacheListener};
|
||||
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
||||
use dom_struct::dom_struct;
|
||||
use euclid::default::Size2D;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use net_traits::image_cache::UsePlaceholder;
|
||||
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageOrMetadataAvailable};
|
||||
use net_traits::image_cache::{ImageResponse, ImageState, PendingImageId};
|
||||
use net_traits::image_cache::{
|
||||
CanRequestImages, ImageCache, ImageCacheResult, ImageOrMetadataAvailable, ImageResponse,
|
||||
PendingImageId, UsePlaceholder,
|
||||
};
|
||||
use net_traits::request::{CredentialsMode, Destination, RequestBuilder};
|
||||
use net_traits::{
|
||||
CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, FetchResponseMsg,
|
||||
|
@ -155,27 +156,23 @@ impl HTMLVideoElement {
|
|||
// network activity as possible.
|
||||
let window = window_from_node(self);
|
||||
let image_cache = window.image_cache();
|
||||
let response = image_cache.find_image_or_metadata(
|
||||
poster_url.clone().into(),
|
||||
let sender = generate_cache_listener_for_element(self);
|
||||
let cache_result = image_cache.track_image(
|
||||
poster_url.clone(),
|
||||
window.origin().immutable().clone(),
|
||||
None,
|
||||
sender,
|
||||
UsePlaceholder::No,
|
||||
CanRequestImages::Yes,
|
||||
);
|
||||
match response {
|
||||
Ok(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);
|
||||
match cache_result {
|
||||
ImageCacheResult::Available(ImageOrMetadataAvailable::ImageAvailable(img, url)) => {
|
||||
self.process_image_response(ImageResponse::Loaded(img, url));
|
||||
},
|
||||
|
||||
Err(ImageState::NotRequested(id)) => {
|
||||
add_cache_listener_for_element(image_cache, id, self);
|
||||
self.do_fetch_poster_frame(poster_url, id, cancel_receiver);
|
||||
ImageCacheResult::ReadyForRequest(id) => {
|
||||
self.do_fetch_poster_frame(poster_url, id, cancel_receiver)
|
||||
},
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue