LibWeb/HTML: Port Location to new String

This commit is contained in:
Linus Groh 2023-03-04 22:16:07 +00:00
parent 7800276c0f
commit 7d50be0b09
Notes: sideshowbarker 2024-07-16 23:29:49 +09:00
3 changed files with 74 additions and 56 deletions

View file

@ -5,7 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/DeprecatedFlyString.h>
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <AK/URLParser.h>
#include <LibJS/Heap/MarkedVector.h>
@ -70,16 +70,18 @@ AK::URL Location::url() const
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-href
DeprecatedString Location::href() const
WebIDL::ExceptionOr<String> Location::href() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
// 2. Return this's url, serialized.
return url().to_deprecated_string();
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(url().serialize()));
}
// https://html.spec.whatwg.org/multipage/history.html#the-location-interface:dom-location-href-2
JS::ThrowCompletionOr<void> Location::set_href(DeprecatedString const& new_href)
JS::ThrowCompletionOr<void> Location::set_href(String const& new_href)
{
auto& vm = this->vm();
auto& window = verify_cast<HTML::Window>(HTML::current_global_object());
@ -87,7 +89,7 @@ JS::ThrowCompletionOr<void> Location::set_href(DeprecatedString const& new_href)
// FIXME: 1. If this's relevant Document is null, then return.
// 2. Parse the given value relative to the entry settings object. If that failed, throw a TypeError exception.
auto href_url = window.associated_document().parse_url(new_href);
auto href_url = window.associated_document().parse_url(new_href.to_deprecated_string());
if (!href_url.is_valid())
return vm.throw_completion<JS::URIError>(TRY_OR_THROW_OOM(vm, String::formatted("Invalid URL '{}'", new_href)));
@ -98,32 +100,38 @@ JS::ThrowCompletionOr<void> Location::set_href(DeprecatedString const& new_href)
}
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-location-origin
DeprecatedString Location::origin() const
WebIDL::ExceptionOr<String> Location::origin() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
// 2. Return the serialization of this's url's origin.
return url().serialize_origin();
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(url().serialize_origin()));
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-protocol
DeprecatedString Location::protocol() const
WebIDL::ExceptionOr<String> Location::protocol() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
// 2. Return this's url's scheme, followed by ":".
return DeprecatedString::formatted("{}:", url().scheme());
return TRY_OR_THROW_OOM(vm, String::formatted("{}:", url().scheme()));
}
JS::ThrowCompletionOr<void> Location::set_protocol(DeprecatedString const&)
JS::ThrowCompletionOr<void> Location::set_protocol(String const&)
{
auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.protocol setter");
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-host
DeprecatedString Location::host() const
WebIDL::ExceptionOr<String> Location::host() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
// 2. Let url be this's url.
@ -131,117 +139,127 @@ DeprecatedString Location::host() const
// 3. If url's host is null, return the empty string.
if (url.host().is_null())
return DeprecatedString::empty();
return String {};
// 4. If url's port is null, return url's host, serialized.
if (!url.port().has_value())
return url.host();
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(url.host()));
// 5. Return url's host, serialized, followed by ":" and url's port, serialized.
return DeprecatedString::formatted("{}:{}", url.host(), *url.port());
return TRY_OR_THROW_OOM(vm, String::formatted("{}:{}", url.host(), *url.port()));
}
JS::ThrowCompletionOr<void> Location::set_host(DeprecatedString const&)
JS::ThrowCompletionOr<void> Location::set_host(String const&)
{
auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.host setter");
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-hostname
DeprecatedString Location::hostname() const
WebIDL::ExceptionOr<String> Location::hostname() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
auto url = this->url();
// 2. If this's url's host is null, return the empty string.
if (url.host().is_null())
return DeprecatedString::empty();
return String {};
// 3. Return this's url's host, serialized.
return url.host();
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(url.host()));
}
JS::ThrowCompletionOr<void> Location::set_hostname(DeprecatedString const&)
JS::ThrowCompletionOr<void> Location::set_hostname(String const&)
{
auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.hostname setter");
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-port
DeprecatedString Location::port() const
WebIDL::ExceptionOr<String> Location::port() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
auto url = this->url();
// 2. If this's url's port is null, return the empty string.
if (!url.port().has_value())
return DeprecatedString::empty();
return String {};
// 3. Return this's url's port, serialized.
return DeprecatedString::number(*url.port());
return TRY_OR_THROW_OOM(vm, String::number(*url.port()));
}
JS::ThrowCompletionOr<void> Location::set_port(DeprecatedString const&)
JS::ThrowCompletionOr<void> Location::set_port(String const&)
{
auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.port setter");
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-pathname
DeprecatedString Location::pathname() const
WebIDL::ExceptionOr<String> Location::pathname() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
// 2. Return the result of URL path serializing this Location object's url.
return url().path();
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(url().path()));
}
JS::ThrowCompletionOr<void> Location::set_pathname(DeprecatedString const&)
JS::ThrowCompletionOr<void> Location::set_pathname(String const&)
{
auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.pathname setter");
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-search
DeprecatedString Location::search() const
WebIDL::ExceptionOr<String> Location::search() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
auto url = this->url();
// 2. If this's url's query is either null or the empty string, return the empty string.
if (url.query().is_empty())
return DeprecatedString::empty();
return String {};
// 3. Return "?", followed by this's url's query.
return DeprecatedString::formatted("?{}", url.query());
return TRY_OR_THROW_OOM(vm, String::formatted("?{}", url.query()));
}
JS::ThrowCompletionOr<void> Location::set_search(DeprecatedString const&)
JS::ThrowCompletionOr<void> Location::set_search(String const&)
{
auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.search setter");
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-hash
DeprecatedString Location::hash() const
WebIDL::ExceptionOr<String> Location::hash() const
{
auto& vm = this->vm();
// FIXME: 1. If this's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.
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())
return DeprecatedString::empty();
return String {};
// 3. Return "#", followed by this's url's fragment.
return DeprecatedString::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
JS::ThrowCompletionOr<void> Location::set_hash(DeprecatedString const& value)
JS::ThrowCompletionOr<void> Location::set_hash(String const& value)
{
// The hash setter steps are:
// 1. If this's relevant Document is null, then return.
@ -254,7 +272,7 @@ JS::ThrowCompletionOr<void> Location::set_hash(DeprecatedString const& value)
auto copy_url = this->url();
// 4. Let input be the given value with a single leading "#" removed, if any.
auto input = value.starts_with("#"sv) ? value.substring(1) : 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("");
@ -281,11 +299,11 @@ void Location::reload() const
}
// https://html.spec.whatwg.org/multipage/history.html#dom-location-replace
void Location::replace(DeprecatedString url) const
void Location::replace(String const& url) const
{
auto& window = verify_cast<HTML::Window>(HTML::current_global_object());
// FIXME: This needs spec compliance work.
window.did_call_location_replace({}, move(url));
window.did_call_location_replace({}, url.to_deprecated_string());
}
// 7.10.5.1 [[GetPrototypeOf]] ( ), https://html.spec.whatwg.org/multipage/history.html#location-getprototypeof

View file

@ -22,33 +22,33 @@ class Location final : public Bindings::PlatformObject {
public:
virtual ~Location() override;
DeprecatedString href() const;
JS::ThrowCompletionOr<void> set_href(DeprecatedString const&);
WebIDL::ExceptionOr<String> href() const;
JS::ThrowCompletionOr<void> set_href(String const&);
DeprecatedString origin() const;
WebIDL::ExceptionOr<String> origin() const;
DeprecatedString protocol() const;
JS::ThrowCompletionOr<void> set_protocol(DeprecatedString const&);
WebIDL::ExceptionOr<String> protocol() const;
JS::ThrowCompletionOr<void> set_protocol(String const&);
DeprecatedString host() const;
JS::ThrowCompletionOr<void> set_host(DeprecatedString const&);
WebIDL::ExceptionOr<String> host() const;
JS::ThrowCompletionOr<void> set_host(String const&);
DeprecatedString hostname() const;
JS::ThrowCompletionOr<void> set_hostname(DeprecatedString const&);
WebIDL::ExceptionOr<String> hostname() const;
JS::ThrowCompletionOr<void> set_hostname(String const&);
DeprecatedString port() const;
JS::ThrowCompletionOr<void> set_port(DeprecatedString const&);
WebIDL::ExceptionOr<String> port() const;
JS::ThrowCompletionOr<void> set_port(String const&);
DeprecatedString pathname() const;
JS::ThrowCompletionOr<void> set_pathname(DeprecatedString const&);
WebIDL::ExceptionOr<String> pathname() const;
JS::ThrowCompletionOr<void> set_pathname(String const&);
DeprecatedString search() const;
JS::ThrowCompletionOr<void> set_search(DeprecatedString const&);
WebIDL::ExceptionOr<String> search() const;
JS::ThrowCompletionOr<void> set_search(String const&);
DeprecatedString hash() const;
JS::ThrowCompletionOr<void> set_hash(DeprecatedString const&);
WebIDL::ExceptionOr<String> hash() const;
JS::ThrowCompletionOr<void> set_hash(String const&);
void replace(DeprecatedString url) const;
void replace(String const& url) const;
void reload() const;
virtual JS::ThrowCompletionOr<JS::Object*> internal_get_prototype_of() const override;

View file

@ -1,5 +1,5 @@
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#location
[Exposed=Window]
[Exposed=Window, UseNewAKString]
interface Location { // but see also additional creation steps and overridden internal methods
[LegacyUnforgeable] stringifier attribute USVString href;
[LegacyUnforgeable] readonly attribute USVString origin;