Instead of bothering the GC heap with a bunch of DOMRect allocations,
we can just pass around CSSPixelRect internally in many cases.
Before this change, we were generating so much DOMRect garbage that
we had to do a garbage collection *every frame* on the Immich demo.
This was due to the large number of intersection observers checked.
We still need to relax way more when idle, but for comparison, before
this change, when doing nothing for 10 seconds on Immich, we'd spend
2.5 seconds updating intersection observers. After this change, we now
spend 600 ms.
The existing `::unite_horizontally()` and `::unite_vertically()` tests
did not properly test the edge cases where left/top in the Rect were
updated, so they get re-arranged a bit.
This accurately reflects the spec it's implementing. This algorithm is
used in 5 spots in the spec but the old buggy behavior was never
triggered:
* In both ::extract() and ::clone_the_contents(), invocations to this
method are guarded by a check to see if the start node is the
inclusive ancestor of the end node, or vice versa - effectively
resulting in the inequality checks to be accidentally correct.
* In ::surround_contents(), we forego the usage of this algorithm as
stated in the spec, and instead use a correct and more optimized
version that simply compares the start and end nodes.
A lot of words to say: no functional changes :^)
Previously, it was assumed that nodes must share the same root, prior
to the calculation of their relative boundary point positions. This is
no longer the case, since `Selection.setBaseAndExtent()` now accepts
anchor and focus nodes that may be in different shadow trees.
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
The main motivation behind this is to remove JS specifics of the Realm
from the implementation of the Heap.
As a side effect of this change, this is a bit nicer to read than the
previous approach, and in my opinion, also makes it a little more clear
that this method is specific to a JavaScript Realm.