EphemeralRange LocalFrame::rangeForPoint(const IntPoint& framePoint) { const PositionWithAffinity positionWithAffinity = positionForPoint(framePoint); if (positionWithAffinity.isNull()) return EphemeralRange(); VisiblePosition position = createVisiblePosition(positionWithAffinity); VisiblePosition previous = previousPositionOf(position); if (previous.isNotNull()) { const EphemeralRange previousCharacterRange = makeRange(previous, position); IntRect rect = editor().firstRectForRange(previousCharacterRange); if (rect.contains(framePoint)) return EphemeralRange(previousCharacterRange); } VisiblePosition next = nextPositionOf(position); const EphemeralRange nextCharacterRange = makeRange(position, next); if (nextCharacterRange.isNotNull()) { IntRect rect = editor().firstRectForRange(nextCharacterRange); if (rect.contains(framePoint)) return EphemeralRange(nextCharacterRange); } return EphemeralRange(); }
static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range) { DCHECK(range.isNotNull()); const VisiblePosition& visibleEnd = createVisiblePosition(range.endPosition()); DCHECK(visibleEnd.isNotNull()); const Position& sentenceEnd = endOfSentence(visibleEnd).deepEquivalent(); // TODO(xiaochengh): |sentenceEnd < range.endPosition()| is possible, // which would trigger a DCHECK in EphemeralRange's constructor if we return // it directly. However, this shouldn't happen and needs to be fixed. return EphemeralRange( range.startPosition(), sentenceEnd.isNotNull() && sentenceEnd > range.endPosition() ? sentenceEnd : range.endPosition()); }