///|
fn semantics_delta_between(
previous : SemanticsSnapshot,
current : SemanticsSnapshot,
) -> SemanticsDelta {
let previous_nodes : Map[SemanticsNodeId, SemanticsNode] = Map([])
let current_ids : Map[SemanticsNodeId, Bool] = Map([])
for node in previous.nodes {
previous_nodes[node.node_id] = node
}
let upserted : Array[SemanticsNode] = []
for node in current.nodes {
current_ids[node.node_id] = true
if previous_nodes.get(node.node_id) != Some(node) {
upserted.push(node)
}
}
let removed : Array[SemanticsNodeId] = []
for node in previous.nodes {
if !current_ids.contains(node.node_id) {
removed.push(node.node_id)
}
}
let announcements : Array[AccessibilityAnnouncement] = []
for node in current.nodes {
if node.live != Off {
let text = join_semantics_text(
join_semantics_text(node.label, node.value),
node.description,
)
let changed = match previous_nodes.get(node.node_id) {
Some(before) =>
text !=
join_semantics_text(
join_semantics_text(before.label, before.value),
before.description,
)
None => true
}
if text != "" && changed {
announcements.push({
node_id: node.node_id,
generation: current.generation,
live: node.live,
is_atomic: node.live_atomic,
text,
})
}
}
}
{
from: previous.generation,
to: current.generation,
root: current.root,
focused: current.focused,
semantic_focused: current.semantic_focused,
upserted,
removed,
issues: current.issues.map(clone_semantics_issue),
announcements,
}
}