LibWeb: Parse CSS/image URLs using DOMURL::parse

DOMURL::parse handles blob URLs.
This commit is contained in:
Timothy Flynn 2025-08-08 09:55:38 -04:00 committed by Tim Ledbetter
commit 4a8c70b3a5
Notes: github-actions[bot] 2025-08-08 16:48:55 +00:00
6 changed files with 60 additions and 7 deletions

View file

@ -4,10 +4,10 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibURL/Parser.h>
#include <LibWeb/CSS/CSSStyleSheet.h> #include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/Fetch.h> #include <LibWeb/CSS/Fetch.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/DOMURL/DOMURL.h>
#include <LibWeb/Fetch/Fetching/Fetching.h> #include <LibWeb/Fetch/Fetching/Fetching.h>
#include <LibWeb/HTML/SharedResourceRequest.h> #include <LibWeb/HTML/SharedResourceRequest.h>
@ -38,7 +38,8 @@ static WebIDL::ExceptionOr<GC::Ref<Fetch::Infrastructure::Request>> fetch_a_styl
auto url_string = url_value.visit( auto url_string = url_value.visit(
[](::URL::URL const& url) { return url.to_string(); }, [](::URL::URL const& url) { return url.to_string(); },
[](CSS::URL const& url) { return url.url(); }); [](CSS::URL const& url) { return url.url(); });
auto parsed_url = ::URL::Parser::basic_parse(url_string, base);
auto parsed_url = DOMURL::parse(url_string, base);
if (!parsed_url.has_value()) if (!parsed_url.has_value())
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::URIError, "Failed to parse URL"sv }; return WebIDL::SimpleException { WebIDL::SimpleExceptionType::URIError, "Failed to parse URL"sv };

View file

@ -7,11 +7,11 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibURL/Parser.h>
#include <LibWeb/CSS/ComputedValues.h> #include <LibWeb/CSS/ComputedValues.h>
#include <LibWeb/CSS/Fetch.h> #include <LibWeb/CSS/Fetch.h>
#include <LibWeb/CSS/StyleValues/ImageStyleValue.h> #include <LibWeb/CSS/StyleValues/ImageStyleValue.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/DOMURL/DOMURL.h>
#include <LibWeb/HTML/DecodedImageData.h> #include <LibWeb/HTML/DecodedImageData.h>
#include <LibWeb/HTML/PotentialCORSRequest.h> #include <LibWeb/HTML/PotentialCORSRequest.h>
#include <LibWeb/HTML/SharedResourceRequest.h> #include <LibWeb/HTML/SharedResourceRequest.h>
@ -208,7 +208,7 @@ ValueComparingNonnullRefPtr<StyleValue const> ImageStyleValue::absolutized(CSSPi
}(); }();
if (base_url.has_value()) { if (base_url.has_value()) {
if (auto resolved_url = ::URL::Parser::basic_parse(m_url.url(), *base_url); resolved_url.has_value()) if (auto resolved_url = DOMURL::parse(m_url.url(), *base_url); resolved_url.has_value())
return ImageStyleValue::create(*resolved_url); return ImageStyleValue::create(*resolved_url);
} }

View file

@ -6,7 +6,7 @@
#include <AK/HashTable.h> #include <AK/HashTable.h>
#include <LibGfx/Bitmap.h> #include <LibGfx/Bitmap.h>
#include <LibURL/Parser.h> #include <LibWeb/DOMURL/DOMURL.h>
#include <LibWeb/Fetch/Fetching/Fetching.h> #include <LibWeb/Fetch/Fetching/Fetching.h>
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h> #include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
#include <LibWeb/Fetch/Infrastructure/FetchController.h> #include <LibWeb/Fetch/Infrastructure/FetchController.h>
@ -71,8 +71,9 @@ void ImageRequest::set_state(State state)
void ImageRequest::set_current_url(JS::Realm& realm, String url) void ImageRequest::set_current_url(JS::Realm& realm, String url)
{ {
m_current_url = move(url); m_current_url = move(url);
if (auto url = URL::Parser::basic_parse(m_current_url); url.has_value())
m_shared_resource_request = SharedResourceRequest::get_or_create(realm, m_page, url.release_value()); if (auto parsed_url = DOMURL::parse(m_current_url); parsed_url.has_value())
m_shared_resource_request = SharedResourceRequest::get_or_create(realm, m_page, parsed_url.release_value());
} }
// https://html.spec.whatwg.org/multipage/images.html#abort-the-image-request // https://html.spec.whatwg.org/multipage/images.html#abort-the-image-request

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<style>
* {
margin: 0;
}
body {
background-color: white;
}
</style>
<img src="../images/css-background-blob-url-ref.png" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<head>
<link rel="match" href="../expected/css-background-blob-url-ref.html" />
<style>
#background {
width: 50px;
height: 50px;
border: 2px solid blue;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<div id="background"></div>
<script>
fetch("../data/smiley.png")
.then(response => response.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
background.style.backgroundImage = `url('${url}')`;
// FIXME: This is pretty hacky. We don't have a way to wait for the background image URL to load to
// signal that the test is done. So we load a second blob URL using Image, which we can wait
// upon. Since these are sequential, the second image load indicates that the first is done.
requestAnimationFrame(() => {
const image = new Image();
image.addEventListener("load", () => {
requestAnimationFrame(() => {
document.documentElement.classList.remove("reftest-wait");
});
});
image.src = URL.createObjectURL(blob);
});
});
</script>
</body>
</html>