Unverified Commit 23f7985e authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Improve how AttributedStrings are presented in the widget inspector (#92450)

parent bd935e5d
......@@ -2839,14 +2839,23 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
}
}
/// If the [value] of the property equals [defaultValue] the priority [level]
/// of the property is downgraded to [DiagnosticLevel.fine] as the property
/// value is uninteresting.
/// The default value of this property, when it has not been set to a specific
/// value.
///
/// For most [DiagnosticsProperty] classes, if the [value] of the property
/// equals [defaultValue], then the priority [level] of the property is
/// downgraded to [DiagnosticLevel.fine] on the basis that the property value
/// is uninteresting. This is implemented by [isInteresting].
///
/// The [defaultValue] is [kNoDefaultValue] by default. Otherwise it must be of
/// type `T?`.
final Object? defaultValue;
/// Whether to consider the property's value interesting. When a property is
/// uninteresting, its [level] is downgraded to [DiagnosticLevel.fine]
/// regardless of the value provided as the constructor's `level` argument.
bool get isInteresting => defaultValue == kNoDefaultValue || value != defaultValue;
final DiagnosticLevel _defaultLevel;
/// Priority level of the diagnostic used to control which diagnostics should
......@@ -2870,8 +2879,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
if (value == null && missingIfNull)
return DiagnosticLevel.warning;
// Use a low level when the value matches the default value.
if (defaultValue != kNoDefaultValue && value == defaultValue)
if (!isInteresting)
return DiagnosticLevel.fine;
return _defaultLevel;
......@@ -3549,7 +3557,9 @@ class DiagnosticsBlock extends DiagnosticsNode {
@override
final DiagnosticLevel level;
final String? _description;
@override
final Object? value;
......
......@@ -255,6 +255,57 @@ class AttributedString {
}
}
/// A [DiagnosticsProperty] for [AttributedString]s, which shows a string
/// when there are no attributes, and more details otherwise.
class AttributedStringProperty extends DiagnosticsProperty<AttributedString> {
/// Create a diagnostics property for an [AttributedString] object.
///
/// Such properties are used with [SemanticsData] objects.
AttributedStringProperty(
String name,
AttributedString? value, {
bool showName = true,
this.showWhenEmpty = false,
Object? defaultValue = kNoDefaultValue,
DiagnosticLevel level = DiagnosticLevel.info,
String? description,
}) : assert(showName != null),
assert(level != null),
super(
name,
value,
showName: showName,
defaultValue: defaultValue,
level: level,
description: description,
);
/// Whether to show the property when the [value] is an [AttributedString]
/// whose [AttributedString.string] is the empty string.
///
/// This overrides [defaultValue].
final bool showWhenEmpty;
@override
bool get isInteresting => super.isInteresting && (showWhenEmpty || (value != null && value!.string.isNotEmpty));
@override
String valueToString({TextTreeConfiguration? parentConfiguration}) {
if (value == null)
return 'null';
String text = value!.string;
if (parentConfiguration != null &&
!parentConfiguration.lineBreakProperties) {
// This follows a similar pattern to StringProperty.
text = text.replaceAll('\n', r'\n');
}
if (value!.attributes.isEmpty) {
return '"$text"';
}
return '"$text" ${value!.attributes}'; // the attributes will be in square brackets since they're a list
}
}
/// Summary information about a [SemanticsNode] object.
///
/// A semantics node might [SemanticsNode.mergeAllDescendantsIntoThisNode],
......@@ -303,9 +354,9 @@ class SemanticsData with Diagnosticable {
assert(attributedHint != null),
assert(attributedLabel.string == '' || textDirection != null, 'A SemanticsData object with label "${attributedLabel.string}" had a null textDirection.'),
assert(attributedValue.string == '' || textDirection != null, 'A SemanticsData object with value "${attributedValue.string}" had a null textDirection.'),
assert(attributedHint.string == '' || textDirection != null, 'A SemanticsData object with hint "${attributedHint.string}" had a null textDirection.'),
assert(attributedDecreasedValue.string == '' || textDirection != null, 'A SemanticsData object with decreasedValue "${attributedDecreasedValue.string}" had a null textDirection.'),
assert(attributedIncreasedValue.string == '' || textDirection != null, 'A SemanticsData object with increasedValue "${attributedIncreasedValue.string}" had a null textDirection.'),
assert(attributedHint.string == '' || textDirection != null, 'A SemanticsData object with hint "${attributedHint.string}" had a null textDirection.'),
assert(rect != null);
/// A bit field of [SemanticsFlag]s that apply to this node.
......@@ -317,62 +368,82 @@ class SemanticsData with Diagnosticable {
/// A textual description for the current label of the node.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedLabel].
String get label => attributedLabel.string;
/// A textual description for the current label of the node in
/// [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [label], which exposes just the raw text.
final AttributedString attributedLabel;
/// A textual description for the current value of the node.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedValue].
String get value => attributedValue.string;
/// A textual description for the current value of the node in
/// [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [value], which exposes just the raw text.
final AttributedString attributedValue;
/// The value that [value] will become after performing a
/// [SemanticsAction.increase] action.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedIncreasedValue].
String get increasedValue => attributedIncreasedValue.string;
/// The value that [value] will become after performing a
/// [SemanticsAction.increase] action in [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [increasedValue], which exposes just the raw text.
final AttributedString attributedIncreasedValue;
/// The value that [value] will become after performing a
/// [SemanticsAction.decrease] action.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedDecreasedValue].
String get decreasedValue => attributedDecreasedValue.string;
/// The value that [value] will become after performing a
/// [SemanticsAction.decrease] action in [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [decreasedValue], which exposes just the raw text.
final AttributedString attributedDecreasedValue;
/// A brief description of the result of performing an action on this node.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedHint].
String get hint => attributedHint.string;
/// A brief description of the result of performing an action on this node
/// in [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [hint], which exposes just the raw text.
final AttributedString attributedHint;
/// The reading direction for the text in [label], [value], [hint],
/// [increasedValue], and [decreasedValue].
/// The reading direction for the text in [label], [value],
/// [increasedValue], [decreasedValue], and [hint].
final TextDirection? textDirection;
/// The currently selected text (or the position of the cursor) within [value]
......@@ -524,11 +595,11 @@ class SemanticsData with Diagnosticable {
describeEnum(flag),
];
properties.add(IterableProperty<String>('flags', flagSummary, ifEmpty: null));
properties.add(StringProperty('label', attributedLabel.attributes.isEmpty ? label : attributedLabel.toString(), defaultValue: ''));
properties.add(StringProperty('value', attributedValue.attributes.isEmpty? value :attributedValue.toString(), defaultValue: ''));
properties.add(StringProperty('increasedValue', attributedIncreasedValue.attributes.isEmpty? increasedValue :attributedIncreasedValue.toString(), defaultValue: ''));
properties.add(StringProperty('decreasedValue', attributedDecreasedValue.attributes.isEmpty? decreasedValue :attributedDecreasedValue.toString(), defaultValue: ''));
properties.add(StringProperty('hint', attributedHint.attributes.isEmpty? hint :attributedHint.toString(), defaultValue: ''));
properties.add(AttributedStringProperty('label', attributedLabel));
properties.add(AttributedStringProperty('value', attributedValue));
properties.add(AttributedStringProperty('increasedValue', attributedIncreasedValue));
properties.add(AttributedStringProperty('decreasedValue', attributedDecreasedValue));
properties.add(AttributedStringProperty('hint', attributedHint));
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
if (textSelection?.isValid == true)
properties.add(MessageProperty('textSelection', '[${textSelection!.start}, ${textSelection!.end}]'));
......@@ -977,10 +1048,10 @@ class SemanticsProperties extends DiagnosticableTree {
///
/// * [SemanticsConfiguration.label] for a description of how this is exposed
/// in TalkBack and VoiceOver.
/// * [attributedLabel] for a [AttributedString] version of this property.
/// * [attributedLabel] for an [AttributedString] version of this property.
final String? label;
/// Provides a [AttributedString] version of textual description of the widget.
/// Provides an [AttributedString] version of textual description of the widget.
///
/// If a [attributedLabel] is provided, there must either by an ambient
/// [Directionality] or an explicit [textDirection] should be provided.
......@@ -1007,10 +1078,10 @@ class SemanticsProperties extends DiagnosticableTree {
///
/// * [SemanticsConfiguration.value] for a description of how this is exposed
/// in TalkBack and VoiceOver.
/// * [attributedLabel] for a [AttributedString] version of this property.
/// * [attributedLabel] for an [AttributedString] version of this property.
final String? value;
/// Provides a [AttributedString] version of textual description of the value
/// Provides an [AttributedString] version of textual description of the value
/// of the widget.
///
/// If a [attributedValue] is provided, there must either by an ambient
......@@ -1040,7 +1111,7 @@ class SemanticsProperties extends DiagnosticableTree {
///
/// * [SemanticsConfiguration.increasedValue] for a description of how this
/// is exposed in TalkBack and VoiceOver.
/// * [attributedIncreasedValue] for a [AttributedString] version of this
/// * [attributedIncreasedValue] for an [AttributedString] version of this
/// property.
final String? increasedValue;
......@@ -1075,7 +1146,7 @@ class SemanticsProperties extends DiagnosticableTree {
///
/// * [SemanticsConfiguration.decreasedValue] for a description of how this
/// is exposed in TalkBack and VoiceOver.
/// * [attributedDecreasedValue] for a [AttributedString] version of this
/// * [attributedDecreasedValue] for an [AttributedString] version of this
/// property.
final String? decreasedValue;
......@@ -1109,10 +1180,10 @@ class SemanticsProperties extends DiagnosticableTree {
///
/// * [SemanticsConfiguration.hint] for a description of how this is exposed
/// in TalkBack and VoiceOver.
/// * [attributedHint] for a [AttributedString] version of this property.
/// * [attributedHint] for an [AttributedString] version of this property.
final String? hint;
/// Provides a [AttributedString] version of brief textual description of the
/// Provides an [AttributedString] version of brief textual description of the
/// result of an action performed on the widget.
///
/// If a [attributedHint] is provided, there must either by an ambient
......@@ -1138,8 +1209,8 @@ class SemanticsProperties extends DiagnosticableTree {
/// On iOS, these are always ignored and the default [hint] is used instead.
final SemanticsHintOverrides? hintOverrides;
/// The reading direction of the [label], [value], [hint], [increasedValue],
/// and [decreasedValue].
/// The reading direction of the [label], [value], [increasedValue],
/// [decreasedValue], and [hint].
///
/// Defaults to the ambient [Directionality].
final TextDirection? textDirection;
......@@ -1409,15 +1480,19 @@ class SemanticsProperties extends DiagnosticableTree {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<bool>('checked', checked, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('selected', selected, defaultValue: null));
properties.add(StringProperty('label', label, defaultValue: ''));
properties.add(StringProperty('attributedLabel', attributedLabel.toString(), defaultValue: ''));
properties.add(StringProperty('value', value));
properties.add(StringProperty('attributedValue', attributedValue.toString(), defaultValue: ''));
properties.add(StringProperty('hint', hint));
properties.add(StringProperty('attributedHint', attributedHint.toString(), defaultValue: ''));
properties.add(StringProperty('label', label, defaultValue: null));
properties.add(AttributedStringProperty('attributedLabel', attributedLabel, defaultValue: null));
properties.add(StringProperty('value', value, defaultValue: null));
properties.add(AttributedStringProperty('attributedValue', attributedValue, defaultValue: null));
properties.add(StringProperty('increasedValue', value, defaultValue: null));
properties.add(AttributedStringProperty('attributedIncreasedValue', attributedIncreasedValue, defaultValue: null));
properties.add(StringProperty('decreasedValue', value, defaultValue: null));
properties.add(AttributedStringProperty('attributedDecreasedValue', attributedDecreasedValue, defaultValue: null));
properties.add(StringProperty('hint', hint, defaultValue: null));
properties.add(AttributedStringProperty('attributedHint', attributedHint, defaultValue: null));
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
properties.add(DiagnosticsProperty<SemanticsHintOverrides>('hintOverrides', hintOverrides));
properties.add(DiagnosticsProperty<SemanticsHintOverrides>('hintOverrides', hintOverrides, defaultValue: null));
}
@override
......@@ -1837,26 +1912,26 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
}
bool _isDifferentFromCurrentSemanticAnnotation(SemanticsConfiguration config) {
return _attributedLabel != config.attributedLabel ||
_attributedHint != config.attributedHint ||
_elevation != config.elevation ||
_thickness != config.thickness ||
_attributedValue != config.attributedValue ||
_attributedIncreasedValue != config.attributedIncreasedValue ||
_attributedDecreasedValue != config.attributedDecreasedValue ||
_flags != config._flags ||
_textDirection != config.textDirection ||
_sortKey != config._sortKey ||
_textSelection != config._textSelection ||
_scrollPosition != config._scrollPosition ||
_scrollExtentMax != config._scrollExtentMax ||
_scrollExtentMin != config._scrollExtentMin ||
_actionsAsBits != config._actionsAsBits ||
indexInParent != config.indexInParent ||
platformViewId != config.platformViewId ||
_maxValueLength != config._maxValueLength ||
_currentValueLength != config._currentValueLength ||
_mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants;
return _attributedLabel != config.attributedLabel
|| _attributedHint != config.attributedHint
|| _elevation != config.elevation
|| _thickness != config.thickness
|| _attributedValue != config.attributedValue
|| _attributedIncreasedValue != config.attributedIncreasedValue
|| _attributedDecreasedValue != config.attributedDecreasedValue
|| _flags != config._flags
|| _textDirection != config.textDirection
|| _sortKey != config._sortKey
|| _textSelection != config._textSelection
|| _scrollPosition != config._scrollPosition
|| _scrollExtentMax != config._scrollExtentMax
|| _scrollExtentMin != config._scrollExtentMin
|| _actionsAsBits != config._actionsAsBits
|| indexInParent != config.indexInParent
|| platformViewId != config.platformViewId
|| _maxValueLength != config._maxValueLength
|| _currentValueLength != config._currentValueLength
|| _mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants;
}
// TAGS, LABELS, ACTIONS
......@@ -1883,74 +1958,93 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
/// A textual description of this node.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedLabel].
String get label => _attributedLabel.string;
/// A textual description of this node in [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [label], which exposes just the raw text.
AttributedString get attributedLabel => _attributedLabel;
AttributedString _attributedLabel = _kEmptyConfig.attributedLabel;
/// A textual description for the current value of the node.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedValue].
String get value => _attributedValue.string;
/// A textual description for the current value of the node in
/// [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [value], which exposes just the raw text.
AttributedString get attributedValue => _attributedValue;
AttributedString _attributedValue = _kEmptyConfig.attributedValue;
/// The value that [value] will have after a [SemanticsAction.decrease] action
/// The value that [value] will have after a [SemanticsAction.increase] action
/// has been performed.
///
/// This property is only valid if the [SemanticsAction.decrease] action is
/// This property is only valid if the [SemanticsAction.increase] action is
/// available on this node.
///
/// The reading direction is given by [textDirection].
String get decreasedValue => _attributedDecreasedValue.string;
///
/// This exposes the raw text of the [attributedIncreasedValue].
String get increasedValue => _attributedIncreasedValue.string;
/// The value in [AttributedString] format that [value] or [attributedValue]
/// will have after a [SemanticsAction.decrease] action has been performed.
/// will have after a [SemanticsAction.increase] action has been performed.
///
/// This property is only valid if the [SemanticsAction.decrease] action is
/// This property is only valid if the [SemanticsAction.increase] action is
/// available on this node.
///
/// The reading direction is given by [textDirection].
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
AttributedString _attributedDecreasedValue = _kEmptyConfig.attributedDecreasedValue;
///
/// See also [increasedValue], which exposes just the raw text.
AttributedString get attributedIncreasedValue => _attributedIncreasedValue;
AttributedString _attributedIncreasedValue = _kEmptyConfig.attributedIncreasedValue;
/// The value that [value] will have after a [SemanticsAction.increase] action
/// The value that [value] will have after a [SemanticsAction.decrease] action
/// has been performed.
///
/// This property is only valid if the [SemanticsAction.increase] action is
/// This property is only valid if the [SemanticsAction.decrease] action is
/// available on this node.
///
/// The reading direction is given by [textDirection].
String get increasedValue => _attributedIncreasedValue.string;
///
/// This exposes the raw text of the [attributedDecreasedValue].
String get decreasedValue => _attributedDecreasedValue.string;
/// The value in [AttributedString] format that [value] or [attributedValue]
/// will have after a [SemanticsAction.increase] action has been performed.
/// will have after a [SemanticsAction.decrease] action has been performed.
///
/// This property is only valid if the [SemanticsAction.increase] action is
/// This property is only valid if the [SemanticsAction.decrease] action is
/// available on this node.
///
/// The reading direction is given by [textDirection].
AttributedString get attributedIncreasedValue => _attributedIncreasedValue;
AttributedString _attributedIncreasedValue = _kEmptyConfig.attributedIncreasedValue;
///
/// See also [decreasedValue], which exposes just the raw text.
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
AttributedString _attributedDecreasedValue = _kEmptyConfig.attributedDecreasedValue;
/// A brief description of the result of performing an action on this node.
///
/// The reading direction is given by [textDirection].
///
/// This exposes the raw text of the [attributedHint].
String get hint => _attributedHint.string;
/// A brief description of the result of performing an action on this node
/// in [AttributedString] format.
///
/// The reading direction is given by [textDirection].
///
/// See also [hint], which exposes just the raw text.
AttributedString get attributedHint => _attributedHint;
AttributedString _attributedHint = _kEmptyConfig.attributedHint;
......@@ -2517,11 +2611,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
properties.add(IterableProperty<String>('flags', flags, ifEmpty: null));
properties.add(FlagProperty('isInvisible', value: isInvisible, ifTrue: 'invisible'));
properties.add(FlagProperty('isHidden', value: hasFlag(SemanticsFlag.isHidden), ifTrue: 'HIDDEN'));
properties.add(StringProperty('label', _attributedLabel.attributes.isEmpty ? _attributedLabel.string : _attributedLabel.toString(), defaultValue: ''));
properties.add(StringProperty('value', _attributedValue.attributes.isEmpty ? _attributedValue.string : _attributedValue.toString(), defaultValue: ''));
properties.add(StringProperty('increasedValue', _attributedIncreasedValue.attributes.isEmpty ? _attributedIncreasedValue.string : _attributedIncreasedValue.toString(), defaultValue: ''));
properties.add(StringProperty('decreasedValue', _attributedDecreasedValue.attributes.isEmpty ? _attributedDecreasedValue.string : _attributedDecreasedValue.toString(), defaultValue: ''));
properties.add(StringProperty('hint', _attributedHint.attributes.isEmpty ? _attributedHint.string : _attributedHint.toString(), defaultValue: ''));
properties.add(AttributedStringProperty('label', _attributedLabel));
properties.add(AttributedStringProperty('value', _attributedValue));
properties.add(AttributedStringProperty('increasedValue', _attributedIncreasedValue));
properties.add(AttributedStringProperty('decreasedValue', _attributedDecreasedValue));
properties.add(AttributedStringProperty('hint', _attributedHint));
properties.add(EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null));
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
if (_textSelection?.isValid == true)
......@@ -3692,7 +3786,8 @@ class SemanticsConfiguration {
/// The reading direction is given by [textDirection].
///
/// See also:
/// * [attributedLabel]: which is the [AttributedString] of this property.
///
/// * [attributedLabel], which is the [AttributedString] of this property.
String get label => _attributedLabel.string;
set label(String label) {
assert(label != null);
......@@ -3710,6 +3805,10 @@ class SemanticsConfiguration {
/// concatenated value is then used as the `Text` description.
///
/// The reading direction is given by [textDirection].
///
/// See also:
///
/// * [label], which is the raw text of this property.
AttributedString get attributedLabel => _attributedLabel;
AttributedString _attributedLabel = AttributedString('');
set attributedLabel(AttributedString attributedLabel) {
......@@ -3726,10 +3825,10 @@ class SemanticsConfiguration {
/// See also:
///
/// * [attributedValue], which is the [AttributedString] of this property.
/// * [decreasedValue] and [attributedDecreasedValue], describes what
/// [value] will be after performing [SemanticsAction.decrease].
/// * [increasedValue] and [attributedIncreasedValue], describes what
/// * [increasedValue] and [attributedIncreasedValue], which describe what
/// [value] will be after performing [SemanticsAction.increase].
/// * [decreasedValue] and [attributedDecreasedValue], which describe what
/// [value] will be after performing [SemanticsAction.decrease].
String get value => _attributedValue.string;
set value(String value) {
assert(value != null);
......@@ -3750,10 +3849,11 @@ class SemanticsConfiguration {
///
/// See also:
///
/// * [attributedDecreasedValue], describes what [value] will be after
/// performing [SemanticsAction.decrease].
/// * [attributedIncreasedValue], describes what [value] will be after
/// * [value], which is the raw text of this property.
/// * [attributedIncreasedValue], which describes what [value] will be after
/// performing [SemanticsAction.increase].
/// * [attributedDecreasedValue], which describes what [value] will be after
/// performing [SemanticsAction.decrease].
AttributedString get attributedValue => _attributedValue;
AttributedString _attributedValue = AttributedString('');
set attributedValue(AttributedString attributedValue) {
......@@ -3762,70 +3862,83 @@ class SemanticsConfiguration {
}
/// The value that [value] will have after performing a
/// [SemanticsAction.decrease] action.
/// [SemanticsAction.increase] action.
///
/// Setting this attribute will override the [attributedDecreasedValue].
/// Setting this attribute will override the [attributedIncreasedValue].
///
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
/// a handler for [SemanticsAction.decrease] is provided and one of the
/// One of the [attributedIncreasedValue] or [increasedValue] must be set if
/// a handler for [SemanticsAction.increase] is provided and one of the
/// [value] or [attributedValue] is set.
///
/// The reading direction is given by [textDirection].
String get decreasedValue => _attributedDecreasedValue.string;
set decreasedValue(String decreasedValue) {
assert(decreasedValue != null);
_attributedDecreasedValue = AttributedString(decreasedValue);
///
/// See also:
///
/// * [attributedIncreasedValue], which is the [AttributedString] of this property.
String get increasedValue => _attributedIncreasedValue.string;
set increasedValue(String increasedValue) {
assert(increasedValue != null);
_attributedIncreasedValue = AttributedString(increasedValue);
_hasBeenAnnotated = true;
}
/// The value that [value] will have after performing a
/// [SemanticsAction.decrease] action in [AttributedString] format.
/// [SemanticsAction.increase] action in [AttributedString] format.
///
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
/// a handler for [SemanticsAction.decrease] is provided and one of the
/// One of the [attributedIncreasedValue] or [increasedValue] must be set if
/// a handler for [SemanticsAction.increase] is provided and one of the
/// [value] or [attributedValue] is set.
///
/// The reading direction is given by [textDirection].
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
AttributedString _attributedDecreasedValue = AttributedString('');
set attributedDecreasedValue(AttributedString attributedDecreasedValue) {
_attributedDecreasedValue = attributedDecreasedValue;
///
/// See also:
///
/// * [increasedValue], which is the raw text of this property.
AttributedString get attributedIncreasedValue => _attributedIncreasedValue;
AttributedString _attributedIncreasedValue = AttributedString('');
set attributedIncreasedValue(AttributedString attributedIncreasedValue) {
_attributedIncreasedValue = attributedIncreasedValue;
_hasBeenAnnotated = true;
}
/// The value that [value] will have after performing a
/// [SemanticsAction.increase] action.
/// [SemanticsAction.decrease] action.
///
/// Setting this attribute will override the [attributedIncreasedValue].
/// Setting this attribute will override the [attributedDecreasedValue].
///
/// One of the [attributedIncreasedValue] or [increasedValue] must be set if
/// a handler for [SemanticsAction.increase] is provided and one of the
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
/// a handler for [SemanticsAction.decrease] is provided and one of the
/// [value] or [attributedValue] is set.
///
/// The reading direction is given by [textDirection].
String get increasedValue => _attributedIncreasedValue.string;
set increasedValue(String increasedValue) {
assert(increasedValue != null);
_attributedIncreasedValue = AttributedString(increasedValue);
///
/// * [attributedDecreasedValue], which is the [AttributedString] of this property.
String get decreasedValue => _attributedDecreasedValue.string;
set decreasedValue(String decreasedValue) {
assert(decreasedValue != null);
_attributedDecreasedValue = AttributedString(decreasedValue);
_hasBeenAnnotated = true;
}
/// The value that [value] will have after performing a
/// [SemanticsAction.increase] action in [AttributedString] format.
/// [SemanticsAction.decrease] action in [AttributedString] format.
///
/// One of the [attributedIncreasedValue] or [increasedValue] must be set if
/// a handler for [SemanticsAction.increase] is provided and one of the
/// One of the [attributedDecreasedValue] or [decreasedValue] must be set if
/// a handler for [SemanticsAction.decrease] is provided and one of the
/// [value] or [attributedValue] is set.
///
/// The reading direction is given by [textDirection].
AttributedString get attributedIncreasedValue => _attributedIncreasedValue;
AttributedString _attributedIncreasedValue = AttributedString('');
set attributedIncreasedValue(AttributedString attributedIncreasedValue) {
_attributedIncreasedValue = attributedIncreasedValue;
///
/// See also:
///
/// * [decreasedValue], which is the raw text of this property.
AttributedString get attributedDecreasedValue => _attributedDecreasedValue;
AttributedString _attributedDecreasedValue = AttributedString('');
set attributedDecreasedValue(AttributedString attributedDecreasedValue) {
_attributedDecreasedValue = attributedDecreasedValue;
_hasBeenAnnotated = true;
}
/// A brief description of the result of performing an action on this node.
///
/// Setting this attribute will override the [attributedHint].
......@@ -3833,7 +3946,8 @@ class SemanticsConfiguration {
/// The reading direction is given by [textDirection].
///
/// See also:
/// * [attributedHint]: which is the [AttributedString] of this property.
///
/// * [attributedHint], which is the [AttributedString] of this property.
String get hint => _attributedHint.string;
set hint(String hint) {
assert(hint != null);
......@@ -3851,6 +3965,10 @@ class SemanticsConfiguration {
/// concatenated value is then used as the `Text` description.
///
/// The reading direction is given by [textDirection].
///
/// See also:
///
/// * [hint], which is the raw text of this property.
AttributedString get attributedHint => _attributedHint;
AttributedString _attributedHint = AttributedString('');
set attributedHint(AttributedString attributedHint) {
......
......@@ -69,6 +69,10 @@ void main() {
expect(config.label, 'label1');
expect(config.attributedLabel.string, 'label1');
expect(config.attributedLabel.attributes.isEmpty, isTrue);
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#1(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label1")',
);
config.attributedLabel = AttributedString(
'label2',
......@@ -81,16 +85,28 @@ void main() {
expect(config.attributedLabel.attributes.length, 1);
expect(config.attributedLabel.attributes[0] is SpellOutStringAttribute, isTrue);
expect(config.attributedLabel.attributes[0].range, const TextRange(start: 0, end: 1));
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#2(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
);
config.label = 'label3';
expect(config.label, 'label3');
expect(config.attributedLabel.string, 'label3');
expect(config.attributedLabel.attributes.isEmpty, isTrue);
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#3(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3")',
);
config.value = 'value1';
expect(config.value, 'value1');
expect(config.attributedValue.string, 'value1');
expect(config.attributedValue.attributes.isEmpty, isTrue);
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#4(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value1")',
);
config.attributedValue = AttributedString(
'value2',
......@@ -103,16 +119,28 @@ void main() {
expect(config.attributedValue.attributes.length, 1);
expect(config.attributedValue.attributes[0] is SpellOutStringAttribute, isTrue);
expect(config.attributedValue.attributes[0].range, const TextRange(start: 0, end: 1));
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
);
config.value = 'value3';
expect(config.value, 'value3');
expect(config.attributedValue.string, 'value3');
expect(config.attributedValue.attributes.isEmpty, isTrue);
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3")',
);
config.hint = 'hint1';
expect(config.hint, 'hint1');
expect(config.attributedHint.string, 'hint1');
expect(config.attributedHint.attributes.isEmpty, isTrue);
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#7(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint1")',
);
config.attributedHint = AttributedString(
'hint2',
......@@ -125,11 +153,19 @@ void main() {
expect(config.attributedHint.attributes.length, 1);
expect(config.attributedHint.attributes[0] is SpellOutStringAttribute, isTrue);
expect(config.attributedHint.attributes[0].range, const TextRange(start: 0, end: 1));
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#8(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
);
config.hint = 'hint3';
expect(config.hint, 'hint3');
expect(config.attributedHint.string, 'hint3');
expect(config.attributedHint.attributes.isEmpty, isTrue);
expect(
(SemanticsNode()..updateWith(config: config)).toString(),
'SemanticsNode#9(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint3")',
);
});
test('mutate existing semantic node list errors', () {
......@@ -654,6 +690,7 @@ void main() {
expect(result.attributes.length, 2);
expect(result.attributes[0].range, const TextRange(start:0, end:4));
expect(result.attributes[0] is SpellOutStringAttribute, isTrue);
expect(result.toString(), "AttributedString('string1string2', attributes: [SpellOutStringAttribute(TextRange(start: 0, end: 4)), LocaleStringAttribute(TextRange(start: 7, end: 11), es-MX)])");
});
test('Semantics id does not repeat', () {
......
......@@ -151,6 +151,17 @@ void main() {
expect(SemanticsUpdateBuilderSpy.observations[1]!.hintAttributes![0] is SpellOutStringAttribute, isTrue);
expect(SemanticsUpdateBuilderSpy.observations[1]!.hintAttributes![0].range, const TextRange(start: 1, end: 2));
expect(
tester.widget(find.byType(Semantics)).toString(),
'Semantics('
'container: false, '
'properties: SemanticsProperties, '
'attributedLabel: "label" [SpellOutStringAttribute(TextRange(start: 0, end: 5))], '
'attributedValue: "value" [LocaleStringAttribute(TextRange(start: 0, end: 5), en-MX)], '
'attributedHint: "hint" [SpellOutStringAttribute(TextRange(start: 1, end: 2))]' // ignore: missing_whitespace_between_adjacent_strings
')',
);
SemanticsUpdateBuilderSpy.observations.clear();
handle.dispose();
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment