AK+LibURL: Move AK::URL into a new URL library

This URL library ends up being a relatively fundamental base library of
the system, as LibCore depends on LibURL.

This change has two main benefits:
 * Moving AK back more towards being an agnostic library that can
   be used between the kernel and userspace. URL has never really fit
   that description - and is not used in the kernel.
 * URL _should_ depend on LibUnicode, as it needs punnycode support.
   However, it's not really possible to do this inside of AK as it can't
   depend on any external library. This change brings us a little closer
   to being able to do that, but unfortunately we aren't there quite
   yet, as the code generators depend on LibCore.
This commit is contained in:
Shannon Booth 2024-03-18 16:22:27 +13:00 committed by Tim Flynn
commit e800605ad3
Notes: sideshowbarker 2024-07-17 04:41:05 +09:00
403 changed files with 1336 additions and 1305 deletions

View file

@ -64,8 +64,8 @@ String CSSFontFaceRule::serialized() const
// 2. The result of invoking serialize a comma-separated list on performing serialize a URL or serialize a LOCAL for each source on the source list.
serialize_a_comma_separated_list(builder, m_font_face.sources(), [&](StringBuilder& builder, FontFace::Source source) -> void {
if (source.local_or_url.has<URL>()) {
serialize_a_url(builder, MUST(source.local_or_url.get<URL>().to_string()));
if (source.local_or_url.has<URL::URL>()) {
serialize_a_url(builder, MUST(source.local_or_url.get<URL::URL>().to_string()));
} else {
builder.appendff("local({})", source.local_or_url.get<String>());
}

View file

@ -7,7 +7,7 @@
*/
#include <AK/Debug.h>
#include <AK/URL.h>
#include <LibURL/URL.h>
#include <LibWeb/Bindings/CSSImportRulePrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/CSSImportRule.h>
@ -21,13 +21,13 @@ namespace Web::CSS {
JS_DEFINE_ALLOCATOR(CSSImportRule);
JS::NonnullGCPtr<CSSImportRule> CSSImportRule::create(URL url, DOM::Document& document)
JS::NonnullGCPtr<CSSImportRule> CSSImportRule::create(URL::URL url, DOM::Document& document)
{
auto& realm = document.realm();
return realm.heap().allocate<CSSImportRule>(realm, move(url), document);
}
CSSImportRule::CSSImportRule(URL url, DOM::Document& document)
CSSImportRule::CSSImportRule(URL::URL url, DOM::Document& document)
: CSSRule(document.realm())
, m_url(move(url))
, m_document(document)

View file

@ -8,7 +8,7 @@
#pragma once
#include <AK/URL.h>
#include <LibURL/URL.h>
#include <LibWeb/CSS/CSSRule.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/DOM/DocumentLoadEventDelayer.h>
@ -23,11 +23,11 @@ class CSSImportRule final
JS_DECLARE_ALLOCATOR(CSSImportRule);
public:
[[nodiscard]] static JS::NonnullGCPtr<CSSImportRule> create(URL, DOM::Document&);
[[nodiscard]] static JS::NonnullGCPtr<CSSImportRule> create(URL::URL, DOM::Document&);
virtual ~CSSImportRule() = default;
URL const& url() const { return m_url; }
URL::URL const& url() const { return m_url; }
// FIXME: This should return only the specified part of the url. eg, "stuff/foo.css", not "https://example.com/stuff/foo.css".
String href() const { return MUST(m_url.to_string()); }
@ -39,7 +39,7 @@ public:
virtual Type type() const override { return Type::Import; }
private:
CSSImportRule(URL, DOM::Document&);
CSSImportRule(URL::URL, DOM::Document&);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
@ -50,7 +50,7 @@ private:
virtual void resource_did_fail() override;
virtual void resource_did_load() override;
URL m_url;
URL::URL m_url;
JS::GCPtr<DOM::Document> m_document;
JS::GCPtr<CSSStyleSheet> m_style_sheet;
Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer;

View file

@ -20,7 +20,7 @@ namespace Web::CSS {
JS_DEFINE_ALLOCATOR(CSSStyleSheet);
JS::NonnullGCPtr<CSSStyleSheet> CSSStyleSheet::create(JS::Realm& realm, CSSRuleList& rules, MediaList& media, Optional<URL> location)
JS::NonnullGCPtr<CSSStyleSheet> CSSStyleSheet::create(JS::Realm& realm, CSSRuleList& rules, MediaList& media, Optional<URL::URL> location)
{
return realm.heap().allocate<CSSStyleSheet>(realm, realm, rules, media, move(location));
}
@ -37,12 +37,12 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<CSSStyleSheet>> CSSStyleSheet::construct_im
// 3. Set sheets stylesheet base URL to the baseURL attribute value from options.
if (options.has_value() && options->base_url.has_value()) {
Optional<URL> sheet_location_url;
Optional<URL::URL> sheet_location_url;
if (sheet->location().has_value())
sheet_location_url = sheet->location().release_value();
// AD-HOC: This isn't explicitly mentioned in the specification, but multiple modern browsers do this.
URL url = sheet->location().has_value() ? sheet_location_url->complete_url(options->base_url.value()) : options->base_url.value();
URL::URL url = sheet->location().has_value() ? sheet_location_url->complete_url(options->base_url.value()) : options->base_url.value();
if (!url.is_valid())
return WebIDL::NotAllowedError::create(realm, "Constructed style sheets must have a valid base URL"_fly_string);
@ -91,7 +91,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<CSSStyleSheet>> CSSStyleSheet::construct_im
return sheet;
}
CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& media, Optional<URL> location)
CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& media, Optional<URL::URL> location)
: StyleSheet(realm, media)
, m_rules(&rules)
{

View file

@ -32,7 +32,7 @@ class CSSStyleSheet final
JS_DECLARE_ALLOCATOR(CSSStyleSheet);
public:
[[nodiscard]] static JS::NonnullGCPtr<CSSStyleSheet> create(JS::Realm&, CSSRuleList&, MediaList&, Optional<URL> location);
[[nodiscard]] static JS::NonnullGCPtr<CSSStyleSheet> create(JS::Realm&, CSSRuleList&, MediaList&, Optional<URL::URL> location);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<CSSStyleSheet>> construct_impl(JS::Realm&, Optional<CSSStyleSheetInit> const& options = {});
virtual ~CSSStyleSheet() override = default;
@ -69,8 +69,8 @@ public:
Optional<FlyString> namespace_uri(StringView namespace_prefix) const;
Optional<URL> base_url() const { return m_base_url; }
void set_base_url(Optional<URL> base_url) { m_base_url = move(base_url); }
Optional<URL::URL> base_url() const { return m_base_url; }
void set_base_url(Optional<URL::URL> base_url) { m_base_url = move(base_url); }
bool constructed() const { return m_constructed; }
@ -80,7 +80,7 @@ public:
bool disallow_modification() const { return m_disallow_modification; }
private:
CSSStyleSheet(JS::Realm&, CSSRuleList&, MediaList&, Optional<URL> location);
CSSStyleSheet(JS::Realm&, CSSRuleList&, MediaList&, Optional<URL::URL> location);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
@ -97,7 +97,7 @@ private:
JS::GCPtr<StyleSheetList> m_style_sheet_list;
JS::GCPtr<CSSRule> m_owner_css_rule;
Optional<URL> m_base_url;
Optional<URL::URL> m_base_url;
JS::GCPtr<DOM::Document const> m_constructor_document;
bool m_constructed { false };
bool m_disallow_modification { false };

View file

@ -201,33 +201,33 @@ public:
: m_value(color)
{
}
SVGPaint(URL const& url)
SVGPaint(URL::URL const& url)
: m_value(url)
{
}
bool is_color() const { return m_value.has<Color>(); }
bool is_url() const { return m_value.has<URL>(); }
bool is_url() const { return m_value.has<URL::URL>(); }
Color as_color() const { return m_value.get<Color>(); }
URL const& as_url() const { return m_value.get<URL>(); }
URL::URL const& as_url() const { return m_value.get<URL::URL>(); }
private:
Variant<URL, Color> m_value;
Variant<URL::URL, Color> m_value;
};
// https://drafts.fxtf.org/css-masking-1/#typedef-mask-reference
class MaskReference {
public:
// TODO: Support other mask types.
MaskReference(URL const& url)
MaskReference(URL::URL const& url)
: m_url(url)
{
}
URL const& url() const { return m_url; }
URL::URL const& url() const { return m_url; }
private:
URL m_url;
URL::URL m_url;
};
struct BackgroundLayerData {

View file

@ -8,15 +8,15 @@
#pragma once
#include <AK/FlyString.h>
#include <AK/URL.h>
#include <LibGfx/Font/UnicodeRange.h>
#include <LibURL/URL.h>
namespace Web::CSS {
class FontFace {
public:
struct Source {
Variant<String, URL> local_or_url;
Variant<String, URL::URL> local_or_url;
// FIXME: Do we need to keep this around, or is it only needed to discard unwanted formats during parsing?
Optional<FlyString> format;
};

View file

@ -15,7 +15,7 @@
namespace Web {
CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<URL> location)
CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<URL::URL> location)
{
if (css.is_empty()) {
auto rule_list = CSS::CSSRuleList::create_empty(context.realm());

View file

@ -124,7 +124,7 @@ Parser::Parser(Parser&& other)
// 5.3.3. Parse a stylesheet
// https://www.w3.org/TR/css-syntax-3/#parse-stylesheet
template<typename T>
Parser::ParsedStyleSheet Parser::parse_a_stylesheet(TokenStream<T>& tokens, Optional<URL> location)
Parser::ParsedStyleSheet Parser::parse_a_stylesheet(TokenStream<T>& tokens, Optional<URL::URL> location)
{
// To parse a stylesheet from an input given an optional url location:
@ -144,7 +144,7 @@ Parser::ParsedStyleSheet Parser::parse_a_stylesheet(TokenStream<T>& tokens, Opti
}
// https://www.w3.org/TR/css-syntax-3/#parse-a-css-stylesheet
CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<URL> location)
CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<URL::URL> location)
{
// To parse a CSS stylesheet, first parse a stylesheet.
auto style_sheet = parse_a_stylesheet(m_token_stream, {});
@ -1160,11 +1160,11 @@ ElementInlineCSSStyleDeclaration* Parser::parse_as_style_attribute(DOM::Element&
return ElementInlineCSSStyleDeclaration::create(element, move(properties), move(custom_properties));
}
Optional<URL> Parser::parse_url_function(ComponentValue const& component_value)
Optional<URL::URL> Parser::parse_url_function(ComponentValue const& component_value)
{
// FIXME: Handle list of media queries. https://www.w3.org/TR/css-cascade-3/#conditional-import
auto convert_string_to_url = [&](StringView url_string) -> Optional<URL> {
auto convert_string_to_url = [&](StringView url_string) -> Optional<URL::URL> {
auto url = m_context.complete_url(url_string);
if (url.is_valid())
return url;
@ -1215,7 +1215,7 @@ CSSRule* Parser::convert_to_rule(NonnullRefPtr<Rule> rule)
return parse_font_face_rule(tokens);
}
if (rule->at_rule_name().equals_ignoring_ascii_case("import"sv) && !rule->prelude().is_empty()) {
Optional<URL> url;
Optional<URL::URL> url;
for (auto const& token : rule->prelude()) {
if (token.is(Token::Type::Whitespace))
continue;

View file

@ -44,7 +44,7 @@ public:
Parser(Parser&&);
CSSStyleSheet* parse_as_css_stylesheet(Optional<URL> location);
CSSStyleSheet* parse_as_css_stylesheet(Optional<URL::URL> location);
ElementInlineCSSStyleDeclaration* parse_as_style_attribute(DOM::Element&);
CSSRule* parse_as_css_rule();
Optional<StyleProperty> parse_as_supports_condition();
@ -86,11 +86,11 @@ private:
// "Parse a stylesheet" is intended to be the normal parser entry point, for parsing stylesheets.
struct ParsedStyleSheet {
Optional<URL> location;
Optional<URL::URL> location;
Vector<NonnullRefPtr<Rule>> rules;
};
template<typename T>
ParsedStyleSheet parse_a_stylesheet(TokenStream<T>&, Optional<URL> location);
ParsedStyleSheet parse_a_stylesheet(TokenStream<T>&, Optional<URL::URL> location);
// "Parse a list of rules" is intended for the content of at-rules such as @media. It differs from "Parse a stylesheet" in the handling of <CDO-token> and <CDC-token>.
template<typename T>
@ -195,7 +195,7 @@ private:
Optional<GridRepeat> parse_repeat(Vector<ComponentValue> const&);
Optional<ExplicitGridTrack> parse_track_sizing_function(ComponentValue const&);
Optional<URL> parse_url_function(ComponentValue const&);
Optional<URL::URL> parse_url_function(ComponentValue const&);
RefPtr<StyleValue> parse_url_value(ComponentValue const&);
Optional<Vector<LinearColorStopListElement>> parse_linear_color_stop_list(TokenStream<ComponentValue>&);
@ -330,7 +330,7 @@ private:
namespace Web {
CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const&, StringView, Optional<URL> location = {});
CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const&, StringView, Optional<URL::URL> location = {});
CSS::ElementInlineCSSStyleDeclaration* parse_css_style_attribute(CSS::Parser::ParsingContext const&, StringView, DOM::Element&);
RefPtr<CSS::StyleValue> parse_css_value(CSS::Parser::ParsingContext const&, StringView, CSS::PropertyID property_id = CSS::PropertyID::Invalid);
Optional<CSS::SelectorList> parse_selector(CSS::Parser::ParsingContext const&, StringView);

View file

@ -19,7 +19,7 @@ ParsingContext::ParsingContext(JS::Realm& realm, Mode mode)
{
}
ParsingContext::ParsingContext(DOM::Document const& document, URL url, Mode mode)
ParsingContext::ParsingContext(DOM::Document const& document, URL::URL url, Mode mode)
: m_realm(const_cast<JS::Realm&>(document.realm()))
, m_document(&document)
, m_url(move(url))
@ -49,7 +49,7 @@ bool ParsingContext::in_quirks_mode() const
}
// https://www.w3.org/TR/css-values-4/#relative-urls
URL ParsingContext::complete_url(StringView relative_url) const
URL::URL ParsingContext::complete_url(StringView relative_url) const
{
return m_url.complete_url(relative_url);
}

View file

@ -21,7 +21,7 @@ public:
explicit ParsingContext(JS::Realm&, Mode = Mode::Normal);
explicit ParsingContext(DOM::Document const&, Mode = Mode::Normal);
explicit ParsingContext(DOM::Document const&, URL, Mode = Mode::Normal);
explicit ParsingContext(DOM::Document const&, URL::URL, Mode = Mode::Normal);
explicit ParsingContext(DOM::ParentNode&, Mode = Mode::Normal);
Mode mode() const { return m_mode; }
@ -30,7 +30,7 @@ public:
bool in_quirks_mode() const;
DOM::Document const* document() const { return m_document; }
HTML::Window const* window() const;
URL complete_url(StringView) const;
URL::URL complete_url(StringView) const;
PropertyID current_property_id() const { return m_current_property_id; }
void set_current_property_id(PropertyID property_id) { m_current_property_id = property_id; }
@ -41,7 +41,7 @@ private:
JS::NonnullGCPtr<JS::Realm> m_realm;
JS::GCPtr<DOM::Document const> m_document;
PropertyID m_current_property_id { PropertyID::Invalid };
URL m_url;
URL::URL m_url;
Mode m_mode { Mode::Normal };
};

View file

@ -285,7 +285,7 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
if (!matches_link_pseudo_class(element))
return false;
auto document_url = element.document().url();
URL target_url = element.document().parse_url(element.attribute(HTML::AttributeNames::href).value_or({}));
URL::URL target_url = element.document().parse_url(element.attribute(HTML::AttributeNames::href).value_or({}));
if (target_url.fragment().has_value())
return document_url.equals(target_url, URL::ExcludeFragment::No);
return document_url.equals(target_url, URL::ExcludeFragment::Yes);

View file

@ -102,7 +102,7 @@ StyleComputer::~StyleComputer() = default;
class StyleComputer::FontLoader : public ResourceClient {
public:
explicit FontLoader(StyleComputer& style_computer, FlyString family_name, Vector<Gfx::UnicodeRange> unicode_ranges, Vector<URL> urls)
explicit FontLoader(StyleComputer& style_computer, FlyString family_name, Vector<Gfx::UnicodeRange> unicode_ranges, Vector<URL::URL> urls)
: m_style_computer(style_computer)
, m_family_name(move(family_name))
, m_unicode_ranges(move(unicode_ranges))
@ -187,7 +187,7 @@ private:
FlyString m_family_name;
Vector<Gfx::UnicodeRange> m_unicode_ranges;
RefPtr<Gfx::VectorFont> m_vector_font;
Vector<URL> m_urls;
Vector<URL::URL> m_urls;
};
struct StyleComputer::MatchingFontCandidate {
@ -2494,11 +2494,11 @@ void StyleComputer::load_fonts_from_sheet(CSSStyleSheet const& sheet)
.slope = font_face.slope().value_or(0),
};
Vector<URL> urls;
Vector<URL::URL> urls;
for (auto& source : font_face.sources()) {
// FIXME: These should be loaded relative to the stylesheet URL instead of the document URL.
if (source.local_or_url.has<URL>())
urls.append(m_document->parse_url(MUST(source.local_or_url.get<URL>().to_string())));
if (source.local_or_url.has<URL::URL>())
urls.append(m_document->parse_url(MUST(source.local_or_url.get<URL::URL>().to_string())));
// FIXME: Handle local()
}

View file

@ -16,11 +16,11 @@
#include <AK/RefPtr.h>
#include <AK/String.h>
#include <AK/StringView.h>
#include <AK/URL.h>
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <AK/WeakPtr.h>
#include <LibGfx/Color.h>
#include <LibURL/URL.h>
#include <LibWeb/CSS/Enums.h>
#include <LibWeb/CSS/Length.h>
#include <LibWeb/CSS/ValueID.h>

View file

@ -20,7 +20,7 @@
namespace Web::CSS {
ImageStyleValue::ImageStyleValue(URL const& url)
ImageStyleValue::ImageStyleValue(URL::URL const& url)
: AbstractImageStyleValue(Type::Image)
, m_url(url)
{

View file

@ -9,9 +9,9 @@
#pragma once
#include <AK/URL.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/Handle.h>
#include <LibURL/URL.h>
#include <LibWeb/CSS/Enums.h>
#include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h>
#include <LibWeb/HTML/SharedImageRequest.h>
@ -22,7 +22,7 @@ class ImageStyleValue final
: public AbstractImageStyleValue
, public Weakable<ImageStyleValue> {
public:
static ValueComparingNonnullRefPtr<ImageStyleValue> create(URL const& url)
static ValueComparingNonnullRefPtr<ImageStyleValue> create(URL::URL const& url)
{
return adopt_ref(*new (nothrow) ImageStyleValue(url));
}
@ -54,14 +54,14 @@ public:
JS::GCPtr<HTML::DecodedImageData> image_data() const;
private:
ImageStyleValue(URL const&);
ImageStyleValue(URL::URL const&);
JS::GCPtr<HTML::SharedImageRequest> m_image_request;
void animate();
Gfx::ImmutableBitmap const* bitmap(size_t frame_index, Gfx::IntSize = {}) const;
URL m_url;
URL::URL m_url;
WeakPtr<DOM::Document> m_document;
size_t m_current_frame_index { 0 };

View file

@ -6,7 +6,7 @@
#pragma once
#include <AK/URL.h>
#include <LibURL/URL.h>
#include <LibWeb/CSS/Serialize.h>
#include <LibWeb/CSS/StyleValue.h>
@ -14,14 +14,14 @@ namespace Web::CSS {
class URLStyleValue final : public StyleValueWithDefaultOperators<URLStyleValue> {
public:
static ValueComparingNonnullRefPtr<URLStyleValue> create(URL const& url)
static ValueComparingNonnullRefPtr<URLStyleValue> create(URL::URL const& url)
{
return adopt_ref(*new (nothrow) URLStyleValue(url));
}
virtual ~URLStyleValue() override = default;
URL const& url() const { return m_url; }
URL::URL const& url() const { return m_url; }
bool properties_equal(URLStyleValue const& other) const { return m_url == other.m_url; }
@ -31,13 +31,13 @@ public:
}
private:
URLStyleValue(URL const& url)
URLStyleValue(URL::URL const& url)
: StyleValueWithDefaultOperators(Type::URL)
, m_url(url)
{
}
URL m_url;
URL::URL m_url;
};
}