Group inline links and list items into browse lines

This commit is contained in:
ak47 committed 2026-11-07 20:31:50 -05:00
1 parent 3dbd7f2554
commit d01965c00d
16 files changed
+309 -15

No files matched your search

+3
View File
@@ -284,6 +284,9 @@ func presentDocumentCaretResult(logger *slog.Logger, speech speechEnqueuer, resu
ancestor.Name = ""
line.Contents = append(line.Contents, atspi.DocumentContent{Snapshot: ancestor})
}
if result.DocumentCaretLine != nil && result.DocumentCaretCommand != review.CaretNextWord && result.DocumentCaretCommand != review.CaretPreviousWord {
line = presentation.DocumentVisualLineForSpeech(*result.DocumentCaretLine)
}
spoken := presentation.DocumentLineSpeechWithOptions(line, options)
request.Text, request.Chunks = spoken.Text, spoken.Chunks
request.Sound = presentation.DocumentLineSoundCues(line, options)
+28
View File
@@ -26,6 +26,7 @@ import (
"git.stormux.org/storm/cthulhu/internal/review"
"git.stormux.org/storm/cthulhu/internal/sound"
"log/slog"
"strings"
"testing"
"time"
)
@@ -420,3 +421,30 @@ func TestCaretPresentationUsesAncestorRoleSound(t *testing.T) {
t.Fatal("missing link sound")
}
}
func TestCaretVisualLinePresentsEveryLink(t *testing.T) {
plain := atspi.Snapshot{BusName: ":1.20", Path: "/plain", Role: "static"}
link := atspi.Snapshot{BusName: ":1.20", Path: "/link", Role: "link", Visited: true}
line := atspi.DocumentLine{Contents: []atspi.DocumentContent{
{Snapshot: plain, Text: "Before "}, {Snapshot: link, Text: "Example"}, {Snapshot: plain, Text: " after."},
}, SourceContexts: [][]atspi.Snapshot{{plain}, {link}, {plain}}}
result := review.Result{Moved: true, DocumentCaretCommand: review.CaretNextLine,
DocumentCaretText: "Before Example after.", DocumentCaretLine: &line,
DocumentPosition: review.DocumentPosition{Snapshot: plain},
}
queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 1)}
presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, result, presentation.DefaultOptions())
if got := (<-queue.requests).Text; got != "Before, Example, visited link, after." {
t.Fatalf("line speech = %q", got)
}
result.ReadAllContext, result.ReadAllLines = t.Context(), []atspi.DocumentLine{line}
presentReadAllResult(slog.New(slog.DiscardHandler), queue, result, presentation.DefaultOptions())
request := <-queue.requests
var text []string
for _, part := range request.ReadAll {
text = append(text, part.Text)
}
if got := strings.Join(text, " "); got != "Before Example visited link after." {
t.Fatalf("Say All = %q", got)
}
}
+3
View File
@@ -39,6 +39,9 @@ func presentReadAllResult(logger *slog.Logger, speech speechEnqueuer, result rev
options.Reading = &reading
options.ReadFullRowInGUITable = false
for index, line := range result.ReadAllLines {
if len(line.Contents) > 1 && len(line.SourceContexts) == len(line.Contents) {
line = presentation.DocumentVisualLineForSpeech(line)
}
if spoken := presentation.DocumentLineSpeechWithOptions(line, options); spoken.Text != "" {
// One request owns the original observation ticket. Conservatively
// keep the entire reading private if any spoken line is sensitive