2020-05-18 21:42:40 +02:00
/*
* Copyright ( c ) 2020 , Andreas Kling < kling @ serenityos . org >
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-05-18 21:42:40 +02:00
*/
# include <AK/FlyString.h>
2020-05-18 21:59:16 +02:00
# include <AK/StringBuilder.h>
2021-09-28 23:54:42 +01:00
# include <LibJS/Runtime/Completion.h>
2020-05-18 21:42:40 +02:00
# include <LibWeb/Bindings/LocationObject.h>
# include <LibWeb/Bindings/WindowObject.h>
# include <LibWeb/DOM/Document.h>
# include <LibWeb/DOM/Window.h>
2021-09-12 14:54:17 +01:00
namespace Web : : Bindings {
2020-05-18 21:42:40 +02:00
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#the-location-interface
2020-06-20 17:28:13 +02:00
LocationObject : : LocationObject ( JS : : GlobalObject & global_object )
2020-06-23 17:21:53 +02:00
: Object ( * global_object . object_prototype ( ) )
2020-06-20 17:28:13 +02:00
{
}
2020-07-22 17:50:18 +02:00
void LocationObject : : initialize ( JS : : GlobalObject & global_object )
2020-05-18 21:42:40 +02:00
{
2021-10-04 20:39:17 +03:00
auto & vm = global_object . vm ( ) ;
2020-07-22 17:50:18 +02:00
Object : : initialize ( global_object ) ;
2020-05-19 21:47:15 +01:00
u8 attr = JS : : Attribute : : Writable | JS : : Attribute : : Enumerable ;
2021-10-31 08:21:02 -04:00
define_native_accessor ( " href " , href_getter , href_setter , attr ) ;
define_native_accessor ( " host " , host_getter , { } , attr ) ;
define_native_accessor ( " hostname " , hostname_getter , { } , attr ) ;
define_native_accessor ( " pathname " , pathname_getter , { } , attr ) ;
define_native_accessor ( " hash " , hash_getter , { } , attr ) ;
define_native_accessor ( " search " , search_getter , { } , attr ) ;
define_native_accessor ( " protocol " , protocol_getter , { } , attr ) ;
define_native_accessor ( " port " , port_getter , { } , attr ) ;
2020-05-18 22:05:13 +02:00
2021-10-31 08:21:02 -04:00
define_native_function ( " reload " , reload , 0 , JS : : Attribute : : Enumerable ) ;
define_native_function ( " replace " , replace , 1 , JS : : Attribute : : Enumerable ) ;
2021-10-04 20:39:17 +03:00
2021-10-31 08:21:02 -04:00
define_native_function ( vm . names . toString , href_getter , 0 , JS : : Attribute : : Enumerable ) ;
2020-05-18 21:42:40 +02:00
}
LocationObject : : ~ LocationObject ( )
{
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-href
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : href_getter )
2020-05-18 21:42:40 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-09 13:55:31 +02:00
return JS : : js_string ( vm , window . impl ( ) . associated_document ( ) . url ( ) . to_string ( ) ) ;
2020-05-18 21:42:40 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#the-location-interface:dom-location-href-2
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : href_setter )
2020-05-18 21:42:40 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-10-31 08:21:02 -04:00
auto new_href = TRY ( vm . argument ( 0 ) . to_string ( global_object ) ) ;
2021-09-09 18:08:56 +02:00
auto href_url = window . impl ( ) . associated_document ( ) . parse_url ( new_href ) ;
2021-10-31 08:21:02 -04:00
if ( ! href_url . is_valid ( ) )
return vm . throw_completion < JS : : URIError > ( global_object , String : : formatted ( " Invalid URL '{}' " , new_href ) ) ;
2022-03-04 23:35:34 +01:00
// 3. Location-object navigate given the resulting URL record.
2020-12-02 12:09:24 +03:30
window . impl ( ) . did_set_location_href ( { } , href_url ) ;
2022-03-04 23:35:34 +01:00
2021-07-05 15:01:57 +03:00
return JS : : js_undefined ( ) ;
2020-05-18 21:42:40 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-pathname
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : pathname_getter )
2020-05-18 21:42:40 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-09 13:55:31 +02:00
return JS : : js_string ( vm , window . impl ( ) . associated_document ( ) . url ( ) . path ( ) ) ;
2020-05-18 21:42:40 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-hostname
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : hostname_getter )
2020-05-18 21:42:40 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-09 13:55:31 +02:00
return JS : : js_string ( vm , window . impl ( ) . associated_document ( ) . url ( ) . host ( ) ) ;
2020-05-18 21:42:40 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-host
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : host_getter )
2020-05-18 21:59:16 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-09 13:55:31 +02:00
auto url = window . impl ( ) . associated_document ( ) . url ( ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-13 23:12:16 +03:00
return JS : : js_string ( vm , String : : formatted ( " {}:{} " , url . host ( ) , url . port_or_default ( ) ) ) ;
2020-05-18 21:59:16 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-hash
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : hash_getter )
2020-05-18 21:42:40 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-09 13:55:31 +02:00
auto fragment = window . impl ( ) . associated_document ( ) . url ( ) . fragment ( ) ;
2020-05-19 21:36:19 +01:00
if ( ! fragment . length ( ) )
2020-09-27 18:36:49 +02:00
return JS : : js_string ( vm , " " ) ;
2022-03-04 23:35:34 +01:00
// 3. Return "#", followed by this's url's fragment.
2020-05-19 21:36:19 +01:00
StringBuilder builder ;
builder . append ( ' # ' ) ;
builder . append ( fragment ) ;
2020-09-27 18:36:49 +02:00
return JS : : js_string ( vm , builder . to_string ( ) ) ;
2020-05-18 21:42:40 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-search
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : search_getter )
2020-05-18 21:42:40 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-09 13:55:31 +02:00
auto query = window . impl ( ) . associated_document ( ) . url ( ) . query ( ) ;
2020-05-19 21:40:30 +01:00
if ( ! query . length ( ) )
2020-09-27 18:36:49 +02:00
return JS : : js_string ( vm , " " ) ;
2022-03-04 23:35:34 +01:00
// 3. Return "?", followed by this's url's query.
2020-05-19 21:40:30 +01:00
StringBuilder builder ;
builder . append ( ' ? ' ) ;
builder . append ( query ) ;
2020-09-27 18:36:49 +02:00
return JS : : js_string ( vm , builder . to_string ( ) ) ;
2020-05-18 21:42:40 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-protocol
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : protocol_getter )
2020-05-18 21:59:16 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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 ":".
2020-05-18 21:59:16 +02:00
StringBuilder builder ;
2021-09-09 13:55:31 +02:00
builder . append ( window . impl ( ) . associated_document ( ) . url ( ) . protocol ( ) ) ;
2020-05-18 21:59:16 +02:00
builder . append ( ' : ' ) ;
2020-09-27 18:36:49 +02:00
return JS : : js_string ( vm , builder . to_string ( ) ) ;
2020-05-18 21:59:16 +02:00
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-port
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : port_getter )
2021-09-18 21:44:45 +02:00
{
auto & window = static_cast < WindowObject & > ( global_object ) ;
2022-03-04 23:35:34 +01:00
// 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.
2021-09-18 21:44:45 +02:00
return JS : : Value ( window . impl ( ) . associated_document ( ) . url ( ) . port_or_default ( ) ) ;
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-reload
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : reload )
2020-05-18 22:05:13 +02:00
{
2020-06-20 13:55:34 +02:00
auto & window = static_cast < WindowObject & > ( global_object ) ;
2020-05-18 22:05:13 +02:00
window . impl ( ) . did_call_location_reload ( { } ) ;
return JS : : js_undefined ( ) ;
}
2022-03-04 23:35:34 +01:00
// https://html.spec.whatwg.org/multipage/history.html#dom-location-replace
2021-10-31 08:21:02 -04:00
JS_DEFINE_NATIVE_FUNCTION ( LocationObject : : replace )
2021-10-03 23:31:52 +02:00
{
auto & window = static_cast < WindowObject & > ( global_object ) ;
2021-10-31 08:21:02 -04:00
auto url = TRY ( vm . argument ( 0 ) . to_string ( global_object ) ) ;
2021-10-03 23:31:52 +02:00
// FIXME: This needs spec compliance work.
window . impl ( ) . did_call_location_replace ( { } , move ( url ) ) ;
return JS : : js_undefined ( ) ;
}
2021-09-12 14:54:17 +01:00
// https://html.spec.whatwg.org/multipage/history.html#location-setprototypeof
2021-09-28 23:54:42 +01:00
JS : : ThrowCompletionOr < bool > LocationObject : : internal_set_prototype_of ( Object * prototype )
2021-09-12 14:54:17 +01:00
{
// 1. Return ! SetImmutablePrototype(this, V).
2021-10-03 19:52:13 +01:00
return MUST ( set_immutable_prototype ( prototype ) ) ;
2021-09-12 14:54:17 +01:00
}
// https://html.spec.whatwg.org/multipage/history.html#location-isextensible
2021-09-29 00:02:05 +01:00
JS : : ThrowCompletionOr < bool > LocationObject : : internal_is_extensible ( ) const
2021-09-12 14:54:17 +01:00
{
// 1. Return true.
return true ;
}
// https://html.spec.whatwg.org/multipage/history.html#location-preventextensions
2021-09-29 00:13:41 +01:00
JS : : ThrowCompletionOr < bool > LocationObject : : internal_prevent_extensions ( )
2021-09-12 14:54:17 +01:00
{
// 1. Return false.
return false ;
2020-05-18 21:42:40 +02:00
}
}