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); }
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); }
// Currenntly ignoring TextCheckingResult::details but should be handled. See Bug 56368. void SpellChecker::didCheck(int sequence, const Vector<TextCheckingResult>& results) { if (!isValid(sequence)) return; if (!m_requestNode->renderer()) { clearRequest(); return; } int startOffset = 0; PositionIterator start = firstPositionInOrBeforeNode(m_requestNode.get()); for (size_t i = 0; i < results.size(); ++i) { if (results[i].type != TextCheckingTypeSpelling && results[i].type != TextCheckingTypeGrammar) continue; // To avoid moving the position backward, we assume the given results are sorted with // startOffset as the ones returned by [NSSpellChecker requestCheckingOfString:]. ASSERT(startOffset <= results[i].location); if (!forwardIterator(start, results[i].location - startOffset)) break; PositionIterator end = start; if (!forwardIterator(end, results[i].length)) break; // Users or JavaScript applications may change text while a spell-checker checks its // spellings in the background. To avoid adding markers to the words modified by users or // JavaScript applications, retrieve the words in the specified region and compare them with // the original ones. RefPtr<Range> range = Range::create(m_requestNode->document(), start, end); // FIXME: Use textContent() compatible string conversion. String destination = range->text(); String source = m_requestText.substring(results[i].location, results[i].length); if (destination == source) m_requestNode->document()->markers()->addMarker(range.get(), toMarkerType(results[i].type)); startOffset = results[i].location; } clearRequest(); }
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); }