diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 499505b8496..dfb187cfc94 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -4975,9 +4975,8 @@ void Document::shared_declarative_refresh_steps(StringView input, GC::Ptrserialize(); + // 1. Let urlString be the result of encoding-parsing-and-serializing a URL given selected source, relative to the element's node document. + auto url_string = document().encoding_parse_and_serialize_url(selected_source.value()); - // 2. Let key be a tuple consisting of urlString, the img element's crossorigin attribute's mode, + // 2. If urlString is failure, then abort this inner set of steps. + if (!url_string.has_value()) + goto after_step_7; + + // 3. Let key be a tuple consisting of urlString, the img element's crossorigin attribute's mode, // and, if that mode is not No CORS, the node document's origin. ListOfAvailableImages::Key key; - key.url = maybe_url.value(); + key.url = *url_string; key.mode = m_cors_setting; key.origin = document().origin(); - // 3. If the list of available images contains an entry for key, then: + // 4. If the list of available images contains an entry for key, then: if (auto* entry = document().list_of_available_images().get(key)) { // 1. Set the ignore higher-layer caching flag for that entry. entry->ignore_higher_layer_caching = true; @@ -601,7 +600,7 @@ void HTMLImageElement::update_the_image_data_impl(bool restart_animations, bool restart_the_animation(); // 2. Set the current request's current URL to urlString. - m_current_request->set_current_url(realm(), url_string); + m_current_request->set_current_url(realm(), *url_string); // 3. If maybe omit events is not set or previousURL is not equal to urlString, then fire an event named load at the img element. if (!maybe_omit_events || previous_url != url_string) @@ -656,10 +655,11 @@ after_step_7: return; } - // 12. Parse selected source, relative to the element's node document, and let urlString be the resulting URL string. - auto maybe_url = document().parse_url(selected_source.value().url.to_byte_string()); - // If that is not successful, then: - if (!maybe_url.has_value()) { + // 12. Let urlString be the result of encoding-parsing-and-serializing a URL given selected source, relative to the element's node document. + auto url_string = document().encoding_parse_and_serialize_url(selected_source.value().url); + + // 13. If urlString is failure, then: + if (!url_string.has_value()) { // 1. Abort the image request for the current request and the pending request. abort_the_image_request(realm(), m_current_request); abort_the_image_request(realm(), m_pending_request); @@ -683,13 +683,12 @@ after_step_7: // 5. Return. return; } - auto url_string = maybe_url->serialize(); - // 13. If the pending request is not null and urlString is the same as the pending request's current URL, then return. + // 14. If the pending request is not null and urlString is the same as the pending request's current URL, then return. if (m_pending_request && url_string == m_pending_request->current_url()) return; - // 14. If urlString is the same as the current request's current URL and the current request's state is partially available, + // 15. If urlString is the same as the current request's current URL and the current request's state is partially available, // then abort the image request for the pending request, // queue an element task on the DOM manipulation task source given the img element // to restart the animation if restart animation is set, and return. @@ -703,24 +702,24 @@ after_step_7: return; } - // 15. If the pending request is not null, then abort the image request for the pending request. + // 16. If the pending request is not null, then abort the image request for the pending request. abort_the_image_request(realm(), m_pending_request); // AD-HOC: At this point we start deviating from the spec in order to allow sharing ImageRequest between // multiple image elements (as well as CSS background-images, etc.) - // 16. Set image request to a new image request whose current URL is urlString. + // 17. Set image request to a new image request whose current URL is urlString. auto image_request = ImageRequest::create(realm(), document().page()); - image_request->set_current_url(realm(), url_string); + image_request->set_current_url(realm(), *url_string); - // 17. If the current request's state is unavailable or broken, then set the current request to image request. + // 18. If the current request's state is unavailable or broken, then set the current request to image request. // Otherwise, set the pending request to image request. if (m_current_request->state() == ImageRequest::State::Unavailable || m_current_request->state() == ImageRequest::State::Broken) m_current_request = image_request; else m_pending_request = image_request; - // 23. Let delay load event be true if the img's lazy loading attribute is in the Eager state, or if scripting is disabled for the img, and false otherwise. + // 24. Let delay load event be true if the img's lazy loading attribute is in the Eager state, or if scripting is disabled for the img, and false otherwise. auto delay_load_event = lazy_loading_attribute() == LazyLoading::Eager; // When delay load event is true, fetching the image must delay the load event of the element's node document @@ -728,30 +727,34 @@ after_step_7: if (delay_load_event) m_load_event_delayer.emplace(document()); - add_callbacks_to_image_request(*image_request, maybe_omit_events, *maybe_url, previous_url); + add_callbacks_to_image_request(*image_request, maybe_omit_events, *url_string, previous_url); // AD-HOC: If the image request is already available or fetching, no need to start another fetch. if (image_request->is_available() || image_request->is_fetching()) return; - // 18. Let request be the result of creating a potential-CORS request given urlString, "image", - // and the current state of the element's crossorigin content attribute. - auto request = create_potential_CORS_request(vm(), *maybe_url, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting); + // AD-HOC: create_potential_CORS_request expects a url, but the following step passes a URL string. + auto url_record = document().encoding_parse_url(selected_source.value().url); + VERIFY(url_record.has_value()); - // 19. Set request's client to the element's node document's relevant settings object. + // 19. Let request be the result of creating a potential-CORS request given urlString, "image", + // and the current state of the element's crossorigin content attribute. + auto request = create_potential_CORS_request(vm(), *url_record, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting); + + // 20. Set request's client to the element's node document's relevant settings object. request->set_client(&document().relevant_settings_object()); - // 20. If the element uses srcset or picture, set request's initiator to "imageset". + // 21. If the element uses srcset or picture, set request's initiator to "imageset". if (uses_srcset_or_picture()) request->set_initiator(Fetch::Infrastructure::Request::Initiator::ImageSet); - // 21. Set request's referrer policy to the current state of the element's referrerpolicy attribute. + // 22. Set request's referrer policy to the current state of the element's referrerpolicy attribute. request->set_referrer_policy(ReferrerPolicy::from_string(get_attribute_value(HTML::AttributeNames::referrerpolicy)).value_or(ReferrerPolicy::ReferrerPolicy::EmptyString)); - // 22. Set request's priority to the current state of the element's fetchpriority attribute. + // 23. Set request's priority to the current state of the element's fetchpriority attribute. request->set_priority(Fetch::Infrastructure::request_priority_from_string(get_attribute_value(HTML::AttributeNames::fetchpriority)).value_or(Fetch::Infrastructure::Request::Priority::Auto)); - // 24. If the will lazy load element steps given the img return true, then: + // 25. If the will lazy load element steps given the img return true, then: if (will_lazy_load_element()) { // 1. Set the img's lazy load resumption steps to the rest of this algorithm starting with the step labeled fetch the image. set_lazy_load_resumption_steps([this, request, image_request]() { @@ -769,7 +772,7 @@ after_step_7: })); } -void HTMLImageElement::add_callbacks_to_image_request(GC::Ref image_request, bool maybe_omit_events, URL::URL const& url_string, String const& previous_url) +void HTMLImageElement::add_callbacks_to_image_request(GC::Ref image_request, bool maybe_omit_events, String const& url_string, String const& previous_url) { image_request->add_callbacks( [this, image_request, maybe_omit_events, url_string, previous_url]() { @@ -803,7 +806,7 @@ void HTMLImageElement::add_callbacks_to_image_request(GC::Ref imag layout_node->set_needs_layout_update(DOM::SetNeedsLayoutReason::HTMLImageElementUpdateTheImageData); // 4. If maybe omit events is not set or previousURL is not equal to urlString, then fire an event named load at the img element. - if (!maybe_omit_events || previous_url != url_string.serialize()) + if (!maybe_omit_events || previous_url != url_string) dispatch_event(DOM::Event::create(realm(), HTML::EventNames::load)); if (image_data->is_animated() && image_data->frame_count() > 1) { @@ -832,7 +835,7 @@ void HTMLImageElement::add_callbacks_to_image_request(GC::Ref imag // and then, if maybe omit events is not set or previousURL is not equal to urlString, // queue an element task on the DOM manipulation task source given the img element // to fire an event named error at the img element. - if (!maybe_omit_events || previous_url != url_string.serialize()) + if (!maybe_omit_events || previous_url != url_string) dispatch_event(DOM::Event::create(realm(), HTML::EventNames::error)); m_load_event_delayer.clear(); @@ -883,40 +886,40 @@ void HTMLImageElement::react_to_changes_in_the_environment() if (selected_source == m_last_selected_source && pixel_density == m_current_request->current_pixel_density()) return; - // 6. ⌛ Parse selected source, relative to the element's node document, - // and let urlString be the resulting URL string. If that is not successful, then return. - auto maybe_url = document().parse_url(selected_source.value()); - if (!maybe_url.has_value()) - return; - auto url_string = maybe_url->serialize(); + // 6. ⌛ Let urlString be the result of encoding-parsing-and-serializing a URL given selected source, relative to the element's node document. + auto url_string = document().encoding_parse_and_serialize_url(selected_source.value()); - // 7. ⌛ Let corsAttributeState be the state of the element's crossorigin content attribute. + // 7. ⌛ If urlString is failure, then return. + if (!url_string.has_value()) + return; + + // 8. ⌛ Let corsAttributeState be the state of the element's crossorigin content attribute. auto cors_attribute_state = m_cors_setting; - // 8. ⌛ Let origin be the img element's node document's origin. + // 9. ⌛ Let origin be the img element's node document's origin. auto origin = document().origin(); - // 9. ⌛ Let client be the img element's node document's relevant settings object. + // 10. ⌛ Let client be the img element's node document's relevant settings object. auto& client = document().relevant_settings_object(); - // 10. ⌛ Let key be a tuple consisting of urlString, corsAttributeState, and, if corsAttributeState is not No CORS, origin. + // 11. ⌛ Let key be a tuple consisting of urlString, corsAttributeState, and, if corsAttributeState is not No CORS, origin. ListOfAvailableImages::Key key; - key.url = *maybe_url; + key.url = *url_string; key.mode = m_cors_setting; if (cors_attribute_state != CORSSettingAttribute::NoCORS) key.origin = document().origin(); - // 11. ⌛ Let image request be a new image request whose current URL is urlString + // 12. ⌛ Let image request be a new image request whose current URL is urlString auto image_request = ImageRequest::create(realm(), document().page()); - image_request->set_current_url(realm(), url_string); + image_request->set_current_url(realm(), *url_string); - // 12. ⌛ Set the element's pending request to image request. + // 13. ⌛ Set the element's pending request to image request. m_pending_request = image_request; - // FIXME: 13. End the synchronous section, continuing the remaining steps in parallel. + // FIXME: 14. End the synchronous section, continuing the remaining steps in parallel. - auto step_15 = [this](String const& selected_source, GC::Ref image_request, ListOfAvailableImages::Key const& key, GC::Ref image_data) { - // 15. Queue an element task on the DOM manipulation task source given the img element and the following steps: + auto step_16 = [this](String const& selected_source, GC::Ref image_request, ListOfAvailableImages::Key const& key, GC::Ref image_data) { + // 16. Queue an element task on the DOM manipulation task source given the img element and the following steps: queue_an_element_task(HTML::Task::Source::DOMManipulation, [this, selected_source, image_request, key, image_data] { // 1. FIXME: If the img element has experienced relevant mutations since this algorithm started, then set the pending request to null and abort these steps. // AD-HOC: Check if we have a pending request still, otherwise we will crash when upgrading the request. This will happen if the image has experienced mutations, @@ -949,16 +952,20 @@ void HTMLImageElement::react_to_changes_in_the_environment() }); }; - // 14. If the list of available images contains an entry for key, then set image request's image data to that of the entry. + // 15. If the list of available images contains an entry for key, then set image request's image data to that of the entry. // Continue to the next step. if (auto* entry = document().list_of_available_images().get(key)) { image_request->set_image_data(entry->image_data); - step_15(selected_source.value(), *image_request, key, entry->image_data); + step_16(selected_source.value(), *image_request, key, entry->image_data); } // Otherwise: else { + // AD-HOC: create_potential_CORS_request expects a url, but the following step passes a URL string. + auto url_record = document().encoding_parse_url(selected_source.value()); + VERIFY(url_record.has_value()); + // 1. Let request be the result of creating a potential-CORS request given urlString, "image", and corsAttributeState. - auto request = create_potential_CORS_request(vm(), *maybe_url, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting); + auto request = create_potential_CORS_request(vm(), *url_record, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting); // 2. Set request's client to client, set request's initiator to "imageset", and set request's synchronous flag. request->set_client(&client); @@ -971,7 +978,7 @@ void HTMLImageElement::react_to_changes_in_the_environment() // Set the callbacks to handle steps 6 and 7 before starting the fetch request. image_request->add_callbacks( - [this, step_15, selected_source = selected_source.value(), image_request, key]() mutable { + [this, step_16, selected_source = selected_source.value(), image_request, key]() mutable { // 6. If response's unsafe response is a network error // NOTE: This is handled in the second callback below. @@ -985,13 +992,13 @@ void HTMLImageElement::react_to_changes_in_the_environment() // then set the pending request to null and abort these steps. - batching_dispatcher().enqueue(GC::create_function(realm().heap(), [step_15, selected_source = move(selected_source), image_request, key] { + batching_dispatcher().enqueue(GC::create_function(realm().heap(), [step_16, selected_source = move(selected_source), image_request, key] { // 7. Otherwise, response's unsafe response is image request's image data. It can be either CORS-same-origin // or CORS-cross-origin; this affects the image's interaction with other APIs (e.g., when used on a canvas). VERIFY(image_request->shared_resource_request()); auto image_data = image_request->shared_resource_request()->image_data(); image_request->set_image_data(image_data); - step_15(selected_source, image_request, key, *image_data); + step_16(selected_source, image_request, key, *image_data); })); }, [this]() { diff --git a/Libraries/LibWeb/HTML/HTMLImageElement.h b/Libraries/LibWeb/HTML/HTMLImageElement.h index f9aa3660390..dd62fc0e3ec 100644 --- a/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -136,7 +136,7 @@ private: void handle_successful_fetch(URL::URL const&, StringView mime_type, ImageRequest&, ByteBuffer, bool maybe_omit_events, URL::URL const& previous_url); void handle_failed_fetch(); - void add_callbacks_to_image_request(GC::Ref, bool maybe_omit_events, URL::URL const& url_string, String const& previous_url); + void add_callbacks_to_image_request(GC::Ref, bool maybe_omit_events, String const& url_string, String const& previous_url); void animate(); diff --git a/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index 24a03b83876..2844e9a03ee 100644 --- a/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -642,7 +642,7 @@ WebIDL::ExceptionOr HTMLLinkElement::load_fallback_favicon_if_needed(GC::R // synchronous flag is set, credentials mode is "include", and whose use-URL-credentials flag is set. // NOTE: Fetch requests no longer have a synchronous flag, see https://github.com/whatwg/fetch/pull/1165 auto request = Fetch::Infrastructure::Request::create(vm); - request->set_url(*document->parse_url("/favicon.ico"sv)); + request->set_url(*document->encoding_parse_url("/favicon.ico"sv)); request->set_client(&document->relevant_settings_object()); request->set_destination(Fetch::Infrastructure::Request::Destination::Image); request->set_credentials_mode(Fetch::Infrastructure::Request::CredentialsMode::Include); diff --git a/Libraries/LibWeb/HTML/HTMLMediaElement.cpp b/Libraries/LibWeb/HTML/HTMLMediaElement.cpp index 9590887ae43..22770da6f40 100644 --- a/Libraries/LibWeb/HTML/HTMLMediaElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLMediaElement.cpp @@ -647,29 +647,28 @@ public: return {}; } - // 3. ⌛ Let urlString and urlRecord be the resulting URL string and the resulting URL record, respectively, that - // would have resulted from parsing the URL specified by candidate's src attribute's value relative to the - // candidate's node document when the src attribute was last changed. - auto url_record = m_candidate->document().parse_url(candidate_src); + // FIXME: 3: ⌛ If candidate has a media attribute whose value does not match the environment, + // then end the synchronous section, and jump down to the failed with elements step below. - // 4. ⌛ If urlString was not obtained successfully, then end the synchronous section, and jump down to the failed - // with elements step below. + // 4. ⌛ Let urlRecord be the result of encoding-parsing a URL given candidate's src attribute's value, relative to candidate's node document when the src attribute was last changed. + auto url_record = m_candidate->document().encoding_parse_url(candidate_src); + + // 5. ⌛ If urlRecord is failure, then end the synchronous section, and jump down to the failed with elements step below. if (!url_record.has_value()) { TRY(failed_with_elements()); return {}; } - auto url_string = url_record->to_string(); - // FIXME: 5. ⌛ If candidate has a type attribute whose value, when parsed as a MIME type (including any codecs described + // FIXME: 6. ⌛ If candidate has a type attribute whose value, when parsed as a MIME type (including any codecs described // by the codecs parameter, for types that define that parameter), represents a type that the user agent knows // it cannot render, then end the synchronous section, and jump down to the failed with elements step below. - // 6. ⌛ Set the currentSrc attribute to urlString. - m_media_element->m_current_src = move(url_string); + // 7. ⌛ Set the currentSrc attribute to the result of applying the URL serializer to urlRecord. + m_media_element->m_current_src = url_record->serialize(); - // 7. End the synchronous section, continuing the remaining steps in parallel. + // 8. End the synchronous section, continuing the remaining steps in parallel. - // 8. Run the resource fetch algorithm with urlRecord. If that algorithm returns without aborting this one, then + // 9. Run the resource fetch algorithm with urlRecord. If that algorithm returns without aborting this one, then // the load failed. TRY(m_media_element->fetch_resource(*url_record, [this](auto) { failed_with_elements().release_value_but_fixme_should_propagate_errors(); @@ -895,13 +894,13 @@ WebIDL::ExceptionOr HTMLMediaElement::select_resource() return; } - // 2. ⌛ Let urlString and urlRecord be the resulting URL string and the resulting URL record, respectively, that would have resulted from parsing - // the URL specified by the src attribute's value relative to the media element's node document when the src attribute was last changed. - auto url_record = document().parse_url(source); + // 2. ⌛ Let urlRecord be the result of encoding-parsing a URL given the src attribute's value, + // relative to the media element's node document when the src attribute was last changed. + auto url_record = document().encoding_parse_url(source); - // 3. ⌛ If urlString was obtained successfully, set the currentSrc attribute to urlString. + // 3. ⌛ If urlRecord is not failure, then set the currentSrc attribute to the result of applying the URL serializer to urlRecord. if (url_record.has_value()) - m_current_src = url_record->to_string(); + m_current_src = url_record->serialize(); // 4. End the synchronous section, continuing the remaining steps in parallel. diff --git a/Libraries/LibWeb/HTML/HTMLScriptElement.cpp b/Libraries/LibWeb/HTML/HTMLScriptElement.cpp index 7d232212824..1dca128d53a 100644 --- a/Libraries/LibWeb/HTML/HTMLScriptElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLScriptElement.cpp @@ -387,10 +387,10 @@ void HTMLScriptElement::prepare_script() // 4. Set el's from an external file to true. m_from_an_external_file = true; - // 5. Parse src relative to el's node document. - auto url = document().parse_url(src); + // 5. Let url be the result of encoding-parsing a URL given src, relative to el's node document. + auto url = document().encoding_parse_url(src); - // 6. If the previous step failed, then queue an element task on the DOM manipulation task source given el to fire an event named error at el, and return. Otherwise, let url be the resulting URL record. + // 6. If url is failure, then queue an element task on the DOM manipulation task source given el to fire an event named error at el, and return. if (!url.has_value()) { dbgln("HTMLScriptElement: Refusing to run script because the src URL '{}' is invalid.", url); queue_an_element_task(HTML::Task::Source::DOMManipulation, [this] { diff --git a/Libraries/LibWeb/HTML/HTMLVideoElement.cpp b/Libraries/LibWeb/HTML/HTMLVideoElement.cpp index 977a26ae359..1817ca33567 100644 --- a/Libraries/LibWeb/HTML/HTMLVideoElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLVideoElement.cpp @@ -183,13 +183,14 @@ WebIDL::ExceptionOr HTMLVideoElement::determine_element_poster_frame(Optio if (!poster.has_value() || poster->is_empty()) return {}; - // 3. Parse the poster attribute's value relative to the element's node document. If this fails, then there is no - // poster frame; return. - auto url_record = document().parse_url(*poster); + // 3. Let url be the result of encoding-parsing a URL given the poster attribute's value, relative to the element's node document. + auto url_record = document().encoding_parse_url(*poster); + + // 4. If url is failure, then return. if (!url_record.has_value()) return {}; - // 4. Let request be a new request whose URL is the resulting URL record, client is the element's node document's + // 5. Let request be a new request whose URL is the resulting URL record, client is the element's node document's // relevant settings object, destination is "image", initiator type is "video", credentials mode is "include", // and whose use-URL-credentials flag is set. auto request = Fetch::Infrastructure::Request::create(vm); @@ -200,10 +201,11 @@ WebIDL::ExceptionOr HTMLVideoElement::determine_element_poster_frame(Optio request->set_credentials_mode(Fetch::Infrastructure::Request::CredentialsMode::Include); request->set_use_url_credentials(true); - // 5. Fetch request. This must delay the load event of the element's node document. + // 6. Fetch request. This must delay the load event of the element's node document. Fetch::Infrastructure::FetchAlgorithms::Input fetch_algorithms_input {}; m_load_event_delayer.emplace(document()); + // 7. If an image is thus obtained, the poster frame is that image. Otherwise, there is no poster frame. fetch_algorithms_input.process_response = [this](auto response) mutable { ScopeGuard guard { [&] { m_load_event_delayer.clear(); } }; diff --git a/Libraries/LibWeb/HTML/ListOfAvailableImages.cpp b/Libraries/LibWeb/HTML/ListOfAvailableImages.cpp index a5fcbe92339..04e61b422fe 100644 --- a/Libraries/LibWeb/HTML/ListOfAvailableImages.cpp +++ b/Libraries/LibWeb/HTML/ListOfAvailableImages.cpp @@ -22,7 +22,7 @@ bool ListOfAvailableImages::Key::operator==(Key const& other) const u32 ListOfAvailableImages::Key::hash() const { if (!cached_hash.has_value()) { - u32 url_hash = Traits::hash(url); + u32 url_hash = url.hash(); u32 mode_hash = static_cast(mode); u32 origin_hash = 0; if (origin.has_value()) diff --git a/Libraries/LibWeb/HTML/ListOfAvailableImages.h b/Libraries/LibWeb/HTML/ListOfAvailableImages.h index 775ba2d1928..ae2548e81b7 100644 --- a/Libraries/LibWeb/HTML/ListOfAvailableImages.h +++ b/Libraries/LibWeb/HTML/ListOfAvailableImages.h @@ -22,7 +22,7 @@ class ListOfAvailableImages : public JS::Cell { public: struct Key { - URL::URL url; + String url; HTML::CORSSettingAttribute mode; Optional origin; diff --git a/Libraries/LibWeb/HTML/NavigableContainer.cpp b/Libraries/LibWeb/HTML/NavigableContainer.cpp index ef55557df12..dad1bf3bc2e 100644 --- a/Libraries/LibWeb/HTML/NavigableContainer.cpp +++ b/Libraries/LibWeb/HTML/NavigableContainer.cpp @@ -209,14 +209,15 @@ Optional NavigableContainer::shared_attribute_processing_steps_for_ifr // 1. Let url be the URL record about:blank. auto url = URL::about_blank(); - // 2. If element has a src attribute specified, and its value is not the empty string, - // then parse the value of that attribute relative to element's node document. - // If this is successful, then set url to the resulting URL record. + // 2. If element has a src attribute specified, and its value is not the empty string, then: auto src_attribute_value = get_attribute_value(HTML::AttributeNames::src); if (!src_attribute_value.is_empty()) { - auto parsed_src = document().parse_url(src_attribute_value); - if (parsed_src.has_value()) - url = parsed_src.release_value(); + // 1. Let maybeURL be the result of encoding-parsing a URL given that attribute's value, relative to element's node document. + auto maybe_url = document().encoding_parse_url(src_attribute_value); + + // 2. If maybeURL is not failure, then set url to maybeURL. + if (maybe_url.has_value()) + url = maybe_url.release_value(); } // 3. If the inclusive ancestor navigables of element's node navigable contains a navigable diff --git a/Libraries/LibWeb/SVG/SVGImageElement.cpp b/Libraries/LibWeb/SVG/SVGImageElement.cpp index e32a9c1a4c6..9262beb38cd 100644 --- a/Libraries/LibWeb/SVG/SVGImageElement.cpp +++ b/Libraries/LibWeb/SVG/SVGImageElement.cpp @@ -146,7 +146,7 @@ void SVGImageElement::process_the_url(Optional const& href) return; } - m_href = document().parse_url(*href); + m_href = document().encoding_parse_url(*href); if (!m_href.has_value()) return; diff --git a/Libraries/LibWeb/SVG/SVGScriptElement.cpp b/Libraries/LibWeb/SVG/SVGScriptElement.cpp index 60616e51b43..188129d1509 100644 --- a/Libraries/LibWeb/SVG/SVGScriptElement.cpp +++ b/Libraries/LibWeb/SVG/SVGScriptElement.cpp @@ -92,7 +92,7 @@ void SVGScriptElement::process_the_script_element() if (has_attribute(SVG::AttributeNames::href) || has_attribute_ns(Namespace::XLink.to_string(), SVG::AttributeNames::href)) { auto href_value = href()->base_val(); - auto maybe_script_url = document().parse_url(href_value); + auto maybe_script_url = document().encoding_parse_url(href_value); if (!maybe_script_url.has_value()) { dbgln("Invalid script URL: {}", href_value); return;