Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/Page/EventHandler.cpp (C++)

Code before:
        auto const affine_transform = Gfx::extract_2d_affine_transform(paintable_box.transform().inverse());

        auto const& origin = paintable_box.transform_origin();
        Gfx::Point<float> const precision_origin = {
            origin.x().to_double(),
            origin.y().to_double()
        };

        precision_offset.translate_by(-precision_origin);
        precision_offset.transform_by(affine_transform);
        precision_offset.translate_by(precision_origin);
    }

    // relative to the origin of the padding edge of the target node
    auto const top_left_of_layout_node = paintable.box_type_agnostic_position();
    CSSPixelPoint offset = {
        CSSPixels(precision_offset.x()),
        CSSPixels(precision_offset.y())
    };
    offset -= top_left_of_layout_node;

    // and terminate these steps.
    return offset;
}

static CSSPixelPoint compute_position_in_nested_navigable(Painting::Paintable const& paintable, CSSPixelPoint viewport_position)
{
    auto& paintable_box = as<Painting::PaintableBox>(paintable);
    auto local_position = paintable_box.transform_to_local_coordinates(viewport_position);
    return local_position - paintable_box.absolute_rect().location();
}

// https://drafts.csswg.org/css-ui/#propdef-user-select
static void set_user_selection(GC::Ptr<DOM::Node> anchor_node, size_t anchor_offset, GC::Ptr<DOM::Node> focus_node, size_t focus_offset, Selection::Selection* selection, CSS::UserSelect user_select)
{
    // https://drafts.csswg.org/css-ui/#valdef-user-select-contain
    // NOTE: This is clamping the focus node to any node with user-select: contain that stands between it and the anchor node.
    if (focus_node != anchor_node) {
        // UAs must not allow a selection which is started in this element to be extended outside of this element.
        auto potential_contain_node = anchor_node;

        // NOTE: The way we do this is searching up the tree from the anchor, to find 'this element', i.e. its nearest contain ancestor.
        //       We stop the search early when we reach an element that contains both the anchor and the focus node, as this means they
        //       are inside the same contain element, or not in a contain element at all.
        //       This takes care of the "selection trying to escape from a contain" case.
        while (
            (!potential_contain_node->is_element() || potential_contain_node->layout_node()->user_select_used_value() != CSS::UserSelect::Contain) && potential_contain_node->parent() && !potential_contain_node->is_inclusive_ancestor_of(*focus_node)) {
            potential_contain_node = potential_contain_node->parent();
        }

        if (

Review comment (suggestion):
lets make this function accept `NavigableContainerViewportPaintable`, so it's explicit that it's not suitable for anything else.

Code after:
        auto const& paintable_box = static_cast<Painting::PaintableBox const&>(paintable);
        auto const affine_transform = Gfx::extract_2d_affine_transform(paintable_box.transform().inverse());

        auto const& origin = paintable_box.transform_origin();
        Gfx::Point<float> const precision_origin = {
            origin.x().to_double(),
            origin.y().to_double()
        };

        precision_offset.translate_by(-precision_origin);
        precision_offset.transform_by(affine_transform);
        precision_offset.translate_by(precision_origin);
    }

    // relative to the origin of the padding edge of the target node
    auto const top_left_of_layout_node = paintable.box_type_agnostic_position();
    CSSPixelPoint offset = {
        CSSPixels(precision_offset.x()),
        CSSPixels(precision_offset.y())
    };
    offset -= top_left_of_layout_node;

    // and terminate these steps.
    return offset;
}

static CSSPixelPoint compute_position_in_nested_navigable(Painting::NavigableContainerViewportPaintable const& paintable, CSSPixelPoint viewport_position)
{
    auto local_position = paintable.transform_to_local_coordinates(viewport_position);
    return local_position - paintable.absolute_rect().location();
}

// https://drafts.csswg.org/css-ui/#propdef-user-select
static void set_user_selection(GC::Ptr<DOM::Node> anchor_node, size_t anchor_offset, GC::Ptr<DOM::Node> focus_node, size_t focus_offset, Selection::Selection* selection, CSS::UserSelect user_select)
{
    // https://drafts.csswg.org/css-ui/#valdef-user-select-contain
    // NOTE: This is clamping the focus node to any node with user-select: contain that stands between it and the anchor node.
    if (focus_node != anchor_node) {
        // UAs must not allow a selection which is started in this element to be extended outside of this element.
        auto potential_contain_node = anchor_node;

        // NOTE: The way we do this is searching up the tree from the anchor, to find 'this element', i.e. its nearest contain ancestor.
        //       We stop the search early when we reach an element that contains both the anchor and the focus node, as this means they
        //       are inside the same contain element, or not in a contain element at all.
        //       This takes care of the "selection trying to escape from a contain" case.
        while (
            (!potential_contain_node->is_element() || potential_contain_node->layout_node()->user_select_used_value() != CSS::UserSelect::Contain) && potential_contain_node->parent() && !potential_contain_node->is_inclusive_ancestor_of(*focus_node)) {
            potential_contain_node = potential_contain_node->parent();
        }

        if (