Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
7.9 KiB
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
chromeAPI. -
Produces: Persian detection based on Persian-specific letters; conservative
rtl/autodecisions 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 asauto, 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): booleanbehavior. -
Step 1: Add failing cases for existing
dir="rtl", sensible inherited direction, inline Arial, stylesheetfont-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.jsandnode 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: truebesideall_framesfor relatedabout:,data:,blob:, andfilesystem: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 andfixDirection. -
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; expectEncoding check passed. -
Step 6: Parse
manifest.jsonwith 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, anddisabledSitesin content, popup, and tests.