Skip to content

[web] semantic node initially missing a label cannot be updated to have one #130546

@yjbanov

Description

@yjbanov

Is there an existing issue for this?

Steps to reproduce

  1. flutter run -d chrome the provided sample repro
  2. Click "Enable accessibility"
  3. Click "Toggle card contents"
  4. Inspect the DOM using Chrome DevTools, and find the <flt-semantics> element with id="flt-semantic-node-5" (it should have role="button" set on it.

Expected results

The element should contain attribute aria-label="Click on me to debugDumpSemanticsTree()".

Actual results

The element does not have an aria-label attribute at all.

The issue is in the assignment of secondary role managers in the web engine. Role managers are assigned upon initialization of the node, and never changed after that. To confirm, swap steps 2 and 3 in the repro steps (first toggle card contents, then enable accessibility), and you will see that arial-label is created. To fix this, class PrimaryRoleManager in its update() method should check if a new role manager should be added. For example, if a node did not previously have a label and does now, it should add LabelAndValue. Similarly, if a node was not tappable before and is now, it should add the Tappable role.

Google internal bug: 290978697

Code sample

Code sample
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var hidden = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title, style: const TextStyle(fontFamily: 'ProductSans')),
      ),
      body: Container(
        alignment: Alignment.center,
        padding: const EdgeInsets.symmetric(horizontal: 100),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const Text(
              'If a11y is enabled before toggling the card contents, '
              'the aria-label for the card will be missing. If it is not '
              'enabled until after toggling the contents visible, then the '
              'aria-label will be correct.',
            ),
            Card(
              child: Semantics(
                button: true,
                child: InkWell(
                  onTap: debugDumpSemanticsTree,
                  child: Padding(
                    padding: const EdgeInsets.all(20),
                    child: hidden
                        ? const CircularProgressIndicator()
                        : const Text('Click on me to debugDumpSemanticsTree()'),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 24),
            FilledButton(
              onPressed: () => setState(() {
                hidden = !hidden;
              }),
              child: const Text('Toggle card contents'),
            ),
            const SizedBox(height: 24),
            FilledButton(
              onPressed: () => SemanticsBinding.instance.ensureSemantics(),
              child: const Text('Enable accessibility'),
            ),
          ],
        ),
      ),
    );
  }
}

Screenshots or Video

No response

Logs

No response

Flutter Doctor output

Doctor output
[!] Flutter (Channel main, 3.13.0-3.0.pre.19, on macOS 13.4.1 22F82 darwin-arm64, locale en)
    ! Upstream repository git@github.com:yjbanov/flutter.git is not a standard remote.
      Set environment variable "FLUTTER_GIT_URL" to git@github.com:yjbanov/flutter.git to dismiss this error.
[!] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] VS Code (version 1.79.2)

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work lista: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)engineflutter/engine related. See also e: labels.platform-webWeb applications specificallyteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions