Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
4.0 KiB
Persian RTL Reliability Improvement Design
Goal
Improve the Manifest V3 extension so it reliably fixes Persian text direction on dynamic AI chat sites and ordinary websites without rewriting text, changing digits, or disturbing intentionally styled content.
Scope
- Detect Persian text only. Arabic-only and Hebrew text do not trigger changes.
- Never change text content, punctuation, or
1234567890digits. - Work automatically on all supported websites and frames.
- Optimize mutation handling for streaming AI responses.
- Apply Vazirmatn only when Persian text has no author-specified font.
- Simplify and improve the popup, tests, documentation, and encoding integrity.
Direction Policy
The extension uses an adaptive-conservative policy:
- Identify Persian-specific letters and marks.
- Inspect meaningful letters and the first strong script in the nearest suitable text block.
- Preserve a sensible explicit
dirsupplied by the site. - Apply
dir="rtl"only to clearly Persian blocks. - Apply
dir="auto"to uncertain mixed-language blocks. - Avoid changing large layout containers when a smaller semantic text block is available.
Every attribute change records its original state and is reversible without reloading the page.
Font Policy
- Any author-specified
font-familycounts as styled, including Arial, generic families, system UI fonts, inherited fonts, inline styles, and web fonts. - Vazirmatn is applied only when no author rule on the element or its ancestors supplies a font family and the element is therefore using the browser default.
- English-only elements are untouched.
- Existing font weight and style are preserved through bundled regular, medium, and bold faces.
- Disabling the feature restores the original inline state.
The popup exposes one clear font option: Use Vazirmatn for unstyled Persian text.
Architecture
The content script is split into focused internal modules or sections:
- settings and lifecycle
- Persian detection and direction classification
- author-font detection
- DOM target selection and reversible mutations
- input handling
- mutation batching and shadow-root discovery
Streaming mutations are coalesced by affected text container. The extension processes changed regions rather than rescanning the complete document for every token.
Popup
The popup shows:
- the current hostname and active/inactive status
- Enable on this site
- Conservative Persian RTL correction
- Use Vazirmatn for unstyled Persian text
- Smart input direction
- Master switch
Dependent controls have accessible disabled states. Switches support keyboard focus, visible focus rings, and status text that does not rely only on color.
Error Handling
- Unsupported/internal browser pages display an unavailable state instead of behaving like an empty hostname.
- Storage and tab-query failures fall back safely and expose a concise popup status.
- DOM and stylesheet access failures are isolated per element so one unusual page cannot stop processing.
- The content script remains idempotent and does not observe its own attribute writes.
Verification
Automated tests cover:
- real UTF-8 Persian fixtures and an encoding-integrity assertion
- Persian-only, Arabic-only, English-only, and mixed text
- Latin digits inside Persian text remaining byte-identical
- explicit RTL/LTR/auto direction preservation and correction
- author fonts from inline, stylesheet, inherited, generic, and custom declarations
- browser-default text receiving Vazirmatn
- streaming text mutations and batched processing
- inputs, code blocks, SVG/MathML, open shadow roots, and reversible teardown
- per-site and master settings
The demo page uses correctly encoded Persian fixtures and includes streaming-chat scenarios.
Non-goals
- Transliteration, translation, numeral conversion, or text rewriting
- Hebrew or Arabic-only correction
- Fragile site-specific selectors for individual AI products
- Closed shadow-root support, which browser extensions cannot access