getWordAtOffset method

  1. @visibleForTesting
TextSelection getWordAtOffset(
  1. TextPosition position
)

Returns a TextSelection that encompasses the word at the given TextPosition.

Implementation

@visibleForTesting
TextSelection getWordAtOffset(TextPosition position) {
  // When long-pressing past the end of the text, we want a collapsed cursor.
  if (position.offset >= plainText.length) {
    return TextSelection.fromPosition(
      TextPosition(offset: plainText.length, affinity: TextAffinity.upstream)
    );
  }
  // If text is obscured, the entire sentence should be treated as one word.
  if (obscureText) {
    return TextSelection(baseOffset: 0, extentOffset: plainText.length);
  }
  final TextRange word = _textPainter.getWordBoundary(position);
  final int effectiveOffset;
  switch (position.affinity) {
    case TextAffinity.upstream:
      // upstream affinity is effectively -1 in text position.
      effectiveOffset = position.offset - 1;
    case TextAffinity.downstream:
      effectiveOffset = position.offset;
  }
  assert(effectiveOffset >= 0);

  // On iOS, select the previous word if there is a previous word, or select
  // to the end of the next word if there is a next word. Select nothing if
  // there is neither a previous word nor a next word.
  //
  // If the platform is Android and the text is read only, try to select the
  // previous word if there is one; otherwise, select the single whitespace at
  // the position.
  if (effectiveOffset > 0
      && TextLayoutMetrics.isWhitespace(plainText.codeUnitAt(effectiveOffset))) {
    final TextRange? previousWord = _getPreviousWord(word.start);
    switch (defaultTargetPlatform) {
      case TargetPlatform.iOS:
        if (previousWord == null) {
          final TextRange? nextWord = _getNextWord(word.start);
          if (nextWord == null) {
            return TextSelection.collapsed(offset: position.offset);
          }
          return TextSelection(
            baseOffset: position.offset,
            extentOffset: nextWord.end,
          );
        }
        return TextSelection(
          baseOffset: previousWord.start,
          extentOffset: position.offset,
        );
      case TargetPlatform.android:
        if (readOnly) {
          if (previousWord == null) {
            return TextSelection(
              baseOffset: position.offset,
              extentOffset: position.offset + 1,
            );
          }
          return TextSelection(
            baseOffset: previousWord.start,
            extentOffset: position.offset,
          );
        }
      case TargetPlatform.fuchsia:
      case TargetPlatform.macOS:
      case TargetPlatform.linux:
      case TargetPlatform.windows:
        break;
    }
  }

  return TextSelection(baseOffset: word.start, extentOffset: word.end);
}