- Create pdf_text_to_html.js: JS port of the Ruby heuristic parser
(ALL_CAPS→h2, numbered headings→h3, bullets→ul/li, body→p dir=auto)
- Add pdf_view, text_view, document_view_options keys to i18n.js (en)
- Update document.vue: tab switcher shown when all pages have extracted
text; PDF View renders the existing page images; Text View renders
heuristic HTML in a prose container with per-page sections
- ArrowLeft/ArrowRight keyboard navigation between tabs with focus management
- Tab is hidden entirely for scanned/image-only PDFs (hasFullText gate)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The page.vue component uses container-type: size for CSS container
queries. This containment context interferes with the clip: rect(0,0,0,0)
technique used by Tailwind's sr-only class, causing the hidden page text
to render visually below the PDF image.
Replace sr-only class with position: absolute; left: -9999px off-screen
technique which is robust against CSS containment contexts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Create PdfTextToHtml heuristic parser (ALL_CAPS→h2, numbered→h3, bullets→ul, body→p)
- Create document-tabs custom element (ARIA APG tab pattern, roving tabindex, localStorage persistence)
- Register document-tabs element in application.js
- Add tab switcher to submissions/show and submit_form/show when all pages have extracted text
- Add text panel with per-page sections to both views
- Fix role="region" bug on sr-only page text divs (excess ARIA landmarks)
- Add 5 new i18n keys: pdf_view, text_view, document_view_options, text_view_disclaimer, signing_fields_below
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extracts PDF text during upload via Pdfium and stores it in attachment
metadata (pdf.pages_text), then surfaces it in visually-hidden sr-only
regions in both the signing form and submission preview views. Also adds
alt text to template builder page images and ARIA role/label to the
page-container custom element.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Added new gems: axe-core-api, axe-core-rspec, axiom-types, coercible, descendants_tracker, dumb_delegator, and virtus for enhanced accessibility and data handling.
- Updated database schema comments for clarity, ensuring proper formatting for index definitions in document_generation_event.rb, email_event.rb, lock_event.rb, submission_event.rb, and submission.rb.
- Adjusted the schema version in db/schema.rb to reflect the latest changes.
These updates contribute to ongoing accessibility improvements and maintain code clarity.
Added Enter and Space key handlers to 3 custom elements for full keyboard accessibility:
1. clipboard_copy.js:
- Added keydown listener for Enter/Space keys
- Set tabindex="0" and role="button" for keyboard focus
- Refactored click handler into reusable copyToClipboard function
- Keyboard users can now copy text without a mouse
2. download_button.js:
- Added keydown listener for Enter/Space keys
- Set tabindex="0" and role="button" for keyboard focus
- Keyboard users can now trigger file downloads
3. password_input.js:
- Added keydown listener to togglePasswordVisibility element
- Set tabindex="0" and role="button" on toggle button
- Properly cleanup event listener in disconnectedCallback
- Keyboard users can now toggle password visibility
All implementations:
- Use e.preventDefault() to prevent default Space key scrolling
- Check for existing tabindex/role attributes before setting
- Follow WCAG 2.1.1 (Keyboard, Level A) guidelines
- Support both Enter and Space keys per ARIA authoring practices
This satisfies WCAG 2.2 Success Criterion 2.1.1 (Keyboard, Level A).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed 6 images missing alt attributes across submission form components:
- signature_step.vue: Added dynamic alt text with field name and "preview"
- initials_step.vue: Added dynamic alt text with field name and "preview"
- image_step.vue: Added dynamic alt text with field name and "preview"
- area.vue: Added alt text for 5 different image types:
* Image field
* Stamp field
* Knowledge-based authentication (KBA) field
* Signature field
* Initials field
All alt text uses field.name when available, falling back to descriptive defaults.
This satisfies WCAG 2.2 Success Criterion 1.1.1 (Non-text Content, Level A).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit establishes the foundation for WCAG 2.2 Level AA compliance:
Infrastructure:
- Add axe-core-rspec gem for automated accessibility testing
- Create spec/accessibility/ directory structure
- Add accessibility_helpers.rb with custom WCAG test helpers
- Add comprehensive testing documentation (README.md, SETUP_NOTES.md)
Semantic Landmarks (WCAG 2.4.1):
- Add <main> landmark with id="main-content" to application layout
- Add <nav> landmark with aria-label to navbar
- Add skip navigation link for keyboard users
- Skip link uses focus:translate-y-0 to appear only on keyboard focus
These changes address critical barriers for screen reader and keyboard users.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>