This could potentially be sped up by tracking the up to three different
ranges of characters known to be digits. This would save the double
parser from checking whether these are digits and because it has the
size it can use the fast parsing method.
It's potentially unsafe to access `m_root` in the destructor since it
may have been swept, so move unregistration of the NodeIterator into a
GC finalizer instead.
It's not safe to unregister ImageBox from the browsing context in the
destructor (since the browsing context may have already been swept and
destroyed).
Now that the layout tree is also GC-allocated, we can't be messing with
it from the DOM::Node destructor. Move everything to a GC finalizer
so we know it runs before the GC sweep phase.
Now that both the layout tree and browsing context are GC-allocated,
we can formalize their relationship a bit better by having layout
nodes keep a NonnullGCPtr to the browsing context.
This makes the previously-indirect link direct, removing an unpleasant
"how do we know the browsing context is alive" question when accessing
it from the layout tree.
This caused `Object.getOwnPropertyNames(window)` to throw, as the
`this` value is `Object`.
All users of document_tree_child_browsing_context_count call it on an
existing Window impl, including WP::internal_own_property_keys, so
getting the impl from the JS VM is not necessary.
Since SafeFunction strongly protects all of its captures, we can't
capture `this` when activating an event handler since that creates a
reference cycle and we end up leaking the entire world.
This removes a set of complex reference cycles between DOM, layout tree
and browsing context.
It also makes lifetimes much easier to reason about, as the DOM and
layout trees are now free to keep each other alive.
(And BrowsingContextGroup had to come along for the ride as well.)
This solves a number of nasty reference cycles between browsing
contexts, history items, and their documents.
This fixes an issue where GC would kill the internal realm if it ran at
the wrong time during startup. Found by aggressively GC'ing between
every allocation.
This prevents a reference cycle between a HTMLParser opened via
document.open() and the document. It was one of many things keeping
some documents alive indefinitely.
Due to the way we lazily construct prototypes and constructors for web
platform interfaces, it's possible for nested GC allocation to occur
while GC objects have been allocated but not fully constructed.
If the garbage collector ends up running in this state, it may attempt
to call JS::Cell::visit_edges() on an object whose vtable pointer hasn't
been set up yet.
This patch works around the issue by deferring GC while intrinsics are
being brought up. Furthermore, we also create a dummy global object for
the internal realm, and populate it with intrinsics. This works around
the same issue happening when allocating something (like the default UA
stylesheets) in the internal realm.
These solutions are pretty hacky and sad, so I've left FIXMEs about
finding a nicer way.
Instead of storing two JS::Handles into the DOM, we can combine them
into a single one.
If the layout node is anonymous, m_dom_node points to the DOM::Document.
Otherwise, m_dom_node points to the associated DOM node.
The anonymous state is moved to an m_anonymous boolean member.
This cuts the number of JS::Handles created by the layout tree in half
(and shrinks Layout::Node by 8 bytes).
When a new document becomes the active document of a browsing context,
we now notify the old document, allowing it to tear down its layout
tree. In the future, there might be more cleanups we'd like to do here.
Capturing a WeakPtr to a GC-allocated object in a JS::SafeFunction is
basically pointless, since the SafeFunction mechanism will then keep
the object alive anyway.
These functions were previously ad-hoc and returned the active
document's window. They now correctly teturn the browsing context's
WindowProxy instead.
When sizing grid children we now also check whether
calculate_min_content_height() adds to the computed height. Previously
we were using the result of layout_inner() which led to zero height of
not specifically sized block level children.
This fixes a height issue with our GitHub page. The footer is now at
its place and is not hovering over other content anymore.
This changes the signature of LoadRequest::set_body() to take by value
and then use move semantics to move the contents of the ByteBuffer.
This is done to avoid the fallible copy constructor of ByteBuffer.