Bayan (بيان) — Phase 1 Editor Stabilization Refactor Plan (Revised)
Goal
Refactor the current editor architecture to solve the core technical problems while avoiding unnecessary complexity.
This phase is strictly focused on editor stability and maintainability.
Success Criteria
- Cursor position is preserved after analysis updates.
- Text selection is preserved.
- Multiple occurrences of the same word are highlighted correctly.
- Suggestions use exact character offsets instead of string replacement.
- Rendering is XSS-safe.
- Editor code becomes modular and easier to extend.
- Future features (DOCX import, export, database persistence) remain possible without major rewrites.
Scope
Included
- Cursor preservation
- Selection preservation
- Offset-based highlighting
- Duplicate occurrence handling
- Secure rendering
- Editor code modularization
Excluded
- DOCX Import
- TXT Import
- DOCX Export
- PDF Export
- Supabase
- Authentication
- Autosave
- Database integration
- Deployment work
These belong to later phases.
Architectural Strategy
Keep Existing contenteditable
We will continue using a single contenteditable editor.
Current:
<div id="editor-container" contenteditable="true"></div>
No dual-layer editor.
No transparent text layer.
No click-forwarding system.
No overlay synchronization.
Why
The current project is a graduation project, not a full-scale IDE.
Keeping contenteditable provides:
- Lower complexity
- Faster implementation
- Fewer bugs
- Easier maintenance
- Faster delivery
while still solving all current issues.
Milestone 1 — Modularize Editor Logic
Objective
Separate editor concerns from UI and networking logic.
New Structure
src/
│
├── js/
│ ├── api.js
│ ├── editor.js
│ ├── renderer.js
│ ├── selection.js
│ └── ui.js
│
├── index.html
Responsibilities
api.js
Handles:
- /api/analyze
- /api/spelling
- /api/autocomplete
- /api/summarize
No DOM manipulation.
editor.js
Handles:
- Reading editor text
- Writing editor text
- Editor events
- Debouncing
renderer.js
Handles:
- Highlight rendering
- Safe HTML generation
- Offset mapping
selection.js
Handles:
- Save selection
- Restore selection
- Caret positioning
ui.js
Handles:
- Tooltips
- Panels
- Buttons
- Notifications
Milestone 2 — Selection Preservation
Problem
Current rendering rewrites the editor DOM.
Result:
- Cursor jumps
- Selection disappears
- Focus is lost
Solution
Before rendering:
const selection = saveSelection();
After rendering:
restoreSelection(selection);
Required Functions
saveSelection()
restoreSelection()
getCaretOffset()
setCaretOffset()
Expected Result
User can:
- Type continuously
- Select text
- Accept suggestions
without cursor jumps.
Milestone 3 — Backend Offset Support
Current Problem
Suggestions identify words only.
Example:
{
"original": "ذهبو",
"correction": "ذهبوا"
}
This fails when the same word appears multiple times.
Required Change
Update backend responses.
Example:
{
"suggestions": [
{
"start": 12,
"end": 17,
"original": "ذهبو",
"correction": "ذهبوا",
"type": "spelling"
}
]
}
Benefits
- Exact positioning
- No ambiguity
- Faster rendering
- Supports duplicate words
Milestone 4 — Offset-Based Rendering
Current Problem
Rendering uses:
text.replace(...)
which only affects the first occurrence.
New Strategy
Use character offsets.
Example:
{
"start": 45,
"end": 50
}
Rendering process:
- Split text into segments.
- Create normal text nodes.
- Create highlighted spans.
- Assemble output safely.
Result
Every occurrence is highlighted correctly.
Milestone 5 — Secure Rendering
Current Problem
Direct innerHTML generation creates XSS risk.
Solution
Escape all user-generated content.
Example:
escapeHtml(text)
before inserting into DOM.
Requirements
Never inject:
userInput
suggestionText
apiResponse
directly into HTML.
Always sanitize first.
Milestone 6 — Highlight Engine Refactor
Objective
Create a reusable rendering pipeline.
Input
{
"text": "...",
"suggestions": [...]
}
Output
Safe highlighted HTML.
Responsibilities
The renderer must support:
- Spelling highlights
- Grammar highlights
- Punctuation highlights
without changing editor logic.
Milestone 7 — Tooltip Mapping
Strategy
Each highlight receives:
<span
class="error-highlight"
data-suggestion-id="42">
</span>
Clicking a span retrieves:
currentSuggestions[id]
and opens the tooltip.
Benefits
- Cleaner architecture
- Easier debugging
- Future extensibility
Deliverables
At the end of Phase 1:
Functional Deliverables
- Stable editor
- Cursor preservation
- Selection preservation
- Duplicate-word support
- Offset-based highlighting
- Secure rendering
- Modular editor code
Technical Deliverables
api.js
editor.js
renderer.js
selection.js
ui.js
Explicitly Deferred
The following are NOT part of this phase:
- Light/Dark Theme
- UI Redesign
- TXT Import/Export
- DOCX Import/Export
- PDF Export
- Authentication
- Supabase
- Database Storage
- Autosave
- Deployment
These will be implemented in later phases.