void SurroundingText::initialize(const Position& startPosition, const Position& endPosition, unsigned maxLength)
{
    ASSERT(startPosition.document() == endPosition.document());

    const unsigned halfMaxLength = maxLength / 2;

    Document* document = startPosition.document();
    // The position will have no document if it is null (as in no position).
    if (!document || !document->documentElement())
        return;

    // The forward range starts at the selection end and ends at the document's
    // end. It will then be updated to only contain the text in the text in the
    // right range around the selection.
    CharacterIterator forwardIterator(endPosition, lastPositionInNode(document->documentElement()).parentAnchoredEquivalent(), TextIteratorStopsOnFormControls);
    // FIXME: why do we stop going trough the text if we were not able to select something on the right?
    if (!forwardIterator.atEnd())
        forwardIterator.advance(maxLength - halfMaxLength);

    EphemeralRange forwardRange = forwardIterator.range();
    if (forwardRange.isNull() || !Range::create(*document, endPosition, forwardRange.startPosition())->text().length())
        return;

    // Same as with the forward range but with the backward range. The range
    // starts at the document's start and ends at the selection start and will
    // be updated.
    BackwardsCharacterIterator backwardsIterator(firstPositionInNode(document->documentElement()).parentAnchoredEquivalent(), startPosition, TextIteratorStopsOnFormControls);
    if (!backwardsIterator.atEnd())
        backwardsIterator.advance(halfMaxLength);

    m_startOffsetInContent = Range::create(*document, backwardsIterator.endPosition(), startPosition)->text().length();
    m_endOffsetInContent = Range::create(*document, backwardsIterator.endPosition(), endPosition)->text().length();
    m_contentRange = Range::create(*document, backwardsIterator.endPosition(), forwardRange.startPosition());
    ASSERT(m_contentRange);
}
Ejemplo n.º 2
0
SurroundingText::SurroundingText(const VisiblePosition& visiblePosition, unsigned maxLength)
    : m_positionOffsetInContent(0)
{
    if (visiblePosition.isNull())
        return;

    const unsigned halfMaxLength = maxLength / 2;
    CharacterIterator forwardIterator(makeRange(visiblePosition, endOfDocument(visiblePosition)).get(), TextIteratorStopsOnFormControls);
    if (!forwardIterator.atEnd())
        forwardIterator.advance(maxLength - halfMaxLength);

    Position position = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
    Document* document = position.document();
    ASSERT(document);
    RefPtr<Range> forwardRange = forwardIterator.range();
    if (!forwardRange || !Range::create(*document, position, forwardRange->startPosition())->text().length()) {
        ASSERT(forwardRange);
        return;
    }

    BackwardsCharacterIterator backwardsIterator(makeRange(startOfDocument(visiblePosition), visiblePosition).get(), TextIteratorStopsOnFormControls);
    if (!backwardsIterator.atEnd())
        backwardsIterator.advance(halfMaxLength);

    RefPtr<Range> backwardsRange = backwardsIterator.range();
    if (!backwardsRange) {
        ASSERT(backwardsRange);
        return;
    }

    m_positionOffsetInContent = Range::create(*document, backwardsRange->endPosition(), position)->text().length();
    m_contentRange = Range::create(*document, backwardsRange->endPosition(), forwardRange->startPosition());
    ASSERT(m_contentRange);
}
Ejemplo n.º 3
0
static size_t findPlainTextInternal(CharacterIteratorAlgorithm<Strategy>& it,
                                    const String& target,
                                    FindOptions options,
                                    size_t& matchStart) {
  matchStart = 0;
  size_t matchLength = 0;

  if (!isValidUTF16(target))
    return 0;

  SearchBuffer buffer(target, options);

  if (buffer.needsMoreContext()) {
    for (SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwardsIterator(
             PositionTemplate<Strategy>::firstPositionInNode(
                 it.ownerDocument()),
             PositionTemplate<Strategy>(it.currentContainer(),
                                        it.startOffset()));
         !backwardsIterator.atEnd(); backwardsIterator.advance()) {
      BackwardsTextBuffer characters;
      backwardsIterator.copyTextTo(&characters);
      buffer.prependContext(characters.data(), characters.size());
      if (!buffer.needsMoreContext())
        break;
    }
  }

  while (!it.atEnd()) {
    // TODO(xiaochengh): Should allow copying text to SearchBuffer directly
    ForwardsTextBuffer characters;
    it.copyTextTo(&characters);
    buffer.append(characters.data(), characters.size());
    it.advance(buffer.numberOfCharactersJustAppended());
  tryAgain:
    size_t matchStartOffset;
    if (size_t newMatchLength = buffer.search(matchStartOffset)) {
      // Note that we found a match, and where we found it.
      size_t lastCharacterInBufferOffset = it.characterOffset();
      DCHECK_GE(lastCharacterInBufferOffset, matchStartOffset);
      matchStart = lastCharacterInBufferOffset - matchStartOffset;
      matchLength = newMatchLength;
      // If searching forward, stop on the first match.
      // If searching backward, don't stop, so we end up with the last match.
      if (!(options & Backwards))
        break;
      goto tryAgain;
    }
    if (it.atBreak() && !buffer.atBreak()) {
      buffer.reachedBreak();
      goto tryAgain;
    }
  }

  return matchLength;
}
Ejemplo n.º 4
0
SurroundingText::SurroundingText(const Position& position, unsigned maxLength)
    : m_positionOffsetInContent(0)
{
    const unsigned halfMaxLength = maxLength / 2;

    Document* document = position.document();
    // The |position| will have no document if it is null (as in no position).
    if (!document)
        return;

    // The forward range starts at the selection end and ends at the document's
    // end. It will then be updated to only contain the text in the text in the
    // right range around the selection.
    RefPtrWillBeRawPtr<Range> forwardRange = Range::create(*document, position, lastPositionInNode(document->documentElement()).parentAnchoredEquivalent());
    CharacterIterator forwardIterator(forwardRange.get(), TextIteratorStopsOnFormControls);
    if (!forwardIterator.atEnd())
        forwardIterator.advance(maxLength - halfMaxLength);

    forwardRange = forwardIterator.range();
    if (!forwardRange || !Range::create(*document, position, forwardRange->startPosition())->text().length()) {
        ASSERT(forwardRange);
        return;
    }

    // Same as with the forward range but with the backward range. The range
    // starts at the document's start and ends at the selection start and will
    // be updated.
    RefPtrWillBeRawPtr<Range> backwardsRange = Range::create(*document, firstPositionInNode(document->documentElement()).parentAnchoredEquivalent(), position);
    BackwardsCharacterIterator backwardsIterator(backwardsRange.get(), TextIteratorStopsOnFormControls);
    if (!backwardsIterator.atEnd())
        backwardsIterator.advance(halfMaxLength);

    backwardsRange = backwardsIterator.range();
    if (!backwardsRange) {
        ASSERT(backwardsRange);
        return;
    }

    m_positionOffsetInContent = Range::create(*document, backwardsRange->endPosition(), position)->text().length();
    m_contentRange = Range::create(*document, backwardsRange->endPosition(), forwardRange->startPosition());
    ASSERT(m_contentRange);
}