ladybird/Libraries/LibWeb/HTML/BrowsingContextGroup.cpp
Psychpsyo 864018b3dc LibWeb: Don't lie about browsing context being top-level
The VERIFY() this was triggering wasn't actually to spec, and by the
time it gets encountered, the browsing context isn't technically a top-
level context yet, because it has just been created and the definition
of a top-level browsing context requires the document to be the
navigables active document, which it only becomes once a history entry
has been created for it.

Therefore we cannot just verify a top-level browsing context actually
being a top-level browsing context when inserting it into the group,
because that happens to early in its life-cycle as a top-level context.

This makes it so that JS console commands from the devtools no longer
get sent to the last created nested frame in the tab, because nested
frames no longer pretend to have a top-level browsing context.
2026-02-06 10:52:31 +00:00

69 lines
2.3 KiB
C++

/*
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/HTML/BrowsingContext.h>
#include <LibWeb/HTML/BrowsingContextGroup.h>
#include <LibWeb/Page/Page.h>
namespace Web::HTML {
GC_DEFINE_ALLOCATOR(BrowsingContextGroup);
// https://html.spec.whatwg.org/multipage/browsers.html#browsing-context-group-set
static HashTable<GC::Ref<BrowsingContextGroup>>& user_agent_browsing_context_group_set()
{
static HashTable<GC::Ref<BrowsingContextGroup>> set;
return set;
}
BrowsingContextGroup::BrowsingContextGroup(GC::Ref<Web::Page> page)
: m_page(page)
{
user_agent_browsing_context_group_set().set(*this);
}
void BrowsingContextGroup::finalize()
{
Base::finalize();
user_agent_browsing_context_group_set().remove(*this);
}
void BrowsingContextGroup::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_page);
visitor.visit(m_browsing_context_set);
}
// https://html.spec.whatwg.org/multipage/document-sequences.html#creating-a-new-browsing-context-group-and-document
auto BrowsingContextGroup::create_a_new_browsing_context_group_and_document(GC::Ref<Page> page) -> WebIDL::ExceptionOr<BrowsingContextGroupAndDocument>
{
// 1. Let group be a new browsing context group.
// 2. Append group to the user agent's browsing context group set.
auto group = Bindings::main_thread_vm().heap().allocate<BrowsingContextGroup>(page);
// 3. Let browsingContext and document be the result of creating a new browsing context and document with null, null, and group.
auto [browsing_context, document] = TRY(BrowsingContext::create_a_new_browsing_context_and_document(page, nullptr, nullptr, group));
// 4. Append browsingContext to group.
group->append(browsing_context);
// 5. Return group and document.
return BrowsingContextGroupAndDocument { group, document };
}
// https://html.spec.whatwg.org/multipage/browsers.html#bcg-append
void BrowsingContextGroup::append(BrowsingContext& browsing_context)
{
// 1. Append browsingContext to group's browsing context set.
m_browsing_context_set.set(browsing_context);
// 2. Set browsingContext's group to group.
browsing_context.set_group(this);
}
}