From e377e28fd29081f809f934c9107a2d742dae7718 Mon Sep 17 00:00:00 2001 From: networkException Date: Tue, 6 Sep 2022 19:56:29 +0200 Subject: [PATCH] LibWeb: Implement window.length --- .../Libraries/LibWeb/HTML/BrowsingContext.cpp | 22 +++++++++++++++++ .../Libraries/LibWeb/HTML/BrowsingContext.h | 4 ++++ Userland/Libraries/LibWeb/HTML/Window.cpp | 24 +++++++++++++++++++ Userland/Libraries/LibWeb/HTML/Window.h | 3 +++ 4 files changed, 53 insertions(+) diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index 28fdb48a01d..a68ce1c19a1 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -742,6 +742,28 @@ BrowsingContext* BrowsingContext::choose_a_browsing_context(StringView name, boo return chosen; } +// https://html.spec.whatwg.org/multipage/browsers.html#document-tree-child-browsing-context +size_t BrowsingContext::document_tree_child_browsing_context_count() const +{ + size_t count = 0; + + // A browsing context child is a document-tree child browsing context of parent if child is a child browsing context and child's container is in a document tree. + for_each_child([this, &count](BrowsingContext const& child) { + if (child.is_child_of(*this) && child.container()->in_a_document_tree()) + ++count; + }); + + return count; +} + +// https://html.spec.whatwg.org/multipage/browsers.html#child-browsing-context +bool BrowsingContext::is_child_of(BrowsingContext const& parent) const +{ + // A browsing context child is said to be a child browsing context of another browsing context parent, + // if child's container document is non-null and child's container document's browsing context is parent. + return container_document() && container_document()->browsing_context() == &parent; +} + // https://html.spec.whatwg.org/multipage/dom.html#still-on-its-initial-about:blank-document bool BrowsingContext::still_on_its_initial_about_blank_document() const { diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h index 1185caf3a95..55ae5444d92 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h @@ -80,6 +80,10 @@ public: BrowsingContext* choose_a_browsing_context(StringView name, bool noopener); + size_t document_tree_child_browsing_context_count() const; + + bool is_child_of(BrowsingContext const&) const; + HTML::BrowsingContextContainer* container() { return m_container; } HTML::BrowsingContextContainer const* container() const { return m_container; } diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index db68182a714..5cd97faf811 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -794,6 +794,7 @@ void Window::initialize(JS::Realm& realm) define_native_accessor(realm, "pageXOffset", scroll_x_getter, {}, attr); define_native_accessor(realm, "scrollY", scroll_y_getter, {}, attr); define_native_accessor(realm, "pageYOffset", scroll_y_getter, {}, attr); + define_native_accessor(realm, "length", length_getter, {}, attr); define_native_function(realm, "scroll", scroll, 2, attr); define_native_function(realm, "scrollTo", scroll, 2, attr); @@ -1074,6 +1075,29 @@ JS_DEFINE_NATIVE_FUNCTION(Window::btoa) return JS::js_string(vm, move(encoded)); } +// https://html.spec.whatwg.org/multipage/window-object.html#number-of-document-tree-child-browsing-contexts +JS::ThrowCompletionOr Window::document_tree_child_browsing_context_count() const +{ + auto* impl = TRY(impl_from(vm())); + + // 1. If W's browsing context is null, then return 0. + auto* this_browsing_context = impl->associated_document().browsing_context(); + if (!this_browsing_context) + return 0; + + // 2. Return the number of document-tree child browsing contexts of W's browsing context. + return this_browsing_context->document_tree_child_browsing_context_count(); +} + +// https://html.spec.whatwg.org/multipage/window-object.html#dom-length +JS_DEFINE_NATIVE_FUNCTION(Window::length_getter) +{ + auto* impl = TRY(impl_from(vm)); + + // The length getter steps are to return the number of document-tree child browsing contexts of this. + return TRY(impl->document_tree_child_browsing_context_count()); +} + // https://html.spec.whatwg.org/multipage/browsers.html#dom-top JS_DEFINE_NATIVE_FUNCTION(Window::top_getter) { diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index 587cc8616f6..5ce1989480d 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -52,6 +52,8 @@ public: HTML::BrowsingContext const* browsing_context() const; HTML::BrowsingContext* browsing_context(); + JS::ThrowCompletionOr document_tree_child_browsing_context_count() const; + void alert_impl(String const&); bool confirm_impl(String const&); String prompt_impl(String const&, String const&); @@ -201,6 +203,7 @@ public: Bindings::CrossOriginPropertyDescriptorMap& cross_origin_property_descriptor_map() { return m_cross_origin_property_descriptor_map; } private: + JS_DECLARE_NATIVE_FUNCTION(length_getter); JS_DECLARE_NATIVE_FUNCTION(top_getter); JS_DECLARE_NATIVE_FUNCTION(document_getter);