script: Cache the current favicon on the document (#39575)

This allows us to notify the embedder when navigating back and forth.

Testing: Manual testing following the steps in issue #39529 
Fixes: https://github.com/servo/servo/issues/39529

Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
webbeef 2025-09-29 19:35:49 -07:00 committed by GitHub
parent 61ce9af122
commit 55facf7b15
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 3 deletions

View file

@ -26,7 +26,9 @@ use cssparser::match_ignore_ascii_case;
use data_url::mime::Mime;
use devtools_traits::ScriptToDevtoolsControlMsg;
use dom_struct::dom_struct;
use embedder_traits::{AllowOrDeny, AnimationState, EmbedderMsg, FocusSequenceNumber, LoadStatus};
use embedder_traits::{
AllowOrDeny, AnimationState, EmbedderMsg, FocusSequenceNumber, Image, LoadStatus,
};
use encoding_rs::{Encoding, UTF_8};
use euclid::Point2D;
use euclid::default::{Rect, Size2D};
@ -576,6 +578,10 @@ pub(crate) struct Document {
#[ignore_malloc_size_of = "type from external crate"]
/// <https://html.spec.whatwg.org/multipage/#active-sandboxing-flag-set>,
active_sandboxing_flag_set: Cell<SandboxingFlagSet>,
/// The cached favicon for that document.
#[no_trace]
#[ignore_malloc_size_of = "TODO: unimplemented on Image"]
favicon: RefCell<Option<Image>>,
}
#[allow(non_snake_case)]
@ -762,6 +768,7 @@ impl Document {
}
self.title_changed();
self.notify_embedder_favicon();
self.dirty_all_nodes();
self.window().resume(can_gc);
media.resume(&client_context_id);
@ -3495,6 +3502,7 @@ impl Document {
current_canvas_epoch: RefCell::new(Epoch(0)),
custom_element_reaction_stack,
active_sandboxing_flag_set: Cell::new(SandboxingFlagSet::empty()),
favicon: RefCell::new(None),
}
}
@ -4478,6 +4486,17 @@ impl Document {
.scrolling_box_query(None, flags)
.expect("We should always have a ScrollingBox for the Viewport")
}
pub(crate) fn notify_embedder_favicon(&self) {
if let Some(ref image) = *self.favicon.borrow() {
self.send_to_embedder(EmbedderMsg::NewFavicon(self.webview_id(), image.clone()));
}
}
pub(crate) fn set_favicon(&self, favicon: Image) {
*self.favicon.borrow_mut() = Some(favicon);
self.notify_embedder_favicon();
}
}
#[allow(non_snake_case)]

View file

@ -7,7 +7,6 @@ use std::cell::Cell;
use std::default::Default;
use dom_struct::dom_struct;
use embedder_traits::EmbedderMsg;
use html5ever::{LocalName, Prefix, local_name, ns};
use ipc_channel::ipc::IpcSender;
use js::rust::HandleObject;
@ -726,6 +725,7 @@ impl HTMLLinkElement {
fn process_favicon_response(&self, image: Image) {
// TODO: Include the size attribute here
let window = self.owner_window();
let document = self.owner_document();
let send_rasterized_favicon_to_embedder = |raster_image: &pixels::RasterImage| {
// Let's not worry about animated favicons...
@ -746,7 +746,7 @@ impl HTMLLinkElement {
raster_image.frames[0].byte_range.clone(),
format,
);
window.send_to_embedder(EmbedderMsg::NewFavicon(window.webview_id(), embedder_image));
document.set_favicon(embedder_image);
};
match image {