diff --git a/Tests/LibWeb/Text/expected/URL/strip_trailing_spaces_from_opaque_path.txt b/Tests/LibWeb/Text/expected/URL/strip_trailing_spaces_from_opaque_path.txt
new file mode 100644
index 0000000000..817503998b
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/URL/strip_trailing_spaces_from_opaque_path.txt
@@ -0,0 +1,4 @@
+pathname => 'foobar '
+pathname => 'foobar'
+pathname => 'baz '
+pathname => 'baz'
diff --git a/Tests/LibWeb/Text/input/URL/strip_trailing_spaces_from_opaque_path.html b/Tests/LibWeb/Text/input/URL/strip_trailing_spaces_from_opaque_path.html
new file mode 100644
index 0000000000..c8c4dce742
--- /dev/null
+++ b/Tests/LibWeb/Text/input/URL/strip_trailing_spaces_from_opaque_path.html
@@ -0,0 +1,14 @@
+
+
diff --git a/Userland/Libraries/LibWeb/URL/URL.cpp b/Userland/Libraries/LibWeb/URL/URL.cpp
index f4961ae02d..c03ae086f6 100644
--- a/Userland/Libraries/LibWeb/URL/URL.cpp
+++ b/Userland/Libraries/LibWeb/URL/URL.cpp
@@ -403,7 +403,8 @@ WebIDL::ExceptionOr URL::set_search(String const& search)
// 2. Empty this’s query object’s list.
m_query->m_list.clear();
- // FIXME: 3. Potentially strip trailing spaces from an opaque path with this.
+ // 3. Potentially strip trailing spaces from an opaque path with this.
+ strip_trailing_spaces_from_an_opaque_path(*this);
// 4. Return.
return {};
@@ -457,7 +458,8 @@ void URL::set_hash(String const& hash)
// 1. Set this’s URL’s fragment to null.
m_url.set_fragment({});
- // FIXME: 2. Potentially strip trailing spaces from an opaque path with this.
+ // 2. Potentially strip trailing spaces from an opaque path with this.
+ strip_trailing_spaces_from_an_opaque_path(*this);
// 3. Return.
return;
@@ -535,6 +537,29 @@ bool host_is_domain(AK::URL::Host const& host)
return host.has() && host.get() != String {};
}
+// https://url.spec.whatwg.org/#potentially-strip-trailing-spaces-from-an-opaque-path
+void strip_trailing_spaces_from_an_opaque_path(URL& url)
+{
+ // 1. If url’s URL does not have an opaque path, then return.
+ // FIXME: Reimplement this step once we modernize the URL implementation to meet the spec.
+ if (!url.cannot_be_a_base_url())
+ return;
+
+ // 2. If url’s URL’s fragment is non-null, then return.
+ if (url.fragment().has_value())
+ return;
+
+ // 3. If url’s URL’s query is non-null, then return.
+ if (url.query().has_value())
+ return;
+
+ // 4. Remove all trailing U+0020 SPACE code points from url’s URL’s path.
+ // NOTE: At index 0 since the first step tells us that the URL only has one path segment.
+ auto opaque_path = url.path_segment_at_index(0);
+ auto trimmed_path = opaque_path.trim(" "sv, TrimMode::Right);
+ url.set_paths({ trimmed_path });
+}
+
// https://url.spec.whatwg.org/#concept-url-parser
AK::URL parse(StringView input, Optional const& base_url)
{
diff --git a/Userland/Libraries/LibWeb/URL/URL.h b/Userland/Libraries/LibWeb/URL/URL.h
index ca67ebc0d5..e3fd2f2e52 100644
--- a/Userland/Libraries/LibWeb/URL/URL.h
+++ b/Userland/Libraries/LibWeb/URL/URL.h
@@ -55,6 +55,15 @@ public:
WebIDL::ExceptionOr pathname() const;
void set_pathname(String const&);
+ Optional const& fragment() const { return m_url.fragment(); }
+
+ DeprecatedString path_segment_at_index(size_t index) const { return m_url.path_segment_at_index(index); }
+
+ void set_paths(Vector const& paths) { return m_url.set_paths(paths); }
+
+ // FIXME: Reimplement this to meet the definition in https://url.spec.whatwg.org/#url-opaque-path once we modernize URL to meet the spec.
+ bool cannot_be_a_base_url() const { return m_url.cannot_be_a_base_url(); }
+
WebIDL::ExceptionOr search() const;
WebIDL::ExceptionOr set_search(String const&);
@@ -65,6 +74,7 @@ public:
WebIDL::ExceptionOr to_json() const;
+ Optional const& query() const { return m_url.query(); }
void set_query(Badge, Optional query) { m_url.set_query(move(query)); }
private:
@@ -80,6 +90,9 @@ private:
HTML::Origin url_origin(AK::URL const&);
bool host_is_domain(AK::URL::Host const&);
+// https://url.spec.whatwg.org/#potentially-strip-trailing-spaces-from-an-opaque-path
+void strip_trailing_spaces_from_an_opaque_path(URL& url);
+
// https://url.spec.whatwg.org/#concept-url-parser
AK::URL parse(StringView input, Optional const& base_url = {});