コード例 #1
0
ファイル: SelectionModifier.cpp プロジェクト: mirror/chromium
VisiblePosition SelectionModifier::nextWordPositionForPlatform(
    const VisiblePosition& originalPosition) {
  VisiblePosition positionAfterCurrentWord = nextWordPosition(originalPosition);

  if (frame() &&
      frame()->editor().behavior().shouldSkipSpaceWhenMovingRight()) {
    // In order to skip spaces when moving right, we advance one
    // word further and then move one word back. Given the
    // semantics of previousWordPosition() this will put us at the
    // beginning of the word following.
    VisiblePosition positionAfterSpacingAndFollowingWord =
        nextWordPosition(positionAfterCurrentWord);
    if (positionAfterSpacingAndFollowingWord.isNotNull() &&
        positionAfterSpacingAndFollowingWord.deepEquivalent() !=
            positionAfterCurrentWord.deepEquivalent())
      positionAfterCurrentWord =
          previousWordPosition(positionAfterSpacingAndFollowingWord);

    bool movingBackwardsMovedPositionToStartOfCurrentWord =
        positionAfterCurrentWord.deepEquivalent() ==
        previousWordPosition(nextWordPosition(originalPosition))
            .deepEquivalent();
    if (movingBackwardsMovedPositionToStartOfCurrentWord)
      positionAfterCurrentWord = positionAfterSpacingAndFollowingWord;
  }
  return positionAfterCurrentWord;
}
コード例 #2
0
VisibleSelection visibleSelectionForClosestActualWordStart(const VisibleSelection& selection)
{
    // VisibleSelection validation has a special case when the caret is at the end of a paragraph where
    // it selects the paragraph marker. As well, if the position is at the end of a word, it will select
    // only the space between words. We want to select an actual word so we move the selection to
    // the start of the leftmost word if the character after the selection point is whitespace.

    if (selection.selectionType() != VisibleSelection::RangeSelection) {
        int leftDistance = 0;
        int rightDistance = 0;

        VisibleSelection leftSelection(previousWordPosition(selection.start()));
        bool leftSelectionIsOnWord = !isWhitespace(leftSelection.visibleStart().characterAfter()) && leftSelection.start().containerNode() == selection.start().containerNode();
        if (leftSelectionIsOnWord) {
            VisibleSelection rangeSelection(endOfWord(leftSelection.start()), selection.visibleStart());
            leftDistance = TextIterator::rangeLength(rangeSelection.toNormalizedRange().get());
        }

        VisibleSelection rightSelection = previousWordPosition(nextWordPosition(selection.start()));
        bool rightSelectionIsOnWord = !isWhitespace(rightSelection.visibleStart().characterAfter()) && rightSelection.start().containerNode() == selection.start().containerNode();
        if (rightSelectionIsOnWord) {
            VisibleSelection rangeSelection = VisibleSelection(rightSelection.visibleStart(), selection.visibleStart());
            rightDistance = TextIterator::rangeLength(rangeSelection.toNormalizedRange().get());
        }

        // Make sure we found an actual word. If not, return the original selection.
        if (!leftSelectionIsOnWord && !rightSelectionIsOnWord)
            return selection;

        if (!rightSelectionIsOnWord || (leftSelectionIsOnWord && leftDistance <= rightDistance)) {
            // Left is closer or right is invalid.
            return leftSelection;
        }

        // Right is closer or equal, or left was invalid.
        return rightSelection;
    }

    // No adjustment required.
    return selection;
}
コード例 #3
0
ファイル: SelectionModifier.cpp プロジェクト: mirror/chromium
VisiblePosition SelectionModifier::modifyMovingBackward(
    TextGranularity granularity) {
  VisiblePosition pos;
  switch (granularity) {
    case CharacterGranularity:
      if (m_selection.isRange())
        pos =
            createVisiblePosition(m_selection.start(), m_selection.affinity());
      else
        pos = previousPositionOf(
            createVisiblePosition(m_selection.extent(), m_selection.affinity()),
            CanSkipOverEditingBoundary);
      break;
    case WordGranularity:
      pos = previousWordPosition(
          createVisiblePosition(m_selection.extent(), m_selection.affinity()));
      break;
    case SentenceGranularity:
      pos = previousSentencePosition(
          createVisiblePosition(m_selection.extent(), m_selection.affinity()));
      break;
    case LineGranularity:
      pos = previousLinePosition(
          startForPlatform(),
          lineDirectionPointForBlockDirectionNavigation(START));
      break;
    case ParagraphGranularity:
      pos = previousParagraphPosition(
          startForPlatform(),
          lineDirectionPointForBlockDirectionNavigation(START));
      break;
    case SentenceBoundary:
      pos = startOfSentence(startForPlatform());
      break;
    case LineBoundary:
      pos = logicalStartOfLine(startForPlatform());
      break;
    case ParagraphBoundary:
      pos = startOfParagraph(startForPlatform());
      break;
    case DocumentBoundary:
      pos = startForPlatform();
      if (isEditablePosition(pos.deepEquivalent()))
        pos = startOfEditableContent(pos);
      else
        pos = startOfDocument(pos);
      break;
  }
  return pos;
}
コード例 #4
0
ファイル: SelectionModifier.cpp プロジェクト: mirror/chromium
VisiblePosition SelectionModifier::modifyExtendingBackward(
    TextGranularity granularity) {
  VisiblePosition pos =
      createVisiblePosition(m_selection.extent(), m_selection.affinity());

  // Extending a selection backward by word or character from just after a table
  // selects the table.  This "makes sense" from the user perspective, esp. when
  // deleting. It was done here instead of in VisiblePosition because we want
  // VPs to iterate over everything.
  switch (granularity) {
    case CharacterGranularity:
      pos = previousPositionOf(pos, CanSkipOverEditingBoundary);
      break;
    case WordGranularity:
      pos = previousWordPosition(pos);
      break;
    case SentenceGranularity:
      pos = previousSentencePosition(pos);
      break;
    case LineGranularity:
      pos = previousLinePosition(
          pos, lineDirectionPointForBlockDirectionNavigation(EXTENT));
      break;
    case ParagraphGranularity:
      pos = previousParagraphPosition(
          pos, lineDirectionPointForBlockDirectionNavigation(EXTENT));
      break;
    case SentenceBoundary:
      pos = startOfSentence(startForPlatform());
      break;
    case LineBoundary:
      pos = logicalStartOfLine(startForPlatform());
      break;
    case ParagraphBoundary:
      pos = startOfParagraph(startForPlatform());
      break;
    case DocumentBoundary:
      pos = startForPlatform();
      if (isEditablePosition(pos.deepEquivalent()))
        pos = startOfEditableContent(pos);
      else
        pos = startOfDocument(pos);
      break;
  }
  adjustPositionForUserSelectAll(pos, !(directionOfEnclosingBlock() == LTR));
  return pos;
}
コード例 #5
0
ファイル: SelectionModifier.cpp プロジェクト: mirror/chromium
VisiblePosition SelectionModifier::modifyExtendingRight(
    TextGranularity granularity) {
  VisiblePosition pos =
      createVisiblePosition(m_selection.extent(), m_selection.affinity());

  // The difference between modifyExtendingRight and modifyExtendingForward is:
  // modifyExtendingForward always extends forward logically.
  // modifyExtendingRight behaves the same as modifyExtendingForward except for
  // extending character or word, it extends forward logically if the enclosing
  // block is LTR direction, but it extends backward logically if the enclosing
  // block is RTL direction.
  switch (granularity) {
    case CharacterGranularity:
      if (directionOfEnclosingBlock() == LTR)
        pos = nextPositionOf(pos, CanSkipOverEditingBoundary);
      else
        pos = previousPositionOf(pos, CanSkipOverEditingBoundary);
      break;
    case WordGranularity:
      if (directionOfEnclosingBlock() == LTR)
        pos = nextWordPositionForPlatform(pos);
      else
        pos = previousWordPosition(pos);
      break;
    case LineBoundary:
      if (directionOfEnclosingBlock() == LTR)
        pos = modifyExtendingForward(granularity);
      else
        pos = modifyExtendingBackward(granularity);
      break;
    case SentenceGranularity:
    case LineGranularity:
    case ParagraphGranularity:
    case SentenceBoundary:
    case ParagraphBoundary:
    case DocumentBoundary:
      // FIXME: implement all of the above?
      pos = modifyExtendingForward(granularity);
      break;
  }
  adjustPositionForUserSelectAll(pos, directionOfEnclosingBlock() == LTR);
  return pos;
}
コード例 #6
0
ファイル: SpellChecker.cpp プロジェクト: Jamesducque/mojo
void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionAtWordBoundary)
{
    if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling))
        return;

    // We want to remove the markers from a word if an editing command will change the word. This can happen in one of
    // several scenarios:
    // 1. Insert in the middle of a word.
    // 2. Appending non whitespace at the beginning of word.
    // 3. Appending non whitespace at the end of word.
    // Note that, appending only whitespaces at the beginning or end of word won't change the word, so we don't need to
    // remove the markers on that word.
    // Of course, if current selection is a range, we potentially will edit two words that fall on the boundaries of
    // selection, and remove words between the selection boundaries.
    //
    VisiblePosition startOfSelection = m_frame.selection().selection().visibleStart();
    VisiblePosition endOfSelection = m_frame.selection().selection().visibleEnd();
    if (startOfSelection.isNull())
        return;
    // First word is the word that ends after or on the start of selection.
    VisiblePosition startOfFirstWord = startOfWord(startOfSelection, LeftWordIfOnBoundary);
    VisiblePosition endOfFirstWord = endOfWord(startOfSelection, LeftWordIfOnBoundary);
    // Last word is the word that begins before or on the end of selection
    VisiblePosition startOfLastWord = startOfWord(endOfSelection, RightWordIfOnBoundary);
    VisiblePosition endOfLastWord = endOfWord(endOfSelection, RightWordIfOnBoundary);

    if (startOfFirstWord.isNull()) {
        startOfFirstWord = startOfWord(startOfSelection, RightWordIfOnBoundary);
        endOfFirstWord = endOfWord(startOfSelection, RightWordIfOnBoundary);
    }

    if (endOfLastWord.isNull()) {
        startOfLastWord = startOfWord(endOfSelection, LeftWordIfOnBoundary);
        endOfLastWord = endOfWord(endOfSelection, LeftWordIfOnBoundary);
    }

    // If doNotRemoveIfSelectionAtWordBoundary is true, and first word ends at the start of selection,
    // we choose next word as the first word.
    if (doNotRemoveIfSelectionAtWordBoundary && endOfFirstWord == startOfSelection) {
        startOfFirstWord = nextWordPosition(startOfFirstWord);
        endOfFirstWord = endOfWord(startOfFirstWord, RightWordIfOnBoundary);
        if (startOfFirstWord == endOfSelection)
            return;
    }

    // If doNotRemoveIfSelectionAtWordBoundary is true, and last word begins at the end of selection,
    // we choose previous word as the last word.
    if (doNotRemoveIfSelectionAtWordBoundary && startOfLastWord == endOfSelection) {
        startOfLastWord = previousWordPosition(startOfLastWord);
        endOfLastWord = endOfWord(startOfLastWord, RightWordIfOnBoundary);
        if (endOfLastWord == startOfSelection)
            return;
    }

    if (startOfFirstWord.isNull() || endOfFirstWord.isNull() || startOfLastWord.isNull() || endOfLastWord.isNull())
        return;

    // Now we remove markers on everything between startOfFirstWord and endOfLastWord.
    // However, if an autocorrection change a single word to multiple words, we want to remove correction mark from all the
    // resulted words even we only edit one of them. For example, assuming autocorrection changes "avantgarde" to "avant
    // garde", we will have CorrectionIndicator marker on both words and on the whitespace between them. If we then edit garde,
    // we would like to remove the marker from word "avant" and whitespace as well. So we need to get the continous range of
    // of marker that contains the word in question, and remove marker on that whole range.
    Document* document = m_frame.document();
    ASSERT(document);
    RefPtr<Range> wordRange = Range::create(*document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent());

    document->markers().removeMarkers(wordRange.get(), DocumentMarker::MisspellingMarkers(), DocumentMarkerController::RemovePartiallyOverlappingMarker);
}