fix: word boundary regards white space as a word (#1157)
This commit is contained in:
parent
c643df7c9e
commit
a1f1c6708a
1 changed files with 54 additions and 2 deletions
|
|
@ -277,11 +277,13 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Selection? getWordBoundaryInOffset(Offset offset) {
|
Selection? getWordBoundaryInOffset(Offset offset) {
|
||||||
|
final renderParagraph = _renderParagraph;
|
||||||
final localOffset = _renderParagraph?.globalToLocal(offset) ?? Offset.zero;
|
final localOffset = _renderParagraph?.globalToLocal(offset) ?? Offset.zero;
|
||||||
final textPosition = _renderParagraph?.getPositionForOffset(localOffset) ??
|
final textPosition = _renderParagraph?.getPositionForOffset(localOffset) ??
|
||||||
const TextPosition(offset: 0);
|
const TextPosition(offset: 0);
|
||||||
final textRange =
|
final textRange = renderParagraph == null
|
||||||
_renderParagraph?.getWordBoundary(textPosition) ?? TextRange.empty;
|
? TextRange.empty
|
||||||
|
: _getNonSpaceWordBoundary(renderParagraph, textPosition);
|
||||||
final start = Position(path: widget.node.path, offset: textRange.start);
|
final start = Position(path: widget.node.path, offset: textRange.start);
|
||||||
final end = Position(path: widget.node.path, offset: textRange.end);
|
final end = Position(path: widget.node.path, offset: textRange.end);
|
||||||
return Selection(start: start, end: end);
|
return Selection(start: start, end: end);
|
||||||
|
|
@ -297,6 +299,56 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
|
||||||
return Selection(start: start, end: end);
|
return Selection(start: start, end: end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextRange _getNonSpaceWordBoundary(
|
||||||
|
RenderParagraph renderParagraph,
|
||||||
|
TextPosition textPosition,
|
||||||
|
) {
|
||||||
|
bool isSpace(String string) => string.trim().isEmpty;
|
||||||
|
|
||||||
|
final text = renderParagraph.text.toPlainText();
|
||||||
|
final boundary = renderParagraph.getWordBoundary(textPosition);
|
||||||
|
|
||||||
|
if (!boundary.isValid) {
|
||||||
|
return TextRange.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
final wordText = text.substring(boundary.start, boundary.end);
|
||||||
|
|
||||||
|
if (!isSpace(wordText)) {
|
||||||
|
return boundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
int currentOffset = boundary.start - 1;
|
||||||
|
while (currentOffset >= 0 && isSpace(text[currentOffset])) {
|
||||||
|
currentOffset--;
|
||||||
|
}
|
||||||
|
if (currentOffset >= 0) {
|
||||||
|
final prevWordBoundary =
|
||||||
|
renderParagraph.getWordBoundary(TextPosition(offset: currentOffset));
|
||||||
|
if (!isSpace(
|
||||||
|
text.substring(prevWordBoundary.start, prevWordBoundary.end),
|
||||||
|
)) {
|
||||||
|
return prevWordBoundary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentOffset = boundary.end;
|
||||||
|
while (currentOffset < text.length && isSpace(text[currentOffset])) {
|
||||||
|
currentOffset++;
|
||||||
|
}
|
||||||
|
if (currentOffset < text.length) {
|
||||||
|
final nextWordBoundary =
|
||||||
|
renderParagraph.getWordBoundary(TextPosition(offset: currentOffset));
|
||||||
|
if (!isSpace(
|
||||||
|
text.substring(nextWordBoundary.start, nextWordBoundary.end),
|
||||||
|
)) {
|
||||||
|
return nextWordBoundary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TextRange.empty;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Rect> getRectsInSelection(
|
List<Rect> getRectsInSelection(
|
||||||
Selection selection, {
|
Selection selection, {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue