Exemplo n.º 1
0
PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
{
    if (!renderView())
        return nullptr;
    HitTestResult result = hitTestInDocument(this, x, y);
    RenderObject* renderer = result.renderer();
    if (!renderer)
        return nullptr;

    PositionWithAffinity positionWithAffinity = result.position();
    if (positionWithAffinity.position().isNull())
        return nullptr;

    Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
    return Range::create(*this, rangeCompliantPosition, rangeCompliantPosition);
}
Exemplo n.º 2
0
bool CaretBase::updateCaretRect(const PositionWithAffinity& caretPosition)
{
    m_caretLocalRect = LayoutRect();

    if (caretPosition.position().isNull())
        return false;

    ASSERT(caretPosition.position().anchorNode()->layoutObject());

    // First compute a rect local to the layoutObject at the selection start.
    LayoutObject* layoutObject;
    m_caretLocalRect = localCaretRectOfPosition(caretPosition, layoutObject);

    // Get the layoutObject that will be responsible for painting the caret
    // (which is either the layoutObject we just found, or one of its containers).
    LayoutBlock* caretPainter = caretLayoutObject(caretPosition.position().anchorNode());

    mapCaretRectToCaretPainter(layoutObject, caretPainter, m_caretLocalRect);

    return true;
}
Exemplo n.º 3
0
PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
{
    if (!renderView())
        return nullptr;
    HitTestResult result = hitTestInDocument(this, x, y);
    RenderObject* renderer = result.renderer();
    if (!renderer)
        return nullptr;

    Node* node = renderer->node();
    Node* shadowAncestorNode = ancestorInThisScope(node);
    if (shadowAncestorNode != node) {
        unsigned offset = shadowAncestorNode->nodeIndex();
        ContainerNode* container = shadowAncestorNode->parentNode();
        return Range::create(*this, container, offset, container, offset);
    }

    PositionWithAffinity positionWithAffinity = result.position();
    if (positionWithAffinity.position().isNull())
        return nullptr;

    Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
    return Range::create(*this, rangeCompliantPosition, rangeCompliantPosition);
}
Exemplo n.º 4
0
bool CaretBase::updateCaretRect(Document* document, const PositionWithAffinity& caretPosition)
{
    m_caretLocalRect = LayoutRect();

    m_caretRectNeedsUpdate = false;

    if (caretPosition.position().isNull())
        return false;

    ASSERT(caretPosition.position().deprecatedNode()->renderer());

    // First compute a rect local to the renderer at the selection start.
    RenderObject* renderer;
    LayoutRect localRect = localCaretRectOfPosition(caretPosition, renderer);

    // Get the renderer that will be responsible for painting the caret
    // (which is either the renderer we just found, or one of its containers).
    RenderBlock* caretPainter = caretRenderer(caretPosition.position().deprecatedNode());

    // Compute an offset between the renderer and the caretPainter.
    bool unrooted = false;
    while (renderer != caretPainter) {
        RenderObject* containerObject = renderer->container();
        if (!containerObject) {
            unrooted = true;
            break;
        }
        localRect.move(renderer->offsetFromContainer(containerObject, localRect.location()));
        renderer = containerObject;
    }

    if (!unrooted)
        m_caretLocalRect = localRect;

    return true;
}
Exemplo n.º 5
0
void FrameCaret::invalidateCaretRect(bool forceInvalidation) {
  if (!m_caretRectDirty)
    return;
  m_caretRectDirty = false;

  DCHECK(caretPositionIsValidForDocument(*m_frame->document()));
  LayoutObject* layoutObject = nullptr;
  LayoutRect newRect;
  PositionWithAffinity currentCaretPosition = caretPosition();
  if (isActive())
    newRect = localCaretRectOfPosition(currentCaretPosition, layoutObject);
  Node* newNode = layoutObject ? layoutObject->node() : nullptr;
  // The current selected node |newNode| could be a child multiple levels below
  // its associated "anchor node" ancestor, so we reference and keep around the
  // anchor node for checking editability.
  // TODO(wkorman): Consider storing previous Position, rather than Node, and
  // making use of EditingUtilies::isEditablePosition() directly.
  Node* newAnchorNode =
      currentCaretPosition.position().parentAnchoredEquivalent().anchorNode();
  if (newNode && newAnchorNode && newNode != newAnchorNode &&
      newAnchorNode->layoutObject() && newAnchorNode->layoutObject()->isBox()) {
    newNode->layoutObject()->mapToVisualRectInAncestorSpace(
        toLayoutBoxModelObject(newAnchorNode->layoutObject()), newRect);
  }
  // It's possible for the timer to be inactive even though we want to
  // invalidate the caret. For example, when running as a layout test the
  // caret blink interval could be zero and thus |m_caretBlinkTimer| will
  // never be started. We provide |forceInvalidation| for use by paint
  // invalidation internals where we need to invalidate the caret regardless
  // of timer state.
  if (!forceInvalidation && !m_caretBlinkTimer.isActive() &&
      newNode == m_previousCaretNode && newRect == m_previousCaretRect &&
      m_caretVisibility == m_previousCaretVisibility)
    return;

  if (m_previousCaretAnchorNode &&
      shouldRepaintCaret(*m_previousCaretAnchorNode)) {
    invalidateLocalCaretRect(m_previousCaretAnchorNode.get(),
                             m_previousCaretRect);
  }
  if (newAnchorNode && shouldRepaintCaret(*newAnchorNode))
    invalidateLocalCaretRect(newAnchorNode, newRect);
  m_previousCaretNode = newNode;
  m_previousCaretAnchorNode = newAnchorNode;
  m_previousCaretRect = newRect;
  m_previousCaretVisibility = m_caretVisibility;
}
VisiblePosition::VisiblePosition(const PositionWithAffinity& positionWithAffinity)
{
    init(positionWithAffinity.position(), positionWithAffinity.affinity());
}