- FIX-35: Narrowed suffix set from {ن,ت,ا,ي,ة,و,ه} to {ن,ت} only.
Only verb conjugation suffixes are blocked. ة/ا/ي/و/ه are legitimate
typo corrections that should not be blocked.
- FIX-37: Raised word threshold from 2 to 4. Prevents noisy period
suggestions while user is still typing short phrases.
- FIX-32b: Removed duplicate .sort() in applyAllSuggestions — already
sorted at line 679, second sort at 695 was redundant.
- Tests updated to match narrowed suffix expectations.
FIX-32b: Add missing reverse sort in applyAllSuggestions
Found during commit audit: the text-based replacement loop iterated
suggestions in original order instead of reverse-sorted by offset.
Without descending sort, applying a fix at offset 5 shifts all text
after it, causing fixes at offset 20+ to corrupt the text.
FIX-33: Grammar rules fix_prepositions_advanced was corrupting
الامتحان→الامتحين. The regex blindly replaced ان→ين after prepositions,
but الامتحان is a root noun not a dual. Added blocklist of ~60 common
root-form nouns and skip all ال-prefixed words ending in ان.
FIX-34: Remove auto-re-analysis from Apply All in editor.js.
When spelling and grammar disagree (spelling strips ذهبن→ذهب,
grammar re-adds ذهبوا→ذهبن), the auto-re-analysis creates an
infinite loop of contradictory suggestions.
FIX-35: Spelling no longer strips valid conjugation suffixes.
The insertion fix was accepting ذهبن→ذهب (removing final ن) as
'extra char removed'. But ن is a feminine plural verb suffix.
Now blocks removal of suffix chars (ن,ت,ا,ي,ة,و,ه) from word
endings, preventing spelling from undoing grammar corrections.
FIX-32: Fix word duplication bug in website frontend
Root cause: applyAllSuggestions used a mixed DOM+text fallback approach.
After DOM-based fixes shifted the editor text, the text-based fallback
used stale offsets from the original API response, inserting corrections
at wrong positions. This caused 'المشروعالمشروع.' (word duplication).
Fix:
1. applyAllSuggestions now uses PURE text-based reverse-order replacement.
Since patches are sorted highest-offset-first, each offset is valid
because nothing before it has been modified yet.
2. _isApplyingSuggestion guard now stays active 400ms (past the 300ms
re-analysis timeout) to prevent normalize()/input events from
triggering duplicate analysis calls.
feat: Complete ALL plan items — gradient tokens, nav scroll glow, focus rings, dropdown keyboard nav, color reset, network delay indicator
Grammar removes period, punctuation re-adds it. Auto re-analyze after apply
creates an infinite cycle. Analysis already auto-triggers when user types
(input event handler), which is the correct behavior.
fix: prevent analyze loop - skip redundant API calls when text unchanged
P1: Integrate fix_common_hamza into /api/analyze pipeline
- Standalone hamza-fix pass runs AFTER spelling, catches انت→أنت,
الان→الآن, ام→أم, انا→أنا in sentence context
- Works even when AraSpell is skipped (>300 chars)
P1: Split multi-word grammar diffs into individual suggestions
- Grammar corrections like 'الي المدرسه الاستاذ'→'إلى المدرسة الأستاذ'
now appear as 3 separate suggestions, not 1 merged block
- Users can accept/reject each correction individually
P2: Auto re-analyze after applying any suggestion (frontend)
- After applying single, alternative, or all suggestions,
editor automatically re-analyzes with 300ms delay
- Shows 'جار التحليل' without user needing to type anything
P3: Word truncation guard
- Reject spelling corrections that shorten valid words by 2+ chars
- Prevents الدمث→الدم (rare word truncation)
P3: CI/CD - regression tests on every push
- Added test job to GitHub Actions workflow
- Runs 120 tests before lint-and-validate
- Grammar service: transient errors (rate limiting, timeout) no longer cached permanently — next request will retry loading instead of failing forever
- Editor: cursor now placed right after corrected text instead of jumping to start — applied to all 3 code paths (UUID span, text-match fallback, offset fallback)
fix: Strip HTML formatting on paste into editor - Added paste event handler that converts clipboard to plain text - Prevents rich text styling (colors, opacity, fonts) from being carried over - Preserves paragraph structure with line breaks - Fixes ghost formatting when pasting from chat or web pages
fix: Re-index suggestion spans after dismiss (keep as-is) - After filtering dismissed suggestion from array, span data-suggestion-id indices became stale - Adjacent error words became unclickable because findSuggestionById used wrong index - Now re-indexes all remaining spans to match updated array positions
fix: Undo/Redo inside editor only + auto-focus after corrections - Moved listener back to editor element (capture:true) as user requested - Added editor.focus() after applySuggestionAtOffsets (line 432) - Added editor.focus() after applyAlternativeCorrection (line 474) - Added editor.focus() after dismissSuggestion (line 518) - After any correction/dismiss, editor auto-focuses so Ctrl+Z works immediately
fix: Undo/Redo now works after spelling corrections - Moved keydown listener from editor to document with capture:true - Uses stopImmediatePropagation to prevent browser native undo - Auto-focuses editor after undo/redo - Works even when tooltip click steals focus from editor
fix: Use capture phase on editor for Ctrl+Z/Y to intercept before browser native undo - Listener now on editor element with capture:true instead of document - Added stopPropagation to prevent browser native undo from also firing - Ensures corrections/dismissals can be properly undone
feat: Add custom Undo/Redo for corrections and dismissals - Ctrl+Z undoes correction/dismiss (restores previous editor state) - Ctrl+Y or Ctrl+Shift+Z redoes - pushUndoState() called before every applyCorrection, applyAlternative, dismissSuggestion, applyAll - 50-level undo stack - Only intercepts when custom stack has entries (falls through to browser native otherwise)
audit-v4: 10 fixes and improvements - FIX: Footer replaced with multi-column layout (Product + Resources) - FIX: cta_primary config now matches button text - FIX: Enterprise 'contact sales' button navigates to editor - FIX: Mock editor 'الكتابه' now has spelling-error class (3 errors) - FIX: Status bar updated to '٣ إملائي' - FIX: Scroll-to-top fallback to window.scrollY - FIX: Remove @view-transition experimental CSS - FIX: Remove injected Cloudflare challenge script - ADD: Toast on applyCorrection + applyAllSuggestions - ADD: confirm() on applyAllSuggestions - ADD: Smart empty state (no text vs no errors) - ADD: Toggle switch HTML for summary checkbox
audit: Fix 15+ issues across entire website - BUGS: Fix copySummary event.target crash, viewbox→viewBox SVGs - HERO: Replace fake stats (10M/99%/50K) with real features (3 types/instant/free) - HERO: 'شاهد العرض التوضيحي'→'استكشف الميزات' with onclick - HERO: Fix mock editor hardcoded light colors→CSS variables - HERO: animate-pulse→animate-fade-in on floating card - PRICING: All 3 buttons now have onclick (go to editor) - FOOTER: Replace dead #links with working page navigation - EDITOR: Confirm dialog before clearing content - CODE: Remove empty style tag and old comments
feat: Remove indent buttons + dismissed words whitelist - Remove indent/outdent buttons from toolbar (keep lists) - 'إبقاء كما هي' now saves word to localStorage whitelist - Whitelisted words are filtered out from future analysis - Persists across page reloads via bayan_dismissed_words key
fix: Lists, indent, and keep button - Change white-space from pre-wrap to normal (fixes lists + indent) - Redesign keep button: centered, cleaner, separated from corrections - Keep button always renders last with clear 'إبقاء كما هي' label - Blockquote/list styling for RTL editor
fix: Critical editor bugs - Dropdowns now visible (remove overflow:hidden from editor-shell) - Font/size/color menus z-index 200 (above editor) - Selection collapses after formatting (no more blue highlight) - Spelling overlay uses textContent for consistent offsets - Correction preserves formatting (replaces inside parent node) - Alt correction same fix - Fallback finds span by matching original text
feat: Rich text formatting toolbar + formatting-preserving renderer - Bold, Italic, Underline, Strikethrough, Alignment, Undo/Redo - Font family and font size dropdowns - New DOM-level overlay renderer (preserves formatting during analysis) - Apply/dismiss corrections keep original formatting
fix: Increase analyze debounce to 1.5s to prevent text overwrite while typing - Debounce 500ms -> 1500ms - Abort in-flight requests when user starts typing again - Double-check no new input before running analysis