From ec1cb050b4cdebd7b691111ea0ac9f240b887abf Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Fri, 16 Aug 2024 22:00:29 +0100 Subject: [PATCH] LibWeb: Implement the setter for `location.protocol` --- .../HTML/Location-protocol-setter.txt | 1 + .../input/HTML/Location-protocol-setter.html | 11 +++++++ Userland/Libraries/LibWeb/HTML/Location.cpp | 33 +++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/HTML/Location-protocol-setter.txt create mode 100644 Tests/LibWeb/Text/input/HTML/Location-protocol-setter.html diff --git a/Tests/LibWeb/Text/expected/HTML/Location-protocol-setter.txt b/Tests/LibWeb/Text/expected/HTML/Location-protocol-setter.txt new file mode 100644 index 0000000000000..6214e941f877d --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/Location-protocol-setter.txt @@ -0,0 +1 @@ +Setting location.protocol to an invalid value throws SyntaxError diff --git a/Tests/LibWeb/Text/input/HTML/Location-protocol-setter.html b/Tests/LibWeb/Text/input/HTML/Location-protocol-setter.html new file mode 100644 index 0000000000000..9a02f7b40451c --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/Location-protocol-setter.html @@ -0,0 +1,11 @@ + + + diff --git a/Userland/Libraries/LibWeb/HTML/Location.cpp b/Userland/Libraries/LibWeb/HTML/Location.cpp index df74d3e5f8785..4507a733ab19c 100644 --- a/Userland/Libraries/LibWeb/HTML/Location.cpp +++ b/Userland/Libraries/LibWeb/HTML/Location.cpp @@ -156,10 +156,37 @@ WebIDL::ExceptionOr Location::protocol() const return TRY_OR_THROW_OOM(vm, String::formatted("{}:", url().scheme())); } -WebIDL::ExceptionOr Location::set_protocol(String const&) +// https://html.spec.whatwg.org/multipage/history.html#dom-location-protocol +WebIDL::ExceptionOr Location::set_protocol(String const& value) { - auto& vm = this->vm(); - return vm.throw_completion(JS::ErrorType::NotImplemented, "Location.protocol setter"); + auto relevant_document = this->relevant_document(); + + // 1. If this's relevant Document is null, then return. + if (!relevant_document) + return {}; + + // 2. If this's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException. + if (!relevant_document->origin().is_same_origin_domain(entry_settings_object().origin())) + return WebIDL::SecurityError::create(realm(), "Cannot set protocol on cross-origin object"_fly_string); + + // 3. Let copyURL be a copy of this's url. + auto copy_url = this->url(); + + // 4. Let possibleFailure be the result of basic URL parsing the given value, followed by ":", with copyURL as url and scheme start state as state override. + auto possible_failure = URL::Parser::basic_parse(value, {}, ©_url, URL::Parser::State::SchemeStart); + + // 5. If possibleFailure is failure, then throw a "SyntaxError" DOMException. + if (!possible_failure.is_valid()) + return WebIDL::SyntaxError::create(realm(), MUST(String::formatted("Failed to set protocol. '{}' is an invalid protocol", value))); + + // 6. if copyURL's scheme is not an HTTP(S) scheme, then terminate these steps. + if (!(copy_url.scheme() == "http"sv || copy_url.scheme() == "https"sv)) + return {}; + + // 7. Location-object navigate this to copyURL. + TRY(navigate(copy_url)); + + return {}; } // https://html.spec.whatwg.org/multipage/history.html#dom-location-host