From d132ac576b38752396db011c3cf317dd4e3b8fd7 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Fri, 24 Apr 2020 14:30:32 -0700 Subject: [PATCH] [web] Fix exception when getting boxes for rich text range (#17933) --- lib/web_ui/lib/src/engine/text/paragraph.dart | 14 ++++++++++++-- lib/web_ui/test/paragraph_test.dart | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/web_ui/lib/src/engine/text/paragraph.dart b/lib/web_ui/lib/src/engine/text/paragraph.dart index 3dbc6fbec..6b28d0609 100644 --- a/lib/web_ui/lib/src/engine/text/paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/paragraph.dart @@ -359,13 +359,23 @@ class EngineParagraph implements ui.Paragraph { }) { assert(boxHeightStyle != null); assert(boxWidthStyle != null); - if (_plainText == null || start == end) { + // Zero-length ranges and invalid ranges return an empty list. + if (start == end || start < 0 || end < 0) { return []; } + // For rich text, we can't measure the boxes. So for now, we'll just return + // a placeholder box to stop exceptions from being thrown in the framework. + // https://github.com/flutter/flutter/issues/55587 + if (_plainText == null) { + return [ + ui.TextBox.fromLTRBD(0, 0, 0, _lineHeight, _textDirection) + ]; + } + final int length = _plainText.length; // Ranges that are out of bounds should return an empty list. - if (start < 0 || end < 0 || start > length || end > length) { + if (start > length || end > length) { return []; } diff --git a/lib/web_ui/test/paragraph_test.dart b/lib/web_ui/test/paragraph_test.dart index c3432a00b..cc3f16663 100644 --- a/lib/web_ui/test/paragraph_test.dart +++ b/lib/web_ui/test/paragraph_test.dart @@ -415,6 +415,25 @@ void main() async { ); }); + testEachMeasurement('getBoxesForRange returns a box for rich text', () { + final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle( + fontFamily: 'Ahem', + fontStyle: FontStyle.normal, + fontWeight: FontWeight.normal, + fontSize: 10, + textDirection: TextDirection.ltr, + )); + builder.addText('abcd'); + builder.pushStyle(TextStyle(fontWeight: FontWeight.bold)); + builder.addText('xyz'); + final Paragraph paragraph = builder.build(); + paragraph.layout(const ParagraphConstraints(width: 1000)); + expect( + paragraph.getBoxesForRange(1, 2).single, + const TextBox.fromLTRBD(0, 0, 0, 10, TextDirection.ltr), + ); + }); + testEachMeasurement( 'getBoxesForRange return empty list for zero-length range', () { final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle( -- GitLab