1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 22:07:34 +00:00

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
3 changed files with 74 additions and 56 deletions

View file

@ -5,7 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/DeprecatedFlyString.h> #include <AK/String.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/URLParser.h> #include <AK/URLParser.h>
#include <LibJS/Heap/MarkedVector.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 // 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. // 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. // 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 // 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& vm = this->vm();
auto& window = verify_cast<HTML::Window>(HTML::current_global_object()); 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. // 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. // 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()) if (!href_url.is_valid())
return vm.throw_completion<JS::URIError>(TRY_OR_THROW_OOM(vm, String::formatted("Invalid URL '{}'", new_href))); 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 // 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. // 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. // 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 // 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. // 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 ":". // 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(); auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.protocol setter"); return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.protocol setter");
} }
// https://html.spec.whatwg.org/multipage/history.html#dom-location-host // 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. // 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. // 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. // 3. If url's host is null, return the empty string.
if (url.host().is_null()) if (url.host().is_null())
return DeprecatedString::empty(); return String {};
// 4. If url's port is null, return url's host, serialized. // 4. If url's port is null, return url's host, serialized.
if (!url.port().has_value()) 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. // 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(); auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.host setter"); return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.host setter");
} }
// https://html.spec.whatwg.org/multipage/history.html#dom-location-hostname // 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. // 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(); auto url = this->url();
// 2. If this's url's host is null, return the empty string. // 2. If this's url's host is null, return the empty string.
if (url.host().is_null()) if (url.host().is_null())
return DeprecatedString::empty(); return String {};
// 3. Return this's url's host, serialized. // 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(); auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.hostname setter"); return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.hostname setter");
} }
// https://html.spec.whatwg.org/multipage/history.html#dom-location-port // 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. // 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(); auto url = this->url();
// 2. If this's url's port is null, return the empty string. // 2. If this's url's port is null, return the empty string.
if (!url.port().has_value()) if (!url.port().has_value())
return DeprecatedString::empty(); return String {};
// 3. Return this's url's port, serialized. // 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(); auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.port setter"); return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.port setter");
} }
// https://html.spec.whatwg.org/multipage/history.html#dom-location-pathname // 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. // 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. // 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(); auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.pathname setter"); return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.pathname setter");
} }
// https://html.spec.whatwg.org/multipage/history.html#dom-location-search // 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. // 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(); 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().is_empty())
return DeprecatedString::empty(); return String {};
// 3. Return "?", followed by this's url's query. // 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(); auto& vm = this->vm();
return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.search setter"); return vm.throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Location.search setter");
} }
// https://html.spec.whatwg.org/multipage/history.html#dom-location-hash // 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. // 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(); auto url = this->url();
// 2. If this's url's fragment is either null or the empty string, return the empty string. // 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().is_empty())
return DeprecatedString::empty(); return String {};
// 3. Return "#", followed by this's url's fragment. // 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 // 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: // The hash setter steps are:
// 1. If this's relevant Document is null, then return. // 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(); auto copy_url = this->url();
// 4. Let input be the given value with a single leading "#" removed, if any. // 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. // 5. Set copyURL's fragment to the empty string.
copy_url.set_fragment(""); copy_url.set_fragment("");
@ -281,11 +299,11 @@ void Location::reload() const
} }
// https://html.spec.whatwg.org/multipage/history.html#dom-location-replace // 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()); auto& window = verify_cast<HTML::Window>(HTML::current_global_object());
// FIXME: This needs spec compliance work. // 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 // 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: public:
virtual ~Location() override; virtual ~Location() override;
DeprecatedString href() const; WebIDL::ExceptionOr<String> href() const;
JS::ThrowCompletionOr<void> set_href(DeprecatedString const&); JS::ThrowCompletionOr<void> set_href(String const&);
DeprecatedString origin() const; WebIDL::ExceptionOr<String> origin() const;
DeprecatedString protocol() const; WebIDL::ExceptionOr<String> protocol() const;
JS::ThrowCompletionOr<void> set_protocol(DeprecatedString const&); JS::ThrowCompletionOr<void> set_protocol(String const&);
DeprecatedString host() const; WebIDL::ExceptionOr<String> host() const;
JS::ThrowCompletionOr<void> set_host(DeprecatedString const&); JS::ThrowCompletionOr<void> set_host(String const&);
DeprecatedString hostname() const; WebIDL::ExceptionOr<String> hostname() const;
JS::ThrowCompletionOr<void> set_hostname(DeprecatedString const&); JS::ThrowCompletionOr<void> set_hostname(String const&);
DeprecatedString port() const; WebIDL::ExceptionOr<String> port() const;
JS::ThrowCompletionOr<void> set_port(DeprecatedString const&); JS::ThrowCompletionOr<void> set_port(String const&);
DeprecatedString pathname() const; WebIDL::ExceptionOr<String> pathname() const;
JS::ThrowCompletionOr<void> set_pathname(DeprecatedString const&); JS::ThrowCompletionOr<void> set_pathname(String const&);
DeprecatedString search() const; WebIDL::ExceptionOr<String> search() const;
JS::ThrowCompletionOr<void> set_search(DeprecatedString const&); JS::ThrowCompletionOr<void> set_search(String const&);
DeprecatedString hash() const; WebIDL::ExceptionOr<String> hash() const;
JS::ThrowCompletionOr<void> set_hash(DeprecatedString const&); JS::ThrowCompletionOr<void> set_hash(String const&);
void replace(DeprecatedString url) const; void replace(String const& url) const;
void reload() const; void reload() const;
virtual JS::ThrowCompletionOr<JS::Object*> internal_get_prototype_of() const override; 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 // 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 interface Location { // but see also additional creation steps and overridden internal methods
[LegacyUnforgeable] stringifier attribute USVString href; [LegacyUnforgeable] stringifier attribute USVString href;
[LegacyUnforgeable] readonly attribute USVString origin; [LegacyUnforgeable] readonly attribute USVString origin;