From fe891727dc264e23d34b877c8b6da4df80b07bc0 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 6 Dec 2024 16:24:08 -0500 Subject: [PATCH] LibWeb: Use correct URL parsing methods throughout LibWeb There are essentially 3 URL parsing AOs defined by the spec: 1. Parse a URL 2. Encoding parse a URL 3. Encoding parse a URL and serialize the result Further, these are replicated between the Document and the ESO. This patch defines these methods in accordance with the spec and updates existing users to invoke the correct method. In places where the correct method is ambiguous, we use the encoding parser to preserve existing ad- hoc behavior. --- Libraries/LibWeb/CSS/SelectorEngine.cpp | 2 +- Libraries/LibWeb/CSS/StyleComputer.cpp | 2 +- Libraries/LibWeb/DOM/Document.cpp | 33 ++++++++++++- Libraries/LibWeb/DOM/Document.h | 2 + Libraries/LibWeb/HTML/EventSource.cpp | 2 +- Libraries/LibWeb/HTML/HTMLBodyElement.cpp | 3 +- Libraries/LibWeb/HTML/HTMLFormElement.cpp | 2 +- .../LibWeb/HTML/HTMLHyperlinkElementUtils.cpp | 17 ++----- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 2 +- Libraries/LibWeb/HTML/HTMLLinkElement.cpp | 10 ++-- Libraries/LibWeb/HTML/HTMLObjectElement.cpp | 4 +- .../LibWeb/HTML/HTMLTableCellElement.cpp | 3 +- Libraries/LibWeb/HTML/HTMLTableElement.cpp | 3 +- Libraries/LibWeb/HTML/HTMLTableRowElement.cpp | 3 +- .../LibWeb/HTML/HTMLTableSectionElement.cpp | 2 +- Libraries/LibWeb/HTML/Location.cpp | 9 ++-- .../LibWeb/HTML/Scripting/Environments.cpp | 47 +++++++++++++++---- .../LibWeb/HTML/Scripting/Environments.h | 2 + Libraries/LibWeb/HTML/Window.cpp | 4 +- Libraries/LibWeb/HTML/Worker.cpp | 2 +- Libraries/LibWeb/HTML/WorkerGlobalScope.cpp | 2 +- Libraries/LibWeb/Page/EventHandler.cpp | 8 ++-- Libraries/LibWeb/SVG/SVGGradientElement.cpp | 2 +- .../BindingsGenerator/IDLGenerators.cpp | 8 ++-- Services/WebContent/ConnectionFromClient.cpp | 2 +- 25 files changed, 119 insertions(+), 57 deletions(-) diff --git a/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Libraries/LibWeb/CSS/SelectorEngine.cpp index 420018e19e7..eef6bfc313f 100644 --- a/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -464,7 +464,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::URL target_url = element.document().parse_url(element.attribute(HTML::AttributeNames::href).value_or({})); + URL::URL target_url = element.document().encoding_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); diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index f00126e38f8..3683c181136 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -2825,7 +2825,7 @@ Optional StyleComputer::load_font_face(ParsedFontFace const& font_f for (auto const& 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()) - urls.append(m_document->parse_url(source.local_or_url.get().to_string())); + urls.append(m_document->encoding_parse_url(source.local_or_url.get().to_string())); // FIXME: Handle local() } diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index b852554b78b..6cbaa010782 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -1081,7 +1081,38 @@ URL::URL Document::parse_url(StringView url) const auto base_url = this->base_url(); // 2. Return the result of applying the URL parser to url, with baseURL. - return DOMURL::parse(url, base_url, Optional { m_encoding }); + return DOMURL::parse(url, base_url); +} + +// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#encoding-parsing-a-url +URL::URL Document::encoding_parse_url(StringView url) const +{ + // 1. Let encoding be UTF-8. + // 2. If environment is a Document object, then set encoding to environment's character encoding. + auto encoding = encoding_or_default(); + + // 3. Otherwise, if environment's relevant global object is a Window object, set encoding to environment's relevant + // global object's associated Document's character encoding. + + // 4. Let baseURL be environment's base URL, if environment is a Document object; otherwise environment's API base URL. + auto base_url = this->base_url(); + + // 5. Return the result of applying the URL parser to url, with baseURL and encoding. + return DOMURL::parse(url, base_url, encoding); +} + +// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#encoding-parsing-and-serializing-a-url +Optional Document::encoding_parse_and_serialize_url(StringView url) const +{ + // 1. Let url be the result of encoding-parsing a URL given url, relative to environment. + auto parsed_url = encoding_parse_url(url); + + // 2. If url is failure, then return failure. + if (!parsed_url.is_valid()) + return {}; + + // 3. Return the result of applying the URL serializer to url. + return parsed_url.serialize(); } void Document::set_needs_layout() diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index f8cd52a6e88..c5d6ad140fc 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -157,6 +157,8 @@ public: void set_opener_policy(HTML::OpenerPolicy policy) { m_opener_policy = move(policy); } URL::URL parse_url(StringView) const; + URL::URL encoding_parse_url(StringView) const; + Optional encoding_parse_and_serialize_url(StringView) const; CSS::StyleComputer& style_computer() { return *m_style_computer; } const CSS::StyleComputer& style_computer() const { return *m_style_computer; } diff --git a/Libraries/LibWeb/HTML/EventSource.cpp b/Libraries/LibWeb/HTML/EventSource.cpp index 79ffec187c5..1bfaef14499 100644 --- a/Libraries/LibWeb/HTML/EventSource.cpp +++ b/Libraries/LibWeb/HTML/EventSource.cpp @@ -43,7 +43,7 @@ WebIDL::ExceptionOr> EventSource::construct_impl(JS::Realm& auto& settings = relevant_settings_object(event_source); // 3. Let urlRecord be the result of encoding-parsing a URL given url, relative to settings. - auto url_record = settings.parse_url(url); + auto url_record = settings.encoding_parse_url(url); // 4. If urlRecord is failure, then throw a "SyntaxError" DOMException. if (!url_record.is_valid()) diff --git a/Libraries/LibWeb/HTML/HTMLBodyElement.cpp b/Libraries/LibWeb/HTML/HTMLBodyElement.cpp index 0326afb764e..d4d75cff7d0 100644 --- a/Libraries/LibWeb/HTML/HTMLBodyElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLBodyElement.cpp @@ -113,7 +113,8 @@ void HTMLBodyElement::attribute_changed(FlyString const& name, Optional if (color.has_value()) document().set_visited_link_color(color.value()); } else if (name.equals_ignoring_ascii_case("background"sv)) { - m_background_style_value = CSS::ImageStyleValue::create(document().parse_url(value.value_or(String {}))); + // https://html.spec.whatwg.org/multipage/rendering.html#the-page:attr-background + m_background_style_value = CSS::ImageStyleValue::create(document().encoding_parse_url(value.value_or(String {}))); m_background_style_value->on_animate = [this] { if (paintable()) { paintable()->set_needs_display(); diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Libraries/LibWeb/HTML/HTMLFormElement.cpp index c397482a86a..3849c18e24a 100644 --- a/Libraries/LibWeb/HTML/HTMLFormElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLFormElement.cpp @@ -222,7 +222,7 @@ WebIDL::ExceptionOr HTMLFormElement::submit_form(GC::Ref subm // 14. Parse a URL given action, relative to the submitter element's node document. If this fails, return. // 15. Let parsed action be the resulting URL record. - auto parsed_action = document().parse_url(action); + auto parsed_action = submitter->document().parse_url(action); if (!parsed_action.is_valid()) { dbgln("Failed to submit form: Invalid URL: {}", action); return {}; diff --git a/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp b/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp index cb496c73408..2e823aa2b36 100644 --- a/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp +++ b/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp @@ -486,22 +486,15 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional hyperlink_ // 8. Let urlString be the result of encoding-parsing-and-serializing a URL given subject's href attribute value, // relative to subject's node document. - auto url = hyperlink_element_utils_document().parse_url(href()); + auto url_string = hyperlink_element_utils_document().encoding_parse_and_serialize_url(href()); // 9. If urlString is failure, then return. - if (!url.is_valid()) + if (!url_string.has_value()) return; - auto url_string = url.to_string(); - // 10. If hyperlinkSuffix is non-null, then append it to urlString. - if (hyperlink_suffix.has_value()) { - StringBuilder url_builder; - url_builder.append(url_string); - url_builder.append(*hyperlink_suffix); - - url_string = MUST(url_builder.to_string()); - } + if (hyperlink_suffix.has_value()) + url_string = MUST(String::formatted("{}{}", *url_string, *hyperlink_suffix)); // 11. Let referrerPolicy be the current state of subject's referrerpolicy content attribute. auto referrer_policy = ReferrerPolicy::from_string(hyperlink_element_utils_referrerpolicy().value_or({})).value_or(ReferrerPolicy::ReferrerPolicy::EmptyString); @@ -509,7 +502,7 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional hyperlink_ // FIXME: 12. If subject's link types includes the noreferrer keyword, then set referrerPolicy to "no-referrer". // 13. Navigate targetNavigable to urlString using subject's node document, with referrerPolicy set to referrerPolicy and userInvolvement set to userInvolvement. - MUST(target_navigable->navigate({ .url = url_string, .source_document = hyperlink_element_utils_document(), .referrer_policy = referrer_policy, .user_involvement = user_involvement })); + MUST(target_navigable->navigate({ .url = *url_string, .source_document = hyperlink_element_utils_document(), .referrer_policy = referrer_policy, .user_involvement = user_involvement })); } } diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index c4a6d14a9bd..c8e9034664e 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1319,7 +1319,7 @@ WebIDL::ExceptionOr HTMLInputElement::handle_src_attribute(String const& v // 1. Let url be the result of encoding-parsing a URL given the src attribute's value, relative to the element's // node document. - auto url = document().parse_url(value); + auto url = document().encoding_parse_url(value); // 2. If url is failure, then return. if (!url.is_valid()) diff --git a/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index 852155bd71c..f4aa0b7c48c 100644 --- a/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -78,14 +78,14 @@ void HTMLLinkElement::inserted() if (m_relationship & Relationship::Preload) { // FIXME: Respect the "as" attribute. LoadRequest request; - request.set_url(document().parse_url(get_attribute_value(HTML::AttributeNames::href))); + request.set_url(document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href))); set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request)); } else if (m_relationship & Relationship::DNSPrefetch) { - ResourceLoader::the().prefetch_dns(document().parse_url(get_attribute_value(HTML::AttributeNames::href))); + ResourceLoader::the().prefetch_dns(document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href))); } else if (m_relationship & Relationship::Preconnect) { - ResourceLoader::the().preconnect(document().parse_url(get_attribute_value(HTML::AttributeNames::href))); + ResourceLoader::the().preconnect(document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href))); } else if (m_relationship & Relationship::Icon) { - auto favicon_url = document().parse_url(href()); + auto favicon_url = document().encoding_parse_url(href()); auto favicon_request = LoadRequest::create_for_url_on_page(favicon_url, &document().page()); set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, favicon_request)); } @@ -261,6 +261,8 @@ GC::Ptr HTMLLinkElement::create_link_request(HTM // FIXME: 2. If options's destination is null, then return null. // 3. Let url be the result of encoding-parsing a URL given options's href, relative to options's base URL. + // FIXME: Spec issue: We should be parsing this URL relative to a document or environment settings object. + // https://github.com/whatwg/html/issues/9715 auto url = options.base_url.complete_url(options.href); // 4. If url is failure, then return null. diff --git a/Libraries/LibWeb/HTML/HTMLObjectElement.cpp b/Libraries/LibWeb/HTML/HTMLObjectElement.cpp index 170c5a2a602..64681cf0a85 100644 --- a/Libraries/LibWeb/HTML/HTMLObjectElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLObjectElement.cpp @@ -137,7 +137,7 @@ String HTMLObjectElement::data() const if (!data.has_value()) return {}; - return document().parse_url(*data).to_string(); + return document().encoding_parse_url(*data).to_string(); } GC::Ptr HTMLObjectElement::create_layout_node(CSS::StyleProperties style) @@ -401,7 +401,7 @@ void HTMLObjectElement::load_image() { // NOTE: This currently reloads the image instead of reusing the resource we've already downloaded. auto data = get_attribute_value(HTML::AttributeNames::data); - auto url = document().parse_url(data); + auto url = document().encoding_parse_url(data); m_resource_request = HTML::SharedResourceRequest::get_or_create(realm(), document().page(), url); m_resource_request->add_callbacks( [this] { diff --git a/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp b/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp index 1188ec0a53b..a482a628d70 100644 --- a/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp @@ -74,7 +74,8 @@ void HTMLTableCellElement::apply_presentational_hints(CSS::StyleProperties& styl style.set_property(CSS::PropertyID::Height, parsed_value.release_nonnull()); return; } else if (name == HTML::AttributeNames::background) { - if (auto parsed_value = document().parse_url(value); parsed_value.is_valid()) + // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url + if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); return; } diff --git a/Libraries/LibWeb/HTML/HTMLTableElement.cpp b/Libraries/LibWeb/HTML/HTMLTableElement.cpp index 0603164e42f..cd391d7a7c0 100644 --- a/Libraries/LibWeb/HTML/HTMLTableElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableElement.cpp @@ -74,7 +74,8 @@ void HTMLTableElement::apply_presentational_hints(CSS::StyleProperties& style) c return; } if (name == HTML::AttributeNames::background) { - if (auto parsed_value = document().parse_url(value); parsed_value.is_valid()) + // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url + if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); return; } diff --git a/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp b/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp index 6e71e30bc3d..4c4d37882a9 100644 --- a/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp @@ -49,7 +49,8 @@ void HTMLTableRowElement::apply_presentational_hints(CSS::StyleProperties& style if (color.has_value()) style.set_property(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); } else if (name == HTML::AttributeNames::background) { - if (auto parsed_value = document().parse_url(value); parsed_value.is_valid()) + // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url + if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); } else if (name == HTML::AttributeNames::height) { if (auto parsed_value = parse_dimension_value(value)) diff --git a/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp b/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp index 31e4fc91a8a..21ed29ea995 100644 --- a/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp @@ -105,7 +105,7 @@ void HTMLTableSectionElement::apply_presentational_hints(CSS::StyleProperties& s for_each_attribute([&](auto& name, auto& value) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url if (name == HTML::AttributeNames::background) { - if (auto parsed_value = document().parse_url(value); parsed_value.is_valid()) + if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); } // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:rules-for-parsing-a-legacy-colour-value diff --git a/Libraries/LibWeb/HTML/Location.cpp b/Libraries/LibWeb/HTML/Location.cpp index 9ca6031f74a..ab04b03e3be 100644 --- a/Libraries/LibWeb/HTML/Location.cpp +++ b/Libraries/LibWeb/HTML/Location.cpp @@ -108,22 +108,21 @@ WebIDL::ExceptionOr Location::href() const WebIDL::ExceptionOr Location::set_href(String const& new_href) { auto& realm = this->realm(); - auto& window = verify_cast(HTML::current_principal_global_object()); // 1. If this's relevant Document is null, then return. auto const relevant_document = this->relevant_document(); if (!relevant_document) return {}; - // FIXME: 2. Let url be the result of encoding-parsing a URL given the given value, relative to the entry settings object. - auto href_url = window.associated_document().parse_url(new_href.to_byte_string()); + // 2. Let url be the result of encoding-parsing a URL given the given value, relative to the entry settings object. + auto url = entry_settings_object().encoding_parse_url(new_href.to_byte_string()); // 3. If url is failure, then throw a "SyntaxError" DOMException. - if (!href_url.is_valid()) + if (!url.is_valid()) return WebIDL::SyntaxError::create(realm, MUST(String::formatted("Invalid URL '{}'", new_href))); // 4. Location-object navigate this to url. - TRY(navigate(href_url)); + TRY(navigate(url)); return {}; } diff --git a/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Libraries/LibWeb/HTML/Scripting/Environments.cpp index 1379f1d6070..217711cc0b7 100644 --- a/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -201,17 +202,45 @@ void prepare_to_run_callback(JS::Realm& realm) // https://html.spec.whatwg.org/multipage/urls-and-fetching.html#parse-a-url URL::URL EnvironmentSettingsObject::parse_url(StringView url) { - // 1. Let encoding be document's character encoding, if document was given, and environment settings object's API URL character encoding otherwise. - // FIXME: Pass in environment settings object's API URL character encoding. - - // 2. Let baseURL be document's base URL, if document was given, and environment settings object's API base URL otherwise. + // 1. Let baseURL be environment's base URL, if environment is a Document object; otherwise environment's API base URL. auto base_url = api_base_url(); - // 3. Let urlRecord be the result of applying the URL parser to url, with baseURL and encoding. - // 4. If urlRecord is failure, then return failure. - // 5. Let urlString be the result of applying the URL serializer to urlRecord. - // 6. Return urlString as the resulting URL string and urlRecord as the resulting URL record. - return base_url.complete_url(url); + // 2. Return the result of applying the URL parser to url, with baseURL. + return DOMURL::parse(url, base_url); +} + +// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#encoding-parsing-a-url +URL::URL EnvironmentSettingsObject::encoding_parse_url(StringView url) +{ + // 1. Let encoding be UTF-8. + auto encoding = "UTF-8"_string; + + // 2. If environment is a Document object, then set encoding to environment's character encoding. + + // 3. Otherwise, if environment's relevant global object is a Window object, set encoding to environment's relevant + // global object's associated Document's character encoding. + if (is(global_object())) + encoding = static_cast(global_object()).associated_document().encoding_or_default(); + + // 4. Let baseURL be environment's base URL, if environment is a Document object; otherwise environment's API base URL. + auto base_url = api_base_url(); + + // 5. Return the result of applying the URL parser to url, with baseURL and encoding. + return DOMURL::parse(url, base_url, encoding); +} + +// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#encoding-parsing-and-serializing-a-url +Optional EnvironmentSettingsObject::encoding_parse_and_serialize_url(StringView url) +{ + // 1. Let url be the result of encoding-parsing a URL given url, relative to environment. + auto parsed_url = encoding_parse_url(url); + + // 2. If url is failure, then return failure. + if (!parsed_url.is_valid()) + return {}; + + // 3. Return the result of applying the URL serializer to url. + return parsed_url.serialize(); } // https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-a-callback diff --git a/Libraries/LibWeb/HTML/Scripting/Environments.h b/Libraries/LibWeb/HTML/Scripting/Environments.h index 118cbfeba49..d7adc8d6c74 100644 --- a/Libraries/LibWeb/HTML/Scripting/Environments.h +++ b/Libraries/LibWeb/HTML/Scripting/Environments.h @@ -88,6 +88,8 @@ public: virtual CanUseCrossOriginIsolatedAPIs cross_origin_isolated_capability() const = 0; URL::URL parse_url(StringView); + URL::URL encoding_parse_url(StringView); + Optional encoding_parse_and_serialize_url(StringView); JS::Realm& realm(); JS::Object& global_object(); diff --git a/Libraries/LibWeb/HTML/Window.cpp b/Libraries/LibWeb/HTML/Window.cpp index 4168c3f4625..dd0774ee5e0 100644 --- a/Libraries/LibWeb/HTML/Window.cpp +++ b/Libraries/LibWeb/HTML/Window.cpp @@ -197,8 +197,8 @@ WebIDL::ExceptionOr Window::window_open_steps_internal(Str // 4. If url is not the empty string, then: if (!url.is_empty()) { - // FIXME: 1. Set urlRecord to the result of encoding-parsing a URL given url, relative to sourceDocument. - url_record = entry_settings_object().parse_url(url); + // 1. Set urlRecord to the result of encoding-parsing a URL given url, relative to sourceDocument. + url_record = source_document.encoding_parse_url(url); // 2. If urlRecord is failure, then throw a "SyntaxError" DOMException. if (!url_record->is_valid()) diff --git a/Libraries/LibWeb/HTML/Worker.cpp b/Libraries/LibWeb/HTML/Worker.cpp index 5a7895bb05d..390f9385f0c 100644 --- a/Libraries/LibWeb/HTML/Worker.cpp +++ b/Libraries/LibWeb/HTML/Worker.cpp @@ -60,7 +60,7 @@ WebIDL::ExceptionOr> Worker::create(String const& script_url, Wo auto& outside_settings = current_principal_settings_object(); // 3. Parse the scriptURL argument relative to outside settings. - auto url = document.parse_url(script_url); + auto url = outside_settings.parse_url(script_url); // 4. If this fails, throw a "SyntaxError" DOMException. if (!url.is_valid()) { diff --git a/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp b/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp index db3c8883e5b..2d85e72ed7b 100644 --- a/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp @@ -103,7 +103,7 @@ WebIDL::ExceptionOr WorkerGlobalScope::import_scripts(Vector const // 5. For each url of urls: for (auto const& url : urls) { // 1. Let urlRecord be the result of encoding-parsing a URL given url, relative to settings object. - auto url_record = settings_object.parse_url(url); + auto url_record = settings_object.encoding_parse_url(url); // 2. If urlRecord is failure, then throw a "SyntaxError" DOMException. if (!url_record.is_valid()) diff --git a/Libraries/LibWeb/Page/EventHandler.cpp b/Libraries/LibWeb/Page/EventHandler.cpp index 71a3282c0bb..961c8823271 100644 --- a/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Libraries/LibWeb/Page/EventHandler.cpp @@ -331,7 +331,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix if (GC::Ptr link = node->enclosing_link_element()) { GC::Ref document = *m_navigable->active_document(); auto href = link->href(); - auto url = document->parse_url(href); + auto url = document->encoding_parse_url(href); if (button == UIEvents::MouseButton::Primary && (modifiers & UIEvents::Mod_PlatformCtrl) != 0) { m_navigable->page().client().page_did_click_link(url, link->target().to_byte_string(), modifiers); @@ -343,13 +343,13 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix } else if (button == UIEvents::MouseButton::Secondary) { if (is(*node)) { auto& image_element = verify_cast(*node); - auto image_url = image_element.document().parse_url(image_element.src()); + auto image_url = image_element.document().encoding_parse_url(image_element.src()); m_navigable->page().client().page_did_request_image_context_menu(viewport_position, image_url, "", modifiers, image_element.immutable_bitmap()->bitmap()); } else if (is(*node)) { auto& media_element = verify_cast(*node); Page::MediaContextMenu menu { - .media_url = media_element.document().parse_url(media_element.current_src()), + .media_url = media_element.document().encoding_parse_url(media_element.current_src()), .is_video = is(*node), .is_playing = media_element.potentially_playing(), .is_muted = media_element.muted(), @@ -636,7 +636,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP if (is_hovering_link) { page.set_is_hovering_link(true); - page.client().page_did_hover_link(document.parse_url(hovered_link_element->href())); + page.client().page_did_hover_link(document.encoding_parse_url(hovered_link_element->href())); } else if (page.is_hovering_link()) { page.set_is_hovering_link(false); page.client().page_did_unhover_link(); diff --git a/Libraries/LibWeb/SVG/SVGGradientElement.cpp b/Libraries/LibWeb/SVG/SVGGradientElement.cpp index e090a3feae4..2fd2441b929 100644 --- a/Libraries/LibWeb/SVG/SVGGradientElement.cpp +++ b/Libraries/LibWeb/SVG/SVGGradientElement.cpp @@ -128,7 +128,7 @@ GC::Ptr SVGGradientElement::linked_gradient(HashTable< auto link = has_attribute(AttributeNames::href) ? get_attribute(AttributeNames::href) : get_attribute("xlink:href"_fly_string); if (auto href = link; href.has_value() && !link->is_empty()) { - auto url = document().parse_url(*href); + auto url = document().encoding_parse_url(*href); auto id = url.fragment(); if (!id.has_value() || id->is_empty()) return {}; diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 5b4da377ae9..35dd36dcbbf 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -3626,7 +3626,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@) } } - if (!has_keyword && !did_set_to_missing_value) + if (!has_keyword && !did_set_to_missing_value) retval = "@invalid_enum_default_value@"_string; )~~~"); @@ -3782,9 +3782,9 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@) if (!content_attribute_value.has_value()) return JS::PrimitiveString::create(vm, String {}); - auto url_string = impl->document().parse_url(*content_attribute_value); - if (url_string.is_valid()) - return JS::PrimitiveString::create(vm, url_string.to_string()); + auto url_string = impl->document().encoding_parse_and_serialize_url(*content_attribute_value); + if (url_string.has_value()) + return JS::PrimitiveString::create(vm, url_string.release_value()); )~~~"); } diff --git a/Services/WebContent/ConnectionFromClient.cpp b/Services/WebContent/ConnectionFromClient.cpp index c7fa9d2ab4d..03944c68bc6 100644 --- a/Services/WebContent/ConnectionFromClient.cpp +++ b/Services/WebContent/ConnectionFromClient.cpp @@ -432,7 +432,7 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, load_html(page_id, "

Failed to find <link rel="match" /> or <link rel="mismatch" /> in ref test page!

Make sure you added it."); } else { auto link = maybe_link.release_value(); - auto url = document->parse_url(link->get_attribute_value(Web::HTML::AttributeNames::href)); + auto url = document->encoding_parse_url(link->get_attribute_value(Web::HTML::AttributeNames::href)); if (url.query().has_value() && !url.query()->is_empty()) { load_html(page_id, "

Invalid ref test link - query string must be empty

"); return;