@inshapardaz/likhari-react 0.1.24 → 0.1.25-dev.224
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EditorRoot.d.ts.map +1 -1
- package/dist/EditorRoot.js +8 -2
- package/dist/autocomplete/AutocompletePlugin.d.ts +11 -0
- package/dist/autocomplete/AutocompletePlugin.d.ts.map +1 -0
- package/dist/autocomplete/AutocompletePlugin.js +180 -0
- package/dist/autocomplete/wordIndex.d.ts +13 -0
- package/dist/autocomplete/wordIndex.d.ts.map +1 -0
- package/dist/autocomplete/wordIndex.js +37 -0
- package/dist/autocorrect/AutoCorrectPlugin.d.ts.map +1 -1
- package/dist/autocorrect/AutoCorrectPlugin.js +18 -2
- package/dist/autocorrect/autoCorrectActions.d.ts +6 -0
- package/dist/autocorrect/autoCorrectActions.d.ts.map +1 -1
- package/dist/autocorrect/autoCorrectActions.js +30 -0
- package/dist/components/AutoCorrectPanel.d.ts +5 -1
- package/dist/components/AutoCorrectPanel.d.ts.map +1 -1
- package/dist/components/AutoCorrectPanel.js +3 -3
- package/dist/components/SpellcheckPanel.d.ts +3 -1
- package/dist/components/SpellcheckPanel.d.ts.map +1 -1
- package/dist/components/SpellcheckPanel.js +2 -2
- package/dist/components/Toolbar.d.ts +4 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +5 -2
- package/dist/i18n/strings.d.ts +4 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +12 -0
- package/dist/spellcheck/spellDictionaries.d.ts +4 -0
- package/dist/spellcheck/spellDictionaries.d.ts.map +1 -1
- package/dist/spellcheck/spellDictionaries.js +29 -3
- package/dist/spellcheck/userWords.d.ts +2 -0
- package/dist/spellcheck/userWords.d.ts.map +1 -1
- package/dist/spellcheck/userWords.js +4 -0
- package/dist/theme/editor.css +22 -0
- package/package.json +1 -1
package/dist/EditorRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAOjE,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIhF,OAAO,EAAgC,KAAK,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACtG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"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"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -32,6 +32,7 @@ import { AutoCorrectPlugin } from './autocorrect/AutoCorrectPlugin.js';
|
|
|
32
32
|
import { localStorageAutoCorrectStore } from './autocorrect/autoCorrectStores.js';
|
|
33
33
|
import { SpellcheckPanel } from './components/SpellcheckPanel.js';
|
|
34
34
|
import { SpellHighlightPlugin } from './spellcheck/SpellHighlightPlugin.js';
|
|
35
|
+
import { AutocompletePlugin } from './autocomplete/AutocompletePlugin.js';
|
|
35
36
|
import { loadUserWords, localStorageUserWordStore } from './spellcheck/userWords.js';
|
|
36
37
|
import { LeaveDialog } from './components/LeaveDialog.js';
|
|
37
38
|
import { clearDraft, createDraftId, hasDraftContent, pruneDrafts, writeDraft, } from './persistence/draftStorage.js';
|
|
@@ -79,6 +80,11 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorre
|
|
|
79
80
|
const lastSavedJsonRef = useRef(null);
|
|
80
81
|
const [isDirty, setIsDirty] = useState(false);
|
|
81
82
|
const [openPanel, setOpenPanel] = useState(null);
|
|
83
|
+
const [autoCorrectPrefill, setAutoCorrectPrefill] = useState(null);
|
|
84
|
+
const openAutoCorrectFor = (from, language) => {
|
|
85
|
+
setAutoCorrectPrefill({ id: Date.now(), from, language });
|
|
86
|
+
setOpenPanel('autocorrect');
|
|
87
|
+
};
|
|
82
88
|
const [autoCorrectVersion, setAutoCorrectVersion] = useState(0);
|
|
83
89
|
const stores = autoCorrectStores ?? DEFAULT_AUTOCORRECT_STORES;
|
|
84
90
|
const wordStores = dictionaryStores ?? DEFAULT_DICTIONARY_STORES;
|
|
@@ -298,9 +304,9 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorre
|
|
|
298
304
|
// rather than colliding on a shared one.
|
|
299
305
|
const portalTargetId = useId();
|
|
300
306
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
301
|
-
return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsxs(UiStringsContext.Provider, { value: strings, children: [_jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, dictionaryStores: wordStores, onSave: handleSave, findOpen: openPanel === 'find', onToggleFind: () => togglePanel('find'), spellOpen: openPanel === 'spell', onToggleSpell: () => togglePanel('spell'), autoCorrectOpen: openPanel === 'autocorrect', onToggleAutoCorrect: () => togglePanel('autocorrect'), isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
|
|
307
|
+
return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsxs(UiStringsContext.Provider, { value: strings, children: [_jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, dictionaryStores: wordStores, onAddAutoCorrect: config.language.autocorrect ? openAutoCorrectFor : undefined, onSave: handleSave, findOpen: openPanel === 'find', onToggleFind: () => togglePanel('find'), spellOpen: openPanel === 'spell', onToggleSpell: () => togglePanel('spell'), autoCorrectOpen: openPanel === 'autocorrect', onToggleAutoCorrect: () => togglePanel('autocorrect'), isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
|
|
302
308
|
? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
|
|
303
|
-
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && openPanel === 'find' && _jsx(FindReplaceBar, { strings: strings, dir: dir, onClose: () => setOpenPanel(null) }), config.language.spellCheck && openPanel === 'spell' && (_jsx(SpellcheckPanel, { strings: strings, dir: dir, dictionaryStores: wordStores, onClose: () => setOpenPanel(null) })), config.language.autocorrect && openPanel === 'autocorrect' && (_jsx(AutoCorrectPanel, { strings: strings, dir: dir, stores: stores, onSaved: () => setAutoCorrectVersion((v) => v + 1), onClose: () => setOpenPanel(null) })), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, spellCheck: false, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.language.spellCheck && _jsx(SpellHighlightPlugin, {}), (config.language.autocorrect || config.language.textCleanup) && _jsx(AutoCorrectPlugin, { stores: stores, version: autoCorrectVersion, enabled: true, typing: config.language.autocorrect, urduNormalization: urduNormalization, punctuation: punctuation }), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
309
|
+
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && openPanel === 'find' && _jsx(FindReplaceBar, { strings: strings, dir: dir, onClose: () => setOpenPanel(null) }), config.language.spellCheck && openPanel === 'spell' && (_jsx(SpellcheckPanel, { strings: strings, dir: dir, dictionaryStores: wordStores, onAddAutoCorrect: config.language.autocorrect ? openAutoCorrectFor : undefined, onClose: () => setOpenPanel(null) })), config.language.autocorrect && openPanel === 'autocorrect' && (_jsx(AutoCorrectPanel, { strings: strings, dir: dir, stores: stores, initialFrom: autoCorrectPrefill?.from, initialLanguage: autoCorrectPrefill?.language, onSaved: () => setAutoCorrectVersion((v) => v + 1), onClose: () => setOpenPanel(null) }, autoCorrectPrefill?.id ?? 0)), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, spellCheck: false, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.language.spellCheck && _jsx(SpellHighlightPlugin, {}), config.language.autocomplete && _jsx(AutocompletePlugin, { label: strings.autoComplete.label }), (config.language.autocorrect || config.language.textCleanup) && _jsx(AutoCorrectPlugin, { stores: stores, version: autoCorrectVersion, enabled: true, typing: config.language.autocorrect, urduNormalization: urduNormalization, punctuation: punctuation }), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
304
310
|
handleSave();
|
|
305
311
|
settleLeave(true);
|
|
306
312
|
}, onSaveDraft: () => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suggests completions for the word being typed, from the dictionary's words and
|
|
3
|
+
* the user's own. Shown only while typing, at the caret. Tab or Enter accepts the
|
|
4
|
+
* highlighted suggestion, the arrow keys move through the list, and Escape (or
|
|
5
|
+
* moving the caret) dismisses it. Left-to-right text uses the English dictionary,
|
|
6
|
+
* right-to-left text the Urdu one.
|
|
7
|
+
*/
|
|
8
|
+
export declare function AutocompletePlugin({ label }: {
|
|
9
|
+
label: string;
|
|
10
|
+
}): import("react").JSX.Element | null;
|
|
11
|
+
//# sourceMappingURL=AutocompletePlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutocompletePlugin.d.ts","sourceRoot":"","sources":["../../src/autocomplete/AutocompletePlugin.tsx"],"names":[],"mappings":"AAgCA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,sCA4J9D"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
+
import { $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_HIGH, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ENTER_COMMAND, KEY_TAB_COMMAND, } from 'lexical';
|
|
5
|
+
import { $replaceMatch } from '../find/findReplaceActions.js';
|
|
6
|
+
import { getDictionaryWords } from '../spellcheck/spellDictionaries.js';
|
|
7
|
+
import { acceptedWords, onSpellWordsChange } from '../spellcheck/userWords.js';
|
|
8
|
+
import { WordIndex } from './wordIndex.js';
|
|
9
|
+
/** The letters at the end of the text before the caret. */
|
|
10
|
+
const WORD_END = /[\p{L}\p{M}]+$/u;
|
|
11
|
+
const LETTER = /[\p{L}\p{M}]/u;
|
|
12
|
+
/** Suggestions only appear once the typed part of a word is this long. */
|
|
13
|
+
const MIN_PREFIX = 2;
|
|
14
|
+
/**
|
|
15
|
+
* Suggests completions for the word being typed, from the dictionary's words and
|
|
16
|
+
* the user's own. Shown only while typing, at the caret. Tab or Enter accepts the
|
|
17
|
+
* highlighted suggestion, the arrow keys move through the list, and Escape (or
|
|
18
|
+
* moving the caret) dismisses it. Left-to-right text uses the English dictionary,
|
|
19
|
+
* right-to-left text the Urdu one.
|
|
20
|
+
*/
|
|
21
|
+
export function AutocompletePlugin({ label }) {
|
|
22
|
+
const [editor] = useLexicalComposerContext();
|
|
23
|
+
const [popup, setPopup] = useState(null);
|
|
24
|
+
const popupRef = useRef(null);
|
|
25
|
+
const typing = useRef(false);
|
|
26
|
+
const indexes = useRef(new Map());
|
|
27
|
+
const show = (next) => {
|
|
28
|
+
popupRef.current = next;
|
|
29
|
+
setPopup(next);
|
|
30
|
+
};
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const indexFor = (language) => {
|
|
33
|
+
let index = indexes.current.get(language);
|
|
34
|
+
if (!index) {
|
|
35
|
+
const words = getDictionaryWords(language);
|
|
36
|
+
if (!words)
|
|
37
|
+
return null;
|
|
38
|
+
index = words.then((dictionary) => new WordIndex([...dictionary, ...acceptedWords(language)]));
|
|
39
|
+
indexes.current.set(language, index);
|
|
40
|
+
}
|
|
41
|
+
return index;
|
|
42
|
+
};
|
|
43
|
+
const hide = () => show(null);
|
|
44
|
+
const refresh = () => {
|
|
45
|
+
if (!typing.current)
|
|
46
|
+
return hide();
|
|
47
|
+
let target = null;
|
|
48
|
+
editor.getEditorState().read(() => {
|
|
49
|
+
const selection = $getSelection();
|
|
50
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed())
|
|
51
|
+
return;
|
|
52
|
+
const node = selection.anchor.getNode();
|
|
53
|
+
if (!$isTextNode(node))
|
|
54
|
+
return;
|
|
55
|
+
const text = node.getTextContent();
|
|
56
|
+
const before = text.slice(0, selection.anchor.offset);
|
|
57
|
+
const prefix = WORD_END.exec(before)?.[0];
|
|
58
|
+
const after = text.charAt(selection.anchor.offset);
|
|
59
|
+
if (!prefix || prefix.length < MIN_PREFIX || (after !== '' && LETTER.test(after)))
|
|
60
|
+
return;
|
|
61
|
+
const rtl = node.getParentOrThrow().getDirection() === 'rtl';
|
|
62
|
+
target = { prefix, language: rtl ? 'ur' : 'en', dir: rtl ? 'rtl' : 'ltr' };
|
|
63
|
+
});
|
|
64
|
+
if (target === null)
|
|
65
|
+
return hide();
|
|
66
|
+
const { prefix, language, dir } = target;
|
|
67
|
+
const index = indexFor(language);
|
|
68
|
+
if (!index)
|
|
69
|
+
return hide();
|
|
70
|
+
void index.then((loaded) => {
|
|
71
|
+
const items = loaded.complete(prefix);
|
|
72
|
+
if (items.length === 0)
|
|
73
|
+
return hide();
|
|
74
|
+
const rect = caretRect(editor);
|
|
75
|
+
show({ items, index: 0, x: rect.left, y: rect.bottom, dir });
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
const move = (delta) => {
|
|
79
|
+
const current = popupRef.current;
|
|
80
|
+
if (!current)
|
|
81
|
+
return false;
|
|
82
|
+
const count = current.items.length;
|
|
83
|
+
show({ ...current, index: (current.index + delta + count) % count });
|
|
84
|
+
return true;
|
|
85
|
+
};
|
|
86
|
+
const onKeyDown = (event) => {
|
|
87
|
+
if (event.key === 'Escape' && popupRef.current) {
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
show(null);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Printable keys and Backspace are typing; any other key (arrows, Home, ...) moves the caret.
|
|
93
|
+
typing.current = (event.key.length === 1 && !event.ctrlKey && !event.metaKey) || event.key === 'Backspace';
|
|
94
|
+
if (!typing.current)
|
|
95
|
+
hide();
|
|
96
|
+
setTimeout(refresh, 0);
|
|
97
|
+
};
|
|
98
|
+
const onMouseDown = () => {
|
|
99
|
+
typing.current = false;
|
|
100
|
+
hide();
|
|
101
|
+
};
|
|
102
|
+
let root = null;
|
|
103
|
+
const attach = (next) => {
|
|
104
|
+
root?.removeEventListener('keydown', onKeyDown);
|
|
105
|
+
root?.removeEventListener('mousedown', onMouseDown);
|
|
106
|
+
root = next;
|
|
107
|
+
root?.addEventListener('keydown', onKeyDown);
|
|
108
|
+
root?.addEventListener('mousedown', onMouseDown);
|
|
109
|
+
};
|
|
110
|
+
const unregisterRoot = editor.registerRootListener((next) => attach(next));
|
|
111
|
+
const unregisterUpdate = editor.registerUpdateListener(() => {
|
|
112
|
+
// Keydown already schedules a refresh; this keeps the list right after the
|
|
113
|
+
// dictionary or user words change.
|
|
114
|
+
if (typing.current)
|
|
115
|
+
setTimeout(refresh, 0);
|
|
116
|
+
});
|
|
117
|
+
const unregisterWords = onSpellWordsChange(() => {
|
|
118
|
+
indexes.current.clear();
|
|
119
|
+
if (typing.current)
|
|
120
|
+
setTimeout(refresh, 0);
|
|
121
|
+
});
|
|
122
|
+
const unregisterCommands = [
|
|
123
|
+
editor.registerCommand(KEY_ARROW_DOWN_COMMAND, () => move(1), COMMAND_PRIORITY_HIGH),
|
|
124
|
+
editor.registerCommand(KEY_ARROW_UP_COMMAND, () => move(-1), COMMAND_PRIORITY_HIGH),
|
|
125
|
+
editor.registerCommand(KEY_TAB_COMMAND, (event) => acceptHighlighted(event), COMMAND_PRIORITY_HIGH),
|
|
126
|
+
editor.registerCommand(KEY_ENTER_COMMAND, (event) => acceptHighlighted(event), COMMAND_PRIORITY_HIGH),
|
|
127
|
+
];
|
|
128
|
+
function acceptHighlighted(event) {
|
|
129
|
+
const current = popupRef.current;
|
|
130
|
+
if (!current)
|
|
131
|
+
return false;
|
|
132
|
+
event?.preventDefault();
|
|
133
|
+
acceptItem(editor, current.items[current.index]);
|
|
134
|
+
show(null);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
return () => {
|
|
138
|
+
unregisterRoot();
|
|
139
|
+
unregisterUpdate();
|
|
140
|
+
unregisterWords();
|
|
141
|
+
unregisterCommands.forEach((unregister) => unregister());
|
|
142
|
+
attach(null);
|
|
143
|
+
show(null);
|
|
144
|
+
};
|
|
145
|
+
}, [editor]);
|
|
146
|
+
if (!popup)
|
|
147
|
+
return null;
|
|
148
|
+
return (_jsx("div", { className: "likhari-autocomplete", role: "listbox", "aria-label": label, dir: popup.dir, style: { position: 'fixed', left: popup.x, top: popup.y + 4 }, children: popup.items.map((item, i) => (_jsx("div", { role: "option", "aria-selected": i === popup.index, className: i === popup.index ? 'likhari-autocomplete-item likhari-autocomplete-item--active' : 'likhari-autocomplete-item', onMouseDown: (event) => {
|
|
149
|
+
event.preventDefault();
|
|
150
|
+
acceptItem(editor, item);
|
|
151
|
+
}, children: item }, item))) }));
|
|
152
|
+
}
|
|
153
|
+
/** Where to put the popup: under the caret, or the editor's top-left if the caret has no position yet. */
|
|
154
|
+
function caretRect(editor) {
|
|
155
|
+
const selection = window.getSelection();
|
|
156
|
+
if (selection && selection.rangeCount > 0) {
|
|
157
|
+
const rect = selection.getRangeAt(0).getBoundingClientRect();
|
|
158
|
+
if (rect.width > 0 || rect.height > 0)
|
|
159
|
+
return { left: rect.left, bottom: rect.bottom };
|
|
160
|
+
}
|
|
161
|
+
const root = editor.getRootElement()?.getBoundingClientRect();
|
|
162
|
+
return { left: root?.left ?? 0, bottom: root?.top ?? 0 };
|
|
163
|
+
}
|
|
164
|
+
function acceptItem(editor, item) {
|
|
165
|
+
editor.update(() => {
|
|
166
|
+
const selection = $getSelection();
|
|
167
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed())
|
|
168
|
+
return;
|
|
169
|
+
const node = selection.anchor.getNode();
|
|
170
|
+
if (!$isTextNode(node))
|
|
171
|
+
return;
|
|
172
|
+
const before = node.getTextContent().slice(0, selection.anchor.offset);
|
|
173
|
+
const prefix = WORD_END.exec(before)?.[0];
|
|
174
|
+
if (!prefix)
|
|
175
|
+
return;
|
|
176
|
+
const start = before.length - prefix.length;
|
|
177
|
+
$replaceMatch({ anchorKey: node.getKey(), anchorOffset: start, focusKey: node.getKey(), focusOffset: before.length }, item);
|
|
178
|
+
}, { discrete: true });
|
|
179
|
+
editor.focus();
|
|
180
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Words sorted once, so every prefix lookup is a binary search rather than a scan. */
|
|
2
|
+
export declare class WordIndex {
|
|
3
|
+
private readonly words;
|
|
4
|
+
constructor(words: Iterable<string>);
|
|
5
|
+
/**
|
|
6
|
+
* Completions for a prefix: words that start with it (other than the prefix
|
|
7
|
+
* itself), shortest first, then alphabetical. Only the first `scanLimit`
|
|
8
|
+
* matches are considered, so a one-letter prefix stays quick.
|
|
9
|
+
*/
|
|
10
|
+
complete(prefix: string, limit?: number, scanLimit?: number): string[];
|
|
11
|
+
private lowerBound;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=wordIndex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wordIndex.d.ts","sourceRoot":"","sources":["../../src/autocomplete/wordIndex.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;gBAErB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;IAInC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAI,EAAE,SAAS,SAAM,GAAG,MAAM,EAAE;IAY9D,OAAO,CAAC,UAAU;CAUnB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Words sorted once, so every prefix lookup is a binary search rather than a scan. */
|
|
2
|
+
export class WordIndex {
|
|
3
|
+
constructor(words) {
|
|
4
|
+
this.words = [...new Set(words)].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Completions for a prefix: words that start with it (other than the prefix
|
|
8
|
+
* itself), shortest first, then alphabetical. Only the first `scanLimit`
|
|
9
|
+
* matches are considered, so a one-letter prefix stays quick.
|
|
10
|
+
*/
|
|
11
|
+
complete(prefix, limit = 5, scanLimit = 500) {
|
|
12
|
+
if (prefix === '')
|
|
13
|
+
return [];
|
|
14
|
+
const matches = [];
|
|
15
|
+
for (let i = this.lowerBound(prefix); i < this.words.length && matches.length < scanLimit; i++) {
|
|
16
|
+
const word = this.words[i];
|
|
17
|
+
if (!word.startsWith(prefix))
|
|
18
|
+
break;
|
|
19
|
+
if (word !== prefix)
|
|
20
|
+
matches.push(word);
|
|
21
|
+
}
|
|
22
|
+
matches.sort((a, b) => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0));
|
|
23
|
+
return matches.slice(0, limit);
|
|
24
|
+
}
|
|
25
|
+
lowerBound(prefix) {
|
|
26
|
+
let low = 0;
|
|
27
|
+
let high = this.words.length;
|
|
28
|
+
while (low < high) {
|
|
29
|
+
const mid = (low + high) >>> 1;
|
|
30
|
+
if (this.words[mid] < prefix)
|
|
31
|
+
low = mid + 1;
|
|
32
|
+
else
|
|
33
|
+
high = mid;
|
|
34
|
+
}
|
|
35
|
+
return low;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoCorrectPlugin.d.ts","sourceRoot":"","sources":["../../src/autocorrect/AutoCorrectPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"AutoCorrectPlugin.d.ts","sourceRoot":"","sources":["../../src/autocorrect/AutoCorrectPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAQL,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAWjB,OAAO,EAA0B,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAiB,KAAK,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAG9F,sFAAsF;AACtF,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,IAAI,CAA6C,CAAC;AAMxG;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,OAAO,EACP,OAAO,EACP,MAAM,EACN,iBAAiB,EACjB,WAAW,GACZ,EAAE;IACD,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,MAAM,EAAE,OAAO,CAAC;IAChB,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;IAC7C,kEAAkE;IAClE,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,QA0GA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
-
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
|
|
4
|
-
import { $correctDocument, $correctPunctuationBeforeCaret, $correctPunctuationDocument, $correctWordBeforeCaret, $preservingSelection, $spacePunctuationDocument, } from './autoCorrectActions.js';
|
|
3
|
+
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, BLUR_COMMAND, COMMAND_PRIORITY_HIGH, KEY_ENTER_COMMAND, createCommand, } from 'lexical';
|
|
4
|
+
import { $correctDocument, $correctPunctuationBeforeCaret, $correctPunctuationDocument, $correctWordBeforeCaret, $correctWordEndingAtCaret, $preservingSelection, $spacePunctuationDocument, } from './autoCorrectActions.js';
|
|
5
5
|
import { $cleanUpText } from '../cleanup/textCleanupActions.js';
|
|
6
6
|
import { activePunctuationRules } from './punctuationRules.js';
|
|
7
7
|
import { loadAutoCorrections } from './autoCorrectStores.js';
|
|
@@ -99,8 +99,24 @@ export function AutoCorrectPlugin({ stores, version, enabled, typing, urduNormal
|
|
|
99
99
|
root?.addEventListener('keydown', onKeyDown);
|
|
100
100
|
};
|
|
101
101
|
const unregister = editor.registerRootListener((next) => attach(next));
|
|
102
|
+
// A word with nothing after it (end of line or document) is corrected when the
|
|
103
|
+
// caret leaves it: Enter splits the line, and blur means the user has moved on.
|
|
104
|
+
const correctEndingWord = () => {
|
|
105
|
+
const selection = $getSelection();
|
|
106
|
+
if (!$isRangeSelection(selection))
|
|
107
|
+
return false;
|
|
108
|
+
const rtl = selection.anchor.getNode().getTopLevelElement()?.getDirection() === 'rtl';
|
|
109
|
+
const table = tableFor(rtl);
|
|
110
|
+
if (table)
|
|
111
|
+
$correctWordEndingAtCaret(table, rtl ? normalizeRtl : undefined);
|
|
112
|
+
return false;
|
|
113
|
+
};
|
|
114
|
+
const unregisterEnter = editor.registerCommand(KEY_ENTER_COMMAND, correctEndingWord, COMMAND_PRIORITY_HIGH);
|
|
115
|
+
const unregisterBlur = editor.registerCommand(BLUR_COMMAND, correctEndingWord, COMMAND_PRIORITY_EDITOR);
|
|
102
116
|
return () => {
|
|
103
117
|
unregister();
|
|
118
|
+
unregisterEnter();
|
|
119
|
+
unregisterBlur();
|
|
104
120
|
attach(null);
|
|
105
121
|
};
|
|
106
122
|
}, [editor, enabled, typing]);
|
|
@@ -32,4 +32,10 @@ export declare function $correctPunctuationDocument(rules: PunctuationRule[]): n
|
|
|
32
32
|
export declare function $preservingSelection(change: () => void): void;
|
|
33
33
|
/** Applies urduhack-style punctuation spacing to every text node. Returns how many changed. */
|
|
34
34
|
export declare function $spacePunctuationDocument(): number;
|
|
35
|
+
/**
|
|
36
|
+
* Corrects the word that ends at the caret when nothing follows it, which is the
|
|
37
|
+
* end of a line: the caret is about to leave the line (Enter). The caret ends
|
|
38
|
+
* after the replacement.
|
|
39
|
+
*/
|
|
40
|
+
export declare function $correctWordEndingAtCaret(table: Map<string, string>, normalize?: (word: string) => string): boolean;
|
|
35
41
|
//# sourceMappingURL=autoCorrectActions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoCorrectActions.d.ts","sourceRoot":"","sources":["../../src/autocorrect/autoCorrectActions.ts"],"names":[],"mappings":"AAWA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAMhF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAiCjH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACtC,MAAM,CA8BR;AAQD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAqBhF;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,MAAM,CA2B5E;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAoB7D;AAED,+FAA+F;AAC/F,wBAAgB,yBAAyB,IAAI,MAAM,CAWlD"}
|
|
1
|
+
{"version":3,"file":"autoCorrectActions.d.ts","sourceRoot":"","sources":["../../src/autocorrect/autoCorrectActions.ts"],"names":[],"mappings":"AAWA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAMhF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAiCjH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACtC,MAAM,CA8BR;AAQD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAqBhF;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,MAAM,CA2B5E;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAoB7D;AAED,+FAA+F;AAC/F,wBAAgB,yBAAyB,IAAI,MAAM,CAWlD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAuBnH"}
|
|
@@ -180,3 +180,33 @@ export function $spacePunctuationDocument() {
|
|
|
180
180
|
}
|
|
181
181
|
return changed;
|
|
182
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Corrects the word that ends at the caret when nothing follows it, which is the
|
|
185
|
+
* end of a line: the caret is about to leave the line (Enter). The caret ends
|
|
186
|
+
* after the replacement.
|
|
187
|
+
*/
|
|
188
|
+
export function $correctWordEndingAtCaret(table, normalize) {
|
|
189
|
+
const selection = $getSelection();
|
|
190
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed())
|
|
191
|
+
return false;
|
|
192
|
+
const anchor = selection.anchor;
|
|
193
|
+
const node = anchor.getNode();
|
|
194
|
+
if (!$isTextNode(node))
|
|
195
|
+
return false;
|
|
196
|
+
const before = node.getTextContent().slice(0, anchor.offset);
|
|
197
|
+
const word = WORD_END.exec(before)?.[0];
|
|
198
|
+
if (!word)
|
|
199
|
+
return false;
|
|
200
|
+
const replacement = correctionFor(word, table, normalize);
|
|
201
|
+
if (replacement === undefined || replacement === word)
|
|
202
|
+
return false;
|
|
203
|
+
const start = before.length - word.length;
|
|
204
|
+
$replaceMatch({ anchorKey: node.getKey(), anchorOffset: start, focusKey: node.getKey(), focusOffset: before.length }, replacement);
|
|
205
|
+
const after = $getSelection();
|
|
206
|
+
if ($isRangeSelection(after)) {
|
|
207
|
+
const caret = start + replacement.length;
|
|
208
|
+
after.anchor.set(node.getKey(), caret, 'text');
|
|
209
|
+
after.focus.set(node.getKey(), caret, 'text');
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { Strings } from '../i18n/strings.js';
|
|
2
2
|
import { type AutoCorrectStore } from '../autocorrect/autoCorrectStores.js';
|
|
3
|
+
import type { SpellLanguage } from '../spellcheck/spellDictionaries.js';
|
|
3
4
|
/**
|
|
4
5
|
* Adds one correction (a typed word and its replacement) to the first store
|
|
5
6
|
* that accepts writes. Saving bumps the editor's correction version, so the new
|
|
6
7
|
* entry applies to the next word the user types.
|
|
7
8
|
*/
|
|
8
|
-
export declare function AutoCorrectPanel({ strings, dir, stores, onSaved, onClose, }: {
|
|
9
|
+
export declare function AutoCorrectPanel({ strings, dir, stores, initialFrom, initialLanguage, onSaved, onClose, }: {
|
|
9
10
|
strings: Strings;
|
|
10
11
|
dir: 'ltr' | 'rtl';
|
|
11
12
|
stores: AutoCorrectStore[];
|
|
13
|
+
/** The typed word to start with, e.g. a misspelled word the user chose to correct. */
|
|
14
|
+
initialFrom?: string;
|
|
15
|
+
initialLanguage?: SpellLanguage;
|
|
12
16
|
onSaved: () => void;
|
|
13
17
|
onClose: () => void;
|
|
14
18
|
}): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoCorrectPanel.d.ts","sourceRoot":"","sources":["../../src/components/AutoCorrectPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"AutoCorrectPanel.d.ts","sourceRoot":"","sources":["../../src/components/AutoCorrectPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAQrE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,GAAG,EACH,MAAM,EACN,WAAgB,EAChB,eAAsB,EACtB,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC;IACnB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,aAAa,CAAC;IAChC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,+BAqEA"}
|
|
@@ -12,10 +12,10 @@ const LANGUAGES = [
|
|
|
12
12
|
* that accepts writes. Saving bumps the editor's correction version, so the new
|
|
13
13
|
* entry applies to the next word the user types.
|
|
14
14
|
*/
|
|
15
|
-
export function AutoCorrectPanel({ strings, dir, stores, onSaved, onClose, }) {
|
|
15
|
+
export function AutoCorrectPanel({ strings, dir, stores, initialFrom = '', initialLanguage = 'en', onSaved, onClose, }) {
|
|
16
16
|
const t = strings.autoCorrect;
|
|
17
|
-
const [language, setLanguage] = useState(
|
|
18
|
-
const [from, setFrom] = useState(
|
|
17
|
+
const [language, setLanguage] = useState(initialLanguage);
|
|
18
|
+
const [from, setFrom] = useState(initialFrom);
|
|
19
19
|
const [to, setTo] = useState('');
|
|
20
20
|
const [status, setStatus] = useState('idle');
|
|
21
21
|
const save = async () => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Strings } from '../i18n/strings.js';
|
|
2
|
+
import { type SpellLanguage } from '../spellcheck/spellDictionaries.js';
|
|
2
3
|
import { type UserWordStore } from '../spellcheck/userWords.js';
|
|
3
4
|
/**
|
|
4
5
|
* Steps through the misspelled words one at a time, like the find widget.
|
|
@@ -6,10 +7,11 @@ import { type UserWordStore } from '../spellcheck/userWords.js';
|
|
|
6
7
|
* can replace it. Checking reads the document on demand, so it never flags
|
|
7
8
|
* words while the user is still typing.
|
|
8
9
|
*/
|
|
9
|
-
export declare function SpellcheckPanel({ strings, dir, dictionaryStores, onClose, }: {
|
|
10
|
+
export declare function SpellcheckPanel({ strings, dir, dictionaryStores, onAddAutoCorrect, onClose, }: {
|
|
10
11
|
strings: Strings;
|
|
11
12
|
dir: 'ltr' | 'rtl';
|
|
12
13
|
dictionaryStores: UserWordStore[];
|
|
14
|
+
onAddAutoCorrect?: (word: string, language: SpellLanguage) => void;
|
|
13
15
|
onClose: () => void;
|
|
14
16
|
}): import("react").JSX.Element;
|
|
15
17
|
//# sourceMappingURL=SpellcheckPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpellcheckPanel.d.ts","sourceRoot":"","sources":["../../src/components/SpellcheckPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"SpellcheckPanel.d.ts","sourceRoot":"","sources":["../../src/components/SpellcheckPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAkC,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrG,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAgBtF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,GAAG,EACH,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC;IACnB,gBAAgB,EAAE,aAAa,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,+BAqKA"}
|
|
@@ -18,7 +18,7 @@ const SUGGESTIONS_PER_WORD = 3;
|
|
|
18
18
|
* can replace it. Checking reads the document on demand, so it never flags
|
|
19
19
|
* words while the user is still typing.
|
|
20
20
|
*/
|
|
21
|
-
export function SpellcheckPanel({ strings, dir, dictionaryStores, onClose, }) {
|
|
21
|
+
export function SpellcheckPanel({ strings, dir, dictionaryStores, onAddAutoCorrect, onClose, }) {
|
|
22
22
|
const [editor] = useLexicalComposerContext();
|
|
23
23
|
const t = strings.spellcheck;
|
|
24
24
|
const [language, setLanguage] = useState('en');
|
|
@@ -87,5 +87,5 @@ export function SpellcheckPanel({ strings, dir, dictionaryStores, onClose, }) {
|
|
|
87
87
|
ignoreWord(language, current.word);
|
|
88
88
|
void check();
|
|
89
89
|
});
|
|
90
|
-
}, children: strings.contextMenu.addToDictionary })] }), current.suggestions.length === 0 ? (_jsx("span", { className: "likhari-spell-note", children: t.noSuggestions })) : (_jsx("div", { className: "likhari-spell-suggestions", children: current.suggestions.map((s) => (_jsx("button", { type: "button", className: "likhari-spell-suggestion", onClick: () => replace(current, s), children: s }, s))) }))] }))] }));
|
|
90
|
+
}, children: strings.contextMenu.addToDictionary }), onAddAutoCorrect && (_jsx("button", { type: "button", className: "likhari-spell-suggestion", onClick: () => onAddAutoCorrect(current.word, language), children: strings.contextMenu.addToAutoCorrect }))] }), current.suggestions.length === 0 ? (_jsx("span", { className: "likhari-spell-note", children: t.noSuggestions })) : (_jsx("div", { className: "likhari-spell-suggestions", children: current.suggestions.map((s) => (_jsx("button", { type: "button", className: "likhari-spell-suggestion", onClick: () => replace(current, s), children: s }, s))) }))] }))] }));
|
|
91
91
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SpellLanguage } from '../spellcheck/spellDictionaries.js';
|
|
1
2
|
import { type UserWordStore } from '../spellcheck/userWords.js';
|
|
2
3
|
import { type DraftsToolbarOptions } from './DraftsDialog.js';
|
|
3
4
|
import type { ResolvedEditorFeatureConfig } from '@inshapardaz/likhari-core';
|
|
@@ -7,6 +8,8 @@ export interface ToolbarProps {
|
|
|
7
8
|
config: ResolvedEditorFeatureConfig;
|
|
8
9
|
/** Where words added to the dictionary are saved. */
|
|
9
10
|
dictionaryStores?: UserWordStore[];
|
|
11
|
+
/** Opens the auto-correct panel with the word filled in. */
|
|
12
|
+
onAddAutoCorrect?: (word: string, language: SpellLanguage) => void;
|
|
10
13
|
/** Whether the find-and-replace widget is open, and how to toggle it (owned by EditorRoot). */
|
|
11
14
|
findOpen?: boolean;
|
|
12
15
|
onToggleFind?: () => void;
|
|
@@ -28,5 +31,5 @@ export interface ToolbarProps {
|
|
|
28
31
|
/** Autosave drafts: when set, the toolbar offers a Drafts button that lists and restores them. */
|
|
29
32
|
drafts?: DraftsToolbarOptions;
|
|
30
33
|
}
|
|
31
|
-
export declare function Toolbar({ config, dictionaryStores, onSave, isDirty, showSave, findOpen, onToggleFind, spellOpen, onToggleSpell, autoCorrectOpen, onToggleAutoCorrect, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
|
|
34
|
+
export declare function Toolbar({ config, dictionaryStores, onAddAutoCorrect, onSave, isDirty, showSave, findOpen, onToggleFind, spellOpen, onToggleSpell, autoCorrectOpen, onToggleAutoCorrect, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
|
|
32
35
|
//# sourceMappingURL=Toolbar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA0CA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAgDtF,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAA6D,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAItG,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AA6hBvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC;IACnC,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,iGAAiG;IACjG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,gBAAqB,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,eAAuB,EAAE,mBAAmB,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAqnCjT"}
|
|
@@ -185,7 +185,7 @@ function PoetryMenuItems({ strings, layout, scale, centered, onAction, }) {
|
|
|
185
185
|
};
|
|
186
186
|
return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), item(IconArrowsShuffle, t.staggered, setLayout('staggered'), layout === 'staggered'), _jsx(Menu.Divider, {}), _jsx(Menu.Divider, {}), item(IconRowInsertTop, t.insertCoupletBefore, () => $insertCoupletRelativeToSelection('before')), item(IconRowInsertBottom, t.insertCoupletAfter, () => $insertCoupletRelativeToSelection('after')), item(IconArrowsMinimize, t.tighterSpacing, () => $adjustPoetrySpacing(-1), !canStep(POETRY_SPACINGS, scale.spacing, -1)), item(IconArrowsMaximize, t.looserSpacing, () => $adjustPoetrySpacing(1), !canStep(POETRY_SPACINGS, scale.spacing, 1)), layout === 'staggered' && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCouplets, () => $adjustPoetryStagger(-1), !canStep(POETRY_STAGGERS, scale.stagger, -1)), item(IconArrowsMaximize, t.widerCouplets, () => $adjustPoetryStagger(1), !canStep(POETRY_STAGGERS, scale.stagger, 1))] })), layout === 'two-column' && (_jsxs(_Fragment, { children: [item(IconAlignCenter, centered ? t.uncenterCouplet : t.centerCouplet, () => $setCoupletCentered(!centered)), item(IconColumns2, t.narrowerGutter, () => $adjustPoetryGutter(-1), !canStep(POETRY_GUTTERS, scale.gutter, -1)), item(IconColumns2, t.widerGutter, () => $adjustPoetryGutter(1), !canStep(POETRY_GUTTERS, scale.gutter, 1))] })), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red'), item(IconTrash, t.deletePoetry, $deletePoetryBlock, false, 'red')] }));
|
|
187
187
|
}
|
|
188
|
-
export function Toolbar({ config, dictionaryStores = [], onSave, isDirty, showSave, findOpen = false, onToggleFind, spellOpen = false, onToggleSpell, autoCorrectOpen = false, onToggleAutoCorrect, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
188
|
+
export function Toolbar({ config, dictionaryStores = [], onAddAutoCorrect, onSave, isDirty, showSave, findOpen = false, onToggleFind, spellOpen = false, onToggleSpell, autoCorrectOpen = false, onToggleAutoCorrect, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
189
189
|
const [editor] = useLexicalComposerContext();
|
|
190
190
|
const [state, setState] = useState(INITIAL_STATE);
|
|
191
191
|
const strings = useStrings(locale);
|
|
@@ -842,7 +842,10 @@ export function Toolbar({ config, dictionaryStores = [], onSave, isDirty, showSa
|
|
|
842
842
|
ignoreWord(language, word);
|
|
843
843
|
});
|
|
844
844
|
setContextMenu(null);
|
|
845
|
-
}, children: strings.contextMenu.addToDictionary }),
|
|
845
|
+
}, children: strings.contextMenu.addToDictionary }), onAddAutoCorrect && config.language.autocorrect && (_jsx(Menu.Item, { onClick: () => {
|
|
846
|
+
onAddAutoCorrect(contextMenu.spelling.word, contextMenu.spelling.language);
|
|
847
|
+
setContextMenu(null);
|
|
848
|
+
}, children: strings.contextMenu.addToAutoCorrect })), _jsx(Menu.Divider, {})] })), contextMenu?.link !== undefined && (_jsxs(_Fragment, { children: [_jsx(LinkMenuItems, { url: contextMenu.link, onEdit: () => {
|
|
846
849
|
restoreSelection();
|
|
847
850
|
openLinkDialog();
|
|
848
851
|
}, onRemove: removeLink, strings: strings }), _jsx(Menu.Divider, {})] })), contextMenu?.table && (_jsxs(_Fragment, { children: [_jsx(TableMenuItems, { strings: strings, direction: direction, rows: contextMenu.table.rows, columns: contextMenu.table.columns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }), _jsx(Menu.Divider, {})] })), contextMenu?.poetry && (_jsxs(_Fragment, { children: [_jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }), _jsx(Menu.Divider, {})] })), _jsx(Menu.Item, { leftSection: _jsx(IconCut, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void copyOrCut(true)(), children: strings.contextMenu.cut }), _jsx(Menu.Item, { leftSection: _jsx(IconCopy, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void copyOrCut(false)(), children: strings.contextMenu.copy }), _jsx(Menu.Item, { leftSection: _jsx(IconClipboard, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void paste(), children: strings.contextMenu.paste }), _jsx(Menu.Item, { leftSection: _jsx(IconSelectAll, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: runMenuAction(() => $selectAll()), children: strings.contextMenu.selectAll })] })] }), _jsxs("div", { "aria-hidden": "true", ref: toolbarMeasureRef, style: {
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -200,9 +200,13 @@ export interface Strings {
|
|
|
200
200
|
selectAll: string;
|
|
201
201
|
ignore: string;
|
|
202
202
|
addToDictionary: string;
|
|
203
|
+
addToAutoCorrect: string;
|
|
203
204
|
spelling: string;
|
|
204
205
|
noSuggestions: string;
|
|
205
206
|
};
|
|
207
|
+
autoComplete: {
|
|
208
|
+
label: string;
|
|
209
|
+
};
|
|
206
210
|
link: {
|
|
207
211
|
menuLabel: string;
|
|
208
212
|
noUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n/strings.js
CHANGED
|
@@ -183,9 +183,13 @@ const en = {
|
|
|
183
183
|
selectAll: 'Select all',
|
|
184
184
|
ignore: 'Ignore',
|
|
185
185
|
addToDictionary: 'Add to dictionary',
|
|
186
|
+
addToAutoCorrect: 'Add to auto-correct',
|
|
186
187
|
spelling: 'Spelling suggestions',
|
|
187
188
|
noSuggestions: 'No suggestions',
|
|
188
189
|
},
|
|
190
|
+
autoComplete: {
|
|
191
|
+
label: 'Suggestions',
|
|
192
|
+
},
|
|
189
193
|
link: {
|
|
190
194
|
menuLabel: 'Link',
|
|
191
195
|
noUrl: '(no URL)',
|
|
@@ -450,9 +454,13 @@ const ur = {
|
|
|
450
454
|
selectAll: 'سب منتخب کریں',
|
|
451
455
|
ignore: 'نظرانداز کریں',
|
|
452
456
|
addToDictionary: 'لغت میں شامل کریں',
|
|
457
|
+
addToAutoCorrect: 'خودکار تصحیح میں شامل کریں',
|
|
453
458
|
spelling: 'ہجے کی تجاویز',
|
|
454
459
|
noSuggestions: 'کوئی تجویز نہیں',
|
|
455
460
|
},
|
|
461
|
+
autoComplete: {
|
|
462
|
+
label: 'تجاویز',
|
|
463
|
+
},
|
|
456
464
|
link: {
|
|
457
465
|
menuLabel: 'لنک',
|
|
458
466
|
noUrl: '(کوئی یو آر ایل نہیں)',
|
|
@@ -717,9 +725,13 @@ const paShahmukhi = {
|
|
|
717
725
|
selectAll: 'سارا چنو',
|
|
718
726
|
ignore: 'نظر انداز کرو',
|
|
719
727
|
addToDictionary: 'شبدکوش وچ پاؤ',
|
|
728
|
+
addToAutoCorrect: 'خودکار درستی وچ پاؤ',
|
|
720
729
|
spelling: 'ہجے دیاں تجویزاں',
|
|
721
730
|
noSuggestions: 'کوئی تجویز نئیں',
|
|
722
731
|
},
|
|
732
|
+
autoComplete: {
|
|
733
|
+
label: 'تجویزاں',
|
|
734
|
+
},
|
|
723
735
|
link: {
|
|
724
736
|
menuLabel: 'لنک',
|
|
725
737
|
noUrl: '(کوئی یو آر ایل نئیں)',
|
|
@@ -27,6 +27,10 @@ export declare function hasSpellDictionary(language: SpellLanguage): boolean;
|
|
|
27
27
|
* can skip spellchecking that language rather than flag every word.
|
|
28
28
|
*/
|
|
29
29
|
export declare function getSpeller(language: SpellLanguage): Promise<Speller> | null;
|
|
30
|
+
/** The dictionary's root words (its .dic entries without affix flags), for completion. */
|
|
31
|
+
export declare function dictionaryWords(dic: string): string[];
|
|
32
|
+
/** The language's dictionary words, or null when no dictionary is registered. */
|
|
33
|
+
export declare function getDictionaryWords(language: SpellLanguage): Promise<string[]> | null;
|
|
30
34
|
/** A word in a text, with its position as character offsets. */
|
|
31
35
|
export interface WordSpan {
|
|
32
36
|
word: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spellDictionaries.d.ts","sourceRoot":"","sources":["../../src/spellcheck/spellDictionaries.ts"],"names":[],"mappings":"AAGA,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,cAAc,CAAC;AAEzD,wFAAwF;AACxF,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACjC;AAED,KAAK,MAAM,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"spellDictionaries.d.ts","sourceRoot":"","sources":["../../src/spellcheck/spellDictionaries.ts"],"names":[],"mappings":"AAGA,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,cAAc,CAAC;AAEzD,wFAAwF;AACxF,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACjC;AAED,KAAK,MAAM,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;AAoB3C;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAIpG;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAc3E;AAYD,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAOrD;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAGpF;AAED,gEAAgE;AAChE,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AASD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAMhD;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,EAAE,CAEzE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import nspell from 'nspell';
|
|
2
2
|
import { isAcceptedWord } from './userWords.js';
|
|
3
3
|
const loaders = new Map();
|
|
4
|
+
const loadedFiles = new Map();
|
|
4
5
|
const spellers = new Map();
|
|
5
6
|
async function fetchText(url) {
|
|
6
7
|
const response = await fetch(url);
|
|
@@ -23,6 +24,7 @@ loaders.set('en', englishLoader);
|
|
|
23
24
|
export function registerSpellDictionary(language, files) {
|
|
24
25
|
loaders.set(language, typeof files === 'function' ? files : async () => files);
|
|
25
26
|
spellers.delete(language);
|
|
27
|
+
loadedFiles.delete(language);
|
|
26
28
|
}
|
|
27
29
|
/** Whether a dictionary is registered for the language. */
|
|
28
30
|
export function hasSpellDictionary(language) {
|
|
@@ -34,12 +36,11 @@ export function hasSpellDictionary(language) {
|
|
|
34
36
|
* can skip spellchecking that language rather than flag every word.
|
|
35
37
|
*/
|
|
36
38
|
export function getSpeller(language) {
|
|
37
|
-
|
|
38
|
-
if (!loader)
|
|
39
|
+
if (!loaders.has(language))
|
|
39
40
|
return null;
|
|
40
41
|
let speller = spellers.get(language);
|
|
41
42
|
if (!speller) {
|
|
42
|
-
speller =
|
|
43
|
+
speller = filesFor(language)
|
|
43
44
|
.then(({ aff, dic }) => nspell(aff, dic))
|
|
44
45
|
.then((base) => ({
|
|
45
46
|
// Words the user added or ignored count as correct, whatever the dictionary says.
|
|
@@ -50,6 +51,31 @@ export function getSpeller(language) {
|
|
|
50
51
|
}
|
|
51
52
|
return speller;
|
|
52
53
|
}
|
|
54
|
+
/** The dictionary's files, loaded once per language and shared by the speller and the word list. */
|
|
55
|
+
function filesFor(language) {
|
|
56
|
+
let loaded = loadedFiles.get(language);
|
|
57
|
+
if (!loaded) {
|
|
58
|
+
loaded = loaders.get(language)();
|
|
59
|
+
loadedFiles.set(language, loaded);
|
|
60
|
+
}
|
|
61
|
+
return loaded;
|
|
62
|
+
}
|
|
63
|
+
/** The dictionary's root words (its .dic entries without affix flags), for completion. */
|
|
64
|
+
export function dictionaryWords(dic) {
|
|
65
|
+
const words = new Set();
|
|
66
|
+
for (const line of dic.split(/\r?\n/).slice(1)) {
|
|
67
|
+
const word = line.split('/')[0].trim();
|
|
68
|
+
if (word)
|
|
69
|
+
words.add(word);
|
|
70
|
+
}
|
|
71
|
+
return [...words];
|
|
72
|
+
}
|
|
73
|
+
/** The language's dictionary words, or null when no dictionary is registered. */
|
|
74
|
+
export function getDictionaryWords(language) {
|
|
75
|
+
if (!loaders.has(language))
|
|
76
|
+
return null;
|
|
77
|
+
return filesFor(language).then(({ dic }) => dictionaryWords(dic));
|
|
78
|
+
}
|
|
53
79
|
/**
|
|
54
80
|
* Letters and combining marks, with apostrophes inside a word kept. The
|
|
55
81
|
* Unicode classes cover Arabic-script letters and their diacritics, so Urdu
|
|
@@ -24,6 +24,8 @@ export declare function apiUserWordStore(options: {
|
|
|
24
24
|
headers?: Record<string, string>;
|
|
25
25
|
fetch?: typeof fetch;
|
|
26
26
|
}): UserWordStore;
|
|
27
|
+
/** The words the user has added to the dictionary for a language. */
|
|
28
|
+
export declare function acceptedWords(language: SpellLanguage): string[];
|
|
27
29
|
/** Calls `listener` whenever accepted or ignored words change. Returns an unsubscribe function. */
|
|
28
30
|
export declare function onSpellWordsChange(listener: () => void): () => void;
|
|
29
31
|
/** Whether the speller should treat the word as correct: it is in the user's dictionary or ignored this session. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userWords.d.ts","sourceRoot":"","sources":["../../src/spellcheck/userWords.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAoBD,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,aAAa,CAoBvF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,GAAG,aAAa,CAmBhB;AAWD,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGnE;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED,2EAA2E;AAC3E,wBAAsB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ1E;AAED,sFAAsF;AACtF,wBAAsB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOlH;AAWD,+DAA+D;AAC/D,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAUtE"}
|
|
1
|
+
{"version":3,"file":"userWords.d.ts","sourceRoot":"","sources":["../../src/spellcheck/userWords.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAoBD,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,aAAa,CAoBvF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,GAAG,aAAa,CAmBhB;AAWD,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CAE/D;AAED,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGnE;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED,2EAA2E;AAC3E,wBAAsB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ1E;AAED,sFAAsF;AACtF,wBAAsB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOlH;AAWD,+DAA+D;AAC/D,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAUtE"}
|
|
@@ -68,6 +68,10 @@ function notify() {
|
|
|
68
68
|
for (const listener of listeners)
|
|
69
69
|
listener();
|
|
70
70
|
}
|
|
71
|
+
/** The words the user has added to the dictionary for a language. */
|
|
72
|
+
export function acceptedWords(language) {
|
|
73
|
+
return [...(accepted.get(language) ?? [])];
|
|
74
|
+
}
|
|
71
75
|
/** Calls `listener` whenever accepted or ignored words change. Returns an unsubscribe function. */
|
|
72
76
|
export function onSpellWordsChange(listener) {
|
|
73
77
|
listeners.add(listener);
|
package/dist/theme/editor.css
CHANGED
|
@@ -1055,3 +1055,25 @@
|
|
|
1055
1055
|
cursor: default;
|
|
1056
1056
|
}
|
|
1057
1057
|
|
|
1058
|
+
/* Autocomplete suggestions, shown under the caret while typing. */
|
|
1059
|
+
.likhari-autocomplete {
|
|
1060
|
+
z-index: 20;
|
|
1061
|
+
min-width: 160px;
|
|
1062
|
+
max-width: 280px;
|
|
1063
|
+
padding: 4px 0;
|
|
1064
|
+
border: 1px solid var(--editor-line);
|
|
1065
|
+
border-radius: 6px;
|
|
1066
|
+
background: var(--editor-paper-dim);
|
|
1067
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.16);
|
|
1068
|
+
font-size: 14px;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
.likhari-autocomplete-item {
|
|
1072
|
+
padding: 3px 10px;
|
|
1073
|
+
cursor: pointer;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
.likhari-autocomplete-item--active {
|
|
1077
|
+
background: var(--editor-accent-soft);
|
|
1078
|
+
}
|
|
1079
|
+
|