From 986bd2e27166440303bc73191debf0af355249f8 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Fri, 4 Mar 2022 23:35:34 +0100 Subject: [PATCH] LibWeb: Add spec comments to LocationObject This revealed a variety of issues, mostly missing origin checks, conflating concepts like the 'associated URL', and serialization (incorrect fallback values, string vs number, etc). This commit fixes none of these issues, only adds FIXMEs. --- .../LibWeb/Bindings/LocationObject.cpp | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp index ca7df09075..207bfc0ef1 100644 --- a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp @@ -14,6 +14,7 @@ namespace Web::Bindings { +// https://html.spec.whatwg.org/multipage/history.html#the-location-interface LocationObject::LocationObject(JS::GlobalObject& global_object) : Object(*global_object.object_prototype()) { @@ -44,81 +45,142 @@ LocationObject::~LocationObject() { } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-href JS_DEFINE_NATIVE_FUNCTION(LocationObject::href_getter) { auto& window = static_cast(global_object); + + // 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 JS::js_string(vm, window.impl().associated_document().url().to_string()); } +// https://html.spec.whatwg.org/multipage/history.html#the-location-interface:dom-location-href-2 JS_DEFINE_NATIVE_FUNCTION(LocationObject::href_setter) { auto& window = static_cast(global_object); + + // 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 new_href = TRY(vm.argument(0).to_string(global_object)); auto href_url = window.impl().associated_document().parse_url(new_href); if (!href_url.is_valid()) return vm.throw_completion(global_object, String::formatted("Invalid URL '{}'", new_href)); + + // 3. Location-object navigate given the resulting URL record. window.impl().did_set_location_href({}, href_url); + return JS::js_undefined(); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-pathname JS_DEFINE_NATIVE_FUNCTION(LocationObject::pathname_getter) { auto& window = static_cast(global_object); + + // 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 JS::js_string(vm, window.impl().associated_document().url().path()); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-hostname JS_DEFINE_NATIVE_FUNCTION(LocationObject::hostname_getter) { auto& window = static_cast(global_object); + + // 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. If this's url's host is null, return the empty string. + // 3. Return this's url's host, serialized. return JS::js_string(vm, window.impl().associated_document().url().host()); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-host JS_DEFINE_NATIVE_FUNCTION(LocationObject::host_getter) { auto& window = static_cast(global_object); + + // 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. auto url = window.impl().associated_document().url(); + + // FIXME: 3. If url's host is null, return the empty string. + // FIXME: 4. If url's port is null, return url's host, serialized. + + // 5. Return url's host, serialized, followed by ":" and url's port, serialized. return JS::js_string(vm, String::formatted("{}:{}", url.host(), url.port_or_default())); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-hash JS_DEFINE_NATIVE_FUNCTION(LocationObject::hash_getter) { auto& window = static_cast(global_object); + + // 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. If this's url's fragment is either null or the empty string, return the empty string. auto fragment = window.impl().associated_document().url().fragment(); if (!fragment.length()) return JS::js_string(vm, ""); + + // 3. Return "#", followed by this's url's fragment. StringBuilder builder; builder.append('#'); builder.append(fragment); return JS::js_string(vm, builder.to_string()); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-search JS_DEFINE_NATIVE_FUNCTION(LocationObject::search_getter) { auto& window = static_cast(global_object); + + // 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. If this's url's query is either null or the empty string, return the empty string. auto query = window.impl().associated_document().url().query(); if (!query.length()) return JS::js_string(vm, ""); + + // 3. Return "?", followed by this's url's query. StringBuilder builder; builder.append('?'); builder.append(query); return JS::js_string(vm, builder.to_string()); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-protocol JS_DEFINE_NATIVE_FUNCTION(LocationObject::protocol_getter) { auto& window = static_cast(global_object); + + // 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 ":". StringBuilder builder; builder.append(window.impl().associated_document().url().protocol()); builder.append(':'); return JS::js_string(vm, builder.to_string()); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-port JS_DEFINE_NATIVE_FUNCTION(LocationObject::port_getter) { auto& window = static_cast(global_object); + + // 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: 2. If this's url's port is null, return the empty string. + + // 3. Return this's url's port, serialized. return JS::Value(window.impl().associated_document().url().port_or_default()); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-reload JS_DEFINE_NATIVE_FUNCTION(LocationObject::reload) { auto& window = static_cast(global_object); @@ -126,6 +188,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocationObject::reload) return JS::js_undefined(); } +// https://html.spec.whatwg.org/multipage/history.html#dom-location-replace JS_DEFINE_NATIVE_FUNCTION(LocationObject::replace) { auto& window = static_cast(global_object);