Merge pull request #2520 from Hixie/TextSpan.toString
Fix crash when dumping the app if it uses RichText
This commit is contained in:
commit
167c433a56
@ -46,6 +46,19 @@ class StockSymbolView extends StatelessComponent {
|
||||
),
|
||||
new Text('Market Cap', style: headings),
|
||||
new Text('${stock.marketCap}'),
|
||||
new Container(
|
||||
height: 8.0
|
||||
),
|
||||
new RichText(
|
||||
text: new TextSpan(
|
||||
style: DefaultTextStyle.of(context).merge(new TextStyle(fontSize: 8.0)),
|
||||
text: 'Prices may be delayed by ',
|
||||
children: <TextSpan>[
|
||||
new TextSpan(text: 'several', style: new TextStyle(fontStyle: FontStyle.italic)),
|
||||
new TextSpan(text: ' years.'),
|
||||
]
|
||||
)
|
||||
),
|
||||
],
|
||||
justifyContent: FlexJustifyContent.collapse
|
||||
)
|
||||
|
@ -12,6 +12,7 @@
|
||||
library services;
|
||||
|
||||
export 'src/services/activity.dart';
|
||||
export 'src/services/assertions.dart';
|
||||
export 'src/services/asset_bundle.dart';
|
||||
export 'src/services/binding.dart';
|
||||
export 'src/services/fetch.dart';
|
||||
|
@ -5,6 +5,7 @@
|
||||
import 'dart:ui' as ui show Paragraph, ParagraphBuilder, ParagraphStyle, TextBox;
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'basic_types.dart';
|
||||
import 'text_editing.dart';
|
||||
@ -51,6 +52,7 @@ class TextSpan {
|
||||
final GestureRecognizer recognizer;
|
||||
|
||||
void build(ui.ParagraphBuilder builder) {
|
||||
assert(debugAssertValid());
|
||||
final bool hasStyle = style != null;
|
||||
if (hasStyle)
|
||||
builder.pushStyle(style.textStyle);
|
||||
@ -81,6 +83,7 @@ class TextSpan {
|
||||
}
|
||||
|
||||
TextSpan getSpanForPosition(TextPosition position) {
|
||||
assert(debugAssertValid());
|
||||
TextAffinity affinity = position.affinity;
|
||||
int targetOffset = position.offset;
|
||||
int offset = 0;
|
||||
@ -101,6 +104,7 @@ class TextSpan {
|
||||
}
|
||||
|
||||
String toPlainText() {
|
||||
assert(debugAssertValid());
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
visitTextSpan((TextSpan span) {
|
||||
buffer.write(span.text);
|
||||
@ -113,15 +117,47 @@ class TextSpan {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.writeln('$prefix$runtimeType:');
|
||||
String indent = '$prefix ';
|
||||
if (style != null)
|
||||
buffer.writeln(style.toString(indent));
|
||||
if (text != null)
|
||||
buffer.writeln('$indent"$text"');
|
||||
if (children != null)
|
||||
for (TextSpan child in children)
|
||||
buffer.writeln(child.toString(indent));
|
||||
if (children != null) {
|
||||
for (TextSpan child in children) {
|
||||
if (child != null) {
|
||||
buffer.write(child.toString(indent));
|
||||
} else {
|
||||
buffer.writeln('$indent<null>');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (style == null && text == null && children == null)
|
||||
buffer.writeln('$indent(empty)');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
bool debugAssertValid() {
|
||||
assert(() {
|
||||
if (!visitTextSpan((TextSpan span) {
|
||||
if (span.children != null) {
|
||||
for (TextSpan child in span.children) {
|
||||
if (child == null)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})) {
|
||||
throw new FlutterError(
|
||||
'TextSpan contains a null child.\n'
|
||||
'A TextSpan object with a non-null child list should not have any nulls in its child list.\n'
|
||||
'The full text in question was:\n'
|
||||
'${toString(" ")}'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator ==(dynamic other) {
|
||||
if (identical(this, other))
|
||||
return true;
|
||||
@ -149,6 +185,7 @@ class TextPainter {
|
||||
/// The (potentially styled) text to paint.
|
||||
TextSpan get text => _text;
|
||||
void set text(TextSpan value) {
|
||||
assert(value == null || value.debugAssertValid());
|
||||
if (_text == value)
|
||||
return;
|
||||
_text = value;
|
||||
|
@ -15,6 +15,7 @@ class RenderParagraph extends RenderBox {
|
||||
TextSpan text
|
||||
) : _textPainter = new TextPainter(text) {
|
||||
assert(text != null);
|
||||
assert(text.debugAssertValid());
|
||||
}
|
||||
|
||||
final TextPainter _textPainter;
|
||||
@ -24,6 +25,7 @@ class RenderParagraph extends RenderBox {
|
||||
/// The text to display
|
||||
TextSpan get text => _textPainter.text;
|
||||
void set text(TextSpan value) {
|
||||
assert(value.debugAssertValid());
|
||||
if (_textPainter.text == value)
|
||||
return;
|
||||
_textPainter.text = value;
|
||||
|
9
packages/flutter/lib/src/services/assertions.dart
Normal file
9
packages/flutter/lib/src/services/assertions.dart
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
class FlutterError extends AssertionError {
|
||||
FlutterError(this.message);
|
||||
final String message;
|
||||
String toString() => message;
|
||||
}
|
@ -27,4 +27,38 @@ void main() {
|
||||
expect(b1 == a2, isFalse);
|
||||
expect(c1 == b2, isFalse);
|
||||
});
|
||||
|
||||
test("TextSpan ", () {
|
||||
final TextSpan test = new TextSpan(
|
||||
text: 'a',
|
||||
style: new TextStyle(
|
||||
fontSize: 10.0
|
||||
),
|
||||
children: <TextSpan>[
|
||||
new TextSpan(
|
||||
text: 'b',
|
||||
children: <TextSpan>[
|
||||
new TextSpan()
|
||||
]
|
||||
),
|
||||
null,
|
||||
new TextSpan(
|
||||
text: 'c'
|
||||
),
|
||||
]
|
||||
);
|
||||
expect(test.toString(), equals(
|
||||
'TextSpan:\n'
|
||||
' inherit: true\n'
|
||||
' size: 10.0\n'
|
||||
' "a"\n'
|
||||
' TextSpan:\n'
|
||||
' "b"\n'
|
||||
' TextSpan:\n'
|
||||
' (empty)\n'
|
||||
' <null>\n'
|
||||
' TextSpan:\n'
|
||||
' "c"\n'
|
||||
));
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user