/*
 * Copyright (C) 2004-2020 Apple Inc. All rights reserved.
 * Portions Copyright (c) 2011 Motorola Mobility, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "VisiblePosition.h"

#include "BoundaryPoint.h"
#include "CaretRectComputation.h"
#include "Document.h"
#include "Editing.h"
#include "FloatQuad.h"
#include "HTMLElement.h"
#include "HTMLHtmlElement.h"
#include "HTMLNames.h"
#include "InlineIteratorBox.h"
#include "InlineIteratorLine.h"
#include "InlineRunAndOffset.h"
#include "Logging.h"
#include "Range.h"
#include "RenderBlockFlow.h"
#include "SimpleRange.h"
#include "Text.h"
#include "TextIterator.h"
#include "VisibleUnits.h"
#include <stdio.h>
#include <wtf/text/CString.h>
#include <wtf/text/TextStream.h>

namespace WebCore {

using namespace HTMLNames;

VisiblePosition::VisiblePosition(const Position& position, Affinity affinity)
    : m_deepPosition { canonicalPosition(position) }
{
    if (affinity == Affinity::Upstream && !isNull()) {
        auto upstreamCopy = *this;
        upstreamCopy.m_affinity = Affinity::Upstream;
        if (!inSameLine(*this, upstreamCopy))
            m_affinity = Affinity::Upstream;
    }
}

VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule, bool* reachedBoundary) const
{
    if (reachedBoundary)
        *reachedBoundary = false;
    // FIXME: Support CanSkipEditingBoundary
    ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary);
    VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affinity);

    if (rule == CanCrossEditingBoundary)
        return next;

    return honorEditingBoundaryAtOrAfter(next, reachedBoundary);
}

VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule, bool* reachedBoundary) const
{
    if (reachedBoundary)
        *reachedBoundary = false;
    // FIXME: Support CanSkipEditingBoundary
    ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary);
    // find first previous DOM position that is visible
    Position pos = previousVisuallyDistinctCandidate(m_deepPosition);

    // return null visible position if there is no previous visible position
    if (pos.atStartOfTree()) {
        if (reachedBoundary)
            *reachedBoundary = true;
        return VisiblePosition();
    }

    VisiblePosition prev = pos;
    ASSERT(prev != *this);

#if ASSERT_ENABLED
    // We should always be able to make the affinity downstream, because going previous from an
    // upstream position can never yield another upstream position unless line wrap length is 0.
    if (prev.isNotNull() && m_affinity == Affinity::Upstream) {
        auto upstreamCopy = prev;
        upstreamCopy.setAffinity(Affinity::Upstream);
        ASSERT(inSameLine(upstreamCopy, prev));
    }
#endif

    if (rule == CanCrossEditingBoundary)
        return prev;
    
    return honorEditingBoundaryAtOrBefore(prev, reachedBoundary);
}

Position VisiblePosition::leftVisuallyDistinctCandidate() const
{
    Position p = m_deepPosition;
    if (p.isNull())
        return Position();

    Position downstreamStart = p.downstream();
    TextDirection primaryDirection = p.primaryDirection();

    InlineIterator::LineLogicalOrderCache orderCache;

    while (true) {
        auto [run, offset] = p.inlineRunAndOffset(m_affinity, primaryDirection);
        if (!run)
            return primaryDirection == TextDirection::LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);

        auto* renderer = &run->renderer();

        while (true) {
            if ((renderer->isReplaced() || renderer->isBR()) && offset == run->rightmostCaretOffset())
                return run->isLeftToRightDirection() ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);

            if (!renderer->node()) {
                run.traversePreviousOnLine();
                if (!run)
                    return primaryDirection == TextDirection::LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
                renderer = &run->renderer();
                offset = run->rightmostCaretOffset();
                continue;
            }

            // Note that this may underflow the (unsigned) offset. This is fine and handled below.
            offset = run->isLeftToRightDirection() ? renderer->previousOffset(offset) : renderer->nextOffset(offset);

            auto caretMinOffset = run->minimumCaretOffset();
            auto caretMaxOffset = run->maximumCaretOffset();

            if (offset > caretMinOffset && offset < caretMaxOffset)
                break;

            if (offset != run->leftmostCaretOffset()) {
                // Overshot to the left.
                auto previousRun = run->previousOnLineIgnoringLineBreak();
                if (!previousRun) {
                    Position positionOnLeft = primaryDirection == TextDirection::LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
                    auto runOnLeft = positionOnLeft.inlineRunAndOffset(m_affinity, primaryDirection).run;
                    if (runOnLeft && runOnLeft->line() == run->line())
                        return Position();
                    return positionOnLeft;
                }

                // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                run = previousRun;
                renderer = &run->renderer();
                offset = previousRun->rightmostCaretOffset();
                continue;
            }

            unsigned char level = run->bidiLevel();
            auto previousRun = run->previousOnLine();

            if (run->direction() == primaryDirection) {
                if (!previousRun) {
                    auto logicalStart = primaryDirection == TextDirection::LTR
                        ? InlineIterator::firstLeafOnLineInLogicalOrderWithNode(run->line(), orderCache)
                        : InlineIterator::lastLeafOnLineInLogicalOrderWithNode(run->line(), orderCache);
                    if (logicalStart) {
                        run = logicalStart;
                        renderer = &run->renderer();
                        offset = primaryDirection == TextDirection::LTR ? run->minimumCaretOffset() : run->maximumCaretOffset();
                    }
                    break;
                }
                if (previousRun->bidiLevel() >= level)
                    break;

                level = previousRun->bidiLevel();

                auto nextRun = run;
                do {
                    nextRun.traverseNextOnLine();
                } while (nextRun && nextRun->bidiLevel() > level);

                if (nextRun && nextRun->bidiLevel() == level)
                    break;

                run = previousRun;
                renderer = &run->renderer();
                offset = run->rightmostCaretOffset();
                if (run->direction() == primaryDirection)
                    break;
                continue;
            }

            while (previousRun && !previousRun->renderer().node())
                previousRun.traversePreviousOnLine();

            if (previousRun) {
                run = previousRun;
                renderer = &run->renderer();
                offset = run->rightmostCaretOffset();
                if (run->bidiLevel() > level) {
                    do {
                        previousRun = previousRun.traversePreviousOnLine();
                    } while (previousRun && previousRun->bidiLevel() > level);

                    if (!previousRun || previousRun->bidiLevel() < level)
                        continue;
                }
            } else {
                // Trailing edge of a secondary run. Set to the leading edge of the entire run.
                while (true) {
                    while (auto nextRun = run->nextOnLine()) {
                        if (nextRun->bidiLevel() < level)
                            break;
                        run = nextRun;
                    }
                    if (run->bidiLevel() == level)
                        break;
                    level = run->bidiLevel();
                    while (auto previousRun = run->previousOnLine()) {
                        if (previousRun->bidiLevel() < level)
                            break;
                        run = previousRun;
                    }
                    if (run->bidiLevel() == level)
                        break;
                    level = run->bidiLevel();
                }
                renderer = &run->renderer();
                offset = primaryDirection == TextDirection::LTR ? run->minimumCaretOffset() : run->maximumCaretOffset();
            }
            break;
        }

        p = makeDeprecatedLegacyPosition(renderer->node(), offset);

        if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
            return p;

        ASSERT(p != m_deepPosition);
    }
}

VisiblePosition VisiblePosition::left(bool stayInEditableContent, bool* reachedBoundary) const
{
    if (reachedBoundary)
        *reachedBoundary = false;
    Position pos = leftVisuallyDistinctCandidate();
    // FIXME: Why can't we move left from the last position in a tree?
    if (pos.atStartOfTree() || pos.atEndOfTree()) {
        if (reachedBoundary)
            *reachedBoundary = true;
        return VisiblePosition();
    }

    VisiblePosition left = pos;
    ASSERT(left != *this);

    if (!stayInEditableContent)
        return left;

    // FIXME: This may need to do something different from "before".
    return honorEditingBoundaryAtOrBefore(left, reachedBoundary);
}

Position VisiblePosition::rightVisuallyDistinctCandidate() const
{
    Position p = m_deepPosition;
    if (p.isNull())
        return Position();

    Position downstreamStart = p.downstream();
    TextDirection primaryDirection = p.primaryDirection();

    InlineIterator::LineLogicalOrderCache orderCache;

    while (true) {
        auto [run, offset] = p.inlineRunAndOffset(m_affinity, primaryDirection);
        if (!run)
            return primaryDirection == TextDirection::LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);

        auto* renderer = &run->renderer();

        while (true) {
            if ((renderer->isReplaced() || renderer->isBR()) && offset == run->leftmostCaretOffset())
                return run->isLeftToRightDirection() ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);

            if (!renderer->node()) {
                run.traverseNextOnLine();
                if (!run)
                    return primaryDirection == TextDirection::LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
                renderer = &run->renderer();
                offset = run->leftmostCaretOffset();
                continue;
            }

            // Note that this may underflow the (unsigned) offset. This is fine and handled below.
            offset = run->isLeftToRightDirection() ? renderer->nextOffset(offset) : renderer->previousOffset(offset);

            auto caretMinOffset = run->minimumCaretOffset();
            auto caretMaxOffset = run->maximumCaretOffset();

            if (offset > caretMinOffset && offset < caretMaxOffset)
                break;

            if (offset != run->rightmostCaretOffset()) {
                // Overshot to the right.
                auto nextRun = run->nextOnLineIgnoringLineBreak();
                if (!nextRun) {
                    Position positionOnRight = primaryDirection == TextDirection::LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
                    auto runOnRight = positionOnRight.inlineRunAndOffset(m_affinity, primaryDirection).run;
                    if (runOnRight && runOnRight->line() == run->line())
                        return Position();
                    return positionOnRight;
                }

                // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                run = nextRun;
                renderer = &run->renderer();
                offset = nextRun->leftmostCaretOffset();
                continue;
            }

            unsigned char level = run->bidiLevel();
            auto nextRun = run->nextOnLine();

            if (run->direction() == primaryDirection) {
                if (!nextRun) {
                    auto logicalEnd = primaryDirection == TextDirection::LTR
                        ? InlineIterator::lastLeafOnLineInLogicalOrderWithNode(run->line(), orderCache)
                        : InlineIterator::firstLeafOnLineInLogicalOrderWithNode(run->line(), orderCache);

                    if (logicalEnd) {
                        run = logicalEnd;
                        renderer = &run->renderer();
                        offset = primaryDirection == TextDirection::LTR ? run->maximumCaretOffset() : run->minimumCaretOffset();
                    }
                    break;
                }

                if (nextRun->bidiLevel() >= level)
                    break;

                level = nextRun->bidiLevel();

                auto previousRun = run;
                do {
                    previousRun.traversePreviousOnLine();
                } while (previousRun && previousRun->bidiLevel() > level);

                if (previousRun && previousRun->bidiLevel() == level) // For example, abc FED 123 ^ CBA
                    break;

                // For example, abc 123 ^ CBA or 123 ^ CBA abc
                run = nextRun;
                renderer = &run->renderer();
                offset = run->leftmostCaretOffset();
                if (run->direction() == primaryDirection)
                    break;
                continue;
            }

            while (nextRun && !nextRun->renderer().node())
                nextRun.traverseNextOnLine();

            if (nextRun) {
                run = nextRun;
                renderer = &run->renderer();
                offset = run->leftmostCaretOffset();

                if (run->bidiLevel() > level) {
                    do {
                        nextRun.traverseNextOnLine();
                    } while (nextRun && nextRun->bidiLevel() > level);

                    if (!nextRun || nextRun->bidiLevel() < level)
                        continue;
                }
            } else {
                // Trailing edge of a secondary run. Set to the leading edge of the entire run.
                while (true) {
                    while (auto previousRun = run->previousOnLine()) {
                        if (previousRun->bidiLevel() < level)
                            break;
                        run = previousRun;
                    }
                    if (run->bidiLevel() == level)
                        break;
                    level = run->bidiLevel();
                    while (auto nextRun = run->nextOnLine()) {
                        if (nextRun->bidiLevel() < level)
                            break;
                        run = nextRun;
                    }
                    if (run->bidiLevel() == level)
                        break;
                    level = run->bidiLevel();
                }
                renderer = &run->renderer();
                offset = primaryDirection == TextDirection::LTR ? run->maximumCaretOffset() : run->minimumCaretOffset();
            }
            break;
        }

        p = makeDeprecatedLegacyPosition(renderer->node(), offset);

        if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
            return p;

        ASSERT(p != m_deepPosition);
    }
}

VisiblePosition VisiblePosition::right(bool stayInEditableContent, bool* reachedBoundary) const
{
    if (reachedBoundary)
        *reachedBoundary = false;
    Position pos = rightVisuallyDistinctCandidate();
    // FIXME: Why can't we move left from the last position in a tree?
    if (pos.atStartOfTree() || pos.atEndOfTree()) {
        if (reachedBoundary)
            *reachedBoundary = true;
        return VisiblePosition();
    }

    VisiblePosition right = pos;
    ASSERT(right != *this);

    if (!stayInEditableContent)
        return right;

    // FIXME: This may need to do something different from "after".
    return honorEditingBoundaryAtOrAfter(right, reachedBoundary);
}

VisiblePosition VisiblePosition::honorEditingBoundaryAtOrBefore(const VisiblePosition& position, bool* reachedBoundary) const
{
    if (reachedBoundary)
        *reachedBoundary = false;
    if (position.isNull())
        return position;
    
    auto* highestRoot = highestEditableRoot(deepEquivalent());
    
    // Return empty position if pos is not somewhere inside the editable region containing this position
    if (highestRoot && !position.deepEquivalent().deprecatedNode()->isDescendantOf(*highestRoot)) {
        if (reachedBoundary)
            *reachedBoundary = true;
        return VisiblePosition();
    }
    
    // Return position itself if the two are from the very same editable region, or both are non-editable
    // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
    // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.
    if (highestEditableRoot(position.deepEquivalent()) == highestRoot) {
        if (reachedBoundary)
            *reachedBoundary = *this == position;
        return position;
    }
  
    // Return empty position if this position is non-editable, but pos is editable
    // FIXME: Move to the previous non-editable region.
    if (!highestRoot) {
        if (reachedBoundary)
            *reachedBoundary = true;
        return VisiblePosition();
    }

    // Return the last position before pos that is in the same editable region as this position
    return lastEditablePositionBeforePositionInRoot(position.deepEquivalent(), highestRoot);
}

VisiblePosition VisiblePosition::honorEditingBoundaryAtOrAfter(const VisiblePosition& otherPosition, bool* reachedBoundary) const
{
    if (reachedBoundary)
        *reachedBoundary = false;
    if (otherPosition.isNull())
        return otherPosition;
    
    auto* highestRoot = highestEditableRoot(deepEquivalent());
    
    // Return empty position if otherPosition is not somewhere inside the editable region containing this position
    if (highestRoot && !otherPosition.deepEquivalent().deprecatedNode()->isDescendantOf(*highestRoot)) {
        if (reachedBoundary)
            *reachedBoundary = true;
        return VisiblePosition();
    }
    
    // Return otherPosition itself if the two are from the very same editable region, or both are non-editable
    // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
    // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.
    if (highestEditableRoot(otherPosition.deepEquivalent()) == highestRoot) {
        if (reachedBoundary)
            *reachedBoundary = *this == otherPosition;
        return otherPosition;
    }

    // Return empty position if this position is non-editable, but otherPosition is editable
    // FIXME: Move to the next non-editable region.
    if (!highestRoot) {
        if (reachedBoundary)
            *reachedBoundary = true;
        return VisiblePosition();
    }

    // Return the next position after pos that is in the same editable region as this position
    return firstEditablePositionAfterPositionInRoot(otherPosition.deepEquivalent(), highestRoot);
}

static Position canonicalizeCandidate(const Position& candidate)
{
    if (candidate.isNull())
        return Position();
    ASSERT(candidate.isCandidate());
    Position upstream = candidate.upstream();
    if (upstream.isCandidate())
        return upstream;
    return candidate;
}

Position VisiblePosition::canonicalPosition(const Position& passedPosition)
{
    // The updateLayout call below can do so much that even the position passed
    // in to us might get changed as a side effect. Specifically, there are code
    // paths that pass selection endpoints, and updateLayout can change the selection.
    Position position = passedPosition;

    // FIXME (9535):  Canonicalizing to the leftmost candidate means that if we're at a line wrap, we will 
    // ask renderers to paint downstream carets for other renderers.
    // To fix this, we need to either a) add code to all paintCarets to pass the responsibility off to
    // the appropriate renderer for VisiblePosition's like these, or b) canonicalize to the rightmost candidate
    // unless the affinity is upstream.
    if (position.isNull())
        return Position();

    ASSERT(position.document());
    position.document()->updateLayoutIgnorePendingStylesheets();

    Node* node = position.containerNode();

    Position candidate = position.upstream();
    if (candidate.isCandidate())
        return candidate;
    candidate = position.downstream();
    if (candidate.isCandidate())
        return candidate;

    // When neither upstream or downstream gets us to a candidate (upstream/downstream won't leave 
    // blocks or enter new ones), we search forward and backward until we find one.
    Position next = canonicalizeCandidate(nextCandidate(position));
    Position prev = canonicalizeCandidate(previousCandidate(position));
    Node* nextNode = next.deprecatedNode();
    Node* prevNode = prev.deprecatedNode();

    // The new position must be in the same editable element. Enforce that first.
    // Unless the descent is from a non-editable html element to an editable body.
    if (is<HTMLHtmlElement>(node) && !node->hasEditableStyle()) {
        auto* body = node->document().bodyOrFrameset();
        if (body && body->hasEditableStyle())
            return next.isNotNull() ? next : prev;
    }

    Node* editingRoot = editableRootForPosition(position);
        
    // If the html element is editable, descending into its body will look like a descent 
    // from non-editable to editable content since rootEditableElement() always stops at the body.
    if ((editingRoot && editingRoot->hasTagName(htmlTag)) || (node && (node->isDocumentNode() || node->isShadowRoot())))
        return next.isNotNull() ? next : prev;
        
    bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;
    bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot;
    if (prevIsInSameEditableElement && !nextIsInSameEditableElement)
        return prev;

    if (nextIsInSameEditableElement && !prevIsInSameEditableElement)
        return next;

    if (!nextIsInSameEditableElement && !prevIsInSameEditableElement)
        return Position();

    // The new position should be in the same block flow element. Favor that.
    Element* originalBlock = deprecatedEnclosingBlockFlowElement(node);
    bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) && nextNode != originalBlock;
    bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) && prevNode != originalBlock;
    if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock)
        return prev;
        
    return next;
}

UChar32 VisiblePosition::characterAfter() const
{
    // We canonicalize to the first of two equivalent candidates, but the second of the two candidates
    // is the one that will be inside the text node containing the character after this visible position.
    Position pos = m_deepPosition.downstream();
    if (!pos.containerNode() || !pos.containerNode()->isTextNode())
        return 0;
    switch (pos.anchorType()) {
    case Position::PositionIsAfterChildren:
    case Position::PositionIsAfterAnchor:
    case Position::PositionIsBeforeAnchor:
    case Position::PositionIsBeforeChildren:
        return 0;
    case Position::PositionIsOffsetInAnchor:
        break;
    }
    unsigned offset = static_cast<unsigned>(pos.offsetInContainerNode());
    Text* textNode = pos.containerText();
    unsigned length = textNode->length();
    if (offset >= length)
        return 0;

    UChar32 ch;
    U16_NEXT(textNode->data(), offset, length, ch);
    return ch;
}

InlineRunAndOffset VisiblePosition::inlineRunAndOffset() const
{
    return m_deepPosition.inlineRunAndOffset(m_affinity);
}

InlineRunAndOffset VisiblePosition::inlineRunAndOffset(TextDirection primaryDirection) const
{
    return m_deepPosition.inlineRunAndOffset(m_affinity, primaryDirection);
}

auto VisiblePosition::localCaretRect() const -> LocalCaretRect
{
    auto node = m_deepPosition.anchorNode();
    if (!node)
        return { };

    auto runAndOffset = inlineRunAndOffset();
    auto renderer = runAndOffset.run ? &runAndOffset.run->renderer() : node->renderer();
    if (!renderer)
        return { };

    return { computeLocalCaretRect(*renderer, runAndOffset), const_cast<RenderObject*>(renderer) };
}

IntRect VisiblePosition::absoluteCaretBounds(bool* insideFixed) const
{
    RenderBlock* renderer = nullptr;
    LayoutRect localRect = localCaretRectInRendererForCaretPainting(*this, renderer);
    return absoluteBoundsForLocalCaretRect(renderer, localRect, insideFixed);
}

FloatRect VisiblePosition::absoluteSelectionBoundsForLine() const
{
    auto run = inlineRunAndOffset().run;
    if (!run)
        return { };

    auto line = run->line();
    auto localRect = FloatRect { FloatPoint { line->contentLogicalLeft(), line->selectionTop() }, FloatPoint { line->contentLogicalRight(), line->selectionBottom() } };
    if (!line->isHorizontal())
        localRect = localRect.transposedRect();
    line->containingBlock().flipForWritingMode(localRect);
    return line->containingBlock().localToAbsoluteQuad(localRect).boundingBox();
}

int VisiblePosition::lineDirectionPointForBlockDirectionNavigation() const
{
    auto localRect = localCaretRect();
    if (localRect.rect.isEmpty() || !localRect.renderer)
        return 0;

    // This ignores transforms on purpose, for now. Vertical navigation is done
    // without consulting transforms, so that 'up' in transformed text is 'up'
    // relative to the text, not absolute 'up'.
    auto caretPoint = localRect.renderer->localToAbsolute(localRect.rect.location());
    RenderObject* containingBlock = localRect.renderer->containingBlock();
    if (!containingBlock)
        containingBlock = localRect.renderer; // Just use ourselves to determine the writing mode if we have no containing block.
    return containingBlock->isHorizontalWritingMode() ? caretPoint.x() : caretPoint.y();
}

#if ENABLE(TREE_DEBUGGING)

void VisiblePosition::debugPosition(const char* msg) const
{
    if (isNull())
        fprintf(stderr, "Position [%s]: null\n", msg);
    else {
        fprintf(stderr, "Position [%s]: %s, ", msg, m_deepPosition.deprecatedNode()->nodeName().utf8().data());
        m_deepPosition.showAnchorTypeAndOffset();
    }
}

String VisiblePosition::debugDescription() const
{
    return m_deepPosition.debugDescription();
}

void VisiblePosition::showTreeForThis() const
{
    m_deepPosition.showTreeForThis();
}

#endif

// FIXME: Maybe this should be deprecated too, like the underlying function?
Element* enclosingBlockFlowElement(const VisiblePosition& visiblePosition)
{
    if (visiblePosition.isNull())
        return nullptr;

    return deprecatedEnclosingBlockFlowElement(visiblePosition.deepEquivalent().deprecatedNode());
}

bool isFirstVisiblePositionInNode(const VisiblePosition& visiblePosition, const Node* node)
{
    if (visiblePosition.isNull())
        return false;

    if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
        return false;

    VisiblePosition previous = visiblePosition.previous();
    return previous.isNull() || !previous.deepEquivalent().deprecatedNode()->isDescendantOf(node);
}

bool isLastVisiblePositionInNode(const VisiblePosition& visiblePosition, const Node* node)
{
    if (visiblePosition.isNull())
        return false;

    if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
        return false;

    VisiblePosition next = visiblePosition.next();
    return next.isNull() || !next.deepEquivalent().deprecatedNode()->isDescendantOf(node);
}

bool areVisiblePositionsInSameTreeScope(const VisiblePosition& a, const VisiblePosition& b)
{
    return connectedInSameTreeScope(a.deepEquivalent().anchorNode(), b.deepEquivalent().anchorNode());
}

bool VisiblePosition::equals(const VisiblePosition& other) const
{
    return m_affinity == other.m_affinity && m_deepPosition.equals(other.m_deepPosition);
}

std::optional<BoundaryPoint> makeBoundaryPoint(const VisiblePosition& position)
{
    return makeBoundaryPoint(position.deepEquivalent());
}

Node* commonInclusiveAncestor(const VisiblePosition& a, const VisiblePosition& b)
{
    return commonInclusiveAncestor(a.deepEquivalent(), b.deepEquivalent());
}

TextStream& operator<<(TextStream& stream, Affinity affinity)
{
    switch (affinity) {
    case Affinity::Upstream:
        stream << "upstream";
        break;
    case Affinity::Downstream:
        stream << "downstream";
        break;
    }
    return stream;
}

TextStream& operator<<(TextStream& stream, const VisiblePosition& visiblePosition)
{
    TextStream::GroupScope scope(stream);
    stream << "VisiblePosition " << &visiblePosition;

    stream.dumpProperty("position", visiblePosition.deepEquivalent());
    stream.dumpProperty("affinity", visiblePosition.affinity());

    return stream;
}

std::optional<SimpleRange> makeSimpleRange(const VisiblePositionRange& range)
{
    return makeSimpleRange(range.start, range.end);
}

VisiblePositionRange makeVisiblePositionRange(const std::optional<SimpleRange>& range)
{
    if (!range)
        return { };
    return { makeContainerOffsetPosition(range->start), makeContainerOffsetPosition(range->end) };
}

PartialOrdering documentOrder(const VisiblePosition& a, const VisiblePosition& b)
{
    // FIXME: Should two positions with different affinity be considered equivalent or not?
    return treeOrder<ComposedTree>(a.deepEquivalent(), b.deepEquivalent());
}

bool intersects(const VisiblePositionRange& a, const VisiblePositionRange& b)
{
    return a.start <= b.end && b.start <= a.end;
}

bool contains(const VisiblePositionRange& range, const VisiblePosition& point)
{
    return point >= range.start && point <= range.end;
}

VisiblePositionRange intersection(const VisiblePositionRange& a, const VisiblePositionRange& b)
{
    return { std::max(a.start, b.start), std::min(a.end, b.end) };
}

Node* commonInclusiveAncestor(const VisiblePositionRange& range)
{
    return commonInclusiveAncestor(range.start, range.end);
}

VisiblePosition midpoint(const VisiblePositionRange& range)
{
    auto rootNode = commonInclusiveAncestor(range);
    if (!rootNode)
        return { };
    auto rootContainerNode = rootNode->isContainerNode() ? downcast<ContainerNode>(rootNode) : rootNode->parentNode();
    if (!rootContainerNode)
        return { };
    auto scope = makeRangeSelectingNodeContents(*rootContainerNode);
    auto characterRange = WebCore::characterRange(scope, *makeSimpleRange(range.start, range.end));
    return makeContainerOffsetPosition(resolveCharacterLocation(scope, characterRange.location + characterRange.length / 2));
}

}  // namespace WebCore

#if ENABLE(TREE_DEBUGGING)

void showTree(const WebCore::VisiblePosition* vpos)
{
    if (vpos)
        vpos->showTreeForThis();
}

void showTree(const WebCore::VisiblePosition& vpos)
{
    vpos.showTreeForThis();
}

#endif
