fix(ui): the accessibility check keeps a saved page range inside the document (#1300) (#1437)

With the options dialog turned off, run_accessibility_check used the range
saved on an earlier, longer document as it was: a page past the end
selected no page, and the page rules came out Passed without looking at
anything. The range is now clamped to the active document's pages, as the
dialog already does. a_saved_page_range_past_the_document_still_checks_its_pages
fails before the change with Passed for Tagged content.
This commit is contained in:
Marco Arnulfo 2026-10-13 06:47:16 +02:00 committed by GitHub
parent 4f375bf45c
commit 251917f685
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 1 deletions

View File

@ -357,7 +357,11 @@ impl PdfCraftApp {
let Some((_, id)) = self.active_ids() else { return };
let Some(doc) = self.session.get(id) else { return };
let o = &self.a11y_options;
let options = Options { rules: o.rules.clone(), pages: (!o.all_pages).then(|| (o.from.max(1) - 1..o.to.max(o.from)).collect()) };
// The range was picked on whatever document had the options dialog last; with the dialog
// turned off it reaches here unchecked, and a page past the end would select nothing.
let to = o.to.clamp(1, doc.info.pages.len().max(1));
let from = o.from.clamp(1, to);
let options = Options { rules: o.rules.clone(), pages: (!o.all_pages).then(|| (from - 1..to).collect()) };
let Some(report) = doc.accessibility_check(&options) else {
self.notify_tr("This document can't be checked: it couldn't be read for editing");
return;

View File

@ -171,6 +171,26 @@ fn checker_summary_does_not_hide_manual_review() {
h.get_by_label("No issues found");
}
#[test]
fn a_saved_page_range_past_the_document_still_checks_its_pages() {
// A range picked on a longer document survives into this one-page document when the options
// dialog is turned off. Unclamped, it selected no page, and the page rules came out Passed
// without having looked at the untagged text (#1300).
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
let mut app = PdfCraftApp::new();
app.set_option("language", "en").unwrap();
app.open_bytes("notes.pdf", None, FIXTURE.to_vec()).unwrap();
app
});
h.run_steps(3);
let o = &mut h.state_mut().a11y_options;
(o.show_dialog, o.all_pages, o.from, o.to) = (false, false, 2, 2);
assert!(h.state_mut().execute("a11y.check"));
h.run_steps(2);
assert_eq!(status(&h, Rule::TaggedContent), Status::Failed);
assert_eq!(h.state().a11y.options.as_ref().and_then(|o| o.pages.clone()), Some(vec![0]));
}
/// Two tagged figures: an image without alternate text and a bar (role-mapped Photo) with.
const FIGURES: &[u8] = b"%PDF-1.7
1 0 obj << /Type /Catalog /Pages 2 0 R /MarkInfo << /Marked true >> /StructTreeRoot 5 0 R >> endobj