-
Notifications
You must be signed in to change notification settings - Fork 6k
Paragraph.GetWordBoundary respects text affinity #36176
Conversation
| /// Standard Annex #29 http://www.unicode.org/reports/tr29/#Word_Boundaries | ||
| TextRange getWordBoundary(TextPosition position) { | ||
| final List<int> boundary = _getWordBoundary(position.offset); | ||
| final int characterPosition; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TextPosition's documentation says
/// A TextPosition can be used to locate a position in a string in code (using
/// the [offset] property), and it can also be used to locate the same position
/// visually in a rendered string of text (using [offset] and, when needed to
/// resolve ambiguity, [affinity]).
so that seems to indicate that the same TextPosition can either be interpreted as an int which points to a code unit in a UTF16 string, or a place to draw the caret in the rendered string.
This works but it should be stated in the documentation that TextPosition here is a caret location instead of an offset (but I feel it's easier to reason about word boundaries using code unit offsets instead of using caret locations). I think i'd prefer we use TextPosition exclusively for caret positions, and let getWordBoundary take an int instead of TextPosition to avoid ambiguity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it was initially an int and was changed in https://github.com/flutter/engine/pull/13765/files. @gspencergoog is there a reason for using TextPosition over int here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like some of the text in this thread should become code comments for future reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was three years ago, so it's hazy, but I think it had to do with being able to move line by line. Here's some additional context: #13727
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at the previous pr it looks like it just part of moving TextRange and related class to ui to fix some line boundary issue, and the getWordBoundary just some how refactor to matches the API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is really down to when we want to make the switch from caret position to code unit position. In my opinion it should be as late as possible in case the a later step may want to use the caret position and they have to do some other hack to restore it back. WDYT @LongCatIsLooong
I think we should always treat TextPosition as a caret position, and use int if it meant to be a code unit position. Otherwise, it will create convoluted code. I will update the document
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#28008 made getLineBoundary TextAffinity aware. I'm ok with making them consistent and document that the parameter is based on the caret location instead of the character location. But still word boundaries generally don't require layout and the caller may just want to tokenize the text without even putting the text on screen. Talking about "caret position" could be confusing in this context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the input may come from a getPositionForOffset from a touch event, which is affinity aware. I will keep it as is and document it. Thanks for the input.
|
It looks like the framework pr needs to go in first because there is workaround in RenderEditable to try to compensate getWordBoundary ignoring the affinity. I will merge the framework pr with workaround to always convert text position to be downStream and remove all the old workarounds so we can merge this PR. Once this PR is merged I can then remove the work around in the framework. |
d42a5e7 to
ff0a5d1
Compare
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
The GetWordBoundary always assume affinity is downstream. This PR fixes it
related flutter/flutter#110367
flutter/flutter#111751
Pre-launch Checklist
writing and running engine tests.
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.