85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package atspi
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// Derive rows from the already captured document. This performs no native
|
|
// queries and keeps large tables bounded to 32 cells and 4096 bytes per row.
|
|
func populate_document_rows(document *DocumentSnapshot) {
|
|
nodes := make(map[ObjectID]int, len(document.Nodes))
|
|
for index, node := range document.Nodes {
|
|
nodes[node.Reference.ID()] = index
|
|
}
|
|
type rowKey struct {
|
|
table ObjectID
|
|
row int
|
|
}
|
|
rows := make(map[rowKey][]int)
|
|
owners := make(map[int]rowKey)
|
|
for index, node := range document.Nodes {
|
|
if node.Hidden || !node.Snapshot.TablePositionKnown || node.Snapshot.Role != "table cell" {
|
|
continue
|
|
}
|
|
current := node.Parent
|
|
var owner ObjectID
|
|
spreadsheet := false
|
|
for depth := 0; depth < 32 && current.Valid(); depth++ {
|
|
parentIndex, exists := nodes[current]
|
|
if !exists {
|
|
break
|
|
}
|
|
parent := document.Nodes[parentIndex]
|
|
if owner == (ObjectID{}) && parent.Snapshot.Role == "table" {
|
|
owner = current
|
|
}
|
|
if parent.Snapshot.Role == "document spreadsheet" {
|
|
spreadsheet = true
|
|
}
|
|
current = parent.Parent
|
|
}
|
|
if !owner.Valid() {
|
|
continue
|
|
}
|
|
document.Nodes[index].Snapshot.Spreadsheet = spreadsheet
|
|
document.Nodes[index].Snapshot.TablePath = owner.Path
|
|
key := rowKey{owner, node.Snapshot.TableRowIndex}
|
|
if len(rows[key]) < 32 {
|
|
rows[key] = append(rows[key], index)
|
|
}
|
|
owners[index] = key
|
|
}
|
|
texts := make(map[rowKey]string, len(rows))
|
|
for key, indices := range rows {
|
|
sort.SliceStable(indices, func(a, b int) bool {
|
|
return document.Nodes[indices[a]].Snapshot.TableColumnIndex < document.Nodes[indices[b]].Snapshot.TableColumnIndex
|
|
})
|
|
var parts []string
|
|
length := 0
|
|
for _, index := range indices {
|
|
snapshot := document.Nodes[index].Snapshot
|
|
label := strings.TrimSpace(snapshot.Name)
|
|
if label == "" {
|
|
label = strings.TrimSpace(snapshot.Text)
|
|
}
|
|
if label == "" {
|
|
label = "blank"
|
|
}
|
|
if length+len(label)+2 > 4096 {
|
|
break
|
|
}
|
|
length += len(label) + 2
|
|
parts = append(parts, label)
|
|
}
|
|
texts[key] = strings.Join(parts, ", ")
|
|
}
|
|
for index, key := range owners {
|
|
document.Nodes[index].Snapshot.TableRowText = texts[key]
|
|
}
|
|
}
|