Browse Source

AK: Port URL::m_fragment from DeprecatedString to String

Shannon Booth 2 years ago
parent
commit
9d60f23abc

+ 8 - 16
AK/URL.cpp

@@ -62,11 +62,6 @@ DeprecatedString URL::basename() const
     return percent_decode(last_segment);
 }
 
-DeprecatedString URL::fragment() const
-{
-    return m_fragment;
-}
-
 // NOTE: This only exists for compatibility with the existing URL tests which check for both .is_null() and .is_empty().
 static DeprecatedString deprecated_string_percent_encode(DeprecatedString const& input, URL::PercentEncodeSet set = URL::PercentEncodeSet::Userinfo, URL::SpaceAsPlus space_as_plus = URL::SpaceAsPlus::No)
 {
@@ -135,11 +130,6 @@ void URL::append_path(StringView path)
     m_paths.append(deprecated_string_percent_encode(path, PercentEncodeSet::Path));
 }
 
-void URL::set_fragment(StringView fragment)
-{
-    m_fragment = fragment;
-}
-
 // https://url.spec.whatwg.org/#cannot-have-a-username-password-port
 bool URL::cannot_have_a_username_or_password_or_port() const
 {
@@ -215,7 +205,8 @@ URL URL::create_with_file_scheme(DeprecatedString const& path, DeprecatedString
     url.set_paths(lexical_path.parts());
     if (path.ends_with('/'))
         url.append_slash();
-    url.set_fragment(fragment);
+    if (!fragment.is_null())
+        url.set_fragment(String::from_deprecated_string(fragment).release_value_but_fixme_should_propagate_errors());
     return url;
 }
 
@@ -232,7 +223,8 @@ URL URL::create_with_help_scheme(DeprecatedString const& path, DeprecatedString
     url.set_paths(lexical_path.parts());
     if (path.ends_with('/'))
         url.append_slash();
-    url.set_fragment(fragment);
+    if (!fragment.is_null())
+        url.set_fragment(String::from_deprecated_string(fragment).release_value_but_fixme_should_propagate_errors());
     return url;
 }
 
@@ -337,9 +329,9 @@ DeprecatedString URL::serialize(ExcludeFragment exclude_fragment) const
     }
 
     // 6. If exclude fragment is false and url’s fragment is non-null, then append U+0023 (#), followed by url’s fragment, to output.
-    if (exclude_fragment == ExcludeFragment::No && !m_fragment.is_null()) {
+    if (exclude_fragment == ExcludeFragment::No && m_fragment.has_value()) {
         output.append('#');
-        output.append(m_fragment);
+        output.append(*m_fragment);
     }
 
     // 7. Return output.
@@ -381,9 +373,9 @@ DeprecatedString URL::serialize_for_display() const
         builder.append(*m_query);
     }
 
-    if (!m_fragment.is_null()) {
+    if (m_fragment.has_value()) {
         builder.append('#');
-        builder.append(m_fragment);
+        builder.append(*m_fragment);
     }
 
     return builder.to_deprecated_string();

+ 3 - 3
AK/URL.h

@@ -83,7 +83,7 @@ public:
     ErrorOr<String> serialized_host() const;
     DeprecatedString basename() const;
     Optional<String> const& query() const { return m_query; }
-    DeprecatedString fragment() const;
+    Optional<String> const& fragment() const { return m_fragment; }
     Optional<u16> port() const { return m_port; }
     DeprecatedString path_segment_at_index(size_t index) const;
     size_t path_segment_count() const { return m_paths.size(); }
@@ -102,7 +102,7 @@ public:
     void set_port(Optional<u16>);
     void set_paths(Vector<DeprecatedString> const&);
     void set_query(Optional<String> query) { m_query = move(query); }
-    void set_fragment(StringView fragment);
+    void set_fragment(Optional<String> fragment) { m_fragment = move(fragment); }
     void set_cannot_be_a_base_url(bool value) { m_cannot_be_a_base_url = value; }
     void append_path(StringView);
     void append_slash()
@@ -183,7 +183,7 @@ private:
     Optional<String> m_query;
 
     // A URL’s fragment is either null or an ASCII string that can be used for further processing on the resource the URL’s other components identify. It is initially null.
-    DeprecatedString m_fragment;
+    Optional<String> m_fragment;
 
     bool m_cannot_be_a_base_url { false };
 };

+ 8 - 8
AK/URLParser.cpp

@@ -924,7 +924,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
                 url->m_scheme = base_url->m_scheme;
                 url->m_paths = base_url->m_paths;
                 url->m_query = base_url->m_query;
-                url->m_fragment = "";
+                url->m_fragment = String {};
                 url->m_cannot_be_a_base_url = true;
                 state = State::Fragment;
             }
@@ -999,7 +999,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
                 }
                 // 3. Otherwise, if c is U+0023 (#), set url’s fragment to the empty string and state to fragment state.
                 else if (code_point == '#') {
-                    url->m_fragment = "";
+                    url->m_fragment = String {};
                     state = State::Fragment;
                 }
                 // 4. Otherwise, if c is not the EOF code point:
@@ -1309,7 +1309,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
                 }
                 // 3. Otherwise, if c is U+0023 (#), set url’s fragment to the empty string and state to fragment state.
                 else if (code_point == '#') {
-                    url->m_fragment = "";
+                    url->m_fragment = String {};
                     state = State::Fragment;
                 }
                 // 4. Otherwise, if c is not the EOF code point:
@@ -1450,7 +1450,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
             }
             // 3. Otherwise, if state override is not given and c is U+0023 (#), set url’s fragment to the empty string and state to fragment state.
             else if (!state_override.has_value() && code_point == '#') {
-                url->m_fragment = "";
+                url->m_fragment = String {};
                 state = State::Fragment;
             }
             // 4. Otherwise, if c is not the EOF code point:
@@ -1519,7 +1519,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
                 }
                 // 7. If c is U+0023 (#), then set url’s fragment to the empty string and state to fragment state.
                 else if (code_point == '#') {
-                    url->m_fragment = "";
+                    url->m_fragment = String {};
                     state = State::Fragment;
                 }
             }
@@ -1551,7 +1551,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
             else if (code_point == '#') {
                 // NOTE: This needs to be percent decoded since the member variables contain decoded data.
                 url->m_paths[0] = buffer.string_view();
-                url->m_fragment = "";
+                url->m_fragment = String {};
                 buffer.clear();
                 state = State::Fragment;
             }
@@ -1597,7 +1597,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
 
                 // 4. If c is U+0023 (#), then set url’s fragment to the empty string and state to fragment state.
                 if (code_point == '#') {
-                    url->m_fragment = "";
+                    url->m_fragment = String {};
                     state = State::Fragment;
                 }
             }
@@ -1627,7 +1627,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
                 // FIXME: 3. UTF-8 percent-encode c using the fragment percent-encode set and append the result to url’s fragment.
                 buffer.append_code_point(code_point);
             } else {
-                url->m_fragment = buffer.string_view();
+                url->m_fragment = buffer.to_string().release_value_but_fixme_should_propagate_errors();
                 buffer.clear();
             }
             break;

+ 12 - 12
Tests/AK/TestURL.cpp

@@ -25,7 +25,7 @@ TEST_CASE(basic)
         EXPECT_EQ(url.port_or_default(), 80);
         EXPECT_EQ(url.serialize_path(), "/");
         EXPECT(!url.query().has_value());
-        EXPECT(url.fragment().is_null());
+        EXPECT(!url.fragment().has_value());
     }
     {
         URL url("https://www.serenityos.org/index.html"sv);
@@ -35,7 +35,7 @@ TEST_CASE(basic)
         EXPECT_EQ(url.port_or_default(), 443);
         EXPECT_EQ(url.serialize_path(), "/index.html");
         EXPECT(!url.query().has_value());
-        EXPECT(url.fragment().is_null());
+        EXPECT(!url.fragment().has_value());
     }
     {
         URL url("https://www.serenityos.org1/index.html"sv);
@@ -45,7 +45,7 @@ TEST_CASE(basic)
         EXPECT_EQ(url.port_or_default(), 443);
         EXPECT_EQ(url.serialize_path(), "/index.html");
         EXPECT(!url.query().has_value());
-        EXPECT(url.fragment().is_null());
+        EXPECT(!url.fragment().has_value());
     }
     {
         URL url("https://localhost:1234/~anon/test/page.html"sv);
@@ -55,7 +55,7 @@ TEST_CASE(basic)
         EXPECT_EQ(url.port_or_default(), 1234);
         EXPECT_EQ(url.serialize_path(), "/~anon/test/page.html");
         EXPECT(!url.query().has_value());
-        EXPECT(url.fragment().is_null());
+        EXPECT(!url.fragment().has_value());
     }
     {
         URL url("http://www.serenityos.org/index.html?#"sv);
@@ -75,7 +75,7 @@ TEST_CASE(basic)
         EXPECT_EQ(url.port_or_default(), 80);
         EXPECT_EQ(url.serialize_path(), "/index.html");
         EXPECT_EQ(url.query(), "foo=1&bar=2");
-        EXPECT(url.fragment().is_null());
+        EXPECT(!url.fragment().has_value());
     }
     {
         URL url("http://www.serenityos.org/index.html#fragment"sv);
@@ -131,7 +131,7 @@ TEST_CASE(file_url_with_hostname)
     EXPECT_EQ(url.serialize_path(), "/my/file");
     EXPECT_EQ(url.serialize(), "file://courage/my/file");
     EXPECT(!url.query().has_value());
-    EXPECT(url.fragment().is_null());
+    EXPECT(!url.fragment().has_value());
 }
 
 TEST_CASE(file_url_with_localhost)
@@ -161,7 +161,7 @@ TEST_CASE(file_url_with_encoded_characters)
     EXPECT_EQ(url.scheme(), "file");
     EXPECT_EQ(url.serialize_path(), "/my/file/test#file.txt");
     EXPECT(!url.query().has_value());
-    EXPECT(url.fragment().is_null());
+    EXPECT(!url.fragment().has_value());
 }
 
 TEST_CASE(file_url_with_fragment)
@@ -206,7 +206,7 @@ TEST_CASE(about_url)
     EXPECT(url.host().has<Empty>());
     EXPECT_EQ(url.serialize_path(), "blank");
     EXPECT(!url.query().has_value());
-    EXPECT(url.fragment().is_null());
+    EXPECT(!url.fragment().has_value());
     EXPECT_EQ(url.serialize(), "about:blank");
 }
 
@@ -220,7 +220,7 @@ TEST_CASE(mailto_url)
     EXPECT_EQ(url.path_segment_count(), 1u);
     EXPECT_EQ(url.path_segment_at_index(0), "mail@example.com");
     EXPECT(!url.query().has_value());
-    EXPECT(url.fragment().is_null());
+    EXPECT(!url.fragment().has_value());
     EXPECT_EQ(url.serialize(), "mailto:mail@example.com");
 }
 
@@ -234,7 +234,7 @@ TEST_CASE(mailto_url_with_subject)
     EXPECT_EQ(url.path_segment_count(), 1u);
     EXPECT_EQ(url.path_segment_at_index(0), "mail@example.com");
     EXPECT_EQ(url.query(), "subject=test");
-    EXPECT(url.fragment().is_null());
+    EXPECT(!url.fragment().has_value());
     EXPECT_EQ(url.serialize(), "mailto:mail@example.com?subject=test");
 }
 
@@ -380,7 +380,7 @@ TEST_CASE(create_with_file_scheme)
     EXPECT_EQ(url.path_segment_at_index(2), "README.md");
     EXPECT_EQ(url.serialize_path(), "/home/anon/README.md");
     EXPECT(!url.query().has_value());
-    EXPECT(url.fragment().is_null());
+    EXPECT(!url.fragment().has_value());
 
     url = URL::create_with_file_scheme("/home/anon/");
     EXPECT(url.is_valid());
@@ -435,7 +435,7 @@ TEST_CASE(unicode)
     EXPECT(url.is_valid());
     EXPECT_EQ(url.serialize_path(), "/_ünicöde_téxt_©");
     EXPECT(!url.query().has_value());
-    EXPECT(url.fragment().is_null());
+    EXPECT(!url.fragment().has_value());
 }
 
 TEST_CASE(complete_file_url_with_base)

+ 1 - 1
Userland/Applications/Spreadsheet/HelpWindow.cpp

@@ -93,7 +93,7 @@ HelpWindow::HelpWindow(GUI::Window* parent)
                 return;
             }
             auto& doc = doc_option.value();
-            auto name = url.fragment();
+            auto name = url.fragment().value_or(String {});
 
             auto maybe_example_data = doc.get_object("example_data"sv);
             if (!maybe_example_data.has_value()) {

+ 2 - 2
Userland/Applications/Spreadsheet/Spreadsheet.cpp

@@ -271,7 +271,7 @@ Optional<Position> Sheet::position_from_url(const URL& url) const
     // FIXME: Figure out a way to do this cross-process.
     VERIFY(url.serialize_path() == DeprecatedString::formatted("/{}", getpid()));
 
-    return parse_cell_name(url.fragment());
+    return parse_cell_name(url.fragment().value_or(String {}));
 }
 
 Position Sheet::offset_relative_to(Position const& base, Position const& offset, Position const& offset_base) const
@@ -757,7 +757,7 @@ URL Position::to_url(Sheet const& sheet) const
     url.set_scheme("spreadsheet"_string);
     url.set_host("cell"_string);
     url.set_paths({ DeprecatedString::number(getpid()) });
-    url.set_fragment(to_cell_identifier(sheet));
+    url.set_fragment(String::from_deprecated_string(to_cell_identifier(sheet)).release_value());
     return url;
 }
 

+ 4 - 2
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -1737,14 +1737,16 @@ Document::IndicatedPart Document::determine_the_indicated_part() const
     // For an HTML document document, the following processing model must be followed to determine its indicated part:
 
     // 1. Let fragment be document's URL's fragment.
-    auto fragment = url().fragment();
+    VERIFY(url().fragment().has_value());
+
+    auto fragment = url().fragment().value();
 
     // 2. If fragment is the empty string, then return the special value top of the document.
     if (fragment.is_empty())
         return Document::TopOfTheDocument {};
 
     // 3. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment.
-    auto potential_indicated_element = find_a_potential_indicated_element(fragment);
+    auto* potential_indicated_element = find_a_potential_indicated_element(fragment.to_deprecated_string());
 
     // 4. If potentialIndicatedElement is not null, then return potentialIndicatedElement.
     if (potential_indicated_element)

+ 1 - 3
Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp

@@ -1077,9 +1077,7 @@ WebIDL::ExceptionOr<Optional<JS::NonnullGCPtr<PendingResponse>>> http_redirect_f
         : static_cast<Infrastructure::FilteredResponse const&>(response).internal_response();
 
     // 3. Let locationURL be actualResponse’s location URL given request’s current URL’s fragment.
-    auto const& fragment = request->current_url().fragment();
-    auto fragment_string = fragment.is_null() ? Optional<String> {} : TRY_OR_THROW_OOM(vm, String::from_deprecated_string(fragment));
-    auto location_url_or_error = actual_response->location_url(fragment_string);
+    auto location_url_or_error = actual_response->location_url(request->current_url().fragment());
 
     // 4. If locationURL is null, then return response.
     if (!location_url_or_error.is_error() && !location_url_or_error.value().has_value())

+ 2 - 2
Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp

@@ -118,8 +118,8 @@ ErrorOr<Optional<AK::URL>> Response::location_url(Optional<String> const& reques
         return Error::from_string_view("Invalid 'Location' header URL"sv);
 
     // 4. If location is a URL whose fragment is null, then set location’s fragment to requestFragment.
-    if (location.fragment().is_null())
-        location.set_fragment(request_fragment.has_value() ? request_fragment->to_deprecated_string() : DeprecatedString {});
+    if (!location.fragment().has_value())
+        location.set_fragment(request_fragment);
 
     // 5. Return location.
     return location;

+ 2 - 2
Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp

@@ -1167,7 +1167,7 @@ WebIDL::ExceptionOr<void> BrowsingContext::navigate(
     //    and resource's URL's fragment is non-null, then:
     if (history_handling != HistoryHandlingBehavior::Reload
         && resource->url().equals(active_document()->url(), AK::URL::ExcludeFragment::Yes)
-        && !resource->url().fragment().is_null()) {
+        && resource->url().fragment().has_value()) {
         // 1. Navigate to a fragment given browsingContext, resource's URL, historyHandling, and navigationId.
         TRY(navigate_to_a_fragment(resource->url(), history_handling, *navigation_id));
 
@@ -1406,7 +1406,7 @@ WebIDL::ExceptionOr<void> BrowsingContext::traverse_the_history(size_t entry_ind
     }
 
     // 10. If entry's persisted user state is null, and its URL's fragment is non-null, then scroll to the fragment.
-    if (!entry->url.fragment().is_null())
+    if (entry->url.fragment().has_value())
         active_document()->scroll_to_the_fragment();
 
     // 11. Set the current entry to entry.

+ 3 - 3
Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp

@@ -378,11 +378,11 @@ DeprecatedString HTMLHyperlinkElementUtils::hash() const
     // 2. Let url be this element's url.
 
     // 3. If url is null, or url's fragment is either null or the empty string, return the empty string.
-    if (!m_url.has_value() || m_url->fragment().is_null() || m_url->fragment().is_empty())
+    if (!m_url.has_value() || !m_url->fragment().has_value() || m_url->fragment()->is_empty())
         return DeprecatedString::empty();
 
     // 4. Return "#", followed by url's fragment.
-    return DeprecatedString::formatted("#{}", m_url->fragment());
+    return DeprecatedString::formatted("#{}", *m_url->fragment());
 }
 
 void HTMLHyperlinkElementUtils::set_hash(DeprecatedString hash)
@@ -406,7 +406,7 @@ void HTMLHyperlinkElementUtils::set_hash(DeprecatedString hash)
 
         //    2. Set url's fragment to the empty string.
         auto url_copy = m_url; // We copy the URL here to follow other browser's behavior of reverting the hash change if the parse failed.
-        url_copy->set_fragment(DeprecatedString::empty());
+        url_copy->set_fragment(String {});
 
         //    3. Basic URL parse input, with url as url and fragment state as state override.
         auto result_url = URLParser::basic_parse(input, {}, move(url_copy), URLParser::State::Fragment);

+ 3 - 3
Userland/Libraries/LibWeb/HTML/Location.cpp

@@ -279,11 +279,11 @@ WebIDL::ExceptionOr<String> Location::hash() const
     auto url = this->url();
 
     // 2. If this's url's fragment is either null or the empty string, return the empty string.
-    if (url.fragment().is_empty())
+    if (!url.fragment().has_value() || url.fragment()->is_empty())
         return String {};
 
     // 3. Return "#", followed by this's url's fragment.
-    return TRY_OR_THROW_OOM(vm, String::formatted("#{}", url.fragment()));
+    return TRY_OR_THROW_OOM(vm, String::formatted("#{}", *url.fragment()));
 }
 
 // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-location-hash
@@ -307,7 +307,7 @@ WebIDL::ExceptionOr<void> Location::set_hash(String const& value)
     auto input = value.bytes_as_string_view().trim("#"sv, TrimMode::Left);
 
     // 5. Set copyURL's fragment to the empty string.
-    copy_url.set_fragment(""sv);
+    copy_url.set_fragment(String {});
 
     // 6. Basic URL parse input, with copyURL as url and fragment state as state override.
     auto result_url = URLParser::basic_parse(input, {}, copy_url, URLParser::State::Fragment);

+ 2 - 4
Userland/Libraries/LibWeb/HTML/Navigable.cpp

@@ -543,9 +543,7 @@ static WebIDL::ExceptionOr<Optional<NavigationParams>> create_navigation_params_
         response_origin = determine_the_origin(*response->url(), final_sandbox_flags, entry->document_state->initiator_origin(), {});
 
         // 14. Set locationURL to response's location URL given currentURL's fragment.
-        auto const& fragment = current_url.fragment();
-        auto fragment_string = fragment.is_null() ? Optional<String> {} : TRY_OR_THROW_OOM(vm, String::from_deprecated_string(fragment));
-        auto location_url = response->location_url(fragment_string);
+        auto location_url = response->location_url(current_url.fragment());
 
         VERIFY(!location_url.is_error());
 
@@ -844,7 +842,7 @@ WebIDL::ExceptionOr<void> Navigable::navigate(
     if (document_resource.has<Empty>()
         && !response
         && url.equals(active_session_history_entry()->url, AK::URL::ExcludeFragment::Yes)
-        && !url.fragment().is_null()) {
+        && url.fragment().has_value()) {
         // 1. Navigate to a fragment given navigable, url, historyHandling, and navigationId.
         TRY(navigate_to_a_fragment(url, history_handling, navigation_id));
 

+ 2 - 2
Userland/Libraries/LibWeb/HTML/WorkerLocation.cpp

@@ -123,11 +123,11 @@ WebIDL::ExceptionOr<String> WorkerLocation::hash() const
     auto const& fragment = m_global_scope->url().fragment();
 
     // 2. If fragment is either null or the empty string, return the empty string.
-    if (fragment.is_empty())
+    if (!fragment.has_value() || fragment->is_empty())
         return String {};
 
     // 3. Return "#", followed by fragment.
-    return TRY_OR_THROW_OOM(vm, String::formatted("#{}", fragment.view()));
+    return TRY_OR_THROW_OOM(vm, String::formatted("#{}", *fragment));
 }
 
 WorkerLocation::WorkerLocation(WorkerGlobalScope& global_scope)

+ 2 - 2
Userland/Libraries/LibWeb/Loader/FrameLoader.cpp

@@ -302,8 +302,8 @@ void FrameLoader::resource_did_load()
         return;
     }
 
-    if (!url.fragment().is_empty())
-        browsing_context().scroll_to_anchor(url.fragment());
+    if (url.fragment().has_value() && !url.fragment()->is_empty())
+        browsing_context().scroll_to_anchor(url.fragment()->to_deprecated_string());
     else
         browsing_context().scroll_to({ 0, 0 });
 

+ 2 - 2
Userland/Libraries/LibWeb/Page/EventHandler.cpp

@@ -284,8 +284,8 @@ bool EventHandler::handle_mouseup(CSSPixelPoint position, unsigned button, unsig
                     if (button == GUI::MouseButton::Primary) {
                         if (href.starts_with("javascript:"sv)) {
                             document->navigate_to_javascript_url(href);
-                        } else if (!url.fragment().is_null() && url.equals(document->url(), AK::URL::ExcludeFragment::Yes)) {
-                            m_browsing_context->scroll_to_anchor(url.fragment());
+                        } else if (url.fragment().has_value() && url.equals(document->url(), AK::URL::ExcludeFragment::Yes)) {
+                            m_browsing_context->scroll_to_anchor(url.fragment()->to_deprecated_string());
                         } else {
                             if (m_browsing_context->is_top_level()) {
                                 if (auto* page = m_browsing_context->page())

+ 2 - 2
Userland/Libraries/LibWeb/SVG/SVGGradientElement.cpp

@@ -87,9 +87,9 @@ JS::GCPtr<SVGGradientElement const> SVGGradientElement::linked_gradient() const
     if (auto href = link; !href.is_empty()) {
         auto url = document().parse_url(href);
         auto id = url.fragment();
-        if (id.is_empty())
+        if (!id.has_value() || id->is_empty())
             return {};
-        auto element = document().get_element_by_id(id);
+        auto element = document().get_element_by_id(id->to_deprecated_string());
         if (!element)
             return {};
         if (!is<SVGGradientElement>(*element))

+ 4 - 2
Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp

@@ -46,8 +46,10 @@ Optional<Gfx::PaintStyle const&> SVGGraphicsElement::svg_paint_computed_value_to
     // FIXME: This entire function is an ad-hoc hack:
     if (!paint_value.has_value() || !paint_value->is_url())
         return {};
-    auto& url = paint_value->as_url();
-    auto gradient = document().get_element_by_id(url.fragment());
+    auto const& url = paint_value->as_url();
+    if (!url.fragment().has_value())
+        return {};
+    auto gradient = document().get_element_by_id(url.fragment()->to_deprecated_string());
     if (!gradient)
         return {};
     if (is<SVG::SVGGradientElement>(*gradient))

+ 2 - 2
Userland/Libraries/LibWeb/URL/URL.cpp

@@ -442,7 +442,7 @@ WebIDL::ExceptionOr<String> URL::hash() const
     auto& vm = realm().vm();
 
     // 1. If this’s URL’s fragment is either null or the empty string, then return the empty string.
-    if (m_url.fragment().is_null() || m_url.fragment().is_empty())
+    if (!m_url.fragment().has_value() || m_url.fragment()->is_empty())
         return String {};
 
     // 2. Return U+0023 (#), followed by this’s URL’s fragment.
@@ -469,7 +469,7 @@ void URL::set_hash(String const& hash)
 
     // 3. Set this’s URL’s fragment to the empty string.
     auto url = m_url; // We copy the URL here to follow other browser's behavior of reverting the hash change if the parse failed.
-    url.set_fragment(DeprecatedString::empty());
+    url.set_fragment(String {});
 
     // 4. Basic URL parse input with this’s URL as url and fragment state as state override.
     auto result_url = URLParser::basic_parse(input, {}, move(url), URLParser::State::Fragment);

+ 1 - 1
Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp

@@ -79,7 +79,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> WebSocket::construct_impl(JS::R
         return WebIDL::SyntaxError::create(realm, "Invalid protocol"sv);
 
     // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" DOMException.
-    if (!url_record.fragment().is_empty())
+    if (url_record.fragment().has_value())
         return WebIDL::SyntaxError::create(realm, "Presence of URL fragment is invalid"sv);
 
     Vector<String> protocols_sequence;

+ 2 - 2
Userland/Services/LaunchServer/Launcher.cpp

@@ -357,12 +357,12 @@ bool Launcher::open_file_url(const URL& url)
 
     if (S_ISDIR(st.st_mode)) {
         Vector<DeprecatedString> fm_arguments;
-        if (url.fragment().is_empty()) {
+        if (!url.fragment().has_value() || url.fragment()->is_empty()) {
             fm_arguments.append(file_path);
         } else {
             fm_arguments.append("-s");
             fm_arguments.append("-r");
-            fm_arguments.append(DeprecatedString::formatted("{}/{}", file_path, url.fragment()));
+            fm_arguments.append(DeprecatedString::formatted("{}/{}", file_path, *url.fragment()));
         }
 
         auto handler_optional = m_file_handlers.get("directory");