AK: Port URL::m_query from DeprecatedString to String

This commit is contained in:
Shannon Booth 2023-08-12 19:28:19 +12:00 committed by Andrew Kaster
parent 55a01e72ca
commit 21fe86d235
Notes: sideshowbarker 2024-07-17 02:55:44 +09:00
14 changed files with 63 additions and 75 deletions

View File

@ -62,11 +62,6 @@ DeprecatedString URL::basename() const
return percent_decode(last_segment); return percent_decode(last_segment);
} }
DeprecatedString URL::query() const
{
return m_query;
}
DeprecatedString URL::fragment() const DeprecatedString URL::fragment() const
{ {
return percent_decode(m_fragment); return percent_decode(m_fragment);
@ -145,11 +140,6 @@ void URL::append_path(StringView path)
m_paths.append(deprecated_string_percent_encode(path, PercentEncodeSet::Path)); m_paths.append(deprecated_string_percent_encode(path, PercentEncodeSet::Path));
} }
void URL::set_query(StringView query)
{
m_query = deprecated_string_percent_encode(query, is_special() ? PercentEncodeSet::SpecialQuery : PercentEncodeSet::Query);
}
void URL::set_fragment(StringView fragment) void URL::set_fragment(StringView fragment)
{ {
m_fragment = deprecated_string_percent_encode(fragment, PercentEncodeSet::Fragment); m_fragment = deprecated_string_percent_encode(fragment, PercentEncodeSet::Fragment);
@ -346,9 +336,9 @@ DeprecatedString URL::serialize(ExcludeFragment exclude_fragment) const
} }
// 5. If urls query is non-null, append U+003F (?), followed by urls query, to output. // 5. If urls query is non-null, append U+003F (?), followed by urls query, to output.
if (!m_query.is_null()) { if (m_query.has_value()) {
output.append('?'); output.append('?');
output.append(m_query); output.append(*m_query);
} }
// 6. If exclude fragment is false and urls fragment is non-null, then append U+0023 (#), followed by urls fragment, to output. // 6. If exclude fragment is false and urls fragment is non-null, then append U+0023 (#), followed by urls fragment, to output.
@ -391,9 +381,9 @@ DeprecatedString URL::serialize_for_display() const
} }
} }
if (!m_query.is_null()) { if (m_query.has_value()) {
builder.append('?'); builder.append('?');
builder.append(m_query); builder.append(*m_query);
} }
if (!m_fragment.is_null()) { if (!m_fragment.is_null()) {

View File

@ -82,7 +82,7 @@ public:
Host const& host() const { return m_host; } Host const& host() const { return m_host; }
ErrorOr<String> serialized_host() const; ErrorOr<String> serialized_host() const;
DeprecatedString basename() const; DeprecatedString basename() const;
DeprecatedString query() const; Optional<String> const& query() const { return m_query; }
// NOTE: fragment() is percent-decoded, raw_fragment() is not. // NOTE: fragment() is percent-decoded, raw_fragment() is not.
DeprecatedString fragment() const; DeprecatedString fragment() const;
DeprecatedString raw_fragment() const; DeprecatedString raw_fragment() const;
@ -103,7 +103,7 @@ public:
void set_host(Host); void set_host(Host);
void set_port(Optional<u16>); void set_port(Optional<u16>);
void set_paths(Vector<DeprecatedString> const&); void set_paths(Vector<DeprecatedString> const&);
void set_query(StringView); void set_query(Optional<String> query) { m_query = move(query); }
void set_fragment(StringView fragment); void set_fragment(StringView fragment);
void set_cannot_be_a_base_url(bool value) { m_cannot_be_a_base_url = value; } void set_cannot_be_a_base_url(bool value) { m_cannot_be_a_base_url = value; }
void append_path(StringView); void append_path(StringView);
@ -182,7 +182,7 @@ private:
Vector<DeprecatedString> m_paths; Vector<DeprecatedString> m_paths;
// A URLs query is either null or an ASCII string. It is initially null. // A URLs query is either null or an ASCII string. It is initially null.
DeprecatedString m_query; Optional<String> m_query;
// A URLs fragment is either null or an ASCII string that can be used for further processing on the resource the URLs other components identify. It is initially null. // A URLs fragment is either null or an ASCII string that can be used for further processing on the resource the URLs other components identify. It is initially null.
DeprecatedString m_fragment; DeprecatedString m_fragment;

View File

@ -994,7 +994,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
// 2. If c is U+003F (?), then set urls query to the empty string, and state to query state. // 2. If c is U+003F (?), then set urls query to the empty string, and state to query state.
if (code_point == '?') { if (code_point == '?') {
url->m_query = ""; url->m_query = String {};
state = State::Query; state = State::Query;
} }
// 3. Otherwise, if c is U+0023 (#), set urls fragment to the empty string and state to fragment state. // 3. Otherwise, if c is U+0023 (#), set urls fragment to the empty string and state to fragment state.
@ -1304,7 +1304,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
// 2. If c is U+003F (?), then set urls query to the empty string and state to query state. // 2. If c is U+003F (?), then set urls query to the empty string and state to query state.
if (code_point == '?') { if (code_point == '?') {
url->m_query = ""; url->m_query = String {};
state = State::Query; state = State::Query;
} }
// 3. Otherwise, if c is U+0023 (#), set urls fragment to the empty string and state to fragment state. // 3. Otherwise, if c is U+0023 (#), set urls fragment to the empty string and state to fragment state.
@ -1445,7 +1445,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
} }
// 2. Otherwise, if state override is not given and c is U+003F (?), set urls query to the empty string and state to query state. // 2. Otherwise, if state override is not given and c is U+003F (?), set urls query to the empty string and state to query state.
else if (!state_override.has_value() && code_point == '?') { else if (!state_override.has_value() && code_point == '?') {
url->m_query = ""; url->m_query = String {};
state = State::Query; state = State::Query;
} }
// 3. Otherwise, if state override is not given and c is U+0023 (#), set urls fragment to the empty string and state to fragment state. // 3. Otherwise, if state override is not given and c is U+0023 (#), set urls fragment to the empty string and state to fragment state.
@ -1514,7 +1514,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
// 6. If c is U+003F (?), then set urls query to the empty string and state to query state. // 6. If c is U+003F (?), then set urls query to the empty string and state to query state.
if (code_point == '?') { if (code_point == '?') {
url->m_query = ""; url->m_query = String {};
state = State::Query; state = State::Query;
} }
// 7. If c is U+0023 (#), then set urls fragment to the empty string and state to fragment state. // 7. If c is U+0023 (#), then set urls fragment to the empty string and state to fragment state.
@ -1543,7 +1543,7 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
// 1. If c is U+003F (?), then set urls query to the empty string and state to query state. // 1. If c is U+003F (?), then set urls query to the empty string and state to query state.
if (code_point == '?') { if (code_point == '?') {
url->m_paths[0] = buffer.string_view(); url->m_paths[0] = buffer.string_view();
url->m_query = ""; url->m_query = String {};
buffer.clear(); buffer.clear();
state = State::Query; state = State::Query;
} }
@ -1584,14 +1584,13 @@ URL URLParser::basic_parse(StringView raw_input, Optional<URL> const& base_url,
// * c is the EOF code point // * c is the EOF code point
if ((!state_override.has_value() && code_point == '#') if ((!state_override.has_value() && code_point == '#')
|| code_point == end_of_file) { || code_point == end_of_file) {
VERIFY(url->m_query == "");
// then: // then:
// 1. Let queryPercentEncodeSet be the special-query percent-encode set if url is special; otherwise the query percent-encode set. // 1. Let queryPercentEncodeSet be the special-query percent-encode set if url is special; otherwise the query percent-encode set.
auto query_percent_encode_set = url->is_special() ? URL::PercentEncodeSet::SpecialQuery : URL::PercentEncodeSet::Query; auto query_percent_encode_set = url->is_special() ? URL::PercentEncodeSet::SpecialQuery : URL::PercentEncodeSet::Query;
// 2. Percent-encode after encoding, with encoding, buffer, and queryPercentEncodeSet, and append the result to urls query. // 2. Percent-encode after encoding, with encoding, buffer, and queryPercentEncodeSet, and append the result to urls query.
url->m_query = percent_encode_after_encoding(buffer.string_view(), query_percent_encode_set); url->m_query = String::from_deprecated_string(percent_encode_after_encoding(buffer.string_view(), query_percent_encode_set)).release_value_but_fixme_should_propagate_errors();
// 3. Set buffer to the empty string. // 3. Set buffer to the empty string.
buffer.clear(); buffer.clear();

View File

@ -24,7 +24,7 @@ TEST_CASE(basic)
EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org"); EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org");
EXPECT_EQ(url.port_or_default(), 80); EXPECT_EQ(url.port_or_default(), 80);
EXPECT_EQ(url.serialize_path(), "/"); EXPECT_EQ(url.serialize_path(), "/");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
} }
{ {
@ -34,7 +34,7 @@ TEST_CASE(basic)
EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org"); EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org");
EXPECT_EQ(url.port_or_default(), 443); EXPECT_EQ(url.port_or_default(), 443);
EXPECT_EQ(url.serialize_path(), "/index.html"); EXPECT_EQ(url.serialize_path(), "/index.html");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
} }
{ {
@ -44,7 +44,7 @@ TEST_CASE(basic)
EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org1"); EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org1");
EXPECT_EQ(url.port_or_default(), 443); EXPECT_EQ(url.port_or_default(), 443);
EXPECT_EQ(url.serialize_path(), "/index.html"); EXPECT_EQ(url.serialize_path(), "/index.html");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
} }
{ {
@ -54,7 +54,7 @@ TEST_CASE(basic)
EXPECT_EQ(MUST(url.serialized_host()), "localhost"); EXPECT_EQ(MUST(url.serialized_host()), "localhost");
EXPECT_EQ(url.port_or_default(), 1234); EXPECT_EQ(url.port_or_default(), 1234);
EXPECT_EQ(url.serialize_path(), "/~anon/test/page.html"); EXPECT_EQ(url.serialize_path(), "/~anon/test/page.html");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
} }
{ {
@ -84,7 +84,7 @@ TEST_CASE(basic)
EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org"); EXPECT_EQ(MUST(url.serialized_host()), "www.serenityos.org");
EXPECT_EQ(url.port_or_default(), 80); EXPECT_EQ(url.port_or_default(), 80);
EXPECT_EQ(url.serialize_path(), "/index.html"); EXPECT_EQ(url.serialize_path(), "/index.html");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT_EQ(url.fragment(), "fragment"); EXPECT_EQ(url.fragment(), "fragment");
} }
{ {
@ -130,7 +130,7 @@ TEST_CASE(file_url_with_hostname)
EXPECT_EQ(url.port_or_default(), 0); EXPECT_EQ(url.port_or_default(), 0);
EXPECT_EQ(url.serialize_path(), "/my/file"); EXPECT_EQ(url.serialize_path(), "/my/file");
EXPECT_EQ(url.serialize(), "file://courage/my/file"); EXPECT_EQ(url.serialize(), "file://courage/my/file");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
} }
@ -160,7 +160,7 @@ TEST_CASE(file_url_with_encoded_characters)
EXPECT(url.is_valid()); EXPECT(url.is_valid());
EXPECT_EQ(url.scheme(), "file"); EXPECT_EQ(url.scheme(), "file");
EXPECT_EQ(url.serialize_path(), "/my/file/test#file.txt"); EXPECT_EQ(url.serialize_path(), "/my/file/test#file.txt");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
} }
@ -170,7 +170,7 @@ TEST_CASE(file_url_with_fragment)
EXPECT(url.is_valid()); EXPECT(url.is_valid());
EXPECT_EQ(url.scheme(), "file"); EXPECT_EQ(url.scheme(), "file");
EXPECT_EQ(url.serialize_path(), "/my/file"); EXPECT_EQ(url.serialize_path(), "/my/file");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT_EQ(url.fragment(), "fragment"); EXPECT_EQ(url.fragment(), "fragment");
} }
@ -205,7 +205,7 @@ TEST_CASE(about_url)
EXPECT_EQ(url.scheme(), "about"); EXPECT_EQ(url.scheme(), "about");
EXPECT(url.host().has<Empty>()); EXPECT(url.host().has<Empty>());
EXPECT_EQ(url.serialize_path(), "blank"); EXPECT_EQ(url.serialize_path(), "blank");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
EXPECT_EQ(url.serialize(), "about:blank"); EXPECT_EQ(url.serialize(), "about:blank");
} }
@ -219,7 +219,7 @@ TEST_CASE(mailto_url)
EXPECT_EQ(url.port_or_default(), 0); EXPECT_EQ(url.port_or_default(), 0);
EXPECT_EQ(url.path_segment_count(), 1u); EXPECT_EQ(url.path_segment_count(), 1u);
EXPECT_EQ(url.path_segment_at_index(0), "mail@example.com"); EXPECT_EQ(url.path_segment_at_index(0), "mail@example.com");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
EXPECT_EQ(url.serialize(), "mailto:mail@example.com"); EXPECT_EQ(url.serialize(), "mailto:mail@example.com");
} }
@ -379,7 +379,7 @@ TEST_CASE(create_with_file_scheme)
EXPECT_EQ(url.path_segment_at_index(1), "anon"); EXPECT_EQ(url.path_segment_at_index(1), "anon");
EXPECT_EQ(url.path_segment_at_index(2), "README.md"); EXPECT_EQ(url.path_segment_at_index(2), "README.md");
EXPECT_EQ(url.serialize_path(), "/home/anon/README.md"); EXPECT_EQ(url.serialize_path(), "/home/anon/README.md");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
url = URL::create_with_file_scheme("/home/anon/"); url = URL::create_with_file_scheme("/home/anon/");
@ -402,8 +402,7 @@ TEST_CASE(complete_url)
EXPECT_EQ(url.scheme(), "http"); EXPECT_EQ(url.scheme(), "http");
EXPECT_EQ(MUST(url.serialized_host()), "serenityos.org"); EXPECT_EQ(MUST(url.serialized_host()), "serenityos.org");
EXPECT_EQ(url.serialize_path(), "/test.html"); EXPECT_EQ(url.serialize_path(), "/test.html");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.query().is_null());
EXPECT_EQ(url.cannot_be_a_base_url(), false); EXPECT_EQ(url.cannot_be_a_base_url(), false);
EXPECT(base_url.complete_url("../index.html#fragment"sv).equals(base_url)); EXPECT(base_url.complete_url("../index.html#fragment"sv).equals(base_url));
@ -435,7 +434,7 @@ TEST_CASE(unicode)
URL url { "http://example.com/_ünicöde_téxt_©"sv }; URL url { "http://example.com/_ünicöde_téxt_©"sv };
EXPECT(url.is_valid()); EXPECT(url.is_valid());
EXPECT_EQ(url.serialize_path(), "/_ünicöde_téxt_©"); EXPECT_EQ(url.serialize_path(), "/_ünicöde_téxt_©");
EXPECT(url.query().is_null()); EXPECT(!url.query().has_value());
EXPECT(url.fragment().is_null()); EXPECT(url.fragment().is_null());
} }

View File

@ -53,9 +53,9 @@ ErrorOr<ByteBuffer> HttpRequest::to_raw_request() const
auto path = m_url.serialize_path(); auto path = m_url.serialize_path();
VERIFY(!path.is_empty()); VERIFY(!path.is_empty());
TRY(builder.try_append(URL::percent_encode(path, URL::PercentEncodeSet::EncodeURI))); TRY(builder.try_append(URL::percent_encode(path, URL::PercentEncodeSet::EncodeURI)));
if (!m_url.query().is_empty()) { if (m_url.query().has_value()) {
TRY(builder.try_append('?')); TRY(builder.try_append('?'));
TRY(builder.try_append(m_url.query())); TRY(builder.try_append(*m_url.query()));
} }
TRY(builder.try_append(" HTTP/1.1\r\nHost: "sv)); TRY(builder.try_append(" HTTP/1.1\r\nHost: "sv));
TRY(builder.try_append(TRY(m_url.serialized_host()))); TRY(builder.try_append(TRY(m_url.serialized_host())));
@ -230,7 +230,7 @@ ErrorOr<HttpRequest, HttpRequest::ParseError> HttpRequest::from_raw_request(Read
if (url_parts.size() == 2) { if (url_parts.size() == 2) {
request.m_resource = url_parts[0]; request.m_resource = url_parts[0];
request.m_url.set_paths({ url_parts[0] }); request.m_url.set_paths({ url_parts[0] });
request.m_url.set_query(url_parts[1]); request.m_url.set_query(String::from_deprecated_string(url_parts[1]).release_value_but_fixme_should_propagate_errors());
} else { } else {
request.m_resource = resource; request.m_resource = resource;
request.m_url.set_paths({ resource }); request.m_url.set_paths({ resource });

View File

@ -616,7 +616,7 @@ ErrorOr<void> HTMLFormElement::mutate_action_url(AK::URL parsed_action, Vector<X
auto query = TRY(url_encode(pairs, encoding)); auto query = TRY(url_encode(pairs, encoding));
// 3. Set parsed action's query component to query. // 3. Set parsed action's query component to query.
parsed_action.set_query(query.to_deprecated_string()); parsed_action.set_query(query);
// 4. Plan to navigate to parsed action. // 4. Plan to navigate to parsed action.
plan_to_navigate_to(move(parsed_action), target_navigable, history_handling); plan_to_navigate_to(move(parsed_action), target_navigable, history_handling);
@ -715,7 +715,7 @@ ErrorOr<void> HTMLFormElement::mail_with_headers(AK::URL parsed_action, Vector<X
TRY(headers.replace("+"sv, "%20"sv, ReplaceMode::All)); TRY(headers.replace("+"sv, "%20"sv, ReplaceMode::All));
// 4. Set parsed action's query to headers. // 4. Set parsed action's query to headers.
parsed_action.set_query(headers.to_deprecated_string()); parsed_action.set_query(headers);
// 5. Plan to navigate to parsed action. // 5. Plan to navigate to parsed action.
plan_to_navigate_to(move(parsed_action), target_navigable, history_handling); plan_to_navigate_to(move(parsed_action), target_navigable, history_handling);
@ -751,15 +751,15 @@ ErrorOr<void> HTMLFormElement::mail_as_body(AK::URL parsed_action, Vector<XHR::F
} }
// 3. If parsed action's query is null, then set it to the empty string. // 3. If parsed action's query is null, then set it to the empty string.
if (parsed_action.query().is_null()) if (!parsed_action.query().has_value())
parsed_action.set_query(DeprecatedString::empty()); parsed_action.set_query(String {});
StringBuilder query_builder; StringBuilder query_builder;
TRY(query_builder.try_append(parsed_action.query())); query_builder.append(*parsed_action.query());
// 4. If parsed action's query is not the empty string, then append a single U+0026 AMPERSAND character (&) to it. // 4. If parsed action's query is not the empty string, then append a single U+0026 AMPERSAND character (&) to it.
if (!parsed_action.query().is_empty()) if (!parsed_action.query()->is_empty())
TRY(query_builder.try_append('&')); TRY(query_builder.try_append('&'));
// 5. Append "body=" to parsed action's query. // 5. Append "body=" to parsed action's query.
@ -768,7 +768,7 @@ ErrorOr<void> HTMLFormElement::mail_as_body(AK::URL parsed_action, Vector<XHR::F
// 6. Append body to parsed action's query. // 6. Append body to parsed action's query.
TRY(query_builder.try_append(body)); TRY(query_builder.try_append(body));
parsed_action.set_query(query_builder.to_deprecated_string()); parsed_action.set_query(MUST(query_builder.to_string()));
// 7. Plan to navigate to parsed action. // 7. Plan to navigate to parsed action.
plan_to_navigate_to(move(parsed_action), target_navigable, history_handling); plan_to_navigate_to(move(parsed_action), target_navigable, history_handling);

View File

@ -330,7 +330,7 @@ DeprecatedString HTMLHyperlinkElementUtils::search() const
// 2. Let url be this element's url. // 2. Let url be this element's url.
// 3. If url is null, or url's query is either null or the empty string, return the empty string. // 3. If url is null, or url's query is either null or the empty string, return the empty string.
if (!m_url.has_value() || m_url->query().is_null() || m_url->query().is_empty()) if (!m_url.has_value() || m_url->query().has_value() || m_url->query()->is_empty())
return DeprecatedString::empty(); return DeprecatedString::empty();
// 4. Return "?", followed by url's query. // 4. Return "?", followed by url's query.
@ -358,7 +358,7 @@ void HTMLHyperlinkElementUtils::set_search(DeprecatedString search)
// 2. Set url's query to the empty string. // 2. Set url's query to the empty string.
auto url_copy = m_url; // We copy the URL here to follow other browser's behavior of reverting the search change if the parse failed. auto url_copy = m_url; // We copy the URL here to follow other browser's behavior of reverting the search change if the parse failed.
url_copy->set_query(DeprecatedString::empty()); url_copy->set_query(String {});
// 3. Basic URL parse input, with null, this element's node document's document's character encoding, url as url, and query state as state override. // 3. Basic URL parse input, with null, this element's node document's document's character encoding, url as url, and query state as state override.
auto result_url = URLParser::basic_parse(input, {}, move(url_copy), URLParser::State::Query); auto result_url = URLParser::basic_parse(input, {}, move(url_copy), URLParser::State::Query);

View File

@ -253,7 +253,7 @@ WebIDL::ExceptionOr<String> Location::search() const
auto url = this->url(); auto url = this->url();
// 2. If this's url's query is either null or the empty string, return the empty string. // 2. If this's url's query is either null or the empty string, return the empty string.
if (url.query().is_empty()) if (!url.query().has_value() || url.query()->is_empty())
return String {}; return String {};
// 3. Return "?", followed by this's url's query. // 3. Return "?", followed by this's url's query.

View File

@ -106,11 +106,11 @@ WebIDL::ExceptionOr<String> WorkerLocation::search() const
auto const& query = m_global_scope->url().query(); auto const& query = m_global_scope->url().query();
// 2. If query is either null or the empty string, return the empty string. // 2. If query is either null or the empty string, return the empty string.
if (query.is_empty()) if (!query.has_value() || query->is_empty())
return String {}; return String {};
// 3. Return "?", followed by query. // 3. Return "?", followed by query.
return TRY_OR_THROW_OOM(vm, String::formatted("?{}", query.view())); return TRY_OR_THROW_OOM(vm, String::formatted("?{}", *query));
} }
// https://html.spec.whatwg.org/multipage/workers.html#dom-workerlocation-hash // https://html.spec.whatwg.org/multipage/workers.html#dom-workerlocation-hash

View File

@ -50,8 +50,6 @@ static Optional<AK::URL> parse_api_url(String const& url, Optional<String> const
// https://url.spec.whatwg.org/#dom-url-url // https://url.spec.whatwg.org/#dom-url-url
WebIDL::ExceptionOr<JS::NonnullGCPtr<URL>> URL::construct_impl(JS::Realm& realm, String const& url, Optional<String> const& base) WebIDL::ExceptionOr<JS::NonnullGCPtr<URL>> URL::construct_impl(JS::Realm& realm, String const& url, Optional<String> const& base)
{ {
auto& vm = realm.vm();
// 1. Let parsedURL be the result of running the API URL parser on url with base, if given. // 1. Let parsedURL be the result of running the API URL parser on url with base, if given.
auto parsed_url = parse_api_url(url, base); auto parsed_url = parse_api_url(url, base);
@ -60,7 +58,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<URL>> URL::construct_impl(JS::Realm& realm,
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid URL"sv }; return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid URL"sv };
// 3. Let query be parsedURLs query, if that is non-null, and the empty string otherwise. // 3. Let query be parsedURLs query, if that is non-null, and the empty string otherwise.
auto query = parsed_url->query().is_null() ? String {} : TRY_OR_THROW_OOM(vm, String::from_deprecated_string(parsed_url->query())); auto query = parsed_url->query().value_or(String {});
// 4. Set thiss URL to parsedURL. // 4. Set thiss URL to parsedURL.
// 5. Set thiss query object to a new URLSearchParams object. // 5. Set thiss query object to a new URLSearchParams object.
@ -182,8 +180,8 @@ WebIDL::ExceptionOr<void> URL::set_href(String const& href)
auto query = m_url.query(); auto query = m_url.query();
// 6. If query is non-null, then set thiss query objects list to the result of parsing query. // 6. If query is non-null, then set thiss query objects list to the result of parsing query.
if (!query.is_null()) if (query.has_value())
m_query->m_list = TRY_OR_THROW_OOM(vm, url_decode(query)); m_query->m_list = TRY_OR_THROW_OOM(vm, url_decode(*query));
return {}; return {};
} }
@ -382,11 +380,11 @@ WebIDL::ExceptionOr<String> URL::search() const
auto& vm = realm().vm(); auto& vm = realm().vm();
// 1. If thiss URLs query is either null or the empty string, then return the empty string. // 1. If thiss URLs query is either null or the empty string, then return the empty string.
if (m_url.query().is_null() || m_url.query().is_empty()) if (!m_url.query().has_value() || m_url.query()->is_empty())
return String {}; return String {};
// 2. Return U+003F (?), followed by thiss URLs query. // 2. Return U+003F (?), followed by thiss URLs query.
return TRY_OR_THROW_OOM(vm, String::formatted("?{}", m_url.query())); return TRY_OR_THROW_OOM(vm, String::formatted("?{}", *m_url.query()));
} }
// https://url.spec.whatwg.org/#ref-for-dom-url-search%E2%91%A0 // https://url.spec.whatwg.org/#ref-for-dom-url-search%E2%91%A0
@ -417,7 +415,7 @@ WebIDL::ExceptionOr<void> URL::set_search(String const& search)
// 4. Set urls query to the empty string. // 4. Set urls query to the empty string.
auto url_copy = url; // We copy the URL here to follow other browser's behavior of reverting the search change if the parse failed. auto url_copy = url; // We copy the URL here to follow other browser's behavior of reverting the search change if the parse failed.
url_copy.set_query(DeprecatedString::empty()); url_copy.set_query(String {});
// 5. Basic URL parse input with url as url and query state as state override. // 5. Basic URL parse input with url as url and query state as state override.
auto result_url = URLParser::basic_parse(input, {}, move(url_copy), URLParser::State::Query); auto result_url = URLParser::basic_parse(input, {}, move(url_copy), URLParser::State::Query);

View File

@ -65,7 +65,7 @@ public:
WebIDL::ExceptionOr<String> to_json() const; WebIDL::ExceptionOr<String> to_json() const;
void set_query(Badge<URLSearchParams>, StringView query) { m_url.set_query(query); } void set_query(Badge<URLSearchParams>, Optional<String> query) { m_url.set_query(move(query)); }
private: private:
URL(JS::Realm&, AK::URL, JS::NonnullGCPtr<URLSearchParams> query); URL(JS::Realm&, AK::URL, JS::NonnullGCPtr<URLSearchParams> query);

View File

@ -32,10 +32,11 @@ DeprecatedString ConnectionInfo::resource_name() const
// The path component // The path component
builder.append(path); builder.append(path);
// "?" if the query component is non-empty // "?" if the query component is non-empty
if (!m_url.query().is_empty()) if (m_url.query().has_value() && !m_url.query()->is_empty()) {
builder.append('?'); builder.append('?');
// the query component // the query component
builder.append(m_url.query()); builder.append(*m_url.query());
}
return builder.to_deprecated_string(); return builder.to_deprecated_string();
} }

View File

@ -393,15 +393,16 @@ bool Launcher::open_file_url(const URL& url)
Vector<DeprecatedString> additional_parameters; Vector<DeprecatedString> additional_parameters;
DeprecatedString filepath = url.serialize_path(); DeprecatedString filepath = url.serialize_path();
auto parameters = url.query().split('&'); if (url.query().has_value()) {
for (auto const& parameter : parameters) { url.query()->bytes_as_string_view().for_each_split_view('&', SplitBehavior::Nothing, [&](auto parameter) {
auto pair = parameter.split('='); auto pair = parameter.split_view('=');
if (pair.size() == 2 && pair[0] == "line_number") { if (pair.size() == 2 && pair[0] == "line_number") {
auto line = pair[1].to_int(); auto line = pair[1].to_int();
if (line.has_value()) if (line.has_value())
// TextEditor uses file:line:col to open a file at a specific line number // TextEditor uses file:line:col to open a file at a specific line number
filepath = DeprecatedString::formatted("{}:{}", filepath, line.value()); filepath = DeprecatedString::formatted("{}:{}", filepath, line.value());
} }
});
} }
additional_parameters.append(filepath); additional_parameters.append(filepath);

View File

@ -58,7 +58,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (access(full_path.characters(), F_OK) == 0) { if (access(full_path.characters(), F_OK) == 0) {
linked = true; linked = true;
auto url = URL::create_with_file_scheme(full_path, {}, hostname); auto url = URL::create_with_file_scheme(full_path, {}, hostname);
url.set_query(DeprecatedString::formatted("line_number={}", source_position.line_number)); url.set_query(TRY(String::formatted("line_number={}", source_position.line_number)));
out("\033]8;;{}\033\\", url.serialize()); out("\033]8;;{}\033\\", url.serialize());
} }