Commit ·
038f3af
1
Parent(s): 8ebd4a6
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
Browse files- src/index.html +1 -7
- src/js/editor.js +22 -1
src/index.html
CHANGED
|
@@ -586,7 +586,7 @@
|
|
| 586 |
</div>
|
| 587 |
</div>
|
| 588 |
<div class="fmt-divider"></div>
|
| 589 |
-
<!-- Item 9: Lists
|
| 590 |
<div class="fmt-group">
|
| 591 |
<button class="fmt-btn" onclick="execFormat('insertUnorderedList')" type="button" title="قائمة نقطية">
|
| 592 |
<svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M4 6h2v2H4V6zm4 0h12v2H8V6zM4 11h2v2H4v-2zm4 0h12v2H8v-2zm-4 5h2v2H4v-2zm4 0h12v2H8v-2z"/></svg>
|
|
@@ -594,12 +594,6 @@
|
|
| 594 |
<button class="fmt-btn" onclick="execFormat('insertOrderedList')" type="button" title="قائمة مرقمة">
|
| 595 |
<svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z"/></svg>
|
| 596 |
</button>
|
| 597 |
-
<button class="fmt-btn" onclick="execFormat('indent')" type="button" title="مسافة بادئة">
|
| 598 |
-
<svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M3 21h18v-2H3v2zM3 8v8l4-4-4-4zm8 9h10v-2H11v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"/></svg>
|
| 599 |
-
</button>
|
| 600 |
-
<button class="fmt-btn" onclick="execFormat('outdent')" type="button" title="إزالة المسافة البادئة">
|
| 601 |
-
<svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M11 17h10v-2H11v2zm-8-5l4 4V8l-4 4zm0 9h18v-2H3v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"/></svg>
|
| 602 |
-
</button>
|
| 603 |
</div>
|
| 604 |
<div class="fmt-divider"></div>
|
| 605 |
<!-- Clear formatting -->
|
|
|
|
| 586 |
</div>
|
| 587 |
</div>
|
| 588 |
<div class="fmt-divider"></div>
|
| 589 |
+
<!-- Item 9: Lists -->
|
| 590 |
<div class="fmt-group">
|
| 591 |
<button class="fmt-btn" onclick="execFormat('insertUnorderedList')" type="button" title="قائمة نقطية">
|
| 592 |
<svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M4 6h2v2H4V6zm4 0h12v2H8V6zM4 11h2v2H4v-2zm4 0h12v2H8v-2zm-4 5h2v2H4v-2zm4 0h12v2H8v-2z"/></svg>
|
|
|
|
| 594 |
<button class="fmt-btn" onclick="execFormat('insertOrderedList')" type="button" title="قائمة مرقمة">
|
| 595 |
<svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z"/></svg>
|
| 596 |
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 597 |
</div>
|
| 598 |
<div class="fmt-divider"></div>
|
| 599 |
<!-- Clear formatting -->
|
src/js/editor.js
CHANGED
|
@@ -7,6 +7,17 @@ let _lastInputTime = 0;
|
|
| 7 |
const ANALYZE_DEBOUNCE_MS = 1000;
|
| 8 |
const MAX_ANALYZE_LENGTH = 5000;
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
/**
|
| 11 |
* Initialize the editor
|
| 12 |
*/
|
|
@@ -162,7 +173,11 @@ async function analyzeText() {
|
|
| 162 |
return;
|
| 163 |
}
|
| 164 |
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
|
| 167 |
// Use DOM overlay instead of innerHTML replacement to preserve formatting
|
| 168 |
const editor = getEditorElement();
|
|
@@ -385,6 +400,12 @@ function applyAlternativeCorrection(suggestion, correctionText) {
|
|
| 385 |
}
|
| 386 |
|
| 387 |
function dismissSuggestion(suggestion) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 388 |
// Remove the error highlight but keep the text as-is
|
| 389 |
const idx = (window.currentSuggestions || []).indexOf(suggestion);
|
| 390 |
const errorSpan = idx >= 0 ? document.querySelector(`[data-suggestion-id="${idx}"]`) : null;
|
|
|
|
| 7 |
const ANALYZE_DEBOUNCE_MS = 1000;
|
| 8 |
const MAX_ANALYZE_LENGTH = 5000;
|
| 9 |
|
| 10 |
+
// Dismissed words whitelist — words the user chose to keep as-is
|
| 11 |
+
const _dismissedWords = new Set(
|
| 12 |
+
JSON.parse(localStorage.getItem('bayan_dismissed_words') || '[]')
|
| 13 |
+
);
|
| 14 |
+
|
| 15 |
+
function _saveDismissedWords() {
|
| 16 |
+
try {
|
| 17 |
+
localStorage.setItem('bayan_dismissed_words', JSON.stringify([..._dismissedWords]));
|
| 18 |
+
} catch (e) {}
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
/**
|
| 22 |
* Initialize the editor
|
| 23 |
*/
|
|
|
|
| 173 |
return;
|
| 174 |
}
|
| 175 |
|
| 176 |
+
// Filter out dismissed (whitelisted) words
|
| 177 |
+
const rawSuggestions = sortSuggestions(data.suggestions || []);
|
| 178 |
+
window.currentSuggestions = rawSuggestions.filter(
|
| 179 |
+
s => !_dismissedWords.has(s.original)
|
| 180 |
+
);
|
| 181 |
|
| 182 |
// Use DOM overlay instead of innerHTML replacement to preserve formatting
|
| 183 |
const editor = getEditorElement();
|
|
|
|
| 400 |
}
|
| 401 |
|
| 402 |
function dismissSuggestion(suggestion) {
|
| 403 |
+
// Add the word to dismissed whitelist so it's never flagged again
|
| 404 |
+
if (suggestion.original) {
|
| 405 |
+
_dismissedWords.add(suggestion.original);
|
| 406 |
+
_saveDismissedWords();
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
// Remove the error highlight but keep the text as-is
|
| 410 |
const idx = (window.currentSuggestions || []).indexOf(suggestion);
|
| 411 |
const errorSpan = idx >= 0 ? document.querySelector(`[data-suggestion-id="${idx}"]`) : null;
|