register static method
String
register({
- required Rect rect,
- required Element element,
- required String groupId,
- required bool isTextField,
- SemanticsNode? node,
- RenderObject? renderObject,
Mints (or returns the cached) token for the supplied tree references.
When node is supplied AND a token has already been issued for the
same node.id, the same token is returned and its underlying entry
is refreshed in place (so action tools always see the latest
element / rect for that node, AND the entry's current groupId
becomes the supplied groupId — the latest snapshot owns the
disposal lifecycle).
When node is null (e.g. the find_by_text walk does not have a
SemanticsNode handle), a fresh token is always minted.
Tokens look like e1, e2, … to mirror Playwright MCP's
[ref=e<N>] shape.
Implementation
static String register({
required Rect rect,
required Element element,
required String groupId,
required bool isTextField,
SemanticsNode? node,
RenderObject? renderObject,
}) {
// 1. Cache hit — only when a SemanticsNode is supplied. Find an
// existing token for node.id and refresh its payload so downstream
// action tools see the latest element/rect/renderObject. The
// entry's groupId is updated to the LATEST caller's groupId so
// older snapshots' disposeGroup calls never strand a still-live
// token.
if (node != null) {
final String? existing = _byNodeId[node.id];
if (existing != null) {
_entries[existing] = RefEntry(
rect: rect,
element: element,
groupId: groupId,
isTextField: isTextField,
node: node,
renderObject: renderObject,
);
return existing;
}
// 2. Mint a new token, store the entry, and remember the node.id
// mapping for future cache hits.
_counter += 1;
final String token = 'e$_counter';
_entries[token] = RefEntry(
rect: rect,
element: element,
groupId: groupId,
isTextField: isTextField,
node: node,
renderObject: renderObject,
);
_byNodeId[node.id] = token;
return token;
}
// 3. No SemanticsNode → mint fresh every call. The entry still
// carries the supplied groupId so disposeGroup cleans it up.
_counter += 1;
final String token = 'e$_counter';
_entries[token] = RefEntry(
rect: rect,
element: element,
groupId: groupId,
isTextField: isTextField,
node: null,
renderObject: renderObject,
);
return token;
}