diff --git a/Tests/LibWeb/Text/expected/HTML/Window-named-properties-iframe.txt b/Tests/LibWeb/Text/expected/HTML/Window-named-properties-iframe.txt
new file mode 100644
index 0000000000..1b00f1e3cc
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/HTML/Window-named-properties-iframe.txt
@@ -0,0 +1,2 @@
+ true
+true
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/HTML/Window-named-properties-iframe.html b/Tests/LibWeb/Text/input/HTML/Window-named-properties-iframe.html
new file mode 100644
index 0000000000..d58d8edc6c
--- /dev/null
+++ b/Tests/LibWeb/Text/input/HTML/Window-named-properties-iframe.html
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp
index 2ef520ca10..4eb7b56cda 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Window.cpp
@@ -1395,4 +1395,46 @@ JS::NonnullGCPtr Window::custom_elements()
return JS::NonnullGCPtr { *m_custom_element_registry };
}
+// https://html.spec.whatwg.org/#document-tree-child-navigable-target-name-property-set
+OrderedHashMap> Window::document_tree_child_navigable_target_name_property_set()
+{
+ // The document-tree child navigable target name property set of a Window object window is the return value of running these steps:
+
+ // 1. Let children be the document-tree child navigables of window's associated Document.
+ auto children = associated_document().document_tree_child_navigables();
+
+ // 2. Let firstNamedChildren be an empty ordered set.
+ OrderedHashMap> first_named_children;
+
+ // 3. For each navigable of children:
+ for (auto const& navigable : children) {
+ // 1. Let name be navigable's target name.
+ auto const& name = navigable->target_name();
+
+ // 2. If name is the empty string, then continue.
+ if (name.is_empty())
+ continue;
+
+ // 3. If firstNamedChildren contains a navigable whose target name is name, then continue.
+ if (first_named_children.contains(name))
+ continue;
+
+ // 4. Append navigable to firstNamedChildren.
+ (void)first_named_children.set(name, *navigable);
+ }
+
+ // 4. Let names be an empty ordered set.
+ OrderedHashMap> names;
+
+ // 5. For each navigable of firstNamedChildren:
+ for (auto const& [name, navigable] : first_named_children) {
+ // 1. Let name be navigable's target name.
+ // 2. If navigable's active document's origin is same origin with window's relevant settings object's origin, then append name to names.
+ if (navigable->active_document()->origin().is_same_origin(relevant_settings_object(*this).origin()))
+ names.set(name, *navigable);
+ }
+
+ return names;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h
index 0a1be8341e..6d090805ea 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.h
+++ b/Userland/Libraries/LibWeb/HTML/Window.h
@@ -191,6 +191,8 @@ public:
static void set_internals_object_exposed(bool);
+ [[nodiscard]] OrderedHashMap> document_tree_child_navigable_target_name_property_set();
+
private:
explicit Window(JS::Realm&);
diff --git a/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp b/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp
index 99fe3c0133..5d9efbce4f 100644
--- a/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp
+++ b/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp
@@ -113,10 +113,11 @@ JS::ThrowCompletionOr> WindowProxy::internal_ge
if (property.has_value())
return property;
- // FIXME: 6. If property is undefined and P is in W's document-tree child browsing context name property set, then:
- if (false) {
- // FIXME: 1. Let value be the WindowProxy object of the named object of W with the name P.
- auto value = JS::js_undefined();
+ // 6. If property is undefined and P is in W's document-tree child navigable target name property set, then:
+ auto navigable_property_set = m_window->document_tree_child_navigable_target_name_property_set();
+ if (auto navigable = navigable_property_set.get(property_key.to_string().view()); navigable.has_value()) {
+ // 1. Let value be the active WindowProxy of the named object of W with the name P.
+ auto value = navigable.value()->active_window_proxy();
// 2. Return PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }.
// NOTE: The reason the property descriptors are non-enumerable, despite this mismatching the same-origin behavior, is for compatibility with existing web content. See issue #3183 for details.