Fix getOffsetForCaret to return correct value if contains widget span (#98542)
This commit is contained in:
parent
9dc9cf57f2
commit
fd41d419b4
@ -41,6 +41,9 @@ abstract class PlaceholderSpan extends InlineSpan {
|
|||||||
TextStyle? style,
|
TextStyle? style,
|
||||||
}) : super(style: style);
|
}) : super(style: style);
|
||||||
|
|
||||||
|
/// The unicode character to represent a placeholder.
|
||||||
|
static const String placeholderCodeUnit = '\uFFFC';
|
||||||
|
|
||||||
/// How the placeholder aligns vertically with the text.
|
/// How the placeholder aligns vertically with the text.
|
||||||
///
|
///
|
||||||
/// See [ui.PlaceholderAlignment] for details on each mode.
|
/// See [ui.PlaceholderAlignment] for details on each mode.
|
||||||
@ -57,7 +60,7 @@ abstract class PlaceholderSpan extends InlineSpan {
|
|||||||
@override
|
@override
|
||||||
void computeToPlainText(StringBuffer buffer, {bool includeSemanticsLabels = true, bool includePlaceholders = true}) {
|
void computeToPlainText(StringBuffer buffer, {bool includeSemanticsLabels = true, bool includePlaceholders = true}) {
|
||||||
if (includePlaceholders) {
|
if (includePlaceholders) {
|
||||||
buffer.write('\uFFFC');
|
buffer.write(placeholderCodeUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +739,7 @@ class TextPainter {
|
|||||||
// Get the Rect of the cursor (in logical pixels) based off the near edge
|
// Get the Rect of the cursor (in logical pixels) based off the near edge
|
||||||
// of the character upstream from the given string offset.
|
// of the character upstream from the given string offset.
|
||||||
Rect? _getRectFromUpstream(int offset, Rect caretPrototype) {
|
Rect? _getRectFromUpstream(int offset, Rect caretPrototype) {
|
||||||
final String flattenedText = _text!.toPlainText(includePlaceholders: false);
|
final String flattenedText = _text!.toPlainText(includeSemanticsLabels: false);
|
||||||
final int? prevCodeUnit = _text!.codeUnitAt(max(0, offset - 1));
|
final int? prevCodeUnit = _text!.codeUnitAt(max(0, offset - 1));
|
||||||
if (prevCodeUnit == null)
|
if (prevCodeUnit == null)
|
||||||
return null;
|
return null;
|
||||||
@ -789,7 +789,7 @@ class TextPainter {
|
|||||||
// Get the Rect of the cursor (in logical pixels) based off the near edge
|
// Get the Rect of the cursor (in logical pixels) based off the near edge
|
||||||
// of the character downstream from the given string offset.
|
// of the character downstream from the given string offset.
|
||||||
Rect? _getRectFromDownstream(int offset, Rect caretPrototype) {
|
Rect? _getRectFromDownstream(int offset, Rect caretPrototype) {
|
||||||
final String flattenedText = _text!.toPlainText(includePlaceholders: false);
|
final String flattenedText = _text!.toPlainText(includeSemanticsLabels: false);
|
||||||
// We cap the offset at the final index of the _text.
|
// We cap the offset at the final index of the _text.
|
||||||
final int? nextCodeUnit = _text!.codeUnitAt(min(offset, flattenedText.length - 1));
|
final int? nextCodeUnit = _text!.codeUnitAt(min(offset, flattenedText.length - 1));
|
||||||
if (nextCodeUnit == null)
|
if (nextCodeUnit == null)
|
||||||
|
@ -139,7 +139,8 @@ class WidgetSpan extends PlaceholderSpan {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
int? codeUnitAtVisitor(int index, Accumulator offset) {
|
int? codeUnitAtVisitor(int index, Accumulator offset) {
|
||||||
return null;
|
offset.increment(1);
|
||||||
|
return PlaceholderSpan.placeholderCodeUnit.codeUnitAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -37,6 +37,24 @@ void main() {
|
|||||||
expect(caretOffset.dx, painter.width);
|
expect(caretOffset.dx, painter.width);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('TextPainter caret test with WidgetSpan', () {
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/98458.
|
||||||
|
final TextPainter painter = TextPainter()
|
||||||
|
..textDirection = TextDirection.ltr;
|
||||||
|
|
||||||
|
painter.text = const TextSpan(children: <InlineSpan>[
|
||||||
|
TextSpan(text: 'before'),
|
||||||
|
WidgetSpan(child: Text('widget')),
|
||||||
|
TextSpan(text: 'after'),
|
||||||
|
]);
|
||||||
|
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
|
||||||
|
PlaceholderDimensions(size: Size(50, 30), baselineOffset: 25, alignment: ui.PlaceholderAlignment.bottom),
|
||||||
|
]);
|
||||||
|
painter.layout();
|
||||||
|
final Offset caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: painter.text!.toPlainText().length), ui.Rect.zero);
|
||||||
|
expect(caretOffset.dx, painter.width);
|
||||||
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
test('TextPainter null text test', () {
|
test('TextPainter null text test', () {
|
||||||
final TextPainter painter = TextPainter()
|
final TextPainter painter = TextPainter()
|
||||||
..textDirection = TextDirection.ltr;
|
..textDirection = TextDirection.ltr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user