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()); }