Reverts "Feat: Add a11y for loading indicators (#165173)" (#178316)

<!-- start_original_pr_link -->
Reverts: flutter/flutter#165173
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: chingjun
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: The PR did not finish "Google Testing", and
actually caused several failures in Google
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: rkishan516
<!-- end_original_pr_author -->

<!-- start_reviewers -->
Reviewed By: {chunhtai, flutter-zl}
<!-- end_reviewers -->

<!-- start_revert_body -->
This change reverts the following previous change:
Feat: Add a11y for loading indicators
fixes: #161631 

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
<!-- end_revert_body -->

Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
This commit is contained in:
auto-submit[bot] 2025-11-11 11:04:20 -08:00 committed by GitHub
parent b1d5f03351
commit ef29db350f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 35 additions and 501 deletions

View File

@ -258,8 +258,6 @@ void sendSemanticsUpdate() {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
_semanticsUpdate(builder.build());
}
@ -321,8 +319,6 @@ void sendSemanticsUpdateWithRole() {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
_semanticsUpdate(builder.build());
}
@ -384,8 +380,6 @@ void sendSemanticsUpdateWithLocale() {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: Locale('es', 'MX'),
minValue: '0',
maxValue: '0',
);
_semanticsUpdate(builder.build());
}
@ -442,8 +436,6 @@ void sendSemanticsUpdateWithIsLink() {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: Locale('es', 'MX'),
minValue: '0',
maxValue: '0',
);
_semanticsUpdate(builder.build());
}

View File

@ -1975,8 +1975,6 @@ abstract class SemanticsUpdateBuilder {
SemanticsHitTestBehavior hitTestBehavior = SemanticsHitTestBehavior.defer,
required SemanticsInputType inputType,
required Locale? locale,
required String minValue,
required String maxValue,
});
/// Update the custom semantics action associated with the given `id`.
@ -2058,8 +2056,6 @@ base class _NativeSemanticsUpdateBuilder extends NativeFieldWrapperClass1
SemanticsHitTestBehavior hitTestBehavior = SemanticsHitTestBehavior.defer,
required SemanticsInputType inputType,
required Locale? locale,
required String minValue,
required String maxValue,
}) {
assert(_matrix4IsValid(transform));
assert(
@ -2111,8 +2107,6 @@ base class _NativeSemanticsUpdateBuilder extends NativeFieldWrapperClass1
hitTestBehavior.index,
inputType.index,
locale?.toLanguageTag() ?? '',
minValue,
maxValue,
);
}
@ -2163,8 +2157,6 @@ base class _NativeSemanticsUpdateBuilder extends NativeFieldWrapperClass1
Int32,
Int32,
Handle,
Handle,
Handle,
)
>(symbol: 'SemanticsUpdateBuilder::updateNode')
external void _updateNode(
@ -2212,8 +2204,6 @@ base class _NativeSemanticsUpdateBuilder extends NativeFieldWrapperClass1
int hitTestBehaviorIndex,
int inputType,
String locale,
String minValue,
String maxValue,
);
@override

View File

@ -145,8 +145,6 @@ struct SemanticsNode {
double scrollPosition = std::nan("");
double scrollExtentMax = std::nan("");
double scrollExtentMin = std::nan("");
std::string minValue;
std::string maxValue;
std::string identifier;
std::string label;
StringAttributes labelAttributes;

View File

@ -74,9 +74,7 @@ void SemanticsUpdateBuilder::updateNode(
int validationResult,
int hitTestBehavior,
int inputType,
std::string locale,
std::string minValue,
std::string maxValue) {
std::string locale) {
FML_CHECK(scrollChildren == 0 ||
(scrollChildren > 0 && childrenInHitTestOrder.data()))
<< "Semantics update contained scrollChildren but did not have "
@ -98,8 +96,6 @@ void SemanticsUpdateBuilder::updateNode(
node.scrollPosition = scrollPosition;
node.scrollExtentMax = scrollExtentMax;
node.scrollExtentMin = scrollExtentMin;
node.minValue = std::move(minValue);
node.maxValue = std::move(maxValue);
node.rect = SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
SafeNarrow(right), SafeNarrow(bottom));
node.identifier = std::move(identifier);

View File

@ -73,9 +73,7 @@ class SemanticsUpdateBuilder
int validationResult,
int hitTestBehavior,
int inputType,
std::string locale,
std::string minValue,
std::string maxValue);
std::string locale);
void updateCustomAction(int id,
std::string label,

View File

@ -753,8 +753,6 @@ class SemanticsUpdateBuilder {
SemanticsHitTestBehavior hitTestBehavior = SemanticsHitTestBehavior.defer,
required SemanticsInputType inputType,
required Locale? locale,
required String minValue,
required String maxValue,
}) {
if (transform.length != 16) {
throw ArgumentError('transform argument must have 16 entries.');
@ -802,8 +800,6 @@ class SemanticsUpdateBuilder {
hitTestBehavior: hitTestBehavior,
inputType: inputType,
locale: locale,
minValue: minValue,
maxValue: maxValue,
),
);
}

View File

@ -116,7 +116,6 @@ export 'engine/semantics/list.dart';
export 'engine/semantics/live_region.dart';
export 'engine/semantics/menus.dart';
export 'engine/semantics/platform_view.dart';
export 'engine/semantics/progress_bar.dart';
export 'engine/semantics/requirable.dart';
export 'engine/semantics/route.dart';
export 'engine/semantics/scrollable.dart';

View File

@ -20,7 +20,6 @@ export 'semantics/list.dart';
export 'semantics/live_region.dart';
export 'semantics/menus.dart';
export 'semantics/platform_view.dart';
export 'semantics/progress_bar.dart';
export 'semantics/requirable.dart';
export 'semantics/scrollable.dart';
export 'semantics/semantics.dart';

View File

@ -1,66 +0,0 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'label_and_value.dart';
import 'semantics.dart';
/// Indicates a progress bar element.
///
/// Uses aria progressbar role to convey this semantic information to the element.
///
/// Screen-readers take advantage of "aria-label" to describe the visual.
class SemanticsProgressBar extends SemanticRole {
SemanticsProgressBar(SemanticsObject semanticsObject)
: super.withBasics(
EngineSemanticsRole.progressBar,
semanticsObject,
preferredLabelRepresentation: LabelRepresentation.ariaLabel,
) {
setAriaRole('progressbar');
// Set ARIA attributes for min, max and current value.
if (semanticsObject.minValue != null) {
setAttribute('aria-valuemin', semanticsObject.minValue!);
}
if (semanticsObject.maxValue != null) {
setAttribute('aria-valuemax', semanticsObject.maxValue!);
}
if (semanticsObject.value != null) {
setAttribute('aria-valuenow', semanticsObject.value!);
}
}
@override
void update() {
super.update();
if (semanticsObject.minValue != null) {
setAttribute('aria-valuemin', semanticsObject.minValue!);
}
if (semanticsObject.maxValue != null) {
setAttribute('aria-valuemax', semanticsObject.maxValue!);
}
if (semanticsObject.value != null) {
setAttribute('aria-valuenow', semanticsObject.value!);
}
}
@override
bool focusAsRouteDefault() => focusable?.focusAsRouteDefault() ?? false;
}
/// Indicates a loading spinner element.
class SementicsLoadingSpinner extends SemanticRole {
SementicsLoadingSpinner(SemanticsObject semanticsObject)
: super.withBasics(
EngineSemanticsRole.loadingSpinner,
semanticsObject,
preferredLabelRepresentation: LabelRepresentation.ariaLabel,
);
@override
bool focusAsRouteDefault() => focusable?.focusAsRouteDefault() ?? false;
}

View File

@ -37,7 +37,6 @@ import 'list.dart';
import 'live_region.dart';
import 'menus.dart';
import 'platform_view.dart';
import 'progress_bar.dart';
import 'requirable.dart';
import 'route.dart';
import 'scrollable.dart';
@ -276,8 +275,6 @@ class SemanticsNodeUpdate {
this.hitTestBehavior = ui.SemanticsHitTestBehavior.defer,
required this.inputType,
required this.locale,
required this.minValue,
required this.maxValue,
});
/// See [ui.SemanticsUpdateBuilder.updateNode].
@ -402,12 +399,6 @@ class SemanticsNodeUpdate {
/// See [ui.SemanticsUpdateBuilder.updateNode].
final ui.Locale? locale;
/// See [ui.SemanticsUpdateBuilder.updateNode].
final String minValue;
/// See [ui.SemanticsUpdateBuilder.updateNode].
final String maxValue;
}
/// Identifies [SemanticRole] implementations.
@ -512,12 +503,6 @@ enum EngineSemanticsRole {
/// An item in a [list].
listItem,
/// A graphic object that shows progress with a numeric number.
progressBar,
/// A graphic object that spins to indicate the application is busy.
loadingSpinner,
/// A role used when a more specific role cannot be assigend to
/// a [SemanticsObject].
///
@ -1565,31 +1550,6 @@ class SemanticsObject {
_dirtyFields |= _hitTestBehaviorIndex;
}
String? get minValue => _minValue;
String? _minValue;
static const int _minValueIndex = 1 << 29;
/// Whether the [minValue] field has been updated but has not been
/// applied to the DOM yet.
bool get isMinValueDirty => _isDirty(_minValueIndex);
void _markMinValueDirty() {
_dirtyFields |= _minValueIndex;
}
/// See [ui.SemanticsUpdateBuilder.updateNode].
String? get maxValue => _maxValue;
String? _maxValue;
static const int _maxValueIndex = 1 << 30;
/// Whether the [maxValue] field has been updated but has not been
/// applied to the DOM yet.
bool get isMaxValueDirty => _isDirty(_maxValueIndex);
void _markMaxValueDirty() {
_dirtyFields |= _maxValueIndex;
}
/// A unique permanent identifier of the semantics node in the tree.
final int id;
@ -1927,16 +1887,6 @@ class SemanticsObject {
_markHitTestBehaviorDirty();
}
if (_minValue != update.minValue) {
_minValue = update.minValue;
_markMinValueDirty();
}
if (_maxValue != update.maxValue) {
_maxValue = update.maxValue;
_markMaxValueDirty();
}
role = update.role;
inputType = update.inputType;
@ -2189,16 +2139,14 @@ class SemanticsObject {
return EngineSemanticsRole.region;
case ui.SemanticsRole.form:
return EngineSemanticsRole.form;
case ui.SemanticsRole.loadingSpinner:
return EngineSemanticsRole.loadingSpinner;
case ui.SemanticsRole.progressBar:
return EngineSemanticsRole.progressBar;
// TODO(chunhtai): implement these roles.
// https://github.com/flutter/flutter/issues/159741.
case ui.SemanticsRole.dragHandle:
case ui.SemanticsRole.spinButton:
case ui.SemanticsRole.comboBox:
case ui.SemanticsRole.tooltip:
case ui.SemanticsRole.loadingSpinner:
case ui.SemanticsRole.progressBar:
case ui.SemanticsRole.hotKey:
case ui.SemanticsRole.none:
// fallback to checking semantics properties.
@ -2265,8 +2213,6 @@ class SemanticsObject {
EngineSemanticsRole.menuItemRadio => SemanticMenuItemRadio(this),
EngineSemanticsRole.alert => SemanticAlert(this),
EngineSemanticsRole.status => SemanticStatus(this),
EngineSemanticsRole.progressBar => SemanticsProgressBar(this),
EngineSemanticsRole.loadingSpinner => SementicsLoadingSpinner(this),
EngineSemanticsRole.generic => GenericRole(this),
EngineSemanticsRole.complementary => SemanticComplementary(this),
EngineSemanticsRole.contentInfo => SemanticContentInfo(this),

View File

@ -160,12 +160,6 @@ void runSemanticsTests() {
group('forms', () {
_testForms();
});
group('progressBar', () {
_testProgressBar();
});
group('loadingSpinner', () {
_testLoadingSpinner();
});
}
void _testSemanticRole() {
@ -6159,55 +6153,6 @@ void _testForms() {
semantics().semanticsEnabled = false;
}
void _testProgressBar() {
test('nodes with progress bar role', () {
semantics()
..debugOverrideTimestampFunction(() => _testTime)
..semanticsEnabled = true;
SemanticsObject pumpSemantics() {
final SemanticsTester tester = SemanticsTester(owner());
tester.updateNode(
id: 0,
role: ui.SemanticsRole.progressBar,
rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
);
tester.apply();
return tester.getSemanticsObject(0);
}
final SemanticsObject object = pumpSemantics();
expect(object.semanticRole?.kind, EngineSemanticsRole.progressBar);
expect(object.element.getAttribute('role'), 'progressbar');
});
semantics().semanticsEnabled = false;
}
void _testLoadingSpinner() {
test('nodes with loading spinner role', () {
semantics()
..debugOverrideTimestampFunction(() => _testTime)
..semanticsEnabled = true;
SemanticsObject pumpSemantics() {
final SemanticsTester tester = SemanticsTester(owner());
tester.updateNode(
id: 0,
role: ui.SemanticsRole.loadingSpinner,
rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
);
tester.apply();
return tester.getSemanticsObject(0);
}
final SemanticsObject object = pumpSemantics();
expect(object.semanticRole?.kind, EngineSemanticsRole.loadingSpinner);
});
semantics().semanticsEnabled = false;
}
/// A facade in front of [ui.SemanticsUpdateBuilder.updateNode] that
/// supplies default values for semantics attributes.
void updateNode(
@ -6252,8 +6197,6 @@ void updateNode(
ui.SemanticsHitTestBehavior hitTestBehavior = ui.SemanticsHitTestBehavior.defer,
ui.SemanticsInputType inputType = ui.SemanticsInputType.none,
ui.Locale? locale,
String minValue = '0',
String maxValue = '0',
}) {
transform ??= Float64List.fromList(Matrix4.identity().storage);
hitTestTransform ??= Float64List.fromList(Matrix4.identity().storage);
@ -6301,8 +6244,6 @@ void updateNode(
hitTestBehavior: hitTestBehavior,
inputType: inputType,
locale: locale,
minValue: minValue,
maxValue: maxValue,
);
}

View File

@ -92,8 +92,6 @@ class SemanticsTester {
ui.SemanticsHitTestBehavior hitTestBehavior = ui.SemanticsHitTestBehavior.defer,
ui.SemanticsInputType inputType = ui.SemanticsInputType.none,
ui.Locale? locale,
String? minValue,
String? maxValue,
}) {
// Actions
if (hasTap ?? false) {
@ -230,8 +228,6 @@ class SemanticsTester {
hitTestBehavior: hitTestBehavior,
inputType: inputType,
locale: locale,
minValue: minValue ?? '0',
maxValue: maxValue ?? '0',
);
_nodeUpdates.add(update);
return update;

View File

@ -316,8 +316,6 @@ void sendSemanticsUpdate() {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
_semanticsUpdate(builder.build());
}

View File

@ -200,8 +200,6 @@ Future<void> a11y_main() async {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
)
..updateNode(
id: 84,
@ -240,8 +238,6 @@ Future<void> a11y_main() async {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
)
..updateNode(
id: 96,
@ -280,8 +276,6 @@ Future<void> a11y_main() async {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
)
..updateNode(
id: 128,
@ -320,8 +314,6 @@ Future<void> a11y_main() async {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
)
..updateCustomAction(id: 21, label: 'Archive', hint: 'archive message');
@ -407,8 +399,6 @@ Future<void> a11y_string_attributes() async {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
PlatformDispatcher.instance.setSemanticsTreeEnabled(true);
@ -1700,8 +1690,6 @@ Future<void> a11y_main_multi_view() async {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
}

View File

@ -478,8 +478,6 @@ Future<void> sendSemanticsTreeInfo() async {
controlsNodes: null,
inputType: ui.SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
return builder.build();
}

View File

@ -77,8 +77,6 @@ class LocaleInitialization extends Scenario {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final SemanticsUpdate semanticsUpdate = semanticsUpdateBuilder.build();
@ -141,8 +139,6 @@ class LocaleInitialization extends Scenario {
controlsNodes: null,
inputType: SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final SemanticsUpdate semanticsUpdate = semanticsUpdateBuilder.build();

View File

@ -8,7 +8,6 @@
library;
import 'dart:math' as math;
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
@ -142,20 +141,11 @@ abstract class ProgressIndicator extends StatefulWidget {
}
Widget _buildSemanticsWrapper({required BuildContext context, required Widget child}) {
bool isProgressBar = false;
String? expandedSemanticsValue = semanticsValue;
if (value != null) {
expandedSemanticsValue ??= '${(value! * 100).round()}';
isProgressBar = true;
expandedSemanticsValue ??= '${(value! * 100).round()}%';
}
return Semantics(
label: semanticsLabel,
role: isProgressBar ? SemanticsRole.progressBar : SemanticsRole.loadingSpinner,
minValue: isProgressBar ? '0' : null,
maxValue: isProgressBar ? '100' : null,
value: expandedSemanticsValue,
child: child,
);
return Semantics(label: semanticsLabel, value: expandedSemanticsValue, child: child);
}
}
@ -1195,32 +1185,28 @@ class _CircularProgressIndicatorState extends State<CircularProgressIndicator>
@override
Widget build(BuildContext context) {
return Builder(
builder: (BuildContext context) {
switch (widget._indicatorType) {
case _ActivityIndicatorType.material:
switch (widget._indicatorType) {
case _ActivityIndicatorType.material:
if (widget.value != null) {
return _buildMaterialIndicator(context, 0.0, 0.0, 0, 0.0);
}
return _buildAnimation();
case _ActivityIndicatorType.adaptive:
final ThemeData theme = Theme.of(context);
switch (theme.platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return _buildCupertinoIndicator(context);
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
if (widget.value != null) {
return _buildMaterialIndicator(context, 0.0, 0.0, 0, 0.0);
}
return _buildAnimation();
case _ActivityIndicatorType.adaptive:
final ThemeData theme = Theme.of(context);
switch (theme.platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return _buildCupertinoIndicator(context);
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
if (widget.value != null) {
return _buildMaterialIndicator(context, 0.0, 0.0, 0, 0.0);
}
return _buildAnimation();
}
}
},
);
}
}
}

View File

@ -1051,12 +1051,6 @@ class RenderCustomPaint extends RenderProxyBox {
if (properties.inputType != null) {
config.inputType = properties.inputType!;
}
if (properties.minValue != null) {
config.minValue = properties.minValue;
}
if (properties.maxValue != null) {
config.maxValue = properties.maxValue;
}
if (properties.onTap != null) {
config.onTap = properties.onTap;
}

View File

@ -4938,12 +4938,6 @@ mixin SemanticsAnnotationsMixin on RenderObject {
if (_properties.inputType != null) {
config.inputType = _properties.inputType!;
}
if (_properties.minValue != null) {
config.minValue = _properties.minValue;
}
if (_properties.maxValue != null) {
config.maxValue = _properties.maxValue;
}
// Registering _perform* as action handlers instead of the user provided
// ones to ensure that changing a user provided handler from a non-null to

View File

@ -182,14 +182,14 @@ sealed class _DebugSemanticsRoleChecks {
SemanticsRole.navigation => _semanticsNavigation,
SemanticsRole.region => _semanticsRegion,
SemanticsRole.form => _noCheckRequired,
SemanticsRole.loadingSpinner => _noCheckRequired,
SemanticsRole.progressBar => _semanticsProgressBar,
// TODO(chunhtai): add checks when the roles are used in framework.
// https://github.com/flutter/flutter/issues/159741.
SemanticsRole.dragHandle => _unimplemented,
SemanticsRole.spinButton => _unimplemented,
SemanticsRole.comboBox => _unimplemented,
SemanticsRole.tooltip => _unimplemented,
SemanticsRole.loadingSpinner => _unimplemented,
SemanticsRole.progressBar => _unimplemented,
SemanticsRole.hotKey => _unimplemented,
}(node);
@ -205,48 +205,6 @@ sealed class _DebugSemanticsRoleChecks {
static FlutterError? _noCheckRequired(SemanticsNode node) => null;
static FlutterError? _semanticsProgressBar(SemanticsNode node) {
final SemanticsData data = node.getSemanticsData();
// Check if value is present
if (data.value.isEmpty) {
return FlutterError('A progress bar must have a value');
}
// Check if minValue and maxValue are present
if (data.minValue == null) {
return FlutterError('A progress bar must have a minValue');
}
if (data.maxValue == null) {
return FlutterError('A progress bar must have a maxValue');
}
// Validate that value is within min and max range
try {
final double currentValue = double.parse(data.value);
final double minVal = double.parse(data.minValue!);
final double maxVal = double.parse(data.maxValue!);
if (currentValue < minVal || currentValue > maxVal) {
return FlutterError(
'Progress bar value ($currentValue) must be between minValue ($minVal) and maxValue ($maxVal)',
);
}
if (minVal >= maxVal) {
return FlutterError('Progress bar minValue ($minVal) must be less than maxValue ($maxVal)');
}
} catch (e) {
return FlutterError(
'Progress bar value, minValue, and maxValue must be valid numbers. '
'value: "${data.value}", minValue: "${data.minValue}", maxValue: "${data.maxValue}"',
);
}
return null;
}
static FlutterError? _semanticsTab(SemanticsNode node) {
final SemanticsData data = node.getSemanticsData();
if (data.flagsCollection.isSelected == Tristate.none) {
@ -1064,8 +1022,6 @@ class SemanticsData with Diagnosticable {
required this.validationResult,
required this.inputType,
required this.locale,
required this.minValue,
required this.maxValue,
this.tags,
this.transform,
this.customSemanticsActionIds,
@ -1341,12 +1297,6 @@ class SemanticsData with Diagnosticable {
/// content of this semantics node.
final Locale? locale;
/// {@macro flutter.semantics.SemanticsProperties.maxValue}
final String? maxValue;
/// {@macro flutter.semantics.SemanticsProperties.minValue}
final String? minValue;
/// Whether [flags] contains the given flag.
@Deprecated(
'Use flagsCollection instead. '
@ -1431,8 +1381,6 @@ class SemanticsData with Diagnosticable {
),
);
}
properties.add(StringProperty('minValue', minValue, defaultValue: null));
properties.add(StringProperty('maxValue', maxValue, defaultValue: null));
}
@override
@ -1468,9 +1416,7 @@ class SemanticsData with Diagnosticable {
other.validationResult == validationResult &&
other.inputType == inputType &&
_sortedListsEqual(other.customSemanticsActionIds, customSemanticsActionIds) &&
setEquals<String>(controlsNodes, other.controlsNodes) &&
minValue == other.minValue &&
maxValue == other.maxValue;
setEquals<String>(controlsNodes, other.controlsNodes);
}
@override
@ -1507,8 +1453,6 @@ class SemanticsData with Diagnosticable {
inputType,
traversalParentIdentifier,
traversalChildIdentifier,
minValue,
maxValue,
),
);
@ -1691,8 +1635,6 @@ class SemanticsProperties extends DiagnosticableTree {
this.onExpand,
this.onCollapse,
this.customSemanticsActions,
this.minValue,
this.maxValue,
}) : assert(
label == null || attributedLabel == null,
'Only one of label or attributedLabel should be provided',
@ -2624,28 +2566,6 @@ class SemanticsProperties extends DiagnosticableTree {
/// {@endtemplate}
final SemanticsInputType? inputType;
/// {@template flutter.semantics.SemanticsProperties.maxValue}
/// The maximum value of the node.
///
/// Used in conjunction with [value] to define the current value and range
/// of a node. A typical usage is for progress indicators, where [value]
/// represents the current progress and [maxValue] defines the maximum
/// possible value.
///
/// {@endtemplate}
final String? maxValue;
/// {@template flutter.semantics.SemanticsProperties.minValue}
/// The minimum value of the node.
///
/// Used in conjunction with [value] to define the current value and range
/// of a node. A typical usage is for progress indicators, where [value]
/// represents the current progress and [minValue] defines the minimum
/// possible value.
///
/// {@endtemplate}
final String? minValue;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
@ -3307,9 +3227,7 @@ class SemanticsNode with DiagnosticableTreeMixin {
_headingLevel != config._headingLevel ||
_linkUrl != config._linkUrl ||
_role != config.role ||
_validationResult != config.validationResult ||
_minValue != config._minValue ||
_maxValue != config._maxValue;
_validationResult != config.validationResult;
}
// TAGS, LABELS, ACTIONS
@ -3599,14 +3517,6 @@ class SemanticsNode with DiagnosticableTreeMixin {
Set<String>? get controlsNodes => _controlsNodes;
Set<String>? _controlsNodes = _kEmptyConfig.controlsNodes;
/// {@macro flutter.semantics.SemanticsProperties.minValue}
String? get minValue => _minValue;
String? _minValue;
/// {@macro flutter.semantics.SemanticsProperties.maxValue}
String? get maxValue => _maxValue;
String? _maxValue;
/// {@macro flutter.semantics.SemanticsProperties.validationResult}
SemanticsValidationResult get validationResult => _validationResult;
SemanticsValidationResult _validationResult = _kEmptyConfig.validationResult;
@ -3694,8 +3604,6 @@ class SemanticsNode with DiagnosticableTreeMixin {
_inputType = config._inputType;
_locale = config.locale;
_minValue = config.minValue;
_maxValue = config.maxValue;
_replaceChildren(childrenInInversePaintOrder ?? const <SemanticsNode>[]);
if (mergeAllDescendantsIntoThisNodeValueChanged) {
@ -3749,8 +3657,6 @@ class SemanticsNode with DiagnosticableTreeMixin {
SemanticsValidationResult validationResult = _validationResult;
SemanticsInputType inputType = _inputType;
final Locale? locale = _locale;
String? minValue = _minValue;
String? maxValue = _maxValue;
final Set<int> customSemanticsActionIds = <int>{};
for (final CustomSemanticsAction action in _customSemanticsActions.keys) {
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
@ -3858,9 +3764,6 @@ class SemanticsNode with DiagnosticableTreeMixin {
controlsNodes = <String>{...controlsNodes!, ...node._controlsNodes!};
}
minValue ??= node._minValue;
maxValue ??= node._maxValue;
if (validationResult == SemanticsValidationResult.none) {
validationResult = node._validationResult;
} else if (validationResult == SemanticsValidationResult.valid) {
@ -3909,8 +3812,6 @@ class SemanticsNode with DiagnosticableTreeMixin {
validationResult: validationResult,
inputType: inputType,
locale: locale,
minValue: minValue,
maxValue: maxValue,
);
}
@ -4102,8 +4003,6 @@ class SemanticsNode with DiagnosticableTreeMixin {
validationResult: data.validationResult,
inputType: data.inputType,
locale: data.locale,
minValue: data.minValue ?? '0',
maxValue: data.maxValue ?? '0',
);
_dirty = false;
}
@ -4397,8 +4296,6 @@ class SemanticsNode with DiagnosticableTreeMixin {
),
);
}
properties.add(StringProperty('minValue', _minValue, defaultValue: null));
properties.add(StringProperty('maxValue', _maxValue, defaultValue: null));
}
/// Returns a string representation of this node and its descendants.
@ -6537,22 +6434,6 @@ class SemanticsConfiguration {
_hasBeenAnnotated = true;
}
/// {@macro flutter.semantics.SemanticsProperties.maxValue}
String? get maxValue => _maxValue;
String? _maxValue;
set maxValue(String? value) {
_maxValue = value;
_hasBeenAnnotated = true;
}
/// {@macro flutter.semantics.SemanticsProperties.minValue}
String? get minValue => _minValue;
String? _minValue;
set minValue(String? value) {
_minValue = value;
_hasBeenAnnotated = true;
}
// TAGS
/// The set of tags that this configuration wants to add to all child
@ -6653,12 +6534,6 @@ class SemanticsConfiguration {
if (_hasExplicitRole && other._hasExplicitRole) {
return false;
}
if (_minValue != null && other._minValue != null) {
return false;
}
if (_maxValue != null && other._maxValue != null) {
return false;
}
return true;
}
@ -6768,8 +6643,6 @@ class SemanticsConfiguration {
_accessiblityFocusBlockType = _accessiblityFocusBlockType._merge(
child._accessiblityFocusBlockType,
);
_minValue ??= child._minValue;
_maxValue ??= child._maxValue;
_hasBeenAnnotated = hasBeenAnnotated || child.hasBeenAnnotated;
}
@ -6816,9 +6689,7 @@ class SemanticsConfiguration {
.._role = _role
.._controlsNodes = _controlsNodes
.._validationResult = _validationResult
.._inputType = _inputType
.._minValue = _minValue
.._maxValue = _maxValue;
.._inputType = _inputType;
}
}

View File

@ -4050,8 +4050,6 @@ sealed class _SemanticsBase extends SingleChildRenderObjectWidget {
required SemanticsValidationResult validationResult,
required ui.SemanticsInputType? inputType,
required Locale? localeForSubtree,
required String? minValue,
required String? maxValue,
}) : this.fromProperties(
key: key,
child: child,
@ -4136,8 +4134,6 @@ sealed class _SemanticsBase extends SingleChildRenderObjectWidget {
controlsNodes: controlsNodes,
validationResult: validationResult,
inputType: inputType,
minValue: minValue,
maxValue: maxValue,
),
);
@ -4388,8 +4384,6 @@ class SliverSemantics extends _SemanticsBase {
super.validationResult = SemanticsValidationResult.none,
super.inputType,
super.localeForSubtree,
super.minValue,
super.maxValue,
}) : super(child: sliver);
/// {@macro flutter.widgets.SemanticsBase.fromProperties}
@ -7972,8 +7966,6 @@ class Semantics extends _SemanticsBase {
super.validationResult = SemanticsValidationResult.none,
super.inputType,
super.localeForSubtree,
super.minValue,
super.maxValue,
});
/// {@macro flutter.widgets.SemanticsBase.fromProperties}

View File

@ -378,12 +378,7 @@ void main() {
expect(
tester.getSemantics(find.byType(CircularProgressIndicator)),
matchesSemantics(
value: '0',
textDirection: TextDirection.ltr,
minValue: '0',
maxValue: '100',
),
matchesSemantics(value: '0%', textDirection: TextDirection.ltr),
);
handle.dispose();
},
@ -945,7 +940,7 @@ void main() {
final SemanticsHandle handle = tester.ensureSemantics();
final GlobalKey key = GlobalKey();
const String label = 'Label';
const String value = '25';
const String value = '25%';
await tester.pumpWidget(
Theme(
data: theme,
@ -987,7 +982,7 @@ void main() {
expect(
tester.getSemantics(find.byKey(key)),
matchesSemantics(textDirection: TextDirection.ltr, label: label, value: '25'),
matchesSemantics(textDirection: TextDirection.ltr, label: label, value: '25%'),
);
handle.dispose();
@ -1042,7 +1037,7 @@ void main() {
final SemanticsHandle handle = tester.ensureSemantics();
final GlobalKey key = GlobalKey();
const String label = 'Label';
const String value = '25';
const String value = '25%';
await tester.pumpWidget(
Theme(
data: theme,
@ -1070,7 +1065,7 @@ void main() {
final SemanticsHandle handle = tester.ensureSemantics();
final GlobalKey key = GlobalKey();
const String label = 'Label';
const String value = '25';
const String value = '25%';
await tester.pumpWidget(
Theme(
data: theme,

View File

@ -723,9 +723,7 @@ void main() {
' scrollPosition: null\n'
' scrollExtentMax: null\n'
' indexInParent: null\n'
' headingLevel: 0\n'
' minValue: null\n'
' maxValue: null\n',
' headingLevel: 0\n',
);
final SemanticsConfiguration config = SemanticsConfiguration()
@ -873,9 +871,7 @@ void main() {
' scrollPosition: null\n'
' scrollExtentMax: null\n'
' indexInParent: null\n'
' headingLevel: 0\n'
' minValue: null\n'
' maxValue: null\n',
' headingLevel: 0\n',
);
});

View File

@ -234,8 +234,6 @@ class SemanticsUpdateBuilderSpy extends Fake implements ui.SemanticsUpdateBuilde
ui.SemanticsHitTestBehavior hitTestBehavior = ui.SemanticsHitTestBehavior.defer,
required ui.SemanticsInputType inputType,
required ui.Locale? locale,
required String minValue,
required String maxValue,
}) {
// Makes sure we don't send the same id twice.
assert(!observations.containsKey(id));

View File

@ -713,8 +713,6 @@ class SemanticsTester {
double? scrollExtentMin,
int? currentValueLength,
int? maxValueLength,
String? maxValue,
String? minValue,
SemanticsNode? ancestor,
SemanticsInputType? inputType,
}) {
@ -812,12 +810,6 @@ class SemanticsTester {
if (inputType != null && node.inputType != inputType) {
return false;
}
if (maxValue != null && node.maxValue != maxValue) {
return false;
}
if (minValue != null && node.minValue != minValue) {
return false;
}
return true;
}
@ -1128,8 +1120,6 @@ class _IncludesNodeWith extends Matcher {
this.maxValueLength,
this.currentValueLength,
this.inputType,
this.minValue,
this.maxValue,
}) : assert(
label != null ||
value != null ||
@ -1145,7 +1135,6 @@ class _IncludesNodeWith extends Matcher {
maxValueLength != null ||
currentValueLength != null ||
inputType != null,
minValue != null || maxValue != null,
);
final AttributedString? attributedLabel;
final AttributedString? attributedValue;
@ -1166,8 +1155,6 @@ class _IncludesNodeWith extends Matcher {
final int? currentValueLength;
final int? maxValueLength;
final SemanticsInputType? inputType;
final String? minValue;
final String? maxValue;
@override
bool matches(covariant SemanticsTester item, Map<dynamic, dynamic> matchState) {
@ -1192,8 +1179,6 @@ class _IncludesNodeWith extends Matcher {
currentValueLength: currentValueLength,
maxValueLength: maxValueLength,
inputType: inputType,
minValue: minValue,
maxValue: maxValue,
)
.isNotEmpty;
}
@ -1230,8 +1215,6 @@ class _IncludesNodeWith extends Matcher {
if (currentValueLength != null) 'currentValueLength "$currentValueLength"',
if (maxValueLength != null) 'maxValueLength "$maxValueLength"',
if (inputType != null) 'inputType $inputType',
if (minValue != null) 'minValue "$minValue"',
if (maxValue != null) 'maxValue "$maxValue"',
];
return strings.join(', ');
}
@ -1261,8 +1244,6 @@ Matcher includesNodeWith({
int? maxValueLength,
int? currentValueLength,
SemanticsInputType? inputType,
String? minValue,
String? maxValue,
}) {
return _IncludesNodeWith(
label: label,
@ -1284,7 +1265,5 @@ Matcher includesNodeWith({
maxValueLength: maxValueLength,
currentValueLength: currentValueLength,
inputType: inputType,
minValue: minValue,
maxValue: maxValue,
);
}

View File

@ -687,8 +687,6 @@ Matcher matchesSemantics({
int? currentValueLength,
SemanticsValidationResult validationResult = SemanticsValidationResult.none,
ui.SemanticsInputType? inputType,
String? maxValue,
String? minValue,
// Flags //
bool hasCheckedState = false,
bool isChecked = false,
@ -774,8 +772,6 @@ Matcher matchesSemantics({
currentValueLength: currentValueLength,
validationResult: validationResult,
inputType: inputType,
minValue: minValue,
maxValue: maxValue,
// Flags
hasCheckedState: hasCheckedState,
isChecked: isChecked,
@ -891,8 +887,6 @@ Matcher containsSemantics({
int? currentValueLength,
SemanticsValidationResult? validationResult,
ui.SemanticsInputType? inputType,
String? maxValue,
String? minValue,
// Flags
bool? hasCheckedState,
bool? isChecked,
@ -978,8 +972,6 @@ Matcher containsSemantics({
currentValueLength: currentValueLength,
validationResult: validationResult,
inputType: inputType,
minValue: minValue,
maxValue: maxValue,
// Flags
hasCheckedState: hasCheckedState,
isChecked: isChecked,
@ -2412,8 +2404,6 @@ class _MatchesSemanticsData extends Matcher {
required this.currentValueLength,
required this.validationResult,
required this.inputType,
required this.minValue,
required this.maxValue,
// Flags
required bool? hasCheckedState,
required bool? isChecked,
@ -2561,8 +2551,6 @@ class _MatchesSemanticsData extends Matcher {
final ui.SemanticsInputType? inputType;
final List<Matcher>? children;
final SemanticsValidationResult? validationResult;
final String? maxValue;
final String? minValue;
/// There are three possible states for these two maps:
///
@ -2672,12 +2660,6 @@ class _MatchesSemanticsData extends Matcher {
if (validationResult != null) {
description.add(' with validation result: $validationResult');
}
if (minValue != null) {
description.add(' with minValue: $minValue');
}
if (maxValue != null) {
description.add(' with maxValue: $maxValue');
}
if (children != null) {
description.add(' with children:\n ');
final List<_MatchesSemanticsData> childMatches = children!.cast<_MatchesSemanticsData>();
@ -2814,12 +2796,6 @@ class _MatchesSemanticsData extends Matcher {
if (inputType != null && inputType != data.inputType) {
return failWithDescription(matchState, 'inputType was: ${data.inputType}');
}
if (minValue != null && minValue != data.minValue) {
return failWithDescription(matchState, 'minValue was: ${data.minValue}');
}
if (maxValue != null && maxValue != data.maxValue) {
return failWithDescription(matchState, 'maxValue was: ${data.maxValue}');
}
if (actions.isNotEmpty) {
final List<SemanticsAction> unexpectedActions = <SemanticsAction>[];
final List<SemanticsAction> missingActions = <SemanticsAction>[];

View File

@ -755,8 +755,6 @@ void main() {
validationResult: SemanticsValidationResult.none,
inputType: ui.SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final _FakeSemanticsNode node = _FakeSemanticsNode(data);
@ -1059,8 +1057,6 @@ void main() {
validationResult: SemanticsValidationResult.none,
inputType: ui.SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final _FakeSemanticsNode node = _FakeSemanticsNode(data);
@ -1163,8 +1159,6 @@ void main() {
validationResult: SemanticsValidationResult.none,
inputType: ui.SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final _FakeSemanticsNode node = _FakeSemanticsNode(data);
@ -1272,8 +1266,6 @@ void main() {
validationResult: SemanticsValidationResult.none,
inputType: ui.SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final _FakeSemanticsNode emptyNode = _FakeSemanticsNode(emptyData);
@ -1309,8 +1301,6 @@ void main() {
validationResult: SemanticsValidationResult.none,
inputType: ui.SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final _FakeSemanticsNode fullNode = _FakeSemanticsNode(fullData);
@ -1445,8 +1435,6 @@ void main() {
validationResult: SemanticsValidationResult.none,
inputType: ui.SemanticsInputType.none,
locale: null,
minValue: '0',
maxValue: '0',
);
final _FakeSemanticsNode node = _FakeSemanticsNode(data);