Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ class _NoEditablePropertiesMessage extends StatelessWidget {
' has no editable widget properties.\n\nThe Flutter Property Editor currently supports editing properties of type ',
style: theme.regularTextStyle,
),
TextSpan(text: 'string', style: fixedFontStyle),
TextSpan(text: 'String', style: fixedFontStyle),
const TextSpan(text: ', '),
TextSpan(text: 'int', style: fixedFontStyle),
const TextSpan(text: ', '),
Expand Down Expand Up @@ -341,31 +341,34 @@ class _WidgetNameAndDocumentation extends StatelessWidget {

@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(bottom: denseSpacing),
child: Text(
name,
style: Theme.of(context).fixedFontStyle.copyWith(
fontWeight: FontWeight.bold,
fontSize: defaultFontSize + 1,
return SelectionArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.only(bottom: denseSpacing),
child: Text(
name,
style: Theme.of(context).fixedFontStyle.copyWith(
fontWeight: FontWeight.bold,
fontSize: defaultFontSize + 1,
),
),
),
),
Row(
children: [
Expanded(
child: _ExpandableWidgetDocumentation(
documentation:
documentation ?? 'Creates ${addIndefiniteArticle(name)}.',
Row(
children: [
Expanded(
child: _ExpandableWidgetDocumentation(
documentation:
documentation ?? 'Creates ${addIndefiniteArticle(name)}.',
),
),
),
],
),
const PaddedDivider.noPadding(),
],
],
),
const PaddedDivider.noPadding(),
],
),
);
}
}
Expand Down Expand Up @@ -410,8 +413,7 @@ class _ExpandableWidgetDocumentationState
final paragraphs = widget.documentation.split('\n');

if (paragraphs.length == 1) {
return convertDartDocToRichText(
widget.documentation,
return DartDocConverter(widget.documentation).toText(
regularFontStyle: regularFontStyle,
fixedFontStyle: fixedFontStyle,
);
Expand All @@ -426,16 +428,14 @@ class _ExpandableWidgetDocumentationState
// or collapses the text block. Because the Dart doc is never very
// large, this is not an expensive operation. However, we could
// consider caching the result if this needs to be optimized.
convertDartDocToRichText(
firstParagraph,
DartDocConverter(firstParagraph).toText(
regularFontStyle: regularFontStyle,
fixedFontStyle: fixedFontStyle,
),
if (_isExpanded)
FadeTransition(
opacity: _expandAnimation,
child: convertDartDocToRichText(
otherParagraphs.join('\n'),
child: DartDocConverter(otherParagraphs.join('\n')).toText(
regularFontStyle: regularFontStyle,
fixedFontStyle: fixedFontStyle,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,77 +5,94 @@
import 'package:flutter/widgets.dart';
import '_utils_desktop.dart' if (dart.library.js_interop) '_utils_web.dart';

/// Converts a [dartDocText] String into a [RichText] widget.
///
/// Removes any brackets and backticks and displays the text inside them as
/// fixed font.
RichText convertDartDocToRichText(
String dartDocText, {
required TextStyle regularFontStyle,
required TextStyle fixedFontStyle,
}) {
final children = <TextSpan>[];
int currentIndex = 0;
/// Converts a [dartDocText] String into a [Text] widget.
class DartDocConverter {
DartDocConverter(this.dartDocText);

while (currentIndex < dartDocText.length) {
final openBracketIndex = dartDocText.indexOf('[', currentIndex);
final openBacktickIndex = dartDocText.indexOf('`', currentIndex);
final String dartDocText;

int nextSpecialCharIndex = -1;
bool isLink = false;
/// Converts the [dartDocText] String into a [Text] widget.
///
/// Removes any brackets and backticks and displays the text inside them with
/// [fixedFontStyle]. All other text uses [regularFontStyle].
Text toText({
required TextStyle regularFontStyle,
required TextStyle fixedFontStyle,
}) {
final children = toTextSpans(
regularFontStyle: regularFontStyle,
fixedFontStyle: fixedFontStyle,
);
return Text.rich(TextSpan(children: children));
}

if (openBracketIndex != -1 &&
(openBacktickIndex == -1 || openBracketIndex < openBacktickIndex)) {
nextSpecialCharIndex = openBracketIndex;
isLink = true;
} else if (openBacktickIndex != -1 &&
(openBracketIndex == -1 || openBacktickIndex < openBracketIndex)) {
nextSpecialCharIndex = openBacktickIndex;
}
@visibleForTesting
List<TextSpan> toTextSpans({
required TextStyle regularFontStyle,
required TextStyle fixedFontStyle,
}) {
final children = <TextSpan>[];
int currentIndex = 0;

if (nextSpecialCharIndex == -1) {
// No more special characters, add the remaining text.
children.add(
TextSpan(
text: dartDocText.substring(currentIndex),
style: regularFontStyle,
),
);
break;
}
while (currentIndex < dartDocText.length) {
final openBracketIndex = dartDocText.indexOf('[', currentIndex);
final openBacktickIndex = dartDocText.indexOf('`', currentIndex);

// Add text before the special character.
children.add(
TextSpan(
text: dartDocText.substring(currentIndex, nextSpecialCharIndex),
style: regularFontStyle,
),
);
int nextSpecialCharIndex = -1;
bool isLink = false;

final closeIndex = dartDocText.indexOf(
isLink ? ']' : '`',
isLink ? nextSpecialCharIndex : nextSpecialCharIndex + 1,
);
if (closeIndex == -1) {
// Treat unmatched brackets/backticks as regular text.
if (openBracketIndex != -1 &&
(openBacktickIndex == -1 || openBracketIndex < openBacktickIndex)) {
nextSpecialCharIndex = openBracketIndex;
isLink = true;
} else if (openBacktickIndex != -1 &&
(openBracketIndex == -1 || openBacktickIndex < openBracketIndex)) {
nextSpecialCharIndex = openBacktickIndex;
}

if (nextSpecialCharIndex == -1) {
// No more special characters, add the remaining text.
children.add(
TextSpan(
text: dartDocText.substring(currentIndex),
style: regularFontStyle,
),
);
break;
}

// Add text before the special character.
children.add(
TextSpan(
text: dartDocText.substring(nextSpecialCharIndex),
text: dartDocText.substring(currentIndex, nextSpecialCharIndex),
style: regularFontStyle,
),
);
currentIndex = dartDocText.length; // Effectively break the loop.
} else {
final content = dartDocText.substring(
nextSpecialCharIndex + 1,
closeIndex,

final closeIndex = dartDocText.indexOf(
isLink ? ']' : '`',
isLink ? nextSpecialCharIndex : nextSpecialCharIndex + 1,
);
children.add(TextSpan(text: content, style: fixedFontStyle));
currentIndex = closeIndex + 1;
if (closeIndex == -1) {
// Treat unmatched brackets/backticks as regular text.
children.add(
TextSpan(
text: dartDocText.substring(nextSpecialCharIndex),
style: regularFontStyle,
),
);
currentIndex = dartDocText.length; // Effectively break the loop.
} else {
final content = dartDocText.substring(
nextSpecialCharIndex + 1,
closeIndex,
);
children.add(TextSpan(text: content, style: fixedFontStyle));
currentIndex = closeIndex + 1;
}
}
return children;
}

return RichText(text: TextSpan(children: children));
}

/// Workaround to force reload the Property Editor when it disconnects.
Expand Down
Loading
Loading