diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp index a616a69d8d..acb1f1ca8f 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -68,6 +68,7 @@ void WindowObject::initialize_global_object() define_native_accessor("top", top_getter, nullptr, JS::Attribute::Enumerable); define_native_accessor("parent", parent_getter, {}, JS::Attribute::Enumerable); define_native_accessor("document", document_getter, {}, JS::Attribute::Enumerable); + define_native_accessor("name", name_getter, name_setter, JS::Attribute::Enumerable); define_native_accessor("history", history_getter, {}, JS::Attribute::Enumerable); define_native_accessor("performance", performance_getter, {}, JS::Attribute::Enumerable); define_native_accessor("crypto", crypto_getter, {}, JS::Attribute::Enumerable); @@ -657,6 +658,19 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::session_storage_getter) return wrap(global_object, *impl->session_storage()); } +JS_DEFINE_NATIVE_FUNCTION(WindowObject::name_getter) +{ + auto* impl = TRY(impl_from(vm, global_object)); + return JS::js_string(vm, impl->name()); +} + +JS_DEFINE_NATIVE_FUNCTION(WindowObject::name_setter) +{ + auto* impl = TRY(impl_from(vm, global_object)); + impl->set_name(TRY(vm.argument(0).to_string(global_object))); + return JS::js_undefined(); +} + #define __ENUMERATE(attribute, event_name) \ JS_DEFINE_NATIVE_FUNCTION(WindowObject::attribute##_getter) \ { \ diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.h b/Userland/Libraries/LibWeb/Bindings/WindowObject.h index 3cf9939b58..f50780828e 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.h @@ -80,6 +80,9 @@ private: JS_DECLARE_NATIVE_FUNCTION(document_getter); + JS_DECLARE_NATIVE_FUNCTION(name_getter); + JS_DECLARE_NATIVE_FUNCTION(name_setter); + JS_DECLARE_NATIVE_FUNCTION(performance_getter); JS_DECLARE_NATIVE_FUNCTION(history_getter); JS_DECLARE_NATIVE_FUNCTION(screen_getter); diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index c9ea049b27..28650df280 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -80,6 +80,19 @@ void BrowsingContext::set_active_document(DOM::Document* document) if (m_active_document) m_active_document->detach_from_browsing_context({}, *this); + // https://html.spec.whatwg.org/multipage/browsing-the-web.html#resetBCName + // FIXME: The rest of set_active_document does not follow the spec very closely, this just implements the + // relevant steps for resetting the browsing context name and should be updated closer to the spec once + // the other parts of history handling/navigating are implemented + // 3. If newDocument's origin is not same origin with the current entry's document's origin, then: + if (!document || !m_active_document || !document->origin().is_same_origin(m_active_document->origin())) { + // 3. If the browsing context is a top-level browsing context, but not an auxiliary browsing context + // whose disowned is false, then set the browsing context's name to the empty string. + // FIXME: this is not checking the second part of the condition yet + if (is_top_level()) + m_name = String::empty(); + } + m_active_document = document; if (m_active_document) { diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h index 067303e2be..70b938551f 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h @@ -107,6 +107,9 @@ public: RefPtr currently_focused_area(); + String const& name() const { return m_name; } + void set_name(String const& name) { m_name = name; } + private: explicit BrowsingContext(Page&, HTML::BrowsingContextContainer*); @@ -129,6 +132,7 @@ private: HashTable m_viewport_clients; HashMap m_frame_nesting_levels; + String m_name; }; } diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index 255f699457..9db4f3dc7f 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -613,4 +613,24 @@ DOM::ExceptionOr Window::post_message(JS::Value message, String const&) return {}; } +// https://html.spec.whatwg.org/multipage/window-object.html#dom-name +String Window::name() const +{ + // 1. If this's browsing context is null, then return the empty string. + if (!browsing_context()) + return String::empty(); + // 2. Return this's browsing context's name. + return browsing_context()->name(); +} + +// https://html.spec.whatwg.org/multipage/window-object.html#dom-name +void Window::set_name(String const& name) +{ + // 1. If this's browsing context is null, then return. + if (!browsing_context()) + return; + // 2. Set this's browsing context's name to the given value. + browsing_context()->set_name(name); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index 252e7da939..41a5a1f0af 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -110,6 +110,9 @@ public: DOM::ExceptionOr post_message(JS::Value, String const& target_origin); + String name() const; + void set_name(String const&); + private: explicit Window(DOM::Document&);