aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2024-05-23 08:49:31 +0200
committerGitHub <noreply@github.com>2024-05-23 06:49:31 +0000
commit14286d913d5a88647fad2255f06bec0763914e55 (patch)
treebb54e1ce8b3b2c4f328d68cfc99bd4a300a64df8
parenta772ecf786bda74cd5202b9ca6fb2d487cc61b94 (diff)
downloadservo-14286d913d5a88647fad2255f06bec0763914e55.tar.gz
servo-14286d913d5a88647fad2255f06bec0763914e55.zip
fonts: Remove web fonts when their stylsheet is removed (#32346)
This is the first part of ensuring that unused fonts do not leak. This change makes it so that when a stylesheet is removed, the corresponding web fonts are removed from the `FontContext`. Note: WebRender assets are still leaked, which was the situation before for all fonts. A followup change will fix this issue. Fixes #15139. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
-rw-r--r--components/gfx/font_cache_thread.rs1
-rw-r--r--components/gfx/font_context.rs95
-rw-r--r--components/gfx/font_store.rs84
-rw-r--r--components/gfx/font_template.rs12
-rw-r--r--components/gfx/tests/font_context.rs2
-rw-r--r--components/layout_thread/lib.rs27
-rw-r--r--components/layout_thread_2020/lib.rs28
-rw-r--r--tests/wpt/meta/MANIFEST.json21
-rw-r--r--tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed-ref.html16
-rw-r--r--tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed.html29
10 files changed, 258 insertions, 57 deletions
diff --git a/components/gfx/font_cache_thread.rs b/components/gfx/font_cache_thread.rs
index 5be2ed7d492..bde22d4b515 100644
--- a/components/gfx/font_cache_thread.rs
+++ b/components/gfx/font_cache_thread.rs
@@ -484,6 +484,7 @@ impl FontSource for FontCacheThread {
identifier: serialized_font_template.identifier,
descriptor: serialized_font_template.descriptor.clone(),
data: font_data.map(Arc::new),
+ stylesheet: None,
}))
})
.collect()
diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs
index ef83d3e9de2..e27c4d0bef4 100644
--- a/components/gfx/font_context.rs
+++ b/components/gfx/font_context.rs
@@ -5,7 +5,6 @@
use std::collections::HashMap;
use std::default::Default;
use std::hash::{BuildHasherDefault, Hash, Hasher};
-use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use app_units::Au;
@@ -24,7 +23,7 @@ use style::font_face::{FontFaceSourceFormat, FontFaceSourceFormatKeyword, Source
use style::media_queries::Device;
use style::properties::style_structs::Font as FontStyleStruct;
use style::shared_lock::SharedRwLockReadGuard;
-use style::stylesheets::{Stylesheet, StylesheetInDocument};
+use style::stylesheets::{DocumentStyleSheet, StylesheetInDocument};
use style::Atom;
use url::Url;
@@ -51,7 +50,6 @@ pub struct FontContext<S: FontSource> {
cache: CachingFontSource<S>,
web_fonts: CrossThreadFontStore,
webrender_font_store: CrossThreadWebRenderFontStore,
- web_fonts_still_loading: AtomicUsize,
}
impl<S: FontSource> MallocSizeOf for FontContext<S> {
@@ -69,12 +67,11 @@ impl<S: FontSource> FontContext<S> {
cache: CachingFontSource::new(font_source),
web_fonts: Arc::new(RwLock::default()),
webrender_font_store: Arc::new(RwLock::default()),
- web_fonts_still_loading: Default::default(),
}
}
pub fn web_fonts_still_loading(&self) -> usize {
- self.web_fonts_still_loading.load(Ordering::SeqCst)
+ self.web_fonts.read().number_of_fonts_still_loading()
}
/// Handle the situation where a web font finishes loading, specifying if the load suceeded or failed.
@@ -83,7 +80,6 @@ impl<S: FontSource> FontContext<S> {
finished_callback: &WebFontLoadFinishedCallback,
succeeded: bool,
) {
- self.web_fonts_still_loading.fetch_sub(1, Ordering::SeqCst);
if succeeded {
self.cache.invalidate_after_web_font_load();
}
@@ -159,6 +155,8 @@ impl<S: FontSource> FontContext<S> {
font_template, font_descriptor
);
+ // TODO: Inserting `None` into the cache here is a bit bogus. Instead we should somehow
+ // mark this template as invalid so it isn't tried again.
let font = self
.create_font(
font_template,
@@ -229,29 +227,31 @@ impl<S: FontSource> FontContext<S> {
#[derive(Clone)]
pub struct WebFontDownloadState {
- css_font_face_descriptors: Arc<CSSFontFaceDescriptors>,
+ pub css_font_face_descriptors: Arc<CSSFontFaceDescriptors>,
remaining_sources: Vec<Source>,
finished_callback: WebFontLoadFinishedCallback,
core_resource_thread: CoreResourceThread,
local_fonts: Arc<HashMap<Atom, Option<FontTemplateRef>>>,
+ pub stylesheet: DocumentStyleSheet,
}
pub trait FontContextWebFontMethods {
fn add_all_web_fonts_from_stylesheet(
&self,
- stylesheet: &Stylesheet,
+ stylesheet: &DocumentStyleSheet,
guard: &SharedRwLockReadGuard,
device: &Device,
finished_callback: WebFontLoadFinishedCallback,
synchronous: bool,
) -> usize;
fn process_next_web_font_source(&self, web_font_download_state: WebFontDownloadState);
+ fn remove_all_web_fonts_from_stylesheet(&self, stylesheet: &DocumentStyleSheet);
}
impl<S: FontSource + Send + 'static> FontContextWebFontMethods for Arc<FontContext<S>> {
fn add_all_web_fonts_from_stylesheet(
&self,
- stylesheet: &Stylesheet,
+ stylesheet: &DocumentStyleSheet,
guard: &SharedRwLockReadGuard,
device: &Device,
finished_callback: WebFontLoadFinishedCallback,
@@ -312,17 +312,20 @@ impl<S: FontSource + Send + 'static> FontContextWebFontMethods for Arc<FontConte
}
}
+ number_loading += 1;
+ self.web_fonts
+ .write()
+ .handle_web_font_load_started_for_stylesheet(stylesheet);
+
self.process_next_web_font_source(WebFontDownloadState {
css_font_face_descriptors: Arc::new(rule.into()),
remaining_sources: sources,
finished_callback: finished_callback.clone(),
core_resource_thread: self.resource_threads.lock().clone(),
local_fonts: Arc::new(local_fonts),
+ stylesheet: stylesheet.clone(),
});
- number_loading += 1;
- self.web_fonts_still_loading.fetch_add(1, Ordering::SeqCst);
-
// If the load is synchronous wait for it to be signalled.
if let Some(ref synchronous_receiver) = synchronous_receiver {
synchronous_receiver.recv().unwrap();
@@ -334,6 +337,9 @@ impl<S: FontSource + Send + 'static> FontContextWebFontMethods for Arc<FontConte
fn process_next_web_font_source(&self, mut state: WebFontDownloadState) {
let Some(source) = state.remaining_sources.pop() else {
+ self.web_fonts
+ .write()
+ .handle_web_font_failed_to_load(&state);
self.handle_web_font_load_finished(&state.finished_callback, false);
return;
};
@@ -354,23 +360,48 @@ impl<S: FontSource + Send + 'static> FontContextWebFontMethods for Arc<FontConte
FontTemplate::new_for_local_web_font(
local_template,
&state.css_font_face_descriptors,
+ state.stylesheet.clone(),
)
.ok()
})
{
- this.web_fonts
+ let not_cancelled = self
+ .web_fonts
.write()
- .families
- .entry(web_font_family_name.clone())
- .or_default()
- .add_template(new_template);
- self.handle_web_font_load_finished(&state.finished_callback, true);
+ .handle_web_font_loaded(&state, new_template);
+ self.handle_web_font_load_finished(&state.finished_callback, not_cancelled);
} else {
this.process_next_web_font_source(state);
}
},
}
}
+
+ fn remove_all_web_fonts_from_stylesheet(&self, stylesheet: &DocumentStyleSheet) {
+ let mut web_fonts = self.web_fonts.write();
+ let mut fonts = self.cache.fonts.write();
+ let mut font_groups = self.cache.resolved_font_groups.write();
+
+ // Cancel any currently in-progress web font loads.
+ web_fonts.handle_stylesheet_removed(stylesheet);
+
+ let mut removed_any = false;
+ for family in web_fonts.families.values_mut() {
+ removed_any |= family.remove_templates_for_stylesheet(stylesheet);
+ }
+ if !removed_any {
+ return;
+ };
+
+ fonts.retain(|_, font| match font {
+ Some(font) => font.template.borrow().stylesheet.as_ref() != Some(stylesheet),
+ _ => true,
+ });
+
+ // Removing this stylesheet modified the available fonts, so invalidate the cache
+ // of resolved font groups.
+ font_groups.clear();
+ }
}
struct RemoteWebFontDownloader<FCT: FontSource> {
@@ -437,6 +468,18 @@ impl<FCT: FontSource + Send + 'static> RemoteWebFontDownloader<FCT> {
/// After a download finishes, try to process the downloaded data, returning true if
/// the font is added successfully to the [`FontContext`] or false if it isn't.
fn process_downloaded_font_and_signal_completion(&self, state: &WebFontDownloadState) -> bool {
+ if self
+ .font_context
+ .web_fonts
+ .read()
+ .font_load_cancelled_for_stylesheet(&state.stylesheet)
+ {
+ self.font_context
+ .handle_web_font_load_finished(&state.finished_callback, false);
+ // Returning true here prevents trying to load the next font on the source list.
+ return true;
+ }
+
let font_data = std::mem::take(&mut *self.response_data.lock());
trace!(
"@font-face {} data={:?}",
@@ -459,21 +502,21 @@ impl<FCT: FontSource + Send + 'static> RemoteWebFontDownloader<FCT> {
self.url.clone().into(),
Arc::new(font_data),
&state.css_font_face_descriptors,
+ Some(state.stylesheet.clone()),
) else {
return false;
};
- let family_name = state.css_font_face_descriptors.family_name.clone();
- self.font_context
+ let not_cancelled = self
+ .font_context
.web_fonts
.write()
- .families
- .entry(family_name.clone())
- .or_default()
- .add_template(new_template);
-
+ .handle_web_font_loaded(state, new_template);
self.font_context
- .handle_web_font_load_finished(&state.finished_callback, true);
+ .handle_web_font_load_finished(&state.finished_callback, not_cancelled);
+
+ // If the load was canceled above, then we still want to return true from this function in
+ // order to halt any attempt to load sources that come later on the source list.
true
}
diff --git a/components/gfx/font_store.rs b/components/gfx/font_store.rs
index 888a0ae0a1e..8abb74fc188 100644
--- a/components/gfx/font_store.rs
+++ b/components/gfx/font_store.rs
@@ -8,15 +8,18 @@ use std::sync::Arc;
use app_units::Au;
use atomic_refcell::AtomicRefCell;
use parking_lot::RwLock;
+use style::stylesheets::DocumentStyleSheet;
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey};
use crate::font::FontDescriptor;
use crate::font_cache_thread::{FontIdentifier, FontSource, LowercaseString};
+use crate::font_context::WebFontDownloadState;
use crate::font_template::{FontTemplate, FontTemplateRef, FontTemplateRefMethods};
#[derive(Default)]
pub struct FontStore {
pub(crate) families: HashMap<LowercaseString, FontTemplates>,
+ web_fonts_loading: Vec<(DocumentStyleSheet, usize)>,
}
pub(crate) type CrossThreadFontStore = Arc<RwLock<FontStore>>;
@@ -24,6 +27,77 @@ impl FontStore {
pub(crate) fn clear(&mut self) {
self.families.clear();
}
+
+ pub(crate) fn font_load_cancelled_for_stylesheet(
+ &self,
+ stylesheet: &DocumentStyleSheet,
+ ) -> bool {
+ !self
+ .web_fonts_loading
+ .iter()
+ .any(|(loading_stylesheet, _)| loading_stylesheet == stylesheet)
+ }
+
+ pub(crate) fn handle_stylesheet_removed(&mut self, stylesheet: &DocumentStyleSheet) {
+ self.web_fonts_loading
+ .retain(|(loading_stylesheet, _)| loading_stylesheet != stylesheet);
+ }
+
+ pub(crate) fn handle_web_font_load_started_for_stylesheet(
+ &mut self,
+ stylesheet: &DocumentStyleSheet,
+ ) {
+ if let Some((_, count)) = self
+ .web_fonts_loading
+ .iter_mut()
+ .find(|(loading_stylesheet, _)| loading_stylesheet == stylesheet)
+ {
+ *count += 1;
+ } else {
+ self.web_fonts_loading.push((stylesheet.clone(), 1))
+ }
+ }
+
+ fn remove_one_web_font_loading_for_stylesheet(&mut self, stylesheet: &DocumentStyleSheet) {
+ if let Some((_, count)) = self
+ .web_fonts_loading
+ .iter_mut()
+ .find(|(loading_stylesheet, _)| loading_stylesheet == stylesheet)
+ {
+ *count -= 1;
+ }
+ self.web_fonts_loading.retain(|(_, count)| *count != 0);
+ }
+
+ pub(crate) fn handle_web_font_failed_to_load(&mut self, state: &WebFontDownloadState) {
+ self.remove_one_web_font_loading_for_stylesheet(&state.stylesheet);
+ }
+
+ /// Handle a web font load finishing, adding the new font to the [`FontStore`]. If the web font
+ /// load was canceled (for instance, if the stylesheet was removed), then do nothing and return
+ /// false.
+ pub(crate) fn handle_web_font_loaded(
+ &mut self,
+ state: &WebFontDownloadState,
+ new_template: FontTemplate,
+ ) -> bool {
+ // Abort processing this web font if the originating stylesheet was removed.
+ if self.font_load_cancelled_for_stylesheet(&state.stylesheet) {
+ return false;
+ }
+
+ let family_name = state.css_font_face_descriptors.family_name.clone();
+ self.families
+ .entry(family_name)
+ .or_default()
+ .add_template(new_template);
+ self.remove_one_web_font_loading_for_stylesheet(&state.stylesheet);
+ true
+ }
+
+ pub(crate) fn number_of_fonts_still_loading(&self) -> usize {
+ self.web_fonts_loading.iter().map(|(_, count)| count).sum()
+ }
}
#[derive(Default)]
@@ -127,4 +201,14 @@ impl FontTemplates {
self.templates
.push(Arc::new(AtomicRefCell::new(new_template)));
}
+
+ pub(crate) fn remove_templates_for_stylesheet(
+ &mut self,
+ stylesheet: &DocumentStyleSheet,
+ ) -> bool {
+ let length_before = self.templates.len();
+ self.templates
+ .retain(|template| template.borrow().stylesheet.as_ref() != Some(stylesheet));
+ length_before != self.templates.len()
+ }
}
diff --git a/components/gfx/font_template.rs b/components/gfx/font_template.rs
index 3bc9f21acf0..bfa8bb49fb4 100644
--- a/components/gfx/font_template.rs
+++ b/components/gfx/font_template.rs
@@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize};
use servo_url::ServoUrl;
use style::computed_values::font_stretch::T as FontStretch;
use style::computed_values::font_style::T as FontStyle;
+use style::stylesheets::DocumentStyleSheet;
use style::values::computed::font::FontWeight;
use crate::font::{FontDescriptor, PlatformFontMethods};
@@ -132,9 +133,11 @@ pub struct FontTemplate {
pub descriptor: FontTemplateDescriptor,
/// The data to use for this [`FontTemplate`]. For web fonts, this is always filled, but
/// for local fonts, this is loaded only lazily in layout.
- ///
- /// TODO: There is no mechanism for web fonts to unset their data!
pub data: Option<Arc<Vec<u8>>>,
+ /// If this font is a web font, this is a reference to the stylesheet that
+ /// created it. This will be used to remove this font from caches, when the
+ /// stylesheet is removed.
+ pub stylesheet: Option<DocumentStyleSheet>,
}
impl malloc_size_of::MallocSizeOf for FontTemplate {
@@ -164,6 +167,7 @@ impl FontTemplate {
identifier: FontIdentifier::Local(identifier),
descriptor,
data: None,
+ stylesheet: None,
}
}
@@ -172,6 +176,7 @@ impl FontTemplate {
url: ServoUrl,
data: Arc<Vec<u8>>,
css_font_template_descriptors: &CSSFontFaceDescriptors,
+ stylesheet: Option<DocumentStyleSheet>,
) -> Result<FontTemplate, &'static str> {
let identifier = FontIdentifier::Web(url.clone());
let Ok(handle) = PlatformFont::new_from_data(identifier, data.clone(), 0, None) else {
@@ -185,6 +190,7 @@ impl FontTemplate {
identifier: FontIdentifier::Web(url),
descriptor,
data: Some(data),
+ stylesheet,
})
}
@@ -194,11 +200,13 @@ impl FontTemplate {
pub fn new_for_local_web_font(
local_template: FontTemplateRef,
css_font_template_descriptors: &CSSFontFaceDescriptors,
+ stylesheet: DocumentStyleSheet,
) -> Result<FontTemplate, &'static str> {
let mut alias_template = local_template.borrow().clone();
alias_template
.descriptor
.override_values_with_css_font_template_descriptors(css_font_template_descriptors);
+ alias_template.stylesheet = Some(stylesheet);
Ok(alias_template)
}
diff --git a/components/gfx/tests/font_context.rs b/components/gfx/tests/font_context.rs
index 06870f6f88c..dc61775db18 100644
--- a/components/gfx/tests/font_context.rs
+++ b/components/gfx/tests/font_context.rs
@@ -24,6 +24,7 @@ use servo_atoms::Atom;
use servo_url::ServoUrl;
use style::properties::longhands::font_variant_caps::computed_value::T as FontVariantCaps;
use style::properties::style_structs::Font as FontStyleStruct;
+use style::stylesheets::Stylesheet;
use style::values::computed::font::{
FamilyName, FontFamily, FontFamilyList, FontFamilyNameSyntax, FontSize, FontStretch, FontStyle,
FontWeight, SingleFontFamily,
@@ -85,6 +86,7 @@ impl MockFontCacheThread {
Self::url_for_font_name(name),
std::sync::Arc::new(data),
&CSSFontFaceDescriptors::new(name),
+ None,
)
.unwrap(),
);
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index f4efdc17c41..0192f58a4f4 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -273,7 +273,10 @@ impl Layout for LayoutThread {
fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc<Stylesheet>) {
let guard = stylesheet.shared_lock.read();
- self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard);
+ self.load_all_web_fonts_from_stylesheet_with_guard(
+ &DocumentStyleSheet(stylesheet.clone()),
+ &guard,
+ );
}
fn add_stylesheet(
@@ -282,24 +285,25 @@ impl Layout for LayoutThread {
before_stylesheet: Option<ServoArc<Stylesheet>>,
) {
let guard = stylesheet.shared_lock.read();
+ let stylesheet = DocumentStyleSheet(stylesheet.clone());
self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard);
match before_stylesheet {
Some(insertion_point) => self.stylist.insert_stylesheet_before(
- DocumentStyleSheet(stylesheet.clone()),
+ stylesheet,
DocumentStyleSheet(insertion_point),
&guard,
),
- None => self
- .stylist
- .append_stylesheet(DocumentStyleSheet(stylesheet.clone()), &guard),
+ None => self.stylist.append_stylesheet(stylesheet, &guard),
}
}
fn remove_stylesheet(&mut self, stylesheet: ServoArc<Stylesheet>) {
let guard = stylesheet.shared_lock.read();
- self.stylist
- .remove_stylesheet(DocumentStyleSheet(stylesheet.clone()), &guard);
+ let stylesheet = DocumentStyleSheet(stylesheet.clone());
+ self.stylist.remove_stylesheet(stylesheet.clone(), &guard);
+ self.font_context
+ .remove_all_web_fonts_from_stylesheet(&stylesheet);
}
fn query_content_box(&self, node: OpaqueNode) -> Option<UntypedRect<Au>> {
@@ -668,7 +672,7 @@ impl LayoutThread {
fn load_all_web_fonts_from_stylesheet_with_guard(
&self,
- stylesheet: &Stylesheet,
+ stylesheet: &DocumentStyleSheet,
guard: &SharedRwLockReadGuard,
) {
if !stylesheet.is_effective_for_device(self.stylist.device(), guard) {
@@ -982,10 +986,7 @@ impl LayoutThread {
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
self.stylist
.append_stylesheet(stylesheet.clone(), &ua_or_user_guard);
- self.load_all_web_fonts_from_stylesheet_with_guard(
- &stylesheet.0,
- &ua_or_user_guard,
- );
+ self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &ua_or_user_guard);
}
if self.stylist.quirks_mode() != QuirksMode::NoQuirks {
@@ -994,7 +995,7 @@ impl LayoutThread {
&ua_or_user_guard,
);
self.load_all_web_fonts_from_stylesheet_with_guard(
- &ua_stylesheets.quirks_mode_stylesheet.0,
+ &ua_stylesheets.quirks_mode_stylesheet,
&ua_or_user_guard,
);
}
diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs
index b9cc25fbc7d..63af1c98349 100644
--- a/components/layout_thread_2020/lib.rs
+++ b/components/layout_thread_2020/lib.rs
@@ -249,7 +249,10 @@ impl Layout for LayoutThread {
fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc<Stylesheet>) {
let guard = stylesheet.shared_lock.read();
- self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard);
+ self.load_all_web_fonts_from_stylesheet_with_guard(
+ &DocumentStyleSheet(stylesheet.clone()),
+ &guard,
+ );
}
fn add_stylesheet(
@@ -258,25 +261,25 @@ impl Layout for LayoutThread {
before_stylesheet: Option<ServoArc<Stylesheet>>,
) {
let guard = stylesheet.shared_lock.read();
+ let stylesheet = DocumentStyleSheet(stylesheet.clone());
self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard);
match before_stylesheet {
Some(insertion_point) => self.stylist.insert_stylesheet_before(
- DocumentStyleSheet(stylesheet.clone()),
+ stylesheet,
DocumentStyleSheet(insertion_point),
&guard,
),
- None => self
- .stylist
- .append_stylesheet(DocumentStyleSheet(stylesheet.clone()), &guard),
+ None => self.stylist.append_stylesheet(stylesheet, &guard),
}
}
fn remove_stylesheet(&mut self, stylesheet: ServoArc<Stylesheet>) {
- // TODO(mrobinson): This should also unload web fonts from the FontCacheThread.
let guard = stylesheet.shared_lock.read();
- self.stylist
- .remove_stylesheet(DocumentStyleSheet(stylesheet.clone()), &guard);
+ let stylesheet = DocumentStyleSheet(stylesheet.clone());
+ self.stylist.remove_stylesheet(stylesheet.clone(), &guard);
+ self.font_context
+ .remove_all_web_fonts_from_stylesheet(&stylesheet);
}
fn query_content_box(&self, node: OpaqueNode) -> Option<UntypedRect<Au>> {
@@ -584,7 +587,7 @@ impl LayoutThread {
fn load_all_web_fonts_from_stylesheet_with_guard(
&self,
- stylesheet: &Stylesheet,
+ stylesheet: &DocumentStyleSheet,
guard: &SharedRwLockReadGuard,
) {
if !stylesheet.is_effective_for_device(self.stylist.device(), guard) {
@@ -651,10 +654,7 @@ impl LayoutThread {
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
self.stylist
.append_stylesheet(stylesheet.clone(), &ua_or_user_guard);
- self.load_all_web_fonts_from_stylesheet_with_guard(
- &stylesheet.0,
- &ua_or_user_guard,
- );
+ self.load_all_web_fonts_from_stylesheet_with_guard(stylesheet, &ua_or_user_guard);
}
if self.stylist.quirks_mode() != QuirksMode::NoQuirks {
@@ -663,7 +663,7 @@ impl LayoutThread {
&ua_or_user_guard,
);
self.load_all_web_fonts_from_stylesheet_with_guard(
- &ua_stylesheets.quirks_mode_stylesheet.0,
+ &ua_stylesheets.quirks_mode_stylesheet,
&ua_or_user_guard,
);
}
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index 3fc382143d9..66ce446fe98 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -179113,7 +179113,20 @@
{}
]
]
- }
+ },
+ "web-font-no-longer-accessible-when-stylesheet-removed.html": [
+ "aac3e77a819019d349123fac2265531f3746f826",
+ [
+ null,
+ [
+ [
+ "/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ]
},
"css-grid": {
"abspos": {
@@ -403830,7 +403843,11 @@
"4e88cace350e32711fc06220c2d14dcbd3ab3339",
[]
]
- }
+ },
+ "web-font-no-longer-accessible-when-stylesheet-removed-ref.html": [
+ "363b88d7180a9471c647cd69b9c69678e2f88da6",
+ []
+ ]
},
"css-gcpm": {
"META.yml": [
diff --git a/tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed-ref.html b/tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed-ref.html
new file mode 100644
index 00000000000..363b88d7180
--- /dev/null
+++ b/tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed-ref.html
@@ -0,0 +1,16 @@
+ <!DOCTYPE html>
+
+<html>
+ <head>
+ <title>CSS fonts: Web fonts from removed stylsheets should not be accessible</title>
+ <link rel="author" title="Martin Robinson" href="mrobinson@igalia.com">
+ <link rel="help" href="https://drafts.csswg.org/css-fonts/#font-face-rule">
+ </head>
+
+ <body>
+ <p>Test passes if the text below is not rendered with Ahem.</p>
+ <p>TEXT</p>
+ </body>
+
+</html>
+
diff --git a/tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed.html b/tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed.html
new file mode 100644
index 00000000000..aac3e77a819
--- /dev/null
+++ b/tests/wpt/tests/css/css-fonts/web-font-no-longer-accessible-when-stylesheet-removed.html
@@ -0,0 +1,29 @@
+ <!DOCTYPE html>
+
+<html>
+ <head>
+ <title>CSS fonts: Web fonts from removed stylsheets should not be accessible</title>
+ <link rel="author" title="Martin Robinson" href="mrobinson@igalia.com">
+ <link rel="match" href="web-font-no-longer-accessible-when-stylesheet-removed-ref.html">
+ <link rel="help" href="https://drafts.csswg.org/css-fonts/#font-face-rule">
+ </head>
+
+ <body>
+ <style id="web-font-stylesheet">
+ @font-face {
+ font-family: CustomFontFamily;
+ src: url(/fonts/Ahem.ttf);
+ }
+ </style>
+
+ <p>Test passes if the text below is not rendered with Ahem.</p>
+ <p style="font-family: CustomFontFamily;">TEXT</p>
+
+ <script>
+ let styleTag = document.getElementById("web-font-stylesheet");
+ styleTag.parentNode.removeChild(styleTag);
+ </script>
+ </body>
+
+</html>
+