Import documentation: docs/superpowers/plans/2026-07-13-persian-rtl-reliability.md

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:07:35 +03:30
parent 6ebc4e7361
commit 2ee5cb30a9
@@ -0,0 +1,115 @@
# Persian RTL Reliability Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make the extension conservatively correct Persian text direction, add Vazirmatn only to author-unstyled Persian text, remain responsive during streaming AI chats, and provide a clearer accessible popup.
**Architecture:** Keep the dependency-free Manifest V3 structure. Replace the corrupted broad Arabic-range detector with testable Persian-specific helpers inside the isolated content script, apply reversible DOM mutations, and coalesce mutation work by semantic block. Keep settings in `chrome.storage.local` and make the popup a small controller over the same schema.
**Tech Stack:** Chrome Extensions Manifest V3, plain JavaScript, HTML/CSS, Node.js, jsdom 29.
## Global Constraints
- Detect Persian text only; Arabic-only and Hebrew text do not trigger changes.
- Never rewrite text, punctuation, or Latin digits.
- Any author-specified font family counts as styled, including generic and inherited families.
- Work automatically on all supported websites and optimize for streaming AI chats without site-specific selectors.
- All mutations must be reversible without a reload.
- This folder is not a Git repository, so verification checkpoints replace commit steps.
---
### Task 1: Real UTF-8 Detection and Direction Contract
**Files:**
- Create: `test/content-engine.js`
- Modify: `src/content.js`
- Remove after replacement: `test/integration-v2.js`, `test/regex-test.js`
**Interfaces:**
- Consumes: the content script's automatic bootstrap with a mocked `chrome` API.
- Produces: Persian detection based on Persian-specific letters; conservative `rtl`/`auto` decisions and byte-identical text.
- [ ] **Step 1: Add failing fixtures** for `این متن فارسی است`, Arabic-only `هذا نص عربي`, mixed English/Persian text, and `نسخه 1234567890`.
- [ ] **Step 2: Run** `node test/content-engine.js`; expect failures for Persian detection and Arabic-only isolation against the corrupted current range.
- [ ] **Step 3: Replace the range** with explicit Unicode escapes for Persian-specific letters plus a broader Arabic-script letter count used only after a Persian trigger. Classify first-strong Persian blocks as `rtl`, English-leading mixed blocks as `auto`, and preserve the original text exactly.
- [ ] **Step 4: Run** `node test/content-engine.js`; expect all direction and integrity assertions to pass.
### Task 2: Conservative Targets and Author-Font Detection
**Files:**
- Modify: `test/content-engine.js`
- Modify: `src/content.js`
**Interfaces:**
- Consumes: `processTextNode(node, votedBlocks)` and reversible element markers.
- Produces: semantic block targeting, explicit-direction preservation, and `hasAuthorFont(element): boolean` behavior.
- [ ] **Step 1: Add failing cases** for existing `dir="rtl"`, sensible inherited direction, inline Arial, stylesheet `font-family: sans-serif`, inherited body font, and a document with no author font.
- [ ] **Step 2: Run** `node test/content-engine.js`; expect the current unconditional Vazirmatn behavior to fail the author-font cases.
- [ ] **Step 3: Implement author-font inspection** by walking the element/ancestor chain and checking matching author stylesheet declarations plus inline declarations. Apply Vazirmatn only when no declaration exists; isolate inaccessible stylesheet errors.
- [ ] **Step 4: Refine target selection** so paragraph/list/heading/message-sized containers win over broad sections, while code, SVG, MathML, and editable content remain protected.
- [ ] **Step 5: Run** `node test/content-engine.js`; expect all font and target cases to pass.
### Task 3: Streaming, Inputs, Frames, and Reversible Lifecycle
**Files:**
- Modify: `test/content-engine.js`
- Modify: `test/edge-cases.js`
- Modify: `src/content.js`
- Modify: `manifest.json`
**Interfaces:**
- Consumes: queued text nodes/roots and storage change callbacks.
- Produces: one scheduled processing pass per burst, reversible teardown/reapply, and related-frame coverage through Manifest V3 fields.
- [ ] **Step 1: Add asynchronous tests** that append a streaming Persian response in several character-data mutations, toggle settings off/on, and verify text identity plus restored `dir`/font state.
- [ ] **Step 2: Run** `node test/content-engine.js` and `node test/edge-cases.js`; expect streaming/lifecycle failures where stale direction or styling remains.
- [ ] **Step 3: Coalesce work by block** and re-evaluate a previously processed block when streamed text changes its classification. Clear queues and observers during teardown.
- [ ] **Step 4: Keep inputs at `dir="auto"`** without rewriting their values, and apply the unstyled-font policy consistently.
- [ ] **Step 5: Add `match_origin_as_fallback: true`** beside `all_frames` for related `about:`, `data:`, `blob:`, and `filesystem:` frames.
- [ ] **Step 6: Run both tests**; expect zero failures and no unhandled jsdom errors.
### Task 4: Accessible Popup and Settings Migration
**Files:**
- Create: `test/popup.js`
- Modify: `popup/popup.html`
- Modify: `popup/popup.css`
- Modify: `popup/popup.js`
**Interfaces:**
- Consumes: settings `{ enabled, fixDirection, useFont, fixInputs, disabledSites }` with legacy values safely defaulted.
- Produces: current-site status, master/site/direction/font/input controls, and safe unsupported-page/error states.
- [ ] **Step 1: Add popup controller tests** with mocked tabs/storage for a normal HTTPS tab, `chrome://extensions`, storage failure, dependency disabling, and setting persistence.
- [ ] **Step 2: Run** `node test/popup.js`; expect failure because current markup lacks status and `fixDirection`.
- [ ] **Step 3: Update markup and copy** to expose the approved five controls and a live status region. Use native checkbox semantics and explicit labels.
- [ ] **Step 4: Update styles** with visible keyboard focus, sufficient contrast, disabled states, compact spacing, and status icons/text that do not rely on color.
- [ ] **Step 5: Update controller** to use `chrome.runtime.lastError`, tolerate missing tab URLs, disable site controls for unsupported pages, and migrate the old settings shape without data loss.
- [ ] **Step 6: Run** `node test/popup.js`; expect all controller and accessibility assertions to pass.
### Task 5: Demo, Documentation, and Complete Verification
**Files:**
- Modify: `demo.html`
- Modify: `README.md`
- Modify: `package.json`
- Modify: `manifest.json`
**Interfaces:**
- Consumes: the final behavior and test commands.
- Produces: correctly encoded manual fixtures, accurate installation/behavior documentation, and a single test entry point.
- [ ] **Step 1: Replace mojibake** in user-visible metadata, popup copy, README, demo, test labels, and Persian fixtures with valid UTF-8.
- [ ] **Step 2: Add a streaming-chat demo** that appends Persian text incrementally without converting its Latin digits.
- [ ] **Step 3: Add package scripts**: `"test": "node test/content-engine.js && node test/edge-cases.js && node test/popup.js"` and `"check:encoding": "node test/encoding.js"`; add an encoding test that rejects known mojibake markers and requires real Persian fixtures.
- [ ] **Step 4: Run** `npm test`; expect all suites to pass.
- [ ] **Step 5: Run** `npm run check:encoding`; expect `Encoding check passed`.
- [ ] **Step 6: Parse `manifest.json`** with Node and inspect the popup/demo in a Chromium browser if available; record any browser-only validation still required.
## Self-Review
- Spec coverage: direction, Persian-only scope, digit preservation, font policy, streaming, popup, reversibility, errors, demo, and tests are each assigned above.
- Placeholder scan: no unresolved implementation placeholders remain.
- Interface consistency: the shared settings keys are `enabled`, `fixDirection`, `useFont`, `fixInputs`, and `disabledSites` in content, popup, and tests.