LibWeb: Skip cosmetic blocking in SVG images

Do not build content blocker cosmetic style sheets for decoded SVG
image documents. These documents are resource documents created for
image painting rather than ordinary navigable documents, and other
engines keep extension cosmetic CSS out of them.

Add text coverage that verifies a generic cosmetic rule still applies
to the embedding HTML document while a matching element inside an SVG
loaded through <img> keeps rendering.
This commit is contained in:
Andreas Kling 2026-05-24 01:44:56 +02:00 committed by Andreas Kling
parent 6ea2a4eff5
commit 762aea0568
3 changed files with 59 additions and 0 deletions

View file

@ -775,6 +775,12 @@ void Document::visit_edges(Cell::Visitor& visitor)
String const& Document::content_blocker_style_sheet()
{
if (is_decoded_svg()) {
if (!m_content_blocker_style_sheet.has_value())
m_content_blocker_style_sheet = String {};
return m_content_blocker_style_sheet.value();
}
if (!m_content_blocker_style_sheet.has_value()) {
m_content_blocker_style_sheet_checked_classes.clear();
m_content_blocker_style_sheet_checked_ids.clear();
@ -816,6 +822,9 @@ void Document::invalidate_content_blocker_style_sheet()
bool Document::content_blocker_style_sheet_may_need_refresh_for_class_or_id(FlyString const* id, ReadonlySpan<FlyString> class_names)
{
if (is_decoded_svg())
return false;
if (!m_content_blocker_style_sheet.has_value())
return false;

View file

@ -0,0 +1,2 @@
html display: none
svg pixel: 255,0,0,255

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<script src="./include.js"></script>
<body>
<div id="html-target" class="ad"></div>
</body>
<script>
asyncTest((done) => {
internals.setContentBlockers("##.ad");
println(`html display: ${getComputedStyle(document.querySelector("#html-target")).display}`);
const image = document.createElement("img");
image.width = 10;
image.height = 10;
function finish() {
internals.setContentBlockers("");
done();
}
image.onload = () => {
try {
const canvas = document.createElement("canvas");
canvas.width = 10;
canvas.height = 10;
const context = canvas.getContext("2d");
context.drawImage(image, 0, 0);
const pixel = context.getImageData(5, 5, 1, 1).data;
println(`svg pixel: ${Array.from(pixel).join(",")}`);
} catch (error) {
println(`Caught error while inspecting SVG image: ${error}`);
}
finish();
};
image.onerror = () => {
println("SVG image failed to load");
finish();
};
document.body.appendChild(image);
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><rect class="ad" width="10" height="10" fill="red"/></svg>`;
image.src = `data:image/svg+xml,${encodeURIComponent(svg)}`;
});
</script>