normaliseClickText function

String normaliseClickText(
  1. String input
)

Android's normaliseForMatch (NFD → strip combining marks → ASCII lowercase → every non-[a-z0-9] run to one space → trim), which the click names are defined against.

Deliberately NOT the tree's text_normalizer.dart: that one is pinned to the backend planner's match transform (it keeps punctuation and spells %), and must never change for naming.

Dart has no Unicode normaliser, so the NFD step is a fold table for the Latin-1 Supplement and Latin Extended-A letters that decompose to an ASCII base (é → e, ş → s). Letters with no ASCII decomposition (ß, æ, ø, ł) and every non-Latin script collapse to a space — exactly as they do on Android.

Implementation

String normaliseClickText(String input) {
  final out = StringBuffer();
  var pendingSpace = false;
  for (final rune in input.runes) {
    // Combining diacritical marks — what NFD leaves after the base letter.
    if (rune >= 0x0300 && rune <= 0x036F) continue;
    var c = rune;
    if (c >= 0xC0 && c <= 0x17F) {
      final folded = _kLatinFold[c - 0xC0];
      c = folded == 0x20 ? -1 : folded;
    }
    if (c >= 0x41 && c <= 0x5A) c += 0x20;
    final alnum = (c >= 0x61 && c <= 0x7A) || (c >= 0x30 && c <= 0x39);
    if (!alnum) {
      pendingSpace = out.isNotEmpty;
      continue;
    }
    if (pendingSpace) {
      out.writeCharCode(0x20);
      pendingSpace = false;
    }
    out.writeCharCode(c);
  }
  return out.toString();
}