Example #1
0
int TextFinder::selectFindMatch(unsigned index, WebRect* selectionRect) {
  SECURITY_DCHECK(index < m_findMatchesCache.size());

  Range* range = m_findMatchesCache[index].m_range;
  if (!range->boundaryPointsValid() || !range->startContainer()->isConnected())
    return -1;

  // Check if the match is already selected.
  if (!m_currentActiveMatchFrame || !m_activeMatch ||
      !areRangesEqual(m_activeMatch.get(), range)) {
    m_activeMatchIndex = m_findMatchesCache[index].m_ordinal - 1;

    // Set this frame as the active frame (the one with the active highlight).
    m_currentActiveMatchFrame = true;
    ownerFrame().viewImpl()->setFocusedFrame(&ownerFrame());

    if (m_activeMatch)
      setMarkerActive(m_activeMatch.get(), false);
    m_activeMatch = range;
    setMarkerActive(m_activeMatch.get(), true);

    // Clear any user selection, to make sure Find Next continues on from the
    // match we just activated.
    ownerFrame().frame()->selection().clear();

    // Make sure no node is focused. See http://crbug.com/38700.
    ownerFrame().frame()->document()->clearFocusedElement();
  }

  IntRect activeMatchRect;
  IntRect activeMatchBoundingBox = enclosingIntRect(
      LayoutObject::absoluteBoundingBoxRectForRange(m_activeMatch.get()));

  if (!activeMatchBoundingBox.isEmpty()) {
    if (m_activeMatch->firstNode() &&
        m_activeMatch->firstNode()->layoutObject()) {
      m_activeMatch->firstNode()->layoutObject()->scrollRectToVisible(
          LayoutRect(activeMatchBoundingBox),
          ScrollAlignment::alignCenterIfNeeded,
          ScrollAlignment::alignCenterIfNeeded, UserScroll);
    }

    // Zoom to the active match.
    activeMatchRect =
        ownerFrame().frameView()->contentsToRootFrame(activeMatchBoundingBox);
    ownerFrame().viewImpl()->zoomToFindInPageRect(activeMatchRect);
  }

  if (selectionRect)
    *selectionRect = activeMatchRect;

  return m_activeMatchIndex + 1;
}
TEST_F(StaticRangeTest, SplitTextNodeRangeOutsideText)
{
    document().body()->setInnerHTML("<span id=\"outer\">0<span id=\"inner-left\">1</span>SPLITME<span id=\"inner-right\">2</span>3</span>", ASSERT_NO_EXCEPTION);

    Element* outer = document().getElementById(AtomicString::fromUTF8("outer"));
    Element* innerLeft = document().getElementById(AtomicString::fromUTF8("inner-left"));
    Element* innerRight = document().getElementById(AtomicString::fromUTF8("inner-right"));
    Text* oldText = toText(outer->childNodes()->item(2));

    StaticRange* staticRangeOuterOutside = StaticRange::create(document(), outer, 0, outer, 5);
    StaticRange* staticRangeOuterInside = StaticRange::create(document(), outer, 1, outer, 4);
    StaticRange* staticRangeOuterSurroundingText = StaticRange::create(document(), outer, 2, outer, 3);
    StaticRange* staticRangeInnerLeft = StaticRange::create(document(), innerLeft, 0, innerLeft, 1);
    StaticRange* staticRangeInnerRight = StaticRange::create(document(), innerRight, 0, innerRight, 1);
    StaticRange* staticRangeFromTextToMiddleOfElement = StaticRange::create(document(), oldText, 6, outer, 3);

    Range* rangeOuterOutside = staticRangeOuterOutside->toRange(ASSERT_NO_EXCEPTION);
    Range* rangeOuterInside = staticRangeOuterInside->toRange(ASSERT_NO_EXCEPTION);
    Range* rangeOuterSurroundingText = staticRangeOuterSurroundingText->toRange(ASSERT_NO_EXCEPTION);
    Range* rangeInnerLeft = staticRangeInnerLeft->toRange(ASSERT_NO_EXCEPTION);
    Range* rangeInnerRight = staticRangeInnerRight->toRange(ASSERT_NO_EXCEPTION);
    Range* rangeFromTextToMiddleOfElement = staticRangeFromTextToMiddleOfElement->toRange(ASSERT_NO_EXCEPTION);

    oldText->splitText(3, ASSERT_NO_EXCEPTION);
    Text* newText = toText(oldText->nextSibling());

    // Range should mutate.
    EXPECT_TRUE(rangeOuterOutside->boundaryPointsValid());
    EXPECT_EQ(outer, rangeOuterOutside->startContainer());
    EXPECT_EQ(0, rangeOuterOutside->startOffset());
    EXPECT_EQ(outer, rangeOuterOutside->endContainer());
    EXPECT_EQ(6, rangeOuterOutside->endOffset()); // Increased by 1 since a new node is inserted.

    EXPECT_TRUE(rangeOuterInside->boundaryPointsValid());
    EXPECT_EQ(outer, rangeOuterInside->startContainer());
    EXPECT_EQ(1, rangeOuterInside->startOffset());
    EXPECT_EQ(outer, rangeOuterInside->endContainer());
    EXPECT_EQ(5, rangeOuterInside->endOffset());

    EXPECT_TRUE(rangeOuterSurroundingText->boundaryPointsValid());
    EXPECT_EQ(outer, rangeOuterSurroundingText->startContainer());
    EXPECT_EQ(2, rangeOuterSurroundingText->startOffset());
    EXPECT_EQ(outer, rangeOuterSurroundingText->endContainer());
    EXPECT_EQ(4, rangeOuterSurroundingText->endOffset());

    EXPECT_TRUE(rangeInnerLeft->boundaryPointsValid());
    EXPECT_EQ(innerLeft, rangeInnerLeft->startContainer());
    EXPECT_EQ(0, rangeInnerLeft->startOffset());
    EXPECT_EQ(innerLeft, rangeInnerLeft->endContainer());
    EXPECT_EQ(1, rangeInnerLeft->endOffset());

    EXPECT_TRUE(rangeInnerRight->boundaryPointsValid());
    EXPECT_EQ(innerRight, rangeInnerRight->startContainer());
    EXPECT_EQ(0, rangeInnerRight->startOffset());
    EXPECT_EQ(innerRight, rangeInnerRight->endContainer());
    EXPECT_EQ(1, rangeInnerRight->endOffset());

    EXPECT_TRUE(rangeFromTextToMiddleOfElement->boundaryPointsValid());
    EXPECT_EQ(newText, rangeFromTextToMiddleOfElement->startContainer());
    EXPECT_EQ(3, rangeFromTextToMiddleOfElement->startOffset());
    EXPECT_EQ(outer, rangeFromTextToMiddleOfElement->endContainer());
    EXPECT_EQ(4, rangeFromTextToMiddleOfElement->endOffset());

    // StaticRange shouldn't mutate.
    EXPECT_EQ(outer, staticRangeOuterOutside->startContainer());
    EXPECT_EQ(0, staticRangeOuterOutside->startOffset());
    EXPECT_EQ(outer, staticRangeOuterOutside->endContainer());
    EXPECT_EQ(5, staticRangeOuterOutside->endOffset());

    EXPECT_EQ(outer, staticRangeOuterInside->startContainer());
    EXPECT_EQ(1, staticRangeOuterInside->startOffset());
    EXPECT_EQ(outer, staticRangeOuterInside->endContainer());
    EXPECT_EQ(4, staticRangeOuterInside->endOffset());

    EXPECT_EQ(outer, staticRangeOuterSurroundingText->startContainer());
    EXPECT_EQ(2, staticRangeOuterSurroundingText->startOffset());
    EXPECT_EQ(outer, staticRangeOuterSurroundingText->endContainer());
    EXPECT_EQ(3, staticRangeOuterSurroundingText->endOffset());

    EXPECT_EQ(innerLeft, staticRangeInnerLeft->startContainer());
    EXPECT_EQ(0, staticRangeInnerLeft->startOffset());
    EXPECT_EQ(innerLeft, staticRangeInnerLeft->endContainer());
    EXPECT_EQ(1, staticRangeInnerLeft->endOffset());

    EXPECT_EQ(innerRight, staticRangeInnerRight->startContainer());
    EXPECT_EQ(0, staticRangeInnerRight->startOffset());
    EXPECT_EQ(innerRight, staticRangeInnerRight->endContainer());
    EXPECT_EQ(1, staticRangeInnerRight->endOffset());

    EXPECT_EQ(oldText, staticRangeFromTextToMiddleOfElement->startContainer());
    EXPECT_EQ(6, staticRangeFromTextToMiddleOfElement->startOffset());
    EXPECT_EQ(outer, staticRangeFromTextToMiddleOfElement->endContainer());
    EXPECT_EQ(3, staticRangeFromTextToMiddleOfElement->endOffset());
}